1.药品分类
1.1 分类模块数据库设计
前言
打开Idea的DataBase或者Navicat等软件,在pms数据库中创建tb_category表,用于存储药品分类信息。 sql如下:
DROP TABLE IF EXISTS `t_category`;
CREATE TABLE `t_category` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`category_code` varchar(50) NOT NULL COMMENT '分类编码(如:XY-001、ZCY-202405-001、SW-002)',
`name` varchar(100) NOT NULL COMMENT '类别名称',
`type` varchar(50) DEFAULT 'other' COMMENT '分类类型:western-西药、chinese-中药、biotech-生物制品、medical_device-医疗器械、other-其他',
`status` tinyint(1) DEFAULT '1' COMMENT '状态(1:启用 0:禁用)',
`sort_order` int(11) DEFAULT '0' COMMENT '排序号(数字越小越靠前)',
`description` text COMMENT '描述信息',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_category_code` (`category_code`), -- 分类编码唯一索引
UNIQUE KEY `uk_category_name` (`name`) -- 分类名称唯一索引(如需允许多条同名分类可删除此索引)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='药品类别表';
INSERT INTO `t_category` (`category_code`, `name`, `type`, `status`, `sort_order`, `description`) VALUES
-- 西药(western)
('XY-001', '抗生素类', 'western', 1, 10, '用于细菌感染治疗的一类药物,如青霉素、头孢菌素'),
('XY-002', '心血管类', 'western', 1, 20, '治疗高血压、冠心病等心血管疾病的药物,如硝苯地平、阿司匹林'),
('XY-003', '消化系统类', 'western', 1, 30, '缓解胃痛、腹泻、消化不良等症状的药物,如奥美拉唑、吗丁啉'),
-- 中药(chinese)
('ZCY-001', '解表类中药', 'chinese', 1, 40, '用于发散表邪、解除表证的中药,如麻黄、桂枝、薄荷'),
('ZCY-002', '清热类中药', 'chinese', 1, 50, '具有清热泻火、解毒功效的中药,如金银花、连翘、黄连'),
('ZCY-003', '补益类中药', 'chinese', 1, 60, '补充人体气血阴阳不足的中药,如人参、黄芪、当归'),
-- 生物制品(biotech)
('SW-001', '疫苗类', 'biotech', 1, 70, '预防传染病的生物制品,如新冠疫苗、乙肝疫苗'),
('SW-002', '血液制品', 'biotech', 1, 80, '从血液中提取的治疗制品,如人血白蛋白、免疫球蛋白'),
('SW-003', '基因工程药', 'biotech', 1, 90, '通过基因工程技术生产的药物,如胰岛素、干扰素'),
-- 医疗器械(medical_device)
('YLQX-001', '诊断设备', 'medical_device', 1, 100, '用于疾病诊断的设备,如血压计、血糖仪、超声仪'),
('YLQX-002', '治疗设备', 'medical_device', 1, 110, '用于治疗或辅助治疗疾病的设备,如呼吸机、输液泵、手术器械'),
('YLQX-003', '康复设备', 'medical_device', 1, 120, '帮助患者恢复功能的设备,如轮椅、拐杖、理疗仪'),
-- 其他(other)
('QT-001', '保健品', 'other', 0, 130, '具有保健功能的食品或产品,如维生素、蛋白粉'),
('QT-002', '消毒用品', 'other', 1, 140, '用于消毒灭菌的产品,如酒精、碘伏、消毒液'),
('QT-003', '特殊药品', 'other', 1, 150, '麻醉药品、精神药品等特殊管理药品');
执行sql后,数据库中会生成tb_category表,用于存储药品分类信息。👇

接下来,我们参考用户管理模块,完成药品分类模块的开发。

搞定数据库表后,接下来,需要创建对应的实体类,TCategoryDao,TCategoryMapper.java,TCategoryMapper.xml等文件
注意: 这些类,我们直接用AI或者MybatisX插件生成即可,无需手动编写。
不能使用MybatisX插件的同学,可以自行编写,或者在微信群里下载老师的资料,拷贝到Idea中对应的目录中(如下图)。

并且在TCategoryMapper.java的接口中,增加查询所有的方法,如下:
public interface TCategoryMapper {
//查询所有
@Select("select * from t_category")
List<TCategory> listAll();
}
然后在mybatis-config.xml中配置TCategoryMapper.xml

接着模拟UserDao,创建TCategoryDao.java,对外提供查询、分页、新增、修改、删除等方法。如下
public class TCategoryDao {
private SqlSessionFactory sqlSessionFactory;
public TCategoryDao() {
sqlSessionFactory = MybatisConfig.getSqlSessionFactory();
}
/**
* 获取所有分类
*/
public List<TCategory> listAll() {
SqlSession sqlSession = sqlSessionFactory.openSession();
TCategoryMapper tCategoryMapper = sqlSession.getMapper(TCategoryMapper.class);
List<TCategory> list=tCategoryMapper.listAll();
sqlSession.close();
return list;
}
}
1.2 分类模块界面设计
前言
由于前一天,我们写了一个CategoryUI的空壳子,接下来,我们将利用AI完成CategoryUI的页面的开发。
其实分页模块和用户模块的结构几乎一致,因此,我们完全可以复用用户模块提示词,只需要稍微修改一下提示词中的内容即可。
修改之后的提示词如下:👇
CategoryUI.java 开发需求文档
分类数据库表设计如下:
CREATE TABLE `t_category` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`category_code` varchar(50) NOT NULL COMMENT '分类编码(如:XY-001、ZCY-202405-001、SW-002)',
`name` varchar(100) NOT NULL COMMENT '类别名称',
`type` varchar(50) DEFAULT 'other' COMMENT '分类类型:western-西药、chinese-中药、biotech-生物制品、medical_device-医疗器械、other-其他',
`status` tinyint(1) DEFAULT '1' COMMENT '状态(1:启用 0:禁用)',
`sort_order` int(11) DEFAULT '0' COMMENT '排序号(数字越小越靠前)',
`description` text COMMENT '描述信息',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_category_code` (`category_code`), -- 分类编码唯一索引
UNIQUE KEY `uk_category_name` (`name`) -- 分类名称唯一索引(如需允许多条同名分类可删除此索引)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='药品类别表';
一、项目环境
• 所属模块:HomeUI.java 内容区嵌入的子界面(通过侧边栏“用户管理”菜单切换显示);
• 技术:Java Swing,风格与现有界面(UserUI、WelcomeUI、HomeUI)一致;
• 数据依赖:需加载数据(模拟从数据库查询,包含分类表的各个字段)。
二、界面设计(苹果风格:简洁、留白、色调统一、控件圆润)
1. 整体布局
采用 BorderLayout + FlowLayout + 边距控制,分区明确:
• 顶部:检索区(左:检索框+检索按钮;右:添加按钮);
• 中部:表格区(占满剩余空间,带滚动条);
• 整体背景白色,四周留白舒适(如 EmptyBorder(10, 10, 10, 10))。
2. 检索与操作区(顶部第一行)
• 左侧:检索组件
• 检索输入框:宽度约 200px,提示文字“请输入分类名字或分类编码”,无边框(或浅灰细边框),圆角(6px);
• 类型下拉框:宽度约 100px,下拉选项“全部”、“中药”、“西药”、“生物制品”、“医疗器械”、“其他”,默认“全部”,无边框(或浅灰细边框),圆角(6px)
• 状态下拉框:宽度约 100px,下拉选项“全部”、“启用”、“禁用”,默认“全部”,无边框(或浅灰细边框),圆角(6px)
• 检索按钮:文字“检索”,浅灰背景(默认)、悬停加深、点击激活变色,圆角矩形,与输入框间距 8px。
• 重置按钮:文字“重置”,浅灰背景(默认)、悬停加深、点击激活变色,圆角矩形,与输入框间距 8px。
• 右侧:添加按钮
• 文字“添加”,样式同检索按钮(统一按钮风格),与左侧检索组件间距 16px。
• 布局:用 FlowLayout 横向排列,居中对齐,整体区域背景白色,高度约 50px(含内边距)。
3. 表格区(第二行)
• 表格组件:JTable + JScrollPane(带垂直滚动条,无水平滚动条,列宽自适应内容);
• 表头字段(按顺序):
ID 分类编码 分类名称 分类类型 状态 排序号 描述 创建时间 操作
• 操作列:每行包含“编辑”和“删除”两个按钮(文字按钮,样式同检索按钮,间距 2,列宽固定约 100px,按钮高度和列一致);
• 表格样式:
• 表头:浅灰背景,深灰文字,加粗,居中对齐;
• 内容行:白色背景,深灰文字,居中对齐(序号、手机号、创建时间),用户名/昵称/角色左对齐;
• 行高:紧凑适中,隔行浅灰背景(斑马纹,提升可读性);
• 边框:表格外框浅灰细边框,单元格间无分隔线(或极浅灰分隔线,符合苹果简洁风格);
• 列宽:序号 20px,其他 100px,剩余的宽度自适应内容(如手机号、创建时间)。
• 按钮:所有的按钮通过一个方法 createButton() 统一初始化样式(如圆角、背景色、字体、边距等),避免重复代码。
三、交互与逻辑
1. 数据加载
• 定义独立方法 loadData():模拟从数据源(如 TCategoryDao)加载数据,返回 List<TCategory>,TCategory实体类在cn.yangeit.entity包下;
• 页面初始化时自动调用 loadData() 加载数据并刷新表格;
• 检索按钮点击时,根据输入框关键词过滤数据,调用 loadData(keyword,type,status) 重新加载并刷新表格(关键词可为空,即加载全部,type如果是全部,则不分类别,如果status选择是全部也是不分状态)。
2. 表格初始化
• 定义独立方法 initTable():创建 DefaultTableModel(指定表头字段,操作列设为非 editable),关联 JTable,并设置表格样式(行高、对齐方式、斑马纹等);
• 数据加载后,将 List<TCategory> 转换为表格行数据,通过 tableModel.setDataVector() 更新表格内容。
3. 按钮交互
• 检索按钮:绑定 ActionListener,获取输入框文本,调用 loadData(keyword,type) 刷新表格;
• 添加按钮:绑定 ActionListener,点击后打开添加对话框(显示分类编码category_code,分类名称name,分类类型type(下拉框),状态status(下拉框启用禁用),排序号sort_order,描述description),点击保存后,触发save方法;
• 编辑/删除按钮:操作列的每行按钮绑定 ActionListener,点击编辑按钮时获取当前行数据(显示分类编码category_code,分类名称name,分类类型type(下拉框),状态status(下拉框启用禁用),排序号sort_order,描述description),弹出对应的编辑对话框(确认和取消按钮 在最下方),确认后执行逻辑save(当前先留空,仅打印日志)。
• 点击删除按钮时获取当前行数据(如分类名字和分类编码),弹出确认对话框(如“确定删除XXX?”),确认后执行逻辑deleteById(分类编码)(当前先留空,仅打印日志)
• 要让 JTable正确显示操作列的按钮(水平布局,编辑在左,删除在右),必须通过 自定义 TableCellRenderer和 TableCellEditor 实现,操作列背景颜色和其他列一致,且删除按钮红色,编辑按钮蓝色
• 删除数据完成时,会刷新数据,但容易导致角标越界异常,因此需要结合SwingUtilities.invokeLater安全操作
4. 组件命名规范
• 检索输入框:searchField;
• 检索按钮:searchBtn;
• 添加按钮:addBtn;
• 表格:userTable;
• 表格模型:tableModel;
• 滚动面板:scrollPane。
四、风格一致性
• 色调:浅灰+白色为主(背景、按钮默认色),深灰文字(表头、内容),按钮悬停/激活色为深一点的浅灰(如 #E0E0E0 → #D0D0D0);
• 字体:系统无衬线字体(苹方/微软雅黑/SansSerif),表头字号 13px(加粗),内容字号 12px;
• 与现有界面统一:按钮样式、对话框风格、背景色与 HomeUI 侧边栏按钮、UserUI 输入框保持一致。
五、输出要求
1. 提供 CategoryUI.java 完整可运行代码(含 import、成员变量、构造方法、界面初始化、事件绑定);
2. 代码注释清晰:说明各区域作用(如“检索区”“表格区”)、主要方法逻辑(如 loadData() 数据加载流程);
3. 独立方法定义:
• initTable():初始化表格模型和样式;
• loadData():无参,加载全部数据;
• loadData(String keyword,String type,Integer status):带参,根据关键词过滤加载数据;
• save():保存数据(仅打印日志)
• deleteById():删除数据(仅打印日志)
4. 暂不实现业务逻辑(如实际数据查询、改密/删除后端交互),仅模拟数据(如 List<TCategory> 硬编码 5-10 条测试数据)和前端交互(按钮点击日志打印);
5. 表格操作列按钮可点击,点击时打印当前行数据(如“点击删除分类:抗生素”)。
6. 核心操作都要输出 System.out.println() 日志,方便检查,如果有异常,直接输出ex.printStackTrace() 方便在控制台查看
目标:符合 JavaSE Swing 开发规范,界面美观(苹果风格)、交互流畅,数据与界面分离,便于后续扩展业务逻辑。
将提示词和文件拖拽到tongyi中,点击“一键生成”按钮,即可生成对应的代码。

生成代码后,将代码复制到项目中,并运行程序,即可看到分类模块的界面。

1.3 分类模块列表
前言
找到CategoryUI.java中加载数据的方法loadData(),将代码修改为数据库获取数据的代码

改成如下代码:👇

接着重启程序,即可看到分类模块的列表数据。

1.4 分类模块添加
前言
效果图如下 👇 
通过日志追踪,发现save方法负责保存数据,但是没有实现,所以需要实现save方法内部逻辑。 
然后在TCategoryDao中增加save方法,并实现逻辑,代码如下 👇
public int save(TCategory tCategory) {
SqlSession sqlSession = sqlSessionFactory.openSession();
TCategoryMapper tCategoryMapper = sqlSession.getMapper(TCategoryMapper.class);
int count = tCategoryMapper.insertSelective(tCategory);
sqlSession.commit();
sqlSession.close();
return count;
}
效果图 👇 
1.5 分类模块编辑
前言
效果图如下 👇 
通过日志追踪,发现save方法负责保存数据,但是没有实现,所以需要实现save方法内部逻辑。

然后在TCategoryDao中增加update方法,并实现逻辑,代码如下 👇
public void update(TCategory category) {
SqlSession sqlSession = sqlSessionFactory.openSession();
TCategoryMapper tCategoryMapper = sqlSession.getMapper(TCategoryMapper.class);
tCategoryMapper.updateByPrimaryKeySelective(category);
sqlSession.commit();
sqlSession.close();
return;
}
效果图 👇

1.6 分类模块删除
前言
注意:删除分类前,需要判断分类下是否有药品,如果有药品,则不能删除。
效果图如下 👇 
通过日志追踪,发现deleteById方法负责保存数据,但是没有实现,所以需要实现deleteById方法内部逻辑。

然后在TCategoryDao中增加deleteById方法,并实现逻辑,代码如下 👇
public void deleteById(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
TCategoryMapper tCategoryMapper = sqlSession.getMapper(TCategoryMapper.class);
tCategoryMapper.deleteByPrimaryKey(Long.valueOf( id));
sqlSession.commit();
sqlSession.close();
}
修改后,重启程序,测试删除功能。
2.药品模块
2.1 药品模块数据库设计
前言
一、ER 图

二、建表 SQL
DROP TABLE IF EXISTS `t_medicine`;
CREATE TABLE `t_medicine` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '药品ID',
`medicine_code` varchar(50) NOT NULL COMMENT '药品编码(如"YP2023001")',
`medicine_name` varchar(200) NOT NULL COMMENT '药品通用名称',
`specification` varchar(100) DEFAULT NULL COMMENT '规格(如"0.25g*24片")',
`manufacturer` varchar(200) DEFAULT NULL COMMENT '生产企业名称',
`approval_number` varchar(100) DEFAULT NULL COMMENT '国家药监局批准文号',
`reference_price` decimal(10,2) DEFAULT NULL COMMENT '参考售价(元)',
`category_code` varchar(50) DEFAULT NULL COMMENT '所属分类编码(逻辑外键,关联 t_category.category_code)',
`status` tinyint(1) DEFAULT '1' COMMENT '状态(0-停用/1-在用)',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_medicine_code` (`medicine_code`),
UNIQUE KEY `uk_approval_number` (`approval_number`),
KEY `idx_category_code` (`category_code`) -- 普通索引提升按分类编码查询的性能
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COMMENT='药品表';
三、30条假数据(使用 category_code 替代 category_id)
我们先回顾分类表的 category_code(来自之前的假数据):
| id | category_code | name | type |
|---|---|---|---|
| 1 | XY-001 | 抗生素类 | western |
| 2 | XY-002 | 心血管类 | western |
| 3 | XY-003 | 消化系统类 | western |
| 4 | ZCY-001 | 解表类中药 | chinese |
| 5 | ZCY-002 | 清热类中药 | chinese |
| 6 | ZCY-003 | 补益类中药 | chinese |
药品假数据中 抗生素类 → XY-001、心血管类 → XY-002、消化系统类 → XY-003、解表类中药 → ZCY-001、清热类中药 → ZCY-002、补益类中药 → ZCY-003。
INSERT INTO `t_medicine` (
`medicine_code`,
`medicine_name`,
`specification`,
`manufacturer`,
`approval_number`,
`reference_price`,
`category_code`,
`status`
) VALUES
-- 抗生素类药品(category_code = XY-001)
('YP2023001', '阿莫西林胶囊', '0.25g*24粒', '华北制药股份有限公司', '国药准字H13020726', 12.50, 'XY-001', 1),
('YP2023002', '头孢拉定胶囊', '0.25g*12粒', '石药集团欧意药业有限公司', '国药准字H13020727', 8.80, 'XY-001', 1),
('YP2023003', '左氧氟沙星片', '0.1g*6片', '浙江医药股份有限公司', '国药准字H20000594', 15.60, 'XY-001', 1),
('YP2023004', '阿奇霉素分散片', '0.25g*6片', '辉瑞制药有限公司', '国药准字H10960167', 28.90, 'XY-001', 1),
('YP2023005', '克拉霉素片', '0.25g*6片', '杭州中美华东制药有限公司', '国药准字H20000054', 18.20, 'XY-001', 1),
-- 心血管类药品(category_code = XY-002)
('YP2023006', '硝苯地平控释片', '30mg*7片', '拜耳医药保健有限公司', '国药准字J20130115', 35.80, 'XY-002', 1),
('YP2023007', '阿司匹林肠溶片', '100mg*30片', '拜耳医药保健有限公司', '国药准字J20171021', 15.50, 'XY-002', 1),
('YP2023008', '阿托伐他汀钙片', '20mg*7片', '辉瑞制药有限公司', '国药准字J200050', 42.30, 'XY-002', 1),
('YP2023009', '酒石酸美托洛尔片', '25mg*20片', '阿斯利康制药有限公司', '国药准字J20150044', 12.80, 'XY-002', 0),
('YP2023010', '单硝酸异山梨酯片', '20mg*48片', '鲁南贝特制药有限公司', '国药准字H37022846', 22.60, 'XY-002', 1),
-- 消化系统类药品(category_code = XY-003)
('YP2023011', '奥美拉唑肠溶胶囊', '20mg*14粒', '阿斯利康制药有限公司', '国药准字H20030412', 25.40, 'XY-003', 0),
('YP2023012', '多潘立酮片', '10mg*30片', '西安杨森制药有限公司', '国药准字H10910003', 18.90, 'XY-003', 1),
('YP2023013', '雷贝拉唑钠肠溶片', '10mg*7片', '卫材(中国)药业有限公司', '国药准字H20090091', 32.70, 'XY-003', 0),
('YP2023014', '铝碳酸镁咀嚼片', '0.5g*20片', '拜耳医药保健有限公司', '国药准字H20013410', 16.50, 'XY-003', 1),
('YP2023015', '复方甘草片', '100片', '东北制药集团沈阳第一制药有限公司', '国药准字H21022474', 8.90, 'XY-003', 1),
-- 解表类中药(category_code = ZCY-001)
('YP2023016', '感冒清热颗粒', '12g*10袋', '北京同仁堂科技发展股份有限公司', '国药准字Z11020361', 18.00, 'ZCY-001', 1),
('YP2023017', '板蓝根颗粒', '10g*20袋', '广州白云山和记黄埔中药有限公司', '国药准字Z44023485', 12.50, 'ZCY-001', 1),
('YP2023018', '双黄连口服液', '10ml*10支', '哈药集团三精制药有限公司', '国药准字Z23021566', 15.80, 'ZCY-001', 1),
('YP2023019', '小柴胡颗粒', '10g*9袋', '广州白云山光华制药股份有限公司', '国药准字Z44020211', 14.20, 'ZCY-001', 1),
('YP2023020', '银翘解毒片', '0.5g*24片', '北京同仁堂科技发展股份有限公司', '国药准字Z11020456', 9.60, 'ZCY-001', 1),
-- 清热类中药(category_code = ZCY-002)
('YP2023021', '牛黄解毒片', '0.25g*24片', '北京同仁堂科技发展股份有限公司', '国药准字Z11020452', 6.80, 'ZCY-002', 1),
('YP2023022', '黄连上清丸', '6g*10丸', '北京同仁堂股份有限公司同仁堂制药厂', '国药准字Z11020259', 16.80, 'ZCY-002', 1),
('YP2023023', '清热解毒口服液', '10ml*6支', '湖北太子药业有限公司', '国药准字Z42020187', 11.50, 'ZCY-002', 1),
('YP2023024', '穿心莲片', '0.21g*24片', '广州白云山和记黄埔中药有限公司', '国药准字Z44022295', 7.90, 'ZCY-002', 1),
('YP2023025', '栀子金花丸', '9g*10袋', '北京同仁堂科技发展股份有限公司', '国药准字Z11020586', 13.20, 'ZCY-002', 1),
-- 补益类中药(category_code = ZCY-003)
('YP2023026', '六味地黄丸', '9g*10丸', '北京同仁堂股份有限公司同仁堂制药厂', '国药准字Z11020056', 19.80, 'ZCY-003', 1),
('YP2023027', '补中益气丸', '6g*10袋', '北京同仁堂科技发展股份有限公司', '国药准字Z11020244', 15.60, 'ZCY-003', 1),
('YP2023028', '人参健脾丸', '6g*10丸', '北京同仁堂股份有限公司同仁堂制药厂', '国药准字Z11021094', 24.50, 'ZCY-003', 1),
('YP2023029', '阿胶补血膏', '200g', '山东东阿阿胶股份有限公司', '国药准字Z37021369', 89.00, 'ZCY-003', 1),
('YP2023030', '十全大补丸', '9g*10丸', '北京同仁堂科技发展股份有限公司', '国药准字Z11020888', 21.30, 'ZCY-003', 1);

四、逻辑外键使用建议
- 应用层校验:在新增/更新药品时,检查
category_code是否存在于t_category.category_code中。 - 查询联表:需要分类名称时,使用
JOIN:SELECT m.*, c.name AS category_name, c.type AS category_type FROM t_medicine m LEFT JOIN t_category c ON m.category_code = c.category_code; - 数据完整性:可编写定期检查脚本,找出
t_medicine中存在但t_category中不存在的category_code,进行清理或修复。
五、完成配套的TMedicineMapper.xml, TMedicineMapper.java,TMedicine.java,TMedicineDao.java等编写和导入

前三个可以使用MybatisX插件自动生成,后面的需要自己TMedicineDao.java手动编写
2.2 药品模块页面设计
前言
由于前一天,我们写了一个TMedicineUI的空壳子,接下来,我们将利用AI完成TMedicineUI的页面的开发。
其实药品模块和分类模块的结构几乎一致,因此,我们完全可以复用用户模块提示词,只需要稍微修改一下提示词中的内容即可。
修改之后的提示词如下:👇
TMedicineUI.java 开发需求文档
药品数据库表设计如下:
CREATE TABLE `t_medicine` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '药品ID',
`medicine_code` varchar(50) NOT NULL COMMENT '药品编码(如"YP2023001")',
`medicine_name` varchar(200) NOT NULL COMMENT '药品通用名称',
`specification` varchar(100) DEFAULT NULL COMMENT '规格(如"0.25g*24片")',
`manufacturer` varchar(200) DEFAULT NULL COMMENT '生产企业名称',
`approval_number` varchar(100) DEFAULT NULL COMMENT '国家药监局批准文号',
`reference_price` decimal(10,2) DEFAULT NULL COMMENT '参考售价(元)',
`category_code` varchar(50) DEFAULT NULL COMMENT '所属分类编码(逻辑外键,关联 t_category.category_code)',
`status` tinyint(1) DEFAULT '1' COMMENT '状态(0-停用/1-在用)',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_medicine_code` (`medicine_code`),
UNIQUE KEY `uk_approval_number` (`approval_number`),
KEY `idx_category_code` (`category_code`) -- 普通索引提升按分类编码查询的性能
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COMMENT='药品表';
一、项目环境
• 所属模块:HomeUI.java 内容区嵌入的子界面(通过侧边栏“药品管理”菜单切换显示);
• 技术:Java Swing,风格与现有界面(UserUI、WelcomeUI、HomeUI)一致;
• 数据依赖:需加载数据(模拟从数据库查询,包含分类表的各个字段)。
二、界面设计(苹果风格:简洁、留白、色调统一、控件圆润)
1. 整体布局
采用 BorderLayout + FlowLayout + 边距控制,分区明确:
• 顶部:检索区(左:检索框+检索按钮;右:添加按钮);
• 中部:表格区(占满剩余空间,带滚动条);
• 整体背景白色,四周留白舒适(如 EmptyBorder(10, 10, 10, 10))。
2. 检索与操作区(顶部第一行)
• 左侧:检索组件
• 检索输入框:宽度约 200px,提示文字“请输入检索关键字”,无边框(或浅灰细边框),圆角(6px);
• 类型下拉框:宽度约 100px,下拉选项(显示分类名字,数据从loadCategoryData方法获取TCategory列表数据,用category_code和category_name两个字段)无边框(或浅灰细边框),圆角(6px)
• 状态下拉框:宽度约 100px,下拉选项“全部”、“在用”、“停用”,默认“全部”,无边框(或浅灰细边框),圆角(6px)
• 检索按钮:文字“检索”,浅灰背景(默认)、悬停加深、点击激活变色,圆角矩形,与输入框间距 8px。
• 重置按钮:文字“重置”,浅灰背景(默认)、悬停加深、点击激活变色,圆角矩形,与输入框间距 8px。
• 右侧:添加按钮
• 文字“添加”,样式同检索按钮(统一按钮风格),与左侧检索组件间距 16px。
• 布局:用 FlowLayout 横向排列,居中对齐,整体区域背景白色,高度约 50px(含内边距)。
3. 表格区(第二行)
• 表格组件:JTable + JScrollPane(带垂直滚动条,无水平滚动条,列宽自适应内容);
• 表头字段(按顺序):
ID 药品编码 药品名称 分类名字 规格 参考售价(元) 库存 状态 创建时间 操作
• 操作列:每行包含编辑和删除2个按钮(文字按钮,样式同检索按钮,间距 2,列宽固定约 100px,按钮高度和列一致);
• 表格样式:
• 表头:浅灰背景,深灰文字,加粗,居中对齐;
• 内容行:白色背景,深灰文字,居中对齐;
• 行高:紧凑适中,隔行浅灰背景(斑马纹,提升可读性);
• 边框:表格外框浅灰细边框,单元格间无分隔线(或极浅灰分隔线,符合苹果简洁风格);
• 列宽:序号 20px,其他 100px,剩余的宽度自适应内容
• 按钮:所有的按钮通过一个方法 createButton() 统一初始化样式(如圆角、背景色、字体、边距等),避免重复代码。
三、交互与逻辑
1. 数据加载
• 定义独立方法 loadData():模拟从数据源(如 TMedicineDao)加载数据,返回 List<TMedicine>,TMedicine实体类在cn.yangeit.entity包下;
• 页面初始化时自动调用 loadData() 加载数据并刷新表格;
• 检索按钮点击时,根据输入框关键词过滤数据,调用 loadData(keyword,category_code,status) 重新加载并刷新表格(关键词可为空,即加载全部,分类如果是全部,则不分类别,如果status选择是全部也是不分状态)。
2. 表格初始化
• 定义独立方法 initTable():创建 DefaultTableModel(指定表头字段,操作列设为非 editable),关联 JTable,并设置表格样式(行高、对齐方式、斑马纹等);
• 数据加载后,将 List<TMedicine> 转换为表格行数据,通过 tableModel.setDataVector() 更新表格内容。
3. 按钮交互
• 检索按钮:绑定 ActionListener,获取输入框文本,调用 loadData(keyword,category_code,status) 刷新表格;
• 添加按钮:绑定 ActionListener,点击后打开添加对话框(显示药品编码medicine_code,药品名称medicine_name,规格specification,生产企业manufacturer,国家药监局批准文号approval_number,参考售价reference_price,所属分类category_code下拉列表(通过loadCategoryData方法获得所有的分类名字和分类编码),状态status(下拉框在用停用),点击保存后,触发save方法;
• 编辑/删除按钮:操作列的每行按钮绑定 ActionListener,点击编辑按钮时获取当前行数据(显示药品编码medicine_code,药品名称medicine_name,规格specification,生产企业manufacturer,国家药监局批准文号approval_number,参考售价reference_price,所属分类category_code下拉列表(通过loadCategoryData方法获得所有的分类名字和分类编码),状态status(下拉框在用停用)),弹出对应的编辑对话框(确认和取消按钮 在最下方),确认后执行逻辑save(当前先留空,仅打印日志)。
• 点击删除按钮时获取当前行数据(如药品名字和药品编码),弹出确认对话框(如“确定删除XXX?”),确认后执行逻辑deleteById(药品编码)(当前先留空,仅打印日志)
• 要让 JTable正确显示操作列的按钮(水平布局,编辑在左,删除在右),必须通过 自定义 TableCellRenderer和 TableCellEditor 实现,操作列背景颜色和其他列一致,且删除按钮红色,编辑按钮蓝色
• 删除数据完成时,会刷新数据,但容易导致角标越界异常,因此需要结合SwingUtilities.invokeLater安全操作
4. 组件命名规范
• 检索输入框:searchField;
• 检索按钮:searchBtn;
• 添加按钮:addBtn;
• 表格:dataTable;
• 表格模型:tableModel;
• 滚动面板:scrollPane。
四、风格一致性
• 色调:浅灰+白色为主(背景、按钮默认色),深灰文字(表头、内容),按钮悬停/激活色为深一点的浅灰(如 #E0E0E0 → #D0D0D0);
• 字体:系统无衬线字体(苹方/微软雅黑/SansSerif),表头字号 13px(加粗),内容字号 12px;
• 与现有界面统一:按钮样式、对话框风格、背景色与 HomeUI 侧边栏按钮、UserUI 输入框保持一致。
五、输出要求
1. 提供 TMedicineUI.java 完整可运行代码(含 import、成员变量、构造方法、界面初始化、事件绑定);
2. 代码注释清晰:说明各区域作用(如“检索区”“表格区”)、主要方法逻辑(如 loadData() 数据加载流程);
3. 独立方法定义:
• initTable():初始化表格模型和样式;
• loadData():无参,加载全部数据;
• loadData(String keyword,String category_code,Integer status):带参,根据关键词过滤加载数据;
• save():保存数据(仅打印日志)
• deleteById():删除数据(仅打印日志)
• loadCategoryData():获取TCategory列表数据(仅打印日志,造几条分类的数据)
4. 暂不实现业务逻辑(如实际数据查询、改密/删除后端交互),仅模拟数据(如 List<TMedicineUI> 硬编码 5-10 条测试数据)和前端交互(按钮点击日志打印);
5. 表格操作列按钮可点击,点击时打印当前行数据(如“点击删除分类:抗生素”)。
6. 核心操作都要输出 System.out.println() 日志,方便检查,如果有异常,直接输出ex.printStackTrace() 方便在控制台查看
目标:符合 JavaSE Swing 开发规范,界面美观(苹果风格)、交互流畅,数据与界面分离,便于后续扩展业务逻辑。
将提示词和文件拖拽到tongyi中,点击“一键生成”按钮,即可生成对应的代码。

生成代码后,将代码复制到项目中,并运行程序,即可看到药品模块的界面。

2.3 药品模块列表
前言

前一步的AI代码中,我们已经实现了药品模块的列表功能,只需要在界面中显示即可。
不过数据为mock数据,因此,我们需要在loadData()方法中加载真实的数据。

然后在TMedicineDao中增加selectAll法,并实现逻辑,代码如下 👇
public List<TMedicine> selectAll() {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<TMedicine> list = sqlSession.getMapper(TMedicineMapper.class).selectAll();
sqlSession.commit();
sqlSession.close();
return list;
}
在TMedicineMapper.java中,定义selectAll方法,代码如下 👇

修改后,重启程序,测试列表功能。
测试后,发现类型检索的数据是假数据,需要记载全部的分类数据,👇

因此在TMedicineUI中找寻loadCategoryData方法,并实现逻辑,代码如下 👇

然后重新启动,观察检索效果。

2.4 药品模块新增
前言
点击TMedicineUI中的添加按钮,弹出对话框,输入药品信息,点击保存按钮,保存数据。

同时观察Idea控制台的输出,定义save方法,代码如下 👇

接下来,我们分析一下增加药品的流程:
- 判断输入的字段是否为空,如果为空,则弹出提示框,提示用户输入完整信息;
- 判断药品编码是否已经存在,如果存在,则弹出提示框,提示用户药品编码已经存在;
- 如果以上条件都不满足,创建TMedicine对象,则保存数据,并刷新表格。

同时在TMedicineDao中增加save方法,并实现逻辑。
public void save(TMedicine medicine) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.getMapper(TMedicineMapper.class).insertSelective(medicine);
sqlSession.commit();
sqlSession.close();
}
重启程序,测试新增功能 👇

2.5 药品模块修改
前言

参考分类模块,自行完成...
2.6 药品模块删除
前言

自行完成...
注意:只有管理员才可以删除药品,普通用户不可以删除药品。同时要思考库存记录是否要保留