271 lines
12 KiB
JavaScript
271 lines
12 KiB
JavaScript
/* ═════ 档案填写页:出生年月/性别/地区 + 日常肤质轮播 → 拍照
|
|
对照 H5 index.html #s-profile(L61-108)、#p-photoguide(L311-327)
|
|
档案字段与 H5 一致:{ real_age, gender, region, daily_skin_type }
|
|
三个选择器均用底部滚轮弹层,滚动只修改草稿,确定后写回字段。 ═════ */
|
|
var api = require('../../utils/api.js');
|
|
var REGION_DATA = require('../../utils/region-data.js');
|
|
var swipe = require('../../utils/swipe-gesture');
|
|
|
|
// 肤质选项(与 H5 SKINS 一致,图片远程加载;第一条描述在 H5 里含 <br>,拆成两行)
|
|
var SKINS = [
|
|
{ img: 'img/ui-20261009/skin-0-dry.png', name: '干性肌肤', desc: '全脸干燥,容易紧绷、', desc2: '缺乏光泽' },
|
|
{ img: 'img/ui-20261009/skin-1-mixeddry.png', name: '混合偏干肌肤', desc: '两颊偏干,T区油脂较少或偶尔出油' },
|
|
{ img: 'img/ui-20261009/skin-2-neutral.png', name: '中性肌肤', desc: '水油平衡,肤感舒适,无明显干燥出油' },
|
|
{ img: 'img/ui-20261009/skin-3-oily.png', name: '油性肌肤', desc: '全脸易出油,容易泛油光、毛孔明显' },
|
|
{ img: 'img/ui-20261009/skin-4-mixedoily.png', name: '混合偏油肌肤', desc: 'T区易出油,两颊相对清爽或轻微干燥' }
|
|
];
|
|
|
|
var NOW = new Date(), NOW_Y = NOW.getFullYear(), NOW_M = NOW.getMonth() + 1;
|
|
var YEARS = [], MONTHS = [];
|
|
for (var y = NOW_Y - 99; y <= NOW_Y - 1; y++) YEARS.push(y + '年');
|
|
for (var m = 1; m <= 12; m++) MONTHS.push(m + '月');
|
|
|
|
function ageFromBirth(y, m) { return NOW_Y - y - (NOW_M < m ? 1 : 0); } // 未过生日月份按少一岁(与 H5 一致)
|
|
|
|
Page(require('../../utils/page-header').page({
|
|
onShareAppMessage: function () { return require('../../utils/share').message(); },
|
|
data: {
|
|
bgUrl: api.assetUrl('img/ui-20261009/bg-profile-h5.jpg'),
|
|
guideBgUrl: api.assetUrl('img/ui-20261009/bg-splash-h5.jpg'),
|
|
sloganUrl: api.assetUrl('img/ui-20261012/splash-slogan.png'),
|
|
closeIconUrl: api.assetUrl('img/ui-20261009/icon-close.png'),
|
|
|
|
// 出生年月(两列滚轮:年+月,默认 30 岁 1 月)
|
|
birthRange: [YEARS, MONTHS],
|
|
birthIndex: [YEARS.indexOf((NOW_Y - 30) + '年'), 0],
|
|
birthText: '',
|
|
birth: '', // 'YYYY-MM'
|
|
age: 0, // real_age
|
|
|
|
// 性别
|
|
genderRange: ['女', '男'],
|
|
genderText: '',
|
|
|
|
// 所在地区(省 + 市两列)
|
|
regionRange: [
|
|
REGION_DATA.map(function (p) { return p[0]; }),
|
|
REGION_DATA[0][1]
|
|
],
|
|
regionIndex: [0, 0],
|
|
regionText: '',
|
|
|
|
// 肤质轮播
|
|
skins: SKINS.map(function (s) {
|
|
return { img: api.assetUrl(s.img), name: s.name, desc: s.desc, desc2: s.desc2 || '' };
|
|
}),
|
|
skinIndex: 0,
|
|
skinPercent: 0, skinDragOffset: 0, skinDragging: false,
|
|
skinLastIndex: SKINS.length - 1,
|
|
|
|
showGuide: false, picker: '', pickerTitle: '', pickerValue: [0, 0],
|
|
toastText: '', toastOn: false, identityChecking: true, identityError: ''
|
|
},
|
|
onLoad: function () {
|
|
if (!api.user()) { my.redirectTo({ url: '/pages/login/login' }); return; }
|
|
this.ownerId = api.user().id;
|
|
if (api.user().kind !== 'taobao_guest') try {
|
|
var saved = my.getStorageSync({ key: 'juzi.taobao.profile.' + api.user().id }).data;
|
|
if (saved) {
|
|
saved.age = ageFromBirth(Number(saved.birth.split('-')[0]), Number(saved.birth.split('-')[1]));
|
|
this.setData(saved);
|
|
}
|
|
} catch (_) {}
|
|
// H5 goSkin(0) 的等价初始化:轨道位移与当前下标同步
|
|
this.setData({ skinIndex: this.data.skinIndex || 0, skinPercent: (this.data.skinIndex || 0) * 100 });
|
|
},
|
|
onShow: function () {
|
|
this.disableSwipeBack();
|
|
this.visible = true;
|
|
if (!api.user() || this.ownerId !== api.user().id) {
|
|
this.clearPrivateProfile(); return Promise.resolve(false);
|
|
}
|
|
if (api.user().kind === 'taobao_guest') {
|
|
this.identityPending = false; var guestPage = this;
|
|
this.setData({ identityChecking: false, identityError: '' }, function () { guestPage.measureSkin(); }); return Promise.resolve(true);
|
|
}
|
|
var that = this, seq = this.identitySeq = (this.identitySeq || 0) + 1;
|
|
this.identityPending = true; this.setData({ identityChecking: true, identityError: '' });
|
|
return (typeof api.restore === 'function' ? api.restore() : Promise.resolve(api.user())).then(function (user) {
|
|
if (!that.visible || seq !== that.identitySeq) return false;
|
|
if (!user || user.id !== that.ownerId) { that.clearPrivateProfile(); return false; }
|
|
that.identityPending = false; that.setData({ identityChecking: false }, function () { that.measureSkin(); }); return true;
|
|
}).catch(function (err) {
|
|
if (!that.visible || seq !== that.identitySeq) return false;
|
|
if (err.status === 401 || !api.user() || api.user().id !== that.ownerId) { that.clearPrivateProfile(); return false; }
|
|
that.setData({ identityChecking: false, identityError: '网络异常,暂时无法确认当前账号,请重试。' }); return false;
|
|
});
|
|
},
|
|
onRetryIdentity: function () { return this.onShow(); },
|
|
disableSwipeBack: function () {
|
|
// Disable the native page-exit gesture, leaving skin carousel touches intact.
|
|
try {
|
|
if (my.tb && typeof my.tb.enableSwipeBack === 'function') {
|
|
var pending = my.tb.enableSwipeBack({ enable: 0 });
|
|
if (pending && typeof pending.catch === 'function') pending.catch(function () {});
|
|
}
|
|
} catch (_) {}
|
|
},
|
|
onReady: function () { this.disableSwipeBack(); this.measureSkin(); },
|
|
measureSkin: function () {
|
|
if (typeof my.createSelectorQuery !== 'function') return;
|
|
var that = this;
|
|
try { my.createSelectorQuery().select('.skin-carousel').boundingClientRect().exec(function (rows) {
|
|
if (that.visible && rows && rows[0] && rows[0].width > 0) that.skinWidth = rows[0].width;
|
|
}); } catch (_) {}
|
|
},
|
|
onResize: function () { this.onSkinTouchCancel(); this.skinWidth = 0; this.measureSkin(); },
|
|
clearPrivateProfile: function () {
|
|
this.identityPending = true;
|
|
this.setData({ birthText: '', birth: '', age: 0, genderText: '', regionText: '', showGuide: false, picker: '', identityChecking: true, identityError: '' });
|
|
my.redirectTo({ url: '/pages/login/login' });
|
|
},
|
|
onHide: function () {
|
|
this.visible = false; this.identitySeq = (this.identitySeq || 0) + 1;
|
|
this.onSkinTouchCancel();
|
|
if (api.user() && api.user().kind !== 'taobao_guest') { this.identityPending = true; this.setData({ identityChecking: true, identityError: '' }); }
|
|
},
|
|
onUnload: function () { this.onHide(); clearTimeout(this.toastTimer); },
|
|
|
|
// H5 .toast
|
|
toast: function (msg) {
|
|
var that = this;
|
|
this.setData({ toastText: msg, toastOn: true });
|
|
clearTimeout(this.toastTimer);
|
|
this.toastTimer = setTimeout(function () {
|
|
that.setData({ toastOn: false });
|
|
}, Math.max(1800, String(msg).length * 130));
|
|
},
|
|
|
|
onOpenBirth: function () {
|
|
// H5 的 mobile-select title 为「出生年月」/「所在地区」
|
|
this.setData({ picker: 'birth', pickerTitle: '出生年月', pickerValue: this.data.birthIndex.slice() });
|
|
},
|
|
onOpenGender: function () {
|
|
var index = this.data.genderRange.indexOf(this.data.genderText);
|
|
this.setData({ picker: 'gender', pickerTitle: '性别', pickerValue: [index < 0 ? 0 : index] });
|
|
},
|
|
onOpenRegion: function () {
|
|
var index = this.data.regionIndex.slice();
|
|
// A canceled draft may have changed the cities while the saved province stayed put.
|
|
this.setData({ picker: 'region', pickerTitle: '所在地区', pickerValue: index,
|
|
regionRange: [REGION_DATA.map(function (p) { return p[0]; }), REGION_DATA[index[0]][1]] });
|
|
},
|
|
onPickerChange: function (e) {
|
|
var value = e.detail.value;
|
|
if (this.data.picker === 'region' && value[0] !== this.data.pickerValue[0]) value[1] = 0;
|
|
var patch = { pickerValue: value };
|
|
if (this.data.picker === 'region') patch.regionRange = [REGION_DATA.map(function (p) { return p[0]; }), REGION_DATA[value[0]][1]];
|
|
this.setData(patch);
|
|
},
|
|
onPickerConfirm: function () {
|
|
var e = { detail: { value: this.data.pickerValue } };
|
|
if (this.data.picker === 'birth') this.onBirthChange(e);
|
|
else if (this.data.picker === 'gender') this.onGenderChange(e);
|
|
else if (this.data.picker === 'region') this.onRegionChange(e);
|
|
this.onPickerClose();
|
|
},
|
|
onPickerClose: function () { this.setData({ picker: '' }); },
|
|
|
|
/* ─── 出生年月 ─── */
|
|
onBirthChange: function (e) {
|
|
var idx = e.detail.value;
|
|
var yv = parseInt(YEARS[idx[0]], 10);
|
|
var mv = idx[1] + 1;
|
|
this.setData({
|
|
birthIndex: idx,
|
|
birthText: yv + '年' + mv + '月',
|
|
birth: yv + '-' + (mv < 10 ? '0' : '') + mv,
|
|
age: ageFromBirth(yv, mv)
|
|
});
|
|
},
|
|
|
|
/* ─── 性别 ─── */
|
|
onGenderChange: function (e) {
|
|
var value = e.detail.value, index = Array.isArray(value) ? value[0] : value;
|
|
if (index === 0 || index === 1) this.setData({ genderText: this.data.genderRange[index] });
|
|
},
|
|
|
|
/* ─── 地区:省份列滚动时联动城市列 ─── */
|
|
onRegionColumnChange: function (e) {
|
|
if (e.detail.column !== 0) return;
|
|
var cities = REGION_DATA[e.detail.value][1];
|
|
this.setData({ 'regionRange[1]': cities, regionIndex: [e.detail.value, 0] });
|
|
},
|
|
onRegionChange: function (e) {
|
|
var idx = e.detail.value;
|
|
var prov = REGION_DATA[idx[0]][0];
|
|
var city = REGION_DATA[idx[0]][1][idx[1]];
|
|
// 直辖市/港澳台只显示一级(与 H5 一致)
|
|
var text = !city || city === prov ? prov : prov + ' ' + city;
|
|
this.setData({ regionIndex: idx, regionText: text });
|
|
},
|
|
|
|
/* ─── 肤质轮播(H5 goSkin 的等价实现:轨道 translateX) ─── */
|
|
applySkin: function (index) {
|
|
var i = Math.max(0, Math.min(SKINS.length - 1, index));
|
|
this.skinGesture = null;
|
|
this.setData({ skinIndex: i, skinPercent: i * 100, skinDragOffset: 0, skinDragging: false });
|
|
},
|
|
onSkinPrev: function () { this.applySkin(this.data.skinIndex - 1); },
|
|
onSkinNext: function () { this.applySkin(this.data.skinIndex + 1); },
|
|
onSkinTouchStart: function (e) {
|
|
if (this.identityPending) return;
|
|
var info = typeof my.getSystemInfoSync === 'function' ? my.getSystemInfoSync() : {};
|
|
this.skinGesture = swipe.start(e, this.data.skinIndex, this.skinWidth || (info.windowWidth || 375) * 191 / 375, SKINS.length);
|
|
},
|
|
onSkinTouchMove: function (e) {
|
|
var value = swipe.move(this.skinGesture, e);
|
|
if (!value) { this.onSkinTouchCancel(); return; }
|
|
if (value.dragging) this.setData({ skinDragOffset: value.offset, skinDragging: true });
|
|
},
|
|
onSkinTouchEnd: function (e) { var value = swipe.end(this.skinGesture, e, false); if (value) this.applySkin(value.index); },
|
|
onSkinTouchCancel: function () {
|
|
this.skinGesture = null;
|
|
if (this.data.skinDragging || this.data.skinDragOffset) this.setData({ skinDragOffset: 0, skinDragging: false });
|
|
},
|
|
|
|
/* ─── 提交 → 拍照引导弹窗(H5 data-action="submit-profile") ─── */
|
|
onSubmit: function () {
|
|
if (this.identityPending) return;
|
|
var d = this.data;
|
|
if (!d.birth || !(d.age >= 1 && d.age <= 99)) {
|
|
this.toast('请选择出生年月');
|
|
return;
|
|
}
|
|
if (!d.genderText) {
|
|
this.toast('请选择性别');
|
|
return;
|
|
}
|
|
if (!d.regionText) {
|
|
this.toast('请选择所在地区');
|
|
return;
|
|
}
|
|
this.setData({ showGuide: true });
|
|
},
|
|
|
|
onCloseGuide: function () {
|
|
this.setData({ showGuide: false });
|
|
},
|
|
|
|
// H5 data-action="start-camera":档案入全局态,进入拍照页
|
|
onStartCamera: function () {
|
|
if (this.identityPending) return;
|
|
if (!api.user()) { my.redirectTo({ url: '/pages/login/login' }); return; }
|
|
var d = this.data;
|
|
getApp().globalData.profile = {
|
|
real_age: d.age,
|
|
gender: d.genderText,
|
|
region: d.regionText,
|
|
daily_skin_type: SKINS[d.skinIndex].name
|
|
};
|
|
if (api.user().kind !== 'taobao_guest') my.setStorageSync({ key: 'juzi.taobao.profile.' + api.user().id, data: {
|
|
birth: d.birth, birthIndex: d.birthIndex, birthText: d.birthText, genderText: d.genderText,
|
|
regionIndex: d.regionIndex, regionText: d.regionText, regionRange: d.regionRange, skinIndex: d.skinIndex
|
|
} });
|
|
this.setData({ showGuide: false });
|
|
my.navigateTo({ url: '/pages/camera/camera' });
|
|
},
|
|
|
|
noop: function () {}
|
|
}, typeof my === 'undefined' ? {} : my));
|