From f7387bfd4d0070294ca41befb5db857e8bb11041 Mon Sep 17 00:00:00 2001 From: wucongxing <815046773@qq.com> Date: Fri, 22 Dec 2023 15:42:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=B3=BB=E7=BB=9F=E5=95=86?= =?UTF-8?q?=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/controller/product.go | 35 +++++++ api/dto/Product.go | 9 ++ api/model/product.go | 3 + api/requests/product.go | 23 +++++ api/router/router.go | 11 ++- api/service/order.go | 16 +-- api/service/product.go | 111 +++++++++++++++++++++ config.yaml | 2 +- extend/prescription/prescription.go | 145 ++++++++++++++++++++++------ utils/replace.go | 5 +- 10 files changed, 315 insertions(+), 45 deletions(-) diff --git a/api/controller/product.go b/api/controller/product.go index 693f3ca..c9b2190 100644 --- a/api/controller/product.go +++ b/api/controller/product.go @@ -155,3 +155,38 @@ func (r *Product) GetProduct(c *gin.Context) { responses.OkWithData(getPlatformProductResponses, c) } + +// AddProduct 新增商品 +func (r *Product) AddProduct(c *gin.Context) { + productRequest := requests.ProductRequest{} + req := productRequest.AddProduct + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + // 获取当前登陆用户id + userId := c.GetInt64("UserId") + if userId == 0 { + responses.FailWithMessage("角色错误", c) + return + } + + userIdStr := strconv.FormatInt(userId, 10) + + // 业务处理 + productService := service.ProductService{} + _, err := productService.AddProduct(userIdStr, req) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + responses.Ok(c) +} diff --git a/api/dto/Product.go b/api/dto/Product.go index 014be80..229f896 100644 --- a/api/dto/Product.go +++ b/api/dto/Product.go @@ -9,6 +9,9 @@ import ( type ProductDto struct { ProductId string `json:"product_id"` // 主键id ProductPlatformId string `json:"product_platform_id"` // 处方平台商品id + ProductStatus int `json:"product_status"` // 商品状态(1:正常 2:下架) + IsDelete int `json:"is_delete"` // 是否删除(0:否 1:是) + PrescriptionNum int `json:"prescription_num"` // 处方可开具的数量 ProductName string `json:"product_name"` // 商品名称 CommonName string `json:"common_name"` // 商品通用名 ProductPrice float64 `json:"product_price"` // 商品价格 @@ -36,6 +39,9 @@ func GetProductDto(m *model.Product) *ProductDto { return &ProductDto{ ProductId: fmt.Sprintf("%d", m.ProductId), ProductPlatformId: fmt.Sprintf("%d", m.ProductPlatformId), + ProductStatus: m.ProductStatus, + IsDelete: m.IsDelete, + PrescriptionNum: m.PrescriptionNum, ProductName: m.ProductName, CommonName: m.ProductName, ProductPrice: m.ProductPrice, @@ -68,6 +74,9 @@ func GetProductListDto(m []*model.Product) []*ProductDto { response := &ProductDto{ ProductId: fmt.Sprintf("%d", v.ProductId), ProductPlatformId: fmt.Sprintf("%d", v.ProductPlatformId), + ProductStatus: v.ProductStatus, + IsDelete: v.IsDelete, + PrescriptionNum: v.PrescriptionNum, ProductName: v.ProductName, CommonName: v.ProductName, ProductPrice: v.ProductPrice, diff --git a/api/model/product.go b/api/model/product.go index 6c2a96a..649c6e6 100644 --- a/api/model/product.go +++ b/api/model/product.go @@ -10,6 +10,9 @@ import ( type Product struct { ProductId int64 `gorm:"column:product_id;type:bigint(19);primary_key;comment:主键id" json:"product_id"` ProductPlatformId int64 `gorm:"column:product_platform_id;type:bigint(19);comment:处方平台商品id" json:"product_platform_id"` + ProductStatus int `gorm:"column:product_status;type:tinyint(1);default:1;comment:商品状态(1:正常 2:下架)" json:"product_status"` + IsDelete int `gorm:"column:is_delete;type:tinyint(1);default:0;comment:是否删除(0:否 1:是)" json:"is_delete"` + PrescriptionNum int `gorm:"column:prescription_num;type:int(11);default:5;comment:处方可开具的数量" json:"prescription_num"` ProductName string `gorm:"column:product_name;type:varchar(255);comment:商品名称" json:"product_name"` CommonName string `gorm:"column:common_name;type:varchar(100);comment:商品通用名" json:"common_name"` ProductPrice float64 `gorm:"column:product_price;type:decimal(10,2);comment:商品价格" json:"product_price"` diff --git a/api/requests/product.go b/api/requests/product.go index bb28705..9780bce 100644 --- a/api/requests/product.go +++ b/api/requests/product.go @@ -3,6 +3,7 @@ package requests type ProductRequest struct { GetPlatformProductPage // 获取平台商品列表-分页 GetProductPage // 获取系统商品列表-分页 + AddProduct // 新增商品 } // GetPlatformProductPage 获取平台商品列表-分页 @@ -32,3 +33,25 @@ type GetProductPage struct { Manufacturer string `json:"manufacturer" form:"manufacturer" label:"生产厂家"` // 生产厂家 ProductRemarks string `json:"product_remarks" form:"product_remarks" label:"商品备注"` // 商品备注 } + +// AddProduct 新增商品 +type AddProduct struct { + ProductPlatformId string `json:"product_platform_id" form:"product_platform_id" label:"平台商品id" validate:"required"` // 处方平台商品id + ProductName string `json:"product_name" form:"product_name" label:"商品名称" validate:"required"` // 商品名称 + CommonName string `json:"common_name" form:"common_name" label:"商品通用名" validate:"required"` // 商品通用名 + ProductPrice float64 `json:"product_price" form:"product_price" label:"商品价格" validate:"required"` // 商品价格 + MnemonicCode string `json:"mnemonic_code" form:"mnemonic_code" label:"商品助记码"` // 商品助记码(首字母简拼) + ProductType *int `json:"product_type" form:"product_type" label:"药品类型" validate:"oneof=0 1 2"` // 药品类型(0:未知 1:中成药 2:西药) + ProductPlatformCode string `json:"product_platform_code" form:"product_platform_code" label:"处方平台商品编码" validate:"required"` // 处方平台商品编码 + ProductPharmacyCode string `json:"product_pharmacy_code" form:"product_pharmacy_code" label:"第三方药店商品编码" validate:"required"` // 第三方药店商品编码 + ProductCoverImg string `json:"product_cover_img" form:"product_cover_img" label:"商品封面图"` // 商品封面图 + ProductSpec string `json:"product_spec" form:"product_spec" label:"商品规格" validate:"required"` // 商品规格 + LicenseNumber string `json:"license_number" form:"license_number" label:"批准文号" validate:"required"` // 批准文号 + Manufacturer string `json:"manufacturer" form:"manufacturer" label:"生产厂家" validate:"required"` // 生产厂家 + SingleUnit string `json:"single_unit" form:"single_unit" label:"单次剂量" validate:"required"` // 单次剂量(例:1次1包) + SingleUse string `json:"single_use" form:"single_use" label:"单次用法" validate:"required"` // 单次用法(例:口服) + PackagingUnit string `json:"packaging_unit" form:"packaging_unit" label:"基本包装单位" validate:"required"` // 基本包装单位(例:盒/瓶) + FrequencyUse string `json:"frequency_use" form:"frequency_use" label:"使用频率" validate:"required"` // 使用频率(例:1天3次) + AvailableDays float64 `json:"available_days" form:"available_days" label:"可用天数" validate:"required"` // 可用天数(3) + ProductRemarks string `json:"product_remarks" form:"product_remarks" label:"商品备注" validate:"required"` // 商品备注 +} diff --git a/api/router/router.go b/api/router/router.go index 4e7ff79..9e62e39 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -661,13 +661,13 @@ func privateRouter(r *gin.Engine, api controller.Api) { // 系统商品详情 productGroup.GET("/:product_id", api.Product.GetProduct) - // 新增系统商品 - productGroup.POST("", api.Dept.AddDept) + // 新增商品 + productGroup.POST("", api.Product.AddProduct) - // 删除系统商品 + // 删除商品 productGroup.DELETE("", api.Dept.DeleteDept) - // 修改系统商品 + // 修改商品 productGroup.PUT("/:product_id", api.Dept.PutDept) // 平台商品 @@ -678,6 +678,9 @@ func privateRouter(r *gin.Engine, api controller.Api) { // 平台商品详情 platformGroup.GET("/:product_platform_id", api.Product.GetProductPlatform) + + // 获取平台商品列表 + platformGroup.GET("/list", api.UserDoctor.GetUserDoctorList) } } } diff --git a/api/service/order.go b/api/service/order.go index 4ae6fe7..358be81 100644 --- a/api/service/order.go +++ b/api/service/order.go @@ -163,8 +163,8 @@ func (r *OrderService) ReportPreProduct(orderProductId, adminUserId int64) (bool icdNameStr := strings.Join(icdNameSlice, ";") // 处理上传数据-药品数据 - drugRequests := make([]prescription.DrugRequest, len(orderProductItems)) - orderDrugRequests := make([]prescription.OrderDrugRequest, len(orderProductItems)) + drugListRequests := make([]prescription.DrugListRequest, len(orderProductItems)) + orderDrugListRequests := make([]prescription.OrderDrugListRequest, len(orderProductItems)) for i, o := range orderProductItems { // 获取商品数据 productDao := dao.ProductDao{} @@ -179,7 +179,7 @@ func (r *OrderService) ReportPreProduct(orderProductId, adminUserId int64) (bool } // 药品数据1 - drugRequest := prescription.DrugRequest{ + drugRequest := prescription.DrugListRequest{ DrugCode: product.ProductPlatformCode, // 药品编码 ApprovalNumber: product.LicenseNumber, // 批准文号 DrugName: product.ProductName, // 药品名称 @@ -194,10 +194,10 @@ func (r *OrderService) ReportPreProduct(orderProductId, adminUserId int64) (bool FrequencyName: product.FrequencyUse, // 频次名称 UseDays: useDays, // 使用天数 } - drugRequests[i] = drugRequest + drugListRequests[i] = drugRequest // 药品数据2 - orderDrugRequest := prescription.OrderDrugRequest{ + orderDrugRequest := prescription.OrderDrugListRequest{ DrugCode: product.ProductPlatformCode, // 药品编码 ApprovalNumber: product.LicenseNumber, // 批准文号 DrugName: product.ProductName, // 药品名称 @@ -206,7 +206,7 @@ func (r *OrderService) ReportPreProduct(orderProductId, adminUserId int64) (bool DrugCount: o.Amount, // 药品数量 PackingUnit: product.PackagingUnit, // 药品单位 } - orderDrugRequests[i] = orderDrugRequest + orderDrugListRequests[i] = orderDrugRequest } // 处理上传数据-处方数据 @@ -237,8 +237,8 @@ func (r *OrderService) ReportPreProduct(orderProductId, adminUserId int64) (bool PhysicalExamination: "无", SupplementaryExamination: "无", AllergicHistory: orderInquiryCase.AllergyHistory, - DrugList: drugRequests, - OrderDrugList: orderDrugRequests, + DrugList: drugListRequests, + OrderDrugList: orderDrugListRequests, } presRequests[0] = presRequest diff --git a/api/service/product.go b/api/service/product.go index e3200eb..42e60e9 100644 --- a/api/service/product.go +++ b/api/service/product.go @@ -4,6 +4,12 @@ import ( "errors" "hospital-admin-api/api/dao" "hospital-admin-api/api/dto" + "hospital-admin-api/api/model" + "hospital-admin-api/api/requests" + "hospital-admin-api/extend/prescription" + "hospital-admin-api/global" + "hospital-admin-api/utils" + "strconv" ) type ProductService struct { @@ -47,3 +53,108 @@ func (r *ProductService) GetProduct(productId int64) (g *dto.ProductDto, err err return g, nil } + +// AddProduct 新增商品 +func (r *ProductService) AddProduct(userId string, req requests.AddProduct) (bool, error) { + productDao := dao.ProductDao{} + productPlatformAmountDao := dao.ProductPlatformAmountDao{} + + productPlatformId, err := strconv.ParseInt(req.ProductPlatformId, 10, 64) + if err != nil { + return false, errors.New("新增失败") + } + + // 检测平台商品是否存在 + productPlatformDao := dao.ProductPlatformDao{} + productPlatform, err := productPlatformDao.GetProductPlatformById(productPlatformId) + if err != nil || productPlatform == nil { + return false, errors.New("平台商品不存在") + } + + // 检测商品是否重复 + maps := make(map[string]interface{}) + maps["product_platform_id"] = req.ProductPlatformId + products, err := productDao.GetProductList(maps) + if err != nil { + return false, errors.New("商品重复添加") + } + + if len(products) != 0 { + return false, errors.New("商品重复添加") + } + + // 处理图片 + productCoverImg := utils.RemoveOssDomain(req.ProductCoverImg) + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + // 新增商品表 + product := &model.Product{ + ProductPlatformId: productPlatform.ProductPlatformId, + ProductName: req.ProductName, + CommonName: req.CommonName, + ProductPrice: req.ProductPrice, + MnemonicCode: req.MnemonicCode, + ProductType: *req.ProductType, + ProductPlatformCode: req.ProductPlatformCode, + ProductPharmacyCode: req.ProductPharmacyCode, + ProductCoverImg: productCoverImg, + ProductSpec: req.ProductSpec, + LicenseNumber: req.LicenseNumber, + Manufacturer: req.Manufacturer, + SingleUnit: req.SingleUnit, + SingleUse: req.SingleUse, + PackagingUnit: req.PackagingUnit, + FrequencyUse: req.FrequencyUse, + AvailableDays: req.AvailableDays, + ProductRemarks: req.ProductRemarks, + } + + product, err = productDao.AddProduct(tx, product) + if err != nil || product == nil { + tx.Rollback() + return false, errors.New(err.Error()) + } + + // 获取商品库存 + ReportPreRequest := prescription.GetProdStockRequest{ + DrugCode: product.ProductPharmacyCode, + } + + result, err := ReportPreRequest.GetProdStock() + if err != nil { + tx.Rollback() + return false, errors.New("获取商品库存失败") + } + + var quantity int + if result.Quantity != "" { + quantity, err = strconv.Atoi(result.Quantity) + if err != nil { + tx.Rollback() + return false, errors.New("获取商品库存失败") + } + } + + // 新增商品库存 + productPlatformAmount := &model.ProductPlatformAmount{ + ProductPlatformId: product.ProductPlatformId, + ProductPlatformCode: product.ProductPlatformCode, + Stock: uint(quantity), + } + + productPlatformAmount, err = productPlatformAmountDao.AddProductPlatformAmount(tx, productPlatformAmount) + if err != nil || productPlatformAmount == nil { + tx.Rollback() + return false, errors.New(err.Error()) + } + + tx.Commit() + return true, nil +} diff --git a/config.yaml b/config.yaml index cdea89d..8bb5c9c 100644 --- a/config.yaml +++ b/config.yaml @@ -90,4 +90,4 @@ pre: pre-plat-client-id: ZD-004 pre-plat-client-secret: 0baa5927164710b9f800bf33546b6da3 pre-plat-app-url: http://49.233.3.200:6304/api/thridapi/ - pre-plat-pharmacy-code: ZD-10003 \ No newline at end of file + pre-plat-pharmacy-code: JG-10009 \ No newline at end of file diff --git a/extend/prescription/prescription.go b/extend/prescription/prescription.go index 8efc581..b625390 100644 --- a/extend/prescription/prescription.go +++ b/extend/prescription/prescription.go @@ -56,37 +56,37 @@ type ReportPreRequest struct { // 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 []DrugRequest `json:"drugList"` // 药品列表 - OrderDrugList []OrderDrugRequest `json:"orderDrugList"` // 订单药品列表 + 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"` // 订单药品列表 } -// DrugRequest 上报处方请求值-药品数据1 -type DrugRequest struct { +// DrugListRequest 上报处方请求值-药品数据1 +type DrugListRequest struct { DrugCode string `json:"drugCode"` // 药品编码 ApprovalNumber string `json:"approvalNumber"` // 批准文号 DrugName string `json:"drugName"` // 药品名称 @@ -102,8 +102,8 @@ type DrugRequest struct { UseDays int `json:"useDays"` // 使用天数 } -// OrderDrugRequest 上报处方请求值-药品数据2 -type OrderDrugRequest struct { +// OrderDrugListRequest 上报处方请求值-药品数据2 +type OrderDrugListRequest struct { DrugCode string `json:"drugCode"` // 药品编码 ApprovalNumber string `json:"approvalNumber"` // 批准文号 DrugName string `json:"drugName"` // 药品名称 @@ -113,12 +113,30 @@ type OrderDrugRequest struct { PackingUnit string `json:"packingUnit"` // 药品单位 } +// 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 数据 @@ -328,3 +346,68 @@ func (r ReportPreRequest) ReportPre() (bool, error) { return true, nil } + +// GetProdStock 获取商品库存 +func (r GetProdStockRequest) GetProdStock() (*GetProdStockDataResponse, error) { + r.PharmacyCode = config.C.Pre.PrePlatPharmacyCode + jsonData, err := json.Marshal(r) + if err != nil { + return nil, err + } + + // 准备请求体 + requestBody := bytes.NewBuffer(jsonData) + + // 设置请求 URL + url := config.C.Pre.PrePlatAppUrl + "v1/pharmacy/pharmacyInventory" + + // 创建 POST 请求 + req, err := http.NewRequest("POST", url, requestBody) + if err != nil { + 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 { + return nil, err + } + } + + req.Header.Set("Authorization", "Bearer "+token) + + // 发送请求 + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + + // 检查响应状态码 + if resp.StatusCode != 200 { + return nil, errors.New("返回数据错误") + } + + var response getProdStockResponse + err = json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + return nil, err + } + + if response.ResultCode != "1000" { + if response.ResultDesc != "" { + return nil, errors.New(response.ResultDesc) + } + return nil, errors.New("获取商品库存失败") + } + + return &response.Data, nil +} diff --git a/utils/replace.go b/utils/replace.go index 2b61b16..dc344c2 100644 --- a/utils/replace.go +++ b/utils/replace.go @@ -7,7 +7,10 @@ import ( // RemoveOssDomain 去除oss地址中的前缀 func RemoveOssDomain(url string) string { - return strings.Replace(url, config.C.Oss.OssCustomDomainName, "", 1) + if url != "" { + url = strings.Replace(url, config.C.Oss.OssCustomDomainName, "", 1) + } + return url } // AddOssDomain 去除oss地址中的前缀