package main

import (
	"bufio"
	"bytes"
	"encoding/csv"

	//	"bytes"
	"database/sql"
	"fmt"
	"io"
	"net/http"
	"os"

	//	"strconv"
	"strings"

	"encoding/json"

	"io/ioutil"

	"time"

	_ "github.com/mattn/go-adodb"

	_ "github.com/LukeMauldin/lodbc"

	"github.com/astaxie/beego/logs"

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

	"github.com/signintech/gopdf"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
	//	"golang.org/x/text/encoding/charmap"
)

var (
	g_report_data chan report_multi_template

	g_ibase_op_ch chan ibase_op_history

	g_inspection_op_ch chan ibase_op_history
)

func init() {
	g_report_data = make(chan report_multi_template, 100)

	g_ibase_op_ch = make(chan ibase_op_history, 100)

	g_inspection_op_ch = make(chan ibase_op_history, 100)

	go create_pdf_g()

	go do_ibase_op_history_g()

	go do_inspection_op_history_g()
}

func get_now_string() (t string) {
	t = time.Now().Format("2006-01-02 15:04:05")
	return t
}

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

	var err error
	var sqlstr string
	var resp CommonResp
	var id int
	var row *sql.Rows

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

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

	row, err = sqlConn.Query(fmt.Sprintf(`select ID from [imn] where [imn_cn] = '%s'`, req.Data.Imn_cn))
	if err != nil {
		logs.Error(fmt.Sprintf("postimn get user cnt err:%v", err.Error()))
		resp.Ret = -1
		goto exit
	}

	for row.Next() {
		if err = row.Scan(&id); err == nil {

		}
	}
	row.Close()

	if id == 0 { //add
		sqlstr = fmt.Sprintf(`INSERT INTO [imn] ([imn_cn],[imn_en]) VALUES ('%s','%s')`,
			req.Data.Imn_cn, req.Data.Imn_en)
	} else if id > 0 { //update
		sqlstr = fmt.Sprintf(`UPDATE [imn] SET [imn_cn] = '%s',[imn_en] = '%s' WHERE ID=%d`,
			req.Data.Imn_cn, req.Data.Imn_en, req.Data.ID)
	}
	fmt.Println(sqlstr)

	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("postimn 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()
	fmt.Println(fmt.Sprintf("postimn recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

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

	var req get_imn_req
	var resp get_imn_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 := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

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

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

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_imn 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_imn scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[imn_cn],[imn_en] from [imn] where ID not in (select top %v ID from [imn] order by ID asc) order by ID asc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[imn_cn],[imn_en] from [imn] where %s and ID not in (select top %v ID from [imn] where %s order by ID asc) order by ID asc", 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_imn Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d imn
		if err := rdRow.Scan(&d.ID, &d.Imn_cn, &d.Imn_en); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_imn scan Error", err.Error())
		}
	}

exit:

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

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

}

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

	var err error
	var resp CommonResp

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

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

	for i := 0; i < len(req.Ids); i++ {

		sqlstr := fmt.Sprintf(`DELETE FROM [imn] where ID=%d`, req.Ids[i].ID)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("del_imn 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()
	fmt.Println(fmt.Sprintf("del_imn recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

//导出检测项目
func export_inspection(response http.ResponseWriter, request *http.Request) {
	beginTime := time.Now().UnixNano()
	fmt.Println("export_inspection recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var res export_file_resp

	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_ibase_req
	var data []Inspection_info

	var sqlstr string
	var rdRow *sql.Rows

	var where_sql string
	var if_where bool

	var size int
	t_data := []string{}

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

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

	if req.P_name != "" {
		where_sql += fmt.Sprintf(`[p_name] = '%s'`, req.P_name)
		if_where = true
	} else {
		goto exit
	}

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

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

	for rdRow.Next() {
		var s string
		if err := rdRow.Scan(&s); err == nil {
			json.Unmarshal([]byte(s), &data)
		} else {
			logs.Error("export_inspection scan Error", err.Error())
		}
	}

	for i := 0; i < len(data); i++ {
		if len(data[i].Result_contain) > size {
			size = len(data[i].Result_contain)
		}
	}

	t_data = []string{"检验项目中", "检验项目英", "检验要求中", "检验要求英", "检验方法中", "检验方法英", "结果类型"}
	for i := 0; i < size; i++ {
		t_data = append(t_data, []string{"结果（中）", "结果（英）"}...)
	}
	csv_data = append(csv_data, t_data)

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

		t_data = []string{}
		t_data = append(t_data, []string{v.Inspection_items_cn, v.Inspection_items_en, v.Inspection_rs_cn, v.Inspection_rs_en, v.Inspection_scheme_cn,
			v.Inspection_scheme_en, v.Inspection_type}...)
		for j := 0; j < len(v.Result_contain); j++ {
			t_data = append(t_data, []string{v.Result_contain[j].Result_cn, v.Result_contain[j].Result_en}...)
		}

		csv_data = append(csv_data, t_data)
	}

exit:

	f.WriteString("\xEF\xBB\xBF") // 写入一个UTF-8 BOM 防止中文乱码
	w := csv.NewWriter(f) //创建一个新的写入文件流
	w.WriteAll(csv_data)
	w.Flush()
	res.FileId = fmt.Sprintf(`%v.csv`, beginTime)

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

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

}

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

	var req get_ibase_req
	var resp get_ibase_op_history_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 := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

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

	if !if_where {
		sqlstr = fmt.Sprintf("select [username],[p_name],[context],[op_time] from [inspection_op_history] order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [username],[p_name],[context],[op_time] from [inspection_op_history] where %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

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

	for rdRow.Next() {
		var d ibase_op_history
		if err := rdRow.Scan(&d.Username, &d.P_name, &d.Context, &d.Op_time); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_inspection_op_history scan Error", err.Error())
		}
	}

exit:

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

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

}

func do_inspection_op_history(req ibase_op_history) {

	req.Op_time = get_now_string()

	sqlstr := fmt.Sprintf(`INSERT INTO [inspection_op_history] ([username],[p_name],[context],[op_time]) VALUES ('%s','%s','%s','%s')`, req.Username, req.P_name, req.Context, req.Op_time)

	_, err := sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("do_inspection_op_history Exec Error:", err.Error())
	}

}

func do_inspection_op_history_g() {
	for {
		select {
		case v := <-g_inspection_op_ch:
			do_inspection_op_history(v)
		default:
			time.Sleep(time.Second * 1)
		}
	}
}

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

	var req get_ibase_req
	var resp get_ibase_op_history_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 := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

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

	if !if_where {
		sqlstr = fmt.Sprintf("select [username],[p_name],[context],[op_time] from [ibase_op_history] order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [username],[p_name],[context],[op_time] from [ibase_op_history] where %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

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

	for rdRow.Next() {
		var d ibase_op_history
		if err := rdRow.Scan(&d.Username, &d.P_name, &d.Context, &d.Op_time); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ibase_op_history scan Error", err.Error())
		}
	}

exit:

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

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

}

func do_ibase_op_history(req ibase_op_history) {

	req.Op_time = get_now_string()

	sqlstr := fmt.Sprintf(`INSERT INTO [ibase_op_history] ([username],[p_name],[context],[op_time]) VALUES ('%s','%s','%s','%s')`, req.Username, req.P_name, req.Context, req.Op_time)

	_, err := sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("do_ibase_op_history Exec Error:", err.Error())
	}

}

func do_ibase_op_history_g() {
	for {
		select {
		case v := <-g_ibase_op_ch:
			do_ibase_op_history(v)
		default:
			time.Sleep(time.Second * 1)
		}
	}
}

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

	var err error
	var sqlstr string
	var resp CommonResp

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

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

	for i := 0; i < len(req.Data); i++ {
		v := req.Data[i]
		sqlstr = fmt.Sprintf(`DELETE FROM [ibase] where [p_name_cn] = '%s'`, v.P_name_cn)
		sqlConn.Exec(sqlstr)

		sqlstr = fmt.Sprintf(`INSERT INTO [ibase] ([p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] ,[p_categories],[p_sub]) VALUES ('%s','%s','%s','%s','%s','%s')`,
			v.P_name_cn, v.P_name_en,
			v.P_ibase_cn, v.P_ibase_en,
			v.P_categories, v.P_sub)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("import_ibase Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}

		var d ibase_op_history
		d.P_name = v.P_name_cn
		d.Username = req.OpUser
		d.Context = "新增"
		g_ibase_op_ch <- d
	}

	resp.Ret = 0

exit:

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

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

}

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

	var res export_file_resp

	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_ibase_req
	var resp get_ibase_resp

	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 := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

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

	if !if_where {
		sqlstr = fmt.Sprintf("select [ID],[p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] ,[p_categories],[p_sub] from [ibase] order by ID desc")
	} else {
		sqlstr = fmt.Sprintf("select [ID],[p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] ,[p_categories],[p_sub] from [ibase] where %s order by ID desc", where_sql)
	}
	fmt.Println(sqlstr)

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

	for rdRow.Next() {
		var d ibase
		if err := rdRow.Scan(&d.ID, &d.P_name_cn, &d.P_name_en, &d.P_ibase_cn, &d.P_ibase_en,
			&d.P_categories, &d.P_sub); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ibase scan Error", err.Error())
		}
	}

	csv_data = append(csv_data, []string{"产品型号及名称(中)", "产品型号及名称(英)", "检验依据(中)", "检验依据(英)", "产品大类", "产品小类"})

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

		csv_data = append(csv_data, []string{v.P_name_cn, v.P_name_en, v.P_ibase_cn, v.P_ibase_en, v.P_categories, v.P_sub})
	}

exit:

	f.WriteString("\xEF\xBB\xBF") // 写入一个UTF-8 BOM 防止中文乱码
	w := csv.NewWriter(f) //创建一个新的写入文件流
	w.WriteAll(csv_data)
	w.Flush()
	res.FileId = fmt.Sprintf(`%v.csv`, beginTime)

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

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

}

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

	var req get_ibase_req
	var resp get_ibase_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 := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

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

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

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ibase 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_ibase scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] ,[p_categories],[p_sub] from [ibase] where ID not in (select top %v ID from [ibase] order by ID desc) order by ID desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] ,[p_categories],[p_sub] from [ibase] where %s and ID not in (select top %v ID from [ibase] 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_ibase Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d ibase
		if err := rdRow.Scan(&d.ID, &d.P_name_cn, &d.P_name_en, &d.P_ibase_cn, &d.P_ibase_en,
			&d.P_categories, &d.P_sub); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ibase scan Error", err.Error())
		}
	}

exit:

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

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

}

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

	var err error
	var sqlstr string
	var resp CommonResp
	var id int
	var row *sql.Rows

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

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

	row, err = sqlConn.Query(fmt.Sprintf(`select ID from [ibase] where [p_name_cn] = '%s'`, req.Data.P_name_cn))
	if err != nil {
		logs.Error(fmt.Sprintf("postibase get user cnt err:%v", err.Error()))
		resp.Ret = -1
		goto exit
	}

	for row.Next() {
		if err = row.Scan(&id); err == nil {

		}
	}
	row.Close()

	if id == 0 { //add
		sqlstr = fmt.Sprintf(`INSERT INTO [ibase] ([p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] ,[p_categories],[p_sub]) VALUES ('%s','%s','%s','%s','%s','%s')`,
			req.Data.P_name_cn, req.Data.P_name_en,
			req.Data.P_ibase_cn, req.Data.P_ibase_en,
			req.Data.P_categories, req.Data.P_sub)
	} else if id > 0 { //update
		sqlstr = fmt.Sprintf(`UPDATE [ibase] SET [p_name_cn] = '%s',[p_name_en] = '%s',[p_ibase_cn] = '%s',[p_ibase_en] = '%s',[p_categories]='%s',[p_sub]='%s' WHERE ID=%d`,
			req.Data.P_name_cn, req.Data.P_name_en,
			req.Data.P_ibase_cn, req.Data.P_ibase_en,
			req.Data.P_categories, req.Data.P_sub,
			id)
	}
	fmt.Println(sqlstr)

	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("postibase Exec Error:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	if resp.Ret == 0 {
		var d ibase_op_history
		d.P_name = req.Data.P_name_cn
		if id == 0 {
			d.Username = req.OpUser
			d.Context = "新增"
		} else {
			d.Username = req.OpUser
			d.Context = "更新"
		}
		g_ibase_op_ch <- d
	}

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

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

}

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

	var err error
	var resp CommonResp

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

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

	for i := 0; i < len(req.Ids); i++ {

		sqlstr := fmt.Sprintf(`DELETE FROM [ibase] where ID=%d`, req.Ids[i].ID)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("del_ibase 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()
	fmt.Println(fmt.Sprintf("del_ibase recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

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

	var req get_p_name_options_req
	var resp get_p_name_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
	}

	sqlstr = fmt.Sprintf("select [p_name_cn] from [ibase] order by ID desc")
	fmt.Println(sqlstr)

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

	for rdRow.Next() {
		var v string

		if err := rdRow.Scan(&v); err == nil {

			resp.Data = append(resp.Data, v)

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

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

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

}

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

	var err error
	var sqlstr string
	var resp CommonResp
	//	var id int
	//	var row *sql.Rows
	var js_data []byte

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

	fmt.Println(req)

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

	sqlstr = fmt.Sprintf(`DELETE FROM [inspection_template] where [p_name] = '%s'`, req.P_name)
	sqlConn.Exec(sqlstr)

	js_data, _ = json.Marshal(req.Data)
	sqlstr = fmt.Sprintf(`INSERT INTO [inspection_template] ([p_name],[data]) VALUES ('%s','%s')`,
		req.P_name, string(js_data))
	fmt.Println(sqlstr)

	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("post_inspection Exec Error:", err.Error())
		resp.Ret = -1
		goto exit
	}

	{
		var d ibase_op_history
		d.P_name = req.P_name
		d.Username = req.OpUser
		d.Context = "新增（修改）"
		g_inspection_op_ch <- d
	}

	resp.Ret = 0

exit:

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

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

}

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

	var req get_inspection_req
	var resp get_inspection_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 := checkIsSysUserOnline(req.OpUser, req.OpUserUuid)
	if !b {
		goto exit
	}

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

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

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_inspection 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_inspection scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_name],[data] from [inspection_template] where ID not in (select top %v ID from [inspection_template] order by ID desc) order by ID desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[p_name],[data] from [inspection_template] where %s and ID not in (select top %v ID from [inspection_template] 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_inspection Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d get_inspection_resp_d
		var s string
		if err := rdRow.Scan(&d.ID, &d.P_name, &s); err == nil {
			json.Unmarshal([]byte(s), &d.Data)
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_inspection scan Error", err.Error())
		}
	}

exit:

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

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

}

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

	var err error
	var resp CommonResp

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

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

	for i := 0; i < len(req.Ids); i++ {

		sqlstr := fmt.Sprintf(`DELETE FROM [inspection_template] where ID=%d`, req.Ids[i].ID)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("del_inspection 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()
	fmt.Println(fmt.Sprintf("del_inspection recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

func get_basis_from_pname(p_name string) (basis ibase) {

	var sqlstr string
	var rdRow *sql.Rows
	var err error
	sqlstr = fmt.Sprintf("select [ID],[p_name_cn],[p_name_en],[p_ibase_cn],[p_ibase_en] from [ibase] where [p_name_cn]='%s'", p_name)
	fmt.Println(sqlstr)

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

	for rdRow.Next() {
		var d ibase
		if err := rdRow.Scan(&d.ID, &d.P_name_cn, &d.P_name_en, &d.P_ibase_cn, &d.P_ibase_en); err == nil {
			basis = d
		} else {
			logs.Error("get_basis_from_pname scan Error", err.Error())
		}
	}

exit:
	return
}

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

	var req get_report_multi_template_req
	var resp report_multi_template

	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 [data] from [inspection_template] where [p_name]='%s'", req.P_name)
	fmt.Println(sqlstr)

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

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

			resp.Time = time.Now().Format("2006-01-02")
			resp.Inspector = req.OpUser

			basis := get_basis_from_pname(req.P_name)
			resp.P_name_cn = basis.P_name_cn
			resp.P_name_en = basis.P_ibase_en
			resp.P_ibase_cn = basis.P_ibase_cn
			resp.P_ibase_en = basis.P_ibase_en

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

				var tv Inspection_info_ex
				tv.Inspection_items_cn = v.Inspection_items_cn
				tv.Inspection_items_en = v.Inspection_items_en
				tv.Inspection_rs_cn = v.Inspection_rs_cn
				tv.Inspection_rs_en = v.Inspection_rs_en
				tv.Inspection_scheme_cn = v.Inspection_scheme_cn
				tv.Inspection_scheme_en = v.Inspection_scheme_en

				tv.Inspection_type = v.Inspection_type
				tv.Result_contain = append(tv.Result_contain, v.Result_contain...)
				resp.Inspection_data = append(resp.Inspection_data, tv)
			}

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

exit:

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

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

}

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

	var req get_ledger_req
	var resp get_ledger_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_name != "" {
		likeStr := "%" + req.P_name + "%"
		where_sql += fmt.Sprintf(`[p_name] like '%s'`, likeStr)
		if_where = true
	}

	if req.Node != "" {
		if if_where {
			where_sql += fmt.Sprintf(` and [inspection_node] = '%s'`, req.Node)
		} else {
			where_sql += fmt.Sprintf(` [inspection_node] = '%s'`, req.Node)
		}

		if_where = true
	}

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

	cntRow, err = sqlConn.Query(sqlstr)
	if err != nil {
		logs.Error(fmt.Sprintf("get_ledger 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_ledger scan %s err:%v", sqlstr, err.Error()))
			goto exit
		}
	}
	resp.Total = rcnt

	if !if_where {
		sqlstr = fmt.Sprintf("select top %v [ID],[time],[p_name],[inspection_node],[serial],[fin_result],[non_conformity_treatment],[inspector],[auditor],[file],[data],[file_en] from [inspection_report] where ID not in (select top %v ID from [inspection_report] order by ID desc) order by ID desc", req.Count, (req.Index-1)*req.Count)
	} else {
		sqlstr = fmt.Sprintf("select top %v [ID],[time],[p_name],[inspection_node],[serial],[fin_result],[non_conformity_treatment],[inspector],[auditor],[file],[data],[file_en] from [inspection_report] where %s and ID not in (select top %v ID from [inspection_report] 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_ledger Query err:%v", err.Error()))
		goto exit
	}
	defer rdRow.Close()

	for rdRow.Next() {
		var d get_ledger_resp_d
		if err := rdRow.Scan(&d.ID, &d.Time, &d.P_name_cn, &d.Inspection_node, &d.Serial, &d.Fin_result, &d.Non_conformity_treatment, &d.Inspector, &d.Auditor, &d.File, &d.Data,
			&d.File_en); err == nil {
			resp.Data = append(resp.Data, d)
		} else {
			logs.Error("get_ledger scan Error", err.Error())
		}
	}

exit:

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

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

}

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

	var err error
	var resp CommonResp

	reqdata, _ := ioutil.ReadAll(request.Body)
	var req del_ledger_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 [inspection_report] where ID=%d`, req.Ids[i].ID)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("del_ledger 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()
	fmt.Println(fmt.Sprintf("del_ledger recv req end, use time: %v ms", (endTime-beginTime)/1e6))

}

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

	var err error
	var sqlstr string
	var resp CommonResp
	//	var id int
	//	var row *sql.Rows
	var js_data []byte

	var data []report_multi_template
	var serials []string

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

	fmt.Println(req)

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

	serials = strings.Split(req.Data.Serial_sets, ",")
	for i := 0; i < len(serials); i++ {
		v := serials[i]
		sqlstr = fmt.Sprintf(`DELETE FROM [inspection_report] where [p_name] = '%s' and [serial]='%s'`, req.Data.P_name_cn, v)
		sqlConn.Exec(sqlstr)
	}

	for i := 0; i < len(serials); i++ {
		var d report_multi_template = req.Data
		d.Inspection_data = []Inspection_info_ex{}
		d.Inspection_data = append(d.Inspection_data, req.Data.Inspection_data...)
		d.Serial_sets = serials[i]

		for j := 0; j < len(req.Data.Inspection_data); j++ {
			v := req.Data.Inspection_data[j]
			fmt.Println("-", v.Result)
			if v.Result != "" {
				results := strings.Split(v.Result, ",")
				if len(results) > 0 && len(results) != len(serials) {
					fmt.Println(results)
					resp.Ret = 1
					goto exit
				} else if len(results) > 0 && len(results) == len(serials) {
					d.Inspection_data[j].Result = results[i]
				}
			}

			var if_exist bool
			if v.Serial_sets != "" {
				non_serials := strings.Split(v.Serial_sets, ",")
				for k := 0; k < len(non_serials); k++ {
					if d.Serial_sets == non_serials[k] {
						if_exist = true
						break
					}
				}
			}

			if if_exist {
				d.Inspection_data[j].If_ok = "×"
			} else {
				d.Inspection_data[j].If_ok = "√"
			}
		}

		data = append(data, d)
	}

	for i := 0; i < len(data); i++ {
		v := data[i]
		js_data, _ = json.Marshal(data[i])
		sqlstr = fmt.Sprintf(`INSERT INTO [inspection_report]
           ([time]
           ,[p_name]
           ,[inspection_node]
           ,[serial]
           ,[fin_result]
           ,[non_conformity_treatment]
           ,[inspector]
           ,[auditor]
           ,[data]
           )
     VALUES
           ('%s','%s','%s','%s','%s','%s','%s','%s','%s')`,
			v.Time, v.P_name_cn, v.Inspection_node, v.Serial_sets, v.Fin_result,
			v.Non_conformity_treatment, v.Inspector, v.Auditor, string(js_data))
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("post_report Exec Error:", err.Error())
			resp.Ret = -1
			goto exit
		}

		g_report_data <- v
	}

	resp.Ret = 0

exit:

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

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

}

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

	var err error
	var sqlstr string
	var resp CommonResp
	//	var id int
	//	var row *sql.Rows
	var js_data []byte

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

	fmt.Println(req)

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

	if req.Data.Auditor != "" {
		req.Data.Audit_time = time.Now().Format("2006-01-02")
	}

	sqlstr = fmt.Sprintf(`DELETE FROM [inspection_report] where [p_name] = '%s' and [serial]='%s'`, req.Data.P_name_cn, req.Data.Serial_sets)
	sqlConn.Exec(sqlstr)

	js_data, _ = json.Marshal(req.Data)
	sqlstr = fmt.Sprintf(`INSERT INTO [inspection_report]
           ([time]
           ,[p_name]
           ,[inspection_node]
           ,[serial]
           ,[fin_result]
           ,[non_conformity_treatment]
           ,[inspector]
           ,[auditor]
           ,[data]
           )
     VALUES
           ('%s','%s','%s','%s','%s','%s','%s','%s','%s')`,
		req.Data.Time, req.Data.P_name_cn, req.Data.Inspection_node, req.Data.Serial_sets, req.Data.Fin_result,
		req.Data.Non_conformity_treatment, req.Data.Inspector, req.Data.Auditor, string(js_data))
	fmt.Println(sqlstr)

	_, err = sqlConn.Exec(sqlstr)
	if err != nil {
		logs.Info("post_report_s Exec Error:", err.Error())
		resp.Ret = -1
		goto exit
	}

	resp.Ret = 0

exit:

	if resp.Ret == 0 {
		g_report_data <- req.Data
	}

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

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

}

func get_pdf_cn_pagesize(data report_multi_template) (page_cnt int) {
	//W: 595, H: 842
	page_W := gopdf.PageSizeA4Landscape.W
	page_H := gopdf.PageSizeA4Landscape.H
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4Landscape})
	pdf.AddPage()
	err := pdf.AddTTFFont("simfang", "./simfang.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	err = pdf.AddTTFFont("wr", "./微软雅黑.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	var margin_top float64 = 2.54 * (page_H / float64(29.7))
	var margin_left float64 = 1.91 * (page_W / float64(21))
	var span float64 = 20
	//	var h_span float64 = 150

	page_context_H := page_H - margin_top

	var one_cm float64 = page_W / float64(21)
	page_F_x := page_W/2 - (0.2 * one_cm)
	page_F_y := gopdf.PageSizeA4Landscape.H - (margin_top / 2)

	pdf.SetFont("simfang", "", 22)
	var option gopdf.CellOption
	option.Align = gopdf.Center
	pdf.SetXY(0, margin_top)
	pdf.CellWithOption(&gopdf.Rect{H: 30, W: page_W}, "检验记录报告", option)

	//cal total pagenum
	var cur_page int = 1
	var total_page int = 1
	fmt.Println("报告总页码：", total_page)

	pdf.SetFont("simfang", "", 14)
	var base float64 = margin_top + 45
	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`产品型号及名称：%s`, data.P_name_cn))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`检验依据：%s`, data.P_ibase_cn))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`检测时间：%s`, data.Time))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`检验节点：%s`, data.Inspection_node))

	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	base0 := margin_left
	base1 := margin_left + 150
	base2 := margin_left + 300
	base3 := margin_left + 450
	base4 := margin_left + 550
	base5 := margin_left + 600
	base6 := margin_left + 700

	base += span
	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)

	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base1, base, base1, base+span)
	pdf.Line(base2, base, base2, base+span)
	pdf.Line(base3, base, base3, base+span)
	pdf.Line(base4, base, base4, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	var option1 gopdf.CellOption
	option1.Align = gopdf.Middle | gopdf.Center
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "检验项目", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base1}, "检验要求", option1)
	pdf.SetXY(base2, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, "检验方法", option1)
	pdf.SetXY(base3, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base4 - base3}, "结果", option1)
	pdf.SetXY(base4, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base4}, "判定", option1)
	pdf.SetXY(base5, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, "附件", option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	cnt := 0
	cur_item := ""
	for i := 0; i < len(data.Inspection_data); i++ {

		v := data.Inspection_data[i]

		if v.Inspection_items_cn != cur_item {

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			cnt++
			cur_item = v.Inspection_items_cn

			//pdf.SetLineWidth(0.1)
			pdf.Line(base0, base, base6, base)

			pdf.Line(base0, base, base0, base+span)
			pdf.Line(base6, base, base6, base+span)

			var option1 gopdf.CellOption
			option1.Align = gopdf.Middle | gopdf.Left
			pdf.SetFont("wr", "", 13)
			pdf.SetXY(base0, base)
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, fmt.Sprintf(`%d.%s`, cnt, v.Inspection_items_cn), option1)
			base += span
			pdf.Line(margin_left, base, base6, base)
		}

		pdf.SetFont("simfang", "", 14)
		var max_h int = 1
		context1, _ := pdf.SplitTextWithWordWrap(v.Inspection_rs_cn, base2-base0)
		if len(context1) > int(max_h) {
			max_h = len(context1)
		}

		context2, _ := pdf.SplitTextWithWordWrap(v.Inspection_scheme_cn, base3-base2)
		if len(context2) > int(max_h) {
			max_h = len(context2)
		}

		context3, _ := pdf.SplitTextWithWordWrap(v.Attach_file, base6-base5)
		fmt.Println(context3, len(context3))
		if len(context3) > int(max_h) {
			max_h = len(context3)
		}

		var context1_base float64 = (float64(max_h-len(context1))/2)*span + base
		var context2_base float64 = (float64(max_h-len(context2))/2)*span + base
		var context3_base float64 = (float64(max_h-len(context3))/2)*span + base

		if base+(float64(max_h)*span) > page_context_H {
			pdf.SetXY(page_F_x, page_F_y)
			pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
			cur_page++

			pdf.AddPage()
			base = margin_top
			pdf.SetXY(margin_left*1, base)
		} else {
			pdf.SetXY(margin_left*1, base)
		}

		//pdf.SetLineWidth(0.1)
		pdf.Line(base0, base, base6, base)

		pdf.Line(base0, base, base0, base+(float64(max_h)*span))
		pdf.Line(base2, base, base2, base+(float64(max_h)*span))
		pdf.Line(base3, base, base3, base+(float64(max_h)*span))
		pdf.Line(base4, base, base4, base+(float64(max_h)*span))
		pdf.Line(base5, base, base5, base+(float64(max_h)*span))
		pdf.Line(base6, base, base6, base+(float64(max_h)*span))

		var option1 gopdf.CellOption
		option1.Align = gopdf.Middle | gopdf.Center

		for j := 0; j < len(context1); j++ {
			pdf.SetXY(base0, context1_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base0}, context1[j], option1)
		}

		for j := 0; j < len(context2); j++ {
			pdf.SetXY(base2, context2_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, context2[j], option1)
		}

		pdf.SetXY(base3, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base4 - base3}, v.Result, option1)
		pdf.SetXY(base4, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base5 - base4}, v.If_ok, option1)

		for j := 0; j < len(context3); j++ {
			pdf.SetXY(base5, context3_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, context3[j], option1)
		}

		base += (float64(max_h) * span)
		pdf.Line(margin_left, base, base6, base)

	}

	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base0}, "备注：□为定性判断，合格√，不合格×  ⊙为定量判断，记录数据", option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base1, base, base1, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "最终结果(合格/不合格)", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base1}, data.Fin_result, option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	//不合格处理方式
	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base1, base, base1, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "不合格处理方式", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base1}, data.Non_conformity_treatment, option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	//审核人
	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`检验员：%s`, data.Inspector), option1)
	pdf.SetXY(base0+200, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`审核员：%s`, data.Auditor), option1)

	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`日 期：%s`, data.Time), option1)
	pdf.SetXY(base0+200, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`日 期：%s`, data.Time), option1)

	base += span + span
	pdf.Line(margin_left, base, base6, base)

	for i := 0; i < len(data.Inspection_data); i++ {
		v := data.Inspection_data[i]
		fmt.Println(v.Attach_file)

		index := strings.LastIndex(v.Attach_file, ".")
		if index <= 0 {
			continue
		}

		file_type := v.Attach_file[index:]
		fmt.Println(file_type)
		if file_type == ".txt" {

			fileHandle, err := os.OpenFile(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), os.O_RDONLY, 0666)
			if err != nil {
				continue
			}

			reader := bufio.NewReader(fileHandle)

			var results []string
			// 按行处理txt
			for {
				line, _, err := reader.ReadLine()
				if err == io.EOF {
					break
				}
				reader := transform.NewReader(bytes.NewReader(line), simplifiedchinese.GBK.NewDecoder())
				d, e := ioutil.ReadAll(reader)
				if e != nil {
					continue
				}
				results = append(results, string(d))
			}
			fileHandle.Close()

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`附件：%s`, v.Attach_file))

			for k := 0; k < len(results); k++ {

				context_result, _ := pdf.SplitTextWithWordWrap(results[k], page_W-margin_left-margin_left)
				for z := 0; z < len(context_result); z++ {
					if base+span > page_context_H {
						pdf.SetXY(page_F_x, page_F_y)
						pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
						cur_page++

						pdf.AddPage()
						base = margin_top
						pdf.SetXY(margin_left*1, base)
					} else {
						pdf.SetXY(margin_left*1, base)
					}

					base += span
					pdf.SetXY(margin_left, base)

					pdf.Text(fmt.Sprintf(`%s`, context_result[z]))
				}
			}

		} else if file_type == ".jpeg" || file_type == ".png" || file_type == ".jpg" {

			if base+((page_H-span-span)/2) > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			pdf.Image(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), margin_left, base, &gopdf.Rect{H: (page_H - span - span) / 2, W: page_W / 2})
			base += ((page_H - span - span) / 2)

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`附件：%s`, v.Attach_file))
		}
	}

	pdf.SetXY(page_F_x, page_F_y)
	pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))

	page_cnt = cur_page
	return
}

func Utf8ToGbk(s []byte) ([]byte, error) {
	reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewEncoder())
	d, e := ioutil.ReadAll(reader)
	if e != nil {
		return nil, e
	}
	return d, nil
}

func create_pdf_cn(data report_multi_template) {
	//W: 595, H: 842
	page_W := gopdf.PageSizeA4Landscape.W
	page_H := gopdf.PageSizeA4Landscape.H
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4Landscape})
	pdf.AddPage()
	err := pdf.AddTTFFont("simfang", "./simfang.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	err = pdf.AddTTFFont("wr", "./微软雅黑.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	var margin_top float64 = 2.54 * (page_H / float64(29.7))
	var margin_left float64 = 1.91 * (page_W / float64(21))
	var span float64 = 20
	//	var h_span float64 = 150

	page_context_H := page_H - margin_top

	var one_cm float64 = page_W / float64(21)
	page_F_x := page_W/2 - (0.2 * one_cm)
	page_F_y := gopdf.PageSizeA4Landscape.H - (margin_top / 2)

	pdf.SetFont("simfang", "", 22)
	var option gopdf.CellOption
	option.Align = gopdf.Center
	pdf.SetXY(0, margin_top)
	pdf.CellWithOption(&gopdf.Rect{H: 30, W: page_W}, "检验记录报告", option)

	//cal total pagenum
	var cur_page int = 1
	var total_page int = 1
	total_page = get_pdf_cn_pagesize(data)
	fmt.Println("报告总页码：", total_page)

	pdf.SetFont("simfang", "", 14)
	var base float64 = margin_top + 45
	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`产品型号及名称：%s`, data.P_name_cn))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`检验依据：%s`, data.P_ibase_cn))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`检测时间：%s`, data.Time))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`检验节点：%s`, data.Inspection_node))

	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	base0 := margin_left
	base1 := margin_left + 150
	base2 := margin_left + 300
	base3 := margin_left + 450
	base4 := margin_left + 550
	base5 := margin_left + 600
	base6 := margin_left + 700

	base += span
	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)

	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base1, base, base1, base+span)
	pdf.Line(base2, base, base2, base+span)
	pdf.Line(base3, base, base3, base+span)
	pdf.Line(base4, base, base4, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	var option1 gopdf.CellOption
	option1.Align = gopdf.Middle | gopdf.Center
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "检验项目", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base1}, "检验要求", option1)
	pdf.SetXY(base2, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, "检验方法", option1)
	pdf.SetXY(base3, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base4 - base3}, "结果", option1)
	pdf.SetXY(base4, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base4}, "判定", option1)
	pdf.SetXY(base5, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, "附件", option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	cnt := 0
	cur_item := ""
	for i := 0; i < len(data.Inspection_data); i++ {

		v := data.Inspection_data[i]

		if v.Inspection_items_cn != cur_item {

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			cnt++
			cur_item = v.Inspection_items_cn

			//pdf.SetLineWidth(0.1)
			pdf.Line(base0, base, base6, base)

			pdf.Line(base0, base, base0, base+span)
			pdf.Line(base6, base, base6, base+span)

			var option1 gopdf.CellOption
			option1.Align = gopdf.Middle | gopdf.Left
			pdf.SetFont("wr", "", 13)
			pdf.SetXY(base0, base)
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, fmt.Sprintf(`%d.%s`, cnt, v.Inspection_items_cn), option1)
			base += span
			pdf.Line(margin_left, base, base6, base)
		}

		pdf.SetFont("simfang", "", 14)
		var max_h int = 1
		context1, _ := pdf.SplitTextWithWordWrap(v.Inspection_rs_cn, base2-base0)
		if len(context1) > int(max_h) {
			max_h = len(context1)
		}

		context2, _ := pdf.SplitTextWithWordWrap(v.Inspection_scheme_cn, base3-base2)
		if len(context2) > int(max_h) {
			max_h = len(context2)
		}

		context3, _ := pdf.SplitTextWithWordWrap(v.Attach_file, base6-base5)
		fmt.Println(context3, len(context3))
		if len(context3) > int(max_h) {
			max_h = len(context3)
		}

		var context1_base float64 = (float64(max_h-len(context1))/2)*span + base
		var context2_base float64 = (float64(max_h-len(context2))/2)*span + base
		var context3_base float64 = (float64(max_h-len(context3))/2)*span + base

		if base+(float64(max_h)*span) > page_context_H {
			pdf.SetXY(page_F_x, page_F_y)
			pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
			cur_page++

			pdf.AddPage()
			base = margin_top
			pdf.SetXY(margin_left*1, base)
		} else {
			pdf.SetXY(margin_left*1, base)
		}

		//pdf.SetLineWidth(0.1)
		pdf.Line(base0, base, base6, base)

		pdf.Line(base0, base, base0, base+(float64(max_h)*span))
		pdf.Line(base2, base, base2, base+(float64(max_h)*span))
		pdf.Line(base3, base, base3, base+(float64(max_h)*span))
		pdf.Line(base4, base, base4, base+(float64(max_h)*span))
		pdf.Line(base5, base, base5, base+(float64(max_h)*span))
		pdf.Line(base6, base, base6, base+(float64(max_h)*span))

		var option1 gopdf.CellOption
		option1.Align = gopdf.Middle | gopdf.Center

		for j := 0; j < len(context1); j++ {
			pdf.SetXY(base0, context1_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base0}, context1[j], option1)
		}

		for j := 0; j < len(context2); j++ {
			pdf.SetXY(base2, context2_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, context2[j], option1)
		}

		pdf.SetXY(base3, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base4 - base3}, v.Result, option1)
		pdf.SetXY(base4, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base5 - base4}, v.If_ok, option1)

		for j := 0; j < len(context3); j++ {
			pdf.SetXY(base5, context3_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, context3[j], option1)
		}

		base += (float64(max_h) * span)
		pdf.Line(margin_left, base, base6, base)

	}

	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base0}, "备注：□为定性判断，合格√，不合格×  ⊙为定量判断，记录数据", option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base1, base, base1, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "最终结果(合格/不合格)", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base1}, data.Fin_result, option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	//不合格处理方式
	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}
	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base1, base, base1, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "不合格处理方式", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base1}, data.Non_conformity_treatment, option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	//审核人
	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`检验员：%s`, data.Inspector), option1)
	pdf.SetXY(base0+200, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`审核员：%s`, data.Auditor), option1)

	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`日 期：%s`, data.Time), option1)
	pdf.SetXY(base0+200, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`日 期：%s`, data.Audit_time), option1)

	base += span + span
	pdf.Line(margin_left, base, base6, base)

	for i := 0; i < len(data.Inspection_data); i++ {
		v := data.Inspection_data[i]
		fmt.Println(v.Attach_file)

		index := strings.LastIndex(v.Attach_file, ".")
		if index <= 0 {
			continue
		}

		file_type := v.Attach_file[index:]
		fmt.Println(file_type)
		if file_type == ".txt" {

			fileHandle, err := os.OpenFile(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), os.O_RDONLY, 0666)
			if err != nil {
				continue
			}

			reader := bufio.NewReader(fileHandle)

			var results []string
			// 按行处理txt
			for {
				line, _, err := reader.ReadLine()
				if err == io.EOF {
					break
				}
				reader := transform.NewReader(bytes.NewReader(line), simplifiedchinese.GBK.NewDecoder())
				d, e := ioutil.ReadAll(reader)
				if e != nil {
					continue
				}
				results = append(results, string(d))
			}
			fileHandle.Close()

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`附件：%s`, v.Attach_file))

			for k := 0; k < len(results); k++ {

				context_result, _ := pdf.SplitTextWithWordWrap(results[k], page_W-margin_left-margin_left)
				for z := 0; z < len(context_result); z++ {
					if base+span > page_context_H {
						pdf.SetXY(page_F_x, page_F_y)
						pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
						cur_page++

						pdf.AddPage()
						base = margin_top
						pdf.SetXY(margin_left*1, base)
					} else {
						pdf.SetXY(margin_left*1, base)
					}

					base += span
					pdf.SetXY(margin_left, base)

					pdf.Text(fmt.Sprintf(`%s`, context_result[z]))
				}
			}

		} else if file_type == ".jpeg" || file_type == ".png" || file_type == ".jpg" {

			if base+((page_H-span-span)/2) > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			pdf.Image(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), margin_left, base, &gopdf.Rect{H: (page_H - span - span) / 2, W: page_W / 2})
			base += ((page_H - span - span) / 2)

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`附件：%s`, v.Attach_file))
		}
	}

	pdf.SetXY(page_F_x, page_F_y)
	pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))

	//save
	beginTime := time.Now().UnixNano()
	pdf.WritePdf(fmt.Sprintf(`./upload_report_file/%v.pdf`, beginTime))

	update_report_file(data, fmt.Sprintf(`%v.pdf`, beginTime), "")

	//filename := strconv.FormatInt(beginTime, 10)
	return
}

func get_pdf_en_pagesize(data report_multi_template) (page_cnt int) {
	//W: 595, H: 842
	page_W := gopdf.PageSizeA4Landscape.W
	page_H := gopdf.PageSizeA4Landscape.H
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4Landscape})
	pdf.AddPage()
	err := pdf.AddTTFFont("simfang", "./simfang.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	err = pdf.AddTTFFont("wr", "./微软雅黑.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	var margin_top float64 = 2.54 * (page_H / float64(29.7))
	var margin_left float64 = 1.91 * (page_W / float64(21))
	var span float64 = 20
	//	var h_span float64 = 150

	page_context_H := page_H - margin_top

	var one_cm float64 = page_W / float64(21)
	page_F_x := page_W/2 - (0.2 * one_cm)
	page_F_y := gopdf.PageSizeA4Landscape.H - (margin_top / 2)

	pdf.SetFont("simfang", "", 22)
	var option gopdf.CellOption
	option.Align = gopdf.Center
	pdf.SetXY(0, margin_top)
	pdf.CellWithOption(&gopdf.Rect{H: 30, W: page_W}, "Inspection Record Report", option)

	//cal total pagenum
	var cur_page int = 1
	var total_page int = 1
	//total_page = get_pdf_cn_pagesize(data)
	fmt.Println("报告总页码：", total_page)

	pdf.SetFont("simfang", "", 14)
	var base float64 = margin_top + 45
	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`Part Number & Part Name：%s`, data.P_name_cn))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`Inspection referred document：%s`, data.P_ibase_cn))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`Inspection time：%s`, data.Time))

	base += span
	pdf.SetXY(margin_left, base)
	if data.Inspection_node == "入库" {
		pdf.Text(fmt.Sprintf(`Inspection step：In stock`))
	} else if data.Inspection_node == "出库" {
		pdf.Text(fmt.Sprintf(`Inspection step：Out of stock`))
	} else if data.Inspection_node == "退库" {
		pdf.Text(fmt.Sprintf(`Inspection step：Return to stock`))
	} else {
		pdf.Text(fmt.Sprintf(`Inspection step：`))
	}

	if base+span+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	base0 := margin_left
	base1 := margin_left + 150
	base2 := margin_left + 300
	base3 := margin_left + 450
	base4 := margin_left + 580
	base5 := margin_left + 660
	base6 := margin_left + 760

	base += span
	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)

	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base1, base, base1, base+span+span)
	pdf.Line(base2, base, base2, base+span+span)
	pdf.Line(base3, base, base3, base+span+span)
	pdf.Line(base4, base, base4, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	var option1 gopdf.CellOption
	option1.Align = gopdf.Middle | gopdf.Center
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "Inspection item", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base1}, "Inspection/Testing", option1)
	pdf.SetXY(base1, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base1}, "Criteria", option1)
	pdf.SetXY(base2, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, "Inspection method", option1)
	pdf.SetXY(base3, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base4 - base3}, "Inspection result", option1)
	pdf.SetXY(base4, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base4}, "Judgment", option1)
	pdf.SetXY(base5, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, "Remark", option1)
	base += span + span
	pdf.Line(margin_left, base, base6, base)

	cnt := 0
	cur_item := ""
	for i := 0; i < len(data.Inspection_data); i++ {

		v := data.Inspection_data[i]

		if v.Inspection_items_en != cur_item {

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			cnt++
			cur_item = v.Inspection_items_en

			//pdf.SetLineWidth(0.1)
			pdf.Line(base0, base, base6, base)

			pdf.Line(base0, base, base0, base+span)
			pdf.Line(base6, base, base6, base+span)

			var option1 gopdf.CellOption
			option1.Align = gopdf.Middle | gopdf.Left
			pdf.SetFont("wr", "", 13)
			pdf.SetXY(base0, base)
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, fmt.Sprintf(`%d.%s`, cnt, v.Inspection_items_en), option1)
			base += span
			pdf.Line(margin_left, base, base6, base)
		}

		pdf.SetFont("simfang", "", 14)
		var max_h int = 1
		context1, _ := pdf.SplitTextWithWordWrap(v.Inspection_rs_en, base2-base0)
		if len(context1) > int(max_h) {
			max_h = len(context1)
		}

		context2, _ := pdf.SplitTextWithWordWrap(v.Inspection_scheme_en, base3-base2)
		if len(context2) > int(max_h) {
			max_h = len(context2)
		}

		context3, _ := pdf.SplitTextWithWordWrap(v.Attach_file, base6-base5)
		fmt.Println(context3, len(context3))
		if len(context3) > int(max_h) {
			max_h = len(context3)
		}

		var context1_base float64 = (float64(max_h-len(context1))/2)*span + base
		var context2_base float64 = (float64(max_h-len(context2))/2)*span + base
		var context3_base float64 = (float64(max_h-len(context3))/2)*span + base

		if base+(float64(max_h)*span) > page_context_H {
			pdf.SetXY(page_F_x, page_F_y)
			pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
			cur_page++

			pdf.AddPage()
			base = margin_top
			pdf.SetXY(margin_left*1, base)
		} else {
			pdf.SetXY(margin_left*1, base)
		}

		//pdf.SetLineWidth(0.1)
		pdf.Line(base0, base, base6, base)

		pdf.Line(base0, base, base0, base+(float64(max_h)*span))
		pdf.Line(base2, base, base2, base+(float64(max_h)*span))
		pdf.Line(base3, base, base3, base+(float64(max_h)*span))
		pdf.Line(base4, base, base4, base+(float64(max_h)*span))
		pdf.Line(base5, base, base5, base+(float64(max_h)*span))
		pdf.Line(base6, base, base6, base+(float64(max_h)*span))

		var option1 gopdf.CellOption
		option1.Align = gopdf.Middle | gopdf.Center

		for j := 0; j < len(context1); j++ {
			pdf.SetXY(base0, context1_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base0}, context1[j], option1)
		}

		for j := 0; j < len(context2); j++ {
			pdf.SetXY(base2, context2_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, context2[j], option1)
		}

		pdf.SetXY(base3, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base4 - base3}, v.Result, option1)
		pdf.SetXY(base4, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base5 - base4}, v.If_ok, option1)

		for j := 0; j < len(context3); j++ {
			pdf.SetXY(base5, context3_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, context3[j], option1)
		}

		base += (float64(max_h) * span)
		pdf.Line(margin_left, base, base6, base)

	}

	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base0}, "Remark：□Attribute judgment, pass √, fail ×   ⊙ measurement judgment, record data.", option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base1, base, base1, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "Final judgment", option1)
	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "(pass/fail)", option1)
	pdf.SetXY(base1, base)
	if data.Fin_result == "合格" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "pass", option1)
	} else if data.Fin_result == "不合格" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "fail", option1)
	} else {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "", option1)
	}

	base += span + span
	pdf.Line(margin_left, base, base6, base)

	//不合格处理方式
	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base1, base, base1, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "Non-conformity", option1)
	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "treatment", option1)
	pdf.SetXY(base1, base)

	if data.Non_conformity_treatment == "退货或换货" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Return or Exchange", option1)
	} else if data.Non_conformity_treatment == "返工返修" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Rework and repair", option1)
	} else if data.Non_conformity_treatment == "报废" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Scrap", option1)
	} else if data.Non_conformity_treatment == "其他" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Others", option1)
	}
	base += span + span
	pdf.Line(margin_left, base, base6, base)

	//审核人
	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Inspected by：%s`, data.Inspector), option1)
	pdf.SetXY(base0+200, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Checked by：%s`, data.Auditor), option1)

	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Date：%s`, data.Time), option1)
	pdf.SetXY(base0+200, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Date：%s`, data.Time), option1)

	base += span + span
	pdf.Line(margin_left, base, base6, base)

	for i := 0; i < len(data.Inspection_data); i++ {
		v := data.Inspection_data[i]
		fmt.Println(v.Attach_file)

		index := strings.LastIndex(v.Attach_file, ".")
		if index <= 0 {
			continue
		}

		file_type := v.Attach_file[index:]
		fmt.Println(file_type)
		if file_type == ".txt" {

			fileHandle, err := os.OpenFile(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), os.O_RDONLY, 0666)
			if err != nil {
				continue
			}

			reader := bufio.NewReader(fileHandle)

			var results []string
			// 按行处理txt
			for {
				line, _, err := reader.ReadLine()
				if err == io.EOF {
					break
				}
				reader := transform.NewReader(bytes.NewReader(line), simplifiedchinese.GBK.NewDecoder())
				d, e := ioutil.ReadAll(reader)
				if e != nil {
					continue
				}
				results = append(results, string(d))
			}
			fileHandle.Close()

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`attach file：%s`, v.Attach_file))

			for k := 0; k < len(results); k++ {

				context_result, _ := pdf.SplitTextWithWordWrap(results[k], page_W-margin_left-margin_left)
				for z := 0; z < len(context_result); z++ {
					if base+span > page_context_H {
						pdf.SetXY(page_F_x, page_F_y)
						pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
						cur_page++

						pdf.AddPage()
						base = margin_top
						pdf.SetXY(margin_left*1, base)
					} else {
						pdf.SetXY(margin_left*1, base)
					}

					base += span
					pdf.SetXY(margin_left, base)

					pdf.Text(fmt.Sprintf(`%s`, context_result[z]))
				}
			}

		} else if file_type == ".jpeg" || file_type == ".png" || file_type == ".jpg" {

			base += span
			if base > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			if base+((page_H-span-span)/2) > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			pdf.Image(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), margin_left, base, &gopdf.Rect{H: (page_H - span - span) / 2, W: page_W / 2})
			base += ((page_H - span - span) / 2)

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`attach file：%s`, v.Attach_file))
		}
	}

	pdf.SetXY(page_F_x, page_F_y)
	pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))

	page_cnt = cur_page
	return
}

func create_pdf_en(data report_multi_template) {
	//W: 595, H: 842
	page_W := gopdf.PageSizeA4Landscape.W
	page_H := gopdf.PageSizeA4Landscape.H
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4Landscape})
	pdf.AddPage()
	err := pdf.AddTTFFont("simfang", "./simfang.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	err = pdf.AddTTFFont("wr", "./微软雅黑.ttf")
	if err != nil {
		logs.Error(err.Error())
		return
	}

	var margin_top float64 = 2.54 * (page_H / float64(29.7))
	var margin_left float64 = 1.91 * (page_W / float64(21))
	var span float64 = 20
	//	var h_span float64 = 150

	page_context_H := page_H - margin_top

	var one_cm float64 = page_W / float64(21)
	page_F_x := page_W/2 - (0.2 * one_cm)
	page_F_y := gopdf.PageSizeA4Landscape.H - (margin_top / 2)

	pdf.SetFont("simfang", "", 22)
	var option gopdf.CellOption
	option.Align = gopdf.Center
	pdf.SetXY(0, margin_top)
	pdf.CellWithOption(&gopdf.Rect{H: 30, W: page_W}, "Inspection Record Report", option)

	//cal total pagenum
	var cur_page int = 1
	var total_page int = 1
	total_page = get_pdf_en_pagesize(data)
	fmt.Println("报告总页码：", total_page)

	pdf.SetFont("simfang", "", 14)
	var base float64 = margin_top + 45
	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`Part Number & Part Name：%s`, data.P_name_en))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`Inspection referred document：%s`, data.P_ibase_en))

	base += span
	pdf.SetXY(margin_left, base)
	pdf.Text(fmt.Sprintf(`Inspection time：%s`, data.Time))

	base += span
	pdf.SetXY(margin_left, base)
	if data.Inspection_node == "入库" {
		pdf.Text(fmt.Sprintf(`Inspection step：In stock`))
	} else if data.Inspection_node == "出库" {
		pdf.Text(fmt.Sprintf(`Inspection step：Out of stock`))
	} else if data.Inspection_node == "退库" {
		pdf.Text(fmt.Sprintf(`Inspection step：Return to stock`))
	} else {
		pdf.Text(fmt.Sprintf(`Inspection step：`))
	}

	if base+span+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	base0 := margin_left
	base1 := margin_left + 150
	base2 := margin_left + 300
	base3 := margin_left + 450
	base4 := margin_left + 580
	base5 := margin_left + 660
	base6 := margin_left + 760

	base += span
	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)

	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base1, base, base1, base+span+span)
	pdf.Line(base2, base, base2, base+span+span)
	pdf.Line(base3, base, base3, base+span+span)
	pdf.Line(base4, base, base4, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	var option1 gopdf.CellOption
	option1.Align = gopdf.Middle | gopdf.Center
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "Inspection item", option1)
	pdf.SetXY(base1, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base1}, "Inspection/Testing", option1)
	pdf.SetXY(base1, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base1}, "Criteria", option1)
	pdf.SetXY(base2, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, "Inspection method", option1)
	pdf.SetXY(base3, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base4 - base3}, "Inspection result", option1)
	pdf.SetXY(base4, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base4}, "Judgment", option1)
	pdf.SetXY(base5, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, "Remark", option1)
	base += span + span
	pdf.Line(margin_left, base, base6, base)

	cnt := 0
	cur_item := ""
	for i := 0; i < len(data.Inspection_data); i++ {

		v := data.Inspection_data[i]

		if v.Inspection_items_en != cur_item {

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			cnt++
			cur_item = v.Inspection_items_en

			//pdf.SetLineWidth(0.1)
			pdf.Line(base0, base, base6, base)

			pdf.Line(base0, base, base0, base+span)
			pdf.Line(base6, base, base6, base+span)

			var option1 gopdf.CellOption
			option1.Align = gopdf.Middle | gopdf.Left
			pdf.SetFont("wr", "", 13)
			pdf.SetXY(base0, base)
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, fmt.Sprintf(`%d.%s`, cnt, v.Inspection_items_en), option1)
			base += span
			pdf.Line(margin_left, base, base6, base)
		}

		pdf.SetFont("simfang", "", 14)
		var max_h int = 1
		context1, _ := pdf.SplitTextWithWordWrap(v.Inspection_rs_en, base2-base0)
		if len(context1) > int(max_h) {
			max_h = len(context1)
		}

		context2, _ := pdf.SplitTextWithWordWrap(v.Inspection_scheme_en, base3-base2)
		if len(context2) > int(max_h) {
			max_h = len(context2)
		}

		context3, _ := pdf.SplitTextWithWordWrap(v.Attach_file, base6-base5)
		fmt.Println(context3, len(context3))
		if len(context3) > int(max_h) {
			max_h = len(context3)
		}

		var context1_base float64 = (float64(max_h-len(context1))/2)*span + base
		var context2_base float64 = (float64(max_h-len(context2))/2)*span + base
		var context3_base float64 = (float64(max_h-len(context3))/2)*span + base

		if base+(float64(max_h)*span) > page_context_H {
			pdf.SetXY(page_F_x, page_F_y)
			pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
			cur_page++

			pdf.AddPage()
			base = margin_top
			pdf.SetXY(margin_left*1, base)
		} else {
			pdf.SetXY(margin_left*1, base)
		}

		//pdf.SetLineWidth(0.1)
		pdf.Line(base0, base, base6, base)

		pdf.Line(base0, base, base0, base+(float64(max_h)*span))
		pdf.Line(base2, base, base2, base+(float64(max_h)*span))
		pdf.Line(base3, base, base3, base+(float64(max_h)*span))
		pdf.Line(base4, base, base4, base+(float64(max_h)*span))
		pdf.Line(base5, base, base5, base+(float64(max_h)*span))
		pdf.Line(base6, base, base6, base+(float64(max_h)*span))

		var option1 gopdf.CellOption
		option1.Align = gopdf.Middle | gopdf.Center

		for j := 0; j < len(context1); j++ {
			pdf.SetXY(base0, context1_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base2 - base0}, context1[j], option1)
		}

		for j := 0; j < len(context2); j++ {
			pdf.SetXY(base2, context2_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base3 - base2}, context2[j], option1)
		}

		pdf.SetXY(base3, base)

		var result string
		for j := 0; j < len(v.Result_contain); j++ {
			if v.Result == v.Result_contain[j].Result_cn {
				result = v.Result_contain[j].Result_en
			}
		}

		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base4 - base3}, result, option1)
		pdf.SetXY(base4, base)
		pdf.CellWithOption(&gopdf.Rect{H: float64(max_h) * span, W: base5 - base4}, v.If_ok, option1)

		for j := 0; j < len(context3); j++ {
			pdf.SetXY(base5, context3_base+(float64(j)*span))
			pdf.CellWithOption(&gopdf.Rect{H: span, W: base6 - base5}, context3[j], option1)
		}

		base += (float64(max_h) * span)
		pdf.Line(margin_left, base, base6, base)

	}

	if base+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span)
	pdf.Line(base5, base, base5, base+span)
	pdf.Line(base6, base, base6, base+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base5 - base0}, "Remark：□Attribute judgment, pass √, fail ×   ⊙ measurement judgment, record data.", option1)
	base += span
	pdf.Line(margin_left, base, base6, base)

	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base1, base, base1, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "Final judgment", option1)
	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "(pass/fail)", option1)
	pdf.SetXY(base1, base)
	if data.Fin_result == "合格" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "pass", option1)
	} else if data.Fin_result == "不合格" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "fail", option1)
	} else {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "", option1)
	}

	base += span + span
	pdf.Line(margin_left, base, base6, base)

	//不合格处理方式
	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base1, base, base1, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	option1.Align = gopdf.Middle | gopdf.Left
	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "Non-conformity", option1)
	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: base1 - base0}, "treatment", option1)
	pdf.SetXY(base1, base)

	if data.Non_conformity_treatment == "退货或换货" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Return or Exchange", option1)
	} else if data.Non_conformity_treatment == "返工返修" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Rework and repair", option1)
	} else if data.Non_conformity_treatment == "报废" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Scrap", option1)
	} else if data.Non_conformity_treatment == "其他" {
		pdf.CellWithOption(&gopdf.Rect{H: 2 * span, W: base5 - base1}, "Others", option1)
	}
	base += span + span
	pdf.Line(margin_left, base, base6, base)

	//审核人
	if base+span+span > page_context_H {
		pdf.SetXY(page_F_x, page_F_y)
		pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
		cur_page++

		pdf.AddPage()
		base = margin_top
		pdf.SetXY(margin_left*1, base)
	} else {
		pdf.SetXY(margin_left*1, base)
	}

	pdf.SetLineWidth(0.1)
	pdf.Line(base0, base, base6, base)
	pdf.Line(base0, base, base0, base+span+span)
	pdf.Line(base5, base, base5, base+span+span)
	pdf.Line(base6, base, base6, base+span+span)

	pdf.SetXY(base0, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Inspected by：%s`, data.Inspector), option1)
	pdf.SetXY(base0+200, base)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Checked by：%s`, data.Auditor), option1)

	pdf.SetXY(base0, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Date：%s`, data.Time), option1)
	pdf.SetXY(base0+200, base+span)
	pdf.CellWithOption(&gopdf.Rect{H: span, W: 200}, fmt.Sprintf(`Date：%s`, data.Audit_time), option1)

	base += span + span
	pdf.Line(margin_left, base, base6, base)

	for i := 0; i < len(data.Inspection_data); i++ {
		v := data.Inspection_data[i]
		fmt.Println(v.Attach_file)

		index := strings.LastIndex(v.Attach_file, ".")
		if index <= 0 {
			continue
		}

		file_type := v.Attach_file[index:]
		fmt.Println(file_type)
		if file_type == ".txt" {

			fileHandle, err := os.OpenFile(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), os.O_RDONLY, 0666)
			if err != nil {
				continue
			}

			reader := bufio.NewReader(fileHandle)

			var results []string
			// 按行处理txt
			for {
				line, _, err := reader.ReadLine()
				if err == io.EOF {
					break
				}
				reader := transform.NewReader(bytes.NewReader(line), simplifiedchinese.GBK.NewDecoder())
				d, e := ioutil.ReadAll(reader)
				if e != nil {
					continue
				}
				results = append(results, string(d))
			}
			fileHandle.Close()

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`attach file：%s`, v.Attach_file))

			for k := 0; k < len(results); k++ {

				context_result, _ := pdf.SplitTextWithWordWrap(results[k], page_W-margin_left-margin_left)
				for z := 0; z < len(context_result); z++ {
					if base+span > page_context_H {
						pdf.SetXY(page_F_x, page_F_y)
						pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
						cur_page++

						pdf.AddPage()
						base = margin_top
						pdf.SetXY(margin_left*1, base)
					} else {
						pdf.SetXY(margin_left*1, base)
					}

					base += span
					pdf.SetXY(margin_left, base)

					pdf.Text(fmt.Sprintf(`%s`, context_result[z]))
				}
			}

		} else if file_type == ".jpeg" || file_type == ".png" || file_type == ".jpg" {
			base += span
			if base > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			if base+((page_H-span-span)/2) > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			pdf.Image(fmt.Sprintf(`./upload_report/%s`, v.Attach_file), margin_left, base, &gopdf.Rect{H: (page_H - span - span) / 2, W: page_W / 2})
			base += ((page_H - span - span) / 2)

			if base+span > page_context_H {
				pdf.SetXY(page_F_x, page_F_y)
				pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))
				cur_page++

				pdf.AddPage()
				base = margin_top
				pdf.SetXY(margin_left*1, base)
			} else {
				pdf.SetXY(margin_left*1, base)
			}

			base += span
			pdf.SetXY(margin_left, base)
			pdf.Text(fmt.Sprintf(`attach file：%s`, v.Attach_file))
		}
	}

	pdf.SetXY(page_F_x, page_F_y)
	pdf.Text(fmt.Sprintf(`%v/%v`, cur_page, total_page))

	//save
	beginTime := time.Now().UnixNano()
	pdf.WritePdf(fmt.Sprintf(`./upload_report_file/%v.pdf`, beginTime))

	update_report_file(data, "", fmt.Sprintf(`%v.pdf`, beginTime))

	//filename := strconv.FormatInt(beginTime, 10)
	return
}

func create_pdf_g() {

	for {
		select {
		case v := <-g_report_data:
			create_pdf_cn(v)
			create_pdf_en(v)
		default:
			time.Sleep(time.Second * 1)
		}
	}
}

func update_report_file(data report_multi_template, file string, file_en string) {

	var err error
	if file != "" {
		sqlstr := fmt.Sprintf(`UPDATE [inspection_report] SET [file] ='%s' where [p_name] ='%s' and [serial] = '%s'`,
			file, data.P_name_cn, data.Serial_sets)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_report_file Exec Error:", err.Error())
		}
	}

	if file_en != "" {
		sqlstr := fmt.Sprintf(`UPDATE [inspection_report] SET [file_en] ='%s' where [p_name] ='%s' and [serial] = '%s'`,
			file_en, data.P_name_cn, data.Serial_sets)
		fmt.Println(sqlstr)

		_, err = sqlConn.Exec(sqlstr)
		if err != nil {
			logs.Info("update_report_file Exec Error:", err.Error())
		}
	}

}

//上传文件
func upload_report_file(w http.ResponseWriter, r *http.Request) {
	beginTime := time.Now().UnixNano()
	logs.Info("upload_report_file recv req begin", time.Now().Format("2006-01-02 15:04:05"))

	var resp upload_reportfile_resp
	var f *os.File
	var err error

	//var rdRow *sql.Rows
	//var d plan_file

	//	var sqlstr string

	//配置文件读取
	base_file_path := modelePath + "/upload_report/"

	r.ParseMultipartForm(32 << 20)

	resp.Inspection_items_cn = r.Form.Get("inspection_items_cn")
	resp.Inspection_rs_cn = r.Form.Get("inspection_rs_cn")

	//读取文件信息
	file, handler, err := r.FormFile("file")
	if err != nil {
		fmt.Println(err)
		resp.Ret = -1
		goto exit
	}
	defer file.Close()
	fmt.Println(handler.Filename)
	resp.File = handler.Filename
	logs.Info(base_file_path + handler.Filename)
	if handler.Filename == "" {
		resp.Ret = -1
		goto exit
	}
	os.Remove(base_file_path + handler.Filename)
	f, err = os.OpenFile(base_file_path+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println(err)
		goto exit
	}
	defer f.Close()
	io.Copy(f, file)

	resp.Ret = 0

exit:
	jdata, _ := json.Marshal(resp)
	fmt.Fprintln(w, string(jdata))

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

}

func download_report_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 + "/upload_report_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)
	}

}
