Merge branch 'feat/production-plan-collaboration' into 'main'
feat(production): add production management service with plan collaboration workflow See merge request kihaneseifu/muyu-apiserver!1
This commit is contained in:
commit
bb212aff36
@ -1,6 +1,7 @@
|
||||
stages:
|
||||
- build-1
|
||||
- build-2
|
||||
- build-3
|
||||
|
||||
variables:
|
||||
HARBOR_REGISTRY: harbor-in-k3s.cheverjohn.me
|
||||
@ -23,14 +24,18 @@ variables:
|
||||
- |
|
||||
if [ -n "$CI_COMMIT_TAG" ]; then
|
||||
TAG="$CI_COMMIT_TAG"
|
||||
else
|
||||
elif [ "$CI_COMMIT_BRANCH" = "main" ]; then
|
||||
TAG="main-${CI_COMMIT_SHORT_SHA}"
|
||||
else
|
||||
TAG="feat-${CI_COMMIT_SHORT_SHA}"
|
||||
fi
|
||||
- docker build --network host -t $HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$TAG -f $DOCKERFILE_PATH .
|
||||
- docker push $HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$TAG
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
- if: $CI_COMMIT_TAG =~ /^v/
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
- if: $CI_COMMIT_BRANCH =~ /^feat\//
|
||||
|
||||
build-muyu-gateway:
|
||||
<<: *build-template
|
||||
@ -52,3 +57,17 @@ build-muyu-inventory-rpc:
|
||||
variables:
|
||||
IMAGE_NAME: muyu-inventory-rpc
|
||||
DOCKERFILE_PATH: deploy/Dockerfile.inventory
|
||||
|
||||
build-muyu-purchase-rpc:
|
||||
<<: *build-template
|
||||
stage: build-2
|
||||
variables:
|
||||
IMAGE_NAME: muyu-purchase-rpc
|
||||
DOCKERFILE_PATH: deploy/Dockerfile.purchase
|
||||
|
||||
build-muyu-production-rpc:
|
||||
<<: *build-template
|
||||
stage: build-3
|
||||
variables:
|
||||
IMAGE_NAME: muyu-production-rpc
|
||||
DOCKERFILE_PATH: deploy/Dockerfile.production
|
||||
|
||||
21
deploy/Dockerfile.production
Normal file
21
deploy/Dockerfile.production
Normal file
@ -0,0 +1,21 @@
|
||||
ARG BASE_REGISTRY=harbor-in-k3s.cheverjohn.me/library
|
||||
FROM ${BASE_REGISTRY}/golang:1.24-alpine AS builder
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||
RUN apk add --no-cache git
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./rpc/production/production.go
|
||||
|
||||
FROM ${BASE_REGISTRY}/alpine:3.20
|
||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||
RUN apk add --no-cache ca-certificates tzdata gettext
|
||||
WORKDIR /app
|
||||
COPY --from=builder /server ./production
|
||||
COPY deploy/etc/production.yaml etc/production.yaml
|
||||
COPY deploy/entrypoint.sh /entrypoint.sh
|
||||
EXPOSE 9004
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
CMD ["./production", "-f", "etc/production.yaml"]
|
||||
@ -1,7 +1,19 @@
|
||||
FROM alpine:3.19
|
||||
ARG BASE_REGISTRY=harbor-in-k3s.cheverjohn.me/library
|
||||
FROM ${BASE_REGISTRY}/golang:1.24-alpine AS builder
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||
RUN apk add --no-cache git
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./rpc/purchase/purchase.go
|
||||
|
||||
FROM ${BASE_REGISTRY}/alpine:3.20
|
||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||
RUN apk add --no-cache ca-certificates tzdata gettext
|
||||
WORKDIR /app
|
||||
COPY deploy/bin/purchase .
|
||||
COPY --from=builder /server ./purchase
|
||||
COPY deploy/etc/purchase.yaml etc/purchase.yaml
|
||||
COPY deploy/entrypoint.sh /entrypoint.sh
|
||||
EXPOSE 9003
|
||||
|
||||
@ -126,6 +126,27 @@ services:
|
||||
TZ: Asia/Shanghai
|
||||
MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
|
||||
|
||||
production-rpc:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile.production
|
||||
container_name: muyu-production-rpc
|
||||
restart: always
|
||||
ports:
|
||||
- "9004:9004"
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
etcd:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./etc/production.yaml:/etc/muyu/production.yaml
|
||||
environment:
|
||||
TZ: Asia/Shanghai
|
||||
MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
|
||||
|
||||
gateway:
|
||||
build:
|
||||
context: ..
|
||||
@ -141,6 +162,8 @@ services:
|
||||
condition: service_started
|
||||
purchase-rpc:
|
||||
condition: service_started
|
||||
production-rpc:
|
||||
condition: service_started
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
|
||||
@ -34,6 +34,14 @@ PurchaseRpc:
|
||||
NonBlock: true
|
||||
Timeout: 60000
|
||||
|
||||
ProductionRpc:
|
||||
Etcd:
|
||||
Hosts:
|
||||
- etcd:2379
|
||||
Key: production.rpc
|
||||
NonBlock: true
|
||||
Timeout: 60000
|
||||
|
||||
Log:
|
||||
ServiceName: gateway-api
|
||||
Mode: console
|
||||
|
||||
17
deploy/etc/production.yaml
Normal file
17
deploy/etc/production.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
Name: production.rpc
|
||||
ListenOn: 0.0.0.0:9004
|
||||
|
||||
Etcd:
|
||||
Hosts:
|
||||
- etcd:2379
|
||||
Key: production.rpc
|
||||
|
||||
DataSource: ${MYSQL_DSN}
|
||||
|
||||
Cache:
|
||||
- Host: redis:6379
|
||||
|
||||
Log:
|
||||
ServiceName: production-rpc
|
||||
Mode: console
|
||||
Level: info
|
||||
79
deploy/mysql/migrations/20260629_phase3_e2e_validation.sql
Normal file
79
deploy/mysql/migrations/20260629_phase3_e2e_validation.sql
Normal file
@ -0,0 +1,79 @@
|
||||
-- End-to-End Validation Queries for Production Plan Collaboration
|
||||
-- Run these after testing the full flow to verify data consistency
|
||||
|
||||
-- 1. Verify production plan exists and has correct structure
|
||||
SELECT p.plan_id, p.plan_code, p.product_name, p.target_quantity,
|
||||
p.completed_quantity, p.status,
|
||||
ROUND(p.completed_quantity * 100.0 / NULLIF(p.target_quantity, 0), 1) as progress_pct
|
||||
FROM pro_production_plan p
|
||||
WHERE p.tenant_id = 'TEST_TENANT'
|
||||
ORDER BY p.created_at DESC LIMIT 5;
|
||||
|
||||
-- 2. Verify yarn ratios sum to 100%
|
||||
SELECT yr.plan_id,
|
||||
COUNT(*) as ratio_count,
|
||||
SUM(yr.ratio) as total_ratio,
|
||||
CASE WHEN ABS(SUM(yr.ratio) - 1.0) < 0.01 THEN 'OK' ELSE 'MISMATCH' END as check_result
|
||||
FROM pro_plan_yarn_ratio yr
|
||||
GROUP BY yr.plan_id;
|
||||
|
||||
-- 3. Verify process steps — each plan should have exactly 5 steps
|
||||
SELECT ps.plan_id,
|
||||
COUNT(*) as step_count,
|
||||
SUM(CASE WHEN ps.status = 2 THEN 1 ELSE 0 END) as completed_steps,
|
||||
CASE WHEN COUNT(*) = 5 THEN 'OK' ELSE 'MISSING_STEPS' END as check_result
|
||||
FROM pro_plan_process_step ps
|
||||
GROUP BY ps.plan_id;
|
||||
|
||||
-- 4. Verify share link lifecycle
|
||||
SELECT sl.short_code, sl.status, sl.click_count,
|
||||
sl.expires_at, NOW() as current_time,
|
||||
CASE WHEN sl.expires_at > NOW() THEN 'VALID' ELSE 'EXPIRED' END as expiry_check,
|
||||
pf.factory_tenant_id
|
||||
FROM pro_share_link sl
|
||||
LEFT JOIN pro_plan_factory pf ON pf.plan_id = sl.plan_id
|
||||
ORDER BY sl.created_at DESC LIMIT 5;
|
||||
|
||||
-- 5. CRITICAL: Verify data consistency — completed_quantity must equal SUM(inbound)
|
||||
SELECT p.plan_id, p.plan_code,
|
||||
p.completed_quantity as plan_completed,
|
||||
COALESCE(SUM(ir.quantity), 0) as inbound_sum,
|
||||
CASE
|
||||
WHEN ABS(p.completed_quantity - COALESCE(SUM(ir.quantity), 0)) < 0.01 THEN 'CONSISTENT'
|
||||
ELSE 'DRIFT_DETECTED'
|
||||
END as consistency_check
|
||||
FROM pro_production_plan p
|
||||
LEFT JOIN pro_inbound_record ir ON ir.plan_id = p.plan_id
|
||||
GROUP BY p.plan_id, p.plan_code, p.completed_quantity;
|
||||
|
||||
-- 6. Verify auto-completion: plans with completed_quantity >= target_quantity should be status=3
|
||||
SELECT p.plan_id, p.plan_code,
|
||||
p.target_quantity, p.completed_quantity, p.status,
|
||||
CASE
|
||||
WHEN p.completed_quantity >= p.target_quantity AND p.status != 3 THEN 'SHOULD_BE_COMPLETED'
|
||||
WHEN p.completed_quantity < p.target_quantity AND p.status = 3 THEN 'PREMATURE_COMPLETION'
|
||||
ELSE 'OK'
|
||||
END as auto_complete_check
|
||||
FROM pro_production_plan p
|
||||
WHERE p.status IN (2, 3);
|
||||
|
||||
-- 7. Verify inventory logs match inbound records
|
||||
SELECT ir.record_id, ir.quantity,
|
||||
il.change_qty, il.ref_type, il.ref_id,
|
||||
CASE
|
||||
WHEN il.log_id IS NULL THEN 'MISSING_LOG'
|
||||
WHEN ABS(ir.quantity - il.change_qty) < 0.01 THEN 'OK'
|
||||
ELSE 'QUANTITY_MISMATCH'
|
||||
END as log_check
|
||||
FROM pro_inbound_record ir
|
||||
LEFT JOIN inv_inventory_log il ON il.ref_id = ir.record_id AND il.ref_type = 'PRODUCTION';
|
||||
|
||||
-- 8. Summary report
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM pro_production_plan) as total_plans,
|
||||
(SELECT COUNT(*) FROM pro_production_plan WHERE status = 3) as completed_plans,
|
||||
(SELECT COUNT(*) FROM pro_share_link) as total_links,
|
||||
(SELECT COUNT(*) FROM pro_share_link WHERE status = 2) as confirmed_links,
|
||||
(SELECT COUNT(*) FROM pro_inbound_record) as total_inbound_records,
|
||||
(SELECT COALESCE(SUM(quantity), 0) FROM pro_inbound_record) as total_inbound_meters,
|
||||
(SELECT COUNT(*) FROM inv_inventory_log WHERE ref_type = 'PRODUCTION') as production_inv_logs;
|
||||
@ -0,0 +1,133 @@
|
||||
-- Phase 3: Production Plan Collaboration + Batch Inbound
|
||||
|
||||
-- ==================== Production Plan ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pro_production_plan` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`plan_id` VARCHAR(32) NOT NULL,
|
||||
`tenant_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`plan_code` VARCHAR(32) NOT NULL COMMENT 'PP-YYYYMMDD-XXXX',
|
||||
`product_id` VARCHAR(32) NOT NULL,
|
||||
`product_name` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`color` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`fabric_code` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`color_code` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
`target_quantity` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'target meters',
|
||||
`completed_quantity` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'completed meters = SUM(inbound)',
|
||||
`yarn_usage_per_meter` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'grams per meter',
|
||||
`production_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'yuan per meter',
|
||||
`supplier_id` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'pur_supplier.supplier_id as textile factory',
|
||||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:draft 1:pending 2:producing 3:completed 4:cancelled',
|
||||
`remark` TEXT,
|
||||
`start_time` DATETIME DEFAULT NULL,
|
||||
`creator` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`operator` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_plan_id` (`plan_id`),
|
||||
UNIQUE KEY `uk_plan_code_tenant` (`plan_code`, `tenant_id`),
|
||||
KEY `idx_tenant_status` (`tenant_id`, `status`),
|
||||
KEY `idx_product` (`product_id`),
|
||||
KEY `idx_supplier` (`supplier_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='生产计划';
|
||||
|
||||
-- ==================== Yarn Ratio ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pro_plan_yarn_ratio` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`ratio_id` VARCHAR(32) NOT NULL,
|
||||
`plan_id` VARCHAR(32) NOT NULL,
|
||||
`yarn_name` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`ratio` DECIMAL(5,2) NOT NULL DEFAULT 0.00 COMMENT '0.00-1.00',
|
||||
`amount_per_meter` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 'grams',
|
||||
`total_amount` DECIMAL(14,2) NOT NULL DEFAULT 0.00 COMMENT 'grams',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_ratio_id` (`ratio_id`),
|
||||
KEY `idx_plan` (`plan_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='纱线配比';
|
||||
|
||||
-- ==================== Process Step ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pro_plan_process_step` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`step_id` VARCHAR(32) NOT NULL,
|
||||
`plan_id` VARCHAR(32) NOT NULL,
|
||||
`step_type` VARCHAR(30) NOT NULL COMMENT 'confirm|yarn_purchase|dyeing|machine_start|fabric_warehouse',
|
||||
`step_order` TINYINT NOT NULL DEFAULT 0,
|
||||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:pending 1:in_progress 2:completed',
|
||||
`operator_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`completed_at` DATETIME DEFAULT NULL,
|
||||
`remark` TEXT,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_step_id` (`step_id`),
|
||||
UNIQUE KEY `uk_plan_step` (`plan_id`, `step_type`),
|
||||
KEY `idx_plan` (`plan_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='生产流程节点';
|
||||
|
||||
-- ==================== Share Link ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pro_share_link` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`link_id` VARCHAR(32) NOT NULL,
|
||||
`tenant_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`plan_id` VARCHAR(32) NOT NULL,
|
||||
`short_code` VARCHAR(16) NOT NULL,
|
||||
`token` VARCHAR(512) NOT NULL DEFAULT '',
|
||||
`factory_type` VARCHAR(20) NOT NULL DEFAULT 'textile',
|
||||
`hide_sensitive` TINYINT NOT NULL DEFAULT 0,
|
||||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:pending 1:clicked 2:confirmed 3:rejected 4:expired',
|
||||
`click_count` INT NOT NULL DEFAULT 0,
|
||||
`clicked_at` DATETIME DEFAULT NULL,
|
||||
`responded_at` DATETIME DEFAULT NULL,
|
||||
`reject_reason` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`expires_at` DATETIME NOT NULL,
|
||||
`created_by` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_link_id` (`link_id`),
|
||||
UNIQUE KEY `uk_short_code` (`short_code`),
|
||||
KEY `idx_plan` (`plan_id`),
|
||||
KEY `idx_tenant` (`tenant_id`),
|
||||
KEY `idx_status_expires` (`status`, `expires_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='分享链接';
|
||||
|
||||
-- ==================== Plan Factory ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pro_plan_factory` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`plan_id` VARCHAR(32) NOT NULL,
|
||||
`factory_tenant_id` VARCHAR(32) NOT NULL,
|
||||
`factory_type` VARCHAR(20) NOT NULL DEFAULT 'textile',
|
||||
`share_link_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_plan_factory` (`plan_id`, `factory_tenant_id`),
|
||||
KEY `idx_factory` (`factory_tenant_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='计划-工厂关联';
|
||||
|
||||
-- ==================== Inbound Record ====================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pro_inbound_record` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`record_id` VARCHAR(32) NOT NULL,
|
||||
`tenant_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`plan_id` VARCHAR(32) NOT NULL,
|
||||
`product_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`batch_no` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`quantity` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'meters',
|
||||
`rolls` INT NOT NULL DEFAULT 0,
|
||||
`price_per_meter` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`operator_id` VARCHAR(32) NOT NULL DEFAULT '',
|
||||
`remark` TEXT,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_record_id` (`record_id`),
|
||||
KEY `idx_plan` (`plan_id`),
|
||||
KEY `idx_tenant` (`tenant_id`),
|
||||
KEY `idx_product` (`product_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='按计划分批入库';
|
||||
@ -20,4 +20,5 @@ type Config struct {
|
||||
SystemRpc zrpc.RpcClientConf
|
||||
InventoryRpc zrpc.RpcClientConf
|
||||
PurchaseRpc zrpc.RpcClientConf
|
||||
ProductionRpc zrpc.RpcClientConf
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/inbound"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func CreateInboundHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayCreateInboundReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := inbound.NewCreateInboundLogic(r.Context(), svcCtx)
|
||||
resp, err := l.CreateInbound(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/inbound"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func ListInboundHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayListInboundReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := inbound.NewListInboundLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ListInbound(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/plan"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func ConfirmPlanHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ConfirmPlanReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := plan.NewConfirmPlanLogic(r.Context(), svcCtx)
|
||||
err := l.ConfirmPlan(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, types.IdResp{})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/plan"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func CreateProductionPlanHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CreateProductionPlanReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := plan.NewCreateProductionPlanLogic(r.Context(), svcCtx)
|
||||
resp, err := l.CreateProductionPlan(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"github.com/zeromicro/go-zero/rest/pathvar"
|
||||
"muyu-apiserver/gateway/internal/logic/production/plan"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func GetProductionPlanHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.WithValue(r.Context(), "pathId", pathvar.Vars(r)["planId"])
|
||||
l := plan.NewGetProductionPlanLogic(ctx, svcCtx)
|
||||
resp, err := l.GetProductionPlan()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/plan"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func ListProductionPlanHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ListProductionPlanReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := plan.NewListProductionPlanLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ListProductionPlan(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package process
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/process"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func CompleteStepHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayCompleteStepReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := process.NewCompleteStepLogic(r.Context(), svcCtx)
|
||||
err := l.CompleteStep(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, types.IdResp{})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/share"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func ClickShareLinkHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayClickShareLinkReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := share.NewClickShareLinkLogic(r.Context(), svcCtx)
|
||||
err := l.ClickShareLink(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, types.IdResp{})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/share"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func ConfirmShareLinkHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayConfirmShareLinkReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := share.NewConfirmShareLinkLogic(r.Context(), svcCtx)
|
||||
err := l.ConfirmShareLink(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, types.IdResp{})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/share"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func CreateShareLinkHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayCreateShareLinkReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := share.NewCreateShareLinkLogic(r.Context(), svcCtx)
|
||||
resp, err := l.CreateShareLink(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"github.com/zeromicro/go-zero/rest/pathvar"
|
||||
"muyu-apiserver/gateway/internal/logic/production/share"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func GetShareLinkPlanViewHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.WithValue(r.Context(), "pathId", pathvar.Vars(r)["shortCode"])
|
||||
l := share.NewGetShareLinkPlanViewLogic(ctx, svcCtx)
|
||||
resp, err := l.GetShareLinkPlanView()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"muyu-apiserver/gateway/internal/logic/production/share"
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
)
|
||||
|
||||
func RejectShareLinkHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GatewayRejectShareLinkReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := share.NewRejectShareLinkLogic(r.Context(), svcCtx)
|
||||
err := l.RejectShareLink(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, types.IdResp{})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,10 @@ import (
|
||||
inventorypanbolt "muyu-apiserver/gateway/internal/handler/inventory/panbolt"
|
||||
inventoryproduct "muyu-apiserver/gateway/internal/handler/inventory/product"
|
||||
inventorystock "muyu-apiserver/gateway/internal/handler/inventory/stock"
|
||||
productioninbound "muyu-apiserver/gateway/internal/handler/production/inbound"
|
||||
productionplan "muyu-apiserver/gateway/internal/handler/production/plan"
|
||||
productionprocess "muyu-apiserver/gateway/internal/handler/production/process"
|
||||
productionshare "muyu-apiserver/gateway/internal/handler/production/share"
|
||||
purchaseorder "muyu-apiserver/gateway/internal/handler/purchase/order"
|
||||
purchasepayment "muyu-apiserver/gateway/internal/handler/purchase/payment"
|
||||
purchasereceipt "muyu-apiserver/gateway/internal/handler/purchase/receipt"
|
||||
@ -634,4 +638,120 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/v1/inventory"),
|
||||
)
|
||||
|
||||
// ─── Production Plan (JWT + Authority) ──────────────────────────────────
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthorityMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/plan",
|
||||
Handler: productionplan.CreateProductionPlanHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/plan",
|
||||
Handler: productionplan.ListProductionPlanHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/plan/:planId",
|
||||
Handler: productionplan.GetProductionPlanHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/plan/confirm",
|
||||
Handler: productionplan.ConfirmPlanHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/v1/production"),
|
||||
)
|
||||
|
||||
// ─── Production Share (JWT + Authority) ─────────────────────────────────
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthorityMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/share",
|
||||
Handler: productionshare.CreateShareLinkHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/share/confirm",
|
||||
Handler: productionshare.ConfirmShareLinkHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/share/reject",
|
||||
Handler: productionshare.RejectShareLinkHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/v1/production"),
|
||||
)
|
||||
|
||||
// ─── Production Process (JWT + Authority) ───────────────────────────────
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthorityMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/process/step",
|
||||
Handler: productionprocess.CompleteStepHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/v1/production"),
|
||||
)
|
||||
|
||||
// ─── Production Inbound (JWT + Authority) ───────────────────────────────
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthorityMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/inbound",
|
||||
Handler: productioninbound.CreateInboundHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/inbound",
|
||||
Handler: productioninbound.ListInboundHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/v1/production"),
|
||||
)
|
||||
|
||||
// ─── Production Public Share (NO JWT) ───────────────────────────────────
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/share/:shortCode",
|
||||
Handler: productionshare.GetShareLinkPlanViewHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/share/click",
|
||||
Handler: productionshare.ClickShareLinkHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/v1/public/production"),
|
||||
)
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CreateInboundLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewCreateInboundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateInboundLogic {
|
||||
return &CreateInboundLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CreateInboundLogic) CreateInbound(req *types.GatewayCreateInboundReq) (*types.IdResp, error) {
|
||||
resp, err := l.svcCtx.ProductionRpc.CreateInbound(l.ctx, &productionservice.CreateInboundReq{
|
||||
PlanId: req.PlanId,
|
||||
ProductId: req.ProductId,
|
||||
BatchNo: req.BatchNo,
|
||||
Quantity: req.Quantity,
|
||||
Rolls: req.Rolls,
|
||||
PricePerMeter: req.PricePerMeter,
|
||||
OperatorId: ctxdata.GetUserId(l.ctx),
|
||||
Remark: req.Remark,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.IdResp{Id: resp.Id}, nil
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListInboundLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewListInboundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListInboundLogic {
|
||||
return &ListInboundLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ListInboundLogic) ListInbound(req *types.GatewayListInboundReq) (*types.ListInboundResp, error) {
|
||||
rpcResp, err := l.svcCtx.ProductionRpc.ListInbound(l.ctx, &productionservice.ListInboundReq{
|
||||
PlanId: req.PlanId,
|
||||
Page: req.Page,
|
||||
PageSize: req.PageSize,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := make([]types.InboundRecordInfo, 0, len(rpcResp.List))
|
||||
for _, ir := range rpcResp.List {
|
||||
list = append(list, types.InboundRecordInfo{
|
||||
RecordId: ir.RecordId,
|
||||
TenantId: ir.TenantId,
|
||||
PlanId: ir.PlanId,
|
||||
ProductId: ir.ProductId,
|
||||
BatchNo: ir.BatchNo,
|
||||
Quantity: ir.Quantity,
|
||||
Rolls: ir.Rolls,
|
||||
PricePerMeter: ir.PricePerMeter,
|
||||
OperatorId: ir.OperatorId,
|
||||
Remark: ir.Remark,
|
||||
CreatedAt: ir.CreatedAt,
|
||||
})
|
||||
}
|
||||
return &types.ListInboundResp{Total: rpcResp.Total, List: list}, nil
|
||||
}
|
||||
34
gateway/internal/logic/production/plan/confirmplanlogic.go
Normal file
34
gateway/internal/logic/production/plan/confirmplanlogic.go
Normal file
@ -0,0 +1,34 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ConfirmPlanLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewConfirmPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmPlanLogic {
|
||||
return &ConfirmPlanLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ConfirmPlanLogic) ConfirmPlan(req *types.ConfirmPlanReq) error {
|
||||
_, err := l.svcCtx.ProductionRpc.ConfirmPlan(l.ctx, &productionservice.ConfirmPlanReq{
|
||||
PlanId: req.PlanId,
|
||||
Operator: ctxdata.GetUserId(l.ctx),
|
||||
})
|
||||
return err
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CreateProductionPlanLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewCreateProductionPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateProductionPlanLogic {
|
||||
return &CreateProductionPlanLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CreateProductionPlanLogic) CreateProductionPlan(req *types.CreateProductionPlanReq) (*types.IdResp, error) {
|
||||
yarnRatios := make([]*productionservice.YarnRatioReq, 0, len(req.YarnRatios))
|
||||
for _, yr := range req.YarnRatios {
|
||||
yarnRatios = append(yarnRatios, &productionservice.YarnRatioReq{
|
||||
YarnName: yr.YarnName,
|
||||
Ratio: yr.Ratio,
|
||||
AmountPerMeter: yr.AmountPerMeter,
|
||||
TotalAmount: yr.TotalAmount,
|
||||
})
|
||||
}
|
||||
|
||||
processSteps := make([]*productionservice.ProcessStepReq, 0, len(req.ProcessSteps))
|
||||
for _, ps := range req.ProcessSteps {
|
||||
processSteps = append(processSteps, &productionservice.ProcessStepReq{
|
||||
StepType: ps.StepType,
|
||||
StepOrder: ps.StepOrder,
|
||||
Remark: ps.Remark,
|
||||
})
|
||||
}
|
||||
|
||||
resp, err := l.svcCtx.ProductionRpc.CreateProductionPlan(l.ctx, &productionservice.CreateProductionPlanReq{
|
||||
ProductId: req.ProductId,
|
||||
ProductName: req.ProductName,
|
||||
Color: req.Color,
|
||||
FabricCode: req.FabricCode,
|
||||
ColorCode: req.ColorCode,
|
||||
TargetQuantity: req.TargetQuantity,
|
||||
YarnUsagePerMeter: req.YarnUsagePerMeter,
|
||||
ProductionPrice: req.ProductionPrice,
|
||||
SupplierId: req.SupplierId,
|
||||
Remark: req.Remark,
|
||||
StartTime: req.StartTime,
|
||||
Creator: ctxdata.GetUserId(l.ctx),
|
||||
YarnRatios: yarnRatios,
|
||||
ProcessSteps: processSteps,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.IdResp{Id: resp.Id}, nil
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetProductionPlanLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetProductionPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductionPlanLogic {
|
||||
return &GetProductionPlanLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetProductionPlanLogic) GetProductionPlan() (*types.ProductionPlanInfo, error) {
|
||||
planId := ctxdata.GetPathId(l.ctx)
|
||||
resp, err := l.svcCtx.ProductionRpc.GetProductionPlan(l.ctx, &productionservice.GetProductionPlanReq{
|
||||
PlanId: planId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return productionPlanInfoFromPB(resp), nil
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListProductionPlanLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewListProductionPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListProductionPlanLogic {
|
||||
return &ListProductionPlanLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ListProductionPlanLogic) ListProductionPlan(req *types.ListProductionPlanReq) (*types.ListProductionPlanResp, error) {
|
||||
rpcResp, err := l.svcCtx.ProductionRpc.ListProductionPlan(l.ctx, &productionservice.ListProductionPlanReq{
|
||||
Page: req.Page,
|
||||
PageSize: req.PageSize,
|
||||
Status: req.Status,
|
||||
ProductName: req.ProductName,
|
||||
PlanCode: req.PlanCode,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := make([]types.ProductionPlanInfo, 0, len(rpcResp.List))
|
||||
for _, p := range rpcResp.List {
|
||||
list = append(list, *productionPlanInfoFromPB(p))
|
||||
}
|
||||
return &types.ListProductionPlanResp{Total: rpcResp.Total, List: list}, nil
|
||||
}
|
||||
|
||||
func productionPlanInfoFromPB(p *productionservice.ProductionPlanInfo) *types.ProductionPlanInfo {
|
||||
if p == nil {
|
||||
return &types.ProductionPlanInfo{}
|
||||
}
|
||||
|
||||
yarnRatios := make([]types.YarnRatioInfo, 0, len(p.YarnRatios))
|
||||
for _, yr := range p.YarnRatios {
|
||||
yarnRatios = append(yarnRatios, types.YarnRatioInfo{
|
||||
RatioId: yr.RatioId,
|
||||
PlanId: yr.PlanId,
|
||||
YarnName: yr.YarnName,
|
||||
Ratio: yr.Ratio,
|
||||
AmountPerMeter: yr.AmountPerMeter,
|
||||
TotalAmount: yr.TotalAmount,
|
||||
CreatedAt: yr.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
processSteps := make([]types.ProcessStepInfo, 0, len(p.ProcessSteps))
|
||||
for _, ps := range p.ProcessSteps {
|
||||
processSteps = append(processSteps, types.ProcessStepInfo{
|
||||
StepId: ps.StepId,
|
||||
PlanId: ps.PlanId,
|
||||
StepType: ps.StepType,
|
||||
StepOrder: ps.StepOrder,
|
||||
Status: ps.Status,
|
||||
OperatorId: ps.OperatorId,
|
||||
CompletedAt: ps.CompletedAt,
|
||||
Remark: ps.Remark,
|
||||
CreatedAt: ps.CreatedAt,
|
||||
UpdatedAt: ps.UpdatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
inboundRecords := make([]types.InboundRecordInfo, 0, len(p.InboundRecords))
|
||||
for _, ir := range p.InboundRecords {
|
||||
inboundRecords = append(inboundRecords, types.InboundRecordInfo{
|
||||
RecordId: ir.RecordId,
|
||||
TenantId: ir.TenantId,
|
||||
PlanId: ir.PlanId,
|
||||
ProductId: ir.ProductId,
|
||||
BatchNo: ir.BatchNo,
|
||||
Quantity: ir.Quantity,
|
||||
Rolls: ir.Rolls,
|
||||
PricePerMeter: ir.PricePerMeter,
|
||||
OperatorId: ir.OperatorId,
|
||||
Remark: ir.Remark,
|
||||
CreatedAt: ir.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return &types.ProductionPlanInfo{
|
||||
PlanId: p.PlanId,
|
||||
TenantId: p.TenantId,
|
||||
PlanCode: p.PlanCode,
|
||||
ProductId: p.ProductId,
|
||||
ProductName: p.ProductName,
|
||||
Color: p.Color,
|
||||
FabricCode: p.FabricCode,
|
||||
ColorCode: p.ColorCode,
|
||||
TargetQuantity: p.TargetQuantity,
|
||||
CompletedQuantity: p.CompletedQuantity,
|
||||
YarnUsagePerMeter: p.YarnUsagePerMeter,
|
||||
ProductionPrice: p.ProductionPrice,
|
||||
SupplierId: p.SupplierId,
|
||||
Status: p.Status,
|
||||
Remark: p.Remark,
|
||||
StartTime: p.StartTime,
|
||||
Creator: p.Creator,
|
||||
Operator: p.Operator,
|
||||
CreatedAt: p.CreatedAt,
|
||||
UpdatedAt: p.UpdatedAt,
|
||||
YarnRatios: yarnRatios,
|
||||
ProcessSteps: processSteps,
|
||||
InboundRecords: inboundRecords,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package process
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CompleteStepLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewCompleteStepLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CompleteStepLogic {
|
||||
return &CompleteStepLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CompleteStepLogic) CompleteStep(req *types.GatewayCompleteStepReq) error {
|
||||
_, err := l.svcCtx.ProductionRpc.CompleteStep(l.ctx, &productionservice.CompleteStepReq{
|
||||
PlanId: req.PlanId,
|
||||
StepType: req.StepType,
|
||||
OperatorId: ctxdata.GetUserId(l.ctx),
|
||||
})
|
||||
return err
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ClickShareLinkLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewClickShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ClickShareLinkLogic {
|
||||
return &ClickShareLinkLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ClickShareLinkLogic) ClickShareLink(req *types.GatewayClickShareLinkReq) error {
|
||||
_, err := l.svcCtx.ProductionRpc.ClickShareLink(l.ctx, &productionservice.ClickShareLinkReq{
|
||||
ShortCode: req.ShortCode,
|
||||
})
|
||||
return err
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ConfirmShareLinkLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewConfirmShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmShareLinkLogic {
|
||||
return &ConfirmShareLinkLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ConfirmShareLinkLogic) ConfirmShareLink(req *types.GatewayConfirmShareLinkReq) error {
|
||||
_, err := l.svcCtx.ProductionRpc.ConfirmShareLink(l.ctx, &productionservice.ConfirmShareLinkReq{
|
||||
ShortCode: req.ShortCode,
|
||||
Token: req.Token,
|
||||
FactoryTenantId: ctxdata.GetTenantId(l.ctx),
|
||||
})
|
||||
return err
|
||||
}
|
||||
108
gateway/internal/logic/production/share/convert.go
Normal file
108
gateway/internal/logic/production/share/convert.go
Normal file
@ -0,0 +1,108 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
)
|
||||
|
||||
func productionPlanInfoFromPB(p *productionservice.ProductionPlanInfo) *types.ProductionPlanInfo {
|
||||
if p == nil {
|
||||
return &types.ProductionPlanInfo{}
|
||||
}
|
||||
|
||||
yarnRatios := make([]types.YarnRatioInfo, 0, len(p.YarnRatios))
|
||||
for _, yr := range p.YarnRatios {
|
||||
yarnRatios = append(yarnRatios, types.YarnRatioInfo{
|
||||
RatioId: yr.RatioId,
|
||||
PlanId: yr.PlanId,
|
||||
YarnName: yr.YarnName,
|
||||
Ratio: yr.Ratio,
|
||||
AmountPerMeter: yr.AmountPerMeter,
|
||||
TotalAmount: yr.TotalAmount,
|
||||
CreatedAt: yr.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
processSteps := make([]types.ProcessStepInfo, 0, len(p.ProcessSteps))
|
||||
for _, ps := range p.ProcessSteps {
|
||||
processSteps = append(processSteps, types.ProcessStepInfo{
|
||||
StepId: ps.StepId,
|
||||
PlanId: ps.PlanId,
|
||||
StepType: ps.StepType,
|
||||
StepOrder: ps.StepOrder,
|
||||
Status: ps.Status,
|
||||
OperatorId: ps.OperatorId,
|
||||
CompletedAt: ps.CompletedAt,
|
||||
Remark: ps.Remark,
|
||||
CreatedAt: ps.CreatedAt,
|
||||
UpdatedAt: ps.UpdatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
inboundRecords := make([]types.InboundRecordInfo, 0, len(p.InboundRecords))
|
||||
for _, ir := range p.InboundRecords {
|
||||
inboundRecords = append(inboundRecords, types.InboundRecordInfo{
|
||||
RecordId: ir.RecordId,
|
||||
TenantId: ir.TenantId,
|
||||
PlanId: ir.PlanId,
|
||||
ProductId: ir.ProductId,
|
||||
BatchNo: ir.BatchNo,
|
||||
Quantity: ir.Quantity,
|
||||
Rolls: ir.Rolls,
|
||||
PricePerMeter: ir.PricePerMeter,
|
||||
OperatorId: ir.OperatorId,
|
||||
Remark: ir.Remark,
|
||||
CreatedAt: ir.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return &types.ProductionPlanInfo{
|
||||
PlanId: p.PlanId,
|
||||
TenantId: p.TenantId,
|
||||
PlanCode: p.PlanCode,
|
||||
ProductId: p.ProductId,
|
||||
ProductName: p.ProductName,
|
||||
Color: p.Color,
|
||||
FabricCode: p.FabricCode,
|
||||
ColorCode: p.ColorCode,
|
||||
TargetQuantity: p.TargetQuantity,
|
||||
CompletedQuantity: p.CompletedQuantity,
|
||||
YarnUsagePerMeter: p.YarnUsagePerMeter,
|
||||
ProductionPrice: p.ProductionPrice,
|
||||
SupplierId: p.SupplierId,
|
||||
Status: p.Status,
|
||||
Remark: p.Remark,
|
||||
StartTime: p.StartTime,
|
||||
Creator: p.Creator,
|
||||
Operator: p.Operator,
|
||||
CreatedAt: p.CreatedAt,
|
||||
UpdatedAt: p.UpdatedAt,
|
||||
YarnRatios: yarnRatios,
|
||||
ProcessSteps: processSteps,
|
||||
InboundRecords: inboundRecords,
|
||||
}
|
||||
}
|
||||
|
||||
func shareLinkInfoFromPB(s *productionservice.ShareLinkInfo) *types.ShareLinkInfoResp {
|
||||
if s == nil {
|
||||
return &types.ShareLinkInfoResp{}
|
||||
}
|
||||
return &types.ShareLinkInfoResp{
|
||||
LinkId: s.LinkId,
|
||||
TenantId: s.TenantId,
|
||||
PlanId: s.PlanId,
|
||||
ShortCode: s.ShortCode,
|
||||
Token: s.Token,
|
||||
FactoryType: s.FactoryType,
|
||||
HideSensitive: s.HideSensitive,
|
||||
Status: s.Status,
|
||||
ClickCount: s.ClickCount,
|
||||
ClickedAt: s.ClickedAt,
|
||||
RespondedAt: s.RespondedAt,
|
||||
RejectReason: s.RejectReason,
|
||||
ExpiresAt: s.ExpiresAt,
|
||||
CreatedBy: s.CreatedBy,
|
||||
CreatedAt: s.CreatedAt,
|
||||
UpdatedAt: s.UpdatedAt,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CreateShareLinkLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewCreateShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateShareLinkLogic {
|
||||
return &CreateShareLinkLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CreateShareLinkLogic) CreateShareLink(req *types.GatewayCreateShareLinkReq) (*types.ShareLinkInfoResp, error) {
|
||||
resp, err := l.svcCtx.ProductionRpc.CreateShareLink(l.ctx, &productionservice.CreateShareLinkReq{
|
||||
PlanId: req.PlanId,
|
||||
FactoryType: req.FactoryType,
|
||||
HideSensitive: req.HideSensitive,
|
||||
ExpiresHours: req.ExpiresHours,
|
||||
CreatedBy: ctxdata.GetUserId(l.ctx),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return shareLinkInfoFromPB(resp), nil
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/pkg/ctxdata"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetShareLinkPlanViewLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetShareLinkPlanViewLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetShareLinkPlanViewLogic {
|
||||
return &GetShareLinkPlanViewLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetShareLinkPlanViewLogic) GetShareLinkPlanView() (*types.ShareLinkPlanViewResp, error) {
|
||||
shortCode := ctxdata.GetPathId(l.ctx)
|
||||
resp, err := l.svcCtx.ProductionRpc.GetShareLinkPlanView(l.ctx, &productionservice.GetShareLinkReq{
|
||||
ShortCode: shortCode,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &types.ShareLinkPlanViewResp{}
|
||||
if resp.Plan != nil {
|
||||
plan := productionPlanInfoFromPB(resp.Plan)
|
||||
result.Plan = plan
|
||||
}
|
||||
if resp.Link != nil {
|
||||
result.Link = shareLinkInfoFromPB(resp.Link)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package share
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/gateway/internal/svc"
|
||||
"muyu-apiserver/gateway/internal/types"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type RejectShareLinkLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewRejectShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RejectShareLinkLogic {
|
||||
return &RejectShareLinkLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RejectShareLinkLogic) RejectShareLink(req *types.GatewayRejectShareLinkReq) error {
|
||||
_, err := l.svcCtx.ProductionRpc.RejectShareLink(l.ctx, &productionservice.RejectShareLinkReq{
|
||||
ShortCode: req.ShortCode,
|
||||
Token: req.Token,
|
||||
RejectReason: req.RejectReason,
|
||||
})
|
||||
return err
|
||||
}
|
||||
@ -13,6 +13,7 @@ import (
|
||||
pkgcasbin "muyu-apiserver/pkg/casbin"
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/rpc/inventory/inventoryservice"
|
||||
"muyu-apiserver/rpc/production/productionservice"
|
||||
"muyu-apiserver/rpc/purchase/purchaseservice"
|
||||
"muyu-apiserver/rpc/system/systemservice"
|
||||
)
|
||||
@ -25,6 +26,7 @@ type ServiceContext struct {
|
||||
SystemRpc systemservice.SystemService
|
||||
InventoryRpc inventoryservice.InventoryService
|
||||
PurchaseRpc purchaseservice.PurchaseService
|
||||
ProductionRpc productionservice.ProductionService
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@ -62,5 +64,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
SystemRpc: systemservice.NewSystemService(zrpc.MustNewClient(c.SystemRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))),
|
||||
InventoryRpc: inventoryservice.NewInventoryService(zrpc.MustNewClient(c.InventoryRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))),
|
||||
PurchaseRpc: purchaseservice.NewPurchaseService(zrpc.MustNewClient(c.PurchaseRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))),
|
||||
ProductionRpc: productionservice.NewProductionService(zrpc.MustNewClient(c.ProductionRpc, zrpc.WithUnaryClientInterceptor(tenantctx.UnaryClientInterceptor()))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,3 +859,192 @@ type PurchaseStatsByProductItem struct {
|
||||
type PurchaseStatsByProductResp struct {
|
||||
List []PurchaseStatsByProductItem `json:"list"`
|
||||
}
|
||||
|
||||
// ─── Production Plan ────────────────────────────────────────────────────────
|
||||
|
||||
type GatewayYarnRatioReq struct {
|
||||
YarnName string `json:"yarnName"`
|
||||
Ratio string `json:"ratio"`
|
||||
AmountPerMeter string `json:"amountPerMeter,optional"`
|
||||
TotalAmount string `json:"totalAmount,optional"`
|
||||
}
|
||||
|
||||
type GatewayProcessStepReq struct {
|
||||
StepType string `json:"stepType"`
|
||||
StepOrder int64 `json:"stepOrder"`
|
||||
Remark string `json:"remark,optional"`
|
||||
}
|
||||
|
||||
type CreateProductionPlanReq struct {
|
||||
ProductId string `json:"productId"`
|
||||
ProductName string `json:"productName"`
|
||||
Color string `json:"color,optional"`
|
||||
FabricCode string `json:"fabricCode,optional"`
|
||||
ColorCode string `json:"colorCode,optional"`
|
||||
TargetQuantity string `json:"targetQuantity"`
|
||||
YarnUsagePerMeter string `json:"yarnUsagePerMeter,optional"`
|
||||
ProductionPrice string `json:"productionPrice,optional"`
|
||||
SupplierId string `json:"supplierId,optional"`
|
||||
Remark string `json:"remark,optional"`
|
||||
StartTime string `json:"startTime,optional"`
|
||||
YarnRatios []GatewayYarnRatioReq `json:"yarnRatios,optional"`
|
||||
ProcessSteps []GatewayProcessStepReq `json:"processSteps,optional"`
|
||||
}
|
||||
|
||||
type ListProductionPlanReq struct {
|
||||
Page int64 `form:"page,default=1"`
|
||||
PageSize int64 `form:"pageSize,default=20"`
|
||||
Status int64 `form:"status,optional,default=-1"`
|
||||
ProductName string `form:"productName,optional"`
|
||||
PlanCode string `form:"planCode,optional"`
|
||||
}
|
||||
|
||||
type YarnRatioInfo struct {
|
||||
RatioId string `json:"ratioId"`
|
||||
PlanId string `json:"planId"`
|
||||
YarnName string `json:"yarnName"`
|
||||
Ratio string `json:"ratio"`
|
||||
AmountPerMeter string `json:"amountPerMeter"`
|
||||
TotalAmount string `json:"totalAmount"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
type ProcessStepInfo struct {
|
||||
StepId string `json:"stepId"`
|
||||
PlanId string `json:"planId"`
|
||||
StepType string `json:"stepType"`
|
||||
StepOrder int64 `json:"stepOrder"`
|
||||
Status int64 `json:"status"`
|
||||
OperatorId string `json:"operatorId"`
|
||||
CompletedAt string `json:"completedAt"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type InboundRecordInfo struct {
|
||||
RecordId string `json:"recordId"`
|
||||
TenantId string `json:"tenantId"`
|
||||
PlanId string `json:"planId"`
|
||||
ProductId string `json:"productId"`
|
||||
BatchNo string `json:"batchNo"`
|
||||
Quantity string `json:"quantity"`
|
||||
Rolls int64 `json:"rolls"`
|
||||
PricePerMeter string `json:"pricePerMeter"`
|
||||
OperatorId string `json:"operatorId"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
type ProductionPlanInfo struct {
|
||||
PlanId string `json:"planId"`
|
||||
TenantId string `json:"tenantId"`
|
||||
PlanCode string `json:"planCode"`
|
||||
ProductId string `json:"productId"`
|
||||
ProductName string `json:"productName"`
|
||||
Color string `json:"color"`
|
||||
FabricCode string `json:"fabricCode"`
|
||||
ColorCode string `json:"colorCode"`
|
||||
TargetQuantity string `json:"targetQuantity"`
|
||||
CompletedQuantity string `json:"completedQuantity"`
|
||||
YarnUsagePerMeter string `json:"yarnUsagePerMeter"`
|
||||
ProductionPrice string `json:"productionPrice"`
|
||||
SupplierId string `json:"supplierId"`
|
||||
Status int64 `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
StartTime string `json:"startTime"`
|
||||
Creator string `json:"creator"`
|
||||
Operator string `json:"operator"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
YarnRatios []YarnRatioInfo `json:"yarnRatios"`
|
||||
ProcessSteps []ProcessStepInfo `json:"processSteps"`
|
||||
InboundRecords []InboundRecordInfo `json:"inboundRecords"`
|
||||
}
|
||||
|
||||
type ListProductionPlanResp struct {
|
||||
Total int64 `json:"total"`
|
||||
List []ProductionPlanInfo `json:"list"`
|
||||
}
|
||||
|
||||
type ConfirmPlanReq struct {
|
||||
PlanId string `json:"planId"`
|
||||
}
|
||||
|
||||
// ─── Share Link ─────────────────────────────────────────────────────────────
|
||||
|
||||
type GatewayCreateShareLinkReq struct {
|
||||
PlanId string `json:"planId"`
|
||||
FactoryType string `json:"factoryType,optional"`
|
||||
HideSensitive int64 `json:"hideSensitive,optional"`
|
||||
ExpiresHours int64 `json:"expiresHours,optional"`
|
||||
}
|
||||
|
||||
type ShareLinkInfoResp struct {
|
||||
LinkId string `json:"linkId"`
|
||||
TenantId string `json:"tenantId"`
|
||||
PlanId string `json:"planId"`
|
||||
ShortCode string `json:"shortCode"`
|
||||
Token string `json:"token"`
|
||||
FactoryType string `json:"factoryType"`
|
||||
HideSensitive int64 `json:"hideSensitive"`
|
||||
Status int64 `json:"status"`
|
||||
ClickCount int64 `json:"clickCount"`
|
||||
ClickedAt string `json:"clickedAt"`
|
||||
RespondedAt string `json:"respondedAt"`
|
||||
RejectReason string `json:"rejectReason"`
|
||||
ExpiresAt string `json:"expiresAt"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type ShareLinkPlanViewResp struct {
|
||||
Plan *ProductionPlanInfo `json:"plan"`
|
||||
Link *ShareLinkInfoResp `json:"link"`
|
||||
}
|
||||
|
||||
type GatewayConfirmShareLinkReq struct {
|
||||
ShortCode string `json:"shortCode"`
|
||||
Token string `json:"token,optional"`
|
||||
}
|
||||
|
||||
type GatewayRejectShareLinkReq struct {
|
||||
ShortCode string `json:"shortCode"`
|
||||
Token string `json:"token,optional"`
|
||||
RejectReason string `json:"rejectReason,optional"`
|
||||
}
|
||||
|
||||
type GatewayClickShareLinkReq struct {
|
||||
ShortCode string `json:"shortCode"`
|
||||
}
|
||||
|
||||
// ─── Process Step ───────────────────────────────────────────────────────────
|
||||
|
||||
type GatewayCompleteStepReq struct {
|
||||
PlanId string `json:"planId"`
|
||||
StepType string `json:"stepType"`
|
||||
}
|
||||
|
||||
// ─── Inbound ────────────────────────────────────────────────────────────────
|
||||
|
||||
type GatewayCreateInboundReq struct {
|
||||
PlanId string `json:"planId"`
|
||||
ProductId string `json:"productId"`
|
||||
BatchNo string `json:"batchNo,optional"`
|
||||
Quantity string `json:"quantity"`
|
||||
Rolls int64 `json:"rolls,optional"`
|
||||
PricePerMeter string `json:"pricePerMeter,optional"`
|
||||
Remark string `json:"remark,optional"`
|
||||
}
|
||||
|
||||
type GatewayListInboundReq struct {
|
||||
PlanId string `form:"planId,optional"`
|
||||
Page int64 `form:"page,default=1"`
|
||||
PageSize int64 `form:"pageSize,default=20"`
|
||||
}
|
||||
|
||||
type ListInboundResp struct {
|
||||
Total int64 `json:"total"`
|
||||
List []InboundRecordInfo `json:"list"`
|
||||
}
|
||||
|
||||
56
model/proinboundrecordmodel.go
Normal file
56
model/proinboundrecordmodel.go
Normal file
@ -0,0 +1,56 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ ProInboundRecordModel = (*customProInboundRecordModel)(nil)
|
||||
|
||||
type (
|
||||
ProInboundRecordModel interface {
|
||||
proInboundRecordModel
|
||||
FindByPlanId(ctx context.Context, planId string, page, pageSize int64) ([]*ProInboundRecord, int64, error)
|
||||
SumQuantityByPlan(ctx context.Context, planId string) (float64, int64, error)
|
||||
}
|
||||
|
||||
customProInboundRecordModel struct {
|
||||
*defaultProInboundRecordModel
|
||||
}
|
||||
)
|
||||
|
||||
func NewProInboundRecordModel(conn sqlx.SqlConn) ProInboundRecordModel {
|
||||
return &customProInboundRecordModel{
|
||||
defaultProInboundRecordModel: newProInboundRecordModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customProInboundRecordModel) FindByPlanId(ctx context.Context, planId string, page, pageSize int64) ([]*ProInboundRecord, int64, error) {
|
||||
var total int64
|
||||
countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE plan_id = ?", m.table)
|
||||
if err := m.conn.QueryRowCtx(ctx, &total, countQuery, planId); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var list []*ProInboundRecord
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE plan_id = ? ORDER BY created_at DESC LIMIT ? OFFSET ?",
|
||||
proInboundRecordRows, m.table)
|
||||
if err := m.conn.QueryRowsCtx(ctx, &list, query, planId, pageSize, (page-1)*pageSize); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (m *customProInboundRecordModel) SumQuantityByPlan(ctx context.Context, planId string) (float64, int64, error) {
|
||||
var result struct {
|
||||
TotalQty float64 `db:"total_qty"`
|
||||
TotalRolls int64 `db:"total_rolls"`
|
||||
}
|
||||
query := fmt.Sprintf("SELECT COALESCE(SUM(quantity),0) as total_qty, COALESCE(SUM(rolls),0) as total_rolls FROM %s WHERE plan_id = ?", m.table)
|
||||
if err := m.conn.QueryRowCtx(ctx, &result, query, planId); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return result.TotalQty, result.TotalRolls, nil
|
||||
}
|
||||
57
model/proinboundrecordmodel_gen.go
Normal file
57
model/proinboundrecordmodel_gen.go
Normal file
@ -0,0 +1,57 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
proInboundRecordFieldNames = builder.RawFieldNames(&ProInboundRecord{})
|
||||
proInboundRecordRows = strings.Join(proInboundRecordFieldNames, ",")
|
||||
proInboundRecordRowsExpectAutoSet = strings.Join(stringx.Remove(proInboundRecordFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
)
|
||||
|
||||
type (
|
||||
proInboundRecordModel interface {
|
||||
Insert(ctx context.Context, data *ProInboundRecord) (sql.Result, error)
|
||||
}
|
||||
|
||||
defaultProInboundRecordModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
ProInboundRecord struct {
|
||||
Id int64 `db:"id"`
|
||||
RecordId string `db:"record_id"`
|
||||
TenantId string `db:"tenant_id"`
|
||||
PlanId string `db:"plan_id"`
|
||||
ProductId string `db:"product_id"`
|
||||
BatchNo string `db:"batch_no"`
|
||||
Quantity float64 `db:"quantity"`
|
||||
Rolls int64 `db:"rolls"`
|
||||
PricePerMeter float64 `db:"price_per_meter"`
|
||||
OperatorId string `db:"operator_id"`
|
||||
Remark sql.NullString `db:"remark"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func newProInboundRecordModel(conn sqlx.SqlConn) *defaultProInboundRecordModel {
|
||||
return &defaultProInboundRecordModel{conn: conn, table: "`pro_inbound_record`"}
|
||||
}
|
||||
|
||||
func (m *defaultProInboundRecordModel) Insert(ctx context.Context, data *ProInboundRecord) (sql.Result, error) {
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
m.table, proInboundRecordRowsExpectAutoSet)
|
||||
return m.conn.ExecCtx(ctx, query, data.RecordId, data.TenantId, data.PlanId,
|
||||
data.ProductId, data.BatchNo, data.Quantity, data.Rolls,
|
||||
data.PricePerMeter, data.OperatorId, data.Remark)
|
||||
}
|
||||
36
model/proplanfactorymodel.go
Normal file
36
model/proplanfactorymodel.go
Normal file
@ -0,0 +1,36 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ ProPlanFactoryModel = (*customProPlanFactoryModel)(nil)
|
||||
|
||||
type (
|
||||
ProPlanFactoryModel interface {
|
||||
proPlanFactoryModel
|
||||
FindByPlanId(ctx context.Context, planId string) ([]*ProPlanFactory, error)
|
||||
}
|
||||
|
||||
customProPlanFactoryModel struct {
|
||||
*defaultProPlanFactoryModel
|
||||
}
|
||||
)
|
||||
|
||||
func NewProPlanFactoryModel(conn sqlx.SqlConn) ProPlanFactoryModel {
|
||||
return &customProPlanFactoryModel{
|
||||
defaultProPlanFactoryModel: newProPlanFactoryModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customProPlanFactoryModel) FindByPlanId(ctx context.Context, planId string) ([]*ProPlanFactory, error) {
|
||||
var list []*ProPlanFactory
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE plan_id = ?", proPlanFactoryRows, m.table)
|
||||
if err := m.conn.QueryRowsCtx(ctx, &list, query, planId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
49
model/proplanfactorymodel_gen.go
Normal file
49
model/proplanfactorymodel_gen.go
Normal file
@ -0,0 +1,49 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
proPlanFactoryFieldNames = builder.RawFieldNames(&ProPlanFactory{})
|
||||
proPlanFactoryRows = strings.Join(proPlanFactoryFieldNames, ",")
|
||||
proPlanFactoryRowsExpectAutoSet = strings.Join(stringx.Remove(proPlanFactoryFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
)
|
||||
|
||||
type (
|
||||
proPlanFactoryModel interface {
|
||||
Insert(ctx context.Context, data *ProPlanFactory) (sql.Result, error)
|
||||
}
|
||||
|
||||
defaultProPlanFactoryModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
ProPlanFactory struct {
|
||||
Id int64 `db:"id"`
|
||||
PlanId string `db:"plan_id"`
|
||||
FactoryTenantId string `db:"factory_tenant_id"`
|
||||
FactoryType string `db:"factory_type"`
|
||||
ShareLinkId string `db:"share_link_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func newProPlanFactoryModel(conn sqlx.SqlConn) *defaultProPlanFactoryModel {
|
||||
return &defaultProPlanFactoryModel{conn: conn, table: "`pro_plan_factory`"}
|
||||
}
|
||||
|
||||
func (m *defaultProPlanFactoryModel) Insert(ctx context.Context, data *ProPlanFactory) (sql.Result, error) {
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?)",
|
||||
m.table, proPlanFactoryRowsExpectAutoSet)
|
||||
return m.conn.ExecCtx(ctx, query, data.PlanId, data.FactoryTenantId, data.FactoryType, data.ShareLinkId)
|
||||
}
|
||||
67
model/proplanprocessstepmodel.go
Normal file
67
model/proplanprocessstepmodel.go
Normal file
@ -0,0 +1,67 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ ProPlanProcessStepModel = (*customProPlanProcessStepModel)(nil)
|
||||
|
||||
type (
|
||||
ProPlanProcessStepModel interface {
|
||||
proPlanProcessStepModel
|
||||
FindByPlanId(ctx context.Context, planId string) ([]*ProPlanProcessStep, error)
|
||||
BulkInsert(ctx context.Context, data []*ProPlanProcessStep) error
|
||||
UpdateStepStatus(ctx context.Context, planId, stepType string, status int64, operatorId string) error
|
||||
}
|
||||
|
||||
customProPlanProcessStepModel struct {
|
||||
*defaultProPlanProcessStepModel
|
||||
}
|
||||
)
|
||||
|
||||
func NewProPlanProcessStepModel(conn sqlx.SqlConn) ProPlanProcessStepModel {
|
||||
return &customProPlanProcessStepModel{
|
||||
defaultProPlanProcessStepModel: newProPlanProcessStepModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customProPlanProcessStepModel) FindByPlanId(ctx context.Context, planId string) ([]*ProPlanProcessStep, error) {
|
||||
var list []*ProPlanProcessStep
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE plan_id = ? ORDER BY step_order", proPlanProcessStepRows, m.table)
|
||||
if err := m.conn.QueryRowsCtx(ctx, &list, query, planId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (m *customProPlanProcessStepModel) BulkInsert(ctx context.Context, data []*ProPlanProcessStep) error {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
values := make([]string, 0, len(data))
|
||||
args := make([]interface{}, 0, len(data)*8)
|
||||
for _, d := range data {
|
||||
values = append(values, "(?, ?, ?, ?, ?, ?, ?, ?)")
|
||||
args = append(args, d.StepId, d.PlanId, d.StepType, d.StepOrder, d.Status,
|
||||
d.OperatorId, d.CompletedAt, d.Remark)
|
||||
}
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s", m.table, proPlanProcessStepRowsExpectAutoSet, strings.Join(values, ","))
|
||||
_, err := m.conn.ExecCtx(ctx, query, args...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customProPlanProcessStepModel) UpdateStepStatus(ctx context.Context, planId, stepType string, status int64, operatorId string) error {
|
||||
var completedAt sql.NullTime
|
||||
if status == 2 {
|
||||
completedAt = sql.NullTime{Time: time.Now(), Valid: true}
|
||||
}
|
||||
query := fmt.Sprintf("UPDATE %s SET status = ?, operator_id = ?, completed_at = ? WHERE plan_id = ? AND step_type = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, status, operatorId, completedAt, planId, stepType)
|
||||
return err
|
||||
}
|
||||
69
model/proplanprocessstepmodel_gen.go
Normal file
69
model/proplanprocessstepmodel_gen.go
Normal file
@ -0,0 +1,69 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
proPlanProcessStepFieldNames = builder.RawFieldNames(&ProPlanProcessStep{})
|
||||
proPlanProcessStepRows = strings.Join(proPlanProcessStepFieldNames, ",")
|
||||
proPlanProcessStepRowsExpectAutoSet = strings.Join(stringx.Remove(proPlanProcessStepFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
)
|
||||
|
||||
type (
|
||||
proPlanProcessStepModel interface {
|
||||
Insert(ctx context.Context, data *ProPlanProcessStep) (sql.Result, error)
|
||||
Delete(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
defaultProPlanProcessStepModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
ProPlanProcessStep struct {
|
||||
Id int64 `db:"id"`
|
||||
StepId string `db:"step_id"`
|
||||
PlanId string `db:"plan_id"`
|
||||
StepType string `db:"step_type"`
|
||||
StepOrder int64 `db:"step_order"`
|
||||
Status int64 `db:"status"`
|
||||
OperatorId string `db:"operator_id"`
|
||||
CompletedAt sql.NullTime `db:"completed_at"`
|
||||
Remark sql.NullString `db:"remark"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func newProPlanProcessStepModel(conn sqlx.SqlConn) *defaultProPlanProcessStepModel {
|
||||
return &defaultProPlanProcessStepModel{
|
||||
conn: conn,
|
||||
table: "`pro_plan_process_step`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultProPlanProcessStepModel) Insert(ctx context.Context, data *ProPlanProcessStep) (sql.Result, error) {
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", m.table, proPlanProcessStepRowsExpectAutoSet)
|
||||
return m.conn.ExecCtx(ctx, query,
|
||||
data.StepId, data.PlanId, data.StepType, data.StepOrder, data.Status,
|
||||
data.OperatorId, data.CompletedAt, data.Remark)
|
||||
}
|
||||
|
||||
func (m *defaultProPlanProcessStepModel) Delete(ctx context.Context, id int64) error {
|
||||
query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultProPlanProcessStepModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
53
model/proplanyarnratiomodel.go
Normal file
53
model/proplanyarnratiomodel.go
Normal file
@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ ProPlanYarnRatioModel = (*customProPlanYarnRatioModel)(nil)
|
||||
|
||||
type (
|
||||
ProPlanYarnRatioModel interface {
|
||||
proPlanYarnRatioModel
|
||||
FindByPlanId(ctx context.Context, planId string) ([]*ProPlanYarnRatio, error)
|
||||
BulkInsert(ctx context.Context, data []*ProPlanYarnRatio) error
|
||||
}
|
||||
|
||||
customProPlanYarnRatioModel struct {
|
||||
*defaultProPlanYarnRatioModel
|
||||
}
|
||||
)
|
||||
|
||||
func NewProPlanYarnRatioModel(conn sqlx.SqlConn) ProPlanYarnRatioModel {
|
||||
return &customProPlanYarnRatioModel{
|
||||
defaultProPlanYarnRatioModel: newProPlanYarnRatioModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customProPlanYarnRatioModel) FindByPlanId(ctx context.Context, planId string) ([]*ProPlanYarnRatio, error) {
|
||||
var list []*ProPlanYarnRatio
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE plan_id = ? ORDER BY id", proPlanYarnRatioRows, m.table)
|
||||
if err := m.conn.QueryRowsCtx(ctx, &list, query, planId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (m *customProPlanYarnRatioModel) BulkInsert(ctx context.Context, data []*ProPlanYarnRatio) error {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
values := make([]string, 0, len(data))
|
||||
args := make([]interface{}, 0, len(data)*6)
|
||||
for _, d := range data {
|
||||
values = append(values, "(?, ?, ?, ?, ?, ?)")
|
||||
args = append(args, d.RatioId, d.PlanId, d.YarnName, d.Ratio, d.AmountPerMeter, d.TotalAmount)
|
||||
}
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s", m.table, proPlanYarnRatioRowsExpectAutoSet, strings.Join(values, ","))
|
||||
_, err := m.conn.ExecCtx(ctx, query, args...)
|
||||
return err
|
||||
}
|
||||
65
model/proplanyarnratiomodel_gen.go
Normal file
65
model/proplanyarnratiomodel_gen.go
Normal file
@ -0,0 +1,65 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
proPlanYarnRatioFieldNames = builder.RawFieldNames(&ProPlanYarnRatio{})
|
||||
proPlanYarnRatioRows = strings.Join(proPlanYarnRatioFieldNames, ",")
|
||||
proPlanYarnRatioRowsExpectAutoSet = strings.Join(stringx.Remove(proPlanYarnRatioFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
)
|
||||
|
||||
type (
|
||||
proPlanYarnRatioModel interface {
|
||||
Insert(ctx context.Context, data *ProPlanYarnRatio) (sql.Result, error)
|
||||
Delete(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
defaultProPlanYarnRatioModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
ProPlanYarnRatio struct {
|
||||
Id int64 `db:"id"`
|
||||
RatioId string `db:"ratio_id"`
|
||||
PlanId string `db:"plan_id"`
|
||||
YarnName string `db:"yarn_name"`
|
||||
Ratio float64 `db:"ratio"`
|
||||
AmountPerMeter float64 `db:"amount_per_meter"`
|
||||
TotalAmount float64 `db:"total_amount"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func newProPlanYarnRatioModel(conn sqlx.SqlConn) *defaultProPlanYarnRatioModel {
|
||||
return &defaultProPlanYarnRatioModel{
|
||||
conn: conn,
|
||||
table: "`pro_plan_yarn_ratio`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultProPlanYarnRatioModel) Insert(ctx context.Context, data *ProPlanYarnRatio) (sql.Result, error) {
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?)", m.table, proPlanYarnRatioRowsExpectAutoSet)
|
||||
return m.conn.ExecCtx(ctx, query,
|
||||
data.RatioId, data.PlanId, data.YarnName, data.Ratio, data.AmountPerMeter, data.TotalAmount)
|
||||
}
|
||||
|
||||
func (m *defaultProPlanYarnRatioModel) Delete(ctx context.Context, id int64) error {
|
||||
query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultProPlanYarnRatioModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
89
model/proproductionplanmodel.go
Normal file
89
model/proproductionplanmodel.go
Normal file
@ -0,0 +1,89 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ ProProductionPlanModel = (*customProProductionPlanModel)(nil)
|
||||
|
||||
type (
|
||||
ProProductionPlanModel interface {
|
||||
proProductionPlanModel
|
||||
FindList(ctx context.Context, tenantId string, page, pageSize int64, status int64, productName, planCode string) ([]*ProProductionPlan, int64, error)
|
||||
CountTodayPlans(ctx context.Context, tenantId, dateStr string) (int64, error)
|
||||
UpdateCompletedQuantity(ctx context.Context, planId string, operator string) error
|
||||
UpdateStatus(ctx context.Context, planId string, status int64) error
|
||||
}
|
||||
|
||||
customProProductionPlanModel struct {
|
||||
*defaultProProductionPlanModel
|
||||
}
|
||||
)
|
||||
|
||||
func NewProProductionPlanModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) ProProductionPlanModel {
|
||||
return &customProProductionPlanModel{
|
||||
defaultProProductionPlanModel: newProProductionPlanModel(conn, c, opts...),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customProProductionPlanModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, status int64, productName, planCode string) ([]*ProProductionPlan, int64, error) {
|
||||
where := "WHERE tenant_id = ?"
|
||||
args := []interface{}{tenantId}
|
||||
|
||||
if status != -1 {
|
||||
where += " AND status = ?"
|
||||
args = append(args, status)
|
||||
}
|
||||
if productName != "" {
|
||||
where += " AND product_name LIKE ?"
|
||||
args = append(args, "%"+productName+"%")
|
||||
}
|
||||
if planCode != "" {
|
||||
where += " AND plan_code LIKE ?"
|
||||
args = append(args, "%"+planCode+"%")
|
||||
}
|
||||
|
||||
var total int64
|
||||
countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where)
|
||||
if err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, args...); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var list []*ProProductionPlan
|
||||
query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?",
|
||||
proProductionPlanRows, m.table, where)
|
||||
args = append(args, pageSize, (page-1)*pageSize)
|
||||
if err := m.QueryRowsNoCacheCtx(ctx, &list, query, args...); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (m *customProProductionPlanModel) CountTodayPlans(ctx context.Context, tenantId, dateStr string) (int64, error) {
|
||||
var count int64
|
||||
query := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE tenant_id = ? AND DATE(created_at) = ?", m.table)
|
||||
if err := m.QueryRowNoCacheCtx(ctx, &count, query, tenantId, dateStr); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (m *customProProductionPlanModel) UpdateCompletedQuantity(ctx context.Context, planId string, operator string) error {
|
||||
// Use SUM to recalculate, not increment — prevents drift
|
||||
query := fmt.Sprintf(`UPDATE %s SET
|
||||
completed_quantity = COALESCE((SELECT SUM(quantity) FROM pro_inbound_record WHERE plan_id = ?), 0),
|
||||
operator = ?
|
||||
WHERE plan_id = ?`, m.table)
|
||||
_, err := m.ExecNoCacheCtx(ctx, query, planId, operator, planId)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customProProductionPlanModel) UpdateStatus(ctx context.Context, planId string, status int64) error {
|
||||
query := fmt.Sprintf("UPDATE %s SET status = ? WHERE plan_id = ?", m.table)
|
||||
_, err := m.ExecNoCacheCtx(ctx, query, status, planId)
|
||||
return err
|
||||
}
|
||||
167
model/proproductionplanmodel_gen.go
Normal file
167
model/proproductionplanmodel_gen.go
Normal file
@ -0,0 +1,167 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
proProductionPlanFieldNames = builder.RawFieldNames(&ProProductionPlan{})
|
||||
proProductionPlanRows = strings.Join(proProductionPlanFieldNames, ",")
|
||||
proProductionPlanRowsExpectAutoSet = strings.Join(stringx.Remove(proProductionPlanFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
proProductionPlanRowsWithPlaceHolder = strings.Join(stringx.Remove(proProductionPlanFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||
|
||||
cacheProProductionPlanIdPrefix = "cache:proProductionPlan:id:"
|
||||
cacheProProductionPlanPlanIdPrefix = "cache:proProductionPlan:planId:"
|
||||
)
|
||||
|
||||
type (
|
||||
proProductionPlanModel interface {
|
||||
Insert(ctx context.Context, data *ProProductionPlan) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id int64) (*ProProductionPlan, error)
|
||||
FindOneByPlanId(ctx context.Context, planId string) (*ProProductionPlan, error)
|
||||
Update(ctx context.Context, data *ProProductionPlan) error
|
||||
Delete(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
defaultProProductionPlanModel struct {
|
||||
sqlc.CachedConn
|
||||
table string
|
||||
}
|
||||
|
||||
ProProductionPlan struct {
|
||||
Id int64 `db:"id"`
|
||||
PlanId string `db:"plan_id"`
|
||||
TenantId string `db:"tenant_id"`
|
||||
PlanCode string `db:"plan_code"`
|
||||
ProductId string `db:"product_id"`
|
||||
ProductName string `db:"product_name"`
|
||||
Color string `db:"color"`
|
||||
FabricCode string `db:"fabric_code"`
|
||||
ColorCode string `db:"color_code"`
|
||||
TargetQuantity float64 `db:"target_quantity"`
|
||||
CompletedQuantity float64 `db:"completed_quantity"`
|
||||
YarnUsagePerMeter float64 `db:"yarn_usage_per_meter"`
|
||||
ProductionPrice float64 `db:"production_price"`
|
||||
SupplierId string `db:"supplier_id"`
|
||||
Status int64 `db:"status"`
|
||||
Remark sql.NullString `db:"remark"`
|
||||
StartTime sql.NullTime `db:"start_time"`
|
||||
Creator string `db:"creator"`
|
||||
Operator string `db:"operator"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func newProProductionPlanModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultProProductionPlanModel {
|
||||
return &defaultProProductionPlanModel{
|
||||
CachedConn: sqlc.NewConn(conn, c, opts...),
|
||||
table: "`pro_production_plan`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) Insert(ctx context.Context, data *ProProductionPlan) (sql.Result, error) {
|
||||
proProductionPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanIdPrefix, data.Id)
|
||||
proProductionPlanPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanPlanIdPrefix, data.PlanId)
|
||||
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, proProductionPlanRowsExpectAutoSet)
|
||||
return conn.ExecCtx(ctx, query,
|
||||
data.PlanId, data.TenantId, data.PlanCode, data.ProductId, data.ProductName,
|
||||
data.Color, data.FabricCode, data.ColorCode, data.TargetQuantity, data.CompletedQuantity,
|
||||
data.YarnUsagePerMeter, data.ProductionPrice, data.SupplierId, data.Status, data.Remark,
|
||||
data.StartTime, data.Creator, data.Operator)
|
||||
}, proProductionPlanIdKey, proProductionPlanPlanIdKey)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) FindOne(ctx context.Context, id int64) (*ProProductionPlan, error) {
|
||||
proProductionPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanIdPrefix, id)
|
||||
var resp ProProductionPlan
|
||||
err := m.QueryRowCtx(ctx, &resp, proProductionPlanIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", proProductionPlanRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, id)
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) FindOneByPlanId(ctx context.Context, planId string) (*ProProductionPlan, error) {
|
||||
proProductionPlanPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanPlanIdPrefix, planId)
|
||||
var resp ProProductionPlan
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, proProductionPlanPlanIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE `plan_id` = ? LIMIT 1", proProductionPlanRows, m.table)
|
||||
if err := conn.QueryRowCtx(ctx, &resp, query, planId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Id, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) Update(ctx context.Context, newData *ProProductionPlan) error {
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proProductionPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanIdPrefix, data.Id)
|
||||
proProductionPlanPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanPlanIdPrefix, data.PlanId)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("UPDATE %s SET %s WHERE `id` = ?", m.table, proProductionPlanRowsWithPlaceHolder)
|
||||
return conn.ExecCtx(ctx, query,
|
||||
newData.PlanId, newData.TenantId, newData.PlanCode, newData.ProductId, newData.ProductName,
|
||||
newData.Color, newData.FabricCode, newData.ColorCode, newData.TargetQuantity, newData.CompletedQuantity,
|
||||
newData.YarnUsagePerMeter, newData.ProductionPrice, newData.SupplierId, newData.Status, newData.Remark,
|
||||
newData.StartTime, newData.Creator, newData.Operator, newData.Id)
|
||||
}, proProductionPlanIdKey, proProductionPlanPlanIdKey)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) Delete(ctx context.Context, id int64) error {
|
||||
data, err := m.FindOne(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proProductionPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanIdPrefix, id)
|
||||
proProductionPlanPlanIdKey := fmt.Sprintf("%s%v", cacheProProductionPlanPlanIdPrefix, data.PlanId)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table)
|
||||
return conn.ExecCtx(ctx, query, id)
|
||||
}, proProductionPlanIdKey, proProductionPlanPlanIdKey)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) formatPrimary(primary any) string {
|
||||
return fmt.Sprintf("%s%v", cacheProProductionPlanIdPrefix, primary)
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE `id` = ? LIMIT 1", proProductionPlanRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, primary)
|
||||
}
|
||||
|
||||
func (m *defaultProProductionPlanModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
74
model/prosharelinkmodel.go
Normal file
74
model/prosharelinkmodel.go
Normal file
@ -0,0 +1,74 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ ProShareLinkModel = (*customProShareLinkModel)(nil)
|
||||
|
||||
type (
|
||||
ProShareLinkModel interface {
|
||||
proShareLinkModel
|
||||
FindByShortCode(ctx context.Context, shortCode string) (*ProShareLink, error)
|
||||
FindByLinkId(ctx context.Context, linkId string) (*ProShareLink, error)
|
||||
FindActiveLinkByPlan(ctx context.Context, planId string) (*ProShareLink, error)
|
||||
UpdateClick(ctx context.Context, shortCode string) error
|
||||
UpdateStatus(ctx context.Context, shortCode string, status int64, rejectReason string) error
|
||||
}
|
||||
|
||||
customProShareLinkModel struct {
|
||||
*defaultProShareLinkModel
|
||||
}
|
||||
)
|
||||
|
||||
func NewProShareLinkModel(conn sqlx.SqlConn) ProShareLinkModel {
|
||||
return &customProShareLinkModel{
|
||||
defaultProShareLinkModel: newProShareLinkModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customProShareLinkModel) FindByShortCode(ctx context.Context, shortCode string) (*ProShareLink, error) {
|
||||
var resp ProShareLink
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE short_code = ? LIMIT 1", proShareLinkRows, m.table)
|
||||
if err := m.conn.QueryRowCtx(ctx, &resp, query, shortCode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *customProShareLinkModel) FindByLinkId(ctx context.Context, linkId string) (*ProShareLink, error) {
|
||||
var resp ProShareLink
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE link_id = ? LIMIT 1", proShareLinkRows, m.table)
|
||||
if err := m.conn.QueryRowCtx(ctx, &resp, query, linkId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *customProShareLinkModel) FindActiveLinkByPlan(ctx context.Context, planId string) (*ProShareLink, error) {
|
||||
var resp ProShareLink
|
||||
query := fmt.Sprintf("SELECT %s FROM %s WHERE plan_id = ? AND status IN (0, 1) AND expires_at > NOW() ORDER BY created_at DESC LIMIT 1",
|
||||
proShareLinkRows, m.table)
|
||||
if err := m.conn.QueryRowCtx(ctx, &resp, query, planId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *customProShareLinkModel) UpdateClick(ctx context.Context, shortCode string) error {
|
||||
query := fmt.Sprintf("UPDATE %s SET status = 1, click_count = click_count + 1, clicked_at = ? WHERE short_code = ? AND status = 0",
|
||||
m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, sql.NullTime{Time: time.Now(), Valid: true}, shortCode)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customProShareLinkModel) UpdateStatus(ctx context.Context, shortCode string, status int64, rejectReason string) error {
|
||||
query := fmt.Sprintf("UPDATE %s SET status = ?, responded_at = ?, reject_reason = ? WHERE short_code = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, status, sql.NullTime{Time: time.Now(), Valid: true}, rejectReason, shortCode)
|
||||
return err
|
||||
}
|
||||
70
model/prosharelinkmodel_gen.go
Normal file
70
model/prosharelinkmodel_gen.go
Normal file
@ -0,0 +1,70 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
proShareLinkFieldNames = builder.RawFieldNames(&ProShareLink{})
|
||||
proShareLinkRows = strings.Join(proShareLinkFieldNames, ",")
|
||||
proShareLinkRowsExpectAutoSet = strings.Join(stringx.Remove(proShareLinkFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
)
|
||||
|
||||
type (
|
||||
proShareLinkModel interface {
|
||||
Insert(ctx context.Context, data *ProShareLink) (sql.Result, error)
|
||||
Delete(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
defaultProShareLinkModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
ProShareLink struct {
|
||||
Id int64 `db:"id"`
|
||||
LinkId string `db:"link_id"`
|
||||
TenantId string `db:"tenant_id"`
|
||||
PlanId string `db:"plan_id"`
|
||||
ShortCode string `db:"short_code"`
|
||||
Token string `db:"token"`
|
||||
FactoryType string `db:"factory_type"`
|
||||
HideSensitive int64 `db:"hide_sensitive"`
|
||||
Status int64 `db:"status"`
|
||||
ClickCount int64 `db:"click_count"`
|
||||
ClickedAt sql.NullTime `db:"clicked_at"`
|
||||
RespondedAt sql.NullTime `db:"responded_at"`
|
||||
RejectReason string `db:"reject_reason"`
|
||||
ExpiresAt time.Time `db:"expires_at"`
|
||||
CreatedBy string `db:"created_by"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func newProShareLinkModel(conn sqlx.SqlConn) *defaultProShareLinkModel {
|
||||
return &defaultProShareLinkModel{conn: conn, table: "`pro_share_link`"}
|
||||
}
|
||||
|
||||
func (m *defaultProShareLinkModel) Insert(ctx context.Context, data *ProShareLink) (sql.Result, error) {
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
m.table, proShareLinkRowsExpectAutoSet)
|
||||
return m.conn.ExecCtx(ctx, query, data.LinkId, data.TenantId, data.PlanId,
|
||||
data.ShortCode, data.Token, data.FactoryType, data.HideSensitive,
|
||||
data.Status, data.ClickCount, data.ClickedAt, data.RespondedAt,
|
||||
data.RejectReason, data.ExpiresAt, data.CreatedBy)
|
||||
}
|
||||
|
||||
func (m *defaultProShareLinkModel) Delete(ctx context.Context, id int64) error {
|
||||
query := fmt.Sprintf("DELETE FROM %s WHERE `id` = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
13
rpc/production/internal/config/config.go
Normal file
13
rpc/production/internal/config/config.go
Normal file
@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
zrpc.RpcServerConf
|
||||
DataSource string
|
||||
Cache cache.CacheConf
|
||||
PrometheusAddr string `json:",default=:9095"`
|
||||
}
|
||||
33
rpc/production/internal/logic/clicksharelinklogic.go
Normal file
33
rpc/production/internal/logic/clicksharelinklogic.go
Normal file
@ -0,0 +1,33 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ClickShareLinkLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewClickShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ClickShareLinkLogic {
|
||||
return &ClickShareLinkLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *ClickShareLinkLogic) ClickShareLink(in *pb.ClickShareLinkReq) (*pb.Empty, error) {
|
||||
_, err := l.svcCtx.ShareLinkModel.FindByShortCode(l.ctx, in.ShortCode)
|
||||
if err != nil {
|
||||
return nil, ErrLinkNotFound
|
||||
}
|
||||
|
||||
if err := l.svcCtx.ShareLinkModel.UpdateClick(l.ctx, in.ShortCode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
66
rpc/production/internal/logic/completesteplogic.go
Normal file
66
rpc/production/internal/logic/completesteplogic.go
Normal file
@ -0,0 +1,66 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CompleteStepLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewCompleteStepLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CompleteStepLogic {
|
||||
return &CompleteStepLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *CompleteStepLogic) CompleteStep(in *pb.CompleteStepReq) (*pb.Empty, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
// Validate plan exists and belongs to tenant
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
if plan.TenantId != tenantId {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
|
||||
// Find steps for this plan and check the target step
|
||||
steps, err := l.svcCtx.ProcessStepModel.FindByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrStepNotFound
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, s := range steps {
|
||||
if s.StepType == in.StepType {
|
||||
found = true
|
||||
if s.Status == 2 {
|
||||
return nil, ErrStepAlreadyComplete
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return nil, ErrStepNotFound
|
||||
}
|
||||
|
||||
operatorId := in.OperatorId
|
||||
if operatorId == "" {
|
||||
operatorId = tenantId
|
||||
}
|
||||
|
||||
// Update step status to 2 (completed)
|
||||
if err := l.svcCtx.ProcessStepModel.UpdateStepStatus(l.ctx, in.PlanId, in.StepType, 2, operatorId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
47
rpc/production/internal/logic/confirmplanlogic.go
Normal file
47
rpc/production/internal/logic/confirmplanlogic.go
Normal file
@ -0,0 +1,47 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ConfirmPlanLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewConfirmPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmPlanLogic {
|
||||
return &ConfirmPlanLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *ConfirmPlanLogic) ConfirmPlan(in *pb.ConfirmPlanReq) (*pb.Empty, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
if plan.TenantId != tenantId {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
if plan.Status != 0 {
|
||||
return nil, ErrPlanNotDraft
|
||||
}
|
||||
|
||||
if err := l.svcCtx.PlanModel.UpdateStatus(l.ctx, in.PlanId, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Mark confirm step as completed
|
||||
if err := l.svcCtx.ProcessStepModel.UpdateStepStatus(l.ctx, in.PlanId, "confirm", 2, in.Operator); err != nil {
|
||||
l.Errorf("update confirm step failed: %v", err)
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
65
rpc/production/internal/logic/confirmsharelinklogic.go
Normal file
65
rpc/production/internal/logic/confirmsharelinklogic.go
Normal file
@ -0,0 +1,65 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/model"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ConfirmShareLinkLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewConfirmShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmShareLinkLogic {
|
||||
return &ConfirmShareLinkLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *ConfirmShareLinkLogic) ConfirmShareLink(in *pb.ConfirmShareLinkReq) (*pb.Empty, error) {
|
||||
link, err := l.svcCtx.ShareLinkModel.FindByShortCode(l.ctx, in.ShortCode)
|
||||
if err != nil {
|
||||
return nil, ErrLinkNotFound
|
||||
}
|
||||
|
||||
// Check not expired
|
||||
if time.Now().After(link.ExpiresAt) {
|
||||
return nil, ErrLinkExpired
|
||||
}
|
||||
|
||||
// Check status is 0 (created) or 1 (clicked)
|
||||
if link.Status != 0 && link.Status != 1 {
|
||||
return nil, ErrLinkAlreadyUsed
|
||||
}
|
||||
|
||||
// Create plan_factory record linking factory to the plan
|
||||
_, err = l.svcCtx.PlanFactoryModel.Insert(l.ctx, &model.ProPlanFactory{
|
||||
PlanId: link.PlanId,
|
||||
FactoryTenantId: in.FactoryTenantId,
|
||||
FactoryType: link.FactoryType,
|
||||
ShareLinkId: link.LinkId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update share link status to 2 (confirmed)
|
||||
if err := l.svcCtx.ShareLinkModel.UpdateStatus(l.ctx, in.ShortCode, 2, ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update plan status to 2 (producing) if currently 1 (pending)
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, link.PlanId)
|
||||
if err == nil && plan.Status == 1 {
|
||||
if err := l.svcCtx.PlanModel.UpdateStatus(l.ctx, link.PlanId, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
126
rpc/production/internal/logic/createinboundlogic.go
Normal file
126
rpc/production/internal/logic/createinboundlogic.go
Normal file
@ -0,0 +1,126 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/pkg/uid"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
type CreateInboundLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewCreateInboundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateInboundLogic {
|
||||
return &CreateInboundLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *CreateInboundLogic) CreateInbound(in *pb.CreateInboundReq) (*pb.IdResp, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
qty, _ := strconv.ParseFloat(in.Quantity, 64)
|
||||
if qty <= 0 {
|
||||
return nil, ErrInvalidQuantity
|
||||
}
|
||||
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
|
||||
// Tenant isolation: allow plan owner OR an associated factory tenant
|
||||
if plan.TenantId != tenantId {
|
||||
factories, fErr := l.svcCtx.PlanFactoryModel.FindByPlanId(l.ctx, in.PlanId)
|
||||
if fErr != nil {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
authorized := false
|
||||
for _, f := range factories {
|
||||
if f.FactoryTenantId == tenantId {
|
||||
authorized = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !authorized {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
|
||||
if plan.Status != 2 { // must be producing
|
||||
return nil, ErrPlanNotProducing
|
||||
}
|
||||
|
||||
// Check if adding this quantity would exceed target
|
||||
if plan.CompletedQuantity+qty > plan.TargetQuantity {
|
||||
return nil, ErrExceedTarget
|
||||
}
|
||||
|
||||
price, _ := strconv.ParseFloat(in.PricePerMeter, 64)
|
||||
recordId := uid.Generate()
|
||||
|
||||
// Transactional: insert record + recalculate completed_quantity + check completion + write inventory log
|
||||
err = l.svcCtx.Conn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
// 1. Insert inbound record
|
||||
_, err := session.ExecCtx(ctx,
|
||||
"INSERT INTO pro_inbound_record (record_id, tenant_id, plan_id, product_id, batch_no, quantity, rolls, price_per_meter, operator_id, remark) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
recordId, tenantId, in.PlanId, plan.ProductId, in.BatchNo, qty, in.Rolls, price, tenantId,
|
||||
sql.NullString{String: in.Remark, Valid: in.Remark != ""})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. Recalculate completed_quantity via SUM (not increment — prevents drift)
|
||||
_, err = session.ExecCtx(ctx,
|
||||
"UPDATE pro_production_plan SET completed_quantity = COALESCE((SELECT SUM(quantity) FROM pro_inbound_record WHERE plan_id = ?), 0), operator = ? WHERE plan_id = ?",
|
||||
in.PlanId, tenantId, in.PlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. Check if plan is now complete
|
||||
var completedQty float64
|
||||
err = session.QueryRowCtx(ctx, &completedQty,
|
||||
"SELECT completed_quantity FROM pro_production_plan WHERE plan_id = ?", in.PlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if completedQty >= plan.TargetQuantity {
|
||||
// Mark plan as completed
|
||||
_, err = session.ExecCtx(ctx,
|
||||
"UPDATE pro_production_plan SET status = 3 WHERE plan_id = ?", in.PlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Mark fabric_warehouse step as completed
|
||||
_, err = session.ExecCtx(ctx,
|
||||
"UPDATE pro_plan_process_step SET status = 2, completed_at = NOW(), operator_id = ? WHERE plan_id = ? AND step_type = 'fabric_warehouse'",
|
||||
tenantId, in.PlanId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Write inventory log (inside transaction via raw SQL)
|
||||
logId := uid.Generate()
|
||||
_, err = session.ExecCtx(ctx,
|
||||
"INSERT INTO `inv_inventory_log` (`log_id`, `tenant_id`, `product_id`, `change_qty`, `balance_after`, `change_type`, `ref_type`, `ref_id`, `contact_id`, `log_date`, `operator`, `remark`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
logId, plan.TenantId, plan.ProductId, qty, float64(0), int64(2), "PRODUCTION", recordId, in.PlanId, time.Now(), tenantId, "生产入库 "+in.BatchNo)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.IdResp{Id: recordId}, nil
|
||||
}
|
||||
122
rpc/production/internal/logic/createproductionplanlogic.go
Normal file
122
rpc/production/internal/logic/createproductionplanlogic.go
Normal file
@ -0,0 +1,122 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/model"
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/pkg/uid"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CreateProductionPlanLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewCreateProductionPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateProductionPlanLogic {
|
||||
return &CreateProductionPlanLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
var defaultSteps = []struct {
|
||||
Type string
|
||||
Order int64
|
||||
}{
|
||||
{"confirm", 1},
|
||||
{"yarn_purchase", 2},
|
||||
{"dyeing", 3},
|
||||
{"machine_start", 4},
|
||||
{"fabric_warehouse", 5},
|
||||
}
|
||||
|
||||
func (l *CreateProductionPlanLogic) CreateProductionPlan(in *pb.CreateProductionPlanReq) (*pb.IdResp, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
// Generate plan code PP-YYYYMMDD-XXXX
|
||||
today := time.Now().Format("20060102")
|
||||
count, err := l.svcCtx.PlanModel.CountTodayPlans(l.ctx, tenantId, time.Now().Format("2006-01-02"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
planCode := fmt.Sprintf("PP-%s-%04d", today, count+1)
|
||||
|
||||
targetQty, _ := strconv.ParseFloat(in.TargetQuantity, 64)
|
||||
yarnUsage, _ := strconv.ParseFloat(in.YarnUsagePerMeter, 64)
|
||||
price, _ := strconv.ParseFloat(in.ProductionPrice, 64)
|
||||
|
||||
var startTime sql.NullTime
|
||||
if in.StartTime != "" {
|
||||
if t, err := time.Parse("2006-01-02", in.StartTime); err == nil {
|
||||
startTime = sql.NullTime{Time: t, Valid: true}
|
||||
}
|
||||
}
|
||||
|
||||
planId := uid.Generate()
|
||||
_, err = l.svcCtx.PlanModel.Insert(l.ctx, &model.ProProductionPlan{
|
||||
PlanId: planId,
|
||||
TenantId: tenantId,
|
||||
PlanCode: planCode,
|
||||
ProductId: in.ProductId,
|
||||
ProductName: in.ProductName,
|
||||
Color: in.Color,
|
||||
FabricCode: in.FabricCode,
|
||||
ColorCode: in.ColorCode,
|
||||
TargetQuantity: targetQty,
|
||||
YarnUsagePerMeter: yarnUsage,
|
||||
ProductionPrice: price,
|
||||
SupplierId: in.SupplierId,
|
||||
Status: 0, // draft
|
||||
Remark: sql.NullString{String: in.Remark, Valid: in.Remark != ""},
|
||||
StartTime: startTime,
|
||||
Creator: tenantId,
|
||||
Operator: tenantId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create yarn ratios
|
||||
if len(in.YarnRatios) > 0 {
|
||||
ratios := make([]*model.ProPlanYarnRatio, 0, len(in.YarnRatios))
|
||||
for _, yr := range in.YarnRatios {
|
||||
ratio, _ := strconv.ParseFloat(yr.Ratio, 64)
|
||||
amtPerM, _ := strconv.ParseFloat(yr.AmountPerMeter, 64)
|
||||
ratios = append(ratios, &model.ProPlanYarnRatio{
|
||||
RatioId: uid.Generate(),
|
||||
PlanId: planId,
|
||||
YarnName: yr.YarnName,
|
||||
Ratio: ratio,
|
||||
AmountPerMeter: amtPerM,
|
||||
TotalAmount: amtPerM * targetQty,
|
||||
})
|
||||
}
|
||||
if err := l.svcCtx.YarnRatioModel.BulkInsert(l.ctx, ratios); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize 5 process steps
|
||||
steps := make([]*model.ProPlanProcessStep, 0, len(defaultSteps))
|
||||
for _, ds := range defaultSteps {
|
||||
steps = append(steps, &model.ProPlanProcessStep{
|
||||
StepId: uid.Generate(),
|
||||
PlanId: planId,
|
||||
StepType: ds.Type,
|
||||
StepOrder: ds.Order,
|
||||
Status: 0, // pending
|
||||
})
|
||||
}
|
||||
if err := l.svcCtx.ProcessStepModel.BulkInsert(l.ctx, steps); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.IdResp{Id: planId}, nil
|
||||
}
|
||||
88
rpc/production/internal/logic/createsharelinklogic.go
Normal file
88
rpc/production/internal/logic/createsharelinklogic.go
Normal file
@ -0,0 +1,88 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/model"
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/pkg/uid"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CreateShareLinkLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewCreateShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateShareLinkLogic {
|
||||
return &CreateShareLinkLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *CreateShareLinkLogic) CreateShareLink(in *pb.CreateShareLinkReq) (*pb.ShareLinkInfo, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
// Validate plan exists
|
||||
_, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
|
||||
// Generate 8-char short code using crypto/rand
|
||||
b := make([]byte, 8)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shortCode := hex.EncodeToString(b)[:8]
|
||||
|
||||
// Generate token
|
||||
tb := make([]byte, 16)
|
||||
if _, err := rand.Read(tb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := hex.EncodeToString(tb)
|
||||
|
||||
// Default expiry: 30 minutes (override with ExpiresHours if provided)
|
||||
expiry := 30 * time.Minute
|
||||
if in.ExpiresHours > 0 {
|
||||
expiry = time.Duration(in.ExpiresHours) * time.Hour
|
||||
}
|
||||
expiresAt := time.Now().Add(expiry)
|
||||
|
||||
linkId := uid.Generate()
|
||||
link := &model.ProShareLink{
|
||||
LinkId: linkId,
|
||||
TenantId: tenantId,
|
||||
PlanId: in.PlanId,
|
||||
ShortCode: shortCode,
|
||||
Token: token,
|
||||
FactoryType: in.FactoryType,
|
||||
HideSensitive: in.HideSensitive,
|
||||
Status: 0, // created
|
||||
ExpiresAt: expiresAt,
|
||||
CreatedBy: tenantId,
|
||||
}
|
||||
|
||||
if _, err := l.svcCtx.ShareLinkModel.Insert(l.ctx, link); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.ShareLinkInfo{
|
||||
LinkId: linkId,
|
||||
TenantId: tenantId,
|
||||
PlanId: in.PlanId,
|
||||
ShortCode: shortCode,
|
||||
Token: token,
|
||||
FactoryType: in.FactoryType,
|
||||
HideSensitive: in.HideSensitive,
|
||||
Status: 0,
|
||||
ExpiresAt: expiresAt.Format("2006-01-02 15:04:05"),
|
||||
CreatedBy: tenantId,
|
||||
}, nil
|
||||
}
|
||||
22
rpc/production/internal/logic/errors.go
Normal file
22
rpc/production/internal/logic/errors.go
Normal file
@ -0,0 +1,22 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrPlanNotFound = status.Error(codes.NotFound, "生产计划不存在")
|
||||
ErrPlanNotDraft = status.Error(codes.FailedPrecondition, "计划不是草稿状态")
|
||||
ErrPlanNotPending = status.Error(codes.FailedPrecondition, "计划不是待确认状态")
|
||||
ErrPlanNotProducing = status.Error(codes.FailedPrecondition, "计划不在生产中")
|
||||
ErrPlanCompleted = status.Error(codes.FailedPrecondition, "计划已完成")
|
||||
ErrLinkNotFound = status.Error(codes.NotFound, "分享链接不存在")
|
||||
ErrLinkExpired = status.Error(codes.FailedPrecondition, "分享链接已过期")
|
||||
ErrLinkAlreadyUsed = status.Error(codes.FailedPrecondition, "分享链接已被使用")
|
||||
ErrStepNotFound = status.Error(codes.NotFound, "流程节点不存在")
|
||||
ErrStepAlreadyComplete = status.Error(codes.FailedPrecondition, "流程节点已完成")
|
||||
ErrInvalidQuantity = status.Error(codes.InvalidArgument, "入库数量必须大于0")
|
||||
ErrExceedTarget = status.Error(codes.FailedPrecondition, "入库总量将超过目标产量")
|
||||
ErrPermissionDenied = status.Error(codes.PermissionDenied, "无权操作该生产计划")
|
||||
)
|
||||
125
rpc/production/internal/logic/getproductionplanlogic.go
Normal file
125
rpc/production/internal/logic/getproductionplanlogic.go
Normal file
@ -0,0 +1,125 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetProductionPlanLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetProductionPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductionPlanLogic {
|
||||
return &GetProductionPlanLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *GetProductionPlanLogic) GetProductionPlan(in *pb.GetProductionPlanReq) (*pb.ProductionPlanInfo, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
|
||||
if plan.TenantId != tenantId {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
|
||||
info := &pb.ProductionPlanInfo{
|
||||
PlanId: plan.PlanId,
|
||||
TenantId: plan.TenantId,
|
||||
PlanCode: plan.PlanCode,
|
||||
ProductId: plan.ProductId,
|
||||
ProductName: plan.ProductName,
|
||||
Color: plan.Color,
|
||||
FabricCode: plan.FabricCode,
|
||||
ColorCode: plan.ColorCode,
|
||||
TargetQuantity: fmt.Sprintf("%.2f", plan.TargetQuantity),
|
||||
CompletedQuantity: fmt.Sprintf("%.2f", plan.CompletedQuantity),
|
||||
YarnUsagePerMeter: fmt.Sprintf("%.4f", plan.YarnUsagePerMeter),
|
||||
ProductionPrice: fmt.Sprintf("%.2f", plan.ProductionPrice),
|
||||
SupplierId: plan.SupplierId,
|
||||
Status: plan.Status,
|
||||
Remark: plan.Remark.String,
|
||||
Creator: plan.Creator,
|
||||
Operator: plan.Operator,
|
||||
CreatedAt: plan.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: plan.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if plan.StartTime.Valid {
|
||||
info.StartTime = plan.StartTime.Time.Format("2006-01-02")
|
||||
}
|
||||
|
||||
// Load yarn ratios
|
||||
ratios, err := l.svcCtx.YarnRatioModel.FindByPlanId(l.ctx, in.PlanId)
|
||||
if err == nil {
|
||||
for _, r := range ratios {
|
||||
info.YarnRatios = append(info.YarnRatios, &pb.YarnRatioInfo{
|
||||
RatioId: r.RatioId,
|
||||
PlanId: r.PlanId,
|
||||
YarnName: r.YarnName,
|
||||
Ratio: fmt.Sprintf("%.2f", r.Ratio),
|
||||
AmountPerMeter: fmt.Sprintf("%.4f", r.AmountPerMeter),
|
||||
TotalAmount: fmt.Sprintf("%.2f", r.TotalAmount),
|
||||
CreatedAt: r.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Load process steps
|
||||
steps, err := l.svcCtx.ProcessStepModel.FindByPlanId(l.ctx, in.PlanId)
|
||||
if err == nil {
|
||||
for _, s := range steps {
|
||||
stepInfo := &pb.ProcessStepInfo{
|
||||
StepId: s.StepId,
|
||||
PlanId: s.PlanId,
|
||||
StepType: s.StepType,
|
||||
StepOrder: s.StepOrder,
|
||||
Status: s.Status,
|
||||
OperatorId: s.OperatorId,
|
||||
CreatedAt: s.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: s.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if s.CompletedAt.Valid {
|
||||
stepInfo.CompletedAt = s.CompletedAt.Time.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
if s.Remark.Valid {
|
||||
stepInfo.Remark = s.Remark.String
|
||||
}
|
||||
info.ProcessSteps = append(info.ProcessSteps, stepInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// Load inbound records
|
||||
records, _, err := l.svcCtx.InboundModel.FindByPlanId(l.ctx, in.PlanId, 1, 100)
|
||||
if err == nil {
|
||||
for _, r := range records {
|
||||
rec := &pb.InboundRecordInfo{
|
||||
RecordId: r.RecordId,
|
||||
TenantId: r.TenantId,
|
||||
PlanId: r.PlanId,
|
||||
ProductId: r.ProductId,
|
||||
BatchNo: r.BatchNo,
|
||||
Quantity: fmt.Sprintf("%.2f", r.Quantity),
|
||||
Rolls: r.Rolls,
|
||||
PricePerMeter: fmt.Sprintf("%.2f", r.PricePerMeter),
|
||||
OperatorId: r.OperatorId,
|
||||
CreatedAt: r.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if r.Remark.Valid {
|
||||
rec.Remark = r.Remark.String
|
||||
}
|
||||
info.InboundRecords = append(info.InboundRecords, rec)
|
||||
}
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
58
rpc/production/internal/logic/getsharelinklogic.go
Normal file
58
rpc/production/internal/logic/getsharelinklogic.go
Normal file
@ -0,0 +1,58 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetShareLinkLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetShareLinkLogic {
|
||||
return &GetShareLinkLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *GetShareLinkLogic) GetShareLink(in *pb.GetShareLinkReq) (*pb.ShareLinkInfo, error) {
|
||||
link, err := l.svcCtx.ShareLinkModel.FindByShortCode(l.ctx, in.ShortCode)
|
||||
if err != nil {
|
||||
return nil, ErrLinkNotFound
|
||||
}
|
||||
|
||||
// Check if expired
|
||||
if time.Now().After(link.ExpiresAt) {
|
||||
return nil, ErrLinkExpired
|
||||
}
|
||||
|
||||
info := &pb.ShareLinkInfo{
|
||||
LinkId: link.LinkId,
|
||||
TenantId: link.TenantId,
|
||||
PlanId: link.PlanId,
|
||||
ShortCode: link.ShortCode,
|
||||
Token: link.Token,
|
||||
FactoryType: link.FactoryType,
|
||||
HideSensitive: link.HideSensitive,
|
||||
Status: link.Status,
|
||||
ClickCount: link.ClickCount,
|
||||
RejectReason: link.RejectReason,
|
||||
ExpiresAt: link.ExpiresAt.Format("2006-01-02 15:04:05"),
|
||||
CreatedBy: link.CreatedBy,
|
||||
CreatedAt: link.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: link.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if link.ClickedAt.Valid {
|
||||
info.ClickedAt = link.ClickedAt.Time.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
if link.RespondedAt.Valid {
|
||||
info.RespondedAt = link.RespondedAt.Time.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
111
rpc/production/internal/logic/getsharelinkplanviewlogic.go
Normal file
111
rpc/production/internal/logic/getsharelinkplanviewlogic.go
Normal file
@ -0,0 +1,111 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetShareLinkPlanViewLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetShareLinkPlanViewLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetShareLinkPlanViewLogic {
|
||||
return &GetShareLinkPlanViewLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *GetShareLinkPlanViewLogic) GetShareLinkPlanView(in *pb.GetShareLinkReq) (*pb.ShareLinkPlanView, error) {
|
||||
link, err := l.svcCtx.ShareLinkModel.FindByShortCode(l.ctx, in.ShortCode)
|
||||
if err != nil {
|
||||
return nil, ErrLinkNotFound
|
||||
}
|
||||
|
||||
// Check if expired
|
||||
if time.Now().After(link.ExpiresAt) {
|
||||
return nil, ErrLinkExpired
|
||||
}
|
||||
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, link.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
|
||||
planInfo := &pb.ProductionPlanInfo{
|
||||
PlanId: plan.PlanId,
|
||||
PlanCode: plan.PlanCode,
|
||||
ProductId: plan.ProductId,
|
||||
ProductName: plan.ProductName,
|
||||
Color: plan.Color,
|
||||
FabricCode: plan.FabricCode,
|
||||
ColorCode: plan.ColorCode,
|
||||
TargetQuantity: fmt.Sprintf("%.2f", plan.TargetQuantity),
|
||||
CompletedQuantity: fmt.Sprintf("%.2f", plan.CompletedQuantity),
|
||||
Status: plan.Status,
|
||||
CreatedAt: plan.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if plan.StartTime.Valid {
|
||||
planInfo.StartTime = plan.StartTime.Time.Format("2006-01-02")
|
||||
}
|
||||
|
||||
// If hide_sensitive is set, mask price/supplier info
|
||||
if link.HideSensitive == 0 {
|
||||
planInfo.YarnUsagePerMeter = fmt.Sprintf("%.4f", plan.YarnUsagePerMeter)
|
||||
planInfo.ProductionPrice = fmt.Sprintf("%.2f", plan.ProductionPrice)
|
||||
planInfo.SupplierId = plan.SupplierId
|
||||
}
|
||||
|
||||
// Load yarn ratios
|
||||
ratios, err := l.svcCtx.YarnRatioModel.FindByPlanId(l.ctx, link.PlanId)
|
||||
if err == nil {
|
||||
for _, r := range ratios {
|
||||
planInfo.YarnRatios = append(planInfo.YarnRatios, &pb.YarnRatioInfo{
|
||||
RatioId: r.RatioId,
|
||||
PlanId: r.PlanId,
|
||||
YarnName: r.YarnName,
|
||||
Ratio: fmt.Sprintf("%.2f", r.Ratio),
|
||||
AmountPerMeter: fmt.Sprintf("%.4f", r.AmountPerMeter),
|
||||
TotalAmount: fmt.Sprintf("%.2f", r.TotalAmount),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Load process steps
|
||||
steps, err := l.svcCtx.ProcessStepModel.FindByPlanId(l.ctx, link.PlanId)
|
||||
if err == nil {
|
||||
for _, s := range steps {
|
||||
stepInfo := &pb.ProcessStepInfo{
|
||||
StepId: s.StepId,
|
||||
PlanId: s.PlanId,
|
||||
StepType: s.StepType,
|
||||
StepOrder: s.StepOrder,
|
||||
Status: s.Status,
|
||||
}
|
||||
if s.CompletedAt.Valid {
|
||||
stepInfo.CompletedAt = s.CompletedAt.Time.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
planInfo.ProcessSteps = append(planInfo.ProcessSteps, stepInfo)
|
||||
}
|
||||
}
|
||||
|
||||
linkInfo := &pb.ShareLinkInfo{
|
||||
LinkId: link.LinkId,
|
||||
PlanId: link.PlanId,
|
||||
ShortCode: link.ShortCode,
|
||||
FactoryType: link.FactoryType,
|
||||
HideSensitive: link.HideSensitive,
|
||||
Status: link.Status,
|
||||
ExpiresAt: link.ExpiresAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
return &pb.ShareLinkPlanView{
|
||||
Plan: planInfo,
|
||||
Link: linkInfo,
|
||||
}, nil
|
||||
}
|
||||
84
rpc/production/internal/logic/listinboundlogic.go
Normal file
84
rpc/production/internal/logic/listinboundlogic.go
Normal file
@ -0,0 +1,84 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListInboundLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewListInboundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListInboundLogic {
|
||||
return &ListInboundLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *ListInboundLogic) ListInbound(in *pb.ListInboundReq) (*pb.ListInboundResp, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
// Verify requester has access to this plan (owner or associated factory)
|
||||
plan, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId)
|
||||
if err != nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
if plan.TenantId != tenantId {
|
||||
factories, fErr := l.svcCtx.PlanFactoryModel.FindByPlanId(l.ctx, in.PlanId)
|
||||
if fErr != nil {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
authorized := false
|
||||
for _, f := range factories {
|
||||
if f.FactoryTenantId == tenantId {
|
||||
authorized = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !authorized {
|
||||
return nil, ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
|
||||
page := in.Page
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
pageSize := in.PageSize
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
|
||||
records, total, err := l.svcCtx.InboundModel.FindByPlanId(l.ctx, in.PlanId, page, pageSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := make([]*pb.InboundRecordInfo, 0, len(records))
|
||||
for _, r := range records {
|
||||
list = append(list, &pb.InboundRecordInfo{
|
||||
RecordId: r.RecordId,
|
||||
TenantId: r.TenantId,
|
||||
PlanId: r.PlanId,
|
||||
ProductId: r.ProductId,
|
||||
BatchNo: r.BatchNo,
|
||||
Quantity: fmt.Sprintf("%.2f", r.Quantity),
|
||||
Rolls: r.Rolls,
|
||||
PricePerMeter: fmt.Sprintf("%.2f", r.PricePerMeter),
|
||||
OperatorId: r.OperatorId,
|
||||
Remark: r.Remark.String,
|
||||
CreatedAt: r.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ListInboundResp{
|
||||
Total: total,
|
||||
List: list,
|
||||
}, nil
|
||||
}
|
||||
74
rpc/production/internal/logic/listproductionplanlogic.go
Normal file
74
rpc/production/internal/logic/listproductionplanlogic.go
Normal file
@ -0,0 +1,74 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"muyu-apiserver/pkg/tenantctx"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListProductionPlanLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewListProductionPlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListProductionPlanLogic {
|
||||
return &ListProductionPlanLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *ListProductionPlanLogic) ListProductionPlan(in *pb.ListProductionPlanReq) (*pb.ListProductionPlanResp, error) {
|
||||
tenantId := tenantctx.ExtractTenantId(l.ctx)
|
||||
|
||||
page := in.Page
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
pageSize := in.PageSize
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
|
||||
plans, total, err := l.svcCtx.PlanModel.FindList(l.ctx, tenantId, page, pageSize, in.Status, in.ProductName, in.PlanCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := make([]*pb.ProductionPlanInfo, 0, len(plans))
|
||||
for _, p := range plans {
|
||||
info := &pb.ProductionPlanInfo{
|
||||
PlanId: p.PlanId,
|
||||
TenantId: p.TenantId,
|
||||
PlanCode: p.PlanCode,
|
||||
ProductId: p.ProductId,
|
||||
ProductName: p.ProductName,
|
||||
Color: p.Color,
|
||||
FabricCode: p.FabricCode,
|
||||
ColorCode: p.ColorCode,
|
||||
TargetQuantity: fmt.Sprintf("%.2f", p.TargetQuantity),
|
||||
CompletedQuantity: fmt.Sprintf("%.2f", p.CompletedQuantity),
|
||||
YarnUsagePerMeter: fmt.Sprintf("%.4f", p.YarnUsagePerMeter),
|
||||
ProductionPrice: fmt.Sprintf("%.2f", p.ProductionPrice),
|
||||
SupplierId: p.SupplierId,
|
||||
Status: p.Status,
|
||||
Remark: p.Remark.String,
|
||||
Creator: p.Creator,
|
||||
Operator: p.Operator,
|
||||
CreatedAt: p.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: p.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
if p.StartTime.Valid {
|
||||
info.StartTime = p.StartTime.Time.Format("2006-01-02")
|
||||
}
|
||||
list = append(list, info)
|
||||
}
|
||||
|
||||
return &pb.ListProductionPlanResp{
|
||||
Total: total,
|
||||
List: list,
|
||||
}, nil
|
||||
}
|
||||
45
rpc/production/internal/logic/rejectsharelinklogic.go
Normal file
45
rpc/production/internal/logic/rejectsharelinklogic.go
Normal file
@ -0,0 +1,45 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type RejectShareLinkLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewRejectShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RejectShareLinkLogic {
|
||||
return &RejectShareLinkLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)}
|
||||
}
|
||||
|
||||
func (l *RejectShareLinkLogic) RejectShareLink(in *pb.RejectShareLinkReq) (*pb.Empty, error) {
|
||||
link, err := l.svcCtx.ShareLinkModel.FindByShortCode(l.ctx, in.ShortCode)
|
||||
if err != nil {
|
||||
return nil, ErrLinkNotFound
|
||||
}
|
||||
|
||||
// Check not expired
|
||||
if time.Now().After(link.ExpiresAt) {
|
||||
return nil, ErrLinkExpired
|
||||
}
|
||||
|
||||
// Check status is 0 (created) or 1 (clicked)
|
||||
if link.Status != 0 && link.Status != 1 {
|
||||
return nil, ErrLinkAlreadyUsed
|
||||
}
|
||||
|
||||
// Update status to 3 (rejected) with reason
|
||||
if err := l.svcCtx.ShareLinkModel.UpdateStatus(l.ctx, in.ShortCode, 3, in.RejectReason); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
83
rpc/production/internal/server/productionserviceserver.go
Normal file
83
rpc/production/internal/server/productionserviceserver.go
Normal file
@ -0,0 +1,83 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/rpc/production/internal/logic"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
)
|
||||
|
||||
type ProductionServiceServer struct {
|
||||
svcCtx *svc.ServiceContext
|
||||
pb.UnimplementedProductionServiceServer
|
||||
}
|
||||
|
||||
func NewProductionServiceServer(svcCtx *svc.ServiceContext) *ProductionServiceServer {
|
||||
return &ProductionServiceServer{svcCtx: svcCtx}
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) CreateProductionPlan(ctx context.Context, in *pb.CreateProductionPlanReq) (*pb.IdResp, error) {
|
||||
l := logic.NewCreateProductionPlanLogic(ctx, s.svcCtx)
|
||||
return l.CreateProductionPlan(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) ListProductionPlan(ctx context.Context, in *pb.ListProductionPlanReq) (*pb.ListProductionPlanResp, error) {
|
||||
l := logic.NewListProductionPlanLogic(ctx, s.svcCtx)
|
||||
return l.ListProductionPlan(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) GetProductionPlan(ctx context.Context, in *pb.GetProductionPlanReq) (*pb.ProductionPlanInfo, error) {
|
||||
l := logic.NewGetProductionPlanLogic(ctx, s.svcCtx)
|
||||
return l.GetProductionPlan(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) ConfirmPlan(ctx context.Context, in *pb.ConfirmPlanReq) (*pb.Empty, error) {
|
||||
l := logic.NewConfirmPlanLogic(ctx, s.svcCtx)
|
||||
return l.ConfirmPlan(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) CreateShareLink(ctx context.Context, in *pb.CreateShareLinkReq) (*pb.ShareLinkInfo, error) {
|
||||
l := logic.NewCreateShareLinkLogic(ctx, s.svcCtx)
|
||||
return l.CreateShareLink(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) GetShareLink(ctx context.Context, in *pb.GetShareLinkReq) (*pb.ShareLinkInfo, error) {
|
||||
l := logic.NewGetShareLinkLogic(ctx, s.svcCtx)
|
||||
return l.GetShareLink(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) GetShareLinkPlanView(ctx context.Context, in *pb.GetShareLinkReq) (*pb.ShareLinkPlanView, error) {
|
||||
l := logic.NewGetShareLinkPlanViewLogic(ctx, s.svcCtx)
|
||||
return l.GetShareLinkPlanView(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) ClickShareLink(ctx context.Context, in *pb.ClickShareLinkReq) (*pb.Empty, error) {
|
||||
l := logic.NewClickShareLinkLogic(ctx, s.svcCtx)
|
||||
return l.ClickShareLink(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) ConfirmShareLink(ctx context.Context, in *pb.ConfirmShareLinkReq) (*pb.Empty, error) {
|
||||
l := logic.NewConfirmShareLinkLogic(ctx, s.svcCtx)
|
||||
return l.ConfirmShareLink(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) RejectShareLink(ctx context.Context, in *pb.RejectShareLinkReq) (*pb.Empty, error) {
|
||||
l := logic.NewRejectShareLinkLogic(ctx, s.svcCtx)
|
||||
return l.RejectShareLink(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) CompleteStep(ctx context.Context, in *pb.CompleteStepReq) (*pb.Empty, error) {
|
||||
l := logic.NewCompleteStepLogic(ctx, s.svcCtx)
|
||||
return l.CompleteStep(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) CreateInbound(ctx context.Context, in *pb.CreateInboundReq) (*pb.IdResp, error) {
|
||||
l := logic.NewCreateInboundLogic(ctx, s.svcCtx)
|
||||
return l.CreateInbound(in)
|
||||
}
|
||||
|
||||
func (s *ProductionServiceServer) ListInbound(ctx context.Context, in *pb.ListInboundReq) (*pb.ListInboundResp, error) {
|
||||
l := logic.NewListInboundLogic(ctx, s.svcCtx)
|
||||
return l.ListInbound(in)
|
||||
}
|
||||
35
rpc/production/internal/svc/servicecontext.go
Normal file
35
rpc/production/internal/svc/servicecontext.go
Normal file
@ -0,0 +1,35 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"muyu-apiserver/model"
|
||||
"muyu-apiserver/rpc/production/internal/config"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
Conn sqlx.SqlConn
|
||||
PlanModel model.ProProductionPlanModel
|
||||
YarnRatioModel model.ProPlanYarnRatioModel
|
||||
ProcessStepModel model.ProPlanProcessStepModel
|
||||
ShareLinkModel model.ProShareLinkModel
|
||||
PlanFactoryModel model.ProPlanFactoryModel
|
||||
InboundModel model.ProInboundRecordModel
|
||||
InventoryLogModel model.InvInventoryLogModel
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
conn := sqlx.NewMysql(c.DataSource)
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
Conn: conn,
|
||||
PlanModel: model.NewProProductionPlanModel(conn, c.Cache),
|
||||
YarnRatioModel: model.NewProPlanYarnRatioModel(conn),
|
||||
ProcessStepModel: model.NewProPlanProcessStepModel(conn),
|
||||
ShareLinkModel: model.NewProShareLinkModel(conn),
|
||||
PlanFactoryModel: model.NewProPlanFactoryModel(conn),
|
||||
InboundModel: model.NewProInboundRecordModel(conn),
|
||||
InventoryLogModel: model.NewInvInventoryLogModel(conn),
|
||||
}
|
||||
}
|
||||
2813
rpc/production/pb/production.pb.go
Normal file
2813
rpc/production/pb/production.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
577
rpc/production/pb/production_grpc.pb.go
Normal file
577
rpc/production/pb/production_grpc.pb.go
Normal file
@ -0,0 +1,577 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v7.35.1
|
||||
// source: rpc/production/production.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
ProductionService_CreateProductionPlan_FullMethodName = "/production.ProductionService/CreateProductionPlan"
|
||||
ProductionService_ListProductionPlan_FullMethodName = "/production.ProductionService/ListProductionPlan"
|
||||
ProductionService_GetProductionPlan_FullMethodName = "/production.ProductionService/GetProductionPlan"
|
||||
ProductionService_ConfirmPlan_FullMethodName = "/production.ProductionService/ConfirmPlan"
|
||||
ProductionService_CreateShareLink_FullMethodName = "/production.ProductionService/CreateShareLink"
|
||||
ProductionService_GetShareLink_FullMethodName = "/production.ProductionService/GetShareLink"
|
||||
ProductionService_GetShareLinkPlanView_FullMethodName = "/production.ProductionService/GetShareLinkPlanView"
|
||||
ProductionService_ClickShareLink_FullMethodName = "/production.ProductionService/ClickShareLink"
|
||||
ProductionService_ConfirmShareLink_FullMethodName = "/production.ProductionService/ConfirmShareLink"
|
||||
ProductionService_RejectShareLink_FullMethodName = "/production.ProductionService/RejectShareLink"
|
||||
ProductionService_CompleteStep_FullMethodName = "/production.ProductionService/CompleteStep"
|
||||
ProductionService_CreateInbound_FullMethodName = "/production.ProductionService/CreateInbound"
|
||||
ProductionService_ListInbound_FullMethodName = "/production.ProductionService/ListInbound"
|
||||
)
|
||||
|
||||
// ProductionServiceClient is the client API for ProductionService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ProductionServiceClient interface {
|
||||
CreateProductionPlan(ctx context.Context, in *CreateProductionPlanReq, opts ...grpc.CallOption) (*IdResp, error)
|
||||
ListProductionPlan(ctx context.Context, in *ListProductionPlanReq, opts ...grpc.CallOption) (*ListProductionPlanResp, error)
|
||||
GetProductionPlan(ctx context.Context, in *GetProductionPlanReq, opts ...grpc.CallOption) (*ProductionPlanInfo, error)
|
||||
ConfirmPlan(ctx context.Context, in *ConfirmPlanReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
CreateShareLink(ctx context.Context, in *CreateShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error)
|
||||
GetShareLink(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error)
|
||||
GetShareLinkPlanView(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkPlanView, error)
|
||||
ClickShareLink(ctx context.Context, in *ClickShareLinkReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
ConfirmShareLink(ctx context.Context, in *ConfirmShareLinkReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
RejectShareLink(ctx context.Context, in *RejectShareLinkReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
CompleteStep(ctx context.Context, in *CompleteStepReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
CreateInbound(ctx context.Context, in *CreateInboundReq, opts ...grpc.CallOption) (*IdResp, error)
|
||||
ListInbound(ctx context.Context, in *ListInboundReq, opts ...grpc.CallOption) (*ListInboundResp, error)
|
||||
}
|
||||
|
||||
type productionServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewProductionServiceClient(cc grpc.ClientConnInterface) ProductionServiceClient {
|
||||
return &productionServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) CreateProductionPlan(ctx context.Context, in *CreateProductionPlanReq, opts ...grpc.CallOption) (*IdResp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(IdResp)
|
||||
err := c.cc.Invoke(ctx, ProductionService_CreateProductionPlan_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) ListProductionPlan(ctx context.Context, in *ListProductionPlanReq, opts ...grpc.CallOption) (*ListProductionPlanResp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListProductionPlanResp)
|
||||
err := c.cc.Invoke(ctx, ProductionService_ListProductionPlan_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) GetProductionPlan(ctx context.Context, in *GetProductionPlanReq, opts ...grpc.CallOption) (*ProductionPlanInfo, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ProductionPlanInfo)
|
||||
err := c.cc.Invoke(ctx, ProductionService_GetProductionPlan_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) ConfirmPlan(ctx context.Context, in *ConfirmPlanReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Empty)
|
||||
err := c.cc.Invoke(ctx, ProductionService_ConfirmPlan_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) CreateShareLink(ctx context.Context, in *CreateShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ShareLinkInfo)
|
||||
err := c.cc.Invoke(ctx, ProductionService_CreateShareLink_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) GetShareLink(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ShareLinkInfo)
|
||||
err := c.cc.Invoke(ctx, ProductionService_GetShareLink_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) GetShareLinkPlanView(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkPlanView, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ShareLinkPlanView)
|
||||
err := c.cc.Invoke(ctx, ProductionService_GetShareLinkPlanView_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) ClickShareLink(ctx context.Context, in *ClickShareLinkReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Empty)
|
||||
err := c.cc.Invoke(ctx, ProductionService_ClickShareLink_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) ConfirmShareLink(ctx context.Context, in *ConfirmShareLinkReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Empty)
|
||||
err := c.cc.Invoke(ctx, ProductionService_ConfirmShareLink_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) RejectShareLink(ctx context.Context, in *RejectShareLinkReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Empty)
|
||||
err := c.cc.Invoke(ctx, ProductionService_RejectShareLink_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) CompleteStep(ctx context.Context, in *CompleteStepReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Empty)
|
||||
err := c.cc.Invoke(ctx, ProductionService_CompleteStep_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) CreateInbound(ctx context.Context, in *CreateInboundReq, opts ...grpc.CallOption) (*IdResp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(IdResp)
|
||||
err := c.cc.Invoke(ctx, ProductionService_CreateInbound_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *productionServiceClient) ListInbound(ctx context.Context, in *ListInboundReq, opts ...grpc.CallOption) (*ListInboundResp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListInboundResp)
|
||||
err := c.cc.Invoke(ctx, ProductionService_ListInbound_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ProductionServiceServer is the server API for ProductionService service.
|
||||
// All implementations must embed UnimplementedProductionServiceServer
|
||||
// for forward compatibility.
|
||||
type ProductionServiceServer interface {
|
||||
CreateProductionPlan(context.Context, *CreateProductionPlanReq) (*IdResp, error)
|
||||
ListProductionPlan(context.Context, *ListProductionPlanReq) (*ListProductionPlanResp, error)
|
||||
GetProductionPlan(context.Context, *GetProductionPlanReq) (*ProductionPlanInfo, error)
|
||||
ConfirmPlan(context.Context, *ConfirmPlanReq) (*Empty, error)
|
||||
CreateShareLink(context.Context, *CreateShareLinkReq) (*ShareLinkInfo, error)
|
||||
GetShareLink(context.Context, *GetShareLinkReq) (*ShareLinkInfo, error)
|
||||
GetShareLinkPlanView(context.Context, *GetShareLinkReq) (*ShareLinkPlanView, error)
|
||||
ClickShareLink(context.Context, *ClickShareLinkReq) (*Empty, error)
|
||||
ConfirmShareLink(context.Context, *ConfirmShareLinkReq) (*Empty, error)
|
||||
RejectShareLink(context.Context, *RejectShareLinkReq) (*Empty, error)
|
||||
CompleteStep(context.Context, *CompleteStepReq) (*Empty, error)
|
||||
CreateInbound(context.Context, *CreateInboundReq) (*IdResp, error)
|
||||
ListInbound(context.Context, *ListInboundReq) (*ListInboundResp, error)
|
||||
mustEmbedUnimplementedProductionServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedProductionServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedProductionServiceServer struct{}
|
||||
|
||||
func (UnimplementedProductionServiceServer) CreateProductionPlan(context.Context, *CreateProductionPlanReq) (*IdResp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateProductionPlan not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) ListProductionPlan(context.Context, *ListProductionPlanReq) (*ListProductionPlanResp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListProductionPlan not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) GetProductionPlan(context.Context, *GetProductionPlanReq) (*ProductionPlanInfo, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetProductionPlan not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) ConfirmPlan(context.Context, *ConfirmPlanReq) (*Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ConfirmPlan not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) CreateShareLink(context.Context, *CreateShareLinkReq) (*ShareLinkInfo, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateShareLink not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) GetShareLink(context.Context, *GetShareLinkReq) (*ShareLinkInfo, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetShareLink not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) GetShareLinkPlanView(context.Context, *GetShareLinkReq) (*ShareLinkPlanView, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetShareLinkPlanView not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) ClickShareLink(context.Context, *ClickShareLinkReq) (*Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ClickShareLink not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) ConfirmShareLink(context.Context, *ConfirmShareLinkReq) (*Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ConfirmShareLink not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) RejectShareLink(context.Context, *RejectShareLinkReq) (*Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RejectShareLink not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) CompleteStep(context.Context, *CompleteStepReq) (*Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CompleteStep not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) CreateInbound(context.Context, *CreateInboundReq) (*IdResp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateInbound not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) ListInbound(context.Context, *ListInboundReq) (*ListInboundResp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListInbound not implemented")
|
||||
}
|
||||
func (UnimplementedProductionServiceServer) mustEmbedUnimplementedProductionServiceServer() {}
|
||||
func (UnimplementedProductionServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeProductionServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ProductionServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeProductionServiceServer interface {
|
||||
mustEmbedUnimplementedProductionServiceServer()
|
||||
}
|
||||
|
||||
func RegisterProductionServiceServer(s grpc.ServiceRegistrar, srv ProductionServiceServer) {
|
||||
// If the following call pancis, it indicates UnimplementedProductionServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&ProductionService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ProductionService_CreateProductionPlan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateProductionPlanReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).CreateProductionPlan(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_CreateProductionPlan_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).CreateProductionPlan(ctx, req.(*CreateProductionPlanReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_ListProductionPlan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListProductionPlanReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).ListProductionPlan(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_ListProductionPlan_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).ListProductionPlan(ctx, req.(*ListProductionPlanReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_GetProductionPlan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetProductionPlanReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).GetProductionPlan(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_GetProductionPlan_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).GetProductionPlan(ctx, req.(*GetProductionPlanReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_ConfirmPlan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ConfirmPlanReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).ConfirmPlan(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_ConfirmPlan_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).ConfirmPlan(ctx, req.(*ConfirmPlanReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_CreateShareLink_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateShareLinkReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).CreateShareLink(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_CreateShareLink_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).CreateShareLink(ctx, req.(*CreateShareLinkReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_GetShareLink_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetShareLinkReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).GetShareLink(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_GetShareLink_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).GetShareLink(ctx, req.(*GetShareLinkReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_GetShareLinkPlanView_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetShareLinkReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).GetShareLinkPlanView(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_GetShareLinkPlanView_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).GetShareLinkPlanView(ctx, req.(*GetShareLinkReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_ClickShareLink_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ClickShareLinkReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).ClickShareLink(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_ClickShareLink_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).ClickShareLink(ctx, req.(*ClickShareLinkReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_ConfirmShareLink_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ConfirmShareLinkReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).ConfirmShareLink(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_ConfirmShareLink_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).ConfirmShareLink(ctx, req.(*ConfirmShareLinkReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_RejectShareLink_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RejectShareLinkReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).RejectShareLink(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_RejectShareLink_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).RejectShareLink(ctx, req.(*RejectShareLinkReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_CompleteStep_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CompleteStepReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).CompleteStep(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_CompleteStep_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).CompleteStep(ctx, req.(*CompleteStepReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_CreateInbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateInboundReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).CreateInbound(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_CreateInbound_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).CreateInbound(ctx, req.(*CreateInboundReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ProductionService_ListInbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListInboundReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ProductionServiceServer).ListInbound(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ProductionService_ListInbound_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ProductionServiceServer).ListInbound(ctx, req.(*ListInboundReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ProductionService_ServiceDesc is the grpc.ServiceDesc for ProductionService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ProductionService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "production.ProductionService",
|
||||
HandlerType: (*ProductionServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "CreateProductionPlan",
|
||||
Handler: _ProductionService_CreateProductionPlan_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListProductionPlan",
|
||||
Handler: _ProductionService_ListProductionPlan_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetProductionPlan",
|
||||
Handler: _ProductionService_GetProductionPlan_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ConfirmPlan",
|
||||
Handler: _ProductionService_ConfirmPlan_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateShareLink",
|
||||
Handler: _ProductionService_CreateShareLink_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetShareLink",
|
||||
Handler: _ProductionService_GetShareLink_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetShareLinkPlanView",
|
||||
Handler: _ProductionService_GetShareLinkPlanView_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ClickShareLink",
|
||||
Handler: _ProductionService_ClickShareLink_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ConfirmShareLink",
|
||||
Handler: _ProductionService_ConfirmShareLink_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RejectShareLink",
|
||||
Handler: _ProductionService_RejectShareLink_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CompleteStep",
|
||||
Handler: _ProductionService_CompleteStep_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateInbound",
|
||||
Handler: _ProductionService_CreateInbound_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListInbound",
|
||||
Handler: _ProductionService_ListInbound_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "rpc/production/production.proto",
|
||||
}
|
||||
43
rpc/production/production.go
Normal file
43
rpc/production/production.go
Normal file
@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"muyu-apiserver/pkg/metrics"
|
||||
"muyu-apiserver/rpc/production/internal/config"
|
||||
"muyu-apiserver/rpc/production/internal/server"
|
||||
"muyu-apiserver/rpc/production/internal/svc"
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/core/service"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/production.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
ctx := svc.NewServiceContext(c)
|
||||
|
||||
metrics.StartHTTP(c.PrometheusAddr)
|
||||
|
||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||
pb.RegisterProductionServiceServer(grpcServer, server.NewProductionServiceServer(ctx))
|
||||
|
||||
if c.Mode == service.DevMode || c.Mode == service.TestMode {
|
||||
reflection.Register(grpcServer)
|
||||
}
|
||||
})
|
||||
s.AddUnaryInterceptors(metrics.UnaryServerInterceptor())
|
||||
defer s.Stop()
|
||||
|
||||
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
|
||||
s.Start()
|
||||
}
|
||||
242
rpc/production/production.proto
Normal file
242
rpc/production/production.proto
Normal file
@ -0,0 +1,242 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package production;
|
||||
|
||||
option go_package = "./pb";
|
||||
|
||||
// ==================== Common ====================
|
||||
|
||||
message IdResp {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message Empty {}
|
||||
|
||||
// ==================== ProductionPlan ====================
|
||||
|
||||
message ProductionPlanInfo {
|
||||
string plan_id = 1;
|
||||
string tenant_id = 2;
|
||||
string plan_code = 3;
|
||||
string product_id = 4;
|
||||
string product_name = 5;
|
||||
string color = 6;
|
||||
string fabric_code = 7;
|
||||
string color_code = 8;
|
||||
string target_quantity = 9;
|
||||
string completed_quantity = 10;
|
||||
string yarn_usage_per_meter = 11;
|
||||
string production_price = 12;
|
||||
string supplier_id = 13;
|
||||
int64 status = 14;
|
||||
string remark = 15;
|
||||
string start_time = 16;
|
||||
string creator = 17;
|
||||
string operator = 18;
|
||||
string created_at = 19;
|
||||
string updated_at = 20;
|
||||
repeated YarnRatioInfo yarn_ratios = 21;
|
||||
repeated ProcessStepInfo process_steps = 22;
|
||||
repeated InboundRecordInfo inbound_records = 23;
|
||||
}
|
||||
|
||||
message CreateProductionPlanReq {
|
||||
string tenant_id = 1;
|
||||
string product_id = 2;
|
||||
string product_name = 3;
|
||||
string color = 4;
|
||||
string fabric_code = 5;
|
||||
string color_code = 6;
|
||||
string target_quantity = 7;
|
||||
string yarn_usage_per_meter = 8;
|
||||
string production_price = 9;
|
||||
string supplier_id = 10;
|
||||
string remark = 11;
|
||||
string start_time = 12;
|
||||
string creator = 13;
|
||||
repeated YarnRatioReq yarn_ratios = 14;
|
||||
repeated ProcessStepReq process_steps = 15;
|
||||
}
|
||||
|
||||
message ListProductionPlanReq {
|
||||
string tenant_id = 1;
|
||||
int64 page = 2;
|
||||
int64 page_size = 3;
|
||||
int64 status = 4;
|
||||
string product_name = 5;
|
||||
string plan_code = 6;
|
||||
}
|
||||
|
||||
message ListProductionPlanResp {
|
||||
int64 total = 1;
|
||||
repeated ProductionPlanInfo list = 2;
|
||||
}
|
||||
|
||||
message GetProductionPlanReq {
|
||||
string plan_id = 1;
|
||||
}
|
||||
|
||||
message ConfirmPlanReq {
|
||||
string plan_id = 1;
|
||||
string operator = 2;
|
||||
}
|
||||
|
||||
// ==================== YarnRatio ====================
|
||||
|
||||
message YarnRatioInfo {
|
||||
string ratio_id = 1;
|
||||
string plan_id = 2;
|
||||
string yarn_name = 3;
|
||||
string ratio = 4;
|
||||
string amount_per_meter = 5;
|
||||
string total_amount = 6;
|
||||
string created_at = 7;
|
||||
}
|
||||
|
||||
message YarnRatioReq {
|
||||
string yarn_name = 1;
|
||||
string ratio = 2;
|
||||
string amount_per_meter = 3;
|
||||
string total_amount = 4;
|
||||
}
|
||||
|
||||
// ==================== ProcessStep ====================
|
||||
|
||||
message ProcessStepInfo {
|
||||
string step_id = 1;
|
||||
string plan_id = 2;
|
||||
string step_type = 3;
|
||||
int64 step_order = 4;
|
||||
int64 status = 5;
|
||||
string operator_id = 6;
|
||||
string completed_at = 7;
|
||||
string remark = 8;
|
||||
string created_at = 9;
|
||||
string updated_at = 10;
|
||||
}
|
||||
|
||||
message ProcessStepReq {
|
||||
string step_type = 1;
|
||||
int64 step_order = 2;
|
||||
string remark = 3;
|
||||
}
|
||||
|
||||
message CompleteStepReq {
|
||||
string plan_id = 1;
|
||||
string step_type = 2;
|
||||
string operator_id = 3;
|
||||
}
|
||||
|
||||
// ==================== ShareLink ====================
|
||||
|
||||
message ShareLinkInfo {
|
||||
string link_id = 1;
|
||||
string tenant_id = 2;
|
||||
string plan_id = 3;
|
||||
string short_code = 4;
|
||||
string token = 5;
|
||||
string factory_type = 6;
|
||||
int64 hide_sensitive = 7;
|
||||
int64 status = 8;
|
||||
int64 click_count = 9;
|
||||
string clicked_at = 10;
|
||||
string responded_at = 11;
|
||||
string reject_reason = 12;
|
||||
string expires_at = 13;
|
||||
string created_by = 14;
|
||||
string created_at = 15;
|
||||
string updated_at = 16;
|
||||
}
|
||||
|
||||
message ShareLinkPlanView {
|
||||
ProductionPlanInfo plan = 1;
|
||||
ShareLinkInfo link = 2;
|
||||
}
|
||||
|
||||
message CreateShareLinkReq {
|
||||
string tenant_id = 1;
|
||||
string plan_id = 2;
|
||||
string factory_type = 3;
|
||||
int64 hide_sensitive = 4;
|
||||
int64 expires_hours = 5;
|
||||
string created_by = 6;
|
||||
}
|
||||
|
||||
message GetShareLinkReq {
|
||||
string short_code = 1;
|
||||
string token = 2;
|
||||
}
|
||||
|
||||
message ClickShareLinkReq {
|
||||
string short_code = 1;
|
||||
}
|
||||
|
||||
message ConfirmShareLinkReq {
|
||||
string short_code = 1;
|
||||
string token = 2;
|
||||
string factory_tenant_id = 3;
|
||||
}
|
||||
|
||||
message RejectShareLinkReq {
|
||||
string short_code = 1;
|
||||
string token = 2;
|
||||
string reject_reason = 3;
|
||||
}
|
||||
|
||||
// ==================== Inbound ====================
|
||||
|
||||
message InboundRecordInfo {
|
||||
string record_id = 1;
|
||||
string tenant_id = 2;
|
||||
string plan_id = 3;
|
||||
string product_id = 4;
|
||||
string batch_no = 5;
|
||||
string quantity = 6;
|
||||
int64 rolls = 7;
|
||||
string price_per_meter = 8;
|
||||
string operator_id = 9;
|
||||
string remark = 10;
|
||||
string created_at = 11;
|
||||
}
|
||||
|
||||
message CreateInboundReq {
|
||||
string tenant_id = 1;
|
||||
string plan_id = 2;
|
||||
string product_id = 3;
|
||||
string batch_no = 4;
|
||||
string quantity = 5;
|
||||
int64 rolls = 6;
|
||||
string price_per_meter = 7;
|
||||
string operator_id = 8;
|
||||
string remark = 9;
|
||||
}
|
||||
|
||||
message ListInboundReq {
|
||||
string tenant_id = 1;
|
||||
string plan_id = 2;
|
||||
int64 page = 3;
|
||||
int64 page_size = 4;
|
||||
}
|
||||
|
||||
message ListInboundResp {
|
||||
int64 total = 1;
|
||||
repeated InboundRecordInfo list = 2;
|
||||
}
|
||||
|
||||
// ==================== Service ====================
|
||||
|
||||
service ProductionService {
|
||||
rpc CreateProductionPlan(CreateProductionPlanReq) returns (IdResp);
|
||||
rpc ListProductionPlan(ListProductionPlanReq) returns (ListProductionPlanResp);
|
||||
rpc GetProductionPlan(GetProductionPlanReq) returns (ProductionPlanInfo);
|
||||
rpc ConfirmPlan(ConfirmPlanReq) returns (Empty);
|
||||
rpc CreateShareLink(CreateShareLinkReq) returns (ShareLinkInfo);
|
||||
rpc GetShareLink(GetShareLinkReq) returns (ShareLinkInfo);
|
||||
rpc GetShareLinkPlanView(GetShareLinkReq) returns (ShareLinkPlanView);
|
||||
rpc ClickShareLink(ClickShareLinkReq) returns (Empty);
|
||||
rpc ConfirmShareLink(ConfirmShareLinkReq) returns (Empty);
|
||||
rpc RejectShareLink(RejectShareLinkReq) returns (Empty);
|
||||
rpc CompleteStep(CompleteStepReq) returns (Empty);
|
||||
rpc CreateInbound(CreateInboundReq) returns (IdResp);
|
||||
rpc ListInbound(ListInboundReq) returns (ListInboundResp);
|
||||
}
|
||||
113
rpc/production/productionservice/productionservice.go
Normal file
113
rpc/production/productionservice/productionservice.go
Normal file
@ -0,0 +1,113 @@
|
||||
package productionservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"muyu-apiserver/rpc/production/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type (
|
||||
CreateProductionPlanReq = pb.CreateProductionPlanReq
|
||||
ListProductionPlanReq = pb.ListProductionPlanReq
|
||||
ListProductionPlanResp = pb.ListProductionPlanResp
|
||||
GetProductionPlanReq = pb.GetProductionPlanReq
|
||||
ProductionPlanInfo = pb.ProductionPlanInfo
|
||||
ConfirmPlanReq = pb.ConfirmPlanReq
|
||||
CreateShareLinkReq = pb.CreateShareLinkReq
|
||||
GetShareLinkReq = pb.GetShareLinkReq
|
||||
ShareLinkInfo = pb.ShareLinkInfo
|
||||
ShareLinkPlanView = pb.ShareLinkPlanView
|
||||
ClickShareLinkReq = pb.ClickShareLinkReq
|
||||
ConfirmShareLinkReq = pb.ConfirmShareLinkReq
|
||||
RejectShareLinkReq = pb.RejectShareLinkReq
|
||||
CompleteStepReq = pb.CompleteStepReq
|
||||
CreateInboundReq = pb.CreateInboundReq
|
||||
ListInboundReq = pb.ListInboundReq
|
||||
ListInboundResp = pb.ListInboundResp
|
||||
InboundRecordInfo = pb.InboundRecordInfo
|
||||
YarnRatioInfo = pb.YarnRatioInfo
|
||||
YarnRatioReq = pb.YarnRatioReq
|
||||
ProcessStepInfo = pb.ProcessStepInfo
|
||||
ProcessStepReq = pb.ProcessStepReq
|
||||
IdResp = pb.IdResp
|
||||
Empty = pb.Empty
|
||||
|
||||
ProductionService interface {
|
||||
CreateProductionPlan(ctx context.Context, in *CreateProductionPlanReq, opts ...grpc.CallOption) (*IdResp, error)
|
||||
ListProductionPlan(ctx context.Context, in *ListProductionPlanReq, opts ...grpc.CallOption) (*ListProductionPlanResp, error)
|
||||
GetProductionPlan(ctx context.Context, in *GetProductionPlanReq, opts ...grpc.CallOption) (*ProductionPlanInfo, error)
|
||||
ConfirmPlan(ctx context.Context, in *ConfirmPlanReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
CreateShareLink(ctx context.Context, in *CreateShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error)
|
||||
GetShareLink(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error)
|
||||
GetShareLinkPlanView(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkPlanView, error)
|
||||
ClickShareLink(ctx context.Context, in *ClickShareLinkReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
ConfirmShareLink(ctx context.Context, in *ConfirmShareLinkReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
RejectShareLink(ctx context.Context, in *RejectShareLinkReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
CompleteStep(ctx context.Context, in *CompleteStepReq, opts ...grpc.CallOption) (*Empty, error)
|
||||
CreateInbound(ctx context.Context, in *CreateInboundReq, opts ...grpc.CallOption) (*IdResp, error)
|
||||
ListInbound(ctx context.Context, in *ListInboundReq, opts ...grpc.CallOption) (*ListInboundResp, error)
|
||||
}
|
||||
|
||||
defaultProductionService struct {
|
||||
cli zrpc.Client
|
||||
}
|
||||
)
|
||||
|
||||
func NewProductionService(cli zrpc.Client) ProductionService {
|
||||
return &defaultProductionService{cli: cli}
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) CreateProductionPlan(ctx context.Context, in *CreateProductionPlanReq, opts ...grpc.CallOption) (*IdResp, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).CreateProductionPlan(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) ListProductionPlan(ctx context.Context, in *ListProductionPlanReq, opts ...grpc.CallOption) (*ListProductionPlanResp, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).ListProductionPlan(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) GetProductionPlan(ctx context.Context, in *GetProductionPlanReq, opts ...grpc.CallOption) (*ProductionPlanInfo, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).GetProductionPlan(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) ConfirmPlan(ctx context.Context, in *ConfirmPlanReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).ConfirmPlan(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) CreateShareLink(ctx context.Context, in *CreateShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).CreateShareLink(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) GetShareLink(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkInfo, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).GetShareLink(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) GetShareLinkPlanView(ctx context.Context, in *GetShareLinkReq, opts ...grpc.CallOption) (*ShareLinkPlanView, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).GetShareLinkPlanView(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) ClickShareLink(ctx context.Context, in *ClickShareLinkReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).ClickShareLink(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) ConfirmShareLink(ctx context.Context, in *ConfirmShareLinkReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).ConfirmShareLink(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) RejectShareLink(ctx context.Context, in *RejectShareLinkReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).RejectShareLink(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) CompleteStep(ctx context.Context, in *CompleteStepReq, opts ...grpc.CallOption) (*Empty, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).CompleteStep(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) CreateInbound(ctx context.Context, in *CreateInboundReq, opts ...grpc.CallOption) (*IdResp, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).CreateInbound(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultProductionService) ListInbound(ctx context.Context, in *ListInboundReq, opts ...grpc.CallOption) (*ListInboundResp, error) {
|
||||
return pb.NewProductionServiceClient(m.cli.Conn()).ListInbound(ctx, in, opts...)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user