权限:移除业务物理删除入口
This commit is contained in:
@@ -111,7 +111,7 @@ async def edit_master_customer(
|
||||
summary='兼容旧接口,固定拒绝,请使用测试数据批次清理',
|
||||
description='兼容旧接口,固定拒绝单条物理删除,请使用测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('master:customer:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('master:customer:list')],
|
||||
)
|
||||
@Log(title='客户管理', business_type=BusinessType.DELETE)
|
||||
async def delete_master_customer(
|
||||
|
||||
@@ -163,7 +163,7 @@ async def edit_business_inbound(
|
||||
summary='不支持单条物理删除,请通过测试数据批次清理',
|
||||
description='不支持单条物理删除,请通过测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('business:inbound:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('business:inbound:list')],
|
||||
)
|
||||
@Log(title='仓库入库', business_type=BusinessType.DELETE)
|
||||
async def delete_business_inbound(
|
||||
|
||||
@@ -109,7 +109,7 @@ async def edit_master_line(
|
||||
summary='兼容旧接口,固定拒绝,请使用测试数据批次清理',
|
||||
description='兼容旧接口,固定拒绝单条物理删除,请使用测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('master:line:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('master:line:list')],
|
||||
)
|
||||
@Log(title='生产线管理', business_type=BusinessType.DELETE)
|
||||
async def delete_master_line(
|
||||
|
||||
@@ -123,7 +123,7 @@ async def edit_master_pallet(
|
||||
summary='兼容旧接口,固定拒绝,请使用测试数据批次清理',
|
||||
description='兼容旧接口,固定拒绝单条物理删除,请使用测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('master:pallet:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('master:pallet:list')],
|
||||
)
|
||||
@Log(title='托盘管理', business_type=BusinessType.DELETE)
|
||||
async def delete_master_pallet(
|
||||
|
||||
@@ -180,7 +180,7 @@ async def edit_business_shipment(
|
||||
summary='不支持单条物理删除,请通过测试数据批次清理',
|
||||
description='不支持单条物理删除,请通过测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('business:shipment:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('business:shipment:list')],
|
||||
)
|
||||
@Log(title='整托发货', business_type=BusinessType.DELETE)
|
||||
async def delete_business_shipment(
|
||||
|
||||
@@ -161,7 +161,7 @@ async def edit_master_site(
|
||||
summary='兼容旧接口,固定拒绝,请使用测试数据批次清理',
|
||||
description='兼容旧接口,固定拒绝单条物理删除,请使用测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('master:site:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('master:site:list')],
|
||||
)
|
||||
@Log(title='客户现场管理', business_type=BusinessType.DELETE)
|
||||
async def delete_master_site(
|
||||
|
||||
@@ -111,7 +111,7 @@ async def edit_master_strain(
|
||||
summary='兼容旧接口,固定拒绝,请使用测试数据批次清理',
|
||||
description='兼容旧接口,固定拒绝单条物理删除,请使用测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('master:strain:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('master:strain:list')],
|
||||
)
|
||||
@Log(title='菌种管理', business_type=BusinessType.DELETE)
|
||||
async def delete_master_strain(
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import Path, Request, Response
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from common.annotation.log_annotation import Log, RequestLogFieldRoot
|
||||
from common.aspect.db_seesion import DBSessionDependency
|
||||
from common.aspect.interface_auth import UserInterfaceAuthDependency
|
||||
from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
|
||||
from common.enums import BusinessType
|
||||
from common.router import APIRouterPro
|
||||
from module_admin.entity.vo.user_vo import CurrentUserModel
|
||||
from module_business.entity.vo.test_batch_vo import (
|
||||
AdoptionExecuteRequestModel,
|
||||
AdoptionPreviewRequestModel,
|
||||
PurgeExecuteRequestModel,
|
||||
TestBatchCreateModel,
|
||||
TestBatchEditModel,
|
||||
TestBatchUserAssignModel,
|
||||
)
|
||||
from module_business.service.test_batch_adoption_service import TestBatchAdoptionService
|
||||
from module_business.service.test_batch_purge_service import TestBatchPurgeService
|
||||
from module_business.service.test_batch_service import TestBatchService
|
||||
from utils.response_util import ResponseUtil
|
||||
|
||||
test_batch_controller = APIRouterPro(
|
||||
prefix='/system/test-batch',
|
||||
tags=['系统管理-测试数据批次'],
|
||||
dependencies=[PreAuthDependency()],
|
||||
)
|
||||
|
||||
|
||||
@test_batch_controller.get('/options')
|
||||
async def list_test_batch_options(
|
||||
request: Request,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.list_available_batches(query_db, current_user)
|
||||
return ResponseUtil.success(data=result)
|
||||
|
||||
|
||||
@test_batch_controller.get(
|
||||
'/list',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:list')],
|
||||
)
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.OTHER,
|
||||
request_log_mode='summary',
|
||||
response_log_mode='summary',
|
||||
)
|
||||
async def list_test_batches(
|
||||
request: Request,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.list_batches(query_db, current_user)
|
||||
return ResponseUtil.success(rows=result, dict_content={'total': len(result)})
|
||||
|
||||
|
||||
@test_batch_controller.post(
|
||||
'',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:add')],
|
||||
)
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.INSERT,
|
||||
request_log_mode='summary',
|
||||
response_log_mode='summary',
|
||||
)
|
||||
async def create_test_batch(
|
||||
request: Request,
|
||||
command: TestBatchCreateModel,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.create_batch(query_db, command, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@test_batch_controller.put(
|
||||
'/{batch_id}',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:edit')],
|
||||
)
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.UPDATE,
|
||||
request_log_mode='summary',
|
||||
response_log_mode='summary',
|
||||
)
|
||||
async def edit_test_batch(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
command: TestBatchEditModel,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.edit_batch(query_db, batch_id, command, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@test_batch_controller.put(
|
||||
'/{batch_id}/users',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:assign')],
|
||||
)
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.GRANT,
|
||||
request_log_mode='summary',
|
||||
response_log_mode='summary',
|
||||
)
|
||||
async def assign_test_batch_users(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
command: TestBatchUserAssignModel,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.replace_users(query_db, batch_id, command, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@test_batch_controller.put(
|
||||
'/{batch_id}/close',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:close')],
|
||||
)
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.UPDATE,
|
||||
request_log_mode='summary',
|
||||
response_log_mode='summary',
|
||||
)
|
||||
async def close_test_batch(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.close_batch(query_db, batch_id, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@test_batch_controller.put(
|
||||
'/{batch_id}/reopen',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:close')],
|
||||
)
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.UPDATE,
|
||||
request_log_mode='summary',
|
||||
response_log_mode='summary',
|
||||
)
|
||||
async def reopen_test_batch(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.reopen_batch(query_db, batch_id, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.CLEAN,
|
||||
request_log_mode='include',
|
||||
request_include_fields=(RequestLogFieldRoot.PATH_PARAMS.field('batch_id'),),
|
||||
response_log_mode='summary',
|
||||
)
|
||||
@test_batch_controller.post(
|
||||
'/{batch_id}/adoption/preview',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:adopt')],
|
||||
)
|
||||
async def preview_test_batch_adoption(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
command: AdoptionPreviewRequestModel,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchAdoptionService.preview(query_db, batch_id, command, current_user)
|
||||
return ResponseUtil.success(data=result)
|
||||
|
||||
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.CLEAN,
|
||||
request_log_mode='include',
|
||||
request_include_fields=(RequestLogFieldRoot.PATH_PARAMS.field('batch_id'),),
|
||||
response_log_mode='summary',
|
||||
)
|
||||
@test_batch_controller.post(
|
||||
'/{batch_id}/adoption/execute',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:adopt')],
|
||||
)
|
||||
async def execute_test_batch_adoption(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
command: AdoptionExecuteRequestModel,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchAdoptionService.execute(query_db, batch_id, command, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.CLEAN,
|
||||
request_log_mode='include',
|
||||
request_include_fields=(RequestLogFieldRoot.PATH_PARAMS.field('batch_id'),),
|
||||
response_log_mode='summary',
|
||||
)
|
||||
@test_batch_controller.post(
|
||||
'/{batch_id}/purge/preview',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:purge')],
|
||||
)
|
||||
async def preview_test_batch_purge(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchPurgeService.preview(query_db, batch_id, current_user)
|
||||
return ResponseUtil.success(data=result)
|
||||
|
||||
|
||||
@Log(
|
||||
title='测试数据批次',
|
||||
business_type=BusinessType.CLEAN,
|
||||
request_log_mode='include',
|
||||
request_include_fields=(RequestLogFieldRoot.PATH_PARAMS.field('batch_id'),),
|
||||
response_log_mode='summary',
|
||||
)
|
||||
@test_batch_controller.post(
|
||||
'/{batch_id}/purge',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:purge')],
|
||||
)
|
||||
async def purge_test_batch(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
command: PurgeExecuteRequestModel,
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchPurgeService.purge(query_db, batch_id, command, current_user)
|
||||
return ResponseUtil.success(msg=result.message)
|
||||
|
||||
|
||||
@test_batch_controller.get(
|
||||
'/{batch_id}',
|
||||
dependencies=[UserInterfaceAuthDependency('system:testbatch:query')],
|
||||
)
|
||||
async def get_test_batch(
|
||||
request: Request,
|
||||
batch_id: Annotated[int, Path(gt=0, description='测试批次ID')],
|
||||
query_db: Annotated[AsyncSession, DBSessionDependency()],
|
||||
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
|
||||
) -> Response:
|
||||
result = await TestBatchService.get_batch_detail(query_db, batch_id, current_user)
|
||||
return ResponseUtil.success(data=result)
|
||||
@@ -166,7 +166,7 @@ async def edit_master_warehouse(
|
||||
summary='兼容旧接口,固定拒绝,请使用测试数据批次清理',
|
||||
description='兼容旧接口,固定拒绝单条物理删除,请使用测试数据批次清理',
|
||||
response_model=ResponseBaseModel,
|
||||
dependencies=[UserInterfaceAuthDependency('master:warehouse:remove')],
|
||||
dependencies=[UserInterfaceAuthDependency('master:warehouse:list')],
|
||||
)
|
||||
@Log(title='仓库管理', business_type=BusinessType.DELETE)
|
||||
async def delete_master_warehouse(
|
||||
|
||||
@@ -135,3 +135,25 @@ ALTER TABLE biz_pallet_event
|
||||
ADD INDEX idx_biz_pallet_event_test_batch_id (test_batch_id),
|
||||
ADD CONSTRAINT fk_biz_pallet_event_test_batch_id
|
||||
FOREIGN KEY (test_batch_id) REFERENCES biz_test_batch (batch_id);
|
||||
|
||||
-- 菜单迁移:移除旧物理删除权限,加入测试数据批次管理菜单。
|
||||
-- 新菜单不自动授予普通角色;超级管理员由现有 admin 权限访问。
|
||||
START TRANSACTION;
|
||||
|
||||
DELETE FROM sys_role_menu
|
||||
WHERE menu_id IN (1068, 1072, 1076, 1081, 1085, 1090, 1095, 1102);
|
||||
|
||||
DELETE FROM sys_menu
|
||||
WHERE menu_id IN (1068, 1072, 1076, 1081, 1085, 1090, 1095, 1102);
|
||||
|
||||
INSERT INTO sys_menu VALUES
|
||||
(519, '测试数据批次', 1, '7', 'testBatch', 'system/testBatch/index', '', '', 1, 0, 'C', '0', '0', 'system:testbatch:list', '#', 'admin', SYSDATE(), '', NULL, '测试数据批次菜单'),
|
||||
(1109, '批次查询', 519, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:query', '#', 'admin', SYSDATE(), '', NULL, ''),
|
||||
(1110, '批次新增', 519, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:add', '#', 'admin', SYSDATE(), '', NULL, ''),
|
||||
(1111, '批次修改', 519, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:edit', '#', 'admin', SYSDATE(), '', NULL, ''),
|
||||
(1112, '批次授权', 519, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:assign', '#', 'admin', SYSDATE(), '', NULL, ''),
|
||||
(1113, '批次关闭', 519, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:close', '#', 'admin', SYSDATE(), '', NULL, ''),
|
||||
(1114, '数据纳入', 519, '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:adopt', '#', 'admin', SYSDATE(), '', NULL, ''),
|
||||
(1115, '批次清理', 519, '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:purge', '#', 'admin', SYSDATE(), '', NULL, '');
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -137,3 +137,25 @@ COMMENT ON COLUMN biz_pallet_event.test_batch_id IS '测试数据批次ID;NULL
|
||||
CREATE INDEX idx_biz_pallet_event_test_batch_id ON biz_pallet_event (test_batch_id);
|
||||
ALTER TABLE biz_pallet_event ADD CONSTRAINT fk_biz_pallet_event_test_batch_id
|
||||
FOREIGN KEY (test_batch_id) REFERENCES biz_test_batch (batch_id);
|
||||
|
||||
-- 菜单迁移:移除旧物理删除权限,加入测试数据批次管理菜单。
|
||||
-- 新菜单不自动授予普通角色;超级管理员由现有 admin 权限访问。
|
||||
BEGIN;
|
||||
|
||||
DELETE FROM sys_role_menu
|
||||
WHERE menu_id IN (1068, 1072, 1076, 1081, 1085, 1090, 1095, 1102);
|
||||
|
||||
DELETE FROM sys_menu
|
||||
WHERE menu_id IN (1068, 1072, 1076, 1081, 1085, 1090, 1095, 1102);
|
||||
|
||||
INSERT INTO sys_menu VALUES
|
||||
(519, '测试数据批次', 1, '7', 'testBatch', 'system/testBatch/index', '', '', 1, 0, 'C', '0', '0', 'system:testbatch:list', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, '测试数据批次菜单'),
|
||||
(1109, '批次查询', 519, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:query', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, ''),
|
||||
(1110, '批次新增', 519, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:add', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, ''),
|
||||
(1111, '批次修改', 519, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:edit', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, ''),
|
||||
(1112, '批次授权', 519, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:assign', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, ''),
|
||||
(1113, '批次关闭', 519, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:close', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, ''),
|
||||
(1114, '数据纳入', 519, '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:adopt', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, ''),
|
||||
(1115, '批次清理', 519, '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:purge', '#', 'admin', CURRENT_TIMESTAMP, '', NULL, '');
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1575,47 +1575,47 @@ insert into sys_menu values
|
||||
(516, '产线消耗', 123, '4', 'consumption', 'report/consumption/index', '', '', 1, 0, 'C', '0', '0', 'report:consumption:list', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(517, '退回仓库', 123, '5', 'reportReturn', 'report/return/index', '', '', 1, 0, 'C', '0', '0', 'report:return:list', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(518, '托盘追溯', 123, '6', 'palletTrace', 'report/palletTrace/index', '', '', 1, 0, 'C', '0', '0', 'report:pallettrace:list', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(519, '测试数据批次', 1, '7', 'testBatch', 'system/testBatch/index', '', '', 1, 0, 'C', '0', '0', 'system:testbatch:list', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1065, '菌种查询', 502, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1066, '菌种新增', 502, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1067, '菌种修改', 502, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1068, '菌种删除', 502, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1069, '客户查询', 503, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1070, '客户新增', 503, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1071, '客户修改', 503, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1072, '客户删除', 503, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1073, '现场查询', 504, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1074, '现场新增', 504, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1075, '现场修改', 504, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1076, '现场删除', 504, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1077, '分配用户', 504, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:assign', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1078, '产线查询', 505, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1079, '产线新增', 505, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1080, '产线修改', 505, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1081, '产线删除', 505, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1082, '仓库查询', 506, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1083, '仓库新增', 506, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1084, '仓库修改', 506, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1085, '仓库删除', 506, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1086, '分配用户', 506, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:assign', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1087, '托盘查询', 507, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1088, '托盘新增', 507, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1089, '托盘修改', 507, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1090, '托盘删除', 507, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1091, '托盘打印', 507, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:print', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1092, '入库查询', 508, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1093, '入库新增', 508, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1094, '入库修改', 508, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1095, '入库删除', 508, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1096, '入库确认', 508, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:confirm', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1097, '装填查询', 509, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:filling:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1098, '装填新增', 509, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:filling:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1099, '发货查询', 510, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1100, '发货新增', 510, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1101, '发货修改', 510, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1102, '发货删除', 510, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:remove', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1103, '发货确认', 510, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:confirm', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1104, '使用查询', 511, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:usage:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1105, '使用新增', 511, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:usage:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1106, '退回查询', 512, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1107, '退回申请', 512, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:request', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1108, '退回确认', 512, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:confirm', '#', 'admin', current_timestamp, '', null, '');
|
||||
(1108, '退回确认', 512, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:confirm', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1109, '批次查询', 519, '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:query', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1110, '批次新增', 519, '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:add', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1111, '批次修改', 519, '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:edit', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1112, '批次授权', 519, '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:assign', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1113, '批次关闭', 519, '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:close', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1114, '数据纳入', 519, '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:adopt', '#', 'admin', current_timestamp, '', null, ''),
|
||||
(1115, '批次清理', 519, '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:purge', '#', 'admin', current_timestamp, '', null, '');
|
||||
|
||||
@@ -307,52 +307,52 @@ insert into sys_menu values('515', '发货出库', '123', '3', 'reportShipment',
|
||||
insert into sys_menu values('516', '产线消耗', '123', '4', 'consumption', 'report/consumption/index', '', '', 1, 0, 'C', '0', '0', 'report:consumption:list', '#', 'admin', sysdate(), '', null, '产线消耗菜单');
|
||||
insert into sys_menu values('517', '退回仓库', '123', '5', 'reportReturn', 'report/return/index', '', '', 1, 0, 'C', '0', '0', 'report:return:list', '#', 'admin', sysdate(), '', null, '退回仓库报表菜单');
|
||||
insert into sys_menu values('518', '托盘追溯', '123', '6', 'palletTrace', 'report/palletTrace/index', '', '', 1, 0, 'C', '0', '0', 'report:pallettrace:list', '#', 'admin', sysdate(), '', null, '托盘追溯菜单');
|
||||
insert into sys_menu values('519', '测试数据批次', '1', '7', 'testBatch', 'system/testBatch/index', '', '', 1, 0, 'C', '0', '0', 'system:testbatch:list', '#', 'admin', sysdate(), '', null, '测试数据批次菜单');
|
||||
|
||||
-- 托盘业务按钮
|
||||
insert into sys_menu values('1065', '菌种查询', '502', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1066', '菌种新增', '502', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1067', '菌种修改', '502', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1068', '菌种删除', '502', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:strain:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1069', '客户查询', '503', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1070', '客户新增', '503', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1071', '客户修改', '503', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1072', '客户删除', '503', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:customer:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1073', '现场查询', '504', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1074', '现场新增', '504', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1075', '现场修改', '504', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1076', '现场删除', '504', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1077', '分配用户', '504', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:site:assign', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1078', '产线查询', '505', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1079', '产线新增', '505', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1080', '产线修改', '505', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1081', '产线删除', '505', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:line:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1082', '仓库查询', '506', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1083', '仓库新增', '506', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1084', '仓库修改', '506', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1085', '仓库删除', '506', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1086', '分配用户', '506', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:warehouse:assign', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1087', '托盘查询', '507', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1088', '托盘新增', '507', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1089', '托盘修改', '507', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1090', '托盘删除', '507', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1091', '托盘打印', '507', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'master:pallet:print', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1092', '入库查询', '508', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1093', '入库新增', '508', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1094', '入库修改', '508', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1095', '入库删除', '508', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1096', '入库确认', '508', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'business:inbound:confirm', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1097', '装填查询', '509', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:filling:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1098', '装填新增', '509', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:filling:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1099', '发货查询', '510', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1100', '发货新增', '510', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1101', '发货修改', '510', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1102', '发货删除', '510', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:remove', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1103', '发货确认', '510', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'business:shipment:confirm', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1104', '使用查询', '511', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:usage:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1105', '使用新增', '511', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:usage:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1106', '退回查询', '512', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1107', '退回申请', '512', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:request', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1108', '退回确认', '512', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'business:return:confirm', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1109', '批次查询', '519', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:query', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1110', '批次新增', '519', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:add', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1111', '批次修改', '519', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:edit', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1112', '批次授权', '519', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:assign', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1113', '批次关闭', '519', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:close', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1114', '数据纳入', '519', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:adopt', '#', 'admin', sysdate(), '', null, '');
|
||||
insert into sys_menu values('1115', '批次清理', '519', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:testbatch:purge', '#', 'admin', sysdate(), '', null, '');
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
@@ -24,11 +24,13 @@ CONTROLLER_NAMES = (
|
||||
'usage',
|
||||
'return',
|
||||
'report',
|
||||
'test_batch',
|
||||
)
|
||||
TARGET_PREFIXES = (
|
||||
'/master',
|
||||
'/business',
|
||||
'/report',
|
||||
'/system/test-batch',
|
||||
)
|
||||
ROUTE_HTTP_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'})
|
||||
WRITE_METHODS = frozenset({'DELETE', 'PATCH', 'POST', 'PUT'})
|
||||
@@ -52,6 +54,7 @@ EXPECTED_PAGE_PERMISSIONS = frozenset(
|
||||
'report:consumption:list',
|
||||
'report:return:list',
|
||||
'report:pallettrace:list',
|
||||
'system:testbatch:list',
|
||||
}
|
||||
)
|
||||
EXPECTED_BUTTON_PERMISSIONS = frozenset(
|
||||
@@ -59,50 +62,54 @@ EXPECTED_BUTTON_PERMISSIONS = frozenset(
|
||||
'master:strain:query',
|
||||
'master:strain:add',
|
||||
'master:strain:edit',
|
||||
'master:strain:remove',
|
||||
'master:customer:query',
|
||||
'master:customer:add',
|
||||
'master:customer:edit',
|
||||
'master:customer:remove',
|
||||
'master:site:query',
|
||||
'master:site:add',
|
||||
'master:site:edit',
|
||||
'master:site:remove',
|
||||
'master:site:assign',
|
||||
'master:line:query',
|
||||
'master:line:add',
|
||||
'master:line:edit',
|
||||
'master:line:remove',
|
||||
'master:warehouse:query',
|
||||
'master:warehouse:add',
|
||||
'master:warehouse:edit',
|
||||
'master:warehouse:remove',
|
||||
'master:warehouse:assign',
|
||||
'master:pallet:query',
|
||||
'master:pallet:add',
|
||||
'master:pallet:edit',
|
||||
'master:pallet:remove',
|
||||
'master:pallet:print',
|
||||
'business:inbound:query',
|
||||
'business:inbound:add',
|
||||
'business:inbound:edit',
|
||||
'business:inbound:remove',
|
||||
'business:inbound:confirm',
|
||||
'business:filling:query',
|
||||
'business:filling:add',
|
||||
'business:shipment:query',
|
||||
'business:shipment:add',
|
||||
'business:shipment:edit',
|
||||
'business:shipment:remove',
|
||||
'business:shipment:confirm',
|
||||
'business:usage:query',
|
||||
'business:usage:add',
|
||||
'business:return:query',
|
||||
'business:return:request',
|
||||
'business:return:confirm',
|
||||
'system:testbatch:query',
|
||||
'system:testbatch:add',
|
||||
'system:testbatch:edit',
|
||||
'system:testbatch:assign',
|
||||
'system:testbatch:close',
|
||||
'system:testbatch:adopt',
|
||||
'system:testbatch:purge',
|
||||
}
|
||||
)
|
||||
EXPECTED_PERMISSIONS = EXPECTED_PAGE_PERMISSIONS | EXPECTED_BUTTON_PERMISSIONS
|
||||
EXPECTED_WEB_PERMISSIONS = frozenset(
|
||||
permission
|
||||
for permission in EXPECTED_PERMISSIONS
|
||||
if not permission.startswith('system:testbatch:') or permission == 'system:testbatch:adopt'
|
||||
)
|
||||
VUE_PAGE_PATHS = (
|
||||
'src/views/master/strain/index.vue',
|
||||
'src/views/master/customer/index.vue',
|
||||
@@ -122,7 +129,30 @@ VUE_PAGE_PATHS = (
|
||||
'src/views/report/return/index.vue',
|
||||
'src/views/report/palletTrace/index.vue',
|
||||
)
|
||||
PERMISSION_LITERAL_PATTERN = re.compile(r'(?:master|business|report):[a-z]+:[a-z]+')
|
||||
PERMISSION_LITERAL_PATTERN = re.compile(r'(?:master|business|report|system):[a-z]+:[a-z]+')
|
||||
UNGUARDED_AUTHENTICATED_ROUTES = {('/system/test-batch/options', 'GET')}
|
||||
REMOVED_DELETE_SYMBOLS = (
|
||||
'delStrain',
|
||||
'delCustomer',
|
||||
'delSite',
|
||||
'delLine',
|
||||
'delWarehouse',
|
||||
'delPallet',
|
||||
'delInbound',
|
||||
'delShipment',
|
||||
)
|
||||
REMOVED_DELETE_PERMISSIONS = frozenset(
|
||||
{
|
||||
'master:strain:remove',
|
||||
'master:customer:remove',
|
||||
'master:site:remove',
|
||||
'master:line:remove',
|
||||
'master:warehouse:remove',
|
||||
'master:pallet:remove',
|
||||
'business:inbound:remove',
|
||||
'business:shipment:remove',
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _build_expected_route_permissions() -> dict[tuple[str, str], str]:
|
||||
@@ -136,7 +166,7 @@ def _build_expected_route_permissions() -> dict[tuple[str, str], str]:
|
||||
(f'{root}/{{{resource}_id}}', 'GET'): f'{permission_root}:query',
|
||||
(root, 'POST'): f'{permission_root}:add',
|
||||
(root, 'PUT'): f'{permission_root}:edit',
|
||||
(f'{root}/{{{resource}_ids}}', 'DELETE'): f'{permission_root}:remove',
|
||||
(f'{root}/{{{resource}_ids}}', 'DELETE'): f'{permission_root}:list',
|
||||
}
|
||||
)
|
||||
|
||||
@@ -153,7 +183,7 @@ def _build_expected_route_permissions() -> dict[tuple[str, str], str]:
|
||||
('/business/inbound/{inbound_id}', 'GET'): 'business:inbound:query',
|
||||
('/business/inbound', 'POST'): 'business:inbound:add',
|
||||
('/business/inbound', 'PUT'): 'business:inbound:edit',
|
||||
('/business/inbound/{inbound_ids}', 'DELETE'): 'business:inbound:remove',
|
||||
('/business/inbound/{inbound_ids}', 'DELETE'): 'business:inbound:list',
|
||||
('/business/inbound/{inbound_id}/confirm', 'PUT'): 'business:inbound:confirm',
|
||||
('/business/filling/list', 'GET'): 'business:filling:list',
|
||||
('/business/filling/strain-options', 'GET'): 'business:filling:query',
|
||||
@@ -167,7 +197,7 @@ def _build_expected_route_permissions() -> dict[tuple[str, str], str]:
|
||||
('/business/shipment/{shipment_id}', 'GET'): 'business:shipment:query',
|
||||
('/business/shipment', 'POST'): 'business:shipment:add',
|
||||
('/business/shipment', 'PUT'): 'business:shipment:edit',
|
||||
('/business/shipment/{shipment_ids}', 'DELETE'): 'business:shipment:remove',
|
||||
('/business/shipment/{shipment_ids}', 'DELETE'): 'business:shipment:list',
|
||||
('/business/shipment/{shipment_id}/confirm', 'PUT'): 'business:shipment:confirm',
|
||||
('/business/usage/list', 'GET'): 'business:usage:list',
|
||||
('/business/usage/line-options', 'GET'): 'business:usage:query',
|
||||
@@ -186,6 +216,17 @@ def _build_expected_route_permissions() -> dict[tuple[str, str], str]:
|
||||
('/report/consumption/list', 'GET'): 'report:consumption:list',
|
||||
('/report/return/list', 'GET'): 'report:return:list',
|
||||
('/report/pallet-trace/list', 'GET'): 'report:pallettrace:list',
|
||||
('/system/test-batch/list', 'GET'): 'system:testbatch:list',
|
||||
('/system/test-batch', 'POST'): 'system:testbatch:add',
|
||||
('/system/test-batch/{batch_id}', 'PUT'): 'system:testbatch:edit',
|
||||
('/system/test-batch/{batch_id}/users', 'PUT'): 'system:testbatch:assign',
|
||||
('/system/test-batch/{batch_id}/close', 'PUT'): 'system:testbatch:close',
|
||||
('/system/test-batch/{batch_id}/reopen', 'PUT'): 'system:testbatch:close',
|
||||
('/system/test-batch/{batch_id}/adoption/preview', 'POST'): 'system:testbatch:adopt',
|
||||
('/system/test-batch/{batch_id}/adoption/execute', 'POST'): 'system:testbatch:adopt',
|
||||
('/system/test-batch/{batch_id}/purge/preview', 'POST'): 'system:testbatch:purge',
|
||||
('/system/test-batch/{batch_id}/purge', 'POST'): 'system:testbatch:purge',
|
||||
('/system/test-batch/{batch_id}', 'GET'): 'system:testbatch:query',
|
||||
}
|
||||
)
|
||||
return expected
|
||||
@@ -214,6 +255,10 @@ STATIC_READS_BEFORE_DETAIL = {
|
||||
'/business/return/warehouse-options',
|
||||
'/business/return/scan/{qr_token}',
|
||||
),
|
||||
'/system/test-batch/{batch_id}': (
|
||||
'/system/test-batch/options',
|
||||
'/system/test-batch/list',
|
||||
),
|
||||
}
|
||||
EXACT_QUERY_PARAMETERS = {
|
||||
('/business/inbound/scan/{qr_token}', 'GET'): {'warehouseId'},
|
||||
@@ -241,7 +286,7 @@ def _auth_dependencies(route: APIRoute) -> list[CheckUserInterfaceAuth]:
|
||||
|
||||
def _assert_controller_permission_literals(test_case: unittest.TestCase, literals: list[str]) -> None:
|
||||
expected = Counter(EXPECTED_ROUTE_PERMISSIONS.values())
|
||||
test_case.assertEqual(74, expected.total())
|
||||
test_case.assertEqual(85, expected.total())
|
||||
test_case.assertEqual(expected, Counter(literals))
|
||||
test_case.assertEqual(EXPECTED_PERMISSIONS, frozenset(expected))
|
||||
|
||||
@@ -368,10 +413,18 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
]
|
||||
|
||||
def test_target_path_selector_uses_namespace_boundaries(self) -> None:
|
||||
for path in ('/master', '/master/foo', '/business', '/business/foo', '/report/foo'):
|
||||
for path in (
|
||||
'/master',
|
||||
'/master/foo',
|
||||
'/business',
|
||||
'/business/foo',
|
||||
'/report/foo',
|
||||
'/system/test-batch',
|
||||
'/system/test-batch/options',
|
||||
):
|
||||
with self.subTest(path=path):
|
||||
self.assertTrue(_is_target_path(path))
|
||||
for path in ('/masterish', '/business-other', '/reporting'):
|
||||
for path in ('/masterish', '/business-other', '/reporting', '/system/test-batches'):
|
||||
with self.subTest(path=path):
|
||||
self.assertFalse(_is_target_path(path))
|
||||
|
||||
@@ -384,8 +437,8 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
if method.upper() in ROUTE_HTTP_METHODS
|
||||
}
|
||||
|
||||
self.assertEqual(set(EXPECTED_ROUTE_PERMISSIONS), actual_operations)
|
||||
self.assertEqual(74, len(actual_operations))
|
||||
self.assertEqual(set(EXPECTED_ROUTE_PERMISSIONS) | UNGUARDED_AUTHENTICATED_ROUTES, actual_operations)
|
||||
self.assertEqual(86, len(actual_operations))
|
||||
|
||||
openapi_ai_paths = sorted(path for path in self.schema['paths'] if path == '/ai' or path.startswith('/ai/'))
|
||||
app_ai_paths = sorted(
|
||||
@@ -406,6 +459,9 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
operation_keys.append(key)
|
||||
|
||||
auth_dependencies = _auth_dependencies(route)
|
||||
if key in UNGUARDED_AUTHENTICATED_ROUTES:
|
||||
self.assertEqual([], auth_dependencies, key)
|
||||
else:
|
||||
self.assertEqual(1, len(auth_dependencies), key)
|
||||
actual_permissions[key] = auth_dependencies[0].perm
|
||||
|
||||
@@ -435,19 +491,19 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
literals.append(node.args[0].value)
|
||||
|
||||
self.assertEqual([], malformed_calls)
|
||||
self.assertEqual(17, len(EXPECTED_PAGE_PERMISSIONS))
|
||||
self.assertEqual(44, len(EXPECTED_BUTTON_PERMISSIONS))
|
||||
self.assertEqual(18, len(EXPECTED_PAGE_PERMISSIONS))
|
||||
self.assertEqual(43, len(EXPECTED_BUTTON_PERMISSIONS))
|
||||
self.assertFalse(EXPECTED_PAGE_PERMISSIONS & EXPECTED_BUTTON_PERMISSIONS)
|
||||
self.assertEqual(61, len(EXPECTED_PERMISSIONS))
|
||||
_assert_controller_permission_literals(self, literals)
|
||||
self.assertEqual(
|
||||
{'add', 'assign', 'confirm', 'edit', 'list', 'print', 'query', 'remove', 'request'},
|
||||
{'add', 'adopt', 'assign', 'close', 'confirm', 'edit', 'list', 'print', 'purge', 'query', 'request'},
|
||||
{permission.rsplit(':', maxsplit=1)[1] for permission in literals},
|
||||
)
|
||||
|
||||
def test_controller_ast_permission_contract_rejects_duplicate_call(self) -> None:
|
||||
literals = list(EXPECTED_ROUTE_PERMISSIONS.values())
|
||||
self.assertEqual(74, len(literals))
|
||||
self.assertEqual(85, len(literals))
|
||||
literals.append(literals[0])
|
||||
|
||||
with self.assertRaises(AssertionError):
|
||||
@@ -473,7 +529,66 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
self.assertTrue(guarded, relative_path)
|
||||
actual_permissions.update(guarded)
|
||||
|
||||
_assert_exact_permission_layers(self, {'vue': actual_permissions})
|
||||
self.assertEqual(EXPECTED_WEB_PERMISSIONS, frozenset(actual_permissions))
|
||||
|
||||
def test_frontend_has_no_physical_delete_api_or_page_contract(self) -> None:
|
||||
relative_paths = (
|
||||
'src/api/master/strain.js',
|
||||
'src/api/master/customer.js',
|
||||
'src/api/master/site.js',
|
||||
'src/api/master/line.js',
|
||||
'src/api/master/warehouse.js',
|
||||
'src/api/master/pallet.js',
|
||||
'src/api/business/inbound.js',
|
||||
'src/api/business/shipment.js',
|
||||
*VUE_PAGE_PATHS,
|
||||
)
|
||||
for relative_path in relative_paths:
|
||||
source = (FRONTEND_ROOT / relative_path).read_text(encoding='utf-8')
|
||||
code, structure = _sanitize_vue_source(source)
|
||||
with self.subTest(relative_path=relative_path):
|
||||
for symbol in REMOVED_DELETE_SYMBOLS:
|
||||
self.assertIsNone(re.search(rf'\b{symbol}\b', structure), symbol)
|
||||
self.assertFalse(REMOVED_DELETE_PERMISSIONS & set(PERMISSION_LITERAL_PATTERN.findall(code)))
|
||||
|
||||
def test_sensitive_test_batch_logs_only_include_batch_id_and_response_summary(self) -> None:
|
||||
source_path = BACKEND_ROOT / 'module_business/controller/test_batch_controller.py'
|
||||
tree = ast.parse(source_path.read_text(encoding='utf-8'), filename=str(source_path))
|
||||
functions = {node.name: node for node in tree.body if isinstance(node, ast.AsyncFunctionDef)}
|
||||
sensitive_handlers = {
|
||||
'preview_test_batch_adoption',
|
||||
'execute_test_batch_adoption',
|
||||
'preview_test_batch_purge',
|
||||
'purge_test_batch',
|
||||
}
|
||||
self.assertEqual(sensitive_handlers, sensitive_handlers & functions.keys())
|
||||
|
||||
for handler_name in sensitive_handlers:
|
||||
log_calls = [
|
||||
decorator
|
||||
for decorator in functions[handler_name].decorator_list
|
||||
if isinstance(decorator, ast.Call)
|
||||
and isinstance(decorator.func, ast.Name)
|
||||
and decorator.func.id == 'Log'
|
||||
]
|
||||
with self.subTest(handler=handler_name):
|
||||
self.assertEqual(1, len(log_calls))
|
||||
keywords = {keyword.arg: keyword.value for keyword in log_calls[0].keywords}
|
||||
self.assertEqual('include', ast.literal_eval(keywords['request_log_mode']))
|
||||
self.assertEqual('summary', ast.literal_eval(keywords['response_log_mode']))
|
||||
include_fields = keywords['request_include_fields']
|
||||
self.assertIsInstance(include_fields, ast.Tuple)
|
||||
self.assertEqual(1, len(include_fields.elts))
|
||||
field_call = include_fields.elts[0]
|
||||
self.assertIsInstance(field_call, ast.Call)
|
||||
self.assertEqual('batch_id', ast.literal_eval(field_call.args[0]))
|
||||
self.assertIsInstance(field_call.func, ast.Attribute)
|
||||
self.assertEqual('field', field_call.func.attr)
|
||||
root = field_call.func.value
|
||||
self.assertIsInstance(root, ast.Attribute)
|
||||
self.assertEqual('PATH_PARAMS', root.attr)
|
||||
self.assertIsInstance(root.value, ast.Name)
|
||||
self.assertEqual('RequestLogFieldRoot', root.value.id)
|
||||
|
||||
def test_vue_guard_parser_rejects_dynamic_arrays_and_has_permi_or(self) -> None:
|
||||
dynamic_sources = (
|
||||
@@ -561,7 +676,7 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
self.assertLess(route_order[static_path], route_order[detail_path])
|
||||
|
||||
def test_openapi_parameter_names_are_exact(self) -> None:
|
||||
for path, method in EXPECTED_ROUTE_PERMISSIONS:
|
||||
for path, method in set(EXPECTED_ROUTE_PERMISSIONS) | UNGUARDED_AUTHENTICATED_ROUTES:
|
||||
parameters = self.schema['paths'][path][method.lower()].get('parameters', [])
|
||||
actual_path_parameters = {parameter['name'] for parameter in parameters if parameter['in'] == 'path'}
|
||||
self.assertEqual(set(re.findall(r'{([^{}]+)}', path)), actual_path_parameters, (path, method))
|
||||
@@ -593,7 +708,7 @@ class ApiPermissionContractTest(unittest.TestCase):
|
||||
for method in route.methods & WRITE_METHODS:
|
||||
actual_write_routes[(route.path, method)] = route
|
||||
|
||||
self.assertEqual(32, len(expected_write_permissions))
|
||||
self.assertEqual(41, len(expected_write_permissions))
|
||||
self.assertEqual(set(expected_write_permissions), set(actual_write_routes))
|
||||
for key, expected_permission in expected_write_permissions.items():
|
||||
with self.subTest(operation=key):
|
||||
|
||||
@@ -446,6 +446,7 @@ EXPECTED_CHECKS.update(
|
||||
)
|
||||
|
||||
EXPECTED_PAGES = {
|
||||
519: ('测试数据批次', 1, 7, 'testBatch', 'system/testBatch/index', 'system:testbatch:list'),
|
||||
502: ('菌种资料', 121, 1, 'strain', 'master/strain/index', 'master:strain:list'),
|
||||
503: ('客户资料', 121, 2, 'customer', 'master/customer/index', 'master:customer:list'),
|
||||
504: ('客户现场', 121, 3, 'site', 'master/site/index', 'master:site:list'),
|
||||
@@ -476,47 +477,46 @@ BUTTON_SPECS = """
|
||||
1065 502 1 菌种查询 master:strain:query
|
||||
1066 502 2 菌种新增 master:strain:add
|
||||
1067 502 3 菌种修改 master:strain:edit
|
||||
1068 502 4 菌种删除 master:strain:remove
|
||||
1069 503 1 客户查询 master:customer:query
|
||||
1070 503 2 客户新增 master:customer:add
|
||||
1071 503 3 客户修改 master:customer:edit
|
||||
1072 503 4 客户删除 master:customer:remove
|
||||
1073 504 1 现场查询 master:site:query
|
||||
1074 504 2 现场新增 master:site:add
|
||||
1075 504 3 现场修改 master:site:edit
|
||||
1076 504 4 现场删除 master:site:remove
|
||||
1077 504 5 分配用户 master:site:assign
|
||||
1078 505 1 产线查询 master:line:query
|
||||
1079 505 2 产线新增 master:line:add
|
||||
1080 505 3 产线修改 master:line:edit
|
||||
1081 505 4 产线删除 master:line:remove
|
||||
1082 506 1 仓库查询 master:warehouse:query
|
||||
1083 506 2 仓库新增 master:warehouse:add
|
||||
1084 506 3 仓库修改 master:warehouse:edit
|
||||
1085 506 4 仓库删除 master:warehouse:remove
|
||||
1086 506 5 分配用户 master:warehouse:assign
|
||||
1087 507 1 托盘查询 master:pallet:query
|
||||
1088 507 2 托盘新增 master:pallet:add
|
||||
1089 507 3 托盘修改 master:pallet:edit
|
||||
1090 507 4 托盘删除 master:pallet:remove
|
||||
1091 507 5 托盘打印 master:pallet:print
|
||||
1092 508 1 入库查询 business:inbound:query
|
||||
1093 508 2 入库新增 business:inbound:add
|
||||
1094 508 3 入库修改 business:inbound:edit
|
||||
1095 508 4 入库删除 business:inbound:remove
|
||||
1096 508 5 入库确认 business:inbound:confirm
|
||||
1097 509 1 装填查询 business:filling:query
|
||||
1098 509 2 装填新增 business:filling:add
|
||||
1099 510 1 发货查询 business:shipment:query
|
||||
1100 510 2 发货新增 business:shipment:add
|
||||
1101 510 3 发货修改 business:shipment:edit
|
||||
1102 510 4 发货删除 business:shipment:remove
|
||||
1103 510 5 发货确认 business:shipment:confirm
|
||||
1104 511 1 使用查询 business:usage:query
|
||||
1105 511 2 使用新增 business:usage:add
|
||||
1106 512 1 退回查询 business:return:query
|
||||
1107 512 2 退回申请 business:return:request
|
||||
1108 512 3 退回确认 business:return:confirm
|
||||
1109 519 1 批次查询 system:testbatch:query
|
||||
1110 519 2 批次新增 system:testbatch:add
|
||||
1111 519 3 批次修改 system:testbatch:edit
|
||||
1112 519 4 批次授权 system:testbatch:assign
|
||||
1113 519 5 批次关闭 system:testbatch:close
|
||||
1114 519 6 数据纳入 system:testbatch:adopt
|
||||
1115 519 7 批次清理 system:testbatch:purge
|
||||
"""
|
||||
EXPECTED_BUTTONS = {
|
||||
int(menu_id): (name, int(parent_id), int(order_num), permission)
|
||||
@@ -526,6 +526,7 @@ EXPECTED_BUTTONS = {
|
||||
}
|
||||
EXPECTED_PAGE_PERMISSIONS = frozenset(
|
||||
[
|
||||
'system:testbatch:list',
|
||||
'master:strain:list',
|
||||
'master:customer:list',
|
||||
'master:site:list',
|
||||
@@ -550,41 +551,40 @@ EXPECTED_BUTTON_PERMISSIONS = frozenset(
|
||||
'master:strain:query',
|
||||
'master:strain:add',
|
||||
'master:strain:edit',
|
||||
'master:strain:remove',
|
||||
'master:customer:query',
|
||||
'master:customer:add',
|
||||
'master:customer:edit',
|
||||
'master:customer:remove',
|
||||
'master:site:query',
|
||||
'master:site:add',
|
||||
'master:site:edit',
|
||||
'master:site:remove',
|
||||
'master:site:assign',
|
||||
'master:line:query',
|
||||
'master:line:add',
|
||||
'master:line:edit',
|
||||
'master:line:remove',
|
||||
'master:warehouse:query',
|
||||
'master:warehouse:add',
|
||||
'master:warehouse:edit',
|
||||
'master:warehouse:remove',
|
||||
'master:warehouse:assign',
|
||||
'master:pallet:query',
|
||||
'master:pallet:add',
|
||||
'master:pallet:edit',
|
||||
'master:pallet:remove',
|
||||
'master:pallet:print',
|
||||
'business:inbound:query',
|
||||
'business:inbound:add',
|
||||
'business:inbound:edit',
|
||||
'business:inbound:remove',
|
||||
'business:inbound:confirm',
|
||||
'business:filling:query',
|
||||
'business:filling:add',
|
||||
'business:shipment:query',
|
||||
'business:shipment:add',
|
||||
'business:shipment:edit',
|
||||
'business:shipment:remove',
|
||||
'system:testbatch:query',
|
||||
'system:testbatch:add',
|
||||
'system:testbatch:edit',
|
||||
'system:testbatch:assign',
|
||||
'system:testbatch:close',
|
||||
'system:testbatch:adopt',
|
||||
'system:testbatch:purge',
|
||||
'business:shipment:confirm',
|
||||
'business:usage:query',
|
||||
'business:usage:add',
|
||||
@@ -595,6 +595,7 @@ EXPECTED_BUTTON_PERMISSIONS = frozenset(
|
||||
)
|
||||
EXPECTED_PERMISSIONS = EXPECTED_PAGE_PERMISSIONS | EXPECTED_BUTTON_PERMISSIONS
|
||||
BUSINESS_MENU_SPECS = """
|
||||
519|1|测试数据批次|testBatch||7|system:testbatch:list|system/testBatch/index
|
||||
121|0|基础资料维护|businessMaster||1||<NULL>
|
||||
122|0|业务管理|businessOperation||2||<NULL>
|
||||
123|0|报表查询|businessReport||3||<NULL>
|
||||
@@ -618,47 +619,46 @@ BUSINESS_MENU_SPECS = """
|
||||
1065|502|菌种查询|||1|master:strain:query|
|
||||
1066|502|菌种新增|||2|master:strain:add|
|
||||
1067|502|菌种修改|||3|master:strain:edit|
|
||||
1068|502|菌种删除|||4|master:strain:remove|
|
||||
1069|503|客户查询|||1|master:customer:query|
|
||||
1070|503|客户新增|||2|master:customer:add|
|
||||
1071|503|客户修改|||3|master:customer:edit|
|
||||
1072|503|客户删除|||4|master:customer:remove|
|
||||
1073|504|现场查询|||1|master:site:query|
|
||||
1074|504|现场新增|||2|master:site:add|
|
||||
1075|504|现场修改|||3|master:site:edit|
|
||||
1076|504|现场删除|||4|master:site:remove|
|
||||
1077|504|分配用户|||5|master:site:assign|
|
||||
1078|505|产线查询|||1|master:line:query|
|
||||
1079|505|产线新增|||2|master:line:add|
|
||||
1080|505|产线修改|||3|master:line:edit|
|
||||
1081|505|产线删除|||4|master:line:remove|
|
||||
1082|506|仓库查询|||1|master:warehouse:query|
|
||||
1083|506|仓库新增|||2|master:warehouse:add|
|
||||
1084|506|仓库修改|||3|master:warehouse:edit|
|
||||
1085|506|仓库删除|||4|master:warehouse:remove|
|
||||
1086|506|分配用户|||5|master:warehouse:assign|
|
||||
1087|507|托盘查询|||1|master:pallet:query|
|
||||
1088|507|托盘新增|||2|master:pallet:add|
|
||||
1089|507|托盘修改|||3|master:pallet:edit|
|
||||
1090|507|托盘删除|||4|master:pallet:remove|
|
||||
1091|507|托盘打印|||5|master:pallet:print|
|
||||
1092|508|入库查询|||1|business:inbound:query|
|
||||
1093|508|入库新增|||2|business:inbound:add|
|
||||
1094|508|入库修改|||3|business:inbound:edit|
|
||||
1095|508|入库删除|||4|business:inbound:remove|
|
||||
1096|508|入库确认|||5|business:inbound:confirm|
|
||||
1097|509|装填查询|||1|business:filling:query|
|
||||
1098|509|装填新增|||2|business:filling:add|
|
||||
1099|510|发货查询|||1|business:shipment:query|
|
||||
1100|510|发货新增|||2|business:shipment:add|
|
||||
1101|510|发货修改|||3|business:shipment:edit|
|
||||
1102|510|发货删除|||4|business:shipment:remove|
|
||||
1103|510|发货确认|||5|business:shipment:confirm|
|
||||
1104|511|使用查询|||1|business:usage:query|
|
||||
1105|511|使用新增|||2|business:usage:add|
|
||||
1106|512|退回查询|||1|business:return:query|
|
||||
1107|512|退回申请|||2|business:return:request|
|
||||
1108|512|退回确认|||3|business:return:confirm|
|
||||
1109|519|批次查询|||1|system:testbatch:query|
|
||||
1110|519|批次新增|||2|system:testbatch:add|
|
||||
1111|519|批次修改|||3|system:testbatch:edit|
|
||||
1112|519|批次授权|||4|system:testbatch:assign|
|
||||
1113|519|批次关闭|||5|system:testbatch:close|
|
||||
1114|519|数据纳入|||6|system:testbatch:adopt|
|
||||
1115|519|批次清理|||7|system:testbatch:purge|
|
||||
""".strip()
|
||||
|
||||
|
||||
@@ -679,7 +679,33 @@ def _expected_business_menu_fields() -> dict[int, tuple]:
|
||||
|
||||
|
||||
EXPECTED_BUSINESS_MENU_FIELDS = _expected_business_menu_fields()
|
||||
LEGACY_PATCH_BUSINESS_MENU_FIELDS = EXPECTED_BUSINESS_MENU_FIELDS | {
|
||||
|
||||
LEGACY_REMOVED_BUTTON_SPECS = {
|
||||
1068: ('菌种删除', 502, 4, 'master:strain:remove'),
|
||||
1072: ('客户删除', 503, 4, 'master:customer:remove'),
|
||||
1076: ('现场删除', 504, 4, 'master:site:remove'),
|
||||
1081: ('产线删除', 505, 4, 'master:line:remove'),
|
||||
1085: ('仓库删除', 506, 4, 'master:warehouse:remove'),
|
||||
1090: ('托盘删除', 507, 4, 'master:pallet:remove'),
|
||||
1095: ('入库删除', 508, 4, 'business:inbound:remove'),
|
||||
1102: ('发货删除', 510, 4, 'business:shipment:remove'),
|
||||
}
|
||||
LEGACY_BUSINESS_MENU_IDS = set(range(121, 124)) | set(range(502, 519)) | set(range(1065, 1109))
|
||||
LEGACY_EXPECTED_BUSINESS_MENU_FIELDS = {
|
||||
menu_id: fields for menu_id, fields in EXPECTED_BUSINESS_MENU_FIELDS.items() if menu_id in LEGACY_BUSINESS_MENU_IDS
|
||||
}
|
||||
LEGACY_EXPECTED_BUSINESS_MENU_FIELDS.update(
|
||||
{
|
||||
menu_id: (parent_id, name, '', '', order_num, permission, '')
|
||||
for menu_id, (name, parent_id, order_num, permission) in LEGACY_REMOVED_BUTTON_SPECS.items()
|
||||
}
|
||||
)
|
||||
LEGACY_EXPECTED_PAGE_PERMISSIONS = EXPECTED_PAGE_PERMISSIONS - {'system:testbatch:list'}
|
||||
LEGACY_EXPECTED_BUTTON_PERMISSIONS = EXPECTED_BUTTON_PERMISSIONS - {
|
||||
permission for permission in EXPECTED_BUTTON_PERMISSIONS if permission.startswith('system:testbatch:')
|
||||
} | {spec[3] for spec in LEGACY_REMOVED_BUTTON_SPECS.values()}
|
||||
LEGACY_EXPECTED_PERMISSIONS = LEGACY_EXPECTED_PAGE_PERMISSIONS | LEGACY_EXPECTED_BUTTON_PERMISSIONS
|
||||
LEGACY_PATCH_BUSINESS_MENU_FIELDS = LEGACY_EXPECTED_BUSINESS_MENU_FIELDS | {
|
||||
121: (1, '基础资料维护', 'businessMaster', '', 10, '', None),
|
||||
122: (1, '业务管理', 'businessOperation', '', 11, '', None),
|
||||
123: (1, '报表查询', 'businessReport', '', 12, '', None),
|
||||
@@ -706,7 +732,28 @@ EXPECTED_TOP_LEVEL_MENU_STABLE_FIELDS = {
|
||||
3: ('系统工具', 'tool', None, '', '', '1', '0', 'M', '0', '0', '', 'tool'),
|
||||
}
|
||||
MENU_PROMOTION_IDS = set(EXPECTED_TOP_LEVEL_MENU_POSITIONS)
|
||||
BUSINESS_MENU_IDS = set(range(121, 124)) | set(range(502, 519)) | set(range(1065, 1109))
|
||||
BUSINESS_MENU_IDS = (
|
||||
set(range(121, 124))
|
||||
| set(range(502, 519))
|
||||
| {519}
|
||||
| set(range(1065, 1068))
|
||||
| set(range(1069, 1072))
|
||||
| set(range(1073, 1076))
|
||||
| {1077}
|
||||
| set(range(1078, 1081))
|
||||
| set(range(1082, 1085))
|
||||
| {1086}
|
||||
| set(range(1087, 1090))
|
||||
| {1091}
|
||||
| set(range(1092, 1095))
|
||||
| {1096}
|
||||
| set(range(1097, 1099))
|
||||
| set(range(1099, 1102))
|
||||
| {1103}
|
||||
| set(range(1104, 1109))
|
||||
| set(range(1109, 1116))
|
||||
)
|
||||
TEST_BATCH_MENU_IDS = {519, 1109, 1110, 1111, 1112, 1113, 1114, 1115}
|
||||
MYSQL_MENU_STABLE_COLUMNS = (
|
||||
'menu_name',
|
||||
'parent_id',
|
||||
@@ -1022,13 +1069,11 @@ def _assert_test_batch_sql_contract(
|
||||
test_case.assertRegex(normalized, index_pattern)
|
||||
test_case.assertIn("comment '测试数据批次id;null表示正式数据'", normalized)
|
||||
else:
|
||||
index_pattern = (
|
||||
rf'\bcreate\s+index\s+{index_name}\s+on\s+{table_name}\s*\(\s*test_batch_id\s*\)'
|
||||
)
|
||||
index_pattern = rf'\bcreate\s+index\s+{index_name}\s+on\s+{table_name}\s*\(\s*test_batch_id\s*\)'
|
||||
test_case.assertRegex(normalized, index_pattern)
|
||||
test_case.assertRegex(
|
||||
normalized,
|
||||
rf"comment\s+on\s+column\s+{table_name}\.test_batch_id\s+is\s+"
|
||||
rf'comment\s+on\s+column\s+{table_name}\.test_batch_id\s+is\s+'
|
||||
r"'测试数据批次id;null表示正式数据'",
|
||||
)
|
||||
|
||||
@@ -1049,8 +1094,8 @@ def _menu_rows(sql: str, menu_ids: set[int]) -> dict[int, list]:
|
||||
return {int(row[0]): row for row in selected}
|
||||
|
||||
|
||||
def _business_menu_rows(sql: str) -> dict[int, list]:
|
||||
return _menu_rows(sql, BUSINESS_MENU_IDS)
|
||||
def _business_menu_rows(sql: str, menu_ids: set[int] | None = None) -> dict[int, list]:
|
||||
return _menu_rows(sql, BUSINESS_MENU_IDS if menu_ids is None else menu_ids)
|
||||
|
||||
|
||||
def _assert_top_level_menu_fields(test_case: unittest.TestCase, sql: str) -> None:
|
||||
@@ -1067,7 +1112,7 @@ def _assert_business_menu_fields(
|
||||
sql: str,
|
||||
expected_fields: dict[int, tuple] = EXPECTED_BUSINESS_MENU_FIELDS,
|
||||
) -> None:
|
||||
rows = _business_menu_rows(sql)
|
||||
rows = _business_menu_rows(sql, set(expected_fields))
|
||||
invalid_widths = {menu_id: len(row) for menu_id, row in rows.items() if len(row) != SYS_MENU_VALUE_COUNT}
|
||||
test_case.assertEqual({}, invalid_widths)
|
||||
actual = {
|
||||
@@ -1085,17 +1130,21 @@ def _assert_business_menu_fields(
|
||||
test_case.assertEqual(expected_fields, actual)
|
||||
|
||||
|
||||
def _assert_business_permission_inventory(test_case: unittest.TestCase, sql: str) -> None:
|
||||
def _assert_business_permission_inventory(
|
||||
test_case: unittest.TestCase,
|
||||
sql: str,
|
||||
expected_permissions: frozenset[str] = EXPECTED_PERMISSIONS,
|
||||
) -> None:
|
||||
permission_rows = [
|
||||
row
|
||||
for row in _insert_rows(sql, 'sys_menu')
|
||||
if len(row) > SYS_MENU_PERMS_INDEX
|
||||
and row[SYS_MENU_PERMS_INDEX]
|
||||
and re.match(r'^(?:master|business|report):', row[SYS_MENU_PERMS_INDEX])
|
||||
and re.match(r'^(?:master|business|report|system:testbatch):', row[SYS_MENU_PERMS_INDEX])
|
||||
]
|
||||
test_case.assertTrue(all(len(row) == SYS_MENU_VALUE_COUNT for row in permission_rows))
|
||||
actual_permissions = Counter(row[SYS_MENU_PERMS_INDEX] for row in permission_rows)
|
||||
test_case.assertEqual(Counter(EXPECTED_PERMISSIONS), actual_permissions)
|
||||
test_case.assertEqual(Counter(expected_permissions), actual_permissions)
|
||||
|
||||
|
||||
MENU_PROMOTION_LOCK_STATEMENT = (
|
||||
@@ -1310,6 +1359,57 @@ class SqlContractTest(unittest.TestCase):
|
||||
is_patch=is_patch,
|
||||
)
|
||||
|
||||
def test_test_batch_patches_migrate_legacy_menu_permissions_without_role_grants(self) -> None:
|
||||
legacy_removed_ids = set(LEGACY_REMOVED_BUTTON_SPECS)
|
||||
for path in (TEST_BATCH_MYSQL_PATCH_PATH, TEST_BATCH_PG_PATCH_PATH):
|
||||
with self.subTest(path=path.name):
|
||||
raw = path.read_text(encoding='utf-8')
|
||||
statements = _sql_statements(raw)
|
||||
normalized = [_normalized_sql_statement(statement) for statement in statements]
|
||||
|
||||
role_delete_indexes = [
|
||||
index
|
||||
for index, statement in enumerate(normalized)
|
||||
if re.fullmatch(r'delete from sys_role_menu where menu_id in \([^)]+\)', statement)
|
||||
]
|
||||
menu_delete_indexes = [
|
||||
index
|
||||
for index, statement in enumerate(normalized)
|
||||
if re.fullmatch(r'delete from sys_menu where menu_id in \([^)]+\)', statement)
|
||||
]
|
||||
menu_insert_indexes = [
|
||||
index
|
||||
for index, statement in enumerate(normalized)
|
||||
if statement.startswith('insert into sys_menu values ')
|
||||
]
|
||||
self.assertEqual(1, len(role_delete_indexes))
|
||||
self.assertEqual(1, len(menu_delete_indexes))
|
||||
self.assertEqual(1, len(menu_insert_indexes))
|
||||
role_delete = normalized[role_delete_indexes[0]]
|
||||
menu_delete = normalized[menu_delete_indexes[0]]
|
||||
role_delete_ids = {
|
||||
int(value.strip()) for value in re.search(r'\(([^)]+)\)', role_delete).group(1).split(',')
|
||||
}
|
||||
menu_delete_ids = {
|
||||
int(value.strip()) for value in re.search(r'\(([^)]+)\)', menu_delete).group(1).split(',')
|
||||
}
|
||||
self.assertEqual(legacy_removed_ids, role_delete_ids)
|
||||
self.assertEqual(legacy_removed_ids, menu_delete_ids)
|
||||
self.assertLess(role_delete_indexes[0], menu_delete_indexes[0])
|
||||
self.assertLess(menu_delete_indexes[0], menu_insert_indexes[0])
|
||||
|
||||
inserted_rows = _insert_rows(raw, 'sys_menu')
|
||||
inserted_by_id = {int(row[0]): row for row in inserted_rows}
|
||||
self.assertEqual(TEST_BATCH_MENU_IDS, set(inserted_by_id))
|
||||
self.assertTrue(all(len(row) == SYS_MENU_VALUE_COUNT for row in inserted_by_id.values()))
|
||||
self.assertEqual('测试数据批次', inserted_by_id[519][1])
|
||||
self.assertEqual('1', inserted_by_id[519][2])
|
||||
self.assertEqual('7', inserted_by_id[519][3])
|
||||
self.assertEqual('system:testbatch:list', inserted_by_id[519][13])
|
||||
self.assertEqual(519, int(inserted_by_id[1109][2]))
|
||||
self.assertEqual('system:testbatch:purge', inserted_by_id[1115][13])
|
||||
self.assertNotRegex('\n'.join(normalized), r'\binsert into sys_role_menu\b')
|
||||
|
||||
def test_initializers_define_exact_business_table_set(self) -> None:
|
||||
for filename in INITIALIZERS:
|
||||
with self.subTest(filename=filename):
|
||||
@@ -1357,8 +1457,8 @@ class SqlContractTest(unittest.TestCase):
|
||||
self.assertFalse(_is_postgres_naive_timestamp_with_default_precision('occurred_at timestamp with time zone'))
|
||||
|
||||
def test_initializers_define_fixed_business_menus_and_permissions(self) -> None:
|
||||
self.assertEqual(17, len(EXPECTED_PAGE_PERMISSIONS))
|
||||
self.assertEqual(44, len(EXPECTED_BUTTON_PERMISSIONS))
|
||||
self.assertEqual(18, len(EXPECTED_PAGE_PERMISSIONS))
|
||||
self.assertEqual(43, len(EXPECTED_BUTTON_PERMISSIONS))
|
||||
self.assertFalse(EXPECTED_PAGE_PERMISSIONS & EXPECTED_BUTTON_PERMISSIONS)
|
||||
self.assertEqual(61, len(EXPECTED_PERMISSIONS))
|
||||
self.assertEqual(64, len(EXPECTED_BUSINESS_MENU_FIELDS))
|
||||
@@ -1969,20 +2069,26 @@ class SqlContractTest(unittest.TestCase):
|
||||
self.assertEqual(LEGACY_EXPECTED_FOREIGN_KEYS[table], foreign_keys)
|
||||
self.assertEqual(LEGACY_EXPECTED_CHECKS[table], checks)
|
||||
_assert_business_menu_fields(self, raw, LEGACY_PATCH_BUSINESS_MENU_FIELDS)
|
||||
_assert_business_permission_inventory(self, raw)
|
||||
patch_rows = _business_menu_rows(raw)
|
||||
_assert_business_permission_inventory(self, raw, LEGACY_EXPECTED_PERMISSIONS)
|
||||
patch_rows = _business_menu_rows(raw, LEGACY_BUSINESS_MENU_IDS)
|
||||
mysql_rows = _business_menu_rows((SQL_ROOT / 'shierfeng-fastapi.sql').read_text(encoding='utf-8'))
|
||||
compared_indexes = (0, 1, *range(4, 15))
|
||||
common_menu_ids = LEGACY_BUSINESS_MENU_IDS & BUSINESS_MENU_IDS
|
||||
expected_legacy_rows = {
|
||||
menu_id: tuple(
|
||||
'#' if index == SYS_MENU_ICON_INDEX and menu_id in EXPECTED_BUSINESS_ROOT_ICONS else row[index]
|
||||
for index in compared_indexes
|
||||
)
|
||||
for menu_id, row in mysql_rows.items()
|
||||
if menu_id in common_menu_ids
|
||||
}
|
||||
self.assertEqual(
|
||||
expected_legacy_rows,
|
||||
{menu_id: tuple(row[index] for index in compared_indexes) for menu_id, row in patch_rows.items()},
|
||||
{
|
||||
menu_id: tuple(row[index] for index in compared_indexes)
|
||||
for menu_id, row in patch_rows.items()
|
||||
if menu_id in common_menu_ids
|
||||
},
|
||||
)
|
||||
self.assertRegex(lower, r'\bon\s+duplicate\s+key\s+update\b')
|
||||
self.assertNotRegex(lower, r'\binsert\s+ignore\b')
|
||||
@@ -2017,7 +2123,7 @@ class SqlContractTest(unittest.TestCase):
|
||||
flags=re.S,
|
||||
)
|
||||
self.assertIsNotNone(menu_insert, 'sys_menu seed must use a fail-closed upsert')
|
||||
self.assertEqual(len(BUSINESS_MENU_IDS), len(_insert_rows(menu_insert_statement, 'sys_menu')))
|
||||
self.assertEqual(len(LEGACY_BUSINESS_MENU_IDS), len(_insert_rows(menu_insert_statement, 'sys_menu')))
|
||||
expected_guard = ' and '.join(f'{column} <=> values({column})' for column in MYSQL_MENU_STABLE_COLUMNS)
|
||||
actual_guard = re.sub(r'\s+', ' ', menu_insert.group('guard')).strip()
|
||||
self.assertEqual(expected_guard, actual_guard)
|
||||
@@ -2039,8 +2145,8 @@ class SqlContractTest(unittest.TestCase):
|
||||
verification_columns = tuple(column.strip() for column in verification.group('columns').split(','))
|
||||
self.assertEqual(('menu_id', *MYSQL_MENU_STABLE_COLUMNS), verification_columns)
|
||||
verification_ids = [int(value.strip()) for value in verification.group('ids').split(',')]
|
||||
self.assertEqual(len(BUSINESS_MENU_IDS), len(verification_ids))
|
||||
self.assertEqual(BUSINESS_MENU_IDS, set(verification_ids))
|
||||
self.assertEqual(len(LEGACY_BUSINESS_MENU_IDS), len(verification_ids))
|
||||
self.assertEqual(LEGACY_BUSINESS_MENU_IDS, set(verification_ids))
|
||||
self.assertRegex(raw, r'查询结果必须为\s*64')
|
||||
|
||||
normalized = [_normalized_sql_statement(statement) for statement in statements]
|
||||
@@ -2149,11 +2255,12 @@ class SqlContractTest(unittest.TestCase):
|
||||
self.assertEqual(('menu_id', *MYSQL_MENU_STABLE_COLUMNS), expected_columns)
|
||||
|
||||
expected_rows = _insert_rows(statements[expected_inserts[0]], expected_table)
|
||||
self.assertEqual(len(BUSINESS_MENU_IDS), len(expected_rows))
|
||||
self.assertEqual(len(LEGACY_BUSINESS_MENU_IDS), len(expected_rows))
|
||||
expected_rows_by_id = {int(row[0]): tuple(row) for row in expected_rows}
|
||||
self.assertEqual(BUSINESS_MENU_IDS, set(expected_rows_by_id))
|
||||
self.assertEqual(LEGACY_BUSINESS_MENU_IDS, set(expected_rows_by_id))
|
||||
seed_rows_by_id = {
|
||||
menu_id: tuple(row[: len(expected_columns)]) for menu_id, row in _business_menu_rows(raw).items()
|
||||
menu_id: tuple(row[: len(expected_columns)])
|
||||
for menu_id, row in _business_menu_rows(raw, LEGACY_BUSINESS_MENU_IDS).items()
|
||||
}
|
||||
self.assertEqual(seed_rows_by_id, expected_rows_by_id)
|
||||
|
||||
|
||||
@@ -17,21 +17,18 @@ const expectedRequests = {
|
||||
{ url: "'/master/strain/' + strainId", method: 'get' },
|
||||
{ url: "'/master/strain'", method: 'post' },
|
||||
{ url: "'/master/strain'", method: 'put' },
|
||||
{ url: "'/master/strain/' + strainIds", method: 'delete' }
|
||||
],
|
||||
'src/api/master/customer.js': [
|
||||
{ url: "'/master/customer/list'", method: 'get' },
|
||||
{ url: "'/master/customer/' + customerId", method: 'get' },
|
||||
{ url: "'/master/customer'", method: 'post' },
|
||||
{ url: "'/master/customer'", method: 'put' },
|
||||
{ url: "'/master/customer/' + customerIds", method: 'delete' }
|
||||
],
|
||||
'src/api/master/site.js': [
|
||||
{ url: "'/master/site/list'", method: 'get' },
|
||||
{ url: "'/master/site/' + siteId", method: 'get' },
|
||||
{ url: "'/master/site'", method: 'post' },
|
||||
{ url: "'/master/site'", method: 'put' },
|
||||
{ url: "'/master/site/' + siteIds", method: 'delete' },
|
||||
{ url: "'/master/site/' + siteId + '/users'", method: 'get' },
|
||||
{ url: "'/master/site/' + siteId + '/users'", method: 'put' }
|
||||
],
|
||||
@@ -40,14 +37,12 @@ const expectedRequests = {
|
||||
{ url: "'/master/line/' + lineId", method: 'get' },
|
||||
{ url: "'/master/line'", method: 'post' },
|
||||
{ url: "'/master/line'", method: 'put' },
|
||||
{ url: "'/master/line/' + lineIds", method: 'delete' }
|
||||
],
|
||||
'src/api/master/warehouse.js': [
|
||||
{ url: "'/master/warehouse/list'", method: 'get' },
|
||||
{ url: "'/master/warehouse/' + warehouseId", method: 'get' },
|
||||
{ url: "'/master/warehouse'", method: 'post' },
|
||||
{ url: "'/master/warehouse'", method: 'put' },
|
||||
{ url: "'/master/warehouse/' + warehouseIds", method: 'delete' },
|
||||
{ url: "'/master/warehouse/' + warehouseId + '/users'", method: 'get' },
|
||||
{ url: "'/master/warehouse/' + warehouseId + '/users'", method: 'put' }
|
||||
],
|
||||
@@ -57,7 +52,6 @@ const expectedRequests = {
|
||||
{ url: "'/master/pallet/' + palletId + '/qrcode'", method: 'get' },
|
||||
{ url: "'/master/pallet'", method: 'post' },
|
||||
{ url: "'/master/pallet'", method: 'put' },
|
||||
{ url: "'/master/pallet/' + palletIds", method: 'delete' }
|
||||
],
|
||||
'src/api/business/inbound.js': [
|
||||
{ url: "'/business/inbound/list'", method: 'get' },
|
||||
@@ -66,7 +60,6 @@ const expectedRequests = {
|
||||
{ url: "'/business/inbound/' + inboundId", method: 'get' },
|
||||
{ url: "'/business/inbound'", method: 'post' },
|
||||
{ url: "'/business/inbound'", method: 'put' },
|
||||
{ url: "'/business/inbound/' + inboundIds", method: 'delete' },
|
||||
{ url: "'/business/inbound/' + inboundId + '/confirm'", method: 'put' }
|
||||
],
|
||||
'src/api/business/filling.js': [
|
||||
@@ -84,7 +77,6 @@ const expectedRequests = {
|
||||
{ url: "'/business/shipment/' + shipmentId", method: 'get' },
|
||||
{ url: "'/business/shipment'", method: 'post' },
|
||||
{ url: "'/business/shipment'", method: 'put' },
|
||||
{ url: "'/business/shipment/' + shipmentIds", method: 'delete' },
|
||||
{ url: "'/business/shipment/' + shipmentId + '/confirm'", method: 'put' }
|
||||
],
|
||||
'src/api/business/usage.js': [
|
||||
@@ -134,43 +126,43 @@ const expectedReportExports = {
|
||||
const masterPageContracts = {
|
||||
strain: {
|
||||
relativePath: 'src/views/master/strain/index.vue',
|
||||
apiNames: ['addStrain', 'delStrain', 'getStrain', 'listStrain', 'updateStrain'],
|
||||
permissions: ['add', 'edit', 'list', 'query', 'remove'],
|
||||
apiNames: ['addStrain', 'getStrain', 'listStrain', 'updateStrain'],
|
||||
permissions: ['add', 'edit', 'list', 'query'],
|
||||
addPayloadKeys: ['remark', 'status', 'strainCode', 'strainName'],
|
||||
editPayloadKeys: ['remark', 'status', 'strainCode', 'strainId', 'strainName']
|
||||
},
|
||||
customer: {
|
||||
relativePath: 'src/views/master/customer/index.vue',
|
||||
apiNames: ['addCustomer', 'delCustomer', 'getCustomer', 'listCustomer', 'updateCustomer'],
|
||||
permissions: ['add', 'edit', 'list', 'query', 'remove'],
|
||||
apiNames: ['addCustomer', 'getCustomer', 'listCustomer', 'updateCustomer'],
|
||||
permissions: ['add', 'edit', 'list', 'query'],
|
||||
addPayloadKeys: ['customerCode', 'customerName', 'remark', 'status'],
|
||||
editPayloadKeys: ['customerCode', 'customerId', 'customerName', 'remark', 'status']
|
||||
},
|
||||
site: {
|
||||
relativePath: 'src/views/master/site/index.vue',
|
||||
apiNames: ['addSite', 'delSite', 'getSite', 'listSite', 'updateSite'],
|
||||
permissions: ['add', 'assign', 'edit', 'list', 'query', 'remove'],
|
||||
apiNames: ['addSite', 'getSite', 'listSite', 'updateSite'],
|
||||
permissions: ['add', 'assign', 'edit', 'list', 'query'],
|
||||
addPayloadKeys: ['address', 'customerId', 'remark', 'siteCode', 'siteName', 'status'],
|
||||
editPayloadKeys: ['address', 'customerId', 'remark', 'siteCode', 'siteId', 'siteName', 'status']
|
||||
},
|
||||
line: {
|
||||
relativePath: 'src/views/master/line/index.vue',
|
||||
apiNames: ['addLine', 'delLine', 'getLine', 'listLine', 'updateLine'],
|
||||
permissions: ['add', 'edit', 'list', 'query', 'remove'],
|
||||
apiNames: ['addLine', 'getLine', 'listLine', 'updateLine'],
|
||||
permissions: ['add', 'edit', 'list', 'query'],
|
||||
addPayloadKeys: ['lineCode', 'lineName', 'remark', 'siteId', 'status'],
|
||||
editPayloadKeys: ['lineCode', 'lineId', 'lineName', 'remark', 'siteId', 'status']
|
||||
},
|
||||
warehouse: {
|
||||
relativePath: 'src/views/master/warehouse/index.vue',
|
||||
apiNames: ['addWarehouse', 'delWarehouse', 'getWarehouse', 'listWarehouse', 'updateWarehouse'],
|
||||
permissions: ['add', 'assign', 'edit', 'list', 'query', 'remove'],
|
||||
apiNames: ['addWarehouse', 'getWarehouse', 'listWarehouse', 'updateWarehouse'],
|
||||
permissions: ['add', 'assign', 'edit', 'list', 'query'],
|
||||
addPayloadKeys: ['address', 'remark', 'status', 'warehouseCode', 'warehouseName'],
|
||||
editPayloadKeys: ['address', 'remark', 'status', 'warehouseCode', 'warehouseId', 'warehouseName']
|
||||
},
|
||||
pallet: {
|
||||
relativePath: 'src/views/master/pallet/index.vue',
|
||||
apiNames: ['addPallet', 'delPallet', 'getPallet', 'getPalletQrcode', 'listPallet', 'updatePallet'],
|
||||
permissions: ['add', 'edit', 'list', 'print', 'query', 'remove'],
|
||||
apiNames: ['addPallet', 'getPallet', 'getPalletQrcode', 'listPallet', 'updatePallet'],
|
||||
permissions: ['add', 'edit', 'list', 'print', 'query'],
|
||||
addPayloadKeys: ['capacityPackages', 'palletCode', 'remark'],
|
||||
editPayloadKeys: ['assetStatus', 'capacityPackages', 'palletId', 'remark']
|
||||
}
|
||||
@@ -182,14 +174,13 @@ const businessPageContracts = {
|
||||
apiNames: [
|
||||
'addInbound',
|
||||
'confirmInbound',
|
||||
'delInbound',
|
||||
'getInbound',
|
||||
'getInboundWarehouseOptions',
|
||||
'listInbound',
|
||||
'scanInboundPallet',
|
||||
'updateInbound'
|
||||
],
|
||||
permissions: ['add', 'confirm', 'edit', 'list', 'query', 'remove'],
|
||||
permissions: ['add', 'confirm', 'edit', 'list', 'query'],
|
||||
payloads: {
|
||||
addInbound: ['palletIds', 'warehouseId'],
|
||||
updateInbound: ['inboundId', 'palletIds', 'warehouseId'],
|
||||
@@ -217,7 +208,6 @@ const businessPageContracts = {
|
||||
apiNames: [
|
||||
'addShipment',
|
||||
'confirmShipment',
|
||||
'delShipment',
|
||||
'getShipment',
|
||||
'getShipmentSiteOptions',
|
||||
'getShipmentWarehouseOptions',
|
||||
@@ -225,7 +215,7 @@ const businessPageContracts = {
|
||||
'scanShipmentPallet',
|
||||
'updateShipment'
|
||||
],
|
||||
permissions: ['add', 'confirm', 'edit', 'list', 'query', 'remove'],
|
||||
permissions: ['add', 'confirm', 'edit', 'list', 'query'],
|
||||
payloads: {
|
||||
addShipment: ['palletIds', 'sourceWarehouseId', 'targetSiteId'],
|
||||
updateShipment: ['palletIds', 'shipmentId', 'sourceWarehouseId', 'targetSiteId'],
|
||||
@@ -361,47 +351,40 @@ const expectedButtonPermissions = [
|
||||
'master:strain:query',
|
||||
'master:strain:add',
|
||||
'master:strain:edit',
|
||||
'master:strain:remove',
|
||||
'master:customer:query',
|
||||
'master:customer:add',
|
||||
'master:customer:edit',
|
||||
'master:customer:remove',
|
||||
'master:site:query',
|
||||
'master:site:add',
|
||||
'master:site:edit',
|
||||
'master:site:remove',
|
||||
'master:site:assign',
|
||||
'master:line:query',
|
||||
'master:line:add',
|
||||
'master:line:edit',
|
||||
'master:line:remove',
|
||||
'master:warehouse:query',
|
||||
'master:warehouse:add',
|
||||
'master:warehouse:edit',
|
||||
'master:warehouse:remove',
|
||||
'master:warehouse:assign',
|
||||
'master:pallet:query',
|
||||
'master:pallet:add',
|
||||
'master:pallet:edit',
|
||||
'master:pallet:remove',
|
||||
'master:pallet:print',
|
||||
'business:inbound:query',
|
||||
'business:inbound:add',
|
||||
'business:inbound:edit',
|
||||
'business:inbound:remove',
|
||||
'business:inbound:confirm',
|
||||
'business:filling:query',
|
||||
'business:filling:add',
|
||||
'business:shipment:query',
|
||||
'business:shipment:add',
|
||||
'business:shipment:edit',
|
||||
'business:shipment:remove',
|
||||
'business:shipment:confirm',
|
||||
'business:usage:query',
|
||||
'business:usage:add',
|
||||
'business:return:query',
|
||||
'business:return:request',
|
||||
'business:return:confirm'
|
||||
'business:return:confirm',
|
||||
'system:testbatch:adopt'
|
||||
]
|
||||
|
||||
const expectedPermissions = [...expectedPagePermissions, ...expectedButtonPermissions].sort()
|
||||
@@ -536,7 +519,7 @@ function parseStaticPermissionArray(expression) {
|
||||
assert.ok(index === ranges.length - 1, '权限门禁数组禁止稀疏元素,仅允许单个尾逗号')
|
||||
continue
|
||||
}
|
||||
const literal = /^(['"])((?:master|business|report):[a-z]+:[a-z]+)\1$/.exec(item)
|
||||
const literal = /^(['"])((?:master|business|report|system):[a-z]+:[a-z]+)\1$/.exec(item)
|
||||
assert.ok(literal, '权限门禁数组禁止动态表达式或非法字面量')
|
||||
permissions.push(literal[2])
|
||||
}
|
||||
@@ -1147,8 +1130,8 @@ test('窄屏模式控件仍保留正式退出与测试批次切换入口', async
|
||||
|
||||
test('17 个页面的真实权限门禁逐项匹配独立硬编码契约', async () => {
|
||||
assert.equal(expectedPagePermissions.length, 17)
|
||||
assert.equal(expectedButtonPermissions.length, 44)
|
||||
assert.equal(new Set(expectedPermissions).size, 61)
|
||||
assert.equal(expectedButtonPermissions.length, 37)
|
||||
assert.equal(new Set(expectedPermissions).size, 54)
|
||||
const relativePaths = [
|
||||
...Object.values(masterPageContracts),
|
||||
...Object.values(businessPageContracts),
|
||||
@@ -1450,7 +1433,7 @@ test('首次入库确认失败后取消重试不丢弃原幂等键', async () =>
|
||||
|
||||
test('17 个 API 文件逐一匹配硬编码请求契约', async (t) => {
|
||||
assert.equal(Object.keys(expectedRequests).length, 17)
|
||||
assert.equal(Object.values(expectedRequests).flat().length, 74)
|
||||
assert.equal(Object.values(expectedRequests).flat().length, 66)
|
||||
|
||||
for (const [relativePath, expected] of Object.entries(expectedRequests)) {
|
||||
await t.test(relativePath, async () => {
|
||||
@@ -1647,7 +1630,6 @@ test('六个基础资料页面逐页满足 API、权限、分页和安全删除
|
||||
assertButtonsUsePermission(source, 'submitCreate', `${permissionPrefix}:add`)
|
||||
assertButtonsUsePermission(source, 'handleUpdate', `${permissionPrefix}:edit`)
|
||||
assertButtonsUsePermission(source, 'submitUpdate', `${permissionPrefix}:edit`)
|
||||
assertButtonsUsePermission(source, 'handleDelete', `${permissionPrefix}:remove`)
|
||||
|
||||
for (const button of extractButtonBlocks(source, 'handleUpdate')) {
|
||||
assert.match(
|
||||
@@ -1708,20 +1690,10 @@ test('六个基础资料页面逐页满足 API、权限、分页和安全删除
|
||||
assert.doesNotMatch(selectionColumn, /:selectable=/)
|
||||
assert.doesNotMatch(source, /function isRowSelectable\(/)
|
||||
assert.match(source, /const selectedIds = ref\(\[\]\)/)
|
||||
assert.match(source, /const removableIds = ref\(\[\]\)/)
|
||||
const selectionSource = source.slice(source.indexOf('function handleSelectionChange('), source.indexOf('function handleAdd('))
|
||||
assert.match(selectionSource, new RegExp(`selectedIds\\.value = selection\\.map\\(\\(item\\) => item\\.${idKey}\\)`))
|
||||
assert.match(selectionSource, new RegExp(`removableIds\\.value = selection\\s*\\.filter\\(\\(item\\) => item\\.canRemove === true\\)\\s*\\.map\\(\\(item\\) => item\\.${idKey}\\)`))
|
||||
assert.match(selectionSource, /single\.value = selectedIds\.value\.length !== 1/)
|
||||
assert.match(selectionSource, /multiple\.value = removableIds\.value\.length === 0/)
|
||||
assert.match(detailSource, new RegExp(`const ${idKey} = row\\.${idKey} \\|\\| selectedIds\\.value\\[0\\]`))
|
||||
assert.match(source, new RegExp(`const targetIds = row\\?\\.${idKey} \\? \\(row\\.canRemove === true \\? \\[row\\.${idKey}\\] : \\[\\]\\) : removableIds\\.value`))
|
||||
const rowDeleteButtons = extractButtonBlocks(source, 'handleDelete')
|
||||
.filter((button) => button.includes('handleDelete(scope.row)'))
|
||||
assert.ok(rowDeleteButtons.length > 0, `${resource} 缺少行删除按钮`)
|
||||
for (const button of rowDeleteButtons) {
|
||||
assert.match(button, /v-if="scope\.row\.canRemove === true"/)
|
||||
}
|
||||
const rowUpdateButtons = extractButtonBlocks(source, 'handleUpdate')
|
||||
.filter((button) => button.includes('handleUpdate(scope.row)'))
|
||||
assert.ok(rowUpdateButtons.length > 0, `${resource} 缺少行修改按钮`)
|
||||
@@ -1980,7 +1952,6 @@ test('入库页面只允许 DRAFT 变更并以 authoritative 详情和独立确
|
||||
assertButtonsUsePermission(source, 'handleAdd', 'business:inbound:add')
|
||||
assertButtonsUsePermission(source, 'submitInbound', 'business:inbound:add')
|
||||
assertButtonsUsePermission(source, 'handleUpdate', 'business:inbound:edit')
|
||||
assertButtonsUsePermission(source, 'handleDelete', 'business:inbound:remove')
|
||||
assertButtonsUsePermission(source, 'handleConfirm', 'business:inbound:confirm')
|
||||
assert.match(source, /proxy\.\$auth\.hasPermiAnd\(\['business:inbound:query', 'business:inbound:add'\]\)/)
|
||||
assert.match(source, /proxy\.\$auth\.hasPermiAnd\(\['business:inbound:query', 'business:inbound:edit'\]\)/)
|
||||
@@ -1999,9 +1970,8 @@ test('入库页面只允许 DRAFT 变更并以 authoritative 详情和独立确
|
||||
/^function handleAdd\(\)\s*\{\s*if \(!canAddInbound\.value \|\| operationPending\.value \|\| optionLoading\.value \|\| detailLoading\.value \|\| open\.value\) return/
|
||||
)
|
||||
assert.match(source, /scope\.row\.status === ['"]DRAFT['"][\s\S]*?handleUpdate\(scope\.row\)/)
|
||||
assert.match(source, /scope\.row\.status === ['"]DRAFT['"][\s\S]*?handleDelete\(scope\.row\)/)
|
||||
assert.match(source, /scope\.row\.status === ['"]DRAFT['"][\s\S]*?handleConfirm\(scope\.row\)/)
|
||||
for (const functionName of ['handleUpdate', 'handleDelete', 'handleConfirm']) {
|
||||
for (const functionName of ['handleUpdate', 'handleConfirm']) {
|
||||
assert.match(extractNamedFunction(source, functionName), /status !== ['"]DRAFT['"]/)
|
||||
}
|
||||
|
||||
@@ -2041,11 +2011,6 @@ test('入库页面只允许 DRAFT 变更并以 authoritative 详情和独立确
|
||||
)
|
||||
assert.match(submitSource, /if \(!valid\) \{\s*submitLoading\.value = false\s*return/)
|
||||
assert.match(submitSource, /\.finally\(\(\) => \{\s*submitLoading\.value = false/)
|
||||
const deleteSource = extractNamedFunction(source, 'handleDelete')
|
||||
assert.ok(
|
||||
deleteSource.indexOf('deleteLoading.value = true') < deleteSource.indexOf('proxy.$modal.confirm('),
|
||||
'入库删除必须在打开二次确认框前加锁'
|
||||
)
|
||||
|
||||
assert.deepEqual(extractSecondCallObjectKeys(source, 'scanInboundPallet'), ['warehouseId'])
|
||||
const scanSource = extractNamedFunction(source, 'handleInboundScan')
|
||||
@@ -2187,7 +2152,6 @@ test('发货页面只允许 DRAFT 变更、展示只读余量并复用确认幂
|
||||
assertButtonsUsePermission(source, 'handleAdd', 'business:shipment:add')
|
||||
assertButtonsUsePermission(source, 'submitShipment', 'business:shipment:add')
|
||||
assertButtonsUsePermission(source, 'handleUpdate', 'business:shipment:edit')
|
||||
assertButtonsUsePermission(source, 'handleDelete', 'business:shipment:remove')
|
||||
assertButtonsUsePermission(source, 'handleConfirm', 'business:shipment:confirm')
|
||||
assert.match(source, /proxy\.\$auth\.hasPermiAnd\(\['business:shipment:query', 'business:shipment:add'\]\)/)
|
||||
assert.match(source, /proxy\.\$auth\.hasPermiAnd\(\['business:shipment:query', 'business:shipment:edit'\]\)/)
|
||||
@@ -2206,9 +2170,8 @@ test('发货页面只允许 DRAFT 变更、展示只读余量并复用确认幂
|
||||
/^function handleAdd\(\)\s*\{\s*if \(!canAddShipment\.value \|\| operationPending\.value \|\| optionLoading\.value \|\| detailLoading\.value \|\| open\.value\) return/
|
||||
)
|
||||
assert.match(source, /scope\.row\.status === ['"]DRAFT['"][\s\S]*?handleUpdate\(scope\.row\)/)
|
||||
assert.match(source, /scope\.row\.status === ['"]DRAFT['"][\s\S]*?handleDelete\(scope\.row\)/)
|
||||
assert.match(source, /scope\.row\.status === ['"]DRAFT['"][\s\S]*?handleConfirm\(scope\.row\)/)
|
||||
for (const functionName of ['handleUpdate', 'handleDelete', 'handleConfirm']) {
|
||||
for (const functionName of ['handleUpdate', 'handleConfirm']) {
|
||||
assert.match(extractNamedFunction(source, functionName), /status !== ['"]DRAFT['"]/)
|
||||
}
|
||||
|
||||
@@ -2250,11 +2213,6 @@ test('发货页面只允许 DRAFT 变更、展示只读余量并复用确认幂
|
||||
)
|
||||
assert.match(submitSource, /if \(!valid\) \{\s*submitLoading\.value = false\s*return/)
|
||||
assert.match(submitSource, /\.finally\(\(\) => \{\s*submitLoading\.value = false/)
|
||||
const deleteSource = extractNamedFunction(source, 'handleDelete')
|
||||
assert.ok(
|
||||
deleteSource.indexOf('deleteLoading.value = true') < deleteSource.indexOf('proxy.$modal.confirm('),
|
||||
'发货删除必须在打开二次确认框前加锁'
|
||||
)
|
||||
|
||||
assert.deepEqual(extractSecondCallObjectKeys(source, 'scanShipmentPallet'), ['sourceWarehouseId', 'targetSiteId'])
|
||||
assert.match(source, /label="[^"]*只读[^"]*"[^>]*prop="remainingPackages"|prop="remainingPackages"[\s\S]*?不可修改/)
|
||||
@@ -2534,6 +2492,7 @@ test('测试批次管理与旧数据纳入遵守 root、权限和预览提交契
|
||||
assert.match(source, /useUserStore\(\)/, `${rootType} 必须读取 admin 可见性`)
|
||||
assert.match(source, /useTestBatchStore\(\)/, `${rootType} 必须读取测试模式`)
|
||||
assert.match(source, /userStore\.admin === true\s*&&\s*!testBatchStore\.isTestMode/, `${rootType} 纳入入口必须只在管理员正式模式显示`)
|
||||
assert.match(source, /v-hasPermi="\['system:testbatch:adopt'\]"/, `${rootType} 纳入入口必须校验批次纳入权限`)
|
||||
assert.match(source, new RegExp(`<test-batch-adoption-dialog\\b[\\s\\S]*?:root-type="['\"]${rootType}['\"][\\s\\S]*?:resource-ids="selectedIds"`))
|
||||
assert.match(source, new RegExp(`selectedIds\\.value\\s*=\\s*selection\\.map\\(\\(item\\)\\s*=>\\s*item\\.${contract.id}\\)`), `${rootType} 必须传递正整数根 ID`)
|
||||
}
|
||||
|
||||
@@ -52,14 +52,6 @@ export function updateInbound(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 删除首次入库草稿
|
||||
export function delInbound(inboundIds) {
|
||||
return request({
|
||||
url: '/business/inbound/' + inboundIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 确认首次入库单
|
||||
export function confirmInbound(inboundId, data) {
|
||||
return request({
|
||||
|
||||
@@ -60,14 +60,6 @@ export function updateShipment(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 删除整托发货草稿
|
||||
export function delShipment(shipmentIds) {
|
||||
return request({
|
||||
url: '/business/shipment/' + shipmentIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 确认整托发货单
|
||||
export function confirmShipment(shipmentId, data) {
|
||||
return request({
|
||||
|
||||
@@ -34,11 +34,3 @@ export function updateCustomer(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除客户
|
||||
export function delCustomer(customerIds) {
|
||||
return request({
|
||||
url: '/master/customer/' + customerIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,11 +34,3 @@ export function updateLine(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除生产线
|
||||
export function delLine(lineIds) {
|
||||
return request({
|
||||
url: '/master/line/' + lineIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,11 +43,3 @@ export function updatePallet(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除托盘
|
||||
export function delPallet(palletIds) {
|
||||
return request({
|
||||
url: '/master/pallet/' + palletIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -35,14 +35,6 @@ export function updateSite(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 删除客户现场
|
||||
export function delSite(siteIds) {
|
||||
return request({
|
||||
url: '/master/site/' + siteIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询客户现场可分配用户
|
||||
export function getSiteUsers(siteId) {
|
||||
return request({
|
||||
|
||||
@@ -34,11 +34,3 @@ export function updateStrain(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除菌种
|
||||
export function delStrain(strainIds) {
|
||||
return request({
|
||||
url: '/master/strain/' + strainIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -35,14 +35,6 @@ export function updateWarehouse(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 删除仓库
|
||||
export function delWarehouse(warehouseIds) {
|
||||
return request({
|
||||
url: '/master/warehouse/' + warehouseIds,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询仓库可分配用户
|
||||
export function getWarehouseUsers(warehouseId) {
|
||||
return request({
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="fillingList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="装填单号" prop="fillingNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="inboundList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="入库单号" prop="inboundNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
@@ -72,15 +72,6 @@
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['business:inbound:edit']"
|
||||
>编辑</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 'DRAFT'"
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
:disabled="operationPending"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['business:inbound:remove']"
|
||||
>删除</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 'DRAFT'"
|
||||
link
|
||||
@@ -208,7 +199,6 @@ import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import {
|
||||
addInbound,
|
||||
confirmInbound,
|
||||
delInbound,
|
||||
getInbound,
|
||||
getInboundWarehouseOptions,
|
||||
listInbound,
|
||||
@@ -229,7 +219,6 @@ const optionLoading = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const scanLoading = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const deleteLoading = ref(false)
|
||||
const confirmLoading = ref(false)
|
||||
const loadError = ref('')
|
||||
const optionError = ref('')
|
||||
@@ -242,7 +231,7 @@ const editDetailReady = ref(false)
|
||||
const isEdit = computed(() => Boolean(form.value.inboundId))
|
||||
const canAddInbound = computed(() => proxy.$auth.hasPermiAnd(['business:inbound:query', 'business:inbound:add']))
|
||||
const canEditInbound = computed(() => proxy.$auth.hasPermiAnd(['business:inbound:query', 'business:inbound:edit']))
|
||||
const operationPending = computed(() => submitLoading.value || deleteLoading.value || confirmLoading.value)
|
||||
const operationPending = computed(() => submitLoading.value || confirmLoading.value)
|
||||
let listGeneration = 0
|
||||
let optionGeneration = 0
|
||||
let detailGeneration = 0
|
||||
@@ -545,27 +534,6 @@ function saveInboundUpdate() {
|
||||
submitInboundForm(true)
|
||||
}
|
||||
|
||||
function handleDelete(row) {
|
||||
if (row.status !== 'DRAFT') {
|
||||
proxy.$modal.msgWarning('只有草稿入库单可以删除')
|
||||
return
|
||||
}
|
||||
if (operationPending.value) return
|
||||
deleteLoading.value = true
|
||||
proxy.$modal.confirm(`是否确认删除入库单“${row.inboundNo || `#${row.inboundId}`}”?`).then(() => {
|
||||
return delInbound(String(row.inboundId))
|
||||
}).then((response) => {
|
||||
proxy.$modal.msgSuccess(response.msg || '删除成功')
|
||||
getList()
|
||||
}).catch((error) => {
|
||||
if (error !== 'cancel' && error !== 'close') {
|
||||
loadError.value = '入库单删除失败,请稍后重试'
|
||||
}
|
||||
}).finally(() => {
|
||||
deleteLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function clearConfirmIdempotency() {
|
||||
confirmIdempotency.inboundId = undefined
|
||||
confirmIdempotency.key = ''
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
</el-form>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="returnList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="退回单号" prop="returnNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="shipmentList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="发货单号" prop="shipmentNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
@@ -69,15 +69,6 @@
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['business:shipment:edit']"
|
||||
>编辑</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 'DRAFT'"
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
:disabled="operationPending"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['business:shipment:remove']"
|
||||
>删除</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === 'DRAFT'"
|
||||
link
|
||||
@@ -219,7 +210,6 @@ import useTestBatchStore from '@/store/modules/testBatch'
|
||||
import {
|
||||
addShipment,
|
||||
confirmShipment,
|
||||
delShipment,
|
||||
getShipment,
|
||||
getShipmentSiteOptions,
|
||||
getShipmentWarehouseOptions,
|
||||
@@ -242,7 +232,6 @@ const optionLoading = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const scanLoading = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const deleteLoading = ref(false)
|
||||
const confirmLoading = ref(false)
|
||||
const loadError = ref('')
|
||||
const optionError = ref('')
|
||||
@@ -255,7 +244,7 @@ const editDetailReady = ref(false)
|
||||
const isEdit = computed(() => Boolean(form.value.shipmentId))
|
||||
const canAddShipment = computed(() => proxy.$auth.hasPermiAnd(['business:shipment:query', 'business:shipment:add']))
|
||||
const canEditShipment = computed(() => proxy.$auth.hasPermiAnd(['business:shipment:query', 'business:shipment:edit']))
|
||||
const operationPending = computed(() => submitLoading.value || deleteLoading.value || confirmLoading.value)
|
||||
const operationPending = computed(() => submitLoading.value || confirmLoading.value)
|
||||
let listGeneration = 0
|
||||
let optionGeneration = 0
|
||||
let detailGeneration = 0
|
||||
@@ -577,25 +566,6 @@ function saveShipmentUpdate() {
|
||||
submitShipmentForm(true)
|
||||
}
|
||||
|
||||
function handleDelete(row) {
|
||||
if (row.status !== 'DRAFT') {
|
||||
proxy.$modal.msgWarning('只有草稿发货单可以删除')
|
||||
return
|
||||
}
|
||||
if (operationPending.value) return
|
||||
deleteLoading.value = true
|
||||
proxy.$modal.confirm(`是否确认删除发货单“${row.shipmentNo || `#${row.shipmentId}`}”?`).then(() => {
|
||||
return delShipment(String(row.shipmentId))
|
||||
}).then((response) => {
|
||||
proxy.$modal.msgSuccess(response.msg || '删除成功')
|
||||
getList()
|
||||
}).catch((error) => {
|
||||
if (error !== 'cancel' && error !== 'close') loadError.value = '发货单删除失败,请稍后重试'
|
||||
}).finally(() => {
|
||||
deleteLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function clearConfirmIdempotency() {
|
||||
confirmIdempotency.shipmentId = undefined
|
||||
confirmIdempotency.key = ''
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
</el-form>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog">纳入测试批次</el-button></div>
|
||||
<div v-if="userStore.admin === true && !testBatchStore.isTestMode" class="mb8"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length || operationPending" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></div>
|
||||
<el-table v-loading="loading" empty-text="暂无数据" :data="usageList" class="data-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="使用记录号" prop="usageNo" min-width="170" :show-overflow-tooltip="true" />
|
||||
|
||||
@@ -27,10 +27,9 @@
|
||||
@click="handleUpdate()" v-hasPermi="['master:customer:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:customer:remove']">删除</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
@@ -51,10 +50,6 @@
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:customer:query', 'master:customer:edit'])"
|
||||
link type="primary" icon="Edit" :disabled="detailLoading" @click="handleUpdate(scope.row)" v-hasPermi="['master:customer:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.canRemove === true"
|
||||
link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['master:customer:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -117,7 +112,7 @@
|
||||
</style>
|
||||
|
||||
<script setup name="Customer">
|
||||
import { addCustomer, delCustomer, getCustomer, listCustomer, updateCustomer } from "@/api/master/customer";
|
||||
import { addCustomer, getCustomer, listCustomer, updateCustomer } from "@/api/master/customer";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
@@ -130,7 +125,6 @@ const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const customerList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
const removableIds = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailLoading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
@@ -138,7 +132,6 @@ const loadError = ref("");
|
||||
const formError = ref("");
|
||||
const open = ref(false);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
let listGeneration = 0;
|
||||
@@ -223,11 +216,7 @@ function handleQuery() { queryParams.value.pageNum = 1; getList(); }
|
||||
function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); }
|
||||
function handleSelectionChange(selection) {
|
||||
selectedIds.value = selection.map((item) => item.customerId);
|
||||
removableIds.value = selection
|
||||
.filter((item) => item.canRemove === true)
|
||||
.map((item) => item.customerId);
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
@@ -309,15 +298,5 @@ function submitUpdate() {
|
||||
}).finally(() => { submitLoading.value = false; });
|
||||
});
|
||||
}
|
||||
function handleDelete(row) {
|
||||
const targetIds = row?.customerId ? (row.canRemove === true ? [row.customerId] : []) : removableIds.value;
|
||||
if (!targetIds.length) { proxy.$modal.msgWarning("请选择允许删除的客户"); return; }
|
||||
proxy.$modal.confirm(`是否确认删除客户编号为“${targetIds.join(",")}”的数据项?`).then(() =>
|
||||
delCustomer(targetIds.join(","))
|
||||
).then(() => { proxy.$modal.msgSuccess("删除成功"); getList(); }).catch((error) => {
|
||||
if (error !== "cancel" && error !== "close") loadError.value = "客户删除失败,请稍后重试";
|
||||
});
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
||||
@@ -30,10 +30,9 @@
|
||||
@click="handleUpdate()" v-hasPermi="['master:line:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:line:remove']">删除</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
@@ -55,10 +54,6 @@
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:line:query', 'master:line:edit'])"
|
||||
link type="primary" icon="Edit" :disabled="detailLoading" @click="handleUpdate(scope.row)" v-hasPermi="['master:line:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.canRemove === true"
|
||||
link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['master:line:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -119,7 +114,7 @@
|
||||
</style>
|
||||
|
||||
<script setup name="Line">
|
||||
import { addLine, delLine, getLine, listLine, updateLine } from "@/api/master/line";
|
||||
import { addLine, getLine, listLine, updateLine } from "@/api/master/line";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
@@ -132,7 +127,6 @@ const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const lineList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
const removableIds = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailLoading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
@@ -140,7 +134,6 @@ const loadError = ref("");
|
||||
const formError = ref("");
|
||||
const open = ref(false);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
let listGeneration = 0;
|
||||
@@ -232,11 +225,7 @@ function handleQuery() { queryParams.value.pageNum = 1; getList(); }
|
||||
function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); }
|
||||
function handleSelectionChange(selection) {
|
||||
selectedIds.value = selection.map((item) => item.lineId);
|
||||
removableIds.value = selection
|
||||
.filter((item) => item.canRemove === true)
|
||||
.map((item) => item.lineId);
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
@@ -319,15 +308,5 @@ function submitUpdate() {
|
||||
}).finally(() => { submitLoading.value = false; });
|
||||
});
|
||||
}
|
||||
function handleDelete(row) {
|
||||
const targetIds = row?.lineId ? (row.canRemove === true ? [row.lineId] : []) : removableIds.value;
|
||||
if (!targetIds.length) { proxy.$modal.msgWarning("请选择允许删除的生产线"); return; }
|
||||
proxy.$modal.confirm(`是否确认删除产线编号为“${targetIds.join(",")}”的数据项?`).then(() =>
|
||||
delLine(targetIds.join(","))
|
||||
).then(() => { proxy.$modal.msgSuccess("删除成功"); getList(); }).catch((error) => {
|
||||
if (error !== "cancel" && error !== "close") loadError.value = "生产线删除失败,请稍后重试";
|
||||
});
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
@click="handleUpdate()" v-hasPermi="['master:pallet:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:pallet:remove']">删除</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
@@ -52,10 +51,6 @@
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:pallet:query', 'master:pallet:edit'])"
|
||||
link type="primary" icon="Edit" :disabled="detailLoading" @click="handleUpdate(scope.row)" v-hasPermi="['master:pallet:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.canRemove === true"
|
||||
link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['master:pallet:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -119,7 +114,7 @@
|
||||
</style>
|
||||
|
||||
<script setup name="Pallet">
|
||||
import { addPallet, delPallet, getPallet, getPalletQrcode, listPallet, updatePallet } from "@/api/master/pallet";
|
||||
import { addPallet, getPallet, getPalletQrcode, listPallet, updatePallet } from "@/api/master/pallet";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
@@ -132,7 +127,6 @@ const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const palletList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
const removableIds = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailLoading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
@@ -140,7 +134,6 @@ const loadError = ref("");
|
||||
const formError = ref("");
|
||||
const open = ref(false);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
const printingIds = ref([]);
|
||||
@@ -232,11 +225,7 @@ function handleQuery() { queryParams.value.pageNum = 1; getList(); }
|
||||
function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); }
|
||||
function handleSelectionChange(selection) {
|
||||
selectedIds.value = selection.map((item) => item.palletId);
|
||||
removableIds.value = selection
|
||||
.filter((item) => item.canRemove === true)
|
||||
.map((item) => item.palletId);
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
@@ -315,16 +304,6 @@ function submitUpdate() {
|
||||
}).finally(() => { submitLoading.value = false; });
|
||||
});
|
||||
}
|
||||
function handleDelete(row) {
|
||||
const targetIds = row?.palletId ? (row.canRemove === true ? [row.palletId] : []) : removableIds.value;
|
||||
if (!targetIds.length) { proxy.$modal.msgWarning("请选择允许删除的托盘"); return; }
|
||||
proxy.$modal.confirm(`是否确认删除托盘编号为“${targetIds.join(",")}”的数据项?`).then(() =>
|
||||
delPallet(targetIds.join(","))
|
||||
).then(() => { proxy.$modal.msgSuccess("删除成功"); getList(); }).catch((error) => {
|
||||
if (error !== "cancel" && error !== "close") loadError.value = "托盘删除失败,请稍后重试";
|
||||
});
|
||||
}
|
||||
|
||||
function isPrinting(palletId) {
|
||||
return printingIds.value.includes(palletId);
|
||||
}
|
||||
|
||||
@@ -30,11 +30,10 @@
|
||||
@click="handleUpdate()" v-hasPermi="['master:site:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:site:remove']">删除</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="User" :disabled="single" @click="handleAssign()" v-hasPermi="['master:site:assign']">分配用户</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
@@ -58,10 +57,6 @@
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:site:query', 'master:site:edit'])"
|
||||
link type="primary" icon="Edit" :disabled="detailLoading" @click="handleUpdate(scope.row)" v-hasPermi="['master:site:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.canRemove === true"
|
||||
link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['master:site:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -128,7 +123,7 @@
|
||||
|
||||
<script setup name="Site">
|
||||
import BusinessUserAssignDialog from "@/components/BusinessUserAssignDialog";
|
||||
import { addSite, delSite, getSite, listSite, updateSite } from "@/api/master/site";
|
||||
import { addSite, getSite, listSite, updateSite } from "@/api/master/site";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
@@ -141,7 +136,6 @@ const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const siteList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
const removableIds = ref([]);
|
||||
const selectedRows = ref([]);
|
||||
const assignDialogRef = ref();
|
||||
const loading = ref(false);
|
||||
@@ -151,7 +145,6 @@ const loadError = ref("");
|
||||
const formError = ref("");
|
||||
const open = ref(false);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
let listGeneration = 0;
|
||||
@@ -244,11 +237,7 @@ function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); }
|
||||
function handleSelectionChange(selection) {
|
||||
selectedRows.value = selection;
|
||||
selectedIds.value = selection.map((item) => item.siteId);
|
||||
removableIds.value = selection
|
||||
.filter((item) => item.canRemove === true)
|
||||
.map((item) => item.siteId);
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
@@ -343,15 +332,5 @@ function submitUpdate() {
|
||||
}).finally(() => { submitLoading.value = false; });
|
||||
});
|
||||
}
|
||||
function handleDelete(row) {
|
||||
const targetIds = row?.siteId ? (row.canRemove === true ? [row.siteId] : []) : removableIds.value;
|
||||
if (!targetIds.length) { proxy.$modal.msgWarning("请选择允许删除的客户现场"); return; }
|
||||
proxy.$modal.confirm(`是否确认删除现场编号为“${targetIds.join(",")}”的数据项?`).then(() =>
|
||||
delSite(targetIds.join(","))
|
||||
).then(() => { proxy.$modal.msgSuccess("删除成功"); getList(); }).catch((error) => {
|
||||
if (error !== "cancel" && error !== "close") loadError.value = "客户现场删除失败,请稍后重试";
|
||||
});
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
||||
@@ -34,12 +34,9 @@
|
||||
v-hasPermi="['master:strain:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:strain:remove']">删除</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
@@ -68,14 +65,6 @@
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['master:strain:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.canRemove === true"
|
||||
link
|
||||
type="primary"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['master:strain:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -136,7 +125,7 @@
|
||||
</style>
|
||||
|
||||
<script setup name="Strain">
|
||||
import { addStrain, delStrain, getStrain, listStrain, updateStrain } from "@/api/master/strain";
|
||||
import { addStrain, getStrain, listStrain, updateStrain } from "@/api/master/strain";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
@@ -150,7 +139,6 @@ const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
|
||||
const strainList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
const removableIds = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailLoading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
@@ -158,7 +146,6 @@ const loadError = ref("");
|
||||
const formError = ref("");
|
||||
const open = ref(false);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
let listGeneration = 0;
|
||||
@@ -256,11 +243,7 @@ function resetQuery() {
|
||||
|
||||
function handleSelectionChange(selection) {
|
||||
selectedIds.value = selection.map((item) => item.strainId);
|
||||
removableIds.value = selection
|
||||
.filter((item) => item.canRemove === true)
|
||||
.map((item) => item.strainId);
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
@@ -350,21 +333,5 @@ function submitUpdate() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(row) {
|
||||
const targetIds = row?.strainId ? (row.canRemove === true ? [row.strainId] : []) : removableIds.value;
|
||||
if (!targetIds.length) {
|
||||
proxy.$modal.msgWarning("请选择允许删除的菌种");
|
||||
return;
|
||||
}
|
||||
proxy.$modal.confirm(`是否确认删除菌种编号为“${targetIds.join(",")}”的数据项?`).then(() =>
|
||||
delStrain(targetIds.join(","))
|
||||
).then(() => {
|
||||
proxy.$modal.msgSuccess("删除成功");
|
||||
getList();
|
||||
}).catch((error) => {
|
||||
if (error !== "cancel" && error !== "close") loadError.value = "菌种删除失败,请稍后重试";
|
||||
});
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
@click="handleUpdate()" v-hasPermi="['master:warehouse:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5"><el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['master:warehouse:remove']">删除</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="User" :disabled="single" @click="handleAssign()" v-hasPermi="['master:warehouse:assign']">分配用户</el-button></el-col>
|
||||
</el-row>
|
||||
<el-row v-if="userStore.admin === true && !testBatchStore.isTestMode" :gutter="10" class="mb8 master-toolbar">
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog">纳入测试批次</el-button></el-col>
|
||||
<el-col :span="1.5"><el-button type="warning" plain icon="FolderAdd" :disabled="!selectedIds.length" @click="openAdoptionDialog" v-hasPermi="['system:testbatch:adopt']">纳入测试批次</el-button></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert v-if="loadError" :title="loadError" type="error" :closable="false" show-icon class="mb8" />
|
||||
@@ -54,10 +53,6 @@
|
||||
v-if="proxy.$auth.hasPermiAnd(['master:warehouse:query', 'master:warehouse:edit'])"
|
||||
link type="primary" icon="Edit" :disabled="detailLoading" @click="handleUpdate(scope.row)" v-hasPermi="['master:warehouse:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.canRemove === true"
|
||||
link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['master:warehouse:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -121,7 +116,7 @@
|
||||
|
||||
<script setup name="Warehouse">
|
||||
import BusinessUserAssignDialog from "@/components/BusinessUserAssignDialog";
|
||||
import { addWarehouse, delWarehouse, getWarehouse, listWarehouse, updateWarehouse } from "@/api/master/warehouse";
|
||||
import { addWarehouse, getWarehouse, listWarehouse, updateWarehouse } from "@/api/master/warehouse";
|
||||
import TestBatchAdoptionDialog from '@/components/TestBatchAdoptionDialog'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useTestBatchStore from '@/store/modules/testBatch'
|
||||
@@ -134,7 +129,6 @@ const adoptionDialogRef = ref()
|
||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||
const warehouseList = ref([]);
|
||||
const selectedIds = ref([]);
|
||||
const removableIds = ref([]);
|
||||
const selectedRows = ref([]);
|
||||
const assignDialogRef = ref();
|
||||
const loading = ref(false);
|
||||
@@ -144,7 +138,6 @@ const loadError = ref("");
|
||||
const formError = ref("");
|
||||
const open = ref(false);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
let listGeneration = 0;
|
||||
@@ -229,11 +222,7 @@ function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); }
|
||||
function handleSelectionChange(selection) {
|
||||
selectedRows.value = selection;
|
||||
selectedIds.value = selection.map((item) => item.warehouseId);
|
||||
removableIds.value = selection
|
||||
.filter((item) => item.canRemove === true)
|
||||
.map((item) => item.warehouseId);
|
||||
single.value = selectedIds.value.length !== 1;
|
||||
multiple.value = removableIds.value.length === 0;
|
||||
}
|
||||
|
||||
function openAdoptionDialog() { adoptionDialogRef.value?.open() }
|
||||
@@ -325,15 +314,5 @@ function submitUpdate() {
|
||||
}).finally(() => { submitLoading.value = false; });
|
||||
});
|
||||
}
|
||||
function handleDelete(row) {
|
||||
const targetIds = row?.warehouseId ? (row.canRemove === true ? [row.warehouseId] : []) : removableIds.value;
|
||||
if (!targetIds.length) { proxy.$modal.msgWarning("请选择允许删除的仓库"); return; }
|
||||
proxy.$modal.confirm(`是否确认删除仓库编号为“${targetIds.join(",")}”的数据项?`).then(() =>
|
||||
delWarehouse(targetIds.join(","))
|
||||
).then(() => { proxy.$modal.msgSuccess("删除成功"); getList(); }).catch((error) => {
|
||||
if (error !== "cancel" && error !== "close") loadError.value = "仓库删除失败,请稍后重试";
|
||||
});
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user