package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
	"strconv"
)

const (
	CompanyInfoKey        = "company_key"
	SupplierInfoKey       = "supplier_key"        //供应商key
	DealerInfoKey         = "dealer_key"          //经销商key
	DetectionInfoKey      = "detection_key"       //检测机构Key
	PeciesInfoKey         = "pecieso_key"         //物种信息key
	ResumeInfoKey         = "resume_key"          //履历key
	BaseInfoKey           = "base_key"            //基地key
	PlotInfoKey           = "plot_key"            //地块key
	EquipmentInfoKey      = "equipment_key"       //农场设备key
	EquipmentUseInfoKey   = "equipment_use_key"   //农场设备使用key
	PurchaseInfoKey       = "purchase_Key"        //化肥进货key
	ReceiveInfoKey        = "receive_key"         //化肥使用key
	PatternInfoKey        = "pattern_key"         //种植方式key
	ActivityInfoKey       = "activity_key"        //种植活动key
	QuarantineInfoKey     = "quarantine_key"      //种植检疫key
	PlantingHarvesInfoKey = "planting_harves_key" //种植采收key
	QualityTestInfoKey    = "quality_test_key"    //质量检测信息key
	PackingInfoKey        = "packing_key"         //包装信息key
	ReprospectShowInfoKey = "reprospect_show_key" //溯源展示信息key
	ReprospectInfoKey     = "reprospect_key"      //溯源key
	SaleInfoKey           = "sale_key"
	QrInfoKey             = "qr_key"
)

type Retrospect struct {
}

/*
  公司信息
*/
type CompanyInfo struct {
	Cid             string `json:"cid"`
	Cname           string `json:"cname"`           //公司名
	Contacts        string `json:"contacts"`        //联系人
	CompanyAddress  string `json:"cmpanyAddress"`   //企业地址
	CompanyDesc     string `json:"companyDesc"`     //企业简介
	CompanyType     string `json:"companyType"`     //企业类型
	BusinessLicense string `json:"businessLicense"` //营业执照
	ContactPhone    string `json:"contactPhone"`    //联系电话
	LegalPerson     string `json:"legalPerson"`     //企业法人
	Status          int    `json:"status"`          //状态
}

/*
 经销商
*/
type DealerInfo struct {
	Did             string  `json:"did"`
	Cid             string  `json:"cid"`             //公司Id
	DealerName      string  `json:"dealerName"`      //经销商名称
	Contacts        string  `json:"contacts"`        //联系人
	ContactPhone    string  `json:"contactPhone"`    //联系电话
	SalesCount      int     `json:"salesCount"`      //销售批次数量
	CommissionRatio float32 `json:"commissionRatio"` //经销商返佣比例
	Status          int     `json:"status"`          //状态

}

/*
	机构
*/
type DetectionInfo struct {
	Did           string `json:"did"`           //机构ID
	Cid           string `json:"cid"`           //公司Id
	DetectionName string `json:"detectionName"` //检测机构名称
	Contacts      string `json:"contacts"`      //联系人
	ContactPhone  string `json:"contactPhone"`  //联系电话
	Status        int    `json:"status"`        //状态
}

/*
	供应商
*/
type SupplierInfo struct {
	Sid             string `json:"sid"`             //供应商Id
	Cid             string `json:"cid"`             //公司Id
	SupplierName    string `json:"supplierName"`    //供应商名称
	SupplierAddress string `json:"supplierAddress"` //
	Principal       string `json:"principal"`       //负责人
	Phone           string `json:"phone"`           //
	Status          int    `json:"status"`          //状态
}

/*
	物种库
*/
type Pecies struct {
	Pid         string   `json:"pid"`
	Cid         string   `json:"cid"`         //公司Id
	SpeciesName string   `json:"speciesName"` //物种名称
	MainClass   string   `json:"mainClass"`   //品种大类
	SubClass    string   `json:"subClass"`    //品种小类
	GrowingEnv  string   `json:"growingEnv"`  //生长环境
	GrowthCycle int      `json:"growthCycle"` //生长周期
	Pics        []string `json:"pics"`        //图片
	SpeciesDesc string   `json:"speciesDesc"` //物种描述
	Status      int      `json:"status"`      //状态
}

/*
	履历信息
*/
type ResumeInfo struct {
	Rid        string `json:"rid"`
	Cid        string `json:"cid"`        //公司Id
	BaseId     string `json:"baseId"`     //基地Id
	Sid        string `json:"sid"`        //物种ID
	Bno        string `json:"bno"`        //批次号
	Pics       []string `json:"pics"`       //图片
	Tags       string `json:"tags"`       //标签
	ResumeTime string `json:"resumeTime"` //履历时间
}

/*
	基地信息
*/
type BaseInfo struct {
	BaseId      string `json:"baseId"`      //基地Id
	Cid         string `json:"cid"`         //公司Id
	BaseName    string `json:"baseName"`    //基地名称
	BaseAddress string `json:"baseAddress"` //基地地址
	Area        int32  `json:"area"`        //面积
	Principal   string `json:"principal"`   //负责人
	Phone       string `json:"phone"`       //联系电话
	BasePics    []string `json:"basePics"`    //基地图片
	Status      int    `json:"status"`      //状态

}

/*
	地块信息
*/
type PlotInfo struct {
	Pid         string `json:"pid"`
	Cid         string `json:"cid"`         //公司Id
	BaseId      string `json:"baseId"`      //基地Id
	PlotName    string `json:"plotName"`    //地块名称
	PlotAddress string `json:"plotAddress"` //地块地址
	Area        int32  `json:"area"`        //面积
	Principal   string `json:"principal"`   //负责人
	Phone       string `json:"phone"`       //联系电话
	PlotPics    []string `json:"plotPics"`    //地块图片
	Status      int    `json:"status"`      //状态
}

/*
	设备信息
*/
type EquipmentInfo struct {
	Eid          string `json:"eid"`
	Cid          string `json:"cid"`          //公司Id
	BaseId       string `json:"baseId"`       //基地Id
	EquipName    string `json:"equipName"`    //设备名称
	EquipModel   string `json:"equipModel"`   //设备型号
	Producer     string `json:"producer"`     //设备生产商
	ProducedDate string `json:"producedDate"` // 生产日期
	UsedDate     string `json:"usedDate"`     //最近使用日期
	Status       int    `json:"status"`       //状态
}

/*
	设备使用信息
*/
type EquipUsedRecord struct {
	EuId     string  `json:"eu_id"`    //使用Id
	Eid      string  `json:"eid"`      //设备ID
	Uid      string  `json:"uid"`      //使用人ID
	UserName string  `json:"userName"` //使用人
	Duration float32 `json:"duration"` //使用时长
	UsedDate string  `json:"usedDate"` //最近使用日期
}

/*
	化肥或者农药进货信息
*/
type PurchaseInfo struct {
	Pid               string `json:"pid"`
	Cid               string `json:"cid"`               //公司Id
	BaseId            string `json:"baseId"`            //基地Id
	PurchaseName      string `json:"purchaseName"`      //进货名称
	PurchaseNo        string `json:"purchaseNo"`        //进货批次号
	PurchaseType      int    `json:"purchaseType"`      //进货类型 1化肥 2农药
	Producer          string `json:"producer"`          //生产商
	PurchaseCount     int64  `json:"purchaseCount"`     //进货数量
	PurchaseDate      string `json:"purchaseDate"`      //采购日期
	PurchasingAgentId string `json:"purchasingAgentId"` //采购人ID
	PurchasingAgent   string `json:"purchasingAgent"`   //采购人
	PackingSize       string `json:"packingSize"`       //包装规格
	BusinessUnit      string `json:"businessUnit"`      //经营单位
	PurchaseAddress   string `json:"purchaseAddress"`   //购买地点
	PurchaseBill      []string `json:"purchaseBill"`      //进货票据
	SupplierId        string `json:"supplierId"`        //供应商ID
}

/*
	化肥或者农药领用信息
*/
type Receive struct {
	Rid          string `json:"rid"`
	Cid          string `json:"cid"`          //公司Id
	BaseId       string `json:"baseId"`       //基地Id
	AreaId       string `json:"areaId"`       //地块ID
	SupplierId   string `json:"supplierId"`   //供应商ID
	ReceiveName  string `json:"receiveName"`  //领用名称
	ReceiveType  string `json:"receiveType"`  //领用类型  1化肥 2农药
	Producer     string `json:"producer"`     //生产商
	ReceiveCount int64  `json:"receiveCount"` //领用数量
	ReceiveDate  string `json:"receiveDate"`  //领用日期
	ReceiverId   string `json:"receiverId"`   //领用人ID
	Receiver     string `json:"receiver"`     //领用人

}

/*
	种植方式
*/
type Pattern struct {
	Id          string `json:"id"`
	PatternName string `json:"patternName"` //方式名称
	BizType     string `json:"bizType"`     //业务类型,种植方式
	Remark      string `json:"remark"`      //备注
	Status      int    `json:"status"`      //状态
}

/*
	种植活动
*/
type ActivityInfo struct {
	Id      string `json:"id"`
	Cid     string `json:"cid"`     //公司Id
	BaseId  string `json:"baseId"`  //基地Id
	PlotId  string `json:"plotId"`  //地块ID
	Sid     string `json:"sid"`     //物种ID
	Bno     string `json:"bno"`     //批次号
	BizType string `json:"bizType"` //业务类型
}

/*
	种植检疫
*/
type QuarantineInfo struct {
	Id          string `json:"id"`
	Cid         string `json:"cid"`         //公司Id
	BaseId      string `json:"baseId"`      //基地Id
	PlotId      string `json:"plotId"`      //地块ID
	Sid         string `json:"sid"`         //物种ID
	Bno         string `json:"bno"`         //批次号
	QuaName     string `json:"quaName"`     //检疫名称
	BizType     string `json:"bizType"`     //业务类型
	Qno         string `json:"qno"`         //编号
	QuaDate     string `json:"quaDate"`     //检疫日期
	QuaReport   []string `json:"quaReport"`   //检测报告
	PrincipalId string `json:"principalId"` //负责人ID
	Principal   string `json:"principal"`   //负责人
}

/*
	种植采收
*/
type Harvesinfo struct {
	Id          string `json:"id"`
	Cid         string `json:"cid"`         //公司Id
	BaseId      string `json:"baseId"`      //基地Id
	PlotId      string `json:"plotId"`      //地块ID
	Sid         string `json:"sid"`         //物种ID
	Bno         string `json:"bno"`         //批次号
	HarvestName string `json:"harvestName"` //收获名称
	BizType     string `json:"bizType"`     //业务类型
	Hno         string `json:"hno"`         //编号
	StartDate   string `json:"startDate"`   //开始日期
	EndDate     string `json:"endDate"`     //结束日期
	PrincipalId string `json:"principalId"` //负责人ID
	Principal   string `json:"principal"`   //负责人
}

/*
	质量检测
*/
type QualityTesting struct {
	QtId        string `json:"qtId"`        //
	QtOrgName   string `json:"qtOrgName"`   //检测机构名称
	QtMethod    string `json:"qtMethod"`    //检测方式
	QtDate      string `json:"qtDate"`      //检测时间
	QtResult    string `json:"qtResult"`    //检测结果
	QtUser      string `json:"qtUser"`      //检测人
	QtReport    string `json:"qtReport"`    //质量检测报告
	WaterReport []string `json:"waterReport"` //水检测报告
	LandReport  []string `json:"landReport"`  //土地检测报告
	AirReport   []string `json:"airReport"`   //空气检测报告
}

/*
	包装信息
*/
type PackagingInfo struct {
	Packid      string `json:"packid"`
	Cid         string `json:"cid"`         //公司Id
	BaseId      string `json:"baseId"`      //基地Id
	PlotId      string `json:"plotId"`      //地块ID
	Sid         string `json:"sid"`         //物种ID
	Bno         string `json:"bno"`         //批次号
	PackInfo    string `json:"packInfo"`    //包装信息
	BizType     string `json:"bizType"`     //业务类型
	Pno         string `json:"pno"`         //编号
	PackCount   int64  `json:"packCount"`   //包装数量
	PackUnit    string `json:"packUnit"`    //包装单位
	PackDate    string `json:"packDate"`    //包装日期F
	PackPics    []string `json:"packPics"`    //包装图片
	PrincipalId string `json:"principalId"` //负责人ID
	Principal   string `json:"principal"`   //负责人
}

/*
	销售信息
*/
type SalesInfo struct {
	Id              string  `json:"id"`
	Cid             string  `json:"cid"`             //公司Id
	BaseId          string  `json:"baseId"`          //基地Id
	PlotId          string  `json:"plotId"`          //地块ID
	Sid             string  `json:"sid"`             //物种ID
	Bno             string  `json:"bno"`             //批次号
	SaleInfo        string  `json:"saleInfo"`        //销售信息
	BizType         string  `json:"bizType"`         //业务类型
	Sno             string  `json:"sno"`             //编号
	Customer        string  `json:"customer"`        //客户名称
	SaleCount       int64   `json:"saleCount"`       //销售数量
	PackingSize     string  `json:"packingSize"`     //包装规格
	SaleDate        string  `json:"saleDate"`        //销售日期
	SalePics        string  `json:"salePics"`        //销售图片
	TrackingNo      string  `json:"trackingNo"`      //运输单号
	LogisticsName   string  `json:"logisticsName"`   //物流信息
	Did             int32   `json:"did"`             //经销商ID
	PrincipalId     string  `json:"principalId"`     //负责人ID
	Principal       string  `json:"principal"`       //负责人
	CommissionRatio float32 `json:"commissionRatio"` //返佣比例
}

/*
	二维码展示信息,打印二维码的时候可能还没有销售信息
*/
type QrCode struct {
	PNo             string          `json:"p_no"`         //批次号
	StartNumber     int64           `json:"start_number"` //
	Count           int32           `json:"count"`        //打印数量  是否存在多次进行二维码展示信息
	ProductShow     ProductShow     `json:"product_show"`
	RetrospectShow  RetrospectShow  `json:"retrospect_show"`
	QualityTestShow QualityTestShow `json:"quality_test_show"`
	CompanyShow     CompanyShow     `json:"company_show"`
}

/*
	产品展示信息
*/
type ProductShow struct {
	ProductName    bool     `json:"product_name"`    //产品名称，可以从物种名称
	PickDate       bool     `json:"pick_date"`       //采收结束日期，从种植采收获得
	ExpirationDate int      `json:"expiration_date"` //产品保质期
	ProductType    bool     `json:"product_type"`    //产品的包装规格。从包装信息处获得
	ProductNo      bool     `json:"product_no"`      //生产批次号
	StoageMode     string   `json:"stoage_mode"`     //存储方式
	ProductDes     bool     `json:"product_des"`     //产品描述，同样是从物种ID查询获得
	ProductFiles   []string `json:"product_files"`   //产品图片，新增的与默认选择的都一同上传
}

/*
	产品展示信息
*/
type SearchProductShow struct {
	ProductName    string   `json:"product_name"`    //产品名称，可以从物种名称
	PickDate       string   `json:"pick_date"`       //采收结束日期，从种植采收获得
	ExpirationDate int      `json:"expiration_date"` //产品保质期
	ProductType    string   `json:"product_type"`    //产品的包装规格。从包装信息处获得
	ProductNo      string   `json:"product_no"`      //生产批次号
	StoageMode     string   `json:"stoage_mode"`     //存储方式
	ProductDes     string   `json:"product_des"`     //产品描述，同样是从物种ID查询获得
	ProductFiles   []string `json:"product_files"`   //产品图片，新增的与默认选择的都一同上传
}

/*
	溯源展示信息
1：展示全部的种植活动，根据批次号进行富查询
2：销售Id,销售ID可能未必是存在
3：包装信息Id
4:质检信息Id
5:物种Id
*/
type RetrospectShow struct {
	BaseName      string   `json:"base_name"`      //基地Id
	PlotName      string   `json:"polt_name"`      //所属地块Id
	SpeciesName   string   `json:"species_name"`   //物种Id
	PlantActivity string   `json:"plant_activity"` //种植活动
	PlantTest     string   `json:"plant_test"`     //种植检疫
	PlantPick     string   `json:"plant_pick"`     //种植采收
	QualityTest   string   `json:"quality_test"`   //质量检测Id
	Packaging     string   `json:"packaging"`      //包装信息Id
	SaleInfo      string   `json:"sale_info"`      //销售信息Id or "true" "false"
	LogisticsInfo bool     `json:"logistics_info"` //物流信息，cc 端不用管
	BaseFiles     []string `json:"base_files"`     //新增的与默认选择的都一同上传
}

/*
	溯源展示信息
*/
type SearchRetrospectShow struct {
	BaseName      string         `json:"base_name"`      //基地Id
	PlotName      string         `json:"polt_name"`      //所属地块Id
	SpeciesName   string         `json:"species_name"`   //物种Id
	PlantActivity []*ActivityInfo `json:"plant_activity"` //种植活动
	PlantTest     *QuarantineInfo `json:"plant_test"`     //种植检疫
	PlantPick     *Harvesinfo     `json:"plant_pick"`     //种植采收
	QualityTest   *QualityTesting `json:"quality_test"`   //质量检测Id
	Packaging     *PackagingInfo  `json:"packaging"`      //包装信息Id
	SaleInfo      *SalesInfo      `json:"sale_info"`      //销售信息Id or "true" "false"
	LogisticsInfo bool           `json:"logistics_info"` //物流信息，if true 表示需要进行进行展示
	BaseFiles     []string       `json:"base_files"`     //新增的与默认选择的都一同上传
}

/*
	质检展示信息
*/
type QualityTestShow struct {
	QtId                string `json:"qtId"`                  //质检信息ID 当前这一批次对应的质检信息ID
	Detection           bool   `json:"detection"`             //检测机构
	DetectionMode       bool   `json:"detection_mode"`        //检测方式
	DetectionTiem       bool   `json:"detection_tiem"`        //检测时间
	DetectionResult     bool   `json:"detection_result"`      //检测结果
	DetectionPeople     bool   `json:"detection_people"`      //检测人
	DetectionPaper      bool   `json:"detection_paper"`       //质量检测报告
	WaterDetectionPaper bool   `json:"write_detection_paper"` //水检测报告
	LandDetectionPaper  bool   `json:"detection_paper"`       //土地检测报告
	AirDetectionPaper   bool   `json:"air_detection_paper"`   //空气检测报告
}

/*
	企业展示信息
*/
type CompanyShow struct {
	Cid             string `json:"cid"` //企业Id 当前这一批次对应的企业信息ID
	CompanyName     bool   `json:"company_name"`
	Principal       bool   `json:"principal"`        //负责人
	PrincipalPhone  bool   `json:"principal"`        //负责人联系电话
	CompanyPerson   bool   `json:"company_person"`   //公司法人
	CompanyAddress  bool   `json:"company_address"`  //公司地址
	CompanyIntro    bool   `json:"company_intro"`    //公司简介
	BusinessLicense bool   `json:"business_license"` //营业执照
}

/*
	从链上查询的二维码溯源信息
*/
type SearchQrCode struct {
	PNo             string               `json:"p_no"`  //批次号
	Count           int32                `json:"count"` //打印数量  是否存在多次进行二维码展示信息
	ProductShow     *SearchProductShow    `json:"product_show"`
	RetrospectShow  *SearchRetrospectShow `json:"retrospect_show"`
	QualityTestShow *QualityTesting       `json:"quality_test_show"`
	CompanyShow     *CompanyInfo          `json:"company_show"`
}

/*
	二维码溯源key
*/
type QrKey struct {
	Pno         string  `json:"pno"`          //批次号
	StartNumber []int64 `json:"start_number"` //
	StartNum    int64   `json:"start_num"`    //当前批次号的二维码开始number
	EndNum      int64   `json:"end_num"`      //当前批次号的二维码结束number
}

func (ret *Retrospect) Init(stub shim.ChaincodeStubInterface) pb.Response {
	return shim.Success([]byte("retrospect chain init success"))
}

// Invoke is called to update or query the ledger in a proposal transaction.
// Updated state variables are not committed to the ledger until the
// transaction is committed.
func (ret *Retrospect) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	functionName, args := stub.GetFunctionAndParameters()
	switch functionName {
	case "addCompanyInfo": //增加公司信息
		return AddCompanyInfo( args, stub)
	case "updateCompanyInfo": //修改公司信息
		return AddCompanyInfo( args, stub)
	case "addSupplierInfo": //添加供应商信息
		return AddSupplierInfo( args, stub)
	case "addDealerInfo": //添加经销商信息
		return AddDealerInfo( args, stub)
	case "addDetectionInfo": //增加检测机构信息
		return AddDetectionInfo( args, stub)
	case "addPeciesInfo": //增加物种信息
		return AddPeciesInfo( args, stub)
	case "addResumeInfo":  //增加履历信息
		return AddResumeInfo(args, stub)
	case "addBaseInfo": //增加基地信息
		return AddBaseInfo(args,stub)
	case "addPlotInfo": //增加地块信息
		return AddPlotInfo( args, stub)
	case "addEquipmentInfo": //增加农场设备信息
		return AddEquipmentInfo( args, stub)
	case "addEquipUsedRecord": //添加农场设备使用信息
		return AddEquipUsedRecord( args, stub)
	case "addPurchaseInfo": //添加农药或化肥进货信息
		return AddPurchaseInfo( args, stub)
	case "addReceiveInfo": //农药或者化肥使用信息
		return AddReceiveInfo( args, stub)
	case "addPatternInfo": //增加种植方式信息
		return AddPatternInfo( args, stub)
	case "addActivityInfo":  //增加种植活动信息
		return AddActivityInfo(args, stub)
	case "addPlantingQuarantineInfo": //增加种植检疫信息
		return AddPlantingQuarantineInfo(args,stub)
	case "addPlantingHarvesinfo": //增加种植采收信息
		return AddPlantingHarvesinfo( args, stub)
	case "addQualityTestInfo": //添加质量检测信息
		return AddQualityTestInfo( args, stub)
	case "addPackingInfo": //添加包装信息
		return AddPackingInfo( args, stub)
	case "addReprospectShowInfo": //添加溯源展示信息
		return AddReprospectShowInfo( args, stub)
	case "addsaleInfo": //增加销售信息
		return AddsaleInfo( args, stub)
	case "searchRespectInfo": //查询溯源信息
		return SearchRespectInfo( args, stub)
	case "testCheck": //测试接口
		return TestCheck(args, stub)
	default:
		return shim.Error(fmt.Sprintf("%s Unsupported function name ", functionName))
	}
	return pb.Response{}
}

func TestCheck(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) == 0 {
		return shim.Success([]byte("参数内容为空"))
	}
	return shim.Success([]byte(args[0]))
}

/*
	增加/编辑 公司信息
*/
func AddCompanyInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add company info expected 1 parameters! ")
	}
	comInfo := &CompanyInfo{}
	err := json.Unmarshal([]byte(args[0]), comInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal CompanyInfo fail,err %s ,info is %s", err,args[0]))
	}
	if comInfo.Cid == " " || len(comInfo.Cid) == 0 {
		return shim.Error("company info cid can not is null")
	}
	companyKey := CompanyInfoKey + "_" + comInfo.Cid
	err = putStateStruct(companyKey, comInfo, stub)
	if err != nil {
		return shim.Error("put company info err: " + err.Error())
	}
	return shim.Success([]byte("put " + comInfo.Cname + " company info successful!"))
}

/*
	添加/编辑 供应商信息
*/
func AddSupplierInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add Supplier info expected 1 parameters! ")
	}
	suppInfo := &SupplierInfo{}
	err := json.Unmarshal([]byte(args[0]), suppInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal SupplierInfo fail,err %s ", err))
	}
	if suppInfo.Sid == " " || len(suppInfo.Sid) == 0 {
		return shim.Error("supplier info sid can not is null")
	}
	companyKey := SupplierInfoKey + "_" + suppInfo.Cid
	err = putStateStruct(companyKey, suppInfo, stub)
	if err != nil {
		return shim.Error("put supplier info err: " + err.Error())
	}
	return shim.Success([]byte("put " + suppInfo.SupplierName + " supplier info successful!"))
}

/*
	添加/编辑 经销商信息
*/
func AddDealerInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add dealer info expected 1 parameters! ")
	}
	dealerInfo := &DealerInfo{}
	err := json.Unmarshal([]byte(args[0]), dealerInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal DealerInfo fail,err %s ", err))
	}
	if dealerInfo.Did == " " || len(dealerInfo.Did) == 0 {
		return shim.Error("dealer info did can not is null")
	}
	companyKey := DealerInfoKey + "_" + dealerInfo.Did
	err = putStateStruct(companyKey, dealerInfo, stub)
	if err != nil {
		return shim.Error("put dealer info err: " + err.Error())
	}
	return shim.Success([]byte("put " + dealerInfo.DealerName + " dealer info successful!"))
}

/*
	添加/编辑 检测机构信息
*/
func AddDetectionInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add detection info expected 1 parameters! ")
	}
	detectionInfo := &DetectionInfo{}
	err := json.Unmarshal([]byte(args[0]), detectionInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal DetectionInfo fail,err %s ", err))
	}
	if detectionInfo.Did == " " || len(detectionInfo.Did) == 0 {
		return shim.Error("detection info did can not is null")
	}
	companyKey := DetectionInfoKey + "_" + detectionInfo.Did
	err = putStateStruct(companyKey, detectionInfo, stub)
	if err != nil {
		return shim.Error("put detection info err: " + err.Error())
	}
	return shim.Success([]byte("put " + detectionInfo.DetectionName + " detection info successful!"))
}

/*
	添加/编辑 物种信息
*/
func AddPeciesInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add pecies info expected 1 parameters! ")
	}
	pecies := &Pecies{}
	err := json.Unmarshal([]byte(args[0]), pecies)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal Pecies fail,err %s ", err))
	}
	if pecies.Pid == " " || len(pecies.Pid) == 0 {
		return shim.Error("pecies info pid can not is null")
	}
	companyKey := PeciesInfoKey + "_" + pecies.Pid
	err = putStateStruct(companyKey, pecies, stub)
	if err != nil {
		return shim.Error("put pecies info err: " + err.Error())
	}
	return shim.Success([]byte("put " + pecies.SpeciesName + " pecies info successful!"))
}

/*
	添加/编辑 履历信息
*/
func AddResumeInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add resume info expected 1 parameters! ")
	}
	resumeInfo := &ResumeInfo{}
	err := json.Unmarshal([]byte(args[0]), resumeInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal resumeInfo fail,err %s ", err))
	}
	if resumeInfo.Rid == " " || len(resumeInfo.Rid) == 0 {
		return shim.Error("resume info rid can not is null")
	}
	companyKey := ResumeInfoKey + "_" + resumeInfo.Rid
	err = putStateStruct(companyKey, resumeInfo, stub)
	if err != nil {
		return shim.Error("put resume info err: " + err.Error())
	}
	return shim.Success([]byte("put " + resumeInfo.Bno + " resume info successful!"))
}

/*
	添加/编辑 基地信息
*/
func AddBaseInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add base info expected 1 parameters! ")
	}
	baseInfo := &BaseInfo{}
	err := json.Unmarshal([]byte(args[0]), baseInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal BaseInfo fail,err %s ", err))
	}
	if baseInfo.BaseId == " " || len(baseInfo.BaseId) == 0 {
		return shim.Error("base info baseId can not is null")
	}
	companyKey := BaseInfoKey + "_" + baseInfo.BaseId
	err = putStateStruct(companyKey, baseInfo, stub)
	if err != nil {
		return shim.Error("put base info err: " + err.Error())
	}
	return shim.Success([]byte("put " + baseInfo.BaseName + " base info successful!"))
}

/*
	添加/编辑 地块信息
*/
func AddPlotInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add plot info expected 1 parameters! ")
	}
	plotInfo := &PlotInfo{}
	err := json.Unmarshal([]byte(args[0]), plotInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal PlotInfo fail,err %s ", err))
	}
	if plotInfo.Pid == " " || len(plotInfo.Pid) == 0 {
		return shim.Error("plot info pid can not is null")
	}
	companyKey := PlotInfoKey + "_" + plotInfo.Pid
	err = putStateStruct(companyKey, plotInfo, stub)
	if err != nil {
		return shim.Error("put plot info err: " + err.Error())
	}
	return shim.Success([]byte("put " + plotInfo.PlotName + " plot info successful!"))
}

/*
	添加/编辑 农场设备信息
*/
func AddEquipmentInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add equipment info expected 1 parameters! ")
	}
	equipmentInfo := &EquipmentInfo{}
	err := json.Unmarshal([]byte(args[0]), equipmentInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal EquipmentInfo fail,err %s ", err))
	}
	if equipmentInfo.Eid == " " || len(equipmentInfo.Eid) == 0 {
		return shim.Error("equipment info eid can not is null")
	}
	companyKey := EquipmentInfoKey + "_" + equipmentInfo.Eid
	err = putStateStruct(companyKey, equipmentInfo, stub)
	if err != nil {
		return shim.Error("put equipment info err: " + err.Error())
	}
	return shim.Success([]byte("put " + equipmentInfo.EquipName + " equipment info successful!"))
}

/*
	添加/编辑 设备使用信息
*/
func AddEquipUsedRecord(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add equipmentuse info expected 1 parameters! ")
	}
	equipUsedRecord := &EquipUsedRecord{}
	err := json.Unmarshal([]byte(args[0]), equipUsedRecord)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal EquipUsedRecord fail,err %s ", err))
	}
	if equipUsedRecord.EuId == " " || len(equipUsedRecord.EuId) == 0 {
		return shim.Error("equipmentuse info euid can not is null")
	}
	companyKey := EquipmentUseInfoKey + "_" + equipUsedRecord.EuId
	err = putStateStruct(companyKey, equipUsedRecord, stub)
	if err != nil {
		return shim.Error("put equipmentuse info err: " + err.Error())
	}
	return shim.Success([]byte("put " + equipUsedRecord.UserName + " equipmentuse info successful!"))
}

/*
	添加/编辑 化肥或者农药进货信息
*/
func AddPurchaseInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add purchase info expected 1 parameters! ")
	}
	purchaseInfo := &PurchaseInfo{}
	err := json.Unmarshal([]byte(args[0]), purchaseInfo)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal PurchaseInfo fail,err %s ", err))
	}
	if purchaseInfo.Pid == " " || len(purchaseInfo.Pid) == 0 {
		return shim.Error("purchase info pid can not is null")
	}
	companyKey := PurchaseInfoKey + "_" + purchaseInfo.Pid
	err = putStateStruct(companyKey, purchaseInfo, stub)
	if err != nil {
		return shim.Error("put purchase info err: " + err.Error())
	}
	return shim.Success([]byte("put " + purchaseInfo.PurchaseName + " purchase info successful!"))
}

/*
	添加/编辑 化肥或者农药使用信息
*/
func AddReceiveInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add receive info expected 1 parameters! ")
	}
	receive := &Receive{}
	err := json.Unmarshal([]byte(args[0]), receive)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal PurchaseInfo fail,err %s ", err))
	}
	if receive.Rid == " " || len(receive.Rid) == 0 {
		return shim.Error("receive info rid can not is null")
	}
	companyKey := ReceiveInfoKey + "_" + receive.Rid
	err = putStateStruct(companyKey, receive, stub)
	if err != nil {
		return shim.Error("put receive info err: " + err.Error())
	}
	return shim.Success([]byte("put " + receive.ReceiveName + " receive info successful!"))
}

/*
	添加/编辑 种植方式信息
*/
func AddPatternInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add pattern info expected 1 parameters! ")
	}
	pattern := &Pattern{}
	err := json.Unmarshal([]byte(args[0]), pattern)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal Pattern fail,err %s ", err))
	}
	if pattern.Id == " " || len(pattern.Id) == 0 {
		return shim.Error("pattern info id can not is null")
	}
	companyKey := PatternInfoKey + "_" + pattern.Id
	err = putStateStruct(companyKey, pattern, stub)
	if err != nil {
		return shim.Error("put pattern info err: " + err.Error())
	}
	return shim.Success([]byte("put " + pattern.PatternName + " pattern info successful!"))
}

/*
	添加/编辑 种植活动信息
*/
func AddActivityInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add activity info expected 1 parameters! ")
	}
	activity := &ActivityInfo{}
	err := json.Unmarshal([]byte(args[0]), activity)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal ActivityInfo fail,err %s ", err))
	}
	if activity.Id == " " || len(activity.Id) == 0 {
		return shim.Error("activity info rid can not is null")
	}
	if activity.Bno == " " || len(activity.Bno) == 0 {
		return shim.Error("activity info bno can not is null")
	}
	activityKey, err := stub.CreateCompositeKey(ActivityInfoKey, []string{activity.Bno, activity.Id})
	if err != nil {
		return shim.Error("create activity composite key err: " + err.Error())
	}
	err = putStateStruct(activityKey, activity, stub)
	if err != nil {
		return shim.Error("put activity info err: " + err.Error())
	}
	return shim.Success([]byte("put " + activity.BizType + " activity info successful!"))
}

/*
	添加/编辑 种植检疫信息
*/
func AddPlantingQuarantineInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add quarantine info expected 1 parameters! ")
	}
	quarantine := &QuarantineInfo{}
	err := json.Unmarshal([]byte(args[0]), quarantine)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal QuarantineInfo fail,err %s ", err))
	}
	if quarantine.Id == " " || len(quarantine.Id) == 0 {
		return shim.Error("quarantine info id can not is null")
	}
	companyKey := QuarantineInfoKey + "_" + quarantine.Id
	err = putStateStruct(companyKey, quarantine, stub)
	if err != nil {
		return shim.Error("put activity info err: " + err.Error())
	}
	return shim.Success([]byte("put " + quarantine.QuaName + " quarantine info successful!"))
}

/*
	添加/编辑 种植采收信息
*/
func AddPlantingHarvesinfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add harves info expected 1 parameters! ")
	}
	harves := &Harvesinfo{}
	err := json.Unmarshal([]byte(args[0]), harves)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal Harvesinfo fail,err %s ", err))
	}
	if harves.Id == " " || len(harves.Id) == 0 {
		return shim.Error("harves info id can not is null")
	}
	companyKey := PlantingHarvesInfoKey + "_" + harves.Id
	err = putStateStruct(companyKey, harves, stub)
	if err != nil {
		return shim.Error("put harves info err: " + err.Error())
	}
	return shim.Success([]byte("put " + harves.HarvestName + " harves info successful!"))
}

/*
	添加/编辑 质量检测信息
*/
func AddQualityTestInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add quality test info expected 1 parameters! ")
	}
	quality := &QualityTesting{}
	err := json.Unmarshal([]byte(args[0]), quality)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal QualityTesting fail,err %s ", err))
	}
	if quality.QtId == " " || len(quality.QtId) == 0 {
		return shim.Error("quality test info qtid can not is null")
	}
	companyKey := QualityTestInfoKey + "_" + quality.QtId
	err = putStateStruct(companyKey, quality, stub)
	if err != nil {
		return shim.Error("put quality test info err: " + err.Error())
	}
	return shim.Success([]byte("put " + quality.QtOrgName + " quality test info successful!"))
}

/*
	添加/编辑 包装信息
*/
func AddPackingInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add packaging info expected 1 parameters! ")
	}
	packaging := &PackagingInfo{}
	err := json.Unmarshal([]byte(args[0]), packaging)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal PackagingInfo fail,err %s ", err))
	}
	if packaging.Packid == " " || len(packaging.Packid) == 0 {
		return shim.Error("packaging info packid can not is null")
	}
	companyKey := PackingInfoKey + "_" + packaging.Packid
	err = putStateStruct(companyKey, packaging, stub)
	if err != nil {
		return shim.Error("put packaging info err: " + err.Error())
	}
	return shim.Success([]byte("put " + packaging.Packid + " packaging info successful!"))
}

/*
	添加溯源展示信息
*/
func AddReprospectShowInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add qrcode info expected 1 parameters! ")
	}
	qrcode := &QrCode{}
	err := json.Unmarshal([]byte(args[0]), qrcode)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal QrCode fail,err %s ", err))
	}
	startNum := qrcode.StartNumber+1
	startStr := strconv.FormatInt(startNum, 10)
	if qrcode.PNo == " " || len(qrcode.PNo) == 0 {
		return shim.Error("activity info bno can not is null")
	}
	qrcodeyKey, err := stub.CreateCompositeKey(ReprospectInfoKey, []string{qrcode.PNo, startStr})
	if err != nil {
		return shim.Error("create respect composite key err: " + err.Error())
	}
	resultByte, err := getStateByte(qrcodeyKey, stub)
	if resultByte != nil {
		return shim.Error(startStr + " qrcode info already exit")
	} else if err != nil && err.Error() != "The query information is empty " {
		return shim.Error("get qrcode info happen err: " + err.Error())
	}
	err = putStateStruct(qrcodeyKey, qrcode, stub)
	if err != nil {
		return shim.Error("put packaging info err: " + err.Error())
	}
	qr := &QrKey{}
	qrKey := QrInfoKey + "_" + qrcode.PNo
	qrKeyByte,err := getStateByte(qrKey,stub)
	if err != nil{
		if err.Error() == "The query information is empty "{
			qr.StartNumber = []int64{startNum}
			qr.StartNum = startNum
			qr.EndNum =  startNum + int64(qrcode.Count)
			qr.Pno = qrcode.PNo
		}else{
			return shim.Error("get qrkey info happen err: " + err.Error())
		}
	}else{
		err = json.Unmarshal(qrKeyByte,qr)
		if err != nil {
			return shim.Error(fmt.Sprintf("Unmarshal QrKey fail,err %s ", err))
		}
		 qrOld := qr.StartNumber[len(qr.StartNumber)-1:]
		if startNum <= qrOld[0]{
			return shim.Error("StratNumber must be ascending order") //startNumber 必须是有序的
		}
		qr.StartNumber = append(qr.StartNumber,startNum)
		qr.EndNum = startNum + int64(qrcode.Count)
	}
	err = putStateStruct(qrKey, qr, stub)
	if err != nil {
		return shim.Error("put QrKey info err: " + err.Error())
	}

	return shim.Success([]byte(fmt.Sprintf("put qrcode info %s successful!", startStr)))
}

/*
	查询溯源信息
返回的溯源信息包括，设计一个统一的结构，如果没有值则设置为空
step:
1； 查询溯源信息是否存在，如果存在则更新，并修改查看次数写入数据库
2： 如果不存在，查询存储的二维码信息
3： 根据二维码信息构建溯源展示信息，返回并写进数据库
*/
func SearchRespectInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) < 2 {
		return shim.Error("search respect info expected 2 parameters! ")
	}
	if args[0] == " " || len(args[0]) == 0 {
		return shim.Error("search key pno can not is null")
	}
	if args[1] == " " || len(args[1]) == 0 {
		return shim.Error("search key number can not is null")
	}
	showKey, err := stub.CreateCompositeKey(ReprospectShowInfoKey, []string{args[0], args[1]})
	if err != nil {
		return shim.Error("create respect show composite key err: " + err.Error())
	}
	showByte, err := getStateByte(showKey, stub)
	qr := &SearchQrCode{}
	if showByte != nil{

		err = json.Unmarshal(showByte,qr)
		if err !=nil{
			return shim.Error(err.Error())
		}
		qr.Count+=1
	}else{
		qrcode,err := getQrcode(args,stub)
		if err!=nil{
			return shim.Error(err.Error())
		}
		qr,err = extractRespectShowInfo(qrcode,stub)
		if err != nil{
			return shim.Error("extract RespectShow info err: " +err.Error())
		}
	}

	valueByte, err := json.Marshal(qr)
	if err != nil {
		return shim.Error(fmt.Sprintf("json marshal data fail,err: %s", err))
	}
	err = stub.PutState(showKey,valueByte)
	if err != nil{
		return shim.Error(err.Error())
	}
	return shim.Success(valueByte)
}

/*
	添加/编辑 销售信息
*/
func AddsaleInfo(args []string, stub shim.ChaincodeStubInterface) pb.Response {
	if len(args) > 1 {
		return shim.Error("add sale info expected 1 parameters! ")
	}
	sale := &SalesInfo{}
	err := json.Unmarshal([]byte(args[0]), sale)
	if err != nil {
		return shim.Error(fmt.Sprintf("Unmarshal SalesInfo fail,err %s ", err))
	}
	if sale.Id == " " || len(sale.Id) == 0 {
		return shim.Error("packaging info id can not is null")
	}
	companyKey := SaleInfoKey + "_" + sale.Id
	err = putStateStruct(companyKey, sale, stub)
	if err != nil {
		return shim.Error("put sale info err: " + err.Error())
	}
	return shim.Success([]byte("put " + sale.Id + " sale info successful!"))
}

/*
	根据QrCode（溯源展示定义结构）构建当前溯源信息
*/
func extractRespectShowInfo(qrcode *QrCode, stub shim.ChaincodeStubInterface)(qr *SearchQrCode,err error) {
	sqrcode := &SearchQrCode{}
	sqrcode.PNo = qrcode.PNo
	sqrcode.Count = 1
	//step1: 查询企业信息
	companyKey := CompanyInfoKey + "_" + qrcode.CompanyShow.Cid
	compResult,err := getStateByte(companyKey,stub)
	if err != nil{
		return nil,err
	}
	company:= &CompanyInfo{}
	err = json.Unmarshal(compResult,company)
	if err != nil{
		return nil,err
	}
	sqrcode.CompanyShow = company
	//step 2: 查询质检信息
	qualityKey := QualityTestInfoKey + "_" + qrcode.QualityTestShow.QtId
	qualityResult,err := getStateByte(qualityKey,stub)
	if err != nil{
		return nil,err
	}
	quality:= &QualityTesting{}
	err = json.Unmarshal(qualityResult,quality)
	if err != nil{
		return nil,err
	}
	sqrcode.QualityTestShow = quality
	//step3: 进行溯源展示信息与产品信息
	retrospect:= &SearchRetrospectShow{}
	productShow := &SearchProductShow{}
	retrospect.BaseFiles = qrcode.RetrospectShow.BaseFiles
	retrospect.LogisticsInfo = qrcode.RetrospectShow.LogisticsInfo
	productShow.ExpirationDate = qrcode.ProductShow.ExpirationDate
	productShow.ProductFiles = qrcode.ProductShow.ProductFiles
	productShow.StoageMode = qrcode.ProductShow.StoageMode
	productShow.ProductNo = qrcode.PNo

	if qrcode.RetrospectShow.BaseName != "false"{
		baseKey := BaseInfoKey + "_" + qrcode.RetrospectShow.BaseName
		baseResult,err := getStateByte(baseKey,stub)
		if err != nil{
			return nil,err
		}
		base:= &BaseInfo{}
		err = json.Unmarshal(baseResult,base)
		if err != nil{
			return nil,err
		}
		retrospect.BaseName = base.BaseName
	}
	if qrcode.RetrospectShow.PlotName != "false" {
		plotKey := PlotInfoKey + "_" + qrcode.RetrospectShow.PlotName
		plotResult,err := getStateByte(plotKey,stub)
		if err != nil{
			return nil,err
		}
		plot:= &PlotInfo{}
		err = json.Unmarshal(plotResult,plot)
		if err != nil{
			return nil,err
		}
		retrospect.PlotName = plot.PlotName
	}

	if qrcode.RetrospectShow.SpeciesName != "false"{
		speciesKey := PeciesInfoKey + "_" + qrcode.RetrospectShow.SpeciesName
		speciesResult,err := getStateByte(speciesKey,stub)
		if err != nil{
			return nil,err
		}
		pecies:= &Pecies{}
		err = json.Unmarshal(speciesResult,pecies)
		if err != nil{
			return nil,err
		}
		retrospect.SpeciesName = pecies.SpeciesName
		productShow.ProductName = pecies.SpeciesName
		productShow.ProductDes = pecies.SpeciesDesc
	}
	if qrcode.RetrospectShow.PlantTest != "false"{
		planttestKey := QuarantineInfoKey + "_" + qrcode.RetrospectShow.PlantTest
		planttestResult,err := getStateByte(planttestKey,stub)
		if err != nil{
			return nil,err
		}
		quar:= &QuarantineInfo{}
		err = json.Unmarshal(planttestResult,quar)
		if err != nil{
			return nil,err
		}
		retrospect.PlantTest = quar
	}
	if qrcode.RetrospectShow.PlantPick != "false"{
		pickKey := PlantingHarvesInfoKey + "_" + qrcode.RetrospectShow.PlantPick
		planttestResult,err := getStateByte(pickKey,stub)
		if err != nil{
			return nil,err
		}
		harves:= &Harvesinfo{}
		err = json.Unmarshal(planttestResult,harves)
		if err != nil{
			return nil,err
		}
		retrospect.PlantPick = harves
		productShow.PickDate =harves.EndDate
	}
	if  qrcode.RetrospectShow.QualityTest != "false"{
		retrospect.QualityTest = quality
	}
	if qrcode.RetrospectShow.Packaging != "false"{
		packKey := PackingInfoKey + "_" + qrcode.RetrospectShow.Packaging
		packResult,err := getStateByte(packKey,stub)
		if err != nil{
			return nil,err
		}
		packing:= &PackagingInfo{}
		err = json.Unmarshal(packResult,packing)
		if err != nil{
			return nil,err
		}
		retrospect.Packaging = packing
	}
	if qrcode.RetrospectShow.SaleInfo != "false"{
		saleKey := SaleInfoKey + "_" + qrcode.RetrospectShow.SaleInfo
		saleResult,err := getStateByte(saleKey,stub)
		if saleResult != nil {
			sale:= &SalesInfo{}
			err = json.Unmarshal(saleResult,sale)
			if err != nil{
				return nil,err
			}
			retrospect.SaleInfo = sale
			productShow.ProductType = sale.PackingSize
		}else if err != nil{
			if err.Error() != "The query information is empty "{
				return nil,err
			}
			retrospect.SaleInfo = nil
		}
	}
	if qrcode.RetrospectShow.PlantActivity != "false"{
		activityKeys := []string{qrcode.PNo}
		activitys ,err := getActivitys(ActivityInfoKey,activityKeys,stub)
		if err != nil{
			return nil,err
		}
		retrospect.PlantActivity = activitys
	}
	sqrcode.ProductShow = productShow
	sqrcode.RetrospectShow =retrospect
	return sqrcode,nil
}

func getActivitys(objectType string,activityKey []string,stub shim.ChaincodeStubInterface)([]*ActivityInfo,error){
	activitys:= make([]*ActivityInfo,1)
	queryIterator,err := stub.GetStateByPartialCompositeKey(objectType,activityKey)
	     if err!= nil{
			 return nil,err
		 }
	if queryIterator.HasNext(){
		kv,err := queryIterator.Next()
		if err != nil{
			return nil,err
		}
		activity := &ActivityInfo{}
		err = json.Unmarshal(kv.Value,activity)
		if err != nil{
			return nil,err
		}
		activitys = append(activitys,activity)
	}
	return activitys,err
}

func getQrcode(args []string, stub shim.ChaincodeStubInterface)(qrCode *QrCode ,err error) {
	startNum,err := strconv.ParseInt(args[1],10,64)
	if err!=nil{
		return nil, errors.New("ParseInt number err,args[1] must be integer ")
	}
	qr := &QrKey{}
	qrKey := QrInfoKey + "_" + args[0]
	qrKeyByte,err := getStateByte(qrKey,stub)
	if err!= nil{
		return nil, errors.New("get qrkey info happen err: " + err.Error())
	}
	err = json.Unmarshal(qrKeyByte,qr)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Unmarshal QrKey fail,err %s ", err))
	}
	if startNum > qr.EndNum {
		return nil, errors.New("invalid startNum ")
	}
	result := SearchQrKey(startNum,qr.StartNumber)
	if result == -1{
		return nil, errors.New(fmt.Sprintf("Unmarshal QrKey fail,err %s ", err))
	}
	numKey := strconv.FormatInt(result,10)
	qrcodeyKey, err := stub.CreateCompositeKey(ReprospectInfoKey, []string{args[0], numKey})
	if err != nil {
		return nil, errors.New("create respect composite key err: " + err.Error())
	}
	resultByte, err := getStateByte(qrcodeyKey, stub)
	if err != nil {
		return nil, errors.New(qrcodeyKey + " qrcode info get err :" + err.Error())
	}
	qrcode := &QrCode{}
	err = json.Unmarshal(resultByte, qrcode)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Unmarshal QrCode fail,err %s ", err))
	}
	return qrcode,nil
}
/*
  使用二分法进行查询和检索，找到startNumber区间
*/
func SearchQrKey(startNum int64,s []int64)int64{
	if len(s) == 0 {
		return -1
	}
	if len(s) == 1{
	return s[0]     //最接近starNum 并且小于它
	}
	middle := len(s)/2
	num := s[middle:middle+1]
	 num1:=make([]int64,1)
	if len(s)-1 > middle{
		num1 = s[middle+1:middle+2]
	}else{
		num1[0] = int64(0)
	}
	if num[0] <= startNum && num1[0] >startNum {
		return num[0]
	} else if num[0] < startNum {
		return SearchQrKey(startNum,s[middle:])
	}else {
		return SearchQrKey(startNum,s[0:middle])
	}

}

func putStateStruct(key string, value interface{}, stub shim.ChaincodeStubInterface) error {
	valueByte, err := json.Marshal(value)
	if err != nil {
		return fmt.Errorf(" %s json marshal data fail,err: %s", key, err)
	}
	err = stub.PutState(key, valueByte)
	if err != nil {
		return fmt.Errorf("putState %s data fail,err: %s", key, err)
	}
	return nil
}

func getStateByte(key string, stub shim.ChaincodeStubInterface) ([]byte, error) {
	byteInfo, err := stub.GetState(key)
	if err != nil {
		return nil, err
	}
	if byteInfo == nil {
		return nil, fmt.Errorf("The query information is empty ")
	}
	return byteInfo, nil
}

func main() {
	err := shim.Start(&Retrospect{})
	if err != nil {
		fmt.Printf("Error starting medical chaincode: %s", err)
	}
}
