package main

import (
	"fmt"
	"sort"

	//	"io"
	"net/http"

	"encoding/json"

	"strconv"

	"io/ioutil"

	"time"

	"database/sql"

	"strings"

	_ "github.com/LukeMauldin/lodbc"
	_ "github.com/denisenkom/go-mssqldb"
	_ "github.com/mattn/go-adodb"

	"ma/ModulePath"

	"os"

	"sync"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"

	_ "github.com/mattn/go-sqlite3"
	uuid "github.com/satori/go.uuid"

	"encoding/csv"
	//_ "net/http/pprof"
	//	"runtime"
	//	"github.com/shopspring/decimal"
	"github.com/tealeg/xlsx"
)

/*
go-adodb ---cache leak

github.com/weigj/go-odbc  ---查询处理特殊字符有问题

github.com/alexbrainman/odbc ---sqlserver读取汉字乱码(编码格式没有转换)


*/

func testAdo() {
	var conf []string
	var db *sql.DB
	var err error
	conf = append(conf, "Provider=SQLOLEDB")
	conf = append(conf, "Data Source=127.0.0.1,1433")          // sqlserver IP 和 服务器名称
	conf = append(conf, "Initial Catalog=WellNameInformation") // 数据库名
	conf = append(conf, "user id=sa")                          // 登陆用户名
	conf = append(conf, "password=lh123456")                   // 登陆密码
	fmt.Println(strings.Join(conf, ";"))
	db, err = sql.Open("adodb", strings.Join(conf, ";"))
	if err != nil {
		fmt.Println("sql open:", err)
		return
	} else {

	}
	defer db.Close()

	beginTime := time.Now()
	// 执行SQL语句
	rows, err := db.Query("select [6506] from [AUTHINFO] order by ID")
	if err != nil {
		fmt.Println("query: ", err)
		return
	}
	for rows.Next() {
		var id float32

		rows.Scan(&id)
		fmt.Println("id: ", id)
	}

	defer rows.Close()

	fmt.Println(fmt.Sprintf("use time:%v", (time.Now().UnixNano()-beginTime.UnixNano())/1e6))
}

// 2008是要升级sqlserver数据库的补丁的，不建议使用。
func testMssqldb() {
	var server = "127.0.0.1"
	port := 1433
	var user = "sa"
	var password = "lh123456"
	var database = "WellNameInformation"

	//连接字符串
	connString := fmt.Sprintf("server=%s;port%d;database=%s;user id=%s;password=%s", server, port, database, user, password)
	fmt.Println(connString)

	//建立连接
	db, err := sql.Open("mssql", connString)
	if err != nil {
		fmt.Println("Open Connection failed:", err.Error())
	}
	defer db.Close()

	//通过连接对象执行查询
	rows, err := db.Query(`select ID from WellInformation order by ID`)
	if err != nil {
		fmt.Println("Query failed:", err.Error())
		return
	}
	defer rows.Close()

	for rows.Next() {
		var id int64

		rows.Scan(&id)
		fmt.Printf("id: %d \n", id)
	}

}

func testOdbc() {
	conn, err := sql.Open("odbc", "driver={SQL Server};SERVER=127.0.0.1;UID=sa;PWD=lh123456?;DATABASE=WellNameInformation")
	if err != nil {
		fmt.Println("Connecting Error", err.Error())
		return
	} else {
		fmt.Println("connect success!")
	}

	defer conn.Close()

	beginTime := time.Now()
	stmt, err := conn.Prepare("select ID from [WellNameInformation].[dbo].[WellInformation] order by ID")
	if err != nil {
		fmt.Println("Query Error", err)
		return
	}
	defer stmt.Close()
	row, err := stmt.Query()
	if err != nil {
		fmt.Println("Query Error", err)
		return
	}
	defer row.Close()

	cnt := 0
	for row.Next() {
		var id int
		if err := row.Scan(&id); err == nil {
			//fmt.Println(id)

			cnt++
		}
	}

	fmt.Println("record len:", cnt)

	fmt.Println(fmt.Sprintf("use time:%v", (time.Now().UnixNano()-beginTime.UnixNano())/1e6))

	fmt.Printf("%s\n", "finish")
	return
}

var (
	server   string
	port     int
	user     string
	password string
	database string

	sqlConn *sql.DB
	//odbcConn *sql.DB

	//user
	refreshSpan    int64
	ExpireTimeSpan time.Duration

	modelePath string

	mu sync.Mutex

	p_lock     sync.Mutex
	p_import_f int

	process_lock   sync.Mutex
	process_lock_n int

	ma_plan_lock   sync.Mutex
	ma_plan_lock_n int

	ma_temp_plan_lock   sync.Mutex
	ma_temp_plan_lock_n int

	g_time_format string = "2006-01-02 15:04:05"
)

func initLog() {

	beego.BeeLogger.DelLogger("console")

	var err error
	modelePath, err = ModulePath.GetModuleCurrentPath()
	if err != nil {
		fmt.Println("ModulePath.GetModuleCurrentPath() failed err:", err.Error())
		return
	}

	fmt.Println("modelePath:", modelePath)

	config := make(map[string]interface{})
	config["filename"] = modelePath + string("/logs/ma.log")
	config["level"] = 7
	config["maxlines"] = 0
	config["maxsize"] = 50 * 1024 * 1024 //50M
	config["daily"] = true
	config["maxdays"] = 10

	configJsonStr, err := json.Marshal(config)
	if err != nil {
		fmt.Println("package main init json.Marshal(config) failed,err:", err.Error())
		os.Exit(-1)
	}

	logs.SetLogger(logs.AdapterFile, string(configJsonStr))
}

func initSqlPool(driverType string) {

	if driverType == "ado" {
		var conf []string
		var err error
		conf = append(conf, "Provider=SQLOLEDB")
		conf = append(conf, fmt.Sprintf("Data Source=%s,%d", server, port)) // sqlserver IP 和 服务器名称
		conf = append(conf, fmt.Sprintf("Initial Catalog=%s", database))    // 数据库名
		conf = append(conf, fmt.Sprintf("user id=%s", user))                // 登陆用户名
		conf = append(conf, fmt.Sprintf("password=%s", password))           // 登陆密码
		fmt.Println(strings.Join(conf, ";"))
		sqlConn, err = sql.Open("adodb", strings.Join(conf, ";"))
		if err != nil {
			fmt.Println("sql open:", err.Error())
			os.Exit(0)
		} else {
			fmt.Println("connect success!")
		}

	} else {
		// dataSource := fmt.Sprintf("driver={SQL Server};SERVER=%s;UID=%s;PWD=%s;DATABASE=%s", server, user, password, database)
		// fmt.Println(dataSource)

		// var err error
		// sqlConn, err = sql.Open("lodbc", dataSource)
		// if err != nil {
		// 	fmt.Println("sql open:", err.Error())
		// 	os.Exit(0)
		// } else {
		// 	logs.Info("connect success!")
		// }
		dataSource := fmt.Sprintf(
			"server=%s;user id=%s;password=%s;database=%s;port=%d;encrypt=disable;TrustServerCertificate=true",
			server, // 仅服务器 IP 或域名（不包含端口）
			user,
			password,
			database,
			port, // 端口通过 port 参数单独指定
		)

		fmt.Println("lalalalala", dataSource)

		var err error
		// sqlConn, err = sql.Open("lodbc", dataSource)
		// sqlConn, err = sql.Open("odbc", dataSource)
		sqlConn, err = sql.Open("sqlserver", dataSource)
		if err = sqlConn.Ping(); err != nil {
			fmt.Println("sql open:", err.Error())
			os.Exit(0)
		} else {
			fmt.Println("连接成功")
		}
	}

	sqlConn.SetMaxOpenConns(10)
	sqlConn.SetMaxIdleConns(3)
}

func getConn(db string) (conn *sql.DB, err error) {
	var conf []string
	conf = append(conf, "Provider=SQLOLEDB")
	conf = append(conf, fmt.Sprintf("Data Source=%s,%d", server, port)) // sqlserver IP 和 服务器名称
	conf = append(conf, fmt.Sprintf("Initial Catalog=%s", db))          // 数据库名
	conf = append(conf, fmt.Sprintf("user id=%s", user))                // 登陆用户名
	conf = append(conf, fmt.Sprintf("password=%s", password))           // 登陆密码
	//fmt.Println(strings.Join(conf, ";"))
	conn, err = sql.Open("adodb", strings.Join(conf, ";"))
	if err != nil {
		fmt.Println("sql open:", err.Error())
		logs.Error("sql open:", err.Error())
		return
	}

	conn.SetMaxIdleConns(1)
	conn.SetMaxOpenConns(2)

	return
}

func getOdbcConn(db string) (conn *sql.DB, err error) {

	dataSource := fmt.Sprintf("driver={SQL Server};SERVER=%s;UID=%s;PWD=%s;DATABASE=%s", server, user, password, db)
	fmt.Println(dataSource)

	conn, err = sql.Open("lodbc", dataSource)
	if err != nil {
		logs.Error("sql open:", err.Error())
		return
	}

	conn.SetMaxOpenConns(2)
	conn.SetMaxIdleConns(1)

	return
}

func init() {

	refreshSpan = 5 //5s

	ExpireTimeSpan = time.Second * 25

	initLog()

	server = beego.AppConfig.String("server")
	port, _ = beego.AppConfig.Int("port")
	user = beego.AppConfig.String("user")
	password = beego.AppConfig.String("password")
	database = beego.AppConfig.String("database")

	initSqlPool("odbc")

}

func main() {

	go checkFileExpired()

	go check_ma_plan_warn_g()

	http.HandleFunc("/test", test)

	http.HandleFunc("/u_ma/login", Login)
	http.HandleFunc("/u_ma/loginOut", LoginOut)
	http.HandleFunc("/u_ma/refreshUser", refreshUser)

	http.HandleFunc("/u_ma/getMenu", getMenu)

	http.HandleFunc("/u_ma/getUsers", getUsers)
	http.HandleFunc("/u_ma/postUser", postUser)

	http.HandleFunc("/u_ma/get_p", get_p)
	http.HandleFunc("/u_ma/post_p", post_p)
	http.HandleFunc("/u_ma/del_p", del_p)
	http.HandleFunc("/u_ma/import_p", import_p)
	http.HandleFunc("/u_ma/export_sap", export_sap)
	http.HandleFunc("/u_ma/download_file", download_file)

	http.HandleFunc("/u_ma/get_process", get_process)
	http.HandleFunc("/u_ma/import_process", import_process)
	http.HandleFunc("/u_ma/update_process", update_process)
	http.HandleFunc("/u_ma/del_process", del_process)

	http.HandleFunc("/u_ma/import_ma_plan", import_ma_plan)
	http.HandleFunc("/u_ma/get_ma_plan", get_ma_plan)
	http.HandleFunc("/u_ma/update_ma_plan_ex", update_ma_plan_ex)
	http.HandleFunc("/u_ma/update_ma_plan_ex1", update_ma_plan_ex1)
	http.HandleFunc("/u_ma/remove_ma_plan", remove_ma_plan)
	http.HandleFunc("/u_ma/export_ma_plan", export_ma_plan)

	http.HandleFunc("/u_ma/get_p_id_options", get_p_id_options)
	http.HandleFunc("/u_ma/get_p_name", get_p_name)
	http.HandleFunc("/u_ma/get_ma_username", get_ma_username)

	http.HandleFunc("/u_ma/cal_completion_date", cal_completion_date)

	http.HandleFunc("/u_ma/get_rs", get_rs)
	http.HandleFunc("/u_ma/postRs", post_rs)

	http.HandleFunc("/u_ma/get_p_process_options", get_p_process_options)

	http.HandleFunc("/u_ma/export_plan_process", export_plan_process)

	http.HandleFunc("/u_ma/get_processes", get_processes)

	http.HandleFunc("/u_ma/export_processes", export_processes)

	http.HandleFunc("/u_ma/approval_provesses", approval_provesses)

	http.HandleFunc("/u_ma/export_base_processes", export_base_processes)

	http.HandleFunc("/u_ma/import_ma_temp_plan", import_ma_temp_plan)
	http.HandleFunc("/u_ma/get_ma_temp_plan", get_ma_temp_plan)
	http.HandleFunc("/u_ma/update_ma_temp_plan", update_ma_temp_plan)
	http.HandleFunc("/u_ma/remove_ma_temp_plan", remove_ma_temp_plan)
	http.HandleFunc("/u_ma/export_ma_temp_plan", export_ma_temp_plan)

	http.HandleFunc("/u_ma/get_ma_temp_plan_fin", get_ma_temp_plan_fin)
	http.HandleFunc("/u_ma/update_ma_temp_ex", update_ma_temp_ex)

	http.HandleFunc("/u_ma/export_ma_plan_processes", export_ma_plan_processes)

	//监听服务
	fmt.Println("listen server ...")
	err := http.ListenAndServe("0.0.0.0:8876", nil)
	if err != nil {
		fmt.Println("服务器错误")
	}

}

func export_ma_plan_processes(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_ma_plan_processes recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var filename string
	var file *xlsx.File

	var err error
	var req get_ma_plan_req
	var resp download_file_Resp
	var data []get_processes_resp_data
	var data1 []get_processes_resp_data

	var sqlstr string
	var rdRow *sql.Rows

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		return
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [return_task] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[return_task] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Bt != "" {

		if if_where {
			where_sql += fmt.Sprintf(` and [acd] >= '%s'`, req.Bt)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [acd] >= '%s'`, req.Bt)
			if_where = true
		}
	}

	if req.Et != "" {

		if if_where {
			where_sql += fmt.Sprintf(` and [acd] <= '%s'`, req.Et)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [acd] <= '%s'`, req.Et)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[data] from [ma_temp_plan] where [state]='已审核' order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[data] from [ma_temp_plan] where [state]='已审核' and %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("export_ma_plan Query err:%v", err.Error()))
		return
	}

	for rdRow.Next() {
		var s string
		var v ma_temp_plan
		var id int
		if err := rdRow.Scan(&id, &s); err == nil {

			json.Unmarshal([]byte(s), &v)
			v.ID = id

			if v.Repair_type == "退库" {
				for i := 0; i < len(v.Plan_data); i++ {
					tv := v.Plan_data[i]
					var d get_processes_resp_data
					d.Actual_finished_t = tv.Actual_finished_t
					d.ID = tv.ID
					d.Process_name = tv.Process_name
					d.Process_t = tv.Process_t
					d.Produce_user = tv.Produce_user
					d.P_id = v.P_id
					d.P_serial = v.P_serial
					d.Repair_id = v.Return_task
					d.Repair_plan = v.Repair_plan
					d.Serial_id = tv.ID
					d.State = tv.State
					d.Times = tv.Times

					data = append(data, d)
				}
			} else if v.Repair_type == "天工" {
				var d get_processes_resp_data
				d.Actual_finished_t = v.Actual_completed_date
				d.ID = v.ID
				d.P_id = v.P_id
				d.P_serial = v.P_serial
				d.Repair_id = v.Return_task
				d.Work = v.Work
				d.Work_h = v.Work_h
				d.State = v.State
				d.Produce_user = v.Repairer
				d.Head = v.Head

				data1 = append(data1, d)
			}

		} else {
			logs.Error("export_ma_plan scan Error", err.Error())
		}
	}
	rdRow.Close()

	file = xlsx.NewFile()
	sheet, err := file.AddSheet("sheet1")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	style := xlsx.NewStyle()
	font := *xlsx.NewFont(11, "宋体")
	style.Font = font
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
	}
	style.Alignment = alignment
	style.ApplyAlignment = true

	row := sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 := row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "退货任务"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "序列号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修方案"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工序"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "次数"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时费"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维保人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "审核状态"

	cost_map := make(map[string]float64)
	for i := 0; i < len(data); i++ {
		v := data[i]

		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_serial

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_plan

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Process_name

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Process_t

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = strconv.Itoa(v.Times)

		cell1 = row.AddCell()
		cell1.SetStyle(style)

		pt, _ := strconv.ParseFloat(v.Process_t, 64)
		cell1.Value = fmt.Sprintf(`%.2f`, pt*float64(v.Times)*25)

		if _, ok := cost_map[v.Produce_user]; ok {
			cost_map[v.Produce_user] += pt * float64(v.Times) * 25
		} else {
			cost_map[v.Produce_user] = pt * float64(v.Times) * 25
		}

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Produce_user

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Actual_finished_t

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.State
	}

	row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时费"

	for key, value := range cost_map {
		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = key

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = fmt.Sprintf(`%.2f`, value)
	}

	/*row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()*/

	sheet, err = file.AddSheet("sheet2")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	row = sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "负责人"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "序列号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "天工内容"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "天工工时"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工费"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维保人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "审核状态"

	cost_map = make(map[string]float64)
	for i := 0; i < len(data1); i++ {
		v := data1[i]

		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Head

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_serial

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Work

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Work_h

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		pt, _ := strconv.ParseFloat(v.Work_h, 64)
		cell1.Value = fmt.Sprintf(`%.2f`, pt*25)
		if _, ok := cost_map[v.Produce_user]; ok {
			cost_map[v.Produce_user] += pt * 25
		} else {
			cost_map[v.Produce_user] = pt * 25
		}

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Produce_user

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Actual_finished_t

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.State
	}

	row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时费"

	for key, value := range cost_map {
		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = key

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = fmt.Sprintf(`%.2f`, value)
	}

	filename = fmt.Sprintf(`%v.xlsx`, beginTime)
	err = file.Save("./file/" + filename)
	if err != nil {
		logs.Error("xlsx save err:", err.Error())
	}

	resp.FileId = filename

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_ma_plan_processes recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_ma_temp_plan_fin_data(req get_ma_temp_plan_req) (resp get_ma_temp_plan_resp) {

	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [return_task] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[return_task] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and [if_do]=1 and [state]='已审核'`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [if_do]=1 and [state]='已审核'`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and [if_do]=1 and [state]!='已审核'`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [if_do]=1 and [state]!='已审核'`)
			if_where = true
		}
	}

	if req.Head != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_id != "" {

		if if_where {
			likeStr := "%" + req.P_id + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_id + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_serial != "" {

		if if_where {
			likeStr := "%" + req.P_serial + "%"
			where_sql += fmt.Sprintf(` and [p_serial] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_serial + "%"
			where_sql += fmt.Sprintf(` [p_serial] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_type != "" {

		if if_where {
			likeStr := "%" + req.Repair_type + "%"
			where_sql += fmt.Sprintf(` and [rt] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_type + "%"
			where_sql += fmt.Sprintf(` [rt] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [ma_temp_plan]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [ma_temp_plan] where %s", where_sql)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_temp_plan query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_ma_temp_plan scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[data] from [ma_temp_plan] where ID not in (select top %v ID from [ma_temp_plan] order by acd desc) order by acd desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[data] from [ma_temp_plan] where %s and ID not in (select top %v ID from [ma_temp_plan] where %s order by acd desc) order by acd desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_temp_plan Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ma_temp_plan
		var id int
		var s string
		if err := rdRow.Scan(&id, &s); err == nil {
			json.Unmarshal([]byte(s), &d)
			d.ID = id

			if len(d.Recv_date) > 2 {
				d.Recv_date = d.Recv_date[2:]
			}

			if len(d.Actual_completed_date) > 2 {
				d.Actual_completed_date = d.Actual_completed_date[2:]
			}

			if len(d.Plan_data) == 0 {
				d.Plan_data = []plan_info{}
			}

			if d.State == "" {
				d.State = "未审核"
			}

			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ma_temp_plan scan Error", err.Error())
		}
	}

exit:
	return
}

func get_ma_temp_plan_fin(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("get_ma_temp_plan_fin recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_ma_temp_plan_req
	var resp get_ma_temp_plan_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	resp = get_ma_temp_plan_fin_data(req)

exit:

	jdata, _ := json.Marshal(resp)
	str := string(jdata)
	str = strings.ReplaceAll(str, "%", "%%")
	fmt.Fprintf(response, str)
	//fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("get_ma_temp_plan_fin recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func export_ma_temp_plan(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_ma_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var filename string
	var file *xlsx.File

	var req get_ma_temp_plan_req
	var resp download_file_Resp
	var data get_ma_temp_plan_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		return
	}

	req.Index = 1
	req.Count = 100000
	data = get_ma_temp_plan_data(req)
	fmt.Println(data)

	file = xlsx.NewFile()
	sheet, err := file.AddSheet("sheet1")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	style := xlsx.NewStyle()
	font := *xlsx.NewFont(11, "宋体")
	style.Font = font
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
	}
	style.Alignment = alignment
	style.ApplyAlignment = true

	row := sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 := row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "接收日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "退库任务"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "负责人"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品名称"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "序列号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修类型"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工作内容"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "初检分析"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修方案"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "自检记录"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "缺料情况"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "物料任务"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "转入E1库"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "转储单号"

	for i := 0; i < len(data.Data); i++ {
		v := data.Data[i]

		var return_task string
		if v.Return_task != "" {
			return_task = "http://123.54.1.214:10010/redmine/issues/" + v.Return_task
		}

		var link string
		if v.Link != "" {
			link = "http://123.54.1.214:10010/redmine/issues/" + v.Link
		}

		var mt string
		if v.Material_task != "" {
			mt = "http://123.54.1.214:10010/redmine/issues/" + v.Material_task
		}

		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度
		cell1 := row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Recv_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = return_task

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Head

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_name

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_serial

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repairer

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_type

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Work

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Inspection_analysis

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_plan

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Actual_completed_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = link

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Material_status

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = mt

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		if v.If_e1 {
			cell1.Value = "是"
		} else {
			cell1.Value = "否"
		}

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Odd_num
	}

	filename = fmt.Sprintf(`%v.xlsx`, beginTime)
	err = file.Save("./file/" + filename)
	if err != nil {
		logs.Error("xlsx save err:", err.Error())
	}

	resp.FileId = filename

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_ma_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func remove_ma_temp_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("remove_ma_temp_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp CommonResp
	var userinfo useInfo

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req remove_ma_plan_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	userinfo, err = getUserInfo(req.OpUser)
	if userinfo.RoleId != 1 {
		resp.Ret = 1
		goto exit
	}

	if req.ID == 0 {
		logs.Info("remove_ma_temp_plan req id ==0")
		resp.Ret = -1
		goto exit
	}

	sqlstr = fmt.Sprintf(`DELETE FROM [ma_temp_plan] where ID=%d`, req.ID)
	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("remove_ma_temp_plan err:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("remove_ma_temp_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func update_ma_temp_ex(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("update_ma_temp_ex recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp CommonResp
	var rows *sql.Rows
	var old_data ma_temp_plan
	var if_exist bool

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req update_ma_temp_plan_req
	json.Unmarshal(reqdata, &req)

	//	var user_info useInfo

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.Plan.ID == 0 {
		logs.Info("update_ma_temp_plan sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	/*user_info, _ = getUserInfo(req.OpUser)
	if user_info.RoleId > 1 {

		names := make(map[string]bool)
		names[req.Plan.Repairer] = true

		for i := 0; i < len(req.Plan.Plan_data); i++ {
			names[req.Plan.Plan_data[i].Produce_user] = true
		}

		if _, ok := names[req.OpUser]; !ok {
			logs.Info("普通用户不可修改不是自己的计划")
			resp.Ret = 1
			goto exit
		}
	}*/

	sqlstr = fmt.Sprintf(`select data from [ma_temp_plan] where ID=%d`, req.Plan.ID)
	rows, err = sqlConn.Query(sqlstr)
	if err == nil {
		for rows.Next() {
			var s string
			if err = rows.Scan(&s); err == nil {
				json.Unmarshal([]byte(s), &old_data)
				if_exist = true
			}
		}
	}

	if if_exist {
		old_data.Plan_data = req.Plan.Plan_data

		if true || old_data.Total_work_time == "" {
			var wt float64
			for i := 0; i < len(old_data.Plan_data); i++ {
				old_data.Plan_data[i].State = "已审核"

				t, _ := strconv.ParseFloat(old_data.Plan_data[i].Process_t, 64)

				t = t * float64(old_data.Plan_data[i].Times)

				wt += t
			}
			old_data.Total_work_time = fmt.Sprintf("%.2f", wt)
		}

		old_data.State = "已审核"

		s, _ := json.Marshal(old_data)
		sqlstr = fmt.Sprintf(`UPDATE [dbo].[ma_temp_plan]
		   SET [data] = '%s'
		      ,[return_task] = '%s'
		      ,[head] = '%s'
		      ,[p_id] = '%s'
		      ,[p_name] = '%s'
		      ,[p_serial] = '%s'
		      ,[repairer] = '%s'
		      ,[rt] = '%s'
		      ,[if_do] = %d
			,[state]='%s'
		 WHERE ID=%d`,
			string(s), old_data.Return_task, old_data.Head, old_data.P_id, old_data.P_name, old_data.P_serial,
			old_data.Repairer, old_data.Repair_type, old_data.If_do, old_data.State,
			req.Plan.ID)
		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_ma_temp_ex Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("update_ma_temp_ex recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func update_ma_temp_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("update_ma_temp_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp CommonResp
	var rows *sql.Rows
	var old_data ma_temp_plan
	var if_exist bool

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req update_ma_temp_plan_req
	json.Unmarshal(reqdata, &req)

	var user_info useInfo

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.Plan.ID == 0 {
		logs.Info("update_ma_temp_plan sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	sqlstr = fmt.Sprintf(`select data from [ma_temp_plan] where ID=%d`, req.Plan.ID)
	rows, err = sqlConn.Query(sqlstr)
	if err == nil {
		for rows.Next() {
			var s string
			if err = rows.Scan(&s); err == nil {
				json.Unmarshal([]byte(s), &old_data)
				if_exist = true
			}
		}
	}

	if if_exist {
		user_info, _ = getUserInfo(req.OpUser)
		if user_info.RoleId > 1 {

			names := make(map[string]bool)
			names[old_data.Repairer] = true

			for i := 0; i < len(old_data.Plan_data); i++ {
				names[old_data.Plan_data[i].Produce_user] = true
			}

			if _, ok := names[req.OpUser]; !ok {
				logs.Info("普通用户不可修改不是自己的计划")
				resp.Ret = 1
				goto exit
			}

			if old_data.State == "已审核" {
				resp.Ret = 1
				goto exit
			}
		}

		old_data = req.Plan

		if true || old_data.Total_work_time == "" {
			var wt float64
			for i := 0; i < len(old_data.Plan_data); i++ {
				t, _ := strconv.ParseFloat(old_data.Plan_data[i].Process_t, 64)

				t = t * float64(old_data.Plan_data[i].Times)

				wt += t
			}
			old_data.Total_work_time = fmt.Sprintf("%.2f", wt)
		}

		if old_data.Actual_completed_date != "" {
			old_data.If_do = 1

			if old_data.Repair_type == "天工" {
				old_data.State = "已审核"
			}
		}

		var if_e1 int
		if old_data.If_e1 {
			if_e1 = 1
		}

		s, _ := json.Marshal(old_data)
		sqlstr = fmt.Sprintf(`UPDATE [dbo].[ma_temp_plan]
		   SET [data] = '%s'
		      ,[return_task] = '%s'
		      ,[head] = '%s'
		      ,[p_id] = '%s'
		      ,[p_name] = '%s'
		      ,[p_serial] = '%s'
		      ,[repairer] = '%s'
		      ,[rt] = '%s'
		      ,[if_do] = %d
				,[if_e1]= %d
				,[state]='%s',[acd]='%s'
		 WHERE ID=%d`,
			string(s), old_data.Return_task, old_data.Head, old_data.P_id, old_data.P_name, old_data.P_serial,
			old_data.Repairer, old_data.Repair_type, old_data.If_do, if_e1, old_data.State, old_data.Actual_completed_date,
			req.Plan.ID)
		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_ma_plan_ex Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("update_ma_temp_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_ma_temp_plan_data(req get_ma_temp_plan_req) (resp get_ma_temp_plan_resp) {

	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [return_task] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[return_task] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and [if_do]=1`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [if_do]=1`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and [if_do]!=1`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [if_do]!=1`)
			if_where = true
		}
	}

	if req.If_e1 {

		if if_where {
			where_sql += fmt.Sprintf(` and [if_e1]=1`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [if_e1]=1`)
			if_where = true
		}
	}

	if req.Head != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_id != "" {

		if if_where {
			likeStr := "%" + req.P_id + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_id + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_serial != "" {

		if if_where {
			likeStr := "%" + req.P_serial + "%"
			where_sql += fmt.Sprintf(` and [p_serial] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_serial + "%"
			where_sql += fmt.Sprintf(` [p_serial] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if req.Repairer == "空" {
			if if_where {
				where_sql += fmt.Sprintf(` and ([repairer] ='' or [repairer] is null)`)
				if_where = true
			} else {
				where_sql += fmt.Sprintf(` ([repairer] ='' or [repairer] is null)`)
				if_where = true
			}
		} else {
			if if_where {
				likeStr := "%" + req.Repairer + "%"
				where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
				if_where = true
			} else {
				likeStr := "%" + req.Repairer + "%"
				where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
				if_where = true
			}
		}

	}

	if req.Repair_type != "" {

		if if_where {
			likeStr := "%" + req.Repair_type + "%"
			where_sql += fmt.Sprintf(` and [rt] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_type + "%"
			where_sql += fmt.Sprintf(` [rt] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [ma_temp_plan]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [ma_temp_plan] where %s", where_sql)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_temp_plan query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_ma_temp_plan scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[data] from [ma_temp_plan] where ID not in (select top %v ID from [ma_temp_plan] order by [acd] desc) order by [acd] desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[data] from [ma_temp_plan] where %s and ID not in (select top %v ID from [ma_temp_plan] where %s order by [acd] desc) order by [acd] desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_temp_plan Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ma_temp_plan
		var id int
		var s string
		if err := rdRow.Scan(&id, &s); err == nil {

			json.Unmarshal([]byte(s), &d)
			d.ID = id

			if len(d.Recv_date) > 2 {
				d.Recv_date = d.Recv_date[2:]
			}

			if len(d.Actual_completed_date) > 2 {
				d.Actual_completed_date = d.Actual_completed_date[2:]
			}

			if len(d.Plan_data) == 0 {
				d.Plan_data = []plan_info{}
			}

			if d.If_e1 {
				d.If_e1_str = "是"
			} else {
				d.If_e1_str = "否"
			}

			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ma_temp_plan scan Error", err.Error())
		}
	}

exit:
	return
}

func get_ma_temp_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("get_ma_temp_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_ma_temp_plan_req
	var resp get_ma_temp_plan_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	resp = get_ma_temp_plan_data(req)

exit:

	jdata, _ := json.Marshal(resp)

	str := string(jdata)
	str = strings.ReplaceAll(str, "%", "%%")
	fmt.Fprintf(response, str)

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("get_ma_temp_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func export_base_processes(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_base_processes recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_process_req
	var resp get_process_resp

	var file_resp download_file_Resp

	var sqlstr string
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		return
	}

	if req.P_id != "" {
		likeStr := "%" + req.P_id + "%"
		where_sql += fmt.Sprintf(`[p_id] like '%s'`, likeStr)
		if_where = true
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(`[p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Process_name != "" {

		if if_where {
			likeStr := "%" + req.Process_name + "%"
			where_sql += fmt.Sprintf(` and [process_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Process_name + "%"
			where_sql += fmt.Sprintf(`[process_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[p_id],[p_name],[process_name],[process_t] from [process] order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[p_id],[p_name],[process_name],[process_t] from [process] where %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("export_base_processes Query err:%v", err.Error()))
		return
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d process_info
		if err := rdRow.Scan(&d.ID, &d.P_id, &d.P_name, &d.Process_name, &d.Process_t); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("export_base_processes scan Error", err.Error())
		}
	}

	file := xlsx.NewFile()
	sheet, err := file.AddSheet("sheet1")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	style := xlsx.NewStyle()
	font := *xlsx.NewFont(11, "宋体")
	style.Font = font
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
	}
	style.Alignment = alignment
	style.ApplyAlignment = true

	row := sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 := row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品名称"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工序"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时"

	for i := 0; i < len(resp.Data); i++ {
		v := resp.Data[i]

		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_name

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Process_name

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Process_t

	}

	filename := fmt.Sprintf(`%v.xlsx`, beginTime)
	err = file.Save("./file/" + filename)
	if err != nil {
		logs.Error("xlsx save err:", err.Error())
	}

	file_resp.FileId = filename

	jdata, _ := json.Marshal(file_resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_plan_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func approval_provesses(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("approval_provesses recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp CommonResp
	var rows *sql.Rows
	var old_data ma_plan
	var if_exist bool

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req approval_provesses_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.ID == 0 {
		logs.Info("update_ma_plan_ex sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	sqlstr = fmt.Sprintf(`select data from [ma_plan] where [repair_id]='%s'`, req.Rid)
	rows, err = sqlConn.Query(sqlstr)
	if err == nil {
		for rows.Next() {
			var s string
			if err = rows.Scan(&s); err == nil {
				json.Unmarshal([]byte(s), &old_data)
				if_exist = true
			}
		}
	}

	if if_exist {
		for i := 0; i < len(old_data.Plan_data); i++ {
			if old_data.Plan_data[i].ID == req.Serial_id {
				if req.Undo {
					old_data.Plan_data[i].State = ""
				} else {
					old_data.Plan_data[i].State = "已审核"
				}

			}
		}
		s, _ := json.Marshal(old_data)
		sqlstr = fmt.Sprintf(`UPDATE [ma_plan] SET [data] = '%s' WHERE [repair_id]='%s' `,
			string(s), req.Rid)
		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_ma_plan_ex Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}

		if req.Undo {
			sqlstr = fmt.Sprintf(`UPDATE [dbo].[processes]
   				SET [state] = '%s' WHERE ID=%d`, "未审核", req.ID)
		} else {
			sqlstr = fmt.Sprintf(`UPDATE [dbo].[processes]
   				SET [state] = '%s' WHERE ID=%d`, "已审核", req.ID)
		}
		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_ma_plan_ex Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("approval_provesses recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

// 导出商丘维保已审核
func export_processes(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_processes recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var filename string
	var file *xlsx.File

	var err error
	var req get_ma_plan_req
	var resp download_file_Resp
	var data []get_processes_resp_data

	var sqlstr string
	var rdRow *sql.Rows

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		return
	}

	//	user_data, _ := getUserInfo(req.OpUser)

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [produce_user] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [produce_user] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Bt != "" {

		if if_where {
			where_sql += fmt.Sprintf(` and [acd] >= '%s'`, req.Bt)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [acd] >= '%s'`, req.Bt)
			if_where = true
		}
	}

	if req.Et != "" {

		if if_where {
			where_sql += fmt.Sprintf(` and [acd] <= '%s'`, req.Et)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [acd] <= '%s'`, req.Et)
			if_where = true
		}
	}

	if if_where {
		likeStr := "%" + "睿控维保" + "%"
		where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
		if_where = true
	} else {
		likeStr := "%" + "睿控维保" + "%"
		where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
		if_where = true
	}

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[data] from [ma_plan] where [state]='已审核' order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[data] from [ma_plan] where [state]='已审核' and %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("export_ma_plan Query err:%v", err.Error()))
		return
	}

	for rdRow.Next() {
		var s string
		var v ma_plan
		var id int
		if err := rdRow.Scan(&id, &s); err == nil {

			json.Unmarshal([]byte(s), &v)
			v.ID = id

			for i := 0; i < len(v.Plan_data); i++ {
				tv := v.Plan_data[i]
				var d get_processes_resp_data
				d.Actual_finished_t = tv.Actual_finished_t
				d.ID = tv.ID
				d.Process_name = tv.Process_name
				d.Process_t = tv.Process_t
				d.Produce_user = tv.Produce_user
				d.P_id = v.P_id
				d.P_serial = v.P_serial
				d.Repair_id = v.Repair_id
				d.Repair_plan = v.Repair_plan
				d.Serial_id = tv.ID
				d.State = tv.State
				d.Times = tv.Times
				data = append(data, d)
			}

		} else {
			logs.Error("export_ma_plan scan Error", err.Error())
		}
	}
	rdRow.Close()

	file = xlsx.NewFile()
	sheet, err := file.AddSheet("sheet1")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	style := xlsx.NewStyle()
	font := *xlsx.NewFont(11, "宋体")
	style.Font = font
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
	}
	style.Alignment = alignment
	style.ApplyAlignment = true

	row := sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 := row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修单号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "序列号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修方案"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工序"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "次数"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时费"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维保人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "审核状态"

	cost_map := make(map[string]float64)
	for i := 0; i < len(data); i++ {
		v := data[i]

		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_serial

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_plan

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Process_name

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Process_t

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = strconv.Itoa(v.Times)

		cell1 = row.AddCell()
		cell1.SetStyle(style)

		pt, _ := strconv.ParseFloat(v.Process_t, 64)
		cell1.Value = fmt.Sprintf(`%.2f`, pt*float64(v.Times)*25)

		if _, ok := cost_map[v.Produce_user]; ok {
			cost_map[v.Produce_user] += pt * float64(v.Times) * 25
		} else {
			cost_map[v.Produce_user] = pt * float64(v.Times) * 25
		}

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Produce_user

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Actual_finished_t

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.State
	}

	row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()
	row = sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时费"

	for key, value := range cost_map {
		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = key

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = fmt.Sprintf(`%.2f`, value)
	}

	filename = fmt.Sprintf(`%v.xlsx`, beginTime)
	err = file.Save("./file/" + filename)
	if err != nil {
		logs.Error("xlsx save err:", err.Error())
	}

	resp.FileId = filename

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_plan_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_done_processes(req get_ma_plan_req) (resp get_ma_plan_resp) {
	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var t_data []ma_plan

	var where_sql string
	var if_where bool

	//	user_data, _ := getUserInfo(req.OpUser)

	if req.ID != "" {
		likeStr := "%" + req.ID + "%"
		if if_where {
			where_sql += fmt.Sprintf(` and [ID] like '%s'`, likeStr)
		} else {
			where_sql += fmt.Sprintf(` [ID] like '%s'`, likeStr)
		}
		if_where = true
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and [state] ='已审核' and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [state] ='已审核' and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and ([state] !='已审核' or [state] is null) and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([state] !='已审核' or [state] is null) and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_status != "" {

		if if_where {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` and [rs] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` [rs] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Regional_head != "" {

		if if_where {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` and [regional_head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` [regional_head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Material_status != "" {

		if if_where {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` and [ms] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` [ms] like '%s'`, likeStr)
			if_where = true
		}
	}

	if if_where {
		likeStr := "%" + "睿控维保" + "%"
		where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
		if_where = true
	} else {
		likeStr := "%" + "睿控维保" + "%"
		where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
		if_where = true
	}

	if req.Station != "" {

		if if_where {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` and [station] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` [station] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [ma_plan]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [ma_plan] where %s", where_sql)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_ma_plan scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[data],[mcn],[state] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by [acd] desc) order by [acd] desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[data],[mcn],[state] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by [acd] desc) order by [acd] desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var mcn string
		var state string
		if err := rdRow.Scan(&id, &s, &mcn, &state); err == nil {
			json.Unmarshal([]byte(s), &d)
			d.ID = id
			d.If_warn = 0
			d.Mcn = mcn

			if len(d.Recv_date) > 2 {
				d.Recv_date = d.Recv_date[2:]
			}
			if len(d.Dispath_date) > 2 {
				d.Dispath_date = d.Dispath_date[2:]
			}

			if len(d.Repair_quotation_date) > 2 {
				d.Repair_quotation_date = d.Repair_quotation_date[2:]
			}

			if len(d.Repair_OK_date) > 2 {
				d.Repair_OK_date = d.Repair_OK_date[2:]
			}

			if len(d.Committed_completed_date) > 2 {
				d.Committed_completed_date = d.Committed_completed_date[2:10]
				d.Committed_completed_date = strings.ReplaceAll(d.Committed_completed_date, "-", "/")
			}

			if len(d.Actual_completed_date) > 2 {
				d.Actual_completed_date = d.Actual_completed_date[2:]
			}

			if len(d.Material_committed_date) > 2 {
				d.Material_committed_date = d.Material_committed_date[2:]
			}

			if len(d.Date_of_issuance) > 2 {
				d.Date_of_issuance = d.Date_of_issuance[2:]
			}

			if d.Actual_completed_date != "" && d.Committed_completed_date != "" {
				if d.Actual_completed_date <= d.Committed_completed_date {
					d.Overdue = "否"
				} else {
					d.Overdue = "是"
				}
			} else {
				d.Overdue = ""
			}

			if len(d.Plan_data) == 0 {
				d.Plan_data = []plan_info{}
			}

			if state != "" && d.State == "" {
				d.State = state
			}

			t_data = append(t_data, d)

			/*
				if len(t_data) == 0 {
					t_data = append(t_data, d)
				} else {
					if d.Repairer == t_data[len(t_data)-1].Repairer {
						t_data = append(t_data, d)
					} else {
						//排序
						sort.Slice(t_data, func(i, j int) bool {
							return t_data[i].Committed_completed_date > t_data[j].Committed_completed_date
						})
						resp.Data = append(resp.Data, t_data...)

						t_data = []ma_plan{}
						t_data = append(t_data, d)
					}
				}*/

		} else {
			logs.Error("get_ma_plan scan Error", err.Error())
		}
	}

exit:
	//fmt.Println(t_data)
	if len(t_data) > 0 {
		sort.Slice(t_data, func(i, j int) bool {
			return t_data[i].Actual_completed_date > t_data[j].Actual_completed_date
		})
		resp.Data = append(resp.Data, t_data...)
	}
	return
}

func get_not_done_processes(req get_ma_plan_req) (resp get_ma_plan_resp) {

	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	//	user_data, _ := getUserInfo(req.OpUser)

	if req.ID != "" {
		likeStr := "%" + req.ID + "%"
		if if_where {
			where_sql += fmt.Sprintf(` and [ID] like '%s'`, likeStr)
		} else {
			where_sql += fmt.Sprintf(` [ID] like '%s'`, likeStr)
		}
		if_where = true
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	//计划必须已处理
	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and [state] ='已审核' and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [state] ='已审核' and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and ([state] !='已审核' or [state] is null) and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([state] !='已审核' or [state] is null) and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_status != "" {

		if if_where {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` and [rs] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` [rs] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Regional_head != "" {

		if if_where {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` and [regional_head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` [regional_head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Material_status != "" {

		if if_where {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` and [ms] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` [ms] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if if_where {
		likeStr := "%" + "睿控维保" + "%"
		where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
		if_where = true
	} else {
		likeStr := "%" + "睿控维保" + "%"
		where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
		if_where = true
	}

	if req.Station != "" {

		if if_where {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` and [station] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` [station] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [ma_plan]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [ma_plan] where %s", where_sql)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_ma_plan scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if req.Sort_field == "" {
		if !if_where {
			sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by acd desc) order by acd desc", req.Count, (req.Index-1)*req.Count)
		} else {
			sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by acd desc) order by acd desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
		}
	} else {
		var field string
		if req.Sort_field == "客户名称" {
			field = "[customer]"
		} else if req.Sort_field == "负责人" {
			field = "[regional_head]"
		} else if req.Sort_field == "维修人员" {
			field = "[repairer]"
		} else if req.Sort_field == "维修状态" {
			field = "[rs]"
		} else if req.Sort_field == "承诺完成日期" {
			field = "[ccd]"
		} else {
			field = "ID"
		}

		if !if_where {
			sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by %s desc) order by %s desc", req.Count, (req.Index-1)*req.Count, field, field)
		} else {
			sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by %s desc) order by %s desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql, field, field)
		}
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var if_warn int
		var mcn string
		if err := rdRow.Scan(&id, &s, &if_warn, &mcn); err == nil {
			json.Unmarshal([]byte(s), &d)
			d.ID = id
			d.Mcn = mcn

			if len(d.Recv_date) > 2 {
				d.Recv_date = d.Recv_date[2:]
			}
			if len(d.Dispath_date) > 2 {
				d.Dispath_date = d.Dispath_date[2:]
			}

			if len(d.Repair_quotation_date) > 2 {
				d.Repair_quotation_date = d.Repair_quotation_date[2:]
			}

			if len(d.Repair_OK_date) > 2 {
				d.Repair_OK_date = d.Repair_OK_date[2:]
			}

			if len(d.Committed_completed_date) > 2 {
				d.Committed_completed_date = d.Committed_completed_date[2:10]
				d.Committed_completed_date = strings.ReplaceAll(d.Committed_completed_date, "-", "/")
			}

			if len(d.Actual_completed_date) > 2 {
				d.Actual_completed_date = d.Actual_completed_date[2:]
			}

			if len(d.Material_committed_date) > 2 {
				d.Material_committed_date = d.Material_committed_date[2:]
			}

			if len(d.Date_of_issuance) > 2 {
				d.Date_of_issuance = d.Date_of_issuance[2:]
			}

			if d.Actual_completed_date != "" && d.Committed_completed_date != "" {
				if d.Actual_completed_date <= d.Committed_completed_date {
					d.Overdue = "否"
				} else {
					d.Overdue = "是"
				}
			} else {
				d.Overdue = ""
			}

			if len(d.Plan_data) == 0 {
				d.Plan_data = []plan_info{}
			}

			if d.State == "" {
				d.State = "未审核"
			}

			d.If_warn = if_warn
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ma_plan scan Error", err.Error())
		}
	}

exit:
	return
}

func get_processes(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("get_processes recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_ma_plan_req
	var resp get_ma_plan_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if !req.If_done { //未处理
		resp = get_not_done_processes(req)
	} else {
		resp = get_done_processes(req)
	}

exit:

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("get_processes recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func export_plan_process(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_plan_process recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var filename string
	var file *xlsx.File

	var err error
	var req get_ma_plan_req
	var resp download_file_Resp
	var data []ma_plan

	var sqlstr string
	var rdRow *sql.Rows

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		return
	}

	user_data, _ := getUserInfo(req.OpUser)

	if req.ID != "" {
		likeStr := "%" + req.ID + "%"
		if if_where {
			where_sql += fmt.Sprintf(` and [ID] like '%s'`, likeStr)
		} else {
			where_sql += fmt.Sprintf(` [ID] like '%s'`, likeStr)
		}
		if_where = true
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_status != "" {

		if if_where {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` and [rs] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` [rs] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Regional_head != "" {

		if if_where {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` and [regional_head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` [regional_head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Material_status != "" {

		if if_where {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` and [ms] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` [ms] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if user_data.RoleId != 1 {
		if if_where {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
			if_where = true
		}
	} else {
		if req.Location != "" {

			if if_where {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
				if_where = true
			} else {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
				if_where = true
			}
		}

	}

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[data],[location] from [ma_plan] order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[data],[location] from [ma_plan] where %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("export_ma_plan Query err:%v", err.Error()))
		return
	}

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var location string
		if err := rdRow.Scan(&id, &s, &location); err == nil {
			json.Unmarshal([]byte(s), &d)
			d.ID = id
			d.Location = location
			data = append(data, d)
		} else {
			logs.Error("export_ma_plan scan Error", err.Error())
		}
	}
	rdRow.Close()

	file = xlsx.NewFile()
	sheet, err := file.AddSheet("sheet1")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	style := xlsx.NewStyle()
	font := *xlsx.NewFont(11, "宋体")
	style.Font = font
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
	}
	style.Alignment = alignment
	style.ApplyAlignment = true

	row := sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 := row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修单号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "序列号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工序"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "工时"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维保人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "审核状态"

	for i := 0; i < len(data); i++ {
		v := data[i]

		for j := 0; j < len(v.Plan_data); j++ {

			row := sheet.AddRow()
			//row.SetHeightCM(1) //设置每行的高度

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.Repair_id

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.P_id

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.P_serial

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.Plan_data[j].Process_name

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.Plan_data[j].Process_t

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.Plan_data[j].Produce_user

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.Plan_data[j].Actual_finished_t

			cell1 = row.AddCell()
			cell1.SetStyle(style)
			cell1.Value = v.Plan_data[j].State
		}
	}

	filename = fmt.Sprintf(`%v.xlsx`, beginTime)
	err = file.Save("./file/" + filename)
	if err != nil {
		logs.Error("xlsx save err:", err.Error())
	}

	resp.FileId = filename

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_plan_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_p_process_options(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("get_p_process_options recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var sqlstr string
	var rdRow *sql.Rows
	var err error

	var req get_p_process_options_req
	var resp get_p_process_options_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.P_id == "" {
		goto exit
	}

	sqlstr = fmt.Sprintf("select [ID],[p_id],[p_name],[process_name],[process_t] from [process] where [p_id] ='%s' order by ID desc", req.P_id)
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_p_process_options Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d process_info
		if err := rdRow.Scan(&d.ID, &d.P_id, &d.P_name, &d.Process_name, &d.Process_t); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_p_process_options scan Error", err.Error())
		}
	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("get_p_process_options recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func post_rs(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("post_rs recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error

	var req post_rs_req
	var resp CommonResp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.Oper_type == 1 {
		insert_sql := fmt.Sprintf(`INSERT INTO [rs] ([rs]) VALUES ('%s')`, req.State)
		_, err = sqlConn.Exec(insert_sql)
		if err != nil {
			logs.Error(fmt.Sprintf(`post_rs insert err:%s`, err.Error()))
		}
	} else if req.Oper_type == 2 {
		if req.ID == 0 {
			goto exit
		}

		update_sql := fmt.Sprintf(`UPDATE [rs] SET [rs] = '%s' WHERE ID=%d`, req.State, req.ID)
		_, err = sqlConn.Exec(update_sql)
		if err != nil {
			logs.Error(fmt.Sprintf(`post_rs update err:%s`, err.Error()))
		}
	} else if req.Oper_type == 3 {
		del_sql := fmt.Sprintf(`DELETE FROM [rs] WHERE ID=%d `, req.ID)
		_, err = sqlConn.Exec(del_sql)
		if err != nil {
			logs.Error(fmt.Sprintf(`post_rs del err:%s`, err.Error()))
		}
	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("post_rs recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_rs(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("get_rs recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var sqlstr string
	var rows *sql.Rows
	var err error

	var req get_rs_req
	var resp get_rs_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.State == "" {
		sqlstr = fmt.Sprintf(`SELECT [ID],[rs] FROM [rs] order by ID desc`)
	} else {

		likestr := "%" + req.State + "%"
		sqlstr = fmt.Sprintf(`SELECT [ID],[rs] FROM [rs] where rs like '%s' order by ID desc`, likestr)
	}

	rows, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf(`get_rs query err:%s`, err.Error()))
		goto exit
	}

	for rows.Next() {
		var d Repair_state
		if err = rows.Scan(&d.ID, &d.Rs); err == nil {
			resp.Data = append(resp.Data, d)
		}

	}
	rows.Close()

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("get_rs recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func cal_completion_date(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("cal_completion_date recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var sqlstr string
	var resp cal_completion_date_resp
	var days int

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req cal_completion_date_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.Bt == "" {
		logs.Info("cal_completion_date req bt 为空")
		goto exit
	}

	req.Bt = strings.ReplaceAll(req.Bt, "/", "-") + " 00:00:00"
	days, _ = strconv.Atoi(req.Days)
	if days > 0 {
		m := make(map[int]int)
		var cnt int

		loc, _ := time.LoadLocation("Local")
		bt, _ := time.ParseInLocation(g_time_format, req.Bt, loc)

		fmt.Println(bt.Month())
		id := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()

		sqlstr = fmt.Sprintf(`select [day],[type] FROM [holiday] where [day] >%d `, id)
		fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Info("cal_completion_date err:", err.Error())
			goto exit
		}

		for rows.Next() {
			var day, day_type int
			if err = rows.Scan(&day, &day_type); err == nil {
				m[day] = day_type
			}
		}
		rows.Close()
		fmt.Println(m)

		for {

			if cnt >= days {
				resp.Completion_date = bt.Format(g_time_format)
				if len(resp.Completion_date) >= 19 {
					resp.Completion_date = resp.Completion_date[:10]
				}
				break
			}

			bt = bt.Add(time.Hour * 24)
			key := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()
			if _, ok := m[key]; ok {
				//1--假期  2--上班
				if m[key] == 1 {

				} else if m[key] == 2 {
					cnt++
				}
			} else {
				if int(bt.Weekday()) == 0 || int(bt.Weekday()) == 6 {

				} else {
					cnt++
				}
			}

		}
	} else {
		resp.Completion_date = req.Bt
		goto exit
	}

exit:

	if len(resp.Completion_date) >= 19 {
		resp.Completion_date = resp.Completion_date[:10]
	}
	resp.Completion_date = strings.ReplaceAll(resp.Completion_date, "-", "/")

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("cal_completion_date recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func export_ma_plan(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_ma_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var filename string
	var file *xlsx.File

	var err error
	var req get_ma_plan_req
	var resp download_file_Resp
	var data []ma_plan

	var sqlstr string
	var rdRow *sql.Rows

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		return
	}

	user_data, _ := getUserInfo(req.OpUser)

	if req.ID != "" {
		likeStr := "%" + req.ID + "%"
		if if_where {
			where_sql += fmt.Sprintf(` and [ID] like '%s'`, likeStr)
		} else {
			where_sql += fmt.Sprintf(` [ID] like '%s'`, likeStr)
		}
		if_where = true
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_status != "" {

		if if_where {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` and [rs] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` [rs] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Regional_head != "" {

		if if_where {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` and [regional_head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` [regional_head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Material_status != "" {

		if if_where {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` and [ms] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` [ms] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Bt != "" {

		if if_where {
			where_sql += fmt.Sprintf(` and [acd] >= '%s'`, req.Bt)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [acd] >= '%s'`, req.Bt)
			if_where = true
		}
	}

	if req.Et != "" {

		if if_where {
			where_sql += fmt.Sprintf(` and [acd] <= '%s'`, req.Et)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` [acd] <= '%s'`, req.Et)
			if_where = true
		}
	}

	if user_data.RoleId != 1 {
		if if_where {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
			if_where = true
		}
	} else {
		if req.Location != "" {

			if if_where {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
				if_where = true
			} else {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
				if_where = true
			}
		}

	}

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[data],[location],[mcn] from [ma_plan] order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[data],[location],[mcn] from [ma_plan] where %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("export_ma_plan Query err:%v", err.Error()))
		return
	}

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var location, mcn string
		if err := rdRow.Scan(&id, &s, &location, &mcn); err == nil {
			json.Unmarshal([]byte(s), &d)
			d.ID = id
			d.Location = location
			d.Mcn = mcn
			data = append(data, d)
		} else {
			logs.Error("export_ma_plan scan Error", err.Error())
		}
	}
	rdRow.Close()

	file = xlsx.NewFile()
	sheet, err := file.AddSheet("sheet1")
	if err != nil {
		logs.Error("file add sheet err:", err.Error())
	}

	style := xlsx.NewStyle()
	font := *xlsx.NewFont(11, "宋体")
	style.Font = font
	alignment := xlsx.Alignment{
		Horizontal: "center",
		Vertical:   "center",
	}
	style.Alignment = alignment
	style.ApplyAlignment = true

	row := sheet.AddRow()
	//row.SetHeightCM(1) //设置每行的高度
	cell1 := row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维保位置"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "接收日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "下发日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修单号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修合同号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "报告编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "客户名称"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "负责人"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品编号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "产品名称"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "序列号"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修人员"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修方案"

	/*cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "库存"*/

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "承诺维修日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修报价日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "维修状态"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "确认维修日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "是否维修"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "承诺完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "实际完成日期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "超期"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "报价耗时(天)"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "缺料情况"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "承诺到料"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "物料任务"

	cell1 = row.AddCell()
	cell1.SetStyle(style)
	cell1.Value = "总工时"

	for i := 0; i < len(data); i++ {
		v := data[i]

		var task string
		if v.Material_task != "" {
			task = "http://123.54.1.214:10010/redmine/issues/" + v.Material_task
		}

		row := sheet.AddRow()
		//row.SetHeightCM(1) //设置每行的高度
		cell1 := row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Location

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Recv_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Dispath_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Mcn

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_report_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Customer

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Regional_head

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_id

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_name

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.P_serial

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repairer

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_plan

		/*cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Inventory*/

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_cycle

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_quotation_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_status

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Repair_OK_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.If_repair

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Committed_completed_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Actual_completed_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Overdue

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Quotation

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Material_status

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Material_committed_date

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = task

		cell1 = row.AddCell()
		cell1.SetStyle(style)
		cell1.Value = v.Total_work_time

	}

	filename = fmt.Sprintf(`%v.xlsx`, beginTime)
	err = file.Save("./file/" + filename)
	if err != nil {
		logs.Error("xlsx save err:", err.Error())
	}

	resp.FileId = filename

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_ma_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func remove_ma_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("remove_ma_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp CommonResp
	var userinfo useInfo

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req remove_ma_plan_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	userinfo, err = getUserInfo(req.OpUser)
	if userinfo.RoleId != 1 {
		resp.Ret = 1
		goto exit
	}

	if req.ID == 0 {
		logs.Info("remove_ma_plan req id ==0")
		resp.Ret = -1
		goto exit
	}

	sqlstr = fmt.Sprintf(`DELETE FROM [ma_plan] where ID=%d`, req.ID)
	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("remove_ma_plan err:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("remove_ma_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_ma_username(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("get_ma_username recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_ma_username_req
	var resp get_ma_username_resp

	var users []useInfo

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	//user_data, _ := getUserInfo(req.OpUser)

	users, _ = get_all_user()
	for i := 0; i < len(users); i++ {
		if users[i].Username != "孙青山" && users[i].Username != "武杏丽" && users[i].Username != "霍涛" &&
			users[i].Username != "王真" && users[i].Username != "李俊杉" && users[i].Username != "马纺霞" &&
			users[i].Username != "温亚辉" && users[i].Username != "尚永强" && users[i].Username != "叶修令" &&
			users[i].RoleId != 3 {

			if req.Location != "" {
				if req.Location == "现场维保" && users[i].Location == "现场维保" {
					resp.Data = append(resp.Data, users[i].Username)
				} else if req.Location == "睿控维保" && (users[i].Location == "睿控维保" || users[i].Location == "") {
					resp.Data = append(resp.Data, users[i].Username)
				}

			} else {
				resp.Data = append(resp.Data, users[i].Username)
			}
		}

	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("get_ma_username recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_p_name(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("get_p_name recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_p_name_req
	var resp get_p_name_resp

	var sqlstr string
	var rdRow *sql.Rows
	var err error

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.P_id != "" {
		sqlstr = fmt.Sprintf("select distinct [p_name] from [process] where p_id = '%s' ", req.P_id)
	} else {
		goto exit
	}

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_p_name Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d string
		if err := rdRow.Scan(&d); err == nil {
			resp.P_name = d
		} else {
			logs.Error("get_p_name scan Error", err.Error())
		}
	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("get_p_name recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_p_id_options(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("get_p_id_options recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_p_id_options_req
	var resp get_p_id_options_resp

	var sqlstr string
	var rdRow *sql.Rows
	var err error

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.P_like_id != "" {
		like_id := "%" + req.P_like_id + "%"
		sqlstr = fmt.Sprintf("select distinct [p_id] from [process] where p_id like '%s' ", like_id)
	} else {
		sqlstr = fmt.Sprintf("select distinct [p_id] from [process] ")
	}

	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_p_id_options Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d string

		if err := rdRow.Scan(&d); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_p_id_options scan Error", err.Error())
		}
	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("get_p_id_options recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func update_ma_plan_ex1(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("update_ma_plan_ex recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp CommonResp
	var rows *sql.Rows
	var old_data ma_plan
	var location string
	var if_exist bool

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req update_ma_plan_req
	json.Unmarshal(reqdata, &req)

	var user_info useInfo

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.Plan.ID == 0 {
		logs.Info("update_ma_plan_ex sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	user_info, _ = getUserInfo(req.OpUser)
	if req.OpUser != "霍涛" && user_info.RoleId > 1 {

		names := make(map[string]bool)
		names[req.Plan.Repairer] = true

		for i := 0; i < len(req.Plan.Plan_data); i++ {
			names[req.Plan.Plan_data[i].Produce_user] = true
		}

		if _, ok := names[req.OpUser]; !ok {
			logs.Info("普通用户不可修改不是自己的计划")
			resp.Ret = 1
			goto exit
		}
	}

	sqlstr = fmt.Sprintf(`select data,[location] from [ma_plan] where ID=%d`, req.Plan.ID)
	rows, err = sqlConn.Query(sqlstr)
	if err == nil {
		for rows.Next() {
			var s string
			if err = rows.Scan(&s, &location); err == nil {
				json.Unmarshal([]byte(s), &old_data)
				if_exist = true
			}
		}
	}

	if if_exist {
		old_data.Plan_data = []plan_info{}
		var wt float64
		for i := 0; i < len(req.Plan.Plan_data); i++ {
			v := req.Plan.Plan_data[i]
			var d plan_info
			d.Actual_finished_t = v.Actual_finished_t
			d.ID = v.ID
			d.Process_name = v.Process_name
			d.Process_t = v.Process_t
			d.Produce_user = v.Produce_user
			d.State = "已审核"
			d.Times = v.Times

			t, _ := strconv.ParseFloat(v.Process_t, 64)
			t = t * float64(v.Times)
			wt += t

			old_data.Plan_data = append(old_data.Plan_data, d)
		}
		old_data.Total_work_time = fmt.Sprintf("%.2f", wt)

		//old_data.Total_work_time = req.Plan.Total_work_time
		old_data.State = "已审核"

		s, _ := json.Marshal(old_data)
		sqlstr = fmt.Sprintf(`UPDATE [ma_plan] SET [data] = '%s',[state] = '%s' WHERE ID=%d`,
			string(s), "已审核",
			req.Plan.ID)
		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_ma_plan_ex Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("update_ma_plan_ex recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func update_ma_plan_ex(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("update_ma_plan_ex recv req begin", time.Now().Format("2006-01-02 15:04:05"))
	fmt.Println("123123")
	var err error
	var sqlstr string
	var resp CommonResp
	var rows *sql.Rows
	var old_data ma_plan
	var location string
	var if_exist bool

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req update_ma_plan_req
	json.Unmarshal(reqdata, &req)

	var user_info useInfo

	// b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	// if !b {
	// 	resp.Ret = -1
	// 	goto exit
	// }

	if req.Plan.ID == 0 {
		logs.Info("update_ma_plan_ex sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	user_info, _ = getUserInfo(req.OpUser)

	sqlstr = fmt.Sprintf(`select data,[location] from [ma_plan] where ID=%d`, req.Plan.ID)
	rows, err = sqlConn.Query(sqlstr)
	if err == nil {
		for rows.Next() {
			var s string
			if err = rows.Scan(&s, &location); err == nil {
				json.Unmarshal([]byte(s), &old_data)
				if_exist = true
			}
		}
	}

	if if_exist {

		if user_info.RoleId > 1 {

			names := make(map[string]bool)
			names[old_data.Repairer] = true

			for i := 0; i < len(old_data.Plan_data); i++ {
				names[old_data.Plan_data[i].Produce_user] = true
			}

			if _, ok := names[req.OpUser]; !ok {
				logs.Info("普通用户不可修改不是自己的计划")
				resp.Ret = 1
				goto exit
			}

			if old_data.State == "已审核" {
				resp.Ret = 1
				goto exit
			}
		}

		old_data = req.Plan

		if old_data.Actual_completed_date != "" && old_data.Committed_completed_date != "" {
			if old_data.Actual_completed_date <= old_data.Committed_completed_date {
				old_data.Overdue = "否"
			} else {
				old_data.Overdue = "是"
			}
		} else {
			old_data.Overdue = ""
		}

		//报价花费时间（天）
		if old_data.Repair_quotation_date != "" {
			loc, _ := time.LoadLocation("Local")
			et, _ := time.ParseInLocation(g_time_format, strings.ReplaceAll(old_data.Repair_quotation_date, "/", "-")+" 00:00:00", loc)
			bt, _ := time.ParseInLocation(g_time_format, strings.ReplaceAll(old_data.Dispath_date, "/", "-")+" 00:00:00", loc)
			fmt.Println(et, bt)

			var cnt int
			var key int
			b_key := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()
			e_key := et.Year()*10000 + int(et.Month())*100 + et.Day()
			key = b_key

			m := make(map[int]int)
			sqlstr = fmt.Sprintf(`select [day],[type] FROM [holiday] where [day] >%d `, b_key)
			fmt.Println(sqlstr)
			rows, err := sqlConn.Query(sqlstr)
			if err != nil {
				logs.Info("update_ma_plan_ex err:", err.Error())
				resp.Ret = -1
				goto exit
			}

			for rows.Next() {
				var day, day_type int
				if err = rows.Scan(&day, &day_type); err == nil {
					m[day] = day_type
				}
			}
			rows.Close()

			if e_key > b_key {
				for {

					if key >= e_key {
						break
					}

					bt = bt.Add(time.Hour * 24)
					key = bt.Year()*10000 + int(bt.Month())*100 + bt.Day()

					if _, ok := m[key]; ok {
						//1--假期  2--上班
						if m[key] == 1 {
						} else if m[key] == 2 {
							cnt++
							//fmt.Println(key)
						}
					} else {
						if int(bt.Weekday()) == 0 || int(bt.Weekday()) == 6 {
						} else {
							cnt++
							//fmt.Println(key)
						}
					}

				}
				old_data.Quotation = strconv.Itoa(cnt)
			} else {
				old_data.Quotation = strconv.Itoa(0)
			}

		} else {
			old_data.Quotation = "未报价"
		}

		old_data.If_warn = warn_ma_plan(old_data)

		if true || old_data.Total_work_time == "" {
			var wt float64
			for i := 0; i < len(old_data.Plan_data); i++ {
				t, _ := strconv.ParseFloat(old_data.Plan_data[i].Process_t, 64)

				t = t * float64(old_data.Plan_data[i].Times)

				wt += t
			}
			old_data.Total_work_time = fmt.Sprintf("%.2f", wt)
		}

		s, _ := json.Marshal(old_data)
		fmt.Println("555555")
		fmt.Println(string(s))
		sqlstr = fmt.Sprintf(`UPDATE [ma_plan] SET [data] = '%s',[repair_id] = '%s',[p_id] = '%s',[p_name]= '%s',[if_repair]='%s',[rs]='%s',[repairer]='%s',[regional_head]='%s',[ms]='%s',[customer]='%s',[ccd]='%s',[if_warn]=%d,[mcn]='%s',[acd]='%s' WHERE ID=%d`,
			string(s), old_data.Repair_id, old_data.P_id, old_data.P_name,
			req.Plan.If_repair, req.Plan.Repair_status,
			req.Plan.Repairer, req.Plan.Regional_head, req.Plan.Material_status,
			req.Plan.Customer, req.Plan.Committed_completed_date, old_data.If_warn,
			req.Plan.Mcn, req.Plan.Actual_completed_date,
			req.Plan.ID)
		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_ma_plan_ex Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}

		if location == "睿控维保" {
			sqlstr = fmt.Sprintf(`DELETE FROM [dbo].[processes] where [repair_id]='%s'`, old_data.Repair_id)
			sqlConn.Exec(sqlstr)

			for i := 0; i < len(old_data.Plan_data); i++ {
				v := old_data.Plan_data[i]
				sqlstr = fmt.Sprintf(`INSERT INTO [dbo].[processes]
           ([repair_id]
           ,[p_id]
           ,[p_serial]
           ,[rp]
           ,[serial_id]
           ,[produce_plan]
           ,[produce_plan_use_t]
           ,[produce_user]
           ,[p_actual_finished_t]
           ,[state]
           ,[times])
     VALUES
           ('%s'
           ,'%s'
        	,'%s'
           ,'%s'
           ,%d
           ,'%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,%d)`, old_data.Repair_id, old_data.P_id, old_data.P_serial, old_data.Repair_plan,
					v.ID, v.Process_name, v.Process_t, v.Produce_user, v.Actual_finished_t, v.State, v.Times)
				_, err = sqlConn.Exec(sqlstr)
				if err != nil {
					logs.Info("update_ma_plan_ex Exec Error:", err.Error())
					resp.Ret = -1
					goto exit
				}
			}

		}
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("update_ma_plan_ex recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func check_ma_plan_warn() {

	sqlstr := fmt.Sprintf("select [ID],[data],[if_warn] from [ma_plan] ")

	rdRow, err := sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("check_ma_plan_warn Query err:%v", err.Error()))
		return
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var if_warn int
		if err := rdRow.Scan(&id, &s, &if_warn); err == nil {
			json.Unmarshal([]byte(s), &d)
			if_warn = warn_ma_plan(d)

			sqlstr = fmt.Sprintf(`UPDATE [ma_plan] SET [if_warn]=%d WHERE ID=%d`,
				if_warn, id)
			_, err = sqlConn.Exec(sqlstr)
			if err != nil {
				logs.Info("check_ma_plan_warn Exec Error:", err.Error())
			}

		} else {
			logs.Error("check_ma_plan_warn scan Error", err.Error())
		}
	}
}

func check_ma_plan_warn_g() {

	tick := time.NewTicker(time.Hour * 1)
	check_ma_plan_warn()

	for {
		select {
		case <-tick.C:
			check_ma_plan_warn()
		default:
			time.Sleep(time.Second * 3)
		}
	}
}

func warn_ma_plan(data ma_plan) (if_warn int) {
	loc, _ := time.LoadLocation("Local")
	//维修报价日期为空
	if data.Repair_quotation_date == "" {
		et := time.Now()
		bt, _ := time.ParseInLocation(g_time_format, strings.ReplaceAll(data.Dispath_date, "/", "-")+" 00:00:00", loc)
		if data.ID == 529 {
			fmt.Println(et, bt)
		}

		var cnt int
		var key int
		b_key := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()
		e_key := et.Year()*10000 + int(et.Month())*100 + et.Day()
		key = b_key

		m := make(map[int]int)
		sqlstr := fmt.Sprintf(`select [day],[type] FROM [holiday] where [day] >%d `, b_key)
		fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Info("warn_ma_plan err:", err.Error())
			return
		}

		for rows.Next() {
			var day, day_type int
			if err = rows.Scan(&day, &day_type); err == nil {
				m[day] = day_type
			}
		}
		rows.Close()

		if e_key > b_key {
			for {

				if key >= e_key {
					break
				}

				bt = bt.Add(time.Hour * 24)
				key = bt.Year()*10000 + int(bt.Month())*100 + bt.Day()

				if _, ok := m[key]; ok {
					//1--假期  2--上班
					if m[key] == 1 {
					} else if m[key] == 2 {
						cnt++
						//fmt.Println(key)
					}
				} else {
					if int(bt.Weekday()) == 0 || int(bt.Weekday()) == 6 {
					} else {
						cnt++
						//fmt.Println(key)
					}
				}

			}
			if cnt > 5 {
				if_warn = 1
				return
			}
		}
	}

	//确认维修日期为空
	if data.Repair_quotation_date != "" && data.Repair_OK_date == "" {
		et := time.Now()
		bt, _ := time.ParseInLocation(g_time_format, strings.ReplaceAll(data.Repair_quotation_date, "/", "-")+" 00:00:00", loc)
		if data.ID == 529 {
			fmt.Println(et, bt)
		}

		var cnt int
		var key int
		b_key := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()
		e_key := et.Year()*10000 + int(et.Month())*100 + et.Day()
		key = b_key

		m := make(map[int]int)
		sqlstr := fmt.Sprintf(`select [day],[type] FROM [holiday] where [day] >%d `, b_key)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Info("warn_ma_plan err:", err.Error())
			return
		}

		for rows.Next() {
			var day, day_type int
			if err = rows.Scan(&day, &day_type); err == nil {
				m[day] = day_type
			}
		}
		rows.Close()

		if e_key > b_key {
			for {

				if key >= e_key {
					break
				}

				bt = bt.Add(time.Hour * 24)
				key = bt.Year()*10000 + int(bt.Month())*100 + bt.Day()

				if _, ok := m[key]; ok {
					//1--假期  2--上班
					if m[key] == 1 {
					} else if m[key] == 2 {
						cnt++
						//fmt.Println(key)
					}
				} else {
					if int(bt.Weekday()) == 0 || int(bt.Weekday()) == 6 {
					} else {
						cnt++
						//fmt.Println(key)
					}
				}

			}
			if cnt > 14 {
				if_warn = 1
				return
			}
		}
	}

	//发料日期为空
	/*if data.Repair_OK_date != "" && data.Date_of_issuance == "" {
		et := time.Now()
		bt, _ := time.ParseInLocation(g_time_format, strings.ReplaceAll(data.Repair_OK_date, "/", "-")+" 00:00:00", loc)
		fmt.Println(et, bt)

		var cnt int
		var key int
		b_key := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()
		e_key := et.Year()*10000 + int(et.Month())*100 + et.Day()
		key = b_key

		m := make(map[int]int)
		sqlstr := fmt.Sprintf(`select [day],[type] FROM [holiday] where [day] >%d `, b_key)
		fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Info("warn_ma_plan err:", err.Error())
			return
		}

		for rows.Next() {
			var day, day_type int
			if err = rows.Scan(&day, &day_type); err == nil {
				m[day] = day_type
			}
		}
		rows.Close()

		if e_key > b_key {
			for {

				if key >= e_key {
					break
				}

				bt = bt.Add(time.Hour * 24)
				key = bt.Year()*10000 + int(bt.Month())*100 + bt.Day()

				if _, ok := m[key]; ok {
					//1--假期  2--上班
					if m[key] == 1 {
					} else if m[key] == 2 {
						cnt++
						//fmt.Println(key)
					}
				} else {
					if int(bt.Weekday()) == 0 || int(bt.Weekday()) == 6 {
					} else {
						cnt++
						//fmt.Println(key)
					}
				}

			}
			if cnt > 3 {
				if_warn = 1
				return
			}
		}
	}*/

	//承诺完成日期
	if data.Committed_completed_date != "" && data.Actual_completed_date == "" {
		bt := time.Now()
		et, _ := time.ParseInLocation(g_time_format, strings.ReplaceAll(data.Committed_completed_date, "/", "-")+" 00:00:00", loc)

		if data.ID == 529 {
			fmt.Println(et, bt)
		}

		var cnt int
		var key int
		b_key := bt.Year()*10000 + int(bt.Month())*100 + bt.Day()
		e_key := et.Year()*10000 + int(et.Month())*100 + et.Day()
		key = b_key

		m := make(map[int]int)
		sqlstr := fmt.Sprintf(`select [day],[type] FROM [holiday] where [day] >%d `, b_key)
		fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Info("warn_ma_plan err:", err.Error())
			return
		}

		for rows.Next() {
			var day, day_type int
			if err = rows.Scan(&day, &day_type); err == nil {
				m[day] = day_type
			}
		}
		rows.Close()

		if e_key > b_key {
			for {

				if key >= e_key {
					break
				}

				bt = bt.Add(time.Hour * 24)
				key = bt.Year()*10000 + int(bt.Month())*100 + bt.Day()

				if _, ok := m[key]; ok {
					//1--假期  2--上班
					if m[key] == 1 {
					} else if m[key] == 2 {
						cnt++
						//fmt.Println(key)
					}
				} else {
					if int(bt.Weekday()) == 0 || int(bt.Weekday()) == 6 {
					} else {
						cnt++
						//fmt.Println(key)
					}
				}

			}
			if cnt < 3 {
				if_warn = 1
				return
			}
		} else {
			if_warn = 1
			return
		}
	}

	return
}

func get_done_ma_plan(req get_ma_plan_req) (resp get_ma_plan_resp) {
	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var t_data []ma_plan

	var where_sql string
	var if_where bool

	user_data, _ := getUserInfo(req.OpUser)

	if req.ID != "" {
		likeStr := "%" + req.ID + "%"
		if if_where {
			where_sql += fmt.Sprintf(` and [ID] like '%s'`, likeStr)
		} else {
			where_sql += fmt.Sprintf(` [ID] like '%s'`, likeStr)
		}
		if_where = true
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_status != "" {

		if if_where {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` and [rs] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` [rs] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Regional_head != "" {

		if if_where {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` and [regional_head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` [regional_head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Material_status != "" {

		if if_where {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` and [ms] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` [ms] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if user_data.RoleId != 1 && user_data.RoleId != 3 {
		if if_where {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
			if_where = true
		}
	} else {
		if req.Location != "" {

			if if_where {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
				if_where = true
			} else {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
				if_where = true
			}
		}

	}

	if req.Station != "" {

		if if_where {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` and [station] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` [station] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [ma_plan]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [ma_plan] where %s", where_sql)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_ma_plan scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[data],[mcn] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by [acd] desc) order by [acd] desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[data],[mcn] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by [acd] desc) order by [acd] desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var mcn string
		if err := rdRow.Scan(&id, &s, &mcn); err == nil {
			json.Unmarshal([]byte(s), &d)
			d.ID = id
			d.If_warn = 0
			d.Mcn = mcn

			if len(d.Recv_date) > 2 {
				d.Recv_date = d.Recv_date[2:]
			}
			if len(d.Dispath_date) > 2 {
				d.Dispath_date = d.Dispath_date[2:]
			}

			if len(d.Repair_quotation_date) > 2 {
				d.Repair_quotation_date = d.Repair_quotation_date[2:]
			}

			if len(d.Repair_OK_date) > 2 {
				d.Repair_OK_date = d.Repair_OK_date[2:]
			}

			if len(d.Committed_completed_date) > 2 {
				d.Committed_completed_date = d.Committed_completed_date[2:10]
				d.Committed_completed_date = strings.ReplaceAll(d.Committed_completed_date, "-", "/")
			}

			if len(d.Actual_completed_date) > 2 {
				d.Actual_completed_date = d.Actual_completed_date[2:]
			}

			if len(d.Material_committed_date) > 2 {
				d.Material_committed_date = d.Material_committed_date[2:]
			}

			if len(d.Date_of_issuance) > 2 {
				d.Date_of_issuance = d.Date_of_issuance[2:]
			}

			if d.Actual_completed_date != "" && d.Committed_completed_date != "" {
				if d.Actual_completed_date <= d.Committed_completed_date {
					d.Overdue = "否"
				} else {
					d.Overdue = "是"
				}
			} else {
				d.Overdue = ""
			}

			if len(d.Plan_data) == 0 {
				d.Plan_data = []plan_info{}
			}

			if len(t_data) == 0 {
				t_data = append(t_data, d)
			} else {
				if d.Repairer == t_data[len(t_data)-1].Repairer {
					t_data = append(t_data, d)
				} else {
					//排序
					sort.Slice(t_data, func(i, j int) bool {
						return t_data[i].Committed_completed_date > t_data[j].Committed_completed_date
					})
					resp.Data = append(resp.Data, t_data...)

					t_data = []ma_plan{}
					t_data = append(t_data, d)
				}
			}

		} else {
			logs.Error("get_ma_plan scan Error", err.Error())
		}
	}

exit:
	//fmt.Println(t_data)
	if len(t_data) > 0 {
		sort.Slice(t_data, func(i, j int) bool {
			return t_data[i].Committed_completed_date > t_data[j].Committed_completed_date
		})
		resp.Data = append(resp.Data, t_data...)
	}
	return
}

func get_not_done_ma_plan(req get_ma_plan_req) (resp get_ma_plan_resp) {
	logs.Info("get_not_done_ma_plan-------------")
	recordCount := 0
	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	user_data, _ := getUserInfo(req.OpUser)

	if req.ID != "" {
		likeStr := "%" + req.ID + "%"
		if if_where {
			where_sql += fmt.Sprintf(` and [ID] like '%s'`, likeStr)
		} else {
			where_sql += fmt.Sprintf(` [ID] like '%s'`, likeStr)
		}
		if_where = true
	}

	if req.Rid != "" {

		if if_where {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(` and [repair_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Rid + "%"
			where_sql += fmt.Sprintf(`[repair_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.If_done {

		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] ='不维修' or [rs]='维修完成')`)
			if_where = true
		}
	} else {
		if if_where {
			where_sql += fmt.Sprintf(` and ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		} else {
			where_sql += fmt.Sprintf(` ([if_repair] !='不维修' and [rs]!='维修完成')`)
			if_where = true
		}
	}

	if req.Repairer != "" {

		if if_where {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` and [repairer] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repairer + "%"
			where_sql += fmt.Sprintf(` [repairer] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Repair_status != "" {

		if if_where {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` and [rs] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Repair_status + "%"
			where_sql += fmt.Sprintf(` [rs] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Regional_head != "" {

		if if_where {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` and [regional_head] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Regional_head + "%"
			where_sql += fmt.Sprintf(` [regional_head] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Material_status != "" {

		if if_where {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` and [ms] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Material_status + "%"
			where_sql += fmt.Sprintf(` [ms] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Pid != "" {

		if if_where {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` and [p_id] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Pid + "%"
			where_sql += fmt.Sprintf(` [p_id] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` [p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if user_data.RoleId != 1 && user_data.RoleId != 3 {
		if if_where {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + user_data.Location + "%"
			where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
			if_where = true
		}
	} else {
		if req.Location != "" {

			if if_where {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` and [location] like '%s'`, likeStr)
				if_where = true
			} else {
				likeStr := "%" + req.Location + "%"
				where_sql += fmt.Sprintf(` [location] like '%s'`, likeStr)
				if_where = true
			}
		}

	}

	if req.Station != "" {

		if if_where {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` and [station] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Station + "%"
			where_sql += fmt.Sprintf(` [station] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [ma_plan]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [ma_plan] where %s", where_sql)
	}
	logs.Info("sqlstr---维保计划---", sqlstr)
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_ma_plan scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if req.Sort_field == "" {

		if req.Repair_status == "确认维修" {
			if !if_where {
				sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by ccd asc) order by ccd asc", req.Count, (req.Index-1)*req.Count)
			} else {
				sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by ccd asc) order by ccd asc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
			}
		} else {
			if !if_where {
				sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by ID desc) order by ID desc", req.Count, (req.Index-1)*req.Count)
			} else {
				sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by ID desc) order by ID desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
			}
		}
	} else {
		var field string
		if req.Sort_field == "客户名称" {
			field = "[customer]"
		} else if req.Sort_field == "负责人" {
			field = "[regional_head]"
		} else if req.Sort_field == "维修人员" {
			field = "[repairer]"
		} else if req.Sort_field == "维修状态" {
			field = "[rs]"
		} else if req.Sort_field == "承诺完成日期" {
			field = "[ccd]"
		} else {
			field = "ID"
		}

		if !if_where {
			sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where ID not in (select top %v ID from [ma_plan] order by %s desc) order by %s desc", req.Count, (req.Index-1)*req.Count, field, field)
		} else {
			sqlstr = fmt.Sprintf("select top %v [ID],[data],[if_warn],[mcn] from [ma_plan] where %s and ID not in (select top %v ID from [ma_plan] where %s order by %s desc) order by %s desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql, field, field)
		}
	}
	logs.Info("sqlstr---维保计划111111111111111---", sqlstr)
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ma_plan Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()
	logs.Info("开始遍历查询结果...")

	for rdRow.Next() {
		var d ma_plan
		var id int
		var s string
		var if_warn int
		var mcn string
		logs.Info(fmt.Sprintf("开始处理第 %d 条记录", recordCount+1))

		if err := rdRow.Scan(&id, &s, &if_warn, &mcn); err == nil {
			logs.Info(fmt.Sprintf("成功扫描记录 ID: %d, 数据长度: %d", id, len(s)))

			logs.Info(fmt.Sprintf("开始JSON反序列化, 原始数据前100字符: %.100s", s))
			json.Unmarshal([]byte(s), &d)
			logs.Info(fmt.Sprintf("JSON反序列化完成, ID: %d", id))
			d.ID = id
			d.Mcn = mcn

			logs.Info(fmt.Sprintf("开始处理日期字段, ID: %d", id))
			if len(d.Recv_date) > 2 {
				d.Recv_date = d.Recv_date[2:]
				logs.Info(fmt.Sprintf("处理Recv_date: %s", d.Recv_date))
			}
			if len(d.Dispath_date) > 2 {
				d.Dispath_date = d.Dispath_date[2:]
				logs.Info(fmt.Sprintf("处理Dispath_date: %s", d.Dispath_date))
			}

			if len(d.Repair_quotation_date) > 2 {
				d.Repair_quotation_date = d.Repair_quotation_date[2:]
				logs.Info(fmt.Sprintf("处理Repair_quotation_date: %s", d.Repair_quotation_date))
			}

			if len(d.Repair_OK_date) > 2 {
				d.Repair_OK_date = d.Repair_OK_date[2:]
				logs.Info(fmt.Sprintf("处理Repair_OK_date: %s", d.Repair_OK_date))
			}

			if len(d.Committed_completed_date) > 2 {
				// 修复：确保不会出现切片越界
				endIndex := 10
				if len(d.Committed_completed_date) < 10 {
					endIndex = len(d.Committed_completed_date)
				}
				d.Committed_completed_date = d.Committed_completed_date[2:endIndex]
				d.Committed_completed_date = strings.ReplaceAll(d.Committed_completed_date, "-", "/")
				logs.Info(fmt.Sprintf("处理Committed_completed_date: %s", d.Committed_completed_date))
			}

			if len(d.Actual_completed_date) > 2 {
				d.Actual_completed_date = d.Actual_completed_date[2:]
				logs.Info(fmt.Sprintf("处理Actual_completed_date: %s", d.Actual_completed_date))
			}

			if len(d.Material_committed_date) > 2 {
				d.Material_committed_date = d.Material_committed_date[2:]
				logs.Info(fmt.Sprintf("处理Material_committed_date: %s", d.Material_committed_date))
			}

			if len(d.Date_of_issuance) > 2 {
				d.Date_of_issuance = d.Date_of_issuance[2:]
				logs.Info(fmt.Sprintf("处理Date_of_issuance: %s", d.Date_of_issuance))
			}
			logs.Info(fmt.Sprintf("检查逾期状态, Actual: %s, Committed: %s", d.Actual_completed_date, d.Committed_completed_date))
			if d.Actual_completed_date != "" && d.Committed_completed_date != "" {
				if d.Actual_completed_date <= d.Committed_completed_date {
					d.Overdue = "否"
				} else {
					d.Overdue = "是"
				}
				logs.Info(fmt.Sprintf("逾期判断结果: %s", d.Overdue))
			} else {
				d.Overdue = ""
				logs.Info("逾期判断: 缺少必要日期数据")
			}

			if len(d.Plan_data) == 0 {
				d.Plan_data = []plan_info{}
				logs.Info(fmt.Sprintf("Plan_data为空, 初始化为空数组"))
			} else {
				logs.Info(fmt.Sprintf("Plan_data有 %d 条记录", len(d.Plan_data)))
			}

			d.If_warn = if_warn
			resp.Data = append(resp.Data, d)
			recordCount++
			logs.Info(fmt.Sprintf("成功处理第 %d 条记录, 当前resp.Data长度: %d", recordCount, len(resp.Data)))
		} else {
			logs.Error("get_ma_plan scan Error", err.Error())
		}
	}
	logs.Info(fmt.Sprintf("记录遍历完成, 总共处理了 %d 条记录", recordCount))

	logs.Info(fmt.Sprintf("函数返回前, resp.Total: %d, resp.Data长度: %d", resp.Total, len(resp.Data)))

exit:
	return
}

func get_ma_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("get_ma_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_ma_plan_req
	var resp get_ma_plan_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	logs.Info("是否在线-----------------", b)
	if !b {
		goto exit
	}
	logs.Info("req.If_done-----------------", req.If_done)
	if !req.If_done { //未处理
		resp = get_not_done_ma_plan(req)
	} else {
		resp = get_done_ma_plan(req)
	}

exit:
	logs.Info("resp-----------------", resp)
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("get_ma_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func import_ma_temp_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("import_ma_temp_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var flag int

	var reqdata []byte
	var req import_ma_temp_plan_Req
	var resp CommonResp
	var b bool

	ma_temp_plan_lock.Lock()
	flag = ma_temp_plan_lock_n
	ma_temp_plan_lock.Unlock()

	if flag == 1 {
		resp.Ret = 1
		goto exit
	} else {
		ma_temp_plan_lock.Lock()
		ma_temp_plan_lock_n = 1
		ma_temp_plan_lock.Unlock()
	}

	reqdata, _ = ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b = checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.OpUser == "王真" || req.OpUser == "刘世界" || req.OpUser == "李俊杉" {
	} else {
		resp.Ret = -1
		goto exit
	}

	for i := 0; i < len(req.Plan); i++ {

		var id int

		sqlstr := fmt.Sprintf(`SELECT ID from [ma_temp_plan] where [return_task]='%s' and [p_id]='%s' and [p_serial]='%s' `, req.Plan[i].Return_task, req.Plan[i].P_id, req.Plan[i].P_serial)
		//fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Error(fmt.Sprintf(`%s err:%s`, sqlstr, err.Error()))
			resp.Ret = -1
			goto exit
		}

		for rows.Next() {
			if err := rows.Scan(&id); err != nil {
				logs.Error(fmt.Sprintf(`%s scan err:%s`, sqlstr, err.Error()))
				resp.Ret = -1
				goto exit
			}
		}
		rows.Close()

		if id > 0 && req.Plan[i].Repair_type != "天工" {
			resp.Ret = 2
			resp.Context = fmt.Sprintf(`维修任务（%s,%s,%s）已存在`, req.Plan[i].Return_task, req.Plan[i].P_id, req.Plan[i].P_serial)
			goto exit
		}

		req.Plan[i].Recv_date = strings.ReplaceAll(req.Plan[i].Recv_date, "-", "/")
		t := strings.Split(req.Plan[i].Recv_date, "/")
		if len(t) == 3 {
			month, _ := strconv.Atoi(t[1])
			day, _ := strconv.Atoi(t[2])
			req.Plan[i].Recv_date = fmt.Sprintf(`%s/%02d/%02d`, t[0], month, day)
		}

		var if_e1 int
		if req.Plan[i].If_e1_str == "是" {
			req.Plan[i].If_e1 = true
			if_e1 = 1
		}

		jdata, _ := json.Marshal(req.Plan[i])
		sqlstr1 := fmt.Sprintf(`INSERT INTO [ma_temp_plan]
           ([data]
           ,[return_task]
           ,[head]
           ,[p_id]
           ,[p_name]
           ,[p_serial]
           ,[repairer]
           ,[rt]
           ,[if_do]
        	,[state]
			,[if_e1])
     	VALUES
           ('%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,'%s'
           ,%d
        	,'%s',%d)`, string(jdata), req.Plan[i].Return_task, req.Plan[i].Head, req.Plan[i].P_id, req.Plan[i].P_name,
			req.Plan[i].P_serial, req.Plan[i].Repairer, req.Plan[i].Repair_type, 0, "", if_e1)

		_, err = sqlConn.Exec(sqlstr1)
		if err != nil {
			logs.Info("import_ma_temp_plan Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	if resp.Ret != 1 {
		ma_temp_plan_lock.Lock()
		ma_temp_plan_lock_n = 0
		ma_temp_plan_lock.Unlock()
	}

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("import_ma_temp_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func import_ma_plan(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("import_ma_plan recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var flag int

	var reqdata []byte
	var req import_ma_plan_Req
	var resp CommonResp
	var b bool

	var user_data useInfo

	ma_plan_lock.Lock()
	flag = ma_plan_lock_n
	ma_plan_lock.Unlock()

	if flag == 1 {
		resp.Ret = 1
		goto exit
	} else {
		ma_plan_lock.Lock()
		ma_plan_lock_n = 1
		ma_plan_lock.Unlock()
	}

	reqdata, _ = ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b = checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	user_data, _ = getUserInfo(req.OpUser)

	for i := 0; i < len(req.Plan); i++ {
		var id int

		sqlstr := fmt.Sprintf(`SELECT ID from ma_plan where [repair_id]='%s'`, req.Plan[i].Repair_id)
		//fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Error(fmt.Sprintf(`%s err:%s`, sqlstr, err.Error()))
			resp.Ret = -1
			goto exit
		}

		for rows.Next() {
			if err := rows.Scan(&id); err != nil {
				logs.Error(fmt.Sprintf(`%s scan err:%s`, sqlstr, err.Error()))
				resp.Ret = -1
				goto exit
			}
		}
		rows.Close()

		if id > 0 {
			resp.Ret = 2
			resp.Context = fmt.Sprintf(`维修订单号（%s）已存在`, req.Plan[i].Repair_id)
			goto exit
		}

		req.Plan[i].Recv_date = strings.ReplaceAll(req.Plan[i].Recv_date, "-", "/")
		t := strings.Split(req.Plan[i].Recv_date, "/")
		if len(t) == 3 {
			month, _ := strconv.Atoi(t[1])
			day, _ := strconv.Atoi(t[2])
			req.Plan[i].Recv_date = fmt.Sprintf(`%s/%02d/%02d`, t[0], month, day)
		}

		req.Plan[i].Dispath_date = strings.ReplaceAll(req.Plan[i].Dispath_date, "-", "/")
		t = strings.Split(req.Plan[i].Dispath_date, "/")
		if len(t) == 3 {
			month, _ := strconv.Atoi(t[1])
			day, _ := strconv.Atoi(t[2])
			req.Plan[i].Dispath_date = fmt.Sprintf(`%s/%02d/%02d`, t[0], month, day)
		}

		jdata, _ := json.Marshal(req.Plan[i])
		if id == 0 {
			sqlstr = fmt.Sprintf(`INSERT INTO [ma_plan] ([data],[repair_id],[p_id],[p_name],[if_repair],[rs] ,[repairer],[regional_head],[ms],[customer],[ccd],[location] ,[if_warn],[station],[mcn])
	     		VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,'%s','%s')`, string(jdata), req.Plan[i].Repair_id,
				req.Plan[i].P_id, req.Plan[i].P_name,
				req.Plan[i].If_repair, req.Plan[i].Repair_status, req.Plan[i].Repairer,
				req.Plan[i].Regional_head, req.Plan[i].Material_status,
				req.Plan[i].Customer, req.Plan[i].Committed_completed_date,
				user_data.Location, 0, req.Plan[i].Station,
				req.Plan[i].Mcn)
		}

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("import_ma_plan Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	if resp.Ret != 1 {
		ma_plan_lock.Lock()
		ma_plan_lock_n = 0
		ma_plan_lock.Unlock()
	}

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("import_ma_plan recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func del_process(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("del_process recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var resp del_p_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req del_process_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	for i := 0; i < len(req.Ids); i++ {

		sqlstr := fmt.Sprintf(`DELETE FROM [process] where ID=%d`, req.Ids[i].ID)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("del_process Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("del_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func update_process(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("update_process recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp post_p_resp

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req update_process_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.Data.ID == 0 {
		logs.Info("update_process sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	sqlstr = fmt.Sprintf(`UPDATE [process] SET [process_name] = '%s',[process_t] = '%s' WHERE ID=%d`,
		req.Data.Process_name, req.Data.Process_t, req.Data.ID)
	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("update_process Exec Error:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("update_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func import_process(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("import_process recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var p_flag int

	var reqdata []byte
	var req import_process_req
	var resp import_p_resp
	var b bool

	process_lock.Lock()
	p_flag = process_lock_n
	process_lock.Unlock()

	if p_flag == 1 {
		resp.Ret = 1
		goto exit
	} else {
		process_lock.Lock()
		process_lock_n = 1
		process_lock.Unlock()
	}

	reqdata, _ = ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b = checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	for i := 0; i < len(req.Data); i++ {
		var id int

		sqlstr := fmt.Sprintf(`SELECT ID from process where p_id='%s' and process_name='%s'`, req.Data[i].P_id, req.Data[i].Process_name)
		//fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Error(fmt.Sprintf(`SELECT ID from process where p_id='%s' err:%s`, req.Data[i].P_id, err.Error()))
			resp.Ret = -1
			goto exit
		}

		for rows.Next() {
			if err := rows.Scan(&id); err != nil {
				logs.Error(fmt.Sprintf(`SELECT ID from process where p_id='%s' scan err:%s`, req.Data[i].P_id, err.Error()))
				resp.Ret = -1
				goto exit
			}
		}
		rows.Close()

		if id == 0 {
			sqlstr = fmt.Sprintf(`INSERT INTO [process] ([p_id],[p_name] ,[process_name],[process_t])
     		VALUES ('%s','%s','%s','%s')`, req.Data[i].P_id, req.Data[i].P_name, req.Data[i].Process_name, req.Data[i].Process_t)
		} else {
			sqlstr = fmt.Sprintf(`UPDATE [process]
   				SET [p_id] = '%s'
				,[p_name]='%s'
      			,[process_name] = '%s'
				,[process_t]= '%s'
				 WHERE ID=%d`, req.Data[i].P_id, req.Data[i].P_name, req.Data[i].Process_name, req.Data[i].Process_t, id)
		}

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("import_process Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	if resp.Ret != 1 {
		process_lock.Lock()
		process_lock_n = 0
		process_lock.Unlock()
	}

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("import_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_process(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("get_process recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_process_req
	var resp get_process_resp

	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.P_id != "" {
		likeStr := "%" + req.P_id + "%"
		where_sql += fmt.Sprintf(`[p_id] like '%s'`, likeStr)
		if_where = true
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(`[p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if req.Process_name != "" {

		if if_where {
			likeStr := "%" + req.Process_name + "%"
			where_sql += fmt.Sprintf(` and [process_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.Process_name + "%"
			where_sql += fmt.Sprintf(`[process_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [process]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [process] where %s", where_sql)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_process query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_process scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_id],[p_name],[process_name],[process_t] from [process] where ID not in (select top %v ID from [process] order by ID desc) order by ID desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_id],[p_name],[process_name],[process_t] from [process] where %s and ID not in (select top %v ID from [process] where %s order by ID desc) order by ID desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_process Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d process_info
		if err := rdRow.Scan(&d.ID, &d.P_id, &d.P_name, &d.Process_name, &d.Process_t); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_process scan Error", err.Error())
		}
	}

exit:

	jdata, _ := json.Marshal(resp)
	//fmt.Println(string(jdata))
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("get_process recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func download_file(rw http.ResponseWriter, r *http.Request) {
	//获取请求参数
	/*var req download_file_req
	reqdata, _ := ioutil.ReadAll(r.Body)
	json.Unmarshal(reqdata, &req)

	fn := req.Filename*/

	filename := r.FormValue("id")
	base_file_path := modelePath + "/file/"

	if filename != "" {
		//设置响应头
		header := rw.Header()
		header.Add("Content-Type", "application/octet-stream")
		//header.Add("Content-Disposition", "attachment;filename="+fn)
		//使用ioutil包读取文件
		filepath := base_file_path + filename
		fmt.Println(filepath)
		b, _ := ioutil.ReadFile(filepath)

		//写入到响应流中
		rw.Write(b)
	}

}

func export_sap(response http.ResponseWriter, request *http.Request) {

	beginTime := time.Now().UnixNano()
	logs.Info("export_sap recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var csv_data [][]string
	var filename string
	filename = fmt.Sprintf(`./file/%v.csv`, beginTime)
	f, err := os.Create(filename)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()

	var req get_p_Req
	var resp download_file_Resp
	var data []p_sap

	var sqlstr string
	var rdRow *sql.Rows

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.P_id != "" {
		likeStr := "%" + req.P_id + "%"
		where_sql += fmt.Sprintf(`[p_id] like '%s'`, likeStr)
		if_where = true
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(`[p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[p_id],[p_name] from [sap] order by ID asc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[p_id],[p_name] from [sap] where %s order by ID asc", where_sql)
	}
	//fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("export_sap Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d p_sap
		if err := rdRow.Scan(&d.ID, &d.P_id, &d.P_name); err == nil {
			data = append(data, d)
		} else {
			logs.Error("export_sap scan Error", err.Error())
		}
	}

	csv_data = append(csv_data, []string{"产品编号", "产品名称"})

	for i := 0; i < len(data); i++ {
		v := data[i]

		csv_data = append(csv_data, []string{v.P_id, v.P_name})
	}

exit:

	f.WriteString("\xEF\xBB\xBF") // 写入一个UTF-8 BOM 防止中文乱码
	w := csv.NewWriter(f) //创建一个新的写入文件流
	w.WriteAll(csv_data)
	w.Flush()
	resp.FileId = fmt.Sprintf(`%v.csv`, beginTime)

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("export_sap recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func import_p(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("import_p recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var p_flag int

	var reqdata []byte
	var req import_p_Req
	var resp import_p_resp
	var b bool

	p_lock.Lock()
	p_flag = p_import_f
	p_lock.Unlock()

	if p_flag == 1 {
		resp.Ret = 1
		goto exit
	} else {
		p_lock.Lock()
		p_import_f = 1
		p_lock.Unlock()
	}

	reqdata, _ = ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b = checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	for i := 0; i < len(req.Data); i++ {
		var id int

		sqlstr := fmt.Sprintf(`SELECT ID from sap where p_id='%s'`, req.Data[i].P_id)
		//fmt.Println(sqlstr)
		rows, err := sqlConn.Query(sqlstr)
		if err != nil {
			logs.Error(fmt.Sprintf(`SELECT ID from sap where p_id='%s' err:%s`, req.Data[i].P_id, err.Error()))
			resp.Ret = -1
			goto exit
		}

		for rows.Next() {
			if err := rows.Scan(&id); err != nil {
				logs.Error(fmt.Sprintf(`SELECT ID from sap where p_id='%s' scan err:%s`, req.Data[i].P_id, err.Error()))
				resp.Ret = -1
				goto exit
			}
		}
		rows.Close()

		if id == 0 {
			sqlstr = fmt.Sprintf(`INSERT INTO [sap] ([p_id],[p_name])
     		VALUES ('%s','%s')`, req.Data[i].P_id, req.Data[i].P_name)
		} else {
			sqlstr = fmt.Sprintf(`UPDATE [dbo].[sap]
   				SET [p_id] = '%s'
      			,[p_name] = '%s'
				 WHERE ID=%d`, req.Data[i].P_id, req.Data[i].P_name, id)
		}

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("import_p Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	if resp.Ret != 1 {
		p_lock.Lock()
		p_import_f = 0
		p_lock.Unlock()
	}

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("import_p recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func del_p(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("del_p recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var resp del_p_resp

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req del_p_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	for i := 0; i < len(req.Ids); i++ {

		sqlstr := fmt.Sprintf(`DELETE FROM [sap] where ID=%d`, req.Ids[i].ID)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("del_p Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}
	}

	resp.Ret = 0

exit:

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("del_p recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func post_p(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("post_p recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var sqlstr string
	var resp post_p_resp

	var jdata []byte

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req post_p_req
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if req.OperType == 2 && req.Id == 0 {
		logs.Info("post_p sap req id ==0")
		resp.Ret = -1
		goto exit
	}

	//add op check user for same info
	if req.OperType == 1 {
		var cnt int
		row, err := sqlConn.Query(fmt.Sprintf(`select ID from [sap] where [p_id] = '%s'`, req.P_id))
		if err != nil {
			logs.Error(fmt.Sprintf("post_p get sap cnt err:%v", err.Error()))
			resp.Ret = -1
			goto exit
		}

		for row.Next() {
			cnt++
		}
		row.Close()

		if cnt > 0 {
			resp.Ret = 1
			goto exit
		}
	}

	if req.OperType == 1 { //add
		sqlstr = fmt.Sprintf(`INSERT INTO [sap] ([p_id],[p_name]) VALUES ('%s','%s')`,
			req.P_id, req.P_name)
	} else if req.OperType == 2 { //update
		sqlstr = fmt.Sprintf(`UPDATE [sap] SET [p_id] = '%s',[p_name] = '%s' WHERE ID=%d`,
			req.P_id, req.P_name, req.Id)
	} else {
		resp.Ret = -1
		goto exit
	}
	fmt.Println(sqlstr)

	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("post_p Exec Error:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	jdata, _ = json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("post_p recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_p(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("get_p recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req get_p_Req
	var resp get_p_Resp

	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	var where_sql string
	var if_where bool

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.P_id != "" {
		likeStr := "%" + req.P_id + "%"
		where_sql += fmt.Sprintf(`[p_id] like '%s'`, likeStr)
		if_where = true
	}

	if req.P_name != "" {

		if if_where {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(` and [p_name] like '%s'`, likeStr)
			if_where = true
		} else {
			likeStr := "%" + req.P_name + "%"
			where_sql += fmt.Sprintf(`[p_name] like '%s'`, likeStr)
			if_where = true
		}
	}

	if !if_where {
		sqlstr = "select count(ID) from [sap]"
	} else {
		sqlstr = fmt.Sprintf("select count(ID) from [sap] where %s", where_sql)
	}
	//fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_p query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("get_p scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_id],[p_name] from [sap] where ID not in (select top %v ID from [sap] order by ID desc) order by ID desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_id],[p_name] from [sap] where %s and ID not in (select top %v ID from [sap] where %s order by ID desc) order by ID desc", req.Count, where_sql, (req.Index-1)*req.Count, where_sql)
	}
	//fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_p Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d p_sap
		if err := rdRow.Scan(&d.ID, &d.P_id, &d.P_name); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_p scan Error", err.Error())
		}
	}

exit:

	jdata, _ := json.Marshal(resp)
	//fmt.Println(string(jdata))
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("get_p recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_time_ex(search_time string) (st []string, b bool) {
	t := strings.Split(search_time, "-")
	if len(t) == 2 {
		t0 := strings.Split(t[0], "/")
		if len(t0) == 3 {
			year, _ := strconv.Atoi(t0[0])
			month, _ := strconv.Atoi(t0[1])
			day, _ := strconv.Atoi(t0[2])

			t0 := fmt.Sprintf(`20%02d/%02d/%02d`, year, month, day)
			st = append(st, t0)
		} else {
			b = true
		}

		t1 := strings.Split(t[1], "/")
		if len(t1) == 3 {
			year, _ := strconv.Atoi(t1[0])
			month, _ := strconv.Atoi(t1[1])
			day, _ := strconv.Atoi(t1[2])

			t0 := fmt.Sprintf(`20%02d/%02d/%02d`, year, month, day)
			st = append(st, t0)
		} else {
			b = true
		}

	} else if len(t) == 1 {
		tt := strings.Split(t[0], "/")
		if len(tt) == 3 {
			year, _ := strconv.Atoi(tt[0])
			month, _ := strconv.Atoi(tt[1])
			day, _ := strconv.Atoi(tt[2])

			bt := fmt.Sprintf(`20%02d/%02d/%02d`, year, month, day)
			et := fmt.Sprintf(`20%02d/%02d/%02d`, year, month, day)
			st = append(st, bt)
			st = append(st, et)
		} else {
			b = true
		}
	}

	if b {
		st = []string{}
	}

	return
}

func get_time(search_time string) (whereSql string) {
	t := strings.Split(search_time, "-")
	if len(t) == 2 {
		var if_where bool
		t0 := strings.Split(t[0], "/")
		if len(t0) == 2 {
			year, _ := strconv.Atoi(t0[0])
			month, _ := strconv.Atoi(t0[1])
			t := (year+2000)*100 + month
			whereSql += fmt.Sprintf(` [month] >= %d `, t)
			if_where = true
		} else if len(t0) == 3 {
			year, _ := strconv.Atoi(t0[0])
			month, _ := strconv.Atoi(t0[1])
			day, _ := strconv.Atoi(t0[2])

			t := fmt.Sprintf(`20%02d-%02d-%02d 00:00:00`, year, month, day)
			whereSql += fmt.Sprintf(` [time]>='%s' `, t)
			if_where = true
		}

		t1 := strings.Split(t[1], "/")
		if len(t1) == 2 {
			year, _ := strconv.Atoi(t1[0])
			month, _ := strconv.Atoi(t1[1])
			t := (year+2000)*100 + month
			if if_where {
				whereSql += fmt.Sprintf(` and [month] <= %d `, t)
			} else {
				whereSql += fmt.Sprintf(` [month] <= %d `, t)
			}
		} else if len(t1) == 3 {
			year, _ := strconv.Atoi(t1[0])
			month, _ := strconv.Atoi(t1[1])
			day, _ := strconv.Atoi(t1[2])

			t := fmt.Sprintf(`20%02d-%02d-%02d 23:59:59`, year, month, day)

			if if_where {
				whereSql += fmt.Sprintf(` and [time]<='%s' `, t)
			} else {
				whereSql += fmt.Sprintf(` [time]<='%s' `, t)
			}

			if_where = true
		}

	} else if len(t) == 1 {
		tt := strings.Split(t[0], "/")
		if len(tt) == 2 {
			year, _ := strconv.Atoi(tt[0])
			month, _ := strconv.Atoi(tt[1])
			search_month := (year+2000)*100 + month
			whereSql = fmt.Sprintf(` [month] = %d`, search_month)
		} else if len(tt) == 3 {
			year, _ := strconv.Atoi(tt[0])
			month, _ := strconv.Atoi(tt[1])
			day, _ := strconv.Atoi(tt[2])

			bt := fmt.Sprintf(`20%02d-%02d-%02d 00:00:00`, year, month, day)
			et := fmt.Sprintf(`20%02d-%02d-%02d 23:59:59`, year, month, day)
			whereSql = fmt.Sprintf(` [time]>='%s' and [time] <='%s' `, bt, et)
		}
	}

	return
}

//用户管理相关接口

func getUserNames(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("getUserNames recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req getUserNamesReq
	var resp getUserNamesResp

	var sqlstr string
	var rdRow *sql.Rows
	var err error

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkUserIfOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	sqlstr = fmt.Sprintf("select [username] from [user] order by ID asc")
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("getUserNames Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var name string
		var v usernams
		if err := rdRow.Scan(&name); err == nil {
			v.Label = name
			v.Value = name
			resp.Names = append(resp.Names, v)
		} else {
			logs.Error("getUserNames scan Error", err.Error())
		}
	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	fmt.Println(fmt.Sprintf("getUserNames recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func checkIsSysUserOnline(username string, op_uuid string) bool {

	deesUserStatMaplck.RLock()
	if v, ok := deesUserStatMap[username]; ok {
		deesUserStatMaplck.RUnlock()

		v.RLock()
		refreshTime := v.RefreshTime
		userrole := v.UserRole
		uuid := v.Uuid
		v.RUnlock()
		if int64(time.Since(refreshTime).Seconds()) > int64(refreshSpan+1) {
			return false
		}

		if op_uuid != uuid {
			return false
		}

		if userrole != 1 {
			return false
		}

		return true
	} else {
		deesUserStatMaplck.RUnlock()

		return false
	}
}

func postUser(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("postUser recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var roleid int
	var err error
	var sqlstr string
	var resp PostUserResp
	var departmentid int

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req PostUserReq
	json.Unmarshal(reqdata, &req)

	b := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		resp.Ret = -1
		goto exit
	}

	if (req.OperType == 2 || req.OperType == 3) && req.Id == 0 {
		logs.Info("update userinfo req id ==0")
		resp.Ret = -1
		goto exit
	}

	//add op check user for same username
	if req.OperType == 1 {
		var cnt int
		row, err := sqlConn.Query(fmt.Sprintf(`select ID from [user] where [username] = '%s'`, req.Username))
		if err != nil {
			logs.Error(fmt.Sprintf("postUser get user cnt err:%v", err.Error()))
			resp.Ret = -1
			goto exit
		}

		for row.Next() {
			cnt++
		}
		row.Close()

		if cnt > 0 {
			resp.Ret = 1
			goto exit
		}
	}

	roleid = 2
	if req.Role == "管理员" {
		roleid = 1
	} else if req.Role == "普通用户" {
		roleid = 2
	} else {
		roleid = 3
	}

	//1生产 2质检 3供应链 4交付 5研发 6 保温瓶
	/*if req.Department == "生产" {
		departmentid = 1
	} else if req.Department == "质检" {
		departmentid = 2
	} else if req.Department == "供应链" {
		departmentid = 3
	} else if req.Department == "交付" {
		departmentid = 4
	} else if req.Department == "研发" {
		departmentid = 5
	} else if req.Department == "保温瓶" {
		departmentid = 6
	} else if req.Department == "技术" {
		departmentid = 7
	} else {
		if req.OperType != 3 {
			goto exit
		}
	}*/

	if req.OperType == 1 { //add
		//opType = 10001
		//opContent = fmt.Sprintf(`新增用户%s`, req.Username)
		sqlstr = fmt.Sprintf(`INSERT INTO [user] ([username],[password],[role_name],[role_id],[department],[department_id],[state],[location]) VALUES ('%s','%s','%s',%d,'%s',%d,'%s','%s')`,
			req.Username, req.Password, req.Role, roleid, req.Department, departmentid,
			"", req.Location)
	} else if req.OperType == 2 { //update
		//opType = 10002
		//opContent = fmt.Sprintf(`修改用户%s`, req.Username)
		sqlstr = fmt.Sprintf(`UPDATE [user] SET [username] = '%s',[password] = '%s',[role_name] = '%s',[role_id] = %d,[department]='%s',[department_id]=%d ,[state]='%s',[location]='%s' WHERE ID=%d`,
			req.Username, req.Password, req.Role, roleid, req.Department, departmentid, "",
			req.Location,
			req.Id)
	} else if req.OperType == 3 {
		//opType = 10003
		//		opContent = fmt.Sprintf(`删除用户%s`, req.Username)
		sqlstr = fmt.Sprintf(`DELETE FROM [user] WHERE ID=%d`, req.Id)
	} else {
		resp.Ret = -1
		goto exit
	}
	fmt.Println(sqlstr)

	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("postUser Exec Error:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("postUser recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func getUsers(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("getUsers recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req getUsersReq
	var resp GetUsersResp

	var sqlstr string
	var rcnt int
	var cntRow *sql.Rows
	var rdRow *sql.Rows
	var err error

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	b := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

	if req.Id == "" {
		sqlstr = "select count(ID) from [user] "
	} else {
		likeStr := "%" + req.Id + "%"
		sqlstr = fmt.Sprintf("select count(ID) from [user] where [username] like '%s'", likeStr)
	}
	fmt.Println(sqlstr)

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("getUsers query %s err:%v", sqlstr, err.Error()))
		goto exit
	}
	defer cntRow.Close()

	for cntRow.Next() {
		if err = cntRow.Scan(&rcnt); err != nil {
			logs.Error(fmt.Sprintf("getUsers scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if req.Id == "" {
		sqlstr = fmt.Sprintf("select top %v [ID],[username],[password],[role_name],[role_id],[department] ,[state],[location] from [user] where ID not in (select top %v ID from [user] order by ID asc) order by ID asc", req.Count, (req.Index-1)*req.Count)
	} else {
		likeStr := "%" + req.Id + "%"
		sqlstr = fmt.Sprintf("select top %v [ID],[username],[password],[role_name],[role_id],[department] ,[state],[location] from [user] where username like '%s' and ID not in (select top %v ID from [user] where username like '%s' order by ID asc) order by ID asc", req.Count, likeStr, (req.Index-1)*req.Count, likeStr)
	}
	fmt.Println(sqlstr)

	rdRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("getUsers Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d useInfo

		if err := rdRow.Scan(&d.Userid, &d.Username, &d.Password, &d.RoleName, &d.RoleId,
			&d.Department, &d.State, &d.Location); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("getUsers scan Error", err.Error())
		}
	}

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("getUsers recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func checkUserIfOnline(username string, uuid string) bool {

	deesUserStatMaplck.RLock()
	if v, ok := deesUserStatMap[username]; ok {
		deesUserStatMaplck.RUnlock()

		v.RLock()
		refreshTime := v.RefreshTime
		lastuuid := v.Uuid
		v.RUnlock()

		if uuid != lastuuid {
			return false
		}

		if int64(time.Since(refreshTime).Seconds()) > int64(refreshSpan+1) {
			return false
		}
		return true
	} else {
		deesUserStatMaplck.RUnlock()

		return false
	}
}

func getUserInfo(username string) (d useInfo, err error) {

	var sql string
	sql = fmt.Sprintf("select [username],[password],[role_name],[role_id],[department],[department_id] ,[location] from [user] where [username] = '%s'", username)
	row, err := sqlConn.Query(sql)
	if err != nil {
		logs.Info("getUserInfo Query Error", err.Error())
		return
	}

	for row.Next() {

		if err = row.Scan(&d.Username, &d.Password, &d.RoleName, &d.RoleId, &d.Department, &d.DepartmentId,
			&d.Location); err == nil {

			if d.Location == "" {
				d.Location = "睿控维保"
			}
		} else {
			logs.Info("Query Error", err.Error())
		}
	}
	row.Close()

	return
}

func get_all_user() (resp []useInfo, err error) {

	var sql string
	sql = fmt.Sprintf("select [username],[password],[role_name],[role_id],[department],[department_id],[location],[state] from [user] ")
	row, err := sqlConn.Query(sql)
	if err != nil {
		logs.Info("get_all_user Query Error", err.Error())
		return
	}

	for row.Next() {

		var d useInfo
		if err = row.Scan(&d.Username, &d.Password, &d.RoleName, &d.RoleId, &d.Department, &d.DepartmentId,
			&d.Location, &d.State); err == nil {
			resp = append(resp, d)
		} else {
			logs.Info("get_all_user scan Error", err.Error())
		}
	}
	row.Close()

	return
}

// 菜单
func getMenu(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("getMenu recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var err error
	var req GetMenuReq
	var resp GetMenuResp

	var menu GetMenuRespData
	var mItem menuItem

	var userInfo useInfo

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	ifOnline := checkUserIfOnline(req.UserName, req.Uuid)
	if !ifOnline {
		goto exit
	}

	userInfo, err = getUserInfo(req.UserName)
	if err != nil {
		goto exit
	}

	menu.Title = "计划管理"
	menu.Index = "2"
	//menu.Class = "el-icon-s-data"
	//menu.SvgData.First = "M992.256 960 960 960 960 576.192C960 540.032 931.072 512 895.424 512l-126.784 0C732.352 512 704 540.736 704 576.192L704 960l-64 0L640 64.448C640 28.736 611.072 0 575.424 0L448.576 0C412.352 0 384 28.864 384 64.448L384 960 320 960 320 319.744C320 284.48 291.072 256 255.424 256L128.576 256C92.352 256 64 284.544 64 319.744L64 960 31.744 960C14.464 960 0 974.336 0 992 0 1009.152 14.208 1024 31.744 1024l960.448 0C1009.536 1024 1024 1009.664 1024 992 1024 974.848 1009.792 960 992.256 960z"
	menu.SvgData.First = "M955.3 77.1H798.1V59.3c0-16.6-13.4-30-30-30s-30 13.4-30 30v17.8H278.3V59.3c0-16.6-13.4-30-30-30s-30 13.4-30 30v17.8H69.2c-22.1 0-40 17.9-40 40v837.1c0 22.1 17.9 40 40 40h886.1c22.1 0 40-17.9 40-40V117.1c0-22.1-17.9-40-40-40z m-29.9 847.1H99.2V376.4h826.2v547.8z m0-607.8H99.2V137.1h119.1v17.8c0 16.6 13.4 30 30 30s30-13.4 30-30v-17.8h459.9v17.8c0 16.6 13.4 30 30 30s30-13.4 30-30v-17.8h127.2v179.3z"
	menu.SvgData.Second = "M470.4 551.3h321.4c18.2 0 33-14.8 33-33s-14.8-33-33-33H470.4c-18.2 0-33 14.8-33 33s14.8 33 33 33zM210.3 562.6l64.8 64.8 110.8-110.8c9.5-9.5 9.5-25 0-34.5s-25-9.5-34.5 0l-76.3 76.3-30.3-30.3c-9.5-9.5-25-9.5-34.5 0s-9.5 25 0 34.5zM470.4 785h321.4c18.2 0 33-14.8 33-33s-14.8-33-33-33H470.4c-18.2 0-33 14.8-33 33s14.8 33 33 33zM316.8 719.2h-67.9c-18.2 0-33 14.8-33 33s14.8 33 33 33h67.9c18.2 0 33-14.8 33-33s-14.8-33-33-33z"
	menu.Key = menu.Index

	mItem.Index = "/scb"
	mItem.Title = "维保计划"
	mItem.Key = mItem.Index
	menu.Items = append(menu.Items, mItem)

	if userInfo.RoleId == 1 || req.UserName == "霍涛" {
		mItem.Index = "/mr"
		mItem.Title = "维保审核"
		mItem.Key = mItem.Index
		menu.Items = append(menu.Items, mItem)
	}

	mItem.Index = "/tw"
	mItem.Title = "临时工作"
	mItem.Key = mItem.Index
	menu.Items = append(menu.Items, mItem)

	resp.MenuData = append(resp.MenuData, menu)

	if userInfo.RoleId == 1 {
		menu.Title = "用户管理"
		menu.Index = "1"
		//menu.Class = "el-icon-user"
		menu.SvgData.First = "M955.456 765.12a41.792 41.792 0 0 0-34.368-32.64 8.256 8.256 0 0 1-6.08-3.904 8.256 8.256 0 0 1-0.384-7.104 41.856 41.856 0 0 0-11.136-45.696 165.76 165.76 0 0 0-60.096-34.56 41.728 41.728 0 0 0-45.056 13.12c-1.216 1.472-3.328 3.264-6.336 3.264s-5.12-1.728-6.336-3.264a41.6 41.6 0 0 0-45.056-13.184 166.4 166.4 0 0 0-60.224 34.624 41.728 41.728 0 0 0-11.136 45.632 8.064 8.064 0 0 1-0.384 7.104 8.256 8.256 0 0 1-6.08 3.904 41.728 41.728 0 0 0-34.304 32.64 166.72 166.72 0 0 0 0 68.928c3.584 16.96 17.28 29.952 34.432 32.64 1.92 0.32 4.544 1.216 6.08 3.904a8.256 8.256 0 0 1 0.384 7.104 41.6 41.6 0 0 0 11.136 45.696c17.344 15.616 37.568 27.2 60.096 34.56a41.728 41.728 0 0 0 45.056-13.056c1.216-1.472 3.328-3.264 6.336-3.264s5.12 1.728 6.336 3.264a41.728 41.728 0 0 0 45.056 13.12c22.528-7.296 42.688-18.88 59.968-34.432 12.8-11.52 17.216-29.696 11.136-45.76a8.192 8.192 0 0 1 0.384-7.168 8.256 8.256 0 0 1 6.08-3.904 41.728 41.728 0 0 0 34.496-32.64 166.144 166.144 0 0 0 0-68.928z m-40.832 60.288a49.92 49.92 0 0 0-35.904 24.256 49.92 49.92 0 0 0-3.264 42.752 123.584 123.584 0 0 1-44.992 25.792 49.92 49.92 0 0 0-38.528-18.432 49.664 49.664 0 0 0-38.528 18.432 125.44 125.44 0 0 1-45.056-25.856 49.728 49.728 0 0 0-39.04-66.944 123.712 123.712 0 0 1 0-51.776 49.92 49.92 0 0 0 35.648-24.256 49.92 49.92 0 0 0 3.328-42.624c12.928-11.648 28.224-20.416 45.12-25.92a49.92 49.92 0 0 0 38.528 18.432c15.68 0 29.44-7.296 38.592-18.432 16.896 5.504 32.128 14.272 45.056 25.856a49.728 49.728 0 0 0 39.04 66.944 122.624 122.624 0 0 1 0 51.776z"
		menu.SvgData.Second = "M791.936 736.96c-34.496 0-62.592 28.096-62.592 62.592s28.096 62.592 62.592 62.592 62.592-28.096 62.592-62.592-28.096-62.592-62.592-62.592z m0 83.456a20.864 20.864 0 1 1 0-41.728 20.864 20.864 0 0 1 0 41.728zM670.336 588.736c0.256 0.128 0.512 0.064 0.768 0.128l1.472 0.512 0.064-0.256a35.392 35.392 0 0 0 22.912-67.008l-0.384-0.064c-8.512-3.392-17.472-6.144-26.304-9.088a247.424 247.424 0 0 0 104.192-201.472 248.192 248.192 0 1 0-496.384 0c0 83.072 41.216 156.224 103.936 201.28-175.68 57.984-304.832 218.368-315.776 410.688 0 0.128 0.256 0.192 0.256 0.256a35.328 35.328 0 0 0 68.608 13.504c1.344-3.456 1.536-7.04 1.728-10.56l0.256-0.192a390.016 390.016 0 0 1 389.248-366.336c51.264 0 100.032 10.176 144.832 28.16 0.192 0.192 0.32 0.384 0.576 0.448zM347.648 311.424a177.28 177.28 0 1 1 354.56 0 177.28 177.28 0 0 1-354.56 0z"
		menu.Key = menu.Index
		menu.Items = []menuItem{}

		mItem.Index = "/user"
		mItem.Title = "用户信息"
		mItem.Key = mItem.Index
		menu.Items = append(menu.Items, mItem)

		resp.MenuData = append(resp.MenuData, menu)
	}

	if userInfo.RoleId == 1 {
		menu.Title = "数据管理"
		menu.Index = "3"
		//menu.Class = "el-icon-user"
		menu.SvgData.First = "M64 192V896h896V192H64zM0 128h1024v832H0V128z"
		menu.SvgData.Second = "M64 384h896v64H64zM64 640h896v64H64zM128 256h192v64H128zM128 512h192v64H128zM128 768h192v64H128z"
		menu.Key = menu.Index
		menu.Items = []menuItem{}

		/*mItem.Index = "/base_data"
		mItem.Title = "产品信息"
		mItem.Key = mItem.Index
		menu.Items = append(menu.Items, mItem)
		*/

		mItem.Index = "/pf"
		mItem.Title = "工序工时"
		mItem.Key = mItem.Index
		menu.Items = append(menu.Items, mItem)

		mItem.Index = "/rsm"
		mItem.Title = "维修状态"
		mItem.Key = mItem.Index
		menu.Items = append(menu.Items, mItem)

		resp.MenuData = append(resp.MenuData, menu)
	}

exit:
	jdata, _ := json.Marshal(resp)

	_, err = response.Write(jdata)
	if err != nil {
		logs.Error("getMenu:", err.Error())
	}

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("getMenu recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func checkFileExpired() {

	t := time.NewTicker(time.Minute * 3)

	for {
		select {
		case <-t.C:
			modelePath, err := ModulePath.GetModuleCurrentPath()
			if err != nil {
				logs.Error("GetModuleCurrentPath() failed err:", err.Error())
				return
			}

			fileInfoList, err := ioutil.ReadDir(modelePath + "/file")
			if err != nil {
				logs.Error("ioutil.ReadDir err:", err.Error())
			}

			for i := range fileInfoList {
				index := strings.Index(fileInfoList[i].Name(), ".")
				filename := fileInfoList[i].Name()[:index]
				//filename := strings.TrimSuffix(fileInfoList[i].Name(), ".auf")
				logs.Info(filename) //打印当前文件或目录下的文件或目录名

				t, err := strconv.ParseInt(filename, 10, 64)
				if err == nil {
					t = t / 1e9

					if time.Now().Unix()-t > 60 {
						os.Remove(modelePath + "/file/" + fileInfoList[i].Name())
					}
				} else {
					//logs.Error("checkFileExpired err:", err.Error())
				}
			}

		default:
			time.Sleep(time.Minute * 1)
		}
	}
}

// 登录
func getUuid() string {
	return uuid.NewV4().String()
}

func refreshUser(response http.ResponseWriter, request *http.Request) {
	//beginTime := time.Now().UnixNano()
	//logs.Info("refreshUser recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var resp CommonResp

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req RefreshUserReq
	json.Unmarshal(reqdata, &req)

	deesUserStatMaplck.RLock()
	if v, ok := deesUserStatMap[req.Username]; ok {
		deesUserStatMaplck.RUnlock()

		v.Lock()
		if v.Uuid == req.Uuid {

			if time.Now().Before(v.ExpireTime) {
				v.RefreshTime = time.Now()
				v.ExpireTime = time.Now().Add(ExpireTimeSpan)
			} else {
				resp.Ret = -1
			}

			//logs.Info(fmt.Sprintf("refreshTime:%v expiretime:%v", v.RefreshTime.Format("2006-01-02 15:04:05"), v.ExpireTime.Format("2006-01-02 15:04:05")))

			v.Unlock()
		} else {
			v.Unlock()
			resp.Ret = -1

			//fmt.Println("uuid:", v.Uuid)
			//fmt.Println("req.uuid", req.Uuid)
		}

	} else {
		deesUserStatMaplck.RUnlock()

		resp.Ret = -1
	}

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	//	endTime := time.Now().UnixNano()
	//logs.Info(fmt.Sprintf("refreshUser recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func LoginOut(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("LoginOut recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var resp CommonResp

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req LoginOutReq
	json.Unmarshal(reqdata, &req)

	/*
		deesUserStatMaplck.Lock()
		if _, ok := deesUserStatMap[req.Username]; ok {
			delete(deesUserStatMap, req.Username)
		}
		deesUserStatMaplck.Unlock()
	*/
	resp.Ret = 0

	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("LoginOut recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func Login(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("Login recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var req LoginReq
	var resp LoginResp
	var err error
	var uuid string

	reqdata, _ := ioutil.ReadAll(request.Body)
	json.Unmarshal(reqdata, &req)

	userinfo, err := getUserInfo(req.Username)
	fmt.Println(userinfo)
	if err != nil {
		resp.Ret = -1
		logs.Error("login::getUserInfo err:", err.Error())
		goto exit
	}

	deesUserStatMaplck.RLock()
	if v, ok := deesUserStatMap[req.Username]; ok {
		deesUserStatMaplck.RUnlock()

		v.RLock()
		uuid = v.Uuid

		if time.Now().Before(v.ExpireTime) {
			refreshTime := v.RefreshTime
			v.RUnlock()

			if int64(time.Since(refreshTime).Seconds()) <= refreshSpan {
				resp.Ret = 1
				goto exit
			}

			//online user nojust refresh
			//...
		} else {
			v.RUnlock()
		}

		uuid = getUuid()

	} else {
		deesUserStatMaplck.RUnlock()

		uuid = getUuid()
	}

	if req.Password != userinfo.Password {
		resp.Ret = -1
		goto exit
	}

exit:

	if resp.Ret == 0 {

		resp.RoleId = userinfo.RoleId
		resp.DId = userinfo.DepartmentId
		resp.Location = userinfo.Location

		//refresh user state
		var v DeesUserStat
		v.Username = req.Username
		v.RefreshTime = time.Now()
		v.ExpireTime = time.Now().Add(ExpireTimeSpan)
		v.Uuid = uuid
		v.UserRole = userinfo.RoleId

		resp.Uuid = uuid

		deesUserStatMaplck.Lock()
		deesUserStatMap[req.Username] = &v
		deesUserStatMaplck.Unlock()
	}

	resp.Url = "main.html"
	jdata, _ := json.Marshal(resp)
	fmt.Fprintf(response, string(jdata))

	endTime := time.Now().UnixNano()
	logs.Info(fmt.Sprintf("Login recv req end, use time: %v ms", (endTime-beginTime)/1e6))
}

// 跨域测试
func test(response http.ResponseWriter, request *http.Request) {
	fmt.Println("recv test req")

	response.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
	response.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
	response.Header().Set("content-type", "application/json")             //返回数据格式是json

	fmt.Fprintf(response, "3")

}
