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