优化代码
This commit is contained in:
6
package-lock.json
generated
6
package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"core-js": "^3.8.3",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.10.4",
|
||||
"goeasy": "^2.13.21",
|
||||
"pinia": "^3.0.3",
|
||||
"qwebchannel": "^6.2.0",
|
||||
"vue": "^3.2.13",
|
||||
@@ -7376,6 +7377,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/goeasy": {
|
||||
"version": "2.13.21",
|
||||
"resolved": "https://registry.npmjs.org/goeasy/-/goeasy-2.13.21.tgz",
|
||||
"integrity": "sha512-KxzYC9KRu02tt3Cv+9QHqP/yD6kl/kmI07UZw6BzRFjJUpNNuefZTD/bKC9a9nYbmLWYxYneoQqowHwl2GaEPw=="
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"core-js": "^3.8.3",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.10.4",
|
||||
"goeasy": "^2.13.21",
|
||||
"pinia": "^3.0.3",
|
||||
"qwebchannel": "^6.2.0",
|
||||
"vue": "^3.2.13",
|
||||
|
||||
@@ -9,6 +9,18 @@ export function getVxQrcode() {
|
||||
export function getScanResult(data) {
|
||||
return getAxios({ url: 'user/check/' + data})
|
||||
}
|
||||
//获取用户信息
|
||||
export function getUserInfo(data) {
|
||||
return postAxios({ url: 'user/getUserInfo',data})
|
||||
}
|
||||
//修改用户信息
|
||||
export function editUserInfo(data) {
|
||||
return postAxios({ url: 'user/updateUserInfo', data })
|
||||
}
|
||||
//检查用户名
|
||||
export function checkUsername(data) {
|
||||
return postAxios({ url: 'user/checkUserName', data })
|
||||
}
|
||||
//注册
|
||||
export function register(data) {
|
||||
return postAxios({ url: 'user/registerWithMail', data })
|
||||
@@ -90,3 +102,19 @@ export function topPkInfo(data) {
|
||||
export function cancelTopPkInfo(data) {
|
||||
return postAxios({ url: 'user/cancelPin', data })
|
||||
}
|
||||
//获取积分详情
|
||||
export function getIntegralDetail(data) {
|
||||
return postAxios({ url: 'user/pointsDetail', data })
|
||||
}
|
||||
//获取PK记录
|
||||
export function getPkRecord(data) {
|
||||
return postAxios({ url: 'user/handlePkInfo', data })
|
||||
}
|
||||
//签到
|
||||
export function signIn(data) {
|
||||
return postAxios({ url: 'user/signIn', data })
|
||||
}
|
||||
//修改邮箱
|
||||
export function editEmail(data) {
|
||||
return postAxios({ url: 'user/updateUserMail', data })
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -102,7 +102,7 @@
|
||||
</el-splitter>
|
||||
</div>
|
||||
<!-- 确认删除弹窗 -->
|
||||
<el-dialog
|
||||
<el-dialog center
|
||||
class="center-dialog"
|
||||
v-model="centerDialogVisible"
|
||||
title="提示"
|
||||
@@ -328,8 +328,7 @@ onUnmounted(() => {
|
||||
.card-content {
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
background-image: url(../../assets/PKbackground.png);
|
||||
background-size: 100% 100%;
|
||||
transition: all 0.4s ease;
|
||||
@@ -337,7 +336,7 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
}
|
||||
.card-content:hover {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8);
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||
transform: scale(1.05);
|
||||
opacity: 0.8;
|
||||
}
|
||||
@@ -397,11 +396,19 @@ onUnmounted(() => {
|
||||
.modify-icon:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
.modify-icon:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.delete-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
.delete-icon:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.delete-icon:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
@@ -474,6 +481,10 @@ onUnmounted(() => {
|
||||
transform: scale(1.1);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.Confirm:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.Reset {
|
||||
width: 400px;
|
||||
height: 50px;
|
||||
@@ -492,6 +503,10 @@ onUnmounted(() => {
|
||||
transform: scale(1.1);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.Reset:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.center-dialog {
|
||||
background-color: #03aba8;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,11 @@ import {
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
import {getPkRecord} from "@/api/account";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {getPromiseStorage } from "@/utils/storage.js";
|
||||
|
||||
const user = ref(null); // 用户信息
|
||||
const refname = ref("");
|
||||
const segmentedvalue = ref(1);
|
||||
const options = [
|
||||
@@ -141,9 +146,44 @@ const options = [
|
||||
SelectedIcon: require("@/assets/InvitationSelected.png"),
|
||||
},
|
||||
];
|
||||
const list = ref([{}, {}, {}, {}, {}, {}, {}]);
|
||||
const list = ref([]);
|
||||
const page = ref(0);
|
||||
const IPKPostedData = ref([]);
|
||||
const InvitationData = ref([]);
|
||||
|
||||
//获取PK记录列表
|
||||
function PkRecord() {
|
||||
getPkRecord({
|
||||
type: segmentedvalue.value,
|
||||
userId: user.value.id,
|
||||
page: page.value,
|
||||
size: 10,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
if (segmentedvalue.value === 1) {
|
||||
IPKPostedData.value.push(...res);
|
||||
list.value = IPKPostedData.value;
|
||||
}else{
|
||||
InvitationData.value.push(...res);
|
||||
list.value = InvitationData.value;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 加载更多
|
||||
function load() {}
|
||||
|
||||
// 组件挂载完成后执行
|
||||
onMounted(() => {
|
||||
getPromiseStorage("user")
|
||||
.then((res) => {
|
||||
user.value = res;
|
||||
PkRecord();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
|
||||
@@ -108,7 +108,9 @@
|
||||
@blur="handleChange()"
|
||||
/>
|
||||
<div class="myanchor">
|
||||
<div class="myanchor-btn" @click="myAnchorDialogVisible = true">选择我的主播</div>
|
||||
<div class="myanchor-btn" @click="myAnchorDialogVisible = true">
|
||||
选择我的主播
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="country">
|
||||
@@ -176,7 +178,8 @@
|
||||
</el-splitter>
|
||||
</div>
|
||||
<!-- 确认删除弹窗 -->
|
||||
<el-dialog
|
||||
<el-dialog
|
||||
center
|
||||
class="center-dialog"
|
||||
v-model="centerDialogVisible"
|
||||
title="提示"
|
||||
@@ -192,41 +195,82 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 选择我的主播弹窗 -->
|
||||
<el-dialog v-model="myAnchorDialogVisible" title="选择我的主播库主播" width="800">
|
||||
<el-dialog align-center center v-model="myAnchorDialogVisible" title="选择我的主播库主播" width="800">
|
||||
<div class="myanchor-content">
|
||||
<div class="myanchor-list">
|
||||
<div class="anchor-library-card" v-for="(item, index) in anchorLibrary" :key="index" @click="selectStreamerLibrary(item)" :style="{transform: item == selectAnchor? 'scale(1.05)':'scale(1)'}">
|
||||
<div class="card-content">
|
||||
<div class="card-avatar">
|
||||
<img
|
||||
style="width: 100%; height: 100%; border-radius: 100px"
|
||||
:src="item.headerIcon"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div class="personalInformation">
|
||||
<div class="name">{{ item.anchorId }}</div>
|
||||
<div class="GenderAndCountry">
|
||||
<div
|
||||
class="Gender"
|
||||
:style="{
|
||||
background: item.gender == 1 ? '#59D8DB' : '#F3876F',
|
||||
}"
|
||||
>
|
||||
{{ item.gender == 1 ? "男" : "女" }}
|
||||
</div>
|
||||
<div class="Country">{{ item.country }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="anchor-library-card"
|
||||
v-for="(item, index) in anchorLibrary"
|
||||
:key="index"
|
||||
@click="selectStreamerLibrary(item)"
|
||||
>
|
||||
<div class="card-content" :style="{ backgroundImage: item == selectAnchor ? '' : '',background: item == selectAnchor ? '#FFFBFA' : '',border: item == selectAnchor ? '1px solid #F4D0C9' : ''}">
|
||||
<div class="card-avatar">
|
||||
<img
|
||||
style="width: 100%; height: 100%; border-radius: 100px"
|
||||
:src="item.headerIcon"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div class="personalInformation">
|
||||
<div class="name">{{ item.anchorId }}</div>
|
||||
<div class="GenderAndCountry">
|
||||
<div
|
||||
class="Gender"
|
||||
:style="{
|
||||
background: item.gender == 1 ? '#59D8DB' : '#F3876F',
|
||||
}"
|
||||
>
|
||||
{{ item.gender == 1 ? "男" : "女" }}
|
||||
</div>
|
||||
<div class="Country">{{ item.country }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="myanchor-dialog-btn">
|
||||
<div class="Reset" @click="myAnchorDialogVisible = false">取消</div>
|
||||
<div class="Confirm" @click="handleSelect">确认</div>
|
||||
<div class="Confirm" @click="myAnchorDialogConfirm()">确认</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 置顶弹窗 -->
|
||||
<el-dialog align-center center v-model="topPositionstate" title="置顶" width="800">
|
||||
<div class="topPosition-content">
|
||||
<div class="topPosition-content-title">
|
||||
置顶后,该用户将在首页置顶,并在指定时长内享有置顶特权。置顶时长
|
||||
不足1小时,系统将按1小时计算积分扣除。请选择置顶时长:
|
||||
</div>
|
||||
<div class="topPosition-input">
|
||||
<el-select-v2
|
||||
v-model="topPositionvalue"
|
||||
:options="topPositionOptions"
|
||||
placeholder="请选择置顶时长"
|
||||
style="width: 100%"
|
||||
size="large"
|
||||
filterable
|
||||
/>
|
||||
</div>
|
||||
<div class="myanchor-dialog-btn">
|
||||
<div class="Reset" @click="topPositionstate = false">取消</div>
|
||||
<div class="Confirm" @click="topPositionstateConfirm()">确认</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 取消置顶弹窗 -->
|
||||
<el-dialog center v-model="cancelTopPositionstate" title="取消置顶" width="700" align-center>
|
||||
<div class="cancelTopPosition">
|
||||
<div class="cancelTopPosition-content">
|
||||
您确定要取消置顶吗?取消置顶后,该用户将不再享有置顶特权,但仍可继续参与
|
||||
PK挑战。若置顶时长不足1小时,系统将按1小时计算积分扣除。取消后按实际使用时长比例返还剩余积分,是否确认执行此操作?
|
||||
</div>
|
||||
<div class="myanchor-dialog-btn">
|
||||
<div class="Reset" @click="cancelTopPositionstate = false">取消</div>
|
||||
<div class="Confirm" @click="cancelTopPositionstateConfirm()">确认</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -245,7 +289,7 @@ import {
|
||||
delPkInfo,
|
||||
topPkInfo,
|
||||
cancelTopPkInfo,
|
||||
getAnchorList
|
||||
getAnchorList,
|
||||
} from "@/api/account";
|
||||
import { TimestamptolocalTime } from "@/utils/timeConversion.js";
|
||||
import { getCountryNamesArray } from "../../utils/countryUtil";
|
||||
@@ -276,25 +320,88 @@ const modifyDialogstateID = ref(null); // 修改弹窗ID
|
||||
const myAnchorDialogVisible = ref(false); // 选择我的主播弹窗
|
||||
const anchorLibrary = ref([]); // 我的主播库
|
||||
const selectAnchor = ref(null); //选中的主播信息
|
||||
const topPositionstate = ref(false); // 置顶弹窗
|
||||
const cancelTopPositionstate = ref(false); // 取消置顶弹窗
|
||||
const topPositiondata = ref(null); // 置顶or取消置顶数据
|
||||
const topPositionvalue = ref(null); // 置顶时长
|
||||
const topPositionOptions = ref([]); // 置顶时长选项
|
||||
// 选择我的主播
|
||||
function selectStreamerLibrary(item) {
|
||||
selectAnchor.value = item
|
||||
selectAnchor.value = item;
|
||||
}
|
||||
function myAnchorDialogConfirm() {
|
||||
AnchorProfilePicture.value = selectAnchor.value.headerIcon.split("/").pop();
|
||||
anchorName.value = selectAnchor.value.anchorId;
|
||||
gendervalue.value = selectAnchor.value.gender;
|
||||
countryvalue.value = selectAnchor.value.country;
|
||||
myAnchorDialogVisible.value = false;
|
||||
}
|
||||
|
||||
|
||||
//获取我的主播库数据
|
||||
function getMyAnchorLibrary() {
|
||||
getAnchorList({id: user.value.id}).then((res) => {
|
||||
getAnchorList({ id: user.value.id }).then((res) => {
|
||||
console.log("anchorLibrary", res);
|
||||
anchorLibrary.value = res
|
||||
})
|
||||
anchorLibrary.value = res;
|
||||
});
|
||||
}
|
||||
// 置顶or取消置顶
|
||||
function topPosition(item) {
|
||||
|
||||
|
||||
if (item.isPin == false) {
|
||||
topPositionstate.value = true;
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
topPositionOptions.value = generateTimeOptions(currentTime, item.pkTime);
|
||||
} else {
|
||||
cancelTopPositionstate.value = true;
|
||||
}
|
||||
topPositiondata.value = item;
|
||||
}
|
||||
// 修改
|
||||
|
||||
// 确认置顶
|
||||
function topPositionstateConfirm() {
|
||||
if (topPositionvalue.value == 0) {
|
||||
topPositionstate.value = false;
|
||||
return;
|
||||
}
|
||||
topPkInfo({
|
||||
articleId: topPositiondata.value.id,
|
||||
pinExpireTime: topPositionvalue.value,
|
||||
}).then((res) => {
|
||||
ElMessage.success("置顶成功");
|
||||
topPositionstate.value = false;
|
||||
list.value = [];
|
||||
page.value = 0;
|
||||
PKInfo();
|
||||
});
|
||||
}
|
||||
|
||||
// 确认取消置顶
|
||||
function cancelTopPositionstateConfirm() {
|
||||
cancelTopPkInfo({articleId: topPositiondata.value.id}).then((res) => {
|
||||
ElMessage.success(res);
|
||||
cancelTopPositionstate.value = false;
|
||||
list.value = [];
|
||||
page.value = 0;
|
||||
PKInfo();
|
||||
});
|
||||
}
|
||||
|
||||
//计算置顶时长
|
||||
function generateTimeOptions(currentTimestamp, targetTimestamp) {
|
||||
const timeDiff = targetTimestamp - currentTimestamp;
|
||||
// 时间差小于0,说明已过期
|
||||
if (timeDiff <= 0) return [{ value: 0, label: "已过期" }];
|
||||
const hours = Math.ceil(timeDiff / 3600);
|
||||
const options = Array.from({ length: hours }, (_, i) => {
|
||||
const hour = i + 1;
|
||||
return {
|
||||
value: currentTimestamp + hour * 3600,
|
||||
label: `${hour}个小时`,
|
||||
};
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
||||
//修改
|
||||
function modify(item) {
|
||||
if (modifyDialogstate.value) {
|
||||
cancel();
|
||||
@@ -311,7 +418,7 @@ function modify(item) {
|
||||
sessionnum.value = item.pkNumber;
|
||||
remark.value = item.remark;
|
||||
}
|
||||
// 取消
|
||||
// 取消修改
|
||||
function cancel() {
|
||||
modifyDialogstateID.value = null;
|
||||
modifyDialogstate.value = false;
|
||||
@@ -324,12 +431,14 @@ function cancel() {
|
||||
sessionnum.value = null;
|
||||
remark.value = null;
|
||||
}
|
||||
|
||||
// 删除
|
||||
const deletePKInfodata = ref(null);
|
||||
function deletePKInfo(item) {
|
||||
deletePKInfodata.value = item;
|
||||
centerDialogVisible.value = true;
|
||||
}
|
||||
|
||||
// 确认删除
|
||||
function deleteAnchor() {
|
||||
centerDialogVisible.value = false;
|
||||
@@ -436,7 +545,7 @@ function Reset() {
|
||||
goldvalue.value = null;
|
||||
sessionnum.value = null;
|
||||
remark.value = null;
|
||||
countryvalue.value = null
|
||||
countryvalue.value = null;
|
||||
}
|
||||
|
||||
//输入框失去焦点
|
||||
@@ -530,7 +639,7 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
background-image: url(../../assets/PKbackground.png);
|
||||
background-image: url(@/assets/PKbackground.png);
|
||||
background-size: 100% 100%;
|
||||
transition: all 0.4s ease;
|
||||
display: flex;
|
||||
@@ -623,6 +732,10 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
.modify-icon:hover {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
.modify-icon:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.delete-icon {
|
||||
width: 20px;
|
||||
height: 28px;
|
||||
@@ -631,6 +744,10 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
.delete-icon:hover {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
.delete-icon:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.add-anchor-library {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -692,6 +809,10 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
.myanchor-btn:hover {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
.myanchor-btn:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.country {
|
||||
width: 90%;
|
||||
height: 50px;
|
||||
@@ -763,6 +884,10 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
transition: all 0.4s ease;
|
||||
border-radius: 25px;
|
||||
}
|
||||
.Confirm:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.Confirm:hover {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||
transform: scale(1.05);
|
||||
@@ -786,14 +911,18 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
transform: scale(1.05);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.myanchor-content{
|
||||
.Reset:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.myanchor-content {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
}
|
||||
.myanchor-list{
|
||||
.myanchor-list {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background-color: #E0F4F1;
|
||||
background-color: #e0f4f1;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #4fcacd;
|
||||
overflow: auto;
|
||||
@@ -801,11 +930,43 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
.myanchor-list::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.myanchor-dialog-btn{
|
||||
.myanchor-dialog-btn {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
justify-content:space-around;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
.topPosition-content {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.topPosition-content-title {
|
||||
width: 80%;
|
||||
height: 100px;
|
||||
margin-top: 50px;
|
||||
color: #999999;
|
||||
font-size: 24px;
|
||||
}
|
||||
.topPosition-input {
|
||||
width: 80%;
|
||||
margin-top: 70px;
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
.cancelTopPosition{
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.cancelTopPosition-content{
|
||||
width: 80%;
|
||||
color: #999999;
|
||||
font-size: 24px;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,23 +8,23 @@
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<div class="points-text">
|
||||
我的积分:
|
||||
我的积分:{{ user.points }}
|
||||
<div class="points-alwaysnum">
|
||||
9999999999999999999999999999999
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="points-list" style="overflow: auto;">
|
||||
<div class="points-list-item" v-for="(item, index) in pointsList" :key="index">
|
||||
<div class="points-list-content">
|
||||
<div class="points-list-content" :style="{background: item.status == 1 ? '#DFFEFC':'#FBECE9'}">
|
||||
<div class="Event">
|
||||
签到增加积分
|
||||
{{ item.info }}
|
||||
</div>
|
||||
<div class="points-num">
|
||||
+200
|
||||
{{ item.number }}
|
||||
</div>
|
||||
<div class="time">
|
||||
2025-08-01 14:27
|
||||
{{TimestamptolocalTime(item.time*1000) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,20 +41,48 @@ import {
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref('');
|
||||
const pointsList = ref([{},{},{},{},{},{},{},{},{},{},{},{},{},{}]);
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
import {getIntegralDetail} from "@/api/account";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {getPromiseStorage } from "@/utils/storage.js";
|
||||
import { TimestamptolocalTime } from "../../utils/timeConversion";
|
||||
const pointsList = ref([]);
|
||||
const user = ref({});//用户信息
|
||||
const page = ref(0);
|
||||
|
||||
//获取积分数据
|
||||
function getPointsList () {
|
||||
getIntegralDetail({
|
||||
page: page.value,
|
||||
size: 30,
|
||||
userId: user.value.id,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
pointsList.value.push(...res);
|
||||
})
|
||||
}
|
||||
|
||||
// 组件挂载完成后执行
|
||||
onMounted(() => {
|
||||
// 组件挂载完成后执行
|
||||
getPromiseStorage("user")
|
||||
.then((res) => {
|
||||
user.value = res;
|
||||
getPointsList()
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
const refname = ref('');
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -106,7 +134,6 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background-color:#E0F4F1;
|
||||
}
|
||||
.Event{
|
||||
color: @Supplementary-text-color;
|
||||
|
||||
@@ -7,8 +7,17 @@ import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; // 引入中文语言包
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
import GoEasy from 'goeasy'
|
||||
|
||||
const goeasy = GoEasy.getInstance({
|
||||
host:"hangzhou.goeasy.io", //若是新加坡区域:singapore.goeasy.io
|
||||
appkey:"您的common key",
|
||||
modules:['pubsub']//根据需要,传入‘pubsub’或'im’,或数组方式同时传入
|
||||
});
|
||||
|
||||
const app = createApp(App);
|
||||
app.config.globalProperties.goeasy = goeasy;
|
||||
export { goeasy };
|
||||
app.use(ElementPlus, {
|
||||
locale: zhCn, // 配置中文
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import emailRegistration from '../views/emailRegistration.vue'
|
||||
import ActivateEmail from '../views/ActivateEmail.vue'
|
||||
import { setStorage , getStorage } from '@/utils/storage.js';
|
||||
const routes = [
|
||||
{
|
||||
@@ -13,6 +14,11 @@ const routes = [
|
||||
name: 'emailRegistration',
|
||||
component: emailRegistration
|
||||
},
|
||||
{
|
||||
path: '/ActivateEmail',
|
||||
name: 'ActivateEmail',
|
||||
component: ActivateEmail
|
||||
},
|
||||
{
|
||||
path: '/nav',
|
||||
name: 'nav',
|
||||
@@ -47,23 +53,23 @@ const router = createRouter({
|
||||
routes
|
||||
})
|
||||
|
||||
// // 添加导航守卫
|
||||
// router.beforeEach((to, from, next) => {
|
||||
// // 假设你有一个方法来检查用户是否已登录
|
||||
// const isAuthenticated = () => {
|
||||
// return localStorage.getItem('token') !== null;
|
||||
// };
|
||||
// 添加导航守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
// 假设你有一个方法来检查用户是否已登录
|
||||
const isAuthenticated = () => {
|
||||
return localStorage.getItem('token') !== null;
|
||||
};
|
||||
|
||||
// // 定义需要登录才能访问的路由
|
||||
// const requiresAuth = ['nav', 'pk', 'Forum', 'Message', 'Mine'];
|
||||
// 定义需要登录才能访问的路由
|
||||
const requiresAuth = ['nav', 'pk', 'Forum', 'Message', 'Mine'];
|
||||
|
||||
// // 如果需要登录且用户未登录,则重定向到登录页面
|
||||
// if (requiresAuth.includes(to.name) && !isAuthenticated()) {
|
||||
// next({ name: 'login' });
|
||||
// } else {
|
||||
// next();
|
||||
// }
|
||||
// });
|
||||
// 如果需要登录且用户未登录,则重定向到登录页面
|
||||
if (requiresAuth.includes(to.name) && !isAuthenticated()) {
|
||||
next({ name: 'login' });
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
export default router
|
||||
|
||||
|
||||
21
src/utils/goeasy.js
Normal file
21
src/utils/goeasy.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { goeasy } from '../main'
|
||||
|
||||
export function goEasyLink(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
goeasy.connect({
|
||||
id:data.id, //im必填,最大长度60字符
|
||||
data:{"avatar":data.avatar,"nickname":data.nickname},
|
||||
otp:data.key,
|
||||
onSuccess: function () { //连接成功
|
||||
console.log("连接成功");
|
||||
resolve(true);
|
||||
},
|
||||
onFailed: function (error) { //连接失败
|
||||
console.log("连接失败,错误码:" + error.code + ",错误信息:" + error.content);
|
||||
},
|
||||
onProgress:function(attempts) { //连接或自动重连中
|
||||
console.log("正在重连中..." + attempts);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
@@ -24,7 +24,9 @@ export function getPromiseStorage(key) {
|
||||
}
|
||||
});
|
||||
}
|
||||
//清除localStorage
|
||||
export function clearStorage() {
|
||||
window.localStorage.clear();
|
||||
// 删除特定的localStorage项
|
||||
export function clearStorage(key) {
|
||||
if (key) {
|
||||
window.localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
95
src/views/ActivateEmail.vue
Normal file
95
src/views/ActivateEmail.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="activate-email">
|
||||
<div class="activate-email-content">
|
||||
您的邮箱{{ user.email }},尚未激活,请在您的邮箱中点击激活链接激活您的账号。
|
||||
</div>
|
||||
<div class="activate-email-btn" @click="sendActivateEmail">
|
||||
重发激活邮件
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
import {getPromiseStorage} from '@/utils/storage.js';
|
||||
import {resendEmail} from "@/api/account";
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage } from "element-plus";
|
||||
const router = useRouter();
|
||||
const refname = ref('');
|
||||
|
||||
function sendActivateEmail() {
|
||||
resendEmail({
|
||||
mailAddress:user.value.email,
|
||||
type:1
|
||||
}).then(res => {
|
||||
ElMessage.success('激活邮件已发送,请注意查收。');
|
||||
router.push('/');
|
||||
}).catch(err => {
|
||||
ElMessage.error('激活邮件发送失败,请稍后再试。');
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
const user = ref({});
|
||||
onMounted(() => {
|
||||
getPromiseStorage('user').then(res => {
|
||||
console.log(res);
|
||||
user.value = res;
|
||||
});
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.activate-email{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-image: url(@/assets/bg.png);
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.activate-email-content{
|
||||
font-size: 30px;
|
||||
color: #4FCACD;
|
||||
font-weight: bold;
|
||||
}
|
||||
.activate-email-btn{
|
||||
background-color: #4FCACD;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin-top: 50px;
|
||||
}
|
||||
.activate-email-btn:hover{
|
||||
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3);
|
||||
transform: scale(1.08);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.activate-email-btn:active{
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
</style>
|
||||
@@ -25,7 +25,7 @@
|
||||
size="large"
|
||||
class="input-text"
|
||||
v-model="refEmail"
|
||||
placeholder="请输入邮箱"
|
||||
placeholder="请输入邮箱或用户名"
|
||||
/>
|
||||
</div>
|
||||
<div class="input-Password">
|
||||
@@ -64,6 +64,7 @@ import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { tokenStore, UserStore } from '@/stores/notice'
|
||||
import { setStorage , getStorage } from '@/utils/storage.js';
|
||||
import { goEasyLink } from '@/utils/goeasy.js';
|
||||
const router = useRouter();
|
||||
const refname = ref("");
|
||||
const refEmail = ref(""); // 邮箱
|
||||
@@ -74,29 +75,42 @@ const token = tokenStore()
|
||||
const user = UserStore()
|
||||
// 登录
|
||||
function EmailLogin() {
|
||||
// 邮箱验证
|
||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
if (!emailRegex.test(refEmail.value)) {
|
||||
ElMessage.error("请输入有效的邮箱地址");
|
||||
return;
|
||||
}
|
||||
// // 邮箱验证
|
||||
// const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
// if (!emailRegex.test(refEmail.value)) {
|
||||
// ElMessage.error("请输入有效的邮箱地址");
|
||||
// return;
|
||||
// }
|
||||
// 密码验证
|
||||
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{6,16}$/;
|
||||
if (!passwordRegex.test(refpassword.value)) {
|
||||
ElMessage.error("密码必须包含大小写字母和数字,长度6-16位");
|
||||
return;
|
||||
}
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: "登录中.....",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
});
|
||||
|
||||
login({
|
||||
email: refEmail.value,
|
||||
userNameOrEmail: refEmail.value,
|
||||
// email: refEmail.value,
|
||||
password: refpassword.value,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
token.setToken(res.token);
|
||||
setStorage("token", res.token);
|
||||
setStorage("email", refEmail.value);
|
||||
setStorage("password", refpassword.value);
|
||||
user.setUser(res);
|
||||
setStorage("user", res);
|
||||
router.push("/nav");
|
||||
// otp/getopt 调用
|
||||
goEasyLink().then(() => {
|
||||
loading.close();
|
||||
router.push("/nav");
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
// 登录切换
|
||||
@@ -145,6 +159,8 @@ watch(refname, async (newQuestion, oldQuestion) => {
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
refEmail.value = getStorage("email");
|
||||
refpassword.value = getStorage("password");
|
||||
// 初始化获取二维码
|
||||
fetchQrcode();
|
||||
// 设置每两分钟轮询一次
|
||||
@@ -164,7 +180,7 @@ onUnmounted(() => {
|
||||
margin: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-image: url(../assets/bg.png);
|
||||
background-image: url(@/assets/bg.png);
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
<div class="Email">
|
||||
<el-input type="text" size="large" class="input-item" v-model="Email" placeholder="请输入邮箱" />
|
||||
</div>
|
||||
<div class="Email">
|
||||
<el-input type="text" size="large" class="input-item" v-model="userName" placeholder="请输入用户名" @blur="userNameBlur"/>
|
||||
</div>
|
||||
<div class="Password">
|
||||
<el-input type="Password" size="large" class="input-item" v-model="Password" show-password placeholder="请输入密码" />
|
||||
<text class="password-tip">您的密码必须包含大小字母和数字,长度在6-16位之间</text>
|
||||
@@ -26,7 +29,7 @@
|
||||
</div>
|
||||
<div class="btn">
|
||||
<div class="Return" @click="Return">返回</div>
|
||||
<div class="nextStep"@click="nextStep">下一步</div>
|
||||
<div class="nextStep" @click="nextStep" >下一步</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 完成注册 -->
|
||||
@@ -43,7 +46,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { register,checkStatus,resendEmail} from "@/api/account"; // 导入登录接口
|
||||
import { register,checkStatus,resendEmail,checkUsername} from "@/api/account"; // 导入登录接口
|
||||
import { tokenStore, UserStore } from '@/stores/notice'
|
||||
import { setStorage , getStorage } from '@/utils/storage.js';
|
||||
import {
|
||||
@@ -58,12 +61,36 @@ import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
const active = ref(0);// 当前步骤
|
||||
const Email = ref("");// 邮箱
|
||||
const userName = ref("");// 用户名
|
||||
const Password = ref("");// 密码
|
||||
const ConfirmPassword = ref("");// 确认密码
|
||||
const token = tokenStore()
|
||||
const user = UserStore()
|
||||
const userNamebtn = ref(false)
|
||||
// 用户名失去焦点
|
||||
function userNameBlur() {
|
||||
if (userName.value.length < 6 || userName.value.length > 16 || userName.value == '' || userName.value == null) {
|
||||
ElMessage.error('用户名长度不能小于2,不能大于16,不能为空');
|
||||
return;
|
||||
}
|
||||
checkUsername({ userName: userName.value }).then(res => {
|
||||
if (res==false) {
|
||||
ElMessage.error('用户名已存在');
|
||||
userNamebtn.value = false
|
||||
return;
|
||||
} else {
|
||||
ElMessage.success('用户名可用');
|
||||
userNamebtn.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
//下一步
|
||||
function nextStep() {
|
||||
//用户名验证
|
||||
if (userNamebtn.value == false) {
|
||||
ElMessage.error('用户名已存在');
|
||||
return;
|
||||
}
|
||||
// 邮箱验证
|
||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
if (!emailRegex.test(Email.value)) {
|
||||
@@ -78,12 +105,18 @@ function nextStep() {
|
||||
return;
|
||||
}
|
||||
|
||||
//用户名验证
|
||||
if (userName.value.length < 6 || userName.value.length > 16 || userName.value == '' || userName.value == null) {
|
||||
ElMessage.error('用户名长度不能小于2,不能大于16,不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
// 确认密码验证
|
||||
if (Password.value !== ConfirmPassword.value) {
|
||||
ElMessage.error('两次输入的密码不一致');
|
||||
return;
|
||||
}
|
||||
register({password: Password.value, email: Email.value, nickName: '用户' + Math.floor(Math.random() * 1000000),headerIcon:'181754562968_.pic_hd.jpg'}).then(res => {
|
||||
register({ userName: userName.value,password: Password.value, email: Email.value, nickName: '用户' + Math.floor(Math.random() * 1000000),headerIcon:'181754562968_.pic_hd.jpg'}).then(res => {
|
||||
active.value = active.value + 1;
|
||||
check(res.id);
|
||||
token.setToken(res.token);
|
||||
@@ -195,14 +228,14 @@ onUnmounted(() => {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.Email{
|
||||
margin-top: 70px;
|
||||
margin-top: 30px;
|
||||
width: 90%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.Password{
|
||||
margin-top: 50px;
|
||||
margin-top: 30px;
|
||||
width: 90%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -210,7 +243,7 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
}
|
||||
.ConfirmPassword{
|
||||
margin-top: 50px;
|
||||
margin-top: 30px;
|
||||
width: 90%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -89,6 +89,6 @@ onUnmounted(() => {
|
||||
}
|
||||
.card-body{
|
||||
color: #333333;
|
||||
font-size: 24px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -645,6 +645,10 @@ onUnmounted(() => {
|
||||
background-size: 100% 100%;
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
.search:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.search:hover {
|
||||
transform: scale(1.2);
|
||||
opacity: 0.8;
|
||||
@@ -653,6 +657,10 @@ onUnmounted(() => {
|
||||
transform: scale(1.2);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.primary:active {
|
||||
transition: all 0.1s ease;
|
||||
transform: scale(0.95) !important;
|
||||
}
|
||||
.infinite-list {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user