diff --git a/apps/profile/ProfileStat.js b/apps/profile/ProfileStat.js index 2b8779dd..93611956 100644 --- a/apps/profile/ProfileStat.js +++ b/apps/profile/ProfileStat.js @@ -51,10 +51,20 @@ export async function profileStat (e) { level: player.level } + let info = player.getInfo() + info.stats = info.stats || {} + info.statMap = { + achievement: '成就', + wayPoint: '锚点', + avatar: '角色', + avatar5: '五星角色', + goldCount: '金卡总数' + } + return await Common.render(isAvatarList ? 'character/avatar-list' : 'character/profile-stat', { save_id: uid, uid, - info: player.getInfo(), + info, updateTime: player.getUpdateTime(), isSelfCookie: e.isSelfCookie, talentLvMap: '0,1,1,1,2,2,3,3,3,4,5'.split(','), diff --git a/apps/stat.js b/apps/stat.js index 39fc1f2a..cabe7b03 100644 --- a/apps/stat.js +++ b/apps/stat.js @@ -210,8 +210,8 @@ async function abyssTeam (e) { let data = {} let noAvatar = {} lodash.forEach(avatarData, (avatar) => { - let t = avatar.talent - avatarRet[avatar.id] = Math.min(avatar.level, avatar.weapon?.level || 1) * 100 + Math.max(t.a?.original, t.e?.original, t.q?.original) * 1000 + let t = avatar.originalTalent + avatarRet[avatar.id] = Math.min(avatar.level, avatar.weapon?.level || 1) * 100 + Math.max(t?.a, t?.e, t?.q) * 1000 }) let getTeamCfg = (str) => { diff --git a/models/Player.js b/models/Player.js index 8c0fc3b4..48182fdb 100644 --- a/models/Player.js +++ b/models/Player.js @@ -173,48 +173,25 @@ export default class Player extends Base { } getInfo () { - let ret = { - ...(this.info || {}), - statMap: { - achievement: '成就数', - commonChest: '普通宝箱', - exquisiteChest: '精致宝箱', - preciousChest: '珍贵宝箱', - luxuriousChest: '豪华宝箱' - } - } - if (ret?.stats?.activeDay) { - let num = ret?.stats?.activeDay - let year = Math.floor(num / 365) - let month = Math.floor((num % 365) / 30.41) - let day = Math.floor((num % 365) % 30.41) - let msg = '' - if (year > 0) { - msg += year + '年' - } - if (month > 0) { - msg += month + '个月' - } - if (day > 0) { - msg += day + '天' - } - ret.activeDay = msg - } - lodash.forEach(ret) - return ret + return MysAvatar.getInfo(this) } // 更新面板 - async refreshProfile (force = true) { + async refreshProfile (force = 1) { return await Profile.refreshProfile(this, force) } // 更新米游社数据 - async refreshMysDetail (force = false) { + /** + * 更新米游社数据 + * @param force: 0:不强制,长超时时间 1:短超时时间 2:无视缓存,强制刷新 + * @returns {Promise} + */ + async refreshMysDetail (force = 0) { return MysAvatar.refreshMysDetail(this, force) } - async refreshMysInfo (force = false) { + async refreshMysInfo (force = 0) { return await MysAvatar.refreshMysInfo(this, force) } @@ -224,7 +201,7 @@ export default class Player extends Base { } // 使用MysApi刷新指定角色的天赋信息 - async refreshTalent (ids = '', force = false) { + async refreshTalent (ids = '', force = 0) { return await MysAvatar.refreshTalent(this, ids, force) } @@ -236,11 +213,11 @@ export default class Player extends Base { async refreshAndGetAvatarData (cfg) { // 更新角色信息 - await this.refreshMysDetail(cfg.force) + await this.refreshMysDetail(cfg.force || 0) // 更新天赋信息 if (cfg.refreshTalent !== false) { - await this.refreshTalent(cfg.ids, cfg.force) + await this.refreshTalent(cfg.ids, cfg.force || 0) } let rank = false diff --git a/models/player-lib/MysAvatar.js b/models/player-lib/MysAvatar.js index 24b01136..0c970eb4 100644 --- a/models/player-lib/MysAvatar.js +++ b/models/player-lib/MysAvatar.js @@ -3,6 +3,17 @@ import { Common, Data } from '../../components/index.js' import moment from 'moment' const MysAvatar = { + + needRefresh (time, force = 0, forceMap = {}) { + if (!time) { + return true + } + let duration = new Date() * 1 - time * 1 + if (isNaN(duration) || duration < 0) { + return true + } + return duration > (forceMap[force] || 60) * 60 * 1000 + }, /** * 更新米游社角色信息 * @param player @@ -10,13 +21,12 @@ const MysAvatar = { * @param force * @returns {Promise} */ - async refreshMysDetail (player, force = false) { + async refreshMysDetail (player, force = 0) { let mys = player?.e?._mys if (!mys) { return false } - // 不必要更新 - if ((new Date() * 1 - player._mys < 10 * 60 * 1000) && !force) { + if (!MysAvatar.needRefresh(player._mys, force, { 0: 60, 1: 2, 2: 0 })) { return false } let charData = await mys.getCharacter() @@ -32,12 +42,12 @@ const MysAvatar = { * @param force * @returns {Promise} */ - async refreshMysInfo (player, force = false) { + async refreshMysInfo (player, force = 0) { let mys = player?.e?._mys if (!mys) { return false } // 不必要更新 - if (player._info && (new Date() * 1 - player._info < 10 * 60 * 1000) && !force) { + if (!MysAvatar.needRefresh(player._info, force, { 0: 60, 1: 2, 2: 0 })) { return false } let infoData = await mys.getIndex() @@ -130,9 +140,10 @@ const MysAvatar = { * 获取当前角色需要更新天赋的角色ID * @param player * @param ids 角色列表,若传入则查询指定角色列表,不传入查询全部 + * @param force * @returns {*[]} */ - getNeedRefreshIds (player, ids) { + getNeedRefreshIds (player, ids, force = 0) { let ret = [] if (!ids) { ids = lodash.keys(player._avatars) @@ -141,7 +152,7 @@ const MysAvatar = { } lodash.forEach(ids, (id) => { let avatar = player.getAvatar(id) - if (avatar.needRefreshTalent) { + if (!avatar.hasTalent || MysAvatar.needRefresh(avatar._talent, force, { 0: 60 * 24, 1: 60, 2: 0 })) { ret.push(avatar.id) } }) @@ -155,13 +166,13 @@ const MysAvatar = { * @param force * @returns {Promise} */ - async refreshTalent (player, ids, force) { + async refreshTalent (player, ids, force = 0) { let e = player?.e let mys = e?._mys if (!e || !mys) { return false } - let needReqIds = MysAvatar.getNeedRefreshIds(player, ids) + let needReqIds = MysAvatar.getNeedRefreshIds(player, ids, force) if (needReqIds.length > 0) { if (needReqIds.length > 8) { e && e.reply('正在获取角色信息,请稍候...') @@ -221,6 +232,56 @@ const MysAvatar = { getDate (time) { return time ? moment(new Date(time)).format('MM-DD HH:mm') : '' + }, + + getInfo (player) { + let ret = { + ...(player.info || {}), + chestMap: [ + { key: 'commonChest', title: '普通宝箱', max: 2521 }, + { key: 'exquisiteChest', title: '精致宝箱', max: 1585 }, + { key: 'preciousChest', title: '珍贵宝箱', max: 482 }, + { key: 'luxuriousChest', title: '豪华宝箱', max: 184 }, + { key: 'magicChest', title: '奇馈宝箱', max: 140 } + ] + } + let stats = ret.stats || {} + if (stats?.activeDay) { + let num = stats?.activeDay + let year = Math.floor(num / 365) + let month = Math.floor((num % 365) / 30.41) + let day = Math.floor((num % 365) % 30.41) + let msg = '' + if (year > 0) { + msg += year + '年' + } + if (month > 0) { + msg += month + '个月' + } + if (day > 0) { + msg += day + '天' + } + ret.activeDay = msg + } + let avatarCount = 0 + let avatar5Count = 0 + let goldCount = 0 + player.forEachAvatar((avatar) => { + avatarCount++ + if (avatar.star === 5) { + avatar5Count++ + goldCount += (avatar.cons || 0) + 1 + } + let w = avatar.weapon + if (w && w.star === 5) { + goldCount += w.affix * 1 + } + }) + stats.avatar = Math.max(stats.avatar, avatarCount) + stats.goldCount = goldCount + stats.avatar5 = avatar5Count + ret.stats = stats + return ret } } export default MysAvatar diff --git a/models/player-lib/Profile.js b/models/player-lib/Profile.js index 80cb8297..6d10ee00 100644 --- a/models/player-lib/Profile.js +++ b/models/player-lib/Profile.js @@ -34,7 +34,7 @@ const Profile = { * @param force * @returns {Promise} */ - async refreshProfile (player, force = true) { + async refreshProfile (player, force = 1) { player._update = [] let { uid, e } = player if (uid.toString().length !== 9 || !e) { diff --git a/resources/character/avatar-list.css b/resources/character/avatar-list.css index 439c80b2..5a69507a 100644 --- a/resources/character/avatar-list.css +++ b/resources/character/avatar-list.css @@ -5,7 +5,7 @@ .head-box { margin-top: 0; } -#banner { +.user-banner { height: 90px; background-size: auto 100%; background-position: right center; @@ -18,7 +18,7 @@ white-space: nowrap; position: relative; } -#banner .face { +.user-banner .face { width: 70px; height: 70px; margin: 10px; @@ -29,33 +29,33 @@ background: url('../common/item/bg5.png'); background-size: cover; } -#banner .face span { +.user-banner .face span { display: block; width: 64px; height: 64px; background-size: auto 100%; background-repeat: no-repeat; } -#banner .user-info { +.user-banner .user-info { padding: 15px 5px; color: #414e64; } -#banner .user-info .name { +.user-banner .user-info .name { height: 34px; line-height: 34px; } -#banner .user-info .name strong { - font-size: 26px; +.user-banner .user-info .name strong { + font-size: 24px; } -#banner .user-info .name span { +.user-banner .user-info .name span { padding-left: 5px; } -#banner .user-info .uid { +.user-banner .user-info .uid { height: 22px; line-height: 22px; font-size: 16px; } -#banner .stat { +.user-banner .stat { position: absolute; right: 0; top: 0; @@ -66,42 +66,38 @@ height: 58px; box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.4); } -#banner .stat-li { +.user-banner .stat-li { padding: 7px; width: 70px; height: 58px; text-align: center; position: relative; } -#banner .stat-li:nth-child(even) { +.user-banner .stat-li:nth-child(even) { background: rgba(225, 225, 225, 0.8); } -#banner .stat-li:first-child { - width: 78px; - padding-left: 15px; +.user-banner .stat-li:first-child { + width: 80px; + padding-left: 17px; } -#banner .stat-li:last-child { - width: 78px; - padding-right: 15px; +.user-banner .stat-li:last-child { + width: 80px; + padding-right: 17px; } -#banner .stat-li strong { +.user-banner .stat-li strong { font-size: 22px; display: block; } -#banner .stat-li span { +.user-banner .stat-li span { display: block; font-size: 14px; color: #414e64; } -#avatar-list { - width: calc(100% + 30px); - margin: 0 -15px -5px; - overflow: hidden; -} .exploration { display: flex; flex-wrap: wrap; - padding: 16px; + margin: 10px 0; + justify-content: center; } .exploration .item { width: 93px; @@ -112,6 +108,7 @@ margin: 3px; text-align: center; color: #fff; + align-items: center; } .exploration .item strong { font-size: 24px; @@ -128,12 +125,70 @@ display: block; text-shadow: 0 0 1px rgba(0, 0, 0, 0.5); } +.chest-list { + margin: 10px 0; + overflow: hidden; + background: rgba(0, 0, 0, 0.6); + padding: 0 15px; + display: flex; + justify-content: center; +} +.chest-list .chest { + width: 20%; + display: flex; + padding: 15px 0; +} +.chest-list .chest:nth-child(even) { + background: rgba(50, 50, 50, 0.5); +} +.chest-list .chest .value { + font-size: 24px; + line-height: 40px; + height: 40px; + padding-right: 8px; + text-align: right; + width: 70px; + text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, 0.5); +} +.chest-list .chest .detail { + width: 60px; + height: 40px; + font-size: 13px; +} +.chest-list .chest .info { + display: flex; + height: 20px; + line-height: 20px; +} +.chest-list .chest .icon { + display: inline-block; + width: 18px; + height: 18px; + margin: 1px; + background: url('./imgs/chest.webp') no-repeat; + background-size: auto 100%; + vertical-align: center; +} +.chest-list .chest .max { + font-size: 12px; + padding-left: 3px; + color: #aaa; +} +.chest-list .chest .title { + height: 20px; + display: flex; + color: #d3bc8e; +} .cont-title { padding: 8px 15px; } +.avatar-cont-main { + overflow: hidden; +} .avatar-cont { background: rgba(0, 0, 0, 0.5); padding: 0; + margin: 10px 0; } .avatar-list { display: flex; diff --git a/resources/character/avatar-list.html b/resources/character/avatar-list.html index 1d6a2e07..cc46fc72 100644 --- a/resources/character/avatar-list.html +++ b/resources/character/avatar-list.html @@ -7,7 +7,7 @@ {{block 'main'}} - + {{if info && info.stats}}
{{each info?.statMap title key}} {{if info.stats[key] }} @@ -32,39 +33,67 @@ {{/if}} {{/each}}
+ {{/if}} + + {{if !isSelfCookie}}
未绑定CK或CK失效,信息可能不完全。发送#体力帮助查看CK绑定方法,发送#更新面板更新游戏内角色展柜信息
{{/if}} -
- {{if info && info?.exploration['蒙德']}} - {{set citys = ['蒙德','龙脊雪山','璃月','层岩巨渊','稻妻','渊下宫','须弥'] }} -
- {{each citys city idx}} -
- {{city}} - {{ (info.exploration[city]||0)/10 || '0'}}% + +{{if info && info.exploration && info.exploration['蒙德']}} +{{set citys = ['蒙德','龙脊雪山','璃月','层岩巨渊','稻妻','渊下宫','须弥'] }} +
+ {{each citys city idx}} +
+ {{city}} + {{ (info.exploration[city]||0)/10 || '0'}}% +
+ {{/each}} +
+{{/if}} + + +{{if info?.stats?.commonChest}} +{{set ds = info?.stats}} +
+ {{each info?.chestMap cfg idx}} +
+
{{ds[cfg.key]}}
+
+
+
+
{{cfg.max>ds[cfg.key]?cfg.max:ds[cfg.key]}}
+
+
{{cfg.title}}
+
+ {{/each}} +
+{{/if}} + + +
+
角色列表
+
+ {{each avatars avatar idx}} + <% include(_layout_path+'../tpl/avatar-card.html', [avatar,{_res_path, cardType:'mini'}]) %> {{/each}}
- {{/if}} -
-
角色列表
-
- {{each avatars avatar idx}} - <% include(_layout_path+'../tpl/avatar-card.html', [avatar,{_res_path, cardType:'mini'}]) %> - {{/each}} -
- +
diff --git a/resources/character/avatar-list.less b/resources/character/avatar-list.less index e81195ba..27def12a 100644 --- a/resources/character/avatar-list.less +++ b/resources/character/avatar-list.less @@ -8,7 +8,8 @@ margin-top: 0; } -#banner { + +.user-banner { height: 90px; background-size: auto 100%; background-position: right center; @@ -50,7 +51,7 @@ line-height: 34px; strong { - font-size: 26px; + font-size: 24px; } span { @@ -79,7 +80,7 @@ .stat-li { @width: 70px; - @padding: 8px; + @padding: 10px; padding: 7px; width: @width; @@ -116,16 +117,12 @@ } } -#avatar-list { - width: calc(100% + 30px); - margin: 0 -15px -5px; - overflow: hidden; -} .exploration { display: flex; flex-wrap: wrap; - padding: 16px; + margin: 10px 0; + justify-content: center; .item { width: 93px; @@ -136,6 +133,7 @@ margin: 3px; text-align: center; color: #fff; + align-items: center; strong { font-size: 24px; @@ -154,17 +152,85 @@ text-shadow: 0 0 1px rgba(0, 0, 0, .5); } } +} + +.chest-list { + margin: 10px 0; + overflow: hidden; + background: rgba(0, 0, 0, .6); + padding: 0 15px; + display: flex; + justify-content: center; + + .chest { + width: 20%; + display: flex; + padding: 15px 0; + + &:nth-child(even) { + background: rgba(50, 50, 50, .5); + } + + .value { + font-size: 24px; + line-height: 40px; + height: 40px; + padding-right: 8px; + text-align: right; + width: 70px; + text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, .5); + } + + .detail { + width: 60px; + height: 40px; + font-size: 13px; + } + + .info { + display: flex; + height: 20px; + line-height: 20px; + } + + .icon { + display: inline-block; + width: 18px; + height: 18px; + margin: 1px; + background: url('./imgs/chest.webp') no-repeat; + background-size: auto 100%; + vertical-align: center; + } + + .max { + font-size: 12px; + padding-left: 3px; + color: #aaa; + } + + .title { + height: 20px; + display: flex; + color: #d3bc8e; + } + } } .cont-title { padding: 8px 15px; } +.avatar-cont-main { + overflow: hidden; +} + .avatar-cont { background: rgba(0, 0, 0, .5); padding: 0; + margin: 10px 0; } .avatar-list { diff --git a/resources/character/imgs/chest.webp b/resources/character/imgs/chest.webp new file mode 100644 index 00000000..b56793ed Binary files /dev/null and b/resources/character/imgs/chest.webp differ