项目-瑞吉外卖

基本要求

1.介绍

开发流程

角色分工

软件环境

开发环境,测试环境,生产环境

2.项目介绍






3.开发环境搭建

1.数据库环境搭建

创建数据库

导入表结构,运行外部SQL文件

/*
Navicat MySQL Data TransferSource Server         : localhost
Source Server Version : 50728
Source Host           : localhost:3306
Source Database       : reggieTarget Server Type    : MYSQL
Target Server Version : 50728
File Encoding         : 65001Date: 2021-07-23 10:41:41
*/SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for address_book
-- ----------------------------
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='地址管理';-- ----------------------------
-- Records of address_book
-- ----------------------------
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');-- ----------------------------
-- Table structure for category
-- ----------------------------
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='菜品及套餐分类';-- ----------------------------
-- Records of category
-- ----------------------------
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');-- ----------------------------
-- Table structure for dish
-- ----------------------------
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='菜品管理';-- ----------------------------
-- Records of dish
-- ----------------------------
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');-- ----------------------------
-- Table structure for dish_flavor
-- ----------------------------
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='菜品口味关系表';-- ----------------------------
-- Records of dish_flavor
-- ----------------------------
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');-- ----------------------------
-- Table structure for employee
-- ----------------------------
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='员工信息';-- ----------------------------
-- Records of employee
-- ----------------------------
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');-- ----------------------------
-- Table structure for orders
-- ----------------------------
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='订单表';-- ----------------------------
-- Records of orders
-- ------------------------------ ----------------------------
-- Table structure for order_detail
-- ----------------------------
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='订单明细表';-- ----------------------------
-- Records of order_detail
-- ------------------------------ ----------------------------
-- Table structure for setmeal
-- ----------------------------
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='套餐';-- ----------------------------
-- Records of setmeal
-- ----------------------------
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');-- ----------------------------
-- Table structure for setmeal_dish
-- ----------------------------
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='套餐菜品关系';-- ----------------------------
-- Records of setmeal_dish
-- ----------------------------
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');-- ----------------------------
-- Table structure for shopping_cart
-- ----------------------------
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='购物车';-- ----------------------------
-- Records of shopping_cart
-- ------------------------------ ----------------------------
-- Table structure for user
-- ----------------------------
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='用户信息';

2.maven项目搭建

创建Maven项目,并确认Maven创库配置和jdk配置

导入poml文件

创建application.yml文件

创建Springboot的程序入口

运行Springboot

3.导入前端文件

4.后台登陆功能开发

需求分析

查看登陆请求信息:点击登录会发送登录请求:http://localhost:8080/backend/page/login/login.html

代码开发

User.java

/*** 用户信息*/
@Data
public class User implements Serializable {private static final long serialVersionUID = 1L;private Long id;//姓名private String name;//手机号private String phone;//性别 0 女 1 男private String sex;//身份证号private String idNumber;//头像private String avatar;//状态 0:禁用,1:正常private Integer status;
}

UserMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User>{
}

UserService.java

import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.entity.User;public interface UserService extends IService<User> {
}

通用返回结果 R.java

*** 通用返回结果,服务端响应的数据最终都会封装成此对象* @param <T>*/
@Data
public class R<T> {private Integer code; //编码:1成功,0和其它数字为失败private String msg; //错误信息private T data; //数据private Map map = new HashMap(); //动态数据public static <T> R<T> success(T object) {R<T> r = new R<T>();r.data = object;r.code = 1;return r;}public static <T> R<T> error(String msg) {R r = new R();r.msg = msg;r.code = 0;return r;}public R<T> add(String key, Object value) {this.map.put(key, value);return this;}}

UserController.java

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;/*** 发送手机短信验证码* @param user* @return*/@PostMapping("/sendMsg")public R<String> sendMsg(@RequestBody User user, HttpSession session){//获取手机号String phone = user.getPhone();if(StringUtils.isNotEmpty(phone)){//生成随机的4位验证码String code = ValidateCodeUtils.generateValidateCode(4).toString();log.info("code={}",code);//调用阿里云提供的短信服务API完成发送短信//SMSUtils.sendMessage("瑞吉外卖","",phone,code);//需要将生成的验证码保存到Sessionsession.setAttribute(phone,code);return R.success("手机验证码短信发送成功");}return R.error("短信发送失败");}/*** 移动端用户登录* @param map* @param session* @return*/@PostMapping("/login")public R<User> login(@RequestBody Map map, HttpSession session){log.info(map.toString());//获取手机号String phone = map.get("phone").toString();//获取验证码String code = map.get("code").toString();//从Session中获取保存的验证码Object codeInSession = session.getAttribute(phone);//进行验证码的比对(页面提交的验证码和Session中保存的验证码比对)if(codeInSession != null && codeInSession.equals(code)){//如果能够比对成功,说明登录成功LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getPhone,phone);User user = userService.getOne(queryWrapper);if(user == null){//判断当前手机号对应的用户是否为新用户,如果是新用户就自动完成注册user = new User();user.setPhone(phone);user.setStatus(1);userService.save(user);}session.setAttribute("user",user.getId());return R.success(user);}return R.error("登录失败");}}

前端login.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no,minimal-ui"><title>菩提阁</title><link rel="icon" href="./../images/favico.ico"><!--不同屏幕尺寸根字体设置--><script src="./../js/base.js"></script><!--element-ui的样式--><link rel="stylesheet" href="../../backend/plugins/element-ui/index.css" /><!--引入vant样式--><link rel="stylesheet" href="../styles/vant.min.css"/><!-- 引入样式  --><link rel="stylesheet" href="../styles/index.css" /><!--本页面内容的样式--><link rel="stylesheet" href="./../styles/login.css" /></head><body><div id="login" v-loading="loading"><div class="divHead">登录</div><div class="divContainer"><el-input placeholder=" 请输入手机号码" v-model="form.phone"  maxlength='20'/></el-input><div class="divSplit"></div><el-input placeholder=" 请输入验证码" v-model="form.code"  maxlength='20'/></el-input><span @click='getCode'>获取验证码</span></div><div class="divMsg" v-if="msgFlag">手机号输入不正确,请重新输入</div><el-button type="primary" :class="{btnSubmit:1===1,btnNoPhone:!form.phone,btnPhone:form.phone}" @click="btnLogin">登录</el-button></div><!-- 开发环境版本,包含了有帮助的命令行警告 --><script src="../../backend/plugins/vue/vue.js"></script><!-- 引入组件库 --><script src="../../backend/plugins/element-ui/index.js"></script><!-- 引入vant样式 --><script src="./../js/vant.min.js"></script>  <!-- 引入axios --><script src="../../backend/plugins/axios/axios.min.js"></script><script src="./../js/request.js"></script><script src="./../api/login.js"></script></body><script>new Vue({el:"#login",data(){return {form:{phone:'',code:''},msgFlag:false,loading:false}},computed:{},created(){},mounted(){},methods:{getCode(){this.form.code = ''const regex = /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/;if (regex.test(this.form.phone)) {this.msgFlag = false//this.form.code = (Math.random()*1000000).toFixed(0)sendMsgApi({phone:this.form.phone})}else{this.msgFlag = true}},async btnLogin(){if(this.form.phone && this.form.code){this.loading = trueconst res = await loginApi(this.form)this.loading = falseif(res.code === 1){sessionStorage.setItem("userPhone",this.form.phone)window.requestAnimationFrame(()=>{window.location.href= '/front/index.html'})                           }else{this.$notify({ type:'warning', message:res.msg});}}else{this.$notify({ type:'warning', message:'请输入手机号码'});}}}})</script>
</html>

login.js

function loginApi(data) {return $axios({'url': '/user/login','method': 'post',data})
}function sendMsgApi(data) {return $axios({'url': '/user/sendMsg','method': 'post',data})
}function loginoutApi() {return $axios({'url': '/user/loginout','method': 'post',})
}

后端login.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>瑞吉外卖管理端</title><link rel="shortcut icon" href="../../favicon.ico"><!-- 引入样式 --><link rel="stylesheet" href="../../plugins/element-ui/index.css" /><link rel="stylesheet" href="../../styles/common.css"><link rel="stylesheet" href="../../styles/login.css"><link rel="stylesheet" href="../../styles/icon/iconfont.css" /><style>.body{min-width: 1366px;}</style>
</head> <body><div class="login" id="login-app"><div class="login-box"><img src="../../images/login/login-l.png" alt=""><div class="login-form"><el-form ref="loginForm" :model="loginForm" :rules="loginRules" ><div class="login-form-title"><img src="../../images/login/logo.png" style="width:139px;height:42px;" alt="" /></div><el-form-item prop="username"><el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号" maxlength="20"prefix-icon="iconfont icon-user" /></el-form-item><el-form-item prop="password"><el-input v-model="loginForm.password" type="password" placeholder="密码" prefix-icon="iconfont icon-lock" maxlength="20"@keyup.enter.native="handleLogin" /></el-form-item><el-form-item style="width:100%;"><el-button :loading="loading" class="login-btn" size="medium" type="primary" style="width:100%;"@click.native.prevent="handleLogin"><span v-if="!loading">登录</span><span v-else>登录中...</span></el-button></el-form-item></el-form></div></div></div><!-- 开发环境版本,包含了有帮助的命令行警告 --><script src="../../plugins/vue/vue.js"></script><!-- 引入组件库 --><script src="../../plugins/element-ui/index.js"></script><!-- 引入axios --><script src="../../plugins/axios/axios.min.js"></script><script src="../../js/request.js"></script><script src="../../js/validate.js"></script><script src="../../api/login.js"></script><script>new Vue({el: '#login-app',data() {return {loginForm:{username: 'admin',password: '123456'},loading: false}},computed: {loginRules() {const validateUsername = (rule, value, callback) => {if (value.length < 1 ) {callback(new Error('请输入用户名'))} else {callback()}}const validatePassword = (rule, value, callback) => {if (value.length < 6) {callback(new Error('密码必须在6位以上'))} else {callback()}}return {'username': [{ 'validator': validateUsername, 'trigger': 'blur' }],'password': [{ 'validator': validatePassword, 'trigger': 'blur' }]}}},created() {},methods: {async handleLogin() {this.$refs.loginForm.validate(async (valid) => {if (valid) {this.loading = truelet res = await loginApi(this.loginForm)if (String(res.code) === '1') {//1表示登录成功localStorage.setItem('userInfo',JSON.stringify(res.data))window.location.href= '/backend/index.html'} else {this.$message.error(res.msg)this.loading = false}}})}}})</script>
</body></html>

5.后台退出功能开发

需求分析

代码开发

backend/index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>瑞吉外卖管理端</title><link rel="shortcut icon" href="favicon.ico"><!-- 引入样式 --><link rel="stylesheet" href="plugins/element-ui/index.css" /><link rel="stylesheet" href="styles/common.css" /><link rel="stylesheet" href="styles/index.css" /><link rel="stylesheet" href="styles/icon/iconfont.css" /><style>.body{min-width: 1366px;}.app-main{height: calc(100% - 64px);}.app-main .divTmp{width: 100%;height: 100%;}</style></head><body><div class="app" id="app"><div class="app-wrapper openSidebar clearfix"><!-- sidebar --><div class="sidebar-container"><div class="logo"><!-- <img src="data:images/logo.png" width="122.5" alt="" /> --><img src="images/login/login-logo.png" alt="" style="width: 117px; height: 32px" /></div><el-scrollbar wrap-class="scrollbar-wrapper"><el-menu:default-active="defAct":unique-opened="false":collapse-transition="false"background-color="#343744"text-color="#bfcbd9"active-text-color="#f4f4f5"><div v-for="item in menuList" :key="item.id"><el-submenu :index="item.id" v-if="item.children && item.children.length>0"><template slot="title"><i class="iconfont" :class="item.icon"></i><span>{{item.name}}</span></template><el-menu-itemv-for="sub in item.children":index="sub.id":key="sub.id"@click="menuHandle(sub,false)"><i :class="iconfont" :class="sub.icon"></i><span slot="title">{{sub.name}}</span></el-menu-item></el-submenu><el-menu-item v-else :index="item.id" @click="menuHandle(item,false)"><i class="iconfont" :class="item.icon"></i><span slot="title">{{item.name}}</span></el-menu-item></div></el-menu></el-scrollbar></div><div class="main-container"><!-- <navbar /> --><div class="navbar"><div class="head-lable"><span v-if="goBackFlag" class="goBack" @click="goBack()"><img src="images/icons/btn_back@2x.png" alt="" /> 返回</span><span>{{headTitle}}</span></div><div class="right-menu"><div class="avatar-wrapper">{{ userInfo.name }}</div><!-- <div class="logout" @click="logout">退出</div> --><img src="images/icons/btn_close@2x.png" class="outLogin" alt="退出" @click="logout" /></div></div><div class="app-main" v-loading="loading"><div class="divTmp" v-show="loading"></div><iframeid="cIframe"class="c_iframe"name="cIframe":src="iframeUrl"width="100%"height="auto"frameborder="0"v-show="!loading"></iframe></div></div></div></div><!-- 开发环境版本,包含了有帮助的命令行警告 --><script src="plugins/vue/vue.js"></script><!-- 引入组件库 --><script src="plugins/element-ui/index.js"></script><!-- 引入axios --><script src="plugins/axios/axios.min.js"></script><script src="js/request.js"></script><script src="./api/login.js"></script><script>new Vue({el: '#app',data() {return {defAct: '2',menuActived: '2',userInfo: {},menuList: [// {//   id: '1',//   name: '门店管理',//   children: [{id: '2',name: '员工管理',url: 'page/member/list.html',icon: 'icon-member'},{id: '3',name: '分类管理',url: 'page/category/list.html',icon: 'icon-category'},{id: '4',name: '菜品管理',url: 'page/food/list.html',icon: 'icon-food'},{id: '5',name: '套餐管理',url: 'page/combo/list.html',icon: 'icon-combo'},{id: '6',name: '订单明细',url: 'page/order/list.html',icon: 'icon-order'}//   ],// },],iframeUrl: 'page/member/list.html',headTitle: '员工管理',goBackFlag: false,loading: true,timer: null}},computed: {},created() {const userInfo = window.localStorage.getItem('userInfo')if (userInfo) {this.userInfo = JSON.parse(userInfo)}this.closeLoading()},beforeDestroy() {this.timer = nullclearTimeout(this.timer)},mounted() {window.menuHandle = this.menuHandle},methods: {logout() {logoutApi().then((res)=>{if(res.code === 1){localStorage.removeItem('userInfo')window.location.href = '/backend/page/login/login.html'}})},goBack() {// window.location.href = 'javascript:history.go(-1)'const menu = this.menuList.find(item=>item.id===this.menuActived)// this.goBackFlag = false// this.headTitle = menu.namethis.menuHandle(menu,false)},menuHandle(item, goBackFlag) {this.loading = truethis.menuActived = item.idthis.iframeUrl = item.urlthis.headTitle = item.namethis.goBackFlag = goBackFlagthis.closeLoading()},closeLoading(){this.timer = nullthis.timer = setTimeout(()=>{this.loading = false},1000)}}})</script></body>
</html>


关于removeItem(‘userInfo’)的细节


6.员工管理系统开发

效果图

功能开发

1.完善登录功能

问题分析

代码实现

LoginCheckFilter.java

package com.itheima.reggie.filter;import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.BaseContext;
import com.itheima.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;/*** 检查用户是否已经完成登录*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter{//路径匹配器,支持通配符public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//1、获取本次请求的URIString requestURI = request.getRequestURI();// /backend/index.htmllog.info("拦截到请求:{}",requestURI);//定义不需要处理的请求路径String[] urls = new String[]{"/employee/login","/employee/logout","/backend/**","/front/**","/common/**","/user/sendMsg","/user/login"};//2、判断本次请求是否需要处理boolean check = check(urls, requestURI);//3、如果不需要处理,则直接放行if(check){log.info("本次请求{}不需要处理",requestURI);filterChain.doFilter(request,response);return;}//4-1、判断登录状态,如果已登录,则直接放行if(request.getSession().getAttribute("employee") != null){log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));Long empId = (Long) request.getSession().getAttribute("employee");BaseContext.setCurrentId(empId);filterChain.doFilter(request,response);return;}//4-2、判断登录状态,如果已登录,则直接放行if(request.getSession().getAttribute("user") != null){log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));Long userId = (Long) request.getSession().getAttribute("user");BaseContext.setCurrentId(userId);filterChain.doFilter(request,response);return;}log.info("用户未登录");//5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));return;}/*** 路径匹配,检查本次请求是否需要放行* @param urls* @param requestURI* @return*/public boolean check(String[] urls,String requestURI){for (String url : urls) {boolean match = PATH_MATCHER.match(url, requestURI);if(match){return true;}}return false;}
}

2.新增员工

需求分析


Employee.java
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 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;@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;}
EmployeeMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.Employee;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface EmployeeMapper extends BaseMapper<Employee>{
}
EmployeeServiceImpl.java
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.mapper.EmployeeMapper;
import com.itheima.reggie.service.EmployeeService;
import org.springframework.stereotype.Service;@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService{
}
EmployeeController.java
package com.itheima.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate EmployeeService employeeService;/*** 员工登录* @param request* @param employee* @return*/@PostMapping("/login")public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){//1、将页面提交的密码password进行md5加密处理String password = employee.getPassword();password = DigestUtils.md5DigestAsHex(password.getBytes());//2、根据页面提交的用户名username查询数据库LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Employee::getUsername,employee.getUsername());Employee emp = employeeService.getOne(queryWrapper);//3、如果没有查询到则返回登录失败结果if(emp == null){return R.error("登录失败");}//4、密码比对,如果不一致则返回登录失败结果if(!emp.getPassword().equals(password)){return R.error("登录失败");}//5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果if(emp.getStatus() == 0){return R.error("账号已禁用");}//6、登录成功,将员工id存入Session并返回登录成功结果request.getSession().setAttribute("employee",emp.getId());return R.success(emp);}/*** 员工退出* @param request* @return*/@PostMapping("/logout")public R<String> logout(HttpServletRequest request){//清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute("employee");return R.success("退出成功");}/*** 新增员工* @param employee* @return*/@PostMappingpublic R<String> save(HttpServletRequest request,@RequestBody Employee employee){log.info("新增员工,员工信息:{}",employee.toString());//设置初始密码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);//employee.setUpdateUser(empId);employeeService.save(employee);return R.success("新增员工成功");}
增加员工信息 add.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 引入样式 --><link rel="stylesheet" href="../../plugins/element-ui/index.css" /><link rel="stylesheet" href="../../styles/common.css" /><link rel="stylesheet" href="../../styles/page.css" />
</head>
<body><div class="addBrand-container" id="member-add-app"><div class="container"><el-formref="ruleForm":model="ruleForm":rules="rules":inline="false"label-width="180px"class="demo-ruleForm"><el-form-item label="账号:" prop="username"><el-input v-model="ruleForm.username" placeholder="请输入账号" maxlength="20"/></el-form-item><el-form-itemlabel="员工姓名:"prop="name"><el-inputv-model="ruleForm.name"placeholder="请输入员工姓名"maxlength="20"/></el-form-item><el-form-itemlabel="手机号:"prop="phone"><el-inputv-model="ruleForm.phone"placeholder="请输入手机号"maxlength="20"/></el-form-item><el-form-itemlabel="性别:"prop="sex"><el-radio-group v-model="ruleForm.sex"><el-radio label=""></el-radio><el-radio label=""></el-radio></el-radio-group></el-form-item><el-form-itemlabel="身份证号:"prop="idNumber"><el-inputv-model="ruleForm.idNumber"placeholder="请输入身份证号"maxlength="20"/></el-form-item><div class="subBox address"><el-form-item><el-button  @click="goBack()">取消</el-button><el-buttontype="primary"@click="submitForm('ruleForm', false)">保存</el-button><el-buttonv-if="actionType == 'add'"type="primary"class="continue"@click="submitForm('ruleForm', true)">保存并继续添加</el-button></el-form-item></div></el-form></div></div><!-- 开发环境版本,包含了有帮助的命令行警告 --><script src="../../plugins/vue/vue.js"></script><!-- 引入组件库 --><script src="../../plugins/element-ui/index.js"></script><!-- 引入axios --><script src="../../plugins/axios/axios.min.js"></script><script src="../../js/request.js"></script><script src="../../api/member.js"></script><script src="../../js/validate.js"></script><script src="../../js/index.js"></script><script>new Vue({el: '#member-add-app',data() {return {id: '',actionType : '',ruleForm : {'name': '','phone': '','sex': '男','idNumber': '',username: ''}}},computed: {rules () {return {//账号username: [{required: true, 'validator': checkUserName, trigger: 'blur'}],//姓名name: [{ required: true, 'validator': checkName, 'trigger': 'blur' }],'phone': [{ 'required': true, 'validator': checkPhone, 'trigger': 'blur' }],'idNumber': [{ 'required': true, 'validator': validID, 'trigger': 'blur' }]}}},created() {this.id = requestUrlParam('id')this.actionType = this.id ? 'edit' : 'add'if (this.id) {this.init()}},mounted() {},methods: {async init () {queryEmployeeById(this.id).then(res => {console.log(res)if (String(res.code) === '1') {console.log(res.data)this.ruleForm = res.datathis.ruleForm.sex = res.data.sex === '0' ? '女' : '男'// this.ruleForm.password = ''} else {this.$message.error(res.msg || '操作失败')}})},submitForm (formName, st) {this.$refs[formName].validate((valid) => {if (valid) {if (this.actionType === 'add') {const params = {...this.ruleForm,sex: this.ruleForm.sex === '女' ? '0' : '1'}addEmployee(params).then(res => {if (res.code === 1) {this.$message.success('员工添加成功!')if (!st) {this.goBack()} else {this.ruleForm = {username: '','name': '','phone': '',// 'password': '',// 'rePassword': '',/'sex': '男','idNumber': ''}}} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})} else {const params = {...this.ruleForm,sex: this.ruleForm.sex === '女' ? '0' : '1'}editEmployee(params).then(res => {if (res.code === 1) {this.$message.success('员工信息修改成功!')this.goBack()} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})}} else {console.log('error submit!!')return false}})},goBack(){window.parent.menuHandle({id: '2',url: '/backend/page/member/list.html',name: '员工管理'},false)}}})</script>
</body>
</html>

        methods: {async init () {queryEmployeeById(this.id).then(res => {console.log(res)if (String(res.code) === '1') {console.log(res.data)this.ruleForm = res.datathis.ruleForm.sex = res.data.sex === '0' ? '女' : '男'// this.ruleForm.password = ''} else {this.$message.error(res.msg || '操作失败')}})},submitForm (formName, st) {this.$refs[formName].validate((valid) => {if (valid) {if (this.actionType === 'add') {const params = {...this.ruleForm,sex: this.ruleForm.sex === '女' ? '0' : '1'}addEmployee(params).then(res => {if (res.code === 1) {this.$message.success('员工添加成功!')if (!st) {this.goBack()} else {this.ruleForm = {username: '','name': '','phone': '',// 'password': '',// 'rePassword': '',/'sex': '男','idNumber': ''}}} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})} else {const params = {...this.ruleForm,sex: this.ruleForm.sex === '女' ? '0' : '1'}editEmployee(params).then(res => {if (res.code === 1) {this.$message.success('员工信息修改成功!')this.goBack()} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})}} else {console.log('error submit!!')return false}})},goBack(){window.parent.menuHandle({id: '2',url: '/backend/page/member/list.html',name: '员工管理'},false)}}})

代码分析

总结

3.员工信息分页查询

需求分析

代码分析

EmployeeController.java
/*** 员工信息分页查询* @param page* @param pageSize* @param name* @return*/@GetMapping("/page")public R<Page> page(int page,int pageSize,String name){log.info("page = {},pageSize = {},name = {}" ,page,pageSize,name);//构造分页构造器Page pageInfo = new Page(page,pageSize);//构造条件构造器LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();//添加过滤条件queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);//添加排序条件queryWrapper.orderByDesc(Employee::getUpdateTime);//执行查询employeeService.page(pageInfo,queryWrapper);return R.success(pageInfo);}/*** 根据id修改员工信息* @param employee* @return*/@PutMappingpublic R<String> update(HttpServletRequest request,@RequestBody Employee employee){log.info(employee.toString());long id = Thread.currentThread().getId();log.info("线程id为:{}",id);//Long empId = (Long)request.getSession().getAttribute("employee");//employee.setUpdateTime(LocalDateTime.now());//employee.setUpdateUser(empId);employeeService.updateById(employee);return R.success("员工信息修改成功");}/*** 根据id查询员工信息* @param id* @return*/@GetMapping("/{id}")public R<Employee> getById(@PathVariable Long id){log.info("根据id查询员工信息...");Employee employee = employeeService.getById(id);if(employee != null){return R.success(employee);}return R.error("没有查询到对应员工信息");}
}


url地址是通过Ajax传输数据

前端全局request拦截器

 // request拦截器service.interceptors.request.use(config => {// 是否需要设置 token// const isToken = (config.headers || {}).isToken === false// if (getToken() && !isToken) {//   config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改// }// get请求映射params参数if (config.method === 'get' && config.params) {let url = config.url + '?';for (const propName of Object.keys(config.params)) {const value = config.params[propName];var part = encodeURIComponent(propName) + "=";if (value !== null && typeof(value) !== "undefined") {if (typeof value === 'object') {for (const key of Object.keys(value)) {let params = propName + '[' + key + ']';var subPart = encodeURIComponent(params) + "=";url += subPart + encodeURIComponent(value[key]) + "&";}} else {url += part + encodeURIComponent(value) + "&";}}}url = url.slice(0, -1);config.params = {};config.url = url;}return config}, error => {console.log(error)Promise.reject(error)})
member/list.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 引入样式 --><link rel="stylesheet" href="../../plugins/element-ui/index.css" /><link rel="stylesheet" href="../../styles/common.css" /><link rel="stylesheet" href="../../styles/page.css" /><style>#member-app  .notAdmin::after{border: 0 !important;}</style>
</head>
<body><div class="dashboard-container" id="member-app"><div class="container"><div class="tableBar"><el-inputv-model="input"placeholder="请输入员工姓名"style="width: 250px"clearable@keyup.enter.native="handleQuery"><islot="prefix"class="el-input__icon el-icon-search"style="cursor: pointer"@click="handleQuery"></i></el-input><el-buttontype="primary"@click="addMemberHandle('add')">+ 添加员工</el-button></div><el-table:data="tableData"stripeclass="tableBox"><el-table-columnprop="name"label="员工姓名"></el-table-column><el-table-columnprop="username"label="账号"></el-table-column><el-table-columnprop="phone"label="手机号"></el-table-column><el-table-column label="账号状态"><template slot-scope="scope">{{ String(scope.row.status) === '0' ? '已禁用' : '正常' }}</template></el-table-column><el-table-columnlabel="操作"width="160"align="center"><template slot-scope="scope"><el-buttontype="text"size="small"class="blueBug"@click="addMemberHandle(scope.row.id)":class="{notAdmin:user !== 'admin'}">编辑</el-button><el-buttontype="text"size="small"class="delBut non"@click="statusHandle(scope.row)"v-if="user === 'admin'">{{ scope.row.status == '1' ? '禁用' : '启用' }}</el-button></template></el-table-column></el-table><el-paginationclass="pageList":page-sizes="[2]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="counts":current-page.sync="page"@size-change="handleSizeChange"@current-change="handleCurrentChange"></el-pagination></div></div><!-- 开发环境版本,包含了有帮助的命令行警告 --><script src="../../plugins/vue/vue.js"></script><!-- 引入组件库 --><script src="../../plugins/element-ui/index.js"></script><!-- 引入axios --><script src="../../plugins/axios/axios.min.js"></script><script src="../../js/request.js"></script><script src="../../api/member.js"></script><script>new Vue({el: '#member-app',data() {return {input: '',counts: 0,page: 1,pageSize: 2,tableData : [],id : '',status : '',}},computed: {},created() {this.init()if(localStorage.getItem('userInfo') != null){//获取当前登录员工的账号,并赋值给模型数据userthis.user = JSON.parse(localStorage.getItem('userInfo')).username}},mounted() {},methods: {async init () {const params = {page: this.page,pageSize: this.pageSize,name: this.input ? this.input : undefined}await getMemberList(params).then(res => {if (String(res.code) === '1') {this.tableData = res.data.records || []this.counts = res.data.total}}).catch(err => {this.$message.error('请求出错了:' + err)})},handleQuery() {this.page = 1;this.init();},// 添加addMemberHandle (st) {if (st === 'add'){window.parent.menuHandle({id: '2',url: '/backend/page/member/add.html',name: '添加员工'},true)} else {window.parent.menuHandle({id: '2',url: '/backend/page/member/add.html?id='+st,name: '修改员工'},true)}},//状态修改statusHandle (row) {this.id = row.idthis.status = row.statusthis.$confirm('确认调整该账号的状态?', '提示', {'confirmButtonText': '确定','cancelButtonText': '取消','type': 'warning'}).then(() => {enableOrDisableEmployee({ 'id': this.id, 'status': !this.status ? 1 : 0 }).then(res => {console.log('enableOrDisableEmployee',res)if (String(res.code) === '1') {this.$message.success('账号状态更改成功!')this.handleQuery()}}).catch(err => {this.$message.error('请求出错了:' + err)})})},handleSizeChange (val) {this.pageSize = valthis.init()},handleCurrentChange (val) {this.page = valthis.init()}}})</script>
</body>
</html>

member.js
function getMemberList (params) {return $axios({url: '/employee/page',method: 'get',params})
}// 修改---启用禁用接口
function enableOrDisableEmployee (params) {return $axios({url: '/employee',method: 'put',data: { ...params }})
}// 新增---添加员工
function addEmployee (params) {return $axios({url: '/employee',method: 'post',data: { ...params }})
}// 修改---添加员工
function editEmployee (params) {return $axios({url: '/employee',method: 'put',data: { ...params }})
}// 修改页面反查详情接口
function queryEmployeeById (id) {return $axios({url: `/employee/${id}`,method: 'get'})
}
js/request.js
 // request拦截器service.interceptors.request.use(config => {// 是否需要设置 token// const isToken = (config.headers || {}).isToken === false// if (getToken() && !isToken) {//   config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改// }// get请求映射params参数if (config.method === 'get' && config.params) {let url = config.url + '?';for (const propName of Object.keys(config.params)) {const value = config.params[propName];var part = encodeURIComponent(propName) + "=";if (value !== null && typeof(value) !== "undefined") {if (typeof value === 'object') {for (const key of Object.keys(value)) {let params = propName + '[' + key + ']';var subPart = encodeURIComponent(params) + "=";url += subPart + encodeURIComponent(value[key]) + "&";}} else {url += part + encodeURIComponent(value) + "&";}}}url = url.slice(0, -1);config.params = {};config.url = url;}return config}, error => {console.log(error)Promise.reject(error)})

4.启用/禁用员工账号

需求分析

代码分析


member.js
// 修改---启用禁用接口
function enableOrDisableEmployee (params) {return $axios({url: '/employee',method: 'put',data: { ...params }})
}

为什么admin账号有显示禁用的功能

member/list.html
<template slot-scope="scope"><el-buttontype="text"size="small"class="blueBug"@click="addMemberHandle(scope.row.id)":class="{notAdmin:user !== 'admin'}">编辑</el-button><el-buttontype="text"size="small"class="delBut non"@click="statusHandle(scope.row)"v-if="user === 'admin'">{{ scope.row.status == '1' ? '禁用' : '启用' }}</el-button></template>

代码修复


common/JacksonObjectMapper.java
package com.itheima.reggie.common;import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;/*** 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]*/
public class JacksonObjectMapper extends ObjectMapper {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 JacksonObjectMapper() {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.java
package com.itheima.reggie.config;import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.itheima.reggie.common.JacksonObjectMapper;
import com.itheima.reggie.entity.Employee;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {/*** 设置静态资源映射* @param registry*/@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {log.info("开始进行静态资源映射...");registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");}/*** 扩展mvc框架的消息转换器* @param converters*/@Overrideprotected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {log.info("扩展消息转换器...");//创建消息转换器对象MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();//设置对象转换器,底层使用Jackson将Java对象转为jsonmessageConverter.setObjectMapper(new JacksonObjectMapper());//将上面的消息转换器对象追加到mvc框架的转换器集合中converters.add(0,messageConverter);}
}

5.编辑员工信息

需求分析

代码分析

代码开发

add.html
 <el-form-item label="账号:" prop="username"><el-input v-model="ruleForm.username" placeholder="请输入账号" maxlength="20"/></el-form-item><el-form-itemlabel="员工姓名:"prop="name"><el-inputv-model="ruleForm.name"placeholder="请输入员工姓名"maxlength="20"/></el-form-item><el-form-itemlabel="手机号:"prop="phone"><el-inputv-model="ruleForm.phone"placeholder="请输入手机号"maxlength="20"/></el-form-item><el-form-itemlabel="性别:"prop="sex"><el-radio-group v-model="ruleForm.sex"><el-radio label="男"></el-radio><el-radio label="女"></el-radio></el-radio-group></el-form-item><el-form-itemlabel="身份证号:"prop="idNumber"><el-inputv-model="ruleForm.idNumber"placeholder="请输入身份证号"maxlength="20"/></el-form-item><div class="subBox address"><el-form-item><el-button  @click="goBack()">取消</el-button><el-buttontype="primary"@click="submitForm('ruleForm', false)">保存</el-button><el-buttonv-if="actionType == 'add'"type="primary"class="continue"@click="submitForm('ruleForm', true)">保存并继续添加</el-button></el-form-item></div></el-form>
add.html内的js代码
computed: {rules () {return {//账号username: [{required: true, 'validator': checkUserName, trigger: 'blur'}],//姓名name: [{ required: true, 'validator': checkName, 'trigger': 'blur' }],'phone': [{ 'required': true, 'validator': checkPhone, 'trigger': 'blur' }],'idNumber': [{ 'required': true, 'validator': validID, 'trigger': 'blur' }]}}},created() {this.id = requestUrlParam('id')this.actionType = this.id ? 'edit' : 'add'if (this.id) {this.init()}},mounted() {},methods: {async init () {queryEmployeeById(this.id).then(res => {console.log(res)if (String(res.code) === '1') {console.log(res.data)this.ruleForm = res.datathis.ruleForm.sex = res.data.sex === '0' ? '女' : '男'// this.ruleForm.password = ''} else {this.$message.error(res.msg || '操作失败')}})},submitForm (formName, st) {this.$refs[formName].validate((valid) => {if (valid) {if (this.actionType === 'add') {const params = {...this.ruleForm,sex: this.ruleForm.sex === '女' ? '0' : '1'}addEmployee(params).then(res => {if (res.code === 1) {this.$message.success('员工添加成功!')if (!st) {this.goBack()} else {this.ruleForm = {username: '','name': '','phone': '',// 'password': '',// 'rePassword': '',/'sex': '男','idNumber': ''}}} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})} else {const params = {...this.ruleForm,sex: this.ruleForm.sex === '女' ? '0' : '1'}editEmployee(params).then(res => {if (res.code === 1) {this.$message.success('员工信息修改成功!')this.goBack()} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})}} else {console.log('error submit!!')return false}})}

Url的地址路径是如何获取的

js/index.js

通过参数截取id的值

/* 自定义trim */
function trim (str) {  //删除左右两端的空格,自定义的trim()方法return str == undefined ? "" : str.replace(/(^\s*)|(\s*$)/g, "")
}//获取url地址上面的参数
function requestUrlParam(argname){var url = location.href //获取完整的请求url路径var arrStr = url.substring(url.indexOf("?")+1).split("&")for(var i =0;i<arrStr.length;i++){var loc = arrStr[i].indexOf(argname+"=")if(loc!=-1){return arrStr[i].replace(argname+"=","").replace("?","")}}return ""
}
EmployeeController.java
    /*** 新增员工* @param employee* @return*/@PostMappingpublic R<String> save(HttpServletRequest request,@RequestBody Employee employee){log.info("新增员工,员工信息:{}",employee.toString());//设置初始密码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);//employee.setUpdateUser(empId);employeeService.save(employee);return R.success("新增员工成功");}/*** 根据id查询员工信息* @param id* @return*/@GetMapping("/{id}")public R<Employee> getById(@PathVariable Long id){log.info("根据id查询员工信息...");Employee employee = employeeService.getById(id);if(employee != null){return R.success(employee);}return R.error("没有查询到对应员工信息");}
}

项目-瑞吉外卖(1)相关推荐

  1. 瑞吉外卖项目——瑞吉外卖

    软件开发整体介绍 软件开发流程 需求分析:产品原型.需求规格说明书 设计:产品文档.UI界面设计.概要设计.详细设计.数据库设计 编码:项目代码.单元测试 测试:测试用例.测试报告 上线运维:软件环境 ...

  2. 【SpringBoot项目】SpringBoot项目-瑞吉外卖【day02】员工管理业务开发

    文章目录 前言 员工管理业务开发 完善登录功能 问题分析 代码实现 功能测试 新增员工 需求分析 数据模型 代码开发 功能测试 统一处理异常 员工信息分页查询 需求分析 代码开发 功能测试 启用/禁用 ...

  3. SpringBoot项目 瑞吉外卖(8)套餐管理

    套餐操作和菜品类似,所以就写得水一点了. 新增套餐: 导入SetmealDto,创建setmealdish相关类和接口,只需创建setmealcontroller即可 套餐/菜品分类数据请求: 已解决 ...

  4. 【SpringBoot项目】SpringBoot项目-瑞吉外卖【day03】分类管理

    文章目录 前言 公共字段自动填充 问题分析 代码实现 功能测试 功能完善 新增分类 需求分析 模型 代码开发 功能测试 分类信息分页查询 需求分析 代码开发 功能测试 删除分类 需求分析 代码开发 功 ...

  5. 瑞吉外卖项目day01

    一.软件开发整体介绍 1.1 软件开发流程 需求分析:产品原型.需求规格说明书 设计:产品文档.UI界面设计.概要设计.详细设计.数据库设计 编码:项目代码,是单元测试 上线运维:软件环境安装.配置 ...

  6. 瑞吉外卖项目重难点及易错点知识点总结

    本文是对b站黑马程序员瑞吉外卖项目的总结,实现流程以及简单部分不做详解,重点归纳难点以及易错点.(前面是对项目的介绍,可以直接略过 看第四点总结) 视频链接:https://www.bilibili. ...

  7. 项目前期准备 -- 手把手教你做ssm+springboot入门后端项目黑马程序员瑞吉外卖(一)

    文章目录 前言 一.导学内容 1.前置知识(必备) 2.博客收获 3.效果展示 4.软件开发流程整体介绍 4.瑞吉外卖整体项目介绍 二.开发环境搭建 1.数据库环境搭建 2.maven环境搭建 总结 ...

  8. 【瑞吉外卖】学习笔记-day1:项目介绍及后台初识

    项目介绍 本项目(瑞吉外卖)是专门为餐饮企业(餐厅.饭店)定制的一款软件产品,包括 系统管理后台 和 移动端应用 两部分.其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的分类.菜品.套餐. ...

  9. 学习【瑞吉外卖①】SpringBoot单体项目

    视频链接:黑马程序员[Java 项目实战<瑞吉外卖>,轻松掌握 SpringBoot + MybatisPlus 开发核心技术] 资料链接:2022 最新版 Java学习 路线图>第 ...

最新文章

  1. splitcontainer如何设置两边一样打_墙洞加筋如何计算?
  2. 【OpenCV 4开发详解】点集拟合
  3. python转载[编码问题]
  4. 东京见闻:快速走红日本市场 阿里云的三大秘密
  5. ITK:在向量容器上迭代
  6. 【代码笔记】iOS-字体抖动动画
  7. 【C语言实现反转数组】(用栈实现)51nod - 训练营
  8. 计算机英语讲课笔记(2020-6-13)
  9. Jsp 页面添加动态水印
  10. Mybatis 源码分析(一)配置文件加载流程
  11. 系统学习深度学习(一) --深度学习与神经网络关系
  12. 使用Windows 7 管理Windows 2008 R2
  13. 数学建模 - 时间序列分析
  14. 嵌入式“Hello World!”——点亮流水灯
  15. 原生js 获取屏幕各种宽高的方法
  16. java毕业设计成品基于JSP实现的飞机票售票管理系统[包运行成功]
  17. 让0球平局怎么算_古迪逊公园默郡德比,平局德比丨第30轮
  18. 查看各大网站服务器操作系统
  19. 吴恩达深度学习课程笔记(二):改善深层神经网络
  20. 行业分析| 物流对讲

热门文章

  1. 图像直方图均衡化c语言程序,数字图像处理——直方图均衡化
  2. SCADE Suite建模基础
  3. AI虚拟主播软件系统 搭建24小时不间断运营的数字人直播间的操作教程分享
  4. python合并音频和视频_ffmpeg+Python实现B站MP4格式音频与视频的合并
  5. Dialog使用介绍
  6. “我学习win32com的秘诀”,本周六(7月1日)上午腾讯会议室见
  7. 《忏悔录》法—让雅克.卢梭
  8. 分类问题 (一) : 基本定义
  9. 以小米4手机为例换算px,dip,dpi等数值
  10. GDKOI2018战记