Browse Source

feat: 当面付代开通 — MCC搜索下拉 + 店铺图片上传 + SDK null FileItem修复

alphah 19 hours ago
parent
commit
1d63fe50cf

+ 269 - 0
frontend/src/constants/mcc-codes.ts

@@ -0,0 +1,269 @@
+/**
+ * 商家经营类目 (MCC) 映射 — 对应支付宝商户签约 MCC 2.0
+ * 格式: 一级类目code_二级类目code → "一级类目 - 二级类目"
+ */
+export interface MccOption {
+  label: string;
+  value: string;
+}
+
+const MccCategory: Record<string, string> = {
+  A0001: "餐饮",
+  A0002: "零售批发",
+  A0003: "商业生活服务",
+  A0004: "休闲娱乐",
+  A0005: "车主生活",
+  A0006: "交通出行",
+  A0007: "网络通讯",
+  A0008: "教育培训",
+  A0009: "医疗卫生",
+  A0010: "酒旅景区",
+  A0011: "生活缴费",
+  A0012: "金融理财",
+  A0013: "公共管理和社会组织",
+  A0015: "物流运输",
+};
+
+const MccItems: [string, string, string][] = [
+  // A0001 餐饮
+  ["A0001", "B0001", "中式正餐"],
+  ["A0001", "B0002", "西式正餐"],
+  ["A0001", "B0003", "日韩/东南亚菜"],
+  ["A0001", "B0004", "中式快餐"],
+  ["A0001", "B0005", "西式快餐"],
+  ["A0001", "B0006", "小吃/熟食"],
+  ["A0001", "B0007", "校园团餐"],
+  ["A0001", "B0008", "综合团餐"],
+  ["A0001", "B0009", "饮品/甜品"],
+  ["A0001", "B0010", "烘焙糕点"],
+  ["A0001", "B0011", "酒吧/清吧"],
+  ["A0001", "B0012", "咖啡馆/茶馆"],
+  ["A0001", "B0117", "宴会提供商"],
+  ["A0001", "B0199", "火锅"],
+  ["A0001", "B0200", "订餐服务平台"],
+  // A0002 零售批发
+  ["A0002", "B0013", "杂货店"],
+  ["A0002", "B0014", "连锁便利店"],
+  ["A0002", "B0015", "大型超市"],
+  ["A0002", "B0016", "大卖场"],
+  ["A0002", "B0017", "百货商场"],
+  ["A0002", "B0018", "购物中心"],
+  ["A0002", "B0019", "奥特莱斯"],
+  ["A0002", "B0020", "商业街"],
+  ["A0002", "B0021", "水果店"],
+  ["A0002", "B0022", "茶叶"],
+  ["A0002", "B0023", "酒类"],
+  ["A0002", "B0024", "烟草/雪茄"],
+  ["A0002", "B0025", "营养品/保健品"],
+  ["A0002", "B0026", "服饰鞋包"],
+  ["A0002", "B0027", "美妆个护"],
+  ["A0002", "B0028", "黄金珠宝/钟表饰品"],
+  ["A0002", "B0029", "眼镜店"],
+  ["A0002", "B0030", "3C数码/家用电器"],
+  ["A0002", "B0031", "图文音像/工美乐器"],
+  ["A0002", "B0032", "母婴用品/儿童玩具"],
+  ["A0002", "B0033", "宠物/宠物用品"],
+  ["A0002", "B0034", "户外运动器材"],
+  ["A0002", "B0035", "五金建材"],
+  ["A0002", "B0216", "家居家纺"],
+  ["A0002", "B0036", "鲜花/绿植"],
+  ["A0002", "B0037", "文物经营/文物复制品"],
+  ["A0002", "B0038", "计生用品"],
+  ["A0002", "B0039", "烟花爆竹"],
+  ["A0002", "B0040", "危险化工产品"],
+  ["A0002", "B0041", "石油及石油产品"],
+  ["A0002", "B0042", "工业产品"],
+  ["A0002", "B0114", "互联网综合电商平台"],
+  ["A0002", "B0115", "互联网垂直电商平台"],
+  ["A0002", "B0118", "社区团购服务平台"],
+  ["A0002", "B0201", "食品零售"],
+  ["A0002", "B0202", "蔬菜/肉蛋/水产"],
+  ["A0002", "B0203", "办公用品"],
+  ["A0002", "B0232", "商品批发/企业采购/供应链服务"],
+  // A0003 商业生活服务
+  ["A0003", "B0044", "美发/美容/美甲服务"],
+  ["A0003", "B0045", "洗浴/保健养生服务"],
+  ["A0003", "B0046", "家政/清洁服务"],
+  ["A0003", "B0047", "电器/家具/其他维修"],
+  ["A0003", "B0048", "建筑装饰/装修服务"],
+  ["A0003", "B0049", "地产/房屋中介代理"],
+  ["A0003", "B0050", "宠物医院/其他宠物服务"],
+  ["A0003", "B0051", "消费品租赁"],
+  ["A0003", "B0052", "无人值守自助服务"],
+  ["A0003", "B0053", "婚介/婚庆/摄影服务"],
+  ["A0003", "B0054", "广告/会展/图文印刷"],
+  ["A0003", "B0055", "法律咨询/律师事务所"],
+  ["A0003", "B0056", "会计/金融咨询服务"],
+  ["A0003", "B0057", "征信和信用报告咨询服务"],
+  ["A0003", "B0058", "人才招聘服务"],
+  ["A0003", "B0059", "丧葬服务"],
+  ["A0003", "B0060", "拍卖/收藏"],
+  ["A0003", "B0116", "生活服务平台"],
+  ["A0003", "B0112", "在线工具"],
+  ["A0003", "B0165", "物业管理"],
+  ["A0003", "B0212", "共享充电宝及其他共享租赁"],
+  ["A0003", "B0213", "无人值守自助零售"],
+  ["A0003", "B0214", "无人值守自助娱乐"],
+  ["A0003", "B0227", "送水订奶"],
+  ["A0003", "B0229", "企业租赁"],
+  ["A0003", "B0230", "目的地租赁"],
+  ["A0003", "B0231", "房产租赁"],
+  // A0004 休闲娱乐
+  ["A0004", "B0062", "歌舞厅/休闲会所/KTV"],
+  ["A0004", "B0063", "棋牌桌游/电玩网吧"],
+  ["A0004", "B0064", "健身房/瑜伽/舞蹈"],
+  ["A0004", "B0065", "院线影城/演出赛事"],
+  ["A0004", "B0066", "游乐园/嘉年华"],
+  ["A0004", "B0067", "文化场馆"],
+  ["A0004", "B0068", "体育场馆"],
+  ["A0004", "B0069", "彩票"],
+  ["A0004", "B0108", "网络社交"],
+  ["A0004", "B0109", "网络图书/视频/音乐"],
+  ["A0004", "B0110", "游戏"],
+  ["A0004", "B0111", "网络直播"],
+  ["A0004", "B0205", "游戏周边服务/交易平台"],
+  // A0005 车主生活
+  ["A0005", "B0071", "车辆零配件/用品精品"],
+  ["A0005", "B0072", "汽车洗美/维修养护"],
+  ["A0005", "B0073", "车辆销售"],
+  ["A0005", "B0074", "二手车销售"],
+  ["A0005", "B0075", "停车服务"],
+  ["A0005", "B0076", "代驾服务"],
+  ["A0005", "B0077", "电动汽车充换电"],
+  ["A0005", "B0078", "两轮电瓶车充换电"],
+  ["A0005", "B0079", "汽车租赁"],
+  ["A0005", "B0080", "ETC不停车自动缴费"],
+  ["A0005", "B0081", "MTC半自动车道收费"],
+  ["A0005", "B0082", "高速服务区"],
+  ["A0005", "B0083", "道路救援"],
+  // A0006 交通出行
+  ["A0006", "B0084", "公路客运"],
+  ["A0006", "B0085", "出租车客运"],
+  ["A0006", "B0086", "网约车客运"],
+  ["A0006", "B0087", "地铁"],
+  ["A0006", "B0088", "公共交通"],
+  ["A0006", "B0089", "共享两轮车服务"],
+  ["A0006", "B0090", "加油卡、加油服务"],
+  ["A0006", "B0091", "加油站、加气站"],
+  ["A0006", "B0097", "航空公司"],
+  ["A0006", "B0098", "机场"],
+  ["A0006", "B0099", "机票代理人"],
+  ["A0006", "B0100", "航空系统商"],
+  ["A0006", "B0101", "铁路旅客运输"],
+  ["A0006", "B0102", "游轮及巡游航线服务"],
+  // A0007 网络通讯
+  ["A0007", "B0113", "信息检索服务/网络论坛"],
+  ["A0007", "B0120", "互联网数据服务"],
+  ["A0007", "B0121", "软件开发服务"],
+  ["A0007", "B0122", "数字类产品-游戏(国际)"],
+  ["A0007", "B0123", "数字类产品-软件提供商(国际)"],
+  ["A0007", "B0124", "数字类产品-其他(国际)"],
+  ["A0007", "B0125", "其他在线应用或综合类服务"],
+  ["A0007", "B0126", "网络推广/网络广告"],
+  ["A0007", "B0127", "电信运营商"],
+  ["A0007", "B0128", "付费电视"],
+  ["A0007", "B0129", "网络电话、传真服务"],
+  // A0008 教育培训
+  ["A0008", "B0130", "儿童保育服务(公立)"],
+  ["A0008", "B0131", "儿童保育服务(民办)"],
+  ["A0008", "B0132", "中小学校(公立)"],
+  ["A0008", "B0133", "中小学校(民办)"],
+  ["A0008", "B0134", "大学与学院(公立)"],
+  ["A0008", "B0135", "大学与学院(民办)"],
+  ["A0008", "B0138", "少年宫及青少年发展中心"],
+  ["A0008", "B0139", "其他教育/培训"],
+  // A0009 医疗卫生
+  ["A0009", "B0140", "医药销售"],
+  ["A0009", "B0141", "医疗器械销售"],
+  ["A0009", "B0142", "健康食品/设备"],
+  ["A0009", "B0143", "公立医院"],
+  ["A0009", "B0144", "社区卫生服务中心/乡镇卫生院"],
+  ["A0009", "B0145", "专业公共卫生机构"],
+  ["A0009", "B0146", "民营医院"],
+  ["A0009", "B0147", "诊所"],
+  ["A0009", "B0148", "个体医生"],
+  ["A0009", "B0149", "医疗美容"],
+  ["A0009", "B0150", "眼科医疗服务"],
+  ["A0009", "B0151", "口腔医疗服务"],
+  ["A0009", "B0152", "医学实验室及诊断中心"],
+  ["A0009", "B0153", "线上医疗服务"],
+  ["A0009", "B0154", "护理机构服务"],
+  ["A0009", "B0155", "体检/健康咨询"],
+  ["A0009", "B0156", "其他医疗保健服务"],
+  // A0010 酒旅景区
+  ["A0010", "B0119", "旅游服务平台(OTA)"],
+  ["A0010", "B0157", "酒店/旅馆/民宿"],
+  ["A0010", "B0158", "景区"],
+  ["A0010", "B0159", "旅行社和旅游服务"],
+  ["A0010", "B0160", "旅游相关服务直销"],
+  ["A0010", "B0219", "风景区系统商"],
+  ["A0010", "B0220", "观光车"],
+  ["A0010", "B0221", "游船码头"],
+  // A0011 生活缴费
+  ["A0011", "B0161", "公共事业(电、气、水)"],
+  ["A0011", "B0162", "公共事业-有线电视缴费"],
+  ["A0011", "B0163", "公共事业-其他缴费"],
+  ["A0011", "B0164", "话费充值与缴费"],
+  ["A0011", "B0204", "公共事业-电力缴费"],
+  ["A0011", "B0206", "公共事业-煤气缴费"],
+  ["A0011", "B0207", "公共事业-清洁服务缴费"],
+  ["A0011", "B0211", "公共事业-自来水缴费"],
+  ["A0011", "B0225", "供暖缴费"],
+  // A0012 金融理财
+  ["A0012", "B0166", "金融机构"],
+  ["A0012", "B0167", "金融机构-其他服务"],
+  ["A0012", "B0168", "外币汇兑"],
+  ["A0012", "B0169", "股票基金服务"],
+  ["A0012", "B0170", "小贷公司"],
+  ["A0012", "B0171", "借贷消费平台"],
+  ["A0012", "B0172", "融资租赁公司"],
+  ["A0012", "B0173", "金融租赁公司"],
+  ["A0012", "B0174", "汽车金融公司"],
+  ["A0012", "B0175", "消费金融公司"],
+  ["A0012", "B0176", "信托公司"],
+  ["A0012", "B0177", "支付机构"],
+  ["A0012", "B0178", "融资担保公司"],
+  ["A0012", "B0179", "其他金融服务"],
+  ["A0012", "B0180", "保险业务/保险代理"],
+  ["A0012", "B0181", "典当"],
+  // A0013 公共管理和社会组织
+  ["A0013", "B0183", "行政费用和罚款(非税)"],
+  ["A0013", "B0184", "公积金"],
+  ["A0013", "B0185", "公安交管"],
+  ["A0013", "B0186", "医保"],
+  ["A0013", "B0187", "社会保障服务"],
+  ["A0013", "B0188", "政府采购"],
+  ["A0013", "B0189", "政府贷款"],
+  ["A0013", "B0190", "法庭费用"],
+  ["A0013", "B0191", "保释金"],
+  ["A0013", "B0192", "税务"],
+  ["A0013", "B0193", "慈善和社会公益服务"],
+  ["A0013", "B0194", "使领馆"],
+  ["A0013", "B0195", "行业协会和专业社团"],
+  ["A0013", "B0196", "汽车协会"],
+  ["A0013", "B0197", "宗教组织"],
+  ["A0013", "B0198", "其他会员组织"],
+  ["A0013", "B0208", "中国共产党机关"],
+  ["A0013", "B0222", "文体机构"],
+  ["A0013", "B0226", "一网通办"],
+  ["A0013", "B0182", "政府机构"],
+  // A0015 物流运输
+  ["A0015", "B0092", "物流/快递公司"],
+  ["A0015", "B0093", "快递服务(个人商户)"],
+  ["A0015", "B0094", "邮政基本服务"],
+  ["A0015", "B0095", "驿站/自提柜"],
+  ["A0015", "B0096", "仓储"],
+  ["A0015", "B0103", "铁路货物运输"],
+  ["A0015", "B0104", "船舶、海运服务提供商"],
+  ["A0015", "B0105", "货品停放交易(国际)"],
+  ["A0015", "B0106", "国际货运代理和报关行"],
+  ["A0015", "B0107", "其他运输代理业"],
+  ["A0015", "B0217", "物流平台"],
+  ["A0015", "B0218", "同城即时配送"],
+];
+
+/** 扁平化的 MCC 选项列表,用于 el-select filterable */
+export const MCC_OPTIONS: MccOption[] = MccItems.map(([cat, code, name]) => ({
+  label: `${MccCategory[cat] || cat} - ${name} (${cat}_${code})`,
+  value: `${cat}_${code}`,
+}));

+ 45 - 0
frontend/src/views/module_payment/enterprise/index.vue

@@ -123,6 +123,12 @@
         <el-form-item label="商户支付宝账号" prop="account">
           <el-input v-model="f2fForm.account" placeholder="支付宝账号或2088开头的pid" />
         </el-form-item>
+        <el-form-item label="经营类目" prop="mcc_code">
+          <el-select v-model="f2fForm.mcc_code" placeholder="请搜索选择经营类目" filterable clearable
+            style="width: 100%">
+            <el-option v-for="item in MCC_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
         <el-form-item label="联系人姓名" prop="contact_name">
           <el-input v-model="f2fForm.contact_name" placeholder="请输入联系人姓名" />
         </el-form-item>
@@ -132,6 +138,12 @@
         <el-form-item label="联系人邮箱">
           <el-input v-model="f2fForm.contact_email" placeholder="选填" />
         </el-form-item>
+        <el-form-item label="店铺门头照">
+          <input type="file" accept="image/*" @change="handleShopSignBoardPicChange" />
+        </el-form-item>
+        <el-form-item label="店铺内景照">
+          <input type="file" accept="image/*" @change="handleShopScenePicChange" />
+        </el-form-item>
         <el-form-item label="签约且授权" prop="sign_and_auth">
           <el-switch v-model="f2fForm.sign_and_auth" />
         </el-form-item>
@@ -180,6 +192,7 @@ import FacetofaceAPI, {
   ORDER_STATUS_TAG_TYPE,
   ORDER_STATUS_LABEL,
 } from "@/api/module_payment/facetoface";
+import { MCC_OPTIONS } from "@/constants/mcc-codes";
 import CrudToolbarLeft from "@/components/CURD/CrudToolbarLeft.vue";
 import CrudToolbarRight from "@/components/CURD/CrudToolbarRight.vue";
 import PageSearch from "@/components/CURD/PageSearch.vue";
@@ -453,12 +466,15 @@ const currentF2fEnterprise = ref<any>(null);
 
 const f2fForm = reactive({
   account: "",
+  mcc_code: "",
   contact_name: "",
   contact_mobile: "",
   contact_email: "",
   sign_and_auth: false,
   rate: "",
   remark: "",
+  shop_sign_board_pic_base64: "",
+  shop_scene_pic_base64: "",
 });
 
 const f2fRules = reactive<FormRules>({
@@ -479,12 +495,15 @@ function handleOpenF2fApply(enterprise: any) {
   currentF2fEnterprise.value = enterprise;
   Object.assign(f2fForm, {
     account: "",
+    mcc_code: "",
     contact_name: "",
     contact_mobile: "",
     contact_email: "",
     sign_and_auth: false,
     rate: "",
     remark: "",
+    shop_sign_board_pic_base64: "",
+    shop_scene_pic_base64: "",
   });
   f2fDialogVisible.value = true;
 }
@@ -494,6 +513,29 @@ function handleCloseF2fDialog() {
   f2fFormRef.value?.resetFields();
 }
 
+function fileToBase64(file: File): Promise<string> {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onload = () => resolve((reader.result as string).split(",")[1]);
+    reader.onerror = reject;
+    reader.readAsDataURL(file);
+  });
+}
+
+async function handleShopSignBoardPicChange(e: Event) {
+  const input = e.target as HTMLInputElement;
+  if (input.files?.[0]) {
+    f2fForm.shop_sign_board_pic_base64 = await fileToBase64(input.files[0]);
+  }
+}
+
+async function handleShopScenePicChange(e: Event) {
+  const input = e.target as HTMLInputElement;
+  if (input.files?.[0]) {
+    f2fForm.shop_scene_pic_base64 = await fileToBase64(input.files[0]);
+  }
+}
+
 async function handleSubmitF2f() {
   if (!f2fFormRef.value || !currentF2fEnterprise.value) return;
   try {
@@ -512,6 +554,7 @@ async function handleSubmitF2f() {
     const submitData: Record<string, any> = {
       enterprise_id: currentF2fEnterprise.value.enterprise_id,
       account: f2fForm.account,
+      mcc_code: f2fForm.mcc_code,
       contact_name: f2fForm.contact_name,
       contact_mobile: f2fForm.contact_mobile,
       sign_and_auth: f2fForm.sign_and_auth,
@@ -519,6 +562,8 @@ async function handleSubmitF2f() {
     if (f2fForm.contact_email) submitData.contact_email = f2fForm.contact_email;
     if (f2fForm.sign_and_auth && f2fForm.rate) submitData.rate = f2fForm.rate;
     if (f2fForm.remark) submitData.remark = f2fForm.remark;
+    if (f2fForm.shop_sign_board_pic_base64) submitData.shop_sign_board_pic_base64 = f2fForm.shop_sign_board_pic_base64;
+    if (f2fForm.shop_scene_pic_base64) submitData.shop_scene_pic_base64 = f2fForm.shop_scene_pic_base64;
 
     await FacetofaceAPI.apply(submitData as any);
     ElMessage.success("当面付代开通申请已提交");

+ 6 - 2
frontend/src/views/module_payment/facetoface/index.vue

@@ -88,8 +88,11 @@
         <el-form-item label="店铺地址" prop="shop_address">
           <el-input v-model="applyForm.shop_address" placeholder="请输入店铺地址" />
         </el-form-item>
-        <el-form-item label="商户类别码" prop="mcc_code">
-          <el-input v-model="applyForm.mcc_code" placeholder="请输入 MCC 码" />
+        <el-form-item label="经营类目" prop="mcc_code">
+          <el-select v-model="applyForm.mcc_code" placeholder="请搜索选择经营类目" filterable clearable
+            style="width: 100%">
+            <el-option v-for="item in MCC_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
         </el-form-item>
         <el-form-item label="费率" prop="rate">
           <el-input v-model="applyForm.rate" placeholder="如 0.006 表示 0.6%" />
@@ -168,6 +171,7 @@ import FacetofaceAPI, {
   ORDER_STATUS_LABEL,
   ORDER_STATUS_OPTIONS,
 } from "@/api/module_payment/facetoface";
+import { MCC_OPTIONS } from "@/constants/mcc-codes";
 import CrudToolbarLeft from "@/components/CURD/CrudToolbarLeft.vue";
 import CrudToolbarRight from "@/components/CURD/CrudToolbarRight.vue";
 import PageSearch from "@/components/CURD/PageSearch.vue";

+ 2 - 1
java/src/main/java/com/payment/platform/core/tenant/TenantInnerInterceptor.java

@@ -37,7 +37,8 @@ public class TenantInnerInterceptor extends TenantLineInnerInterceptor {
             "sys_user_roles",     // 用户角色关联表(无 tenant_id 列)
             "sys_user_positions", // 用户岗位关联表(无 tenant_id 列)
             "sys_user_social",    // 用户第三方登录(无 tenant_id 列)
-            "pay_service_provider", // 服务商配置(无 tenant_id 列)
+            "pay_service_provider",         // 服务商配置(无 tenant_id 列)
+            "pay_service_provider_profile", // 服务商业务凭证(无 tenant_id 列)
             "sys_invitation_code" // 邀请码表(无 tenant_id 列,系统级功能)
     );
 

+ 10 - 0
java/src/main/java/com/payment/platform/module/payment/facetoface/dto/F2fOrderCreateDTO.java

@@ -43,4 +43,14 @@ public class F2fOrderCreateDTO {
 
     @Schema(description = "费率")
     private String rate;
+
+    @NotBlank(message = "MCC码不能为空")
+    @Schema(description = "商家经营类目编码,如 A0001_B0199")
+    private String mccCode;
+
+    @Schema(description = "店铺门头照(base64)")
+    private String shopSignBoardPicBase64;
+
+    @Schema(description = "店铺内景照(base64)")
+    private String shopScenePicBase64;
 }

+ 21 - 1
java/src/main/java/com/payment/platform/module/payment/facetoface/service/FacetofaceService.java

@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.bean.copier.CopyOptions;
 import cn.hutool.core.util.StrUtil;
 import com.alipay.api.AlipayApiException;
+import com.alipay.api.FileItem;
 import com.alipay.api.domain.*;
 import com.alipay.api.request.*;
 import com.alipay.api.response.*;
@@ -145,14 +146,33 @@ public class FacetofaceService {
                 log.info("当面付代开通 - Step1 创建事务成功: batch_no={}, account={}", batchNo, dto.getAccount());
 
                 // Step 2: 提交当面付签约申请
-                AlipayOpenAgentFacetofaceSignRequest signRequest = new AlipayOpenAgentFacetofaceSignRequest();
+                // SDK bug: getFileParams() 将 null FileItem 也塞入 multipart,导致支付宝报"为空或数据错误"
+                // 用匿名子类覆盖 getFileParams() 过滤 null
+                AlipayOpenAgentFacetofaceSignRequest signRequest = new AlipayOpenAgentFacetofaceSignRequest() {
+                    @Override
+                    public Map<String, FileItem> getFileParams() {
+                        Map<String, FileItem> filtered = new HashMap<>(super.getFileParams());
+                        filtered.values().removeIf(java.util.Objects::isNull);
+                        return filtered;
+                    }
+                };
                 signRequest.setBatchNo(batchNo);
+                signRequest.setMccCode(dto.getMccCode());
                 if (dto.getSignAndAuth() != null) {
                     signRequest.setSignAndAuth(dto.getSignAndAuth());
                 }
                 if (StrUtil.isNotBlank(dto.getRate())) {
                     signRequest.setRate(dto.getRate());
                 }
+                // base64 图片 → FileItem
+                if (StrUtil.isNotBlank(dto.getShopSignBoardPicBase64())) {
+                    byte[] signBoardBytes = Base64.getDecoder().decode(dto.getShopSignBoardPicBase64());
+                    signRequest.setShopSignBoardPic(new FileItem("shop_sign_board.jpg", signBoardBytes));
+                }
+                if (StrUtil.isNotBlank(dto.getShopScenePicBase64())) {
+                    byte[] sceneBytes = Base64.getDecoder().decode(dto.getShopScenePicBase64());
+                    signRequest.setShopScenePic(new FileItem("shop_scene.jpg", sceneBytes));
+                }
 
                 AlipayOpenAgentFacetofaceSignResponse signResponse = alipayClientFactory.getClient(dto.getEnterpriseId(), ServiceProviderBizType.FACETOFACE_AGENT.getValue()).execute(signRequest);
                 if (!signResponse.isSuccess())

+ 2 - 2
java/src/main/java/com/payment/platform/module/payment/serviceprovider/entity/ServiceProviderProfileEntity.java

@@ -1,7 +1,7 @@
 package com.payment.platform.module.payment.serviceprovider.entity;
 
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.payment.platform.common.base.PaymentTenantBaseEntity;
+import com.payment.platform.common.base.PaymentBaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("pay_service_provider_profile")
-public class ServiceProviderProfileEntity extends PaymentTenantBaseEntity {
+public class ServiceProviderProfileEntity extends PaymentBaseEntity {
 
     private Long serviceProviderId;
     private String bizType;