From 256ff96c579df8559d94286ba2dacdca984c2b16 Mon Sep 17 00:00:00 2001 From: undefined Date: Sun, 16 May 2021 01:02:52 +0800 Subject: [PATCH] ui: rating history --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/model/domain.ts | 6 ++ packages/hydrooj/src/script/rating.ts | 5 +- packages/ui-default/components/tab/Tab.js | 2 +- packages/ui-default/package.json | 3 +- packages/ui-default/pages/user_detail.page.js | 67 ++++++++++++++++++- .../ui-default/pages/user_detail.page.styl | 3 + .../ui-default/templates/user_detail.html | 5 ++ 8 files changed, 86 insertions(+), 7 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index b05f02ca6..37d5c983c 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.26.2", + "version": "2.26.3", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index c53886330..4205ea7ee 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -205,6 +205,12 @@ class DomainModel { return await collUser.updateOne({ domainId, uid }, { $set: params }, { upsert: true }); } + static async updateUserInDomain(domainId: string, uid: number, update: any) { + const udoc = await UserModel.getById(domainId, uid); + deleteUserCache(udoc); + return await collUser.updateOne({ domainId, uid }, update, { upsert: true }); + } + @ArgMethod static async incUserInDomain(domainId: string, uid: number, field: string, n: number = 1) { // @ts-ignore diff --git a/packages/hydrooj/src/script/rating.ts b/packages/hydrooj/src/script/rating.ts index b55335148..ab8ada849 100644 --- a/packages/hydrooj/src/script/rating.ts +++ b/packages/hydrooj/src/script/rating.ts @@ -150,10 +150,9 @@ async function runInDomain(domainId: string, isSub: boolean, report: Function) { await domain.setMultiUserInDomain(domainId, {}, { rp: 1500 }); const tasks = []; for (const uid in udict) { + const rp = udict[uid] + (deltaudict[uid] || 0); tasks.push( - domain.setUserInDomain( - domainId, parseInt(uid, 10), { rp: udict[uid] + (deltaudict[uid] || 0) }, - ), + domain.updateUserInDomain(domainId, +uid, { $set: { rp }, $push: { ratingHistory: rp } }), ); } await Promise.all(tasks); diff --git a/packages/ui-default/components/tab/Tab.js b/packages/ui-default/components/tab/Tab.js index fc134dd1b..979482115 100644 --- a/packages/ui-default/components/tab/Tab.js +++ b/packages/ui-default/components/tab/Tab.js @@ -17,7 +17,7 @@ export default class Tab extends DOMAttachedObject { const targetIndex = $(ev.currentTarget).attr('data-tab-index'); const $container = $(ev.currentTarget).closest('.section__tab-container'); const tabInstance = Tab.get($container); - tabInstance.switchToTab(parseInt(targetIndex, 10)); + tabInstance.switchToTab(+targetIndex); }); } diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index bc8882512..8d21377dd 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.8.15", + "version": "4.8.16", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", @@ -38,6 +38,7 @@ "copy-webpack-plugin": "^6.1.1", "css-loader": "^4.2.2", "diff-dom": "^4.2.2", + "echarts": "^5.1.1", "emojify.js": "^1.1.0", "eslint": "^7.26.0", "eslint-config-airbnb": "^18.2.1", diff --git a/packages/ui-default/pages/user_detail.page.js b/packages/ui-default/pages/user_detail.page.js index 2ba61480c..4cd788259 100644 --- a/packages/ui-default/pages/user_detail.page.js +++ b/packages/ui-default/pages/user_detail.page.js @@ -1,10 +1,12 @@ import Clipboard from 'clipboard'; - +import * as echarts from 'echarts'; +import moment from 'moment-timezone'; import { NamedPage } from 'vj/misc/Page'; import substitute from 'vj/utils/substitute'; import Notification from 'vj/components/notification'; import i18n from 'vj/utils/i18n'; import base64 from 'vj/utils/base64'; +import request from 'vj/utils/request'; const page = new NamedPage('user_detail', async () => { $('[name="profile_contact_copy"]').get().forEach((el) => { @@ -18,6 +20,69 @@ const page = new NamedPage('user_detail', async () => { Notification.error(substitute(i18n('Copy "{data}" failed :('), { data: decoded })); }); }); + const data = await request.get(''); + const history = data.udoc?.history || []; + while (history.length > 30) history.shift(); + while (history.length < 30) history.unshift(1500); + const $dom = document.getElementById('rating-placeholder'); + const chart = echarts.init($dom, undefined); + chart.setOption({ + title: { + text: 'Rating', + left: '1%', + }, + tooltip: { trigger: 'axis' }, + grid: { + left: '5%', + right: '1%', + bottom: '10%', + }, + xAxis: { data: history.map((x, i) => moment().add(-30 + i, 'days').fromNow()) }, + yAxis: {}, + toolbox: { + right: 10, + feature: { + dataZoom: { yAxisIndex: 'none' }, + restore: {}, + saveAsImage: {}, + }, + }, + dataZoom: [{ type: 'inside' }], + visualMap: { + show: false, + pieces: [{ + lte: 1000, + color: '#AC3B2A', + }, { + gt: 1000, + lte: 1200, + color: '#AA069F', + }, { + gt: 1200, + lte: 1400, + color: '#FD0100', + }, { + gt: 1400, + lte: 1600, + color: '#FC7D02', + }, { + gt: 1600, + lte: 1900, + color: '#FBDB0F', + }, { + gt: 1900, + color: '#93CE07', + }], + outOfRange: { + color: '#999', + }, + }, + series: { + name: 'Rating', + type: 'line', + data: history, + }, + }); }); export default page; diff --git a/packages/ui-default/pages/user_detail.page.styl b/packages/ui-default/pages/user_detail.page.styl index fc9ad0cc6..d9d584549 100644 --- a/packages/ui-default/pages/user_detail.page.styl +++ b/packages/ui-default/pages/user_detail.page.styl @@ -88,3 +88,6 @@ +mobile() padding-top: rem($tab-item-height-mobile) + #rating-placeholder + width: auto + height: 600px \ No newline at end of file diff --git a/packages/ui-default/templates/user_detail.html b/packages/ui-default/templates/user_detail.html index 88e0a501a..c56169e32 100644 --- a/packages/ui-default/templates/user_detail.html +++ b/packages/ui-default/templates/user_detail.html @@ -153,6 +153,11 @@ +
+
+
+
+
{% if isSelfProfile %}