package kingdee import ( "bytes" "encoding/json" "fmt" "io/ioutil" "mime/multipart" "net/http" "strconv" "time" "kingdee-dbapi/config" "kingdee-dbapi/logger" "kingdee-dbapi/nsqclient" ) var JoHeadTemplate = ` { "fdate": "%s", //日期 当天日期 "ftype": 1054, //固定值 "forderinterid": 0, //固定值 "fpporderinterid": 0, //固定值 "fparentinterid": 0, //固定值 "fsupplyid": 0, //固定值 "fplanconfirmed": 0, //计划确认 "fplanmode": 14036, //计划模式 "fworktypeid": 55, //生产类型 "fmrp": 1052, //单据来源 "fbomcategory": 36820, //BOM 类别 "fcardclosed": 1059, //流转卡关联关闭 "fprintcount": 0, //打印次数 "ffinclosed": 0, //财务结算标志 "ffinclosedate": "", //财务结算日期 "ffincloseer": 0, //财务结算人 "fmtono": " ", //计划跟踪号: "fauxqtyforitem": 0, //因料报废数量 "funitid": 0, //单位 接口自动获取, 设置成0就可以 "fcostobjid": 0, //成本对象 , 接口自动获取, 设置成0就可以 "fbominterid": 0, //BOM编号 接口自动获取, 设置成0就可以 "fbillerid": 16394, //与制单人一致 "fplancategory": 2, //计划类别 "fcheckdate": "%s", //制单日期 "fstartdate": "%s", //开工日期 "ffinishdate": "%s", //完工日期 "fplancommitdate": "%s", //计划开工日期 "fplanfinishdate": "%s", //计划完工日期 "fitemid": "%s->", //物料编码 * "fworkshop": "%s->", //生产车间编号 "fauxqty": %d, //计划生产数量 "fauxinhighlimitqty": %d, //完工入库上限 "fauxinlowlimitqty": %d, //完工入库下限 "finhighlimit": 0, //完工入库超收比例 "finlowlimit": 0 //完工入库欠收比例 } ` type CSTNsqQuery struct { FBillNo string `json:"FBillNo"` // 订单编号 FNumber string `json:"FNumber"` // 物料代码 FSource string `json:"FSource"` // 生产车间代码 FStartDate string `json:"FStartDate"` // 开工日期 FFinishDate string `json:"FFinishDate"` // 完工日期 UseAmount float64 `json:"UseAmount"` // 使用数量 } type CSTNsqReply struct { FBillNo string `json:"FBillNo"` // 订单编号 FNumber string `json:"FNumber"` // 物料代码 ICMONo string `json:"ICMONo"` // 金蝶系统的生产任务单编号 Code int `json:"code"` // CST接口返回的code, 成功200 Message string `json:"message"` // 失败的错误信息 } type CSTServiceResponse struct { ErrCode int `json:"errcode"` ErrMsg string `json:"errmsg"` Data struct { FBillNo string `json:"fbillno"` FBillId string `json:"fbillid"` FTranType string `json:"ftrantype"` FClassTypeId int `json:"fclasstypeid"` } `json:"data"` } func CSTQueryHandle(msg []byte) error { var query []CSTNsqQuery var reply []CSTNsqReply if err := json.Unmarshal(msg, &query); err != nil { logger.Warn("解析请求失败, %s", err.Error()) return err } logger.Debug("接收到创建生产任务单请求, 共%d条订单", len(query)) for _, q := range query { ret := Commit2CSTService(q) reply = append(reply, ret) } replyData, _ := json.Marshal(reply) ok := nsqclient.Produce(config.Options.CSTReplyTopic, replyData) logger.Warn("应答查询请求结果:%t, key:%s", ok, replyData) return nil } func Commit2CSTService(order CSTNsqQuery) (result CSTNsqReply) { result.Code = -1 result.FBillNo = order.FBillNo result.FNumber = order.FNumber if result.FBillNo == "" || result.FNumber == "" { result.Message = "订单编号或物料编号不能为空" return } today := time.Now().Format("2006-01-02") joHead := fmt.Sprintf(JoHeadTemplate, today, // 日期 today, // 制单日期 order.FStartDate, // 开工日期 order.FFinishDate, // 完工日期 order.FStartDate, // 计划开工日期 order.FFinishDate, // 计划完工日期 order.FNumber, // 物料编码 order.FSource, // 生产车间编码 int(order.UseAmount), // 生产数量 int(order.UseAmount), // 完工入库上限 int(order.UseAmount), // 完工入库下限 ) //fmt.Println(joHead) params := map[string]string{ "action": "生产任务单.新增", "fuserid": "16394", "jo_head": joHead, "ja_body": "[{}]", } request, err := newMultipartRequest(config.Options.CSTWebApi, params) if err != nil { result.Message = err.Error() return } client := &http.Client{} resp, err := client.Do(request) if err != nil { result.Message = err.Error() return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { result.Message = err.Error() return } var rspMsg CSTServiceResponse err = json.Unmarshal(body, &rspMsg) if err != nil { result.Message = err.Error() return } if rspMsg.ErrCode == 0 { result.Code = 200 result.ICMONo = rspMsg.Data.FBillNo } else { result.Code = rspMsg.ErrCode result.Message = rspMsg.ErrMsg } return } func newMultipartRequest(url string, params map[string]string) (*http.Request, error) { body := &bytes.Buffer{} writer := multipart.NewWriter(body) // 设置Boundary, 接口验证了六个- if err := writer.SetBoundary("------basicHttpClient" + strconv.Itoa(int(time.Now().Unix()))); err != nil { fmt.Println(err.Error()) } for key, val := range params { _ = writer.WriteField(key, val) } writer.Close() req, err := http.NewRequest("POST", url, body) if err != nil { return nil, err } req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("User-Agent", "basicHttpClient/0.0.1") req.Header.Set("Connection", "keep-alive") req.Header.Set("Accept", "*/*") return req, err }