432 lines
14 KiB
Go
432 lines
14 KiB
Go
// Package prescription 处方平台
|
||
package prescription
|
||
|
||
import (
|
||
"bytes"
|
||
"context"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"hospital-admin-api/config"
|
||
"hospital-admin-api/global"
|
||
"hospital-admin-api/utils"
|
||
"io"
|
||
"net/http"
|
||
"time"
|
||
)
|
||
|
||
// 获取token请求值
|
||
type getTokeRequest struct {
|
||
ClientId string `json:"clientId"`
|
||
ClientSecret string `json:"clientSecret"`
|
||
}
|
||
|
||
// 通知处方平台订单取消
|
||
type noticePreOrderCancelRequest struct {
|
||
OrgCode string `json:"orgCode"` // 机构编码
|
||
OrderNo string `json:"orderNo"` // 院内订单编号
|
||
OptCode string `json:"optCode"` // 操作状态
|
||
}
|
||
|
||
// 通知处方平台订单取消返回数据
|
||
type noticePreOrderCancelResponse struct {
|
||
ResultCode string `json:"resultCode"` // 操作编码
|
||
ResultDesc string `json:"resultDesc"` // 描述
|
||
}
|
||
|
||
// ReportPreRequest 上报处方请求值-基础数据
|
||
type ReportPreRequest struct {
|
||
TerminalCode string `json:"terminalCode"` // 终端代码
|
||
OrderNo string `json:"orderNo"` // 订单编号
|
||
TransactNo string `json:"transactNo"` // 流水单号
|
||
PayDate string `json:"payDate"` // 支付时间
|
||
Money float64 `json:"money"` // 订单金额
|
||
Freight float64 `json:"freight"` // 运费(单位:元)
|
||
TakeTypeCode int `json:"takeTypeCode"` // 取货方式 1 自提 2 快递,目前只支持快递,传固定值 2
|
||
BuyerName string `json:"buyerName"` // 收货人姓名
|
||
BuyerPhone string `json:"buyerPhone"` // 收货人联系方式
|
||
BuyerAddress string `json:"buyerAddress"` // 收货人地址
|
||
ProvinceCode string `json:"provinceCode"` // 收货地址(省) 编码
|
||
ProvinceName string `json:"provinceName"` // 收货地址(省) 名称
|
||
CityCode string `json:"cityCode"` // 收货地址(市) 编码
|
||
CityName string `json:"cityName"` // 收货地址(市) 名称
|
||
DistrictCode string `json:"districtCode"` // 收货地址(区 县)编码
|
||
DistrictName string `json:"districtName"` // 收货地址(区 县)名称
|
||
PresList []PresRequest `json:"presList"` // 处方列表
|
||
}
|
||
|
||
// PresRequest 上报处方请求值-处方数据
|
||
type PresRequest struct {
|
||
PrescriptionNo string `json:"prescriptionNo"` // 处方编号
|
||
PrescriptionSubType int `json:"prescriptionSubType"` // 处方类型 0:无类型 1:普通处方 2:儿科处方
|
||
PatientName string `json:"patientName"` // 就诊人姓名
|
||
PatientPhone string `json:"patientPhone"` // 就诊人联系方式
|
||
IdCard string `json:"idCard"` // 身份证号
|
||
Advice string `json:"advice"` // 医嘱
|
||
DiagnosisName string `json:"diagnosisName"` // 诊断
|
||
ThirdDoctorName string `json:"thirdDoctorName"` // 开方医生姓名
|
||
ThirdDeptName string `json:"thirdDeptName"` // 开方科室名称
|
||
ThirdDoctorNameImg string `json:"thirdDoctorNameImg"` // 开方医生签名链接
|
||
PrescriptionTime string `json:"prescriptionTime"` // 开方时间
|
||
ThirdFirstPharmacist string `json:"thirdFirstPharmacist"` // 初审药师姓名
|
||
ThirdFirstPharmacistImg string `json:"thirdFirstPharmacistImg"` // 初审药师签名链接
|
||
ThirdFirstTime string `json:"thirdFirstTime"` // 初审时间
|
||
ThirdLastPharmacist string `json:"thirdLastPharmacist"` // 终审药师姓名
|
||
ThirdLastPharmacistImg string `json:"thirdLastPharmacistImg"` // 终审药师签名链接
|
||
ThirdLastTime string `json:"ThirdLastTime"` // 终审时间
|
||
ThirdSignImg string `json:"thirdSignImg"` // 处方签章链接
|
||
ReferenceCharge float64 `json:"referenceCharge"` // 处方费用(不包含运费)
|
||
ChiefComplaint string `json:"chiefComplaint"` // 主诉
|
||
HistoryPresent string `json:"historyPresent"` // 现病史
|
||
PastHistory string `json:"pastHistory"` // 既往史
|
||
PhysicalExamination string `json:"physicalExamination"` // 体格检查
|
||
SupplementaryExamination string `json:"supplementaryExamination"` // 辅助检查
|
||
AllergicHistory string `json:"allergicHistory"` // 过敏史
|
||
DrugList []DrugListRequest `json:"drugList"` // 药品列表
|
||
OrderDrugList []OrderDrugListRequest `json:"orderDrugList"` // 订单药品列表
|
||
}
|
||
|
||
// DrugListRequest 上报处方请求值-药品数据1
|
||
type DrugListRequest struct {
|
||
DrugCode string `json:"drugCode"` // 药品编码
|
||
ApprovalNumber string `json:"approvalNumber"` // 批准文号
|
||
DrugName string `json:"drugName"` // 药品名称
|
||
Specifications string `json:"specifications"` // 药品规格
|
||
Price float64 `json:"price"` // 药品单价
|
||
PackingCount int `json:"packingCount"` // 药品数量
|
||
SurplusPackingCount int `json:"surplusPackingCount"` // 处方药品剩余使用数量
|
||
PackingUnit string `json:"packingUnit"` // 药品单位
|
||
SingleDosage int `json:"singleDosage"` // 单次用量
|
||
SingleDosageUnit string `json:"singleDosageUnit"` // 单次用量单位
|
||
UseName string `json:"useName"` // 用法名称
|
||
FrequencyName string `json:"frequencyName"` // 频次名称
|
||
UseDays int `json:"useDays"` // 使用天数
|
||
}
|
||
|
||
// OrderDrugListRequest 上报处方请求值-药品数据2
|
||
type OrderDrugListRequest struct {
|
||
DrugCode string `json:"drugCode"` // 药品编码
|
||
ApprovalNumber string `json:"approvalNumber"` // 批准文号
|
||
DrugName string `json:"drugName"` // 药品名称
|
||
Specifications string `json:"specifications"` // 药品规格
|
||
Price float64 `json:"price"` // 药品单价
|
||
DrugCount int `json:"drugCount"` // 药品数量
|
||
PackingUnit string `json:"packingUnit"` // 药品单位
|
||
ActualSellingPrice float64 `json:"actual_product_price"` // 药品实际销售单价
|
||
}
|
||
|
||
// GetProdStockRequest 获取商品库存请求值
|
||
type GetProdStockRequest struct {
|
||
PharmacyCode string `json:"pharmacyCode"` // 药房编码
|
||
DrugCode string `json:"drugCode"` // 三方药房药品编码
|
||
}
|
||
|
||
// 上报处方返回数据
|
||
type reportPreResponse struct {
|
||
ResultCode string `json:"resultCode"` // 操作编码
|
||
ResultDesc string `json:"resultDesc"` // 描述
|
||
}
|
||
|
||
// 获取商品库存返回数据
|
||
type getProdStockResponse struct {
|
||
ResultCode string `json:"resultCode"` // 操作编码
|
||
ResultDesc string `json:"resultDesc"` // 描述
|
||
Data []GetProdStockDataResponse `json:"data"` // 具体内容
|
||
}
|
||
|
||
type GetProdStockDataResponse struct {
|
||
Quantity string `json:"quantity"` // 库存
|
||
Threshold string `json:"threshold"` // 库存阈值
|
||
}
|
||
|
||
// GetToken 获取token
|
||
func GetToken() (string, error) {
|
||
// 准备要发送的 JSON 数据
|
||
requestData := getTokeRequest{
|
||
ClientId: config.C.Pre.PrePlatClientId,
|
||
ClientSecret: config.C.Pre.PrePlatClientSecret,
|
||
}
|
||
|
||
// 将 JSON 数据编码为字节数组
|
||
jsonData, err := json.Marshal(requestData)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
// 准备请求体
|
||
requestBody := bytes.NewBuffer(jsonData)
|
||
|
||
// 设置请求 URL
|
||
url := config.C.Pre.PrePlatAppUrl + "v1/user_thrid/token"
|
||
|
||
// 创建 POST 请求
|
||
req, err := http.NewRequest("POST", url, requestBody)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
// 设置请求头
|
||
req.Header.Set("Content-Type", "application/json")
|
||
|
||
// 发送请求
|
||
client := &http.Client{}
|
||
resp, err := client.Do(req)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
defer func(Body io.ReadCloser) {
|
||
_ = Body.Close()
|
||
}(resp.Body)
|
||
|
||
// 检查响应状态码
|
||
if resp.StatusCode != 200 {
|
||
return "", errors.New("返回数据错误")
|
||
}
|
||
|
||
// 读取响应体
|
||
var response map[string]interface{}
|
||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||
if err != nil {
|
||
return "", errors.New("返回数据错误")
|
||
}
|
||
|
||
// 获取 result 字段
|
||
result, ok := response["data"].(map[string]interface{})["result"].(map[string]interface{})
|
||
if !ok {
|
||
return "", errors.New("返回数据错误2")
|
||
}
|
||
|
||
// 获取 token 值
|
||
token, ok := result["token"].(string)
|
||
if !ok {
|
||
return "", errors.New("返回数据错误3")
|
||
}
|
||
|
||
// 添加缓存
|
||
_, err = global.Redis.Set(context.Background(), "prescription_token", token, (60*60*1.5)*time.Second).Result()
|
||
if err != nil {
|
||
return "", errors.New("添加缓存失败")
|
||
}
|
||
|
||
return token, nil
|
||
}
|
||
|
||
// NoticePreOrderCancel 通知处方平台订单取消
|
||
func NoticePreOrderCancel(orderNo string) (bool, error) {
|
||
// 准备要发送的 JSON 数据
|
||
data := noticePreOrderCancelRequest{
|
||
OrgCode: config.C.Pre.PrePlatPharmacyCode,
|
||
OrderNo: orderNo,
|
||
OptCode: "EVTDOD-04",
|
||
}
|
||
|
||
// 将 JSON 数据编码为字节数组
|
||
jsonData, err := json.Marshal(data)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
// 准备请求体
|
||
requestBody := bytes.NewBuffer(jsonData)
|
||
|
||
// 设置请求 URL
|
||
url := config.C.Pre.PrePlatAppUrl + "v1/preOrder/changeOrderByOrg"
|
||
|
||
// 创建 POST 请求
|
||
req, err := http.NewRequest("POST", url, requestBody)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
// 设置请求头,指定 Content-Type 为 application/json
|
||
req.Header.Set("Content-Type", "application/json")
|
||
|
||
token, _ := global.Redis.Get(context.Background(), "prescription_token").Result()
|
||
if token == "" {
|
||
token, err = GetToken()
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
}
|
||
|
||
req.Header.Set("Authorization", "Bearer "+token)
|
||
|
||
// 发送请求
|
||
client := &http.Client{}
|
||
resp, err := client.Do(req)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
defer func(Body io.ReadCloser) {
|
||
_ = Body.Close()
|
||
}(resp.Body)
|
||
|
||
// 检查响应状态码
|
||
if resp.StatusCode != 200 {
|
||
return false, errors.New("返回数据错误")
|
||
}
|
||
|
||
var response noticePreOrderCancelResponse
|
||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
fmt.Println(response)
|
||
if response.ResultCode != "1000" {
|
||
if response.ResultDesc != "" {
|
||
return false, errors.New(response.ResultDesc)
|
||
}
|
||
return false, errors.New("取消处方平台订单失败")
|
||
}
|
||
|
||
return true, nil
|
||
}
|
||
|
||
// ReportPre 上报处方
|
||
func (r ReportPreRequest) ReportPre() (bool, error) {
|
||
jsonData, err := json.Marshal(r)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
utils.LogJsonInfo("上报处方平台:", jsonData)
|
||
|
||
// 准备请求体
|
||
requestBody := bytes.NewBuffer(jsonData)
|
||
|
||
// 设置请求 URL
|
||
url := config.C.Pre.PrePlatAppUrl + "v1/preOrder/receivePreOrder"
|
||
|
||
// 创建 POST 请求
|
||
req, err := http.NewRequest("POST", url, requestBody)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
// 设置请求头,指定 Content-Type 为 application/json
|
||
req.Header.Set("Content-Type", "application/json")
|
||
|
||
token, _ := global.Redis.Get(context.Background(), "prescription_token").Result()
|
||
if token == "" {
|
||
token, err = GetToken()
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
}
|
||
|
||
req.Header.Set("Authorization", "Bearer "+token)
|
||
|
||
// 发送请求
|
||
client := &http.Client{}
|
||
resp, err := client.Do(req)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
defer func(Body io.ReadCloser) {
|
||
_ = Body.Close()
|
||
}(resp.Body)
|
||
|
||
// 检查响应状态码
|
||
if resp.StatusCode != 200 {
|
||
return false, errors.New("返回数据错误")
|
||
}
|
||
|
||
var response reportPreResponse
|
||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
if response.ResultCode != "1000" {
|
||
if response.ResultDesc != "" {
|
||
return false, errors.New(response.ResultDesc)
|
||
}
|
||
return false, errors.New("上报处方平台失败")
|
||
}
|
||
|
||
return true, nil
|
||
}
|
||
|
||
// GetProdStock 获取商品库存
|
||
func (r GetProdStockRequest) GetProdStock() (*GetProdStockDataResponse, error) {
|
||
r.PharmacyCode = config.C.Pre.PrePlatPharmacyCode
|
||
jsonData, err := json.Marshal(r)
|
||
if err != nil {
|
||
utils.LogJsonErr("获取商品库存-序列化请求参数失败", err)
|
||
return nil, err
|
||
}
|
||
|
||
utils.LogJsonInfo("获取商品库存-请求参数:", r)
|
||
|
||
// 准备请求体
|
||
requestBody := bytes.NewBuffer(jsonData)
|
||
|
||
// 设置请求 URL
|
||
url := config.C.Pre.PrePlatAppUrl + "v1/pharmacy/pharmacyInventory"
|
||
|
||
// 打印请求信息
|
||
utils.LogJsonInfo("获取商品库存-请求URL:", url)
|
||
utils.LogJsonInfo("获取商品库存-请求体:", requestBody.String())
|
||
|
||
// 创建 POST 请求
|
||
req, err := http.NewRequest("POST", url, requestBody)
|
||
if err != nil {
|
||
utils.LogJsonErr("获取商品库存-创建请求失败", err)
|
||
return nil, err
|
||
}
|
||
|
||
// 设置请求头,指定 Content-Type 为 application/json
|
||
req.Header.Set("Content-Type", "application/json")
|
||
|
||
token, _ := global.Redis.Get(context.Background(), "prescription_token").Result()
|
||
if token == "" {
|
||
token, err = GetToken()
|
||
if err != nil {
|
||
utils.LogJsonErr("获取商品库存-获取token失败", err)
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
req.Header.Set("Authorization", "Bearer "+token)
|
||
|
||
// 发送请求
|
||
client := &http.Client{}
|
||
resp, err := client.Do(req)
|
||
if err != nil {
|
||
utils.LogJsonErr("获取商品库存-发送请求失败", err)
|
||
return nil, err
|
||
}
|
||
|
||
defer func(Body io.ReadCloser) {
|
||
_ = Body.Close()
|
||
}(resp.Body)
|
||
|
||
// 检查响应状态码
|
||
if resp.StatusCode != 200 {
|
||
utils.LogJsonErr("获取商品库存-响应状态码错误", fmt.Sprintf("statusCode: %d", resp.StatusCode))
|
||
return nil, errors.New("返回数据错误")
|
||
}
|
||
|
||
var response getProdStockResponse
|
||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||
if err != nil {
|
||
utils.LogJsonErr("获取商品库存-解析响应数据失败", err)
|
||
return nil, err
|
||
}
|
||
|
||
if response.ResultCode != "1000" {
|
||
utils.LogJsonErr("获取商品库存-业务处理失败", response)
|
||
if response.ResultDesc != "" {
|
||
return nil, errors.New(response.ResultDesc)
|
||
}
|
||
return nil, errors.New("获取商品库存失败")
|
||
}
|
||
|
||
utils.LogJsonInfo("获取商品库存-成功", response.Data)
|
||
return &response.Data[0], nil
|
||
}
|