Chever John 4144628cb6 build(deploy): replace pre-compiled arm64 binaries with multi-stage Go compilation for amd64
WHY: existing Dockerfiles copied pre-compiled arm64 binaries which cannot
run on the amd64 K3s cluster (exec format error). Also fixed port conflicts
when running muyu alongside iloom in docker-compose.

HOW:
- rewrite 3 Dockerfiles (system/inventory/gateway) to multi-stage builds
  using golang:1.24-alpine with CGO_ENABLED=0 GOARCH=amd64
- parameterize host ports in docker-compose to avoid conflicts (3306->13306,
  6379->16379, 8080->18080)
- fix inv_product unique key from product_name-only to composite
  (product_name, spec, color) to allow same-name products with different specs
- add X-Token to Authorization header middleware in gateway for
  iloom frontend compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-14 12:38:46 +08:00

313 lines
14 KiB
SQL

-- Muyu Warehouse Management System - Database Init Script
SET NAMES utf8mb4;
SET CHARACTER SET utf8mb4;
CREATE DATABASE IF NOT EXISTS `muyu_wms` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE `muyu_wms`;
-- ==================== System Management Tables ====================
CREATE TABLE `sys_user` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`user_id` VARCHAR(32) NOT NULL,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`salt` VARCHAR(32) NOT NULL,
`real_name` VARCHAR(50) NOT NULL DEFAULT '',
`phone` VARCHAR(20) NOT NULL DEFAULT '',
`email` VARCHAR(100) NOT NULL DEFAULT '',
`avatar` VARCHAR(255) NOT NULL DEFAULT '',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1:enabled 0:disabled',
`last_login_time` DATETIME DEFAULT NULL,
`last_login_ip` VARCHAR(50) NOT NULL DEFAULT '',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
UNIQUE KEY `uk_username` (`username`),
KEY `idx_status` (`status`),
KEY `idx_deleted_at` (`deleted_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `sys_role` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`role_id` VARCHAR(32) NOT NULL,
`role_name` VARCHAR(50) NOT NULL,
`role_key` VARCHAR(50) NOT NULL,
`role_desc` VARCHAR(200) NOT NULL DEFAULT '',
`sort_order` INT NOT NULL DEFAULT 0,
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1:enabled 0:disabled',
`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_role_id` (`role_id`),
UNIQUE KEY `uk_role_key` (`role_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `sys_user_role` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`user_id` VARCHAR(32) NOT NULL,
`role_id` VARCHAR(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_role` (`user_id`, `role_id`),
KEY `idx_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `sys_menu` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`menu_id` VARCHAR(32) NOT NULL,
`parent_id` VARCHAR(32) NOT NULL DEFAULT '',
`menu_name` VARCHAR(50) NOT NULL,
`menu_type` TINYINT NOT NULL DEFAULT 1 COMMENT '1:directory 2:menu 3:button',
`path` VARCHAR(200) NOT NULL DEFAULT '',
`component` VARCHAR(200) NOT NULL DEFAULT '',
`permission` VARCHAR(100) NOT NULL DEFAULT '',
`icon` VARCHAR(50) NOT NULL DEFAULT '',
`sort_order` INT NOT NULL DEFAULT 0,
`visible` TINYINT NOT NULL DEFAULT 1 COMMENT '1:visible 0:hidden',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1:enabled 0:disabled',
`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_menu_id` (`menu_id`),
KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `sys_role_menu` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`role_id` VARCHAR(32) NOT NULL,
`menu_id` VARCHAR(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_role_menu` (`role_id`, `menu_id`),
KEY `idx_menu_id` (`menu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `sys_operation_log` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`log_id` VARCHAR(32) NOT NULL,
`user_id` VARCHAR(32) NOT NULL DEFAULT '',
`username` VARCHAR(50) NOT NULL DEFAULT '',
`module` VARCHAR(50) NOT NULL DEFAULT '',
`operation` VARCHAR(20) NOT NULL DEFAULT '',
`method` VARCHAR(10) NOT NULL DEFAULT '',
`path` VARCHAR(200) NOT NULL DEFAULT '',
`request_body` TEXT,
`response_body` TEXT,
`ip` VARCHAR(50) NOT NULL DEFAULT '',
`user_agent` VARCHAR(500) NOT NULL DEFAULT '',
`duration` INT NOT NULL DEFAULT 0 COMMENT 'milliseconds',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1:success 0:fail',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_log_id` (`log_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_module` (`module`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `sys_config` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`config_id` VARCHAR(32) NOT NULL,
`config_key` VARCHAR(50) NOT NULL,
`config_value` TEXT,
`config_name` VARCHAR(100) NOT NULL DEFAULT '',
`config_group` VARCHAR(50) NOT NULL DEFAULT '',
`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_config_id` (`config_id`),
UNIQUE KEY `uk_config_key` (`config_key`),
KEY `idx_config_group` (`config_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ==================== Inventory Management Tables ====================
CREATE TABLE `inv_product` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`product_id` VARCHAR(32) NOT NULL,
`product_name` VARCHAR(100) NOT NULL,
`image_url` VARCHAR(255) NOT NULL DEFAULT '',
`spec` VARCHAR(100) NOT NULL DEFAULT '',
`color` VARCHAR(50) NOT NULL DEFAULT '',
`unit_pieces` INT NOT NULL DEFAULT 0,
`unit_rolls` INT NOT NULL DEFAULT 0,
`stock_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`location` VARCHAR(100) NOT NULL DEFAULT '',
`cost_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`sales_price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`remark` TEXT,
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '1:enabled 0:disabled',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_product_id` (`product_id`),
UNIQUE KEY `uk_product_name_spec_color` (`product_name`, `spec`, `color`),
KEY `idx_color` (`color`),
KEY `idx_location` (`location`),
KEY `idx_status` (`status`),
KEY `idx_deleted_at` (`deleted_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `inv_stock_import_log` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`import_id` VARCHAR(32) NOT NULL,
`file_name` VARCHAR(200) NOT NULL DEFAULT '',
`total_count` INT NOT NULL DEFAULT 0,
`success_count` INT NOT NULL DEFAULT 0,
`fail_count` INT NOT NULL DEFAULT 0,
`error_msg` TEXT,
`operator` VARCHAR(50) NOT NULL DEFAULT '',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_import_id` (`import_id`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `inv_stock_check` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`check_id` VARCHAR(32) NOT NULL,
`check_no` VARCHAR(32) NOT NULL,
`check_date` DATE NOT NULL,
`checker` VARCHAR(50) NOT NULL DEFAULT '',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:draft 1:in_progress 2:completed',
`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_check_id` (`check_id`),
UNIQUE KEY `uk_check_no` (`check_no`),
KEY `idx_status` (`status`),
KEY `idx_check_date` (`check_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `inv_stock_check_detail` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`detail_id` VARCHAR(32) NOT NULL,
`check_id` VARCHAR(32) NOT NULL,
`product_id` VARCHAR(32) NOT NULL,
`system_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`actual_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`diff_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`diff_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
`remark` TEXT,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_detail_id` (`detail_id`),
KEY `idx_check_id` (`check_id`),
KEY `idx_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `inv_stock_adjust` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`adjust_id` VARCHAR(32) NOT NULL,
`adjust_no` VARCHAR(32) NOT NULL,
`adjust_date` DATE NOT NULL,
`adjust_reason` VARCHAR(50) NOT NULL DEFAULT '',
`operator` VARCHAR(50) NOT NULL DEFAULT '',
`approver` VARCHAR(50) NOT NULL DEFAULT '',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0:pending 1:approved 2:rejected',
`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_adjust_id` (`adjust_id`),
UNIQUE KEY `uk_adjust_no` (`adjust_no`),
KEY `idx_status` (`status`),
KEY `idx_adjust_date` (`adjust_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `inv_stock_adjust_detail` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`detail_id` VARCHAR(32) NOT NULL,
`adjust_id` VARCHAR(32) NOT NULL,
`product_id` VARCHAR(32) NOT NULL,
`before_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`adjust_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`after_quantity` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`remark` TEXT,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_detail_id` (`detail_id`),
KEY `idx_adjust_id` (`adjust_id`),
KEY `idx_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Casbin policy storage
CREATE TABLE `casbin_rule` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`ptype` VARCHAR(100) NOT NULL DEFAULT '',
`v0` VARCHAR(100) NOT NULL DEFAULT '',
`v1` VARCHAR(100) NOT NULL DEFAULT '',
`v2` VARCHAR(100) NOT NULL DEFAULT '',
`v3` VARCHAR(100) NOT NULL DEFAULT '',
`v4` VARCHAR(100) NOT NULL DEFAULT '',
`v5` VARCHAR(100) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_casbin` (`ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ==================== Initial Data ====================
-- Default admin user (password: admin123, bcrypt hashed)
INSERT INTO `sys_user` (`user_id`, `username`, `password`, `salt`, `real_name`, `status`)
VALUES ('u_admin_001', 'admin', '$2a$10$S5XPWRXUnexAt9KJw2CefeHMa6aude7j5dm5qgWM1YMQAAwRgsGXa', 'bcrypt', 'System Admin', 1);
-- Default roles
INSERT INTO `sys_role` (`role_id`, `role_name`, `role_key`, `role_desc`, `sort_order`, `status`) VALUES
('r_001', '系统管理员', 'admin', 'Full system access', 1, 1),
('r_002', '仓库管理员', 'warehouse', 'Warehouse management access', 2, 1),
('r_003', '普通用户', 'user', 'Basic read access', 3, 1);
-- Assign admin role to admin user
INSERT INTO `sys_user_role` (`user_id`, `role_id`) VALUES ('u_admin_001', 'r_001');
-- Default menus
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `menu_name`, `menu_type`, `path`, `component`, `permission`, `icon`, `sort_order`, `visible`, `status`) VALUES
-- Dashboard
('m_001', '', '首页', 1, '/dashboard', './Dashboard', '', 'DashboardOutlined', 1, 1, 1),
-- System Management
('m_100', '', '系统管理', 1, '/system', '', '', 'SettingOutlined', 100, 1, 1),
('m_101', 'm_100', '用户管理', 2, '/system/users', './System/Users', 'system:user:list', 'UserOutlined', 1, 1, 1),
('m_102', 'm_100', '角色管理', 2, '/system/roles', './System/Roles', 'system:role:list', 'TeamOutlined', 2, 1, 1),
('m_103', 'm_100', '菜单管理', 2, '/system/menus', './System/Menus', 'system:menu:list', 'MenuOutlined', 3, 1, 1),
('m_104', 'm_100', '操作日志', 2, '/system/logs', './System/Logs', 'system:log:list', 'FileTextOutlined', 4, 1, 1),
('m_105', 'm_100', '系统配置', 2, '/system/configs', './System/Configs', 'system:config:list', 'ToolOutlined', 5, 1, 1),
-- Inventory Management
('m_200', '', '库存管理', 1, '/inventory', '', '', 'DatabaseOutlined', 200, 1, 1),
('m_201', 'm_200', '产品档案', 2, '/inventory/products', './Inventory/Products', 'inventory:product:list', 'AppstoreOutlined', 1, 1, 1),
('m_202', 'm_200', '库存查询', 2, '/inventory/stocks', './Inventory/Stocks', 'inventory:stock:list', 'SearchOutlined', 2, 1, 1),
('m_203', 'm_200', '库存统计', 2, '/inventory/stats', './Inventory/Stats', 'inventory:stock:stats', 'BarChartOutlined', 3, 1, 1),
('m_204', 'm_200', '库存盘点', 2, '/inventory/checks', './Inventory/Checks', 'inventory:check:list', 'AuditOutlined', 4, 1, 1),
('m_205', 'm_200', '库存调整', 2, '/inventory/adjusts', './Inventory/Adjusts', 'inventory:adjust:list', 'SwapOutlined', 5, 1, 1),
('m_206', 'm_200', 'Excel导入', 2, '/inventory/import', './Inventory/Import', 'inventory:import:exec', 'ImportOutlined', 6, 1, 1);
-- Assign all menus to admin role
INSERT INTO `sys_role_menu` (`role_id`, `menu_id`)
SELECT 'r_001', `menu_id` FROM `sys_menu`;
-- Assign inventory menus to warehouse role
INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES
('r_002', 'm_001'),
('r_002', 'm_200'), ('r_002', 'm_201'), ('r_002', 'm_202'),
('r_002', 'm_203'), ('r_002', 'm_204'), ('r_002', 'm_205'), ('r_002', 'm_206');
-- Default Casbin policies
INSERT INTO `casbin_rule` (`ptype`, `v0`, `v1`, `v2`) VALUES
('p', 'admin', '/api/v1/*', '*'),
('p', 'warehouse', '/api/v1/auth/*', '*'),
('p', 'warehouse', '/api/v1/inventory/*', '*'),
('p', 'user', '/api/v1/auth/*', '*'),
('p', 'user', '/api/v1/inventory/products', 'GET'),
('p', 'user', '/api/v1/inventory/stocks', 'GET'),
('p', 'user', '/api/v1/inventory/stocks/*', 'GET');
-- Default system configs
INSERT INTO `sys_config` (`config_id`, `config_key`, `config_value`, `config_name`, `config_group`, `remark`) VALUES
('c_001', 'sys_name', 'muyuqingfeng仓储管理系统', 'System Name', 'basic', 'System display name'),
('c_002', 'sys_logo', '', 'System Logo', 'basic', 'System logo URL'),
('c_003', 'upload_max_size', '10', 'Upload Max Size (MB)', 'upload', 'Maximum file upload size'),
('c_004', 'upload_allowed_types', 'jpg,jpeg,png,gif,xlsx,xls,csv', 'Allowed Upload Types', 'upload', 'Allowed file extensions');