feat: add account deletion, announcements and subscription renewal

Support personal records and persistent smoking visibility. Add upload quota preflight, file cleanup, privacy entry, image caching and revision-based page refresh across the backend, admin and mini program.
This commit is contained in:
2026-11-03 22:06:47 +08:00
parent 4c9708b562
commit 8be6d9b1ab
98 changed files with 1679 additions and 372 deletions
+25 -1
View File
@@ -19,7 +19,7 @@ test('GET business parameters and POST bodies use clean paths with auth', async
});
test('multipart upload retains action and token when Android omits headers',async()=>{
let upload;
const {uploadFileCompat}=load('utils/request.js',{getStorageSync:()=> 'test-token',compressImage(o){o.fail();},uploadFile(o){upload=o;o.success({statusCode:200,data:'{"success":true,"path":"uploads/test.jpg"}'});} });
const {uploadFileCompat}=load('utils/request.js',{getStorageSync:()=> 'test-token',getFileInfo(o){o.success({size:100,digest:'a'.repeat(32)});},request(o){o.success({statusCode:200,data:{success:true}});},compressImage(o){o.fail();},uploadFile(o){upload=o;o.success({statusCode:200,data:'{"success":true,"path":"uploads/test.jpg"}'});} });
await uploadFileCompat({url:'https://we.sundynix.cn/api/uploadPartnerAvatar',filePath:'test.jpg',name:'file',formData:{partner_id:87}});
assert.equal(upload.url,'https://we.sundynix.cn/api/uploadPartnerAvatar?token=test-token');
assert.equal(upload.formData.action,'uploadPartnerAvatar');
@@ -59,3 +59,27 @@ test('unbound newcomer loads homepage records without requesting couple-only pet
assert.equal(page.data.homeError,false);assert.equal(page.data.statsError,false);assert.equal(page.data.statsLoading,false);
assert.equal(page.data.recentDiary.length,0);assert.equal(page.data.stats.pet,0);
});
test('smoking visibility page uses the real request adapter and restores the persisted response',async()=>{
let definition,visible=1;const calls=[];
const wx={getStorageSync:()=> 'test-token',showToast(){},request(o){
calls.push(o);
if(o.url.endsWith('/checkAuth'))o.success({statusCode:200,data:{user:{smokingCardVisible:visible}}});
else if(o.url.endsWith('/smokingCardVisible')){visible=o.data.visible;o.success({statusCode:200,data:{success:true,cardVisible:visible}});}
else throw new Error('Unexpected request: '+o.url);
}};
require('./load-module.cjs')({wx,console,Date,Promise,Page:p=>definition=p},{'../../utils/page-cache':{withDataCache:p=>p}})(path.join(__dirname,'../pages/punch/punch.js'));
const makePage=()=>({...definition,data:JSON.parse(JSON.stringify(definition.data)),setData(p){Object.assign(this.data,p);}});
const page=makePage();await page.loadSmokingPreference();assert.equal(page.data.smokingVisible,true);
await page.toggleSmoking({detail:{value:false}});assert.equal(visible,0);assert.equal(page.data.smokingVisible,false);
const save=calls.find(c=>c.url.endsWith('/smokingCardVisible'));assert.equal(save.method,'POST');assert.equal(save.data.visible,0);assert.equal(save.header.Authorization,'Bearer test-token');
const reopened=makePage();await reopened.loadSmokingPreference();assert.equal(reopened.data.smokingVisible,false);
await reopened.toggleSmoking({detail:{value:true}});assert.equal(visible,1);assert.equal(reopened.data.smokingVisible,true);
});
test('silent subscription persistence never hides a business spinner or shows a network toast',async()=>{
const ui=[];
const {api}=load('utils/request.js',{getStorageSync:()=> 'token',hideLoading:()=>ui.push('hide'),showToast:()=>ui.push('toast'),request:o=>o.fail({errMsg:'offline'})});
await assert.rejects(api.subscribeTemplate({template_type:'notify',template_id:'template'},{silent:true}));
assert.equal(ui.length,0);
});