<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot+Vue項(xiàng)目實(shí)戰(zhàn)之前后端開(kāi)發(fā)實(shí)現(xiàn)增刪改查

          共 12091字,需瀏覽 25分鐘

           ·

          2021-03-09 16:12

          場(chǎng)景:公司要開(kāi)發(fā)一個(gè)新的項(xiàng)目,但是我們的前端就一個(gè),還要忙著維護(hù)處理其他的項(xiàng)目,但是后端人員比較多,所以就要求后臺(tái)管理系統(tǒng)的頁(yè)面由后端人員開(kāi)發(fā),實(shí)在不會(huì)的找前端協(xié)助,這就沒(méi)辦法了,只能自己上了!

          前言:登錄頁(yè)面實(shí)現(xiàn)好后,這次實(shí)現(xiàn)和后端的交互,實(shí)現(xiàn)我們經(jīng)常使用的增刪改查,其實(shí)就是簡(jiǎn)單的實(shí)現(xiàn)發(fā)送請(qǐng)求調(diào)用后端編寫(xiě)好的接口,再根據(jù)返回的結(jié)果動(dòng)態(tài)渲染頁(yè)面。本次代碼有點(diǎn)多,粘貼主要部分,需要的可在文章末尾下載項(xiàng)目

          前端項(xiàng)目

          先看下這次實(shí)現(xiàn)主要用到的頁(yè)面



          接下來(lái)就是粘貼主要代碼

          EditForm.vue

          <template>
          <div>
          <i class="el-icon-circle-plus-outline" @click="dialogFormVisible = true"></i>
          <el-dialog
          title="添加/修改圖書(shū)"
          :visible.sync="dialogFormVisible"
          @close="clear">

          <el-form v-model="form" style="text-align: left" ref="dataForm">
          <el-form-item label="書(shū)名" :label-width="formLabelWidth" prop="title">
          <el-input v-model="form.title" autocomplete="off" placeholder="不加《》"></el-input>
          </el-form-item>
          <el-form-item label="作者" :label-width="formLabelWidth" prop="author">
          <el-input v-model="form.author" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="出版日期" :label-width="formLabelWidth" prop="date">
          <el-input v-model="form.date" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="出版社" :label-width="formLabelWidth" prop="press">
          <el-input v-model="form.press" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="封面" :label-width="formLabelWidth" prop="cover">
          <el-input v-model="form.cover" autocomplete="off" placeholder="圖片 URL"></el-input>
          <img-upload @onUpload="uploadImg" ref="imgUpload"></img-upload>
          </el-form-item>
          <el-form-item label="簡(jiǎn)介" :label-width="formLabelWidth" prop="abs">
          <el-input type="textarea" v-model="form.abs" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="分類(lèi)" :label-width="formLabelWidth" prop="cid">
          <el-select v-model="form.category.id" placeholder="請(qǐng)選擇分類(lèi)">
          <el-option label="文學(xué)" value="1"></el-option>
          <el-option label="流行" value="2"></el-option>
          <el-option label="文化" value="3"></el-option>
          <el-option label="生活" value="4"></el-option>
          <el-option label="經(jīng)管" value="5"></el-option>
          <el-option label="科技" value="6"></el-option>
          </el-select>
          </el-form-item>
          <el-form-item prop="id" style="height: 0">
          <el-input type="hidden" v-model="form.id" autocomplete="off"></el-input>
          </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取 消</el-button>
          <el-button type="primary" @click="onSubmit">確 定</el-button>
          </div>
          </el-dialog>
          </div>
          </template>

          <script>
          import ImgUpload from '../upload/ImgUpload'
          export default {
          name: 'EditForm',
          components: {ImgUpload},
          data () {
          return {
          dialogFormVisible: false,
          form: {
          id: '',
          title: '',
          author: '',
          date: '',
          press: '',
          cover: '',
          abs: '',
          category: {
          id: '',
          name: ''
          }
          },
          formLabelWidth: '120px'
          }
          },
          methods: {
          clear () {
          this.form = {
          id: '',
          title: '',
          author: '',
          date: '',
          press: '',
          cover: '',
          abs: '',
          category: ''
          }
          },
          onSubmit () {
          this.$axios
          .post('/books', {
          id: this.form.id,
          cover: this.form.cover,
          title: this.form.title,
          author: this.form.author,
          date: this.form.date,
          press: this.form.press,
          abs: this.form.abs,
          category: this.form.category
          }).then(resp => {
          if (resp && resp.status === 200) {
          this.dialogFormVisible = false
          this.$emit('onSubmit')
          }
          })
          },
          uploadImg () {
          this.form.cover = this.$refs.imgUpload.url
          }
          }
          }
          </script>

          <style scoped>
          .el-icon-circle-plus-outline {
          margin: 50px 0 0 20px;
          font-size: 100px;
          float: left;
          cursor: pointer;
          }
          </style>

          LibraryIndex.vue

          <template>
          <el-container>
          <el-aside style="width: 200px;margin-top: 20px">
          <switch></switch>
          <SideMenu @indexSelect="listByCategory" ref="sideMenu"></SideMenu>
          </el-aside>
          <el-main>
          <books class="books-area" ref="booksArea"></books>
          </el-main>
          </el-container>
          </template>

          <script>
          import SideMenu from './SideMenu'
          import Books from './Books'
          export default {
          name: "LibraryIndex",
          components: {SideMenu,Books},
          methods: {
          listByCategory () {
          var _this = this
          var cid = this.$refs.sideMenu.cid
          var url = 'categories/' + cid + '/books'
          this.$axios.get(url).then(resp => {
          if (resp && resp.status === 200) {
          _this.$refs.booksArea.books = resp.data
          }
          })
          }
          }
          }
          </script>

          <style scoped>
          .books-area {
          width: 990px;
          margin-left: auto;
          margin-right: auto;
          }
          </style>

          后端

          LibraryController

          package org.jeemp.api.controller;

          import org.jeemp.api.pojo.Book;
          import org.jeemp.api.service.BookService;
          import org.jeemp.api.util.StringUtils;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.web.bind.annotation.*;
          import org.springframework.web.multipart.MultipartFile;

          import java.io.File;
          import java.io.IOException;
          import java.util.List;

          /**
          * @author JackRen
          * @date 2021-03-07 17:17
          * @description:
          */

          @RestController
          public class LibraryController {

          @Autowired
          BookService bookService;

          @GetMapping("/api/books")
          public List<Book> list() throws Exception {
          return bookService.list();
          }

          @PostMapping("/api/books")
          public Book addOrUpdate(@RequestBody Book book) throws Exception {
          bookService.addOrUpdate(book);
          return book;
          }

          @PostMapping("/api/delete")
          public void delete(@RequestBody Book book) throws Exception {
          bookService.deleteById(book.getId());
          }

          @GetMapping("/api/categories/{cid}/books")
          public List<Book> listByCategory(@PathVariable("cid") int cid) throws Exception {
          if (0 != cid) {
          return bookService.listByCategory(cid);
          } else {
          return list();
          }
          }

          @GetMapping("/api/search")
          public List<Book> searchResult(@RequestParam("keywords") String keywords) {
          // 關(guān)鍵詞為空時(shí)查詢出所有書(shū)籍
          if ("".equals(keywords)) {
          return bookService.list();
          } else {
          return bookService.Search(keywords);
          }
          }


          }

          FastDfsController

          package org.jeemp.api.controller;

          import org.apache.commons.io.IOUtils;
          import org.jeemp.api.util.FastDfsUtil;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.PostMapping;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RestController;
          import org.springframework.web.multipart.MultipartFile;

          import javax.servlet.http.HttpServletResponse;
          import java.io.ByteArrayInputStream;
          import java.io.IOException;
          import java.net.URLEncoder;
          import java.util.logging.Logger;

          /**
          * @author JackRen
          * @date 2021-02-05 16:26
          * @description:
          */

          @RestController
          @RequestMapping("/fastDfs")
          public class FastDfsController {

          private static Logger logger = Logger.getLogger("FastDfsController");

          @Autowired
          private FastDfsUtil fastDfsUtil;

          @PostMapping("/upload")
          public String uploadFile(MultipartFile file) throws IOException {
          String s = fastDfsUtil.uploadFile(file);
          String resAccessUrl = fastDfsUtil.getResAccessUrl(s);
          System.out.println(resAccessUrl);
          return resAccessUrl;
          }

          @GetMapping("/download")
          public void downloadFile(String filePath, HttpServletResponse response) throws IOException {
          byte[] bytes = fastDfsUtil.downloadFile(filePath);
          String fileName = "哈哈.jpg";
          response.setContentType("application/force-download");// 設(shè)置強(qiáng)制下載不打開(kāi)
          //方式一
          // fileName=new String(fileName.getBytes(), "ISO8859-1")
          //方式二
          fileName = URLEncoder.encode(fileName, "utf-8");
          response.setHeader("Content-disposition", "attachment;filename=" + fileName);
          IOUtils.write(bytes, response.getOutputStream());
          }

          /**
          * 流媒體的方式播放視頻,只能從頭看到尾,不能手動(dòng)點(diǎn)擊重新看已經(jīng)看過(guò)的內(nèi)容
          * @param filePath
          * @param response
          * @throws IOException
          */

          @GetMapping("/play")
          public void streamMedia(String filePath, HttpServletResponse response) throws IOException {
          byte[] bytes = fastDfsUtil.downloadFile(filePath);
          IOUtils.copy(new ByteArrayInputStream(bytes), response.getOutputStream());
          response.flushBuffer();
          }

          @GetMapping("/delete")
          public void deleteFile(String filePath) {
          Boolean result = fastDfsUtil.deleteFile(filePath);
          }

          }

          項(xiàng)目啟動(dòng)后會(huì)出現(xiàn)跨域請(qǐng)求問(wèn)題,加上下面的類(lèi):

          CorsConfig

          package org.jeemp.api.config;

          import org.springframework.core.Ordered;
          import org.springframework.core.annotation.Order;
          import org.springframework.stereotype.Component;

          import javax.servlet.*;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import java.io.IOException;

          /**
          * @author JackRen
          * @date 2021/3/7
          * 解決跨域問(wèn)題
          **/

          @Component
          @Order(Ordered.HIGHEST_PRECEDENCE)
          public class CorsConfig implements Filter {

          @Override
          public void init(FilterConfig filterConfig) throws ServletException {

          }

          @Override
          public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
          HttpServletResponse response = (HttpServletResponse) res;
          HttpServletRequest request = (HttpServletRequest) req;
          //允許所有的域訪問(wèn)
          response.setHeader("Access-Control-Allow-Origin", "*");
          //允許所有方式的請(qǐng)求
          response.setHeader("Access-Control-Allow-Methods", "*");
          //頭信息緩存有效時(shí)長(zhǎng)(如果不設(shè) Chromium 同時(shí)規(guī)定了一個(gè)默認(rèn)值 5 秒),沒(méi)有緩存將已OPTIONS進(jìn)行預(yù)請(qǐng)求
          response.setHeader("Access-Control-Max-Age", "3600");
          //允許的頭信息
          response.setHeader("Access-Control-Allow-Headers", "*");

          response.setStatus(HttpServletResponse.SC_OK);

          if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
          response.setStatus(HttpServletResponse.SC_OK);
          } else {
          chain.doFilter(request,response);
          }


          }

          @Override
          public void destroy() {

          }
          }

          測(cè)試




          項(xiàng)目下載地址

          鏈接:https://pan.baidu.com/s/1VtsiBvkNpicODIHbS_sRIw 
          提取碼:2gby
          復(fù)制這段內(nèi)容后打開(kāi)百度網(wǎng)盤(pán)手機(jī)App,操作更方便哦


          瀏覽 98
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲精品午夜在线 | 国产经典的三级字在线播放 | 国产的内射 | 日月俱乐部 小美 | 一区二区永久 |