trustbase-seller-backend 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/routes/onboard.html +73 -44
- package/test-onboard-applyment.js +7 -0
package/package.json
CHANGED
package/routes/onboard.html
CHANGED
|
@@ -70,6 +70,16 @@ h1{font-size:22px;margin-bottom:4px}
|
|
|
70
70
|
#apply-form div[id^="a_up_"] label.sbtn::after{content:'支持 jpg/png, 本机压缩后上传';font-size:11px;color:#BDB5A6;font-weight:400;border:none;background:none;padding:0}
|
|
71
71
|
#apply-form div[id^="a_up_"] label.sbtn:hover{border-color:#C4633C;background:#FBF1EA}
|
|
72
72
|
#apply-form div[id^="a_up_"] span[id^="st_"]{display:block;font-size:12px;margin-top:6px}
|
|
73
|
+
/* 上传槽已传态 (2026-10-03 二重框修复): 缩略图占满卡片 + 文件名 + 替换/删除 */
|
|
74
|
+
#apply-form .upfilled .auprev{display:block;width:100%;max-height:150px;object-fit:cover;border-radius:8px;border:1px solid #EAE3D6;margin-bottom:6px}
|
|
75
|
+
#apply-form .upph{background:#F0FDF4;border:1px solid #BBF7D0;color:#166534;border-radius:8px;padding:20px 10px;font-size:14px;font-weight:600;text-align:center;margin-bottom:6px}
|
|
76
|
+
#apply-form .upph .upph-sub{font-size:11px;font-weight:400;color:#4D7C5F;margin-top:2px}
|
|
77
|
+
#apply-form .upstat{display:block;font-size:12px;margin:4px 0 6px}
|
|
78
|
+
#apply-form .upops{display:flex;gap:8px}
|
|
79
|
+
#apply-form .upop{flex:1;text-align:center;font-size:12px;color:#C4633C;border:1px solid #C4633C;border-radius:6px;padding:5px 8px;background:#fff;cursor:pointer}
|
|
80
|
+
#apply-form .upop:hover{background:#F7EDE6}
|
|
81
|
+
#apply-form .upop.updel{color:#DC2626;border-color:#FCA5A5}
|
|
82
|
+
#apply-form .upop.updel:hover{background:#FEF2F2}
|
|
73
83
|
img.auprev{display:none;width:100%;max-height:140px;object-fit:cover;border-radius:8px;margin-bottom:8px;border:1px solid #EAE3D6}
|
|
74
84
|
.auname{font-size:11px;color:#8A857B;margin:-2px 0 6px;word-break:break-all}
|
|
75
85
|
/* 提交按钮 + 隐私行 */
|
|
@@ -535,27 +545,67 @@ function shrinkImage(file,cb){
|
|
|
535
545
|
rd.onerror=function(){cb(new Error('文件读取失败'))};
|
|
536
546
|
rd.readAsDataURL(file);
|
|
537
547
|
}
|
|
538
|
-
//
|
|
548
|
+
// 照片上传位 (2026-10-03 二重框 bug 修复): 槽位双态收进本函数统一管理 —
|
|
549
|
+
// 空态: 只有虚线"拍照/选图"卡; 已传态: 缩略图(占满卡片)+文件名+状态行+替换/删除小按钮,
|
|
550
|
+
// 空态卡整体隐藏 (旧实现上传后虚线框不隐藏 + 增强脚本另插预览 → 二重框)。
|
|
551
|
+
// 预填路径 (media_id 复用): 无本地预览 → "已上传 ✓"占位 + 同款替换/删除 (不显示空框)。
|
|
552
|
+
var _aSlots={}; // field → {prefill, clear} (预填/场景切换用)
|
|
539
553
|
function mountApplyUpload(slotId,field,label){
|
|
540
554
|
var slot=document.getElementById(slotId);
|
|
541
555
|
slot.innerHTML='<label>'+label+'</label>'
|
|
542
|
-
+'<label class="sbtn" style="cursor:pointer">拍照/选图<input type="file" accept="image/*" style="display:none"></label>'
|
|
543
|
-
+'
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
556
|
+
+'<label class="sbtn upzone" style="cursor:pointer">拍照/选图<input type="file" accept="image/*" style="display:none"></label>'
|
|
557
|
+
+'<div class="upfilled" style="display:none">'
|
|
558
|
+
+'<img class="auprev" alt="预览" style="display:none">'
|
|
559
|
+
+'<div class="upph" style="display:none">已上传 ✓<div class="upph-sub">照片已传过, 无需重传</div></div>'
|
|
560
|
+
+'<div class="auname"></div>'
|
|
561
|
+
+'<div class="upstat" id="st_'+field+'"></div>'
|
|
562
|
+
+'<div class="upops">'
|
|
563
|
+
+'<label class="upop" style="cursor:pointer">替换<input type="file" accept="image/*" style="display:none"></label>'
|
|
564
|
+
+'<button type="button" class="upop updel">删除</button>'
|
|
565
|
+
+'</div></div>';
|
|
566
|
+
var zone=slot.querySelector('.upzone');
|
|
567
|
+
var filled=slot.querySelector('.upfilled');
|
|
568
|
+
var img=slot.querySelector('.auprev');
|
|
569
|
+
var ph=slot.querySelector('.upph');
|
|
570
|
+
var uname=slot.querySelector('.auname');
|
|
571
|
+
var stat=slot.querySelector('.upstat');
|
|
572
|
+
function toEmpty(){
|
|
573
|
+
zone.style.display=''; filled.style.display='none';
|
|
574
|
+
img.style.display='none'; img.removeAttribute('src');
|
|
575
|
+
ph.style.display='none'; uname.textContent=''; stat.textContent=''; stat.style.color='';
|
|
576
|
+
slot.querySelectorAll('input[type=file]').forEach(function(i){i.value='';});
|
|
577
|
+
delete _aMedia[field]; // 删除必须清 media_id, 否则删除后提交还带旧值
|
|
578
|
+
}
|
|
579
|
+
function toFilled(o){
|
|
580
|
+
zone.style.display='none'; filled.style.display='block'; // 空态卡整体隐藏 — 无二重框
|
|
581
|
+
if(o.previewUrl){ img.src=o.previewUrl; img.style.display='block'; ph.style.display='none'; }
|
|
582
|
+
else { img.style.display='none'; img.removeAttribute('src'); ph.style.display='block'; }
|
|
583
|
+
uname.textContent=o.name||'';
|
|
584
|
+
stat.style.color=o.err?'#DC2626':(o.stat&&o.stat.indexOf('✓')===0?'#16A34A':'');
|
|
585
|
+
stat.textContent=o.stat||'';
|
|
586
|
+
}
|
|
587
|
+
_aSlots[field]={
|
|
588
|
+
prefill:function(mediaId){ _aMedia[field]=mediaId; toFilled({stat:'✓ 已上传过, 无需重传'}); },
|
|
589
|
+
clear:toEmpty
|
|
590
|
+
};
|
|
591
|
+
function onFile(input){
|
|
547
592
|
if(!input.files||!input.files[0]) return;
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
593
|
+
var file=input.files[0];
|
|
594
|
+
var previewUrl=URL.createObjectURL(file); // 本地即时预览 (不依赖上传结果)
|
|
595
|
+
toFilled({previewUrl:previewUrl,name:file.name,stat:'压缩中...'});
|
|
596
|
+
shrinkImage(file,function(err,payload){
|
|
597
|
+
if(err){ toFilled({previewUrl:previewUrl,name:file.name,stat:err.message,err:true}); return; }
|
|
598
|
+
toFilled({previewUrl:previewUrl,name:file.name,stat:'上传中...'});
|
|
552
599
|
fetch('/api/onboard/applyment/upload',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)})
|
|
553
600
|
.then(readJson).then(function(j){
|
|
554
|
-
if(j.ok&&j.media_id){_aMedia[field]=j.media_id;
|
|
555
|
-
else{
|
|
556
|
-
}).catch(function(e){
|
|
601
|
+
if(j.ok&&j.media_id){ _aMedia[field]=j.media_id; toFilled({previewUrl:previewUrl,name:file.name,stat:'✓ 已上传'}); }
|
|
602
|
+
else toFilled({previewUrl:previewUrl,name:file.name,stat:'上传失败: '+(j.message||j.error||'未知错误'),err:true});
|
|
603
|
+
}).catch(function(e){ toFilled({previewUrl:previewUrl,name:file.name,stat:'网络错误: '+e.message,err:true}); });
|
|
557
604
|
});
|
|
558
|
-
}
|
|
605
|
+
}
|
|
606
|
+
zone.querySelector('input[type=file]').addEventListener('change',function(){ onFile(this); });
|
|
607
|
+
filled.querySelector('.upops input[type=file]').addEventListener('change',function(){ onFile(this); });
|
|
608
|
+
filled.querySelector('.updel').addEventListener('click',toEmpty);
|
|
559
609
|
}
|
|
560
610
|
mountApplyUpload('a_up_license','license_media_id','营业执照照片 (必传)');
|
|
561
611
|
mountApplyUpload('a_up_idfront','legal_id_front_media_id','身份证人像面 (必传)');
|
|
@@ -759,13 +809,13 @@ function prefillApplyForm(snap){
|
|
|
759
809
|
var e=document.getElementById(PREFILL_MAP[k]);
|
|
760
810
|
if(e&&!e.value) e.value=v;
|
|
761
811
|
}
|
|
762
|
-
// 照片复用: media_id
|
|
812
|
+
// 照片复用: media_id 还在微信侧有效 → 槽位走"已上传"双态 (占位图+替换/删除, 无第二个空框)
|
|
763
813
|
var reused=0;
|
|
764
814
|
PREFILL_MEDIA.forEach(function(k){
|
|
765
815
|
if(!snap[k]) return;
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
816
|
+
reused++;
|
|
817
|
+
if(_aSlots[k]) _aSlots[k].prefill(snap[k]);
|
|
818
|
+
else _aMedia[k]=snap[k]; // 槽未挂载兜底 (不应发生)
|
|
769
819
|
});
|
|
770
820
|
var msg=document.getElementById('apply-msg');
|
|
771
821
|
msg.style.display='block';
|
|
@@ -878,8 +928,8 @@ async function restoreIdentity(){
|
|
|
878
928
|
</script>
|
|
879
929
|
<script>
|
|
880
930
|
/* ===== ③ 进件表单 美化增强 (2026-10-03) —— 纯追加脚本: 不修改/不覆盖任何现有函数,
|
|
881
|
-
|
|
882
|
-
|
|
931
|
+
① 编码字段下拉+联动 ② 状态卡片着色 + 签约二维码占位。
|
|
932
|
+
(证件缩略图预览已于二重框修复时并入主脚本 mountApplyUpload 槽位双态) ===== */
|
|
883
933
|
(function(){
|
|
884
934
|
// ⓪ 编码字段下拉 (2026-10-03 xiaomu: 手填编码易被微信秒拒 → 下拉)
|
|
885
935
|
// 经营类目 ↔ 主体类型联动 (企业默认 716 / 个体户默认 719, 可手改)
|
|
@@ -935,30 +985,9 @@ async function restoreIdentity(){
|
|
|
935
985
|
linkSelectManual('a_bank_address_code','a_bankcode_manual','__MANUAL__');
|
|
936
986
|
linkSelectManual('a_store_address_code','a_storecode_manual','__MANUAL__');
|
|
937
987
|
|
|
938
|
-
// ①
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
form.addEventListener('change',function(ev){
|
|
942
|
-
var input=ev.target;
|
|
943
|
-
if(!input||input.type!=='file'||!input.files||!input.files[0]) return;
|
|
944
|
-
var slot=input.closest('div[id^="a_up_"]');
|
|
945
|
-
if(!slot) return;
|
|
946
|
-
var rd=new FileReader();
|
|
947
|
-
rd.onload=function(){
|
|
948
|
-
var img=slot.querySelector('img.auprev');
|
|
949
|
-
if(!img){
|
|
950
|
-
img=document.createElement('img');
|
|
951
|
-
img.className='auprev';img.alt='预览';
|
|
952
|
-
slot.insertBefore(img,slot.children[1]||null); // 标题label之后
|
|
953
|
-
}
|
|
954
|
-
img.src=rd.result;img.style.display='block';
|
|
955
|
-
var nm=slot.querySelector('.auname');
|
|
956
|
-
if(!nm){nm=document.createElement('div');nm.className='auname';img.insertAdjacentElement('afterend',nm);}
|
|
957
|
-
nm.textContent=input.files[0].name+' · 点卡片可重新选择';
|
|
958
|
-
};
|
|
959
|
-
rd.readAsDataURL(input.files[0]);
|
|
960
|
-
},true);
|
|
961
|
-
}
|
|
988
|
+
// ① 证件缩略图预览已并入 mountApplyUpload 槽位双态 (2026-10-03 二重框 bug 修复:
|
|
989
|
+
// 旧补丁在槽位里另插 img/文件名, 与上传后未隐藏的虚线框并存 → 二重框。本段已删除,
|
|
990
|
+
// 预览/替换/删除由主脚本 mountApplyUpload 统一渲染)。
|
|
962
991
|
// ② 状态卡片着色 + 签约二维码占位 (监听现有状态机的 DOM 更新, 不改其内容逻辑)
|
|
963
992
|
var box=document.getElementById('apply-status');
|
|
964
993
|
if(box){
|
|
@@ -279,6 +279,13 @@ test("onboard 页面含进件表单 (btn-apply-submit) 且第③步状态机元
|
|
|
279
279
|
assert.ok(html.includes('name="sales_scene"'), "场景单选");
|
|
280
280
|
assert.ok(html.includes("SALES_SCENES_WEB") && html.includes("SALES_SCENES_MP"), "WEB/MP 场景");
|
|
281
281
|
assert.ok(html.includes("apply-err"), "错误红卡容器");
|
|
282
|
+
// 2026-10-03 二重框修复: 上传槽双态 (替换/删除按钮 + _aSlots 注册 + 删除清 media_id)
|
|
283
|
+
assert.ok(html.includes("upops") && html.includes("updel"), "替换/删除按钮结构");
|
|
284
|
+
assert.ok(html.includes("替换") && html.includes("删除"), "替换/删除文案");
|
|
285
|
+
assert.ok(html.includes("_aSlots"), "槽位双态注册表");
|
|
286
|
+
assert.ok(html.includes("delete _aMedia[field]"), "删除清 media_id");
|
|
287
|
+
assert.ok(!html.includes("slot.insertBefore(img"), "旧增强脚本预览补丁已删 (二重框根因)");
|
|
288
|
+
assert.ok(html.includes("prefill:function(mediaId)"), "预填走双态 (无第二个空框)");
|
|
282
289
|
assert.ok(html.includes("maybeAutoKyc"), "M2: 进件受理后自动 KYC 提交");
|
|
283
290
|
assert.ok(!html.includes("btn-verify"), "手动实名按钮已删 (自动触发)");
|
|
284
291
|
} finally { srv.close(); }
|