|
@@ -0,0 +1,225 @@
|
|
|
|
|
+package space.anyi.controller.admin;
|
|
|
|
|
+
|
|
|
|
|
+import space.anyi.entity.*;
|
|
|
|
|
+import space.anyi.entity.dto.*;
|
|
|
|
|
+import space.anyi.service.*;
|
|
|
|
|
+import space.anyi.util.Converter;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
+import org.springframework.stereotype.Controller;
|
|
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
+import org.springframework.web.servlet.ModelAndView;
|
|
|
|
|
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.File;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.UUID;
|
|
|
|
|
+
|
|
|
|
|
+@Controller
|
|
|
|
|
+@RequestMapping("/admin")
|
|
|
|
|
+public class AdminCakeController {
|
|
|
|
|
+
|
|
|
|
|
+ @Value("${upload.path}")
|
|
|
|
|
+ private String uploadPath;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired private CategoryService categoryService;
|
|
|
|
|
+ @Autowired private CakeService cakeService;
|
|
|
|
|
+ @Autowired private CakeSpecService cakeSpecService;
|
|
|
|
|
+ @Autowired private CustomOptionService customOptionService;
|
|
|
|
|
+
|
|
|
|
|
+ // === Category Management ===
|
|
|
|
|
+ @GetMapping("/category")
|
|
|
|
|
+ public ModelAndView category() {
|
|
|
|
|
+ ModelAndView mv = new ModelAndView("admin/category");
|
|
|
|
|
+ mv.addObject("categories", categoryService.findAll());
|
|
|
|
|
+ return mv;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/category")
|
|
|
|
|
+ public String addCategory(CategoryDTO dto, RedirectAttributes attr) {
|
|
|
|
|
+ categoryService.add(Converter.toCategory(dto));
|
|
|
|
|
+ attr.addFlashAttribute("success", "添加成功");
|
|
|
|
|
+ return "redirect:/admin/category";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/category/update")
|
|
|
|
|
+ public String updateCategory(CategoryDTO dto, RedirectAttributes attr) {
|
|
|
|
|
+ categoryService.update(Converter.toCategory(dto));
|
|
|
|
|
+ attr.addFlashAttribute("success", "更新成功");
|
|
|
|
|
+ return "redirect:/admin/category";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/category/delete/{id}")
|
|
|
|
|
+ public String deleteCategory(@PathVariable Integer id, RedirectAttributes attr) {
|
|
|
|
|
+ categoryService.delete(id);
|
|
|
|
|
+ attr.addFlashAttribute("success", "删除成功");
|
|
|
|
|
+ return "redirect:/admin/category";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // === Cake Management ===
|
|
|
|
|
+ @GetMapping("/cake")
|
|
|
|
|
+ public ModelAndView cakeList(@RequestParam(required = false) String status,
|
|
|
|
|
+ @RequestParam(defaultValue = "1") Integer page) {
|
|
|
|
|
+ ModelAndView mv = new ModelAndView("admin/cake");
|
|
|
|
|
+ CakeSearchCriteria criteria = new CakeSearchCriteria();
|
|
|
|
|
+ criteria.setStatus(status);
|
|
|
|
|
+ List<Cake> cakeList = cakeService.search(criteria, page, 10);
|
|
|
|
|
+ int totalPages = 1;
|
|
|
|
|
+ if (cakeList instanceof com.github.pagehelper.Page) {
|
|
|
|
|
+ com.github.pagehelper.Page<Cake> p = (com.github.pagehelper.Page<Cake>) cakeList;
|
|
|
|
|
+ totalPages = p.getPages();
|
|
|
|
|
+ }
|
|
|
|
|
+ mv.addObject("cakes", Converter.toCakeVOList(cakeList));
|
|
|
|
|
+ mv.addObject("categories", categoryService.findAll());
|
|
|
|
|
+ mv.addObject("status", status);
|
|
|
|
|
+ mv.addObject("page", page);
|
|
|
|
|
+ mv.addObject("totalPages", totalPages);
|
|
|
|
|
+ return mv;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping("/cake/add")
|
|
|
|
|
+ public ModelAndView addCakePage() {
|
|
|
|
|
+ ModelAndView mv = new ModelAndView("admin/cakeEdit");
|
|
|
|
|
+ mv.addObject("categories", categoryService.findAll());
|
|
|
|
|
+ return mv;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping("/cake/edit/{id}")
|
|
|
|
|
+ public ModelAndView editCakePage(@PathVariable Integer id) {
|
|
|
|
|
+ ModelAndView mv = new ModelAndView("admin/cakeEdit");
|
|
|
|
|
+ mv.addObject("cake", Converter.toCakeVO(cakeService.findById(id)));
|
|
|
|
|
+ mv.addObject("categories", categoryService.findAll());
|
|
|
|
|
+ return mv;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/cake/save")
|
|
|
|
|
+ public String saveCake(CakeSaveDTO dto,
|
|
|
|
|
+ @RequestParam(required = false) MultipartFile mainImageFile,
|
|
|
|
|
+ RedirectAttributes attr) {
|
|
|
|
|
+ if (mainImageFile != null && !mainImageFile.isEmpty()) {
|
|
|
|
|
+ String path = saveUploadFile(mainImageFile);
|
|
|
|
|
+ if (path != null) {
|
|
|
|
|
+ dto.setMainImage(path);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dto.getName() == null || dto.getName().trim().isEmpty()) {
|
|
|
|
|
+ attr.addFlashAttribute("error", "蛋糕名称不能为空");
|
|
|
|
|
+ return "redirect:/admin/cake";
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dto.getBasePrice() == null) {
|
|
|
|
|
+ attr.addFlashAttribute("error", "基础价格不能为空");
|
|
|
|
|
+ return "redirect:/admin/cake";
|
|
|
|
|
+ }
|
|
|
|
|
+ Cake cake = Converter.toCake(dto);
|
|
|
|
|
+ if (cake.getId() != null) {
|
|
|
|
|
+ cakeService.update(cake);
|
|
|
|
|
+ attr.addFlashAttribute("success", "更新成功");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ cakeService.add(cake);
|
|
|
|
|
+ attr.addFlashAttribute("success", "添加成功");
|
|
|
|
|
+ }
|
|
|
|
|
+ return "redirect:/admin/cake";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String saveUploadFile(MultipartFile file) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ String dirPath = new File(uploadPath).getAbsolutePath();
|
|
|
|
|
+ File dir = new File(dirPath);
|
|
|
|
|
+ if (!dir.exists()) {
|
|
|
|
|
+ dir.mkdirs();
|
|
|
|
|
+ }
|
|
|
|
|
+ String originalFilename = file.getOriginalFilename();
|
|
|
|
|
+ String ext = "";
|
|
|
|
|
+ if (originalFilename != null && originalFilename.contains(".")) {
|
|
|
|
|
+ ext = originalFilename.substring(originalFilename.lastIndexOf("."));
|
|
|
|
|
+ }
|
|
|
|
|
+ String newFilename = UUID.randomUUID().toString().replace("-", "") + ext;
|
|
|
|
|
+ File dest = new File(dir, newFilename);
|
|
|
|
|
+ file.transferTo(dest);
|
|
|
|
|
+ return "/upload/" + newFilename;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/cake/delete/{id}")
|
|
|
|
|
+ public String deleteCake(@PathVariable Integer id, RedirectAttributes attr) {
|
|
|
|
|
+ cakeService.delete(id);
|
|
|
|
|
+ attr.addFlashAttribute("success", "删除成功");
|
|
|
|
|
+ return "redirect:/admin/cake";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/cake/toggleStatus")
|
|
|
|
|
+ @ResponseBody
|
|
|
|
|
+ public String toggleStatus(@RequestParam Integer id) {
|
|
|
|
|
+ cakeService.toggleStatus(id);
|
|
|
|
|
+ return "ok";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // === Spec Management ===
|
|
|
|
|
+ @GetMapping("/spec")
|
|
|
|
|
+ public String specRedirect() {
|
|
|
|
|
+ return "redirect:/admin/cake";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping("/spec/{cakeId}")
|
|
|
|
|
+ public ModelAndView spec(@PathVariable Integer cakeId) {
|
|
|
|
|
+ ModelAndView mv = new ModelAndView("admin/spec");
|
|
|
|
|
+ mv.addObject("cakeId", cakeId);
|
|
|
|
|
+ mv.addObject("specs", Converter.toCakeSpecVOList(cakeSpecService.findByCakeId(cakeId)));
|
|
|
|
|
+ return mv;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/spec/save")
|
|
|
|
|
+ public String saveSpec(CakeSpecDTO dto, RedirectAttributes attr) {
|
|
|
|
|
+ CakeSpec spec = Converter.toCakeSpec(dto);
|
|
|
|
|
+ if (spec.getId() != null) {
|
|
|
|
|
+ cakeSpecService.update(spec);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ cakeSpecService.add(spec);
|
|
|
|
|
+ }
|
|
|
|
|
+ attr.addFlashAttribute("success", "保存成功");
|
|
|
|
|
+ return "redirect:/admin/spec/" + spec.getCakeId();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/spec/delete/{id}")
|
|
|
|
|
+ public String deleteSpec(@PathVariable Integer id, @RequestParam Integer cakeId, RedirectAttributes attr) {
|
|
|
|
|
+ cakeSpecService.delete(id);
|
|
|
|
|
+ attr.addFlashAttribute("success", "删除成功");
|
|
|
|
|
+ return "redirect:/admin/spec/" + cakeId;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // === Custom Option Management ===
|
|
|
|
|
+ @GetMapping("/customOption")
|
|
|
|
|
+ public String customOptionRedirect() {
|
|
|
|
|
+ return "redirect:/admin/cake";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping("/custom-option/{cakeId}")
|
|
|
|
|
+ public ModelAndView customOption(@PathVariable Integer cakeId) {
|
|
|
|
|
+ ModelAndView mv = new ModelAndView("admin/customOption");
|
|
|
|
|
+ mv.addObject("cakeId", cakeId);
|
|
|
|
|
+ mv.addObject("customOptions", customOptionService.findByCakeId(cakeId));
|
|
|
|
|
+ return mv;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/custom-option/save")
|
|
|
|
|
+ public String saveCustomOption(CustomOptionDTO dto, RedirectAttributes attr) {
|
|
|
|
|
+ CustomOption option = Converter.toCustomOption(dto);
|
|
|
|
|
+ if (option.getId() != null) {
|
|
|
|
|
+ customOptionService.update(option);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ customOptionService.add(option);
|
|
|
|
|
+ }
|
|
|
|
|
+ attr.addFlashAttribute("success", "保存成功");
|
|
|
|
|
+ return "redirect:/admin/custom-option/" + option.getCakeId();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/custom-option/delete/{id}")
|
|
|
|
|
+ public String deleteCustomOption(@PathVariable Integer id, @RequestParam Integer cakeId, RedirectAttributes attr) {
|
|
|
|
|
+ customOptionService.delete(id);
|
|
|
|
|
+ attr.addFlashAttribute("success", "删除成功");
|
|
|
|
|
+ return "redirect:/admin/custom-option/" + cakeId;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|