用户主页初版

This commit is contained in:
Searchstars
2025-01-30 16:28:39 +08:00
parent aab1c95cc8
commit 852bc848a5
11 changed files with 260 additions and 65 deletions
+28
View File
@@ -17,6 +17,34 @@ export const BilibiliClientUserMethods = {
return response.data.data return response.data.data
}, },
// 获取单个用户投稿的视频的代表作
async getUserMasterPieceByUID(this: any, uid: String) {
const url = `https://api.bilibili.com/x/space/masterpiece`;
const response = await this.getRequest(`${url}?vmid=${uid}`);
return response.data.data
},
// 获取用户投稿列表(分页)
async getUserVideosByUID(this: any, uid: String, pn: Number, ps: Number = 5) {
const url = `https://api.bilibili.com/x/space/wbi/arc/search`;
const response = await this.getRequestWbi(url, {
mid: uid,
pn,
ps
});
return response.data.data
},
// 获取用户空间动态列表
async getUserDynamicListByUID(this: any, uid: String) {
const url = `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space`;
const response = await this.getRequest(`${url}?host_mid=${uid}`);
return response.data.data
},
// 获取单个用户的导航栏状态数 // 获取单个用户的导航栏状态数
async getUserNavnumByUID(this: any, uid: String) { async getUserNavnumByUID(this: any, uid: String) {
const url = `https://api.bilibili.com/x/space/navnum`; const url = `https://api.bilibili.com/x/space/navnum`;
+11 -1
View File
@@ -1,5 +1,5 @@
<template> <template>
<div class="user"> <div class="user" onclick="OpenUser(user.mid)">
<div class="userinfo"> <div class="userinfo">
<image src="{{user.upic}}@46w_46h" alt="/common/fullgray.png" <image src="{{user.upic}}@46w_46h" alt="/common/fullgray.png"
style="border-radius: 50%; width: 46px; height: 46px; object-fit: scale-down"></image> style="border-radius: 50%; width: 46px; height: 46px; object-fit: scale-down"></image>
@@ -34,6 +34,8 @@
</template> </template>
<script> <script>
import router from "@system.router"
export default { export default {
props: ["user"], props: ["user"],
computed: { computed: {
@@ -41,6 +43,14 @@ export default {
return this.$app.$def.tools.formatNumber(this.user.fans) return this.$app.$def.tools.formatNumber(this.user.fans)
} }
}, },
OpenUser(id) {
router.push({
uri: "pages/user",
params: {
uid: id
}
})
},
onInit(){ onInit(){
if(!(this.user.upic.includes("http://") || this.user.upic.includes("https://"))){ if(!(this.user.upic.includes("http://") || this.user.upic.includes("https://"))){
this.user.upic = "https:" + this.user.upic this.user.upic = "https:" + this.user.upic
+58 -44
View File
@@ -1,25 +1,28 @@
<import name="online-image" src="@components/BetterOnlineImage/BetterOnlineImage.ux"></import> <import name="online-image" src="@components/BetterOnlineImage/BetterOnlineImage.ux"></import>
<template> <template>
<div> <div class="vid">
<div class="vid" @click="OpenVideo(video.bvid)" if="{{loadComp}}"> <div class="loadedbox" @click="OpenVideo(video.bvid)" if="{{loadComp}}">
<div style="{{vidinfo_style}}" class="vidinfo"> <div style="{{vidinfo_style}}" class="vidinfo">
<div class="vidpicture" style="{{vidpicture_style}}"> <div class="vidpicture" style="{{vidpicture_style}}">
<online-image width="{{vidpicture_style['max-width']}}" height="{{vidpicture_style['max-height']}}" lock-size="true" border-radius="30px" object-fit="cover" loading-anim="true" src="{{video.pic}}@{{onlineimg_width}}w_{{onlineimg_height}}h"></online-image> <online-image width="{{vidpicture_style['max-width']}}" height="{{vidpicture_style['max-height']}}"
</div> lock-size="true" border-radius="30px" object-fit="cover" loading-anim="true"
<text class="vidtitle" if="{{!useColumnTitle}}">{{ video.title }}</text> src="{{video.pic}}@{{onlineimg_width}}w_{{onlineimg_height}}h"></online-image>
</div> </div>
<text class="vidtitle_column" if="{{useColumnTitle}}">{{ video.title }}</text> <text class="vidtitle" if="{{!useColumnTitle}}">{{ video.title }}</text>
<div class="vidstat"> </div>
<text class="upinfo">UP{{ video.owner.name }}</text> <text class="vidtitle_column" if="{{useColumnTitle}}">{{ video.title }}</text>
<div class="stat_view"> <div class="vidstat">
<image class="stat_view_img" src="/common/playcounticon.png"></image> <text class="upinfo">UP{{ video.owner.name }}</text>
<text class="stat_view_text"> <div class="stat_view">
{{ stat_view }} <image class="stat_view_img" src="/common/playcounticon.png"></image>
</text> <text class="stat_view_text">
</div> {{ stat_view }}
</text>
</div> </div>
</div>
</div> </div>
<text else class="compLoadingTip">视频加载中...</text>
</div> </div>
</template> </template>
@@ -41,7 +44,7 @@ export default {
loadComp: false loadComp: false
}, },
computed: { computed: {
stat_view(){ stat_view() {
return this.$app.$def.tools.formatNumber(this.video.stat.view) return this.$app.$def.tools.formatNumber(this.video.stat.view)
} }
}, },
@@ -52,47 +55,47 @@ export default {
}) })
}, },
// 在线图片展示大小(UI层) // 在线图片展示大小(UI层)
SetOnlineImageSize(width, height){ SetOnlineImageSize(width, height) {
this.vidpicture_style["min-width"] = width + "px"; this.vidpicture_style["min-width"] = width + "px"
this.vidpicture_style["max-width"] = width + "px"; this.vidpicture_style["max-width"] = width + "px"
this.vidpicture_style["min-height"] = height + "px"; this.vidpicture_style["min-height"] = height + "px"
this.vidpicture_style["max-height"] = height + "px"; this.vidpicture_style["max-height"] = height + "px"
}, },
// 在线图片加载大小(组件层) // 在线图片加载大小(组件层)
// 使用比展示大小更小的加载大小可以节省设备RAM、降低渲染压力、节省流量等 // 使用比展示大小更小的加载大小可以节省设备RAM、降低渲染压力、节省流量等
// 推荐是展示大小的等比例缩放 // 推荐是展示大小的等比例缩放
SetOnlineImageLoadSize(width, height){ SetOnlineImageLoadSize(width, height) {
this.onlineimg_width = width; this.onlineimg_width = width
this.onlineimg_height = height; this.onlineimg_height = height
}, },
doStyleAdjustTask(){ doStyleAdjustTask() {
const deviceInfo = global.DEVICE_INFO; const deviceInfo = global.DEVICE_INFO
if (deviceInfo.screenShape == "rect" || this.video.title.length > 25){ if (deviceInfo.screenShape == "rect" || this.video.title.length > 25) {
this.useColumnTitle = true; this.useColumnTitle = true
// 手环Pro 系列 // 手环Pro 系列
if (deviceInfo.screenWidth <= 380){ if (deviceInfo.screenWidth <= 380) {
this.SetOnlineImageSize(200, 150); this.SetOnlineImageSize(200, 150)
this.SetOnlineImageLoadSize(100, 75); this.SetOnlineImageLoadSize(100, 75)
} }
// RW系列 // RW系列
else if (deviceInfo.screenShape == "rect"){ else if (deviceInfo.screenShape == "rect") {
this.SetOnlineImageSize(265, 150); this.SetOnlineImageSize(265, 150)
this.SetOnlineImageLoadSize(265, 150); this.SetOnlineImageLoadSize(265, 150)
} }
// 圆屏系列 // 圆屏系列
else{ else {
this.SetOnlineImageSize(300, 150); this.SetOnlineImageSize(300, 150)
this.SetOnlineImageLoadSize(300, 150); this.SetOnlineImageLoadSize(300, 150)
} }
} }
}, },
doVidObjectPatch(){ doVidObjectPatch() {
if(!(this.video.pic.includes("http://") || this.video.pic.includes("https://"))){ if (!(this.video.pic.includes("http://") || this.video.pic.includes("https://"))) {
this.video.pic = "https:" + this.video.pic this.video.pic = "https:" + this.video.pic
} }
}, },
async asyncInit(){ async asyncInit() {
if(!this.video){ if (!this.video) {
this.video = await global.biliclient.getVideoInfoByBVID(this.bvid) this.video = await global.biliclient.getVideoInfoByBVID(this.bvid)
} }
@@ -101,14 +104,14 @@ export default {
this.doVidObjectPatch() this.doVidObjectPatch()
this.doStyleAdjustTask() this.doStyleAdjustTask()
}, },
onInit(){ onInit() {
this.asyncInit() this.asyncInit()
} }
} }
</script> </script>
<style lang="less"> <style lang="less">
@import '@less/global.less'; @import "@less/global.less";
.vid { .vid {
margin-top: 10px; margin-top: 10px;
@@ -120,6 +123,12 @@ export default {
flex-direction: column; flex-direction: column;
} }
.loadedbox {
justify-content: center;
align-items: center;
flex-direction: column;
}
.vidinfo { .vidinfo {
width: 100%; width: 100%;
justify-content: center; justify-content: center;
@@ -180,4 +189,9 @@ export default {
font-weight: 600; font-weight: 600;
margin-left: 5px; margin-left: 5px;
} }
.compLoadingTip {
font-weight: 600;
font-size: 18px;
}
</style> </style>
+4 -1
View File
@@ -126,7 +126,10 @@
} }
}, },
"user": { "user": {
"title": "User" "title": "User",
"videos": "Videos",
"dynamices": "Dynamic",
"nocontent": "There is no content to show at present."
}, },
"sessionood": { "sessionood": {
"title": "Some problems have occurred", "title": "Some problems have occurred",
+7 -1
View File
@@ -131,7 +131,13 @@
} }
}, },
"user": { "user": {
"title": "用户主页" "title": "用户主页",
"videos": "TA的视频",
"dynamices": "TA的动态",
"nocontent": "暂无可展示内容",
"uservideos": {
"title": "用户投稿"
}
}, },
"sessionood": { "sessionood": {
"title": "遇到了一些问题", "title": "遇到了一些问题",
+6
View File
@@ -163,6 +163,12 @@
}, },
"pages/error/sessionood": { "pages/error/sessionood": {
"component": "sessionood" "component": "sessionood"
},
"pages/user/userdynamic": {
"component": "userdynamic"
},
"pages/user/uservideos": {
"component": "uservideos"
} }
} }
} }
+16 -14
View File
@@ -4,20 +4,22 @@
<template> <template>
<div class="page"> <div class="page">
<image style="position: absolute; left: 0px" src="{{getBgImg}}"></image> <image style="position: absolute; left: 0px" src="{{getBgImg}}"></image>
<switch-bar title="search.title" static></switch-bar> <scroll class="scroll" scroll-y="true">
<div class="searchbtn" @click="OpenInput"> <switch-bar title="search.title" static></switch-bar>
<image src="/common/searchpage_search.png" style="margin-left: 25px" static></image> <div class="searchbtn" @click="OpenInput">
<text class="searchtip" style="margin-left: 15px" static>{{ $t("search.clickToSearch") }}</text> <image src="/common/searchpage_search.png" style="margin-left: 25px" static></image>
</div> <text class="searchtip" style="margin-left: 15px" static>{{ $t("search.clickToSearch") }}</text>
<div style="flex-direction: row; align-items: center; margin-top: 20px" static> </div>
<image src="/common/searchpage_fire.png" style="object-fit: scale-down" static></image> <div style="flex-direction: row; align-items: center; margin-top: 20px" static>
<text class="hottitle" static>{{ $t("search.hotSearch") }}</text> <image src="/common/searchpage_fire.png" style="object-fit: scale-down" static></image>
</div> <text class="hottitle" static>{{ $t("search.hotSearch") }}</text>
<div for="{{hotwords}}" style="margin-top: 15px"> </div>
<image src="{{$item.icon}}@22w_22h" static></image> <div for="{{hotwords}}" style="margin-top: 15px">
<text class="hotword-text">{{ $item.show_name }}</text> <image src="{{$item.icon}}@22w_22h" static></image>
</div> <text class="hotword-text">{{ $item.show_name }}</text>
<text style="margin-top: 25px"></text> </div>
<text style="margin-top: 25px"></text>
</scroll>
<image style="position: absolute; margin-top: 305px" if="{{anims.show_loading}}" src="{{anims.loading_src.value}}"></image> <image style="position: absolute; margin-top: 305px" if="{{anims.show_loading}}" src="{{anims.loading_src.value}}"></image>
<full-screen-input style="position: absolute" if="{{input_mode}}" @send="GoSearch" @exit="ExitInput"></full-screen-input> <full-screen-input style="position: absolute" if="{{input_mode}}" @send="GoSearch" @exit="ExitInput"></full-screen-input>
</div> </div>
+11
View File
@@ -4,10 +4,12 @@
.ctxcard { .ctxcard {
.flex-column(15px); .flex-column(15px);
.radius(15px); .radius(15px);
width: 300px;
} }
.ctxdesc { .ctxdesc {
.flex-row(0px, #00000000); .flex-row(0px, #00000000);
width: 100%;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
@@ -20,4 +22,13 @@
.gs { .gs {
font-size: 20px; font-size: 20px;
color: gray; color: gray;
}
.mp-scroll {
width: 100%;
}
.mp {
.flex-row(0px, #00000000);
height: 100%;
} }
+39 -4
View File
@@ -1,25 +1,43 @@
<import name="title-bar" src="@components/TitleBar/TitleBar.ux"></import> <import name="title-bar" src="@components/TitleBar/TitleBar.ux"></import>
<import name="user-info" src="@components/UserInfo/UserInfo.ux"></import> <import name="user-info" src="@components/UserInfo/UserInfo.ux"></import>
<import name="online-image" src="@components/BetterOnlineImage/BetterOnlineImage.ux"></import>
<template> <template>
<div class="page"> <div class="page">
<title-bar title="user.title"></title-bar> <title-bar title="user.title"></title-bar>
<user-info account-info="{{user}}" if="{{loaded}}"></user-info> <user-info account-info="{{user}}" if="{{loaded}}"></user-info>
<div class="ctxcard" if="{{loaded}}"> <div class="ctxcard" style="margin-top: 25px" if="{{loaded}}" @click="GoUserVideos">
<div class="ctxdesc"> <div class="ctxdesc">
<div style="width: 280px;"> <div style="width: 290px;">
<text class="desctxt">TA的视频</text> <text class="desctxt">{{ $t("user.videos") }}</text>
<text class="desctxt gs" style="margin-left: 15px">{{navnum.video}}</text> <text class="desctxt gs" style="margin-left: 15px">{{navnum.video}}</text>
</div> </div>
<text class="desctxt gs">></text> <text class="desctxt gs">></text>
</div> </div>
<scroll class="mp-scroll" scroll-x="true">
<div if="{{masterpiece.length > 0}}" class="mp">
<online-image for="{{masterpiece}}" src="{{$item.pic}}@90h" style="padding-right: 10px"></online-image>
</div>
</scroll>
</div> </div>
<div class="ctxcard" style="margin-top: 10px" if="{{loaded}}" @click="WIPTips">
<div class="ctxdesc">
<div style="width: 290px;">
<text class="desctxt">{{ $t("user.dynamices") }}</text>
<text class="desctxt gs" style="margin-left: 15px">{{dynamiclist.items.length}}+</text>
</div>
<text class="desctxt gs">></text>
</div>
</div>
<text style="margin-top: 30px"></text>
<image style="position: absolute; margin-top: 245px" if="{{anims.show_loading}}" src="{{anims.loading_src.value}}"></image> <image style="position: absolute; margin-top: 245px" if="{{anims.show_loading}}" src="{{anims.loading_src.value}}"></image>
</div> </div>
</template> </template>
<script> <script>
import router from "@system.router"
import prompt from "@system.prompt"
export default { export default {
public: { public: {
uid: 1 uid: 1
@@ -28,6 +46,8 @@ export default {
user: {}, user: {},
stat: {}, stat: {},
navnum: {}, navnum: {},
masterpiece: {},
dynamiclist: {},
anims: { anims: {
show_loading: false show_loading: false
}, },
@@ -39,11 +59,26 @@ export default {
this.user = await global.biliclient.getUserInfoByUID(this.uid) this.user = await global.biliclient.getUserInfoByUID(this.uid)
this.stat = await global.biliclient.getUserStatByUID(this.uid) this.stat = await global.biliclient.getUserStatByUID(this.uid)
this.navnum = await global.biliclient.getUserNavnumByUID(this.uid) this.navnum = await global.biliclient.getUserNavnumByUID(this.uid)
this.masterpiece = await global.biliclient.getUserMasterPieceByUID(this.uid)
this.dynamiclist = await global.biliclient.getUserDynamicListByUID(this.uid)
this.anims.loading.stop() this.anims.loading.stop()
this.anims.show_loading = false this.anims.show_loading = false
this.loaded = true this.loaded = true
}, },
GoUserVideos(){
router.push({
uri: "pages/user/uservideos",
params: {
uid: this.uid
}
})
},
WIPTips(){
prompt.showToast({
message: "该功能仍未开发完毕"
})
},
onInit(){ onInit(){
global.animengine.defaults.loading.CreateLoadingAnimation(this) global.animengine.defaults.loading.CreateLoadingAnimation(this)
this.LoadUserInfo() this.LoadUserInfo()
@@ -0,0 +1,9 @@
<template>
<div></div>
</template>
<script>
export default {}
</script>
<style></style>
+71
View File
@@ -0,0 +1,71 @@
<import name="title-bar" src="@components/TitleBar/TitleBar.ux"></import>
<import name="videoshow" src="@components/Video/Video.ux"></import>
<import
name="floating-page-changer"
src="@components/FloatingPageChanger/FloatingPageChanger.ux"
></import>
<template>
<div class="page">
<scroll class="scroll" scroll-y="true">
<title-bar title="user.uservideos.title"></title-bar>
<div style="flex-direction: column; width: 77%">
<videoshow if="{{!anims.show_loading}}" for="{{vids.list.vlist}}" bvid="{{$item.bvid}}"></videoshow>
</div>
<text style="margin-top: 30px"></text>
</scroll>
<floating-page-changer style="position: absolute" current_pn="{{current_pn}}" @backpn="BackPN"
@nextpn="NextPN"></floating-page-changer>
<image style="position: absolute; margin-top: 245px" if="{{anims.show_loading}}" src="{{anims.loading_src.value}}">
</image>
</div>
</template>
<script>
export default {
public: {
uid: 1
},
private: {
vids: null,
current_pn: 1,
maxpn: 1,
anims: {
show_loading: false
}
},
BackPN() {
if (this.current_pn > 1) {
this.current_pn--
this.LoadVideos(false)
}
},
NextPN() {
if (this.current_pn < this.maxpn) {
this.current_pn++
this.LoadVideos(false)
}
},
async LoadVideos(init) {
this.anims.show_loading = true
this.anims.loading.start()
this.vids = null
this.vids = await global.biliclient.getUserVideosByUID(this.uid, this.current_pn, 5)
if (init) {
this.maxpn = Math.ceil(this.vids.page.count / 5)
}
this.anims.show_loading = false
this.anims.loading.stop()
},
onInit() {
global.animengine.defaults.loading.CreateLoadingAnimation(this)
this.LoadVideos(true)
}
}
</script>
<style lang="less">
@import "@less/global.less";
</style>