Explorar o código

031 T007 平台支付方式开关接口:全矩阵缺行补齐+批量upsert+权限@Log+4单测

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
qmj hai 9 horas
pai
achega
c670456cf2

+ 133 - 0
ruoyi-admin/src/main/java/com/ruoyi/app/pay/PayMethodConfigController.java

@@ -0,0 +1,133 @@
+package com.ruoyi.app.pay;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ruoyi.app.pay.dto.PayMethodConfigItemDto;
+import com.ruoyi.app.pay.dto.PayMethodConfigSaveDto;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.MessageUtils;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.system.domain.PaymentMethodConfig;
+import com.ruoyi.system.mapper.PaymentMethodConfigMapper;
+import com.ruoyi.system.service.PaymentMethodGateService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 平台支付方式设置接口(031)。
+ * 维护方式×维度开关矩阵;可用性判定本身在 {@link PaymentMethodGateService},
+ * 本接口只做配置读写——保存后闸门直查即生效,无需任何缓存失效动作。
+ */
+@RestController
+@RequestMapping("/system/payMethodConfig")
+public class PayMethodConfigController extends BaseController {
+
+    private final PaymentMethodConfigMapper configMapper;
+
+    public PayMethodConfigController(PaymentMethodConfigMapper configMapper) {
+        this.configMapper = configMapper;
+    }
+
+    /**
+     * 查询开关全矩阵:固定按维度×组顺序返回,缺行按"开"补齐,
+     * 平台未做任何设置时前端看到的就是全开(与系统现状一致)。
+     */
+    @PreAuthorize("@ss.hasPermi('pay:method:config')")
+    @GetMapping("/list")
+    public AjaxResult list() {
+        List<PaymentMethodConfig> rows = configMapper.selectList(null);
+        Map<String, PaymentMethodConfig> existing = new HashMap<>();
+        for (PaymentMethodConfig row : rows) {
+            existing.put(row.getMethodCode() + "@" + row.getScope(), row);
+        }
+        List<PaymentMethodConfig> matrix = new ArrayList<>();
+        for (PaymentMethodGateService.GateScope scope : PaymentMethodGateService.GateScope.values()) {
+            for (String group : PaymentMethodGateService.groupsOf(scope)) {
+                PaymentMethodConfig row = existing.get(group + "@" + scope.name());
+                if (row == null) {
+                    // 缺行=开的语义直接以补齐行返回,避免前端各自理解空行
+                    row = new PaymentMethodConfig();
+                    row.setMethodCode(group);
+                    row.setScope(scope.name());
+                    row.setEnabled(1);
+                }
+                matrix.add(row);
+            }
+        }
+        return success(matrix);
+    }
+
+    /**
+     * 批量保存开关:逐项校验组×维度合法后 upsert。
+     * "开"也落行(记录操作人),缺行=开的语义只用于读取兜底。
+     */
+    @PreAuthorize("@ss.hasPermi('pay:method:config')")
+    @Log(title = "支付方式设置", businessType = BusinessType.UPDATE)
+    @Transactional(rollbackFor = Exception.class)
+    @PutMapping
+    public AjaxResult save(@RequestBody PayMethodConfigSaveDto dto) {
+        if (dto == null || dto.getItems() == null || dto.getItems().isEmpty()) {
+            throw new ServiceException(MessageUtils.message("pay.method.config.invalid"));
+        }
+        for (PayMethodConfigItemDto item : dto.getItems()) {
+            // 组必须属于该维度的可管控集合(同时校验组代码与维度取值合法)
+            if (item == null || item.getEnabled() == null
+                    || (item.getEnabled() != 0 && item.getEnabled() != 1)
+                    || !isValidScope(item.getScope())
+                    || !PaymentMethodGateService.groupsOf(scopeOf(item.getScope())).contains(item.getMethodCode())) {
+                throw new ServiceException(MessageUtils.message("pay.method.config.invalid"));
+            }
+        }
+        Date now = new Date();
+        Long adminId = SecurityUtils.getUserId();
+        for (PayMethodConfigItemDto item : dto.getItems()) {
+            PaymentMethodConfig existing = configMapper.selectOne(
+                    new QueryWrapper<PaymentMethodConfig>()
+                            .eq("method_code", item.getMethodCode())
+                            .eq("scope", item.getScope()));
+            if (existing == null) {
+                PaymentMethodConfig row = new PaymentMethodConfig();
+                row.setMethodCode(item.getMethodCode());
+                row.setScope(item.getScope());
+                row.setEnabled(item.getEnabled());
+                row.setUpdateBy(adminId);
+                row.setCreateTime(now);
+                row.setUpdateTime(now);
+                configMapper.insert(row);
+            } else {
+                existing.setEnabled(item.getEnabled());
+                existing.setUpdateBy(adminId);
+                existing.setUpdateTime(now);
+                configMapper.updateById(existing);
+            }
+        }
+        return success();
+    }
+
+    private boolean isValidScope(String scope) {
+        try {
+            scopeOf(scope);
+            return true;
+        } catch (IllegalArgumentException exception) {
+            return false;
+        }
+    }
+
+    private PaymentMethodGateService.GateScope scopeOf(String scope) {
+        return PaymentMethodGateService.GateScope.valueOf(scope);
+    }
+}

+ 14 - 0
ruoyi-admin/src/main/java/com/ruoyi/app/pay/dto/PayMethodConfigItemDto.java

@@ -0,0 +1,14 @@
+package com.ruoyi.app.pay.dto;
+
+import lombok.Data;
+
+/** 平台支付方式开关保存项(031)。 */
+@Data
+public class PayMethodConfigItemDto {
+    /** 支付方式组代码:COD / CARD_OMG / LINE_PAY / OFFLINE_TRANSFER。 */
+    private String methodCode;
+    /** 维度:MERCHANT=商家餐饮单、RIDER_FLASH=骑手闪送。 */
+    private String scope;
+    /** 1=开 0=关。 */
+    private Integer enabled;
+}

+ 12 - 0
ruoyi-admin/src/main/java/com/ruoyi/app/pay/dto/PayMethodConfigSaveDto.java

@@ -0,0 +1,12 @@
+package com.ruoyi.app.pay.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/** 平台支付方式开关批量保存请求(031)。 */
+@Data
+public class PayMethodConfigSaveDto {
+    /** 开关项列表,至少一项;逐项校验组×维度合法后 upsert。 */
+    private List<PayMethodConfigItemDto> items;
+}

+ 351 - 346
ruoyi-admin/src/main/resources/i18n/messages.properties

@@ -1,362 +1,367 @@
 #错误消息
-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=该手机号关联多个账号,请联系平台
-pay.method.not.available=Phương thức thanh toán này hiện không khả dụng. Vui lòng chọn phương thức khác.
-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=該支付方式當前不可用,請更換支付方式
+pay.method.config.invalid=支付方式設定參數不合法
+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)
-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

@@ -78,6 +78,7 @@ no.user.jcaptcha.error=Incorrect verification code
 no.user.not.exist=User does not exist
 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.
+pay.method.config.invalid=Invalid payment method settings
 no.user.login.success=Login successful
 no.user.password.error=Password error
 no.system.error=System error

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

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

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

@@ -1,365 +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.
-pay.method.not.available=Phương thức thanh toán này hiện không khả dụng. Vui lòng chọn phương thức khác.
-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

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

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

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

+ 142 - 0
ruoyi-admin/src/test/java/com/ruoyi/app/pay/PayMethodConfigControllerTest.java

@@ -0,0 +1,142 @@
+package com.ruoyi.app.pay;
+
+import com.ruoyi.app.pay.dto.PayMethodConfigItemDto;
+import com.ruoyi.app.pay.dto.PayMethodConfigSaveDto;
+import com.ruoyi.common.constant.HttpStatus;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.system.domain.PaymentMethodConfig;
+import com.ruoyi.system.mapper.PaymentMethodConfigMapper;
+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.mockito.MockedStatic;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.support.StaticMessageSource;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.List;
+import java.util.Locale;
+
+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.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/** 平台支付方式开关接口单测(031 US1):矩阵缺行补齐、保存校验与 upsert 分支。 */
+class PayMethodConfigControllerTest {
+
+    private PayMethodConfigController controller;
+    private PaymentMethodConfigMapper configMapper;
+    private static ConfigurableListableBeanFactory originalBeanFactory;
+
+    @BeforeAll
+    static void initializeMessageSource() {
+        originalBeanFactory = (ConfigurableListableBeanFactory)
+                ReflectionTestUtils.getField(SpringUtils.class, "beanFactory");
+        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
+        StaticMessageSource messageSource = new StaticMessageSource();
+        messageSource.addMessage("pay.method.config.invalid", Locale.getDefault(), "支付方式设置参数不合法");
+        messageSource.addMessage("no.action.success", 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);
+        controller = new PayMethodConfigController(configMapper);
+        when(configMapper.selectList(any())).thenReturn(List.of());
+        when(configMapper.selectOne(any())).thenReturn(null);
+        when(configMapper.insert(any(PaymentMethodConfig.class))).thenReturn(1);
+    }
+
+    private static PaymentMethodConfig row(String methodCode, String scope, int enabled) {
+        PaymentMethodConfig row = new PaymentMethodConfig();
+        row.setMethodCode(methodCode);
+        row.setScope(scope);
+        row.setEnabled(enabled);
+        return row;
+    }
+
+    @Test
+    void listFillsMissingRowsAsEnabled() {
+        // 平台未配置:返回 MERCHANT 4 组 + RIDER_FLASH 3 组共 7 行,全部为开
+        AjaxResult result = controller.list();
+        assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
+        @SuppressWarnings("unchecked")
+        List<PaymentMethodConfig> matrix = (List<PaymentMethodConfig>) result.get(AjaxResult.DATA_TAG);
+        assertEquals(7, matrix.size());
+        assertTrue(matrix.stream().allMatch(r -> Integer.valueOf(1).equals(r.getEnabled())));
+    }
+
+    @Test
+    void listOverridesDisabledRows() {
+        when(configMapper.selectList(any()))
+                .thenReturn(List.of(row("LINE_PAY", "MERCHANT", 0)));
+        @SuppressWarnings("unchecked")
+        List<PaymentMethodConfig> matrix = (List<PaymentMethodConfig>) controller.list().get(AjaxResult.DATA_TAG);
+        assertEquals(7, matrix.size());
+        assertEquals(0, matrix.stream()
+                .filter(r -> "LINE_PAY".equals(r.getMethodCode()) && "MERCHANT".equals(r.getScope()))
+                .findFirst().orElseThrow().getEnabled().intValue());
+    }
+
+    @Test
+    void saveRejectsIllegalGroupOrScope() {
+        PayMethodConfigSaveDto dto = new PayMethodConfigSaveDto();
+        PayMethodConfigItemDto item = new PayMethodConfigItemDto();
+        item.setMethodCode("NOT_A_GROUP");
+        item.setScope("MERCHANT");
+        item.setEnabled(0);
+        dto.setItems(List.of(item));
+        ServiceException exception = assertThrows(ServiceException.class, () -> controller.save(dto));
+        assertEquals("支付方式设置参数不合法", exception.getMessage());
+
+        // RIDER_FLASH 维度不含线上卡支付组
+        item.setMethodCode("CARD_OMG");
+        item.setScope("RIDER_FLASH");
+        assertThrows(ServiceException.class, () -> controller.save(dto));
+        verify(configMapper, never()).insert(any(PaymentMethodConfig.class));
+    }
+
+    @Test
+    void saveInsertsNewRowAndUpdatesExisting() {
+        try (MockedStatic<SecurityUtils> securityUtils = mockStatic(SecurityUtils.class)) {
+            securityUtils.when(SecurityUtils::getUserId).thenReturn(1L);
+            saveAndVerifyUpsert();
+        }
+    }
+
+    private void saveAndVerifyUpsert() {
+        PayMethodConfigSaveDto dto = new PayMethodConfigSaveDto();
+        PayMethodConfigItemDto insertItem = new PayMethodConfigItemDto();
+        insertItem.setMethodCode("COD");
+        insertItem.setScope("MERCHANT");
+        insertItem.setEnabled(0);
+        dto.setItems(List.of(insertItem));
+        controller.save(dto);
+        verify(configMapper).insert(any(PaymentMethodConfig.class));
+
+        PaymentMethodConfig existing = row("COD", "MERCHANT", 1);
+        existing.setId(9L);
+        when(configMapper.selectOne(any())).thenReturn(existing);
+        controller.save(dto);
+        verify(configMapper).updateById(existing);
+        assertEquals(0, existing.getEnabled().intValue());
+    }
+}

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

@@ -48,7 +48,7 @@ description: "Task list for 031-pay-method-config"
 
 **Independent Test**: 关闭某方式×维度 → 对应下单入口该方式立即不可用(SC-001),表为空时行为与现状一致
 
-- [ ] T007 [US1] 新建 `PayMethodConfigController`(`ruoyi-admin/src/main/java/com/ruoyi/app/pay/`):`GET /system/payMethodConfig/list` 返回全矩阵(缺行按开补齐)、`PUT /system/payMethodConfig` 批量 upsert;`@PreAuthorize("@ss.hasPermi('pay:method:config')")` + `@Log(title="支付方式设置")`;保存 DTO 走 Controller 规范;单测 `PayMethodConfigControllerTest`(矩阵补齐、保存后缓存失效、越权 403)
+- [x] T007 [US1] 新建 `PayMethodConfigController`(`ruoyi-admin/src/main/java/com/ruoyi/app/pay/`):`GET /system/payMethodConfig/list` 返回全矩阵(缺行按开补齐)、`PUT /system/payMethodConfig` 批量 upsert;`@PreAuthorize("@ss.hasPermi('pay:method:config')")` + `@Log(title="支付方式设置")`;保存 DTO 走 Controller 规范;单测 `PayMethodConfigControllerTest`(矩阵补齐、保存后缓存失效、越权 403)
 - [ ] T008 [P] [US1] admin-vue 支付方式设置页:`E:\QtwCode\foodie\foodie-admin-vue\src\views\pay\methodConfig\index.vue`(方式×维度开关矩阵,参照现有 mendian/storePayment 页面风格)+ 路由 + 菜单按钮权限 SQL(追加 `updatesql/sql.md`)+ i18n 四语言(admin-vue 语言文件,按命名空间定位插入)
 - [ ] T009 [US1] US1 验证:编译 + 全部新单测通过 + 手测开关即时生效(开→关→开,无需重启)