소스 검색

add:采购管理添加导出接口

zoie 2 일 전
부모
커밋
3592574909
5개의 변경된 파일501개의 추가작업 그리고 42개의 파일을 삭제
  1. 336 0
      controllers/Purchase.go
  2. 32 8
      controllers/Validation.go
  3. 97 23
      models/Purchase/Purchase.go
  4. 28 6
      models/validationtool/validationHistory.go
  5. 8 5
      routers/Purchase.go

+ 336 - 0
controllers/Purchase.go

@@ -3,14 +3,19 @@ package controllers
 import (
 	"ERP_storage/Nats/NatsServer"
 	"ERP_storage/conf"
+	"ERP_storage/logs"
 	"ERP_storage/models/Account"
 	"ERP_storage/models/Purchase"
 	"fmt"
 	"github.com/beego/beego/v2/adapter/orm"
 	beego "github.com/beego/beego/v2/server/web"
+	"github.com/xuri/excelize/v2"
 	userlibs "gogs.baozhida.cn/zoie/ERP_libs/User"
 	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"math"
+	"net/url"
+	"os"
+	"time"
 )
 
 type PurchaseController struct {
@@ -270,6 +275,9 @@ func (c *PurchaseController) Purchase_Edit() {
 		clos = append(clos, "T_approver")
 	}
 	if T_State > 0 {
+		if T_State == Purchase.NotPass {
+			T_State = Purchase.WaitAudit
+		}
 		purchase.T_State = T_State
 		clos = append(clos, "T_State")
 	}
@@ -320,3 +328,331 @@ func (c *PurchaseController) Purchase_Del() {
 	c.ServeJSON()
 	return
 }
+
+// 下载采购申请
+func (c *PurchaseController) Purchase_Excel() {
+
+	T_id, _ := c.GetInt("T_id")
+
+	o := orm.NewOrm()
+	PurchaseDao := Purchase.NewPurchase(o)
+	purchase, err := PurchaseDao.Read_Purchase_ById(T_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+	detail := Purchase.PurchaseToPurchase_Detail(purchase)
+
+	f := excelize.NewFile() //设置单元格值
+	// 这里设置表头ÒÒ
+	Style1, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 16, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+	Style2, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 15, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "left", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+	Style3, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 13, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+	Style4, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 13, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+
+	f.MergeCell("Sheet1", "A1", "I1")
+	f.SetCellValue("Sheet1", "A1", fmt.Sprintf("%d宝智达冷链采购申请", time.Now().Year()))
+	f.SetCellStyle("Sheet1", "A1", "I1", Style1)
+
+	f.MergeCell("Sheet1", "A2", "E2")
+	date, _ := lib.DateStrToTime(detail.T_date)
+	f.SetCellValue("Sheet1", "A2", fmt.Sprintf("申请时间:%s", date.Format("2006年01月02日")))
+	f.MergeCell("Sheet1", "F2", "I2")
+	f.SetCellValue("Sheet1", "F2", fmt.Sprintf("申请人:%-10s负责人审批:", detail.T_uuid_name))
+
+	f.MergeCell("Sheet1", "A3", "E3")
+	f.SetCellValue("Sheet1", "A3", "执行时间:")
+	f.MergeCell("Sheet1", "F3", "I3")
+	f.SetCellValue("Sheet1", "F3", fmt.Sprintf("执行部门:%-15s执行人:", ""))
+
+	f.MergeCell("Sheet1", "A4", "E4")
+	f.SetCellValue("Sheet1", "A4", fmt.Sprintf("审批人:%s", detail.T_approver_name))
+	f.MergeCell("Sheet1", "F4", "I4")
+	approver_date := ""
+	if len(detail.T_approver_date) > 0 {
+		date2, _ := lib.DateStrToTime(detail.T_approver_date)
+		approver_date = date2.Format("2006年01月02日")
+	}
+	f.SetCellValue("Sheet1", "F4", fmt.Sprintf("审批时间:%s", approver_date))
+
+	f.SetCellStyle("Sheet1", "A2", "I4", Style2)
+	f.SetRowHeight("Sheet1", 1, 40)
+	height := 30.0
+	f.SetRowHeight("Sheet1", 2, height)
+	f.SetRowHeight("Sheet1", 3, height)
+	f.SetRowHeight("Sheet1", 4, height)
+	f.SetRowHeight("Sheet1", 5, height)
+
+	f.MergeCell("Sheet1", "A5", "I5")
+	f.SetCellValue("Sheet1", "A5", "申请采购明细")
+	f.SetCellStyle("Sheet1", "A5", "I5", Style1)
+
+	f.SetCellValue("Sheet1", "A6", "序号")
+	f.SetCellValue("Sheet1", "B6", "名称")
+	f.SetCellValue("Sheet1", "C6", "型号")
+	f.SetCellValue("Sheet1", "D6", "规格")
+	f.SetCellValue("Sheet1", "E6", "数量")
+	f.SetCellValue("Sheet1", "F6", "参考网址")
+	f.SetCellValue("Sheet1", "G6", "需求")
+	f.SetCellValue("Sheet1", "H6", "备注")
+	f.SetCellValue("Sheet1", "I6", "采购金额")
+	// 这里设置表头
+	f.SetCellStyle("Sheet1", "A6", "H6", Style3)
+	f.SetRowHeight("Sheet1", 2, 25)
+
+	// 设置列宽
+	f.SetColWidth("Sheet1", "A", "A", 6)
+	f.SetColWidth("Sheet1", "B", "B", 12)
+	f.SetColWidth("Sheet1", "C", "C", 10)
+	f.SetColWidth("Sheet1", "D", "D", 10)
+	f.SetColWidth("Sheet1", "E", "E", 6)
+	f.SetColWidth("Sheet1", "F", "F", 30)
+	f.SetColWidth("Sheet1", "G", "G", 12)
+	f.SetColWidth("Sheet1", "H", "H", 15)
+	f.SetColWidth("Sheet1", "I", "I", 15)
+
+	line := 6
+	for i, v := range detail.T_Detail {
+		line++
+		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
+		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), v.T_name)
+		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.T_model)
+		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.T_spec)
+		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.T_quantity)
+		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.T_reference_site)
+		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.T_demand)
+		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), v.T_remark)
+		f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), fmt.Sprintf("%.2f", v.T_unit_price*float32(v.T_quantity)))
+	}
+	line++
+	f.MergeCell("Sheet1", fmt.Sprintf("A%d", line), fmt.Sprintf("H%d", line))
+	f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), "合计")
+	f.SetCellFormula("Sheet1", fmt.Sprintf("I%d", line), fmt.Sprintf("SUM(I7:I%d)", line-1))
+	f.SetCellStyle("Sheet1", "A6", fmt.Sprintf("I%d", line), Style4)
+
+	timeStr := time.Now().Format("20060102150405")
+	fileName := fmt.Sprintf("%d宝智达冷链采购申请%v.xlsx", time.Now().Year(), timeStr)
+	filePath := "ofile/" + fileName
+	// 保存文件
+	if err = f.SaveAs(filePath); err != nil {
+		logs.Error("保存文件失败:", err)
+	}
+	defer func() {
+		os.Remove(filePath)
+	}()
+	c.Ctx.Output.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
+	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
+	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
+	c.Ctx.Output.Download(filePath, fileName)
+}
+
+// 下载采购统计
+func (c *PurchaseController) Purchase_Stat_Excel() {
+
+	T_uuid := c.GetString("T_uuid")
+	T_dept := c.GetString("T_dept")
+
+	T_start_date := c.GetString("T_start_date") // 开始时间
+	T_end_date := c.GetString("T_end_date")     // 结束时间
+
+	T_state, _ := c.GetInt("T_state")
+
+	userList, _ := NatsServer.Read_User_List_All()
+	Account.Read_User_All_Map(userList)
+
+	PurchaseDao := Purchase.NewPurchase(orm.NewOrm())
+	R_List, _ := PurchaseDao.Read_Purchase_Stat(T_dept, T_uuid, "", T_state, true, T_start_date, T_end_date, 0, 9999)
+
+	f := excelize.NewFile() //设置单元格值
+	// 这里设置表头ÒÒ
+	Style1, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 20, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		})
+	Style2, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 15, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+			Fill: excelize.Fill{Type: "pattern", Color: []string{"D9D9D9"}, Pattern: 1},
+		})
+	Style3, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 15, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+
+	f.MergeCell("Sheet1", "A1", "M1")
+	f.SetCellValue("Sheet1", "A1", "资金一览表")
+	f.SetCellStyle("Sheet1", "A1", "I1", Style1)
+
+	// 写入表头
+	headers := []string{"序号", "采购物品", "规格", "单价", "数量", "实际金额", "合计金额", "用途", "采购申请人", "采购申请时间", "是否已有发票", "报销上报时间", "备注"}
+	for col, header := range headers {
+		cell := fmt.Sprintf("%c%d", rune('A'+col), 2)
+		f.SetCellValue("Sheet1", cell, header)
+	}
+	// 这里设置表头
+	f.SetCellStyle("Sheet1", "A2", "M2", Style2)
+	f.SetRowHeight("Sheet1", 2, 25)
+
+	colsWidth := []float64{6, 12, 10, 10, 6, 30, 12, 15, 15, 15, 15, 15, 15}
+
+	for col, width := range colsWidth {
+		cell := fmt.Sprintf("%c", rune('A'+col))
+		f.SetColWidth("Sheet1", cell, cell, width)
+	}
+	line := 2
+	for i, purchase := range R_List {
+		// 写入数据
+		startRow := line + 1
+		for _, v := range purchase.T_Detail {
+			line++
+			f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
+			f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), v.T_name)
+			f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), v.T_model)
+			f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.T_unit_price)
+			f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.T_quantity)
+			f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.T_amount)
+			if len(purchase.T_Detail) == 1 {
+				f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.T_amount)
+				f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), purchase.T_uuid_name)
+				f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), purchase.T_date)
+				f.SetCellValue("Sheet1", fmt.Sprintf("M%d", line), purchase.T_remark)
+			}
+		}
+		if len(purchase.T_Detail) > 1 {
+
+			f.MergeCell("Sheet1", fmt.Sprintf("G%d", startRow), fmt.Sprintf("G%d", line))
+			f.SetCellFormula("Sheet1", fmt.Sprintf("G%d", startRow), fmt.Sprintf("SUM(F%d:F%d)", startRow, line))
+
+			f.MergeCell("Sheet1", fmt.Sprintf("I%d", startRow), fmt.Sprintf("I%d", line))
+			f.SetCellValue("Sheet1", fmt.Sprintf("I%d", startRow), purchase.T_uuid_name)
+
+			f.MergeCell("Sheet1", fmt.Sprintf("J%d", startRow), fmt.Sprintf("J%d", line))
+			f.SetCellValue("Sheet1", fmt.Sprintf("J%d", startRow), purchase.T_date)
+
+			f.MergeCell("Sheet1", fmt.Sprintf("M%d", startRow), fmt.Sprintf("M%d", line))
+			f.SetCellValue("Sheet1", fmt.Sprintf("M%d", startRow), purchase.T_remark)
+		}
+
+	}
+
+	f.SetCellStyle("Sheet1", "A3", fmt.Sprintf("M%d", line), Style3)
+
+	timeStr := time.Now().Format("20060102150405")
+	fileName := fmt.Sprintf("%d资金一览表%v.xlsx", time.Now().Year(), timeStr)
+	filePath := "ofile/" + fileName
+	// 保存文件
+	if err := f.SaveAs(filePath); err != nil {
+		logs.Error("保存文件失败:", err)
+	}
+	defer func() {
+		os.Remove(filePath)
+	}()
+	c.Ctx.Output.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
+	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))
+	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
+	c.Ctx.Output.Download(filePath, fileName)
+}
+
+func (c *PurchaseController) User_List() {
+	var r_jsons lib.R_JSONS
+	// 分页参数 初始化
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	T_name := c.GetString("T_name")
+
+	PurchaseDao := Purchase.NewPurchase(orm.NewOrm())
+
+	uuidList := PurchaseDao.Read_T_uuid_List()
+	if len(uuidList) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+		c.ServeJSON()
+		return
+	}
+
+	R_List, R_cnt, err := NatsServer.Read_User_List_T_uuid(T_name, uuidList, page, page_z)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败"}
+		c.ServeJSON()
+		return
+	}
+
+	var U_List []userlibs.User
+	for _, user := range R_List {
+		U_List = append(U_List, user)
+	}
+
+	r_jsons.Num = R_cnt
+	r_jsons.Data = U_List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}

+ 32 - 8
controllers/Validation.go

@@ -855,9 +855,11 @@ func (c *ValidationController) Operation_Excel() {
 	f.SetCellValue("Sheet1", "E1", "关联项目")
 	f.SetCellValue("Sheet1", "F1", "备注")
 	f.SetCellValue("Sheet1", "G1", "设备数量")
-	f.SetCellValue("Sheet1", "H1", "SN")
+	f.SetCellValue("Sheet1", "H1", "SN关联项目")
+	f.SetCellValue("Sheet1", "I1", "SN数量")
+	f.SetCellValue("Sheet1", "J1", "SN")
 	// 这里设置表头
-	f.SetCellStyle("Sheet1", "A1", "H1", Style2)
+	f.SetCellStyle("Sheet1", "A1", "J1", Style2)
 	f.SetRowHeight("Sheet1", 2, 20)
 
 	// 设置列宽
@@ -868,12 +870,29 @@ func (c *ValidationController) Operation_Excel() {
 	f.SetColWidth("Sheet1", "E", "E", 20)
 	f.SetColWidth("Sheet1", "F", "F", 20)
 	f.SetColWidth("Sheet1", "G", "G", 12)
-	f.SetColWidth("Sheet1", "H", "H", 15)
+	f.SetColWidth("Sheet1", "H", "H", 20)
+	f.SetColWidth("Sheet1", "I", "I", 15)
+	f.SetColWidth("Sheet1", "J", "J", 15)
 
 	line := 1
 	for i, v := range R_List {
-		line++
+		startRow := line + 1
+		for _, sn := range v.T_sn_List {
+			startRow2 := line + 1
+			for _, v2 := range sn.T_sn {
+				line++
+				f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), v2)
+			}
+			f.MergeCell("Sheet1", fmt.Sprintf("H%d", startRow2), fmt.Sprintf("H%d", line))
+			f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), sn.T_project)
+			f.MergeCell("Sheet1", fmt.Sprintf("I%d", startRow2), fmt.Sprintf("I%d", line))
+			f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), len(sn.T_sn))
+		}
+
+		f.MergeCell("Sheet1", fmt.Sprintf("A%d", startRow), fmt.Sprintf("A%d", line))
 		f.SetCellValue("Sheet1", fmt.Sprintf("A%d", line), i+1)
+
+		f.MergeCell("Sheet1", fmt.Sprintf("B%d", startRow), fmt.Sprintf("B%d", line))
 		f.SetCellValue("Sheet1", fmt.Sprintf("B%d", line), v.BatchNumber)
 
 		var state string
@@ -890,15 +909,20 @@ func (c *ValidationController) Operation_Excel() {
 			state = "损坏"
 
 		}
+		f.MergeCell("Sheet1", fmt.Sprintf("C%d", startRow), fmt.Sprintf("C%d", line))
 		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), state)
+		f.MergeCell("Sheet1", fmt.Sprintf("D%d", startRow), fmt.Sprintf("D%d", line))
 		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), v.LendUser)
-		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), v.T_project)
+		f.MergeCell("Sheet1", fmt.Sprintf("E%d", startRow), fmt.Sprintf("E%d", line))
+		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), strings.Join(v.T_project, "\r\n"))
+		f.MergeCell("Sheet1", fmt.Sprintf("F%d", startRow), fmt.Sprintf("F%d", line))
 		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), v.T_remark)
-		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), len(v.T_sn_List))
-		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), strings.Join(v.T_sn_List, "\r\n"))
+		f.MergeCell("Sheet1", fmt.Sprintf("G%d", startRow), fmt.Sprintf("G%d", line))
+		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), v.T_sn_quantity)
+
 	}
 
-	f.SetCellStyle("Sheet1", "A2", fmt.Sprintf("H%d", line), Style4)
+	f.SetCellStyle("Sheet1", "A2", fmt.Sprintf("J%d", line), Style4)
 
 	timeStr := time.Now().Format("20060102150405")
 	fileName := fmt.Sprintf("验证工具操作记录表%v.xlsx", timeStr)

+ 97 - 23
models/Purchase/Purchase.go

@@ -70,17 +70,17 @@ type Purchase_R struct {
 }
 
 type PurchaseDetail_R struct {
-	T_name           string // 名称
-	T_model          string // 型号
-	T_spec           string // 规格
-	T_quantity       int    // 数量
-	T_demand         string // 需求
-	T_remark         string // 备注
-	T_state          int    // 状态
-	T_date           string // 采购时间
-	T_unit_price     string // 采购单价
-	T_amount         string // 采购金额
-	T_reference_site string // 参考网址
+	T_name           string  // 名称
+	T_model          string  // 型号
+	T_spec           string  // 规格
+	T_quantity       int     // 数量
+	T_demand         string  // 需求
+	T_remark         string  // 备注
+	T_state          int     // 状态
+	T_date           string  // 采购时间
+	T_unit_price     float32 // 采购单价
+	T_amount         string  // 采购金额
+	T_reference_site string  // 参考网址
 }
 type Purchase_Detail struct {
 	Id              int
@@ -164,7 +164,7 @@ func PurchaseToPurchaseDetail(T_detail string) (r []PurchaseDetail_R) {
 			T_remark:         T_remark,
 			T_state:          lib.To_int(T_state),
 			T_date:           T_date,
-			T_unit_price:     T_unit_price,
+			T_unit_price:     lib.To_float32(T_unit_price),
 			T_amount:         T_amount,
 			T_reference_site: T_reference_site,
 		})
@@ -235,42 +235,42 @@ func (dao *PurchaseDaoImpl) Read_Purchase_List(T_dept, T_uid, T_approver string,
 	}
 
 	cond := orm.NewCondition()
-	cond = cond.And("T_State__gt", Delete)
+	cond1 := cond.And("T_State__gt", Delete)
 	if isManager {
-		cond = cond.And("T_State__in", []int{WaitPurchase, PurchaseCompleted})
+		cond1 = cond1.And("T_State__in", []int{WaitPurchase, PurchaseCompleted})
 	}
 	if len(T_uid) > 0 {
-		cond = cond.AndCond(cond.Or("T_uuid", T_uid).Or("T_submit", T_uid))
+		cond1 = cond1.AndCond(cond.Or("T_uuid", T_uid).Or("T_submit", T_uid))
 	}
 	// 审批人
 	if len(T_dept) > 0 {
-		cond = cond.And("T_dept__icontains", T_dept)
+		cond1 = cond1.And("T_dept__icontains", T_dept)
 	}
 	if len(T_approver) > 0 {
-		cond = cond.And("T_approver", T_approver)
+		cond1 = cond1.And("T_approver", T_approver)
 	}
 	if T_state > 0 {
-		cond = cond.And("T_state", T_state)
+		cond1 = cond1.And("T_state", T_state)
 	}
 	if len(T_start_date) > 0 {
-		cond = cond.And("T_date__gte", T_start_date)
+		cond1 = cond1.And("T_date__gte", T_start_date)
 	}
 
 	if len(T_start_date) > 0 {
-		cond = cond.And("T_date__lte", T_end_date)
+		cond1 = cond1.And("T_date__lte", T_end_date)
 	}
 	var err error
 	if page_z == 9999 {
-		_, err = qs.SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&map_r)
+		_, err = qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
 	} else {
-		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&map_r)
+		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
 	}
 
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 		return
 	}
-	cnt, err = qs.SetCond((*orm2.Condition)(cond)).Count()
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 		return
@@ -283,3 +283,77 @@ func (dao *PurchaseDaoImpl) Read_Purchase_List(T_dept, T_uid, T_approver string,
 	return r, cnt
 
 }
+func (dao *PurchaseDaoImpl) Read_Purchase_Stat(T_dept, T_uid, T_approver string, T_state int, isManager bool, T_start_date, T_end_date string, page, page_z int) (r []Purchase_Detail, cnt int64) {
+
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	var map_r []Purchase
+	qs := o.QueryTable(new(Purchase))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_State__gt", Delete)
+	if isManager {
+		cond = cond.And("T_State__in", []int{WaitPurchase, PurchaseCompleted})
+	}
+	if len(T_uid) > 0 {
+		cond1 = cond1.AndCond(cond.Or("T_uuid", T_uid).Or("T_submit", T_uid))
+	}
+	// 审批人
+	if len(T_dept) > 0 {
+		cond1 = cond1.And("T_dept__icontains", T_dept)
+	}
+	if len(T_approver) > 0 {
+		cond1 = cond1.And("T_approver", T_approver)
+	}
+	if T_state > 0 {
+		cond1 = cond1.And("T_state", T_state)
+	}
+	if len(T_start_date) > 0 {
+		cond1 = cond1.And("T_date__gte", T_start_date)
+	}
+
+	if len(T_start_date) > 0 {
+		cond1 = cond1.And("T_date__lte", T_end_date)
+	}
+	var err error
+	if page_z == 9999 {
+		_, err = qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+	} else {
+		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&map_r)
+	}
+
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range map_r {
+		r = append(r, PurchaseToPurchase_Detail(v))
+	}
+
+	return r, cnt
+
+}
+
+func (dao *PurchaseDaoImpl) Read_T_uuid_List() (lists []string) {
+
+	o := orm.NewOrm()
+	sql := "SELECT DISTINCT t_uuid FROM purchase WHERE t_state in (1,2) LIMIT 0,1000"
+	_, err := o.Raw(sql).QueryRows(&lists)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+	return lists
+}

+ 28 - 6
models/validationtool/validationHistory.go

@@ -58,15 +58,22 @@ type ValidationToolHistory_R2 struct {
 	History_imei     string   //  历史模组
 	T_state          int      //  1-已出库 2-待使用(已入库)  3-维修中 4-已报废
 	T_remark         string   //  备注r
-	T_project        string   //  出库项目
+	T_project        []string //  出库项目
 	T_uuid           string   //	用户uuid
 	LendUser         string   //	借出用户
 	BatchNumber      string   //	批号
-	T_sn_List        []string //	批号
+	T_sn_List        []SN_R2  //	批号
+	T_sn_quantity    int      //	批号
 	CreateTime       string   //	auto_now_add 第一次保存时才设置时间
 	UpdateTime       string   //	auto_now 每次 model 保存时都会对时间自动更新
 }
 
+type SN_R2 struct {
+	T_project string   //  出库项目
+	T_sn      []string //	批号
+
+}
+
 func ValidationToolHistoryToValidationToolHistory_R(t ValidationToolHistory) (r ValidationToolHistory_R) {
 	r.Id = t.Id
 	r.T_class = t.T_class
@@ -86,6 +93,10 @@ func ValidationToolHistoryToValidationToolHistory_R(t ValidationToolHistory) (r
 	return r
 }
 func ValidationToolHistoryToValidationToolHistory_R2(t ValidationToolHistory) (r ValidationToolHistory_R2) {
+	r.T_project, r.T_sn_List = ReadSNANDProjectListBytBatchNumber(t.BatchNumber)
+	for _, v := range r.T_sn_List {
+		r.T_sn_quantity += len(v.T_sn)
+	}
 	r.Id = t.Id
 	r.T_class = t.T_class
 	r.Validationnumber = t.Validationnumber
@@ -96,11 +107,9 @@ func ValidationToolHistoryToValidationToolHistory_R2(t ValidationToolHistory) (r
 	r.History_imei = t.History_imei
 	r.T_state = t.T_state
 	r.T_remark = t.T_remark
-	r.T_project = t.T_project
 	r.T_uuid = t.T_uuid
 	r.LendUser = t.LendUser
 	r.BatchNumber = t.BatchNumber
-	r.T_sn_List = ReadSNListBytBatchNumber(t.BatchNumber)
 	r.CreateTime = t.CreateTime.Format("2006-01-02 15:04:05")
 	r.UpdateTime = t.UpdateTime.Format("2006-01-02 15:04:05")
 	return r
@@ -147,7 +156,7 @@ func (dao *ValidationToolRecordImpl) ADD(r ValidationTool, BatchNumber string) (
 	return id, err
 
 }
-func ReadSNListBytBatchNumber(BatchNumber string) (r []string) {
+func ReadSNANDProjectListBytBatchNumber(BatchNumber string) (project []string, sn []SN_R2) {
 	o := orm.NewOrm()
 	qs := o.QueryTable(new(ValidationToolHistory))
 	var maps []ValidationToolHistory
@@ -155,9 +164,22 @@ func ReadSNListBytBatchNumber(BatchNumber string) (r []string) {
 	if err != nil {
 		logs.Error(lib.FuncName(), err)
 	}
+	snMaps := make(map[string][]string)
 	for _, v := range maps {
-		r = append(r, v.T_sn)
+		if _, ok := snMaps[v.T_project]; !ok {
+			snMaps[v.T_project] = []string{v.T_sn}
+		} else {
+			snMaps[v.T_project] = append(snMaps[v.T_project], v.T_sn)
+		}
+	}
+	for s, snList := range snMaps {
+		project = append(project, s)
+		sn = append(sn, SN_R2{
+			T_project: s,
+			T_sn:      snList,
+		})
 	}
+
 	return
 }
 

+ 8 - 5
routers/Purchase.go

@@ -11,11 +11,14 @@ func init() {
 		beego.NSRouter("/List", &controllers.PurchaseController{}, "*:Purchase_List"),             // 管理员列表
 		beego.NSRouter("/Audit_List", &controllers.PurchaseController{}, "*:Purchase_Audit_List"), // 管理员列表
 		beego.NSRouter("/User_list", &controllers.PurchaseController{}, "*:Purchase_User_List"),   // 用户列表
-		beego.NSRouter("/Add", &controllers.PurchaseController{}, "*:Purchase_Add"),               // 添加项目
-		beego.NSRouter("/Get", &controllers.PurchaseController{}, "*:Purchase_Get"),               // 项目详情
-		beego.NSRouter("/Edit", &controllers.PurchaseController{}, "*:Purchase_Edit"),             // 修改项目
-		beego.NSRouter("/Approval", &controllers.PurchaseController{}, "*:Purchase_Approval"),     // 项目审批
-		beego.NSRouter("/Del", &controllers.PurchaseController{}, "*:Purchase_Del"),               // 删除项目
+		beego.NSRouter("/Add", &controllers.PurchaseController{}, "*:Purchase_Add"),               // 添加采购
+		beego.NSRouter("/Get", &controllers.PurchaseController{}, "*:Purchase_Get"),               // 采购详情
+		beego.NSRouter("/Edit", &controllers.PurchaseController{}, "*:Purchase_Edit"),             // 修改采购
+		beego.NSRouter("/Approval", &controllers.PurchaseController{}, "*:Purchase_Approval"),     // 采购审批
+		beego.NSRouter("/Del", &controllers.PurchaseController{}, "*:Purchase_Del"),               // 删除采购
+		beego.NSRouter("/Excel", &controllers.PurchaseController{}, "*:Purchase_Excel"),           // 导出采购
+		beego.NSRouter("/Stat_Excel", &controllers.PurchaseController{}, "*:Purchase_Stat_Excel"), // 采购统计表格
+		beego.NSRouter("/User/list", &controllers.PurchaseController{}, "*:User_List"),            // 采购统计表格
 	)
 	beego.AddNamespace(Purchase)
 }