2026-09-15 15:50:24 +08:00
|
|
|
|
-- 采购申请模块。执行一次后,在角色管理中给员工分配采购申请菜单;
|
|
|
|
|
|
-- “采购管理”按钮权限仅分配给采购管理员。
|
|
|
|
|
|
|
|
|
|
|
|
create table if not exists purchase_batch (
|
|
|
|
|
|
id bigint(20) not null auto_increment comment '主键',
|
|
|
|
|
|
batch_no varchar(64) not null comment '采购批次编号',
|
|
|
|
|
|
batch_name varchar(200) default null comment '采购批次名称',
|
|
|
|
|
|
purchase_status tinyint(1) not null default 1 comment '批次状态:1规划中 2执行中 3已结束 4已归档 5已取消',
|
|
|
|
|
|
progress_remark varchar(500) default null comment '进度说明',
|
|
|
|
|
|
create_by varchar(64) default null comment '创建人',
|
|
|
|
|
|
create_time datetime default null comment '创建时间',
|
|
|
|
|
|
update_by varchar(64) default null comment '更新人',
|
|
|
|
|
|
update_time datetime default null comment '更新时间',
|
|
|
|
|
|
primary key (id),
|
|
|
|
|
|
unique key uk_purchase_batch_no (batch_no)
|
|
|
|
|
|
) engine=innodb default charset=utf8mb4 comment='采购批次表';
|
|
|
|
|
|
|
|
|
|
|
|
alter table purchase_batch modify column purchase_status tinyint(1) not null default 1
|
|
|
|
|
|
comment '批次状态:1规划中 2执行中 3已结束 4已归档 5已取消';
|
|
|
|
|
|
|
|
|
|
|
|
create table if not exists purchase_request (
|
|
|
|
|
|
id bigint(20) not null auto_increment comment '主键',
|
|
|
|
|
|
request_no varchar(64) not null comment '申请单号',
|
|
|
|
|
|
product_id bigint(20) default null comment '关联库房物料ID',
|
|
|
|
|
|
purchase_batch_id bigint(20) default null comment '采购批次ID',
|
|
|
|
|
|
material_name varchar(200) not null comment '物料名称',
|
|
|
|
|
|
material_brand varchar(100) default null comment '品牌',
|
|
|
|
|
|
category varchar(100) default null comment '类别',
|
|
|
|
|
|
material_params varchar(500) default null comment '参数规格',
|
|
|
|
|
|
purchase_link varchar(1000) default null comment '采购链接',
|
|
|
|
|
|
quantity decimal(16,3) not null default 1.000 comment '需求数量',
|
|
|
|
|
|
unit varchar(32) default null comment '单位',
|
|
|
|
|
|
expected_date date default null comment '期望到货日期',
|
|
|
|
|
|
applicant_id bigint(20) not null comment '申请人用户ID',
|
|
|
|
|
|
applicant_name varchar(64) not null comment '申请人账号',
|
|
|
|
|
|
purchase_status tinyint(1) not null default 0 comment '状态:0待采购 1已下单 2采购中 3部分到货 4已到齐 5已取消',
|
|
|
|
|
|
purchase_batch_no varchar(64) default null comment '采购批次',
|
|
|
|
|
|
progress_remark varchar(500) default null comment '进度说明',
|
|
|
|
|
|
remark varchar(500) default null comment '申请备注',
|
|
|
|
|
|
create_by varchar(64) default null comment '创建人',
|
|
|
|
|
|
create_time datetime default null comment '创建时间',
|
|
|
|
|
|
update_by varchar(64) default null comment '更新人',
|
|
|
|
|
|
update_time datetime default null comment '更新时间',
|
|
|
|
|
|
primary key (id),
|
|
|
|
|
|
unique key uk_purchase_request_no (request_no),
|
|
|
|
|
|
key idx_purchase_request_product (product_id),
|
|
|
|
|
|
key idx_purchase_request_batch_id (purchase_batch_id),
|
|
|
|
|
|
key idx_purchase_request_applicant (applicant_id),
|
|
|
|
|
|
key idx_purchase_request_status (purchase_status),
|
|
|
|
|
|
key idx_purchase_request_batch (purchase_batch_no)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
) engine=innodb default charset=utf8mb4 comment='采购申请表';
|
|
|
|
|
|
|
|
|
|
|
|
create table if not exists purchase_arrival (
|
|
|
|
|
|
id bigint(20) not null auto_increment comment '主键',
|
|
|
|
|
|
arrival_no varchar(64) not null comment '到货单号',
|
|
|
|
|
|
purchase_request_id bigint(20) not null comment '采购申请ID',
|
|
|
|
|
|
arrival_quantity decimal(16,3) not null comment '本次到货数量',
|
|
|
|
|
|
arrival_date date not null comment '到货日期',
|
|
|
|
|
|
acceptance_status tinyint(1) not null default 0 comment '验收状态:0待验收 1验收通过 2验收拒绝',
|
|
|
|
|
|
acceptance_remark varchar(500) default null comment '验收说明',
|
|
|
|
|
|
accepted_by varchar(64) default null comment '验收人',
|
|
|
|
|
|
accepted_time datetime default null comment '验收时间',
|
|
|
|
|
|
pre_accept_purchase_status tinyint(1) default null comment '验收前采购状态',
|
|
|
|
|
|
revoked_by varchar(64) default null comment '最近撤销人',
|
|
|
|
|
|
revoked_time datetime default null comment '最近撤销时间',
|
|
|
|
|
|
revoke_remark varchar(500) default null comment '最近撤销原因',
|
|
|
|
|
|
remark varchar(500) default null comment '到货备注',
|
|
|
|
|
|
create_by varchar(64) default null comment '创建人',
|
|
|
|
|
|
create_time datetime default null comment '创建时间',
|
|
|
|
|
|
update_by varchar(64) default null comment '更新人',
|
|
|
|
|
|
update_time datetime default null comment '更新时间',
|
|
|
|
|
|
primary key (id),
|
|
|
|
|
|
unique key uk_purchase_arrival_no (arrival_no),
|
|
|
|
|
|
key idx_purchase_arrival_request (purchase_request_id),
|
2026-09-28 10:55:48 +08:00
|
|
|
|
key idx_purchase_arrival_request_status (purchase_request_id, acceptance_status),
|
2026-09-15 15:50:24 +08:00
|
|
|
|
key idx_purchase_arrival_status (acceptance_status)
|
|
|
|
|
|
) engine=innodb default charset=utf8mb4 comment='采购分批到货及验收记录';
|
|
|
|
|
|
|
|
|
|
|
|
-- 兼容已执行过早期脚本的数据库。
|
|
|
|
|
|
set @purchase_brand_column = (
|
|
|
|
|
|
select count(*) from information_schema.columns
|
|
|
|
|
|
where table_schema = database() and table_name = 'purchase_request' and column_name = 'material_brand'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @purchase_brand_sql = if(
|
|
|
|
|
|
@purchase_brand_column = 0,
|
|
|
|
|
|
'alter table purchase_request add column material_brand varchar(100) default null comment ''品牌'' after material_name',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare purchase_brand_stmt from @purchase_brand_sql;
|
|
|
|
|
|
execute purchase_brand_stmt;
|
|
|
|
|
|
deallocate prepare purchase_brand_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @purchase_batch_id_column = (
|
|
|
|
|
|
select count(*) from information_schema.columns
|
|
|
|
|
|
where table_schema = database() and table_name = 'purchase_request' and column_name = 'purchase_batch_id'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @purchase_batch_id_sql = if(
|
|
|
|
|
|
@purchase_batch_id_column = 0,
|
|
|
|
|
|
'alter table purchase_request add column purchase_batch_id bigint(20) default null comment ''采购批次ID'' after product_id, add key idx_purchase_request_batch_id (purchase_batch_id)',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare purchase_batch_id_stmt from @purchase_batch_id_sql;
|
|
|
|
|
|
execute purchase_batch_id_stmt;
|
|
|
|
|
|
deallocate prepare purchase_batch_id_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @arrival_revoke_columns = (
|
|
|
|
|
|
select count(*) from information_schema.columns
|
|
|
|
|
|
where table_schema = database() and table_name = 'purchase_arrival' and column_name = 'pre_accept_purchase_status'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @arrival_revoke_sql = if(
|
|
|
|
|
|
@arrival_revoke_columns = 0,
|
|
|
|
|
|
'alter table purchase_arrival add column pre_accept_purchase_status tinyint(1) default null comment ''验收前采购状态'' after accepted_time, add column revoked_by varchar(64) default null comment ''最近撤销人'' after pre_accept_purchase_status, add column revoked_time datetime default null comment ''最近撤销时间'' after revoked_by, add column revoke_remark varchar(500) default null comment ''最近撤销原因'' after revoked_time',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare arrival_revoke_stmt from @arrival_revoke_sql;
|
|
|
|
|
|
execute arrival_revoke_stmt;
|
|
|
|
|
|
deallocate prepare arrival_revoke_stmt;
|
|
|
|
|
|
|
2026-09-28 10:55:48 +08:00
|
|
|
|
set @purchase_arrival_request_status_index = (
|
|
|
|
|
|
select count(*) from information_schema.statistics
|
|
|
|
|
|
where table_schema = database() and table_name = 'purchase_arrival'
|
|
|
|
|
|
and index_name = 'idx_purchase_arrival_request_status'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @purchase_arrival_request_status_sql = if(
|
|
|
|
|
|
@purchase_arrival_request_status_index = 0,
|
|
|
|
|
|
'alter table purchase_arrival add key idx_purchase_arrival_request_status (purchase_request_id, acceptance_status)',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare purchase_arrival_request_status_stmt from @purchase_arrival_request_status_sql;
|
|
|
|
|
|
execute purchase_arrival_request_status_stmt;
|
|
|
|
|
|
deallocate prepare purchase_arrival_request_status_stmt;
|
|
|
|
|
|
|
2026-09-15 15:50:24 +08:00
|
|
|
|
alter table purchase_request modify column purchase_status tinyint(1) not null default 0
|
|
|
|
|
|
comment '状态:0待采购 1已下单 2采购中 3部分到货 4已到齐 5已取消';
|
|
|
|
|
|
|
|
|
|
|
|
-- 把旧版本中写在申请行上的批次编号迁移为批次主数据。
|
|
|
|
|
|
insert ignore into purchase_batch(batch_no, batch_name, purchase_status, progress_remark, create_by, create_time)
|
|
|
|
|
|
select purchase_batch_no, purchase_batch_no, greatest(max(purchase_status), 1), max(progress_remark), 'migration', sysdate()
|
|
|
|
|
|
from purchase_request
|
|
|
|
|
|
where purchase_batch_no is not null and purchase_batch_no != ''
|
|
|
|
|
|
group by purchase_batch_no;
|
|
|
|
|
|
|
|
|
|
|
|
update purchase_request pr
|
|
|
|
|
|
join purchase_batch pb on pb.batch_no = pr.purchase_batch_no
|
|
|
|
|
|
set pr.purchase_batch_id = pb.id,
|
|
|
|
|
|
pr.purchase_status = pb.purchase_status,
|
|
|
|
|
|
pr.progress_remark = pb.progress_remark
|
|
|
|
|
|
where pr.purchase_batch_id is null;
|
|
|
|
|
|
|
|
|
|
|
|
-- 采购完成后先生成待入库记录,库区和入库人由仓库人员补充后再确认入库。
|
|
|
|
|
|
alter table in_record modify column area_id bigint(20) default null comment '库区id,待入库时可为空';
|
|
|
|
|
|
|
|
|
|
|
|
set @in_purchase_request_column = (
|
|
|
|
|
|
select count(*) from information_schema.columns
|
|
|
|
|
|
where table_schema = database() and table_name = 'in_record' and column_name = 'purchase_request_id'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @in_purchase_request_sql = if(
|
|
|
|
|
|
@in_purchase_request_column = 0,
|
|
|
|
|
|
'alter table in_record add column purchase_request_id bigint(20) default null comment ''采购申请ID'' after product_id',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare in_purchase_request_stmt from @in_purchase_request_sql;
|
|
|
|
|
|
execute in_purchase_request_stmt;
|
|
|
|
|
|
deallocate prepare in_purchase_request_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @in_source_no_column = (
|
|
|
|
|
|
select count(*) from information_schema.columns
|
|
|
|
|
|
where table_schema = database() and table_name = 'in_record' and column_name = 'source_no'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @in_source_no_sql = if(
|
|
|
|
|
|
@in_source_no_column = 0,
|
|
|
|
|
|
'alter table in_record add column source_no varchar(64) default null comment ''来源单号'' after purchase_request_id',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare in_source_no_stmt from @in_source_no_sql;
|
|
|
|
|
|
execute in_source_no_stmt;
|
|
|
|
|
|
deallocate prepare in_source_no_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @in_arrival_column = (
|
|
|
|
|
|
select count(*) from information_schema.columns
|
|
|
|
|
|
where table_schema = database() and table_name = 'in_record' and column_name = 'arrival_id'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @in_arrival_sql = if(
|
|
|
|
|
|
@in_arrival_column = 0,
|
|
|
|
|
|
'alter table in_record add column arrival_id bigint(20) default null comment ''采购到货ID'' after purchase_request_id',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare in_arrival_stmt from @in_arrival_sql;
|
|
|
|
|
|
execute in_arrival_stmt;
|
|
|
|
|
|
deallocate prepare in_arrival_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @in_purchase_request_unique_index = (
|
|
|
|
|
|
select count(*) from information_schema.statistics
|
|
|
|
|
|
where table_schema = database() and table_name = 'in_record'
|
|
|
|
|
|
and index_name = 'uk_in_record_purchase_request' and non_unique = 0
|
|
|
|
|
|
);
|
|
|
|
|
|
set @drop_in_purchase_request_unique_sql = if(
|
|
|
|
|
|
@in_purchase_request_unique_index > 0,
|
|
|
|
|
|
'alter table in_record drop index uk_in_record_purchase_request',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare drop_in_purchase_request_unique_stmt from @drop_in_purchase_request_unique_sql;
|
|
|
|
|
|
execute drop_in_purchase_request_unique_stmt;
|
|
|
|
|
|
deallocate prepare drop_in_purchase_request_unique_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @in_purchase_request_index = (
|
|
|
|
|
|
select count(*) from information_schema.statistics
|
|
|
|
|
|
where table_schema = database() and table_name = 'in_record' and index_name = 'idx_in_record_purchase_request'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @in_purchase_request_index_sql = if(
|
|
|
|
|
|
@in_purchase_request_index = 0,
|
|
|
|
|
|
'alter table in_record add key idx_in_record_purchase_request (purchase_request_id)',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare in_purchase_request_index_stmt from @in_purchase_request_index_sql;
|
|
|
|
|
|
execute in_purchase_request_index_stmt;
|
|
|
|
|
|
deallocate prepare in_purchase_request_index_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
set @in_arrival_index = (
|
|
|
|
|
|
select count(*) from information_schema.statistics
|
|
|
|
|
|
where table_schema = database() and table_name = 'in_record' and index_name = 'uk_in_record_arrival'
|
|
|
|
|
|
);
|
|
|
|
|
|
set @in_arrival_index_sql = if(
|
|
|
|
|
|
@in_arrival_index = 0,
|
|
|
|
|
|
'alter table in_record add unique key uk_in_record_arrival (arrival_id)',
|
|
|
|
|
|
'select 1'
|
|
|
|
|
|
);
|
|
|
|
|
|
prepare in_arrival_index_stmt from @in_arrival_index_sql;
|
|
|
|
|
|
execute in_arrival_index_stmt;
|
|
|
|
|
|
deallocate prepare in_arrival_index_stmt;
|
|
|
|
|
|
|
|
|
|
|
|
-- 旧版本按批次完成自动生成、但尚未真实入库的记录没有经过验收,升级时移除。
|
|
|
|
|
|
delete from in_record
|
|
|
|
|
|
where arrival_id is null and purchase_request_id is not null
|
|
|
|
|
|
and in_status = 0 and in_no like 'PIN%';
|
|
|
|
|
|
|
|
|
|
|
|
-- 菜单及按钮权限
|
|
|
|
|
|
delete from sys_menu where menu_id in (2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042);
|
|
|
|
|
|
insert into sys_menu values('2035', '采购申请', '0', '6', 'purchase', 'warehouse/purchase/index', '', '', 1, 0, 'C', '0', '0', 'warehouse:purchase:list', 'shopping', 'admin', sysdate(), '', null, '与库存管理同级的采购申请菜单');
|
|
|
|
|
|
insert into sys_menu values('2036', '采购查询', '2035', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:query', '#', 'admin', sysdate(), '', null, '');
|
|
|
|
|
|
insert into sys_menu values('2037', '采购申请新增', '2035', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:add', '#', 'admin', sysdate(), '', null, '');
|
|
|
|
|
|
insert into sys_menu values('2038', '采购申请修改', '2035', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:edit', '#', 'admin', sysdate(), '', null, '');
|
|
|
|
|
|
insert into sys_menu values('2039', '采购申请删除', '2035', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:remove', '#', 'admin', sysdate(), '', null, '');
|
|
|
|
|
|
insert into sys_menu values('2040', '采购申请导入', '2035', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:import', '#', 'admin', sysdate(), '', null, '');
|
|
|
|
|
|
insert into sys_menu values('2041', '采购申请导出', '2035', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:export', '#', 'admin', sysdate(), '', null, '');
|
|
|
|
|
|
insert into sys_menu values('2042', '采购管理', '2035', '7', '#', '', '', '', 1, 0, 'F', '0', '0', 'warehouse:purchase:manage', '#', 'admin', sysdate(), '', null, '仅管理员分配,可查看全部申请并修改采购进度');
|
|
|
|
|
|
|
|
|
|
|
|
-- 独立采购管理员角色。该角色可分配给普通用户,不使用受保护的 admin 超级管理员角色。
|
|
|
|
|
|
insert into sys_role(role_name, role_key, role_sort, data_scope, menu_check_strictly,
|
|
|
|
|
|
dept_check_strictly, status, del_flag, create_by, create_time, remark)
|
|
|
|
|
|
select '采购管理员', 'purchase_manager', 3, '1', 1, 1, '0', '0', 'admin', sysdate(),
|
|
|
|
|
|
'维护全部采购申请、采购批次和采购进度'
|
|
|
|
|
|
where not exists (
|
|
|
|
|
|
select 1 from sys_role where role_key = 'purchase_manager' and del_flag = '0'
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
set @purchase_manager_role_id = (
|
|
|
|
|
|
select role_id from sys_role
|
|
|
|
|
|
where role_key = 'purchase_manager' and del_flag = '0'
|
|
|
|
|
|
order by role_id limit 1
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
insert ignore into sys_role_menu(role_id, menu_id)
|
|
|
|
|
|
select @purchase_manager_role_id, menu_id
|
|
|
|
|
|
from sys_menu
|
|
|
|
|
|
where menu_id in (2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042);
|
|
|
|
|
|
|
|
|
|
|
|
delete from sys_role_menu
|
|
|
|
|
|
where role_id = @purchase_manager_role_id and menu_id = 2000;
|
|
|
|
|
|
|
|
|
|
|
|
-- 普通采购申请人:可查看、导出全部申请,但服务端只允许修改和删除本人数据。
|
|
|
|
|
|
insert into sys_role(role_name, role_key, role_sort, data_scope, menu_check_strictly,
|
|
|
|
|
|
dept_check_strictly, status, del_flag, create_by, create_time, remark)
|
|
|
|
|
|
select '采购申请人', 'purchase_user', 4, '1', 1, 1, '0', '0', 'admin', sysdate(),
|
|
|
|
|
|
'提交采购申请;查看和导出全部申请;修改、删除本人申请'
|
|
|
|
|
|
where not exists (
|
|
|
|
|
|
select 1 from sys_role where role_key = 'purchase_user' and del_flag = '0'
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
set @purchase_user_role_id = (
|
|
|
|
|
|
select role_id from sys_role
|
|
|
|
|
|
where role_key = 'purchase_user' and del_flag = '0'
|
|
|
|
|
|
order by role_id limit 1
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
insert ignore into sys_role_menu(role_id, menu_id)
|
|
|
|
|
|
select @purchase_user_role_id, menu_id
|
|
|
|
|
|
from sys_menu
|
|
|
|
|
|
where menu_id in (2035, 2036, 2037, 2038, 2039, 2040, 2041);
|
|
|
|
|
|
|
|
|
|
|
|
delete from sys_role_menu
|
|
|
|
|
|
where role_id = @purchase_user_role_id and menu_id = 2000;
|