主頁 > 後端開發 > 網站怎么接入微信掃碼支付?

網站怎么接入微信掃碼支付?

2023-06-21 07:55:09 後端開發

第01章-準備作業

1、微信支付產品介紹

參考資料:產品中心 - 微信支付商戶平臺 (qq.com)

付款碼支付、JSAPI支付、小程式支付、Native支付、APP支付、刷臉支付

1.1、付款碼支付

用戶展示微信錢包內的“付款碼”給商家,商家掃描后直接完成支付,適用于線下面對面收銀的場景,

1.2、JSAPI支付

  • 線下場所:商戶展示一個支付二維碼,用戶使用微信掃描二維碼后,輸入需要支付的金額,完成支付,
  • 公眾號場景:用戶在微信內進入商家公眾號,打開某個頁面,選擇某個產品,完成支付,
  • PC網站場景:在網站中展示二維碼,用戶使用微信掃描二維碼,輸入需要支付的金額,完成支付,

特點:用戶在客戶端輸入支付金額

1.3、小程式支付

在微信小程式平臺內實作支付的功能,

1.4、Native支付

Native支付是指商戶展示支付二維碼,用戶再用微信“掃一掃”完成支付的模式,這種方式適用于PC網站,

特點:商家預先指定支付金額

1.5、APP支付

商戶通過在移動端獨立的APP應用程式中集成微信支付模塊,完成支付,

1.6、刷臉支付

用戶在刷臉設備前通過攝像頭刷臉、識別身份后進行的一種支付方式,

2、介面版本

微信支付企業主流的API版本有v2和v3,課程中我們使用微信支付APIv3,

V2和V3的比較

image-20230227201412325

相比較而言,APIv2比APIv3安全性更高,但是APIv2中有一些功能在APIv3中尚未完整實作,具體參考如下API字典頁面:API字典概覽 | 微信支付商戶平臺檔案中心 (qq.com)

image-20230318134648306

3、接入指引

3.1、獲取開發引數

如果需要獨立申請和開通微信支付功能,可以參考如下官方檔案,開通微信支付后,才能獲取相關的開發引數以及商戶公鑰和商戶私鑰檔案,

參考資料:微信支付接入指引 - 微信支付商戶平臺 (qq.com)

3.2、配置開發引數

service-order服務的resources目錄中創建wxpay.properties

這個檔案定義了在“接入指引”的步驟中我們提前準備的微信支付相關的引數,例如商戶號、APPID、API秘鑰等等

# 微信支付相關引數
wxpay:
  mch-id: 1558950191 #商戶號
  mch-serial-no: 34345964330B66427E0D3D28826C4993C77E631F # 商戶API證書序列號
  private-key-path: D:/project/yygh/cert/apiclient_key.pem # 商戶私鑰檔案
  api-v3-key: UDuLFDcmy5Eb6o0nTNZdu6ek4DDh4K8B # APIv3密鑰
  appid: wx74862e0dfcf69954 # APPID
  notify-url: https://7d92-115-171-63-135.ngrok.io/api/order/wxpay/payment/notify # 接收支付結果通知地址
  notify-refund-url: http://agxnyzl04y90.ngrok.xiaomiqiu123.top/api/order/wxpay/refunds/notify # 接收退款結果通知地址

3.3、復制商戶私鑰

將商戶私鑰檔案復制到組態檔指定的目錄下:

資料:資料>微信支付>商戶證書>apiclient_key.pem

private-key-path: D:/project/yygh/cert/apiclient_key.pem # 商戶私鑰檔案

3.4、證書密鑰使用說明(了解)

參考檔案:APIv3證書與密鑰使用說明

一個完整的請求和回應的流程:

  • 商戶使用商戶私鑰對請求進行簽名,發送給微信支付平臺,平臺使用商戶公鑰進行簽名驗證,
  • 微信支付平臺使用平臺私鑰對回應進行簽名,商戶使用微信支付平臺公鑰對回應進行驗簽,

img

第02章-訂單支付

1、微信支付平臺證書的獲取

1.1、引入SDK

參考檔案:SDK&工具

我們可以使用官方提供的 SDK wechatpay-java

在service-order微服務中添加依賴:

<!--微信支付APIv3-->
<dependency>
  <groupId>com.github.wechatpay-apiv3</groupId>
  <artifactId>wechatpay-java</artifactId>
  <version>0.2.6</version>
</dependency>

1.2、讀取支付引數

在config 包中 創建 WxPayConfig.java

package com.atguigu.syt.order.config;

@Configuration
@PropertySource("classpath:wxpay.properties") //讀取組態檔
@ConfigurationProperties(prefix="wxpay") //讀取wxpay節點
@Data
public class WxPayConfig {

    // 商戶號
    private String mchId;

    // 商戶API證書序列號
    private String mchSerialNo;

    // 商戶私鑰檔案
    private String privateKeyPath;

    // APIv3密鑰
    private String apiV3Key;

    // APPID
    private String appid;
    
    // 接收支付結果通知地址
    private String notifyUrl;
    
    // 接收退款結果通知地址
    private String notifyRefundUrl;
   
}

1.3、自動更新微信支付平臺證書

在 API 請求程序中,客戶端需使用微信支付平臺證書,驗證服務器應答的真實性和完整性,我們使用自動更新平臺證書的配置類 RSAAutoCertificateConfig,每個商戶號只能創建一個 RSAAutoCertificateConfig

WxPayConfig中添加如下方法:

/**
     * 獲取微信支付配置物件
     * @return
     */
@Bean
public RSAAutoCertificateConfig getConfig(){

    return new RSAAutoCertificateConfig.Builder()
        .merchantId(mchId)
        .privateKeyFromPath(privateKeyPath)
        .merchantSerialNumber(mchSerialNo)
        .apiV3Key(apiV3Key)
        .build();
}

RSAAutoCertificateConfig 通過 RSAAutoCertificateProvider 自動下載微信支付平臺證書, 同時,RSAAutoCertificateProvider 會啟動一個后臺執行緒,定時更新證書(目前設計為60分鐘),以實作證書過期時的新老證書平滑切換,

常見錯誤:引入商戶私鑰后如果專案無法啟動,則需要升級JDK版本,并重新配置idea編譯和運行環境到最新版本的JDK,建議升級到1.8.0_300以上

img

2、生成支付二維碼

2.1、Native支付流程

參考檔案:業務流程時序圖

img

2.2、Controller

在service-order中創建FrontWXPayController

package com.atguigu.syt.order.controller.front;

@Api(tags = "微信支付介面")
@RestController
@RequestMapping("/front/order/wxpay")
public class FrontWXPayController {

    @Resource
    private WxPayService wxPayService;

    @Resource
    private AuthContextHolder authContextHolder;

    @ApiOperation("獲取支付二維碼url")
    @ApiImplicitParam(name = "outTradeNo",value = "https://www.cnblogs.com/deyo/archive/2023/06/20/訂單號", required = true)
    @GetMapping("/auth/nativePay/{outTradeNo}")
    public Result<String> nativePay(@PathVariable String outTradeNo, HttpServletRequest request, HttpServletResponse response) {

        //校驗用戶登錄狀態
        authContextHolder.checkAuth(request, response);

        String codeUrl = wxPayService.createNative(outTradeNo);
        return Result.ok(codeUrl);
    }
}

2.3、Service

SDK參考代碼:wechatpay-java/NativePayServiceExample.java at main · wechatpay-apiv3/wechatpay-java · GitHub

image-20230228224937529

具體代碼示例如下:

image-20230228225031308

Native下單API引數參考:Native下單API

介面:OrderInfoService

/**
 * 根據訂單號獲取訂單
 * @param outTradeNo
 * @return
 */
OrderInfo selectByOutTradeNo(String outTradeNo);

實作:OrderInfoServiceImpl

@Override
public OrderInfo selectByOutTradeNo(String outTradeNo) {
    LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(OrderInfo::getOutTradeNo, outTradeNo);
    return baseMapper.selectOne(queryWrapper);
}

介面:WxPayService

package com.atguigu.syt.order.service;

public interface WxPayService {

    /**
     * 獲取支付二維碼utl
     * @param outTradeNo
     * @return
     */
    String createNative(String outTradeNo);
}

實作:WxPayServiceImpl

package com.atguigu.syt.order.service.impl;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

    @Resource
    private RSAAutoCertificateConfig rsaAutoCertificateConfig;

    @Resource
    private WxPayConfig wxPayConfig;

    @Resource
    private OrderInfoService orderInfoService;

    @Override
    public String createNative(String outTradeNo) {

        // 初始化服務
        NativePayService service = new NativePayService.Builder().config(rsaAutoCertificateConfig).build();

        // 呼叫介面
        try {

            //獲取訂單
            OrderInfo orderInfo = orderInfoService.selectByOutTradeNo(outTradeNo);

            PrepayRequest request = new PrepayRequest();
            // 呼叫request.setXxx(val)設定所需引數,具體引數可見Request定義
            request.setAppid(wxPayConfig.getAppid());
            request.setMchid(wxPayConfig.getMchId());

            request.setDescription(orderInfo.getTitle());
            request.setOutTradeNo(outTradeNo);
            request.setNotifyUrl(wxPayConfig.getNotifyUrl());

            Amount amount = new Amount();
            //amount.setTotal(orderInfo.getAmount().multiply(new BigDecimal(100)).intValue());
            amount.setTotal(1);//1分錢
            request.setAmount(amount);
            // 呼叫介面
            PrepayResponse prepayResponse = service.prepay(request);

            return prepayResponse.getCodeUrl();

        } catch (HttpException e) { // 發送HTTP請求失敗
            // 呼叫e.getHttpRequest()獲取請求列印日志或上報監控,更多方法見HttpException定義
            log.error(e.getHttpRequest().toString());
            throw new GuiguException(ResultCodeEnum.FAIL);
        } catch (ServiceException e) { // 服務回傳狀態小于200或大于等于300,例如500
            // 呼叫e.getResponseBody()獲取回傳體列印日志或上報監控,更多方法見ServiceException定義
            log.error(e.getResponseBody());
            throw new GuiguException(ResultCodeEnum.FAIL);
        } catch (MalformedMessageException e) { // 服務回傳成功,回傳體型別不合法,或者決議回傳體失敗
            // 呼叫e.getMessage()獲取資訊列印日志或上報監控,更多方法見MalformedMessageException定義
            log.error(e.getMessage());
            throw new GuiguException(ResultCodeEnum.FAIL);
        }
    }
}

可見,使用 SDK 并不需要計算請求簽名和驗證應答簽名,

3、前端整合

3.1、api

創建api/wxpay.js

import request from '~/utils/request'
export default {
  //獲取支付二維碼url
  nativePay(outTradeNo) {
    return request({
      url: `/front/order/wxpay/auth/nativePay/${outTradeNo}`,
      method: 'get'
    })
  },
}

3.2、修改show.vue

引入api

import wxpayApi from '~/api/wxpay'

添加data資料

codeUrl: null, //微信支付二維碼
isPayShow: false, //不顯示登錄二維碼組件
payText: '支付'

修改按鈕

將
<div  @click="pay()">支付</div>
修改為
<div  @click="pay()">{{payText}}</div>

添加方法

//支付
pay() {
    //防止重復提交
    if(this.isPayShow) return
    this.isPayShow = true
    this.payText = '支付中.....'

    //顯示二維碼
    wxpayApi.nativePay(this.orderInfo.outTradeNo).then((response) => {
        this.codeUrl = response.data
        this.dialogPayVisible = true
    })
},

//關閉對話框
closeDialog(){
    //恢復支付按鈕
    this.isPayShow = false
    this.payText = '支付'
}

用二維碼組件替換img圖片

<img src="https://www.cnblogs.com/deyo/archive/2023/06/20/二維碼鏈接" alt="" />

替換成

<qriously :value="https://www.cnblogs.com/deyo/archive/2023/06/20/codeUrl" :size="220"/>

img

第03章-查詢支付結果

1、支付查單

參考檔案:微信支付查單介面

商戶可以主動呼叫微信支付查單介面,同步訂單狀態,

呼叫查詢訂單介面,如果支付成功則更新訂單狀態添加交易記錄,如果支付尚未成功則輪詢查單

1.1、更新訂單狀態

OrderInfoService介面

/**
     * 根據訂單號更新訂單狀態
     * @param outTradeNo
     * @param status
     */
void updateStatus(String outTradeNo, Integer status);

OrderInfoServiceImpl實作

@Override
public void updateStatus(String outTradeNo, Integer status) {

    LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(OrderInfo::getOutTradeNo, outTradeNo);

    OrderInfo orderInfo = new OrderInfo();
    orderInfo.setOrderStatus(status);
    baseMapper.update(orderInfo, queryWrapper);
}

1.2、添加交易記錄

PaymentInfoService介面

/**
     * 保存交易記錄
     * @param orderInfo
     * @param transaction
     */
void savePaymentInfo(OrderInfo orderInfo, Transaction transaction);

實作:PaymentInfoServiceImpl

@Override
public void savePaymentInfo(OrderInfo orderInfo, Transaction transaction) {

    PaymentInfo paymentInfo = new PaymentInfo();
    paymentInfo.setOrderId(orderInfo.getId());
    paymentInfo.setPaymentType(PaymentTypeEnum.WEIXIN.getStatus());
    paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());//資料庫欄位的長度改成32
    paymentInfo.setSubject(orderInfo.getTitle());
    paymentInfo.setTotalAmount(orderInfo.getAmount());
    paymentInfo.setPaymentStatus(PaymentStatusEnum.PAID.getStatus());
    paymentInfo.setTradeNo(transaction.getTransactionId());
    paymentInfo.setCallbackTime(new Date());
    paymentInfo.setCallbackContent(transaction.toString());
    baseMapper.insert(paymentInfo);
}

1.3、查單Controller

FrontWXPayController

@ApiOperation("查詢支付狀態")
@ApiImplicitParam(name = "outTradeNo",value = "https://www.cnblogs.com/deyo/archive/2023/06/20/訂單id", required = true)
@GetMapping("/queryPayStatus/{outTradeNo}")
public Result queryPayStatus(@PathVariable String outTradeNo) {
    //呼叫查詢介面
    boolean success = wxPayService.queryPayStatus(outTradeNo);
    if (success) {
        return Result.ok().message("支付成功");
    }
    return Result.ok().message("支付中").code(250);
}

1.4、查單Service

介面:WxPayService

/**
     * 查詢訂單支付狀態
     * @param outTradeNo
     * @return
     */
boolean queryPayStatus(String outTradeNo);

實作:WxPayServiceImpl

@Resource
private PaymentInfoService paymentInfoService;

@Override
public boolean queryPayStatus(String outTradeNo) {

    // 初始化服務
    NativePayService service = new NativePayService.Builder().config(rsaAutoCertificateConfig).build();

    // 呼叫介面
    try {

        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        // 呼叫request.setXxx(val)設定所需引數,具體引數可見Request定義
        request.setOutTradeNo(outTradeNo);
        request.setMchid(wxPayConfig.getMchId());

        // 呼叫介面
        Transaction transaction = service.queryOrderByOutTradeNo(request);
        Transaction.TradeStateEnum tradeState = transaction.getTradeState();

        //支付成功
        if(tradeState.equals(Transaction.TradeStateEnum.SUCCESS)){

            OrderInfo orderInfo = orderInfoService.selectByOutTradeNo(outTradeNo);

            //更新訂單狀態
            orderInfoService.updateStatus(outTradeNo, OrderStatusEnum.PAID.getStatus());
            //記錄支付日志
            paymentInfoService.savePaymentInfo(orderInfo, transaction);

            //通知醫院修改訂單狀態
            //組裝引數
            HashMap<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("hoscode", orderInfo.getHoscode());
            paramsMap.put("hosOrderId", orderInfo.getHosOrderId());
            paramsMap.put("timestamp", HttpRequestHelper.getTimestamp());

            paramsMap.put("sign", HttpRequestHelper.getSign(paramsMap, "8af52af00baf6aec434109fc17164aae"));
            //發送請求
            JSONObject jsonResult = HttpRequestHelper.sendRequest(paramsMap, "http://localhost:9998/order/updatePayStatus");
            //決議回應
            if(jsonResult.getInteger("code") != 200) {
                log.error("查單失敗,"
                          + "code:" + jsonResult.getInteger("code")
                          + ",message:" + jsonResult.getString("message")
                         );
                throw new GuiguException(ResultCodeEnum.FAIL.getCode(), jsonResult.getString("message"));
            }

            //回傳支付結果
            return true;//支付成功
        }

        return false;//支付中

    } catch (HttpException e) { // 發送HTTP請求失敗
        // 呼叫e.getHttpRequest()獲取請求列印日志或上報監控,更多方法見HttpException定義
        log.error(e.getHttpRequest().toString());
        throw new GuiguException(ResultCodeEnum.FAIL);
    } catch (ServiceException e) { // 服務回傳狀態小于200或大于等于300,例如500
        // 呼叫e.getResponseBody()獲取回傳體列印日志或上報監控,更多方法見ServiceException定義
        log.error(e.getResponseBody());
        throw new GuiguException(ResultCodeEnum.FAIL);
    } catch (MalformedMessageException e) { // 服務回傳成功,回傳體型別不合法,或者決議回傳體失敗
        // 呼叫e.getMessage()獲取資訊列印日志或上報監控,更多方法見MalformedMessageException定義
        log.error(e.getMessage());
        throw new GuiguException(ResultCodeEnum.FAIL);
    }
}

2、前端整合

2.1、修改request.js

utils/request.js的回應攔截器中增加對250狀態的判斷

}else if (response.data.code !== 200) {
    
修改為

}else if (response.data.code !== 200 && response.data.code !== 250) {

2.2、api

在api/wxpay.js中添加的方法

//查詢訂單
queryPayStatus(outTradeNo) {
    return request({
        url: `/front/order/wxpay/queryPayStatus/${outTradeNo}`,
        method: 'get'
    })
},

3.3、show.vue輪詢查單

js中修改pay方法:每隔3秒查單

添加queryPayStatus方法

完善closeDialog方法:停止定時器

//發起支付
pay(){
  if(this.isPayShow) return
  this.isPayShow = true
  this.payText = '支付中.....'
    
  wxpayApi.nativePay(this.orderInfo.outTradeNo).then((response) => {
    this.codeUrl = response.data
    this.dialogPayVisible = true
      
    //每隔3秒查單
    this.timer = setInterval(()=>{
      console.log('輪詢查單:' + new Date())
      this.queryPayStatus()
    }, 3000)
  })
},
    
//查詢訂單狀態
queryPayStatus(){
  wxpayApi.queryPayStatus(this.orderInfo.outTradeNo).then(response => {
    if(response.code == 250){
        return
    }
    //清空定時器
    clearInterval(this.timer)
    window.location.reload()
  })
},

//關閉對話框
closeDialog(){
    //停止定時器
    clearInterval(this.timer)
    //恢復支付按鈕
    this.isPayShow = false
    this.payText = '支付'
}

3、查單應答超時

3.1、測驗應答超時

//應答超時
//設定回應超時,支付成功后沒有及時回應,可能繼續輪詢查單,此時資料庫會記錄多余的支付日志
try {
    TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
    throw new RuntimeException(e);
}


//回傳支付結果
return true;//支付成功

3.2、處理重復通知

支付成功后,判斷訂單狀態:

OrderInfo orderInfo = orderInfoService.selectByOutTradeNo(outTradeNo);
//處理支付成功后重復查單
//保證介面呼叫的冪等性:無論介面被呼叫多少次,產生的結果是一致的
Integer orderStatus = orderInfo.getOrderStatus();
if (OrderStatusEnum.UNPAID.getStatus().intValue() != orderStatus.intValue()) {
    return true;//支付成功、關單、,,,
}

//更新訂單狀態
//記錄支付日志
......

本文來自博客園,作者:自律即自由-,轉載請注明原文鏈接:https://www.cnblogs.com/deyo/p/17495203.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555677.html

標籤:其他

上一篇:C++面試八股文:static_cast了解一下?

下一篇:返回列表

標籤雲
其他(161380) Python(38243) JavaScript(25509) Java(18250) C(15238) 區塊鏈(8271) C#(7972) AI(7469) 爪哇(7425) MySQL(7259) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4606) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2436) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) HtmlCss(1968) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 網站怎么接入微信掃碼支付?

    # 第01章-準備作業 ## 1、微信支付產品介紹 參考資料:[產品中心 - 微信支付商戶平臺 (qq.com)](https://pay.weixin.qq.com/static/product/product_index.shtml#payment_product) 付款碼支付、JSAPI支付、 ......

    uj5u.com 2023-06-21 07:55:09 more
  • C++面試八股文:static_cast了解一下?

    某日二師兄參加XXX科技公司的C++工程師開發崗位第20面: > 面試官:C++中支持哪些型別轉換? > > 二師兄:C++支持C風格的型別轉換,并在C++11引入新的關鍵字規范了型別轉換。 > > 二師兄:C++11引入四種新的型別轉換,分別是`static_cast`、`dynamic_cast ......

    uj5u.com 2023-06-21 07:55:03 more
  • 提前預體驗阿里大模型“通義千問”的方法來了!

    隨著AI大模型的浪潮席卷全球,如今的AI技術已經顛覆了大家對傳統AI的認識,微軟更是用瀏覽器與搜索引擎上的實踐,證明了當今的AI技術具備打破行業格局的能力。 對于我們應用開發者來說,AI基建的建設與競爭是無法參與的,但在AI的應用領域依然大有可為!目前,國內各大科技公司已經陸續推出了各自的AI大模型 ......

    uj5u.com 2023-06-21 07:54:55 more
  • 使用EasyExcel對excel資料進行相似度判斷

    @Data public class ExeclDto { /** * execl表 */ private String filename; /** * 需要匹配的作業表名 */ private String name1; /** * 需要匹配的作業表名 */ private String name ......

    uj5u.com 2023-06-21 07:54:44 more
  • 【whale-starry-stl】01天 list學習筆記

    # 一、知識點 ## 1. std::bidirectional_iterator_tag `std::bidirectional_iterator_tag` 是 C++ 標準庫中定義的一個迭代器型別標簽,用于標識支持雙向遍歷的迭代器型別。 在 C++ 中,迭代器是一種泛型指標,用于遍歷容器中的元素 ......

    uj5u.com 2023-06-21 07:54:25 more
  • 52基于java的心理健康評測管理系統設計與實作

    基于java心理健康評測管理系統設計與實作,大學生心理健康,大學生心理評測管理系統,心理健康平臺系統,校園心理健康評測平臺,校園健康咨詢,校園心理健康咨詢,java心理咨詢室,校園心理咨詢室。 ......

    uj5u.com 2023-06-21 07:53:35 more
  • Python工具箱系列(三十六)

    Docker提供了基于鏡像的運行環境,可以將作業系統、應用程式以及相關依賴打包,為使用者提供完整的使用體驗,因此一經推出大獲好評,迅速成為主流的軟體開發技術之一。 ......

    uj5u.com 2023-06-21 07:53:14 more
  • jxls根據模板匯出Excel(二)

    說明:本文是jxls根據模板匯出Excel直接下載。 使用版本:jxls V2.10.0 excel模板版本:.xlsx格式 jxls官網地址:https://jxls.sourceforge.net/index.html 1、pom參考 <dependency> <groupId>org.jxls ......

    uj5u.com 2023-06-21 07:48:02 more
  • 51基于java的高校就業管理系統設計與實作

    基于java的高校就業管理系統設計與實作,可適用于高校就業招聘,大學招聘管理系統,校園招聘系統,就業資訊管理系統,畢業招聘系統,畢業就業系統,大學生就業招聘平臺,校園就業資訊平臺,校園畢業資訊管理平臺,大學生就業招聘,大學生畢業招聘管理平臺等等 ......

    uj5u.com 2023-06-21 07:42:36 more
  • JPA在事務結束時自動更新查詢資料

    [toc] # 現象 最近解決了一個困惑幾天的bug,資料庫里的某一些記錄莫名其妙的被重繪了,排查過代碼跟應用日志,可以確定不是代碼執行的更新。直到今天看到了一條日志,在事務提交時報錯“Column 'user_name' cannot be null”,在出錯的事務中,針對這一個表只會執行quer ......

    uj5u.com 2023-06-21 07:42:21 more