作者 Your Name

更新

... ... @@ -5,9 +5,10 @@
- 前端调用的地址 http://allied-creation-gateway-dev.fjmaimaimai.com/v1/manufacture
- 前端调用的地址 http://allied-creation-gateway-test.fjmaimaimai.com/v1/manufacture
## 1.数据导入导出模块
### 1.1.Excel导入流程
### 1.1.Excel 导入流程
- 原型说明
... ... @@ -19,7 +20,6 @@
- [导入接口文档地址](https://doc-press.fjmaimaimai.com/team/frontend/plugins/business/import.html)
```
POST/v1/web/file-import
... ... @@ -31,11 +31,10 @@ file 文件
code 对应导入模块的编码
```
- ``对接步骤``以导入公司用户模块为例
- `对接步骤`以导入公司用户模块为例
1.定义接口导入的`code`为`ADMIN_SYSTEM-MANAGE_BASE_USER` 2.根据接口解析导入文件的数据 3.调用基础库解析数据并传到后台
1.定义接口导入的``code``为``ADMIN_SYSTEM-MANAGE_BASE_USER``
2.根据接口解析导入文件的数据
3.调用基础库解析数据并传到后台
```go
// 1.解析列
... ... @@ -85,21 +84,23 @@ result, err := userGateway.UserBatchAdd(allied_creation_user.ReqBatchAddUser{
```
```go
```
### 2.2 Excel导出流程
### 2.2 Excel 导出流程
- 功能原型说明
实现可以自定义选择列进行导出,以及选择导出格式,导出格式有 ``xlsx``\\``csv``,功能如下图所示:
实现可以自定义选择列进行导出,以及选择导出格式,导出格式有 `xlsx`\\`csv`,功能如下图所示:
![](https://timeless-world.oss-cn-shenzhen.aliyuncs.com/opportunity/dev_online/20220225/object/1645789890_JbTa22EtANsD3fm2nJ4aH6FJkHzXaHJB.png)
- 前后端交互说明
``接口定义``
`接口定义`
导出接口
```shell
POST /v1/web/file-export
... ... @@ -135,9 +136,7 @@ GET/v1/web/file-export/fields/:code
- 交互流程
1.前台根据 ``导出列查询接口`` 获取可以导出的列;
2.勾选需要导出的列、文件格式,调用 ``导出接口`` 向后台发起导出数据请求;
1.前台根据 `导出列查询接口` 获取可以导出的列; 2.勾选需要导出的列、文件格式,调用 `导出接口` 向后台发起导出数据请求;
#### 2.2.1 后端导出实现
... ... @@ -153,6 +152,7 @@ type ExcelMaker interface {
```
如下所示
```go
//ExportCooperationUserData 导出共创用户数据
type ExportCooperationUserData struct {
... ... @@ -256,5 +256,5 @@ func (controller *ExcelDataController) responseExcelByFile(ctx *context.Context,
//跳过保存文件,直接写入ctx.ResponseWriter
excelExport.ExcelFile.Write(ctx.ResponseWriter)
return nil
}
}
```
... ...
package service
import (
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/utils/excel"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/ecelData/command"
productTroubleCommand "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productTrouble/command"
productTroubleService "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/productTrouble/service"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils/converter"
)
// ImportProductTrouble 导入事故记录
func (srv ExcelDataService) ImportProductTrouble(importDataCommand *command.ImportDataCommand) (interface{}, error) {
excelImport := excel.NewExcelImport()
excelImport.RowBegin = 3 //第二行开始读取
excelImport.DataFields = []excel.DataField{
{EnName: "RecordDate", CnName: "日期"},
{EnName: "WorkshopName", CnName: "车间"},
{EnName: "LineName", CnName: "线别"},
{EnName: "SectionName", CnName: "工段"},
{EnName: "WorkerName", CnName: "姓名"},
{EnName: "TypesName", CnName: "事故类型"},
{EnName: "AmountLoss", CnName: "损失金额"},
}
excelData, err := converter.OpenImportFileFromIoReader(excelImport, importDataCommand.Reader, importDataCommand.FileExt) //excelImport.OpenExcelFromIoReader(importDataCommand.Reader)
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
items := make([]productTroubleCommand.BatchAddProductTroubleCommand, 0, len(excelData))
item := productTroubleCommand.BatchAddProductTroubleCommand{}
for _, v := range excelData {
item = productTroubleCommand.BatchAddProductTroubleCommand{
RecordDate: v["RecordDate"],
WorkshopName: v["WorkshopName"],
LineName: v["LineName"],
SectionName: v["SectionName"],
WorkerName: v["WorkerName"],
AmountLoss: v["AmountLoss"],
TypesName: v["TypesName"],
FailReason: "",
}
items = append(items, item)
}
svr := productTroubleService.NewProductTroubleService(nil)
failRows, err := svr.BatchAddProductTrouble(importDataCommand.Operator, items)
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
return srv.importResultWithHeader(excelImport.DataFields, failRows, len(items)), nil
}
... ...
package command
import "errors"
type BatchAddProductTroubleCommand struct {
RecordDate string `json:"recordDate"` //事故发生的日期 2006-01-02
WorkshopName string `json:"workshopId"` //车间
LineName string `json:"lineName"` //生产线
SectionName string `json:"sectionId" valid:"Required"` //工段
WorkerName string `json:"workerId"` //员工名字
AmountLoss string `json:"amountLoss"` // 损失的金额
TypesName string `json:"types"` // 事故类型 1 安全事故 ,2 质量事故, 3 金属事故 ,4 非金属事故
FailReason string `json:"failReason"` // 数据检查失败的原因
}
func (c *BatchAddProductTroubleCommand) ValidField() error {
if len(c.RecordDate) == 0 {
return errors.New("日期 必填")
}
if len(c.WorkshopName) == 0 {
return errors.New("车间 必填")
}
if len(c.LineName) == 0 {
return errors.New("生产线 必填")
}
if len(c.SectionName) == 0 {
return errors.New("工段 必填")
}
if len(c.WorkerName) == 0 {
return errors.New("员工名字 必填")
}
if len(c.AmountLoss) == 0 {
return errors.New("损失金额 必填")
}
if len(c.TypesName) == 0 {
return errors.New("事故类型 必填")
}
return nil
}
... ...
... ... @@ -9,7 +9,7 @@ type SaveProductTroubleCommand struct {
WorkerId int `json:"workerId"` //员工id
Remark string `json:"remark"` //备注
AmountLoss float64 `json:"amountLoss"` // 损失的金额
Types int `json:"types"` // 事故类型 1 安全事故 ,2 质量事故, 3 金属事故 ,4 非金属事故
Types string `json:"types"` // 事故类型 1 安全事故 ,2 质量事故, 3 金属事故 ,4 非金属事故
RecordDate string `json:"recordDate"` // 事故发生的日期
SaveAndApprove bool `json:"saveAndApprove"` //保存并审核
}
... ...
... ... @@ -13,5 +13,5 @@ type ProductTroubleInfo struct {
Remark string `json:"remark"` //备注
ProductDate string `json:"productDate"` //日期
AmountLoss float64 `json:"amountLoss"` //损失的金额
Types int `json:"types"` //事故类型
Types string `json:"types"` //事故类型
}
... ...
package service
import (
"strconv"
"strings"
"time"
"github.com/linmadan/egglib-go/core/application"
... ... @@ -149,7 +151,7 @@ func (srv ProductTroubleService) GetProductTrouble(id int) (*dto.ProductTroubleI
Remark: troubleData.Remark,
ProductDate: troubleData.RecordData.Format("2006-01-02"),
AmountLoss: troubleData.AmountLoss,
Types: int(troubleData.Types),
Types: string(troubleData.Types),
WorkerId: troubleData.ProductWorker.UserId,
WorkerName: troubleData.ProductWorker.UserName,
}
... ... @@ -294,5 +296,158 @@ func (srv ProductTroubleService) ListProductTrouble(param *query.ListProductTrou
}
result = append(result, item)
}
return cnt, result, nil
}
// 批量添加事故数据
func (srv ProductTroubleService) BatchAddProductTrouble(operateInfo *domain.OperateInfo, param []command.BatchAddProductTroubleCommand) (failRows []interface{}, err error) {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
//获取当前操作人
userSrv := domainService.NewUserService()
operateUser, err := userSrv.User(operateInfo.UserId)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, "查询操作人数据失败。"+err.Error())
}
//生产班组 数据
productGroupRepo, _ := factory.CreateProductGroupRepository(map[string]interface{}{
"transactionContext": transactionContext,
})
_, productGroupList, err := productGroupRepo.Find(map[string]interface{}{
"companyId": operateInfo.CompanyId,
"orgId": operateInfo.OrgId,
})
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
//车间名称+/+线别名称+/+工段名称 作为键名
workStationMap := map[string]*domain.WorkStation{}
//车间名称+/+工人名 作为键名
workerMap := map[string][]*domain.User{}
//班组名称 作为键名
productGroupMap := map[string]*domain.ProductGroup{}
for _, v := range productGroupList {
workStationName := strings.Join([]string{
v.WorkStation.WorkshopName, v.WorkStation.LineName, v.WorkStation.SectionName,
}, "/")
workStationMap[workStationName] = v.WorkStation
productGroupMap[v.GroupName] = v
for _, vv := range v.GroupMembers {
k := v.WorkStation.WorkshopName + "/" + vv.UserName
isIn := false
for _, vvv := range workerMap[k] {
if vvv.UserId == vv.UserId {
isIn = true
break
}
}
if !isIn {
workerMap[k] = append(workerMap[k], vv)
}
}
}
troubleDataList := make([]*domain.ProductTrouble, 0, len(param))
nowTime := time.Now()
for i := range param {
//检查字段
err = param[i].ValidField()
if err != nil {
param[i].FailReason = err.Error()
failRows = append(failRows, param[i])
continue
}
//检查日期格式
recordDate, err := time.ParseInLocation("2006-01-02", param[i].RecordDate, time.Local)
if err != nil {
param[i].FailReason = "日期格式错误,例 2006-01-02。"
failRows = append(failRows, param[i])
continue
}
//检查工位
var workStation *domain.WorkStation
workStationName := param[i].WorkerName + "/" + param[i].LineName + "/" + param[i].SectionName
if v, ok := workStationMap[workStationName]; ok {
workStation = v
} else {
param[i].FailReason = "车间、线别、工段不存在"
failRows = append(failRows, param[i])
continue
}
//检查员工姓名
var worker *domain.User
workKey := param[i].WorkshopName + "/" + param[i].WorkerName
if u, ok := workerMap[workKey]; ok {
if len(u) > 1 {
param[i].FailReason = "当前车间存在重复的用户名"
failRows = append(failRows, param[i])
continue
}
worker = u[0]
} else {
param[i].FailReason = "当前车间不存在用户" + param[i].WorkerName
failRows = append(failRows, param[i])
continue
}
//损失金额
amountLoss, err := strconv.ParseFloat(param[i].AmountLoss, 64)
if err != nil {
param[i].FailReason = "损失金额填写错误"
failRows = append(failRows, param[i])
continue
}
item := &domain.ProductTrouble{
Id: 0,
CompanyId: 0,
OrgId: 0,
WorkStation: *workStation,
ProductWorker: *worker,
AmountLoss: amountLoss,
Types: "",
RecordData: recordDate,
Remark: "",
ApproveStatus: domain.TroubleIsApprove,
ApproveAt: &nowTime,
ApproveUser: operateUser,
CreatedAt: nowTime,
UpdatedAt: nowTime,
DeletedAt: nil,
}
err = item.SetTypes(param[i].TypesName)
if err != nil {
param[i].FailReason = "事故类型填写错误"
failRows = append(failRows, param[i])
continue
}
troubleDataList = append(troubleDataList, item)
}
if len(failRows) > 0 {
return failRows, nil
}
productTroubleRepo, _ := factory.CreateProductTroubleRepository(map[string]interface{}{
"transactionContext": transactionContext,
})
//添加事故数据
for i := range troubleDataList {
_, err = productTroubleRepo.Save(troubleDataList[i])
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
}
... ...
... ... @@ -25,14 +25,14 @@ type ProductTrouble struct {
}
// 事故类型
type TroubleType int
type TroubleType string
// 事故类型 1 安全事故 ,2 质量事故, 3 金属事故 ,4 非金属事故
const (
TroubleType1 TroubleType = 1
TroubleType2 TroubleType = 2
TroubleType3 TroubleType = 3
TroubleType4 TroubleType = 4
TroubleType1 TroubleType = "安全事故"
TroubleType2 TroubleType = "质量事故"
TroubleType3 TroubleType = "金属事故"
TroubleType4 TroubleType = "非金属事故"
)
// 事故管理 审核状态
... ... @@ -51,7 +51,7 @@ type ProductTroubleRepository interface {
Find(queryOptions map[string]interface{}) (int64, []*ProductTrouble, error)
}
func (m *ProductTrouble) SetTypes(v int) error {
func (m *ProductTrouble) SetTypes(v string) error {
troubleType := TroubleType(v)
switch troubleType {
case TroubleType1, TroubleType2, TroubleType3, TroubleType4:
... ...
... ... @@ -2,7 +2,7 @@ package domain
import "time"
//RewardStandard 奖惩规则
// RewardStandard 奖惩规则
type RewardRule struct {
Id int `json:"id"` //奖惩规则id
CompanyId int `json:"companyId"` //企业id
... ... @@ -14,6 +14,7 @@ type RewardRule struct {
FaultNum int `json:"faultNum"`
FaultAmount string `json:"faultAmount"`
Remark string `json:"remark"`
IsBackup int `json:"IsBackup"` //是否作为备份遗留的 0 否 1 是
CreatedAt time.Time
UpdatedAt time.Time
}
... ... @@ -41,3 +42,12 @@ func (m *RewardRule) ValidFaultTag() bool {
}
return true
}
// 编辑 奖惩标准时 ,是否需要将旧数据做备份处理
func (m *RewardRule) NeedMakeBackup() bool {
// 当前时间与 数据最后更新的时间 不是同一天时
// 备份数据
updateAt := m.UpdatedAt.Local().Format("2006-01-02")
nowDate := time.Now().Format("2006-01-02")
return !(updateAt == nowDate)
}
... ...
... ... @@ -7,7 +7,7 @@ import (
"time"
)
//RewardStandard 奖惩标准
// RewardStandard 奖惩标准
type RewardStandard struct {
Id int `json:"id"` //奖惩标准id
CompanyId int `json:"companyId"` //企业id
... ... @@ -16,6 +16,7 @@ type RewardStandard struct {
ProductLine SimpleProductLine `json:"productLine"` //生产线
ProductSection ProductSection `json:"ProductSection"` //工段
Remark string `json:"remark"` //备注
IsBackup int `json:"IsBackup"` //是否作为备份遗留的 0 否 1是
TargetType int `json:"targetType"` //指标类别 1:产效 2:合格率 3:安全事故 4:质量事故 5:异物次数
TargeVal1 string `json:"targeVal1"` //填写的指标值1
TargeVal2 string `json:"targeVal2"` //填写的指标值2
... ... @@ -44,7 +45,7 @@ type RewardStandardRepository interface {
Find(queryOptions map[string]interface{}) (int64, []*RewardStandard, error)
}
//指标类别 1:产效 2:合格率 3:安全事故 4:质量事故 5:异物次数
// 指标类别 1:产效 2:合格率 3:安全事故 4:质量事故 5:异物次数
const (
TargetType1 int = 1
TargetType2 int = 2
... ... @@ -53,7 +54,7 @@ const (
TargetType5 int = 5
)
//UpdateTarge 更新指标内容
// UpdateTarge 更新指标内容
func (m *RewardStandard) UpdateTarge(targetType int, targeVal1 string, targeVal2 string, targeVal3 string, targeVal4 string) error {
switch targetType {
case TargetType1, TargetType2:
... ... @@ -105,7 +106,7 @@ func (m *RewardStandard) UpdateTarge(targetType int, targeVal1 string, targeVal2
return nil
}
//TargetTypeName
// TargetTypeName
func (m *RewardStandard) TargetTypeName() string {
switch m.TargetType {
case TargetType1:
... ... @@ -122,7 +123,7 @@ func (m *RewardStandard) TargetTypeName() string {
return ""
}
//ShowTargeReward 功过指标描述,功劳
// ShowTargeReward 功过指标描述,功劳
func (m *RewardStandard) ShowTargeReward() string {
show := ""
switch m.TargetType {
... ... @@ -140,7 +141,7 @@ func (m *RewardStandard) ShowTargeReward() string {
return show
}
//ShowTargeFault 功过指标描述,过失
// ShowTargeFault 功过指标描述,过失
func (m *RewardStandard) ShowTargeFault() string {
show := ""
switch m.TargetType {
... ... @@ -157,3 +158,12 @@ func (m *RewardStandard) ShowTargeFault() string {
}
return show
}
// 编辑 奖惩标准时 ,是否需要将旧数据做备份处理
func (m *RewardStandard) NeedMakeBackup() bool {
// 当前时间与 数据最后更新的时间 不是同一天时
// 备份数据
updateAt := m.UpdatedAt.Local().Format("2006-01-02")
nowDate := time.Now().Format("2006-01-02")
return !(updateAt == nowDate)
}
... ...
... ... @@ -15,7 +15,7 @@ type ProductTrouble struct {
WorkStation domain.WorkStation // 工作位置
ProductWorker domain.User // 生产工人
AmountLoss float64 // 损失的金额
Types int // 事故类型
Types string // 事故类型
RecordData time.Time // 事故发生的日期
Remark string // 备注
ApproveStatus int // 审核状态 1:未审核 2:已审核 3.自动审核
... ...
... ... @@ -34,7 +34,7 @@ func (repo *ProductTroubleRepository) Save(param *domain.ProductTrouble) (*domai
WorkStation: param.WorkStation,
ProductWorker: param.ProductWorker,
AmountLoss: param.AmountLoss,
Types: int(param.Types),
Types: string(param.Types),
RecordData: param.RecordData,
Remark: param.Remark,
ApproveStatus: int(param.ApproveStatus),
... ...
... ... @@ -30,6 +30,7 @@ func (controller *ExcelDataController) responseExcelByFile(ctx *context.Context,
return nil
}
// FileImport 导入excel数据
func (controller *ExcelDataController) FileImport() {
var (
data interface{}
... ... @@ -55,6 +56,8 @@ func (controller *ExcelDataController) FileImport() {
// data, err = excelService.ImportCooperationUser(cmd)
//case domain.ImportOrganization:
// data, err = excelService.ImportOrganization(cmd)
case "ImportProductTrouble":
data, err = excelService.ImportProductTrouble(cmd)
case "ImportProductRecord":
data, err = excelService.ImportProductRecord(cmd)
case "ImportAttendance":
... ...