Просмотр исходного кода

031 Phase1-2:DDL文档+三实体+PaymentMethodGateService闸门(缺行=开/CARD_OMG联动/现金放行)+i18n+11单测全过

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
qmj 8 часов назад
Родитель
Сommit
d1ef68d3c9

+ 350 - 345
ruoyi-admin/src/main/resources/i18n/messages.properties

@@ -1,361 +1,366 @@
 #错误消息
 #错误消息
-not.null=* Cần điền
-user.jcaptcha.error=Lỗi CAPTCHA
-user.jcaptcha.expire=CAPTCHA không hoạt động
-user.not.exists=Người dùng không tồn tại/Lỗi mật khẩu
-user.password.not.match=Người dùng không tồn tại/Lỗi mật khẩu
-user.password.retry.limit.count=Nhập mật khẩu sai {0} lần
-user.password.retry.limit.exceed=Nhập sai mật khẩu {0} lần, khóa tài khoản {1} phút
-user.password.delete=Không, tài khoản của bạn đã bị xóa.
-user.blocked=Người dùng đã bị chặn, vui lòng liên hệ với quản trị viên
-role.blocked=Nhân vật bị cấm, vui lòng liên hệ với quản trị viên
-login.blocked=Thật không may, IP truy cập đã bị đưa vào danh sách đen hệ thống
-user.logout.success=Thoát thành công
+not.null=* 必須填寫
+user.jcaptcha.error=驗證碼錯誤
+user.jcaptcha.expire=驗證碼已失效
+user.not.exists=用戶不存在/密碼錯誤
+user.password.not.match=用戶不存在/密碼錯誤
+user.password.retry.limit.count=密碼輸入錯誤{0}次
+user.password.retry.limit.exceed=密碼輸入錯誤{0}次,帳戶鎖定{1}分鐘
+user.password.delete=對不起,您的帳號已被删除
+user.blocked=用戶已封禁,請聯系管理員
+role.blocked=角色已封禁,請聯系管理員
+login.blocked=很遺憾,訪問IP已被列入系統黑名單
+user.logout.success=退出成功
 
 
-length.not.valid=Độ dài phải từ {min} đến {max} ký tự
+length.not.valid=長度必須在{min}到{max}個字元之間
 
 
-user.username.not.valid=* Từ 2 đến 20 ký tự Trung Quốc, chữ cái, số hoặc gạch dưới và phải bắt đầu bằng một số không phải là số
-user.password.not.valid=* 5-50 ký tự
+user.username.not.valid=* 2到20個漢字、字母、數位或底線組成,且必須以非數位開頭
+user.password.not.valid=* 5-50個字元
 
 
-user.email.not.valid=Lỗi định dạng hộp thư
-user.mobile.phone.number.not.valid=Định dạng số điện thoại sai
-user.login.success=Đăng nhập thành công
-user.register.success=Đăng ký thành công
-user.notfound=Vui lòng đăng nhập lại
-user.forcelogout=Quản trị viên buộc thoát, vui lòng đăng nhập lại
-user.unknown.error=Lỗi không rõ, vui lòng đăng nhập lại
+user.email.not.valid=郵箱格式錯誤
+user.mobile.phone.number.not.valid=手機號格式錯誤
+user.login.success=登入成功
+user.register.success=注册成功
+user.notfound=請重新登入
+user.forcelogout=管理員強制退出,請重新登入
+user.unknown.error=未知錯誤,請重新登入
 
 
 ##文件上传消息
 ##文件上传消息
-upload.exceed.maxSize=Kích thước tập tin được tải lên vượt quá kích thước tập tin giới hạn!< <br/>Kích thước tối đa cho phép của tập tin là: {0}MB !
-upload.filename.exceed.length=Tên tập tin đã tải lên Dài nhất {0} ký tự
+upload.exceed.maxSize=上傳的文件大小超出限制的文件大小!< br/>允許的檔案最大大小是: {0}MB !
+upload.filename.exceed.length=上傳的檔名最長{0}個字元
 
 
 ##权限
 ##权限
-no.permission=Bạn không có quyền cho dữ liệu, hãy liên hệ với quản trị viên để thêm quyền [{0}]
-no.create.permission=Bạn không có quyền tạo dữ liệu, hãy liên hệ với quản trị viên để thêm quyền [{0}]
-no.update.permission=Bạn không có quyền sửa đổi dữ liệu, vui lòng liên hệ với quản trị viên để thêm quyền [{0}]
-no.delete.permission=Bạn không có quyền xóa dữ liệu, hãy liên hệ với quản trị viên để thêm quyền [{0}]
-no.export.permission=Bạn không có quyền xuất dữ liệu, vui lòng liên hệ với quản trị viên để thêm quyền [{0}]
-no.view.permission=Bạn không có quyền xem dữ liệu, vui lòng liên hệ với quản trị viên để thêm quyền [{0}]
+no.permission=您沒有數據的許可權,請聯系管理員添加許可權[{0}]
+no.create.permission=您沒有創建數據的許可權,請聯系管理員添加許可權[{0}]
+no.update.permission=您沒有修改數據的許可權,請聯系管理員添加許可權[{0}]
+no.delete.permission=您沒有删除數據的許可權,請聯系管理員添加許可權[{0}]
+no.export.permission=您沒有匯出數據的許可權,請聯系管理員添加許可權[{0}]
+no.view.permission=您沒有查看數據的許可權,請聯系管理員添加許可權[{0}]
 
 
 ##自定义返回
 ##自定义返回
-no.obtained.permission=Nhận thành công
-no.obtained.success=Truy vấn thành công
-no.action.success=Hoạt động thành công
-no.action.fail=Hoạt động thất bại
-no.data.exist.not.del=Danh mục này có hàng hóa và không thể xóa
-no.comment.success=Đánh giá thành công
-no.comment.fail=Thất bại, vui lòng thử lại
-no.comment.repeat=Bạn đã đánh giá đơn đặt hàng
-no.delete.success=Xóa thành công
-no.delete.fail=Thất bại, vui lòng thử lại
-no.tip.lock.keywork=Vui lòng điền từ khóa
-no.load.success=Tải thành công
-no.modify.success=Sửa đổi thành công
-no.collection.success=Sưu tầm thành công
-no.collection.cancel=Hủy bộ sưu tập
-no.success=Thành công
-no.cash_on_delivery_amount.exceed.limit_amount=thu tiền khi giao hàng Số tiền vượt quá giới hạn
-no.exist.cash_on_delivery_order.incomplete=Vẫn còn nhiều đơn đặt hàng chưa hoàn thành
-no.address.not.exist=Địa chỉ nhận hàng không tồn tại
-no.mendian.not.exist=Cửa hàng không còn tồn tại
-no.mendian.not.set.business.hours=Cửa hàng hiện tại không đặt giờ hoạt động
-no.mendian.is.closed=Cửa hàng đã đóng cửa.
-no.goods.not.exist=Không còn nữa, vui lòng chọn sản phẩm khác
-no.goods.is.off.shelf=Sản phẩm đã được gỡ khỏi kệ. Vui lòng chọn sản phẩm khác để đặt hàng.
-no.order.submit.success=Gửi đơn đặt hàng thành công
-no.mendian.exist.classify.not.del=Cửa hàng này tồn tại dữ liệu phân loại, vui lòng xóa phân loại trước khi xóa
-no.insufficient.user.security.deposit=Tiền đặt cọc bảo đảm của người dùng không đủ
-no.order.snatched=Lệnh bị cướp
-no.exist.undelivered.order=Bạn có đơn đặt hàng chưa giao, vui lòng xử lý đơn đặt hàng trước khi nhận
-no.user.not.vip=Thành viên này chưa mở thành viên
-no.user.vip.expired=Thành viên hết hạn
-no.user.add=Người dùng mới
-no.user.login.exist=Không thành công, tài khoản đăng nhập đã tồn tại
-no.user.mobile.exist=Thất bại, số điện thoại di động đã tồn tại
-no.user.phone.blank=手机号不能为空
-no.user.password.not.null=Mật khẩu không được để trống
-no.user.jcaptcha.error=CAPTCHA không đúng
-no.user.not.exist=Người dùng không tồn tại
-no.user.phone.duplicate=该手机号关联多个账号,请联系平台
-no.user.login.success=Đăng nhập thành công
-no.user.password.error=Mật khẩu sai
-no.system.error=Lỗi hệ thống
-no.sms.send.success=Gửi SMS thành công
-no.user.password.modify.success=Thay đổi mật khẩu thành công
-no.user.password.old.error=Mật khẩu cũ không đúng
-no.user.stop=Người dùng đã bị vô hiệu hóa
-no.user.token.success=Nhận token thành công
-no.user.info=Thông tin người dùng
-no.user.deposit.not.exist=Không có bản ghi tiền gửi
-no.user.deposit.type.not.exist=Không có khoản tiền gửi nào thuộc loại này tồn tại
-no.user.call.status.not.exist=Không có trạng thái cuộc gọi, không thể cúp máy
-no.user.call.hangup.success=Kết thúc cuộc gọi thành công
-no.user.call.not.exist=Người dùng này không có thông tin cuộc gọi nào
-no.user.call.calling.success=Cuộc gọi đã được khởi tạo thành công
-no.user.call.other.is.calling=Người kia hiện đang gọi điện và không thể gọi được
-no.user.call.accept.success=Yêu cầu kết nối thành công
-no.user.call.request.success=Yêu cầu cuộc gọi thành công
-no.user.not.vip=Bạn không phải là thành viên
-no.upload.success=Tải lên thành công
-no.send.success=Đã gửi thành công
-no.send.fail=Gửi không thành công
-no.convert.success=Chuyển đổi thành công
-no.order.not.exist=Đơn hàng không tồn tại
-no.order.place.success=Đã đặt hàng thành công
-no.order.id.error=Mã đơn hàng không đúng
-no.order.create.success=Đơn hàng đã được tạo thành công
-no.message.push.message=tin nhắn
-no.message.push.delivery.personnel.receiving.order=Người giao hàng đã nhận đơn
-no.message.push.rider.accepted.merchant=Tài xế đã nhận đơn, vui lòng xác nhận và chuẩn bị món
-no.message.push.order.cancelled=Đơn hàng đã bị hủy
-no.order.rider.accept.required=Vui lòng đợi tài xế nhận đơn trước khi thao tác
-no.message.push.delivery.personnel.qspsz.order=Shipper đang giao đến
-no.message.push.delivery.personnel.qsysd.order=Shipper đã giao xong.
-no.message.push.new.order=có lệnh mới
-no.message.push.recharge.success=nạp tiền thành công
-no.message.push.payment.success=thanh toán thành công
-no.message.push.payment.fail=thanh toán thất bại
-no.message.push.end.call=Kết thúc cuộc gọi
-no.message.push.call.hangoup=Cuộc gọi đã bị ngắt kết nối
-no.message.push.call.call=cuộc gọi
-no.message.push.call.request=Yêu cầu gọi
-no.message.push.call.accept=Bật tin nhắn
-no.message.push.call.agree=đồng ý với yêu cầu gọi của bạn
-no.export.excel.mendian.classify=Dữ liệu phân loại cửa hàng
-no.export.excel.goods.classify=Dữ liệu phân loại hàng hóa
-no.export.excel.collection=Dữ liệu bộ sưu tập
-no.export.excel.food=Dữ liệu thực phẩm
-no.export.excel.posstore=Dữ liệu PosStore
-no.export.excel.servicetype=Dữ liệu ServiceType
-no.export.excel.distancemultiplier=Dữ liệu DistanceMultiplier
-no.export.excel.address=Dữ liệu địa chỉ
-no.export.excel.freight.data=Dữ liệu vận chuyển hàng hóa
-no.export.excel.posorder=Dữ liệu PosOrder
-no.export.excel.review=Xem lại dữ liệu
-no.export.excel.taxiorder=Dữ liệu TaxiOrder
-no.export.excel.taxiprices=Dữ liệu TaxiPrices
-no.export.excel.bankcard=Dữ liệu thẻ ngân hàng
-no.export.excel.ipnlog=Dữ liệu IpnLog
-no.export.excel.billing=Dữ liệu thanh toán
-no.export.excel.salespromotion=Dữ liệu SalesPromotion
-no.export.excel.enterpriseintroduce=EnterpriseIntroduce dữ liệu
-no.export.excel.userinfo=Dữ liệu thông tin người dùng
-no.export.excel.margin=Dữ liệu lề
-no.export.excel.riderposition=Dữ liệu RiderPosition
-no.export.excel.feedback=Dữ liệu phản hồi
-no.export.excel.help=Dữ liệu trợ giúp
-no.export.excel.footprint=Dữ liệu dấu chân
-no.export.excel.usermargin=Dữ liệu UserMargin
-no.export.excel.videocall=Dữ liệu cuộc gọi video
-no.export.excel.viplist=Dữ liệu VipList
-no.export.excel.rights=Dữ liệu quyền
-no.export.excel.version=Dữ liệu phiên bản
-no.userquanyi.not.exist=Không tìm thấy phiếu giảm giá
-userquanyi.isUsed=Phiếu giảm giá đã được sử dụng
-no.activity.not.exist=Khuyến mãi không tồn tại
-no.map.exception=Lỗi truy vấn đường đi trên bản đồ
-no.xiadanyz.message=Để đảm bảo an toàn tài sản của bạn, hãy sử dụng phiên bản mới nhất đặt hàng!
-no.youhuiquan.lqnodata=Không tìm thấy thông tin ưu đãi
-no.youhuiquan.lqyhqgb=Phiếu ưu đãi đã đóng
-no.youhuiquan.lqyhqolqw=Phiếu ưu đãi đã được nhận hết
-no.youhuiquan.lqyhqdy=Số lượng nhận phải lớn hơn 0
-no.youhuiquan.lqyhqysx=Bạn đã đạt giới hạn nhận phiếu ưu đãi này
-no.youhuiquan.lqyhqybxg=Dữ liệu đã bị thay đổi, vui lòng làm mới và thử lại
-no.points.insufficient=Số điểm của bạn không đủ
-no.points.use.enable=Việc sử dụng điểm đã bị tắt
-no.points.update.fail=Cập nhật ví điểm thất bại, vui lòng thử lại
-no.points.use.fail=Khấu trừ điểm chưa được bật
-no.points.not.exist=Ví điểm của bạn không tồn tại
-no.message.push.merchant.ready.title=Thương gia đã chuẩn bị xong
-no.message.push.merchant.ready.content=Thương gia đã chuẩn bị xong, mã đơn hàng:
-no.posorder.md.yh.mc.messag=优惠券:{};
-no.posorder.md.yh.jiner.messag=优惠抵扣:{};
-no.posorder.md.cx.mc.messag=促销:{};
-no.posorder.md.cx.jiner.messag=促销抵扣:{};
-no.wallet.common.cs.error=操作失败,请联系客服
+no.obtained.permission=獲取成功
+no.obtained.success=査詢成功
+no.action.success=操作成功
+no.action.fail=操作失敗
+no.data.exist.not.del=此分類存在商品,無法删除
+no.comment.success=評估成功
+no.comment.fail=失敗,請重試
+no.comment.repeat=您已評估過該訂單
+no.delete.success=删除成功
+no.delete.fail=失敗,請重試
+no.tip.lock.keywork=請填寫關鍵字
+no.load.success=加載成功
+no.modify.success=修改成功
+no.collection.success=收藏成功
+no.collection.cancel=取消收藏
+no.success=成功
+no.cash_on_delivery_amount.exceed.limit_amount=貨到付款金額超過限定金額
+no.exist.cash_on_delivery_order.incomplete=還有多個到付訂單未完成
+no.address.not.exist=收貨地址不存在
+no.mendian.not.exist=門店已不存在
+no.mendian.not.set.business.hours=當前門店未設定營業時間
+no.mendian.is.closed=門店已打烊
+no.goods.not.exist=已不存在,請選擇別的商品下單
+no.goods.is.off.shelf=已下架,請選擇別的商品下單
+no.order.submit.success=提交訂單成功
+no.mendian.exist.classify.not.del=此門店存在分類數據,請先删除分類再删除
+no.insufficient.user.security.deposit=用戶保正金不足
+no.order.snatched=訂單被創走了
+no.exist.undelivered.order=您有未送達訂單,請處理完訂單再接單
+no.user.not.vip=此用戶未開通會員
+no.user.vip.expired=會員已過期
+no.user.add=新增用戶
+no.user.login.exist=失敗,登入帳號已存在
+no.user.mobile.exist=失敗,手機號碼已存在
+no.user.phone.blank=手機號碼不可為空
+no.user.password.not.null=密碼不能為空
+no.user.jcaptcha.error=驗證碼不正確
+no.user.not.exist=用戶不存在
+no.user.phone.duplicate=該手機號關聯多個帳號,請聯繫平台
+pay.method.not.available=該支付方式當前不可用,請更換支付方式
+no.user.login.success=登入成功
+no.user.password.error=密碼錯誤
+no.system.error=系統錯誤
+no.sms.send.success=短信發送成功
+no.user.password.modify.success=密碼修改成功
+no.user.password.old.error=原密碼不正確
+no.user.stop=用戶已停用
+no.user.token.success=獲取token成功
+no.user.info=用戶資訊
+no.user.deposit.not.exist=無保證金記錄
+no.user.deposit.type.not.exist=無此類型押金
+no.user.call.status.not.exist=無通話狀態,無法掛斷
+no.user.call.hangup.success=掛斷呼叫成功
+no.user.call.not.exist=此用戶不存在通話資訊
+no.user.call.calling.success=發起呼叫成功
+no.user.call.other.is.calling=對方正在通話,無法呼叫
+no.user.call.accept.success=接通請求成功
+no.user.call.request.success=請求通話成功
+no.user.not.vip=您不是會員
+no.upload.success=上傳成功
+no.send.success=發送成功
+no.send.fail=發送失敗
+no.convert.success=轉換成功
+no.order.not.exist=訂單不存在
+no.order.place.success=下單成功
+no.order.id.error=訂單id不正確
+no.order.create.success=創建訂單成功
+no.message.push.message=訊息
+no.message.push.delivery.personnel.receiving.order=騎手已接單
+no.message.push.rider.accepted.merchant=騎手已接單,請及時確認並備餐
+no.message.push.order.cancelled=訂單已取消
+no.order.rider.accept.required=請等待騎手接單後再操作訂單
+no.message.push.new.order=有新訂單
+no.message.push.recharge.success=充值成功
+no.message.push.payment.success=支付成功
+no.message.push.payment.fail=支付失敗
+no.message.push.end.call=結束通話
+no.message.push.call.hangup=通話已被對方掛斷
+no.message.push.call.calling=通話呼叫
+no.message.push.call.request=向你發起通話請求
+no.message.push.call.accept=接通消息
+no.message.push.call.agree=同意了您的通話請求
+no.export.excel.mendian.classify=門店分類數據
+no.export.excel.goods.classify=商品分類數據
+no.export.excel.collection=收藏數據
+no.export.excel.food=Food數據
+no.export.excel.posstore=PosStore數據
+no.export.excel.servicetype=ServiceType數據
+no.export.excel.distancemultiplier=DistanceMultiplier數據
+no.export.excel.address=Address數據
+no.export.excel.freight.data=Freight數據
+no.export.excel.posorder=PosOrder數據
+no.export.excel.review=Review數據
+no.export.excel.taxiorder=TaxiOrder數據
+no.export.excel.taxiprices=TaxiPrices數據
+no.export.excel.bankcard=BankCard數據
+no.export.excel.ipnlog=IpnLog數據
+no.export.excel.billing=Billing數據
+no.export.excel.salespromotion=SalesPromotion數據
+no.export.excel.enterpriseintroduce=EnterpriseIntroduce數據
+no.export.excel.userinfo=用戶資訊數據
+no.export.excel.margin=Margin數據
+no.export.excel.riderposition=RiderPosition數據
+no.export.excel.feedback=Feedback數據
+no.export.excel.help=Help數據
+no.export.excel.footprint=Footprint數據
+no.export.excel.usermargin=UserMargin數據
+no.export.excel.videocall=VideoCall數據
+no.export.excel.viplist=VipList數據
+no.export.excel.rights=Rights數據
+no.export.excel.version=Version數據
+no.userquanyi.not.exist=未找到優惠券
+userquanyi.isUsed=優惠券已被使用
+no.activity.not.exist=促銷活動不存在
+no.map.exception=地圖路線查詢錯誤
+no.xiadanyz.message=為確保您的帳戶安全,請更新後重新下單!
+no.youhuiquan.lqnodata=未找到優惠券資訊
+no.youhuiquan.lqyhqgb=優惠券已經關閉
+no.youhuiquan.lqyhqolqw=優惠券已被領取完
+no.youhuiquan.lqyhqdy=領取數量必須大於0
+no.youhuiquan.lqyhqysx=您已達到該優惠券的領取上限
+no.youhuiquan.lqyhqybxg=資料已被修改,請重新整理後重試
+no.points.insufficient=您的積分不足
+no.points.use.enable=積分使用已關閉
+no.points.update.fail=積分錢包更新失敗,請重試
+no.points.use.fail=積分抵扣未開啟
+no.points.not.exist=您的積分錢包不存在
+no.message.push.delivery.personnel.qspsz.order=騎手配送中
+no.message.push.delivery.personnel.qsysd.order=騎手已送達
+no.wallet.noexist.userinfo=用戶資訊不存在
+no.user.state.no.audit=帳號狀態未審核
+no.system.busy.try.again=系統繁忙,請稍後重試
+no.operation.interrupted.try.again=操作被中斷,請重試
+no.message.push.merchant.ready.title=商家已經出餐
+no.message.push.merchant.ready.content=商家已經出餐,訂單號:
+no.posorder.md.yh.mc.messag=優惠券:{};
+no.posorder.md.yh.jiner.messag=優惠抵扣:{};
+no.posorder.md.cx.mc.messag=促銷:{};
+no.posorder.md.cx.jiner.messag=促銷抵扣:{};
+no.wallet.common.cs.error=操作失敗,請聯繫客服
 
 
 # 三方登录(017-oauth-login)
 # 三方登录(017-oauth-login)
-no.oauth.provider.blank=登录方式不能为空
-no.oauth.credential.blank=三方凭证不能为空
-no.oauth.provider.unsupported=不支持的登录方式:{0}
-no.oauth.needphone=首次登录请验证手机号
-no.oauth.tempkey.missing=登录凭证缺失,请重新登录
-no.oauth.tempkey.expired=登录凭证已过期,请重新登录
-no.oauth.phone.blank=手机号不能为
-no.oauth.line.config.invalid=LINE登录配置不完整
-no.oauth.client.config.invalid={0}登录配置不完整
-no.oauth.state.invalid=登录授权已失效,请重新发起登录
-no.oauth.token.invalid={0}登录凭证无
-no.oauth.token.expired={0}登录凭证已过
-no.oauth.audience.mismatch={0}凭证校验未通过
-no.oauth.verify.fail={0}登录校验失败
-no.oauth.phone.duplicate=该手机号关联多个账号,请联系平台
+no.oauth.provider.blank=登入方式不能為
+no.oauth.credential.blank=第三方憑證不能為
+no.oauth.provider.unsupported=不支援的登入方式:{0}
+no.oauth.needphone=首次登入請驗證手機號
+no.oauth.tempkey.missing=登入憑證缺失,請重新登入
+no.oauth.tempkey.expired=登入憑證已過期,請重新登入
+no.oauth.phone.blank=手機號碼不可為
+no.oauth.line.config.invalid=LINE登入設定不完整
+no.oauth.client.config.invalid={0}登入設定不完整
+no.oauth.state.invalid=登入授權已失效,請重新發起登入
+no.oauth.token.invalid={0}登入憑證無
+no.oauth.token.expired={0}登入憑證已過
+no.oauth.audience.mismatch={0}憑證校驗未通過
+no.oauth.verify.fail={0}登入校驗失敗
+no.oauth.phone.duplicate=該手機號關聯多個帳號,請聯繫平台
 
 
-# 订单发票校验(010)
-no.invoice.choice.invalid=发票类型不合法:{0}
-no.invoice.barcode.format=手机条码格式不正确(须为 / 加 7 位大写英文/数字/+-.)
-no.invoice.barcode.service.unavailable=手机条码校验服务暂不可用,请稍后重试
-no.invoice.barcode.notexist=手机条码不存在,请确认或改选纸本发
-no.invoice.citizen.format=自然人凭证格式不正确(须为 2 位大写英文 + 14 位数字)
-no.invoice.lovecode.format=捐赠码格式不正确(须为 3-7 位数字)
-no.invoice.lovecode.invalid=捐赠码无
-no.invoice.lovecode.verify.fail=捐赠码验证失败,请稍后重试
-no.invoice.ubn.format=统一编号格式不正确(须为 8 位数字)
-no.invoice.company.email=公司发票须填写有效的买方邮箱(用于接收发票)
-no.invoice.store.notsupport.barcode=门店暂不支持电子发票,无法校验手机条码
-no.invoice.store.notsupport.lovecode=门店暂不支持电子发票,无法校验捐赠码
+# 訂單發票校驗(010)
+no.invoice.choice.invalid=發票類型不合法:{0}
+no.invoice.barcode.format=手機條碼格式不正確(須為 / 加 7 位大寫英文/數字/+-.)
+no.invoice.barcode.service.unavailable=手機條碼驗證服務暫不可用,請稍後重試
+no.invoice.barcode.notexist=手機條碼不存在,請確認或改選紙本發
+no.invoice.citizen.format=自然人憑證格式不正確(須為 2 位大寫英文 + 14 位數字)
+no.invoice.lovecode.format=捐贈碼格式不正確(須為 3-7 位數字)
+no.invoice.lovecode.invalid=捐贈碼無
+no.invoice.lovecode.verify.fail=捐贈碼驗證失敗,請稍後重試
+no.invoice.ubn.format=統一編號格式不正確(須為 8 位數字)
+no.invoice.company.email=公司發票須填寫有效的買方電子郵件(用於接收發票)
+no.invoice.store.notsupport.barcode=門市暫不支援電子發票,無法驗證手機條碼
+no.invoice.store.notsupport.lovecode=門市暫不支援電子發票,無法驗證捐贈碼
 
 
-# 订单发票校验 - 申请发票入参(010)
-no.invoice.b2b.buyername.blank=B2B 发票须填写买方名称
-no.invoice.b2b.buyeremail.blank=B2B 发票须填写买方邮箱
-no.invoice.b2b.nocarrier=B2B 发票不支持载
-no.invoice.donation.nocarrier=捐赠发票不支持载
-no.invoice.donation.noubn=捐赠发票不支持统编
-no.invoice.buyername.blank=买方名称不能为
-no.invoice.carriertype.invalid=载具类型只能为 0手机条码/1自然人凭证/2ezPay会员
-no.invoice.carriernum.blank=载具号码不能为
-line.pay.credential.required=LINE Pay 门店、Channel ID 和 Secret 不能为
-line.pay.credential.verify.unknown=LINE Pay 凭证验证服务暂不可用,请稍后重试
-line.pay.credential.invalid=LINE Pay 凭证验证失败,请检查 Channel ID 和 Secret
-line.pay.credential.enabled=LINE Pay 凭证验证通过并已启
-line.pay.order.required=LINE Pay 订单号不能为
-line.pay.operation.failed=LINE Pay 操作未完成,请稍后重试
-line.pay.order.not.found=LINE Pay 订单不存在
-line.pay.refund.not.allowed=当前订单状态不允许 LINE Pay 退款
-line.pay.refund.payment.not.found=没有可退款的 LINE Pay 支付记录
-line.pay.refund.already.completed=LINE Pay 支付已退款
-line.pay.order.completion.not.allowed=当前 LINE Pay 订单状态不允许完成
-line.pay.legacy.endpoint.disabled=LINE Pay 订单请使用专用订单操作接口
-line.pay.offline.merchant.required=当前账号不是有效商家账号
-line.pay.offline.single.store.required=商家扫码订单只能包含一个门
-line.pay.offline.order.invalid=当前订单不能使用 LINE Pay 扫码付款
-line.pay.offline.order.forbidden=订单不存在或不属于当前商家
-line.pay.offline.mycode.invalid=LINE Pay My Code 必须为 18 位数
-line.pay.offline.attempt.blocked=当前订单已有待处理的支付,请先查询支付状态
-line.pay.offline.not.enabled=该门店暂未启用 LINE Pay 扫码付款
-line.pay.offline.attempt.not.found=当前订单没有 LINE Pay 扫码支付记录
-line.pay.offline.operation.failed=LINE Pay 扫码支付未完成,请稍后查询状态
-rider.operation.role.required=只有骑手可以操作配送订单
+# 訂單發票校驗 - 申請發票入參(010)
+no.invoice.b2b.buyername.blank=B2B 發票須填寫買方名稱
+no.invoice.b2b.buyeremail.blank=B2B 發票須填寫買方電子郵件
+no.invoice.b2b.nocarrier=B2B 發票不支援載
+no.invoice.donation.nocarrier=捐贈發票不支援載
+no.invoice.donation.noubn=捐贈發票不支援統編
+no.invoice.buyername.blank=買方名稱不能為
+no.invoice.carriertype.invalid=載具類型只能為 0手機條碼/1自然人憑證/2ezPay會員
+no.invoice.carriernum.blank=載具號碼不能為
+line.pay.credential.required=LINE Pay 門店、Channel ID 和 Secret 不能為
+line.pay.credential.verify.unknown=LINE Pay 憑證驗證服務暫時無法使用,請稍後重試
+line.pay.credential.invalid=LINE Pay 憑證驗證失敗,請檢查 Channel ID 和 Secret
+line.pay.credential.enabled=LINE Pay 憑證驗證通過並已啟
+line.pay.order.required=LINE Pay 訂單號不能為
+line.pay.operation.failed=LINE Pay 操作未完成,請稍後重試
+line.pay.order.not.found=LINE Pay 訂單不存在
+line.pay.refund.not.allowed=目前訂單狀態不允許 LINE Pay 退款
+line.pay.refund.payment.not.found=沒有可退款的 LINE Pay 支付記錄
+line.pay.refund.already.completed=LINE Pay 支付已退款
+line.pay.order.completion.not.allowed=目前 LINE Pay 訂單狀態不允許完成
+line.pay.legacy.endpoint.disabled=LINE Pay 訂單請使用專用訂單操作介面
+line.pay.offline.merchant.required=目前帳號不是有效商家帳號
+line.pay.offline.single.store.required=商家掃碼訂單只能包含一個門
+line.pay.offline.order.invalid=目前訂單不能使用 LINE Pay 掃碼付款
+line.pay.offline.order.forbidden=訂單不存在或不屬於目前商家
+line.pay.offline.mycode.invalid=LINE Pay My Code 必須為 18 位數
+line.pay.offline.attempt.blocked=目前訂單已有待處理的付款,請先查詢付款狀態
+line.pay.offline.not.enabled=此門店尚未啟用 LINE Pay 掃碼付款
+line.pay.offline.attempt.not.found=目前訂單沒有 LINE Pay 掃碼付款記錄
+line.pay.offline.operation.failed=LINE Pay 掃碼付款未完成,請稍後查詢狀態
+rider.operation.role.required=只有騎手可以操作配送訂單
 
 
-omg.payment.ddid.required=OMG 支付订单号不能为
-omg.payment.merchantTradeNo.required=OMG MerchantTradeNo 不能
-omg.payment.merchantTradeNo.invalid=OMG MerchantTradeNo 必须为最多 20 位大写英数
-omg.payment.storeId.required=OMG 门店 ID 不能为
-omg.payment.merchantId.required=OMG 商户号不能为
-omg.payment.merchantId.invalid=OMG 商户号必须为最多 10 位英数
-omg.payment.amount.invalid=OMG 支付金额必须大于 0
-omg.payment.credential.snapshot.required=OMG 支付凭证快照不能为
-omg.pay.auth.required=请先登录
-omg.pay.order.required=订单号不能为
-omg.pay.order.not.available=订单不存在或无权操作
-omg.pay.multi.store.unsupported=多门店订单暂不支持 OMG 支付
-omg.pay.order.state.not.payable=当前订单状态不可支付
-omg.pay.order.already.paid=订单已支付或支付状态不可用
-omg.pay.order.amount.invalid=订单金额异
-omg.pay.payment.type.invalid=订单支付方式不是 OMG
-omg.pay.payment.method.invalid=请选择信用卡或 Apple Pay
-omg.pay.credential.unavailable=该门店暂未启用 OMG 支付
-omg.pay.attempt.exists=该订单已有待处理的支付尝试
-omg.pay.configuration.invalid=OMG 支付配置无
-omg.pay.creation.failed=OMG 支付创建失败,请稍后重试
-omg.pay.query.not.available=当前没有可查询的 OMG 支付信息
-omg.pay.query.failed=无法查询 OMG 支付状态,请稍后重试
-omg.pay.retry.not.available=当前支付状态无法重新发起,请先刷新支付结
-omg.pay.retry.failed=重新发起 OMG 支付失败,请稍后重试
-omg.pay.refund.unavailable.test.environment=OMG 测试环境不支持退款,请在正式环境启用后操作
-omg.pay.refund.failed=OMG 退款操作失败,请稍后重试
-no.paytype.cash.merchant.only=Thanh toán tiền mặt chỉ dành cho đơn hàng do merchant tạo
-no.order.paytype.not.cash=Đơn hàng này không phải thanh toán tiền mặt
-no.order.cash.already.paid=Đơn hàng này đã được xác nhận thu tiền
-no.order.paytype.not.transfer=Đơn hàng này không phải thanh toán chuyển khoản
-no.order.transfer.cancelled=Đơn hàng đã hủy, không thể xác nhận thu tiền
-no.order.transfer.already.paid=Đơn hàng này đã được xác nhận thu tiền
-no.order.transfer.not.paid=Chỉ có thể nhận đơn sau khi nhà hàng xác nhận đã nhận tiền
-no.order.cash.cancelled=Đơn hàng đã bị hủy, không thể xác nhận thu tiền
-no.user.audit.reject.reason.required=审核不通过时必须填写审核不通过原因
-merchant.account.unavailable=Merchant account is unavailable
-merchant.owner.unavailable=Merchant owner account is unavailable
-merchant.owner.required=Only the merchant owner account can perform this operation
-merchant.owner.not.found=Merchant owner account was not found
-merchant.store.access.denied=You do not have permission to access this store
-menu.copy.store.required=Source and target stores are required
-menu.copy.store.same=Source and target stores must be different
-menu.copy.strategy.invalid=Invalid conflict strategy
-merchant.order.not.found=Order was not found
-merchant.food.not.found=Product was not found
-merchant.session.invalid=Merchant session is invalid, please sign in again
-merchant.subaccount.request.required=Request data is required
-merchant.subaccount.name.required=Subaccount name is required
-merchant.subaccount.phone.required=Subaccount phone number is required
-merchant.subaccount.phone.invalid=Subaccount phone number is invalid
-merchant.subaccount.phone.exists=This phone number is already in use
-merchant.subaccount.password.required=Subaccount password is required
-merchant.subaccount.store.required=Select at least one responsible store
-merchant.subaccount.status.required=Subaccount status is required
-merchant.subaccount.not.found=Subaccount was not found
-merchant.subaccount.access.denied=You cannot manage this subaccount
-merchant.subaccount.create.failed=Failed to create subaccount
-merchant.subaccount.update.failed=Failed to update subaccount
-merchant.subaccount.platform.managed=Subaccounts can only be managed from the dedicated merchant subaccount entry
-no.user.delivery.type.invalid=配送类型无效,仅支持美食外送或闪
-no.user.delivery.type.not.enabled=当前账号未开通美食外送配送
+omg.payment.ddid.required=OMG 支付訂單號不能為
+omg.payment.merchantTradeNo.required=OMG MerchantTradeNo 不能
+omg.payment.merchantTradeNo.invalid=OMG MerchantTradeNo 必須為最多 20 位大寫英數
+omg.payment.storeId.required=OMG 門店 ID 不能為
+omg.payment.merchantId.required=OMG 商戶號不能為
+omg.payment.merchantId.invalid=OMG 商戶號必須為最多 10 位英數
+omg.payment.amount.invalid=OMG 支付金額必須大於 0
+omg.payment.credential.snapshot.required=OMG 支付憑證快照不能為
+omg.pay.auth.required=請先登入
+omg.pay.order.required=訂單號不能為
+omg.pay.order.not.available=訂單不存在或無權操作
+omg.pay.multi.store.unsupported=多門店訂單暫不支援 OMG 支付
+omg.pay.order.state.not.payable=目前訂單狀態不可支付
+omg.pay.order.already.paid=訂單已付款或付款狀態不可用
+omg.pay.order.amount.invalid=訂單金額異
+omg.pay.payment.type.invalid=訂單付款方式不是 OMG
+omg.pay.payment.method.invalid=請選擇信用卡或 Apple Pay
+omg.pay.credential.unavailable=此門店尚未啟用 OMG 支付
+omg.pay.attempt.exists=此訂單已有待處理的支付嘗試
+omg.pay.configuration.invalid=OMG 支付設定無
+omg.pay.creation.failed=OMG 支付建立失敗,請稍後再試
+omg.pay.query.not.available=目前沒有可查詢的 OMG 付款資訊
+omg.pay.query.failed=無法查詢 OMG 付款狀態,請稍後再試
+omg.pay.retry.not.available=目前付款狀態無法重新發起,請先重新整理付款結
+omg.pay.retry.failed=重新發起 OMG 付款失敗,請稍後再試
+omg.pay.refund.unavailable.test.environment=OMG 測試環境不支援退款,請在正式環境啟用後操作
+omg.pay.refund.failed=OMG 退款操作失敗,請稍後再試
+no.paytype.cash.merchant.only=現金支付僅支援商家建立訂單
+no.order.paytype.not.cash=該訂單不是現金支付訂單
+no.order.cash.already.paid=該訂單已確認收款
+no.order.paytype.not.transfer=該訂單不是轉賬支付訂單
+no.order.transfer.cancelled=訂單已取消,不能確認收款
+no.order.transfer.already.paid=該訂單已確認收款
+no.order.transfer.not.paid=商家確認收款後騎手才能接單
+no.order.cash.cancelled=訂單已取消,不能確認收款
+no.user.audit.reject.reason.required=審核不通過時必須填寫審核不通過原因
+merchant.account.unavailable=商家帳號不可用
+merchant.owner.unavailable=所屬商家主帳號不可用
+merchant.owner.required=僅商家主帳號可執行此操作
+merchant.owner.not.found=商家主帳號不存在
+merchant.store.access.denied=無權存取該店鋪
+menu.copy.store.required=來源門店和目標門店不能為空
+menu.copy.store.same=來源門店和目標門店不能相同
+menu.copy.strategy.invalid=差異商品處理方式無效
+merchant.order.not.found=訂單不存在
+merchant.food.not.found=商品不存在
+merchant.session.invalid=商家登入已失效,請重新登入
+merchant.subaccount.request.required=請求資料不可為空
+merchant.subaccount.name.required=分管帳號姓名不可為空
+merchant.subaccount.phone.required=分管帳號手機號碼不可為空
+merchant.subaccount.phone.invalid=分管帳號手機號碼格式無效
+merchant.subaccount.phone.exists=該手機號碼已被使用
+merchant.subaccount.password.required=分管帳號密碼不可為空
+merchant.subaccount.store.required=請至少選擇一個負責店鋪
+merchant.subaccount.status.required=分管帳號狀態不可為空
+merchant.subaccount.not.found=分管帳號不存在
+merchant.subaccount.access.denied=無權管理該分管帳號
+merchant.subaccount.create.failed=建立分管帳號失敗
+merchant.subaccount.update.failed=更新分管帳號失敗
+merchant.subaccount.platform.managed=分管帳號只能透過專用入口管理
+no.user.delivery.type.invalid=配送類型無效,僅支持美食外送或闁
+no.user.delivery.type.not.enabled=當前賬號未開通美食外送配送
 
 
-# Flash delivery
-flash.delivery.request.required=Request data is required
-flash.delivery.auth.required=Please sign in first
-flash.delivery.client.request.id.invalid=Client request ID is required and must not exceed 64 characters
-flash.delivery.note.too.long=The note must not exceed 500 characters
-flash.delivery.service.type.invalid=Unsupported flash delivery service type
-flash.delivery.service.unavailable=This flash delivery service is currently unavailable
-flash.delivery.address.invalid=Contact, address, or coordinates are invalid
-flash.delivery.address.same=Pickup and delivery locations must be different
-flash.delivery.order.not.found=Flash delivery order does not exist or is not accessible
-flash.delivery.order.already.accepted=This order has already been accepted
-flash.delivery.rider.required=Only rider accounts can perform this operation
-flash.delivery.proof.required=At least one proof image is required
-flash.delivery.proof.url.invalid=Proof image URL is invalid
-flash.delivery.proof.too.many=At most 9 proof images are allowed
-flash.delivery.transition.not.allowed=The current order status does not allow this operation
-flash.delivery.cancel.reason.required=A cancellation reason is required
-flash.delivery.cancel.not.allowed=The current order status cannot be cancelled this way
-flash.delivery.complete.not.allowed=The order is not ready to complete
-flash.delivery.state.changed=The order status changed; please refresh and retry
-flash.delivery.pricing.invalid=Pricing values must be valid positive numbers
-flash.delivery.pricing.not.available=No pricing is available for the current time period
-flash.delivery.pricing.overlap=Pricing periods for the same service cannot overlap
-flash.delivery.package.type.invalid=Please select a valid package type
-flash.delivery.package.size.invalid=Please select a valid package size tier
-flash.delivery.distance.too.far=Delivery distance cannot exceed 40 kilometres
-flash.delivery.mode.invalid=Invalid delivery mode
-flash.delivery.schedule.invalid=Invalid scheduled pickup slot
-flash.delivery.pin.invalid=Invalid delivery PIN
-flash.delivery.scene.invalid=Invalid order status group
-flash.delivery.pricing.not.found=Pricing configuration does not exist
-flash.delivery.pricing.changed=Pricing configuration has changed, please refresh and retry
-flash.delivery.delivery.type.invalid=Unsupported delivery level
-flash.delivery.item.invalid=Item quantity, weight range or specification is invalid
-flash.delivery.tip.invalid=Rider tip must be a non-negative integer TWD amount
-flash.delivery.quote.changed=The quote has changed, please review the latest price
-flash.delivery.tab.invalid=Invalid flash delivery list tab
-flash.delivery.coordinates.invalid=Latitude and longitude must be provided in pairs and within valid ranges
-address.access.denied=Address does not exist or is not accessible
-address.data.invalid=Contact, address, or coordinates are invalid
-flash.delivery.rider.type.not.enabled=当前账号未开通闪送配送
-no.store.stall.selfdelivery.readonly=Phương thức giao hàng của quầy do chủ chợ đêm thiết lập thống nhất
-no.store.selfdelivery.nightmarket.only=Chỉ chủ chợ đêm mới được cấu hình tự giao hàng
-no.store.selfdelivery.market.missing=Không tìm thấy cửa hàng chợ đêm, vui lòng hoàn thành tạo chợ đêm trong quản lý cửa hàng trước
-no.store.selfdelivery.hours.invalid=Cấu hình khung giờ tự giao không hợp lệ
-no.order.selfdelivery.required=Đơn hàng này không phải là đơn hàng do cửa hàng tự giao
-no.order.selfdelivery.rider.denied=Đơn hàng này do cửa hàng tự giao, không cần tài xế
-no.order.selfdelivery.status.invalid=Trạng thái đơn hàng không cho phép thao tác này
-no.message.push.merchant.delivery.start=Cửa hàng đã bắt đầu giao đơn hàng của bạn
-no.billing.selfdelivery.freight=Phí giao hàng tự giao của cửa hàng
-no.message.push.merchant.delivery.complete=Cửa hàng đã xác nhận giao đơn hàng của bạn
-no.order.selfdelivery.unpaid=Đơn hàng chưa thanh toán, vui lòng xác nhận đã thu tiền trước khi xác nhận giao hàng
-no.message.push.merchant.accepted.content=Cửa hàng đã nhận đơn và đang chuẩn bị món của bạn
-no.order.not.found=Không tìm thấy đơn hàng
-flash.delivery.rider.exclusive.conflict=The rider has an active exclusive delivery and cannot accept this order
-flash.delivery.edit.not.allowed=仅待接单且未分配骑手的订单可以修改
-flash.delivery.order.version.invalid=请提供有效的订单版本
-flash.delivery.tip.additional.invalid=追加小费必须为正整数且不能超出金额范围
-flash.delivery.pay.type.invalid=Chiỉ hỗ trợ thanh toán bằng tiền mặt hoặc chuyển khoản ngoại tuyến
+# 閃送配送
+flash.delivery.request.required=請求資料不能為空
+flash.delivery.auth.required=請先登入
+flash.delivery.client.request.id.invalid=客戶端請求號不能為空且不能超過64個字元
+flash.delivery.note.too.long=備註不能超過500個字元
+flash.delivery.service.type.invalid=不支援的閃送服務類型
+flash.delivery.service.unavailable=目前閃送服務暫不可用
+flash.delivery.address.invalid=聯絡人、地址或經緯度資訊無效
+flash.delivery.address.same=取件地址和收件地址不能相同
+flash.delivery.order.not.found=閃送訂單不存在或無權存取
+flash.delivery.order.already.accepted=訂單已被其他騎手接走
+flash.delivery.rider.required=只有騎手帳號可以執行此操作
+flash.delivery.proof.required=請至少上傳一張憑證圖片
+flash.delivery.proof.url.invalid=憑證圖片網址無效
+flash.delivery.proof.too.many=憑證圖片最多上傳9張
+flash.delivery.transition.not.allowed=目前訂單狀態不允許此操作
+flash.delivery.cancel.reason.required=取消原因不能為空
+flash.delivery.cancel.not.allowed=目前訂單狀態不允許這樣取消
+flash.delivery.complete.not.allowed=目前訂單尚不能完成
+flash.delivery.state.changed=訂單狀態已變更,請重新整理後再試
+flash.delivery.pricing.invalid=計價設定必須為有效正數
+flash.delivery.pricing.not.available=目前時段暫無可用運價
+flash.delivery.pricing.overlap=同一服務類型的運價時段不能重疊
+flash.delivery.package.type.invalid=請選擇有效的包裹類型
+flash.delivery.package.size.invalid=請選擇有效的包裹重量級距
+flash.delivery.distance.too.far=配送距離不能超過40公里
+flash.delivery.mode.invalid=配送方式無效
+flash.delivery.schedule.invalid=預約取件時段無效
+flash.delivery.pin.invalid=交付PIN不正確
+flash.delivery.scene.invalid=訂單狀態分組參數無效
+flash.delivery.pricing.not.found=計價設定不存在
+flash.delivery.pricing.changed=計價設定已發生變更,請重新整理後重試
+flash.delivery.delivery.type.invalid=不支援的配送等級
+flash.delivery.item.invalid=物品數量、重量範圍或規格資訊不正確
+flash.delivery.tip.invalid=騎手小費必須是非負整數新台幣金額
+flash.delivery.quote.changed=報價已變更,請重新確認最新費用
+flash.delivery.tab.invalid=閃送列表頁籤無效
+flash.delivery.coordinates.invalid=經緯度必須成對提供且範圍有效
+address.access.denied=地址不存在或無權存取
+address.data.invalid=聯絡人、地址或經緯度資訊無效
+flash.delivery.rider.type.not.enabled=當前賬號未開通闁送配送
+no.store.stall.selfdelivery.readonly=攤位配送方式由夜市主統一設定
+no.store.selfdelivery.nightmarket.only=自配送僅夜市主可設定
+no.store.selfdelivery.market.missing=未找到夜市門店,請先在門店管理完成夜市創建
+no.store.selfdelivery.hours.invalid=自配送時段配置無效
+no.order.selfdelivery.required=該訂單不是商家自配送訂單
+no.order.selfdelivery.rider.denied=該訂單為商家自配送訂單,無需騎手配送
+no.order.selfdelivery.status.invalid=訂單狀態不允許該操作
+no.message.push.merchant.delivery.start=商家已開始配送您的訂單
+no.billing.selfdelivery.freight=商家自配送運費
+no.message.push.merchant.delivery.complete=商家已確認送達您的訂單
+no.order.selfdelivery.unpaid=訂單未支付,請先確認收款後再確認送達
+no.message.push.merchant.accepted.content=商家已接單,正在為您備餐
+no.order.not.found=訂單不存在
+flash.delivery.rider.exclusive.conflict=騎手存在進行中的獨佔配送任務,暫時不能接此訂單
+flash.delivery.edit.not.allowed=僅待接單且未分配騎手的訂單可以修改
+flash.delivery.order.version.invalid=請提供有效的訂單版本
+flash.delivery.tip.additional.invalid=追加小費必須為正整數且不能超出金額範圍
+flash.delivery.pay.type.invalid=支付方式僅支援現金或線下轉帳

+ 1 - 0
ruoyi-admin/src/main/resources/i18n/messages_en_US.properties

@@ -77,6 +77,7 @@ no.user.password.not.null=Password cannot be empty
 no.user.jcaptcha.error=Incorrect verification code
 no.user.jcaptcha.error=Incorrect verification code
 no.user.not.exist=User does not exist
 no.user.not.exist=User does not exist
 no.user.phone.duplicate=This phone number is linked to multiple accounts. Please contact the platform.
 no.user.phone.duplicate=This phone number is linked to multiple accounts. Please contact the platform.
+pay.method.not.available=This payment method is currently unavailable. Please choose another.
 no.user.login.success=Login successful
 no.user.login.success=Login successful
 no.user.password.error=Password error
 no.user.password.error=Password error
 no.system.error=System error
 no.system.error=System error

+ 1 - 0
ruoyi-admin/src/main/resources/i18n/messages_th_TH.properties

@@ -76,6 +76,7 @@ no.user.password.not.null=รหัสผ่านต้องไม่ว่า
 no.user.jcaptcha.error=รหัสยืนยันไม่ถูกต้อง
 no.user.jcaptcha.error=รหัสยืนยันไม่ถูกต้อง
 no.user.not.exist=ไม่มีผู้ใช้นี้
 no.user.not.exist=ไม่มีผู้ใช้นี้
 no.user.phone.duplicate=หมายเลขโทรศัพท์นี้เชื่อมโยงกับบัญชีหลายบัญชี โปรดติดต่อแพลตฟอร์ม
 no.user.phone.duplicate=หมายเลขโทรศัพท์นี้เชื่อมโยงกับบัญชีหลายบัญชี โปรดติดต่อแพลตฟอร์ม
+pay.method.not.available=วิธีการชำระเงินนี้ไม่พร้อมใช้งานในขณะนี้ โปรดเลือกวิธีอื่น
 no.user.login.success=เข้าสู่ระบบสำเร็จ
 no.user.login.success=เข้าสู่ระบบสำเร็จ
 no.user.password.error=รหัสผ่านไม่ถูกต้อง
 no.user.password.error=รหัสผ่านไม่ถูกต้อง
 no.system.error=เกิดข้อผิดพลาดของระบบ
 no.system.error=เกิดข้อผิดพลาดของระบบ

+ 0 - 364
ruoyi-admin/src/main/resources/i18n/messages_vi.properties

@@ -1,364 +0,0 @@
-#错误消息
-not.null=* Cần điền
-user.jcaptcha.error=Lỗi CAPTCHA
-user.jcaptcha.expire=CAPTCHA không hoạt động
-user.not.exists=Người dùng không tồn tại/Lỗi mật khẩu
-user.password.not.match=Người dùng không tồn tại/Lỗi mật khẩu
-user.password.retry.limit.count=Nhập mật khẩu sai {0} lần
-user.password.retry.limit.exceed=Nhập sai mật khẩu {0} lần, khóa tài khoản {1} phút
-user.password.delete=Không, tài khoản của bạn đã bị xóa.
-user.blocked=Người dùng đã bị chặn, vui lòng liên hệ với quản trị viên
-role.blocked=Nhân vật bị cấm, vui lòng liên hệ với quản trị viên
-login.blocked=Thật không may, IP truy cập đã bị đưa vào danh sách đen hệ thống
-user.logout.success=Thoát thành công
-
-length.not.valid=Độ dài phải từ {min} đến {max} ký tự
-
-user.username.not.valid=* Từ 2 đến 20 ký tự Trung Quốc, chữ cái, số hoặc gạch dưới và phải bắt đầu bằng một số không phải là số
-user.password.not.valid=* 5-50 ký tự
-
-user.email.not.valid=Lỗi định dạng hộp thư
-user.mobile.phone.number.not.valid=Định dạng số điện thoại sai
-user.login.success=Đăng nhập thành công
-user.register.success=Đăng ký thành công
-user.notfound=Vui lòng đăng nhập lại
-user.forcelogout=Quản trị viên buộc thoát, vui lòng đăng nhập lại
-user.unknown.error=Lỗi không rõ, vui lòng đăng nhập lại
-
-##文件上传消息
-upload.exceed.maxSize=Kích thước tập tin được tải lên vượt quá kích thước tập tin giới hạn!< <br/>Kích thước tối đa cho phép của tập tin là: {0}MB !
-upload.filename.exceed.length=Tên tập tin đã tải lên Dài nhất {0} ký tự
-
-##权限
-no.permission=Bạn không có quyền cho dữ liệu, hãy liên hệ với quản trị viên để thêm quyền [{0}]
-no.create.permission=Bạn không có quyền tạo dữ liệu, hãy liên hệ với quản trị viên để thêm quyền [{0}]
-no.update.permission=Bạn không có quyền sửa đổi dữ liệu, vui lòng liên hệ với quản trị viên để thêm quyền [{0}]
-no.delete.permission=Bạn không có quyền xóa dữ liệu, hãy liên hệ với quản trị viên để thêm quyền [{0}]
-no.export.permission=Bạn không có quyền xuất dữ liệu, vui lòng liên hệ với quản trị viên để thêm quyền [{0}]
-no.view.permission=Bạn không có quyền xem dữ liệu, vui lòng liên hệ với quản trị viên để thêm quyền [{0}]
-
-##自定义返回
-no.obtained.permission=Nhận thành công
-no.obtained.success=Truy vấn thành công
-no.action.success=Hoạt động thành công
-no.action.fail=Hoạt động thất bại
-no.data.exist.not.del=Danh mục này có hàng hóa và không thể xóa
-no.comment.success=Đánh giá thành công
-no.comment.fail=Thất bại, vui lòng thử lại
-no.comment.repeat=Bạn đã đánh giá đơn đặt hàng
-no.delete.success=Xóa thành công
-no.delete.fail=Thất bại, vui lòng thử lại
-no.tip.lock.keywork=Vui lòng điền từ khóa
-no.load.success=Tải thành công
-no.modify.success=Sửa đổi thành công
-no.collection.success=Sưu tầm thành công
-no.collection.cancel=Hủy bộ sưu tập
-no.success=Thành công
-no.cash_on_delivery_amount.exceed.limit_amount=thu tiền khi giao hàng Số tiền vượt quá giới hạn
-no.exist.cash_on_delivery_order.incomplete=Vẫn còn nhiều đơn đặt hàng chưa hoàn thành
-no.address.not.exist=Địa chỉ nhận hàng không tồn tại
-no.mendian.not.exist=Cửa hàng không còn tồn tại
-no.mendian.not.set.business.hours=Cửa hàng hiện tại không đặt giờ hoạt động
-no.mendian.is.closed=Cửa hàng đã đóng cửa.
-no.goods.not.exist=Không còn nữa, vui lòng chọn sản phẩm khác
-no.goods.is.off.shelf=Sản phẩm đã được gỡ khỏi kệ. Vui lòng chọn sản phẩm khác để đặt hàng.
-no.order.submit.success=Gửi đơn đặt hàng thành công
-no.mendian.exist.classify.not.del=Cửa hàng này tồn tại dữ liệu phân loại, vui lòng xóa phân loại trước khi xóa
-no.insufficient.user.security.deposit=Tiền đặt cọc bảo đảm của người dùng không đủ
-no.order.snatched=Lệnh bị cướp
-no.exist.undelivered.order=Bạn có đơn đặt hàng chưa giao, vui lòng xử lý đơn đặt hàng trước khi nhận
-no.user.not.vip=Thành viên này chưa mở thành viên
-no.user.vip.expired=Thành viên hết hạn
-no.user.add=Người dùng mới
-no.user.login.exist=Không thành công, tài khoản đăng nhập đã tồn tại
-no.user.mobile.exist=Thất bại, số điện thoại di động đã tồn tại
-no.user.phone.blank=Số điện thoại không được để trống
-no.user.password.not.null=Mật khẩu không được để trống
-no.user.jcaptcha.error=CAPTCHA không đúng
-no.user.not.exist=Người dùng không tồn tại
-no.user.phone.duplicate=Số điện thoại này được liên kết với nhiều tài khoản. Vui lòng liên hệ nền tảng.
-no.user.login.success=Đăng nhập thành công
-no.user.password.error=Mật khẩu sai
-no.system.error=Lỗi hệ thống
-no.sms.send.success=Gửi SMS thành công
-no.user.password.modify.success=Thay đổi mật khẩu thành công
-no.user.password.old.error=Mật khẩu cũ không đúng
-no.user.stop=Người dùng đã bị vô hiệu hóa
-no.user.token.success=Nhận token thành công
-no.user.info=Thông tin người dùng
-no.user.deposit.not.exist=Không có bản ghi tiền gửi
-no.user.deposit.type.not.exist=Không có khoản tiền gửi nào thuộc loại này tồn tại
-no.user.call.status.not.exist=Không có trạng thái cuộc gọi, không thể cúp máy
-no.user.call.hangup.success=Kết thúc cuộc gọi thành công
-no.user.call.not.exist=Người dùng này không có thông tin cuộc gọi nào
-no.user.call.calling.success=Cuộc gọi đã được khởi tạo thành công
-no.user.call.other.is.calling=Người kia hiện đang gọi điện và không thể gọi được
-no.user.call.accept.success=Yêu cầu kết nối thành công
-no.user.call.request.success=Yêu cầu cuộc gọi thành công
-no.user.not.vip=Bạn không phải là thành viên
-no.upload.success=Tải lên thành công
-no.send.success=Đã gửi thành công
-no.send.fail=Gửi không thành công
-no.convert.success=Chuyển đổi thành công
-no.order.not.exist=Đơn hàng không tồn tại
-no.order.place.success=Đã đặt hàng thành công
-no.order.id.error=Mã đơn hàng không đúng
-no.order.create.success=Đơn hàng đã được tạo thành công
-no.message.push.message=tin nhắn
-no.message.push.delivery.personnel.receiving.order=Người giao hàng đã nhận đơn
-no.message.push.rider.accepted.merchant=Tài xế đã nhận đơn, vui lòng xác nhận và chuẩn bị món
-no.message.push.order.cancelled=Đơn hàng đã bị hủy
-no.order.rider.accept.required=Vui lòng đợi tài xế nhận đơn trước khi thao tác
-no.message.push.new.order=có lệnh mới
-no.message.push.recharge.success=nạp tiền thành công
-no.message.push.payment.success=thanh toán thành công
-no.message.push.payment.fail=thanh toán thất bại
-no.message.push.end.call=Kết thúc cuộc gọi
-no.message.push.call.hangup=Cuộc gọi đã bị ngắt kết nối
-no.message.push.call.calling=cuộc gọi
-no.message.push.call.request=Yêu cầu gọi
-no.message.push.call.accept=Bật tin nhắn
-no.message.push.call.agree=đồng ý với yêu cầu gọi của bạn
-no.export.excel.mendian.classify=Dữ liệu phân loại cửa hàng
-no.export.excel.goods.classify=Dữ liệu phân loại hàng hóa
-no.export.excel.collection=Dữ liệu bộ sưu tập
-no.export.excel.food=Dữ liệu thực phẩm
-no.export.excel.posstore=Dữ liệu PosStore
-no.export.excel.servicetype=Dữ liệu ServiceType
-no.export.excel.distancemultiplier=Dữ liệu DistanceMultiplier
-no.export.excel.address=Dữ liệu địa chỉ
-no.export.excel.freight.data=Dữ liệu vận chuyển hàng hóa
-no.export.excel.posorder=Dữ liệu PosOrder
-no.export.excel.review=Xem lại dữ liệu
-no.export.excel.taxiorder=Dữ liệu TaxiOrder
-no.export.excel.taxiprices=Dữ liệu TaxiPrices
-no.export.excel.bankcard=Dữ liệu thẻ ngân hàng
-no.export.excel.ipnlog=Dữ liệu IpnLog
-no.export.excel.billing=Dữ liệu thanh toán
-no.export.excel.salespromotion=Dữ liệu SalesPromotion
-no.export.excel.enterpriseintroduce=EnterpriseIntroduce dữ liệu
-no.export.excel.userinfo=Dữ liệu thông tin người dùng
-no.export.excel.margin=Dữ liệu lề
-no.export.excel.riderposition=Dữ liệu RiderPosition
-no.export.excel.feedback=Dữ liệu phản hồi
-no.export.excel.help=Dữ liệu trợ giúp
-no.export.excel.footprint=Dữ liệu dấu chân
-no.export.excel.usermargin=Dữ liệu UserMargin
-no.export.excel.videocall=Dữ liệu cuộc gọi video
-no.export.excel.viplist=Dữ liệu VipList
-no.export.excel.rights=Dữ liệu quyền
-no.export.excel.version=Dữ liệu phiên bản
-no.userquanyi.not.exist=Không tìm thấy phiếu giảm giá
-userquanyi.isUsed=Phiếu giảm giá đã được sử dụng
-no.activity.not.exist=Khuyến mãi không tồn tại
-no.map.exception=Lỗi truy vấn đường đi trên bản đồ
-no.xiadanyz.message=Để đảm bảo an toàn tài sản của bạn, hãy sử dụng phiên bản mới nhất đặt hàng!
-no.youhuiquan.lqnodata=Không tìm thấy thông tin ưu đãi
-no.youhuiquan.lqyhqgb=Phiếu ưu đãi đã đóng
-no.youhuiquan.lqyhqolqw=Phiếu ưu đãi đã được nhận hết
-no.youhuiquan.lqyhqdy=Số lượng nhận phải lớn hơn 0
-no.youhuiquan.lqyhqysx=Bạn đã đạt giới hạn nhận phiếu ưu đãi này
-no.youhuiquan.lqyhqybxg=Dữ liệu đã bị thay đổi, vui lòng làm mới và thử lại
-no.points.insufficient=Số điểm của bạn không đủ
-no.points.use.enable=Việc sử dụng điểm đã bị tắt
-no.points.update.fail=Cập nhật ví điểm thất bại, vui lòng thử lại
-no.points.use.fail=Khấu trừ điểm chưa được bật
-no.points.not.exist=Ví điểm của bạn không tồn tại
-no.message.push.delivery.personnel.qspsz.order= Shipper đang giao đến
-no.message.push.delivery.personnel.qsysd.order=Shipper đã giao xong.
-no.wallet.noexist.userinfo=Thông tin người dùng không tồn tại
-no.user.state.no.audit=Trạng thái tài khoản chưa được xét duyệt
-no.system.busy.try.again=Hệ thống đang bận, vui lòng thử lại sau
-no.operation.interrupted.try.again=Thao tác đã bị gián đoạn, vui lòng thử lại
-no.message.push.merchant.ready.title=Thương gia đã chuẩn bị xong
-no.message.push.merchant.ready.content=Thương gia đã chuẩn bị xong, mã đơn hàng:
-no.posorder.md.yh.mc.messag=Phiếu giảm giá: {};
-no.posorder.md.yh.jiner.messag=Giảm giá: {};
-no.posorder.md.cx.mc.messag=Khuyến mãi: {};
-no.posorder.md.cx.jiner.messag=Giảm KM: {};
-no.wallet.common.cs.error=Thất bại, vui lòng liên hệ CSKH
-
-# 三方登录(017-oauth-login)
-no.oauth.provider.blank=Vui lòng chọn cách đăng nhập
-no.oauth.credential.blank=Thông tin xác thực bên thứ ba không được để trống
-no.oauth.provider.unsupported=Không hỗ trợ cách đăng nhập: {0}
-no.oauth.needphone=Cần xác minh số điện thoại ở lần đăng nhập đầu
-no.oauth.tempkey.missing=Thiếu thông tin đăng nhập, vui lòng đăng nhập lại
-no.oauth.tempkey.expired=Thông tin đăng nhập đã hết hạn, vui lòng đăng nhập lại
-no.oauth.phone.blank=Số điện thoại không được để trống
-no.oauth.line.config.invalid=Cấu hình đăng nhập LINE chưa đầy đủ
-no.oauth.client.config.invalid=Cấu hình đăng nhập {0} chưa đầy đủ
-no.oauth.state.invalid=Phiên xác thực đã hết hiệu lực. Vui lòng đăng nhập lại.
-no.oauth.token.invalid=Thông tin đăng nhập {0} không hợp lệ
-no.oauth.token.expired=Thông tin đăng nhập {0} đã hết hạn
-no.oauth.audience.mismatch=Xác minh thông tin {0} không thành công
-no.oauth.verify.fail=Xác minh đăng nhập {0} thất bại
-no.oauth.phone.duplicate=Số điện thoại này được liên kết với nhiều tài khoản. Vui lòng liên hệ nền tảng.
-
-# Kiểm tra hóa đơn đơn hàng (010)
-no.invoice.choice.invalid=Loại hóa đơn không hợp lệ: {0}
-no.invoice.barcode.format=Định dạng mã vạch điện thoại không hợp lệ (phải là / và 7 ký tự hoa/chữ số/+-.)
-no.invoice.barcode.service.unavailable=Dịch vụ xác minh mã vạch điện thoại tạm thời không khả dụng, vui lòng thử lại sau
-no.invoice.barcode.notexist=Mã vạch điện thoại không tồn tại, vui lòng xác nhận hoặc chọn hóa đơn giấy
-no.invoice.citizen.format=Định dạng chứng chỉ số công dân không hợp lệ (phải là 2 chữ cái hoa + 14 chữ số)
-no.invoice.lovecode.format=Định dạng mã quyên góp không hợp lệ (phải là 3-7 chữ số)
-no.invoice.lovecode.invalid=Mã quyên góp không hợp lệ
-no.invoice.lovecode.verify.fail=Xác minh mã quyên góp thất bại, vui lòng thử lại sau
-no.invoice.ubn.format=Định dạng mã số doanh nghiệp không hợp lệ (phải là 8 chữ số)
-no.invoice.company.email=Hóa đơn công ty yêu cầu email người mua hợp lệ (để nhận hóa đơn)
-no.invoice.store.notsupport.barcode=Cửa hàng này không hỗ trợ hóa đơn điện tử, không thể xác minh mã vạch điện thoại
-no.invoice.store.notsupport.lovecode=Cửa hàng này không hỗ trợ hóa đơn điện tử, không thể xác minh mã quyên góp
-
-# Kiểm tra hóa đơn - đầu vào đăng ký (010)
-no.invoice.b2b.buyername.blank=Hóa đơn B2B yêu cầu tên người mua
-no.invoice.b2b.buyeremail.blank=Hóa đơn B2B yêu cầu email người mua
-no.invoice.b2b.nocarrier=Hóa đơn B2B không hỗ trợ thiết bị lưu trữ
-no.invoice.donation.nocarrier=Hóa đơn quyên góp không hỗ trợ thiết bị lưu trữ
-no.invoice.donation.noubn=Hóa đơn quyên góp không hỗ trợ mã số doanh nghiệp
-no.invoice.buyername.blank=Tên người mua không được để trống
-no.invoice.carriertype.invalid=Loại thiết bị lưu trữ chỉ có thể là 0 (mã vạch điện thoại) / 1 (chứng chỉ số công dân) / 2 (thành viên ezPay)
-no.invoice.carriernum.blank=Số thiết bị lưu trữ không được để trống
-line.pay.credential.required=Cửa hàng, Channel ID và Secret của LINE Pay là bắt buộc
-line.pay.credential.verify.unknown=Dịch vụ xác minh thông tin LINE Pay tạm thời không khả dụng
-line.pay.credential.invalid=Xác minh thông tin LINE Pay thất bại; vui lòng kiểm tra Channel ID và Secret
-line.pay.credential.enabled=Thông tin LINE Pay đã được xác minh và kích hoạt
-line.pay.order.required=Vui lòng nhập mã đơn hàng LINE Pay
-line.pay.operation.failed=Không thể hoàn tất thao tác LINE Pay, vui lòng thử lại sau
-line.pay.order.not.found=Đơn hàng LINE Pay không tồn tại
-line.pay.refund.not.allowed=Trạng thái đơn hàng hiện tại không cho phép hoàn tiền LINE Pay
-line.pay.refund.payment.not.found=Không có giao dịch LINE Pay nào có thể hoàn tiền
-line.pay.refund.already.completed=Giao dịch LINE Pay đã được hoàn tiền
-line.pay.order.completion.not.allowed=Trạng thái đơn hàng LINE Pay hiện tại không cho phép hoàn tất
-line.pay.legacy.endpoint.disabled=Hãy sử dụng API thao tác đơn hàng chuyên dụng cho đơn LINE Pay
-line.pay.offline.merchant.required=Tài khoản hiện tại không phải là tài khoản người bán hợp lệ
-line.pay.offline.single.store.required=Đơn quét mã của người bán chỉ được chứa đúng một cửa hàng
-line.pay.offline.order.invalid=Đơn hàng này không thể thanh toán bằng cách quét LINE Pay tại cửa hàng
-line.pay.offline.order.forbidden=Đơn hàng không tồn tại hoặc không thuộc người bán hiện tại
-line.pay.offline.mycode.invalid=LINE Pay My Code phải gồm đúng 18 chữ số
-line.pay.offline.attempt.blocked=Đơn hàng đang có giao dịch chờ xử lý; hãy kiểm tra trạng thái trước
-line.pay.offline.not.enabled=Cửa hàng này chưa bật thanh toán quét mã LINE Pay
-line.pay.offline.attempt.not.found=Đơn hàng này chưa có giao dịch quét mã LINE Pay
-line.pay.offline.operation.failed=Thanh toán quét mã LINE Pay chưa hoàn tất; vui lòng kiểm tra lại trạng thái sau
-rider.operation.role.required=Chỉ tài xế giao hàng mới có thể thao tác đơn giao hàng
-omg.payment.ddid.required=Mã đơn hàng thanh toán OMG là bắt buộc
-omg.payment.merchantTradeNo.required=OMG MerchantTradeNo là bắt buộc
-omg.payment.merchantTradeNo.invalid=OMG MerchantTradeNo phải có tối đa 20 chữ cái in hoa hoặc chữ số
-omg.payment.storeId.required=ID cửa hàng OMG là bắt buộc
-omg.payment.merchantId.required=Mã thương nhân OMG là bắt buộc
-omg.payment.merchantId.invalid=Mã thương nhân OMG phải có tối đa 10 chữ cái hoặc chữ số
-omg.payment.amount.invalid=Số tiền thanh toán OMG phải lớn hơn 0
-omg.payment.credential.snapshot.required=Ảnh chụp thông tin xác thực thanh toán OMG là bắt buộc
-omg.pay.auth.required=Vui lòng đăng nhập trước
-omg.pay.order.required=Vui lòng nhập mã đơn hàng
-omg.pay.order.not.available=Đơn hàng không tồn tại hoặc người dùng không có quyền truy cập
-omg.pay.multi.store.unsupported=OMG Pay chưa hỗ trợ đơn hàng từ nhiều cửa hàng
-omg.pay.order.state.not.payable=Trạng thái đơn hàng hiện tại không thể thanh toán
-omg.pay.order.already.paid=Đơn hàng đã được thanh toán hoặc trạng thái thanh toán không khả dụng
-omg.pay.order.amount.invalid=Số tiền đơn hàng không hợp lệ
-omg.pay.payment.type.invalid=Phương thức thanh toán của đơn hàng không phải OMG Pay
-omg.pay.payment.method.invalid=Vui lòng chọn Thẻ tín dụng hoặc Apple Pay
-omg.pay.credential.unavailable=Cửa hàng này chưa bật OMG Pay
-omg.pay.attempt.exists=Đơn hàng này đã có một lần thanh toán đang chờ xử lý
-omg.pay.configuration.invalid=Cấu hình OMG Pay không hợp lệ
-omg.pay.creation.failed=Không thể tạo trang thanh toán OMG Pay; vui lòng thử lại sau
-omg.pay.query.not.available=Không có giao dịch thanh toán OMG hiện tại để truy vấn
-omg.pay.query.failed=Không thể truy vấn trạng thái thanh toán OMG; vui lòng thử lại sau
-omg.pay.retry.not.available=Trạng thái thanh toán hiện tại không thể thử lại; vui lòng làm mới kết quả thanh toán trước
-omg.pay.retry.failed=Không thể tạo lại thanh toán OMG; vui lòng thử lại sau
-omg.pay.refund.unavailable.test.environment=Môi trường thử nghiệm OMG không hỗ trợ hoàn tiền; hãy bật môi trường chính thức trước
-omg.pay.refund.failed=Thao tác hoàn tiền OMG thất bại; vui lòng thử lại sau
-no.paytype.cash.merchant.only=Thanh toán tiền mặt chỉ dành cho đơn hàng do merchant tạo
-no.order.paytype.not.cash=Đơn hàng này không phải thanh toán tiền mặt
-no.order.cash.already.paid=Đơn hàng này đã được xác nhận thu tiền
-no.order.paytype.not.transfer=Đơn hàng này không phải thanh toán chuyển khoản
-no.order.transfer.cancelled=Đơn hàng đã hủy, không thể xác nhận thu tiền
-no.order.transfer.already.paid=Đơn hàng này đã được xác nhận thu tiền
-no.order.transfer.not.paid=Chỉ có thể nhận đơn sau khi nhà hàng xác nhận đã nhận tiền
-no.order.cash.cancelled=Đơn hàng đã bị hủy, không thể xác nhận thu tiền
-no.user.audit.reject.reason.required=Phải nhập lý do khi kết quả xét duyệt không được thông qua
-merchant.account.unavailable=Tài khoản cửa hàng không khả dụng
-merchant.owner.unavailable=Tài khoản chủ cửa hàng không khả dụng
-merchant.owner.required=Chỉ tài khoản chủ cửa hàng mới được thực hiện thao tác này
-merchant.owner.not.found=Không tìm thấy tài khoản chủ cửa hàng
-merchant.store.access.denied=Bạn không có quyền truy cập cửa hàng này
-menu.copy.store.required=Cửa hàng nguồn và cửa hàng đích là bắt buộc
-menu.copy.store.same=Cửa hàng nguồn và cửa hàng đích phải khác nhau
-menu.copy.strategy.invalid=Cách xử lý xung đột không hợp lệ
-merchant.order.not.found=Không tìm thấy đơn hàng
-merchant.food.not.found=Không tìm thấy sản phẩm
-merchant.session.invalid=Phiên đăng nhập cửa hàng đã hết hiệu lực, vui lòng đăng nhập lại
-merchant.subaccount.request.required=Dữ liệu yêu cầu không được để trống
-merchant.subaccount.name.required=Tên tài khoản phụ không được để trống
-merchant.subaccount.phone.required=Số điện thoại tài khoản phụ không được để trống
-merchant.subaccount.phone.invalid=Số điện thoại tài khoản phụ không hợp lệ
-merchant.subaccount.phone.exists=Số điện thoại này đã được sử dụng
-merchant.subaccount.password.required=Mật khẩu tài khoản phụ không được để trống
-merchant.subaccount.store.required=Vui lòng chọn ít nhất một cửa hàng phụ trách
-merchant.subaccount.status.required=Trạng thái tài khoản phụ không được để trống
-merchant.subaccount.not.found=Không tìm thấy tài khoản phụ
-merchant.subaccount.access.denied=Bạn không có quyền quản lý tài khoản phụ này
-merchant.subaccount.create.failed=Tạo tài khoản phụ thất bại
-merchant.subaccount.update.failed=Cập nhật tài khoản phụ thất bại
-merchant.subaccount.platform.managed=Tài khoản phụ chỉ được quản lý tại mục quản lý chuyên dụng
-no.user.delivery.type.invalid=Loại giao hàng không hợp lệ, chỉ hỗ trợ giao đồ ăn hoặc giao nhanh
-no.user.delivery.type.not.enabled=Tài khoản này chưa mở giao đồ ăn
-
-# Giao hàng nhanh
-flash.delivery.request.required=Dữ liệu yêu cầu không được để trống
-flash.delivery.auth.required=Vui lòng đăng nhập trước
-flash.delivery.client.request.id.invalid=Mã yêu cầu không được để trống và tối đa 64 ký tự
-flash.delivery.note.too.long=Ghi chú không được vượt quá 500 ký tự
-flash.delivery.service.type.invalid=Loại dịch vụ giao hàng nhanh không được hỗ trợ
-flash.delivery.service.unavailable=Dịch vụ giao hàng nhanh hiện không khả dụng
-flash.delivery.address.invalid=Thông tin liên hệ, địa chỉ hoặc tọa độ không hợp lệ
-flash.delivery.address.same=Địa điểm lấy và giao hàng phải khác nhau
-flash.delivery.order.not.found=Đơn giao hàng không tồn tại hoặc không có quyền truy cập
-flash.delivery.order.already.accepted=Đơn hàng đã được tài xế khác nhận
-flash.delivery.rider.required=Chỉ tài khoản tài xế mới được thực hiện thao tác này
-flash.delivery.proof.required=Cần ít nhất một ảnh chứng từ
-flash.delivery.proof.url.invalid=Địa chỉ ảnh chứng từ không hợp lệ
-flash.delivery.proof.too.many=Chỉ được tải lên tối đa 9 ảnh chứng từ
-flash.delivery.transition.not.allowed=Trạng thái hiện tại không cho phép thao tác này
-flash.delivery.cancel.reason.required=Phải nhập lý do hủy
-flash.delivery.cancel.not.allowed=Trạng thái hiện tại không cho phép hủy theo cách này
-flash.delivery.complete.not.allowed=Đơn hàng chưa thể hoàn tất
-flash.delivery.state.changed=Trạng thái đơn đã thay đổi, vui lòng tải lại và thử lại
-flash.delivery.pricing.invalid=Cấu hình giá phải là số dương hợp lệ
-flash.delivery.pricing.not.available=Không có mức giá khả dụng trong khung giờ hiện tại
-flash.delivery.pricing.overlap=Khung giờ giá của cùng một loại dịch vụ không được chồng lấn
-flash.delivery.package.type.invalid=Vui lòng chọn loại kiện hàng hợp lệ
-flash.delivery.package.size.invalid=Vui lòng chọn mức trọng lượng kiện hàng hợp lệ
-flash.delivery.distance.too.far=Khoảng cách giao hàng không được vượt quá 40 km
-flash.delivery.mode.invalid=Phương thức giao hàng không hợp lệ
-flash.delivery.schedule.invalid=Khung giờ lấy hàng đã đặt không hợp lệ
-flash.delivery.pin.invalid=Mã PIN giao hàng không chính xác
-flash.delivery.scene.invalid=Nhóm trạng thái đơn hàng không hợp lệ
-flash.delivery.pricing.not.found=Không tìm thấy cấu hình giá
-flash.delivery.pricing.changed=Cấu hình giá đã thay đổi, vui lòng tải lại và thử lại
-flash.delivery.delivery.type.invalid=Cấp độ giao hàng không được hỗ trợ
-flash.delivery.item.invalid=Số lượng, khoảng trọng lượng hoặc quy cách hàng hóa không hợp lệ
-flash.delivery.tip.invalid=Tiền boa cho tài xế phải là số nguyên TWD không âm
-flash.delivery.quote.changed=Báo giá đã thay đổi, vui lòng xác nhận lại chi phí mới nhất
-flash.delivery.tab.invalid=Tab danh sách giao hàng nhanh không hợp lệ
-flash.delivery.coordinates.invalid=Vĩ độ và kinh độ phải được cung cấp theo cặp và nằm trong phạm vi hợp lệ
-address.access.denied=Địa chỉ không tồn tại hoặc không có quyền truy cập
-address.data.invalid=Thông tin liên hệ, địa chỉ hoặc tọa độ không hợp lệ
-flash.delivery.rider.type.not.enabled=Tài khoản này chưa mở giao hàng nhanh
-no.store.stall.selfdelivery.readonly=Phương thức giao hàng của quầy do chủ chợ đêm thiết lập thống nhất
-no.store.selfdelivery.nightmarket.only=Chỉ chủ chợ đêm mới được cấu hình tự giao hàng
-no.store.selfdelivery.market.missing=Không tìm thấy cửa hàng chợ đêm, vui lòng hoàn thành tạo chợ đêm trong quản lý cửa hàng trước
-no.store.selfdelivery.hours.invalid=Cấu hình khung giờ tự giao không hợp lệ
-no.order.selfdelivery.required=Đơn hàng này không phải là đơn hàng do cửa hàng tự giao
-no.order.selfdelivery.rider.denied=Đơn hàng này do cửa hàng tự giao, không cần tài xế
-no.order.selfdelivery.status.invalid=Trạng thái đơn hàng không cho phép thao tác này
-no.message.push.merchant.delivery.start=Cửa hàng đã bắt đầu giao đơn hàng của bạn
-no.billing.selfdelivery.freight=Phí giao hàng tự giao của cửa hàng
-no.message.push.merchant.delivery.complete=Cửa hàng đã xác nhận giao đơn hàng của bạn
-no.order.selfdelivery.unpaid=Đơn hàng chưa thanh toán, vui lòng xác nhận đã thu tiền trước khi xác nhận giao hàng
-no.message.push.merchant.accepted.content=Cửa hàng đã nhận đơn và đang chuẩn bị món của bạn
-no.order.not.found=Không tìm thấy đơn hàng
-flash.delivery.rider.exclusive.conflict=Tài xế đang có nhiệm vụ giao hàng độc quyền và tạm thời không thể nhận đơn này
-flash.delivery.edit.not.allowed=Chỉ có thể sửa đơn đang chờ nhận và chưa có tài xế
-flash.delivery.order.version.invalid=Vui lòng cung cấp phiên bản đơn hàng hợp lệ
-flash.delivery.tip.additional.invalid=Tiền boa thêm phải là số nguyên dương trong phạm vi số tiền được hỗ trợ
-flash.delivery.pay.type.invalid=Chiỉ hỗ trợ thanh toán bằng tiền mặt hoặc chuyển khoản ngoại tuyến

+ 1 - 0
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties

@@ -77,6 +77,7 @@ no.user.password.not.null=密码不能为空
 no.user.jcaptcha.error=验证码不正确
 no.user.jcaptcha.error=验证码不正确
 no.user.not.exist=用户不存在
 no.user.not.exist=用户不存在
 no.user.phone.duplicate=该手机号关联多个账号,请联系平台
 no.user.phone.duplicate=该手机号关联多个账号,请联系平台
+pay.method.not.available=该支付方式当前不可用,请更换支付方式
 no.user.login.success=登录成功
 no.user.login.success=登录成功
 no.user.password.error=密码错误
 no.user.password.error=密码错误
 no.system.error=系统错误
 no.system.error=系统错误

+ 1 - 0
ruoyi-admin/src/main/resources/i18n/messages_zh_TW.properties

@@ -77,6 +77,7 @@ no.user.password.not.null=密碼不能為空
 no.user.jcaptcha.error=驗證碼不正確
 no.user.jcaptcha.error=驗證碼不正確
 no.user.not.exist=用戶不存在
 no.user.not.exist=用戶不存在
 no.user.phone.duplicate=該手機號關聯多個帳號,請聯繫平台
 no.user.phone.duplicate=該手機號關聯多個帳號,請聯繫平台
+pay.method.not.available=該支付方式當前不可用,請更換支付方式
 no.user.login.success=登入成功
 no.user.login.success=登入成功
 no.user.password.error=密碼錯誤
 no.user.password.error=密碼錯誤
 no.system.error=系統錯誤
 no.system.error=系統錯誤

+ 35 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoBankCard.java

@@ -0,0 +1,35 @@
+package com.ruoyi.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 收款银行卡(031 银行卡列表化)。
+ * 商家与骑手通用,可维护多张卡但同一用户同时仅一张启用;
+ * 付款方(用户)仅能看到收款方当前启用的卡;替代 027 的 info_user 固定三字段。
+ */
+@Data
+@TableName("info_bank_card")
+public class InfoBankCard {
+    /** 主键 ID,数据库自增。 */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /** 归属用户 ID(商家主账号或骑手),不区分身份。 */
+    private Long userId;
+    /** 银行名称,取字典 taiwan_bank_list 的银行中文名。 */
+    private String bankName;
+    /** 银行账号。 */
+    private String accountNo;
+    /** 户名。 */
+    private String accountName;
+    /** 1=启用 0=停用;启用新卡时同事务停旧卡,保证同一用户最多一张启用。 */
+    private Integer isActive;
+    /** 创建时间。 */
+    private Date createTime;
+    /** 更新时间。 */
+    private Date updateTime;
+}

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoUser.java

@@ -204,6 +204,11 @@ public class InfoUser
     @Excel(name = "银行账号")
     @Excel(name = "银行账号")
     private String bankAccountNo;
     private String bankAccountNo;
 
 
+    /** 商家接受的支付方式组代码 CSV(031):NULL/空=全部启用,存量商家零行为变化。 */
+    private String payMethods;
+    /** 骑手接受的闪送收款方式组代码 CSV(031):NULL/空=平台开放的全部方式。 */
+    private String flashPayMethods;
+
     /** 商家说明 */
     /** 商家说明 */
     @Excel(name = "商家说明")
     @Excel(name = "商家说明")
     private String merchantIntroduction;
     private String merchantIntroduction;

+ 34 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/PaymentMethodConfig.java

@@ -0,0 +1,34 @@
+package com.ruoyi.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 平台支付方式开关(031 可配置支付方式)。
+ * 按支付方式组代码 × 维度独立控制;缺行语义=开启,因此平台未做任何设置时系统行为与历史现状完全一致。
+ */
+@Data
+@TableName("payment_method_config")
+public class PaymentMethodConfig {
+    /** 主键 ID,数据库自增。 */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /** 支付方式组代码:COD=到付、CARD_OMG=信用卡+ApplePay 同组、LINE_PAY、OFFLINE_TRANSFER=线下转账。 */
+    private String methodCode;
+    /** 维度:MERCHANT=商家餐饮单、RIDER_FLASH=骑手闪送;两维度独立开关可交叉。 */
+    private String scope;
+    /** 1=开 0=关;仅存在且为 0 时才表示平台关闭。 */
+    private Integer enabled;
+    /** 平台设置页展示排序,小的在前。 */
+    private Integer sort;
+    /** 最后操作的管理员用户 ID。 */
+    private Long updateBy;
+    /** 创建时间。 */
+    private Date createTime;
+    /** 更新时间。 */
+    private Date updateTime;
+}

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/InfoBankCardMapper.java

@@ -0,0 +1,7 @@
+package com.ruoyi.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.system.domain.InfoBankCard;
+
+/** 收款银行卡持久化接口;启用互斥(同用户单张启用)由服务层事务保证。 */
+public interface InfoBankCardMapper extends BaseMapper<InfoBankCard> { }

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/PaymentMethodConfigMapper.java

@@ -0,0 +1,7 @@
+package com.ruoyi.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.system.domain.PaymentMethodConfig;
+
+/** 平台支付方式开关持久化接口;缺行=开,读取方需自行按缺行语义补齐。 */
+public interface PaymentMethodConfigMapper extends BaseMapper<PaymentMethodConfig> { }

+ 233 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/PaymentMethodGateService.java

@@ -0,0 +1,233 @@
+package com.ruoyi.system.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.MessageUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.domain.InfoBankCard;
+import com.ruoyi.system.domain.InfoUser;
+import com.ruoyi.system.domain.PaymentMethodConfig;
+import com.ruoyi.system.domain.PosStoreLinePay;
+import com.ruoyi.system.domain.PosStoreOmg;
+import com.ruoyi.system.mapper.InfoBankCardMapper;
+import com.ruoyi.system.mapper.InfoUserMapper;
+import com.ruoyi.system.mapper.PaymentMethodConfigMapper;
+import com.ruoyi.system.mapper.PosStoreLinePayMapper;
+import com.ruoyi.system.mapper.PosStoreOmgMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 支付方式闸门服务(031 可配置支付方式)——全系统唯一的支付方式可用性判定入口。
+ *
+ * <p>三层闸门:某支付方式可用 = 平台开关(方式×维度,缺行=开)
+ * ∩ 收款方选择(info_user 选择列,NULL=全部)∩ 就绪度(门店凭证或启用银行卡)。
+ * 所有下单入口(用户餐饮下单、商家建单、闪送下单)与 bankInfo 必须统一调用
+ * {@link #assertUsable(String, GateScope, Long, Long)},禁止在各自入口重复实现判定逻辑,
+ * 保证闸门规则变化只改本类、全部入口行为一致(spec FR-004)。</p>
+ *
+ * <p>刻意不加缓存:开关表最多 4×2 行的小表索引查询,直查天然满足"保存后下一次查询即生效"
+ * (SC-001),避免缓存失效复杂度。</p>
+ */
+@Service
+public class PaymentMethodGateService {
+
+    /** 支付方式组代码:到付(payType=1)。 */
+    public static final String GROUP_COD = "COD";
+    /** 支付方式组代码:信用卡+Apple Pay 同组(payType=2、5,OMG 渠道同开同关)。 */
+    public static final String GROUP_CARD_OMG = "CARD_OMG";
+    /** 支付方式组代码:LINE Pay(payType=3)。 */
+    public static final String GROUP_LINE_PAY = "LINE_PAY";
+    /** 支付方式组代码:线下转账(payType=6)。 */
+    public static final String GROUP_OFFLINE = "OFFLINE_TRANSFER";
+
+    /** 现金 payType=4:仅商家建单场景,明确不纳入闸门管控,直接放行(spec FR-006)。 */
+    public static final String PAY_TYPE_CASH = "4";
+
+    /** payType 数值 → 组代码;不在表内的值视为非法。 */
+    private static final Map<String, String> PAY_TYPE_TO_GROUP = Map.of(
+            "1", GROUP_COD,
+            "2", GROUP_CARD_OMG,
+            "3", GROUP_LINE_PAY,
+            "5", GROUP_CARD_OMG,
+            "6", GROUP_OFFLINE);
+
+    /** 各维度可管控的组集合;RIDER_FLASH 无线上卡支付(闪送资金直达骑手)。 */
+    private static final Map<GateScope, List<String>> SCOPE_GROUPS = Map.of(
+            GateScope.MERCHANT, List.of(GROUP_COD, GROUP_CARD_OMG, GROUP_LINE_PAY, GROUP_OFFLINE),
+            GateScope.RIDER_FLASH, List.of(GROUP_COD, GROUP_LINE_PAY, GROUP_OFFLINE));
+
+    /** 闸门维度:商家餐饮单(用户向商家付款)与骑手闪送(用户直达骑手)独立开关。 */
+    public enum GateScope {
+        MERCHANT, RIDER_FLASH
+    }
+
+    /**
+     * 供结算页渲染的一项可选支付方式。
+     * CARD_OMG 组按 payType 展开为 2(信用卡)、5(Apple Pay)两项,组内 ready 一致。
+     */
+    public static class PayMethodOption {
+        /** 支付方式组代码。 */
+        private final String methodCode;
+        /** 对外 payType 数值("1"/"2"/"3"/"5"/"6")。 */
+        private final String payType;
+        /** 就绪度:false 表示当前不可实际使用(如线下转账无启用卡),前端应置灰或不渲染。 */
+        private final boolean ready;
+
+        public PayMethodOption(String methodCode, String payType, boolean ready) {
+            this.methodCode = methodCode;
+            this.payType = payType;
+            this.ready = ready;
+        }
+
+        public String getMethodCode() { return methodCode; }
+        public String getPayType() { return payType; }
+        public boolean isReady() { return ready; }
+    }
+
+    private final PaymentMethodConfigMapper configMapper;
+    private final InfoUserMapper userMapper;
+    private final InfoBankCardMapper bankCardMapper;
+    private final PosStoreOmgMapper omgMapper;
+    private final PosStoreLinePayMapper linePayMapper;
+
+    public PaymentMethodGateService(PaymentMethodConfigMapper configMapper,
+                                    InfoUserMapper userMapper,
+                                    InfoBankCardMapper bankCardMapper,
+                                    PosStoreOmgMapper omgMapper,
+                                    PosStoreLinePayMapper linePayMapper) {
+        this.configMapper = configMapper;
+        this.userMapper = userMapper;
+        this.bankCardMapper = bankCardMapper;
+        this.omgMapper = omgMapper;
+        this.linePayMapper = linePayMapper;
+    }
+
+    /**
+     * 校验支付方式可用,不可用抛出国际化异常;三下单入口与 bankInfo 统一调用(唯一入口)。
+     *
+     * @param payType 支付方式数值(与订单 payType 同域)
+     * @param scope 闸门维度
+     * @param storeId 门店 ID(MERCHANT 维度线上渠道就绪度用:pos_store_omg/pos_store_line_pay 为门店级凭证)
+     * @param payeeUserId 收款方用户 ID(商家主账号;闪送下单时无收款方传 null,跳过选择与就绪度层)
+     */
+    public void assertUsable(String payType, GateScope scope, Long storeId, Long payeeUserId) {
+        if (!isUsable(payType, scope, storeId, payeeUserId)) {
+            throw new ServiceException(MessageUtils.message("pay.method.not.available"));
+        }
+    }
+
+    /**
+     * 列出某维度对收款方当前可用的支付方式(结算页可选项、骑手端可选集共用)。
+     * 返回平台开关 ∩ 收款方选择的全部项并附就绪度;RIDER_FLASH 维度就绪度恒 true
+     * (收款方未定或即骑手本人,线下卡是否就绪由骑手自选方式时自行把握,抢单过滤兜底)。
+     */
+    public List<PayMethodOption> listAvailable(GateScope scope, Long storeId, Long payeeUserId) {
+        Map<String, Boolean> disabled = platformDisabledMap(scope);
+        Set<String> selected = selectedGroups(scope, payeeUserId);
+        List<PayMethodOption> result = new ArrayList<>();
+        for (String group : SCOPE_GROUPS.get(scope)) {
+            if (disabled.containsKey(group)) continue;
+            if (selected != null && !selected.contains(group)) continue;
+            boolean ready = isReady(group, scope, storeId, payeeUserId);
+            for (String payType : payTypesOf(group)) {
+                result.add(new PayMethodOption(group, payType, ready));
+            }
+        }
+        return result;
+    }
+
+    /** 单一判定实现:assertUsable 与调用方需要的布尔语义共用,保证两口径永不分裂。 */
+    private boolean isUsable(String payType, GateScope scope, Long storeId, Long payeeUserId) {
+        // 现金仅商家建单场景使用,明确不纳入管控(spec FR-006)。
+        if (PAY_TYPE_CASH.equals(payType)) return true;
+        String group = PAY_TYPE_TO_GROUP.get(payType);
+        if (group == null || !SCOPE_GROUPS.get(scope).contains(group)) return false;
+        if (platformDisabledMap(scope).containsKey(group)) return false;
+        Set<String> selected = selectedGroups(scope, payeeUserId);
+        if (selected != null && !selected.contains(group)) return false;
+        return isReady(group, scope, storeId, payeeUserId);
+    }
+
+    /** 平台已关闭的组集合(该维度);缺行=开,仅 enabled=0 的行进集合。 */
+    private Map<String, Boolean> platformDisabledMap(GateScope scope) {
+        List<PaymentMethodConfig> rows = configMapper.selectList(
+                new QueryWrapper<PaymentMethodConfig>().eq("scope", scope.name()));
+        Map<String, Boolean> disabled = new HashMap<>();
+        for (PaymentMethodConfig row : rows) {
+            if (Integer.valueOf(0).equals(row.getEnabled())) {
+                disabled.put(row.getMethodCode(), Boolean.TRUE);
+            }
+        }
+        return disabled;
+    }
+
+    /** 收款方接受的组集合;null/空选择返回 null 表示"全部接受"(存量零行为变化)。 */
+    private Set<String> selectedGroups(GateScope scope, Long payeeUserId) {
+        if (payeeUserId == null) return null;
+        InfoUser user = userMapper.selectById(payeeUserId);
+        if (user == null) return null;
+        String csv = scope == GateScope.MERCHANT ? user.getPayMethods() : user.getFlashPayMethods();
+        if (StringUtils.isEmpty(csv) || csv.trim().isEmpty()) return null;
+        Set<String> groups = new java.util.HashSet<>();
+        for (String part : csv.split(",")) {
+            String value = part.trim();
+            if (!value.isEmpty()) groups.add(value);
+        }
+        return groups.isEmpty() ? null : groups;
+    }
+
+    /**
+     * 就绪度判定:MERCHANT 维度线上渠道看门店级凭证、线下转账看商家启用卡;
+     * RIDER_FLASH 维度恒满足(收款方未定,由骑手选择层与抢单过滤兜底)。
+     */
+    private boolean isReady(String group, GateScope scope, Long storeId, Long payeeUserId) {
+        if (group.equals(GROUP_COD)) return true;
+        if (scope == GateScope.RIDER_FLASH) return true;
+        switch (group) {
+            case GROUP_CARD_OMG:
+                return storeId != null && omgMapper.selectCount(
+                        new QueryWrapper<PosStoreOmg>().eq("store_id", storeId).eq("is_enabled", 1)) > 0;
+            case GROUP_LINE_PAY:
+                return storeId != null && linePayMapper.selectCount(
+                        new QueryWrapper<PosStoreLinePay>().eq("store_id", storeId).eq("is_enabled", 1)) > 0;
+            case GROUP_OFFLINE:
+                return payeeUserId != null && bankCardMapper.selectCount(
+                        new QueryWrapper<InfoBankCard>().eq("user_id", payeeUserId).eq("is_active", 1)) > 0;
+            default:
+                return false;
+        }
+    }
+
+    /** 组代码 → 对外 payType 展开顺序(保持稳定展示顺序)。 */
+    private List<String> payTypesOf(String group) {
+        switch (group) {
+            case GROUP_COD: return List.of("1");
+            case GROUP_CARD_OMG: return List.of("2", "5");
+            case GROUP_LINE_PAY: return List.of("3");
+            case GROUP_OFFLINE: return List.of("6");
+            default: return List.of();
+        }
+    }
+
+    /** 全部合法组代码(平台设置页与保存校验用)。 */
+    public static List<String> allGroups() {
+        return Arrays.asList(GROUP_COD, GROUP_CARD_OMG, GROUP_LINE_PAY, GROUP_OFFLINE);
+    }
+
+    /** 维度合法组集合(保存收款方选择时校验值域用)。 */
+    public static List<String> groupsOf(GateScope scope) {
+        return SCOPE_GROUPS.get(scope);
+    }
+
+    /** payType → 组代码映射查询(保存/展示场景用);未知返回 null。 */
+    public static String groupOfPayType(String payType) {
+        return PAY_TYPE_TO_GROUP.get(payType);
+    }
+}

+ 207 - 0
ruoyi-system/src/test/java/com/ruoyi/system/service/PaymentMethodGateServiceTest.java

@@ -0,0 +1,207 @@
+package com.ruoyi.system.service;
+
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.system.domain.InfoBankCard;
+import com.ruoyi.system.domain.InfoUser;
+import com.ruoyi.system.domain.PaymentMethodConfig;
+import com.ruoyi.system.domain.PosStoreLinePay;
+import com.ruoyi.system.domain.PosStoreOmg;
+import com.ruoyi.system.mapper.InfoBankCardMapper;
+import com.ruoyi.system.mapper.InfoUserMapper;
+import com.ruoyi.system.mapper.PaymentMethodConfigMapper;
+import com.ruoyi.system.mapper.PosStoreLinePayMapper;
+import com.ruoyi.system.mapper.PosStoreOmgMapper;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import org.apache.ibatis.builder.MapperBuilderAssistant;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.support.StaticMessageSource;
+
+import java.util.List;
+import java.util.Locale;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * 闸门服务单测(031):覆盖三层闸门各拒绝原因、缺行=开、NULL 选择=全部、
+ * CARD_OMG 组 2/5 联动、COD 恒过、现金放行、RIDER_FLASH 维度就绪度恒满足与 listAvailable 口径。
+ */
+class PaymentMethodGateServiceTest {
+
+    private PaymentMethodGateService service;
+    private PaymentMethodConfigMapper configMapper;
+    private InfoUserMapper userMapper;
+    private InfoBankCardMapper bankCardMapper;
+    private PosStoreOmgMapper omgMapper;
+    private PosStoreLinePayMapper linePayMapper;
+    private static ConfigurableListableBeanFactory originalBeanFactory;
+
+    @BeforeAll
+    static void initializeMessageSource() {
+        // MessageUtils 静态依赖 SpringUtils 容器中的 MessageSource,单测注册 StaticMessageSource
+        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""),
+                PaymentMethodConfig.class);
+        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""),
+                InfoBankCard.class);
+        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""),
+                PosStoreOmg.class);
+        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""),
+                PosStoreLinePay.class);
+        originalBeanFactory = (ConfigurableListableBeanFactory)
+                org.springframework.test.util.ReflectionTestUtils.getField(SpringUtils.class, "beanFactory");
+        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
+        StaticMessageSource messageSource = new StaticMessageSource();
+        messageSource.addMessage("pay.method.not.available", Locale.getDefault(),
+                "该支付方式当前不可用,请更换支付方式");
+        beanFactory.registerSingleton("messageSource", messageSource);
+        new SpringUtils().postProcessBeanFactory(beanFactory);
+    }
+
+    @AfterAll
+    static void restoreBeanFactory() {
+        new SpringUtils().postProcessBeanFactory(originalBeanFactory);
+    }
+
+    @BeforeEach
+    void setUp() {
+        configMapper = mock(PaymentMethodConfigMapper.class);
+        userMapper = mock(InfoUserMapper.class);
+        bankCardMapper = mock(InfoBankCardMapper.class);
+        omgMapper = mock(PosStoreOmgMapper.class);
+        linePayMapper = mock(PosStoreLinePayMapper.class);
+        service = new PaymentMethodGateService(configMapper, userMapper, bankCardMapper, omgMapper, linePayMapper);
+        // 默认:平台无任何开关行(缺行=开),避免各用例重复 stub
+        when(configMapper.selectList(any())).thenReturn(List.of());
+    }
+
+    private static PaymentMethodConfig disabled(String methodCode, String scope) {
+        PaymentMethodConfig row = new PaymentMethodConfig();
+        row.setMethodCode(methodCode);
+        row.setScope(scope);
+        row.setEnabled(0);
+        return row;
+    }
+
+    private static InfoUser merchant(String payMethods) {
+        InfoUser user = new InfoUser();
+        user.setUserId(7L);
+        user.setPayMethods(payMethods);
+        return user;
+    }
+
+    @Test
+    void missingRowsMeanEnabled() {
+        // 缺行=开:COD 无就绪度要求,平台未配置时直接放行
+        assertDoesNotThrow(() ->
+                service.assertUsable("1", PaymentMethodGateService.GateScope.MERCHANT, null, 7L));
+    }
+
+    @Test
+    void platformDisabledRejectsWithI18nMessage() {
+        when(configMapper.selectList(any()))
+                .thenReturn(List.of(disabled("OFFLINE_TRANSFER", "MERCHANT")));
+        ServiceException exception = assertThrows(ServiceException.class, () ->
+                service.assertUsable("6", PaymentMethodGateService.GateScope.MERCHANT, null, 7L));
+        assertEquals("该支付方式当前不可用,请更换支付方式", exception.getMessage());
+    }
+
+    @Test
+    void cardOmgGroupDisablesBothCreditAndApplePay() {
+        when(configMapper.selectList(any()))
+                .thenReturn(List.of(disabled("CARD_OMG", "MERCHANT")));
+        assertThrows(ServiceException.class, () ->
+                service.assertUsable("2", PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L));
+        assertThrows(ServiceException.class, () ->
+                service.assertUsable("5", PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L));
+    }
+
+    @Test
+    void payeeSelectionRejectsUnselectedGroup() {
+        // 商家只接受 COD:LINE Pay 被拒,即使平台开启
+        when(userMapper.selectById(7L)).thenReturn(merchant("COD"));
+        assertThrows(ServiceException.class, () ->
+                service.assertUsable("3", PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L));
+        assertDoesNotThrow(() ->
+                service.assertUsable("1", PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L));
+    }
+
+    @Test
+    void nullSelectionMeansAllAccepted() {
+        when(userMapper.selectById(7L)).thenReturn(merchant(null));
+        when(linePayMapper.selectCount(any())).thenReturn(1L);
+        assertDoesNotThrow(() ->
+                service.assertUsable("3", PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L));
+    }
+
+    @Test
+    void offlineReadyRequiresActiveBankCard() {
+        when(userMapper.selectById(7L)).thenReturn(merchant(null));
+        when(bankCardMapper.selectCount(any())).thenReturn(0L);
+        assertThrows(ServiceException.class, () ->
+                service.assertUsable("6", PaymentMethodGateService.GateScope.MERCHANT, null, 7L));
+        when(bankCardMapper.selectCount(any())).thenReturn(1L);
+        assertDoesNotThrow(() ->
+                service.assertUsable("6", PaymentMethodGateService.GateScope.MERCHANT, null, 7L));
+    }
+
+    @Test
+    void cashBypassesGateAlways() {
+        // 现金仅商家建单场景,不纳入管控:任何维度无任何依赖直接放行
+        assertDoesNotThrow(() ->
+                service.assertUsable("4", PaymentMethodGateService.GateScope.MERCHANT, null, null));
+    }
+
+    @Test
+    void unknownPayTypeAndWrongScopeReject() {
+        assertThrows(ServiceException.class, () ->
+                service.assertUsable("9", PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L));
+        // 闪送维度不含线上卡支付
+        assertThrows(ServiceException.class, () ->
+                service.assertUsable("2", PaymentMethodGateService.GateScope.RIDER_FLASH, null, null));
+    }
+
+    @Test
+    void riderFlashScopeSkipsReadiness() {
+        // 闪送下单无收款方:仅平台开关层,线下转账就绪度由骑手选择与抢单过滤兜底
+        assertDoesNotThrow(() ->
+                service.assertUsable("6", PaymentMethodGateService.GateScope.RIDER_FLASH, null, null));
+    }
+
+    @Test
+    void listAvailableExpandsGroupsAndMarksReadiness() {
+        when(userMapper.selectById(7L)).thenReturn(merchant(null));
+        when(bankCardMapper.selectCount(any())).thenReturn(0L);
+        List<PaymentMethodGateService.PayMethodOption> options =
+                service.listAvailable(PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L);
+        // 全开+全接受:4 组按 payType 展开为 5 项(CARD_OMG=2、5 两项)
+        assertEquals(5, options.size());
+        PaymentMethodGateService.PayMethodOption offline = options.stream()
+                .filter(o -> "6".equals(o.getPayType())).findFirst().orElseThrow();
+        assertTrue(!offline.isReady(), "无启用卡时线下转账应标记不就绪但仍出现在可选项中");
+    }
+
+    @Test
+    void listAvailableRespectsPlatformAndSelection() {
+        when(configMapper.selectList(any()))
+                .thenReturn(List.of(disabled("LINE_PAY", "MERCHANT")));
+        when(userMapper.selectById(7L)).thenReturn(merchant("COD,CARD_OMG"));
+        List<PaymentMethodGateService.PayMethodOption> options =
+                service.listAvailable(PaymentMethodGateService.GateScope.MERCHANT, 1L, 7L);
+        // 平台关 LINE_PAY、商家未选 OFFLINE:只剩 COD+CARD_OMG 共 3 个 payType
+        assertEquals(3, options.size());
+        assertTrue(options.stream().noneMatch(o -> "3".equals(o.getPayType())));
+        assertTrue(options.stream().noneMatch(o -> "6".equals(o.getPayType())));
+    }
+}

+ 6 - 6
specs/031-pay-method-config/tasks.md

@@ -22,7 +22,7 @@ description: "Task list for 031-pay-method-config"
 
 
 **Purpose**: 一次性落全部数据库变更文档
 **Purpose**: 一次性落全部数据库变更文档
 
 
-- [ ] T001 将 031 全部 DDL 与迁移 SQL 追加到 `updatesql/sql.md`(2026-09-11 标注):新表 `payment_method_config`(uk(method_code,scope),缺行=开)、新表 `info_bank_card`、`info_user` 加 `pay_methods`/`flash_pay_methods` 两列、`flash_delivery_order` 加 `payment_status`、027 三字段迁移 INSERT...SELECT(结构见 `data-model.md` 第 1-5 节,逐条含用途注释)
+- [x] T001 将 031 全部 DDL 与迁移 SQL 追加到 `updatesql/sql.md`(2026-09-11 标注):新表 `payment_method_config`(uk(method_code,scope),缺行=开)、新表 `info_bank_card`、`info_user` 加 `pay_methods`/`flash_pay_methods` 两列、`flash_delivery_order` 加 `payment_status`、027 三字段迁移 INSERT...SELECT(结构见 `data-model.md` 第 1-5 节,逐条含用途注释)
 
 
 ---
 ---
 
 
@@ -32,11 +32,11 @@ description: "Task list for 031-pay-method-config"
 
 
 **⚠️ CRITICAL**: 本阶段完成前不得开始任何用户故事
 **⚠️ CRITICAL**: 本阶段完成前不得开始任何用户故事
 
 
-- [ ] T002 [P] 新建实体 `PaymentMethodConfig` + `PaymentMethodConfigMapper`(`ruoyi-system/src/main/java/com/ruoyi/system/domain/` 与 `mapper/`,MyBatis-Plus,全字段注释,字段见 data-model.md 第 1 节)
-- [ ] T003 [P] 新建实体 `InfoBankCard` + `InfoBankCardMapper`(同上目录,字段见 data-model.md 第 3 节;`user_id` 索引在 T001 DDL 已含)
-- [ ] T004 [P] `InfoUser` 加 `payMethods`/`flashPayMethods` 字段(`ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoUser.java`,注释注明 NULL=全部;同步其 mapper XML 的 resultMap/列清单若存在)
-- [ ] T005 实现 `PaymentMethodGateService`(`ruoyi-system/src/main/java/com/ruoyi/system/service/PaymentMethodGateService.java`,依赖 T002-T004):`assertUsable(payType, scope, payeeUserId)` 三层闸门(平台开关缺行=开 → 收款方选择 NULL=全部 → 就绪度:CARD_OMG 查 pos_store_omg、LINE_PAY 查 pos_store_line_pay、OFFLINE_TRANSFER 查 info_bank_card is_active=1、COD 恒满足;现金 4 不校验直接放行);`listAvailable(scope, payeeUserId)` 供可选项;开关读取加缓存(DictUtils 同款模式,保存后失效);payType↔组代码映射(2+5→CARD_OMG 联动);i18n key `pay.method.not.available` 写入 6 个 `ruoyi-admin/src/main/resources/i18n/messages*.properties`
-- [ ] T006 闸门服务单测(`ruoyi-system/src/test/java/com/ruoyi/system/service/PaymentMethodGateServiceTest.java`):三种拒绝原因各自抛错且消息为国际化 key 文案、缺行=开、NULL 选择=全部、CARD_OMG 组 2 与 5 同开同关、COD 恒过、现金放行、缓存失效后新值生效
+- [x] T002 [P] 新建实体 `PaymentMethodConfig` + `PaymentMethodConfigMapper`(`ruoyi-system/src/main/java/com/ruoyi/system/domain/` 与 `mapper/`,MyBatis-Plus,全字段注释,字段见 data-model.md 第 1 节)
+- [x] T003 [P] 新建实体 `InfoBankCard` + `InfoBankCardMapper`(同上目录,字段见 data-model.md 第 3 节;`user_id` 索引在 T001 DDL 已含)
+- [x] T004 [P] `InfoUser` 加 `payMethods`/`flashPayMethods` 字段(`ruoyi-system/src/main/java/com/ruoyi/system/domain/InfoUser.java`,注释注明 NULL=全部;同步其 mapper XML 的 resultMap/列清单若存在)
+- [x] T005 实现 `PaymentMethodGateService`(`ruoyi-system/src/main/java/com/ruoyi/system/service/PaymentMethodGateService.java`,依赖 T002-T004):`assertUsable(payType, scope, payeeUserId)` 三层闸门(平台开关缺行=开 → 收款方选择 NULL=全部 → 就绪度:CARD_OMG 查 pos_store_omg、LINE_PAY 查 pos_store_line_pay、OFFLINE_TRANSFER 查 info_bank_card is_active=1、COD 恒满足;现金 4 不校验直接放行);`listAvailable(scope, payeeUserId)` 供可选项;开关读取加缓存(DictUtils 同款模式,保存后失效);payType↔组代码映射(2+5→CARD_OMG 联动);i18n key `pay.method.not.available` 写入 6 个 `ruoyi-admin/src/main/resources/i18n/messages*.properties`
+- [x] T006 闸门服务单测(`ruoyi-system/src/test/java/com/ruoyi/system/service/PaymentMethodGateServiceTest.java`):三种拒绝原因各自抛错且消息为国际化 key 文案、缺行=开、NULL 选择=全部、CARD_OMG 组 2 与 5 同开同关、COD 恒过、现金放行、缓存失效后新值生效
 
 
 **Checkpoint**: 闸门可用,各故事可并行开始
 **Checkpoint**: 闸门可用,各故事可并行开始
 
 

+ 50 - 0
updatesql/sql.md

@@ -1607,3 +1607,53 @@ ALTER TABLE flash_delivery_order
 ALTER TABLE flash_delivery_order
 ALTER TABLE flash_delivery_order
   ADD COLUMN pay_type VARCHAR(4) NOT NULL DEFAULT '4' COMMENT '支付方式:4=现金,6=线下转账(下单时锁定)' AFTER currency;
   ADD COLUMN pay_type VARCHAR(4) NOT NULL DEFAULT '4' COMMENT '支付方式:4=现金,6=线下转账(下单时锁定)' AFTER currency;
 ```
 ```
+
+## 2026-09-11 可配置支付方式(031-pay-method-config)
+
+> 用途:平台支付方式开关(方式x维度)、商家/骑手收款方式选择、银行卡列表化、闪送收款状态与 027 存量迁移;缺行=开(payment_method_config 无数据时系统行为与现状一致);脚本只记录,由开发者手动执行,US5 上线前必须先执行本节全部 SQL。
+
+```sql
+-- 平台支付方式开关表(缺行=开;CARD_OMG=信用卡+ApplePay同组;现金4不纳入)
+CREATE TABLE payment_method_config (
+  id          BIGINT AUTO_INCREMENT PRIMARY KEY,
+  method_code VARCHAR(32) NOT NULL COMMENT '支付方式组代码:COD/CARD_OMG/LINE_PAY/OFFLINE_TRANSFER',
+  scope       VARCHAR(32) NOT NULL COMMENT '维度:MERCHANT=商家餐饮单,RIDER_FLASH=骑手闪送',
+  enabled     TINYINT     NOT NULL DEFAULT 1 COMMENT '1=开 0=关',
+  sort        INT         NOT NULL DEFAULT 0 COMMENT '平台设置页展示排序',
+  update_by   BIGINT               DEFAULT NULL COMMENT '最后操作管理员用户ID',
+  create_time DATETIME             DEFAULT NULL COMMENT '创建时间',
+  update_time DATETIME             DEFAULT NULL COMMENT '更新时间',
+  UNIQUE KEY uk_method_scope (method_code, scope)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='平台支付方式开关';
+
+-- 商家/骑手收款方式选择(NULL=全部,存量零行为变化)
+ALTER TABLE info_user
+  ADD COLUMN pay_methods       VARCHAR(128) DEFAULT NULL COMMENT '商家接受的支付方式组代码CSV,NULL=全部启用',
+  ADD COLUMN flash_pay_methods VARCHAR(128) DEFAULT NULL COMMENT '骑手接受的闪送收款方式组代码CSV,NULL=平台开放全部';
+
+-- 收款银行卡(多卡同时仅一张启用,商家/骑手通用)
+CREATE TABLE info_bank_card (
+  id           BIGINT AUTO_INCREMENT PRIMARY KEY,
+  user_id      BIGINT      NOT NULL COMMENT '归属用户(商家主账号/骑手)',
+  bank_name    VARCHAR(64) NOT NULL COMMENT '银行名称(取字典taiwan_bank_list)',
+  account_no   VARCHAR(64) NOT NULL COMMENT '银行账号',
+  account_name VARCHAR(64) NOT NULL COMMENT '户名',
+  is_active    TINYINT     NOT NULL DEFAULT 0 COMMENT '1=启用 0=停用,同一user同时最多一张启用',
+  create_time  DATETIME             DEFAULT NULL COMMENT '创建时间',
+  update_time  DATETIME             DEFAULT NULL COMMENT '更新时间',
+  KEY idx_user_id (user_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='收款银行卡';
+
+-- 闪送骑手确认收款状态
+ALTER TABLE flash_delivery_order
+  ADD COLUMN payment_status TINYINT NOT NULL DEFAULT 0 COMMENT '收款状态:0=未收款,1=骑手已确认收款';
+
+-- 027 存量迁移:银行三字段齐全的商家转成一张启用卡(迁移后 bankInfo 改读 info_bank_card)
+INSERT INTO info_bank_card (user_id, bank_name, account_no, account_name, is_active, create_time)
+SELECT user_id, bank_name, bank_account_no, bank_account_name, 1, NOW()
+FROM info_user
+WHERE user_id IS NOT NULL
+  AND bank_name IS NOT NULL AND bank_name <> ''
+  AND bank_account_no IS NOT NULL AND bank_account_no <> ''
+  AND bank_account_name IS NOT NULL AND bank_account_name <> '';
+```