This commit is contained in:
Simmons 2024-08-30 16:27:39 +08:00
parent 513e40b769
commit 7c7a17733a
38 changed files with 7998 additions and 1269 deletions

View File

@ -150,6 +150,24 @@ func (S *TestService) CPMap(c *gin.Context) {
response.OkWithData(res, c) response.OkWithData(res, c)
} }
// @Tags 数据分析平台
// @Summary CP All Map图
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CPMap true "CP Map图"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/cpMap/all [post]
func (S *TestService) AllCPMap(c *gin.Context) {
r := request.CPMap{}
_ = c.ShouldBind(&r)
if msg, ok := utils.ValidateInfo2CN(r); !ok {
response.FailWithMessage(msg, c)
return
}
response.OkWithData(test_data.AllCPMap(&r), c)
}
// @Tags 数据分析平台 // @Tags 数据分析平台
// @Summary 导出CP Map图 // @Summary 导出CP Map图
// @Security ApiKeyAuth // @Security ApiKeyAuth

View File

@ -2,6 +2,9 @@ package test_data
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gorm.io/gorm"
"testData/global"
"testData/model"
"testData/model/response" "testData/model/response"
test_data "testData/repository/test.data" test_data "testData/repository/test.data"
"testData/request" "testData/request"
@ -12,10 +15,15 @@ type IFinalReportExcelInterface struct {
} }
type SFinalReportExcelService struct { type SFinalReportExcelService struct {
DB *gorm.DB
} }
func InitFinalReportExcelService() *SFinalReportExcelService { func InitFinalReportExcelService() *SFinalReportExcelService {
return &SFinalReportExcelService{} db := global.PostGreSQL
_ = db.AutoMigrate(&model.FinalReportExcel{})
return &SFinalReportExcelService{
DB: db,
}
} }
// @Tags 数据分析平台 // @Tags 数据分析平台

View File

@ -16,7 +16,9 @@ type IReportListService interface {
type ReportListService struct{} type ReportListService struct{}
func InitReportService() *ReportListService { func InitReportService() *ReportListService {
global.PostGreSQL.AutoMigrate(&model.Report{}, &model.FinalReport{}, &model.ReportSites{}, &model.BinFail{}) global.PostGreSQL.AutoMigrate(&model.Report{}, &model.FinalReport{}, &model.ReportSites{}, &model.BinFail{},
&model.WaferList{}, &model.WaferStock{}, &model.ABList{}, &model.ABListStock{}, &model.BPList{}, &model.BPListStock{},
&model.TRList{}, &model.TRListStock{}, &model.CPList{}, &model.CPListStock{}, &model.FTList{}, &model.FTListStock{})
return &ReportListService{} return &ReportListService{}
} }
@ -35,7 +37,79 @@ func (S *ReportListService) WaferList(c *gin.Context) {
response.FailWithMessage(msg, c) response.FailWithMessage(msg, c)
return return
} }
response.OkWithData(test_data.WaferList(&r), c) waferList, total := test_data.WaferList(&r)
response.OkWithData(gin.H{"wafer_list": waferList, "total": total}, c)
}
// @Tags 数据分析平台-生产
// @Summary 封装记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.ABList true "查询参数"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/ab [post]
func (S *ReportListService) ABList(c *gin.Context) {
r := request.ABList{}
_ = c.ShouldBind(&r)
if msg, ok := utils.ValidateInfo2CN(r); !ok {
response.FailWithMessage(msg, c)
return
}
list, total := test_data.ABList(&r)
response.OkWithData(gin.H{"list": list, "total": total}, c)
}
// @Tags 数据分析平台-生产
// @Summary 导出AB记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/ab/export [post]
func (S *ReportListService) ExportABList(c *gin.Context) {
response.OkWithData(test_data.ExportABList(), c)
}
// @Tags 数据分析平台-生产
// @Summary BP记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.BPList true "查询参数"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/bp [post]
func (S *ReportListService) BPList(c *gin.Context) {
r := request.BPList{}
_ = c.ShouldBind(&r)
if msg, ok := utils.ValidateInfo2CN(r); !ok {
response.FailWithMessage(msg, c)
return
}
list, total := test_data.BPList(&r)
response.OkWithData(gin.H{"list": list, "total": total}, c)
}
// @Tags 数据分析平台-生产
// @Summary 导出BP记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/bp/export [post]
func (S *ReportListService) ExportBPList(c *gin.Context) {
response.OkWithData(test_data.ExportBPList(), c)
}
// @Tags 数据分析平台-生产
// @Summary 导出晶圆记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/wafer/export [post]
func (S *ReportListService) ExportWaferList(c *gin.Context) {
response.OkWithData(test_data.ExportWaferList(), c)
} }
// @Tags 数据分析平台-生产 // @Tags 数据分析平台-生产
@ -58,21 +132,14 @@ func (S *ReportListService) CPList(c *gin.Context) {
} }
// @Tags 数据分析平台-生产 // @Tags 数据分析平台-生产
// @Summary 封装记录 // @Summary 导出CP记录
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @accept application/json // @accept application/json
// @Produce application/json // @Produce application/json
// @Param data body request.ABList true "查询参数"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}" // @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/ab [post] // @Router /testData/report/cp/export [post]
func (S *ReportListService) ABList(c *gin.Context) { func (S *ReportListService) ExportCPList(c *gin.Context) {
r := request.ABList{} response.OkWithData(test_data.ExportCPList(), c)
_ = c.ShouldBind(&r)
if msg, ok := utils.ValidateInfo2CN(r); !ok {
response.FailWithMessage(msg, c)
return
}
response.OkWithData(test_data.ABList(&r), c)
} }
// @Tags 数据分析平台-生产 // @Tags 数据分析平台-生产
@ -93,3 +160,44 @@ func (S *ReportListService) FTList(c *gin.Context) {
list, total := test_data.FTList(&r) list, total := test_data.FTList(&r)
response.OkWithData(gin.H{"list": list, "total": total}, c) response.OkWithData(gin.H{"list": list, "total": total}, c)
} }
// @Tags 数据分析平台-生产
// @Summary 导出FT记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/ft/export [post]
func (S *ReportListService) ExportFTList(c *gin.Context) {
response.OkWithData(test_data.ExportFTList(), c)
}
// @Tags 数据分析平台-生产
// @Summary TR记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.TRList true "查询参数"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/tr [post]
func (S *ReportListService) TRList(c *gin.Context) {
r := request.TRList{}
_ = c.ShouldBind(&r)
if msg, ok := utils.ValidateInfo2CN(r); !ok {
response.FailWithMessage(msg, c)
return
}
list, total := test_data.TRList(&r)
response.OkWithData(gin.H{"list": list, "total": total}, c)
}
// @Tags 数据分析平台-生产
// @Summary 导出TR记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"操作成功"}"
// @Router /testData/report/tr/export [post]
func (S *ReportListService) ExportTRList(c *gin.Context) {
response.OkWithData(test_data.ExportTRList(), c)
}

View File

@ -2,6 +2,8 @@ package test_data
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gorm.io/gorm"
"testData/global"
"testData/model" "testData/model"
"testData/model/response" "testData/model/response"
test_data "testData/repository/test.data" test_data "testData/repository/test.data"
@ -12,9 +14,13 @@ type IWarningInterface struct {
} }
type SWarningService struct { type SWarningService struct {
DB *gorm.DB
} }
func InitWarningService() *SWarningService { func InitWarningService() *SWarningService {
db := global.PostGreSQL
db.AutoMigrate(&model.Warning{}, &model.ProductionControl{}, &model.PassProbabilityDiff{}, &model.BinControl{},
&model.SelectionDiffControl{}, &model.StackingMaterialsWarning{}, &model.HistogramSelection{}, &model.ScatterSelection{})
return &SWarningService{} return &SWarningService{}
} }

View File

@ -61,6 +61,44 @@ var doc = `{
} }
} }
}, },
"/testData/cpMap/all": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台"
],
"summary": "CP All Map图",
"parameters": [
{
"description": "CP Map图",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.CPMap"
}
}
],
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/cpMap/export": { "/testData/cpMap/export": {
"post": { "post": {
"security": [ "security": [
@ -484,6 +522,98 @@ var doc = `{
} }
} }
}, },
"/testData/report/ab/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出AB记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/bp": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "BP记录",
"parameters": [
{
"description": "查询参数",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.BPList"
}
}
],
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/bp/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出BP记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/cp": { "/testData/report/cp": {
"post": { "post": {
"security": [ "security": [
@ -522,6 +652,33 @@ var doc = `{
} }
} }
}, },
"/testData/report/cp/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出CP记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/fTPassProbabilityByFactory": { "/testData/report/fTPassProbabilityByFactory": {
"post": { "post": {
"security": [ "security": [
@ -636,6 +793,33 @@ var doc = `{
} }
} }
}, },
"/testData/report/ft/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出FT记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/packageOrderNumberBar": { "/testData/report/packageOrderNumberBar": {
"post": { "post": {
"security": [ "security": [
@ -712,6 +896,71 @@ var doc = `{
} }
} }
}, },
"/testData/report/tr": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "TR记录",
"parameters": [
{
"description": "查询参数",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.TRList"
}
}
],
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/tr/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出TR记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/wafer": { "/testData/report/wafer": {
"post": { "post": {
"security": [ "security": [
@ -750,6 +999,33 @@ var doc = `{
} }
} }
}, },
"/testData/report/wafer/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出晶圆记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/scatter": { "/testData/scatter": {
"post": { "post": {
"security": [ "security": [
@ -1208,6 +1484,10 @@ var doc = `{
"id": { "id": {
"type": "integer" "type": "integer"
}, },
"selection": {
"description": "参数",
"type": "string"
},
"site_diff": { "site_diff": {
"description": "SITE间差异均值最大值-均值最小值)", "description": "SITE间差异均值最大值-均值最小值)",
"type": "string" "type": "string"
@ -1339,10 +1619,6 @@ var doc = `{
"description": "封装不良品", "description": "封装不良品",
"type": "string" "type": "string"
}, },
"is_finish": {
"description": "是否已完成",
"type": "string"
},
"lot": { "lot": {
"description": "批号", "description": "批号",
"type": "string" "type": "string"
@ -1355,14 +1631,28 @@ var doc = `{
"description": "下单日期", "description": "下单日期",
"type": "string" "type": "string"
}, },
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": { "package": {
"description": "封装", "description": "封装",
"type": "string" "type": "string"
}, },
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pass_probability": { "pass_probability": {
"description": "良率", "description": "良率",
"type": "string" "type": "string"
}, },
"pass_quantity": {
"description": "封装良品",
"type": "string"
},
"pbi": { "pbi": {
"description": "订单号", "description": "订单号",
"type": "string" "type": "string"
@ -1379,6 +1669,10 @@ var doc = `{
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"status": {
"description": "是否已完成",
"type": "string"
},
"stock_in_quantity": { "stock_in_quantity": {
"description": "入库数", "description": "入库数",
"type": "string" "type": "string"
@ -1397,21 +1691,96 @@ var doc = `{
} }
} }
}, },
"request.CPList": { "request.BPList": {
"type": "object", "type": "object",
"properties": { "properties": {
"die_quantity": {
"description": "Die数量",
"type": "string"
},
"factory": { "factory": {
"description": "CP厂", "description": "CP测试厂",
"type": "string" "type": "string"
}, },
"lot": { "lot": {
"description": "晶圆批号", "description": "批号",
"type": "string"
},
"online_quantity": {
"description": "在线数量",
"type": "string" "type": "string"
}, },
"order_date": { "order_date": {
"description": "下单日期", "description": "下单日期",
"type": "string" "type": "string"
}, },
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": {
"description": "封装",
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pbi": {
"description": "订单号",
"type": "string"
},
"product": {
"description": "晶圆型号",
"type": "string"
},
"quantity": {
"description": "订单数量",
"type": "string"
},
"return_quantity": {
"description": "回货数量",
"type": "string"
},
"status": {
"description": "状态",
"type": "string"
},
"wafer_id": {
"description": "片号",
"type": "string"
}
}
},
"request.CPList": {
"type": "object",
"properties": {
"die_quantity": {
"description": "Die数量",
"type": "string"
},
"factory": {
"description": "CP测试厂",
"type": "string"
},
"lot": {
"description": "批号",
"type": "string"
},
"online_quantity": {
"description": "未交数量",
"type": "string"
},
"order_date": {
"description": "下单日期(订单日期)",
"type": "string"
},
"package": {
"description": "封装(规格)",
"type": "string"
},
"page": { "page": {
"type": "integer" "type": "integer"
}, },
@ -1419,18 +1788,38 @@ var doc = `{
"type": "integer" "type": "integer"
}, },
"pbi": { "pbi": {
"description": "PBI(订单号)",
"type": "string" "type": "string"
}, },
"query_type": { "product": {
"description": "查询类型", "description": "晶圆型号",
"type": "string"
},
"quantity": {
"description": "订单数量",
"type": "string"
},
"return_quantity": {
"description": "回货数量",
"type": "string"
},
"status": {
"type": "string" "type": "string"
}, },
"test_machine": { "test_machine": {
"description": "测试机台", "description": "测试机台",
"type": "string" "type": "string"
}, },
"wafer_product": { "test_program": {
"description": "晶圆型号", "description": "测试程序",
"type": "string"
},
"test_program_version": {
"description": "测试程序版本",
"type": "string"
},
"wafer_id": {
"description": "片号",
"type": "string" "type": "string"
} }
} }
@ -1503,6 +1892,12 @@ var doc = `{
"wafer_id": { "wafer_id": {
"description": "片号", "description": "片号",
"type": "string" "type": "string"
},
"wafer_ids": {
"type": "array",
"items": {
"type": "string"
}
} }
} }
}, },
@ -1604,6 +1999,10 @@ var doc = `{
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"step": {
"description": "工序",
"type": "string"
},
"test_program": { "test_program": {
"description": "测试程序", "description": "测试程序",
"type": "string" "type": "string"
@ -1622,15 +2021,35 @@ var doc = `{
"type": "object", "type": "object",
"properties": { "properties": {
"factory": { "factory": {
"description": "SubBatch string ` + "`" + `json:\"sub_batch\"` + "`" + ` // 子批次", "description": "FT测试厂",
"type": "string"
},
"ft_fail_quantity": {
"description": "FT不良品",
"type": "string"
},
"ft_pass_quantity": {
"description": "FT良品",
"type": "string" "type": "string"
}, },
"lot": { "lot": {
"description": "晶圆批号", "description": "批号",
"type": "string"
},
"online_quantity": {
"description": "未交数量",
"type": "string" "type": "string"
}, },
"order_date": { "order_date": {
"description": "下单日期", "description": "下单日期(订单日期)",
"type": "string"
},
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": {
"description": "封装(规格)",
"type": "string" "type": "string"
}, },
"page": { "page": {
@ -1640,22 +2059,38 @@ var doc = `{
"type": "integer" "type": "integer"
}, },
"pbi": { "pbi": {
"description": "PBI(订单号)",
"type": "string" "type": "string"
}, },
"product": { "product": {
"description": "成品型号", "description": "成品型号",
"type": "string" "type": "string"
}, },
"query_type": { "quantity": {
"description": "查询类型", "description": "订单数量",
"type": "string"
},
"return_quantity": {
"description": "回货数量",
"type": "string" "type": "string"
}, },
"seal": { "seal": {
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"status": {
"type": "string"
},
"test_program": { "test_program": {
"description": "测试程序", "description": "FT测试程序",
"type": "string"
},
"test_program_version": {
"description": "测试程序版本",
"type": "string"
},
"wafer_product": {
"description": "晶圆型号",
"type": "string" "type": "string"
} }
} }
@ -2136,6 +2571,73 @@ var doc = `{
} }
} }
}, },
"request.TRList": {
"type": "object",
"properties": {
"factory": {
"description": "封装厂",
"type": "string"
},
"fail_quantity": {
"description": "FT不良品",
"type": "string"
},
"lot": {
"description": "批号",
"type": "string"
},
"online_quantity": {
"description": "在线数量",
"type": "string"
},
"order_date": {
"description": "下单日期",
"type": "string"
},
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": {
"description": "封装",
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pass_quantity": {
"description": "FT良品",
"type": "string"
},
"pbi": {
"description": "订单号",
"type": "string"
},
"product": {
"description": "成品型号",
"type": "string"
},
"quantity": {
"description": "订单数量",
"type": "string"
},
"seal": {
"description": "丝印",
"type": "string"
},
"status": {
"description": "是否已完成",
"type": "string"
},
"wafer_product": {
"description": "晶圆型号",
"type": "string"
}
}
},
"request.UpdateFinalReportExcel": { "request.UpdateFinalReportExcel": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2224,6 +2726,10 @@ var doc = `{
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"step": {
"description": "工序",
"type": "string"
},
"test_program": { "test_program": {
"description": "测试程序", "description": "测试程序",
"type": "string" "type": "string"
@ -2249,6 +2755,12 @@ var doc = `{
"description": "下单日期", "description": "下单日期",
"type": "string" "type": "string"
}, },
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pbi": { "pbi": {
"description": "订单号", "description": "订单号",
"type": "string" "type": "string"
@ -2269,6 +2781,10 @@ var doc = `{
"description": "回货数量", "description": "回货数量",
"type": "string" "type": "string"
}, },
"status": {
"description": "状态",
"type": "string"
},
"wafer_size": { "wafer_size": {
"description": "晶圆尺寸", "description": "晶圆尺寸",
"type": "string" "type": "string"

View File

@ -42,6 +42,44 @@
} }
} }
}, },
"/testData/cpMap/all": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台"
],
"summary": "CP All Map图",
"parameters": [
{
"description": "CP Map图",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.CPMap"
}
}
],
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/cpMap/export": { "/testData/cpMap/export": {
"post": { "post": {
"security": [ "security": [
@ -465,6 +503,98 @@
} }
} }
}, },
"/testData/report/ab/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出AB记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/bp": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "BP记录",
"parameters": [
{
"description": "查询参数",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.BPList"
}
}
],
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/bp/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出BP记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/cp": { "/testData/report/cp": {
"post": { "post": {
"security": [ "security": [
@ -503,6 +633,33 @@
} }
} }
}, },
"/testData/report/cp/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出CP记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/fTPassProbabilityByFactory": { "/testData/report/fTPassProbabilityByFactory": {
"post": { "post": {
"security": [ "security": [
@ -617,6 +774,33 @@
} }
} }
}, },
"/testData/report/ft/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出FT记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/packageOrderNumberBar": { "/testData/report/packageOrderNumberBar": {
"post": { "post": {
"security": [ "security": [
@ -693,6 +877,71 @@
} }
} }
}, },
"/testData/report/tr": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "TR记录",
"parameters": [
{
"description": "查询参数",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.TRList"
}
}
],
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/tr/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出TR记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/report/wafer": { "/testData/report/wafer": {
"post": { "post": {
"security": [ "security": [
@ -731,6 +980,33 @@
} }
} }
}, },
"/testData/report/wafer/export": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"数据分析平台-生产"
],
"summary": "导出晶圆记录",
"responses": {
"200": {
"description": "{\"success\":true,\"data\":{},\"msg\":\"操作成功\"}",
"schema": {
"type": "string"
}
}
}
}
},
"/testData/scatter": { "/testData/scatter": {
"post": { "post": {
"security": [ "security": [
@ -1189,6 +1465,10 @@
"id": { "id": {
"type": "integer" "type": "integer"
}, },
"selection": {
"description": "参数",
"type": "string"
},
"site_diff": { "site_diff": {
"description": "SITE间差异均值最大值-均值最小值)", "description": "SITE间差异均值最大值-均值最小值)",
"type": "string" "type": "string"
@ -1320,10 +1600,6 @@
"description": "封装不良品", "description": "封装不良品",
"type": "string" "type": "string"
}, },
"is_finish": {
"description": "是否已完成",
"type": "string"
},
"lot": { "lot": {
"description": "批号", "description": "批号",
"type": "string" "type": "string"
@ -1336,14 +1612,28 @@
"description": "下单日期", "description": "下单日期",
"type": "string" "type": "string"
}, },
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": { "package": {
"description": "封装", "description": "封装",
"type": "string" "type": "string"
}, },
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pass_probability": { "pass_probability": {
"description": "良率", "description": "良率",
"type": "string" "type": "string"
}, },
"pass_quantity": {
"description": "封装良品",
"type": "string"
},
"pbi": { "pbi": {
"description": "订单号", "description": "订单号",
"type": "string" "type": "string"
@ -1360,6 +1650,10 @@
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"status": {
"description": "是否已完成",
"type": "string"
},
"stock_in_quantity": { "stock_in_quantity": {
"description": "入库数", "description": "入库数",
"type": "string" "type": "string"
@ -1378,21 +1672,96 @@
} }
} }
}, },
"request.CPList": { "request.BPList": {
"type": "object", "type": "object",
"properties": { "properties": {
"die_quantity": {
"description": "Die数量",
"type": "string"
},
"factory": { "factory": {
"description": "CP厂", "description": "CP测试厂",
"type": "string" "type": "string"
}, },
"lot": { "lot": {
"description": "晶圆批号", "description": "批号",
"type": "string"
},
"online_quantity": {
"description": "在线数量",
"type": "string" "type": "string"
}, },
"order_date": { "order_date": {
"description": "下单日期", "description": "下单日期",
"type": "string" "type": "string"
}, },
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": {
"description": "封装",
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pbi": {
"description": "订单号",
"type": "string"
},
"product": {
"description": "晶圆型号",
"type": "string"
},
"quantity": {
"description": "订单数量",
"type": "string"
},
"return_quantity": {
"description": "回货数量",
"type": "string"
},
"status": {
"description": "状态",
"type": "string"
},
"wafer_id": {
"description": "片号",
"type": "string"
}
}
},
"request.CPList": {
"type": "object",
"properties": {
"die_quantity": {
"description": "Die数量",
"type": "string"
},
"factory": {
"description": "CP测试厂",
"type": "string"
},
"lot": {
"description": "批号",
"type": "string"
},
"online_quantity": {
"description": "未交数量",
"type": "string"
},
"order_date": {
"description": "下单日期(订单日期)",
"type": "string"
},
"package": {
"description": "封装(规格)",
"type": "string"
},
"page": { "page": {
"type": "integer" "type": "integer"
}, },
@ -1400,18 +1769,38 @@
"type": "integer" "type": "integer"
}, },
"pbi": { "pbi": {
"description": "PBI(订单号)",
"type": "string" "type": "string"
}, },
"query_type": { "product": {
"description": "查询类型", "description": "晶圆型号",
"type": "string"
},
"quantity": {
"description": "订单数量",
"type": "string"
},
"return_quantity": {
"description": "回货数量",
"type": "string"
},
"status": {
"type": "string" "type": "string"
}, },
"test_machine": { "test_machine": {
"description": "测试机台", "description": "测试机台",
"type": "string" "type": "string"
}, },
"wafer_product": { "test_program": {
"description": "晶圆型号", "description": "测试程序",
"type": "string"
},
"test_program_version": {
"description": "测试程序版本",
"type": "string"
},
"wafer_id": {
"description": "片号",
"type": "string" "type": "string"
} }
} }
@ -1484,6 +1873,12 @@
"wafer_id": { "wafer_id": {
"description": "片号", "description": "片号",
"type": "string" "type": "string"
},
"wafer_ids": {
"type": "array",
"items": {
"type": "string"
}
} }
} }
}, },
@ -1585,6 +1980,10 @@
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"step": {
"description": "工序",
"type": "string"
},
"test_program": { "test_program": {
"description": "测试程序", "description": "测试程序",
"type": "string" "type": "string"
@ -1603,15 +2002,35 @@
"type": "object", "type": "object",
"properties": { "properties": {
"factory": { "factory": {
"description": "SubBatch string `json:\"sub_batch\"` // 子批次", "description": "FT测试厂",
"type": "string"
},
"ft_fail_quantity": {
"description": "FT不良品",
"type": "string"
},
"ft_pass_quantity": {
"description": "FT良品",
"type": "string" "type": "string"
}, },
"lot": { "lot": {
"description": "晶圆批号", "description": "批号",
"type": "string"
},
"online_quantity": {
"description": "未交数量",
"type": "string" "type": "string"
}, },
"order_date": { "order_date": {
"description": "下单日期", "description": "下单日期(订单日期)",
"type": "string"
},
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": {
"description": "封装(规格)",
"type": "string" "type": "string"
}, },
"page": { "page": {
@ -1621,22 +2040,38 @@
"type": "integer" "type": "integer"
}, },
"pbi": { "pbi": {
"description": "PBI(订单号)",
"type": "string" "type": "string"
}, },
"product": { "product": {
"description": "成品型号", "description": "成品型号",
"type": "string" "type": "string"
}, },
"query_type": { "quantity": {
"description": "查询类型", "description": "订单数量",
"type": "string"
},
"return_quantity": {
"description": "回货数量",
"type": "string" "type": "string"
}, },
"seal": { "seal": {
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"status": {
"type": "string"
},
"test_program": { "test_program": {
"description": "测试程序", "description": "FT测试程序",
"type": "string"
},
"test_program_version": {
"description": "测试程序版本",
"type": "string"
},
"wafer_product": {
"description": "晶圆型号",
"type": "string" "type": "string"
} }
} }
@ -2117,6 +2552,73 @@
} }
} }
}, },
"request.TRList": {
"type": "object",
"properties": {
"factory": {
"description": "封装厂",
"type": "string"
},
"fail_quantity": {
"description": "FT不良品",
"type": "string"
},
"lot": {
"description": "批号",
"type": "string"
},
"online_quantity": {
"description": "在线数量",
"type": "string"
},
"order_date": {
"description": "下单日期",
"type": "string"
},
"outsourcing_pbi": {
"description": "委外工单号",
"type": "string"
},
"package": {
"description": "封装",
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pass_quantity": {
"description": "FT良品",
"type": "string"
},
"pbi": {
"description": "订单号",
"type": "string"
},
"product": {
"description": "成品型号",
"type": "string"
},
"quantity": {
"description": "订单数量",
"type": "string"
},
"seal": {
"description": "丝印",
"type": "string"
},
"status": {
"description": "是否已完成",
"type": "string"
},
"wafer_product": {
"description": "晶圆型号",
"type": "string"
}
}
},
"request.UpdateFinalReportExcel": { "request.UpdateFinalReportExcel": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -2205,6 +2707,10 @@
"description": "丝印", "description": "丝印",
"type": "string" "type": "string"
}, },
"step": {
"description": "工序",
"type": "string"
},
"test_program": { "test_program": {
"description": "测试程序", "description": "测试程序",
"type": "string" "type": "string"
@ -2230,6 +2736,12 @@
"description": "下单日期", "description": "下单日期",
"type": "string" "type": "string"
}, },
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"pbi": { "pbi": {
"description": "订单号", "description": "订单号",
"type": "string" "type": "string"
@ -2250,6 +2762,10 @@
"description": "回货数量", "description": "回货数量",
"type": "string" "type": "string"
}, },
"status": {
"description": "状态",
"type": "string"
},
"wafer_size": { "wafer_size": {
"description": "晶圆尺寸", "description": "晶圆尺寸",
"type": "string" "type": "string"

View File

@ -87,6 +87,9 @@ definitions:
type: string type: string
id: id:
type: integer type: integer
selection:
description: 参数
type: string
site_diff: site_diff:
description: SITE间差异均值最大值-均值最小值) description: SITE间差异均值最大值-均值最小值)
type: string type: string
@ -178,9 +181,6 @@ definitions:
fail_quantity: fail_quantity:
description: 封装不良品 description: 封装不良品
type: string type: string
is_finish:
description: 是否已完成
type: string
lot: lot:
description: 批号 description: 批号
type: string type: string
@ -190,12 +190,22 @@ definitions:
order_date: order_date:
description: 下单日期 description: 下单日期
type: string type: string
outsourcing_pbi:
description: 委外工单号
type: string
package: package:
description: 封装 description: 封装
type: string type: string
page:
type: integer
pageSize:
type: integer
pass_probability: pass_probability:
description: 良率 description: 良率
type: string type: string
pass_quantity:
description: 封装良品
type: string
pbi: pbi:
description: 订单号 description: 订单号
type: string type: string
@ -208,6 +218,9 @@ definitions:
seal: seal:
description: 丝印 description: 丝印
type: string type: string
status:
description: 是否已完成
type: string
stock_in_quantity: stock_in_quantity:
description: 入库数 description: 入库数
type: string type: string
@ -221,31 +234,101 @@ definitions:
description: 晶圆型号 description: 晶圆型号
type: string type: string
type: object type: object
request.CPList: request.BPList:
properties: properties:
die_quantity:
description: Die数量
type: string
factory: factory:
description: CP厂 description: CP测试
type: string type: string
lot: lot:
description: 晶圆批号 description: 批号
type: string
online_quantity:
description: 在线数量
type: string type: string
order_date: order_date:
description: 下单日期 description: 下单日期
type: string type: string
outsourcing_pbi:
description: 委外工单号
type: string
package:
description: 封装
type: string
page:
type: integer
pageSize:
type: integer
pbi:
description: 订单号
type: string
product:
description: 晶圆型号
type: string
quantity:
description: 订单数量
type: string
return_quantity:
description: 回货数量
type: string
status:
description: 状态
type: string
wafer_id:
description: 片号
type: string
type: object
request.CPList:
properties:
die_quantity:
description: Die数量
type: string
factory:
description: CP测试厂
type: string
lot:
description: 批号
type: string
online_quantity:
description: 未交数量
type: string
order_date:
description: 下单日期(订单日期)
type: string
package:
description: 封装(规格)
type: string
page: page:
type: integer type: integer
page_size: page_size:
type: integer type: integer
pbi: pbi:
description: PBI(订单号)
type: string type: string
query_type: product:
description: 查询类型 description: 晶圆型号
type: string
quantity:
description: 订单数量
type: string
return_quantity:
description: 回货数量
type: string
status:
type: string type: string
test_machine: test_machine:
description: 测试机台 description: 测试机台
type: string type: string
wafer_product: test_program:
description: 晶圆型号 description: 测试程序
type: string
test_program_version:
description: 测试程序版本
type: string
wafer_id:
description: 片号
type: string type: string
type: object type: object
request.CPMap: request.CPMap:
@ -296,6 +379,10 @@ definitions:
wafer_id: wafer_id:
description: 片号 description: 片号
type: string type: string
wafer_ids:
items:
type: string
type: array
type: object type: object
request.CPMapColor: request.CPMapColor:
properties: properties:
@ -367,6 +454,9 @@ definitions:
seal: seal:
description: 丝印 description: 丝印
type: string type: string
step:
description: 工序
type: string
test_program: test_program:
description: 测试程序 description: 测试程序
type: string type: string
@ -379,31 +469,58 @@ definitions:
request.FTList: request.FTList:
properties: properties:
factory: factory:
description: SubBatch string `json:"sub_batch"` // 子批次 description: FT测试厂
type: string
ft_fail_quantity:
description: FT不良品
type: string
ft_pass_quantity:
description: FT良品
type: string type: string
lot: lot:
description: 晶圆批号 description: 批号
type: string
online_quantity:
description: 未交数量
type: string type: string
order_date: order_date:
description: 下单日期 description: 下单日期(订单日期)
type: string
outsourcing_pbi:
description: 委外工单号
type: string
package:
description: 封装(规格)
type: string type: string
page: page:
type: integer type: integer
page_size: page_size:
type: integer type: integer
pbi: pbi:
description: PBI(订单号)
type: string type: string
product: product:
description: 成品型号 description: 成品型号
type: string type: string
query_type: quantity:
description: 查询类型 description: 订单数量
type: string
return_quantity:
description: 回货数量
type: string type: string
seal: seal:
description: 丝印 description: 丝印
type: string type: string
status:
type: string
test_program: test_program:
description: 测试程序 description: FT测试程序
type: string
test_program_version:
description: 测试程序版本
type: string
wafer_product:
description: 晶圆型号
type: string type: string
type: object type: object
request.Histogram: request.Histogram:
@ -742,6 +859,55 @@ definitions:
wafer_id: wafer_id:
type: string type: string
type: object type: object
request.TRList:
properties:
factory:
description: 封装厂
type: string
fail_quantity:
description: FT不良品
type: string
lot:
description: 批号
type: string
online_quantity:
description: 在线数量
type: string
order_date:
description: 下单日期
type: string
outsourcing_pbi:
description: 委外工单号
type: string
package:
description: 封装
type: string
page:
type: integer
pageSize:
type: integer
pass_quantity:
description: FT良品
type: string
pbi:
description: 订单号
type: string
product:
description: 成品型号
type: string
quantity:
description: 订单数量
type: string
seal:
description: 丝印
type: string
status:
description: 是否已完成
type: string
wafer_product:
description: 晶圆型号
type: string
type: object
request.UpdateFinalReportExcel: request.UpdateFinalReportExcel:
properties: properties:
bent_stitch: bent_stitch:
@ -805,6 +971,9 @@ definitions:
seal: seal:
description: 丝印 description: 丝印
type: string type: string
step:
description: 工序
type: string
test_program: test_program:
description: 测试程序 description: 测试程序
type: string type: string
@ -823,6 +992,10 @@ definitions:
order_date: order_date:
description: 下单日期 description: 下单日期
type: string type: string
page:
type: integer
pageSize:
type: integer
pbi: pbi:
description: 订单号 description: 订单号
type: string type: string
@ -838,6 +1011,9 @@ definitions:
return_quantity: return_quantity:
description: 回货数量 description: 回货数量
type: string type: string
status:
description: 状态
type: string
wafer_size: wafer_size:
description: 晶圆尺寸 description: 晶圆尺寸
type: string type: string
@ -875,6 +1051,29 @@ paths:
summary: CP Map图 summary: CP Map图
tags: tags:
- 数据分析平台 - 数据分析平台
/testData/cpMap/all:
post:
consumes:
- application/json
parameters:
- description: CP Map图
in: body
name: data
required: true
schema:
$ref: '#/definitions/request.CPMap'
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: CP All Map图
tags:
- 数据分析平台
/testData/cpMap/export: /testData/cpMap/export:
post: post:
consumes: consumes:
@ -1133,6 +1332,61 @@ paths:
summary: 封装记录 summary: 封装记录
tags: tags:
- 数据分析平台-生产 - 数据分析平台-生产
/testData/report/ab/export:
post:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: 导出AB记录
tags:
- 数据分析平台-生产
/testData/report/bp:
post:
consumes:
- application/json
parameters:
- description: 查询参数
in: body
name: data
required: true
schema:
$ref: '#/definitions/request.BPList'
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: BP记录
tags:
- 数据分析平台-生产
/testData/report/bp/export:
post:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: 导出BP记录
tags:
- 数据分析平台-生产
/testData/report/cp: /testData/report/cp:
post: post:
consumes: consumes:
@ -1156,6 +1410,22 @@ paths:
summary: CP记录 summary: CP记录
tags: tags:
- 数据分析平台-生产 - 数据分析平台-生产
/testData/report/cp/export:
post:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: 导出CP记录
tags:
- 数据分析平台-生产
/testData/report/fTPassProbabilityByFactory: /testData/report/fTPassProbabilityByFactory:
post: post:
consumes: consumes:
@ -1225,6 +1495,22 @@ paths:
summary: FT记录 summary: FT记录
tags: tags:
- 数据分析平台-生产 - 数据分析平台-生产
/testData/report/ft/export:
post:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: 导出FT记录
tags:
- 数据分析平台-生产
/testData/report/packageOrderNumberBar: /testData/report/packageOrderNumberBar:
post: post:
consumes: consumes:
@ -1271,6 +1557,45 @@ paths:
summary: 封装良率折线图 summary: 封装良率折线图
tags: tags:
- 数据分析平台-生产 - 数据分析平台-生产
/testData/report/tr:
post:
consumes:
- application/json
parameters:
- description: 查询参数
in: body
name: data
required: true
schema:
$ref: '#/definitions/request.TRList'
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: TR记录
tags:
- 数据分析平台-生产
/testData/report/tr/export:
post:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: 导出TR记录
tags:
- 数据分析平台-生产
/testData/report/wafer: /testData/report/wafer:
post: post:
consumes: consumes:
@ -1294,6 +1619,22 @@ paths:
summary: 晶圆记录 summary: 晶圆记录
tags: tags:
- 数据分析平台-生产 - 数据分析平台-生产
/testData/report/wafer/export:
post:
consumes:
- application/json
produces:
- application/json
responses:
"200":
description: '{"success":true,"data":{},"msg":"操作成功"}'
schema:
type: string
security:
- ApiKeyAuth: []
summary: 导出晶圆记录
tags:
- 数据分析平台-生产
/testData/scatter: /testData/scatter:
post: post:
consumes: consumes:

1
go.mod
View File

@ -76,6 +76,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect

2
go.sum
View File

@ -207,6 +207,8 @@ github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=

30
initialization/cron.go Normal file
View File

@ -0,0 +1,30 @@
package initialization
import (
"fmt"
"gitee.com/golang-module/carbon/v2"
"github.com/robfig/cron/v3"
"log"
"testData/global"
test_data "testData/repository/test.data"
)
func InitCronListCron() {
c := cron.New(cron.WithChain(cron.SkipIfStillRunning(cron.DefaultLogger)))
//_, err := c.AddFunc("0 */1 * * *", func() {
_, err := c.AddFunc("*/10 * * * *", func() {
fmt.Println(carbon.Now().Format("Y-m-d H:i:s") + "CronListCron start")
test_data.CronWaferList()
test_data.CronABList()
test_data.CronBPList()
test_data.CronCPList()
test_data.CronFTList()
test_data.CronTRList()
fmt.Println(carbon.Now().Format("Y-m-d H:i:s") + "CronListCron finish")
})
if err != nil {
global.Log.Errorf("InitCronListCron AddFunc error: %s", err)
log.Fatalln(err)
}
c.Start()
}

View File

@ -1057,3 +1057,347 @@
2024-07-24 17:36:22 INFO | 192.168.0.219 | 200 | 0s | GET | 未登录 | /docs/swagger-ui-standalone-preset.js 2024-07-24 17:36:22 INFO | 192.168.0.219 | 200 | 0s | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-07-24 17:36:22 INFO | 192.168.0.219 | 200 | 423.8µs | GET | 未登录 | /docs/doc.json 2024-07-24 17:36:22 INFO | 192.168.0.219 | 200 | 423.8µs | GET | 未登录 | /docs/doc.json
2024-07-24 17:36:22 INFO | 192.168.0.219 | 200 | 0s | GET | 未登录 | /docs/favicon-32x32.png 2024-07-24 17:36:22 INFO | 192.168.0.219 | 200 | 0s | GET | 未登录 | /docs/favicon-32x32.png
2024-07-29 10:10:23 INFO | 192.168.0.1 | 200 | 5.055359ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:27 INFO | 192.168.0.1 | 200 | 3.702118ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:29 INFO | 192.168.0.1 | 200 | 2.220715ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:30 INFO | 192.168.0.1 | 200 | 2.305414ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:31 INFO | 192.168.0.1 | 200 | 2.132325ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:33 INFO | 192.168.0.1 | 200 | 2.308174ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:34 INFO | 192.168.0.1 | 200 | 2.023023ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:34 INFO | 192.168.0.1 | 200 | 1.369673ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:50 INFO | 192.168.0.1 | 200 | 2.451984ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:53 INFO | 192.168.0.1 | 200 | 2.088553ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:10:56 INFO | 192.168.0.1 | 200 | 3.174496ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:11:01 INFO | 192.168.0.1 | 200 | 2.218233ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:21:45 INFO | 192.168.0.1 | 200 | 6.099993ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:21:48 INFO | 192.168.0.1 | 200 | 3.900889ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:21:58 INFO | 192.168.0.1 | 200 | 3.281257ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:25:03 INFO | 192.168.0.1 | 200 | 4.155518ms | POST | 未登录 | /testData/report/cp
2024-07-29 10:25:13 INFO | 192.168.0.1 | 200 | 3.741826ms | POST | 未登录 | /testData/report/cp
2024-07-29 12:24:12 INFO | 192.168.0.1 | 200 | 11.416573ms | POST | 未登录 | /testData/report/cp
2024-07-29 13:08:26 INFO | 192.168.0.1 | 200 | 3.631949ms | POST | 未登录 | /testData/report/cp
2024-07-29 13:51:42 INFO | 192.168.0.1 | 200 | 16.794811ms | POST | 未登录 | /testData/cpMap
2024-07-29 13:51:42 INFO | 192.168.0.1 | 200 | 5.372851ms | POST | 未登录 | /testData/cpMap
2024-07-29 13:51:46 INFO | 192.168.0.1 | 200 | 6.409192ms | POST | 未登录 | /testData/cpMap
2024-07-29 13:51:46 INFO | 192.168.0.1 | 200 | 5.05991ms | POST | 未登录 | /testData/cpMap
2024-07-29 13:53:12 INFO | 192.168.0.1 | 200 | 543.923784ms | POST | 未登录 | /testData/selection
2024-07-29 13:55:29 INFO | 192.168.0.1 | 200 | 6.628043ms | POST | 未登录 | /testData/report/ft
2024-07-29 14:28:33 INFO | 192.168.0.1 | 200 | 9.780901ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:28:33 INFO | 192.168.0.1 | 200 | 5.22955ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:28:39 INFO | 192.168.0.248 | 200 | 580.928938ms | POST | 未登录 | /testData/selection
2024-07-29 14:30:04 INFO | 192.168.0.1 | 200 | 5.971721ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:30:04 INFO | 192.168.0.1 | 200 | 5.43475ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:30:05 INFO | 192.168.0.248 | 200 | 448.411436ms | POST | 未登录 | /testData/selection
2024-07-29 14:30:13 INFO | 192.168.0.248 | 200 | 4.96432ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:30:13 INFO | 192.168.0.248 | 200 | 5.2926ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:30:57 INFO | 192.168.0.248 | 200 | 9.42839ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:30:57 INFO | 192.168.0.248 | 200 | 5.17681ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:33:23 INFO | 192.168.0.248 | 200 | 458.605555ms | POST | 未登录 | /testData/selection
2024-07-29 14:34:50 INFO | 192.168.0.1 | 200 | 3.706726ms | POST | 未登录 | /testData/report/fTPassProbabilityByFactory
2024-07-29 14:34:57 INFO | 192.168.0.1 | 200 | 4.1854ms | POST | 未登录 | /testData/report/fTPassProbabilityByProduct
2024-07-29 14:35:02 INFO | 192.168.0.1 | 200 | 4.748619ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:35:03 INFO | 192.168.0.1 | 200 | 4.28863ms | POST | 未登录 | /testData/report/ft
2024-07-29 14:35:15 INFO | 192.168.0.248 | 200 | 448.672543ms | POST | 未登录 | /testData/selection
2024-07-29 14:36:07 INFO | 192.168.0.248 | 200 | 6.149051ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:07 INFO | 192.168.0.248 | 200 | 5.382509ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:14 INFO | 192.168.0.1 | 200 | 5.772961ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:14 INFO | 192.168.0.1 | 200 | 6.579484ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:21 INFO | 192.168.0.1 | 200 | 129.675112ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:22 INFO | 192.168.0.1 | 200 | 131.494035ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:33 INFO | 192.168.0.248 | 200 | 6.095444ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:33 INFO | 192.168.0.248 | 200 | 5.195859ms | POST | 未登录 | /testData/cpMap
2024-07-29 14:36:58 INFO | 192.168.0.1 | 200 | 1.259938134s | POST | 未登录 | /testData/histogram
2024-07-29 14:37:02 INFO | 192.168.0.1 | 200 | 383.962258ms | POST | 未登录 | /testData/selection
2024-07-29 14:37:06 INFO | 192.168.0.1 | 200 | 1.475821204s | POST | 未登录 | /testData/histogram
2024-07-29 14:37:10 INFO | 192.168.0.1 | 200 | 384.78794ms | POST | 未登录 | /testData/selection
2024-07-29 14:37:16 INFO | 192.168.0.248 | 200 | 411.154808ms | POST | 未登录 | /testData/selection
2024-07-29 14:37:17 INFO | 192.168.0.1 | 200 | 399.694488ms | POST | 未登录 | /testData/selection
2024-07-29 14:37:26 INFO | 192.168.0.1 | 200 | 747.416129ms | POST | 未登录 | /testData/scatter
2024-07-29 14:37:35 INFO | 192.168.0.1 | 200 | 776.110676ms | POST | 未登录 | /testData/scatter
2024-07-29 14:37:40 INFO | 192.168.0.1 | 200 | 3.726326ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:37:46 INFO | 192.168.0.1 | 200 | 4.460989ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:38:10 INFO | 192.168.0.248 | 200 | 3.906788ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:38:21 INFO | 192.168.0.248 | 200 | 3.242057ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:39:01 INFO | 192.168.0.1 | 200 | 2.846186ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:39:12 INFO | 192.168.0.248 | 200 | 3.648797ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:39:13 INFO | 192.168.0.248 | 200 | 4.014977ms | POST | 未登录 | /testData/report/cp
2024-07-29 14:48:30 INFO | 192.168.0.1 | 200 | 626.478951ms | POST | 未登录 | /testData/selection
2024-07-29 14:52:30 INFO | 192.168.0.1 | 200 | 11.535343ms | POST | 未登录 | /testData/selection
2024-07-29 14:52:37 INFO | 192.168.0.1 | 200 | 600.410977ms | POST | 未登录 | /testData/selection
2024-07-29 16:56:02 INFO | 45.148.10.230 | 200 | 93.22µs | GET | 未登录 | /.env
2024-07-29 17:05:06 INFO | 192.168.0.248 | 200 | 12.033281ms | POST | 未登录 | /testData/report/cp
2024-07-29 17:07:52 INFO | 45.148.10.59 | 200 | 35.83µs | GET | 未登录 | /
2024-07-29 17:18:01 INFO | 192.168.0.248 | 200 | 10.742862ms | POST | 未登录 | /testData/selection
2024-07-29 17:18:06 INFO | 192.168.0.248 | 200 | 4.63536ms | POST | 未登录 | /testData/report/ft
2024-07-29 17:19:09 INFO | 192.168.0.219 | 200 | 530.321µs | GET | 未登录 | /docs/index.html
2024-07-29 17:19:09 INFO | 192.168.0.219 | 200 | 986.492µs | GET | 未登录 | /docs/swagger-ui.css
2024-07-29 17:19:09 INFO | 192.168.0.219 | 200 | 1.631663ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-07-29 17:19:09 INFO | 192.168.0.219 | 200 | 8.310646ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-07-29 17:19:09 INFO | 192.168.0.219 | 200 | 618.821µs | GET | 未登录 | /docs/doc.json
2024-07-29 17:19:09 INFO | 192.168.0.219 | 200 | 50.87µs | GET | 未登录 | /docs/favicon-32x32.png
2024-07-29 17:19:22 INFO | 192.168.0.248 | 200 | 224.211µs | GET | 未登录 | /docs/index.html
2024-07-29 17:19:22 INFO | 192.168.0.248 | 200 | 810.161µs | GET | 未登录 | /docs/swagger-ui.css
2024-07-29 17:19:22 INFO | 192.168.0.248 | 200 | 2.305654ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-07-29 17:19:22 INFO | 192.168.0.248 | 200 | 9.380389ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-07-29 17:19:22 INFO | 192.168.0.248 | 200 | 495.491µs | GET | 未登录 | /docs/doc.json
2024-07-29 17:19:22 INFO | 192.168.0.248 | 200 | 52.82µs | GET | 未登录 | /docs/favicon-32x32.png
2024-07-29 17:28:01 INFO | 192.168.0.248 | 200 | 11.406534ms | POST | 未登录 | /testData/cpMap
2024-07-29 17:29:02 INFO | 192.168.0.248 | 200 | 142.664605ms | POST | 未登录 | /testData/cpMap
2024-07-30 07:53:58 INFO | 147.185.132.73 | 200 | 39.82µs | GET | 未登录 | /
2024-07-30 10:42:50 INFO | 192.168.0.114 | 200 | 17.049755ms | POST | 未登录 | /testData/pie
2024-07-30 10:42:50 INFO | 192.168.0.114 | 200 | 21.868984ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:04 INFO | 192.168.0.114 | 200 | 11.517346ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:05 INFO | 192.168.0.114 | 200 | 13.143876ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:05 INFO | 192.168.0.114 | 200 | 10.184303ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:06 INFO | 192.168.0.114 | 200 | 11.1094ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:07 INFO | 192.168.0.114 | 200 | 10.27814ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:16 INFO | 192.168.0.114 | 200 | 5.745161ms | POST | 未登录 | /testData/selection
2024-07-30 10:43:31 INFO | 192.168.0.114 | 200 | 10.297823ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:31 INFO | 192.168.0.114 | 200 | 11.781035ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:32 INFO | 192.168.0.114 | 200 | 12.930702ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:32 INFO | 192.168.0.114 | 200 | 10.178157ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:33 INFO | 192.168.0.114 | 200 | 10.414288ms | POST | 未登录 | /testData/histogram
2024-07-30 10:43:39 INFO | 192.168.0.114 | 200 | 2.715806155s | POST | 未登录 | /testData/report/packagePassProbabilityLine
2024-07-30 10:43:39 INFO | 192.168.0.114 | 200 | 2.72296078s | POST | 未登录 | /testData/report/packageOrderNumberBar
2024-07-30 14:03:16 INFO | 192.168.0.1 | 200 | 10.085227ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:03:18 INFO | 192.168.0.1 | 200 | 4.986805ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:04:59 INFO | 192.168.0.1 | 200 | 5.642606ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:05:00 INFO | 192.168.0.1 | 200 | 5.312574ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:07:54 INFO | 192.168.0.1 | 200 | 5.860555ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:08:07 INFO | 192.168.0.1 | 200 | 4.017191ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:08:48 INFO | 192.168.0.1 | 200 | 3.55621ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:08:50 INFO | 192.168.0.1 | 200 | 3.75124ms | POST | 未登录 | /testData/report/cp
2024-07-30 14:09:32 INFO | 192.168.0.1 | 200 | 2.896208ms | POST | 未登录 | /testData/report/cp
2024-07-31 10:48:12 INFO | 192.168.0.219 | 200 | 13.8484ms | POST | 未登录 | /testData/warning
2024-07-31 10:48:45 INFO | 192.168.0.219 | 200 | 12.2467596s | POST | 未登录 | /testData/warning
2024-07-31 10:49:05 INFO | 192.168.0.219 | 200 | 3.7431739s | POST | 未登录 | /testData/warning
2024-07-31 14:52:30 INFO | 192.168.0.219 | 200 | 12.41ms | POST | 未登录 | /testData/cpMap/all
2024-07-31 14:52:56 INFO | 192.168.0.219 | 200 | 6.8259ms | POST | 未登录 | /testData/cpMap/all
2024-07-31 15:01:03 INFO | 192.168.0.219 | 200 | 1m11.7962108s | POST | 未登录 | /testData/warning
2024-07-31 15:02:00 INFO | 192.168.0.219 | 200 | 41.5114837s | POST | 未登录 | /testData/warning
2024-07-31 15:04:06 INFO | 192.168.0.219 | 200 | 1m45.8499673s | POST | 未登录 | /testData/warning
2024-07-31 15:04:30 INFO | 192.168.0.219 | 200 | 9.2476348s | POST | 未登录 | /testData/warning
2024-08-01 09:18:03 INFO | 192.168.0.219 | 200 | 14h52m53.0976011s | POST | 未登录 | /testData/cpMap
2024-08-01 09:18:48 INFO | 192.168.0.219 | 200 | 41.6681267s | POST | 未登录 | /testData/cpMap
2024-08-06 16:41:30 INFO | 192.168.0.219 | 200 | 12.6715ms | POST | 未登录 | /testData/report/ft
2024-08-06 16:45:30 INFO | 192.168.0.219 | 200 | 1m12.2731158s | POST | 未登录 | /testData/report/ft
2024-08-08 17:52:42 INFO | 192.168.0.219 | 200 | 12.1432ms | POST | 未登录 | /testData/report/wafer
2024-08-08 17:53:11 INFO | 192.168.0.219 | 200 | 11.5016ms | POST | 未登录 | /testData/report/wafer
2024-08-08 17:53:57 INFO | 192.168.0.219 | 200 | 2.5051038s | POST | 未登录 | /testData/report/wafer
2024-08-08 17:54:27 INFO | 192.168.0.219 | 200 | 15.9895636s | POST | 未登录 | /testData/report/wafer
2024-08-08 17:54:45 INFO | 192.168.0.219 | 200 | 1.7887048s | POST | 未登录 | /testData/report/wafer
2024-08-08 18:02:52 INFO | 192.168.0.219 | 200 | 2.263282s | POST | 未登录 | /testData/report/wafer
2024-08-14 14:19:03 INFO | 192.168.0.1 | 200 | 13.550964ms | POST | 未登录 | /testData/report/wafer
2024-08-14 14:26:03 INFO | 192.168.0.1 | 200 | 15.547767ms | POST | 未登录 | /testData/report/wafer
2024-08-14 14:37:13 INFO | 192.168.0.248 | 200 | 6.00125ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:22:13 INFO | 192.168.0.219 | 200 | 2.654ms | POST | 未登录 | /testData/report/ab
2024-08-14 16:23:19 INFO | 192.168.0.1 | 200 | 18.514366ms | POST | 未登录 | /testData/report/ab
2024-08-14 16:35:22 INFO | 192.168.0.1 | 200 | 20.335032ms | POST | 未登录 | /testData/report/cp
2024-08-14 16:35:26 INFO | 192.168.0.1 | 200 | 17.026575ms | POST | 未登录 | /testData/report/cp
2024-08-14 16:45:15 INFO | 192.168.0.248 | 200 | 5.260246ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:45:49 INFO | 192.168.0.248 | 200 | 11.975476ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:46:42 INFO | 192.168.0.248 | 200 | 13.745757ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:46:56 INFO | 192.168.0.248 | 200 | 13.850555ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:48:01 INFO | 192.168.0.248 | 200 | 12.497572ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:48:19 INFO | 192.168.0.248 | 200 | 13.001357ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:48:56 INFO | 192.168.0.248 | 200 | 3.357544ms | POST | 未登录 | /testData/report/wafer
2024-08-14 16:49:07 INFO | 192.168.0.248 | 200 | 12.041145ms | POST | 未登录 | /testData/report/wafer
2024-08-14 17:00:44 INFO | 192.168.0.1 | 200 | 2.759803ms | POST | 未登录 | /testData/report/cp
2024-08-14 17:28:04 INFO | 192.168.0.1 | 200 | 28.675388ms | POST | 未登录 | /testData/report/cp
2024-08-14 17:28:16 INFO | 192.168.0.1 | 200 | 3.234754ms | POST | 未登录 | /testData/report/cp
2024-08-14 17:29:42 INFO | 192.168.0.1 | 200 | 9.007153ms | POST | 未登录 | /testData/report/cp
2024-08-14 17:29:55 INFO | 192.168.0.1 | 200 | 7.899442ms | POST | 未登录 | /testData/report/cp
2024-08-14 17:30:14 INFO | 192.168.0.1 | 200 | 2.526774ms | POST | 未登录 | /testData/report/cp
2024-08-14 17:37:35 INFO | 192.168.0.1 | 200 | 8.461872ms | POST | 未登录 | /testData/report/cp
2024-08-14 20:40:10 INFO | 8.142.165.189 | 200 | 196.03µs | GET | 未登录 | /
2024-08-14 20:40:11 INFO | 8.142.165.189 | 200 | 30.22µs | HEAD | 未登录 | /
2024-08-14 20:40:11 INFO | 8.142.165.189 | 200 | 28.48µs | GET | 未登录 | /dist/images/mask/guide/cn/step1.jpg
2024-08-14 20:40:11 INFO | 8.142.165.189 | 200 | 38.72µs | GET | 未登录 | /
2024-08-15 09:46:38 INFO | 192.168.0.1 | 200 | 12.888579ms | POST | 未登录 | /testData/report/cp
2024-08-15 09:47:39 INFO | 192.168.0.1 | 200 | 9.340834ms | POST | 未登录 | /testData/report/cp
2024-08-15 09:47:47 INFO | 192.168.0.1 | 200 | 9.443075ms | POST | 未登录 | /testData/report/cp
2024-08-15 09:49:36 INFO | 192.168.0.248 | 200 | 23.747777ms | POST | 未登录 | /testData/report/ab
2024-08-15 09:51:28 INFO | 192.168.0.1 | 200 | 8.787141ms | POST | 未登录 | /testData/report/cp
2024-08-15 09:51:29 INFO | 192.168.0.248 | 200 | 23.4657ms | POST | 未登录 | /testData/report/ab
2024-08-15 10:04:29 INFO | 192.168.0.1 | 200 | 9.701556ms | POST | 未登录 | /testData/report/cp
2024-08-15 10:04:29 INFO | 192.168.0.248 | 200 | 19.636231ms | POST | 未登录 | /testData/report/ab
2024-08-15 10:04:32 INFO | 192.168.0.248 | 200 | 3.923025ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:20:50 INFO | 192.168.0.248 | 200 | 4.170466ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:27:02 INFO | 192.168.0.248 | 200 | 2.432015ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:27:41 INFO | 192.168.0.248 | 200 | 2.609103ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:27:51 INFO | 192.168.0.248 | 200 | 22.721457ms | POST | 未登录 | /testData/report/ab
2024-08-15 10:28:20 INFO | 192.168.0.248 | 200 | 2.922794ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:29:31 INFO | 192.168.0.248 | 200 | 2.610235ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:30:19 INFO | 192.168.0.248 | 200 | 3.185415ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:30:47 INFO | 192.168.0.248 | 200 | 3.434475ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:30:50 INFO | 192.168.0.248 | 200 | 2.436445ms | POST | 未登录 | /testData/report/bp
2024-08-15 10:35:47 INFO | 192.168.0.1 | 200 | 6.64381ms | POST | 未登录 | /testData/report/ft
2024-08-15 11:44:43 INFO | 192.168.0.1 | 200 | 45.23615ms | POST | 未登录 | /testData/report/ft
2024-08-15 11:44:51 INFO | 192.168.0.1 | 200 | 9.668052ms | POST | 未登录 | /testData/report/ft
2024-08-15 11:44:53 INFO | 192.168.0.1 | 200 | 7.066812ms | POST | 未登录 | /testData/report/ft
2024-08-15 11:45:09 INFO | 192.168.0.1 | 200 | 12.509832ms | POST | 未登录 | /testData/report/ft
2024-08-15 11:45:13 INFO | 192.168.0.1 | 200 | 8.28618ms | POST | 未登录 | /testData/report/ft
2024-08-15 13:58:39 INFO | 192.168.0.1 | 200 | 8.615503ms | POST | 未登录 | /testData/report/ft
2024-08-15 13:58:45 INFO | 192.168.0.1 | 200 | 37.609131ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:00:41 INFO | 192.168.0.1 | 200 | 8.757905ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:09:18 INFO | 192.168.0.248 | 200 | 5.740459ms | POST | 未登录 | /testData/report/tr
2024-08-15 14:10:44 INFO | 192.168.0.1 | 200 | 19.041047ms | POST | 未登录 | /testData/report/ab
2024-08-15 14:13:33 INFO | 192.168.0.248 | 200 | 3.948245ms | POST | 未登录 | /testData/report/tr
2024-08-15 14:13:58 INFO | 192.168.0.248 | 200 | 4.072285ms | POST | 未登录 | /testData/report/bp
2024-08-15 14:25:38 INFO | 192.168.0.1 | 200 | 43.145855ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:26:33 INFO | 192.168.0.1 | 200 | 19.716416ms | POST | 未登录 | /testData/report/ab
2024-08-15 14:35:44 INFO | 192.168.0.1 | 200 | 9.588763ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:45:29 INFO | 192.168.0.1 | 200 | 17.938428ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:45:32 INFO | 192.168.0.1 | 200 | 8.049303ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:47:16 INFO | 192.168.0.1 | 200 | 12.105178ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:50:28 INFO | 192.168.0.1 | 200 | 16.702352ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:53:23 INFO | 192.168.0.1 | 200 | 9.615154ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:53:45 INFO | 192.168.0.1 | 200 | 43.319765ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:53:51 INFO | 192.168.0.1 | 200 | 3.739616ms | POST | 未登录 | /testData/report/bp
2024-08-15 14:54:06 INFO | 192.168.0.1 | 200 | 7.459971ms | POST | 未登录 | /testData/report/tr
2024-08-15 14:54:13 INFO | 192.168.0.1 | 200 | 5.085087ms | POST | 未登录 | /testData/report/tr
2024-08-15 14:57:52 INFO | 192.168.0.248 | 200 | 69.500323ms | POST | 未登录 | /testData/report/ft
2024-08-15 14:58:30 INFO | 192.168.0.248 | 200 | 386.361µs | GET | 未登录 | /docs/index.html
2024-08-15 14:58:31 INFO | 192.168.0.248 | 200 | 4.260286ms | GET | 未登录 | /docs/swagger-ui.css
2024-08-15 14:58:31 INFO | 192.168.0.248 | 200 | 2.638093ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-15 14:58:31 INFO | 192.168.0.248 | 200 | 9.916285ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-15 14:58:31 INFO | 192.168.0.248 | 200 | 640.491µs | GET | 未登录 | /docs/doc.json
2024-08-15 14:58:31 INFO | 192.168.0.248 | 200 | 148.3µs | GET | 未登录 | /docs/favicon-32x32.png
2024-08-15 14:59:58 INFO | 192.168.0.248 | 200 | 78.696591ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:00:05 INFO | 192.168.0.248 | 200 | 81.734542ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:00:35 INFO | 192.168.0.248 | 200 | 11.549865ms | POST | 未登录 | /testData/report/cp
2024-08-15 15:01:32 INFO | 192.168.0.219 | 200 | 181.341µs | GET | 未登录 | /docs/index.html
2024-08-15 15:01:55 INFO | 192.168.0.219 | 200 | 405.361µs | GET | 未登录 | /docs/index.html
2024-08-15 15:01:55 INFO | 192.168.0.219 | 200 | 729.201µs | GET | 未登录 | /docs/swagger-ui.css
2024-08-15 15:01:55 INFO | 192.168.0.219 | 200 | 4.127166ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-15 15:01:55 INFO | 192.168.0.219 | 200 | 13.658731ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-15 15:01:55 INFO | 192.168.0.219 | 200 | 425.871µs | GET | 未登录 | /docs/doc.json
2024-08-15 15:01:55 INFO | 192.168.0.219 | 200 | 25.02µs | GET | 未登录 | /docs/favicon-32x32.png
2024-08-15 15:02:32 INFO | 192.168.0.219 | 200 | 93.32µs | GET | 未登录 | /docs/index.html
2024-08-15 15:02:32 INFO | 192.168.0.219 | 304 | 41.45µs | GET | 未登录 | /docs/swagger-ui.css
2024-08-15 15:02:32 INFO | 192.168.0.219 | 304 | 35.73µs | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-15 15:02:32 INFO | 192.168.0.219 | 304 | 26.65µs | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-15 15:02:32 INFO | 192.168.0.219 | 200 | 460.45µs | GET | 未登录 | /docs/doc.json
2024-08-15 15:02:32 INFO | 192.168.0.219 | 304 | 28.16µs | GET | 未登录 | /docs/favicon-32x32.png
2024-08-15 15:02:43 INFO | 192.168.0.219 | 200 | 520.141µs | GET | 未登录 | /docs/index.html
2024-08-15 15:02:43 INFO | 192.168.0.219 | 200 | 838.251µs | GET | 未登录 | /docs/swagger-ui.css
2024-08-15 15:02:43 INFO | 192.168.0.219 | 200 | 6.966422ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-15 15:02:43 INFO | 192.168.0.219 | 200 | 4.733767ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-15 15:02:43 INFO | 192.168.0.219 | 200 | 608.261µs | GET | 未登录 | /docs/doc.json
2024-08-15 15:02:43 INFO | 192.168.0.219 | 200 | 77.57µs | GET | 未登录 | /docs/favicon-32x32.png
2024-08-15 15:02:46 INFO | 192.168.0.248 | 200 | 196.3µs | GET | 未登录 | /docs/index.html
2024-08-15 15:02:46 INFO | 192.168.0.248 | 200 | 766.861µs | GET | 未登录 | /docs/swagger-ui.css
2024-08-15 15:02:46 INFO | 192.168.0.248 | 200 | 1.839123ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-15 15:02:46 INFO | 192.168.0.248 | 200 | 17.460715ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-15 15:02:46 INFO | 192.168.0.248 | 200 | 471.27µs | GET | 未登录 | /docs/doc.json
2024-08-15 15:02:46 INFO | 192.168.0.248 | 200 | 41.2µs | GET | 未登录 | /docs/favicon-32x32.png
2024-08-15 15:08:44 INFO | 192.168.0.1 | 200 | 16.701791ms | POST | 未登录 | /testData/selection
2024-08-15 15:25:08 INFO | 192.168.0.1 | 200 | 39.667157ms | POST | 未登录 | /testData/report/ab
2024-08-15 15:25:10 INFO | 192.168.0.1 | 200 | 34.439115ms | POST | 未登录 | /testData/report/ab
2024-08-15 15:25:23 INFO | 192.168.0.248 | 200 | 68.99426ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:26:57 INFO | 192.168.0.248 | 200 | 74.410302ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:36:38 INFO | 192.168.0.248 | 200 | 65.295601ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:37:49 INFO | 192.168.0.248 | 200 | 66.641281ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:37:51 INFO | 192.168.0.248 | 200 | 8.515655ms | POST | 未登录 | /testData/report/cp
2024-08-15 15:39:03 INFO | 192.168.0.248 | 200 | 67.698489ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:39:21 INFO | 192.168.0.248 | 200 | 83.417261ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:39:36 INFO | 192.168.0.248 | 200 | 82.252005ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:40:47 INFO | 192.168.0.248 | 200 | 83.938553ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:41:06 INFO | 192.168.0.248 | 200 | 92.653321ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:41:20 INFO | 192.168.0.248 | 200 | 78.585352ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:42:14 INFO | 192.168.0.248 | 200 | 79.736328ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:42:33 INFO | 192.168.0.248 | 200 | 9.441052ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:42:48 INFO | 192.168.0.248 | 200 | 75.836924ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:42:55 INFO | 192.168.0.248 | 200 | 30.829581ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:43:00 INFO | 192.168.0.248 | 200 | 75.80017ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:43:21 INFO | 192.168.0.248 | 200 | 89.649537ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:52:46 INFO | 192.168.0.248 | 200 | 97.914484ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:52:57 INFO | 192.168.0.248 | 200 | 100.69554ms | POST | 未登录 | /testData/report/ft
2024-08-15 15:52:59 INFO | 192.168.0.248 | 200 | 399.413186ms | POST | 未登录 | /testData/report/ft/export
2024-08-15 15:52:59 INFO | 192.168.0.248 | 200 | 12.258815ms | GET | 未登录 | /files/2024-08/%E8%AE%B0%E5%BD%95/CP%E8%AE%B0%E5%BD%952024-08-15_155259.xlsx
2024-08-15 16:17:02 INFO | 192.168.0.248 | 200 | 10.747659ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:23:07 INFO | 192.168.0.248 | 200 | 8.074607ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:23:34 INFO | 192.168.0.248 | 200 | 7.226194ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:24:06 INFO | 192.168.0.248 | 200 | 7.898232ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:29:33 INFO | 192.168.0.219 | 200 | 635.27µs | GET | 未登录 | /docs/swagger-ui.css
2024-08-15 16:29:33 INFO | 192.168.0.219 | 200 | 4.27511ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-15 16:29:33 INFO | 192.168.0.219 | 200 | 11.029059ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-15 16:29:34 INFO | 192.168.0.219 | 200 | 596.75µs | GET | 未登录 | /docs/doc.json
2024-08-15 16:29:34 INFO | 192.168.0.1 | 200 | 8.066799ms | POST | 未登录 | /testData/report/tr
2024-08-15 16:30:28 INFO | 192.168.0.248 | 200 | 12.271599ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:30:42 INFO | 192.168.0.248 | 200 | 13.095298ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:31:35 INFO | 192.168.0.248 | 200 | 10.006749ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:31:41 INFO | 192.168.0.248 | 200 | 19.958138ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:32:01 INFO | 192.168.0.248 | 200 | 8.832355ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:32:04 INFO | 192.168.0.248 | 200 | 24.925558ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:32:18 INFO | 192.168.0.248 | 200 | 10.855038ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:32:49 INFO | 192.168.0.248 | 200 | 11.759789ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:37:33 INFO | 192.168.0.248 | 200 | 5.37815ms | POST | 未登录 | /testData/report/tr
2024-08-15 16:38:11 INFO | 192.168.0.248 | 200 | 5.591179ms | POST | 未登录 | /testData/report/tr
2024-08-15 16:39:04 INFO | 192.168.0.248 | 200 | 90.925979ms | POST | 未登录 | /testData/report/ft
2024-08-15 16:47:53 INFO | 192.168.0.248 | 200 | 84.713464ms | POST | 未登录 | /testData/report/ft
2024-08-15 16:47:56 INFO | 192.168.0.248 | 200 | 10.786048ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:48:43 INFO | 192.168.0.248 | 200 | 23.665701ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:48:50 INFO | 192.168.0.248 | 200 | 20.527946ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:52:00 INFO | 192.168.0.248 | 200 | 31.799185ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:52:09 INFO | 192.168.0.248 | 200 | 21.233747ms | POST | 未登录 | /testData/report/cp
2024-08-15 16:52:11 INFO | 192.168.0.248 | 200 | 79.845411ms | POST | 未登录 | /testData/report/ft
2024-08-15 16:55:06 INFO | 192.168.0.248 | 200 | 14.432765ms | POST | 未登录 | /testData/report/wafer
2024-08-15 16:57:10 INFO | 192.168.0.248 | 200 | 12.563091ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:00:05 INFO | 192.168.0.248 | 200 | 8.350954ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:00:33 INFO | 192.168.0.248 | 200 | 10.552539ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:01:27 INFO | 192.168.0.248 | 200 | 10.201767ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:04:06 INFO | 192.168.0.248 | 200 | 39.371167ms | POST | 未登录 | /testData/report/ab
2024-08-15 17:06:27 INFO | 192.168.0.248 | 200 | 34.319569ms | POST | 未登录 | /testData/report/ab
2024-08-15 17:06:33 INFO | 192.168.0.248 | 200 | 35.518011ms | POST | 未登录 | /testData/report/ab
2024-08-15 17:19:51 INFO | 192.168.0.248 | 200 | 14.548567ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:19:55 INFO | 192.168.0.248 | 200 | 82.422784ms | POST | 未登录 | /testData/report/ft
2024-08-15 17:20:57 INFO | 192.168.0.248 | 200 | 75.602545ms | POST | 未登录 | /testData/report/ft
2024-08-15 17:21:49 INFO | 192.168.0.248 | 200 | 16.967649ms | POST | 未登录 | /testData/report/cp
2024-08-15 17:22:02 INFO | 192.168.0.248 | 200 | 3.863147ms | POST | 未登录 | /testData/report/bp
2024-08-15 17:24:34 INFO | 192.168.0.248 | 200 | 1.897013ms | POST | 未登录 | /testData/report/bp
2024-08-15 17:24:45 INFO | 192.168.0.248 | 200 | 2.076574ms | POST | 未登录 | /testData/report/bp
2024-08-15 17:24:48 INFO | 192.168.0.248 | 200 | 2.275984ms | POST | 未登录 | /testData/report/bp
2024-08-15 17:26:01 INFO | 192.168.0.248 | 200 | 2.817256ms | POST | 未登录 | /testData/report/bp
2024-08-15 17:26:05 INFO | 192.168.0.248 | 200 | 4.105798ms | POST | 未登录 | /testData/report/tr
2024-08-15 17:26:33 INFO | 192.168.0.248 | 200 | 4.315717ms | POST | 未登录 | /testData/report/tr
2024-08-15 17:26:39 INFO | 192.168.0.248 | 200 | 4.43678ms | POST | 未登录 | /testData/report/tr
2024-08-15 17:26:47 INFO | 192.168.0.248 | 200 | 2.222764ms | POST | 未登录 | /testData/report/bp
2024-08-15 17:26:49 INFO | 192.168.0.248 | 200 | 18.464695ms | POST | 未登录 | /testData/report/cp
2024-08-15 17:26:51 INFO | 192.168.0.248 | 200 | 88.041998ms | POST | 未登录 | /testData/report/ft
2024-08-15 17:26:53 INFO | 192.168.0.248 | 200 | 25.450627ms | POST | 未登录 | /testData/report/ab
2024-08-15 17:26:54 INFO | 192.168.0.248 | 200 | 13.948424ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:27:36 INFO | 192.168.0.248 | 200 | 10.1484ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:27:36 INFO | 192.168.0.1 | 200 | 3.756906ms | POST | 未登录 | /testData/report/tr
2024-08-15 17:27:37 INFO | 192.168.0.1 | 200 | 79.867531ms | POST | 未登录 | /testData/report/ft
2024-08-15 17:27:47 INFO | 192.168.0.248 | 200 | 10.668629ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:27:47 INFO | 192.168.0.1 | 200 | 3.714977ms | POST | 未登录 | /testData/report/tr
2024-08-15 17:27:47 INFO | 192.168.0.1 | 200 | 77.219307ms | POST | 未登录 | /testData/report/ft
2024-08-15 17:28:06 INFO | 192.168.0.248 | 200 | 9.432676ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:28:06 INFO | 192.168.0.1 | 200 | 3.676936ms | POST | 未登录 | /testData/report/tr
2024-08-15 17:28:07 INFO | 192.168.0.1 | 200 | 103.0871ms | POST | 未登录 | /testData/report/ft
2024-08-15 17:43:25 INFO | 192.168.0.248 | 200 | 15.549357ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:43:37 INFO | 192.168.0.248 | 200 | 1.670573ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:43:39 INFO | 192.168.0.248 | 200 | 14.588236ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:43:43 INFO | 192.168.0.248 | 200 | 1.262472ms | POST | 未登录 | /testData/report/wafer
2024-08-15 17:45:24 INFO | 192.168.0.248 | 200 | 13.567804ms | POST | 未登录 | /testData/report/wafer
2024-08-15 18:14:48 INFO | 192.168.0.248 | 200 | 7.944314ms | POST | 未登录 | /testData/report/tr
2024-08-16 09:27:57 INFO | 192.168.0.248 | 200 | 9.172692ms | POST | 未登录 | /testData/report/tr
2024-08-16 09:49:44 INFO | 192.168.0.248 | 200 | 9.250031ms | POST | 未登录 | /testData/report/tr
2024-08-16 09:50:02 INFO | 192.168.0.248 | 200 | 3.526815ms | POST | 未登录 | /testData/report/tr
2024-08-16 09:50:12 INFO | 192.168.0.248 | 200 | 5.996027ms | POST | 未登录 | /testData/report/tr
2024-08-16 09:50:34 INFO | 192.168.0.248 | 200 | 6.776659ms | POST | 未登录 | /testData/report/tr
2024-08-16 10:07:41 INFO | 192.168.0.1 | 200 | 8.04361ms | POST | 未登录 | /testData/report/tr
2024-08-16 10:07:48 INFO | 192.168.0.1 | 200 | 5.442117ms | POST | 未登录 | /testData/report/tr
2024-08-23 15:24:20 INFO | 192.168.0.219 | 200 | 527.9µs | GET | 未登录 | /docs/index.html
2024-08-23 15:24:20 INFO | 192.168.0.219 | 200 | 260.5µs | GET | 未登录 | /docs/swagger-ui.css
2024-08-23 15:24:20 INFO | 192.168.0.219 | 200 | 1.0233ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-23 15:24:20 INFO | 192.168.0.219 | 200 | 90.9µs | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-23 15:24:20 INFO | 192.168.0.219 | 200 | 600.1µs | GET | 未登录 | /docs/doc.json
2024-08-23 15:24:20 INFO | 192.168.0.219 | 200 | 0s | GET | 未登录 | /docs/favicon-32x32.png
2024-08-23 15:29:36 INFO | 192.168.0.248 | 200 | 0s | GET | 未登录 | /docs/index.html
2024-08-23 15:29:36 INFO | 192.168.0.248 | 200 | 2.0664ms | GET | 未登录 | /docs/swagger-ui.css
2024-08-23 15:29:36 INFO | 192.168.0.248 | 200 | 3.5538ms | GET | 未登录 | /docs/swagger-ui-standalone-preset.js
2024-08-23 15:29:36 INFO | 192.168.0.248 | 200 | 16.8957ms | GET | 未登录 | /docs/swagger-ui-bundle.js
2024-08-23 15:29:36 INFO | 192.168.0.248 | 200 | 752µs | GET | 未登录 | /docs/doc.json
2024-08-23 15:29:36 INFO | 192.168.0.248 | 200 | 139.6µs | GET | 未登录 | /docs/favicon-32x32.png

13
main.go
View File

@ -2,6 +2,7 @@ package main
import ( import (
"testData/initialization" "testData/initialization"
test_data "testData/repository/test.data"
) )
func main() { func main() {
@ -23,7 +24,17 @@ func main() {
//for _, fileHandle := range fileHandles { //for _, fileHandle := range fileHandles {
// var report *model.Report // var report *model.Report
// global.PostGreSQL.Where("product = ? AND lot = ? AND wafer_id = ?", "TP2202B", "EP5NYR.1", fileHandle.WaferID).Find(&report) // global.PostGreSQL.Where("product = ? AND lot = ? AND wafer_id = ?", "TP2202B", "EP5NYR.1", fileHandle.WaferID).Find(&report)
// test_data.SaveCP(fileHandle.Product, fileHandle.Lot, fileHandle.WaferID, report) // test_data.SaveCP(fileHandle.PBI, fileHandle.Product, fileHandle.Lot, fileHandle.WaferID, report)
//} //}
//fmt.Println(test_data.LotInAFile("TP2212B", "EP8HDR.1", "M591-2208220003", "", "01", "CP1+CP2"))
//report_reader.FTSMCReportReader("./SMC-3月.xlsx")
//test_data.CronWaferList()
//test_data.CronABList()
//test_data.CronBPList()
//test_data.CronCPList()
//test_data.CronFTList()
//test_data.CronTRList()
//initialization.InitCronListCron()
test_data.ExportFT()
initialization.RunServer() initialization.RunServer()
} }

View File

@ -15,18 +15,20 @@ type TcSfcFile struct {
func (TcSfcFile) TableName() string { return "tc_sfc_file" } func (TcSfcFile) TableName() string { return "tc_sfc_file" }
type TcSfdFile struct { type TcSfdFile struct {
TcSfd01 string `json:"tc_sfd01"` // PBI TcSfd01 string `json:"tc_sfd01"` // PBI
TcSfd02 int `json:"tc_sfd02"` // 回货项次 TcSfd02 int `json:"tc_sfd02"` // 回货项次
TcSfd03 string `json:"tc_sfd03"` // 料号 TcSfd03 string `json:"tc_sfd03"` // 料号
ImaFile ImaFile `gorm:"foreignKey:Ima01;references:TcSfd03"` ImaFile ImaFile `gorm:"foreignKey:Ima01;references:TcSfd03"`
TcSfd05 float64 `json:"tc_sfd05"` // 数量 TcImbFile TcImbFile `gorm:"foreignKey:TcImb01;references:TcSfd03"`
TcSfd06 string `json:"tc_sfd06"` // 批号 TcSfd05 float64 `json:"tc_sfd05"` // 数量
TcSfd13 string `json:"tc_sfd13"` // 委外工单号 TcSfd06 string `json:"tc_sfd06"` // 批号
SfbFile SfbFile `gorm:"foreignKey:Sfb01;references:TcSfd13"` TcSfd13 string `json:"tc_sfd13"` // 委外工单号
SfbFile SfbFile `gorm:"foreignKey:Sfb01;references:TcSfd13"`
RvbFile []RvbFile `gorm:"foreignKey:Rvb34;references:TcSfd13"`
//RvbFile []RvbFile `gorm:"foreignKey:Rvb34;references:TcSfd13"` //RvbFile []RvbFile `gorm:"foreignKey:Rvb34;references:TcSfd13"`
TcSfd14 string `json:"tc_sfd14"` // 委外采购单号 TcSfd14 string `json:"tc_sfd14"` // 委外采购单号
RvaFile []RvaFile `gorm:"foreignKey:Rva02;references:TcSfd14"` RvaFile RvaFile `gorm:"foreignKey:Rva02;references:TcSfd14"`
TcSfdUd02 string `json:"tc_sfdud02" gorm:"column:TC_SFDUD02"` // 丝印 TcSfdUd02 string `json:"tc_sfdud02" gorm:"column:TC_SFDUD02"` // 丝印
} }
func (TcSfdFile) TableName() string { return "tc_sfd_file" } func (TcSfdFile) TableName() string { return "tc_sfd_file" }
@ -37,12 +39,22 @@ type TcSfeFile struct {
TcSfe04 string `json:"tc_sfe04"` // 料号 TcSfe04 string `json:"tc_sfe04"` // 料号
ImaFile ImaFile `gorm:"foreignKey:Ima01;references:TcSfe04"` ImaFile ImaFile `gorm:"foreignKey:Ima01;references:TcSfe04"`
TcSfe10 string `json:"tc_sfe10"` // 晶圆批号 TcSfe10 string `json:"tc_sfe10"` // 晶圆批号
TcSfe12 float64 `json:"tc_sfe12"` // 发料数量
TcSfe14 float64 `json:"tc_sfe14"` // 参考数量
TcSfe15 string `json:"tc_sfe15"` // 片号 TcSfe15 string `json:"tc_sfe15"` // 片号
TcSfe17 string `json:"tc_sfe17"` // 是否主芯 TcSfe17 string `json:"tc_sfe17"` // 是否主芯
} }
func (TcSfeFile) TableName() string { return "tc_sfe_file" } func (TcSfeFile) TableName() string { return "tc_sfe_file" }
type TcImbFile struct {
TcImb01 string `json:"tc_imb01"` // 料号
TcImb03 string `json:"tc_imb03"` // 测试程序
TcImb04 string `json:"tc_imb04"` // 测试程序版本
}
func (TcImbFile) TableName() string { return "tc_imb_file" }
type ImaFile struct { type ImaFile struct {
Ima01 string `json:"ima01"` // 料号 Ima01 string `json:"ima01"` // 料号
Ima02 string `json:"ima02"` // 型号 Ima02 string `json:"ima02"` // 型号
@ -55,7 +67,8 @@ type PmmFile struct {
Pmm01 string `json:"pmm01"` // 采购单号 Pmm01 string `json:"pmm01"` // 采购单号
Pmm04 time.Time `json:"pmm04"` // 采购日期 Pmm04 time.Time `json:"pmm04"` // 采购日期
Pmm09 string `json:"pmm09"` // 供应厂商编号 Pmm09 string `json:"pmm09"` // 供应厂商编号
PmnFile PmnFile `gorm:"foreignKey:Pmn01;references:Pmm01"` Pmm25 string `json:"pmm25"` // 状态码
PmnFile []PmnFile `gorm:"foreignKey:Pmn01;references:Pmm01"`
PmcFile PmcFile `gorm:"foreignKey:Pmc01;references:Pmm09"` PmcFile PmcFile `gorm:"foreignKey:Pmc01;references:Pmm09"`
RvbFile []RvbFile `gorm:"foreignKey:Rvb04;references:Pmm01"` RvbFile []RvbFile `gorm:"foreignKey:Rvb04;references:Pmm01"`
} }
@ -63,7 +76,9 @@ type PmmFile struct {
func (PmmFile) TableName() string { return "pmm_file" } func (PmmFile) TableName() string { return "pmm_file" }
type PmnFile struct { type PmnFile struct {
Pmn01 string `json:"pmn01"` Pmn01 string `json:"pmn01"`
//PmmFile PmmFile `json:"pmm_file" gorm:"foreignKey:Pmm01;references:Pmn01"`
Pmn02 string `json:"pmn02"`
Pmn04 string `json:"pmn04"` // 料件编号 Pmn04 string `json:"pmn04"` // 料件编号
ImaFile ImaFile `gorm:"foreignKey:Ima01;references:Pmn04"` ImaFile ImaFile `gorm:"foreignKey:Ima01;references:Pmn04"`
Pmn20 float64 `json:"pmn20"` // 采购量 Pmn20 float64 `json:"pmn20"` // 采购量
@ -77,8 +92,9 @@ func (PmnFile) TableName() string { return "pmn_file" }
type RvaFile struct { type RvaFile struct {
Rva01 string `json:"rva01"` // 收货单号 Rva01 string `json:"rva01"` // 收货单号
IddFile []IddFile `gorm:"foreignKey:Idd10;references:Rva01"` IddFile []IddFile `gorm:"foreignKey:Idd10;references:Rva01"`
RvbFile []RvbFile `gorm:"foreignKey:Rvb01;references:Rva01"`
Rva02 string `json:"rva02"` // 采购单号 Rva02 string `json:"rva02"` // 采购单号
Rva06 string `json:"rva06"` Rva06 time.Time `json:"rva06"` //收货日期
} }
func (RvaFile) TableName() string { return "rva_file" } func (RvaFile) TableName() string { return "rva_file" }
@ -99,14 +115,21 @@ type PmcFile struct {
func (PmcFile) TableName() string { return "pmc_file" } func (PmcFile) TableName() string { return "pmc_file" }
type RvbFile struct { type RvbFile struct {
Rvb01 string `json:"rvb01"` // 收货单号 Rvb01 string `json:"rvb01"` // 收货单号
//IddFile IddFile `gorm:"foreignKey:Idd10;references:Rvb01"` RvaFile RvaFile `gorm:"foreignKey:Rva01;references:Rvb01"`
Rvb04 string `json:"rvb04"` // 采购单号 IddFile []IddFile `gorm:"foreignKey:Idd10;references:Rvb01"`
Rvb12 time.Time `json:"rvb12"` // 收货日期 Rvb02 string `json:"rvb02"` // 项次
Rvb29 float64 `json:"rvb29"` // 退货量 Rvb03 string `json:"rvb03"`
Rvb30 float64 `json:"rvb30"` // 入库数 Rvb04 string `json:"rvb04"` // 采购单号
Rvb34 string `json:"rvb34"` // PBI Rvb05 string `json:"rvb05"`
Rvb38 string `json:"rvb38"` // 批号 ImaFile ImaFile `json:"ima_file" gorm:"foreignKey:Ima01;references:Rvb05"`
Rvb12 time.Time `json:"rvb12"` // 收货日期
Rvb29 float64 `json:"rvb29"` // 退货量
Rvb30 float64 `json:"rvb30"` // 入库数
Rvb34 string `json:"rvb34"` // 委外单号
Rvb38 string `json:"rvb38"` // 批号
Rvb82 float64 `json:"rvb82"` // 收货数量
Rvb85 float64 `json:"rvb85"` // DIE数量
} }
func (RvbFile) TableName() string { return "rvb_file" } func (RvbFile) TableName() string { return "rvb_file" }
@ -114,9 +137,12 @@ func (RvbFile) TableName() string { return "rvb_file" }
type IddFile struct { type IddFile struct {
Idd01 string `json:"idd01"` // 料号 Idd01 string `json:"idd01"` // 料号
Idd04 string `json:"idd04"` // 批号 Idd04 string `json:"idd04"` // 批号
Idd05 string `json:"idd05"` // 片号
Idd06 string `json:"idd06"` // 良品/不良品 Idd06 string `json:"idd06"` // 良品/不良品
Idd10 string `json:"idd10"` // 收货单号 Idd10 string `json:"idd10"` // 收货单号
Idd11 string `json:"idd11"` // 收货项次
Idd13 float64 `json:"idd13"` // 数量 Idd13 float64 `json:"idd13"` // 数量
Idd16 string `json:"idd16"` // 批次
} }
func (IddFile) TableName() string { return "idd_file" } func (IddFile) TableName() string { return "idd_file" }

25
model/export.go Normal file
View File

@ -0,0 +1,25 @@
package model
type ExportFT struct {
Product string `json:"product"` // 成品型号
Lot string `json:"lot"` // 批号
PBI string `json:"pbi"` // PBI(订单号)
Factory string `json:"factory"` // 测试厂
TestProgram string `json:"test_program"` // 测试程序
OrderDate string `json:"order_date"` // 下单日期(订单日期)
Seal string `json:"seal"` // 丝印
FinalTestQuantity string `json:"final_test_quantity"` // 结批测试数量
FinalPassQuantity string `json:"final_pass_quantity"` // 结批良品数量
FinalPassProbability string `json:"final_pass_probability"` // 结批良率
FirstPassQuantity string `json:"first_pass_quantity"` // 初测良品数量
FirstPassProbability string `json:"first_pass_probability"` // 初测良率
TestQuantity string `json:"test_quantity"` // 测试数量
PassQuantity string `json:"pass_quantity"` // 良品数量(包括回收数据)
PassProbability string `json:"pass_probability"` // 良率(包括回收数据)
ReturnProbability string `json:"return_probability"` // 回收率
TestQuantityDiff string `json:"test_quantity_diff"` // 测试数量差异
PassQuantityDiff string `json:"pass_quantity_diff"` // 良品数量差异
HardBinState string `json:"hard_bin_state"` // 硬件Bin
SiteDiffState string `json:"site_diff_state"` // SITE差异
StackingMaterials string `json:"stacking_materials"` // 叠料风险
}

View File

@ -6,62 +6,82 @@ import (
) )
type Report struct { type Report struct {
ID int64 `json:"id" gorm:"primaryKey"` ID int64 `json:"id" gorm:"primaryKey"`
Product string `json:"product"` // 成品型号 Step string `json:"step"` // 工序
Lot string `json:"lot"` //晶圆批次 Product string `json:"product"` // 成品型号
Factory string `json:"factory"` // 测试厂 Lot string `json:"lot"` //晶圆批次
TestMachine string `json:"test_machine"` // 测试机台 Factory string `json:"factory"` // 测试厂
TestProgram string `json:"test_program"` // 测试程序 TestMachine string `json:"test_machine"` // 测试机台
PBI string `json:"pbi"` // PBI TestProgram string `json:"test_program"` // 测试程序
SubBatch string `json:"sub_batch"` // 子批次 PBI string `json:"pbi"` // PBI
OrderDate string `json:"order_date"` // 下单日期 SubBatch string `json:"sub_batch"` // 子批次
Seal string `json:"seal"` // 丝印 OrderDate string `json:"order_date"` // 下单日期
TestQuantity string `json:"test_quantity"` // 测试数量 Seal string `json:"seal"` // 丝印
FirstPassQuantity string `json:"first_pass_quantity"` // 初测良品数量 // Log File
FirstPassProbability string `json:"first_pass_probability"` // 初测良率 TestQuantity string `json:"test_quantity"` // 测试数量
PassQuantity string `json:"pass_quantity"` // 良品数量(包括回收数据) FirstPassQuantity string `json:"first_pass_quantity"` // 初测良品数量
PassProbability string `json:"pass_probability"` // 良率(包括回收数据) FirstPassProbability string `json:"first_pass_probability"` // 初测良率
WaferID string `json:"wafer_id"` // 片号 PassQuantity string `json:"pass_quantity"` // 良品数量(包括回收数据)
TestTime string `json:"test_time"` // 测试时间 PassProbability string `json:"pass_probability"` // 良率(包括回收数据)
Step string `json:"step"` // 工序 // Report File
StackingMaterials bool `json:"stacking_materials"` // 是否叠料 //ReportTestQuantity string `json:"report_test_quantity"` // 结批测试数量
BinFail []BinFail `json:"bin_fail" gorm:"foreignKey:ReportID"` // 硬件和软件Bin的不良数量 //ReportPassQuantity string `json:"report_pass_quantity"` // 结批良品数量
Site []ReportSites `json:"site" gorm:"foreignKey:ReportID"` // Site测试情况 //ReportPassProbability string `json:"report_pass_probability"` // 结批良率
CreatedAt time.Time `json:"created_at"` //Bin2 string `json:"bin2"`
UpdatedAt time.Time `json:"-"` //Bin3 string `json:"bin3"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` //Bin4 string `json:"bin4"`
//Bin5 string `json:"bin5"`
//Bin6 string `json:"bin6"`
//Bin7 string `json:"bin7"`
//Bin8 string `json:"bin8"`
//Bin9 string `json:"bin9"`
//Bin10 string `json:"bin10"`
//OutlookFail string `json:"outlook_fail"` // 外观不良
//Other string `json:"other"` // 少数
//BentStitch string `json:"bent_stitch"` // 弯脚
//Scrapped string `json:"scrapped"` // 报废
WaferID string `json:"wafer_id"` // 片号
TestTime string `json:"test_time"` // 测试时间
StackingMaterials bool `json:"stacking_materials"` // 是否叠料
BinFail []BinFail `json:"bin_fail" gorm:"foreignKey:ReportID"` // 硬件和软件Bin的不良数量
Site []ReportSites `json:"site" gorm:"foreignKey:ReportID"` // Site测试情况
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
} }
type FinalReport struct { type FinalReport struct {
ID int64 `json:"id" gorm:"primaryKey"` ID int64 `json:"id" gorm:"primaryKey"`
Step string `json:"step"` Step string `json:"step"`
Product string `json:"product"` // 成品型号 Product string `json:"product"` // 成品型号
Lot string `json:"lot"` // 晶圆批次 Lot string `json:"lot"` // 晶圆批次
Factory string `json:"factory"` // 测试厂 Factory string `json:"factory"` // 测试厂
TestProgram string `json:"test_program"` // 测试程序 TestProgram string `json:"test_program"` // 测试程序
PBI string `json:"pbi"` // PBI PBI string `json:"pbi"` // PBI
OrderDate string `json:"order_date"` // 下单日期 OrderDate string `json:"order_date"` // 下单日期
Seal string `json:"seal"` // 丝印 Seal string `json:"seal"` // 丝印
FinalTestQuantity string `json:"final_test_quantity"` // 结批测试数量 SubBatch string `json:"sub_batch"` // 子批次
FinalPassQuantity string `json:"final_pass_quantity"` // 结批良品数量 WaferID string `json:"wafer_id"` // 片号
FinalPassProbability string `json:"final_pass_probability"` // 结批良率 ReportTestQuantity string `json:"report_test_quantity"` // 结批测试数量
Bin1 string `json:"bin1"` ReportPassQuantity string `json:"report_pass_quantity"` // 结批良品数量
Bin2 string `json:"bin2"` ReportPassProbability string `json:"report_pass_probability"` // 结批良率
Bin3 string `json:"bin3"` Bin1 string `json:"bin1"`
Bin4 string `json:"bin4"` Bin2 string `json:"bin2"`
Bin5 string `json:"bin5"` Bin3 string `json:"bin3"`
Bin6 string `json:"bin6"` Bin4 string `json:"bin4"`
Bin7 string `json:"bin7"` Bin5 string `json:"bin5"`
Bin8 string `json:"bin8"` Bin6 string `json:"bin6"`
Bin9 string `json:"bin9"` Bin7 string `json:"bin7"`
Bin10 string `json:"bin10"` Bin8 string `json:"bin8"`
OutlookFail string `json:"outlook_fail"` // 外观不良 Bin9 string `json:"bin9"`
Other string `json:"other"` // 少数 Bin10 string `json:"bin10"`
BentStitch string `json:"bent_stitch"` // 弯脚 OutlookFail string `json:"outlook_fail"` // 外观不良
Scrapped string `json:"scrapped"` // 报废 Other string `json:"other"` // 少数
CreatedAt time.Time `json:"created_at"` BentStitch string `json:"bent_stitch"` // 弯脚
UpdatedAt time.Time `json:"-"` Scrapped string `json:"scrapped"` // 报废
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
} }
type ReportSites struct { type ReportSites struct {
@ -90,7 +110,6 @@ type BinFail struct {
} }
type ReportList struct { type ReportList struct {
ID int64 `json:"id" gorm:"primaryKey"`
Product string `json:"product"` // 成品型号 Product string `json:"product"` // 成品型号
Lot string `json:"lot"` //晶圆批次 Lot string `json:"lot"` //晶圆批次
Factory string `json:"factory"` // 测试厂 Factory string `json:"factory"` // 测试厂
@ -147,8 +166,11 @@ type ReportBinFail struct {
type FinalReportExcel struct { type FinalReportExcel struct {
ID int64 `json:"id" gorm:"primaryKey"` ID int64 `json:"id" gorm:"primaryKey"`
Step string `json:"step"` // 工序
Product string `json:"product"` // 成品型号 Product string `json:"product"` // 成品型号
Lot string `json:"lot"` // 晶圆批次 Lot string `json:"lot"` // 晶圆批次
SubBatch string `json:"sub_batch"` // 子批次
WaferID string `json:"wafer_id"` // 片号
Factory string `json:"factory"` // 测试厂 Factory string `json:"factory"` // 测试厂
TestProgram string `json:"test_program"` // 测试程序 TestProgram string `json:"test_program"` // 测试程序
PBI string `json:"pbi"` // PBI PBI string `json:"pbi"` // PBI

View File

@ -1,19 +1,47 @@
package model package model
import (
"gorm.io/gorm"
"time"
)
type WaferList struct { type WaferList struct {
OrderDate string `json:"order_date"` // 下单日期 ID int64 `json:"id" gorm:"primaryKey"`
PBI string `json:"pbi"` // 订单号 Status string `json:"status"` // 状态
Product string `json:"product"` // 晶圆型号 OrderDate string `json:"order_date"` // 下单日期
Factory string `json:"factory"` // 晶圆厂 PBI string `json:"pbi"` // 订单号
WaferSize string `json:"wafer_size"` // 晶圆尺寸 Product string `json:"product"` // 晶圆型号
Quantity float64 `json:"quantity"` // 投片数量 Factory string `json:"factory"` // 晶圆厂
OnlineQuantity float64 `json:"online_quantity"` // 在线数量 WaferSize string `json:"wafer_size"` // 晶圆尺寸
ReturnDate string `json:"return_date"` // 回货日期 Quantity float64 `json:"quantity"` // 投片数量
Lot string `json:"lot"` // 批号 OnlineQuantity float64 `json:"online_quantity"` // 在线数量
ReturnQuantity float64 `json:"return_quantity"` // 回货数量 ReturnQuantity float64 `json:"return_quantity"` // 回货数量
DieQuantity float64 `json:"die_quantity"` // Die数量
WaferStock []WaferStock `json:"wafer_stock" gorm:"foreignKey:WaferListID;references:ID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type WaferStock struct {
ID int64 `json:"id" gorm:"primaryKey"`
WaferListID int64 `json:"wafer_list_id"`
PBI string `json:"pbi"` // 订单号
Product string `json:"product"` // 晶圆型号
Specification string `json:"specification"` // 规格
ReturnDate string `json:"return_date"` // 回货日期
Lot string `json:"lot"` // 批次
WaferID string `json:"wafer_id"` // 片号
ReturnQuantity float64 `json:"return_quantity"` // 回货数量
DieQuantity float64 `json:"die_quantity"` // DIE数量
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
} }
type ABList struct { type ABList struct {
ID int64 `json:"id" gorm:"primaryKey"`
Status string `json:"status"` // 是否已完成
OrderDate string `json:"order_date"` // 下单日期 OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号 PBI string `json:"pbi"` // 订单号
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号 OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
@ -26,12 +54,26 @@ type ABList struct {
WaferID string `json:"wafer_id"` // 片号 WaferID string `json:"wafer_id"` // 片号
Quantity float64 `json:"quantity"` // 订单数量 Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 在线数量 OnlineQuantity float64 `json:"online_quantity"` // 在线数量
IsFinish string `json:"is_finish"` // 是否已完成
PassProbability string `json:"pass_probability"` // 良率 PassProbability string `json:"pass_probability"` // 良率
StockOutQuantity float64 `json:"stock_out_quantity"` // 出库数 StockOutQuantity float64 `json:"stock_out_quantity"` // 出库数
StockInQuantity float64 `json:"stock_in_quantity"` // 入库数 StockInQuantity float64 `json:"stock_in_quantity"` // 入库数
PassQuantity float64 `json:"pass_quantity"` // 封装良品
FailQuantity float64 `json:"fail_quantity"` // 封装不良品 FailQuantity float64 `json:"fail_quantity"` // 封装不良品
ABWaferList []*ABWaferList `json:"ab_wafer_list"` ABListStock []ABListStock `json:"ab_list_stock" gorm:"foreignKey:ABListID;references:ID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type ABListStock struct {
ID int64 `json:"id" gorm:"primaryKey"`
ABListID int64 `json:"ab_list_id"`
ReturnDate string `json:"return_date"`
PassQuantity float64 `json:"pass_quantity"`
FailQuantity float64 `json:"fail_quantity"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
} }
type ABWaferList struct { type ABWaferList struct {
@ -41,3 +83,224 @@ type ABWaferList struct {
Lot string `json:"lot"` // 批号 Lot string `json:"lot"` // 批号
WaferID string `json:"wafer_id"` // 片号 WaferID string `json:"wafer_id"` // 片号
} }
type BPList struct {
ID int64 `json:"id" gorm:"primaryKey"`
Status string `json:"status"` // 状态
OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 晶圆型号
Package string `json:"package"` // 封装
Factory string `json:"factory"` // CP测试厂
Lot string `json:"lot"` // 批号
WaferID string `json:"wafer_id"` // 片号
Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 在线数量
ReturnQuantity float64 `json:"return_quantity"` // 回货数量
DieQuantity float64 `json:"die_quantity"` // Die数量
BPListStock []BPListStock `gorm:"foreignKey:BPListID;references:ID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type BPListStock struct {
ID int64 `json:"id" gorm:"primaryKey"`
BPListID int64 `json:"bp_list_id"`
ReturnDate string `json:"return_date"`
Quantity float64 `json:"quantity"`
DieQuantity float64 `json:"die_quantity"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type CPList struct {
ID int64 `json:"id" gorm:"primaryKey"`
Status string `json:"status"`
OrderDate string `json:"order_date"` // 下单日期(订单日期)
PBI string `json:"pbi"` // PBI(订单号)
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 晶圆型号
Package string `json:"package"` // 封装(规格)
Factory string `json:"factory"` // CP测试厂
Lot string `json:"lot"` // 批号
WaferID string `json:"wafer_id"` // 片号
TestProgram string `json:"test_program"` // 测试程序
TestProgramVersion string `json:"test_program_version"` // 测试程序版本
Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 未交数量
ReturnQuantity float64 `json:"return_quantity"` // 回货数量
DieQuantity float64 `json:"die_quantity"` // Die数量
CPListStock []CPListStock `gorm:"foreignKey:CPListID;references:ID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type CPListStock struct {
ID int64 `json:"id" gorm:"primaryKey"`
CPListID int64 `json:"cp_list_id"`
ReturnDate string `json:"return_date"`
Quantity float64 `json:"quantity"`
DieQuantity float64 `json:"die_quantity"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type CPShowList struct {
Status string `json:"status"`
OrderDate string `json:"order_date"` // 下单日期(订单日期)
PBI string `json:"pbi"` // PBI(订单号)
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 晶圆型号
Package string `json:"package"` // 封装(规格)
Factory string `json:"factory"` // CP测试厂
Lot string `json:"lot"` // 批号
WaferID string `json:"wafer_id"` // 片号
TestProgram string `json:"test_program"` // 测试程序
TestProgramVersion string `json:"test_program_version"` // 测试程序版本
Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 未交数量
ReturnQuantity float64 `json:"return_quantity"` // 回货数量
DieQuantity float64 `json:"die_quantity"` // Die数量
CPListStock []CPListStock `gorm:"foreignKey:CPListID;references:ID"`
TestMachine string `json:"test_machine"` // 测试机台
TestQuantity string `json:"test_quantity"` // 测试数量
FirstPassQuantity string `json:"first_pass_quantity"` // 初测良品数量
FirstPassProbability string `json:"first_pass_probability"` // 初测良率
PassQuantity string `json:"pass_quantity"` // 良品数量(包括回收数据)
PassProbability string `json:"pass_probability"` // 良率(包括回收数据)
ReportTestQuantity string `json:"report_test_quantity"` // 报表测试数量
ReportPassQuantity string `json:"report_pass_quantity"` // 报表良品数量
ReportPassProbability string `json:"report_pass_probability"` // 报表良率
TestTime string `json:"test_time"` // 测试时间
TestQuantityDiff string `json:"test_quantity_diff"` // 测试数量差异
TestQuantityDiffLabel bool `json:"test_quantity_diff_label"`
PassQuantityDiff string `json:"pass_quantity_diff"` // 良品数量差异
PassQuantityDiffLabel bool `json:"pass_quantity_diff_label"`
ReturnProbability string `json:"return_probability"` // 回收率
ReturnProbabilityLabel bool `json:"return_probability_label"`
StackingMaterials bool `json:"stacking_materials"` // 是否叠料
SoftBinFailMap map[string]float64 `json:"soft_bin_fail_map"` // 软件Bin的不良数量
HardBinFailMap map[string]float64 `json:"hard_bin_fail_map"` // 硬件Bin的不良数量
SoftBinFail []*ReportBinFail `json:"soft_bin_fail"` // 软件Bin的不良数量
HardBinFail []*ReportBinFail `json:"hard_bin_fail"` // 硬件Bin的不良数量
Site []*ReportListSites `json:"site"` // Site测试情况
WaferDetails []ReportList `json:"wafer_details"` // 片号细节
}
type FTList struct {
ID int64 `json:"id" gorm:"primaryKey"`
Status string `json:"status"`
OrderDate string `json:"order_date"` // 下单日期(订单日期)
PBI string `json:"pbi"` // PBI(订单号)
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 成品型号
WaferProduct string `json:"wafer_product"` // 晶圆型号
Package string `json:"package"` // 封装(规格)
Factory string `json:"factory"` // FT测试厂
Lot string `json:"lot"` // 批号
Seal string `json:"seal"` // 丝印
TestProgram string `json:"test_program"` // FT测试程序
TestProgramVersion string `json:"test_program_version"` // 测试程序版本
Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 未交数量
ReturnQuantity float64 `json:"return_quantity"` // 回货数量
PassQuantity float64 `json:"pass_quantity"` // FT良品
FailQuantity float64 `json:"fail_quantity"` // FT不良品
FTListStock []FTListStock `gorm:"foreignKey:FTListID;references:ID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type FTListStock struct {
ID int64 `json:"id" gorm:"primaryKey"`
FTListID int64 `json:"cp_list_id"`
ReturnDate string `json:"return_date"`
PassQuantity float64 `json:"pass_quantity"`
FailQuantity float64 `json:"fail_quantity"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type FTShowList struct {
Status string `json:"status"`
OrderDate string `json:"order_date"` // 下单日期(订单日期)
PBI string `json:"pbi"` // PBI(订单号)
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 成品型号
WaferProduct string `json:"wafer_product"` // 晶圆型号
Package string `json:"package"` // 封装(规格)
Factory string `json:"factory"` // CP测试厂
Lot string `json:"lot"` // 批号
Seal string `json:"seal"` // 丝印
TestProgram string `json:"test_program"` // 测试程序
TestProgramVersion string `json:"test_program_version"` // 测试程序版本
Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 未交数量
ReturnQuantity float64 `json:"return_quantity"` // 回货数量
FTPassQuantity float64 `json:"ft_pass_quantity"` // FT良品
FTFailQuantity float64 `json:"ft_fail_quantity"` // FT不良品
FTListStock []FTListStock `gorm:"foreignKey:FTListID;references:ID"`
TestMachine string `json:"test_machine"` // 测试机台
TestQuantity string `json:"test_quantity"` // 测试数量
FirstPassQuantity string `json:"first_pass_quantity"` // 初测良品数量
FirstPassProbability string `json:"first_pass_probability"` // 初测良率
PassQuantity string `json:"pass_quantity"` // 良品数量(包括回收数据)
PassProbability string `json:"pass_probability"` // 良率(包括回收数据)
ReportTestQuantity string `json:"report_test_quantity"` // 报表测试数量
ReportPassQuantity string `json:"report_pass_quantity"` // 报表良品数量
ReportPassProbability string `json:"report_pass_probability"` // 报表良率
TestTime string `json:"test_time"` // 测试时间
TestQuantityDiff string `json:"test_quantity_diff"` // 测试数量差异
TestQuantityDiffLabel bool `json:"test_quantity_diff_label"`
PassQuantityDiff string `json:"pass_quantity_diff"` // 良品数量差异
PassQuantityDiffLabel bool `json:"pass_quantity_diff_label"`
ReturnProbability string `json:"return_probability"` // 回收率
ReturnProbabilityLabel bool `json:"return_probability_label"`
StackingMaterials bool `json:"stacking_materials"` // 是否叠料
SoftBinFailMap map[string]float64 `json:"soft_bin_fail_map"` // 软件Bin的不良数量
HardBinFailMap map[string]float64 `json:"hard_bin_fail_map"` // 硬件Bin的不良数量
SoftBinFail []*ReportBinFail `json:"soft_bin_fail"` // 软件Bin的不良数量
HardBinFail []*ReportBinFail `json:"hard_bin_fail"` // 硬件Bin的不良数量
Site []*ReportListSites `json:"site"` // Site测试情况
SubBatchDetails []ReportList `json:"sub_batch_details"` // 子批号细节
}
type TRList struct {
ID int64 `json:"id" gorm:"primaryKey"`
Status string `json:"status"` // 是否已完成
OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 成品型号
WaferProduct string `json:"wafer_product"` // 晶圆型号
Package string `json:"package"` // 封装
Factory string `json:"factory"` // FT测试厂
Lot string `json:"lot"` // 批号
Seal string `json:"seal"` // 丝印
Quantity float64 `json:"quantity"` // 订单数量
OnlineQuantity float64 `json:"online_quantity"` // 在线数量
PassQuantity float64 `json:"pass_quantity"` // FT良品
FailQuantity float64 `json:"fail_quantity"` // FT不良品
TRListStock []TRListStock `gorm:"foreignKey:TRListID;references:ID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
type TRListStock struct {
ID int64 `json:"id" gorm:"primaryKey"`
TRListID int64 `json:"tr_list_id"`
ReturnDate string `json:"return_date"`
PassQuantity float64 `json:"pass_quantity"`
FailQuantity float64 `json:"fail_quantity"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}

View File

@ -62,6 +62,7 @@ type BinControl struct {
type SelectionDiffControl struct { type SelectionDiffControl struct {
ID int64 `json:"id" gorm:"primaryKey"` ID int64 `json:"id" gorm:"primaryKey"`
WarningID int64 `json:"warning_id"` WarningID int64 `json:"warning_id"`
Selection string `json:"selection"` // 参数
SiteDiff string `json:"site_diff"` // SITE间差异均值最大值-均值最小值) SiteDiff string `json:"site_diff"` // SITE间差异均值最大值-均值最小值)
SubBatchDiff string `json:"sub_batch_diff"` // 批次间差异(均值最大值-均值最小值) SubBatchDiff string `json:"sub_batch_diff"` // 批次间差异(均值最大值-均值最小值)
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
@ -75,7 +76,7 @@ type StackingMaterialsWarning struct {
Selection string `json:"selection"` // 参数 Selection string `json:"selection"` // 参数
Diff string `json:"diff"` // 差异 Diff string `json:"diff"` // 差异
Unit string `json:"unit"` // 单位 Unit string `json:"unit"` // 单位
Quantity string `json:"quantity"` // 数量 Quantity int `json:"quantity"` // 数量
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"-"` UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`

View File

@ -0,0 +1,305 @@
package log_reader
import (
"bytes"
"encoding/csv"
"encoding/json"
"errors"
"gitee.com/golang-module/carbon/v2"
"github.com/extrame/xls"
"github.com/xuri/excelize/v2"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
"gorm.io/gorm"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"strings"
"testData/global"
"testData/model"
"testData/utils"
)
func ChangDian(fileText *model.FileText) {
rows := make([][]string, 0)
if strings.ToLower(path.Ext(fileText.Name)) == ".csv" {
csvBytes, err := ioutil.ReadFile(fileText.Path)
if err != nil {
log.Println("open err:", err)
return
}
//解决读取csv中文乱码的问题
reader := csv.NewReader(transform.NewReader(bytes.NewReader(csvBytes), simplifiedchinese.GBK.NewDecoder()))
//reader := csv.NewReader(file)
reader.FieldsPerRecord = -1
csvRows, err := reader.ReadAll()
if err != nil {
log.Println("open err:", err)
return
}
rows = csvRows
} else if strings.ToLower(path.Ext(fileText.Name)) == ".xls" {
if xlFile, err := xls.Open(fileText.Path, "utf-8"); err == nil {
//第一个sheet
sheet := xlFile.GetSheet(0)
if sheet.MaxRow != 0 {
temp := make([][]string, 0)
for i := 0; i < int(sheet.MaxRow); i++ {
row := sheet.Row(i)
if row == nil {
continue
}
data := make([]string, 0)
if row.LastCol() > 0 {
for j := 0; j < row.LastCol(); j++ {
col := row.Col(j)
data = append(data, col)
}
temp = append(temp, data)
}
}
rows = append(rows, temp...)
} else {
log.Println("open err:", err)
return
}
}
} else if strings.ToLower(path.Ext(fileText.Name)) == ".xlsx" {
xlsxFile, err := excelize.OpenFile(fileText.Path)
if err != nil {
log.Println("open err:", err)
return
}
sheetName := xlsxFile.GetSheetName(0)
rows, err = xlsxFile.GetRows(sheetName)
if err != nil {
log.Println("xlsx读取数据失败:", err)
return
}
}
details := make(map[string]string)
newExcel := make([][]string, 0)
var title []string
titleInfoMap := make(map[string]model.DataInfo)
sBinMap := make(map[string]model.BinInfo)
sbinStartIndex, sbinEndIndex := -1, -1
titleIndex, unitIndex, limitLIndex, limitUIndex, dataIndex := -1, -1, -1, -1, -1
for i := 1; i < len(rows); i++ {
if rows[i][0] == "" {
continue
}
if i == len(rows)-1 && unitIndex == -1 {
log.Println("特殊文件格式,文件路径为:", fileText.Path)
return
}
// SBin HBin standard and relation
if sbinEndIndex < 0 {
if strings.Contains(rows[i][0], "SBin") {
if sbinStartIndex < 0 {
sbinStartIndex = i
}
s := rows[i][0]
if strings.Index(s, "]") != -1 {
sbinNumStartIndex := strings.Index(s, "[")
sbinNumEndIndex := strings.Index(s, "]")
var startIndex, endIndex int
for index := sbinNumEndIndex + 1; index < len(s); index++ {
if startIndex == 0 {
if s[index] != ' ' {
startIndex = index
}
} else {
if s[index] == ' ' || s[index] == '_' {
endIndex = index
break
}
}
}
sBinMap[s[sbinNumStartIndex+1:sbinNumEndIndex]] = model.BinInfo{
Name: s[startIndex:endIndex],
HBin: s[strings.LastIndex(s, " ")+1:],
}
}
} else {
if sbinStartIndex > 0 {
sbinEndIndex = i
continue
}
}
}
//if len(sBinMap) == 0 {
//}
if titleIndex < 0 {
// Log File Details
rows[i][0] = strings.ReplaceAll(rows[i][0], "", ":")
splitIndex := strings.Index(rows[i][0], ":")
if splitIndex != -1 {
details[rows[i][0][:splitIndex]] = rows[i][0][splitIndex+1:]
}
// Data Title
if strings.Contains(rows[i][0], "SITE_NUM") {
titleIndex = i
title = rows[i]
continue
}
} else {
// Data Title's Unit or Limit
if dataIndex < 0 {
if unitIndex < 0 {
if strings.Contains(rows[i][0], "Unit") {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
unitIndex = i
continue
}
}
if limitLIndex < 0 {
if strings.Contains(rows[i][0], "LimitL") {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
limitLIndex = i
continue
}
}
if limitUIndex < 0 {
if strings.Contains(rows[i][0], "LimitU") {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
limitUIndex = i
continue
}
}
// Get Data Index
if unitIndex > 0 && limitLIndex > 0 && limitUIndex > 0 {
dataIndex = i
break
}
}
}
}
if titleIndex != -1 {
// Save Title Info
for k, v := range rows[titleIndex] {
titleInfoMap[v] = model.DataInfo{
Unit: rows[unitIndex][k],
LimitL: rows[limitLIndex][k],
LimitU: rows[limitUIndex][k],
}
}
// Complete and Save Data
for i := dataIndex; i < len(rows); i++ {
if len(rows[i]) < len(rows[titleIndex]) {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
}
newExcel = append(newExcel, rows[i])
}
} else {
log.Println("特殊文件格式,文件路径为:", fileText.Path)
return
}
//if details["Test_Code"] == "" {
// details["Test_Code"] = step
//} else {
// details["Test_Code"] = details["Test_Code"][:2]
//}
if fileText.Factory == "ruisi" {
s := strings.Split(fileText.Name, "_")
details["PBI"] = s[0]
details["Device_Name"] = s[1]
details["Lot"] = s[2]
if strings.Contains(s[len(s)-1], "RT") {
details["Test_Code"] = "RT"
} else if strings.Contains(s[len(s)-1], "FT") {
details["Test_Code"] = "FT"
}
} else if fileText.Factory == "changdian" {
s := strings.Split(fileText.Name, "_")
details["PBI"] = s[0]
details["Device_Name"] = s[1]
details["Lot"] = s[2]
details["Sub_LotNo"] = s[3]
if strings.Contains(s[4], "RT") {
details["Test_Code"] = "RT"
} else if strings.Contains(s[len(s)-1], "FT") {
details["Test_Code"] = "FT"
}
}
//strReader := transform.NewReader(bytes.NewReader([]byte(details["Device_Name"])), simplifiedchinese.GBK.NewDecoder())
//product, _ := ioutil.ReadAll(strReader)
//if string(product) == "" {
// product = []byte(fileText.ProductName)
//}
details["Program"] = details["Program"][strings.LastIndex(details["Program"], "\\")+1:]
sbinHbin, _ := json.Marshal(&sBinMap)
titleInfo, _ := json.Marshal(&titleInfoMap)
fileName := details["Device_Name"] + "_" + details["Lot"] + "_" + details["Sub_LotNo"] + "_" + details["Test_Code"] + ".csv"
var waferID string
//strings.ReplaceAll(fileText.Lot, ".", "-")
dirPath := filepath.Join("/testData/test/" + fileText.Factory)
utils.MakeDir(dirPath)
filePath := filepath.Join(dirPath, fileName)
var fileHandled *model.FileHandled
if _, err := os.Stat(filePath); err != nil {
if os.IsNotExist(err) {
newExcel = append([][]string{title}, newExcel...)
_, err = os.Create(filePath)
if err != nil {
log.Println("创建文件失败:", err)
return
}
if errors.Is(global.PostGreSQL.Where("name = ?", fileName).First(&fileHandled).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FileHandled{
Name: fileName,
Path: filePath,
Size: "",
Product: details["Device_Name"],
Factory: fileText.Factory,
PBI: details["PBI"],
Step: details["Test_Code"],
Lot: details["Lot"],
SubBatch: details["Sub_LotNo"],
TestMachineModel: "STS8200",
TestMachine: details["Tester ID"],
TestProgram: details["Program"],
BeginningTime: details["Beginning Time"],
EndingTime: details["Ending Time"],
SbinHbin: string(sbinHbin),
TitleInfo: string(titleInfo),
WaferID: waferID,
})
}
}
}
newCsv, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
log.Println("打开新Excel错误:", fileText.Path)
return
}
defer newCsv.Close()
writer := csv.NewWriter(newCsv)
defer writer.Flush()
err = writer.WriteAll(newExcel)
if err != nil {
log.Println("写入新Excel错误:", fileText.Path)
return
}
newFile, err := os.Stat(filePath)
if err != nil {
log.Println("获取新Excel信息:", fileText.Path)
return
}
if !carbon.Parse(fileHandled.BeginningTime).Gt(carbon.Parse(details["Beginning Time"])) {
details["Beginning Time"] = fileHandled.BeginningTime
}
if !carbon.Parse(details["Ending Time"]).Gt(carbon.Parse(fileHandled.EndingTime)) {
details["Ending Time"] = fileHandled.EndingTime
}
global.PostGreSQL.Model(&fileHandled).Where("name = ?", fileName).Updates(map[string]interface{}{
"beginning_time": details["Beginning Time"],
"ending_time": details["Ending Time"],
"size": utils.FormatFileSize(float64(newFile.Size())),
})
}

View File

@ -0,0 +1,294 @@
package log_reader
import (
"bytes"
"encoding/csv"
"encoding/json"
"errors"
"gitee.com/golang-module/carbon/v2"
"github.com/extrame/xls"
"github.com/xuri/excelize/v2"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
"gorm.io/gorm"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"strings"
"testData/global"
"testData/model"
"testData/utils"
)
func RuiSiLogReader(fileText *model.FileText) {
rows := make([][]string, 0)
if strings.ToLower(path.Ext(fileText.Name)) == ".csv" {
csvBytes, err := ioutil.ReadFile(fileText.Path)
if err != nil {
log.Println("open err:", err)
return
}
//解决读取csv中文乱码的问题
reader := csv.NewReader(transform.NewReader(bytes.NewReader(csvBytes), simplifiedchinese.GBK.NewDecoder()))
//reader := csv.NewReader(file)
reader.FieldsPerRecord = -1
csvRows, err := reader.ReadAll()
if err != nil {
log.Println("open err:", err)
return
}
rows = csvRows
} else if strings.ToLower(path.Ext(fileText.Name)) == ".xls" {
if xlFile, err := xls.Open(fileText.Path, "utf-8"); err == nil {
//第一个sheet
sheet := xlFile.GetSheet(0)
if sheet.MaxRow != 0 {
temp := make([][]string, 0)
for i := 0; i < int(sheet.MaxRow); i++ {
row := sheet.Row(i)
if row == nil {
continue
}
data := make([]string, 0)
if row.LastCol() > 0 {
for j := 0; j < row.LastCol(); j++ {
col := row.Col(j)
data = append(data, col)
}
temp = append(temp, data)
}
}
rows = append(rows, temp...)
} else {
log.Println("open err:", err)
return
}
}
} else if strings.ToLower(path.Ext(fileText.Name)) == ".xlsx" {
xlsxFile, err := excelize.OpenFile(fileText.Path)
if err != nil {
log.Println("open err:", err)
return
}
sheetName := xlsxFile.GetSheetName(0)
rows, err = xlsxFile.GetRows(sheetName)
if err != nil {
log.Println("xlsx读取数据失败:", err)
return
}
}
details := make(map[string]string)
newExcel := make([][]string, 0)
var title []string
titleInfoMap := make(map[string]model.DataInfo)
sBinMap := make(map[string]model.BinInfo)
sbinStartIndex, sbinEndIndex := -1, -1
titleIndex, unitIndex, limitLIndex, limitUIndex, dataIndex := -1, -1, -1, -1, -1
for i := 1; i < len(rows); i++ {
if rows[i][0] == "" {
continue
}
if i == len(rows)-1 && unitIndex == -1 {
log.Println("特殊文件格式,文件路径为:", fileText.Path)
return
}
// SBin HBin standard and relation
if sbinEndIndex < 0 {
if strings.Contains(rows[i][0], "SBin") {
if sbinStartIndex < 0 {
sbinStartIndex = i
}
s := rows[i][0]
if strings.Index(s, "]") != -1 {
sbinNumStartIndex := strings.Index(s, "[")
sbinNumEndIndex := strings.Index(s, "]")
var startIndex, endIndex int
for index := sbinNumEndIndex + 1; index < len(s); index++ {
if startIndex == 0 {
if s[index] != ' ' {
startIndex = index
}
} else {
if s[index] == ' ' || s[index] == '_' {
endIndex = index
break
}
}
}
sBinMap[s[sbinNumStartIndex+1:sbinNumEndIndex]] = model.BinInfo{
Name: s[startIndex:endIndex],
HBin: s[strings.LastIndex(s, " ")+1:],
}
}
} else {
if sbinStartIndex > 0 {
sbinEndIndex = i
continue
}
}
}
//if len(sBinMap) == 0 {
//}
if titleIndex < 0 {
// Log File Details
rows[i][0] = strings.ReplaceAll(rows[i][0], "", ":")
splitIndex := strings.Index(rows[i][0], ":")
if splitIndex != -1 {
details[rows[i][0][:splitIndex]] = rows[i][0][splitIndex+1:]
}
// Data Title
if strings.Contains(rows[i][0], "SITE_NUM") {
titleIndex = i
title = rows[i]
continue
}
} else {
// Data Title's Unit or Limit
if dataIndex < 0 {
if unitIndex < 0 {
if strings.Contains(rows[i][0], "Unit") {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
unitIndex = i
continue
}
}
if limitLIndex < 0 {
if strings.Contains(rows[i][0], "LimitL") {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
limitLIndex = i
continue
}
}
if limitUIndex < 0 {
if strings.Contains(rows[i][0], "LimitU") {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
limitUIndex = i
continue
}
}
// Get Data Index
if unitIndex > 0 && limitLIndex > 0 && limitUIndex > 0 {
dataIndex = i
break
}
}
}
}
if titleIndex != -1 {
// Save Title Info
for k, v := range rows[titleIndex] {
titleInfoMap[v] = model.DataInfo{
Unit: rows[unitIndex][k],
LimitL: rows[limitLIndex][k],
LimitU: rows[limitUIndex][k],
}
}
// Complete and Save Data
for i := dataIndex; i < len(rows); i++ {
if len(rows[i]) < len(rows[titleIndex]) {
rows[i] = append(rows[i], utils.FillData(len(rows[titleIndex])-len(rows[i]))...)
}
newExcel = append(newExcel, rows[i])
}
} else {
log.Println("特殊文件格式,文件路径为:", fileText.Path)
return
}
//if details["Test_Code"] == "" {
// details["Test_Code"] = step
//} else {
// details["Test_Code"] = details["Test_Code"][:2]
//}
if fileText.Factory == "ruisi" {
s := strings.Split(fileText.Name, "_")
details["PBI"] = s[0]
details["Device_Name"] = s[1]
details["Lot"] = s[2]
if strings.Contains(s[len(s)-1], "RT") {
details["Test_Code"] = "RT"
} else if strings.Contains(s[len(s)-1], "FT") {
details["Test_Code"] = "FT"
}
}
//strReader := transform.NewReader(bytes.NewReader([]byte(details["Device_Name"])), simplifiedchinese.GBK.NewDecoder())
//product, _ := ioutil.ReadAll(strReader)
//if string(product) == "" {
// product = []byte(fileText.ProductName)
//}
details["Program"] = details["Program"][strings.LastIndex(details["Program"], "\\")+1:]
sbinHbin, _ := json.Marshal(&sBinMap)
titleInfo, _ := json.Marshal(&titleInfoMap)
fileName := details["Device_Name"] + "_" + details["Lot"] + "_" + details["Sub_LotNo"] + "_" + details["Test_Code"] + ".csv"
var waferID string
//strings.ReplaceAll(fileText.Lot, ".", "-")
dirPath := filepath.Join("/testData/test/" + fileText.Factory)
utils.MakeDir(dirPath)
filePath := filepath.Join(dirPath, fileName)
var fileHandled *model.FileHandled
if _, err := os.Stat(filePath); err != nil {
if os.IsNotExist(err) {
newExcel = append([][]string{title}, newExcel...)
_, err = os.Create(filePath)
if err != nil {
log.Println("创建文件失败:", err)
return
}
if errors.Is(global.PostGreSQL.Where("name = ?", fileName).First(&fileHandled).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FileHandled{
Name: fileName,
Path: filePath,
Size: "",
Product: details["Device_Name"],
Factory: fileText.Factory,
PBI: details["PBI"],
Step: details["Test_Code"],
Lot: details["Lot"],
SubBatch: details["Sub_LotNo"],
TestMachineModel: "STS8200",
TestMachine: details["Tester ID"],
TestProgram: details["Program"],
BeginningTime: details["Beginning Time"],
EndingTime: details["Ending Time"],
SbinHbin: string(sbinHbin),
TitleInfo: string(titleInfo),
WaferID: waferID,
})
}
}
}
newCsv, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
log.Println("打开新Excel错误:", fileText.Path)
return
}
defer newCsv.Close()
writer := csv.NewWriter(newCsv)
defer writer.Flush()
err = writer.WriteAll(newExcel)
if err != nil {
log.Println("写入新Excel错误:", fileText.Path)
return
}
newFile, err := os.Stat(filePath)
if err != nil {
log.Println("获取新Excel信息:", fileText.Path)
return
}
if !carbon.Parse(fileHandled.BeginningTime).Gt(carbon.Parse(details["Beginning Time"])) {
details["Beginning Time"] = fileHandled.BeginningTime
}
if !carbon.Parse(details["Ending Time"]).Gt(carbon.Parse(fileHandled.EndingTime)) {
details["Ending Time"] = fileHandled.EndingTime
}
global.PostGreSQL.Model(&fileHandled).Where("name = ?", fileName).Updates(map[string]interface{}{
"beginning_time": details["Beginning Time"],
"ending_time": details["Ending Time"],
"size": utils.FormatFileSize(float64(newFile.Size())),
})
}

View File

@ -0,0 +1,374 @@
package report_reader
import (
"errors"
"github.com/xuri/excelize/v2"
"gorm.io/gorm"
"strings"
"testData/global"
"testData/model"
)
func CPSMCReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%赛美科%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "CP").Find(&finalReportExcel)
var product, lot, testProgram string
for rowIndex, row := range rows {
if rowIndex < 6 {
if rowIndex == 2 {
row[0] = strings.ReplaceAll(row[0], " ", "")
row[0] = strings.ReplaceAll(row[0], "", ":")
productStart := strings.Index(row[0], "型号:")
productEnd := strings.Index(row[0], "出货型号:")
product = row[0][productStart:productEnd]
lotStart := strings.Index(row[0], "型号:")
lotEnd := strings.Index(row[0], "出货型号:")
lot = row[0][lotStart:lotEnd]
testProgramStart := strings.Index(row[0], "型号:")
testProgramEnd := strings.Index(row[0], "出货型号:")
testProgram = row[0][testProgramStart:testProgramEnd]
}
if rowIndex == 4 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
}
continue
} else {
if row[0] == "Total" {
break
}
var report *model.FinalReport
info := make(map[string]string)
info = CPEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND wafer_id = ?",
"CP", product, lot,
row[titleMap[finalReportExcel.WaferID]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: product,
Lot: lot,
Factory: testProgram,
TestProgram: info["test_program"],
PBI: info["pbi"],
WaferID: info["wafer_id"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"wafer_id": info["wafer_id"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
f.Close()
}
func CPYuanFangReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%圆方%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "CP").Find(&finalReportExcel)
var product, lot string
product, _ = f.GetCellValue(sheetName, "J2")
lot, _ = f.GetCellValue(sheetName, "C3")
for rowIndex, row := range rows {
if rowIndex < 6 {
if rowIndex == 3 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
}
continue
} else {
if strings.Contains(row[0], "Total") {
break
}
var report *model.FinalReport
info := make(map[string]string)
info = CPEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND wafer_id = ?",
"CP", product, lot,
row[titleMap[finalReportExcel.WaferID]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: product,
Lot: lot,
Factory: pmc.Pmc03,
TestProgram: info["test_program"],
PBI: info["pbi"],
WaferID: info["wafer_id"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"wafer_id": info["wafer_id"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
f.Close()
}
func CPYuChengReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%育成%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "CP").Find(&finalReportExcel)
var product, lot, testProgram string
product, _ = f.GetCellValue(sheetName, "A4")
lot, _ = f.GetCellValue(sheetName, "B4")
testProgram, _ = f.GetCellValue(sheetName, "D2")
for rowIndex, row := range rows {
if rowIndex < 6 {
if rowIndex == 3 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
}
continue
} else {
if row[0] == "" {
break
}
var report *model.FinalReport
info := make(map[string]string)
info = CPEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND wafer_id = ?",
"CP", product, lot,
row[titleMap[finalReportExcel.WaferID]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: product,
Lot: lot,
Factory: pmc.Pmc03,
TestProgram: testProgram,
PBI: info["pbi"],
WaferID: info["wafer_id"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"wafer_id": info["wafer_id"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
f.Close()
}
func CPEmptyInfoHandler(titleMap map[string]int, finalReportExcel *model.FinalReportExcel,
info map[string]string, row []string) map[string]string {
if _, ok := titleMap[finalReportExcel.PBI]; !ok {
info["pbi"] = ""
} else {
info["pbi"] = row[titleMap[finalReportExcel.PBI]]
}
if _, ok := titleMap[finalReportExcel.WaferID]; !ok {
info["wafer_id"] = ""
} else {
info["wafer_id"] = row[titleMap[finalReportExcel.WaferID]]
}
if _, ok := titleMap[finalReportExcel.FinalTestQuantity]; !ok {
info["report_test_quantity"] = ""
} else {
info["report_test_quantity"] = row[titleMap[finalReportExcel.FinalTestQuantity]]
}
if _, ok := titleMap[finalReportExcel.FinalPassQuantity]; !ok {
info["report_pass_quantity"] = ""
} else {
info["report_pass_quantity"] = row[titleMap[finalReportExcel.FinalPassQuantity]]
}
if _, ok := titleMap[finalReportExcel.FinalTestQuantity]; !ok {
info["report_test_quantity"] = ""
} else {
info["report_test_quantity"] = row[titleMap[finalReportExcel.FinalTestQuantity]]
}
if _, ok := titleMap[finalReportExcel.FinalPassProbability]; !ok {
info["report_pass_probability"] = ""
} else {
info["report_pass_probability"] = row[titleMap[finalReportExcel.FinalPassProbability]]
}
if _, ok := titleMap[finalReportExcel.Bin2]; !ok {
info["bin2"] = ""
} else {
info["bin2"] = row[titleMap[finalReportExcel.Bin2]]
}
if _, ok := titleMap[finalReportExcel.Bin3]; !ok {
info["bin3"] = ""
} else {
info["bin3"] = row[titleMap[finalReportExcel.Bin3]]
}
if _, ok := titleMap[finalReportExcel.Bin4]; !ok {
info["bin4"] = ""
} else {
info["bin4"] = row[titleMap[finalReportExcel.Bin4]]
}
if _, ok := titleMap[finalReportExcel.Bin5]; !ok {
info["bin5"] = ""
} else {
info["bin5"] = row[titleMap[finalReportExcel.Bin5]]
}
if _, ok := titleMap[finalReportExcel.Bin6]; !ok {
info["bin6"] = ""
} else {
info["bin6"] = row[titleMap[finalReportExcel.Bin6]]
}
if _, ok := titleMap[finalReportExcel.Bin7]; !ok {
info["bin7"] = ""
} else {
info["bin7"] = row[titleMap[finalReportExcel.Bin7]]
}
if _, ok := titleMap[finalReportExcel.Bin8]; !ok {
info["bin8"] = ""
} else {
info["bin8"] = row[titleMap[finalReportExcel.Bin8]]
}
if _, ok := titleMap[finalReportExcel.Bin9]; !ok {
info["bin9"] = ""
} else {
info["bin9"] = row[titleMap[finalReportExcel.Bin9]]
}
if _, ok := titleMap[finalReportExcel.Bin10]; !ok {
info["bin10"] = ""
} else {
info["bin10"] = row[titleMap[finalReportExcel.Bin10]]
}
if _, ok := titleMap[finalReportExcel.OutlookFail]; !ok {
info["outlook_fail"] = ""
} else {
info["outlook_fail"] = row[titleMap[finalReportExcel.OutlookFail]]
}
if _, ok := titleMap[finalReportExcel.Other]; !ok {
info["other"] = ""
} else {
info["other"] = row[titleMap[finalReportExcel.Other]]
}
if _, ok := titleMap[finalReportExcel.BentStitch]; !ok {
info["bent_stitch"] = ""
} else {
info["bent_stitch"] = row[titleMap[finalReportExcel.BentStitch]]
}
if _, ok := titleMap[finalReportExcel.Scrapped]; !ok {
info["scrapped"] = ""
} else {
info["scrapped"] = row[titleMap[finalReportExcel.Scrapped]]
}
return info
}

View File

@ -0,0 +1,500 @@
package report_reader
import (
"errors"
"github.com/xuri/excelize/v2"
"gorm.io/gorm"
"testData/global"
"testData/model"
)
func FTSMCReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
//sheetName := f.GetSheetName(0)
sheetName := "FT0801 test Yield(2024.03)"
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%赛美科%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "FT").Find(&finalReportExcel)
for rowIndex, row := range rows {
if rowIndex == 0 {
continue
} else if rowIndex == 1 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
} else {
var report *model.FinalReport
info := make(map[string]string)
FTEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND sub_batch = ?",
"FT", row[titleMap[finalReportExcel.Product]], row[titleMap[finalReportExcel.Lot]],
row[titleMap[finalReportExcel.SubBatch]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: info["product"],
Lot: info["lot"],
Factory: pmc.Pmc03,
TestProgram: info["test_program"],
PBI: info["pbi"],
SubBatch: info["sub_batch"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"sub_batch": info["sub_batch"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
}
func FTSuYinChangDianReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%江苏长电%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "FT").Find(&finalReportExcel)
for rowIndex, row := range rows {
if rowIndex == 0 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
} else {
var report *model.Report
info := make(map[string]string)
FTEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND sub_batch = ?",
"FT", row[titleMap[finalReportExcel.Product]], row[titleMap[finalReportExcel.Lot]],
row[titleMap[finalReportExcel.SubBatch]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: info["product"],
Lot: info["lot"],
Factory: pmc.Pmc03,
TestProgram: info["test_program"],
PBI: info["pbi"],
SubBatch: info["sub_batch"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"sub_batch": info["sub_batch"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
f.Close()
}
func FTQiPaiReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var finalReportExcel *model.FinalReportExcel
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%气派%").Find(&pmc)
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "FT").Find(&finalReportExcel)
for rowIndex, row := range rows {
if rowIndex == 0 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
} else {
var report *model.FinalReport
info := make(map[string]string)
FTEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND sub_batch = ?",
"FT", row[titleMap[finalReportExcel.Product]], row[titleMap[finalReportExcel.Lot]],
row[titleMap[finalReportExcel.SubBatch]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: row[titleMap[finalReportExcel.Product]],
Lot: row[titleMap[finalReportExcel.Lot]],
Factory: pmc.Pmc03,
TestProgram: row[titleMap[finalReportExcel.TestProgram]],
PBI: row[titleMap[finalReportExcel.PBI]],
SubBatch: row[titleMap[finalReportExcel.SubBatch]],
ReportTestQuantity: row[titleMap[finalReportExcel.FinalTestQuantity]],
ReportPassQuantity: row[titleMap[finalReportExcel.FinalPassQuantity]],
ReportPassProbability: row[titleMap[finalReportExcel.FinalPassProbability]],
Bin2: row[titleMap[finalReportExcel.Bin2]],
Bin3: row[titleMap[finalReportExcel.Bin3]],
Bin4: row[titleMap[finalReportExcel.Bin4]],
Bin5: row[titleMap[finalReportExcel.Bin5]],
Bin6: row[titleMap[finalReportExcel.Bin6]],
Bin7: row[titleMap[finalReportExcel.Bin7]],
Bin8: row[titleMap[finalReportExcel.Bin8]],
Bin9: row[titleMap[finalReportExcel.Bin9]],
Bin10: row[titleMap[finalReportExcel.Bin10]],
OutlookFail: row[titleMap[finalReportExcel.OutlookFail]],
Other: row[titleMap[finalReportExcel.Other]],
BentStitch: row[titleMap[finalReportExcel.BentStitch]],
Scrapped: row[titleMap[finalReportExcel.Scrapped]],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": row[titleMap[finalReportExcel.PBI]],
"sub_batch": row[titleMap[finalReportExcel.SubBatch]],
"report_test_quantity": row[titleMap[finalReportExcel.FinalTestQuantity]],
"report_pass_quantity": row[titleMap[finalReportExcel.FinalPassQuantity]],
"report_pass_probability": row[titleMap[finalReportExcel.FinalPassProbability]],
"bin2": row[titleMap[finalReportExcel.Bin2]],
"bin3": row[titleMap[finalReportExcel.Bin3]],
"bin4": row[titleMap[finalReportExcel.Bin4]],
"bin5": row[titleMap[finalReportExcel.Bin5]],
"bin6": row[titleMap[finalReportExcel.Bin6]],
"bin7": row[titleMap[finalReportExcel.Bin7]],
"bin8": row[titleMap[finalReportExcel.Bin8]],
"bin9": row[titleMap[finalReportExcel.Bin9]],
"bin10": row[titleMap[finalReportExcel.Bin10]],
"outlook_fail": row[titleMap[finalReportExcel.OutlookFail]],
"other": row[titleMap[finalReportExcel.Other]],
"bent_stitch": row[titleMap[finalReportExcel.BentStitch]],
"scrapped": row[titleMap[finalReportExcel.Scrapped]],
})
}
}
}
f.Close()
}
func FTRuiSiReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%赛美科%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "FT").Find(&finalReportExcel)
for rowIndex, row := range rows {
if rowIndex == 0 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
} else {
if row[0] == "" {
break
}
var report *model.FinalReport
info := make(map[string]string)
FTEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND sub_batch = ?",
"FT", row[titleMap[finalReportExcel.Product]], row[titleMap[finalReportExcel.Lot]],
row[titleMap[finalReportExcel.SubBatch]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: info["product"],
Lot: info["lot"],
Factory: pmc.Pmc03,
TestProgram: info["test_program"],
PBI: info["pbi"],
SubBatch: info["sub_batch"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"sub_batch": info["sub_batch"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
f.Close()
}
func FTXinDeReportReader(filePath string) {
f, _ := excelize.OpenFile(filePath)
sheetName := f.GetSheetName(0)
rows, _ := f.GetRows(sheetName)
titleMap := make(map[string]int)
var pmc *model.PmcFile
global.Oracle.Where("pmc03 LIKE ?", "%芯德%").Find(&pmc)
var finalReportExcel *model.FinalReportExcel
global.PostGreSQL.Where("factory = ? AND step = ?", pmc.Pmc03, "FT").Find(&finalReportExcel)
for rowIndex, row := range rows {
if rowIndex == 0 {
for i := 0; i < len(row); i++ {
titleMap[row[i]] = i
}
} else {
var report *model.FinalReport
info := make(map[string]string)
FTEmptyInfoHandler(titleMap, finalReportExcel, info, row)
if errors.Is(global.PostGreSQL.Where("step = ? AND product = ? AND lot = ? AND sub_batch = ?",
"FT", row[titleMap[finalReportExcel.Product]], row[titleMap[finalReportExcel.Lot]],
row[titleMap[finalReportExcel.SubBatch]]).First(&report).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReport{
Step: "FT",
Product: info["product"],
Lot: info["lot"],
Factory: pmc.Pmc03,
TestProgram: info["test_program"],
PBI: info["pbi"],
SubBatch: info["sub_batch"],
ReportTestQuantity: info["report_test_quantity"],
ReportPassQuantity: info["report_pass_quantity"],
ReportPassProbability: info["report_pass_probability"],
Bin2: info["bin2"],
Bin3: info["bin3"],
Bin4: info["bin4"],
Bin5: info["bin5"],
Bin6: info["bin6"],
Bin7: info["bin7"],
Bin8: info["bin8"],
Bin9: info["bin9"],
Bin10: info["bin10"],
OutlookFail: info["outlook_fail"],
Other: info["other"],
BentStitch: info["bent_stitch"],
Scrapped: info["scrapped"],
})
} else {
global.PostGreSQL.Model(&report).Updates(map[string]interface{}{
"pbi": info["pbi"],
"sub_batch": info["sub_batch"],
"report_test_quantity": info["report_test_quantity"],
"report_pass_quantity": info["report_pass_quantity"],
"report_pass_probability": info["report_pass_probability"],
"bin2": info["bin2"],
"bin3": info["bin3"],
"bin4": info["bin4"],
"bin5": info["bin5"],
"bin6": info["bin6"],
"bin7": info["bin7"],
"bin8": info["bin8"],
"bin9": info["bin9"],
"bin10": info["bin10"],
"outlook_fail": info["outlook_fail"],
"other": info["other"],
"bent_stitch": info["bent_stitch"],
"scrapped": info["scrapped"],
})
}
}
}
f.Close()
}
func FTEmptyInfoHandler(titleMap map[string]int, finalReportExcel *model.FinalReportExcel,
info map[string]string, row []string) map[string]string {
if _, ok := titleMap[finalReportExcel.Product]; !ok {
info["product"] = ""
} else {
info["product"] = row[titleMap[finalReportExcel.Product]]
}
if _, ok := titleMap[finalReportExcel.Lot]; !ok {
info["lot"] = ""
} else {
info["lot"] = row[titleMap[finalReportExcel.Lot]]
}
if _, ok := titleMap[finalReportExcel.TestProgram]; !ok {
info["test_program"] = ""
} else {
info["test_program"] = row[titleMap[finalReportExcel.TestProgram]]
}
if _, ok := titleMap[finalReportExcel.PBI]; !ok {
info["pbi"] = ""
} else {
info["pbi"] = row[titleMap[finalReportExcel.PBI]]
}
if _, ok := titleMap[finalReportExcel.SubBatch]; !ok {
info["sub_batch"] = ""
} else {
info["sub_batch"] = row[titleMap[finalReportExcel.SubBatch]]
}
if _, ok := titleMap[finalReportExcel.FinalTestQuantity]; !ok {
info["report_test_quantity"] = ""
} else {
info["report_test_quantity"] = row[titleMap[finalReportExcel.FinalTestQuantity]]
}
if _, ok := titleMap[finalReportExcel.FinalPassQuantity]; !ok {
info["report_pass_quantity"] = ""
} else {
info["report_pass_quantity"] = row[titleMap[finalReportExcel.FinalPassQuantity]]
}
if _, ok := titleMap[finalReportExcel.FinalTestQuantity]; !ok {
info["report_test_quantity"] = ""
} else {
info["report_test_quantity"] = row[titleMap[finalReportExcel.FinalTestQuantity]]
}
if _, ok := titleMap[finalReportExcel.FinalPassProbability]; !ok {
info["report_pass_probability"] = ""
} else {
info["report_pass_probability"] = row[titleMap[finalReportExcel.FinalPassProbability]]
}
if _, ok := titleMap[finalReportExcel.Bin2]; !ok {
info["bin2"] = ""
} else {
info["bin2"] = row[titleMap[finalReportExcel.Bin2]]
}
if _, ok := titleMap[finalReportExcel.Bin3]; !ok {
info["bin3"] = ""
} else {
info["bin3"] = row[titleMap[finalReportExcel.Bin3]]
}
if _, ok := titleMap[finalReportExcel.Bin4]; !ok {
info["bin4"] = ""
} else {
info["bin4"] = row[titleMap[finalReportExcel.Bin4]]
}
if _, ok := titleMap[finalReportExcel.Bin5]; !ok {
info["bin5"] = ""
} else {
info["bin5"] = row[titleMap[finalReportExcel.Bin5]]
}
if _, ok := titleMap[finalReportExcel.Bin6]; !ok {
info["bin6"] = ""
} else {
info["bin6"] = row[titleMap[finalReportExcel.Bin6]]
}
if _, ok := titleMap[finalReportExcel.Bin7]; !ok {
info["bin7"] = ""
} else {
info["bin7"] = row[titleMap[finalReportExcel.Bin7]]
}
if _, ok := titleMap[finalReportExcel.Bin8]; !ok {
info["bin8"] = ""
} else {
info["bin8"] = row[titleMap[finalReportExcel.Bin8]]
}
if _, ok := titleMap[finalReportExcel.Bin9]; !ok {
info["bin9"] = ""
} else {
info["bin9"] = row[titleMap[finalReportExcel.Bin9]]
}
if _, ok := titleMap[finalReportExcel.Bin10]; !ok {
info["bin10"] = ""
} else {
info["bin10"] = row[titleMap[finalReportExcel.Bin10]]
}
if _, ok := titleMap[finalReportExcel.OutlookFail]; !ok {
info["outlook_fail"] = ""
} else {
info["outlook_fail"] = row[titleMap[finalReportExcel.OutlookFail]]
}
if _, ok := titleMap[finalReportExcel.Other]; !ok {
info["other"] = ""
} else {
info["other"] = row[titleMap[finalReportExcel.Other]]
}
if _, ok := titleMap[finalReportExcel.BentStitch]; !ok {
info["bent_stitch"] = ""
} else {
info["bent_stitch"] = row[titleMap[finalReportExcel.BentStitch]]
}
if _, ok := titleMap[finalReportExcel.Scrapped]; !ok {
info["scrapped"] = ""
} else {
info["scrapped"] = row[titleMap[finalReportExcel.Scrapped]]
}
return info
}

View File

@ -1,16 +1,12 @@
package test_data package test_data
import ( import (
"bufio"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"log"
"math" "math"
"os"
"sort" "sort"
"strconv" "strconv"
"strings"
"testData/global" "testData/global"
"testData/model" "testData/model"
"testData/request" "testData/request"
@ -18,7 +14,7 @@ import (
// QuerySelection 查询可选择的参数 // QuerySelection 查询可选择的参数
func QuerySelection(req *request.QuerySelection) map[string][]string { func QuerySelection(req *request.QuerySelection) map[string][]string {
return LotInMultipleFilesSelection(req.Product, req.Lot, req.PBI) return LotInMultipleFilesSelection(req.Product, req.Lot, req.PBI, req.Step, req.WaferID)
} }
// Histogram 直方图 // Histogram 直方图
@ -42,11 +38,11 @@ func Histogram(req *request.Histogram) ([]*model.Histogram, error) {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if group == "" { if group == "" {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else if len(req.SubBatch) != 0 { } else if len(req.SubBatch) != 0 {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "") datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "", req.Step)
} else if len(req.WaferID) != 0 { } else if len(req.WaferID) != 0 {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group, req.Step)
} }
left := req.Average - req.Offset*req.StandardDeviation left := req.Average - req.Offset*req.StandardDeviation
@ -291,11 +287,11 @@ func Histogram(req *request.Histogram) ([]*model.Histogram, error) {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if group == "" { if group == "" {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else if len(req.SubBatch) != 0 { } else if len(req.SubBatch) != 0 {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "") datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "", req.Step)
} else if len(req.WaferID) != 0 { } else if len(req.WaferID) != 0 {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group, req.Step)
} }
for _, selection := range req.Selections { for _, selection := range req.Selections {
@ -461,15 +457,15 @@ func Scatter(req *request.Scatter) ([]*model.Scatter, model.ScatterLimit, model.
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if len(req.SubBatch) == 0 { if len(req.SubBatch) == 0 {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else { } else {
for _, group := range groups { for _, group := range groups {
if len(req.SubBatch) != 0 { if len(req.SubBatch) != 0 {
groupDatas, groupFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, group, "") groupDatas, groupFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, group, "", req.Step)
datas = append(datas, groupDatas...) datas = append(datas, groupDatas...)
fieldMap = groupFieldMap fieldMap = groupFieldMap
} else { } else {
groupDatas, groupFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", group) groupDatas, groupFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", group, req.Step)
datas = append(datas, groupDatas...) datas = append(datas, groupDatas...)
fieldMap = groupFieldMap fieldMap = groupFieldMap
} }
@ -655,9 +651,9 @@ func Pie(req *request.Pie) ([]*model.Pie, error) {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if req.SubBatch == "" { if req.SubBatch == "" {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else { } else {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, req.SubBatch, req.Step) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, req.SubBatch, req.Step, req.Step)
} }
if _, ok := fieldMap[req.Selection]; !ok { if _, ok := fieldMap[req.Selection]; !ok {
return nil, errors.New("不存在该参数") return nil, errors.New("不存在该参数")
@ -735,9 +731,9 @@ func Line(req *request.Line) (*model.Line, error) {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if req.SubBatch == "" { if req.SubBatch == "" {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else { } else {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, req.SubBatch, req.Step) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, req.SubBatch, req.Step, req.Lot)
} }
var x, y []string var x, y []string
for index, data := range datas { for index, data := range datas {
@ -785,35 +781,36 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
// CP测试没有子批次 // CP测试没有子批次
var fileHandle *model.FileHandled var fileHandle *model.FileHandled
global.PostGreSQL.Where("pbi = ? AND product = ? AND lot = ? AND wafer_id = ?", global.PostGreSQL.Where("pbi = ? AND product = ? AND lot = ? AND wafer_id = ? AND step = ?",
req.PBI, req.Product, req.Lot, req.WaferID). req.PBI, req.Product, req.Lot, req.WaferID, req.Step).
Find(&fileHandle) Find(&fileHandle)
f, err := os.Open(fileHandle.Path) //f, err := os.Open(fileHandle.Path)
if err != nil { //if err != nil {
log.Println(err) // log.Println(err)
return nil, err // return nil, err
} //}
defer f.Close() //defer f.Close()
scanner := bufio.NewScanner(f) //scanner := bufio.NewScanner(f)
datas := make([][]string, 0) //datas := make([][]string, 0)
fieldMap := make(map[string]int) //fieldMap := make(map[string]int)
for scanner.Scan() { //for scanner.Scan() {
line := scanner.Text() // line := scanner.Text()
s := strings.Split(line, ",") // s := strings.Split(line, ",")
datas = append(datas, s[:len(s)-1]) // datas = append(datas, s[:len(s)-1])
if len(datas) == 1 { // if len(datas) == 1 {
for index, cell := range s { // for index, cell := range s {
if index == len(s)-1 { // if index == len(s)-1 {
continue // continue
} // }
fieldMap[cell] = index // fieldMap[cell] = index
} // }
} // }
} //}
if len(datas) >= 1 { //if len(datas) >= 1 {
datas = datas[1:] // datas = datas[1:]
} //}
datas, fieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", req.WaferID, req.Step)
sbinHbinMap := make(map[string]map[string]string) sbinHbinMap := make(map[string]map[string]string)
res := make(map[string]interface{}) res := make(map[string]interface{})
@ -857,7 +854,13 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
hbinColorMap := make(map[string]int) hbinColorMap := make(map[string]int)
selectionColorMap := make(map[string]int) selectionColorMap := make(map[string]int)
for _, data := range datas { for _, data := range datas {
binInfoMap := sbinHbinMap[data[fieldMap["SOFT_BIN"]]] var softBinName string
if req.Step == "CP1+CP2" && data[fieldMap["SOFT_BIN_CP2"]] != "" {
softBinName = "SOFT_BIN_CP2"
} else {
softBinName = "SOFT_BIN"
}
binInfoMap := sbinHbinMap[data[fieldMap[softBinName]]]
// 筛选Site // 筛选Site
var siteInclude bool var siteInclude bool
if len(req.Site) == 0 { if len(req.Site) == 0 {
@ -879,7 +882,7 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
sBinInclude = true sBinInclude = true
} else { } else {
for _, bin := range req.SBin { for _, bin := range req.SBin {
if data[fieldMap["SOFT_BIN"]] == bin { if data[fieldMap[softBinName]] == bin {
sBinInclude = true sBinInclude = true
break break
} }
@ -910,10 +913,10 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
//data = append(data, binInfoMap["HBin"]) //data = append(data, binInfoMap["HBin"])
x := data[fieldMap["X_COORD"]] x := data[fieldMap["X_COORD"]]
y := data[fieldMap["Y_COORD"]] y := data[fieldMap["Y_COORD"]]
data[fieldMap["PASSFG"]] = strings.ToLower(data[fieldMap["PASSFG"]]) //data[fieldMap["PASSFG"]] = strings.ToLower(data[fieldMap["PASSFG"]])
// 判断测试点是否通过测试 // 判断测试点是否通过测试
var isPass bool var isPass bool
if data[fieldMap["PASSFG"]] == "true" { if data[fieldMap[softBinName]] == "1" {
isPass = true isPass = true
} }
@ -970,6 +973,7 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
isFinal = true isFinal = true
} else { } else {
lastFailArray = append(lastFailArray, append([]string{x, y}, field...)) lastFailArray = append(lastFailArray, append([]string{x, y}, field...))
isFinal = true
} }
} }
@ -978,8 +982,8 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
if isPass { if isPass {
pass++ pass++
} }
binMap[data[fieldMap["SOFT_BIN"]]]++ binMap[data[fieldMap[softBinName]]]++
sbinColorMap[data[fieldMap["SOFT_BIN"]]]++ sbinColorMap[data[fieldMap[softBinName]]]++
hbinColorMap[binInfoMap["HBin"]]++ hbinColorMap[binInfoMap["HBin"]]++
// 根据SOFT_BIN区分颜色 // 根据SOFT_BIN区分颜色
for _, sBinColor := range req.SBinColor { for _, sBinColor := range req.SBinColor {
@ -992,7 +996,7 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
break break
} }
} }
if !isReplace && data[fieldMap["SOFT_BIN"]] == sBinColor.Name { if !isReplace && data[fieldMap[softBinName]] == sBinColor.Name {
array = append(array, append([]string{x, y}, field...)) array = append(array, append([]string{x, y}, field...))
selectDatas[sBinColor.Name] = array selectDatas[sBinColor.Name] = array
break break
@ -1118,15 +1122,54 @@ func CPMap(req *request.CPMap) (map[string]interface{}, error) {
return res, nil return res, nil
} }
// CPMap CP晶圆图
func AllCPMap(req *request.CPMap) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
var fileHandles []*model.FileHandled
if len(req.WaferIDS) == 0 {
global.PostGreSQL.Where("product = ? AND lot = ? AND step = ?", req.Product, req.Lot, req.Step).
Order("wafer_id").Find(&fileHandles)
} else {
global.PostGreSQL.Where("product = ? AND lot = ? AND step = ? AND wafer_id IN ?",
req.Product, req.Lot, req.Step, req.WaferIDS).Order("wafer_id").Find(&fileHandles)
}
for _, fileHandle := range fileHandles {
//cpMap, err := CPMap(&request.CPMap{
// PBI: fileHandle.PBI,
// Product: req.Product,
// Lot: req.Lot,
// WaferID: fileHandle.WaferID,
// Step: req.Step,
//})
//if err != nil {
// log.Println(err)
//}
//res = append(res, cpMap)
//fmt.Println(cpMap)
_, err := strconv.Atoi(fileHandle.WaferID)
if err != nil {
continue
}
res = append(res, map[string]interface{}{
"pbi": fileHandle.PBI,
"product": req.Product,
"lot": req.Lot,
"wafer_id": fileHandle.WaferID,
"step": req.Step,
})
}
return res
}
func LogSiteChart(req *request.LogSiteChart) *model.Histogram { func LogSiteChart(req *request.LogSiteChart) *model.Histogram {
//var fileHandle *model.FileHandled //var fileHandle *model.FileHandled
//global.PostGreSQL.Where("product = ? AND sub_batch = ?", req.Product, req.SubBatch).Find(&fileHandle) //global.PostGreSQL.Where("product = ? AND sub_batch = ?", req.Product, req.SubBatch).Find(&fileHandle)
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if req.SubBatch == "" { if req.SubBatch == "" {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else { } else {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, req.SubBatch, req.Step) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, req.SubBatch, req.Step, req.Step)
} }
var x []string var x []string
for _, v := range req.Site { for _, v := range req.Site {

View File

@ -6,6 +6,7 @@ import (
"log" "log"
"math" "math"
"os" "os"
"sort"
"strconv" "strconv"
"strings" "strings"
"testData/global" "testData/global"
@ -66,14 +67,17 @@ func LotInAFileSelection(product, lot, pbi, subBatch, step string) ([]string, []
return selection, sBin, hBin, site return selection, sBin, hBin, site
} }
func LotInAFile(product, lot, pbi, subBatch, waferID string) ([][]string, map[string]int) { func LotInAFile(product, lot, pbi, subBatch, waferID, step string) ([][]string, map[string]int) {
var fileHandle *model.FileHandled var fileHandle *model.FileHandled
if subBatch != "" { if subBatch != "" {
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND sub_batch = ? AND step != ?", global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND sub_batch = ? AND step = ?",
product, lot, pbi, subBatch, "RT").Find(&fileHandle) product, lot, pbi, subBatch, step).Find(&fileHandle)
} else if waferID != "" { } else if waferID != "" && step != "CP1+CP2" {
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND wafer_id = ?", global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND wafer_id = ? AND step = ?",
product, lot, pbi, waferID).Find(&fileHandle) product, lot, pbi, waferID, step).Find(&fileHandle)
} else if step == "CP1+CP2" {
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND wafer_id = ? AND step = ?",
product, lot, pbi, waferID, "CP1").Find(&fileHandle)
} else { } else {
return nil, nil return nil, nil
} }
@ -87,6 +91,7 @@ func LotInAFile(product, lot, pbi, subBatch, waferID string) ([][]string, map[st
scanner := bufio.NewScanner(f) scanner := bufio.NewScanner(f)
datas := make([][]string, 0) datas := make([][]string, 0)
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
var maxIndex int
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
s := strings.Split(line, ",") s := strings.Split(line, ",")
@ -105,6 +110,7 @@ func LotInAFile(product, lot, pbi, subBatch, waferID string) ([][]string, map[st
if len(datas) == 1 { if len(datas) == 1 {
for index, cell := range s { for index, cell := range s {
if index == len(s)-1 { if index == len(s)-1 {
maxIndex = len(s)
continue continue
} }
fieldMap[cell] = index fieldMap[cell] = index
@ -114,12 +120,42 @@ func LotInAFile(product, lot, pbi, subBatch, waferID string) ([][]string, map[st
if len(datas) >= 1 { if len(datas) >= 1 {
datas = datas[1:] datas = datas[1:]
} }
latestMaxIndex := maxIndex
if step == "CP1+CP2" {
cp2Datas, cp2FieldMap := LotInAFile(product, lot, pbi, "", waferID, "CP2")
for k, v := range cp2FieldMap {
fieldMap[k+"_CP2"] = maxIndex + v - 1
if latestMaxIndex < maxIndex+v {
latestMaxIndex = maxIndex + v
}
}
for index, data := range datas {
for _, cpData := range cp2Datas {
if data[fieldMap["X_COORD"]] == cpData[fieldMap["X_COORD"]] &&
data[fieldMap["Y_COORD"]] == cpData[fieldMap["Y_COORD"]] && data[fieldMap["SOFT_BIN"]] == "1" {
datas[index] = append(datas[index], cpData...)
break
}
}
if len(data)-1 < latestMaxIndex {
for i := len(data) - 1; i < latestMaxIndex; i++ {
datas[index] = append(datas[index], "")
}
}
}
}
return datas, fieldMap return datas, fieldMap
} }
func LotInMultipleFilesSelection(product, lot, pbi string) map[string][]string { func LotInMultipleFilesSelection(product, lot, pbi, step, waferId string) map[string][]string {
var fileHandles []*model.FileHandled var fileHandles []*model.FileHandled
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ?", product, lot, pbi).Find(&fileHandles) if waferId != "" {
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND step = ? AND wafer_id = ?",
product, lot, pbi, step, waferId).Find(&fileHandles)
} else {
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND step = ?", product, lot, pbi, step).Find(&fileHandles)
}
datas := make([][]string, 0) datas := make([][]string, 0)
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
@ -180,7 +216,7 @@ func LotInMultipleFilesSelection(product, lot, pbi string) map[string][]string {
sBinMap := make(map[string]int) sBinMap := make(map[string]int)
siteMap := make(map[string]int) siteMap := make(map[string]int)
for _, data := range datas { for _, data := range datas {
sBinMap[data[fieldMap["SOFT_BIN"]]] = 1 sBinMap[data[fieldMap["SOFT_BIN"]]] += 1
siteMap[data[fieldMap["SITE_NUM"]]] = 1 siteMap[data[fieldMap["SITE_NUM"]]] = 1
} }
hBinMap := make(map[string]int) hBinMap := make(map[string]int)
@ -189,15 +225,22 @@ func LotInMultipleFilesSelection(product, lot, pbi string) map[string][]string {
if _, ok := binMap[k]; ok { if _, ok := binMap[k]; ok {
sBin = append(sBin, k) sBin = append(sBin, k)
sBinInfoMap := binMap[k].(map[string]interface{}) sBinInfoMap := binMap[k].(map[string]interface{})
hBinMap[sBinInfoMap["HBin"].(string)] = 1 hBinMap[sBinInfoMap["HBin"].(string)] += 1
} }
} }
sort.Slice(sBin, func(i, j int) bool {
return sBinMap[sBin[i]] > sBinMap[sBin[j]]
})
for k := range siteMap { for k := range siteMap {
site = append(site, k) site = append(site, k)
} }
for k := range hBinMap { for k := range hBinMap {
hBin = append(hBin, k) hBin = append(hBin, k)
} }
sort.Slice(hBin, func(i, j int) bool {
return hBinMap[hBin[i]] > hBinMap[hBin[j]]
})
for k := range subBatchMap { for k := range subBatchMap {
subBatch = append(subBatch, k) subBatch = append(subBatch, k)
} }
@ -214,9 +257,9 @@ func LotInMultipleFilesSelection(product, lot, pbi string) map[string][]string {
return res return res
} }
func LotInMultipleFiles(product, lot, pbi string) ([][]string, map[string]int) { func LotInMultipleFiles(product, lot, pbi, step string) ([][]string, map[string]int) {
var fileHandles []*model.FileHandled var fileHandles []*model.FileHandled
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND step != ?", product, lot, pbi, "RT").Find(&fileHandles) global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND step = ?", product, lot, pbi, step).Find(&fileHandles)
datas := make([][]string, 0) datas := make([][]string, 0)
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
for _, fileHandle := range fileHandles { for _, fileHandle := range fileHandles {
@ -263,8 +306,8 @@ func LotInMultipleFiles(product, lot, pbi string) ([][]string, map[string]int) {
func SelectionLimit(req *request.SelectionLimit) (string, string) { func SelectionLimit(req *request.SelectionLimit) (string, string) {
// CP测试没有子批次 // CP测试没有子批次
var fileHandle *model.FileHandled var fileHandle *model.FileHandled
global.PostGreSQL.Where("pbi = ? AND product = ? AND lot = ? AND wafer_id = ?", req.PBI, req.Product, req.Lot, req.WaferID). global.PostGreSQL.Where("pbi = ? AND product = ? AND lot = ? AND wafer_id = ? AND step = ?",
Find(&fileHandle) req.PBI, req.Product, req.Lot, req.WaferID, req.Step).Find(&fileHandle)
f, err := os.Open(fileHandle.Path) f, err := os.Open(fileHandle.Path)
if err != nil { if err != nil {
log.Println(err) log.Println(err)

View File

@ -321,17 +321,17 @@ func ExportHistogram(req *request.Histogram) string {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if len(req.SubBatch) == 0 && len(req.WaferID) == 0 { if len(req.SubBatch) == 0 && len(req.WaferID) == 0 {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else { } else {
if len(req.SubBatch) != 0 { if len(req.SubBatch) != 0 {
for _, subBatch := range req.SubBatch { for _, subBatch := range req.SubBatch {
subBatchDatas, subBatchFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, subBatch, "") subBatchDatas, subBatchFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, subBatch, "", req.Step)
datas = append(datas, subBatchDatas...) datas = append(datas, subBatchDatas...)
fieldMap = subBatchFieldMap fieldMap = subBatchFieldMap
} }
} else if len(req.WaferID) != 0 { } else if len(req.WaferID) != 0 {
for _, waferID := range req.WaferID { for _, waferID := range req.WaferID {
waferIDDatas, waferIDFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", waferID) waferIDDatas, waferIDFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", waferID, req.Step)
datas = append(datas, waferIDDatas...) datas = append(datas, waferIDDatas...)
fieldMap = waferIDFieldMap fieldMap = waferIDFieldMap
} }
@ -747,9 +747,9 @@ func ExportHistogram(req *request.Histogram) string {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if isFT { if isFT {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "") datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "", req.Step)
} else { } else {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group, req.Step)
} }
group = strings.ReplaceAll(group, "-", "_") group = strings.ReplaceAll(group, "-", "_")
@ -1183,17 +1183,17 @@ func ExportScatter(req *request.Scatter) string {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if len(req.SubBatch) == 0 && len(req.WaferID) == 0 { if len(req.SubBatch) == 0 && len(req.WaferID) == 0 {
datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI) datas, fieldMap = LotInMultipleFiles(req.Product, req.Lot, req.PBI, req.Step)
} else { } else {
if len(req.SubBatch) != 0 { if len(req.SubBatch) != 0 {
for _, subBatch := range req.SubBatch { for _, subBatch := range req.SubBatch {
subBatchDatas, subBatchFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, subBatch, "") subBatchDatas, subBatchFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, subBatch, "", req.Step)
datas = append(datas, subBatchDatas...) datas = append(datas, subBatchDatas...)
fieldMap = subBatchFieldMap fieldMap = subBatchFieldMap
} }
} else if len(req.WaferID) != 0 { } else if len(req.WaferID) != 0 {
for _, waferID := range req.WaferID { for _, waferID := range req.WaferID {
waferIDDatas, waferIDFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", waferID) waferIDDatas, waferIDFieldMap := LotInAFile(req.Product, req.Lot, req.PBI, "", waferID, req.Step)
datas = append(datas, waferIDDatas...) datas = append(datas, waferIDDatas...)
fieldMap = waferIDFieldMap fieldMap = waferIDFieldMap
} }
@ -1324,9 +1324,9 @@ func ExportScatter(req *request.Scatter) string {
var datas [][]string var datas [][]string
fieldMap := make(map[string]int) fieldMap := make(map[string]int)
if isFT { if isFT {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "") datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, group, "", req.Step)
} else { } else {
datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group) datas, fieldMap = LotInAFile(req.Product, req.Lot, req.PBI, "", group, req.Step)
} }
group = strings.ReplaceAll(group, "-", "_") group = strings.ReplaceAll(group, "-", "_")
selectionPointsMap := make(map[string]map[string]int) selectionPointsMap := make(map[string]map[string]int)
@ -1441,3 +1441,796 @@ func ExportScatter(req *request.Scatter) string {
defer scatterFile.Close() defer scatterFile.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
} }
func ExportFT() string {
//start := carbon.Now().SubWeek().Format("Y-m-d")
//end := carbon.Now().Format("Y-m-d")
//var fileHandles []*model.FileHandled
//global.PostGreSQL.Where("ending_time != ? AND DATE(ending_time) BETWEEN ? AND ?", "", start, end).
// Find(&fileHandles)
file := excelize.NewFile()
var ftLists []*model.FTList
//global.PostGreSQL.Where("order_date BETWEEN ? AND ?", start, end).Find(&ftLists)
global.PostGreSQL.Find(&ftLists)
//global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ?", "MP5016-5EC0", "S3S592", "M589-2306200001").Find(&ftLists)
var exportFTs []*model.ExportFT
for _, ftList := range ftLists {
var warning *model.Warning
global.PostGreSQL.Where("step LIKE ? AND product = ?", "%FT%", ftList.Product).
Preload("ProductionControl").Preload("PassProbabilityDiff").Preload("BinControl").
Preload("SelectionDiffControl").Preload("StackingMaterialsWarning").Preload("HistogramSelection").
Preload("ScatterSelection").Find(&warning)
var testQuantity, firstPassQuantity, firstPassProbability, passQuantity, passProbability string
var finalTestQuantity, finalPassQuantity, finalPassProbability, returnProbability string
var reports []*model.Report
global.PostGreSQL.Where("step LIKE ? AND product = ? AND lot = ? AND pbi = ?",
"%FT%", ftList.Product, ftList.Lot, ftList.PBI).Find(&reports)
for _, report := range reports {
reportTestQuantityDecimal, _ := decimal.NewFromString(report.TestQuantity)
testQuantityDecimal, _ := decimal.NewFromString(testQuantity)
testQuantity = testQuantityDecimal.Add(reportTestQuantityDecimal).String()
reportFirstPassQuantityDecimal, _ := decimal.NewFromString(report.FirstPassQuantity)
firstPassQuantityDecimal, _ := decimal.NewFromString(firstPassQuantity)
firstPassQuantity = firstPassQuantityDecimal.Add(reportFirstPassQuantityDecimal).String()
reportPassQuantityDecimal, _ := decimal.NewFromString(report.PassQuantity)
passQuantityDecimal, _ := decimal.NewFromString(passQuantity)
passQuantity = passQuantityDecimal.Add(reportPassQuantityDecimal).String()
}
testQuantityDecimal, _ := decimal.NewFromString(testQuantity)
firstPassQuantityDecimal, _ := decimal.NewFromString(firstPassQuantity)
passQuantityDecimal, _ := decimal.NewFromString(passQuantity)
if !testQuantityDecimal.IsZero() {
firstPassProbability = firstPassQuantityDecimal.Div(testQuantityDecimal).Round(4).
Mul(decimal.NewFromInt(100)).String() + "%"
passProbability = passQuantityDecimal.Div(testQuantityDecimal).Round(4).
Mul(decimal.NewFromInt(100)).String() + "%"
returnProbability = passQuantityDecimal.Sub(firstPassQuantityDecimal).Div(testQuantityDecimal).Round(4).
Mul(decimal.NewFromInt(100)).String() + "%"
}
var finalReports []*model.FinalReport
hardBinCounter := make(map[string]float64)
global.PostGreSQL.Where("step LIKE ? AND product = ? AND lot = ? AND pbi = ?",
"%FT%", ftList.Product, ftList.Lot, ftList.PBI).Find(&finalReports)
for _, finalReport := range finalReports {
reportTestQuantityDecimal, _ := decimal.NewFromString(finalReport.ReportTestQuantity)
finalTestQuantityDecimal, _ := decimal.NewFromString(finalTestQuantity)
finalTestQuantity = finalTestQuantityDecimal.Add(reportTestQuantityDecimal).String()
reportPassQuantityDecimal, _ := decimal.NewFromString(finalReport.ReportPassQuantity)
finalPassQuantityDecimal, _ := decimal.NewFromString(finalPassQuantity)
finalPassQuantity = finalPassQuantityDecimal.Add(reportPassQuantityDecimal).String()
bin1Decimal, _ := decimal.NewFromString(finalReport.Bin1)
bin2Decimal, _ := decimal.NewFromString(finalReport.Bin2)
bin2, _ := bin2Decimal.Float64()
hardBinCounter["BIN2"] += bin2
bin3Decimal, _ := decimal.NewFromString(finalReport.Bin3)
bin3, _ := bin3Decimal.Float64()
hardBinCounter["BIN3"] += bin3
bin4Decimal, _ := decimal.NewFromString(finalReport.Bin4)
bin4, _ := bin4Decimal.Float64()
hardBinCounter["BIN4"] += bin4
bin5Decimal, _ := decimal.NewFromString(finalReport.Bin5)
bin5, _ := bin5Decimal.Float64()
hardBinCounter["BIN5"] += bin5
bin6Decimal, _ := decimal.NewFromString(finalReport.Bin6)
bin6, _ := bin6Decimal.Float64()
hardBinCounter["BIN6"] += bin6
bin7Decimal, _ := decimal.NewFromString(finalReport.Bin7)
bin7, _ := bin7Decimal.Float64()
hardBinCounter["BIN7"] += bin7
bin8Decimal, _ := decimal.NewFromString(finalReport.Bin8)
bin8, _ := bin8Decimal.Float64()
hardBinCounter["BIN8"] += bin8
bin9Decimal, _ := decimal.NewFromString(finalReport.Bin9)
bin9, _ := bin9Decimal.Float64()
hardBinCounter["BIN9"] += bin9
bin10Decimal, _ := decimal.NewFromString(finalReport.Bin10)
bin10, _ := bin10Decimal.Float64()
hardBinCounter["BIN10"] += bin10
outlookFailDecimal, _ := decimal.NewFromString(finalReport.OutlookFail)
otherDecimal, _ := decimal.NewFromString(finalReport.Other)
bentStitchDecimal, _ := decimal.NewFromString(finalReport.BentStitch)
scrappedDecimal, _ := decimal.NewFromString(finalReport.Scrapped)
if !reportTestQuantityDecimal.IsZero() {
finalReport.Bin1 = bin1Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin2 = bin2Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin3 = bin3Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin4 = bin4Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin5 = bin5Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin6 = bin6Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin7 = bin7Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin8 = bin8Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin9 = bin9Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Bin10 = bin10Decimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.OutlookFail = outlookFailDecimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Other = otherDecimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.BentStitch = bentStitchDecimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
finalReport.Scrapped = scrappedDecimal.Div(reportTestQuantityDecimal).Round(4).Mul(decimal.NewFromInt(100)).
String() + "%"
}
}
finalTestQuantityDecimal, _ := decimal.NewFromString(finalTestQuantity)
finalPassQuantityDecimal, _ := decimal.NewFromString(finalPassQuantity)
if !finalTestQuantityDecimal.IsZero() {
finalPassProbability = finalPassQuantityDecimal.Div(finalTestQuantityDecimal).Round(4).
Mul(decimal.NewFromInt(100)).String() + "%"
}
var testQuantityDiff, passQuantityDiff string
hardBinState := "正常"
if !testQuantityDecimal.IsZero() {
testQuantityDiff = testQuantityDecimal.Sub(finalTestQuantityDecimal).Div(testQuantityDecimal).Round(4).
Mul(decimal.NewFromInt(100)).String() + "%"
passQuantityDiff = passQuantityDecimal.Sub(finalPassQuantityDecimal).Div(passQuantityDecimal).Round(4).
Mul(decimal.NewFromInt(100)).String() + "%"
for _, binControl := range warning.BinControl {
binDecimal := decimal.NewFromFloat(hardBinCounter[binControl.Bin])
limitDecimal, _ := decimal.NewFromString(strings.ReplaceAll(binControl.BinFailLimitH, "%", ""))
if !binDecimal.Div(testQuantityDecimal).Mul(decimal.NewFromInt(100)).LessThanOrEqual(limitDecimal) {
hardBinState = "异常"
}
}
}
var fileHandles []*model.FileHandled
global.PostGreSQL.Where("step = ? AND pbi = ? AND product = ? AND lot = ?", "FT", ftList.PBI,
ftList.Product, ftList.Lot).Find(&fileHandles)
siteDiffState := "正常"
stackingMaterials := "否"
for _, fileHandle := range fileHandles {
f, err := os.Open(fileHandle.Path)
if err != nil {
log.Println(err)
}
scanner := bufio.NewScanner(f)
datas := make([][]string, 0)
fieldMap := make(map[string]int)
for scanner.Scan() {
line := scanner.Text()
s := strings.Split(line, ",")
datas = append(datas, s[:len(s)-1])
if len(datas) == 1 {
for index, cell := range s {
if index == len(s)-1 {
continue
}
fieldMap[cell] = index
}
}
}
if len(datas) >= 1 {
datas = datas[1:]
}
siteCounter := make(map[string]int64)
sitePassCounter := make(map[string]int64)
selectionCounter := make(map[string]map[string]string)
stackingMaterialsArray := make(map[string]map[string][]float64)
for _, data := range datas {
siteCounter[data[fieldMap["SITE_NUM"]]]++
if _, ok := stackingMaterialsArray[data[fieldMap["SITE_NUM"]]]; !ok {
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]] = make(map[string][]float64)
}
if data[fieldMap["SOFT_BIN"]] == "1" {
sitePassCounter[data[fieldMap["SITE_NUM"]]]++
for _, stackingMaterialsWarning := range warning.StackingMaterialsWarning {
selectionDecimal, _ := decimal.NewFromString(data[fieldMap[stackingMaterialsWarning.Selection]])
selectionFloat64, _ := selectionDecimal.Float64()
if _, ok := stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection]; !ok {
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection] = []float64{selectionFloat64}
} else {
//quantity, _ := strconv.Atoi(stackingMaterialsWarning.Quantity)
if len(stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection]) >
stackingMaterialsWarning.Quantity { //quantity
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection] =
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection][1:]
}
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection] = append(
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection], selectionFloat64)
}
if len(stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection]) ==
stackingMaterialsWarning.Quantity {
diff, _ := strconv.ParseFloat(stackingMaterialsWarning.Diff, 64)
midArray := stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection]
sort.Slice(midArray,
func(i, j int) bool {
return midArray[i] >
midArray[j]
})
if midArray[0]-midArray[len(midArray)-1] >
diff {
stackingMaterials = "是"
}
}
}
} else {
for _, stackingMaterialsWarning := range warning.StackingMaterialsWarning {
stackingMaterialsArray[data[fieldMap["SITE_NUM"]]][stackingMaterialsWarning.Selection] = []float64{}
}
}
for _, selectionDiffControl := range warning.SelectionDiffControl {
if _, ok := selectionCounter[data[fieldMap["SITE_NUM"]]]; !ok {
selectionCounter[data[fieldMap["SITE_NUM"]]] = make(map[string]string)
}
sumDecimal, _ := decimal.NewFromString(selectionCounter[data[fieldMap["SITE_NUM"]]][selectionDiffControl.Selection])
aDecimal, _ := decimal.NewFromString(data[fieldMap[selectionDiffControl.Selection]])
selectionCounter[data[fieldMap["SITE_NUM"]]][selectionDiffControl.Selection] = sumDecimal.Add(aDecimal).String()
}
}
for _, selectionDiffControl := range warning.SelectionDiffControl {
maxAverage, minAverage := math.SmallestNonzeroFloat64, math.MaxFloat64
for _, v := range selectionCounter {
sumDecimal, _ := decimal.NewFromString(v[selectionDiffControl.Selection])
average, _ := sumDecimal.Div(decimal.NewFromInt(siteCounter[selectionDiffControl.Selection])).Float64()
if average > maxAverage {
maxAverage = average
}
if average < minAverage {
minAverage = average
}
}
siteDiffDecimal, _ := decimal.NewFromString(selectionDiffControl.SiteDiff)
averageDiffDecimal := decimal.NewFromFloat(maxAverage - minAverage)
if !siteDiffDecimal.LessThanOrEqual(averageDiffDecimal) {
siteDiffState = "异常"
break
}
}
if siteDiffState == "正常" {
for site := range siteCounter {
sumDecimal := decimal.NewFromInt(siteCounter[site])
sumPassDecimal := decimal.NewFromInt(sitePassCounter[site])
sitePassProbabilityDecimal, _ := decimal.NewFromString(strings.ReplaceAll(warning.FirstPassProbabilityLimitL, "%", ""))
if !sumPassDecimal.Div(sumDecimal).Mul(decimal.NewFromInt(100)).LessThanOrEqual(sitePassProbabilityDecimal) {
siteDiffState = "异常"
break
}
}
}
f.Close()
}
exportFTs = append(exportFTs, &model.ExportFT{
Product: ftList.Product,
Lot: ftList.Lot,
PBI: ftList.PBI,
Factory: ftList.Factory,
TestProgram: ftList.TestProgram,
OrderDate: ftList.OrderDate,
Seal: ftList.Seal,
FinalTestQuantity: finalTestQuantity,
FinalPassQuantity: finalPassQuantity,
FinalPassProbability: finalPassProbability,
FirstPassQuantity: firstPassQuantity,
FirstPassProbability: firstPassProbability,
TestQuantity: testQuantity,
PassQuantity: passQuantity,
PassProbability: passProbability,
ReturnProbability: returnProbability,
TestQuantityDiff: testQuantityDiff,
PassQuantityDiff: passQuantityDiff,
HardBinState: hardBinState,
SiteDiffState: siteDiffState,
StackingMaterials: stackingMaterials,
})
if len(finalReports) > 0 {
ExportFTDetailsSheet(finalReports, file)
}
if warning != nil {
ExportFTHistogramSheet(warning, ftList, file)
ExportFTScatterSheet(warning, ftList, file)
}
}
ExportFTSumSheet(exportFTs, file)
file.DeleteSheet("Sheet1")
filePath := time.Now().Format("FT自动导出_2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("自动导出"), filePath)
file.SaveAs(filePath)
defer file.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}
func ExportFTSumSheet(exportFTs []*model.ExportFT, f *excelize.File) {
sheetName := "FT记录总表"
_, _ = f.NewSheet(sheetName)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"成品型号", "晶圆批次", "PBI", "测试厂", "测试程序", "下单日期",
"丝印", "结批测试数量", "结批良品数量", "结批良率", "初测良品数量", "初测良率", "测试数量", "良品数量", "测试良率",
"回收率", "测试数量差异", "良品数量差异", "硬件bin", "SITE差异", "叠料风险",
})
_ = f.SetCellStyle(sheetName, "A1", "U1", ExportFTSheetTitleStyle(f))
for index, exportFT := range exportFTs {
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{exportFT.Product, exportFT.Lot,
exportFT.PBI, exportFT.Factory, exportFT.TestProgram, exportFT.OrderDate, exportFT.Seal, exportFT.FinalTestQuantity,
exportFT.FinalPassQuantity, exportFT.FinalPassProbability, exportFT.FirstPassQuantity, exportFT.FirstPassProbability,
exportFT.TestQuantity, exportFT.PassQuantity, exportFT.PassProbability, exportFT.ReturnProbability,
exportFT.TestQuantityDiff, exportFT.PassQuantityDiff, exportFT.HardBinState, exportFT.SiteDiffState,
exportFT.StackingMaterials})
}
_ = f.SetRowStyle(sheetName, 2, len(exportFTs)+1, NormalSheetStyle(f))
_ = f.SetColWidth(sheetName, "A", "U", 20)
}
func ExportFTDetailsSheet(finalReports []*model.FinalReport, f *excelize.File) {
sheetName := "FT记录BIN表"
_, _ = f.NewSheet(sheetName)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"成品型号", "晶圆批次", "PBI", "测试厂", "测试程序", "下单日期", "丝印",
"子批", "结批测试数量", "结批良品数量", "结批良率", "BIN1", "BIN2", "BIN3", "BIN4", "BIN5", "BIN6", "BIN7", "BIN8", "BIN9",
"BIN10", "外观不良", "少数", "弯脚", "报废",
})
_ = f.SetCellStyle(sheetName, "A1", "Y1", ExportFTSheetTitleStyle(f))
for index, finalReport := range finalReports {
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{finalReport.Product, finalReport.Lot,
finalReport.PBI, finalReport.Factory, finalReport.TestProgram, finalReport.OrderDate, finalReport.Seal,
finalReport.SubBatch, finalReport.ReportTestQuantity, finalReport.ReportPassQuantity, finalReport.ReportPassProbability,
finalReport.Bin1, finalReport.Bin2, finalReport.Bin3, finalReport.Bin4, finalReport.Bin5, finalReport.Bin6,
finalReport.Bin7, finalReport.Bin8, finalReport.Bin9, finalReport.Bin10, finalReport.OutlookFail,
finalReport.Other, finalReport.BentStitch, finalReport.Scrapped})
}
_ = f.SetRowStyle(sheetName, 2, len(finalReports)+1, NormalSheetStyle(f))
_ = f.SetColWidth(sheetName, "A", "Y", 20)
}
func ExportFTHistogramSheet(warning *model.Warning, ftList *model.FTList, f *excelize.File) {
row := 1
start := row
selectionUnit := make(map[string]string)
subBatchDiff := make(map[string][]float64)
sheetName := ftList.Lot + "汇总表"
f.NewSheet(sheetName)
var groups []string
global.PostGreSQL.Model(&model.FileHandled{}).Where("product = ? AND lot = ? AND pbi = ?",
ftList.Product, ftList.Lot, ftList.PBI).Group("sub_batch").Select("sub_batch").Find(&groups)
for _, group := range groups {
var fileHandle *model.FileHandled
global.PostGreSQL.Where("product = ? AND lot = ? AND pbi = ? AND sub_batch = ?",
ftList.Product, ftList.Lot, ftList.PBI, group).Find(&fileHandle)
m := make(map[string]map[string]string)
_ = json.Unmarshal([]byte(fileHandle.TitleInfo), &m)
siteSelectionInfo := make(map[string][]float64)
selectionInfo := make(map[string][]float64)
var datas [][]string
fieldMap := make(map[string]int)
datas, fieldMap = LotInAFile(ftList.Product, ftList.Lot, ftList.PBI, group, "", "FT")
group = strings.ReplaceAll(group, "-", "_")
if len(datas) == 0 {
continue
}
for _, data := range datas {
for _, histogramSelection := range warning.HistogramSelection {
selectionDecimal, _ := decimal.NewFromString(data[fieldMap[histogramSelection.Selection]])
selectionFloat, _ := selectionDecimal.Float64()
var filed string
filed = histogramSelection.Selection
if _, ok := siteSelectionInfo[filed]; !ok {
siteSelectionInfo[filed] = []float64{math.MaxInt, math.MinInt, 0, 0}
}
if siteSelectionInfo[filed][0] > selectionFloat {
siteSelectionInfo[filed][0] = selectionFloat
}
if siteSelectionInfo[filed][1] < selectionFloat {
siteSelectionInfo[filed][1] = selectionFloat
}
siteSelectionInfo[filed][2] += selectionFloat
siteSelectionInfo[filed][3]++
if _, ok := selectionInfo[histogramSelection.Selection]; !ok {
selectionInfo[histogramSelection.Selection] = []float64{math.MaxInt, math.MinInt, 0, 0}
}
if selectionInfo[histogramSelection.Selection][0] > selectionFloat {
selectionInfo[histogramSelection.Selection][0] = selectionFloat
}
if selectionInfo[histogramSelection.Selection][1] < selectionFloat {
selectionInfo[histogramSelection.Selection][1] = selectionFloat
}
selectionInfo[histogramSelection.Selection][2] += selectionFloat
selectionInfo[histogramSelection.Selection][3]++
}
}
selectionHistogramX := make(map[string][]string)
selectionHistogramY := make(map[string][]int)
for k, v := range siteSelectionInfo {
siteSelectionInfo[k] = []float64{v[0], v[1], v[2], v[3], v[2] / v[3], 0, 0}
}
for k, v := range selectionInfo {
selectionInfo[k] = []float64{v[0], v[1], v[2], v[3], v[2] / v[3], 0, 0}
selectionHistogramX[group+"_"+k] = []string{}
minDecimal := decimal.NewFromFloat(v[0])
if minDecimal.LessThan(decimal.NewFromInt(0)) {
minDecimal = minDecimal.RoundUp(0)
} else {
minDecimal = minDecimal.RoundDown(0)
}
maxDecimal := decimal.NewFromFloat(v[1])
if maxDecimal.LessThan(decimal.NewFromInt(0)) {
maxDecimal = maxDecimal.RoundDown(0)
} else {
maxDecimal = maxDecimal.RoundUp(0)
}
interval := maxDecimal.Sub(minDecimal).Div(decimal.NewFromInt(20))
for i := 0; i < 21; i++ {
xPoint := minDecimal.Add(interval.Mul(decimal.NewFromInt(int64(i)))).String()
selectionHistogramX[group+"_"+k] = append(selectionHistogramX[group+"_"+k], xPoint)
}
}
for _, data := range datas {
for k, v := range siteSelectionInfo {
var field string
field = k
if data[fieldMap[field]] != "" {
selectionDecimal, _ := decimal.NewFromString(data[fieldMap[field]])
averageDecimal := decimal.NewFromFloat(v[4])
d, _ := averageDecimal.Sub(selectionDecimal).Pow(decimal.NewFromInt(2)).
Float64()
v[5] += d
v[6]++
}
}
for k, v := range selectionInfo {
if data[fieldMap[k]] != "" {
selectionDecimal, _ := decimal.NewFromString(data[fieldMap[k]])
averageDecimal := decimal.NewFromFloat(v[4])
d, _ := averageDecimal.Sub(selectionDecimal).Pow(decimal.NewFromInt(2)).
Float64()
field := group + "_" + k
for i := 0; i < len(selectionHistogramX[field]); i++ {
if i == len(selectionHistogramX[field])-1 {
xPointDecimal, _ := decimal.NewFromString(selectionHistogramX[field][i])
if xPointDecimal.Equals(selectionDecimal) {
selectionHistogramY[field][i]++
}
break
}
xPointMin, _ := decimal.NewFromString(selectionHistogramX[field][i])
xPointMax, _ := decimal.NewFromString(selectionHistogramX[field][i+1])
if _, ok := selectionHistogramY[field]; !ok {
selectionHistogramY[field] = make([]int, len(selectionHistogramX[field]))
}
if xPointMin.LessThanOrEqual(selectionDecimal) && selectionDecimal.LessThan(xPointMax) {
selectionHistogramY[field][i]++
}
}
v[5] += d
v[6]++
}
}
}
rowIndex, colIndex := 2, 1
histogramSheetName := ftList.Lot + "_" + group + "直方图"
f.NewSheet(histogramSheetName)
selectionValueMap := make(map[string][]int)
for k, v := range selectionHistogramX {
sheetX := []interface{}{k}
for _, x := range v {
sheetX = append(sheetX, x)
}
sheetY := []interface{}{"数量"}
for _, y := range selectionHistogramY[k] {
sheetY = append(sheetY, y)
}
for idx, rows := range [][]interface{}{
sheetX,
sheetY,
} {
cell, err := excelize.CoordinatesToCellName(colIndex, rowIndex+idx)
if err != nil {
fmt.Println(err)
}
if err = f.SetSheetRow(histogramSheetName, cell, &rows); err != nil {
fmt.Println(err)
}
}
selectionValueMap[k] = []int{rowIndex, len(selectionHistogramY[k]) + 1}
rowIndex += 2
}
a := 1
for _, histogramSelection := range warning.HistogramSelection {
b := 1
for k, v := range selectionValueMap {
if strings.Contains(k, histogramSelection.Selection) {
if err := f.AddChart(histogramSheetName, utils.NumToRow(strconv.Itoa(b))+strconv.Itoa(a), &excelize.Chart{
Type: excelize.Col,
Series: []excelize.ChartSeries{
{
Name: histogramSheetName + "!$A$1",
Categories: histogramSheetName + "!$B$" + strconv.Itoa(v[0]) + ":$" +
utils.NumToRow(strconv.Itoa(v[1])) + "$" + strconv.Itoa(v[0]),
Values: histogramSheetName + "!$B$" + strconv.Itoa(v[0]+1) + ":$" +
utils.NumToRow(strconv.Itoa(v[1])) + "$" + strconv.Itoa(v[0]+1),
Marker: excelize.ChartMarker{
Symbol: "none", Size: 10,
},
},
},
Format: excelize.GraphicOptions{
ScaleX: 1,
ScaleY: 1,
OffsetX: 15,
OffsetY: 10,
},
Legend: excelize.ChartLegend{
Position: "left",
},
Title: []excelize.RichTextRun{
{
Text: k,
},
},
PlotArea: excelize.ChartPlotArea{
ShowCatName: false,
ShowLeaderLines: false,
ShowVal: true,
},
ShowBlanksAs: "zero",
}, &excelize.Chart{
Type: excelize.Line,
Series: []excelize.ChartSeries{
{
Name: group + "!$A$1",
Categories: group + "!$B$" + strconv.Itoa(v[0]) + ":$" +
utils.NumToRow(strconv.Itoa(v[1])) + "$" + strconv.Itoa(v[0]),
Values: group + "!$B$" + strconv.Itoa(v[0]+1) + ":$" +
utils.NumToRow(strconv.Itoa(v[1])) + "$" + strconv.Itoa(v[0]+1),
Marker: excelize.ChartMarker{
Symbol: "none", Size: 10,
},
},
},
Format: excelize.GraphicOptions{
ScaleX: 1,
ScaleY: 1,
OffsetX: 15,
OffsetY: 10,
},
Legend: excelize.ChartLegend{
Position: "right",
},
PlotArea: excelize.ChartPlotArea{
ShowCatName: false,
ShowLeaderLines: false,
},
}); err != nil {
fmt.Println(err)
}
b += 9
}
}
a += 20
}
col := 1
_ = f.SetSheetCol(sheetName, "A"+strconv.Itoa(start), &[]interface{}{
"子批:" + group})
_ = f.SetSheetCol(sheetName, "A"+strconv.Itoa(start+1), &[]interface{}{
"", "最小值", "最大值", "平均值", "δ", "数量", "Limit L", "Limit H", "UNIT"})
col++
var selectionInfoArray []SelectionInfo
for _, histogramSelection := range warning.HistogramSelection {
var oneSelectionInfo []SelectionInfo
for k, v := range siteSelectionInfo {
if !strings.Contains(k, histogramSelection.Selection) {
continue
}
oneSelectionInfo = append(oneSelectionInfo, SelectionInfo{
Field: k,
Min: v[0],
Max: v[1],
Average: v[4],
StandardDeviation: math.Sqrt(v[5] / v[6]),
Num: v[3],
})
}
sort.Slice(oneSelectionInfo, func(i, j int) bool {
return oneSelectionInfo[i].Field < oneSelectionInfo[j].Field
})
selectionInfoArray = append(selectionInfoArray, oneSelectionInfo...)
}
for _, v := range selectionInfoArray {
field := strings.Split(v.Field, "_Site")[0]
limitLDecimal, _ := decimal.NewFromString(m[field]["LimitL"])
limitLFloat, _ := limitLDecimal.Float64()
limitUDecimal, _ := decimal.NewFromString(m[field]["LimitU"])
limitUFloat, _ := limitUDecimal.Float64()
selectionUnit[field] = m[field]["Unit"]
_ = f.SetSheetCol(sheetName, utils.NumToRow(strconv.Itoa(col))+strconv.Itoa(start+1), &[]interface{}{
v.Field, v.Min, v.Max, v.Average, v.StandardDeviation, v.Num, limitLFloat, limitUFloat, m[field]["Unit"]})
col++
}
for k, v := range selectionInfo {
if _, ok := subBatchDiff[k]; !ok {
subBatchDiff[k] = []float64{v[4], v[4], v[5] / v[6], v[5] / v[6]}
selectionUnit[k] = m[k]["Unit"]
} else {
if v[4] > subBatchDiff[k][0] {
subBatchDiff[k][0] = v[4]
}
if v[4] < subBatchDiff[k][1] {
subBatchDiff[k][1] = v[4]
}
if v[5]/v[6] > subBatchDiff[k][2] {
subBatchDiff[k][2] = v[5] / v[6]
}
if v[5]/v[6] < subBatchDiff[k][3] {
subBatchDiff[k][3] = v[5] / v[6]
}
}
}
_ = f.MergeCell(sheetName, "A"+strconv.Itoa(start), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start),
NormalSheetStyle(f))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start+1), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start+1),
TitleStyle(f))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start+2), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start+6),
ActualLimitStyle(f))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start+7), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start+9),
LimitStyle(f))
_ = f.SetColWidth(sheetName, "A", utils.NumToRow(strconv.Itoa(col-1)),
20)
start += 10
start += 1
}
start += 1
col := 2
_ = f.SetSheetCol(sheetName, "A"+strconv.Itoa(start), &[]interface{}{
"批次差异汇总"})
_ = f.SetSheetCol(sheetName, "A"+strconv.Itoa(start+1), &[]interface{}{
"", "平均值", "δ", "UNIT"})
for _, histogramSelection := range warning.HistogramSelection {
if len(subBatchDiff[histogramSelection.Selection]) != 0 {
_ = f.SetSheetCol(sheetName, utils.NumToRow(strconv.Itoa(col))+strconv.Itoa(start+1), &[]interface{}{
histogramSelection.Selection, subBatchDiff[histogramSelection.Selection][0] - subBatchDiff[histogramSelection.Selection][1],
subBatchDiff[histogramSelection.Selection][2] - subBatchDiff[histogramSelection.Selection][3],
selectionUnit[histogramSelection.Selection]})
col++
}
}
_ = f.MergeCell(sheetName, "A"+strconv.Itoa(start), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start),
NormalSheetStyle(f))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start+1), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start+1),
TitleStyle(f))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start+2), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start+3),
ActualLimitStyle(f))
_ = f.SetCellStyle(sheetName, "A"+strconv.Itoa(start+4), utils.NumToRow(strconv.Itoa(col-1))+strconv.Itoa(start+4),
LimitStyle(f))
}
func ExportFTScatterSheet(warning *model.Warning, ftList *model.FTList, f *excelize.File) {
var groups []string
global.PostGreSQL.Model(&model.FileHandled{}).Where("product = ? AND lot = ? AND pbi = ?",
ftList.Product, ftList.Lot, ftList.PBI).Group("sub_batch").Select("sub_batch").Find(&groups)
for _, group := range groups {
var datas [][]string
fieldMap := make(map[string]int)
datas, fieldMap = LotInAFile(ftList.Product, ftList.Lot, ftList.PBI, group, "", "FT")
if len(datas) == 0 {
continue
}
group = strings.ReplaceAll(group, "-", "_")
selectionPointsMap := make(map[string]map[string]int)
for _, data := range datas {
for _, scatterSelection := range warning.ScatterSelection {
var field string
field = scatterSelection.XSelection + "," + scatterSelection.YSelection
if _, ok := selectionPointsMap[field]; !ok {
selectionPointsMap[field] = map[string]int{}
}
selectionPointsMap[field][data[fieldMap[scatterSelection.XSelection]]+","+data[fieldMap[scatterSelection.YSelection]]]++
}
}
sheetName := ftList.Lot + "_" + group + "散点图"
f.NewSheet(sheetName)
selectionValueMap := make(map[string][]int)
rowIndex := 1
for _, scatterSelection := range warning.ScatterSelection {
for k := range selectionPointsMap {
if strings.Contains(k, scatterSelection.XSelection+","+scatterSelection.YSelection) {
sheetX := []interface{}{k, scatterSelection.XSelection}
sheetY := []interface{}{"", scatterSelection.YSelection}
for point := range selectionPointsMap[k] {
pointXY := strings.Split(point, ",")
xDecimal, _ := decimal.NewFromString(pointXY[0])
x, _ := xDecimal.Float64()
yDecimal, _ := decimal.NewFromString(pointXY[1])
y, _ := yDecimal.Float64()
sheetX = append(sheetX, x)
sheetY = append(sheetY, y)
}
for idx, row := range [][]interface{}{
sheetX,
sheetY,
} {
cell, err := excelize.CoordinatesToCellName(1, rowIndex+idx)
if err != nil {
fmt.Println(err)
}
if err = f.SetSheetRow(sheetName, cell, &row); err != nil {
fmt.Println(err)
}
}
selectionValueMap[k] = []int{rowIndex, len(sheetY) + 1}
rowIndex += 2
}
}
}
a := 1
for _, scatterSelection := range warning.ScatterSelection {
b := 1
for k, v := range selectionValueMap {
if strings.Contains(k, scatterSelection.XSelection+","+scatterSelection.YSelection) {
if err := f.AddChart(sheetName, utils.NumToRow(strconv.Itoa(b))+strconv.Itoa(a), &excelize.Chart{
Type: excelize.Scatter,
Series: []excelize.ChartSeries{
{
Name: sheetName + "!$A$1",
Categories: sheetName + "!$C$" + strconv.Itoa(v[0]) + ":$" +
utils.NumToRow(strconv.Itoa(v[1])) + "$" + strconv.Itoa(v[0]),
Values: sheetName + "!$C$" + strconv.Itoa(v[0]+1) + ":$" +
utils.NumToRow(strconv.Itoa(v[1])) + "$" + strconv.Itoa(v[0]+1),
Marker: excelize.ChartMarker{
Symbol: "circle", Size: 1,
},
},
},
Format: excelize.GraphicOptions{
ScaleX: 1,
ScaleY: 1,
OffsetX: 15,
OffsetY: 10,
},
Legend: excelize.ChartLegend{
Position: "bottom",
},
Title: []excelize.RichTextRun{
{
Text: k,
},
},
//PlotArea: excelize.ChartPlotArea{
// ShowCatName: false,
// ShowLeaderLines: false,
//},
ShowBlanksAs: "zero",
}); err != nil {
fmt.Println(err)
}
b += 9
}
}
a += 20
}
}
}

View File

@ -115,3 +115,20 @@ func NormalNumberSheetStyle(f *excelize.File) int {
}) })
return style return style
} }
func ExportFTSheetTitleStyle(f *excelize.File) int {
style, _ := f.NewStyle(&excelize.Style{
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", Pattern: 1, Color: []string{"FFC000"}},
Font: &excelize.Font{Family: "微软雅黑", Size: 10, Bold: false},
Alignment: &excelize.Alignment{
Horizontal: "center",
},
})
return style
}

View File

@ -87,17 +87,17 @@ func PackagePassProbabilityLine(r *request.PackagePassProbabilityLine) ([]*model
continue continue
} }
var stockInQuantity, failQuantity float64 var stockInQuantity, failQuantity float64
for _, rva := range tcSfd.RvaFile { //for _, rva := range tcSfd.RvaFile {
for _, idd := range rva.IddFile { for _, idd := range tcSfd.RvaFile.IddFile {
if _, ok := lotMap[idd.Idd04]; !ok && len(lotMap) > 0 { if _, ok := lotMap[idd.Idd04]; !ok && len(lotMap) > 0 {
continue continue
} }
stockInQuantity += idd.Idd13 stockInQuantity += idd.Idd13
if idd.Idd06 == "BIN99" { if idd.Idd06 == "BIN99" {
failQuantity += idd.Idd13 failQuantity += idd.Idd13
}
} }
} }
//}
var s string var s string
if r.DateSize == "天" { if r.DateSize == "天" {
s = carbon.Parse(r.OrderDateStart).AddDays(int(carbon.Parse(r.OrderDateStart). s = carbon.Parse(r.OrderDateStart).AddDays(int(carbon.Parse(r.OrderDateStart).
@ -224,14 +224,14 @@ func OrderNumberHistogram(r *request.PackagePassProbabilityLine) []*model.Histog
continue continue
} }
var stockInQuantity float64 var stockInQuantity float64
for _, rva := range tcSfd.RvaFile { //for _, rva := range tcSfd.RvaFile {
for _, idd := range rva.IddFile { for _, idd := range tcSfd.RvaFile.IddFile {
if _, ok := lotMap[idd.Idd04]; !ok && len(lotMap) > 0 { if _, ok := lotMap[idd.Idd04]; !ok && len(lotMap) > 0 {
continue continue
}
stockInQuantity += idd.Idd13
} }
stockInQuantity += idd.Idd13
} }
//}
var s string var s string
if r.DateSize == "天" { if r.DateSize == "天" {
s = carbon.Parse(r.OrderDateStart).AddDays(int(carbon.Parse(r.OrderDateStart). s = carbon.Parse(r.OrderDateStart).AddDays(int(carbon.Parse(r.OrderDateStart).
@ -453,3 +453,7 @@ func FTPassProbabilityByProduct(r *request.PassProbabilityByProduct) (*model.Lin
} }
return line, histogram, binLine, binHistogram return line, histogram, binLine, binHistogram
} }
func PassProbabilityLine(r *request.TestPassProbabilityLine) {
}

View File

@ -10,8 +10,9 @@ import (
func CreateFinalReportExcel(req *request.CreateFinalReportExcel) error { func CreateFinalReportExcel(req *request.CreateFinalReportExcel) error {
var finalReportExcel *model.FinalReportExcel var finalReportExcel *model.FinalReportExcel
if errors.Is(global.PostGreSQL.Where("factory = ?", req.Factory).Find(&finalReportExcel).Error, gorm.ErrRecordNotFound) { if errors.Is(global.PostGreSQL.Where("factory = ?", req.Factory).First(&finalReportExcel).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.FinalReportExcel{ global.PostGreSQL.Create(&model.FinalReportExcel{
Step: req.Step,
Product: req.Product, Product: req.Product,
Lot: req.Lot, Lot: req.Lot,
Factory: req.Factory, Factory: req.Factory,
@ -37,6 +38,7 @@ func CreateFinalReportExcel(req *request.CreateFinalReportExcel) error {
BentStitch: req.BentStitch, BentStitch: req.BentStitch,
Scrapped: req.Scrapped, Scrapped: req.Scrapped,
}) })
return nil
} }
return errors.New(req.Factory + "信息已存在") return errors.New(req.Factory + "信息已存在")
} }
@ -54,6 +56,7 @@ func UpdateFinalReportExcel(req *request.UpdateFinalReportExcel) error {
return errors.New("未找到需要修改的厂商") return errors.New("未找到需要修改的厂商")
} }
global.PostGreSQL.Model(&finalReportExcel).Updates(map[string]interface{}{ global.PostGreSQL.Model(&finalReportExcel).Updates(map[string]interface{}{
"step": req.Step,
"product": req.Product, "product": req.Product,
"lot": req.Lot, "lot": req.Lot,
"factory": req.Factory, "factory": req.Factory,
@ -90,3 +93,11 @@ func DeleteFinalReportExcel(req *request.DeleteFinalReportExcel) error {
global.PostGreSQL.Delete(&finalReportExcel) global.PostGreSQL.Delete(&finalReportExcel)
return nil return nil
} }
//
//func A() {
// var finalReportExcel *model.FinalReportExcel
// global.PostGreSQL.Where("factory = ?", "").Find(&finalReportExcel)
// f, _ := excelize.OpenFile("")
//
//}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,172 @@
package test_data
import (
"github.com/spf13/viper"
"github.com/xuri/excelize/v2"
"gorm.io/gorm"
"path/filepath"
"strconv"
"strings"
"testData/global"
"testData/model"
"testData/utils"
"time"
)
func ExportWaferList() string {
f := excelize.NewFile()
sheetName := f.GetSheetName(0)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"状态", "下单日期", "订单号", "晶圆型号", "晶圆厂", "晶圆尺寸", "投片数量",
"在线数量", "回货数量", "回货日期", "回货批次"})
var waferLists []*model.WaferList
global.PostGreSQL.Preload("WaferStock", func(db *gorm.DB) *gorm.DB {
return db.Order("return_date")
}).Find(&waferLists)
for index, waferList := range waferLists {
var returnDate, returnLot string
if len(waferList.WaferStock) > 0 {
returnDate = waferList.WaferStock[0].ReturnDate
returnLot = waferList.WaferStock[0].Lot
}
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{waferList.Status, waferList.OrderDate, waferList.PBI,
waferList.Product, waferList.Factory, waferList.WaferSize, waferList.Quantity,
waferList.OnlineQuantity, waferList.ReturnQuantity, returnDate, returnLot})
}
_ = f.SetColWidth(sheetName, "B", "K", 20)
filePath := time.Now().Format("Wafer记录2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("记录"), filePath)
_ = f.SaveAs(filePath)
f.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}
func ExportABList() string {
f := excelize.NewFile()
sheetName := f.GetSheetName(0)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"状态", "下单日期", "订单号", "成品型号", "晶圆型号", "封装", "封装厂", "批号", "片号",
"订单数量", "在线数量", "良率", "出库数", "入库数", "回货日期", "封装良品", "封装不良品"})
var abLists []*model.ABList
global.PostGreSQL.Order("pbi").Preload("ABListStock", func(db *gorm.DB) *gorm.DB {
return db.Order("return_date")
}).Find(&abLists)
for index, abList := range abLists {
var returnDate string
if len(abList.ABListStock) > 0 {
returnDate = abList.ABListStock[0].ReturnDate
}
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{abList.Status, abList.OrderDate, abList.PBI,
abList.Product, abList.WaferProduct, abList.Package, abList.Factory, abList.Lot, abList.WaferID, abList.Quantity,
abList.OnlineQuantity, abList.PassProbability, abList.StockOutQuantity, abList.StockInQuantity,
returnDate, abList.PassQuantity, abList.FailQuantity})
}
_ = f.SetColWidth(sheetName, "B", "Q", 20)
filePath := time.Now().Format("AB记录2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("记录"), filePath)
_ = f.SaveAs(filePath)
f.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}
func ExportBPList() string {
f := excelize.NewFile()
sheetName := f.GetSheetName(0)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"状态", "下单日期", "订单号", "晶圆型号", "封装", "CP测试厂", "批号", "片号",
"订单数量", "在线数量", "回货日期", "到货数量", "DIE数量"})
var bpLists []*model.BPList
global.PostGreSQL.Order("pbi").Preload("BPListStock", func(db *gorm.DB) *gorm.DB {
return db.Order("return_date")
}).Find(&bpLists)
for index, bpList := range bpLists {
var returnDate string
if len(bpList.BPListStock) > 0 {
returnDate = bpList.BPListStock[0].ReturnDate
}
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{bpList.Status, bpList.OrderDate, bpList.PBI,
bpList.Product, bpList.Package, bpList.Factory, bpList.Lot, bpList.WaferID, bpList.Quantity,
bpList.OnlineQuantity, returnDate, bpList.ReturnQuantity, bpList.DieQuantity})
}
_ = f.SetColWidth(sheetName, "B", "M", 20)
filePath := time.Now().Format("BP记录2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("记录"), filePath)
_ = f.SaveAs(filePath)
f.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}
func ExportCPList() string {
f := excelize.NewFile()
sheetName := f.GetSheetName(0)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"状态", "下单日期", "订单号", "晶圆型号", "封装", "CP测试厂", "批号", "片号",
"订单数量", "在线数量", "测试程序", "回货日期", "到货数量", "DIE数量"})
var cpLists []*model.CPList
global.PostGreSQL.Order("pbi").Preload("CPListStock", func(db *gorm.DB) *gorm.DB {
return db.Order("return_date")
}).Find(&cpLists)
for index, cpList := range cpLists {
var returnDate string
if len(cpList.CPListStock) > 0 {
returnDate = cpList.CPListStock[0].ReturnDate
}
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{cpList.Status, cpList.OrderDate, cpList.PBI,
cpList.Product, cpList.Package, cpList.Factory, cpList.Lot, cpList.WaferID, cpList.Quantity,
cpList.OnlineQuantity, cpList.TestProgram, returnDate, cpList.ReturnQuantity, cpList.DieQuantity})
}
_ = f.SetColWidth(sheetName, "B", "M", 20)
filePath := time.Now().Format("CP记录2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("记录"), filePath)
_ = f.SaveAs(filePath)
f.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}
func ExportFTList() string {
f := excelize.NewFile()
sheetName := f.GetSheetName(0)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"状态", "下单日期", "订单号", "成品型号", "晶圆型号", "封装", "FT测试厂", "批号", "丝印",
"订单数量", "在线数量", "FT测试程序", "回货日期", "回货数量", "FT良品", "FT不良品"})
var ftLists []*model.FTList
global.PostGreSQL.Order("pbi").Preload("CPListStock", func(db *gorm.DB) *gorm.DB {
return db.Order("return_date")
}).Find(&ftLists)
for index, ftList := range ftLists {
var returnDate string
if len(ftList.FTListStock) > 0 {
returnDate = ftList.FTListStock[0].ReturnDate
}
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{ftList.Status, ftList.OrderDate, ftList.PBI,
ftList.Product, ftList.WaferProduct, ftList.Package, ftList.Factory, ftList.Lot, ftList.Seal, ftList.Quantity,
ftList.OnlineQuantity, ftList.TestProgram, returnDate, ftList.ReturnQuantity, ftList.PassQuantity, ftList.FailQuantity})
}
_ = f.SetColWidth(sheetName, "B", "P", 20)
filePath := time.Now().Format("CP记录2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("记录"), filePath)
_ = f.SaveAs(filePath)
f.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}
func ExportTRList() string {
f := excelize.NewFile()
sheetName := f.GetSheetName(0)
_ = f.SetSheetRow(sheetName, "A1", &[]interface{}{"状态", "下单日期", "订单号", "成品型号", "晶圆型号", "封装", "封装厂", "批号",
"订单数量", "在线数量", "回货日期", "封装良品", "封装不良品"})
var trLists []*model.TRList
global.PostGreSQL.Order("pbi").Preload("TRListStock", func(db *gorm.DB) *gorm.DB {
return db.Order("return_date")
}).Find(&trLists)
for index, abList := range trLists {
var returnDate string
if len(abList.TRListStock) > 0 {
returnDate = abList.TRListStock[0].ReturnDate
}
_ = f.SetSheetRow(sheetName, "A"+strconv.Itoa(index+2), &[]interface{}{abList.Status, abList.OrderDate, abList.PBI,
abList.Product, abList.WaferProduct, abList.Package, abList.Factory, abList.Lot, abList.Quantity,
abList.OnlineQuantity, returnDate, abList.PassQuantity, abList.FailQuantity})
}
_ = f.SetColWidth(sheetName, "B", "M", 20)
filePath := time.Now().Format("TR记录2006-01-02_150405.xlsx")
filePath = filepath.Join(utils.MakeSavePath("记录"), filePath)
_ = f.SaveAs(filePath)
f.Close()
return strings.ReplaceAll(viper.GetString("domain"), "\\", "/") + filePath
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
package test_data
import (
"testData/global"
"testData/model"
)
func GetERPProduct() []string {
var fileHandleds []*model.FileHandled
var product []string
global.Oracle.Where("").Find(&fileHandleds).Select("product").Group("product").Find(&product)
return product
}

View File

@ -9,7 +9,7 @@ import (
func UpdateWarning(req *model.Warning) error { func UpdateWarning(req *model.Warning) error {
var warning *model.Warning var warning *model.Warning
if errors.Is(global.PostGreSQL.Where("product = ? AND step = ?", req.Product, req.Step).Find(&warning).Error, gorm.ErrRecordNotFound) { if errors.Is(global.PostGreSQL.Where("product = ? AND step = ?", req.Product, req.Step).First(&warning).Error, gorm.ErrRecordNotFound) {
global.PostGreSQL.Create(&model.Warning{ global.PostGreSQL.Create(&model.Warning{
Product: req.Product, Product: req.Product,
Step: req.Step, Step: req.Step,
@ -26,38 +26,45 @@ func UpdateWarning(req *model.Warning) error {
"average_pass_probability": req.AveragePassProbability, "average_pass_probability": req.AveragePassProbability,
}) })
} }
for _, v := range req.ProductionControl { for k := range req.ProductionControl {
v.WarningID = warning.ID req.ProductionControl[k].ID = 0
req.ProductionControl[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.ProductionControl{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.ProductionControl{})
global.PostGreSQL.Create(&req.ProductionControl) global.PostGreSQL.Create(&req.ProductionControl)
for _, v := range req.PassProbabilityDiff { for k := range req.PassProbabilityDiff {
v.WarningID = warning.ID req.PassProbabilityDiff[k].ID = 0
req.PassProbabilityDiff[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.PassProbabilityDiff{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.PassProbabilityDiff{})
global.PostGreSQL.Create(&req.PassProbabilityDiff) global.PostGreSQL.Create(&req.PassProbabilityDiff)
for _, v := range req.BinControl { for k := range req.BinControl {
v.WarningID = warning.ID req.BinControl[k].ID = 0
req.BinControl[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.BinControl{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.BinControl{})
global.PostGreSQL.Create(&req.BinControl) global.PostGreSQL.Create(&req.BinControl)
for _, v := range req.SelectionDiffControl { for k := range req.SelectionDiffControl {
v.WarningID = warning.ID req.SelectionDiffControl[k].ID = 0
req.SelectionDiffControl[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.SelectionDiffControl{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.SelectionDiffControl{})
global.PostGreSQL.Create(&req.SelectionDiffControl) global.PostGreSQL.Create(&req.SelectionDiffControl)
for _, v := range req.StackingMaterialsWarning { for k := range req.StackingMaterialsWarning {
v.WarningID = warning.ID req.StackingMaterialsWarning[k].ID = 0
req.StackingMaterialsWarning[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.StackingMaterialsWarning{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.StackingMaterialsWarning{})
global.PostGreSQL.Create(&req.StackingMaterialsWarning) global.PostGreSQL.Create(&req.StackingMaterialsWarning)
for _, v := range req.HistogramSelection { for k := range req.HistogramSelection {
v.WarningID = warning.ID req.HistogramSelection[k].ID = 0
req.HistogramSelection[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.HistogramSelection{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.HistogramSelection{})
global.PostGreSQL.Create(&req.HistogramSelection) global.PostGreSQL.Create(&req.HistogramSelection)
for _, v := range req.ScatterSelection { for k := range req.ScatterSelection {
v.WarningID = warning.ID req.ScatterSelection[k].ID = 0
req.ScatterSelection[k].WarningID = warning.ID
} }
global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.ScatterSelection{}) global.PostGreSQL.Where("warning_id = ?", warning.ID).Delete(&model.ScatterSelection{})
global.PostGreSQL.Create(&req.ScatterSelection) global.PostGreSQL.Create(&req.ScatterSelection)
@ -82,7 +89,7 @@ func ShowListWarning(offset, limit int, keyWord string) ([]*model.Warning, int64
func DeleteWarning(req *model.Warning) error { func DeleteWarning(req *model.Warning) error {
var warning *model.Warning var warning *model.Warning
if errors.Is(global.PostGreSQL.Find(&warning, req.ID).Error, gorm.ErrRecordNotFound) { if errors.Is(global.PostGreSQL.First(&warning, req.ID).Error, gorm.ErrRecordNotFound) {
return errors.New("未找到需要删除的型号信息") return errors.New("未找到需要删除的型号信息")
} }
global.PostGreSQL.Delete(&warning) global.PostGreSQL.Delete(&warning)

View File

@ -101,6 +101,7 @@ type CPMap struct {
SBinColor []CPMapColor `json:"sbin_color"` SBinColor []CPMapColor `json:"sbin_color"`
HBinColor []CPMapColor `json:"hbin_color"` HBinColor []CPMapColor `json:"hbin_color"`
SelectionColor []SelectionColor `json:"selection_color"` SelectionColor []SelectionColor `json:"selection_color"`
WaferIDS []string `json:"wafer_ids"`
} }
type LogSiteChart struct { type LogSiteChart struct {

View File

@ -20,3 +20,14 @@ type PassProbabilityByProduct struct {
Factory string `json:"factory"` // 封装厂 Factory string `json:"factory"` // 封装厂
Type string `json:"type" validate:"required"` Type string `json:"type" validate:"required"`
} }
type TestPassProbabilityLine struct {
Product string `json:"product"` // 成品型号
Lot string `json:"lot"` // 晶圆批次
Factory string `json:"factory"` // 测试厂
TestProgram string `json:"test_program"` // 测试程序
TestMachine string `json:"test_machine"` // 测试机台
OrderDateStart string `json:"order_date_start"` // 下单日期开始时间
OrderDateEnd string `json:"order_date_end"` // 下单日期结束时间
DateSize string `json:"date_size"` // 时间大小
}

View File

@ -1,6 +1,7 @@
package request package request
type CreateFinalReportExcel struct { type CreateFinalReportExcel struct {
Step string `json:"step"` // 工序
Product string `json:"product"` // 成品型号 Product string `json:"product"` // 成品型号
Lot string `json:"lot"` // 晶圆批次 Lot string `json:"lot"` // 晶圆批次
Factory string `json:"factory"` // 测试厂 Factory string `json:"factory"` // 测试厂

View File

@ -1,6 +1,7 @@
package request package request
type WaferList struct { type WaferList struct {
Status string `json:"status"` // 状态
OrderDate string `json:"order_date"` // 下单日期 OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号 PBI string `json:"pbi"` // 订单号
Product string `json:"product"` // 晶圆型号 Product string `json:"product"` // 晶圆型号
@ -11,11 +12,15 @@ type WaferList struct {
ReturnDate string `json:"return_date"` // 回货日期 ReturnDate string `json:"return_date"` // 回货日期
Lot string `json:"lot"` // 批号 Lot string `json:"lot"` // 批号
ReturnQuantity string `json:"return_quantity"` // 回货数量 ReturnQuantity string `json:"return_quantity"` // 回货数量
Page int `json:"page"`
PageSize int `json:"pageSize"`
} }
type ABList struct { type ABList struct {
Status string `json:"status"` // 是否已完成
OrderDate string `json:"order_date"` // 下单日期 OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号 PBI string `json:"pbi"` // 订单号
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 成品型号 Product string `json:"product"` // 成品型号
WaferProduct string `json:"wafer_product"` // 晶圆型号 WaferProduct string `json:"wafer_product"` // 晶圆型号
Package string `json:"package"` // 封装 Package string `json:"package"` // 封装
@ -25,35 +30,90 @@ type ABList struct {
WaferID string `json:"wafer_id"` // 片号 WaferID string `json:"wafer_id"` // 片号
Quantity string `json:"quantity"` // 订单数量 Quantity string `json:"quantity"` // 订单数量
OnlineQuantity string `json:"online_quantity"` // 在线数量 OnlineQuantity string `json:"online_quantity"` // 在线数量
IsFinish string `json:"is_finish"` // 是否已完成
PassProbability string `json:"pass_probability"` // 良率 PassProbability string `json:"pass_probability"` // 良率
StockOutQuantity string `json:"stock_out_quantity"` // 出库数 StockOutQuantity string `json:"stock_out_quantity"` // 出库数
StockInQuantity string `json:"stock_in_quantity"` // 入库数 StockInQuantity string `json:"stock_in_quantity"` // 入库数
PassQuantity string `json:"pass_quantity"` // 封装良品
FailQuantity string `json:"fail_quantity"` // 封装不良品 FailQuantity string `json:"fail_quantity"` // 封装不良品
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
type BPList struct {
Status string `json:"status"` // 状态
OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 晶圆型号
Package string `json:"package"` // 封装
Factory string `json:"factory"` // CP测试厂
Lot string `json:"lot"` // 批号
WaferID string `json:"wafer_id"` // 片号
Quantity string `json:"quantity"` // 订单数量
OnlineQuantity string `json:"online_quantity"` // 在线数量
ReturnQuantity string `json:"return_quantity"` // 回货数量
DieQuantity string `json:"die_quantity"` // Die数量
Page int `json:"page"`
PageSize int `json:"pageSize"`
} }
type CPList struct { type CPList struct {
WaferProduct string `json:"wafer_product"` // 晶圆型号 Status string `json:"status"`
Lot string `json:"lot"` // 晶圆批号 OrderDate string `json:"order_date"` // 下单日期(订单日期)
Factory string `json:"factory"` // CP厂 PBI string `json:"pbi"` // PBI(订单号)
PBI string `json:"pbi"` Product string `json:"product"` // 晶圆型号
OrderDate string `json:"order_date"` // 下单日期 Package string `json:"package"` // 封装(规格)
TestMachine string `json:"test_machine"` // 测试机台 Factory string `json:"factory"` // CP测试厂
QueryType string `json:"query_type"` // 查询类型 Lot string `json:"lot"` // 批号
Page int `json:"page"` WaferID string `json:"wafer_id"` // 片号
PageSize int `json:"page_size"` TestProgram string `json:"test_program"` // 测试程序
TestProgramVersion string `json:"test_program_version"` // 测试程序版本
Quantity string `json:"quantity"` // 订单数量
OnlineQuantity string `json:"online_quantity"` // 未交数量
ReturnQuantity string `json:"return_quantity"` // 回货数量
DieQuantity string `json:"die_quantity"` // Die数量
TestMachine string `json:"test_machine"` // 测试机台
Page int `json:"page"`
PageSize int `json:"page_size"`
} }
type FTList struct { type FTList struct {
Product string `json:"product"` // 成品型号 Status string `json:"status"`
Lot string `json:"lot"` // 晶圆批号 OrderDate string `json:"order_date"` // 下单日期(订单日期)
//SubBatch string `json:"sub_batch"` // 子批次 PBI string `json:"pbi"` // PBI(订单号)
Factory string `json:"factory"` // 测试厂 OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
TestProgram string `json:"test_program"` // 测试程序 Product string `json:"product"` // 成品型号
PBI string `json:"pbi"` WaferProduct string `json:"wafer_product"` // 晶圆型号
OrderDate string `json:"order_date"` // 下单日期 Package string `json:"package"` // 封装(规格)
Seal string `json:"seal"` // 丝印 Factory string `json:"factory"` // FT测试厂
QueryType string `json:"query_type"` // 查询类型 Lot string `json:"lot"` // 批号
Page int `json:"page"` Seal string `json:"seal"` // 丝印
PageSize int `json:"page_size"` TestProgram string `json:"test_program"` // FT测试程序
TestProgramVersion string `json:"test_program_version"` // 测试程序版本
Quantity string `json:"quantity"` // 订单数量
OnlineQuantity string `json:"online_quantity"` // 未交数量
ReturnQuantity string `json:"return_quantity"` // 回货数量
FTPassQuantity string `json:"ft_pass_quantity"` // FT良品
FTFailQuantity string `json:"ft_fail_quantity"` // FT不良品
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type TRList struct {
Status string `json:"status"` // 是否已完成
OrderDate string `json:"order_date"` // 下单日期
PBI string `json:"pbi"` // 订单号
OutsourcingPBI string `json:"outsourcing_pbi"` // 委外工单号
Product string `json:"product"` // 成品型号
WaferProduct string `json:"wafer_product"` // 晶圆型号
Package string `json:"package"` // 封装
Factory string `json:"factory"` // 封装厂
Lot string `json:"lot"` // 批号
Seal string `json:"seal"` // 丝印
Quantity string `json:"quantity"` // 订单数量
OnlineQuantity string `json:"online_quantity"` // 在线数量
PassQuantity string `json:"pass_quantity"` // FT良品
FailQuantity string `json:"fail_quantity"` // FT不良品
Page int `json:"page"`
PageSize int `json:"pageSize"`
} }

View File

@ -15,6 +15,7 @@ func InitChartRouter(R *gin.RouterGroup) {
chartGroup.POST("pie", chartService.Pie) chartGroup.POST("pie", chartService.Pie)
chartGroup.POST("line", chartService.Line) chartGroup.POST("line", chartService.Line)
chartGroup.POST("cpMap", chartService.CPMap) chartGroup.POST("cpMap", chartService.CPMap)
chartGroup.POST("cpMap/all", chartService.AllCPMap)
chartGroup.POST("cpMap/export", chartService.CPMapExport) chartGroup.POST("cpMap/export", chartService.CPMapExport)
chartGroup.POST("ftHistogram/export", chartService.ExportHistogram) chartGroup.POST("ftHistogram/export", chartService.ExportHistogram)
chartGroup.POST("scatter/export", chartService.ExportScatter) chartGroup.POST("scatter/export", chartService.ExportScatter)

View File

@ -10,8 +10,16 @@ func InitReportListRouter(R *gin.RouterGroup) {
reportListGroup := R.Group("") reportListGroup := R.Group("")
{ {
reportListGroup.POST("report/wafer", reportListService.WaferList) reportListGroup.POST("report/wafer", reportListService.WaferList)
reportListGroup.POST("report/cp", reportListService.CPList) reportListGroup.POST("report/wafer/export", reportListService.ExportWaferList)
reportListGroup.POST("report/ab", reportListService.ABList) reportListGroup.POST("report/ab", reportListService.ABList)
reportListGroup.POST("report/ab/export", reportListService.ExportABList)
reportListGroup.POST("report/bp", reportListService.BPList)
reportListGroup.POST("report/bp/export", reportListService.ExportBPList)
reportListGroup.POST("report/cp", reportListService.CPList)
reportListGroup.POST("report/cp/export", reportListService.ExportCPList)
reportListGroup.POST("report/ft", reportListService.FTList) reportListGroup.POST("report/ft", reportListService.FTList)
reportListGroup.POST("report/ft/export", reportListService.ExportFTList)
reportListGroup.POST("report/tr", reportListService.TRList)
reportListGroup.POST("report/tr/export", reportListService.ExportTRList)
} }
} }