员工管理
Day01
数据库建立
数据库文件配置,创建数据库 Reggie,新建 Query
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `address_book`;
CREATE TABLE `address_book` (
`id` bigint(20) NOT NULL COMMENT '主键',
`user_id` bigint(20) NOT NULL COMMENT '用户id',
`consignee` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '收货人',
`sex` tinyint(4) NOT NULL COMMENT '性别 0 女 1 男',
`phone` varchar(11) COLLATE utf8_bin NOT NULL COMMENT '手机号',
`province_code` varchar(12) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '省级区划编号',
`province_name` varchar(32) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '省级名称',
`city_code` varchar(12) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '市级区划编号',
`city_name` varchar(32) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '市级名称',
`district_code` varchar(12) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '区级区划编号',
`district_name` varchar(32) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '区级名称',
`detail` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '详细地址',
`label` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '标签',
`is_default` tinyint(1) NOT NULL DEFAULT '0' COMMENT '默认 0 否 1是',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
`is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='地址管理';
INSERT INTO `address_book` VALUES ('1417414526093082626', '1417012167126876162', '小明', '1', '13812345678', null, null, null, null, null, null, '昌平区金燕龙办公楼', '公司', '1', '2021-07-20 17:22:12', '2021-07-20 17:26:33', '1417012167126876162', '1417012167126876162', '0');
INSERT INTO `address_book` VALUES ('1417414926166769666', '1417012167126876162', '小李', '1', '13512345678', null, null, null, null, null, null, '测试', '家', '0', '2021-07-20 17:23:47', '2021-07-20 17:23:47', '1417012167126876162', '1417012167126876162', '0');
DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
`id` bigint(20) NOT NULL COMMENT '主键',
`type` int(11) DEFAULT NULL COMMENT '类型 1 菜品分类 2 套餐分类',
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '分类名称',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '顺序',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_category_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品及套餐分类';
INSERT INTO `category` VALUES ('1397844263642378242', '1', '湘菜', '1', '2021-05-27 09:16:58', '2021-07-15 20:25:23', '1', '1');
INSERT INTO `category` VALUES ('1397844303408574465', '1', '川菜', '2', '2021-05-27 09:17:07', '2021-06-02 14:27:22', '1', '1');
INSERT INTO `category` VALUES ('1397844391040167938', '1', '粤菜', '3', '2021-05-27 09:17:28', '2021-07-09 14:37:13', '1', '1');
INSERT INTO `category` VALUES ('1413341197421846529', '1', '饮品', '11', '2021-07-09 11:36:15', '2021-07-09 14:39:15', '1', '1');
INSERT INTO `category` VALUES ('1413342269393674242', '2', '商务套餐', '5', '2021-07-09 11:40:30', '2021-07-09 14:43:45', '1', '1');
INSERT INTO `category` VALUES ('1413384954989060097', '1', '主食', '12', '2021-07-09 14:30:07', '2021-07-09 14:39:19', '1', '1');
INSERT INTO `category` VALUES ('1413386191767674881', '2', '儿童套餐', '6', '2021-07-09 14:35:02', '2021-07-09 14:39:05', '1', '1');
DROP TABLE IF EXISTS `dish`;
CREATE TABLE `dish` (
`id` bigint(20) NOT NULL COMMENT '主键',
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '菜品名称',
`category_id` bigint(20) NOT NULL COMMENT '菜品分类id',
`price` decimal(10,2) DEFAULT NULL COMMENT '菜品价格',
`code` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '商品码',
`image` varchar(200) COLLATE utf8_bin NOT NULL COMMENT '图片',
`description` varchar(400) COLLATE utf8_bin DEFAULT NULL COMMENT '描述信息',
`status` int(11) NOT NULL DEFAULT '1' COMMENT '0 停售 1 起售',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '顺序',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
`is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_dish_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品管理';
INSERT INTO `dish` VALUES ('1397849739276890114', '辣子鸡', '1397844263642378242', '7800.00', '222222222', 'f966a38e-0780-40be-bb52-5699d13cb3d9.jpg', '来自鲜嫩美味的小鸡,值得一尝', '1', '0', '2021-05-27 09:38:43', '2021-05-27 09:38:43', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397850140982161409', '毛氏红烧肉', '1397844263642378242', '6800.00', '123412341234', '0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg', '毛氏红烧肉毛氏红烧肉,确定不来一份?', '1', '0', '2021-05-27 09:40:19', '2021-05-27 09:40:19', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397850392090947585', '组庵鱼翅', '1397844263642378242', '4800.00', '123412341234', '740c79ce-af29-41b8-b78d-5f49c96e38c4.jpg', '组庵鱼翅,看图足以表明好吃程度', '1', '0', '2021-05-27 09:41:19', '2021-05-27 09:41:19', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397850851245600769', '霸王别姬', '1397844263642378242', '12800.00', '123412341234', '057dd338-e487-4bbc-a74c-0384c44a9ca3.jpg', '还有什么比霸王别姬更美味的呢?', '1', '0', '2021-05-27 09:43:08', '2021-05-27 09:43:08', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397851099502260226', '全家福', '1397844263642378242', '11800.00', '23412341234', 'a53a4e6a-3b83-4044-87f9-9d49b30a8fdc.jpg', '别光吃肉啦,来份全家福吧,让你长寿又美味', '1', '0', '2021-05-27 09:44:08', '2021-05-27 09:44:08', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397851370462687234', '邵阳猪血丸子', '1397844263642378242', '13800.00', '1246812345678', '2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg', '看,美味不?来嘛来嘛,这才是最爱吖', '1', '0', '2021-05-27 09:45:12', '2021-05-27 09:45:12', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397851668262465537', '口味蛇', '1397844263642378242', '16800.00', '1234567812345678', '0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg', '爬行界的扛把子,东兴-口味蛇,让你欲罢不能', '1', '0', '2021-05-27 09:46:23', '2021-05-27 09:46:23', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397852391150759938', '辣子鸡丁', '1397844303408574465', '8800.00', '2346812468', 'ef2b73f2-75d1-4d3a-beea-22da0e1421bd.jpg', '辣子鸡丁,辣子鸡丁,永远的魂', '1', '0', '2021-05-27 09:49:16', '2021-05-27 09:49:16', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397853183287013378', '麻辣兔头', '1397844303408574465', '19800.00', '123456787654321', '2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg', '麻辣兔头的详细制作,麻辣鲜香,色泽红润,回味悠长', '1', '0', '2021-05-27 09:52:24', '2021-05-27 09:52:24', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397853709101740034', '蒜泥白肉', '1397844303408574465', '9800.00', '1234321234321', 'd2f61d70-ac85-4529-9b74-6d9a2255c6d7.jpg', '多么的有食欲啊', '1', '0', '2021-05-27 09:54:30', '2021-05-27 09:54:30', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397853890262118402', '鱼香肉丝', '1397844303408574465', '3800.00', '1234212321234', '8dcfda14-5712-4d28-82f7-ae905b3c2308.jpg', '鱼香肉丝简直就是我们童年回忆的一道经典菜,上学的时候点个鱼香肉丝盖饭坐在宿舍床上看着肥皂剧,绝了!现在完美复刻一下上学的时候感觉', '1', '0', '2021-05-27 09:55:13', '2021-05-27 09:55:13', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397854652581064706', '麻辣水煮鱼', '1397844303408574465', '14800.00', '2345312·345321', '1fdbfbf3-1d86-4b29-a3fc-46345852f2f8.jpg', '鱼片是买的切好的鱼片,放几个虾,增加味道', '1', '0', '2021-05-27 09:58:15', '2021-05-27 09:58:15', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397854865672679425', '鱼香炒鸡蛋', '1397844303408574465', '2000.00', '23456431·23456', '0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg', '鱼香菜也是川味的特色。里面没有鱼却鱼香味', '1', '0', '2021-05-27 09:59:06', '2021-05-27 09:59:06', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397860242057375745', '脆皮烧鹅', '1397844391040167938', '12800.00', '123456786543213456', 'e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg', '“广东烤鸭美而香,却胜烧鹅说古冈(今新会),燕瘦环肥各佳妙,君休偏重便宜坊”,可见烧鹅与烧鸭在粤菜之中已早负盛名。作为广州最普遍和最受欢迎的烧烤肉食,以它的“色泽金红,皮脆肉嫩,味香可口”的特色,在省城各大街小巷的烧卤店随处可见。', '1', '0', '2021-05-27 10:20:27', '2021-05-27 10:20:27', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397860578738352129', '白切鸡', '1397844391040167938', '6600.00', '12345678654', '9ec6fc2d-50d2-422e-b954-de87dcd04198.jpeg', '白切鸡是一道色香味俱全的特色传统名肴,又叫白斩鸡,是粤菜系鸡肴中的一种,始于清代的民间。白切鸡通常选用细骨农家鸡与沙姜、蒜茸等食材,慢火煮浸白切鸡皮爽肉滑,清淡鲜美。著名的泮溪酒家白切鸡,曾获商业部优质产品金鼎奖。湛江白切鸡更是驰名粤港澳。粤菜厨坛中,鸡的菜式有200余款之多,而最为人常食不厌的正是白切鸡,深受食家青睐。', '1', '0', '2021-05-27 10:21:48', '2021-05-27 10:21:48', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397860792492666881', '烤乳猪', '1397844391040167938', '38800.00', '213456432123456', '2e96a7e3-affb-438e-b7c3-e1430df425c9.jpeg', '广式烧乳猪主料是小乳猪,辅料是蒜,调料是五香粉、芝麻酱、八角粉等,本菜品主要通过将食材放入炭火中烧烤而成。烤乳猪是广州最著名的特色菜,并且是“满汉全席”中的主打菜肴之一。烤乳猪也是许多年来广东人祭祖的祭品之一,是家家都少不了的应节之物,用乳猪祭完先人后,亲戚们再聚餐食用。', '1', '0', '2021-05-27 10:22:39', '2021-05-27 10:22:39', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397860963880316929', '脆皮乳鸽', '1397844391040167938', '10800.00', '1234563212345', '3fabb83a-1c09-4fd9-892b-4ef7457daafa.jpeg', '“脆皮乳鸽”是广东菜中的一道传统名菜,属于粤菜系,具有皮脆肉嫩、色泽红亮、鲜香味美的特点,常吃可使身体强健,清肺顺气。随着菜品制作工艺的不断发展,逐渐形成了熟炸法、生炸法和烤制法三种制作方法。无论那种制作方法,都是在鸽子经过一系列的加工,挂脆皮水后再加工而成,正宗的“脆皮乳鸽皮脆肉嫩、色泽红亮、鲜香味美、香气馥郁。这三种方法的制作过程都不算复杂,但想达到理想的效果并不容易。', '1', '0', '2021-05-27 10:23:19', '2021-05-27 10:23:19', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397861683434139649', '清蒸河鲜海鲜', '1397844391040167938', '38800.00', '1234567876543213456', '1405081e-f545-42e1-86a2-f7559ae2e276.jpeg', '新鲜的海鲜,清蒸是最好的处理方式。鲜,体会为什么叫海鲜。清蒸是广州最经典的烹饪手法,过去岭南地区由于峻山大岭阻隔,交通不便,经济发展起步慢,自家打的鱼放在锅里煮了就吃,没有太多的讲究,但却发现这清淡的煮法能使鱼的鲜甜跃然舌尖。', '1', '0', '2021-05-27 10:26:11', '2021-05-27 10:26:11', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397862198033297410', '老火靓汤', '1397844391040167938', '49800.00', '123456786532455', '583df4b7-a159-4cfc-9543-4f666120b25f.jpeg', '老火靓汤又称广府汤,是广府人传承数千年的食补养生秘方,慢火煲煮的中华老火靓汤,火候足,时间长,既取药补之效,又取入口之甘甜。 广府老火汤种类繁多,可以用各种汤料和烹调方法,烹制出各种不同口味、不同功效的汤来。', '1', '0', '2021-05-27 10:28:14', '2021-05-27 10:28:14', '1', '1', '0');
INSERT INTO `dish` VALUES ('1397862477831122945', '上汤焗龙虾', '1397844391040167938', '108800.00', '1234567865432', '5b8d2da3-3744-4bb3-acdc-329056b8259d.jpeg', '上汤焗龙虾是一道色香味俱全的传统名菜,属于粤菜系。此菜以龙虾为主料,配以高汤制成的一道海鲜美食。本品肉质洁白细嫩,味道鲜美,蛋白质含量高,脂肪含量低,营养丰富。是色香味俱全的传统名菜。', '1', '0', '2021-05-27 10:29:20', '2021-05-27 10:29:20', '1', '1', '0');
INSERT INTO `dish` VALUES ('1413342036832100354', '北冰洋', '1413341197421846529', '500.00', '', 'c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png', '', '1', '0', '2021-07-09 11:39:35', '2021-07-09 15:12:18', '1', '1', '0');
INSERT INTO `dish` VALUES ('1413384757047271425', '王老吉', '1413341197421846529', '500.00', '', '00874a5e-0df2-446b-8f69-a30eb7d88ee8.png', '', '1', '0', '2021-07-09 14:29:20', '2021-07-12 09:09:16', '1', '1', '0');
INSERT INTO `dish` VALUES ('1413385247889891330', '米饭', '1413384954989060097', '200.00', '', 'ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', '', '1', '0', '2021-07-09 14:31:17', '2021-07-11 16:35:26', '1', '1', '0');
DROP TABLE IF EXISTS `dish_flavor`;
CREATE TABLE `dish_flavor` (
`id` bigint(20) NOT NULL COMMENT '主键',
`dish_id` bigint(20) NOT NULL COMMENT '菜品',
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '口味名称',
`value` varchar(500) COLLATE utf8_bin DEFAULT NULL COMMENT '口味数据list',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
`is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品口味关系表';
INSERT INTO `dish_flavor` VALUES ('1397849417888346113', '1397849417854791681', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:37:27', '2021-05-27 09:37:27', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397849739297861633', '1397849739276890114', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:38:43', '2021-05-27 09:38:43', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397849739323027458', '1397849739276890114', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:38:43', '2021-05-27 09:38:43', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397849936421761025', '1397849936404983809', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:39:30', '2021-05-27 09:39:30', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397849936438538241', '1397849936404983809', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:39:30', '2021-05-27 09:39:30', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850141015715841', '1397850140982161409', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:40:19', '2021-05-27 09:40:19', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850141040881665', '1397850140982161409', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:40:19', '2021-05-27 09:40:19', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850392120307713', '1397850392090947585', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:41:19', '2021-05-27 09:41:19', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850392137084929', '1397850392090947585', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:41:19', '2021-05-27 09:41:19', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850630734262274', '1397850630700707841', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:42:16', '2021-05-27 09:42:16', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850630755233794', '1397850630700707841', '辣度', '[\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:42:16', '2021-05-27 09:42:16', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850851274960898', '1397850851245600769', '忌口', '[\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:43:08', '2021-05-27 09:43:08', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397850851283349505', '1397850851245600769', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:43:08', '2021-05-27 09:43:08', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397851099523231745', '1397851099502260226', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:44:08', '2021-05-27 09:44:08', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397851099527426050', '1397851099502260226', '辣度', '[\"不辣\",\"微辣\",\"中辣\"]', '2021-05-27 09:44:08', '2021-05-27 09:44:08', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397851370483658754', '1397851370462687234', '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', '2021-05-27 09:45:12', '2021-05-27 09:45:12', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397851370483658755', '1397851370462687234', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:45:12', '2021-05-27 09:45:12', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397851370483658756', '1397851370462687234', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:45:12', '2021-05-27 09:45:12', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397851668283437058', '1397851668262465537', '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', '2021-05-27 09:46:23', '2021-05-27 09:46:23', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397852391180120065', '1397852391150759938', '忌口', '[\"不要葱\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:49:16', '2021-05-27 09:49:16', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397852391196897281', '1397852391150759938', '辣度', '[\"不辣\",\"微辣\",\"重辣\"]', '2021-05-27 09:49:16', '2021-05-27 09:49:16', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397853183307984898', '1397853183287013378', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:52:24', '2021-05-27 09:52:24', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397853423486414850', '1397853423461249026', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:53:22', '2021-05-27 09:53:22', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397853709126905857', '1397853709101740034', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:54:30', '2021-05-27 09:54:30', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397853890283089922', '1397853890262118402', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:55:13', '2021-05-27 09:55:13', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397854133632413697', '1397854133603053569', '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', '2021-05-27 09:56:11', '2021-05-27 09:56:11', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397854652623007745', '1397854652581064706', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 09:58:15', '2021-05-27 09:58:15', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397854652635590658', '1397854652581064706', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:58:15', '2021-05-27 09:58:15', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397854865735593986', '1397854865672679425', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 09:59:06', '2021-05-27 09:59:06', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397855742303186946', '1397855742273826817', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:02:35', '2021-05-27 10:02:35', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397855906497605633', '1397855906468245506', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 10:03:14', '2021-05-27 10:03:14', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397856190573621250', '1397856190540066818', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:04:21', '2021-05-27 10:04:21', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397859056709316609', '1397859056684150785', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:15:45', '2021-05-27 10:15:45', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397859277837217794', '1397859277812051969', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:16:37', '2021-05-27 10:16:37', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397859487502086146', '1397859487476920321', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:17:27', '2021-05-27 10:17:27', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397859757061615618', '1397859757036449794', '甜味', '[\"无糖\",\"少糖\",\"半躺\",\"多糖\",\"全糖\"]', '2021-05-27 10:18:32', '2021-05-27 10:18:32', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397860242086735874', '1397860242057375745', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:20:27', '2021-05-27 10:20:27', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397860963918065665', '1397860963880316929', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:23:19', '2021-05-27 10:23:19', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397861135754506242', '1397861135733534722', '甜味', '[\"无糖\",\"少糖\",\"半躺\",\"多糖\",\"全糖\"]', '2021-05-27 10:24:00', '2021-05-27 10:24:00', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397861370035744769', '1397861370010578945', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-27 10:24:56', '2021-05-27 10:24:56', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397861683459305474', '1397861683434139649', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 10:26:11', '2021-05-27 10:26:11', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397861898467717121', '1397861898438356993', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 10:27:02', '2021-05-27 10:27:02', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397862198054268929', '1397862198033297410', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-27 10:28:14', '2021-05-27 10:28:14', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1397862477835317250', '1397862477831122945', '辣度', '[\"不辣\",\"微辣\",\"中辣\"]', '2021-05-27 10:29:20', '2021-05-27 10:29:20', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398089545865015297', '1398089545676271617', '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', '2021-05-28 01:31:38', '2021-05-28 01:31:38', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398089782323097601', '1398089782285348866', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:32:34', '2021-05-28 01:32:34', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398090003262255106', '1398090003228700673', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-28 01:33:27', '2021-05-28 01:33:27', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398090264554811394', '1398090264517062657', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-28 01:34:29', '2021-05-28 01:34:29', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398090455399837698', '1398090455324340225', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:35:14', '2021-05-28 01:35:14', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398090685449023490', '1398090685419663362', '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', '2021-05-28 01:36:09', '2021-05-28 01:36:09', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398090825358422017', '1398090825329061889', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-28 01:36:43', '2021-05-28 01:36:43', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398091007051476993', '1398091007017922561', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:37:26', '2021-05-28 01:37:26', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398091296164851713', '1398091296131297281', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:38:35', '2021-05-28 01:38:35', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398091546531246081', '1398091546480914433', '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', '2021-05-28 01:39:35', '2021-05-28 01:39:35', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398091729809747969', '1398091729788776450', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:40:18', '2021-05-28 01:40:18', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398091889499484161', '1398091889449152513', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:40:56', '2021-05-28 01:40:56', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398092095179763713', '1398092095142014978', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:41:45', '2021-05-28 01:41:45', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398092283877306370', '1398092283847946241', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:42:30', '2021-05-28 01:42:30', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398094018939236354', '1398094018893099009', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:49:24', '2021-05-28 01:49:24', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1398094391494094850', '1398094391456346113', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-05-28 01:50:53', '2021-05-28 01:50:53', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1399574026165727233', '1399305325713600514', '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', '2021-06-01 03:50:25', '2021-06-01 03:50:25', '1399309715396669441', '1399309715396669441', '0');
INSERT INTO `dish_flavor` VALUES ('1413389540592263169', '1413384757047271425', '温度', '[\"常温\",\"冷藏\"]', '2021-07-12 09:09:16', '2021-07-12 09:09:16', '1', '1', '0');
INSERT INTO `dish_flavor` VALUES ('1413389684020682754', '1413342036832100354', '温度', '[\"常温\",\"冷藏\"]', '2021-07-09 15:12:18', '2021-07-09 15:12:18', '1', '1', '0');
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` bigint(20) NOT NULL COMMENT '主键',
`name` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '姓名',
`username` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '用户名',
`password` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '密码',
`phone` varchar(11) COLLATE utf8_bin NOT NULL COMMENT '手机号',
`sex` varchar(2) COLLATE utf8_bin NOT NULL COMMENT '性别',
`id_number` varchar(18) COLLATE utf8_bin NOT NULL COMMENT '身份证号',
`status` int(11) NOT NULL DEFAULT '1' COMMENT '状态 0:禁用,1:正常',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='员工信息';
INSERT INTO `employee` VALUES ('1', '管理员', 'admin', 'e10adc3949ba59abbe56e057f20f883e', '13812312312', '1', '110101199001010047', '1', '2021-05-06 17:20:07', '2021-05-10 02:24:09', '1', '1');
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL COMMENT '主键',
`number` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '订单号',
`status` int(11) NOT NULL DEFAULT '1' COMMENT '订单状态 1待付款,2待派送,3已派送,4已完成,5已取消',
`user_id` bigint(20) NOT NULL COMMENT '下单用户',
`address_book_id` bigint(20) NOT NULL COMMENT '地址id',
`order_time` datetime NOT NULL COMMENT '下单时间',
`checkout_time` datetime NOT NULL COMMENT '结账时间',
`pay_method` int(11) NOT NULL DEFAULT '1' COMMENT '支付方式 1微信,2支付宝',
`amount` decimal(10,2) NOT NULL COMMENT '实收金额',
`remark` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
`phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`address` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`user_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`consignee` varchar(255) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='订单表';
DROP TABLE IF EXISTS `order_detail`;
CREATE TABLE `order_detail` (
`id` bigint(20) NOT NULL COMMENT '主键',
`name` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '名字',
`image` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '图片',
`order_id` bigint(20) NOT NULL COMMENT '订单id',
`dish_id` bigint(20) DEFAULT NULL COMMENT '菜品id',
`setmeal_id` bigint(20) DEFAULT NULL COMMENT '套餐id',
`dish_flavor` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '口味',
`number` int(11) NOT NULL DEFAULT '1' COMMENT '数量',
`amount` decimal(10,2) NOT NULL COMMENT '金额',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='订单明细表';
DROP TABLE IF EXISTS `setmeal`;
CREATE TABLE `setmeal` (
`id` bigint(20) NOT NULL COMMENT '主键',
`category_id` bigint(20) NOT NULL COMMENT '菜品分类id',
`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '套餐名称',
`price` decimal(10,2) NOT NULL COMMENT '套餐价格',
`status` int(11) DEFAULT NULL COMMENT '状态 0:停用 1:启用',
`code` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '编码',
`description` varchar(512) COLLATE utf8_bin DEFAULT NULL COMMENT '描述信息',
`image` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '图片',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
`is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `idx_setmeal_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='套餐';
INSERT INTO `setmeal` VALUES ('1415580119015145474', '1413386191767674881', '儿童套餐A计划', '4000.00', '1', '', '', '61d20592-b37f-4d72-a864-07ad5bb8f3bb.jpg', '2021-07-15 15:52:55', '2021-07-15 15:52:55', '1415576781934608386', '1415576781934608386', '0');
DROP TABLE IF EXISTS `setmeal_dish`;
CREATE TABLE `setmeal_dish` (
`id` bigint(20) NOT NULL COMMENT '主键',
`setmeal_id` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '套餐id ',
`dish_id` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '菜品id',
`name` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '菜品名称 (冗余字段)',
`price` decimal(10,2) DEFAULT NULL COMMENT '菜品原价(冗余字段)',
`copies` int(11) NOT NULL COMMENT '份数',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '更新时间',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`update_user` bigint(20) NOT NULL COMMENT '修改人',
`is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='套餐菜品关系';
INSERT INTO `setmeal_dish` VALUES ('1415580119052894209', '1415580119015145474', '1397862198033297410', '老火靓汤', '49800.00', '1', '0', '2021-07-15 15:52:55', '2021-07-15 15:52:55', '1415576781934608386', '1415576781934608386', '0');
INSERT INTO `setmeal_dish` VALUES ('1415580119061282817', '1415580119015145474', '1413342036832100354', '北冰洋', '500.00', '1', '0', '2021-07-15 15:52:55', '2021-07-15 15:52:55', '1415576781934608386', '1415576781934608386', '0');
INSERT INTO `setmeal_dish` VALUES ('1415580119069671426', '1415580119015145474', '1413385247889891330', '米饭', '200.00', '1', '0', '2021-07-15 15:52:55', '2021-07-15 15:52:55', '1415576781934608386', '1415576781934608386', '0');
DROP TABLE IF EXISTS `shopping_cart`;
CREATE TABLE `shopping_cart` (
`id` bigint(20) NOT NULL COMMENT '主键',
`name` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '名称',
`image` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '图片',
`user_id` bigint(20) NOT NULL COMMENT '主键',
`dish_id` bigint(20) DEFAULT NULL COMMENT '菜品id',
`setmeal_id` bigint(20) DEFAULT NULL COMMENT '套餐id',
`dish_flavor` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '口味',
`number` int(11) NOT NULL DEFAULT '1' COMMENT '数量',
`amount` decimal(10,2) NOT NULL COMMENT '金额',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='购物车';
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL COMMENT '主键',
`name` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '姓名',
`phone` varchar(100) COLLATE utf8_bin NOT NULL COMMENT '手机号',
`sex` varchar(2) COLLATE utf8_bin DEFAULT NULL COMMENT '性别',
`id_number` varchar(18) COLLATE utf8_bin DEFAULT NULL COMMENT '身份证号',
`avatar` varchar(500) COLLATE utf8_bin DEFAULT NULL COMMENT '头像',
`status` int(11) DEFAULT '0' COMMENT '状态 0:禁用,1:正常',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='用户信息';
依赖建立和版本控制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
</parent>
<groupId>com.heyu</groupId>
<artifactId>reggie_take_out</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
<fastjson.version>2.0.6</fastjson.version>
<commons-lang.version>2.6</commons-lang.version>
<durid.version>1.2.11</durid.version>
<maven-plugin.version>2.7.1</maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${durid.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${maven-plugin.version}</version>
</plugin>
</plugins>
</build>
</project>
配置文件
建立普通环境和开发环境,默认激活Dev 环境
spring:
profiles:
active: dev
Application-dev.yml
server:
port: 8080
spring:
application:
name: reggie_take_out
datasource:
druid:
username: root
password: root1234
url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
type: com.alibaba.druid.pool.DruidDataSource
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: assign_id
主启动类
@Slf4j
@SpringBootApplication
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class,args);
log.info("项目启动成功.....");
}
}
配置静态资源映射
package com.heyu.reggie.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry){
log.info("开始静态资源映射");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("front/**").addResourceLocations("classpath:/front/");
}
}
后台登录功能开发
需求分析
前端 URL 发送的请求—>接收到 Controller—>Service—>Mapper—>DataBase
导入返回结果类 R
此类是一个通用结果类,服务端响应的所有结果最终都会包装成此类类型返回给前端页面
entity.Employee
@Data
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String name;
private String password;
private String phone;
private String sex;
private String idNumber;
private Integer status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
}
Mapper.EmployeeMapper
@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}
Service.EmployeeService
public interface EmployeeService extends IService<Employee> {
}
Service.EmployeeServiceImpl
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService {
}
业务逻辑
1.将页面提交的密码 password 进行 md5 加密处理
2.根据页面提交的用户名 username 查询数据库
3.如果没有查询到就返回---登录失败
4.密码比对,如果不一致,返回---登录失败
5.查看员工状态,如果为已禁用状态,则返回---员工已禁用
6.登录成功,将员工 ID 存入 session 并返回---登录成功
Controller.EmployeeController
@RestController
@Slf4j
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
String password = employee.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);
if (emp == null ){
return R.error("用户不存在");
}
if (!emp.getPassword().equals(password)){
return R.error("密码不正确");
}
if (emp.getStatus() == 0){
return R.error("账号已禁用");
}
request.getSession().setAttribute("employee",emp.getId());
return R.success(emp);
}
}
Day02
问题
登录报错 406
Debug 错误内容
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@73b865ee] will not be managed by Spring
==> Preparing: SELECT id,username,name,password,phone,sex,id_number,status,create_time,update_time,create_user,update_user FROM employee WHERE (username = ?)
==> Parameters: admin(String)
<== Columns: id, username, name, password, phone, sex, id_number, status, create_time, update_time, create_user, update_user
<== Row: 1, admin, 管理员, e10adc3949ba59abbe56e057f20f883e, 13812312312, 1, 110101199001010047, 1, 2021-05-06 17:20:07, 2021-05-10 02:24:09, 1, 1
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6e4dbf4a]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6c6f3c95] will not be managed by Spring
==> Preparing: SELECT id,username,name,password,phone,sex,id_number,status,create_time,update_time,create_user,update_user FROM employee WHERE (username = ?)
==> Parameters: admin(String)
<== Columns: id, username, name, password, phone, sex, id_number, status, create_time, update_time, create_user, update_user
<== Row: 1, admin, 管理员, e10adc3949ba59abbe56e057f20f883e, 13812312312, 1, 110101199001010047, 1, 2021-05-06 17:20:07, 2021-05-10 02:24:09, 1, 1
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3d6369a1]
第一次解决:406 异常—>500 异常
解决方法:
@RequestMapping(value="/employee",produces = "application/json")
猜测:客户端无法解析服务端返回的内容,客户端希望返回的数据格式是 JSON 格式,但我们实际返回的是 text/html格式,所以使用@Requestmapping注解的 produces 属性,设置返回数据的类型以及编码形式
可以有如下写法:
@RequestMapping(value="/xxx",produces = {"application/json;charset=UTF-8"})
或
@RequestMapping(value="/xxx",produces = {"application/xml;charset=UTF-8"})
问题解决:重新创建项目,问题原因是依赖版本不匹配,更换依赖后解决
404 路径错误,500 代码功能错误
后台退出功能开发
需求分析
员工登录成功后,页面跳转到后台系统首页面(backend/index.html),此时会显示当前登录用户的姓名
如果员工需要退出系统,直接点击右侧的退出按钮就可以退出系统,退出系统后页面应跳转回登录页面
代码开发功能流程
1.用户点击页面--退出 logout,发送请求,请求地址为/employee/logout,请求方式为 POST
2.任务内容:
(1)清理 session 中的 ID
(2)返回结果
@PostMapping(value = "/logout")
public R<String> logout(HttpServletRequest request){
request.removeAttribute("employee");
return R.success("退出成功");
}
完善登录功能
问题分析
前面完成的后台系统的员工登录功能开发,但是还存在问题:用户如果不登录而是知己访问系统首页面,照样可以正常访问,这种设计显然不合理,我们希望设计:只有登录成功才能访问到系统中的页面,如果没有登录则跳转到登录页面
采用过滤器或者拦截器来实现,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面
实现步骤:
1.创建自定义过滤器 LoginCheckFilter
2.在启动类上加入注解@ServletComponentScan
3.完善过滤器的处理逻辑
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
log.info("拦截到的请求:{}",request.getRequestURI());
filterChain.doFilter(request,response);
}
同时需要在启动类添加注解@ServletComponentScan
URI&&URL
URI:统一资源标识符
用来标识Web 上可访问的任意类型的资源(HTML,视频,音频,程序等)
URI 由三部分组成:
- 访问资源的命名机制:比如 com(公司)、gov(政府)、edu(教育组织)
- 存放资源的主机名(计算机的 IP 号)
- 标识资源自身的路径
URL:统一资源定位符
理解为 Internet 资源的地址,用来定义引用地址的字符串,用于定位一个资源的位置以及它所使用的协议
URL 由七部分组成:
- 所使用的协议(HTTP,FTP)
- 服务器的位置(IP)
- 服务器端口号(0~65535)
- 资源所在的路径(path)
- 参数(访问该资源时,携带的参数信息)
- 片段(发给 HTTP 服务器的数据)
- 登录信息(authority)
URI 是 URL 的父类,URL 是 URI 的子集
过滤器的处理逻辑
1.获取本次请求的 URI
2.判断本次请求是否需要处理
3.如果不需要处理,则直接放行
4.判断登录状态,如果已登录,则直接放行
5.如果未登录则返回未登录结果
过滤器代码实现
package com.heyu.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.heyu.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestURI = request.getRequestURI();
String[] urls = new String[]{
"/employee/login","/employee/logout",
"/backend/**","/front/**"
};
log.info("拦截到请求:{}",requestURI);
boolean check = check(urls,requestURI);
if(check){
log.info("本次请求{}不需要处理",requestURI);
filterChain.doFilter(request,response);
return;
}
if(request.getSession().getAttribute("employee")!=null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("用户未登录");
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
}
public boolean check(String[] urls, String requestURI){
for(String url: urls){
boolean match = PATH_MATCHER.match(url,requestURI);
if (match){
return true;
}
}
return false;
}
}
员工管理模块
需求分析
- 前端页面发送 Ajax 请求,将新增员工页面中输入的数据以 JSON 的形式提交到服务端
- 服务端 Controller 接收页面提交的数据并调用 Service 将数据保存
- Service 调用 Mapper 操作数据库,保存数据
新增员工代码
/**
* 新增员工
* @param employee
* @return
*/
@PostMapping()//因为请求就是 /employee 在类上已经写了,所以咱俩不用再写了
public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
//对新增的员工设置初始化密码123456,需要进行md5加密处理,后续员工可以直接修改密码
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
//获得当前登录用户的id
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setCreateUser(empId); //创建人的id,就是当前用户的id(在进行添加操作的id)
employee.setUpdateUser(empId);//最后的更新人是谁
//mybatis提供的新增方法
employeeService.save(employee);
return R.success("新增员工成功");
}
功能测试:登陆之后,点击添加,然后确认,然后去数据库看一下新增数据成功没,新增成功,那就表示代码可以执行; 注意:但是因为我们把username设置为唯一索引,所以下次再新增用户的时候,就会出现异常,这个异常是MySQL数据库抛出来的;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEabtJIY-1657719042133)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16.png)]
全局异常处理
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException e){
log.error(e.getMessage());
if (e.getMessage().contains("Duplicate entry")){
String[] split = e.getMessage().split(" ");
String msg = split[2]+"用户名已存在";
return R.error(msg);
}
return R.error("未知错误");
}
}
使用@ExceptionHandler(),括号内表示本方法所捕捉的异常类型
总结
- 根据产品原型明确业务需求
- 重点分析数据的流转过程和数据格式
- 通过 debug 断点调试跟踪程序执行过程
Day03
员工信息分页查询
代码开发
程序执行过程:
1. 页面发送 Ajax 请求,将分页查询参数(page,PageSize,name)提交到服务端
2. 服务端 Controller 接收页面提交的数据并调用 Service 查询数据
3. Service 调用 Mapper 操作数据库,查询分页数据
4. Controller 将查询到的分页数据,转为 JSON,响应给页面
5. 页面接收到分页数据并通过 ElementUI 的 Table 组件展示到页面上
配置 mybaits-plus 分页插件拦截器
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
controller-分页控制
/*
* @description:分页控制输出和查询
* @author: heyu
* @date: 2022.7.10
* @param: int page, int pageSize,String name
* @return: R.success(pageInfo)
**/
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
//此处之所以是返回 page 对象(mybatis-plus 的 page 对象),是因为前端需要这些分页数据(比如当前页,总页数)
//使用日志输出,判断一下前端传回来的分页数据有没有被我们接收到
log.info("page={},pageSize={},name={}",page,pageSize,name);
//构造分页器,即 page 对象
Page pageInfo = new Page(page,pageSize);
//构造条件构造器,即动态的封装前端传过来的过滤条件,加泛型
LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//根据条件查询,如果搜索框不为空,我们就同样执行搜索框中的限定条件
lambdaQueryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
//添加一个排序条件
lambdaQueryWrapper.orderByDesc(Employee::getUpdateTime);
//执行查询,mp已经封装好了
employeeService.page(pageInfo,lambdaQueryWrapper);
return R.success(pageInfo);
}
}
Day04
启用/禁用员工账号
需求分析
在员工管理列表界面,可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登陆系统,启用的用户才能登录
需要注意的是:只有管理员(admin用户)才可以对其他普通用户进行启用操作,禁用操作,所以普通用户登录系统后启用,禁用按钮不显示;
并且如果某个员工账号的状态为正常,则按钮显示为’‘禁用’,如果员工账号状态为已禁用,则按钮显示为“启用”。
普通员工登录系统后,启用,禁用按钮不显示;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v7hGktZx-1657719042134)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_18,color_FFFFFF,t_70,g_se,x_16.png)]
注意:这里修改状态码要反着来,因为正常的用户你只能把它设置为禁用;已经禁用的账号你只能把它设置为正常
根据 id 修改员工信息
@PutMapping
public R<String> update(HttpServletRequest request,@RequestBody Employee employee){
log.info(employee.toString());
Long empId = (Long)request.getSession().getAttribute("employee");
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(empId);
employeeService.updateById(employee);
return R.success("员工信息修改成功");
}
丢失问题
修改员工状态,前端显示修改成功,数据库字段却并没有发生变化,原因是因为后台的 SQL 语句使用的 id 和数据库字段的 ID 不同
原因是:mybatis-plus对id使用了雪花算法,所以存入数据库中的id是19为长度,但是前端的js只能保证数据的前16位的数据的精度,对我们id后面三位数据进行了四舍五入,所以就出现了精度丢失;就会出现前度传过来的id和数据里面的id不匹配,就没办法正确的修改到我们想要的数据;
问题解决
自定义消息转换器
既然js对long型的数据会进行精度丢失,那么我们就对数据进行转型,我们可以在服务端(Java端)给页面响应json格式的数据时进行处理,将long型的数据统一转换为string字符串;
代码实现步骤
- 提供对象转换器 JacksonObjectMapper,基于 Jackson 进行 Java 对象到 JSON 数据的转换
- 在配置类的 WebMvcConfig 中扩展 SpringMVC 的消息转换器,在此消息转换器中使用提供的对象转换器进行 Java 对象到 json数据的转换
自定义消息转换器
/*
* 对象映射器:基于 Jackson 将 Java 对象转为 JSON,或者将 JSON 转为 JSON 对象
* 将 JSON 解析为 Java 对象的过程成为----从 JSON 反序列化 Java 对象
* 从 Java 对象生成 JSON 的过程称为----序列化 Java 对象到 JSON
*/
public class JasksonObjectMapper extends ObjectMapper {
//将日期的格式从数组的形式转化为易读的 String 类型
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JasksonObjectMapper(){
super();
//接收到位置属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES,false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
在前面的webMvcConfig 配置类中扩展spring mvc 的消息转换器,在此消息转换器中使用spring提供的对象转换器进行Java对象到json数据的转换
/*
* @description:将自定义消息转换器配置到 MVC 框架中
* @author: heyu
* @date: 2022/7/11 15:05
* @Param: null
* @return:
**/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>>converters){
log.info("扩展消息转换器...");
//创建消息转换器对象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//设置消息转换器,底层使用 Jackson 将 Java 对象转为 JSON
//下面这行代码将我们在 common 包中自己设置的消息转换器加入到 MNC 框架的转换器集合中
messageConverter.setObjectMapper(new JasksonObjectMapper());
//转换器有先后顺序,我们将自己配置的转换器设置为第一优先级
converters.add(0,messageConverter);
}
编辑员工信息
在员工管理列表页面中点击编辑按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击保存按钮完成编辑操作
代码开发
- 点击编辑按钮,页面跳转到 add.html,并在 URL 中携带员工 ID
- 在 add.html页面获取 URL 中的参数「员工 ID」
- 发送 Ajax 请求,请求服务端,同时提交员工 ID
- 服务端接受请求,根据员工 ID 查询员工信息,将员工信息以 JSON 形式响应给页面
- 页面接受服务端响应的 JSON 数据,通过vue 的数据绑定进行员工信息回显
- 点击保存按钮,发送 Ajax 请求,将页面中的员工信息以 JSON 方式提交给服务端
- 服务端接受员工信息,并进行处理,完成后交给页面响应
- 页面接受到服务端响应信息后进行相应处理
菜品分类管理
Day04
公共字段自动填充
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tn0O2UOS-1657719042134)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16-7524746.png)]
代码实现
- 在实体类的属性上加入@TableField注解,指定自动填充的策略
- 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现 MetaObjecthandler接口
在实体类中添加@TableField注解
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
编写 MetaObjectHandler类,实现 MetaObjectHandler 接口,从而接手这些公共字段
/*
*@description:自定义元数据对象处理器
*@createTime:2022/7/11 15:44
*@author:heyu
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject){
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("createUser",BaseContext.getCurrentId());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
@Override
public void updateFill(MetaObject metaObject){
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("updateUser", BaseContext.getCurrentId());
}
}
这里有一个方法调用,为 BaseContext.getCurrentId(),该调用是为了满足动态获取用户 ID 的需求,为了实现这一需求,编写工具类 BaseContext,该工具类使用了 ThreadLocal
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h9yIB8yI-1657719042134)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16-20220711164756666.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JnHHRzyu-1657719042134)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16-20220711164801653.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vunpGq3A-1657719042135)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16-20220711164817836.png)]
然后为了动态的获取员工的id,这里我们使用了threadLocal这个局部变量来获取和存储员工id;
创建一个工具类来设置和获取threadLocal中的员工id, 注意:要先把数据设置进threadLocal中,才能获取到
package com.heyu.reggie.utils;
public class BaseContext {
private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id){
threadLocal.set(id);
}
public static Long getCurrentId(){
return threadLocal.get();
}
}
同时在前面的过滤器中也进行配置—LoginCheckFilter
if(request.getSession().getAttribute("employee") != null){
Long emId = (Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(emId);
filterChain.doFilter(request,response);
return;
}
新增分类(菜品和套餐)
需求分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zsz0v1Yh-1657719042135)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16-20220711170333596.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWeqgGQe-1657719042135)(单体项目-瑞吉外卖.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyq5p2l5b6I6ZW_77yM5Yir5Y-q55yL55y85YmN,size_20,color_FFFFFF,t_70,g_se,x_16-20220711170341342.png)]
数据模型
本模块需要用到的类和接口基本结构如下
1. 实体类 Category
2. Mapper接口 CategoryMapper
3. 业务层接口 CategoryService
4. 业务层实现类 CategoryServiceImpl
5. 控制层 CategoryController
创建实体类 Category
package com.heyu.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 分类
*/
@Data
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//类型 1 菜品分类 2 套餐分类
private Integer type;
//分类名称
private String name;
//顺序
private Integer sort;
//创建时间
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//更新时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
//创建人
@TableField(fill = FieldFill.INSERT)
private Long createUser;
//修改人
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
//是否删除
private Integer isDeleted;
}
Day05
新增分类-菜品/套餐
代码开发
创建 CategoryController
首先创建添加菜品 API
@Slf4j
@RestController
@RequestMapping("/category")
public class CategoryController {
@Autowired
CategoryService categoryService;
@PostMapping
public R<String> save(@RequestBody Category category){
log.info("category:{}",category);
categoryService.save(category);
return R.success("新增分类成功");
}
}
进行测试,我们选择
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RehWwftU-1657719042136)(单体项目-瑞吉外卖.assets/image-20220712092510889.png)]
川菜在数据库中已经存在,所以显示为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5pkj48Vb-1657719042136)(单体项目-瑞吉外卖.assets/image-20220712092601713.png)]
这个已存在的错误提示,来自于全局异常处理 GlobalExceptionHandler,因为控制台输入了以下错误
2022-07-12 09:25:54.287 ERROR 3117 --- [nio-8090-exec-1] c.h.r.common.GlobalExceptionHandler : Duplicate entry '川菜' for key 'category.idx_category_name'
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException e){
log.error(e.getMessage());
if (e.getMessage().contains("Duplicate entry")){
String[] split = e.getMessage().split(" ");
String msg = split[2]+"已存在";
return R.error(msg);
}
return R.error("未知错误");
}
}
分类信息分页查询
需求分析
系统重的分类很多的时候,如果在一个页面中全部显示出来会比较乱,采用分页展示列表数据
代码开发
- 页面发送 Ajax 请求,将分页查询参数(page,PageSize,name)提交到服务端
- 服务端 Controller 接收页面提交的数据并调用 Service 查询数据
- Service 调用 Mapper 操作数据库,查询分页数据
- Controller 将查询到的分页数据,转为 JSON,响应给页面
- 页面接收到分页数据并通过 ElementUI 的 Table 组件展示到页面上
@GetMapping("/page")
public R<Page> page(int page, int pageSize){
Page<Category> pageInfo = new Page<>(page,pageSize);
LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByAsc(Category::getSort);
categoryService.page(pageInfo,wrapper);
return R.success(pageInfo);
}
}
删除分类
需求分析
在分类管理列表中,可以对某个分类进行删除,需要注意的是当分类关联了菜品或者套餐时,此分类不允许被删除
代码开发
- 页面发送 Ajax 请求,将参数 id 提交到服务端
- 服务端 Controller 接收页面提交的数据并调用 Service 删除数据
- Service 调用 Mapper 操作数据库
创建实体类、Mapper、Service、ServiceImpl和对应的 Controller
Dish
package com.heyu.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class Dish implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Long categoryId;
private BigDecimal price;
private String code;
private String image;
private String description;
private Integer status;
private Integer sort;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
private Integer isDeleted;
}
SetMeal
package com.heyu.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class SetMeal implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long categoryId;
private String name;
private BigDecimal price;
private Integer status;
private String code;
private String description;
private String image;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
private Integer isDeleted;
}
DishMapper
package com.heyu.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fasterxml.jackson.databind.ser.Serializers;
import com.heyu.reggie.entity.Category;
import com.heyu.reggie.entity.Dish;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DishMapper extends BaseMapper<Dish> {
}
SetMealMapper
package com.heyu.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heyu.reggie.entity.SetMeal;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SetMealMapper extends BaseMapper<SetMeal> {
}
DishService
package com.heyu.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.heyu.reggie.entity.Dish;
public interface DishService extends IService<Dish> {
}
SetMealService
package com.heyu.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.heyu.reggie.entity.SetMeal;
public interface SetMealService extends IService<SetMeal> {
}
DishServiceImpl
package com.heyu.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heyu.reggie.entity.Dish;
import com.heyu.reggie.mapper.DishMapper;
import com.heyu.reggie.service.DishService;
import org.springframework.stereotype.Service;
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
}
SetMealServiceImpl
package com.heyu.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heyu.reggie.entity.SetMeal;
import com.heyu.reggie.mapper.SetMealMapper;
import com.heyu.reggie.service.SetMealService;
import org.springframework.stereotype.Service;
@Service
public class SetMealServiceImpl extends ServiceImpl<SetMealMapper, SetMeal> implements SetMealService {
}
在 CategoryServiceImpl 中编写实现逻辑
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
@Autowired
DishService dishService;
@Autowired
SetMealService setMealService;
@Override
public void remove(Long id){
LambdaQueryWrapper<Dish> dishQueryWrapper = new LambdaQueryWrapper<>();
dishQueryWrapper.eq(Dish::getCategoryId,id);
int count_Dish = dishService.count(dishQueryWrapper);
if (count_Dish>0){
throw new CustomException("当前分类下关联了菜品,不能删除");
}
LambdaQueryWrapper<SetMeal> setMealLambdaQueryWrapper = new LambdaQueryWrapper<>();
setMealLambdaQueryWrapper.eq(SetMeal::getCategoryId,id);
int count_SetMeal = setMealService.count(setMealLambdaQueryWrapper);
if (count_SetMeal>0){
throw new CustomException("当前分类下关联了套餐,不能删除");
}
super.removeById(id);
}
}
同时需要处理异常信息,抛出这种异常,先自定义异常 CustomException
package com.heyu.reggie.common;
public class CustomException extends RuntimeException{
public CustomException(String message){
super(message);
}
}
将其纳入全局异常处理器管理异常
@ExceptionHandler({CustomException.class})
public R<String> exceptionHandler(CustomException customException){
log.error(customException.getMessage());//将报错信息打印到日志
//这里拿到的 message 是业务类抛出的异常,我们把它显示到前端
return R.error(customException.getMessage());
}
文件上传和下载
文件上传
文件上传对页面的 form 表单有要求为:
method = “post” 采用 post 方式提交数据
enctype = “multipart/form-data 采用 multipart 格式上传文件
type = “file” 使用 input 的 file控件上传
<form method ="post" action="/common/upload"enctype="multipart/form-data">
<input name="myFile" type="file"/>
<input type="submit" value="提交"/>
</form>
服务端需要使用 Apache 的两个组件
common-fileupload
commons-io
Spring框架在 Spring-web 包中对文件上传进行了封装,大大简化了服务端代码,我们只需要在 Controller 的方法中声明一个 MulitpartFile 类型的参数即可接收上传的文件
文件下载
下载完成的两种表现:
以附件形式下载,弹出保存对话框,将文件保存到指定目录
直接在浏览器打开
新增菜品
需求分析
后台系统重可以管理菜品信息,通过新增功能来添加一个新的菜品,在添加菜品时需要选择当前菜品所属的菜品分裂,并且需要上传菜品图片,在移动端会按照菜品分类来展示对应的菜品信息
数据模型
新增菜品,其实就是将新增页面录入的菜品信息插入到 dish 表,如果添加了口味作法,还需要向 dish_flavor表插入数据,新增菜品这一功能涉及到两个表:
dish————————————-dish_flavor
代码开发
实体类 DishFlavor
package com.heyu.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
菜品口味
*/
@Data
public class DishFlavor implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//菜品id
private Long dishId;
//口味名称
private String name;
//口味数据list
private String value;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
//是否删除
private Integer isDeleted;
}
Mapper接口 DishFlavorMapper
@Mapper
public interface DishFlavorMapper extends BaseMapper<DishFlavor> {
}
业务层接口 DishFlavorService
public interface DishFlavorService extends IService<DishFlavor> {
}
业务层实现类 DishFlavorServiceImpl
@Service
public class DishFlavorServiceImpl extends ServiceImpl<DishFlavorMapper, DishFlavor> implements DishFlavorService {
}
控制层 DishController
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {
@Autowired
DishFlavorService dishFlavorService;
@Autowired
DishService dishService;
@PostMapping
public R<String> save(@RequestBody DishDto dishDto){
dishService.saveWithFlavor(dishDto);
return R.success("新增菜品成功");
}
}
DishServiceImpl
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
@Autowired
DishFlavorService dishFlavorService;
@Override
@Transactional
public void saveWithFlavor(DishDto dishDto){
//保存菜品的基本信息到菜品表 dish
this.save(dishDto);//只保存基本信息到dish 表
//需要获得菜品的 ID,这个 ID 在之前就已经获得了
Long dishId = dishDto.getId();
//菜品口味处理
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map((item)->{
item.setDishId(dishId);
return item;
}).collect(Collectors.toList());//重新转回为 list 对象
//保存菜品口味数据到菜品口味表 dish_flavor,因为口味有多条,采用批处理的方式
dishFlavorService.saveBatch(dishDto.getFlavors());
}
}
Day06
菜品信息分页查询
@GetMapping("/page")
public R<Page> page(int page ,int pageSize,String name){
//分页构造器对象
Page<Dish> pageInfo = new Page<>(page,pageSize);
Page<DishDto> dishDtoPage = new Page<>();
//条件构造器
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
//添加过滤条件,根据name进行查询
queryWrapper.like(name!=null,Dish::getName,name);
//添加排序条件
queryWrapper.orderByDesc(Dish::getUpdateTime);
dishService.page(pageInfo,queryWrapper);
//对象拷贝,records属性不拷贝,单独拿出 record的 list 集合
BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");
List<Dish> records = pageInfo.getRecords();
List<DishDto> list = records.stream().map((item) -> {
DishDto dishDto = new DishDto();
//对象拷贝,从 item 到 dishDto
BeanUtils.copyProperties(item, dishDto);
//拿到每个菜品的分类 id
Long categoryId = item.getCategoryId();
//根据 id 查询分类对象
Category category = categoryService.getById(categoryId);
if (category!=null){
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
}
return dishDto;
}).collect(Collectors.toList());
dishDtoPage.setRecords(list);
return R.success(dishDtoPage);
}
修改菜品
修改菜品的 Controller 页面
@PutMapping
public R<String> update(@RequestBody DishDto dishDto){
dishService.updateWithFlavor(dishDto);
return R.success("菜品更新成功");
}
在 DishService 接口中 编写方法 updateWithFlavor,这一方法用于更新菜品信息,同时更新对应的口味
void updateWithFlavor(DishDto dishDto);
在对应实现类中实现该方法
@Override
@Transactional
public void updateWithFlavor(DishDto dishDto){
//更新 dish表和flavor 表
this.updateById(dishDto);
//先清理当前菜品对应的口味数据------dish_flavor表执行 delete操作
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
dishFlavorService.remove(queryWrapper);
//添加当前提交过来的口味数据-------dish_flavor表的 insert 操作
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map((item)->{
item.setDishId(dishDto.getId());
return item;
}).collect(Collectors.toList());
dishFlavorService.saveBatch(flavors);
}
新增套餐
需求分析
通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照 套餐分类来展示对应的套餐
数据模型
将新增页面录入的套餐信息插入到 setmeal表,还需要向 setmeal_dish表插入套餐和菜品关联数据
主要涉及两个表 setmeal ————套餐表 setmeal_dish———————-套餐菜品关系表
代码开发
实体类 SetmealDish
@Data
public class SetmealDish implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long setmealId;
private Long dishId;
private String name;
private BigDecimal price;
private Integer copies;
private Integer sort;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
private Integer isDeleted;
}
DTO SetmealDto
@Data
public class SetmealDto extends Setmeal {
private List<SetmealDish> setmealDishes;
private String categoryName;
}
Mapper setmealMapper
@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}
Service setmealService
public interface SetmealService extends IService<Setmeal> {
void saveWithDish(SetmealDto setMealDto);
}
ServiceImpl setmealServiceImpl
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
@Autowired
SetmealDishService setMealDishService;
@Override
@Transactional
public void saveWithDish(SetmealDto setMealDto){
this.save(setMealDto);
List<SetmealDish> setmealDishes = setMealDto.getSetmealDishes();
setmealDishes.stream().map((item)->{
item.setSetmealId(setMealDto.getId());
return item;
}).collect(Collectors.toList());
setMealDishService.saveBatch(setmealDishes);
}
}
控制层 SetmealController
@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {
@Autowired
SetmealDishService setMealDishService;
@Autowired
SetmealService setMealService;
@PostMapping
public R<String> save(@RequestBody SetmealDto setMealDto){
log.info("测试:{}",setMealDto);
setMealService.saveWithDish(setMealDto);
return R.success("新增套餐成功");
}
}
套餐信息分页查询
和前面的分页方法是相同的
代码开发
- 页面(backend/page/combo/list.html)发送 Ajax 请求,将分页查询参数(page,pageSize,name)提交到服务端,获取分页数据
- 页面发送请求,请求服务端进行图片下载,用于页面图片展示
分页查询直接通过 Controller 实现
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
Page<Setmeal> pageInfo = new Page<>(page,pageSize);
Page<SetmealDto> dtoPage = new Page<>();
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(name!=null,Setmeal::getName,name);
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
setMealService.page(pageInfo,queryWrapper);
BeanUtils.copyProperties(pageInfo,dtoPage,"records");
List<Setmeal> records = pageInfo.getRecords();
List<SetmealDto> list=records.stream().map((item)->{
SetmealDto setmealDto = new SetmealDto();
BeanUtils.copyProperties(item,setmealDto);
Long categoryId = item.getCategoryId();
Category category = categoryService.getById(categoryId);
if (category!=null){
String categoryName = category.getName();
setmealDto.setCategoryName(categoryName);
}
return setmealDto;
}).collect(Collectors.toList());
dtoPage.setRecords(list);
return R.success(dtoPage);
}
删除套餐
setmealService方法
void deleteWithDish(List<Long> ids);
setmealServiceImpl
@Override
public void deleteWithDish(List<Long> ids){
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(Setmeal::getId,ids);
queryWrapper.eq(Setmeal::getStatus,1);
int count = this.count(queryWrapper);
if(count>0){
throw new CustomException("套餐正在售卖中,不能删除");
}
this.removeByIds(ids);
LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
wrapper.in(SetmealDish::getSetmealId,ids);
setMealDishService.remove(wrapper);
}
controller
@DeleteMapping
public R<String> delete(@RequestParam List<Long> ids){
setMealService.deleteWithDish(ids);
return R.success("套餐删除成功");
}
|