diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d187858..b7884ff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 diff --git a/deploy/Dockerfile.production b/deploy/Dockerfile.production new file mode 100644 index 0000000..eab1702 --- /dev/null +++ b/deploy/Dockerfile.production @@ -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"] diff --git a/deploy/Dockerfile.purchase b/deploy/Dockerfile.purchase index c63bb1a..9ad5558 100644 --- a/deploy/Dockerfile.purchase +++ b/deploy/Dockerfile.purchase @@ -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 diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml index 1429ac1..d251554 100644 --- a/deploy/docker-compose.yaml +++ b/deploy/docker-compose.yaml @@ -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: diff --git a/deploy/etc/gateway.yaml b/deploy/etc/gateway.yaml index a67dc4b..9b16731 100644 --- a/deploy/etc/gateway.yaml +++ b/deploy/etc/gateway.yaml @@ -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 diff --git a/deploy/etc/production.yaml b/deploy/etc/production.yaml new file mode 100644 index 0000000..f658436 --- /dev/null +++ b/deploy/etc/production.yaml @@ -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 diff --git a/deploy/mysql/migrations/20260629_phase3_e2e_validation.sql b/deploy/mysql/migrations/20260629_phase3_e2e_validation.sql new file mode 100644 index 0000000..f7e7a2f --- /dev/null +++ b/deploy/mysql/migrations/20260629_phase3_e2e_validation.sql @@ -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; diff --git a/deploy/mysql/migrations/20260629_phase3_production_management.sql b/deploy/mysql/migrations/20260629_phase3_production_management.sql new file mode 100644 index 0000000..87e48a5 --- /dev/null +++ b/deploy/mysql/migrations/20260629_phase3_production_management.sql @@ -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='按计划分批入库'; diff --git a/gateway/internal/config/config.go b/gateway/internal/config/config.go index 4588aa2..14a363d 100644 --- a/gateway/internal/config/config.go +++ b/gateway/internal/config/config.go @@ -20,4 +20,5 @@ type Config struct { SystemRpc zrpc.RpcClientConf InventoryRpc zrpc.RpcClientConf PurchaseRpc zrpc.RpcClientConf + ProductionRpc zrpc.RpcClientConf } diff --git a/gateway/internal/handler/production/inbound/createinboundhandler.go b/gateway/internal/handler/production/inbound/createinboundhandler.go new file mode 100644 index 0000000..5d026b9 --- /dev/null +++ b/gateway/internal/handler/production/inbound/createinboundhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/inbound/listinboundhandler.go b/gateway/internal/handler/production/inbound/listinboundhandler.go new file mode 100644 index 0000000..7607bb8 --- /dev/null +++ b/gateway/internal/handler/production/inbound/listinboundhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/plan/confirmplanhandler.go b/gateway/internal/handler/production/plan/confirmplanhandler.go new file mode 100644 index 0000000..3ea1553 --- /dev/null +++ b/gateway/internal/handler/production/plan/confirmplanhandler.go @@ -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{}) + } + } +} diff --git a/gateway/internal/handler/production/plan/createproductionplanhandler.go b/gateway/internal/handler/production/plan/createproductionplanhandler.go new file mode 100644 index 0000000..8d609c4 --- /dev/null +++ b/gateway/internal/handler/production/plan/createproductionplanhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/plan/getproductionplanhandler.go b/gateway/internal/handler/production/plan/getproductionplanhandler.go new file mode 100644 index 0000000..e54979d --- /dev/null +++ b/gateway/internal/handler/production/plan/getproductionplanhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/plan/listproductionplanhandler.go b/gateway/internal/handler/production/plan/listproductionplanhandler.go new file mode 100644 index 0000000..67b0d73 --- /dev/null +++ b/gateway/internal/handler/production/plan/listproductionplanhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/process/completestephandler.go b/gateway/internal/handler/production/process/completestephandler.go new file mode 100644 index 0000000..eec2385 --- /dev/null +++ b/gateway/internal/handler/production/process/completestephandler.go @@ -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{}) + } + } +} diff --git a/gateway/internal/handler/production/share/clicksharelinkhandler.go b/gateway/internal/handler/production/share/clicksharelinkhandler.go new file mode 100644 index 0000000..0803a7d --- /dev/null +++ b/gateway/internal/handler/production/share/clicksharelinkhandler.go @@ -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{}) + } + } +} diff --git a/gateway/internal/handler/production/share/confirmsharelinkhandler.go b/gateway/internal/handler/production/share/confirmsharelinkhandler.go new file mode 100644 index 0000000..b945746 --- /dev/null +++ b/gateway/internal/handler/production/share/confirmsharelinkhandler.go @@ -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{}) + } + } +} diff --git a/gateway/internal/handler/production/share/createsharelinkhandler.go b/gateway/internal/handler/production/share/createsharelinkhandler.go new file mode 100644 index 0000000..5eb3591 --- /dev/null +++ b/gateway/internal/handler/production/share/createsharelinkhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/share/getsharelinkplanviewhandler.go b/gateway/internal/handler/production/share/getsharelinkplanviewhandler.go new file mode 100644 index 0000000..3e1b42e --- /dev/null +++ b/gateway/internal/handler/production/share/getsharelinkplanviewhandler.go @@ -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) + } + } +} diff --git a/gateway/internal/handler/production/share/rejectsharelinkhandler.go b/gateway/internal/handler/production/share/rejectsharelinkhandler.go new file mode 100644 index 0000000..20b9501 --- /dev/null +++ b/gateway/internal/handler/production/share/rejectsharelinkhandler.go @@ -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{}) + } + } +} diff --git a/gateway/internal/handler/routes.go b/gateway/internal/handler/routes.go index c674731..f0b2379 100644 --- a/gateway/internal/handler/routes.go +++ b/gateway/internal/handler/routes.go @@ -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"), + ) } diff --git a/gateway/internal/logic/production/inbound/createinboundlogic.go b/gateway/internal/logic/production/inbound/createinboundlogic.go new file mode 100644 index 0000000..a44bb02 --- /dev/null +++ b/gateway/internal/logic/production/inbound/createinboundlogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/inbound/listinboundlogic.go b/gateway/internal/logic/production/inbound/listinboundlogic.go new file mode 100644 index 0000000..4af5fa7 --- /dev/null +++ b/gateway/internal/logic/production/inbound/listinboundlogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/plan/confirmplanlogic.go b/gateway/internal/logic/production/plan/confirmplanlogic.go new file mode 100644 index 0000000..bd2be55 --- /dev/null +++ b/gateway/internal/logic/production/plan/confirmplanlogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/plan/createproductionplanlogic.go b/gateway/internal/logic/production/plan/createproductionplanlogic.go new file mode 100644 index 0000000..2655620 --- /dev/null +++ b/gateway/internal/logic/production/plan/createproductionplanlogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/plan/getproductionplanlogic.go b/gateway/internal/logic/production/plan/getproductionplanlogic.go new file mode 100644 index 0000000..d763a9f --- /dev/null +++ b/gateway/internal/logic/production/plan/getproductionplanlogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/plan/listproductionplanlogic.go b/gateway/internal/logic/production/plan/listproductionplanlogic.go new file mode 100644 index 0000000..3243dbc --- /dev/null +++ b/gateway/internal/logic/production/plan/listproductionplanlogic.go @@ -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, + } +} diff --git a/gateway/internal/logic/production/process/completesteplogic.go b/gateway/internal/logic/production/process/completesteplogic.go new file mode 100644 index 0000000..f3d790b --- /dev/null +++ b/gateway/internal/logic/production/process/completesteplogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/share/clicksharelinklogic.go b/gateway/internal/logic/production/share/clicksharelinklogic.go new file mode 100644 index 0000000..03ac599 --- /dev/null +++ b/gateway/internal/logic/production/share/clicksharelinklogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/share/confirmsharelinklogic.go b/gateway/internal/logic/production/share/confirmsharelinklogic.go new file mode 100644 index 0000000..13796d3 --- /dev/null +++ b/gateway/internal/logic/production/share/confirmsharelinklogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/share/convert.go b/gateway/internal/logic/production/share/convert.go new file mode 100644 index 0000000..83b3cd7 --- /dev/null +++ b/gateway/internal/logic/production/share/convert.go @@ -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, + } +} diff --git a/gateway/internal/logic/production/share/createsharelinklogic.go b/gateway/internal/logic/production/share/createsharelinklogic.go new file mode 100644 index 0000000..72faefc --- /dev/null +++ b/gateway/internal/logic/production/share/createsharelinklogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/share/getsharelinkplanviewlogic.go b/gateway/internal/logic/production/share/getsharelinkplanviewlogic.go new file mode 100644 index 0000000..44d5bb9 --- /dev/null +++ b/gateway/internal/logic/production/share/getsharelinkplanviewlogic.go @@ -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 +} diff --git a/gateway/internal/logic/production/share/rejectsharelinklogic.go b/gateway/internal/logic/production/share/rejectsharelinklogic.go new file mode 100644 index 0000000..90ca59d --- /dev/null +++ b/gateway/internal/logic/production/share/rejectsharelinklogic.go @@ -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 +} diff --git a/gateway/internal/svc/serviceContext.go b/gateway/internal/svc/serviceContext.go index f502e3e..3d28e33 100644 --- a/gateway/internal/svc/serviceContext.go +++ b/gateway/internal/svc/serviceContext.go @@ -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()))), } } diff --git a/gateway/internal/types/types.go b/gateway/internal/types/types.go index 60ecbc1..77e0e87 100644 --- a/gateway/internal/types/types.go +++ b/gateway/internal/types/types.go @@ -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"` +} diff --git a/model/proinboundrecordmodel.go b/model/proinboundrecordmodel.go new file mode 100644 index 0000000..86a828d --- /dev/null +++ b/model/proinboundrecordmodel.go @@ -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 +} diff --git a/model/proinboundrecordmodel_gen.go b/model/proinboundrecordmodel_gen.go new file mode 100644 index 0000000..d67cccd --- /dev/null +++ b/model/proinboundrecordmodel_gen.go @@ -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) +} diff --git a/model/proplanfactorymodel.go b/model/proplanfactorymodel.go new file mode 100644 index 0000000..5b9def1 --- /dev/null +++ b/model/proplanfactorymodel.go @@ -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 +} diff --git a/model/proplanfactorymodel_gen.go b/model/proplanfactorymodel_gen.go new file mode 100644 index 0000000..251cfcd --- /dev/null +++ b/model/proplanfactorymodel_gen.go @@ -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) +} diff --git a/model/proplanprocessstepmodel.go b/model/proplanprocessstepmodel.go new file mode 100644 index 0000000..38b871e --- /dev/null +++ b/model/proplanprocessstepmodel.go @@ -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 +} diff --git a/model/proplanprocessstepmodel_gen.go b/model/proplanprocessstepmodel_gen.go new file mode 100644 index 0000000..9870b2b --- /dev/null +++ b/model/proplanprocessstepmodel_gen.go @@ -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 +} diff --git a/model/proplanyarnratiomodel.go b/model/proplanyarnratiomodel.go new file mode 100644 index 0000000..67f9c8e --- /dev/null +++ b/model/proplanyarnratiomodel.go @@ -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 +} diff --git a/model/proplanyarnratiomodel_gen.go b/model/proplanyarnratiomodel_gen.go new file mode 100644 index 0000000..a076ed1 --- /dev/null +++ b/model/proplanyarnratiomodel_gen.go @@ -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 +} diff --git a/model/proproductionplanmodel.go b/model/proproductionplanmodel.go new file mode 100644 index 0000000..8d18a72 --- /dev/null +++ b/model/proproductionplanmodel.go @@ -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 +} diff --git a/model/proproductionplanmodel_gen.go b/model/proproductionplanmodel_gen.go new file mode 100644 index 0000000..72d572f --- /dev/null +++ b/model/proproductionplanmodel_gen.go @@ -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 +} diff --git a/model/prosharelinkmodel.go b/model/prosharelinkmodel.go new file mode 100644 index 0000000..6b8b28a --- /dev/null +++ b/model/prosharelinkmodel.go @@ -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 +} diff --git a/model/prosharelinkmodel_gen.go b/model/prosharelinkmodel_gen.go new file mode 100644 index 0000000..ba7e2fd --- /dev/null +++ b/model/prosharelinkmodel_gen.go @@ -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 +} diff --git a/rpc/production/internal/config/config.go b/rpc/production/internal/config/config.go new file mode 100644 index 0000000..822dde0 --- /dev/null +++ b/rpc/production/internal/config/config.go @@ -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"` +} diff --git a/rpc/production/internal/logic/clicksharelinklogic.go b/rpc/production/internal/logic/clicksharelinklogic.go new file mode 100644 index 0000000..8b4fb28 --- /dev/null +++ b/rpc/production/internal/logic/clicksharelinklogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/completesteplogic.go b/rpc/production/internal/logic/completesteplogic.go new file mode 100644 index 0000000..12f1eee --- /dev/null +++ b/rpc/production/internal/logic/completesteplogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/confirmplanlogic.go b/rpc/production/internal/logic/confirmplanlogic.go new file mode 100644 index 0000000..a72c1ca --- /dev/null +++ b/rpc/production/internal/logic/confirmplanlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/confirmsharelinklogic.go b/rpc/production/internal/logic/confirmsharelinklogic.go new file mode 100644 index 0000000..b18f9b9 --- /dev/null +++ b/rpc/production/internal/logic/confirmsharelinklogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/createinboundlogic.go b/rpc/production/internal/logic/createinboundlogic.go new file mode 100644 index 0000000..298a742 --- /dev/null +++ b/rpc/production/internal/logic/createinboundlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/createproductionplanlogic.go b/rpc/production/internal/logic/createproductionplanlogic.go new file mode 100644 index 0000000..f7557ab --- /dev/null +++ b/rpc/production/internal/logic/createproductionplanlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/createsharelinklogic.go b/rpc/production/internal/logic/createsharelinklogic.go new file mode 100644 index 0000000..e62fb16 --- /dev/null +++ b/rpc/production/internal/logic/createsharelinklogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/errors.go b/rpc/production/internal/logic/errors.go new file mode 100644 index 0000000..4eb991d --- /dev/null +++ b/rpc/production/internal/logic/errors.go @@ -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, "无权操作该生产计划") +) diff --git a/rpc/production/internal/logic/getproductionplanlogic.go b/rpc/production/internal/logic/getproductionplanlogic.go new file mode 100644 index 0000000..9e1ca75 --- /dev/null +++ b/rpc/production/internal/logic/getproductionplanlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/getsharelinklogic.go b/rpc/production/internal/logic/getsharelinklogic.go new file mode 100644 index 0000000..7542e3d --- /dev/null +++ b/rpc/production/internal/logic/getsharelinklogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/getsharelinkplanviewlogic.go b/rpc/production/internal/logic/getsharelinkplanviewlogic.go new file mode 100644 index 0000000..74ada48 --- /dev/null +++ b/rpc/production/internal/logic/getsharelinkplanviewlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/listinboundlogic.go b/rpc/production/internal/logic/listinboundlogic.go new file mode 100644 index 0000000..93338df --- /dev/null +++ b/rpc/production/internal/logic/listinboundlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/listproductionplanlogic.go b/rpc/production/internal/logic/listproductionplanlogic.go new file mode 100644 index 0000000..a61c126 --- /dev/null +++ b/rpc/production/internal/logic/listproductionplanlogic.go @@ -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 +} diff --git a/rpc/production/internal/logic/rejectsharelinklogic.go b/rpc/production/internal/logic/rejectsharelinklogic.go new file mode 100644 index 0000000..acc94fd --- /dev/null +++ b/rpc/production/internal/logic/rejectsharelinklogic.go @@ -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 +} diff --git a/rpc/production/internal/server/productionserviceserver.go b/rpc/production/internal/server/productionserviceserver.go new file mode 100644 index 0000000..a099eaa --- /dev/null +++ b/rpc/production/internal/server/productionserviceserver.go @@ -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) +} diff --git a/rpc/production/internal/svc/servicecontext.go b/rpc/production/internal/svc/servicecontext.go new file mode 100644 index 0000000..a367edf --- /dev/null +++ b/rpc/production/internal/svc/servicecontext.go @@ -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), + } +} diff --git a/rpc/production/pb/production.pb.go b/rpc/production/pb/production.pb.go new file mode 100644 index 0000000..5d4ecec --- /dev/null +++ b/rpc/production/pb/production.pb.go @@ -0,0 +1,2813 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v7.35.1 +// source: rpc/production/production.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type IdResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *IdResp) Reset() { + *x = IdResp{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdResp) ProtoMessage() {} + +func (x *IdResp) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdResp.ProtoReflect.Descriptor instead. +func (*IdResp) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{0} +} + +func (x *IdResp) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{1} +} + +type ProductionPlanInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PlanId string `protobuf:"bytes,1,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + TenantId string `protobuf:"bytes,2,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + PlanCode string `protobuf:"bytes,3,opt,name=plan_code,json=planCode,proto3" json:"plan_code,omitempty"` + ProductId string `protobuf:"bytes,4,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductName string `protobuf:"bytes,5,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + Color string `protobuf:"bytes,6,opt,name=color,proto3" json:"color,omitempty"` + FabricCode string `protobuf:"bytes,7,opt,name=fabric_code,json=fabricCode,proto3" json:"fabric_code,omitempty"` + ColorCode string `protobuf:"bytes,8,opt,name=color_code,json=colorCode,proto3" json:"color_code,omitempty"` + TargetQuantity string `protobuf:"bytes,9,opt,name=target_quantity,json=targetQuantity,proto3" json:"target_quantity,omitempty"` + CompletedQuantity string `protobuf:"bytes,10,opt,name=completed_quantity,json=completedQuantity,proto3" json:"completed_quantity,omitempty"` + YarnUsagePerMeter string `protobuf:"bytes,11,opt,name=yarn_usage_per_meter,json=yarnUsagePerMeter,proto3" json:"yarn_usage_per_meter,omitempty"` + ProductionPrice string `protobuf:"bytes,12,opt,name=production_price,json=productionPrice,proto3" json:"production_price,omitempty"` + SupplierId string `protobuf:"bytes,13,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + Status int64 `protobuf:"varint,14,opt,name=status,proto3" json:"status,omitempty"` + Remark string `protobuf:"bytes,15,opt,name=remark,proto3" json:"remark,omitempty"` + StartTime string `protobuf:"bytes,16,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + Creator string `protobuf:"bytes,17,opt,name=creator,proto3" json:"creator,omitempty"` + Operator string `protobuf:"bytes,18,opt,name=operator,proto3" json:"operator,omitempty"` + CreatedAt string `protobuf:"bytes,19,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt string `protobuf:"bytes,20,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + YarnRatios []*YarnRatioInfo `protobuf:"bytes,21,rep,name=yarn_ratios,json=yarnRatios,proto3" json:"yarn_ratios,omitempty"` + ProcessSteps []*ProcessStepInfo `protobuf:"bytes,22,rep,name=process_steps,json=processSteps,proto3" json:"process_steps,omitempty"` + InboundRecords []*InboundRecordInfo `protobuf:"bytes,23,rep,name=inbound_records,json=inboundRecords,proto3" json:"inbound_records,omitempty"` +} + +func (x *ProductionPlanInfo) Reset() { + *x = ProductionPlanInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProductionPlanInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProductionPlanInfo) ProtoMessage() {} + +func (x *ProductionPlanInfo) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProductionPlanInfo.ProtoReflect.Descriptor instead. +func (*ProductionPlanInfo) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{2} +} + +func (x *ProductionPlanInfo) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *ProductionPlanInfo) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *ProductionPlanInfo) GetPlanCode() string { + if x != nil { + return x.PlanCode + } + return "" +} + +func (x *ProductionPlanInfo) GetProductId() string { + if x != nil { + return x.ProductId + } + return "" +} + +func (x *ProductionPlanInfo) GetProductName() string { + if x != nil { + return x.ProductName + } + return "" +} + +func (x *ProductionPlanInfo) GetColor() string { + if x != nil { + return x.Color + } + return "" +} + +func (x *ProductionPlanInfo) GetFabricCode() string { + if x != nil { + return x.FabricCode + } + return "" +} + +func (x *ProductionPlanInfo) GetColorCode() string { + if x != nil { + return x.ColorCode + } + return "" +} + +func (x *ProductionPlanInfo) GetTargetQuantity() string { + if x != nil { + return x.TargetQuantity + } + return "" +} + +func (x *ProductionPlanInfo) GetCompletedQuantity() string { + if x != nil { + return x.CompletedQuantity + } + return "" +} + +func (x *ProductionPlanInfo) GetYarnUsagePerMeter() string { + if x != nil { + return x.YarnUsagePerMeter + } + return "" +} + +func (x *ProductionPlanInfo) GetProductionPrice() string { + if x != nil { + return x.ProductionPrice + } + return "" +} + +func (x *ProductionPlanInfo) GetSupplierId() string { + if x != nil { + return x.SupplierId + } + return "" +} + +func (x *ProductionPlanInfo) GetStatus() int64 { + if x != nil { + return x.Status + } + return 0 +} + +func (x *ProductionPlanInfo) GetRemark() string { + if x != nil { + return x.Remark + } + return "" +} + +func (x *ProductionPlanInfo) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *ProductionPlanInfo) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + +func (x *ProductionPlanInfo) GetOperator() string { + if x != nil { + return x.Operator + } + return "" +} + +func (x *ProductionPlanInfo) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *ProductionPlanInfo) GetUpdatedAt() string { + if x != nil { + return x.UpdatedAt + } + return "" +} + +func (x *ProductionPlanInfo) GetYarnRatios() []*YarnRatioInfo { + if x != nil { + return x.YarnRatios + } + return nil +} + +func (x *ProductionPlanInfo) GetProcessSteps() []*ProcessStepInfo { + if x != nil { + return x.ProcessSteps + } + return nil +} + +func (x *ProductionPlanInfo) GetInboundRecords() []*InboundRecordInfo { + if x != nil { + return x.InboundRecords + } + return nil +} + +type CreateProductionPlanReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + ProductId string `protobuf:"bytes,2,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductName string `protobuf:"bytes,3,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + Color string `protobuf:"bytes,4,opt,name=color,proto3" json:"color,omitempty"` + FabricCode string `protobuf:"bytes,5,opt,name=fabric_code,json=fabricCode,proto3" json:"fabric_code,omitempty"` + ColorCode string `protobuf:"bytes,6,opt,name=color_code,json=colorCode,proto3" json:"color_code,omitempty"` + TargetQuantity string `protobuf:"bytes,7,opt,name=target_quantity,json=targetQuantity,proto3" json:"target_quantity,omitempty"` + YarnUsagePerMeter string `protobuf:"bytes,8,opt,name=yarn_usage_per_meter,json=yarnUsagePerMeter,proto3" json:"yarn_usage_per_meter,omitempty"` + ProductionPrice string `protobuf:"bytes,9,opt,name=production_price,json=productionPrice,proto3" json:"production_price,omitempty"` + SupplierId string `protobuf:"bytes,10,opt,name=supplier_id,json=supplierId,proto3" json:"supplier_id,omitempty"` + Remark string `protobuf:"bytes,11,opt,name=remark,proto3" json:"remark,omitempty"` + StartTime string `protobuf:"bytes,12,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + Creator string `protobuf:"bytes,13,opt,name=creator,proto3" json:"creator,omitempty"` + YarnRatios []*YarnRatioReq `protobuf:"bytes,14,rep,name=yarn_ratios,json=yarnRatios,proto3" json:"yarn_ratios,omitempty"` + ProcessSteps []*ProcessStepReq `protobuf:"bytes,15,rep,name=process_steps,json=processSteps,proto3" json:"process_steps,omitempty"` +} + +func (x *CreateProductionPlanReq) Reset() { + *x = CreateProductionPlanReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateProductionPlanReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateProductionPlanReq) ProtoMessage() {} + +func (x *CreateProductionPlanReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateProductionPlanReq.ProtoReflect.Descriptor instead. +func (*CreateProductionPlanReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateProductionPlanReq) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *CreateProductionPlanReq) GetProductId() string { + if x != nil { + return x.ProductId + } + return "" +} + +func (x *CreateProductionPlanReq) GetProductName() string { + if x != nil { + return x.ProductName + } + return "" +} + +func (x *CreateProductionPlanReq) GetColor() string { + if x != nil { + return x.Color + } + return "" +} + +func (x *CreateProductionPlanReq) GetFabricCode() string { + if x != nil { + return x.FabricCode + } + return "" +} + +func (x *CreateProductionPlanReq) GetColorCode() string { + if x != nil { + return x.ColorCode + } + return "" +} + +func (x *CreateProductionPlanReq) GetTargetQuantity() string { + if x != nil { + return x.TargetQuantity + } + return "" +} + +func (x *CreateProductionPlanReq) GetYarnUsagePerMeter() string { + if x != nil { + return x.YarnUsagePerMeter + } + return "" +} + +func (x *CreateProductionPlanReq) GetProductionPrice() string { + if x != nil { + return x.ProductionPrice + } + return "" +} + +func (x *CreateProductionPlanReq) GetSupplierId() string { + if x != nil { + return x.SupplierId + } + return "" +} + +func (x *CreateProductionPlanReq) GetRemark() string { + if x != nil { + return x.Remark + } + return "" +} + +func (x *CreateProductionPlanReq) GetStartTime() string { + if x != nil { + return x.StartTime + } + return "" +} + +func (x *CreateProductionPlanReq) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + +func (x *CreateProductionPlanReq) GetYarnRatios() []*YarnRatioReq { + if x != nil { + return x.YarnRatios + } + return nil +} + +func (x *CreateProductionPlanReq) GetProcessSteps() []*ProcessStepReq { + if x != nil { + return x.ProcessSteps + } + return nil +} + +type ListProductionPlanReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + Page int64 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + Status int64 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"` + ProductName string `protobuf:"bytes,5,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + PlanCode string `protobuf:"bytes,6,opt,name=plan_code,json=planCode,proto3" json:"plan_code,omitempty"` +} + +func (x *ListProductionPlanReq) Reset() { + *x = ListProductionPlanReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProductionPlanReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProductionPlanReq) ProtoMessage() {} + +func (x *ListProductionPlanReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProductionPlanReq.ProtoReflect.Descriptor instead. +func (*ListProductionPlanReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{4} +} + +func (x *ListProductionPlanReq) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *ListProductionPlanReq) GetPage() int64 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListProductionPlanReq) GetPageSize() int64 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListProductionPlanReq) GetStatus() int64 { + if x != nil { + return x.Status + } + return 0 +} + +func (x *ListProductionPlanReq) GetProductName() string { + if x != nil { + return x.ProductName + } + return "" +} + +func (x *ListProductionPlanReq) GetPlanCode() string { + if x != nil { + return x.PlanCode + } + return "" +} + +type ListProductionPlanResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*ProductionPlanInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +func (x *ListProductionPlanResp) Reset() { + *x = ListProductionPlanResp{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListProductionPlanResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListProductionPlanResp) ProtoMessage() {} + +func (x *ListProductionPlanResp) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListProductionPlanResp.ProtoReflect.Descriptor instead. +func (*ListProductionPlanResp) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{5} +} + +func (x *ListProductionPlanResp) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListProductionPlanResp) GetList() []*ProductionPlanInfo { + if x != nil { + return x.List + } + return nil +} + +type GetProductionPlanReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PlanId string `protobuf:"bytes,1,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` +} + +func (x *GetProductionPlanReq) Reset() { + *x = GetProductionPlanReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProductionPlanReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProductionPlanReq) ProtoMessage() {} + +func (x *GetProductionPlanReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProductionPlanReq.ProtoReflect.Descriptor instead. +func (*GetProductionPlanReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{6} +} + +func (x *GetProductionPlanReq) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +type ConfirmPlanReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PlanId string `protobuf:"bytes,1,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + Operator string `protobuf:"bytes,2,opt,name=operator,proto3" json:"operator,omitempty"` +} + +func (x *ConfirmPlanReq) Reset() { + *x = ConfirmPlanReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfirmPlanReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmPlanReq) ProtoMessage() {} + +func (x *ConfirmPlanReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfirmPlanReq.ProtoReflect.Descriptor instead. +func (*ConfirmPlanReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{7} +} + +func (x *ConfirmPlanReq) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *ConfirmPlanReq) GetOperator() string { + if x != nil { + return x.Operator + } + return "" +} + +type YarnRatioInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RatioId string `protobuf:"bytes,1,opt,name=ratio_id,json=ratioId,proto3" json:"ratio_id,omitempty"` + PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + YarnName string `protobuf:"bytes,3,opt,name=yarn_name,json=yarnName,proto3" json:"yarn_name,omitempty"` + Ratio string `protobuf:"bytes,4,opt,name=ratio,proto3" json:"ratio,omitempty"` + AmountPerMeter string `protobuf:"bytes,5,opt,name=amount_per_meter,json=amountPerMeter,proto3" json:"amount_per_meter,omitempty"` + TotalAmount string `protobuf:"bytes,6,opt,name=total_amount,json=totalAmount,proto3" json:"total_amount,omitempty"` + CreatedAt string `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *YarnRatioInfo) Reset() { + *x = YarnRatioInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *YarnRatioInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*YarnRatioInfo) ProtoMessage() {} + +func (x *YarnRatioInfo) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use YarnRatioInfo.ProtoReflect.Descriptor instead. +func (*YarnRatioInfo) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{8} +} + +func (x *YarnRatioInfo) GetRatioId() string { + if x != nil { + return x.RatioId + } + return "" +} + +func (x *YarnRatioInfo) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *YarnRatioInfo) GetYarnName() string { + if x != nil { + return x.YarnName + } + return "" +} + +func (x *YarnRatioInfo) GetRatio() string { + if x != nil { + return x.Ratio + } + return "" +} + +func (x *YarnRatioInfo) GetAmountPerMeter() string { + if x != nil { + return x.AmountPerMeter + } + return "" +} + +func (x *YarnRatioInfo) GetTotalAmount() string { + if x != nil { + return x.TotalAmount + } + return "" +} + +func (x *YarnRatioInfo) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +type YarnRatioReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + YarnName string `protobuf:"bytes,1,opt,name=yarn_name,json=yarnName,proto3" json:"yarn_name,omitempty"` + Ratio string `protobuf:"bytes,2,opt,name=ratio,proto3" json:"ratio,omitempty"` + AmountPerMeter string `protobuf:"bytes,3,opt,name=amount_per_meter,json=amountPerMeter,proto3" json:"amount_per_meter,omitempty"` + TotalAmount string `protobuf:"bytes,4,opt,name=total_amount,json=totalAmount,proto3" json:"total_amount,omitempty"` +} + +func (x *YarnRatioReq) Reset() { + *x = YarnRatioReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *YarnRatioReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*YarnRatioReq) ProtoMessage() {} + +func (x *YarnRatioReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use YarnRatioReq.ProtoReflect.Descriptor instead. +func (*YarnRatioReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{9} +} + +func (x *YarnRatioReq) GetYarnName() string { + if x != nil { + return x.YarnName + } + return "" +} + +func (x *YarnRatioReq) GetRatio() string { + if x != nil { + return x.Ratio + } + return "" +} + +func (x *YarnRatioReq) GetAmountPerMeter() string { + if x != nil { + return x.AmountPerMeter + } + return "" +} + +func (x *YarnRatioReq) GetTotalAmount() string { + if x != nil { + return x.TotalAmount + } + return "" +} + +type ProcessStepInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StepId string `protobuf:"bytes,1,opt,name=step_id,json=stepId,proto3" json:"step_id,omitempty"` + PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + StepType string `protobuf:"bytes,3,opt,name=step_type,json=stepType,proto3" json:"step_type,omitempty"` + StepOrder int64 `protobuf:"varint,4,opt,name=step_order,json=stepOrder,proto3" json:"step_order,omitempty"` + Status int64 `protobuf:"varint,5,opt,name=status,proto3" json:"status,omitempty"` + OperatorId string `protobuf:"bytes,6,opt,name=operator_id,json=operatorId,proto3" json:"operator_id,omitempty"` + CompletedAt string `protobuf:"bytes,7,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"` + Remark string `protobuf:"bytes,8,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt string `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *ProcessStepInfo) Reset() { + *x = ProcessStepInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessStepInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessStepInfo) ProtoMessage() {} + +func (x *ProcessStepInfo) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessStepInfo.ProtoReflect.Descriptor instead. +func (*ProcessStepInfo) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{10} +} + +func (x *ProcessStepInfo) GetStepId() string { + if x != nil { + return x.StepId + } + return "" +} + +func (x *ProcessStepInfo) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *ProcessStepInfo) GetStepType() string { + if x != nil { + return x.StepType + } + return "" +} + +func (x *ProcessStepInfo) GetStepOrder() int64 { + if x != nil { + return x.StepOrder + } + return 0 +} + +func (x *ProcessStepInfo) GetStatus() int64 { + if x != nil { + return x.Status + } + return 0 +} + +func (x *ProcessStepInfo) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +func (x *ProcessStepInfo) GetCompletedAt() string { + if x != nil { + return x.CompletedAt + } + return "" +} + +func (x *ProcessStepInfo) GetRemark() string { + if x != nil { + return x.Remark + } + return "" +} + +func (x *ProcessStepInfo) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *ProcessStepInfo) GetUpdatedAt() string { + if x != nil { + return x.UpdatedAt + } + return "" +} + +type ProcessStepReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StepType string `protobuf:"bytes,1,opt,name=step_type,json=stepType,proto3" json:"step_type,omitempty"` + StepOrder int64 `protobuf:"varint,2,opt,name=step_order,json=stepOrder,proto3" json:"step_order,omitempty"` + Remark string `protobuf:"bytes,3,opt,name=remark,proto3" json:"remark,omitempty"` +} + +func (x *ProcessStepReq) Reset() { + *x = ProcessStepReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProcessStepReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProcessStepReq) ProtoMessage() {} + +func (x *ProcessStepReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProcessStepReq.ProtoReflect.Descriptor instead. +func (*ProcessStepReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{11} +} + +func (x *ProcessStepReq) GetStepType() string { + if x != nil { + return x.StepType + } + return "" +} + +func (x *ProcessStepReq) GetStepOrder() int64 { + if x != nil { + return x.StepOrder + } + return 0 +} + +func (x *ProcessStepReq) GetRemark() string { + if x != nil { + return x.Remark + } + return "" +} + +type CompleteStepReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PlanId string `protobuf:"bytes,1,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + StepType string `protobuf:"bytes,2,opt,name=step_type,json=stepType,proto3" json:"step_type,omitempty"` + OperatorId string `protobuf:"bytes,3,opt,name=operator_id,json=operatorId,proto3" json:"operator_id,omitempty"` +} + +func (x *CompleteStepReq) Reset() { + *x = CompleteStepReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CompleteStepReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompleteStepReq) ProtoMessage() {} + +func (x *CompleteStepReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CompleteStepReq.ProtoReflect.Descriptor instead. +func (*CompleteStepReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{12} +} + +func (x *CompleteStepReq) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *CompleteStepReq) GetStepType() string { + if x != nil { + return x.StepType + } + return "" +} + +func (x *CompleteStepReq) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +type ShareLinkInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LinkId string `protobuf:"bytes,1,opt,name=link_id,json=linkId,proto3" json:"link_id,omitempty"` + TenantId string `protobuf:"bytes,2,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + PlanId string `protobuf:"bytes,3,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + ShortCode string `protobuf:"bytes,4,opt,name=short_code,json=shortCode,proto3" json:"short_code,omitempty"` + Token string `protobuf:"bytes,5,opt,name=token,proto3" json:"token,omitempty"` + FactoryType string `protobuf:"bytes,6,opt,name=factory_type,json=factoryType,proto3" json:"factory_type,omitempty"` + HideSensitive int64 `protobuf:"varint,7,opt,name=hide_sensitive,json=hideSensitive,proto3" json:"hide_sensitive,omitempty"` + Status int64 `protobuf:"varint,8,opt,name=status,proto3" json:"status,omitempty"` + ClickCount int64 `protobuf:"varint,9,opt,name=click_count,json=clickCount,proto3" json:"click_count,omitempty"` + ClickedAt string `protobuf:"bytes,10,opt,name=clicked_at,json=clickedAt,proto3" json:"clicked_at,omitempty"` + RespondedAt string `protobuf:"bytes,11,opt,name=responded_at,json=respondedAt,proto3" json:"responded_at,omitempty"` + RejectReason string `protobuf:"bytes,12,opt,name=reject_reason,json=rejectReason,proto3" json:"reject_reason,omitempty"` + ExpiresAt string `protobuf:"bytes,13,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + CreatedBy string `protobuf:"bytes,14,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + CreatedAt string `protobuf:"bytes,15,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt string `protobuf:"bytes,16,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *ShareLinkInfo) Reset() { + *x = ShareLinkInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareLinkInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareLinkInfo) ProtoMessage() {} + +func (x *ShareLinkInfo) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareLinkInfo.ProtoReflect.Descriptor instead. +func (*ShareLinkInfo) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{13} +} + +func (x *ShareLinkInfo) GetLinkId() string { + if x != nil { + return x.LinkId + } + return "" +} + +func (x *ShareLinkInfo) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *ShareLinkInfo) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *ShareLinkInfo) GetShortCode() string { + if x != nil { + return x.ShortCode + } + return "" +} + +func (x *ShareLinkInfo) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ShareLinkInfo) GetFactoryType() string { + if x != nil { + return x.FactoryType + } + return "" +} + +func (x *ShareLinkInfo) GetHideSensitive() int64 { + if x != nil { + return x.HideSensitive + } + return 0 +} + +func (x *ShareLinkInfo) GetStatus() int64 { + if x != nil { + return x.Status + } + return 0 +} + +func (x *ShareLinkInfo) GetClickCount() int64 { + if x != nil { + return x.ClickCount + } + return 0 +} + +func (x *ShareLinkInfo) GetClickedAt() string { + if x != nil { + return x.ClickedAt + } + return "" +} + +func (x *ShareLinkInfo) GetRespondedAt() string { + if x != nil { + return x.RespondedAt + } + return "" +} + +func (x *ShareLinkInfo) GetRejectReason() string { + if x != nil { + return x.RejectReason + } + return "" +} + +func (x *ShareLinkInfo) GetExpiresAt() string { + if x != nil { + return x.ExpiresAt + } + return "" +} + +func (x *ShareLinkInfo) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *ShareLinkInfo) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *ShareLinkInfo) GetUpdatedAt() string { + if x != nil { + return x.UpdatedAt + } + return "" +} + +type ShareLinkPlanView struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Plan *ProductionPlanInfo `protobuf:"bytes,1,opt,name=plan,proto3" json:"plan,omitempty"` + Link *ShareLinkInfo `protobuf:"bytes,2,opt,name=link,proto3" json:"link,omitempty"` +} + +func (x *ShareLinkPlanView) Reset() { + *x = ShareLinkPlanView{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareLinkPlanView) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareLinkPlanView) ProtoMessage() {} + +func (x *ShareLinkPlanView) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareLinkPlanView.ProtoReflect.Descriptor instead. +func (*ShareLinkPlanView) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{14} +} + +func (x *ShareLinkPlanView) GetPlan() *ProductionPlanInfo { + if x != nil { + return x.Plan + } + return nil +} + +func (x *ShareLinkPlanView) GetLink() *ShareLinkInfo { + if x != nil { + return x.Link + } + return nil +} + +type CreateShareLinkReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + FactoryType string `protobuf:"bytes,3,opt,name=factory_type,json=factoryType,proto3" json:"factory_type,omitempty"` + HideSensitive int64 `protobuf:"varint,4,opt,name=hide_sensitive,json=hideSensitive,proto3" json:"hide_sensitive,omitempty"` + ExpiresHours int64 `protobuf:"varint,5,opt,name=expires_hours,json=expiresHours,proto3" json:"expires_hours,omitempty"` + CreatedBy string `protobuf:"bytes,6,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` +} + +func (x *CreateShareLinkReq) Reset() { + *x = CreateShareLinkReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateShareLinkReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateShareLinkReq) ProtoMessage() {} + +func (x *CreateShareLinkReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateShareLinkReq.ProtoReflect.Descriptor instead. +func (*CreateShareLinkReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{15} +} + +func (x *CreateShareLinkReq) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *CreateShareLinkReq) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *CreateShareLinkReq) GetFactoryType() string { + if x != nil { + return x.FactoryType + } + return "" +} + +func (x *CreateShareLinkReq) GetHideSensitive() int64 { + if x != nil { + return x.HideSensitive + } + return 0 +} + +func (x *CreateShareLinkReq) GetExpiresHours() int64 { + if x != nil { + return x.ExpiresHours + } + return 0 +} + +func (x *CreateShareLinkReq) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +type GetShareLinkReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShortCode string `protobuf:"bytes,1,opt,name=short_code,json=shortCode,proto3" json:"short_code,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *GetShareLinkReq) Reset() { + *x = GetShareLinkReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetShareLinkReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetShareLinkReq) ProtoMessage() {} + +func (x *GetShareLinkReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetShareLinkReq.ProtoReflect.Descriptor instead. +func (*GetShareLinkReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{16} +} + +func (x *GetShareLinkReq) GetShortCode() string { + if x != nil { + return x.ShortCode + } + return "" +} + +func (x *GetShareLinkReq) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type ClickShareLinkReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShortCode string `protobuf:"bytes,1,opt,name=short_code,json=shortCode,proto3" json:"short_code,omitempty"` +} + +func (x *ClickShareLinkReq) Reset() { + *x = ClickShareLinkReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClickShareLinkReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClickShareLinkReq) ProtoMessage() {} + +func (x *ClickShareLinkReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClickShareLinkReq.ProtoReflect.Descriptor instead. +func (*ClickShareLinkReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{17} +} + +func (x *ClickShareLinkReq) GetShortCode() string { + if x != nil { + return x.ShortCode + } + return "" +} + +type ConfirmShareLinkReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShortCode string `protobuf:"bytes,1,opt,name=short_code,json=shortCode,proto3" json:"short_code,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + FactoryTenantId string `protobuf:"bytes,3,opt,name=factory_tenant_id,json=factoryTenantId,proto3" json:"factory_tenant_id,omitempty"` +} + +func (x *ConfirmShareLinkReq) Reset() { + *x = ConfirmShareLinkReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfirmShareLinkReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmShareLinkReq) ProtoMessage() {} + +func (x *ConfirmShareLinkReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfirmShareLinkReq.ProtoReflect.Descriptor instead. +func (*ConfirmShareLinkReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{18} +} + +func (x *ConfirmShareLinkReq) GetShortCode() string { + if x != nil { + return x.ShortCode + } + return "" +} + +func (x *ConfirmShareLinkReq) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ConfirmShareLinkReq) GetFactoryTenantId() string { + if x != nil { + return x.FactoryTenantId + } + return "" +} + +type RejectShareLinkReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ShortCode string `protobuf:"bytes,1,opt,name=short_code,json=shortCode,proto3" json:"short_code,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + RejectReason string `protobuf:"bytes,3,opt,name=reject_reason,json=rejectReason,proto3" json:"reject_reason,omitempty"` +} + +func (x *RejectShareLinkReq) Reset() { + *x = RejectShareLinkReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RejectShareLinkReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RejectShareLinkReq) ProtoMessage() {} + +func (x *RejectShareLinkReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RejectShareLinkReq.ProtoReflect.Descriptor instead. +func (*RejectShareLinkReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{19} +} + +func (x *RejectShareLinkReq) GetShortCode() string { + if x != nil { + return x.ShortCode + } + return "" +} + +func (x *RejectShareLinkReq) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *RejectShareLinkReq) GetRejectReason() string { + if x != nil { + return x.RejectReason + } + return "" +} + +type InboundRecordInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RecordId string `protobuf:"bytes,1,opt,name=record_id,json=recordId,proto3" json:"record_id,omitempty"` + TenantId string `protobuf:"bytes,2,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + PlanId string `protobuf:"bytes,3,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + ProductId string `protobuf:"bytes,4,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + BatchNo string `protobuf:"bytes,5,opt,name=batch_no,json=batchNo,proto3" json:"batch_no,omitempty"` + Quantity string `protobuf:"bytes,6,opt,name=quantity,proto3" json:"quantity,omitempty"` + Rolls int64 `protobuf:"varint,7,opt,name=rolls,proto3" json:"rolls,omitempty"` + PricePerMeter string `protobuf:"bytes,8,opt,name=price_per_meter,json=pricePerMeter,proto3" json:"price_per_meter,omitempty"` + OperatorId string `protobuf:"bytes,9,opt,name=operator_id,json=operatorId,proto3" json:"operator_id,omitempty"` + Remark string `protobuf:"bytes,10,opt,name=remark,proto3" json:"remark,omitempty"` + CreatedAt string `protobuf:"bytes,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *InboundRecordInfo) Reset() { + *x = InboundRecordInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InboundRecordInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InboundRecordInfo) ProtoMessage() {} + +func (x *InboundRecordInfo) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InboundRecordInfo.ProtoReflect.Descriptor instead. +func (*InboundRecordInfo) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{20} +} + +func (x *InboundRecordInfo) GetRecordId() string { + if x != nil { + return x.RecordId + } + return "" +} + +func (x *InboundRecordInfo) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *InboundRecordInfo) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *InboundRecordInfo) GetProductId() string { + if x != nil { + return x.ProductId + } + return "" +} + +func (x *InboundRecordInfo) GetBatchNo() string { + if x != nil { + return x.BatchNo + } + return "" +} + +func (x *InboundRecordInfo) GetQuantity() string { + if x != nil { + return x.Quantity + } + return "" +} + +func (x *InboundRecordInfo) GetRolls() int64 { + if x != nil { + return x.Rolls + } + return 0 +} + +func (x *InboundRecordInfo) GetPricePerMeter() string { + if x != nil { + return x.PricePerMeter + } + return "" +} + +func (x *InboundRecordInfo) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +func (x *InboundRecordInfo) GetRemark() string { + if x != nil { + return x.Remark + } + return "" +} + +func (x *InboundRecordInfo) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +type CreateInboundReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + ProductId string `protobuf:"bytes,3,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + BatchNo string `protobuf:"bytes,4,opt,name=batch_no,json=batchNo,proto3" json:"batch_no,omitempty"` + Quantity string `protobuf:"bytes,5,opt,name=quantity,proto3" json:"quantity,omitempty"` + Rolls int64 `protobuf:"varint,6,opt,name=rolls,proto3" json:"rolls,omitempty"` + PricePerMeter string `protobuf:"bytes,7,opt,name=price_per_meter,json=pricePerMeter,proto3" json:"price_per_meter,omitempty"` + OperatorId string `protobuf:"bytes,8,opt,name=operator_id,json=operatorId,proto3" json:"operator_id,omitempty"` + Remark string `protobuf:"bytes,9,opt,name=remark,proto3" json:"remark,omitempty"` +} + +func (x *CreateInboundReq) Reset() { + *x = CreateInboundReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateInboundReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateInboundReq) ProtoMessage() {} + +func (x *CreateInboundReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateInboundReq.ProtoReflect.Descriptor instead. +func (*CreateInboundReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{21} +} + +func (x *CreateInboundReq) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *CreateInboundReq) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *CreateInboundReq) GetProductId() string { + if x != nil { + return x.ProductId + } + return "" +} + +func (x *CreateInboundReq) GetBatchNo() string { + if x != nil { + return x.BatchNo + } + return "" +} + +func (x *CreateInboundReq) GetQuantity() string { + if x != nil { + return x.Quantity + } + return "" +} + +func (x *CreateInboundReq) GetRolls() int64 { + if x != nil { + return x.Rolls + } + return 0 +} + +func (x *CreateInboundReq) GetPricePerMeter() string { + if x != nil { + return x.PricePerMeter + } + return "" +} + +func (x *CreateInboundReq) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +func (x *CreateInboundReq) GetRemark() string { + if x != nil { + return x.Remark + } + return "" +} + +type ListInboundReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"` + Page int64 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"` + PageSize int64 `protobuf:"varint,4,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` +} + +func (x *ListInboundReq) Reset() { + *x = ListInboundReq{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInboundReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInboundReq) ProtoMessage() {} + +func (x *ListInboundReq) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInboundReq.ProtoReflect.Descriptor instead. +func (*ListInboundReq) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{22} +} + +func (x *ListInboundReq) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *ListInboundReq) GetPlanId() string { + if x != nil { + return x.PlanId + } + return "" +} + +func (x *ListInboundReq) GetPage() int64 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListInboundReq) GetPageSize() int64 { + if x != nil { + return x.PageSize + } + return 0 +} + +type ListInboundResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + List []*InboundRecordInfo `protobuf:"bytes,2,rep,name=list,proto3" json:"list,omitempty"` +} + +func (x *ListInboundResp) Reset() { + *x = ListInboundResp{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_production_production_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListInboundResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListInboundResp) ProtoMessage() {} + +func (x *ListInboundResp) ProtoReflect() protoreflect.Message { + mi := &file_rpc_production_production_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListInboundResp.ProtoReflect.Descriptor instead. +func (*ListInboundResp) Descriptor() ([]byte, []int) { + return file_rpc_production_production_proto_rawDescGZIP(), []int{23} +} + +func (x *ListInboundResp) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListInboundResp) GetList() []*InboundRecordInfo { + if x != nil { + return x.List + } + return nil +} + +var File_rpc_production_production_proto protoreflect.FileDescriptor + +var file_rpc_production_production_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x18, 0x0a, + 0x06, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0xdd, 0x06, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x6c, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x14, 0x79, 0x61, + 0x72, 0x6e, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x79, 0x61, 0x72, 0x6e, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x75, 0x70, + 0x70, 0x6c, 0x69, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, + 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, + 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3a, 0x0a, 0x0b, 0x79, 0x61, + 0x72, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x59, 0x61, 0x72, + 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x79, 0x61, 0x72, 0x6e, + 0x52, 0x61, 0x74, 0x69, 0x6f, 0x73, 0x12, 0x40, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x65, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x46, 0x0a, 0x0f, 0x69, 0x6e, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, + 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x0e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, + 0x22, 0xc1, 0x04, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x71, 0x75, 0x61, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x2f, 0x0a, 0x14, 0x79, 0x61, + 0x72, 0x6e, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x79, 0x61, 0x72, 0x6e, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x75, 0x70, + 0x70, 0x6c, 0x69, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, + 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x0b, 0x79, 0x61, 0x72, 0x6e, + 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x59, 0x61, 0x72, 0x6e, 0x52, + 0x61, 0x74, 0x69, 0x6f, 0x52, 0x65, 0x71, 0x52, 0x0a, 0x79, 0x61, 0x72, 0x6e, 0x52, 0x61, 0x74, + 0x69, 0x6f, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, + 0x74, 0x65, 0x70, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x74, 0x65, 0x70, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x6e, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x6e, + 0x43, 0x6f, 0x64, 0x65, 0x22, 0x62, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x32, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, + 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x22, 0x45, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x70, + 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, + 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x22, 0xe2, 0x01, 0x0a, 0x0d, 0x59, 0x61, 0x72, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x49, 0x64, 0x12, 0x17, 0x0a, + 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x79, 0x61, 0x72, 0x6e, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x79, 0x61, 0x72, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x0c, 0x59, 0x61, 0x72, 0x6e, 0x52, 0x61, + 0x74, 0x69, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, 0x79, 0x61, 0x72, 0x6e, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x79, 0x61, 0x72, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x28, 0x0a, 0x10, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb1, 0x02, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x65, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x74, + 0x65, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x65, + 0x70, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x74, 0x65, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x74, 0x65, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x65, + 0x70, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, + 0x74, 0x65, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x64, 0x0a, 0x0e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x74, 0x65, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x74, 0x65, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x65, + 0x70, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, + 0x74, 0x65, 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x61, + 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, + 0x22, 0x68, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x65, 0x70, + 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x74, 0x65, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x74, 0x65, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x22, 0xf9, 0x03, 0x0a, 0x0d, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, + 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, + 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x68, 0x69, 0x64, + 0x65, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x64, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x76, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, + 0x69, 0x6e, 0x6b, 0x50, 0x6c, 0x61, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x12, 0x32, 0x0a, 0x04, 0x70, + 0x6c, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x12, + 0x2d, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0xd8, + 0x01, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, + 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, + 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x66, + 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x68, 0x69, 0x64, 0x65, 0x53, 0x65, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, + 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x73, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0x46, 0x0a, 0x0f, 0x47, 0x65, 0x74, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0x32, 0x0a, 0x11, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, + 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, + 0x74, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x76, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x6e, 0x0a, + 0x12, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x65, 0x71, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xd2, 0x02, + 0x0a, 0x11, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, + 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, + 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x6f, + 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x6f, 0x6c, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x6f, 0x6c, + 0x6c, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, + 0x63, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6d, + 0x61, 0x72, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x22, 0x95, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x62, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x6c, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x72, 0x69, + 0x63, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x65, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x22, 0x77, 0x0a, 0x0e, 0x4c, 0x69, + 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, + 0x69, 0x7a, 0x65, 0x22, 0x5a, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x31, 0x0a, 0x04, + 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x32, + 0xdd, 0x07, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x23, 0x2e, + 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, + 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x5b, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x21, 0x2e, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x1a, + 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x55, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x50, 0x6c, + 0x61, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1e, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, + 0x6e, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x46, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, + 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x6c, + 0x61, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x6c, 0x61, 0x6e, 0x56, 0x69, + 0x65, 0x77, 0x12, 0x42, 0x0a, 0x0e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, + 0x0a, 0x0f, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, + 0x6b, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, + 0x65, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x68, 0x61, 0x72, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, + 0x71, 0x1a, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x53, 0x74, 0x65, 0x70, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, + 0x71, 0x1a, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x42, + 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_rpc_production_production_proto_rawDescOnce sync.Once + file_rpc_production_production_proto_rawDescData = file_rpc_production_production_proto_rawDesc +) + +func file_rpc_production_production_proto_rawDescGZIP() []byte { + file_rpc_production_production_proto_rawDescOnce.Do(func() { + file_rpc_production_production_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_production_production_proto_rawDescData) + }) + return file_rpc_production_production_proto_rawDescData +} + +var file_rpc_production_production_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_rpc_production_production_proto_goTypes = []interface{}{ + (*IdResp)(nil), // 0: production.IdResp + (*Empty)(nil), // 1: production.Empty + (*ProductionPlanInfo)(nil), // 2: production.ProductionPlanInfo + (*CreateProductionPlanReq)(nil), // 3: production.CreateProductionPlanReq + (*ListProductionPlanReq)(nil), // 4: production.ListProductionPlanReq + (*ListProductionPlanResp)(nil), // 5: production.ListProductionPlanResp + (*GetProductionPlanReq)(nil), // 6: production.GetProductionPlanReq + (*ConfirmPlanReq)(nil), // 7: production.ConfirmPlanReq + (*YarnRatioInfo)(nil), // 8: production.YarnRatioInfo + (*YarnRatioReq)(nil), // 9: production.YarnRatioReq + (*ProcessStepInfo)(nil), // 10: production.ProcessStepInfo + (*ProcessStepReq)(nil), // 11: production.ProcessStepReq + (*CompleteStepReq)(nil), // 12: production.CompleteStepReq + (*ShareLinkInfo)(nil), // 13: production.ShareLinkInfo + (*ShareLinkPlanView)(nil), // 14: production.ShareLinkPlanView + (*CreateShareLinkReq)(nil), // 15: production.CreateShareLinkReq + (*GetShareLinkReq)(nil), // 16: production.GetShareLinkReq + (*ClickShareLinkReq)(nil), // 17: production.ClickShareLinkReq + (*ConfirmShareLinkReq)(nil), // 18: production.ConfirmShareLinkReq + (*RejectShareLinkReq)(nil), // 19: production.RejectShareLinkReq + (*InboundRecordInfo)(nil), // 20: production.InboundRecordInfo + (*CreateInboundReq)(nil), // 21: production.CreateInboundReq + (*ListInboundReq)(nil), // 22: production.ListInboundReq + (*ListInboundResp)(nil), // 23: production.ListInboundResp +} +var file_rpc_production_production_proto_depIdxs = []int32{ + 8, // 0: production.ProductionPlanInfo.yarn_ratios:type_name -> production.YarnRatioInfo + 10, // 1: production.ProductionPlanInfo.process_steps:type_name -> production.ProcessStepInfo + 20, // 2: production.ProductionPlanInfo.inbound_records:type_name -> production.InboundRecordInfo + 9, // 3: production.CreateProductionPlanReq.yarn_ratios:type_name -> production.YarnRatioReq + 11, // 4: production.CreateProductionPlanReq.process_steps:type_name -> production.ProcessStepReq + 2, // 5: production.ListProductionPlanResp.list:type_name -> production.ProductionPlanInfo + 2, // 6: production.ShareLinkPlanView.plan:type_name -> production.ProductionPlanInfo + 13, // 7: production.ShareLinkPlanView.link:type_name -> production.ShareLinkInfo + 20, // 8: production.ListInboundResp.list:type_name -> production.InboundRecordInfo + 3, // 9: production.ProductionService.CreateProductionPlan:input_type -> production.CreateProductionPlanReq + 4, // 10: production.ProductionService.ListProductionPlan:input_type -> production.ListProductionPlanReq + 6, // 11: production.ProductionService.GetProductionPlan:input_type -> production.GetProductionPlanReq + 7, // 12: production.ProductionService.ConfirmPlan:input_type -> production.ConfirmPlanReq + 15, // 13: production.ProductionService.CreateShareLink:input_type -> production.CreateShareLinkReq + 16, // 14: production.ProductionService.GetShareLink:input_type -> production.GetShareLinkReq + 16, // 15: production.ProductionService.GetShareLinkPlanView:input_type -> production.GetShareLinkReq + 17, // 16: production.ProductionService.ClickShareLink:input_type -> production.ClickShareLinkReq + 18, // 17: production.ProductionService.ConfirmShareLink:input_type -> production.ConfirmShareLinkReq + 19, // 18: production.ProductionService.RejectShareLink:input_type -> production.RejectShareLinkReq + 12, // 19: production.ProductionService.CompleteStep:input_type -> production.CompleteStepReq + 21, // 20: production.ProductionService.CreateInbound:input_type -> production.CreateInboundReq + 22, // 21: production.ProductionService.ListInbound:input_type -> production.ListInboundReq + 0, // 22: production.ProductionService.CreateProductionPlan:output_type -> production.IdResp + 5, // 23: production.ProductionService.ListProductionPlan:output_type -> production.ListProductionPlanResp + 2, // 24: production.ProductionService.GetProductionPlan:output_type -> production.ProductionPlanInfo + 1, // 25: production.ProductionService.ConfirmPlan:output_type -> production.Empty + 13, // 26: production.ProductionService.CreateShareLink:output_type -> production.ShareLinkInfo + 13, // 27: production.ProductionService.GetShareLink:output_type -> production.ShareLinkInfo + 14, // 28: production.ProductionService.GetShareLinkPlanView:output_type -> production.ShareLinkPlanView + 1, // 29: production.ProductionService.ClickShareLink:output_type -> production.Empty + 1, // 30: production.ProductionService.ConfirmShareLink:output_type -> production.Empty + 1, // 31: production.ProductionService.RejectShareLink:output_type -> production.Empty + 1, // 32: production.ProductionService.CompleteStep:output_type -> production.Empty + 0, // 33: production.ProductionService.CreateInbound:output_type -> production.IdResp + 23, // 34: production.ProductionService.ListInbound:output_type -> production.ListInboundResp + 22, // [22:35] is the sub-list for method output_type + 9, // [9:22] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_rpc_production_production_proto_init() } +func file_rpc_production_production_proto_init() { + if File_rpc_production_production_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_rpc_production_production_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProductionPlanInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateProductionPlanReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProductionPlanReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListProductionPlanResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProductionPlanReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfirmPlanReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*YarnRatioInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*YarnRatioReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessStepInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProcessStepReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CompleteStepReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShareLinkInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ShareLinkPlanView); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateShareLinkReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetShareLinkReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClickShareLinkReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfirmShareLinkReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RejectShareLinkReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InboundRecordInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateInboundReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInboundReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_production_production_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListInboundResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_production_production_proto_rawDesc, + NumEnums: 0, + NumMessages: 24, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_rpc_production_production_proto_goTypes, + DependencyIndexes: file_rpc_production_production_proto_depIdxs, + MessageInfos: file_rpc_production_production_proto_msgTypes, + }.Build() + File_rpc_production_production_proto = out.File + file_rpc_production_production_proto_rawDesc = nil + file_rpc_production_production_proto_goTypes = nil + file_rpc_production_production_proto_depIdxs = nil +} diff --git a/rpc/production/pb/production_grpc.pb.go b/rpc/production/pb/production_grpc.pb.go new file mode 100644 index 0000000..d85cd75 --- /dev/null +++ b/rpc/production/pb/production_grpc.pb.go @@ -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", +} diff --git a/rpc/production/production.go b/rpc/production/production.go new file mode 100644 index 0000000..be3063c --- /dev/null +++ b/rpc/production/production.go @@ -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() +} diff --git a/rpc/production/production.proto b/rpc/production/production.proto new file mode 100644 index 0000000..cde1f6e --- /dev/null +++ b/rpc/production/production.proto @@ -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); +} diff --git a/rpc/production/productionservice/productionservice.go b/rpc/production/productionservice/productionservice.go new file mode 100644 index 0000000..d07a0e8 --- /dev/null +++ b/rpc/production/productionservice/productionservice.go @@ -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...) +}