日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

瑞吉外卖(五)

發布時間:2024/3/26 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 瑞吉外卖(五) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

套餐業務開發

新增套餐

需求分析

新增套餐,其實就是將新增頁面錄入的套餐信息插入到setmeal表,還需要向setmeal_dish表插入套餐和菜品關聯數據。所以在新增套餐時,涉及到兩個表:

在開發業務功能前,先將需要用到的類和接口基本結構創建好:

  • 實體類SetmealDish(直接從課程資料中導入即可,Setmeal實體前面+ 課程中已經導入過了)
  • DTO SetmealDto(直接從課程資料中導入即可)
  • Mapper接口SetmealDishMapper
  • 業務層接口SetmealDishService
  • 業務層實現類SetmealDishServicelmpl
  • 控制層SetmealController
代碼開發

在開發代碼之前,需要梳理一下新增套餐時前端頁面和服務端的交互過程:

1、頁面(backend/ page/comboladd.html)發送ajax請求,請求服務端獲取套餐分類數據并展示到下拉框中

這個方法我們在前面在新增菜品獲取菜品分類的時候我們已經寫過了,只不過是請求參數不同而已。

2、頁面發送ajax請求,請求服務端獲取菜品分類數據并展示到添加菜品窗口中

3、頁面發送ajax請求,請求服務端,根據菜品分類查詢對應的菜品數據并展示到添加菜品窗口中

前端頁面可以根據菜品分類和菜品名稱查找,這兩個接口都是通用的,

根據菜品分類獲取菜品信息:

根據菜品名稱獲取菜品信息:

const queryDishList = (params) => {return $axios({url: '/dish/list',method: 'get',params}) }

代碼編寫:

@GetMapping("/list") public Result<List<Dish>> getDishByCategory(Dish dish){LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();dishLambdaQueryWrapper.eq(Dish::getStatus,1);dishLambdaQueryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());dishLambdaQueryWrapper.like(dish.getName()!=null,Dish::getName,dish.getName());dishLambdaQueryWrapper.orderByDesc(Dish::getUpdateTime);List<Dish> dishes = dishService.list(dishLambdaQueryWrapper);return Result.success(dishes); }

4、頁面發送請求進行圖片上傳,請求服務端將圖片保存到服務器

5、頁面發送請求進行圖片下載,將上傳的圖片進行回顯

6、點擊保存按鈕,發送ajax請求,將套餐相關數據以json形式提交到服務端

前端接口:

const addSetmeal = (params) => {return $axios({url: '/setmeal',method: 'post',data: { ...params }}) }

前端請求的數據:

@Override public void saveSetmealDto(SetmealDto setmealDto) {this.save(setmealDto);Long setmealId = setmealDto.getId();List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));setmealDishService.saveBatch(setmealDishes); }

套餐分頁查詢

需求開發

前端接口:

const getSetmealPage = (params) => {return $axios({url: '/setmeal/page',method: 'get',params}) }
代碼開發
@GetMapping("page") public Result<Page> page(@RequestParam(value = "page",defaultValue = "1") Integer page,@RequestParam(value = "pageSize",defaultValue = "10") Integer pageSize,String name){log.info("page={},pageSize={},name={}",page,pageSize,name);Page<Setmeal> setmealPage = new Page<>();//查詢條件LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealLambdaQueryWrapper.like(StringUtils.hasLength(name),Setmeal::getName,name);//按名稱查找setmealLambdaQueryWrapper.orderByDesc(Setmeal::getUpdateTime);//按更新時間查找setmealService.page(setmealPage,setmealLambdaQueryWrapper);Page<SetmealDto> setmealDtoPage = new Page<>();BeanUtils.copyProperties(setmealPage,setmealDtoPage,"records");List<Setmeal> setmeals = setmealPage.getRecords();List<SetmealDto> setmealDtos=new LinkedList<>();setmeals.forEach(setmeal -> {SetmealDto setmealDto = new SetmealDto();//講setmeal對象內容移到setmealDtoBeanUtils.copyProperties(setmeal,setmealDto);//查找套裝分類并給每個setmealDto的categoryName屬性賦值Long categoryId = setmealDto.getCategoryId();Category category = categoryService.getById(categoryId);if (category!=null){setmealDto.setCategoryName(category.getName());}setmealDtos.add(setmealDto);});setmealDtoPage.setRecords(setmealDtos);return Result.success(setmealDtoPage); }

刪除套餐

需求開發

前端接口:

const deleteSetmeal = (ids) => {return $axios({url: '/setmeal',method: 'delete',params: { ids }}) }
代碼開發
@Override @Transactional public void removeSetmealDtoBatch(List<Long> ids) {List<Setmeal> setmeals = this.listByIds(ids);setmeals.forEach(setmeal -> {if(setmeal.getStatus()==1){throw new SetmealException("啟售中的套餐不能刪除");}LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId,setmeal.getId());setmealDishService.remove(setmealDishLambdaQueryWrapper);});this.removeByIds(ids);setmeals.forEach(setmeal -> {File file = new File(basePath + setmeal.getImage());file.delete();}); }

修改套餐信息

需求開發

在修改套裝之前要獲取套餐的信息

前端接口:

async init() {querySetmealById(this.id).then((res) => {if (String(res.code) === '1') {this.ruleForm = res.datathis.ruleForm.status = res.data.status === '1'this.ruleForm.price = res.data.price / 100this.imageUrl = `/common/download?name=${res.data.image}`this.checkList = res.data.setmealDishesthis.dishTable = res.data.setmealDishesthis.ruleForm.idType = res.data.categoryId// this.ruleForm.password = ''} else {this.$message.error(res.msg || '操作失敗')}}) }const querySetmealById = (id) => {return $axios({url: `/setmeal/${id}`,method: 'get'}) }
代碼開發

根據套餐ID獲取套餐信息:

@Override public SetmealDto getSetmealDtoById(Long id) {Setmeal setmeal = this.getById(id);SetmealDto setmealDto = new SetmealDto();BeanUtils.copyProperties(setmeal,setmealDto);LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId,id);setmealDishLambdaQueryWrapper.orderByDesc(SetmealDish::getUpdateTime);List<SetmealDish> setmealDishes = setmealDishService.list(setmealDishLambdaQueryWrapper);setmealDto.setSetmealDishes(setmealDishes);return setmealDto; }

點擊保存按鈕之后,前端會發送以下請求給服務器,與添加套餐功能類似:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FOSrnlxf-1678802048382)(null)]

@Override @Transactional public void updateSetmealDto(SetmealDto setmealDto) {this.updateById(setmealDto);Long setmealId = setmealDto.getId();LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealDishLambdaQueryWrapper.eq(SetmealDish::getSetmealId,setmealId);setmealDishService.remove(setmealDishLambdaQueryWrapper);List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));setmealDishService.saveBatch(setmealDishes); }

手機驗證碼登錄

短信發送

短信服務介紹

目前市面上有很多第三方提供的短信服務,這些第三方短信服務會和各個運營商(移動、聯通、電信)對接,我們只需要注冊成為會員并且按照提供的開發文檔進行調用就可以發送短信。需要說明的是,這些短信服務一般都是收費服務。

常用短信服務:

  • 阿里云
  • 華為云
  • 騰訊云
  • 京東
  • 夢網
  • 樂信

阿里云短信服務-介紹

阿里云短信服務(Short Message Service)是廣大企業客戶快速觸達手機用戶所優選使用的通信能力。調用API或用群發助手,即可發送驗證碼、通知類和營銷類短信;國內驗證短信秒級觸達,到達率最高可達99%;國際/港澳臺短信覆蓋200多個國家和地區,安全穩定,廣受出海企業選用。

應用場景:

  • 驗證碼
  • 短信通知
  • 推廣短信

阿里云短信服務-注冊賬號

阿里云官網: https://www.aliyun.com/

點擊官網首頁注冊按鈕。

阿里云短信服務-設置短信簽名

注冊成功后,點擊登錄按鈕進行登錄。登錄后進入短信服務管理頁面,選擇國內消息菜單:

短信簽名是短信發送者的署名,表示發送方的身份。

阿里云短信服務-設置短信模板

切換到【模板管理】標簽頁:

短信模板包含短信發送內容、場景、變量信息。

阿里云短信服務-設置AccessKey

光標移動到用戶頭像上,在彈出的窗口中點擊【AccessKey管理】∶

代碼開發

在開發代碼之前,需要梳理一下登錄時前端頁面和服務端的交互過程:

1、在登錄頁面(front/page/login.html)輸入手機號,點擊【獲取驗證碼】按鈕,頁面發送ajax請求,在服務端調用短信服務API給指定手機號發送驗證碼短信

2、在登錄頁面輸入驗證碼,點擊【登錄】按鈕,發送ajax請求,在服務端處理登錄請求

開發手機驗證碼登錄功能,其實就是在服務端編寫代碼去處理前端頁面發送的這2次請求即可。

在開發業務功能前,先將需要用到的類和接口基本結構創建好:

  • 實體類User(直接從課程資料中導入即可)
  • Mapper接口UserMapper
  • 業務層接口UserService
  • 業務層實現類UserServicelmpl
  • 控制層UserController
  • 工具類SMSutils、 ValidateCodeutils(直接從課程資料中導入即可)

前面我們已經完成了LogincheckFilter過濾器的開發,此過濾器用于檢查用戶的登錄狀態。我們在進行手機驗證碼登錄時,發送的請求需要在此過濾器處理時直接放行。

LoginCheckFilter過濾器添加

// 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; }

由于資料中代碼不全login.js自行添加

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

login.html

// this.form.code = (Math.random()*1000000).toFixed(0) sendMsgApi({phone:this.form.phone})

UserController處理post請求(發送驗證碼的請求)

@PostMapping("/sendMsg") public R<String> sendMsg(@RequestBody User user, HttpSession session){//獲取手機號String phone=user.getPhone();if(!StringUtils.isEmpty(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("手機短信發送失敗"); }

由于前端頁面有部分代碼缺失,建議拷貝資料中day05的front代碼

在UserController編寫login處理post請求

@PostMapping("/login") public R<User> login(@RequestBody Map map, HttpSession session) {log.info("map:{}", 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("登陸失敗"); }

總結

以上是生活随笔為你收集整理的瑞吉外卖(五)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。