当前,随着数字化时代的到来,外卖小程序的开发引起了广泛关注。这其中包括了多种技术和功能的策划,对于开发者而言,掌握这些知识至关重要。同时,对于创业者或是那些希望深入探究外卖后台运营的人来说,这些信息同样具有重要意义。
功能与用户需求
外卖软件功能丰富多样。首先,对用户来说,最基本的需求是能够方便快捷地订购食物。例如,在像北京中关村软件园这样的上班族密集区域,许多人在中午休息时间很短,他们期望能在极短的时间内完成点餐。这些需求促使功能设计更加注重便捷性,比如菜品分类清晰、搜索功能简便。其次,从商家的角度来看,他们需要具备订单管理和菜品管理的功能,以便能够及时更新菜品信息,调整菜品的上架和下架状态。
在设计功能时,如何协调用户与商家的需求至关重要。用户倾向于期望有更丰富的菜品选项,而商家则可能因食材供应等因素受到限制。那么,开发者该如何准确掌握这一平衡点?
系统总体设计考量
外卖系统小程序的设计在B/S模式下相对复杂。首先,架构的选择至关重要。我们选择B/S模式,主要是因为它操作简便,用户只需通过浏览器就能轻松访问系统。例如,大型外卖平台的后台管理系统,即便是在不同地区的运营中心,也能通过B/S架构,让管理人员远程进行维护和管理。
系统的分层结构同样关键。前端需打造简洁且易用的界面,需考虑不同年龄层的用户习惯,年轻人可能偏好时尚且炫目的界面,而老年人可能更倾向于大字体和清晰的操作步骤。后端则需要妥善处理业务逻辑和数据库交流等任务,以保证订单处理和用户数据管理等操作的效率和稳定性。
这种系统分层后各部分如何有效协作以提升整体性能?
详细设计之页面呈现
页面呈现的细节对用户感受至关重要。微信开发者工具在助力小程序开发方面发挥了重要作用。在沿海地区,不少小型外卖创业团队借助微信开发者工具进行小程序开发,他们通过其简便的操作来设计页面。
页面设计需注重美观,其中,菜品与店铺的图片需保证清晰度。动态效果亦需适度,比如购物车添加菜品的动画和下单后的加载动画等。若动态效果过于繁琐,可能造成加载缓慢,损害用户体验;若过于简单,则缺乏吸引力。那么,如何把握这个平衡点?
数据库设计要点
设计MySQL数据库时,需注意多个关键点。首先要确立实体之间的联系,比如用户与菜品信息之间的多对一关系。这种联系对数据存储与检索有重要影响。以一家繁忙的外卖店为例,订单数量庞大,每个订单都与菜品信息相连。若关系设计不当,在高峰时段,数据查询可能会出现异常。
数据库表结构需科学规划,关键数据库表的E-R实体关系图应全面反映系统运行中的核心数据关联。此外,数据的完整性及一致性亦不容忽视。那么,我们该如何防止数据丢失或数据不匹配的问题发生?
用户权限管理
外卖小程序中,用户权限管理至关重要。一般用户登录后,仅能进行个人操作,如修改个人资料、查看订单等。相比之下,管理员权限更广,可对系统数据进行全面管理。以某跨区域外卖连锁品牌总部为例,管理员可查看各区域订单和商家信息,并对其进行相应调整。
在权限配置方面,必须对管理人员的权限进行适度控制,以免权限过度使用导致数据泄露等安全隐患。那么,我们该如何有效地阻止恶意攻击者获取管理员权限?
项目的技术基础
该项目以Java语言为核心,Java开发工具包(JDK)是运行Java程序的关键。缺少JDK,Java程序就无法执行,就如同高楼缺乏稳固的基石。在Java这一面向对象的语言环境中,能够编写出既高效又易于维护的代码。此外,基于Java的B/S架构系统还需服务器来支持其运行。在发达地区,数据中心拥有丰富的服务器资源,确保系统稳定。然而,在偏远地区部署时,如何应对服务器资源短缺的问题?
/**
* 用户账户:用于保存用户登录信息(User)表控制层
*/
@Slf4j
@RestController
@RequestMapping("user")
public class UserController extends BaseController {
/**
* 服务对象
*/
@Autowired
public UserController(UserService service) {
setService(service);
}
/**
* Token服务
*/
@Autowired
private AccessTokenService tokenService;
@Autowired
private UserGroupService userGroupService;
/**
* 注册
* @param user
* @return
*/
@PostMapping("register")
public Map signUp(@RequestBody User user) {
// 查询用户
Map query = new HashMap();
query.put("username",user.getUsername());
List list = service.select(query, new HashMap()).getResultList();
if (list.size()>0){
return error(30000, "用户已存在");
}
user.setUserId(null);
user.setPassword(service.encryption(user.getPassword()));
service.save(user);
return success(1);
}
/**
* 找回密码
* @param form
* @return
*/
@PostMapping("forget_password")
public Map forgetPassword(@RequestBody User form,HttpServletRequest request) {
JSONObject ret = new JSONObject();
String username = form.getUsername();
String code = form.getCode();
String password = form.getPassword();
// 判断条件
if(code == null || code.length() == 0){
return error(30000, "验证码不能为空");
}
if(username == null || username.length() == 0){
return error(30000, "用户名不能为空");
}
if(password == null || password.length() == 0){
return error(30000, "密码不能为空");
}
// 查询用户
Map query = new HashMap();
query.put("username",username);
Query select = service.select(query, service.readConfig(request));
List list = select.getResultList();
if (list.size() > 0) {
User o = (User) list.get(0);
JSONObject query2 = new JSONObject();
JSONObject form2 = new JSONObject();
// 修改用户密码
query2.put("user_id",o.getUserId());
form2.put("password",service.encryption(password));
service.update(query, service.readConfig(request), form2);
return success(1);
}
return error(70000,"用户不存在");
}
/**
* 登录
* @param data
* @param httpServletRequest
* @return
*/
@PostMapping("login")
public Map login(@RequestBody Map data, HttpServletRequest httpServletRequest) {
log.info("[执行登录接口]");
String username = data.get("username");
String email = data.get("email");
String phone = data.get("phone");
String password = data.get("password");
List resultList = null;
Map map = new HashMap();
if(username != null && "".equals(username) == false){
map.put("username", username);
resultList = service.select(map, new HashMap()).getResultList();
}
else if(email != null && "".equals(email) == false){
map.put("email", email);
resultList = service.select(map, new HashMap()).getResultList();
}
else if(phone != null && "".equals(phone) == false){
map.put("phone", phone);
resultList = service.select(map, new HashMap()).getResultList();
}else{
return error(30000, "账号或密码不能为空");
}
if (resultList == null || password == null) {
return error(30000, "账号或密码不能为空");
}
//判断是否有这个用户
if (resultList.size()<=0){
return error(30000,"用户不存在");
}
User byUsername = (User) resultList.get(0);
Map groupMap = new HashMap();
groupMap.put("name",byUsername.getUserGroup());
List groupList = userGroupService.select(groupMap, new HashMap()).getResultList();
if (groupList.size()<1){
return error(30000,"用户组不存在");
}
UserGroup userGroup = (UserGroup) groupList.get(0);
//查询用户审核状态
if (!StringUtils.isEmpty(userGroup.getSourceTable())){
String sql = "select examine_state from "+ userGroup.getSourceTable() +" WHERE user_id = " + byUsername.getUserId();
String res = String.valueOf(service.runCountSql(sql).getSingleResult());
if (res==null){
return error(30000,"用户不存在");
}
if (!res.equals("已通过")){
return error(30000,"该用户审核未通过");
}
}
//查询用户状态
if (byUsername.getState()!=1){
return error(30000,"用户非可用状态,不能登录");
}
String md5password = service.encryption(password);
if (byUsername.getPassword().equals(md5password)) {
// 存储Token到数据库
AccessToken accessToken = new AccessToken();
accessToken.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
accessToken.setUser_id(byUsername.getUserId());
tokenService.save(accessToken);
// 返回用户信息
JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(byUsername));
user.put("token", accessToken.getToken());
JSONObject ret = new JSONObject();
ret.put("obj",user);
return success(ret);
} else {
return error(30000, "账号或密码不正确");
}
}
/**
* 修改密码
* @param data
* @param request
* @return
*/
@PostMapping("change_password")
public Map change_password(@RequestBody Map data, HttpServletRequest request){
// 根据Token获取UserId
String token = request.getHeader("x-auth-token");
Integer userId = tokenGetUserId(token);
// 根据UserId和旧密码获取用户
Map query = new HashMap();
String o_password = data.get("o_password");
query.put("user_id" ,String.valueOf(userId));
query.put("password" ,service.encryption(o_password));
Query ret = service.count(query, service.readConfig(request));
List list = ret.getResultList();
Object s = list.get(0);
int count = Integer.parseInt(list.get(0).toString());
if(count > 0){
// 修改密码
Map form = new HashMap();
form.put("password",service.encryption(data.get("password")));
service.update(query,service.readConfig(request),form);
return success(1);
}
return error(10000,"密码修改失败!");
}
/**
* 登录态
* @param request
* @return
*/
@GetMapping("state")
public Map state(HttpServletRequest request) {
JSONObject ret = new JSONObject();
// 获取状态
String token = request.getHeader("x-auth-token");
// 根据登录态获取用户ID
Integer userId = tokenGetUserId(token);
log.info("[返回userId] {}",userId);
if(userId == null || userId == 0){
return error(10000,"用户未登录!");
}
// 根据用户ID获取用户
Map query = new HashMap();
query.put("user_id" ,String.valueOf(userId));
// 根据用户ID获取
Query select = service.select(query,service.readConfig(request));
List resultList = select.getResultList();
if (resultList.size() > 0) {
JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(resultList.get(0)));
user.put("token",token);
ret.put("obj",user);
return success(ret);
} else {
return error(10000,"用户未登录!");
}
}
/**
* 登录态
* @param request
* @return
*/
@GetMapping("quit")
public Map quit(HttpServletRequest request) {
String token = request.getHeader("x-auth-token");
JSONObject ret = new JSONObject();
Map query = new HashMap(16);
query.put("token", token);
try{
tokenService.delete(query,service.readConfig(request));
}catch (Exception e){
e.printStackTrace();
}
return success("退出登录成功!");
}
/**
* 获取登录用户ID
* @param token
* @return
*/
public Integer tokenGetUserId(String token) {
log.info("[获取的token] {}",token);
// 根据登录态获取用户ID
if(token == null || "".equals(token)){
return 0;
}
Map query = new HashMap(16);
query.put("token", token);
AccessToken byToken = tokenService.findOne(query);
if(byToken == null){
return 0;
}
return byToken.getUser_id();
}
/**
* 重写add
* @return
*/
@PostMapping("/add")
@Transactional
public Map add(HttpServletRequest request) throws IOException {
Map map = service.readBody(request.getReader());
map.put("password",service.encryption(String.valueOf(map.get("password"))));
service.insert(map);
return success(1);
}
}
如有关于外卖小程序开发的独到看法或疑问,欢迎在评论区发表意见。如觉得本文对您有帮助,别忘了点赞并转发。