{"id":635,"date":"2025-01-03T14:48:13","date_gmt":"2025-01-03T06:48:13","guid":{"rendered":"http:\/\/www.cmd137blog.top\/?p=635"},"modified":"2025-02-27T15:23:25","modified_gmt":"2025-02-27T07:23:25","slug":"%e8%8b%8d%e7%a9%b9%e5%a4%96%e5%8d%96%e7%ac%94%e8%ae%b0","status":"publish","type":"post","link":"http:\/\/www.cmd137blog.top\/?p=635","title":{"rendered":"\u82cd\u7a79\u5916\u5356\u7b14\u8bb0"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">0.\u51c6\u5907\u5de5\u4f5c\u53ca\u524d\u7f6e\u77e5\u8bc6\uff1a<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">0.1 \u7248\u672c\u63a7\u5236<\/h2>\n\n\n\n<p><a href=\"https:\/\/blog.csdn.net\/mucaoyx\/article\/details\/98476174\">Git\u5728IDEA\u4e2d\u7684\u4f7f\u7528\uff08\u8be6\u7ec6\u56fe\u6587\u5168\u89e3\uff09_idea\u64cd\u4f5cgit-CSDN\u535a\u5ba2<\/a><\/p>\n\n\n\n<p>Gitee\u4ed3\u5e93\uff1a<a href=\"https:\/\/gitee.com\/CMD137\/sky-take-out\">CMD137\/sky-take-out<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">0.2 Nginx\uff1a\u53cd\u5411\u4ee3\u7406\u4e0e\u8d1f\u8f7d\u5747\u8861<\/h2>\n\n\n\n<p>\u53ef\u4ee5\u53d1\u73b0\u524d\u7aef\u8bf7\u6c42URL\u4e0e\u540e\u7aef\u8bbe\u8ba1\u7684URL\u5e76\u4e0d\u76f8\u540c\uff0c\u4f46\u80fd\u201c\u8fde\u63a5\u201d\u8d77\u6765\u3002<\/p>\n\n\n\n<p>\u8fd9\u662f\u7531Nginx\u53cd\u5411\u4ee3\u7406\u5b9e\u73b0\u7684\uff1a\u5c06\u524d\u7aef\u53d1\u9001\u7684\u52a8\u6001\u8bf7\u6c42\u8f6c\u53d1\u5230\u540e\u7aef\u670d\u52a1\u5668\u3002<\/p>\n\n\n\n<p>\u4f18\u70b9\uff1a\u63d0\u9ad8\u8bbf\u95ee\u901f\u5ea6\uff08nginx\u7f13\u5b58\uff09\u3001\u8fdb\u884c\u8d1f\u8f7d\u5747\u8861\uff08\u5373\u6b64\u5904\u901a\u8fc7\u53cd\u5411\u4ee3\u7406\u5b9e\u73b0\uff09\u3001\u4fdd\u8bc1\u540e\u7aef\u670d\u52a1\u5b89\u5168<\/p>\n\n\n\n<p>\u5177\u4f53\u5b9e\u73b0\uff1a<\/p>\n\n\n\n<p>nginx.conf\u4e2d\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#\u914d\u7f6e\u8d1f\u8f7d\u5747\u8861\u7684\u670d\u52a1\u5668\nupstream webservers{\n    server 127.0.0.1:8080 weight=90 ;\n    #server 127.0.0.1:8088 weight=10 ;\n}\n\nserver {\n    listen       80;\n    server_name  localhost;\n    \n    #\u53cd\u5411\u4ee3\u7406\u90e8\u5206\n    location \/api\/ {\n        proxy_pass   http:\/\/localhost:8080\/admin\/;\n        #proxy_pass   http:\/\/webservers\/admin\/;\n    }\n\n    location \/user\/ {\n        proxy_pass   http:\/\/webservers\/user\/;\n    }\n\n    location \/ws\/ {\n        proxy_pass   http:\/\/webservers\/ws\/;\n        proxy_http_version 1.1;\n        proxy_read_timeout 3600s;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"$connection_upgrade\";\n    }\n}\n  <\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">0.3 \u5728APIfox\u4e2d\u5bfc\u5165\u63a5\u53e3\u6587\u6863<\/h2>\n\n\n\n<p>\u4ee5\u9879\u76ee\u4e3a\u5355\u4f4d\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7ba1\u7406\u7aef\u63a5\u53e3<\/li>\n\n\n\n<li>\u7528\u6237\u7aef\u63a5\u53e3<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">0.4 Swagger:Knife4j&nbsp;\u751f\u6210API\u6587\u6863<\/h2>\n\n\n\n<p>\u7528\u4e8e\u540e\u7aef\u6d4b\u8bd5<\/p>\n\n\n\n<p>\u4f7f\u7528\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>pom\u5bfc\u5165knife4j maven\u5750\u6807<\/li>\n\n\n\n<li>\u5728\u914d\u7f6e\u7c7b\u4e2d\u52a0\u5165\u76f8\u5173\u914d\u7f6e<\/li>\n\n\n\n<li>\u8bbe\u7f6e\u9759\u6001\u8d44\u6e90\u6620\u5c04<\/li>\n<\/ol>\n\n\n\n<p><a href=\"http:\/\/localhost:8080\/doc.html#\/home\">\u82cd\u7a79\u5916\u5356\u9879\u76ee\u63a5\u53e3\u6587\u6863<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">0.5\u7406\u89e3\u521d\u59cb\u4ee3\u7801\uff1a<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">0.5.1 application.yml\u53ca\u76f8\u5173\u914d\u7f6e\u6587\u4ef6\u3001\u914d\u7f6e\u7c7b\uff1a<\/h3>\n\n\n\n<p><code>application.yml<\/code>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server:\n  port: 8080\n\nspring:\n  profiles:\n    active: dev\n  main:\n    allow-circular-references: true\n  datasource:\n    druid:\n      driver-class-name: ${sky.datasource.driver-class-name}\n      url: jdbc:mysql:\/\/${sky.datasource.host}:${sky.datasource.port}\/${sky.datasource.database}?serverTimezone=Asia\/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false&amp;allowPublicKeyRetrieval=true\n      username: ${sky.datasource.username}\n      password: ${sky.datasource.password}\n\nmybatis:\n  #mapper\u914d\u7f6e\u6587\u4ef6\n  mapper-locations: classpath:mapper\/*.xml\n  type-aliases-package: com.sky.entity\n  configuration:\n    #\u5f00\u542f\u9a7c\u5cf0\u547d\u540d\n    map-underscore-to-camel-case: true\n\nlogging:\n  level:\n    com:\n      sky:\n        mapper: debug\n        service: info\n        controller: info\n\nsky:\n  jwt:\n    # \u8bbe\u7f6ejwt\u7b7e\u540d\u52a0\u5bc6\u65f6\u4f7f\u7528\u7684\u79d8\u94a5\n    admin-secret-key: itcast\n    # \u8bbe\u7f6ejwt\u8fc7\u671f\u65f6\u95f4\n    admin-ttl: 7200000\n    # \u8bbe\u7f6e\u524d\u7aef\u4f20\u9012\u8fc7\u6765\u7684\u4ee4\u724c\u540d\u79f0\n    admin-token-name: token<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>spring: profiles: active: dev<\/code><br><code>profiles<\/code>\u7528\u4e8e\u6839\u636e\u4e0d\u540c\u7684\u73af\u5883\uff08\u5982\u5f00\u53d1\u3001\u6d4b\u8bd5\u3001\u751f\u4ea7\u7b49\uff09\u6765\u52a0\u8f7d\u4e0d\u540c\u7684\u914d\u7f6e\u3002\u8fd9\u91cc\u6fc0\u6d3b\u4e86<code>dev<\/code>\u73af\u5883\u914d\u7f6e\uff0c\u610f\u5473\u7740\u5728\u9879\u76ee\u4e2d\u6709\u5bf9\u5e94<code>application-dev.yml<\/code>\u7b49\u4ee5<code>dev<\/code>\u4e3a\u540e\u7f00\u533a\u5206\u7684\u914d\u7f6e\u6587\u4ef6\u65f6\uff0c\u4f1a\u4f18\u5148\u52a0\u8f7d\u548c\u5e94\u7528\u8fd9\u4e9b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u8bbe\u7f6e\uff08\u7528\u4e8e\u8986\u76d6\u5f53\u524d\u914d\u7f6e\u6587\u4ef6\u4e2d\u76f8\u540c\u914d\u7f6e\u9879\u7684\u5185\u5bb9\uff09\uff0c\u65b9\u4fbf\u5728\u4e0d\u540c\u73af\u5883\u4e0b\u7075\u6d3b\u5207\u6362\u914d\u7f6e\u3002<\/li>\n\n\n\n<li><code>spring: datasource: druid: ...<\/code><br>\u914d\u7f6e\u6570\u636e\u5e93\u8fde\u63a5\u76f8\u5173\u4fe1\u606f\n<ul class=\"wp-block-list\">\n<li>\u901a\u8fc7\u4f7f\u7528\u5360\u4f4d\u7b26\u5982&nbsp;<code>${sky.datasource.driver-class-name}<\/code>\uff0c\u8868\u793a\u5b9e\u9645\u7684\u6570\u636e\u5e93\u9a71\u52a8\u7c7b\u540d\u4f1a\u4ece\u4e0a\u6587\u63d0\u5230\u7684<code>application-dev.yml<\/code>\u4e2d\u914d\u7f6e\uff0c\u5982\u4e0b\uff1a<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><code>application-dev.yml<\/code>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sky:\n  datasource:\n    driver-class-name: com.mysql.cj.jdbc.Driver\n    host: localhost\n    port: 3306\n    database: sky_take_out\n    username: root\n    password: **********\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>sky.jwt\u53ca\u914d\u7f6e\u7c7b\n<ul class=\"wp-block-list\">\n<li>\u8bbe\u7f6e jwt \u7b7e\u540d\u52a0\u5bc6\u65f6\u4f7f\u7528\u7684\u79d8\u94a5<\/li>\n\n\n\n<li>\u8bbe\u7f6e jwt \u8fc7\u671f\u65f6\u95f4<\/li>\n\n\n\n<li>\u8bbe\u7f6e\u524d\u7aef\u4f20\u9012\u8fc7\u6765\u7684\u4ee4\u724c\u540d\u79f0<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>\u5728\u5bf9\u5e94\u7684\u914d\u7f6e\u7c7b\u4e2d\u4f7f\u7528\uff1a<\/p>\n\n\n\n<p>JwtPreperties,java:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Component\n@ConfigurationProperties(prefix = \"sky.jwt\")\/\/\u5bf9\u5e94\u914d\u7f6e\u6587\u4ef6\u4e2d\n@Data\npublic class JwtProperties {\n\n    \/**\n     * \u7ba1\u7406\u7aef\u5458\u5de5\u751f\u6210jwt\u4ee4\u724c\u76f8\u5173\u914d\u7f6e\n     *\/\n    private String adminSecretKey;\n    private long adminTtl;\n    private String adminTokenName;\n\n    \/**\n     * \u7528\u6237\u7aef\u5fae\u4fe1\u7528\u6237\u751f\u6210jwt\u4ee4\u724c\u76f8\u5173\u914d\u7f6e\n     *\/\n    private String userSecretKey;\n    private long userTtl;\n    private String userTokenName;\n}<\/code><\/pre>\n\n\n\n<p>\u6b64\u5904\u901a\u8fc7\u914d\u7f6e\u7c7b\uff0c\u5c06\u914d\u7f6e\u4fe1\u606f\u653e\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\uff0c<strong>\u9075\u5faa\u914d\u7f6e\u4e0e\u4ee3\u7801\u5206\u79bb\u539f\u5219<\/strong>\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">1 \u65b0\u589e\u5458\u5de5<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">1.1 \u65b0\u77e5\u8bc6\u70b9\uff1a<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1.1.1 \uff1aThreadLocal<\/h3>\n\n\n\n<p>ThreadLocal\u5e76\u4e0d\u662f\u4e00\u4e2aThread\uff0c\u800c\u662fThread\u7684\u5c40\u90e8\u53d8\u91cf\u3002\u5bf9\u4e8e\u6bcf\u4e00\u4e2a\u7ebf\u7a0b\u5355\u72ec\u63d0\u4f9b\u4e00\u4e2a\u5b58\u50a8\u7a7a\u95f4\uff0c\u53ea\u80fd\u5728\u8fd9\u4e2a\u7ebf\u7a0b\u5185\u83b7\u53d6\u3002<\/p>\n\n\n\n<p><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">\u6bcf\u6b21\u8bf7\u6c42\u90fd\u662f\u4e00\u4e2a\u5355\u72ec\u7684\u7ebf\u7a0b<\/mark><\/strong><\/p>\n\n\n\n<p>ThreadLocal \u5e38\u7528\u65b9\u6cd5\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>public void set (T value)\uff1a\u7528\u4e8e\u8bbe\u7f6e\u5f53\u524d\u7ebf\u7a0b\u7684\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf\u7684\u503c\u3002<\/li>\n\n\n\n<li>public T get ()\uff1a\u80fd\u591f\u8fd4\u56de\u5f53\u524d\u7ebf\u7a0b\u6240\u5bf9\u5e94\u7684\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf\u7684\u503c\u3002<\/li>\n\n\n\n<li>public void remove ()\uff1a\u53ef\u4ee5\u79fb\u9664\u5f53\u524d\u7ebf\u7a0b\u7684\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u5728\u672c\u8282\u5c01\u88c5\u4e3aBaseContext\uff0c\u7528\u4e8e\u5728\u62e6\u622a\u5668\u4e2d\u83b7\u53d6token\u4e2d\u7684id\uff0c\u63d0\u4f9b\u7ed9EmployeeServiceImpl\u3002<\/p>\n\n\n\n<p>\u53e6\u5916\uff0c\u6b64\u5904\u4e5f\u53ef\u4ee5\u76f4\u63a5\u83b7\u53d6\u8bf7\u6c42\u5bf9\u8c61\uff0c\u4ece\u8bf7\u6c42\u4e2d\u89e3\u6790\u5e76\u83b7\u53d6id\uff0c\u53ef\u89c1<a href=\"http:\/\/www.cmd137blog.top\/?p=626\">Javaweb-AOP \u2013 CMD137&#8217;s Blog<\/a>\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.2 \u5b9e\u73b0\uff1a<\/h2>\n\n\n\n<p>\u673a\u68b0\u5316\u7684\u64cd\u4f5c\u4e0d\u518d\u8d58\u8ff0\u3002<\/p>\n\n\n\n<p>\u6559\u7a0b\u4e2d\u5904\u7406\u7528\u6237\u540d\u5df2\u5b58\u5728\u800c\u4e0d\u8fdb\u884c\u6ce8\u518c\u7684\u5f02\u5e38\u65f6\uff0c\u76f4\u63a5\u5728\u5168\u5c40\u5f02\u5e38\u5904\u7406\u5668\u4e2d\u5904\u7406\u4e86SQLIntegrityConstraintViolationException\u5e76\u76f4\u63a5\u5904\u7406\u62a5\u9519\u4fe1\u606f\u5b57\u7b26\u4e32\u8fd4\u56deerror\uff0c\u89c9\u5f97\u8fc7\u4e8e\u7c97\u66b4\uff0c\u505a\u4ee5\u4e0b\u6539\u8fdb\uff1a<\/p>\n\n\n\n<p>\u8fd9\u91cc\u81ea\u5b9a\u4e49\u4e00\u4e2a\u5f02\u5e38UsernameAlreadyExistsException\uff0c\u5728server\u4e2dadd\u65f6\u5148\u67e5\u8be2\u5224\u65ad\u7528\u6237\u540d\u662f\u5426\u5df2\u5b58\u5728\uff0c\u82e5\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u629b\u51faUsernameAlreadyExistsException,\u5426\u5219\u5199\u5165\u6570\u636e\u5e93\u3002<\/p>\n\n\n\n<p>UsernameAlreadyExistsException.java:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.sky.exception;\n\n\/**\n * \u7528\u6237\u540d\u662f\u5426\u5df2\u5b58\u5728\u5f02\u5e38\uff0c\u4f7f\u7528\u4e8e\u65b0\u589e\u5458\u5de5\n *\/\npublic class UsernameAlreadyExistsException extends BaseException {\n    public UsernameAlreadyExistsException() {\n    }\n\n    public UsernameAlreadyExistsException(String msg) {\n        super(msg);\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>EmployeeServiceImpl\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void addEmp(EmployeeDTO employeeDTO) {\n        Employee employee = new Employee();\n        \/\/\u5bf9\u8c61\u5c5e\u6027\u62f7\u8d1d\n        BeanUtils.copyProperties(employeeDTO,employee);\n\n        employee.setStatus(StatusConstant.ENABLE);\n        employee.setCreateTime(LocalDateTime.now());\n        employee.setUpdateTime(LocalDateTime.now());\n        \/\/\u8bbe\u7f6e\u9ed8\u8ba4\u5bc6\u7801\uff1a123456\n        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));\n        \/\/\u4f7f\u7528ThreadLocal\u83b7\u53d6\u5b58\u50a8\u5728token\u4e2d\u7684id\n        employee.setCreateUser(BaseContext.getCurrentId());\n        employee.setUpdateUser(BaseContext.getCurrentId());\n\n        \/\/\u5224\u65ad\u7528\u6237\u540d\u662f\u5426\u5df2\u5b58\u5728\uff0c\u82e5\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u629b\u51faUsernameAlreadyExistsException,\u5426\u5219\u5199\u5165\u6570\u636e\u5e93\n        if (employeeMapper.getByUsername(employee.getUsername())!=null){\n            throw new UsernameAlreadyExistsException(\"\u7528\u6237\u540d\"+employee.getUsername()+\"\u5df2\u5b58\u5728\");\n        }\n\n        employeeMapper.addEmp(employee);\n    }<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">2 \u5458\u5de5\u5206\u9875\u67e5\u8be2<\/h1>\n\n\n\n<p>\u4f7f\u7528pagehelper<\/p>\n\n\n\n<p><code>PageHelper<\/code>&nbsp;\u7684\u6838\u5fc3\u539f\u7406\u662f\u901a\u8fc7\u62e6\u622a MyBatis \u7684 SQL \u6267\u884c\u8fc7\u7a0b\uff0c\u52a8\u6001\u5730\u5728\u539f\u59cb SQL \u8bed\u53e5\u4e0a\u6dfb\u52a0\u5206\u9875\u903b\u8f91\uff08\u5982&nbsp;<code>LIMIT<\/code>&nbsp;\u6216&nbsp;<code>ROWNUM<\/code>\uff09\uff0c\u4ece\u800c\u5b9e\u73b0\u5206\u9875\u67e5\u8be2\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>controller\u5bf9\u8c61\u7c7b\u578b\u5e94\u4e3aPageResult<\/li>\n\n\n\n<li>service\u5bf9\u8c61\u7c7b\u578b\u5e94\u4e3aPage\uff08T\uff09<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"> 2.1 \u65b0\u77e5\u8bc6\u70b9\uff1a<\/h2>\n\n\n\n<p>\u901a\u8fc7\u5728 WebMvcConfiguration \u4e2d\u6269\u5c55Spring MVC\u7684\u6d88\u606f\u8f6c\u6362\u5668\uff0c\u7edf\u4e00\u5bf9\u65e5\u671f\u7c7b\u578b\u8fdb\u884c\u683c\u5f0f\u5316\u5904\u7406<\/p>\n\n\n\n<p>\u5199\u6cd5\u56fa\u5b9a\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n     * \u6269\u5c55Spring MVC \u6846\u67b6\u6d88\u606f\u8f6c\u6362\u5668\n     * @param converters\n     *\/\n    protected void extendMessageConverters(List&lt;HttpMessageConverter&lt;?&gt;&gt; converters) {\n        log.info(\"\u6269\u5c55\u6d88\u606f\u8f6c\u6362\u5668...\");\n        \/\/\u521b\u5efa\u4e00\u4e2a\u6d88\u606f\u8f6c\u6362\u5668\u5bf9\u8c61\n        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();\n        \/\/\u4e3a\u6d88\u606f\u8f6c\u6362\u5668\u8bbe\u7f6e\u4e00\u4e2a\u5bf9\u8c61\u8f6c\u6362\u5668\uff0c\u5bf9\u8c61\u8f6c\u6362\u5668\u53ef\u4ee5\u5c06java\u5bf9\u8c61\u5e8f\u5217\u5316\u4e3ajson\u6570\u636e\n        converter.setObjectMapper(new JacksonObjectMapper());\n        \/\/\u5c06\u81ea\u5b9a\u4e49\u7684\u6d88\u606f\u8f6c\u6362\u5668\u52a0\u5165converters\u5bb9\u5668,0\u7528\u6765\u8bbe\u5b9a\u4f18\u5148\u7ea7\n        converters.add(0,converter);\n    }<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">3 \u542f\u7528\u7981\u7528\u5458\u5de5\u8d26\u53f7<\/h1>\n\n\n\n<p>\u518d\u5b9e\u73b0service\u5c42\u65f6\uff0c\u8003\u8651\u5230\u901a\u7528\u6027\uff0c\u4e0d\u5355\u72ec\u5b9e\u73b0\u53ea\u4fee\u6539status\u7684mapper\u5c42\uff0c\u800c\u76f4\u63a5\u5728mapper\u7f16\u5199\u901a\u8fc7id\u66f4\u65b0\u7684mapper\u4f9b\u8be5service\u4f7f\u7528\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.1 \u65b0\u77e5\u8bc6\u70b9\uff1a@Builder<\/h2>\n\n\n\n<p><code>@Builder<\/code> \u662f Lombok \u5e93\u4e2d\u7684\u4e00\u4e2a\u6ce8\u89e3\uff0c\u7528\u4e8e\u81ea\u52a8\u751f\u6210\u4e00\u4e2a\u6784\u5efa\u5668\uff08Builder\uff09\u6a21\u5f0f\u7684\u7c7b\u3002\u4f7f\u7528\u8fd9\u4e2a\u6ce8\u89e3\u53ef\u4ee5\u7b80\u5316\u5bf9\u8c61\u7684\u521b\u5efa\u8fc7\u7a0b<\/p>\n\n\n\n<p>\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Employee employee=Employee.builder()\n                .status(status)\n                .id(id)\n                .build();<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">4 \u7f16\u8f91\u5458\u5de5<\/h1>\n\n\n\n<p>\u4e0d\u53ea\u662f\u4fee\u6539\uff0c\u8fd8\u8981\u56de\u663e\uff08\u6839\u636eid\u67e5\u8be2\u4fe1\u606f\uff09<\/p>\n\n\n\n<p>\u6ce8\u610f\u9700\u8981\u518d\u6b21\u68c0\u67e5\u7528\u6237\u540d\u662f\u5426\u5df2\u5b58\u5728\u7684\u95ee\u9898\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">5 \u5206\u7c7b\u7ba1\u7406\u6a21\u5757<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5206\u7c7b\u540d\u79f0\u552f\u4e00\uff0c\u6240\u4ee5\u5bf9\u4e8e\u4fee\u6539\u548c\u65b0\u589e\u540c\u6837\u9700\u8981\u68c0\u67e5\u5206\u7c7b\u540d\u79f0\u3002\u4e0e\u4e4b\u524d\u5458\u5de5username\u540c\u6837\uff0c\u6dfb\u52a0CategoryNameAlreadyExistsException\u5f02\u5e38<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5220\u9664\u5206\u7c7b\u6ce8\u610f\u6761\u4ef6<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">6 \u516c\u5171\u5b57\u6bb5\u81ea\u52a8\u586b\u5145<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u95ee\u9898\uff1a\u89e3\u51b3\u516c\u5171\u5b57\u6bb5\u66f4\u65b0\u4ee3\u7801\u5197\u4f59\u4e0d\u6613\u7ef4\u62a4\u7684\u95ee\u9898\u3002<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5b9e\u73b0\u601d\u8def\uff1a\n<ul class=\"wp-block-list\">\n<li>\u81ea\u5b9a\u4e49\u6ce8\u89e3AutoFill\uff0c\u7528\u4e8e\u6807\u8bc6\u9700\u8981\u8fdb\u884c\u516c\u5171\u5b57\u6bb5\u81ea\u52a8\u586b\u5145\u7684\u65b9\u6cd5<\/li>\n\n\n\n<li>\u81ea\u5b9a\u4e49\u5207\u9762\u7c7bAutoFillAspect\uff0c\u7edf\u4e00\u62e6\u622a\u6807\u6ce8\u4e86AutoFill\u6ce8\u89e3\u7684\u65b9\u6cd5\uff0c\u901a\u8fc7\u53cd\u5c04\u4e3a\u516c\u5171\u5b57\u6bb5\u8d4b\u503c<\/li>\n\n\n\n<li>\u5728Mapper\u5c42\u6807\u6ce8AutoFill<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>\u81ea\u5b9a\u4e49\u6ce8\u89e3AutoFill\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface AutoFill {\n    \/\/\u6307\u5b9a\u6570\u636e\u5e93\u64cd\u4f5c\u7c7b\u578b:Update;Insert\n    OperationType value();\n}\n<\/code><\/pre>\n\n\n\n<p>\u81ea\u5b9a\u4e49\u5207\u9762\u7c7bAutoFillAspect\uff1a\u91cd\u70b9\uff01\uff01\uff01<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.sky.aspect;\n\nimport com.sky.annotation.AutoFill;\nimport com.sky.constant.AutoFillConstant;\nimport com.sky.context.BaseContext;\nimport com.sky.enumeration.OperationType;\nimport lombok.extern.slf4j.Slf4j;\nimport org.aspectj.lang.JoinPoint;\nimport org.aspectj.lang.Signature;\nimport org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.annotation.Before;\nimport org.aspectj.lang.annotation.Pointcut;\nimport org.aspectj.lang.reflect.MethodSignature;\nimport org.springframework.stereotype.Component;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.time.LocalDateTime;\n\n\/**\n * \u81ea\u5b9a\u4e49\u5207\u9762\uff0c\u5b9e\u73b0\u516c\u5171\u5b57\u6bb5\u81ea\u52a8\u586b\u5145\n *\/\n\n@Aspect\n@Component\n@Slf4j\npublic class AutoFillAspect {\n    \/\/\u5207\u9762=\u5207\u5165\u70b9+\u901a\u77e5\n\n    \/**\n     * \u5207\u5165\u70b9\n     *\/\n    @Pointcut(\"execution(* com.sky.mapper.*.*(..)) &amp;&amp; @annotation(com.sky.annotation.AutoFill)\")\n    public void autoFillPointCut(){}\n\n    \/**\n     * \u524d\u7f6e\u901a\u77e5\uff0c\u4e3a\u516c\u5171\u5b57\u6bb5\u8d4b\u503c\n     *\/\n    @Before(\"autoFillPointCut()\")\n    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {\n\n        \/\/\u83b7\u53d6\u5f53\u524d\u88ab\u62e6\u622a\u65b9\u6cd5\u7684\u6ce8\u89e3value\u503c\n        MethodSignature signature = (MethodSignature)joinPoint.getSignature();\/\/\u901a\u8fc7\u8fde\u63a5\u70b9\u83b7\u53d6\u65b9\u6cd5\u7b7e\u540d\u5bf9\u8c61\n        OperationType value = signature.getMethod().getAnnotation(AutoFill.class).value();\/\/\u901a\u8fc7\u65b9\u6cd5\u7b7e\u540d\u5bf9\u8c61\u83b7\u53d6\u6ce8\u89e3\u5bf9\u8c61\uff0c\u518d\u83b7\u53d6\u6ce8\u89e3\u5bf9\u8c61\u7684\u503c\n\n        \/\/\u83b7\u53d6\u65b9\u6cd5\u7684\u53c2\u6570\u4e2d\u7684\u5b9e\u4f53\n        Object&#91;] args = joinPoint.getArgs();\n            \/\/\u6b64\u5904\u7ea6\u5b9a\u4e86\u62e6\u622a\u65b9\u6cd5\u53ea\u6709\u4e00\u4e2a\u53c2\u6570\uff0c\u5373\u4e3a\u6240\u9700\u5b9e\u4f53\n        Object obj=args&#91;0];\n\n        \/\/\u901a\u8fc7\u53cd\u5c04\u4e3a\u5b9e\u4f53\u5bf9\u8c61\u7684\u516c\u5171\u5c5e\u6027\u8d4b\u503c\uff0c\u5206\u4e24\u79cd\u60c5\u51b5\u3001INSERT;UPDATE\n        LocalDateTime now = LocalDateTime.now();\n        Long id = BaseContext.getCurrentId();\n\n        if(value==OperationType.INSERT){\n            log.info(\"\u4e3a\u516c\u5171\u5b57\u6bb5\u8d4b\u503c:INSERT\");\n\n            Method setCreateTime = obj.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);\n            setCreateTime.invoke(obj, now);\n\n            Method setCreateUser = obj.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);\n            setCreateUser.invoke(obj, id);\n\n            Method setUpdateTime = obj.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);\n            setUpdateTime.invoke(obj, now);\n\n            Method setUpdateUser = obj.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);\n            setUpdateUser.invoke(obj, id);\n\n        }else if (value==OperationType.UPDATE){\n            log.info(\"\u4e3a\u516c\u5171\u5b57\u6bb5\u8d4b\u503c:UPDATE\");\n\n            Method setUpdateTime = obj.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);\n            setUpdateTime.invoke(obj, now);\n\n            Method setUpdateUser = obj.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);\n            setUpdateUser.invoke(obj, id);\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">7 \u65b0\u589e\u83dc\u54c1\uff1a\uff08\u4e91OSS\u5b58\u50a8\uff09<\/h1>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7.1 \u6587\u4ef6\u4e0a\u4f20<\/h2>\n\n\n\n<p><br>1.\u963f\u91cc\u4e91oss\u521b\u5efabucket<\/p>\n\n\n\n<p>2.\u5728yml\u6587\u4ef6\u4e2d\u8fdb\u884cendpoint\u3001accesskey\uff1aid\uff0csecret\uff1bbucket-name\u7684\u914d\u7f6e<\/p>\n\n\n\n<p>3.\u521b\u5efaOssConfiguration\u914d\u7f6e\u7c7b\u5e76\u5c06AliOssUtil\u5bf9\u8c61\u4ea4\u7ed9\u5bb9\u5668\u7ba1\u7406\uff08\u5e94\u7528\u542f\u52a8\u5c31\u4f1a\u521b\u5efa\u5bf9\u8c61\uff09<\/p>\n\n\n\n<p>4.\u5728CommonController\u4e2d\u8fdb\u884c\u5904\u7406\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@PostMapping(\"\/upload\")\n    @ApiOperation(\"\u6587\u4ef6\u4e0a\u4f20\")\n    public Result&lt;String&gt; upload(MultipartFile file){\n        log.info(\"\u6587\u4ef6\u4e0a\u4f20{}\",file);\n\n        try {\n            \/\/\u539f\u59cb\u6587\u4ef6\u540d\n            String originalFilename = file.getOriginalFilename();\n            \/\/\u622a\u53d6\u539f\u59cb\u6587\u4ef6\u540d\u7684\u62d3\u5c55\u540d\n            String extension = originalFilename.split(\"\\\\.\")&#91;1];\n            \/\/\u6784\u5efa\u65b0\u6587\u4ef6\u540d\u79f0\n            String objectName = UUID.randomUUID().toString() + extension;\n\n            \/\/\u6587\u4ef6\u8bf7\u6c42\u8def\u5f84\n            String filePath = aliOssUtil.upload(file.getBytes(), objectName);\n            return Result.success(filePath);\n        } catch (IOException e) {\n            log.error(\"\u6587\u4ef6\u4e0a\u4f20\u5931\u8d25\uff1a{}\",e);\n        }\n        return Result.error(MessageConstant.UPLOAD_FAILED);\n    }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">7.2 \u65b0\u589e\u83dc\u54c1 \u6b64\u5904\u64cd\u4f5c\u4e24\u5f20\u8868\uff1a\u83dc\u54c1\u8868&#8212;-1:n&#8212;&gt;\u53e3\u5473\u8868<\/h2>\n\n\n\n<p>\u6d89\u53ca\u591a\u8868\u64cd\u4f5c\uff0c\u9700\u8981@Transactional\u4e8b\u52a1\u6ce8\u89e3\u4fdd\u8bc1\u65b9\u6cd5\u539f\u5b50\u6027\uff08\u5728\u542f\u52a8\u7c7b<code>@EnableTransactionManagement<\/code>&nbsp;\u6ce8\u89e3\u6765\u542f\u7528\u57fa\u4e8e\u6ce8\u89e3\u7684\u4e8b\u52a1\u7ba1\u7406\uff09<\/p>\n\n\n\n<p>\u64cd\u4f5c\u4e24\u5f20\u8868\uff0c\u5219\u9700\u4e24\u4e2aMapper\u3002\u6bcf\u6b21\u65b0\u589e\u83dc\u54c1\uff0c\u5728DishMapper\u4e2d\u63d2\u5165\u4e00\u6761\u6570\u636e\uff0c\u5728DishFlavorMapper\u4e2d\u63d2\u5165n\u6761\u6570\u636e\uff08\u4f7f\u7528\u6279\u91cf\u63d2\u5165\uff09\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;insert id=\"insertBatch\"&gt;\n        insert into dish_flavor (dish_id, name, value) values \n        &lt;foreach collection=\"flavors\" item=\"df\" separator=\",\"&gt;\n            (#{df.dishId},#{df.name},#{df.value})\n        &lt;\/foreach&gt;\n    &lt;\/insert&gt;<\/code><\/pre>\n\n\n\n<p>\u5728\u63d2\u5165\u53e3\u5473\u6570\u636e\u65f6\uff0c\u9700\u8981\u83b7\u53d6dishId\uff0c\u5219\u9700\u8981\u5728\u63d2\u5165dish\u65f6<strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">\u4e3b\u952e\u56de\u663e<\/mark><\/strong>\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>useGeneratedKeys = true<\/code>\uff1a\u8868\u793a\u4f7f\u7528\u6570\u636e\u5e93\u81ea\u52a8\u751f\u6210\u7684\u4e3b\u952e\u3002<\/li>\n\n\n\n<li><code>keyProperty = \"id\"<\/code>\uff1a\u6307\u5b9a\u5c06\u751f\u6210\u7684\u4e3b\u952e\u503c\u8d4b\u7ed9\u5b9e\u4f53\u7c7b\u4e2d\u7684\u54ea\u4e2a\u5c5e\u6027\u3002<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;insert id=\"add\" useGeneratedKeys=\"true\" keyProperty=\"id\"&gt;\n        INSERT INTO dish (name, category_id, price, image, description, create_time, update_time, create_user, update_user, status)\n        VALUES (#{name}, #{categoryId}, #{price}, #{image}, #{description}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser}, #{status})\n    &lt;\/insert&gt;<\/code><\/pre>\n\n\n\n<p><strong>\u4e3b\u952e\u56de\u663e\u540e\uff0c\u751f\u6210\u7684\u4e3b\u952e\u503c\u4f1a\u88ab\u8bbe\u7f6e\u5230\u4f20\u5165\u7684\u5b9e\u4f53\u5bf9\u8c61\u4e2d<\/strong>\u3002\u5219\u53ef\u5728service\u4e2d\u64cd\u4f5c\u5b9e\u4f53\u5bf9\u8c61\u83b7\u53d6ID\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">8 \u83dc\u54c1\u5206\u9875\u67e5\u8be2 \uff08\u591a\u8868\u67e5\u8be2\uff09<\/h1>\n\n\n\n<p>\u7531\u4e8ecategoryName\u5b57\u6bb5\uff0c\u9700\u8981\u591a\u8868\u67e5\u8be2\uff0c\u8fd9\u91cc\u4f7f\u7528dish\u8868\u5de6\u5916\u8fde\u63a5category\u8868<\/p>\n\n\n\n<p>\u6ce8\u610f\uff1a\u5bf9\u5e94 DishVO\uff0c\u9700\u8981\u7ed9 c.name \u7528 as \u8d77\u522b\u540d categoryName<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;select id=\"pageQuery\" resultType=\"com.sky.vo.DishVO\"&gt;\n        SELECT d.*,c.name as categoryName from dish d left outer join sky_take_out.category c on d.category_id = c.id\n        &lt;where&gt;\n            &lt;if test=\"name !=null\"&gt;\n                and d.name like concat('%',#{name},'%')\n            &lt;\/if&gt;\n            &lt;if test=\"categoryId !=null\"&gt;\n                and d.category_id = #{categoryId}\n            &lt;\/if&gt;\n            &lt;if test=\"status !=null\"&gt;\n                and d.status  = #{status}\n            &lt;\/if&gt;\n        &lt;\/where&gt;\n        order by d.create_time DESC\n    &lt;\/select&gt;<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">9 \u5220\u9664\u83dc\u54c1<\/h1>\n\n\n\n<p>\u7531\u4e8e\u662f\u6279\u91cf\u5220\u9664\u83dc\u54c1\uff0c\u524d\u7aef\u8bf7\u6c42\u53c2\u6570\uff1aids string&nbsp;\u83dc\u54c1id\uff0c\u4e4b\u95f4\u7528\u9017\u53f7\u5206\u9694\u3002\u793a\u4f8b\u503c: 1,2,3<\/p>\n\n\n\n<p>\u4f7f\u7528<code>@RequestParam<\/code>&nbsp; \u81ea\u52a8\u7c7b\u578b\u8f6c\u6362\uff1a<a href=\"http:\/\/www.cmd137blog.top\/?p=399\">\u5c0f\u77e5\u8bc6\u70b9\u5408\u96c6\uff08\u6301\u7eed\u66f4\u65b0\uff09 \u2013 CMD137&#8217;s Blog<\/a>\u89c116<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@DeleteMapping\n    @ApiOperation(\"\u6279\u91cf\u5220\u9664\u83dc\u54c1\")\n    public Result delete(@RequestParam List&lt;Long&gt; ids){\n        log.info(\"\u6279\u91cf\u5220\u9664\u83dc\u54c1:{}\",ids);\n        dishService.delete(ids);\n        return Result.success();\n    }<\/code><\/pre>\n\n\n\n<p>\u5728Service\u4e2d\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em>\/**\n * \u6279\u91cf\u5220\u9664\u83dc\u54c1\n * <\/em><strong><em>@param <\/em><\/strong><em>ids\n * <\/em><strong><em>@return\n <\/em><\/strong><em>*\/\n<\/em>@Transactional\npublic void deleteBatch(List&lt;Long&gt; ids) {\n    \/\/\u6b64\u5904\u4e1a\u52a1\u903b\u8f91\u8bbe\u5b9a\uff1a\u5f53\u5176\u4e2d\u4e00\u4e2a\u4e0d\u80fd\u5220\u9664\u65f6\uff0c\u5176\u4ed6\u6ee1\u8db3\u5220\u9664\u89c4\u5219\u7684\u4e5f\u4e0d\u5220\u9664\uff0c\u629b\u51fa\u4e0d\u53ef\u5220\u9664\u5f02\u5e38\n\n    \/\/\u5224\u65ad\u5f53\u524d\u83dc\u54c1\u662f\u5426\u80fd\u591f\u5220\u9664\n    \/\/\u662f\u5426\u8d77\u552e\u4e2d\uff1f\n    for (Long id:ids){\n        Dish dish = dishMapper.getById(id);\n        if (dish.getStatus().equals(StatusConstant.<em>ENABLE<\/em>))\n            throw new DeletionNotAllowedException(MessageConstant.<em>DISH_ON_SALE<\/em>);\n    }\n    \/\/\u662f\u5426\u5c5e\u4e8e\u67d0\u4e2a\u5957\u9910\n    List&lt;Long&gt; setmealIds = setmealDishMapper.getSetmealIdsByDishIds(ids);\n    if(!setmealIds.isEmpty())\n        throw new DeletionNotAllowedException(MessageConstant.<em>DISH_BE_RELATED_BY_SETMEAL<\/em>);\n\n    \/\/\u5220\u9664\u83dc\u54c1\u5173\u8054\u7684\u53e3\u5473\u6570\u636e \u548c \u83dc\u54c1\u8868\u4e2d\u7684\u83dc\u54c1\u6570\u636e\n    for (Long id:ids){\n        dishFlavorMapper.deleteById(id);\n        dishMapper.deleteById(id);\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u5f53\u524d\u4ee3\u7801\u662f\u901a\u8fc7\u5faa\u73af\u904d\u5386&nbsp;<code>ids<\/code>&nbsp;\u5217\u8868\uff0c\u5bf9\u6bcf\u4e2a&nbsp;<code>id<\/code>&nbsp;\u5206\u522b\u8c03\u7528&nbsp;<code>deleteById<\/code>&nbsp;\u65b9\u6cd5\u8fdb\u884c\u5220\u9664\u64cd\u4f5c\uff0c\u8fd9\u4f1a\u4ea7\u751f\u591a\u6b21\u6570\u636e\u5e93\u4ea4\u4e92\uff0c\u589e\u52a0\u4e86\u6570\u636e\u5e93\u7684\u8d1f\u62c5\u548c\u64cd\u4f5c\u7684\u65f6\u95f4\u5f00\u9500\u3002\u66f4\u597d\u7684\u505a\u6cd5\u662f\u4f7f\u7528\u6279\u91cf\u5220\u9664\u529f\u80fd\uff0c\u51cf\u5c11\u4e0e\u6570\u636e\u5e93\u7684\u4ea4\u4e92\u6b21\u6570\u3002\u8fdb\u884c\u4f18\u5316\uff1a<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>mapper\uff1a<\/p>\n\n\n\n<p><em>\u6839\u636e\u83dc\u54c1<\/em><em>Id<\/em><em>\u67e5\u8be2\u5957\u9910<\/em><em>Id<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!--&gt;\u539f\u59cbSQL\u4e3a\uff1a select setmeal_id from setmeal_dish where setmeal_id in (1,2,65,29,...)  &lt;!--&gt;<br>&lt;select id=\"getSetmealIdsByDishIds\" resultType=\"java.lang.Long\"&gt;<br>    select setmeal_id from setmeal_dish where dish_id in<br>    &lt;foreach collection=\"dishIds\" item=\"dishId\" separator=\",\" open=\"(\" close=\")\"&gt;<br>        #{dishId}<br>    &lt;\/foreach&gt;<br>&lt;\/select&gt;<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">10 \u66f4\u65b0\u83dc\u54c1<\/h1>\n\n\n\n<p>\u4fee\u6539\u83dc\u54c1\u65f6\uff1a\u53ef\u76f4\u63a5update<\/p>\n\n\n\n<p>\u4fee\u6539\u83dc\u54c1\u53e3\u5473\u65f6\uff1a\u53ef\u80fd\u4f1a\u6709\u65b0\u589e\u53e3\u5473\u3001\u5220\u9664\u53e3\u5473\u6216\u4fee\u6539\u53e3\u5473\u7b49\u591a\u79cd\u64cd\u4f5c\u3002\u5148\u5220\u9664\u539f\u6709\u7684\u53e3\u5473\u8bb0\u5f55\uff0c\u518d\u91cd\u65b0\u63d2\u5165\u65b0\u7684\u53e3\u5473\u8bb0\u5f55\uff0c\u53ef\u4ee5\u66f4\u65b9\u4fbf\u5730\u5904\u7406\u8fd9\u4e9b\u590d\u6742\u7684\u64cd\u4f5c\uff0c\u907f\u514d\u4e86\u9010\u4e2a\u5224\u65ad\u54ea\u4e9b\u53e3\u5473\u9700\u8981\u66f4\u65b0\u3001\u54ea\u4e9b\u9700\u8981\u5220\u9664\u3001\u54ea\u4e9b\u9700\u8981\u65b0\u589e\u7684\u590d\u6742\u903b\u8f91\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void updateWithFlavor(DishDTO dishDTO) {\n        Dish dish = new Dish();\n        BeanUtils.copyProperties(dishDTO, dish);\n        List&lt;DishFlavor&gt; flavors = dishDTO.getFlavors();\n        \n        \/\/\u66f4\u65b0\u83dc\u54c1\n        dishMapper.update(dish);\n        \/\/\u66f4\u65b0\u83dc\u54c1\u5bf9\u5e94\u7684\u53e3\u5473\n        dishFlavorMapper.deleteById(dish.getId());\n        \/\/\u7531\u4e8e\u63a5\u53e3\u4e2ddishId\u53ef\u9009(\u5b9e\u9645\u539f\u56e0\u662f\u65b0\u7684\u53e3\u5473\u6ca1\u6709dishId),\u9700\u8981\u91cd\u65b0\u8bbe\u7f6edishId\n        if(flavors != null &amp;&amp; !flavors.isEmpty()){\n            flavors.forEach(dishFlavor -&gt; {\n                dishFlavor.setDishId(dish.getId());\n            });\n            dishFlavorMapper.insertBatch(flavors);\n        }\n    }<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">10 \u5957\u9910\u76f8\u5173\uff1a<\/h1>\n\n\n\n<p>\u4fee\u6539\u5957\u9910\u6a21\u5757\u5f00\u53d1\u65f6\u53d1\u73b0\u8981\u68c0\u67e5\u5b57\u6bb5\u552f\u4e00\u6027\u65f6\u903b\u8f91\u4e0e\u65b0\u589e\u5e76\u4e0d\u5b8c\u5168\u76f8\u540c\uff0c\u4e0d\u80fd\u7b80\u5355\u7684CV\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\u5224\u65ad\u5957\u9910\u540d\u79f0name\u662f\u5426\u5df2\u5b58\u5728\uff0c\u82e5\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u629b\u51faSetmealNameAlreadyExistsException\n        if (setmealMapper.getByName(setmealDTO.getName()) != null){\n            throw new SetmealNameAlreadyExistsException(\"\u5957\u9910\u540d\u79f0\"+setmealDTO.getName()+\"\u5df2\u5b58\u5728\");\n        }<\/code><\/pre>\n\n\n\n<p>\u8fd9\u6837\u5199\u5728\u65b0\u589e\u64cd\u4f5c\u65f6\u6b63\u786e\uff0c\u4f46\u662f\u5728\u4fee\u6539\u64cd\u4f5c\u4e2d\uff0c\u5f53\u524d\u4ee3\u7801\u76f4\u63a5\u68c0\u67e5\u5957\u9910\u540d\u79f0\u662f\u5426\u5df2\u5b58\u5728\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4e00\u4e2a\u95ee\u9898\uff1a\u5982\u679c\u7528\u6237\u53ea\u662f\u4fee\u6539\u4e86\u5957\u9910\u7684\u5176\u4ed6\u4fe1\u606f\uff0c\u800c\u5957\u9910\u540d\u79f0\u6ca1\u6709\u6539\u53d8\uff0c\u6b64\u65f6\u68c0\u67e5\u4e5f\u4f1a\u5224\u5b9a\u540d\u79f0\u5df2\u5b58\u5728\u5e76\u629b\u51fa\u5f02\u5e38\u3002<strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">\u5e94\u8be5\u8fd8\u8981\u6392\u9664\u5f53\u524d\u8981\u4fee\u6539\u7684\u5957\u9910\u672c\u8eab<\/mark><\/strong>\uff1a\uff08\u4e3a\u8d76\u8fdb\u5ea6\uff0c\u6b64\u5904\u5bf9\u4e4b\u524d\u7684\u66f4\u65b0\u64cd\u4f5c\u4e0d\u518d\u505a\u51fa\u4fee\u6b63\uff09<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\u6392\u9664name\u4e0d\u53d8\uff0c\u5224\u65ad\u5957\u9910\u540d\u79f0name\u662f\u5426\u5df2\u5b58\u5728\uff0c\u82e5\u5df2\u7ecf\u5b58\u5728\uff0c\uff0c\u5219\u629b\u51faSetmealNameAlreadyExistsException\n        if (setmealMapper.getById(setmealDTO.getId()).getName().equals(setmealDTO.getName())){\n            \/\/name\u4e0d\u53d8\n        }else if (setmealMapper.getByName(setmealDTO.getName()) != null){\n            throw new SetmealNameAlreadyExistsException(\"\u5957\u9910\u540d\u79f0\"+setmealDTO.getName()+\"\u5df2\u5b58\u5728\");\n        }<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">11 \u5e97\u94fa\u8425\u4e1a\u72b6\u6001\u8bbe\u7f6e\uff08Redis\uff09<\/h1>\n\n\n\n<p><a href=\"http:\/\/www.cmd137blog.top\/?p=698\">Redis \u2013 CMD137&#8217;s Blog<\/a><\/p>\n\n\n\n<p>\u6ce8\u610f\uff1a<\/p>\n\n\n\n<p><strong>\u4f7f\u7528\u914d\u7f6e\u6587\u4ef6\uff0c\u5219\u5728\u542f\u52a8\u65f6\u5fc5\u987b\u6307\u5b9a\u6240\u4f7f\u7528\u7684\u914d\u7f6e\u6587\u4ef6\u3002\u5982\u679c\u4e0d\u4f7f\u7528\u914d\u7f6e\u6587\u4ef6\uff0cRedis \u4f1a\u4f7f\u7528\u9ed8\u8ba4\u53c2\u6570\u8fd0\u884c\uff1b<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>\u7531\u4e8e\u64cd\u4f5c\u7b80\u5355\uff0c\u6240\u4ee5\u76f4\u63a5\u5728controller\u5c42\u5904\u7406\uff1a<\/p>\n\n\n\n<p>\u6b64\u5904\u5bf9\u6559\u7a0b\u4f5c\u51fa\u6539\u52a8\uff1a\u6dfb\u52a0\u4e86\u9ed8\u8ba4\u8425\u4e1a\u72b6\u6001<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@GetMapping(\"\/status\")\n    @ApiOperation(\"\u83b7\u53d6\u8425\u4e1a\u72b6\u6001\")\n    public Result&lt;Integer&gt; getShopStatus(){\n        log.info(\"Admin\u83b7\u53d6\u5e97\u94fa\u8425\u4e1a\u72b6\u6001\");\n        Object value = redisTemplate.opsForValue().get(KEY);\n        if (value == null) {\n            \/\/ \u82e5 Redis \u4e2d\u6ca1\u6709\u503c\uff0c\u8fd4\u56de\u9ed8\u8ba4\u8425\u4e1a\u72b6\u6001\n            return Result.success(DEFAULT_SHOP_STATUS);\n        }\n        return Result.success((Integer) value);\n    }<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">12 \u5fae\u4fe1\u767b\u9646<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">12.1 \u767b\u5f55\u6d41\u7a0b\uff1a<\/h2>\n\n\n\n<p><a href=\"https:\/\/developers.weixin.qq.com\/miniprogram\/dev\/framework\/open-ability\/login.html\">\u5f00\u653e\u80fd\u529b \/ \u7528\u6237\u4fe1\u606f \/ \u5c0f\u7a0b\u5e8f\u767b\u5f55<\/a><\/p>\n\n\n\n<p><a href=\"http:\/\/www.cmd137blog.top\/?p=705\">HttpClient \u2013 CMD137&#8217;s Blog<\/a><\/p>\n\n\n\n<p>\u901a\u8fc7\u5fae\u4fe1\u767b\u5f55\u7684\u6d41\u7a0b\uff0c\u5982\u679c\u8981\u5b8c\u6210\u5fae\u4fe1\u767b\u5f55\u7684\u8bdd\uff0c\u6700\u7ec8\u5c31\u8981\u83b7\u5f97\u5fae\u4fe1\u7528\u6237\u7684openid\u3002\u5728\u5c0f\u7a0b\u5e8f\u7aef\u83b7\u53d6\u6388\u6743\u7801\u540e\uff0c\u5411\u540e\u7aef\u670d\u52a1\u53d1\u9001\u8bf7\u6c42\uff0c\u5e76\u643a\u5e26\u6388\u6743\u7801\uff0c\u8fd9\u6837\u540e\u7aef\u670d\u52a1\u5728\u6536\u5230\u6388\u6743\u7801\u540e\uff0c\u5c31\u53ef\u4ee5\u53bb\u8bf7\u6c42\u5fae\u4fe1\u63a5\u53e3\u670d\u52a1\u3002\u6700\u7ec8\uff0c\u540e\u7aef\u5411\u5c0f\u7a0b\u5e8f\u8fd4\u56deid\u3001openid\u3001token\u6570\u636e\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">12.2 \u4ee3\u7801\uff1a<\/h2>\n\n\n\n<p>Controller\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@PostMapping(\"\/login\")\n    @ApiOperation(\"\u5fae\u4fe1\u767b\u5f55\")\n    public Result&lt;UserLoginVO&gt; login(@RequestBody UserLoginDTO userLoginDTO)  {\n        log.info(\"\u5fae\u4fe1\u767b\u5f55:{}\",userLoginDTO);\n\n        \/\/\u8bf7\u6c42\u5fae\u4fe1\u63a5\u53e3\n        User user = userService.wxLogin(userLoginDTO);\n\n        \/\/\u4e3a\u5fae\u4fe1\u7528\u6237\u751f\u6210jwt\u4ee4\u724c\n        Map&lt;String, Object&gt; claims =new HashMap&lt;&gt;();\n        claims.put(\"userId\",user.getId());\n        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);\n\n        UserLoginVO userLoginVO = UserLoginVO.builder()\n                .id(user.getId())\n                .token(token)\n                .openid(user.getOpenid())\n                .build();\n\n        return Result.success(userLoginVO);\n    }<\/code><\/pre>\n\n\n\n<p>Service\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public User wxLogin(UserLoginDTO userLoginDTO) {<br>    \/\/1.\u8c03\u7528\u5fae\u4fe1\u63a5\u53e3\uff0c\u53d1\u9001appid+appsecret+code\uff0c\u83b7\u53d6session_key\u548copenid<br>    \/\/\u7f16\u5199\u8bf7\u6c42<br>    Map&lt;String, String&gt; maps=new HashMap&lt;&gt;();<br>    maps.put(\"appid\",weChatProperties.getAppid());<br>    maps.put(\"secret\",weChatProperties.getSecret());<br>    maps.put(\"js_code\",userLoginDTO.getCode());<br>    maps.put(\"grant_type\",\"authorization_code\");<br><br>    \/\/\u53d1\u9001\u3001\u63a5\u6536\u8bf7\u6c42\u5e76\u5904\u7406\u7ed3\u679c(\u5f97\u5230openid)<br>    String json = HttpClientUtil.<em>doGet<\/em>(<em>WX_LOGIN<\/em>, maps);<br>    JSONObject jsonObject = JSON.<em>parseObject<\/em>(json);<br>    String openid = jsonObject.getString(\"openid\");<br><br>    \/\/\u5224\u65adopenid\u662f\u5426\u4e3a\u7a7a\uff0c\u5982\u679c\u4e3a\u7a7a\u5219\u8868\u793a\u767b\u5f55\u5931\u8d25,\u629b\u51fa\u4e1a\u52a1\u5f02\u5e38<br>    if (openid == null){<br>        throw new LoginFailedException(MessageConstant.<em>LOGIN_FAILED<\/em>);<br>    }<br><br>    \/\/\u5224\u65ad\u5f53\u524d\u7528\u6237\u662f\u5426\u4e3a\u65b0\u7528\u6237<br>    User user= userMapper.getByOpenid(openid);<br><br>    \/\/\u5982\u679c\u662f\u65b0\u7528\u6237\uff0c\u5219\u6ce8\u518c<br>    if (user==null){<br>        user = User.<em>builder<\/em>()<br>                .openid(openid)<br>                .createTime(LocalDateTime.<em>now<\/em>())<br>                .build();<br>        userMapper.insert(user);<br>    }<br><br>    return user;<br>}<\/pre>\n\n\n\n<p>\u6b64\u5916\uff0c\u8fd8\u6709\u9762\u5411\u7528\u6237\u7aef\u7684\u62e6\u622a\u5668\u53ca\u62e6\u622a\u5668\u7684\u6ce8\u518c<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">13 \u5546\u54c1\u6d4f\u89c8\u529f\u80fd\u4ee3\u7801\u9009\u62e9\u76f4\u63a5\u5bfc\u5165\u3002<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">14 \u7f13\u5b58\u83dc\u54c1\uff1a<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">14.1 \u67e5\u8be2\u548c\u7f13\u5b58<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>@GetMapping(\"\/list\")\n    @ApiOperation(\"\u6839\u636e\u5206\u7c7bid\u67e5\u8be2\u83dc\u54c1\")\n    public Result&lt;List&lt;DishVO&gt;&gt; list(Long categoryId) {\n        log.info(\"\u6839\u636e\u5206\u7c7bid\u67e5\u8be2\u83dc\u54c1:{}\",categoryId);\n\n        String key = \"dishes_\"+categoryId;\n\n        \/\/\u5148\u5728\u7f13\u5b58\u4e2d\u67e5\u8be2\n        List&lt;DishVO&gt; list = (List&lt;DishVO&gt;) redisTemplate.opsForValue().get(key);\n\n        \/\/\u5982\u679c\u67e5\u5230\uff0c\u76f4\u63a5\u8fd4\u56de\n        if (list!=null&amp;&amp;list.size()&gt;0){\n            return Result.success(list);\n        }else {\n            \/\/\u5982\u679c\u7f13\u5b58\u4e2d\u6ca1\u6709\uff0c\u67e5\u8be2\u6570\u636e\u5e93\uff0c\u518d\u5199\u5165\u7f13\u5b58\n            Dish dish = new Dish();\n            dish.setCategoryId(categoryId);\n            dish.setStatus(StatusConstant.ENABLE);\/\/\u67e5\u8be2\u8d77\u552e\u4e2d\u7684\u83dc\u54c1\n            list = dishService.listWithFlavor(dish);\n\n            redisTemplate.opsForValue().set(key,list);\n\n            return Result.success(list);\n        }\n    }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">14.2 \u6e05\u7406\u7f13\u5b58<\/h2>\n\n\n\n<p>\u4e3a\u4fdd\u8bc1\u6570\u636e\u4e00\u81f4\u6027\uff0c\u5728\u7ba1\u7406\u7aef\u7684\u65b0\u589e\u3001\u4fee\u6539\u3001\u5220\u9664\u64cd\u4f5c\u90fd\u9700\u8981\u6e05\u7406\u7f13\u5b58\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> public Result add(@RequestBody DishDTO dishDTO){\n        log.info(\"\u65b0\u589e\u83dc\u54c1\");\n        dishService.add(dishDTO);\n\n        \/\/\u6e05\u7406\u7f13\u5b58\u6570\u636e\uff1a\u65b0\u589e\u83dc\u54c1\u6240\u5728\u7684list\u7684\u6570\u636e\n        String key=\"dishes_\"+dishDTO.getCategoryId();\n        redisTemplate.delete(key);\n\n        return Result.success();\n    }\n\n\/**\n     * \u6e05\u7406\u7f13\u5b58\u6570\u636e\n     * @param pattern\n     *\/\n    private void cleanCache(String pattern){\n        Set keys = redisTemplate.keys(pattern);\n        redisTemplate.delete(keys);\n    }\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">15 \u7f13\u5b58\u5957\u9910\uff08Spring Cache\uff09<\/h1>\n\n\n\n<p><a href=\"http:\/\/www.cmd137blog.top\/?p=715\">Spring Cache \u2013 CMD137&#8217;s Blog<\/a><\/p>\n\n\n\n<p>\u4f7f\u7528@Cacheable\u6ce8\u89e3\u65f6\u6ce8\u610f\u6709\u4e24\u4e2a\u5305\uff0c\u5bfc\u5165spring\u5b98\u65b9\u7684\u3002\u8bb0\u5f97\u5728\u542f\u52a8\u7c7b\u52a0\u4e0a@EnableCaching<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">16 \u8d2d\u7269\u8f66\uff1a<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">16.1 \u6dfb\u52a0\u8d2d\u7269\u8f66\uff1a<\/h2>\n\n\n\n<p>\u6ce8\u610f\u4f53\u4f1a\u8fd9\u91cc\u7ed9\u5df2\u5b58\u5728\u6570\u636e\u76f4\u63a5\u6570\u91cf+1\u7684\u5199\u6cd5\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void addShoppingCart(ShoppingCartDTO shoppingCartDTO) {\n        ShoppingCart shoppingCart = new ShoppingCart();\n        BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);\n        \/\/\u53ea\u80fd\u67e5\u8be2\u81ea\u5df1\u7684\u8d2d\u7269\u8f66\u6570\u636e\n        shoppingCart.setUserId(BaseContext.getCurrentId());\n\n        \/\/\u5224\u65ad\u5f53\u524d\u5546\u54c1\u662f\u5426\u5728\u8d2d\u7269\u8f66\u4e2d (\u6b64\u5904\u8fd4\u56de\u7ed3\u679c\u53ea\u6709\u4e00\u6761\uff0c\u7528list\u662f\u4e3a\u4e86\u65b9\u6cd5\u590d\u7528)\n        List&lt;ShoppingCart&gt; shoppingCartList = shoppingCartMapper.list(shoppingCart);\n\n        if (shoppingCartList != null &amp;&amp; shoppingCartList.size() == 1) {\n            \/\/\u5982\u679c\u5df2\u7ecf\u5b58\u5728\uff0c\u5c31\u66f4\u65b0\u6570\u91cf\uff0c\u6570\u91cf\u52a01\n            shoppingCart = shoppingCartList.get(0);\n            shoppingCart.setNumber(shoppingCart.getNumber() + 1);\n            shoppingCartMapper.updateNumberById(shoppingCart);\n        } else {\n            \/\/\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u63d2\u5165\u6570\u636e\n\n            \/\/\u5224\u65ad\u5f53\u524d\u6dfb\u52a0\u5230\u8d2d\u7269\u8f66\u7684\u662f\u83dc\u54c1\u8fd8\u662f\u5957\u9910\n            Long dishId = shoppingCartDTO.getDishId();\n            if (dishId != null) {\n                \/\/\u6dfb\u52a0\u5230\u8d2d\u7269\u8f66\u7684\u662f\u83dc\u54c1\n                Dish dish = dishMapper.getById(dishId);\n                shoppingCart.setName(dish.getName());\n                shoppingCart.setImage(dish.getImage());\n                shoppingCart.setAmount(dish.getPrice());\n            } else {\n                \/\/\u6dfb\u52a0\u5230\u8d2d\u7269\u8f66\u7684\u662f\u5957\u9910\n                Setmeal setmeal = setmealMapper.getById(shoppingCartDTO.getSetmealId());\n                shoppingCart.setName(setmeal.getName());\n                shoppingCart.setImage(setmeal.getImage());\n                shoppingCart.setAmount(setmeal.getPrice());\n            }\n            shoppingCart.setNumber(1);\n            shoppingCart.setCreateTime(LocalDateTime.now());\n            shoppingCartMapper.insert(shoppingCart);\n        }\n    }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">16.2 \u5220\u9664\u8d2d\u7269\u8f66\u4e2d\u4e00\u4e2a\u5546\u54c1\uff1a<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>public void subOne(ShoppingCartDTO shoppingCartDTO) {\n        ShoppingCart shoppingCart = new ShoppingCart();\n        BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);\n        \/\/\u8bbe\u7f6e\u67e5\u8be2\u6761\u4ef6\uff0c\u67e5\u8be2\u5f53\u524d\u767b\u5f55\u7528\u6237\u7684\u8d2d\u7269\u8f66\u6570\u636e\n        shoppingCart.setUserId(BaseContext.getCurrentId());\n\n        List&lt;ShoppingCart&gt; list = shoppingCartMapper.list(shoppingCart);\n\n        if(list != null &amp;&amp; list.size() &gt; 0){\n            shoppingCart = list.get(0);\n\n            Integer number = shoppingCart.getNumber();\n            if(number == 1){\n                \/\/\u5f53\u524d\u5546\u54c1\u5728\u8d2d\u7269\u8f66\u4e2d\u7684\u4efd\u6570\u4e3a1\uff0c\u76f4\u63a5\u5220\u9664\u5f53\u524d\u8bb0\u5f55\n                shoppingCartMapper.deleteById(shoppingCart.getId());\n            }else {\n                \/\/\u5f53\u524d\u5546\u54c1\u5728\u8d2d\u7269\u8f66\u4e2d\u7684\u4efd\u6570\u4e0d\u4e3a1\uff0c\u4fee\u6539\u4efd\u6570\u5373\u53ef\n                shoppingCart.setNumber(shoppingCart.getNumber() - 1);\n                shoppingCartMapper.updateNumberById(shoppingCart);\n            }\n        }\n    }<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">17 \u5730\u5740\u7c3f\u529f\u80fd\u76f4\u63a5\u5bfc\u5165<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">18 \u7528\u6237\u4e0b\u5355\uff1a<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">18.1 \u4e1a\u52a1\u903b\u8f91\uff1a<\/h2>\n\n\n\n<p>1.\u5904\u7406\u4e1a\u52a1\u5f02\u5e38\uff1a\u5730\u5740\u7c3f\u4e3a\u7a7a\u5f02\u5e38\u3001\u8d2d\u7269\u8f66\u4e3a\u7a7a\u5f02\u5e38<br>2.\u5411\u8ba2\u5355\u8868\u6dfb\u52a01\u6761\u6570\u636e<br>3.\u5411\u8ba2\u5355\u660e\u7ec6\u8868\u6dfb\u52a0n\u6761\u6570\u636e<br>4.\u6e05\u7a7a\u7528\u6237\u8d2d\u7269\u8f66<br><\/p>\n\n\n\n<p>\u6d89\u53ca\u591a\u8868\u64cd\u4f5c\uff0c\u6ce8\u610f@Transactional<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">19 \u8ba2\u5355\u652f\u4ed8<\/h1>\n\n\n\n<p>\u4e2a\u4eba\u5f00\u53d1\u8005\u65e0\u6cd5\u4f7f\u7528<br><a href=\"https:\/\/pay.weixin.qq.com\/doc\/v3\/merchant\/4012791911\">\u5f00\u53d1\u6307\u5f15_\u5c0f\u7a0b\u5e8f\u652f\u4ed8|\u5fae\u4fe1\u652f\u4ed8\u5546\u6237\u6587\u6863\u4e2d\u5fc3<\/a><br>\u5185\u7f51\u7a7f\u900f\u5de5\u5177\uff1acpolar<\/p>\n\n\n\n<p>\u53c2\u8003\uff1a\u4fee\u6539\u540e\uff0c\u4e0b\u5355\u5219\u76f4\u63a5\u652f\u4ed8\u6210\u529f\u3002<\/p>\n\n\n\n<p><a href=\"https:\/\/www.bilibili.com\/opus\/824427171567108103?spm_id_from=333.1387.0.0\">\u9ed1\u9a6c\u82cd\u7a79\u5916\u5356\u9879\u76eeday8 &#8211; \u8df3\u8fc7 \u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u8ba2\u5355\u652f\u4ed8\/\u5fae\u4fe1\u652f\u4ed8\u6d41\u7a0b &#8211; \u54d4\u54e9\u54d4\u54e9<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">20 \u7528\u6237\u7aef\u5386\u53f2\u8ba2\u5355\u6a21\u5757<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">20.1 <strong>\u67e5\u8be2\u5386\u53f2\u8ba2\u5355<\/strong><\/h2>\n\n\n\n<p>\u6ce8\u610f\u8fd4\u56de\u53c2\u6570\uff01\u662forderVO\u7684list\uff0cOrderVo=order+\u5b83\u62e5\u6709\u7684OrderDetail\u3002<\/p>\n\n\n\n<p>\u5b9e\u73b0\u903b\u8f91\uff1a<\/p>\n\n\n\n<p>\u901a\u8fc7pagehelper\u5f97\u5230order\u7684list\uff0c\u7136\u540e\u904d\u5386\u6bcf\u4e2aorder\uff0c\u5f97\u5230\u5176\u6240\u6709\u7684OrderDetail\uff0c\u5e76\u5c01\u88c5\u8fdb\u4e00\u4e2aOrderVO\u7684list\u5e76\u5c06\u5176\u8fd4\u56de\u3002<\/p>\n\n\n\n<p>service\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public PageResult pageQuery4User(Integer pageNum, Integer pageSize, Integer status) {<br>    PageHelper.<em>startPage<\/em>(pageNum,pageSize);<br><br>    OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO();<br>    ordersPageQueryDTO.setUserId(BaseContext.<em>getCurrentId<\/em>());<br>    ordersPageQueryDTO.setStatus(status);<br><br><br>    \/\/ \u5206\u9875\u6761\u4ef6\u67e5\u8be2\u5f97\u5230order\u4e2d\u7684list\u7ed3\u679c<br>    Page&lt;Orders&gt; page = orderMapper.pageQuery(ordersPageQueryDTO);<br><br>    \/\/\u6700\u540e\u7684\u7ed3\u679c\u662fOrderVO\u7c7b\u578b\uff0cOrderVO = Order + orderDetail<br>    List&lt;OrderVO&gt; list = new ArrayList();<br><br><br>    \/\/ \u67e5\u8be2\u51fa\u8ba2\u5355\u660e\u7ec6\uff0c\u5e76\u5c01\u88c5\u5165OrderVO\u8fdb\u884c\u54cd\u5e94<br>    if (page != null &amp;&amp; page.getTotal() &gt; 0) {<br>        for (Orders orders : page.getResult()) {<br>            Long orderId = orders.getId();\/\/ \u8ba2\u5355id<br><br>            \/\/ \u67e5\u8be2\u8ba2\u5355\u660e\u7ec6<br>            List&lt;OrderDetail&gt; orderDetails = orderDetailMapper.getByOrderId(orderId);<br><br>            OrderVO orderVO = new OrderVO();<br>            BeanUtils.<em>copyProperties<\/em>(orders, orderVO);\/\/OrderVO\u7ee7\u627f\u4e86Orders<br>            orderVO.setOrderDetailList(orderDetails);<br><br>            list.add(orderVO);<br>        }<br>    }<br>    \/\/\u6ce8\u610f\u6b64\u5904\u8fd4\u56de\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u4e0d\u518d\u662f page.getResult()\uff0c\u800c\u662f\u518d\u6b21\u96c6\u5408\u540e\u7684 VO \u7684 list<br>    return new PageResult(page.getTotal(), list);<br>}<\/pre>\n\n\n\n<p>\u5176\u4ed6\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\uff0c\u50ac\u5355\u529f\u80fd\u5728\u540e\u9762\u5b9e\u73b0\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">21 \u5546\u5bb6\u7aef\u8ba2\u5355\u7ba1\u7406\u6a21\u5757<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">21.1 <strong>\u518d\u6765\u4e00\u5355<\/strong><\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">public void repeat(Long id) {<br>    Long userId= BaseContext.<em>getCurrentId<\/em>();<br><br>    \/\/\u901a\u8fc7id\u83b7\u53d6\u5f53\u524d\u8ba2\u5355\u8be6\u7ec6\u6570\u636e\uff1a\u83dc\u54c1\u548c\u5957\u9910<br>    List&lt;OrderDetail&gt; orderDetailList = orderDetailMapper.getByOrderId(id);<br><br>    \/\/\u6839\u636e\u5f53\u524d\u8ba2\u5355\u6570\u636e\u590d\u5236\u5f97\u5230\u8d2d\u7269\u8f66list<br>    List&lt;ShoppingCart&gt; shoppingCartList = new ArrayList&lt;&gt;();<br>    for (OrderDetail orderDetail: orderDetailList){<br>        ShoppingCart shoppingCart=new ShoppingCart();<br>        BeanUtils.<em>copyProperties<\/em>(orderDetail,shoppingCart,\"id\");\/\/\u6ce8\u610f\u4e0d\u8981\u590d\u5236id<br>        shoppingCart.setUserId(userId);<br>        shoppingCart.setCreateTime(LocalDateTime.<em>now<\/em>());<br>        shoppingCartList.add(shoppingCart);<br>    }<br><br>    shoppingCartMapper.insertBatch(shoppingCartList);<br>}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">21.2 \u7ba1\u7406\u7aef\u8ba2\u5355\u641c\u7d22<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {<br>    PageHelper.<em>startPage<\/em>(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());<br>    \/\/\u5f97\u5230order\u7684\u5206\u9875\u67e5\u8be2\u7ed3\u679c<br>    Page&lt;Orders&gt; page=orderMapper.pageQuery(ordersPageQueryDTO);<br>    \/\/\u5bf9\u4e8e\u6bcf\u4e2aorder\u5f97\u5230\u5176\u5bf9\u5e94\u7684detailList\uff0c\u5904\u7406\u4e3a\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u5e76\u5c01\u88c5\u8fdb\u6700\u540e\u8981\u8fd4\u56de\u7684VOList<br>    List&lt;OrderVO&gt; voList = new ArrayList&lt;&gt;();<br>    for (Orders orders:page.getResult()){<br>        OrderVO orderVO = new OrderVO();<br>        \/\/\u5c06\u67e5\u8be2\u5230\u7684order\u4fe1\u606f\u5c01\u88c5\u7ed9vo<br>        BeanUtils.<em>copyProperties<\/em>(orders,orderVO);<br><br>        StringBuilder sb = new StringBuilder();<br><br>        \/\/\u83b7\u53d6detail,\u5f97\u5230\u8ba2\u5355\u83dc\u54c1<br>        List&lt;OrderDetail&gt; orderDetails=orderDetailMapper.getByOrderId(orders.getId());<br>        for (OrderDetail od:orderDetails){<br>            sb.append(od.getName()+'*'+od.getNumber()+';');<br>        }<br><br>        orderVO.setOrderDishes(sb.toString());<br>        voList.add(orderVO);<br>    }<br>    return new PageResult(page.getTotal(),voList);<br>}<\/pre>\n\n\n\n<p>\u5176\u4ed6\u529f\u80fd\u57fa\u672c\u5c31\u662f\u4f53\u529b\u6d3b\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">22 <strong>\u6821\u9a8c\u6536\u8d27\u5730\u5740\u662f\u5426\u8d85\u51fa\u914d\u9001\u8303\u56f4<\/strong><\/h1>\n\n\n\n<p>\/\/TODO<\/p>\n\n\n\n<p>\u767e\u5ea6\u5e73\u53f0\u6682\u672a\u9a8c\u8bc1<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">23 \u8ba2\u5355\u72b6\u6001\u5b9a\u65f6\u5904\u7406<\/h1>\n\n\n\n<p><a href=\"http:\/\/www.cmd137blog.top\/?p=732\">Spring Task \u2013 CMD137&#8217;s Blog<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">23.1 \u8ba2\u5355\uff1a\u201c\u5f85\u652f\u4ed8\u201d-&gt;\u201c\u5df2\u53d6\u6d88\u201d<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u901a\u8fc7\u5b9a\u65f6\u4efb\u52a1\u6bcf\u5206\u949f\u68c0\u67e5\u4e00\u6b21\u662f\u5426\u5b58\u5728\u652f\u4ed8\u8d85\u65f6\u8ba2\u5355\uff08\u4e0b\u5355\u540e\u8d85\u8fc715\u5206\u949f\u4ecd\u672a\u652f\u4ed8\u5219\u5224\u5b9a\u4e3a\u652f\u4ed8\u8d85\u65f6\u8ba2\u5355\uff09\uff0c\u5982\u679c\u5b58\u5728\u5219\u4fee\u6539\u8ba2\u5355\u72b6\u6001\u4e3a\u201c\u5df2\u53d6\u6d88\u201d<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">@Scheduled(cron = \" 0 * * * * ?\")\/\/\u6bcf\u5206\u949f\u68c0\u67e5\u4e00\u6b21<br>@Transactional \/\/\u6709\u591a\u6b21\u4fee\u6539\u64cd\u4f5c<br>public void processTimeoutOrder(){<br>    <em>log<\/em>.info(\"\u5904\u7406\u652f\u4ed8\u8d85\u65f6\u8ba2\u5355\uff1a{}\", LocalDateTime.<em>now<\/em>());<br><br>    \/\/\u8ba2\u5355\u65f6\u95f4&lt;\u5f53\u524d\u65f6\u95f4-15min\uff0c\u5373\u4e3a\u8d85\u65f6\u8ba2\u5355<br>    LocalDateTime deltaTime = LocalDateTime.<em>now<\/em>().minusMinutes(15);<br><br>    List&lt;Orders&gt; ordersList = orderMapper.getOrdersByStatusAndOrderTimeLT(Orders.<em>PENDING_PAYMENT<\/em>,deltaTime);<br>    if (ordersList != null &amp;&amp; ordersList.size()&gt;0) {<br>        for (Orders o : ordersList){<br>            o.setStatus(Orders.<em>CANCELLED<\/em>);<br>            o.setCancelReason(\"\u652f\u4ed8\u65f6\u95f4\u8d85\u65f6\uff0c\u8ba2\u5355\u81ea\u52a8\u53d6\u6d88\");<br>            o.setCancelTime(LocalDateTime.<em>now<\/em>());<br><br>            orderMapper.update(o);<br>        }<br>    }<br>}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">23.2 \u8ba2\u5355\uff1a\u201c\u6d3e\u9001\u4e2d\u201d-&gt;\u201c\u5df2\u5b8c\u6210\u201d<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u901a\u8fc7\u5b9a\u65f6\u4efb\u52a1\u6bcf\u5929\u51cc\u66681\u70b9\u68c0\u67e5\u4e00\u6b21\u662f\u5426\u5b58\u5728\u201c\u6d3e\u9001\u4e2d\u201d\u7684\u8ba2\u5355\uff0c\u5982\u679c\u5b58\u5728\u5219\u4fee\u6539\u8ba2\u5355\u72b6\u6001\u4e3a\u201c\u5df2\u5b8c\u6210\u201d<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">@Scheduled(cron = \"0 0 1 * * ?\")\/\/\u6bcf\u5929\u51cc\u66681\u70b9\u6267\u884c<br>@Transactional \/\/\u6709\u591a\u6b21\u4fee\u6539\u64cd\u4f5c<br>public void processDeliveryOrder(){<br>    <em>log<\/em>.info(\"\u5904\u7406\u6d3e\u9001\u4e2d\u8ba2\u5355\uff1a{}\",LocalDateTime.<em>now<\/em>());<br><br>    LocalDateTime deltaTime = LocalDateTime.<em>now<\/em>().minusMinutes(60);<br><br>    List&lt;Orders&gt; ordersList = orderMapper.getOrdersByStatusAndOrderTimeLT(Orders.<em>DELIVERY_IN_PROGRESS<\/em>,deltaTime);<br>    if (ordersList != null &amp;&amp; ordersList.size()&gt;0) {<br>        for (Orders o : ordersList){<br>            o.setStatus(Orders.<em>COMPLETED<\/em>);<br><br>            orderMapper.update(o);<br>        }<br>    }<br>}<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">24 websocket\uff1a<\/h1>\n\n\n\n<p><a href=\"http:\/\/www.cmd137blog.top\/?p=738\">WebSocket \u2013 CMD137&#8217;s Blog<\/a><\/p>\n\n\n\n<p>\u901a\u8fc7websocket\u5b9e\u73b0\u7ba1\u7406\u7aef\u4e0e\u540e\u7aef\u670d\u52a1\u5668\u7684\u957f\u8fde\u63a5\uff1a<\/p>\n\n\n\n<p>\u5f53\u7528\u6237\u7aef\u8fdb\u884c\u4e0b\u5355\u652f\u4ed8\uff0c\u540e\u7aef\u63d0\u9192\u7ba1\u7406\u7aef\u6709\u65b0\u7684\u8ba2\u5355\u3002<\/p>\n\n\n\n<p>\u5f53\u7528\u6237\u7aef\u8fdb\u884c\u50ac\u5355\u64cd\u4f5c\uff0c\u540e\u7aef\u63d0\u9192\u7ba1\u7406\u7aef\u7531\u7528\u6237\u50ac\u5355\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">24.1 \u6765\u5355\u63d0\u9192<\/h2>\n\n\n\n<p>\u6dfb\u52a0\u5728\u652f\u4ed8\u6210\u529f\u65b9\u6cd5\u4e2d\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/\u901a\u8fc7websocket\u5411\u7ba1\u7406\u7aef\u63a8\u9001\u7531\u7528\u6237\u4e0b\u5355\u7684\u6d88\u606f<br>Map map = new HashMap();<br>map.put(\"type\", 1);\/\/\u6d88\u606f\u7c7b\u578b\uff0c1\u8868\u793a\u6765\u5355\u63d0\u9192<br>map.put(\"orderId\", orders.getId());<br>map.put(\"content\", \"\u8ba2\u5355\u53f7\uff1a\" + outTradeNo);<br><br>webSocketServer.sendToAllClient(JSON.<em>toJSONString<\/em>(map));<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">24.2 \u7528\u6237\u50ac\u5355<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">public void reminder(Long id) {<br>    \/\/ \u67e5\u8be2\u8ba2\u5355\u662f\u5426\u5b58\u5728<br>    Orders orders = orderMapper.getById(id);<br>    if (orders == null) {<br>        throw new OrderBusinessException(MessageConstant.<em>ORDER_NOT_FOUND<\/em>);<br>    }<br><br>    \/\/\u57fa\u4e8eWebSocket\u5b9e\u73b0\u50ac\u5355<br>    Map map = new HashMap();<br>    map.put(\"type\", 2);\/\/2\u4ee3\u8868\u7528\u6237\u50ac\u5355<br>    map.put(\"orderId\", id);<br>    map.put(\"content\", \"\u8ba2\u5355\u53f7\uff1a\" + orders.getNumber());<br>    webSocketServer.sendToAllClient(JSON.<em>toJSONString<\/em>(map));<br>}<\/pre>\n\n\n\n<p>\u4f46\u662f\u8bed\u97f3\u64ad\u62a5\u5e76\u4e0d\u7a33\u5b9a\uff0c\u6709\u65f6\u5019\u9700\u8981\u5237\u65b0\u6d4f\u89c8\u5668\u624d\u6709\u53cd\u5e94\uff0c\u6682\u672a\u89e3\u51b3\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">25 \u6570\u636e\u7edf\u8ba1\uff1a\uff08Apache ECharts\uff09<\/h1>\n\n\n\n<p><a href=\"https:\/\/echarts.apache.org\/zh\/index.html\">Apache ECharts<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">25.1 \u8425\u4e1a\u989d\u7edf\u8ba1\uff1a<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/dateList \u5373\u4e3a\u4e24\u4e2a\u65f6\u95f4\u7684\u95ed\u533a\u95f4\u7684\u65e5\u671f,turnoverList \u901a\u8fc7\u65e5\u671f\u548c\u8ba2\u5355\u72b6\u6001\u67e5\u8be2<br>    List&lt;LocalDate&gt; dateList = new ArrayList&lt;&gt;();<br>    List&lt;Double&gt; turnoverList = new ArrayList&lt;&gt;();<br>    while(!begin.isAfter(end)){<br>        \/\/\u5f97\u5230\u5355\u4e2a\u65e5\u671f\u7684\u5f00\u59cb\u65f6\u95f4\u4e0e\u7ed3\u675f\u65f6\u95f4<br>        LocalDateTime beginInDay = LocalDateTime.<em>of<\/em>(begin, LocalTime.<em>MIN<\/em>);<br>        LocalDateTime endInDay = LocalDateTime.<em>of<\/em>(begin, LocalTime.<em>MAX<\/em>);<br><br>        Map map = new HashMap&lt;&gt;();<br>        map.put(\"begin\",beginInDay);<br>        map.put(\"end\",endInDay);<br>        map.put(\"status\", Orders.<em>COMPLETED<\/em>);<br><br>        \/\/\u5f97\u5230\u5355\u4e2a\u65e5\u671f\u5185\u7684\u603b\u8425\u4e1a\u989d<br>        Double turnover = orderMapper.getSumByMap(map);<br>        turnover = turnover==null? 0.0:turnover;<br><br>        dateList.add(begin);<br>        turnoverList.add(turnover);<br><br>        \/\/begin\u65e5\u671f+1\uff0c\u904d\u5386\u76f4\u5230end\uff08\u5305\u62ecend\uff09<br>        begin= begin.plusDays(1);<br>    }<br><br><br>    return TurnoverReportVO.<em>builder<\/em>()<br>            .dateList(StringUtils.<em>join<\/em>(dateList,\",\"))<br>            .turnoverList(StringUtils.<em>join<\/em>(turnoverList,\",\"))<br>            .build();<br>}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">25.2 \u7528\u6237\u7edf\u8ba1<\/h2>\n\n\n\n<p>\u4f53\u529b\u6d3b<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">25.3 \u8ba2\u5355\u7edf\u8ba1<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {<br>    List&lt;LocalDate&gt; dateList = new ArrayList&lt;&gt;();<br>    List&lt;Integer&gt; orderCountList = new ArrayList&lt;&gt;();<br>    List&lt;Integer&gt; validOrderCountList = new ArrayList&lt;&gt;();<br>    int orderCount = 0,orderCountInDay = 0;<br>    int validOrderCount =0,validOrderCountInDay = 0;<br><br>    while(!begin.isAfter(end)){<br>        \/\/\u5f97\u5230\u5355\u4e2a\u65e5\u671f\u7684\u5f00\u59cb\u65f6\u95f4\u4e0e\u7ed3\u675f\u65f6\u95f4<br>        LocalDateTime beginInDay = LocalDateTime.<em>of<\/em>(begin, LocalTime.<em>MIN<\/em>);<br>        LocalDateTime endInDay = LocalDateTime.<em>of<\/em>(begin, LocalTime.<em>MAX<\/em>);<br><br>        Map map = new HashMap&lt;&gt;();<br>        map.put(\"begin\",beginInDay);<br>        map.put(\"end\",endInDay);<br><br>        \/\/\u5f97\u5230\u5355\u4e2a\u65e5\u671f\u5185\u7684\u8ba2\u5355\u6570<br>        orderCountInDay = orderMapper.countByMap(map);<br>        \/\/\u5f97\u5230\u5355\u4e2a\u65e5\u671f\u5185\u7684\u6709\u6548\u8ba2\u5355\u6570<br>        map.put(\"status\", Orders.<em>COMPLETED<\/em>);<br>        validOrderCountInDay= orderMapper.countByMap(map);<br>        <br>        \/\/\u7edf\u8ba1<br>        dateList.add(begin);<br>        orderCountList.add(orderCountInDay);<br>        validOrderCountList.add(validOrderCountInDay);<br>        orderCount+=orderCountInDay;<br>        validOrderCount+=validOrderCountInDay;<br><br>        \/\/begin\u65e5\u671f+1\uff0c\u904d\u5386\u76f4\u5230end\uff08\u5305\u62ecend\uff09<br>        begin= begin.plusDays(1);<br>    }<br>    <br>    \/\/\u6ce8\u610f\u9664\u4ee50\u5f02\u5e38\u548cdouble\u7c7b\u578b\u8f6c\u6362<br>    double orderCompletionRate = 0.0;<br>    if (orderCount!=0)<br>        orderCompletionRate = (double) validOrderCount\/orderCount;<br><br>    return OrderReportVO.<em>builder<\/em>()<br>            .dateList(StringUtils.<em>join<\/em>(dateList,\",\"))<br>            .orderCountList(StringUtils.<em>join<\/em>(orderCountList,\",\"))<br>            .validOrderCountList(StringUtils.<em>join<\/em>(validOrderCountList,\",\"))<br>            .totalOrderCount(orderCount)<br>            .validOrderCount(validOrderCount)<br>            .orderCompletionRate(orderCompletionRate)<br>            .build();<br>}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">25.4 \u9500\u552e\u989d\u6392\u884c<\/h2>\n\n\n\n<p>\u4e3b\u8981\u662fSQL\u8bed\u53e5\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;select id=\"getTop10\" resultType=\"com.sky.dto.GoodsSalesDTO\"&gt;<br>        select od.name name,sum(od.number) number from order_detail od ,orders o<br>        where od.order_id = o.id<br>        and o.status = 5<br>        &lt;if test=\"begin != null\"&gt;<br>                and order_time &amp;gt;= #{begin}<br>        &lt;\/if&gt;<br>        &lt;if test=\"end != null\"&gt;<br>                and order_time &amp;lt;= #{end}<br>        &lt;\/if&gt;<br>        group by name<br>        order by number desc<br>        limit 0, 10<br>&lt;\/select&gt;<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">26 \u5de5\u4f5c\u53f0\u4ee3\u7801\u5bfc\u5165<\/h1>\n\n\n\n<h1 class=\"wp-block-heading\">27 \u5bfc\u51fa\u8fd0\u8425\u6570\u636e \uff08Apache POI\uff09<\/h1>\n\n\n\n<p><a href=\"https:\/\/blog.csdn.net\/hadues\/article\/details\/113859228\">Apache POI \u4e2d\u6587\u4f7f\u7528\u6307\u5357_apache poi\u4e2d\u6587\u6587\u6863-CSDN\u535a\u5ba2<\/a><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public void exportBusinessData(HttpServletResponse response) {<br>    LocalDate begin = LocalDate.<em>now<\/em>().minusDays(30);<br>    LocalDate end = LocalDate.<em>now<\/em>().minusDays(1);<br>    \/\/\u67e5\u8be2\u6982\u89c8\u8fd0\u8425\u6570\u636e\uff0c\u63d0\u4f9b\u7ed9Excel\u6a21\u677f\u6587\u4ef6<br>    BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.<em>of<\/em>(begin,LocalTime.<em>MIN<\/em>), LocalDateTime.<em>of<\/em>(end, LocalTime.<em>MAX<\/em>));<br>    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(\"template\/\u8fd0\u8425\u6570\u636e\u62a5\u8868\u6a21\u677f.xlsx\");<br>    try {<br>        \/\/\u57fa\u4e8e\u63d0\u4f9b\u597d\u7684\u6a21\u677f\u6587\u4ef6\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Excel\u8868\u683c\u5bf9\u8c61<br>        XSSFWorkbook excel = new XSSFWorkbook(inputStream);<br>        \/\/\u83b7\u5f97Excel\u6587\u4ef6\u4e2d\u7684\u4e00\u4e2aSheet\u9875<br>        XSSFSheet sheet = excel.getSheet(\"Sheet1\");<br><br>        sheet.getRow(1).getCell(1).setCellValue(begin + \"\u81f3\" + end);<br>        \/\/\u83b7\u5f97\u7b2c4\u884c<br>        XSSFRow row = sheet.getRow(3);<br>        \/\/\u83b7\u53d6\u5355\u5143\u683c<br>        row.getCell(2).setCellValue(businessData.getTurnover());<br>        row.getCell(4).setCellValue(businessData.getOrderCompletionRate());<br>        row.getCell(6).setCellValue(businessData.getNewUsers());<br>        row = sheet.getRow(4);<br>        row.getCell(2).setCellValue(businessData.getValidOrderCount());<br>        row.getCell(4).setCellValue(businessData.getUnitPrice());<br>        for (int i = 0; i &lt; 30; i++) {<br>            LocalDate date = begin.plusDays(i);<br>            \/\/\u51c6\u5907\u660e\u7ec6\u6570\u636e<br>            businessData = workspaceService.getBusinessData(LocalDateTime.<em>of<\/em>(date,LocalTime.<em>MIN<\/em>), LocalDateTime.<em>of<\/em>(date, LocalTime.<em>MAX<\/em>));<br>            row = sheet.getRow(7 + i);<br>            row.getCell(1).setCellValue(date.toString());<br>            row.getCell(2).setCellValue(businessData.getTurnover());<br>            row.getCell(3).setCellValue(businessData.getValidOrderCount());<br>            row.getCell(4).setCellValue(businessData.getOrderCompletionRate());<br>            row.getCell(5).setCellValue(businessData.getUnitPrice());<br>            row.getCell(6).setCellValue(businessData.getNewUsers());<br>        }<br>        \/\/\u901a\u8fc7\u8f93\u51fa\u6d41\u5c06\u6587\u4ef6\u4e0b\u8f7d\u5230\u5ba2\u6237\u7aef\u6d4f\u89c8\u5668\u4e2d<br>        ServletOutputStream out = response.getOutputStream();<br>        excel.write(out);<br>        \/\/\u5173\u95ed\u8d44\u6e90<br>        out.flush();<br>        out.close();<br>        excel.close();<br><br>    }catch (IOException e){<br>        e.printStackTrace();<br>    }<br>}<\/pre>\n\n\n\n<p>\u6b64\u5904\u5728ReportService\u91cc\u8c03\u7528\u4e86\u53e6\u4e00\u4e2aservice\uff0c\u4e0d\u8fdd\u53cd\u89c4\u8303\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u65b0\u77e5\u8bc6\uff1a<\/h3>\n\n\n\n<p><strong><code>HttpServletResponse<\/code><\/strong>\uff1a\u8fd9\u662f Servlet API \u4e2d\u7684\u4e00\u4e2a\u63a5\u53e3\uff0c\u4ee3\u8868\u4e86\u670d\u52a1\u5668\u5bf9\u5ba2\u6237\u7aef\u8bf7\u6c42\u7684\u54cd\u5e94\u3002\u5728\u8fd9\u4e2a\u65b9\u6cd5\u4e2d\uff0c\u5b83\u7528\u4e8e\u5411\u5ba2\u6237\u7aef\u53d1\u9001\u751f\u6210\u7684 Excel \u6587\u4ef6\u3002Servlet \u5bb9\u5668\uff08\u5982 Tomcat\uff09\u5728\u8c03\u7528\u8fd9\u4e2a\u65b9\u6cd5\u65f6\uff0c\u4f1a\u81ea\u52a8\u4f20\u5165\u4e00\u4e2a\u5b9e\u73b0\u4e86<code>HttpServletResponse<\/code>\u63a5\u53e3\u7684\u5bf9\u8c61\uff0c\u8be5\u5bf9\u8c61\u5c01\u88c5\u4e86\u4e0e\u5ba2\u6237\u7aef\u901a\u4fe1\u7684\u76f8\u5173\u4fe1\u606f\u548c\u64cd\u4f5c\u65b9\u6cd5\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>2025\/2\/27 \uff0c\u5b8c\u7ed3\u6492\u82b1<\/p>\n","protected":false},"excerpt":{"rendered":"<p>0.\u51c6\u5907\u5de5\u4f5c\u53ca\u524d\u7f6e\u77e5\u8bc6\uff1a 0.1 \u7248\u672c\u63a7\u5236 Git\u5728IDEA\u4e2d\u7684\u4f7f\u7528\uff08\u8be6\u7ec6\u56fe\u6587\u5168\u89e3\uff09_idea\u64cd\u4f5cgit-CS [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66],"tags":[62,67],"class_list":["post-635","post","type-post","status-publish","format-standard","hentry","category-66","tag-javaweb","tag-67"],"_links":{"self":[{"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=\/wp\/v2\/posts\/635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=635"}],"version-history":[{"count":34,"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=\/wp\/v2\/posts\/635\/revisions"}],"predecessor-version":[{"id":748,"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=\/wp\/v2\/posts\/635\/revisions\/748"}],"wp:attachment":[{"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=635"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.cmd137blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}