蒼穹外賣-第一章項目介紹

来源:https://www.cnblogs.com/szlsay/archive/2023/09/30/17737747.html
-Advertisement-
Play Games

1. 蒼穹外賣項目介紹 1.1 項目介紹 1)管理端功能 員工登錄/退出 , 員工信息管理 , 分類管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 訂單管理 ,數據統計,來單提醒。 2)用戶端功能 微信登錄 , 收件人地址管理 , 用戶歷史訂單查詢 , 菜品規格查詢 , 購物車功能 , 下單 ...


1. 蒼穹外賣項目介紹

1.1 項目介紹

1)管理端功能

員工登錄/退出 , 員工信息管理 , 分類管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 訂單管理 ,數據統計,來單提醒。

2)用戶端功能

微信登錄 , 收件人地址管理 , 用戶歷史訂單查詢 , 菜品規格查詢 , 購物車功能 , 下單 , 支付、分類及菜品瀏覽。

1.2 產品原型

1)管理端

餐飲企業內部員工使用。 主要功能有:

模塊 描述
登錄/退出 內部員工必須登錄後,才可以訪問系統管理後臺
員工管理 管理員可以在系統後臺對員工信息進行管理,包含查詢、新增、編輯、禁用等功能
分類管理 主要對當前餐廳經營的 菜品分類 或 套餐分類 進行管理維護, 包含查詢、新增、修改、刪除等功能
菜品管理 主要維護各個分類下的菜品信息,包含查詢、新增、修改、刪除、啟售、停售等功能
套餐管理 主要維護當前餐廳中的套餐信息,包含查詢、新增、修改、刪除、啟售、停售等功能
訂單管理 主要維護用戶在移動端下的訂單信息,包含查詢、取消、派送、完成,以及訂單報表下載等功能
數據統計 主要完成對餐廳的各類數據統計,如營業額、用戶數量、訂單等

2)用戶端

移動端應用主要提供給消費者使用。主要功能有:

模塊 描述
登錄/退出 用戶需要通過微信授權後登錄使用小程式進行點餐
點餐-菜單 在點餐界面需要展示出菜品分類/套餐分類, 並根據當前選擇的分類載入其中的菜品信息, 供用戶查詢選擇
點餐-購物車 用戶選中的菜品就會加入用戶的購物車, 主要包含 查詢購物車、加入購物車、刪除購物車、清空購物車等功能
訂單支付 用戶選完菜品/套餐後, 可以對購物車菜品進行結算支付, 這時就需要進行訂單的支付
個人信息 在個人中心頁面中會展示當前用戶的基本信息, 用戶可以管理收貨地址, 也可以查詢歷史訂單數據

1.3 技術選型

關於本項目的技術選型, 我們將會從 用戶層、網關層、應用層、數據層 這幾個方面進行介紹,主要用於展示項目中使用到的技術框架和中間件等。

  • 用戶層 node.js VUE.js ElementUI 微信小程式 apache echarts
  • 網關層 Nginx
  • 應用層 SpringBoot SpringMVC SpringTask SpringCache JWT 阿裡雲OSS httpclient Swagger POI WebSocket
  • 數據層 MySQL Redis mybatis
  • 工具 Git maven Junit postman pagehelper springdataredis

1)用戶層
後臺的前端頁面用到H5、Vue.js、ElementUI、apache echarts(展示圖表)等技術。移動端應用使用到微信小程式。

2)網關層
Nginx是一個伺服器,主要用來作為Http伺服器,部署靜態資源,訪問性能高。在Nginx中還有兩個比較重要的作用: 反向代理和負載均衡, 在進行項目部署時,要實現Tomcat的負載均衡,就可以通過Nginx來實現。

3)應用層

  • SpringBoot: 快速構建Spring項目, 採用 "約定優於配置" 的思想, 簡化Spring項目的配置開發。
  • SpringMVC:SpringMVC是spring框架的一個模塊,springmvc和spring無需通過中間整合層進行整合,可以無縫集成。
  • Spring Task: 由Spring提供的定時任務框架。
  • httpclient: 主要實現了對http請求的發送。
  • Spring Cache: 由Spring提供的數據緩存框架
  • JWT: 用於對應用程式上的用戶進行身份驗證的標記。
  • 阿裡雲OSS: 對象存儲服務,在項目中主要存儲文件,如圖片等。
  • Swagger: 可以自動的幫助開發人員生成介面文檔,並對介面進行測試。
  • POI: 封裝了對Excel表格的常用操作。
  • WebSocket: 一種通信網路協議,使客戶端和伺服器之間的數據交換更加簡單,用於項目的來單、催單功能實現。

4)數據層

  • MySQL: 關係型資料庫, 本項目的核心業務數據都會採用MySQL進行存儲。
  • Redis: 基於key-value格式存儲的記憶體資料庫, 訪問速度快, 經常使用它做緩存。
  • Mybatis: 本項目持久層將會使用Mybatis開發。
  • pagehelper: 分頁插件。
  • spring data redis: 簡化java代碼操作Redis的API。

5)工具

  • git: 版本控制工具, 在團隊協作中, 使用該工具對項目中的代碼進行管理。
  • maven: 項目構建工具。
  • junit:單元測試工具,開發人員功能實現完畢後,需要通過junit對功能進行單元測試。
  • postman: 介面測工具,模擬用戶發起的各類HTTP請求,獲取對應的響應結果。

2. 開發環境搭建

2.1 熟悉項目結構

對工程的每個模塊作用說明:

序號 名稱 說明
1 sky-take-out maven父工程,統一管理依賴版本,聚合其他子模塊
2 sky-common 子模塊,存放公共類,例如:工具類、常量類、異常類等
3 sky-pojo 子模塊,存放實體類、VO、DTO等
4 sky-server 子模塊,後端服務,存放配置文件、Controller、Service、Mapper等
  • sky-common: 模塊中存放的是一些公共類,可以供其他模塊使用

    分析sky-common模塊的每個包的作用:

    名稱 說明
    constant 存放相關常量類
    context 存放上下文類
    enumeration 項目的枚舉類存儲
    exception 存放自定義異常類
    json 處理json轉換的類
    properties 存放SpringBoot相關的配置屬性類
    result 返回結果類的封裝
    utils 常用工具類
  • sky-pojo: 模塊中存放的是一些 entity、DTO、VO

    分析sky-pojo模塊的每個包的作用:

    名稱 說明
    Entity 實體,通常和資料庫中的表對應
    DTO 數據傳輸對象,通常用於程式中各層之間傳遞數據
    VO 視圖對象,為前端展示數據提供的對象
    POJO 普通Java對象,只有屬性和對應的getter和setter
  • sky-server: 模塊中存放的是 配置文件、配置類、攔截器、controller、service、mapper、啟動類等

    分析sky-server模塊的每個包的作用:

    名稱 說明
    config 存放配置類
    controller 存放controller類
    interceptor 存放攔截器類
    mapper 存放mapper介面
    service 存放service類
    SkyApplication 啟動類

2.2 資料庫環境搭建

序號 表名 中文名
1 employee 員工表
2 category 分類表
3 dish 菜品表
4 dish_flavor 菜品口味表
5 setmeal 套餐表
6 setmeal_dish 套餐菜品關係表
7 user 用戶表
8 address_book 地址表
9 shopping_cart 購物車表
10 orders 訂單表
11 order_detail 訂單明細表

2.3 前後端聯調

1.Controller層

在sky-server模塊中,com.sky.controller.admin.EmployeeController

/**
     * 登錄
     *
     * @param employeeLoginDTO
     * @return
     */
    @PostMapping("/login")
    public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
        log.info("員工登錄:{}", employeeLoginDTO);
		//調用service方法查詢資料庫
        Employee employee = employeeService.login(employeeLoginDTO);

        //登錄成功後,生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

        EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
                .id(employee.getId())
                .userName(employee.getUsername())
                .name(employee.getName())
                .token(token)
                .build();

        return Result.success(employeeLoginVO);
    }

2.Service層

在sky-server模塊中,com.sky.service.impl.EmployeeServiceImpl

/**
     * 員工登錄
     *
     * @param employeeLoginDTO
     * @return
     */
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {
        String username = employeeLoginDTO.getUsername();
        String password = employeeLoginDTO.getPassword();

        //1、根據用戶名查詢資料庫中的數據
        Employee employee = employeeMapper.getByUsername(username);

        //2、處理各種異常情況(用戶名不存在、密碼不對、賬號被鎖定)
        if (employee == null) {
            //賬號不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密碼比對
        if (!password.equals(employee.getPassword())) {
            //密碼錯誤
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (employee.getStatus() == StatusConstant.DISABLE) {
            //賬號被鎖定
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回實體對象
        return employee;
    }

3.Mapper層

在sky-server模塊中,com.sky.mapper.EmployeeMapper

package com.sky.mapper;

import com.sky.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface EmployeeMapper {

    /**
     * 根據用戶名查詢員工
     * @param username
     * @return
     */
    @Select("select * from employee where username = #{username}")
    Employee getByUsername(String username);

}

註:可以通過斷點調試跟蹤後端程式的執行過程

2.4 nginx反向代理和負載均衡

對登錄功能測試完畢後,接下來一個問題:前端發送的請求,是如何請求到後端服務的?

前端請求地址:http://localhost/api/employee/login
後端介面地址:http://localhost:8080/admin/employee/login
很明顯,兩個地址不一致,那是如何請求到後端服務的呢?

1)nginx反向代理

nginx 反向代理,就是將前端發送的動態請求由 nginx 轉發到後端伺服器

那為什麼不直接通過瀏覽器直接請求後臺服務端,需要通過nginx反向代理呢?

nginx 反向代理的好處:

  • 提高訪問速度
    因為nginx本身可以進行緩存,如果訪問的同一介面,並且做了數據緩存,nginx就直接可把數據返回,不需要真正地訪問服務端,從而提高訪問速度。

  • 進行負載均衡
    所謂負載均衡,就是把大量的請求按照我們指定的方式均衡的分配給集群中的每台伺服器。

  • 保證後端服務安全
    因為一般後臺服務地址不會暴露,所以使用瀏覽器不能直接訪問,可以把nginx作為請求訪問的入口,請求到達nginx後轉發到具體的服務中,從而保證後端服務的安全。

nginx 反向代理的配置方式:

server{
    listen 80;
    server_name localhost;

    location /api/{
        proxy_pass http://localhost:8080/admin/; #反向代理
    }
}

proxy_pass:該指令是用來設置代理伺服器的地址,可以是主機名稱,IP地址加埠號等形式。

如上代碼的含義是:監聽80埠號, 然後當我們訪問 http://localhost:80/api/../..這樣的介面的時候,它會通過 location /api/ {} 這樣的反向代理到 http://localhost:8080/admin/上來。

接下來,進到nginx-1.20.2\conf,打開nginx配置

# 反向代理,處理管理端發送的請求
location /api/ {
	proxy_pass   http://localhost:8080/admin/;
    #proxy_pass   http://webservers/admin/;
}

當在訪問http://localhost/api/employee/login,nginx接收到請求後轉到http://localhost:8080/admin/,故最終的請求地址為http://localhost:8080/admin/employee/login,和後臺服務的訪問地址一致

2)nginx 負載均衡

當如果服務以集群的方式進行部署時,那nginx在轉發請求到伺服器時就需要做相應的負載均衡。其實,負載均衡從本質上來說也是基於反向代理來實現的,最終都是轉發請求。

nginx 負載均衡的配置方式:

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}
server{
    listen 80;
    server_name localhost;

    location /api/{
        proxy_pass http://webservers/admin;#負載均衡
    }
}

upstream:如果代理伺服器是一組伺服器的話,我們可以使用upstream指令配置後端伺服器組。

如上代碼的含義是:監聽80埠號, 然後當我們訪問 http://localhost:80/api/../..這樣的介面的時候,它會通過 location /api/ {} 這樣的反向代理到 http://webservers/admin,根據webservers名稱找到一組伺服器,根據設置的負載均衡策略(預設是輪詢)轉發到具體的伺服器。

註:upstream後面的名稱可自定義,但要上下保持一致。

nginx 負載均衡策略:

名稱 說明
輪詢 預設方式
weight 權重方式,預設為1,權重越高,被分配的客戶端請求就越多
ip_hash 依據ip分配方式,這樣每個訪客可以固定訪問一個後端服務
least_conn 依據最少連接方式,把請求優先分配給連接數少的後端服務
url_hash 依據url分配方式,這樣相同的url會被分配到同一個後端服務
fair 依據響應時間方式,響應時間短的服務將會被優先分配

具體配置方式:

輪詢:

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

weight:

upstream webservers{
    server 192.168.100.128:8080 weight=90;
    server 192.168.100.129:8080 weight=10;
}

ip_hash:

upstream webservers{
    ip_hash;
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

least_conn:

upstream webservers{
    least_conn;
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

url_hash:

upstream webservers{
    hash &request_uri;
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

fair:

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
    fair;
}

3. 完善登錄功能

問題:員工表中的密碼是明文存儲,安全性太低。
解決思路:

  1. 將密碼加密後存儲,提高安全性
  2. 使用MD5加密方式對明文密碼加密

實現步驟:

  1. 修改資料庫中明文密碼,改為MD5加密後的密文
    打開employee表,修改密碼

  2. 修改Java代碼,前端提交的密碼進行MD5加密後再跟資料庫中密碼比對
    打開EmployeeServiceImpl.java,修改比對密碼

   /**
        * 員工登錄
        *
        * @param employeeLoginDTO
        * @return
        */
       public Employee login(EmployeeLoginDTO employeeLoginDTO) {
           //1、根據用戶名查詢資料庫中的數據
           //2、處理各種異常情況(用戶名不存在、密碼不對、賬號被鎖定)
           //.......
           //密碼比對
           // TODO 後期需要進行md5加密,然後再進行比對
           password = DigestUtils.md5DigestAsHex(password.getBytes());
           if (!password.equals(employee.getPassword())) {
               //密碼錯誤
               throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
           }
           //3、返回實體對象
           return employee;
       }

4. Swagger

4.1 介紹

Swagger 是一個規範和完整的框架,用於生成、描述、調用和可視化 RESTful 風格的 Web 服務(https://swagger.io/)。 它的主要作用是:

  1. 使得前後端分離開發更加方便,有利於團隊協作
  2. 介面的文檔線上自動生成,降低後端開發人員編寫介面文檔的負擔
  3. 功能測試

Spring已經將Swagger納入自身的標準,建立了Spring-swagger項目,現在叫Springfox。通過在項目中引入Springfox ,即可非常簡單快捷的使用Swagger。

knife4j是為Java MVC框架集成Swagger生成Api文檔的增強解決方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一樣小巧,輕量,並且功能強悍!

目前,一般都使用knife4j框架。

4.2 使用步驟

  1. 導入 knife4j 的maven坐標

在pom.xml中添加依賴

   <dependency>
      <groupId>com.github.xiaoymin</groupId>
      <artifactId>knife4j-spring-boot-starter</artifactId>
   </dependency>
  1. 在配置類中加入 knife4j 相關配置

WebMvcConfiguration.java

   /**
        * 通過knife4j生成介面文檔
        * @return
   */
       @Bean
       public Docket docket() {
           ApiInfo apiInfo = new ApiInfoBuilder()
                   .title("蒼穹外賣項目介面文檔")
                   .version("2.0")
                   .description("蒼穹外賣項目介面文檔")
                   .build();
           Docket docket = new Docket(DocumentationType.SWAGGER_2)
                   .apiInfo(apiInfo)
                   .select()
                   .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
                   .paths(PathSelectors.any())
                   .build();
           return docket;
       }
  1. 設置靜態資源映射,否則介面文檔頁面無法訪問

WebMvcConfiguration.java

   /**
        * 設置靜態資源映射
        * @param registry
   */
   protected void addResourceHandlers(ResourceHandlerRegistry registry) {
           registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
           registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
   }
  1. 訪問測試

介面文檔訪問路徑為 http://ip:port/doc.html ---> http://localhost:8080/doc.html

4.3 常用註解

通過註解可以控制生成的介面文檔,使介面文檔擁有更好的可讀性,常用註解如下:

註解 說明
@Api 用在類上,例如Controller,表示對類的說明
@ApiModel 用在類上,例如entity、DTO、VO
@ApiModelProperty 用在屬性上,描述屬性信息
@ApiOperation 用在方法上,例如Controller的方法,說明方法的用途、作用

接下來,使用上述註解,生成可讀性更好的介面文檔

在sky-pojo模塊中
EmployeeLoginDTO.java

package com.sky.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

@Data
@ApiModel(description = "員工登錄時傳遞的數據模型")
public class EmployeeLoginDTO implements Serializable {

    @ApiModelProperty("用戶名")
    private String username;

    @ApiModelProperty("密碼")
    private String password;

}

EmployeeLoginVo.java

package com.sky.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "員工登錄返回的數據格式")
public class EmployeeLoginVO implements Serializable {

    @ApiModelProperty("主鍵值")
    private Long id;

    @ApiModelProperty("用戶名")
    private String userName;

    @ApiModelProperty("姓名")
    private String name;

    @ApiModelProperty("jwt令牌")
    private String token;

}

在sky-server模塊中

EmployeeController.java

package com.sky.controller.admin;

import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.entity.Employee;
import com.sky.properties.JwtProperties;
import com.sky.result.Result;
import com.sky.service.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.EmployeeLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 員工管理
 */
@RestController
@RequestMapping("/admin/employee")
@Slf4j
@Api(tags = "員工相關介面")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 登錄
     *
     * @param employeeLoginDTO
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "員工登錄")
    public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) 	{
        //
    }

    /**
     * 退出
     *
     * @return
     */
    @PostMapping("/logout")
    @ApiOperation("員工退出")
    public Result<String> logout() {
        return Result.success();
    }

}

啟動服務:訪問http://localhost:8080/doc.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 從今年(2023)三月份開始,Github開始強制用戶開啟兩步驗證2FA(雙因數)登錄驗證,毫無疑問,是出於安全層面的考慮,畢竟Github賬號一旦被盜,所有代碼倉庫都會毀於一旦,關於雙因數登錄的必要性請參見:別讓你的伺服器(vps)淪為肉雞(ssh暴力破解),密鑰驗證、雙向因數登錄值得擁有。 雙因 ...
  • 一、XML概述 XML(可擴展標記語言)是一種用於描述數據的標記語言,旨在提供一種通用的方式來傳輸和存儲數據,特別是Web應用程式中經常使用的數據。XML並不預定義標記。因此,XML更加靈活,並且可以適用於廣泛的應用領域。 XML文檔由元素(element)、屬性(attribute)和內容(con ...
  • WPF本身不支持直接的3D繪圖,但是它提供了一些用於實現3D效果的高級技術。 如果你想要在WPF中進行3D繪圖,你可以使用兩種主要的方法: WPF 3D:這是一種在WPF應用程式中創建3D圖形的方式。WPF 3D提供了一些基本的3D形狀(如立方體、球體和錐體)以及一些用於控制3D場景和對象的工具(如 ...
  • VOD模塊NGINX編譯部署 主要解決我那破電視的觀影需求、軟體裝不了又不想掏錢看線上廣告;U盤也沒法播、沒幾個相容的解碼軟體,五六年前的電視買的是真坑爹,我又不會刷機,那索性用廢筆記本裝linux整個nginx-vod模塊整個音視頻鏈接,電視上用短小精悍的VLC觀影。 下包 mkdir /usr/ ...
  • 二進位方式安裝 說明 以下操作都是基於Linux操作系統 cenos7.9 ,並且所有的操作都是基於root用戶 關閉防火牆 停止防火牆 systemctl stop firewalld 禁用防火牆開機自啟 systemctl disable firewalld 下載安裝包 下載地址如下 https ...
  • 1 StyleSheet 一張 StyleSheet 由一系列 Rules 組成,這些 Rules 可以分成 2 大類: 1 Style Rule 2 At-Rule 下麵的例子展示了 Style Rule 和 At-Rule: // Style Rule div { background-colo ...
  • 今天來盤點北京的泛互聯網公司。涵蓋了綜合類、外企類、硬體類、電商類、游戲類、娛樂類、生活類、工具類、人工智慧類、金融類、教育類、招聘類、汽車類、外包類、信息化類以及國企央企類等多個領域。 綜合類 位元組跳動 美團 百度 阿裡巴巴 騰訊 網易 外企類 微軟 谷歌 亞馬遜 Paypel Canva Sho ...
  • 針對改動範圍大、影響面廣的需求,我通常會問上線了最壞情況是什麼?應急預案是什麼?你帶開關了嗎?。當然開關也是有成本的,接下來本篇跟大家一起交流下高頻發佈支撐下的功能開關技術理論與實踐結合的點點滴滴。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...