修正了 pages 名为拼音的问题
This commit is contained in:
@@ -1,680 +0,0 @@
|
||||
// pages/guanshizhongxin/guanshizhongxin.js
|
||||
import request from '../../utils/request.js';
|
||||
import popupService from '../../services/popupService.js';
|
||||
import { buildInviterPeerId } from '../../utils/im-user.js';
|
||||
import { resolveAvatarUrl } from '../../utils/avatar.js';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
// 图片路径对象(逻辑层拼接完整URL)
|
||||
imgUrls: {},
|
||||
|
||||
isGuanshi: false,
|
||||
isLoading: false,
|
||||
inviteCode: '',
|
||||
uid: '',
|
||||
nicheng: '',
|
||||
avatarUrl: '',
|
||||
|
||||
// 管事信息
|
||||
gszhstatus: '',
|
||||
yaoqingzongshu: 0,
|
||||
fenyongzonge: '0.00',
|
||||
fenyongtixian: '0.00',
|
||||
yichongzhiDashou: 0,
|
||||
zhuanhualv: 0,
|
||||
|
||||
// 称号列表
|
||||
chenghaoList: [],
|
||||
|
||||
// 邀请人(组长)缓存
|
||||
inviterCache: null,
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
let url = '/pages/dashouduan/dashouduan?registerType=guanshi';
|
||||
if (options.scene) {
|
||||
try {
|
||||
url += '&inviteCode=' + encodeURIComponent(decodeURIComponent(options.scene));
|
||||
} catch (e) {
|
||||
console.error('scene解码失败', e);
|
||||
}
|
||||
} else if (options.inviteCode) {
|
||||
url += '&inviteCode=' + encodeURIComponent(options.inviteCode);
|
||||
}
|
||||
wx.redirectTo({ url });
|
||||
return;
|
||||
// --- 以下保留供恢复参考,不再执行 ---
|
||||
// 拼接所有图片完整路径
|
||||
const app = getApp();
|
||||
const ossImageUrl = app.globalData.ossImageUrl || '';
|
||||
const imgBase = ossImageUrl + 'beijing/guanshiduan/';
|
||||
this.setData({
|
||||
imgUrls: {
|
||||
pageBg: imgBase + 'page-bg.jpg',
|
||||
topDecor: imgBase + 'top-decor.png',
|
||||
cardBg1: imgBase + 'card-bg1.png',
|
||||
cardBg2: imgBase + 'card-bg2.png',
|
||||
iconRefresh: imgBase + 'icon-refresh.png',
|
||||
iconCopy: imgBase + 'icon-copy.png',
|
||||
avatarDefault: ossImageUrl + 'avatar/default.jpg',
|
||||
iconInvite: imgBase + 'icon-invite.png',
|
||||
iconSub: imgBase + 'icon-sub.png',
|
||||
iconRecord: imgBase + 'icon-record.png',
|
||||
iconRank: imgBase + 'icon-rank.png',
|
||||
iconPoster: imgBase + 'icon-poster.png',
|
||||
iconWithdraw: imgBase + 'icon-withdraw.png',
|
||||
iconContact: imgBase + 'icon-contact.png',
|
||||
iconArrow: imgBase + 'icon-arrow.png',
|
||||
}
|
||||
});
|
||||
|
||||
// 处理扫码 scene
|
||||
if (options.scene) {
|
||||
try {
|
||||
const scene = decodeURIComponent(options.scene);
|
||||
options.inviteCode = scene;
|
||||
} catch (e) {
|
||||
console.error('scene解码失败', e);
|
||||
}
|
||||
}
|
||||
|
||||
this.checkGuanshiStatus();
|
||||
|
||||
const { inviteCode } = options || {};
|
||||
if (inviteCode) {
|
||||
this.setData({ inviteCode });
|
||||
setTimeout(() => {
|
||||
this.handleInviteCodeWithLoginCheck(inviteCode);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
if (!app.globalData.hasShownPopupOnColdStart) {
|
||||
app.globalData.hasShownPopupOnColdStart = true;
|
||||
setTimeout(() => {
|
||||
popupService.checkAndShow(this, 'guanshiduan');
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
|
||||
onReady() {
|
||||
if (this._isGuanshiPageActive()) {
|
||||
this.ensureGuanshiRoleAndTabBar();
|
||||
}
|
||||
},
|
||||
|
||||
onHide() {
|
||||
const popupComp = this.selectComponent('#popupNotice');
|
||||
if (popupComp && popupComp.cleanup) {
|
||||
popupComp.cleanup();
|
||||
}
|
||||
},
|
||||
|
||||
onShow() {
|
||||
const inviterCache = wx.getStorageSync('inviterCache') || null;
|
||||
this.setData({ inviterCache });
|
||||
|
||||
this.registerNotificationComponent();
|
||||
|
||||
if (this._isGuanshiPageActive()) {
|
||||
if (!this.data.isGuanshi) {
|
||||
this.setData({ isGuanshi: true });
|
||||
}
|
||||
this.ensureGuanshiRoleAndTabBar();
|
||||
setTimeout(() => {
|
||||
this.getGuanshiInfo();
|
||||
this.fetchChenghaoList();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const options = currentPage.options || {};
|
||||
if (options.inviteCode && !this._isGuanshiPageActive()) {
|
||||
setTimeout(() => {
|
||||
this.handleInviteCodeWithLoginCheck(options.inviteCode);
|
||||
}, 300);
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 全局通知注册 ==========
|
||||
registerNotificationComponent() {
|
||||
const app = getApp();
|
||||
const comp = this.selectComponent('#global-notification');
|
||||
if (comp && comp.showNotification) {
|
||||
app.globalData.globalNotification = {
|
||||
show: (data) => comp.showNotification(data),
|
||||
hide: () => comp.hideNotification()
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 称号列表(新接口,区分管事) ==========
|
||||
async fetchChenghaoList() {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/dengji/chenghao',
|
||||
method: 'POST',
|
||||
data: { role: 'guanshi' }
|
||||
});
|
||||
if (res && res.data.code === 0 && res.data.data) {
|
||||
this.setData({ chenghaoList: res.data.data.chenghao_list || [] });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取称号失败', e);
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 联系组长(新接口) ==========
|
||||
// 管事联系组长 —— 获取组长信息并跳转聊天
|
||||
// 管事联系组长
|
||||
async contactInviter() {
|
||||
wx.showLoading({ title: '获取组长信息...', mask: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/yonghu/guanshi_contact',
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
if (res && res.data.code === 200 && res.data.data) {
|
||||
const inviter = res.data.data;
|
||||
const ossImageUrl = getApp().globalData.ossImageUrl || '';
|
||||
const fullAvatar = inviter.touxiang
|
||||
? (inviter.touxiang.startsWith('http') ? inviter.touxiang : ossImageUrl + inviter.touxiang)
|
||||
: '';
|
||||
|
||||
// 缓存邀请人信息
|
||||
const cacheData = {
|
||||
uid: inviter.uid,
|
||||
nicheng: inviter.nicheng || '',
|
||||
avatar: fullAvatar
|
||||
};
|
||||
wx.setStorageSync('inviterCache', cacheData);
|
||||
this.setData({ inviterCache: cacheData });
|
||||
|
||||
// 联系邀请人:统一 Ds 前缀(管事/组长均走打手身份)
|
||||
const param = {
|
||||
toUserId: buildInviterPeerId(inviter.uid),
|
||||
toName: inviter.nicheng || '邀请人',
|
||||
toAvatar: fullAvatar
|
||||
};
|
||||
wx.navigateTo({
|
||||
url: '/pages/liaotian/liaotian?data=' + encodeURIComponent(JSON.stringify(param))
|
||||
});
|
||||
} else {
|
||||
wx.showToast({ title: '未绑定邀请人', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||||
} finally {
|
||||
wx.hideLoading();
|
||||
}
|
||||
},
|
||||
// ========== 管事状态辅助 ==========
|
||||
_isApiSuccess(body) {
|
||||
if (!body) return false;
|
||||
const code = Number(body.code);
|
||||
return code === 200 || code === 0;
|
||||
},
|
||||
|
||||
_getApiMsg(body) {
|
||||
if (!body) return '';
|
||||
return body.msg || body.message || '';
|
||||
},
|
||||
|
||||
_extractUserData(body) {
|
||||
if (!body) return {};
|
||||
if (body.data && typeof body.data === 'object' && !Array.isArray(body.data)) {
|
||||
return body.data;
|
||||
}
|
||||
const userData = { ...body };
|
||||
delete userData.code;
|
||||
delete userData.msg;
|
||||
delete userData.message;
|
||||
return userData;
|
||||
},
|
||||
|
||||
_isGuanshiStatusActive(status) {
|
||||
return Number(status) === 1;
|
||||
},
|
||||
|
||||
_isAlreadyGuanshiMsg(msg) {
|
||||
if (!msg || typeof msg !== 'string') return false;
|
||||
return msg.includes('已是管事') || msg.includes('已经是管事');
|
||||
},
|
||||
|
||||
_syncGuanshiCache() {
|
||||
const app = getApp();
|
||||
wx.setStorageSync('guanshistatus', 1);
|
||||
app.globalData.guanshistatus = 1;
|
||||
},
|
||||
|
||||
// 仅同步后端响应里「明确返回」的身份 status 字段(含 0),不臆测、不补打手
|
||||
_syncRoleStatuses(data) {
|
||||
if (!data || typeof data !== 'object') return;
|
||||
const app = getApp();
|
||||
const roleFields = ['dashoustatus', 'guanshistatus', 'shangjiastatus', 'zuzhangstatus', 'kaoheguanstatus'];
|
||||
roleFields.forEach(field => {
|
||||
if (Object.prototype.hasOwnProperty.call(data, field)) {
|
||||
const val = Number(data[field]);
|
||||
const normalized = Number.isNaN(val) ? 0 : val;
|
||||
wx.setStorageSync(field, normalized);
|
||||
app.globalData[field] = normalized;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 后端若返回打手详情字段则写入 globalData(与 dashoustatus 是否=1 无关)
|
||||
_syncDashouGlobalData(data) {
|
||||
const app = getApp();
|
||||
const map = {
|
||||
dashouNicheng: data.dashounicheng,
|
||||
zhanghaoStatus: data.zhanghaostatus,
|
||||
yongjin: data.yongjin,
|
||||
zonge: data.zonge,
|
||||
yajin: data.yajin,
|
||||
chenghao: data.chenghao,
|
||||
jinfen: data.jinfen,
|
||||
clumber: data.clumber,
|
||||
chengjiaoliang: data.chengjiaoliang,
|
||||
zaixianZhuangtai: data.zaixianzhuangtai,
|
||||
dashouzhuangtai: data.dashouzhuangtai,
|
||||
};
|
||||
Object.keys(map).forEach(key => {
|
||||
if (map[key] !== undefined) {
|
||||
app.globalData[key] = map[key];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_isGuanshiPageActive() {
|
||||
return this.data.isGuanshi || this._isGuanshiStatusActive(wx.getStorageSync('guanshistatus'));
|
||||
},
|
||||
|
||||
// 管事页必须切到 guanshi 角色,并强制刷新 TabBar(扫码落地页不在老板 Tab 列表里)
|
||||
ensureGuanshiRoleAndTabBar() {
|
||||
const app = getApp();
|
||||
if (app.setCurrentRole) {
|
||||
app.setCurrentRole('guanshi');
|
||||
} else {
|
||||
app.globalData.currentRole = 'guanshi';
|
||||
wx.setStorageSync('currentRole', 'guanshi');
|
||||
app.emitEvent('currentRoleChanged', { role: 'guanshi' });
|
||||
}
|
||||
this._refreshTabBar();
|
||||
},
|
||||
|
||||
_refreshTabBar() {
|
||||
const tryRefresh = () => {
|
||||
const tabBar = this.getTabBar && this.getTabBar();
|
||||
if (tabBar && tabBar.refresh) {
|
||||
tabBar.refresh();
|
||||
}
|
||||
};
|
||||
tryRefresh();
|
||||
[50, 150, 300, 500, 800].forEach((delay) => setTimeout(tryRefresh, delay));
|
||||
},
|
||||
|
||||
_applyRegisterSuccess(userData, toastMsg) {
|
||||
const app = getApp();
|
||||
const data = userData || {};
|
||||
if (data.token) wx.setStorageSync('token', data.token);
|
||||
if (data.token) app.globalData.token = data.token;
|
||||
|
||||
const profileFields = ['nicheng', 'uid', 'touxiang'];
|
||||
profileFields.forEach(field => {
|
||||
if (data[field] !== undefined && data[field] !== null) {
|
||||
wx.setStorageSync(field, data[field]);
|
||||
if (field === 'nicheng') {
|
||||
app.globalData.nicheng = data[field];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 身份列表完全以后端返回的 *status 字段为准(见 _syncRoleStatuses)
|
||||
this._syncRoleStatuses(data);
|
||||
// 仅在本页管事注册成功、但后端未带 guanshistatus 时兜底
|
||||
if (!Object.prototype.hasOwnProperty.call(data, 'guanshistatus') &&
|
||||
!this._isGuanshiStatusActive(wx.getStorageSync('guanshistatus'))) {
|
||||
this._syncGuanshiCache();
|
||||
}
|
||||
this._syncDashouGlobalData(data);
|
||||
|
||||
const groupFields = ['dashouqun', 'dashouqunid', 'guanshiqun', 'guanshiqunid'];
|
||||
groupFields.forEach(field => {
|
||||
if (data[field] !== undefined) {
|
||||
wx.setStorageSync(field, data[field]);
|
||||
app.globalData[field] = data[field];
|
||||
}
|
||||
});
|
||||
|
||||
const guanshiData = {
|
||||
gszhstatus: data.gszhstatus ?? '',
|
||||
yaoqingzongshu: data.yaoqingzongshu ?? 0,
|
||||
fenyongzonge: data.fenyongzonge ?? '0.00',
|
||||
fenyongtixian: data.fenyongtixian ?? '0.00',
|
||||
yichongzhiDashou: data.yichongzhiDashou ?? 0
|
||||
};
|
||||
if (!app.globalData.guanshi) app.globalData.guanshi = {};
|
||||
Object.assign(app.globalData.guanshi, guanshiData);
|
||||
|
||||
const zhuanhualv = guanshiData.yaoqingzongshu > 0
|
||||
? (guanshiData.yichongzhiDashou / guanshiData.yaoqingzongshu * 100).toFixed(1)
|
||||
: 0;
|
||||
|
||||
this.setData({
|
||||
isGuanshi: true,
|
||||
uid: data.uid || wx.getStorageSync('uid') || '',
|
||||
nicheng: data.nicheng || app.globalData.nicheng || wx.getStorageSync('nicheng') || '',
|
||||
...guanshiData,
|
||||
zhuanhualv,
|
||||
isLoading: false
|
||||
});
|
||||
this.loadUserInfo();
|
||||
this.switchToGuanshiRole();
|
||||
wx.hideLoading();
|
||||
if (toastMsg) {
|
||||
wx.showToast({ title: toastMsg, icon: 'success', duration: 2000 });
|
||||
}
|
||||
},
|
||||
|
||||
_enterRegisteredGuanshiState(toastMsg, userData) {
|
||||
if (userData && typeof userData === 'object') {
|
||||
this._applyRegisterSuccess(userData, toastMsg);
|
||||
return;
|
||||
}
|
||||
this._syncGuanshiCache();
|
||||
this.setData({ isGuanshi: true, isLoading: false });
|
||||
this.loadUserInfo();
|
||||
this.switchToGuanshiRole();
|
||||
this.getGuanshiInfo(false);
|
||||
this.fetchChenghaoList();
|
||||
wx.hideLoading();
|
||||
if (toastMsg) {
|
||||
wx.showToast({ title: toastMsg, icon: 'success', duration: 2000 });
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 邀请码处理 ==========
|
||||
handleInviteCodeWithLoginCheck(inviteCode) {
|
||||
const token = wx.getStorageSync('token');
|
||||
const uid = wx.getStorageSync('uid');
|
||||
if (!token || !uid) {
|
||||
this.loginAndRegisterWithInviteCode(inviteCode);
|
||||
} else {
|
||||
if (!this.data.isGuanshi) {
|
||||
wx.showLoading({ title: '自动注册中...', mask: true });
|
||||
this.callRegisterApi(inviteCode);
|
||||
} else {
|
||||
this._enterRegisteredGuanshiState('您已是管事');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
loginAndRegisterWithInviteCode(inviteCode) {
|
||||
const that = this;
|
||||
wx.showLoading({ title: '登录注册中...', mask: true });
|
||||
wx.login({
|
||||
success: (loginRes) => {
|
||||
if (loginRes.code) {
|
||||
that.callLoginRegisterApi(loginRes.code, inviteCode);
|
||||
} else {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '微信登录失败', icon: 'none' });
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
wx.hideLoading();
|
||||
wx.reLaunch({ url: '/pages/gerenzhongxin/gerenzhongxin' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
callLoginRegisterApi(code, inviteCode) {
|
||||
const that = this;
|
||||
const app = getApp();
|
||||
const apiBaseUrl = app.globalData.apiBaseUrl;
|
||||
if (!apiBaseUrl) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '服务器配置错误', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
wx.request({
|
||||
url: apiBaseUrl + '/yonghu/zuzhangyqmzc',
|
||||
method: 'POST',
|
||||
data: { code: code, inviteCode: inviteCode },
|
||||
header: { 'content-type': 'application/json' },
|
||||
success: (res) => {
|
||||
const body = res.data || {};
|
||||
if (res.statusCode === 200 && that._isApiSuccess(body)) {
|
||||
const userData = that._extractUserData(body);
|
||||
const toastMsg = that._isAlreadyGuanshiMsg(that._getApiMsg(body))
|
||||
? that._getApiMsg(body)
|
||||
: '注册成功!';
|
||||
that._applyRegisterSuccess(userData, toastMsg);
|
||||
} else if (res.statusCode === 200 && that._isAlreadyGuanshiMsg(that._getApiMsg(body))) {
|
||||
that._enterRegisteredGuanshiState(that._getApiMsg(body) || '您已是管事', that._extractUserData(body));
|
||||
} else {
|
||||
wx.hideLoading();
|
||||
that.setData({ isLoading: false });
|
||||
wx.showToast({ title: that._getApiMsg(body) || '注册失败', icon: 'none' });
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '网络请求失败', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async callRegisterApi(inviteCode) {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/yonghu/guanshizhuce',
|
||||
method: 'POST',
|
||||
data: { inviteCode }
|
||||
});
|
||||
const body = res?.data || {};
|
||||
if (res && this._isApiSuccess(body)) {
|
||||
const userData = this._extractUserData(body);
|
||||
const toastMsg = this._isAlreadyGuanshiMsg(this._getApiMsg(body))
|
||||
? this._getApiMsg(body)
|
||||
: '注册成功!';
|
||||
this._applyRegisterSuccess(userData, toastMsg);
|
||||
} else if (this._isAlreadyGuanshiMsg(this._getApiMsg(body))) {
|
||||
this._enterRegisteredGuanshiState(this._getApiMsg(body) || '您已是管事', this._extractUserData(body));
|
||||
} else {
|
||||
wx.hideLoading();
|
||||
this.setData({ isLoading: false });
|
||||
wx.showToast({ title: this._getApiMsg(body) || '注册失败', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('注册失败:', e);
|
||||
wx.hideLoading();
|
||||
this.setData({ isLoading: false });
|
||||
wx.showToast({ title: e.message || '注册失败', icon: 'error' });
|
||||
}
|
||||
},
|
||||
|
||||
switchToGuanshiRole() {
|
||||
const app = getApp();
|
||||
this.ensureGuanshiRoleAndTabBar();
|
||||
if (app.switchRoleAndReconnect) {
|
||||
app.switchRoleAndReconnect('dashou').catch(() => {});
|
||||
} else if (app.connectForCurrentRole) {
|
||||
app.connectForCurrentRole();
|
||||
} else if (app.ensureConnection) {
|
||||
app.ensureConnection();
|
||||
}
|
||||
},
|
||||
|
||||
checkGuanshiStatus() {
|
||||
try {
|
||||
const status = wx.getStorageSync('guanshistatus');
|
||||
if (this._isGuanshiStatusActive(status)) {
|
||||
this.setData({ isGuanshi: true });
|
||||
this.loadUserInfo();
|
||||
this.checkGlobalData();
|
||||
this.ensureGuanshiRoleAndTabBar();
|
||||
} else {
|
||||
this.setData({ isGuanshi: false });
|
||||
}
|
||||
} catch (e) {
|
||||
this.setData({ isGuanshi: false });
|
||||
}
|
||||
},
|
||||
|
||||
loadUserInfo() {
|
||||
const app = getApp();
|
||||
const globalData = app.globalData || {};
|
||||
const touxiang = wx.getStorageSync('touxiang');
|
||||
const ossImageUrl = globalData.ossImageUrl || '';
|
||||
const morentouxiang = 'avatar/default.jpg';
|
||||
let avatarUrl = '';
|
||||
if (touxiang) {
|
||||
avatarUrl = ossImageUrl + (touxiang.startsWith('/') ? touxiang : '/' + touxiang);
|
||||
} else {
|
||||
avatarUrl = ossImageUrl + (morentouxiang.startsWith('/') ? morentouxiang : '/' + morentouxiang);
|
||||
}
|
||||
this.setData({
|
||||
avatarUrl,
|
||||
uid: wx.getStorageSync('uid') || '',
|
||||
nicheng: globalData.nicheng || wx.getStorageSync('nicheng') || ''
|
||||
});
|
||||
},
|
||||
|
||||
checkGlobalData() {
|
||||
const app = getApp();
|
||||
const gd = app.globalData.guanshi || {};
|
||||
const needRefresh = !gd.yaoqingzongshu && !gd.fenyongzonge && !gd.fenyongtixian;
|
||||
if (needRefresh) {
|
||||
this.getGuanshiInfo();
|
||||
} else {
|
||||
this.setDataFromGlobalData();
|
||||
}
|
||||
},
|
||||
|
||||
setDataFromGlobalData() {
|
||||
const gd = getApp().globalData.guanshi || {};
|
||||
const zhuanhualv = gd.yaoqingzongshu > 0
|
||||
? (gd.yichongzhiDashou / gd.yaoqingzongshu * 100).toFixed(1)
|
||||
: 0;
|
||||
this.setData({
|
||||
gszhstatus: gd.gszhstatus || '',
|
||||
yaoqingzongshu: gd.yaoqingzongshu || 0,
|
||||
fenyongzonge: gd.fenyongzonge || '0.00',
|
||||
fenyongtixian: gd.fenyongtixian || '0.00',
|
||||
yichongzhiDashou: gd.yichongzhiDashou || 0,
|
||||
zhuanhualv,
|
||||
isLoading: false
|
||||
});
|
||||
},
|
||||
|
||||
async getGuanshiInfo(showToast = true) {
|
||||
this.setData({ isLoading: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/yonghu/guanshixinxi',
|
||||
method: 'POST'
|
||||
});
|
||||
if (res && this._isApiSuccess(res.data)) {
|
||||
const data = this._extractUserData(res.data);
|
||||
const app = getApp();
|
||||
this._syncGuanshiCache();
|
||||
if (!app.globalData.guanshi) app.globalData.guanshi = {};
|
||||
const updateData = {
|
||||
gszhstatus: data.gszhstatus || '',
|
||||
yaoqingzongshu: data.yaoqingzongshu || 0,
|
||||
fenyongzonge: data.fenyongzonge || '0.00',
|
||||
fenyongtixian: data.fenyongtixian || '0.00',
|
||||
yichongzhiDashou: data.yichongzhiDashou || 0
|
||||
};
|
||||
Object.assign(app.globalData.guanshi, updateData);
|
||||
const zhuanhualv = updateData.yaoqingzongshu > 0
|
||||
? (updateData.yichongzhiDashou / updateData.yaoqingzongshu * 100).toFixed(1)
|
||||
: 0;
|
||||
this.setData({
|
||||
isGuanshi: true,
|
||||
...updateData,
|
||||
zhuanhualv,
|
||||
isLoading: false
|
||||
});
|
||||
if (showToast) {
|
||||
wx.showToast({ title: '信息已更新', icon: 'success', duration: 1500 });
|
||||
}
|
||||
} else {
|
||||
this.setData({ isLoading: false });
|
||||
if (showToast) {
|
||||
wx.showToast({ title: this._getApiMsg(res?.data) || '获取失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.setData({ isLoading: false });
|
||||
if (showToast) {
|
||||
wx.showToast({ title: e.message || '获取失败', icon: 'error' });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
refreshGuanshiInfo() {
|
||||
this.getGuanshiInfo();
|
||||
this.fetchChenghaoList();
|
||||
},
|
||||
|
||||
onInviteCodeInput(e) {
|
||||
this.setData({ inviteCode: e.detail.value.trim() });
|
||||
},
|
||||
|
||||
async onRegister() {
|
||||
const { inviteCode } = this.data;
|
||||
if (!inviteCode) {
|
||||
wx.showToast({ title: '请输入邀请码', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (inviteCode.length > 100) {
|
||||
wx.showToast({ title: '邀请码过长', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
this.setData({ isLoading: true });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/yonghu/guanshizhuce',
|
||||
method: 'POST',
|
||||
data: { inviteCode }
|
||||
});
|
||||
const body = res?.data || {};
|
||||
if (res && this._isApiSuccess(body)) {
|
||||
const userData = this._extractUserData(body);
|
||||
const toastMsg = this._isAlreadyGuanshiMsg(this._getApiMsg(body))
|
||||
? this._getApiMsg(body)
|
||||
: '注册成功!';
|
||||
this._applyRegisterSuccess(userData, toastMsg);
|
||||
} else if (this._isAlreadyGuanshiMsg(this._getApiMsg(body))) {
|
||||
this._enterRegisteredGuanshiState(this._getApiMsg(body) || '您已是管事', this._extractUserData(body));
|
||||
} else {
|
||||
this.setData({ isLoading: false });
|
||||
wx.showToast({ title: this._getApiMsg(body) || '注册失败', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
this.setData({ isLoading: false });
|
||||
wx.showToast({ title: e.message || '注册失败', icon: 'error' });
|
||||
}
|
||||
},
|
||||
|
||||
copyUid() {
|
||||
const { uid } = this.data;
|
||||
if (!uid) return;
|
||||
wx.setClipboardData({
|
||||
data: uid,
|
||||
success: () => wx.showToast({ title: '已复制', icon: 'success' })
|
||||
});
|
||||
},
|
||||
|
||||
// ========== 页面跳转 ==========
|
||||
goToWithdraw() { wx.navigateTo({ url: '/pages/tixian/tixian' }); },
|
||||
goToInviteUser() { wx.navigateTo({ url: '/pages/yaoqingdashou/yaoqingdashou' }); },
|
||||
goToMySubordinate() { wx.navigateTo({ url: '/pages/wodedashou/wodedashou' }); },
|
||||
goToRechargeRecord() { wx.navigateTo({ url: '/pages/czjilu/czjilu' }); },
|
||||
goToGuanshiRanking() { wx.navigateTo({ url: '/pages/guanshipaihang/guanshipaihang' }); },
|
||||
goToPromoPoster() { wx.navigateTo({ url: '/pages/haibao/haibao' }); }
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"global-notification": "/components/global-notification/global-notification",
|
||||
"chenghao-tag": "/components/chenghao-tag/chenghao-tag",
|
||||
"custom-tab-bar": "/custom-tab-bar/index"
|
||||
},
|
||||
"navigationBarBackgroundColor": "#f0f4f8",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "管事中心",
|
||||
"backgroundColor": "#f0f4f8",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
<!--pages/guanshizhongxin/guanshizhongxin.wxml-->
|
||||
<image class="page-bg" src="{{imgUrls.pageBg}}" mode="aspectFill" />
|
||||
|
||||
<!-- 未注册状态 -->
|
||||
<view class="unreg-area" wx:if="{{!isGuanshi}}">
|
||||
<view class="unreg-card">
|
||||
<text class="unreg-title">✦ 管事认证 ✦</text>
|
||||
<input class="unreg-input" type="text" placeholder="输入邀请码" maxlength="100" value="{{inviteCode}}" bindinput="onInviteCodeInput" placeholder-class="ph" />
|
||||
<view class="unreg-btn" bindtap="onRegister">
|
||||
<text class="unreg-btn-text">立即注册</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 已注册状态 -->
|
||||
<view class="main-body" wx:else>
|
||||
<!-- 刷新按钮 -->
|
||||
<view class="refresh-btn" bindtap="refreshGuanshiInfo">
|
||||
<image class="refresh-icon" src="{{imgUrls.iconRefresh}}" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
<!-- 用户信息卡片 -->
|
||||
<view class="user-card">
|
||||
<image class="user-avatar" src="{{avatarUrl}}" mode="aspectFill" bindtap="previewAvatar" />
|
||||
<view class="user-info">
|
||||
<text class="user-name">{{nicheng || '管事'}}</text>
|
||||
<view class="uid-row" bindtap="copyUid">
|
||||
<text class="uid-text">UID: {{uid || '--'}}</text>
|
||||
<image class="copy-icon" src="{{imgUrls.iconCopy}}" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 称号滑动条 -->
|
||||
<view class="badge-zone" wx:if="{{chenghaoList.length > 0}}">
|
||||
<scroll-view scroll-x class="badge-scroll">
|
||||
<chenghao-tag wx:for="{{chenghaoList}}" wx:key="index" mingcheng="{{item.mingcheng}}" texiaoJson="{{item.texiao_json}}" />
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 资产卡片 -->
|
||||
<view class="asset-card">
|
||||
<text class="asset-title">可提现分成</text>
|
||||
<view class="asset-amount">
|
||||
<text class="amount-number">{{fenyongtixian}}</text>
|
||||
<text class="amount-unit">元</text>
|
||||
</view>
|
||||
<!-- 四列数据:邀请总数、已充值、分成总额、有效率 -->
|
||||
<view class="four-stats">
|
||||
<view class="stat-item">
|
||||
<text class="stat-val">{{yaoqingzongshu}}</text>
|
||||
<text class="stat-label">邀请总数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-val">{{yichongzhiDashou}}</text>
|
||||
<text class="stat-label">已充值</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-val">{{fenyongzonge}}</text>
|
||||
<text class="stat-label">分成总额</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-val">{{zhuanhualv}}%</text>
|
||||
<text class="stat-label">有效率</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提现按钮 -->
|
||||
<view class="withdraw-btn" bindtap="goToWithdraw">
|
||||
<image class="withdraw-icon" src="{{imgUrls.iconWithdraw}}" mode="aspectFit" />
|
||||
<text class="withdraw-text">提现</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能入口区:三列布局,6项已补全 -->
|
||||
<view class="func-grid">
|
||||
<view class="func-item" bindtap="goToInviteUser">
|
||||
<image class="func-icon" src="{{imgUrls.iconInvite}}" mode="aspectFit" />
|
||||
<text class="func-label">邀请用户</text>
|
||||
</view>
|
||||
<view class="func-item" bindtap="goToMySubordinate">
|
||||
<image class="func-icon" src="{{imgUrls.iconSub}}" mode="aspectFit" />
|
||||
<text class="func-label">我的下级</text>
|
||||
</view>
|
||||
<view class="func-item" bindtap="goToRechargeRecord">
|
||||
<image class="func-icon" src="{{imgUrls.iconRecord}}" mode="aspectFit" />
|
||||
<text class="func-label">会员记录</text>
|
||||
</view>
|
||||
<view class="func-item" bindtap="goToGuanshiRanking">
|
||||
<image class="func-icon" src="{{imgUrls.iconRank}}" mode="aspectFit" />
|
||||
<text class="func-label">管事排行</text>
|
||||
</view>
|
||||
<view class="func-item" bindtap="goToPromoPoster">
|
||||
<image class="func-icon" src="{{imgUrls.iconPoster}}" mode="aspectFit" />
|
||||
<text class="func-label">推广海报</text>
|
||||
</view>
|
||||
<view class="func-item" bindtap="contactInviter">
|
||||
<image class="func-icon" src="{{imgUrls.iconContact}}" mode="aspectFit" />
|
||||
<text class="func-label">联系组长</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 原有的联系组长卡片 -->
|
||||
<view class="contact-card" bindtap="contactInviter">
|
||||
<view class="contact-left">
|
||||
<image class="contact-avatar" src="{{inviterCache.avatar || imgUrls.avatarDefault}}" mode="aspectFill" />
|
||||
<view class="contact-info">
|
||||
<text class="contact-name">{{inviterCache.nicheng || '联系组长'}}</text>
|
||||
<text class="contact-uid" wx:if="{{inviterCache && inviterCache.uid}}">ID: {{inviterCache.uid}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<image class="contact-arrow" src="{{imgUrls.iconArrow}}" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载遮罩 -->
|
||||
<view class="loading-mask" wx:if="{{isLoading}}">
|
||||
<view class="loading-spinner"></view>
|
||||
</view>
|
||||
|
||||
<global-notification id="global-notification" />
|
||||
<custom-tab-bar />
|
||||
<popup-notice id="popupNotice" />
|
||||
@@ -1,367 +0,0 @@
|
||||
/* ========== 全局背景 ========== */
|
||||
page {
|
||||
background: #F8FAFE;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
/* 背景图清晰可见 */
|
||||
.page-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.4;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* ========== 未注册区域 ========== */
|
||||
.unreg-area {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
padding: 0 50rpx;
|
||||
}
|
||||
|
||||
.unreg-card {
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
backdrop-filter: blur(25rpx);
|
||||
-webkit-backdrop-filter: blur(25rpx);
|
||||
border-radius: 48rpx;
|
||||
padding: 60rpx 50rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 20rpx 50rpx rgba(0,0,0,0.06);
|
||||
border: 1rpx solid rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
.unreg-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #1A1A1A;
|
||||
display: block;
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.unreg-input {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 48rpx;
|
||||
padding: 0 40rpx;
|
||||
font-size: 30rpx;
|
||||
color: #1A1A1A;
|
||||
margin-bottom: 40rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.03);
|
||||
}
|
||||
|
||||
.ph {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.unreg-btn {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
background: rgba(255,255,255,0.6);
|
||||
backdrop-filter: blur(15rpx);
|
||||
border-radius: 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx solid rgba(0,0,0,0.08);
|
||||
box-shadow: 0 12rpx 30rpx rgba(0,0,0,0.05);
|
||||
}
|
||||
.unreg-btn:active { opacity: 0.8; }
|
||||
.unreg-btn-text {
|
||||
color: #1A1A1A;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ========== 已注册主区域 ========== */
|
||||
.main-body {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 0 30rpx 40rpx;
|
||||
}
|
||||
|
||||
/* 刷新按钮 */
|
||||
.refresh-btn {
|
||||
position: absolute;
|
||||
top: 40rpx;
|
||||
right: 40rpx;
|
||||
width: 68rpx;
|
||||
height: 68rpx;
|
||||
background: rgba(255,255,255,0.75);
|
||||
backdrop-filter: blur(12rpx);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 20;
|
||||
border: 1rpx solid rgba(255,255,255,0.6);
|
||||
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
.refresh-icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
|
||||
/* 用户卡片 */
|
||||
.user-card {
|
||||
margin-top: 60rpx;
|
||||
margin-bottom: 30rpx;
|
||||
background: rgba(255,255,255,0.7);
|
||||
backdrop-filter: blur(20rpx);
|
||||
-webkit-backdrop-filter: blur(20rpx);
|
||||
border-radius: 36rpx;
|
||||
padding: 28rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1rpx solid rgba(255,255,255,0.5);
|
||||
box-shadow: 0 12rpx 35rpx rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
border: 3rpx solid #FFFFFF;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 38rpx;
|
||||
font-weight: 700;
|
||||
color: #1A1A1A;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.uid-row {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: rgba(0,0,0,0.03);
|
||||
border-radius: 20rpx;
|
||||
padding: 6rpx 18rpx;
|
||||
}
|
||||
|
||||
.uid-text {
|
||||
font-size: 26rpx;
|
||||
color: #1A1A1A;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
|
||||
/* 称号区域 */
|
||||
.badge-zone {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
.badge-scroll {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 资产卡片(纯玻璃质感) */
|
||||
.asset-card {
|
||||
background: rgba(255,255,255,0.7);
|
||||
backdrop-filter: blur(20rpx);
|
||||
-webkit-backdrop-filter: blur(20rpx);
|
||||
border-radius: 36rpx;
|
||||
padding: 28rpx 30rpx;
|
||||
margin-bottom: 28rpx;
|
||||
border: 1rpx solid rgba(255,255,255,0.5);
|
||||
box-shadow: 0 12rpx 35rpx rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.asset-title {
|
||||
font-size: 26rpx;
|
||||
color: #1A1A1A;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.asset-amount {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin: 10rpx 0 22rpx;
|
||||
}
|
||||
|
||||
.amount-number {
|
||||
font-size: 74rpx;
|
||||
font-weight: 800;
|
||||
color: #1A1A1A;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.amount-unit {
|
||||
font-size: 32rpx;
|
||||
color: #1A1A1A;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 四列数据统计 */
|
||||
.four-stats {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding: 20rpx 0;
|
||||
border-top: 1rpx solid rgba(0,0,0,0.06);
|
||||
border-bottom: 1rpx solid rgba(0,0,0,0.06);
|
||||
margin-bottom: 22rpx;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-val {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #1A1A1A;
|
||||
display: block;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 20rpx;
|
||||
color: #1A1A1A;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 提现按钮 */
|
||||
.withdraw-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255,255,255,0.55);
|
||||
backdrop-filter: blur(12rpx);
|
||||
border-radius: 48rpx;
|
||||
padding: 16rpx 0;
|
||||
border: 2rpx solid rgba(0,0,0,0.06);
|
||||
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.withdraw-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.withdraw-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
/* 功能入口三列布局 */
|
||||
.func-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.func-item {
|
||||
width: 31%;
|
||||
aspect-ratio: 1 / 1;
|
||||
background: rgba(255,255,255,0.7);
|
||||
backdrop-filter: blur(16rpx);
|
||||
-webkit-backdrop-filter: blur(16rpx);
|
||||
border-radius: 28rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20rpx;
|
||||
border: 1rpx solid rgba(255,255,255,0.5);
|
||||
box-shadow: 0 8rpx 22rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.func-icon {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.func-label {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #1A1A1A;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 联系组长卡片(底部横条) */
|
||||
.contact-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: rgba(255,255,255,0.7);
|
||||
backdrop-filter: blur(20rpx);
|
||||
-webkit-backdrop-filter: blur(20rpx);
|
||||
border-radius: 36rpx;
|
||||
padding: 20rpx 30rpx;
|
||||
margin-bottom: 40rpx;
|
||||
border: 1rpx solid rgba(255,255,255,0.5);
|
||||
box-shadow: 0 10rpx 25rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.contact-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.contact-avatar {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 18rpx;
|
||||
border: 2rpx solid #FFFFFF;
|
||||
}
|
||||
|
||||
.contact-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
.contact-uid {
|
||||
font-size: 22rpx;
|
||||
color: #1A1A1A;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.contact-arrow {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
|
||||
/* 加载遮罩 */
|
||||
.loading-mask {
|
||||
position: fixed;
|
||||
top:0; left:0; right:0; bottom:0;
|
||||
background: rgba(255,255,255,0.85);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
.loading-spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 4rpx solid rgba(0,0,0,0.1);
|
||||
border-top-color: #1A1A1A;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
Reference in New Issue
Block a user