Add instant payment collection flow aligned with Android.
Implement收款详情与收款记录 pages with pay-code API, QR generation, amount setting, and record grouping so merchants can collect payments from the home quick action. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
59
suixinkan/Common/QRCodeGenerator.swift
Normal file
59
suixinkan/Common/QRCodeGenerator.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// QRCodeGenerator.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import CoreImage
|
||||
import UIKit
|
||||
|
||||
/// 圆角样式二维码生成器,对齐 Android `QrCodeUtils.generateStyledQrBitmap`。
|
||||
enum QRCodeGenerator {
|
||||
|
||||
private static let defaultPixelSize = 580
|
||||
private static let defaultCornerRadius: CGFloat = 24
|
||||
|
||||
/// 根据内容生成带圆角背景的二维码图片。
|
||||
static func generateStyledQRCode(
|
||||
content: String,
|
||||
pixelSize: Int = defaultPixelSize,
|
||||
backgroundColor: UIColor = AppColor.inputBackground,
|
||||
cornerRadius: CGFloat = defaultCornerRadius
|
||||
) -> UIImage? {
|
||||
guard !content.isEmpty,
|
||||
let qrImage = makeQRCodeImage(from: content, pixelSize: pixelSize) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let size = CGSize(width: pixelSize, height: pixelSize)
|
||||
let format = UIGraphicsImageRendererFormat()
|
||||
format.scale = 1
|
||||
let renderer = UIGraphicsImageRenderer(size: size, format: format)
|
||||
return renderer.image { context in
|
||||
let rect = CGRect(origin: .zero, size: size)
|
||||
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
|
||||
backgroundColor.setFill()
|
||||
path.fill()
|
||||
|
||||
context.cgContext.saveGState()
|
||||
path.addClip()
|
||||
qrImage.draw(in: rect)
|
||||
context.cgContext.restoreGState()
|
||||
}
|
||||
}
|
||||
|
||||
private static func makeQRCodeImage(from content: String, pixelSize: Int) -> UIImage? {
|
||||
guard let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
|
||||
let data = Data(content.utf8)
|
||||
filter.setValue(data, forKey: "inputMessage")
|
||||
filter.setValue("M", forKey: "inputCorrectionLevel")
|
||||
guard let outputImage = filter.outputImage else { return nil }
|
||||
|
||||
let scale = CGFloat(pixelSize) / outputImage.extent.width
|
||||
let scaledImage = outputImage.transformed(by: CGAffineTransform(scaleX: scale, y: scale))
|
||||
let context = CIContext()
|
||||
guard let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) else {
|
||||
return nil
|
||||
}
|
||||
return UIImage(cgImage: cgImage)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user