Compare commits
2 Commits
c3b84946fb
...
b3d9b0c100
| Author | SHA1 | Date | |
|---|---|---|---|
| b3d9b0c100 | |||
| 66b004d6bf |
60
App.vue
60
App.vue
@@ -1,29 +1,55 @@
|
|||||||
<script>
|
<script>
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
import update from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
|
import update from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
|
||||||
|
|
||||||
// #endif
|
// #endif
|
||||||
export default {
|
import { useUserStore } from '@/stores/user'
|
||||||
onLaunch: function() {
|
export default {
|
||||||
console.log('App Launch')
|
onLaunch: function() {
|
||||||
|
const userStore = useUserStore()
|
||||||
|
console.log('App Launch')
|
||||||
|
// 保存原生 switchTab 方法
|
||||||
|
const originalSwitchTab = uni.switchTab;
|
||||||
|
uni.switchTab = (options) => {
|
||||||
|
if (options.url.includes('/pages/book/index') && !userStore.token) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '请先登录后访问该页面',
|
||||||
|
confirmText: '去登录',
|
||||||
|
success: (res) => {
|
||||||
|
console.log(res, 'res');
|
||||||
|
if (res.confirm) uni.navigateTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return; // 拦截跳转
|
||||||
|
}
|
||||||
|
// 已登录/非拦截页 → 执行原生跳转
|
||||||
|
originalSwitchTab.call(uni, options);
|
||||||
|
}
|
||||||
// 检测自动更新
|
// 检测自动更新
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
update();
|
update();
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
onShow: function() {
|
onShow: function() {
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
},
|
},
|
||||||
onHide: function() {
|
onHide: function() {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
}
|
},
|
||||||
}
|
onTabItemTap: function() {
|
||||||
|
console.log('点击了');
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "@/style/tailwind.css";
|
@import "@/style/tailwind.css";
|
||||||
@import "@/style/ui.scss";
|
@import "@/style/ui.scss";
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -7,8 +7,8 @@ export const ENV = process.env.NODE_ENV || 'development';
|
|||||||
*/
|
*/
|
||||||
const BASE_URL_MAP = {
|
const BASE_URL_MAP = {
|
||||||
development: {
|
development: {
|
||||||
// MAIN: 'http://192.168.110.100:9300/pb/', // 张川川
|
MAIN: 'http://192.168.110.100:9300/pb/', // 张川川
|
||||||
MAIN: 'https://global.nuttyreading.com/', // 线上
|
//MAIN: 'https://global.nuttyreading.com/', // 线上
|
||||||
// PAYMENT: 'https://dev-pay.example.com', // 暂时用不到
|
// PAYMENT: 'https://dev-pay.example.com', // 暂时用不到
|
||||||
// CDN: 'https://cdn-dev.example.com', // 暂时用不到
|
// CDN: 'https://cdn-dev.example.com', // 暂时用不到
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
import { mainClient } from '@/api/clients/main'
|
import { mainClient } from '@/api/clients/main'
|
||||||
import type { IApiResponse } from '@/api/types'
|
import type { IApiResponse } from '@/api/types'
|
||||||
import type { IAgreement } from '@/types/user'
|
import type { IAgreement } from '@/types/user'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const commonApi = {
|
export const commonApi = {
|
||||||
/**
|
/**
|
||||||
@@ -36,8 +39,9 @@ export const commonApi = {
|
|||||||
* @returns 消息列表
|
* @returns 消息列表
|
||||||
*/
|
*/
|
||||||
getMessageList(isBook: number, isMedical: number, isSociology: number) {
|
getMessageList(isBook: number, isMedical: number, isSociology: number) {
|
||||||
|
const userStore = useUserStore()
|
||||||
return mainClient.request<IMessageListResponse>({
|
return mainClient.request<IMessageListResponse>({
|
||||||
url: 'common/message/listByPage',
|
url: userStore.token ? 'common/message/listByPage' : '/visitor/listByPage',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: { isBook, isMedical, isSociology }
|
data: { isBook, isMedical, isSociology }
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import type {
|
|||||||
} from '@/types/course'
|
} from '@/types/course'
|
||||||
import type { ISearchRequest, ISearchResponse } from '@/types/search'
|
import type { ISearchRequest, ISearchResponse } from '@/types/search'
|
||||||
import type { ICommentListResponse, IAddCommentResponse, IComment } from '@/types/comment'
|
import type { ICommentListResponse, IAddCommentResponse, IComment } from '@/types/comment'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
|
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
|
||||||
|
|
||||||
@@ -57,8 +60,9 @@ export const courseApi = {
|
|||||||
page: number,
|
page: number,
|
||||||
limit: number
|
limit: number
|
||||||
}) {
|
}) {
|
||||||
|
const userStore = useUserStore()
|
||||||
return client.request<IMarketCourseListResponse>({
|
return client.request<IMarketCourseListResponse>({
|
||||||
url: 'medical/home/getMarketCourseList',
|
url: userStore.token ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import type {
|
|||||||
IMarketCourseListResponse,
|
IMarketCourseListResponse,
|
||||||
ICourseMedicalLabelsResponse
|
ICourseMedicalLabelsResponse
|
||||||
} from '@/types/course'
|
} from '@/types/course'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
|
|
||||||
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
|
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
|
||||||
|
|
||||||
@@ -20,8 +22,9 @@ export const courseSubjectClassificationApi = {
|
|||||||
* @returns 分类数据
|
* @returns 分类数据
|
||||||
*/
|
*/
|
||||||
getCourseMedicalTree() {
|
getCourseMedicalTree() {
|
||||||
|
const userStore = useUserStore()
|
||||||
return client.request<ICourseCategoryResponse>({
|
return client.request<ICourseCategoryResponse>({
|
||||||
url: 'medical/home/getCourseMedicalTree',
|
url: userStore.token ? 'medical/home/getCourseMedicalTree' : '/visitor/getCourseMedicalTree',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {}
|
data: {}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -329,4 +329,32 @@ export async function getUserMigrateInfo() {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
})
|
})
|
||||||
return res
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我的湖分
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
export async function getUserContributionData() {
|
||||||
|
const res = await mainClient.request<IApiResponse>({
|
||||||
|
url: 'common/userContribution/getUserContribution',
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 湖分列表
|
||||||
|
* @param current 当前页码
|
||||||
|
* @param limit 每页数量
|
||||||
|
* @param type 湖分类型
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
export async function getUserContributionByTypeList(current : number, limit : number, type : string,) {
|
||||||
|
const res = await mainClient.request<IApiResponse>({
|
||||||
|
url: 'common/userContribution/getUserContributionByType',
|
||||||
|
method: 'POST',
|
||||||
|
data: { current, limit, type, }
|
||||||
|
})
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
1014
locale/en.json
1014
locale/en.json
File diff suppressed because it is too large
Load Diff
1016
locale/zh-Hans.json
1016
locale/zh-Hans.json
File diff suppressed because it is too large
Load Diff
23
pages.json
23
pages.json
@@ -67,6 +67,24 @@
|
|||||||
"navigationBarTitleText": "%user.feedback%",
|
"navigationBarTitleText": "%user.feedback%",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
|
},{
|
||||||
|
"path": "pages/user/certificate/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%user.certificate%",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"path": "pages/user/hufen/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%user.hufen%",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"path": "pages/user/hufen/forDetails",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "%user.hufen%",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
"path": "pages/user/recharge/index",
|
"path": "pages/user/recharge/index",
|
||||||
"style": {
|
"style": {
|
||||||
@@ -219,6 +237,11 @@
|
|||||||
"animationDuration": 200
|
"animationDuration": 200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
"path": "pages/visitor/index",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
|
|||||||
@@ -211,7 +211,9 @@ import { commonApi } from '@/api/modules/common'
|
|||||||
import { getNotchHeight } from '@/utils/system'
|
import { getNotchHeight } from '@/utils/system'
|
||||||
// import { onPageJump } from '@/utils'
|
// import { onPageJump } from '@/utils'
|
||||||
import type { IMedicalTag, ICourse, INews } from '@/types/course'
|
import type { IMedicalTag, ICourse, INews } from '@/types/course'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 系统信息
|
// 系统信息
|
||||||
@@ -239,18 +241,21 @@ const selectedFirstLevel = ref<number>('医学') // 当前选中的一级分类
|
|||||||
* 学科点击处理
|
* 学科点击处理
|
||||||
*/
|
*/
|
||||||
const handleFirstLevelClick = (item: string) => {
|
const handleFirstLevelClick = (item: string) => {
|
||||||
selectedFirstLevel.value = item
|
getPrompt()
|
||||||
switch (item) {
|
if(!userStore.token) return
|
||||||
case '医学':
|
selectedFirstLevel.value = item
|
||||||
getMedicalTags()
|
switch (item) {
|
||||||
break
|
case '医学':
|
||||||
case '心理学':
|
getMedicalTags()
|
||||||
getSoulCateList()
|
break
|
||||||
break
|
case '心理学':
|
||||||
case '国学':
|
getSoulCateList()
|
||||||
getSociologyCateList()
|
break
|
||||||
break
|
case '国学':
|
||||||
}
|
getSociologyCateList()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 医学
|
* 医学
|
||||||
@@ -326,15 +331,19 @@ const getSociologyCateList = async () => {
|
|||||||
* 终极分类点击处理
|
* 终极分类点击处理
|
||||||
*/
|
*/
|
||||||
const curseClickJump = (item: IMedicalTag) => {
|
const curseClickJump = (item: IMedicalTag) => {
|
||||||
uni.navigateTo({
|
getPrompt()
|
||||||
url: `/pages/course/list/category?id=${item.id}&title=${item.title}&pid=${item.pid}&subject=${selectedFirstLevel.value}`
|
if(!userStore.token) return
|
||||||
})
|
uni.navigateTo({
|
||||||
|
url: `/pages/course/list/category?id=${item.id}&title=${item.title}&pid=${item.pid}&subject=${selectedFirstLevel.value}`
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面跳转统一处理
|
* 页面跳转统一处理
|
||||||
*/
|
*/
|
||||||
const onPageJump = (url: string, id?: number, title?: string) => {
|
const onPageJump = (url: string, id?: number, title?: string) => {
|
||||||
|
getPrompt()
|
||||||
|
if(!userStore.token) return
|
||||||
let targetUrl = url
|
let targetUrl = url
|
||||||
if (id !== undefined) {
|
if (id !== undefined) {
|
||||||
targetUrl += `?id=${id}`
|
targetUrl += `?id=${id}`
|
||||||
@@ -381,9 +390,12 @@ const getNewsList = async () => {
|
|||||||
* 新闻点击处理
|
* 新闻点击处理
|
||||||
*/
|
*/
|
||||||
const newsClick = (item: INews) => {
|
const newsClick = (item: INews) => {
|
||||||
uni.navigateTo({
|
getPrompt()
|
||||||
url: `/pages/news/details?newsId=${item.id}&url=${item.url}&type=${item.type}`
|
if(!userStore.token) return
|
||||||
})
|
uni.navigateTo({
|
||||||
|
url: `/pages/news/details?newsId=${item.id}&url=${item.url}&type=${item.type}`
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 精彩试听
|
// 精彩试听
|
||||||
@@ -406,31 +418,59 @@ const getTryListenList = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录提示语
|
||||||
|
*/
|
||||||
|
const getPrompt = () => {
|
||||||
|
if(!userStore.token) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '请先登录后访问该页面',
|
||||||
|
confirmText: '去登录',
|
||||||
|
success: (res) => {
|
||||||
|
console.log(res, 'res');
|
||||||
|
if (res.confirm) uni.navigateTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一请求所有数据
|
* 统一请求所有数据
|
||||||
*/
|
*/
|
||||||
const requestAll = async () => {
|
const requestAll = async () => {
|
||||||
getLearnCourse()
|
if(userStore.token){
|
||||||
getMedicalTags()
|
getLearnCourse()
|
||||||
getTryListenList()
|
}
|
||||||
getNewsList()
|
getMedicalTags()
|
||||||
|
getTryListenList()
|
||||||
|
getNewsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面挂载
|
* 页面挂载
|
||||||
*/
|
*/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
if(!userStore.token) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
});
|
||||||
|
}
|
||||||
// 重置分类索引
|
// 重置分类索引
|
||||||
currentIndex.value = 0
|
currentIndex.value = 0
|
||||||
|
|
||||||
// 请求所有数据
|
// 请求所有数据
|
||||||
requestAll()
|
requestAll()
|
||||||
|
console.log('进来了2');
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面显示
|
* 页面显示
|
||||||
*/
|
*/
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
|
console.log('进来了1');
|
||||||
// 检查是否有固定的分类选择状态
|
// 检查是否有固定的分类选择状态
|
||||||
const fixed = uni.getStorageSync('fixed')
|
const fixed = uni.getStorageSync('fixed')
|
||||||
if (fixed && currentItem.value) {
|
if (fixed && currentItem.value) {
|
||||||
|
|||||||
@@ -115,11 +115,11 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 游客体验 -->
|
<!-- 游客体验 -->
|
||||||
<!-- <view class="youke-l">
|
<view class="youke-l">
|
||||||
<view @click="onPageJump('/pages/visitor/visitor')">
|
<view @click="onPageJump('/pages/course/index')">
|
||||||
{{ $t('login.noLogin') }}
|
{{ $t('login.noLogin') }}
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 用户协议弹窗 -->
|
<!-- 用户协议弹窗 -->
|
||||||
@@ -399,7 +399,7 @@ const yszc = () => {
|
|||||||
* 页面跳转
|
* 页面跳转
|
||||||
*/
|
*/
|
||||||
const onPageJump = (url: string) => {
|
const onPageJump = (url: string) => {
|
||||||
uni.navigateTo({
|
uni.switchTab({
|
||||||
url: url,
|
url: url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
134
pages/user/certificate/index.vue
Normal file
134
pages/user/certificate/index.vue
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<view class="certificate-page">
|
||||||
|
<nav-bar :title="$t('user.certificate')"></nav-bar>
|
||||||
|
<view v-if="certificateList.length > 0">
|
||||||
|
<view style="margin: 10rpx;" >【共{{certificateList.length}}个证书】</view>
|
||||||
|
<view class="certificate-list" v-for="(item,index) in certificateList" :key="index">
|
||||||
|
<view class="certificate-list-row">
|
||||||
|
<h3>证书编号:{{item.bh}}</h3>
|
||||||
|
<text style="font-size: 26rpx; color: #999;">获得时间:{{item.time}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="certificate-certificate">
|
||||||
|
<view class="img" v-for="(i,index) in item.certificateUrl" :key="index">
|
||||||
|
<image @click="preveImg(i.url)" :src="i.url" mode="heightFix"></image>
|
||||||
|
</view>
|
||||||
|
<view class="certificate-detailed" @click="detailed(item)">详细信息</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else><wd-divider>您还未获得证书</wd-divider></view>
|
||||||
|
</view>
|
||||||
|
<wd-popup v-model="detailedState" position="bottom" :closeable="true">
|
||||||
|
<view class="detailed">
|
||||||
|
<view class="detailed-text">
|
||||||
|
证书详情
|
||||||
|
</view>
|
||||||
|
<view class="detailed-row">证书类型:<text class="text">{{detailedData.a}}</text></view>
|
||||||
|
<view class="detailed-row">获得时间:<text class="text">{{detailedData.time}}</text></view>
|
||||||
|
<view class="detailed-row">获得途径:<text class="text">{{detailedData.b}}</text></view>
|
||||||
|
</view>
|
||||||
|
</wd-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const detailedState = ref(false)
|
||||||
|
const detailedData = ref({})
|
||||||
|
|
||||||
|
// 模拟的 certificateList 数据
|
||||||
|
const certificateList = ref([
|
||||||
|
{ a: 'ZH', b: '吴门', bh: 1, time: '2025-6-20', certificateUrl: "https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/ca2140c3-d212-4d4e-9203-ddc161d50470.jpg,https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/18a7ea22-b75a-4ef6-9109-f448f45e424f.jpg" },
|
||||||
|
{ bh: 2, time: '2025-6-22', certificateUrl: "https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/ca2140c3-d212-4d4e-9203-ddc161d50470.jpg,https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/18a7ea22-b75a-4ef6-9109-f448f45e424f.jpg" }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 重新获取数据
|
||||||
|
certificateList.value = certificateList.value.map(item => {
|
||||||
|
return { ...item, certificateUrl: item.certificateUrl.split(',').map(url => ({ url })) };
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看证书详情信息
|
||||||
|
*/
|
||||||
|
const detailed = (item) => {
|
||||||
|
detailedState.value = true
|
||||||
|
detailedData.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看照片
|
||||||
|
*/
|
||||||
|
const preveImg = (url : any) => {
|
||||||
|
uni.previewImage({
|
||||||
|
urls: [url],
|
||||||
|
current: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.certificate-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f7faf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.certificate-list {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.certificate-list-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.certificate-certificate {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-top: 20rpx;
|
||||||
|
|
||||||
|
.img {
|
||||||
|
width: 36%;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 300rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.certificate-detailed {
|
||||||
|
color: #55aaff;
|
||||||
|
border: #55aaff 1px solid;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed {
|
||||||
|
padding: 20rpx;
|
||||||
|
|
||||||
|
.detailed-text {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-row {
|
||||||
|
color: #999;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
font-size: 26rpx;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
113
pages/user/hufen/forDetails.vue
Normal file
113
pages/user/hufen/forDetails.vue
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<z-paging ref="paging" v-model="bookList" auto-show-back-to-top class="my-book-page" @query="hufenList"
|
||||||
|
:default-page-size="10">
|
||||||
|
<template #top>
|
||||||
|
<!-- 自定义导航栏 -->
|
||||||
|
<nav-bar :title="$t('user.hufenRecord')"></nav-bar>
|
||||||
|
</template>
|
||||||
|
<view class="recharge-record" v-if="(bookList && bookList.length > 0)">
|
||||||
|
<view class="go-gecharge">{{hufenData.nameValue}} {{$t('user.hufenRecord')}}</view>
|
||||||
|
<view class="recharge-record-block" v-for="(item, index) in bookList" :key="index">
|
||||||
|
<view class="recharge-record-block-row">{{item.createTime}}<text class="text">{{item.score}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="time">{{item.detail}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</z-paging>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { getUserContributionByTypeList } from '@/api/modules/user'
|
||||||
|
import { copyToClipboard } from '@/utils/index'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const paging = ref<any>()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 数据状态
|
||||||
|
const bookList = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const firstLoad = ref(true)
|
||||||
|
const hufenData = ref('')
|
||||||
|
|
||||||
|
// 湖分记录
|
||||||
|
async function hufenList(pageNo : number, pageSize : number) {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getUserContributionByTypeList(pageNo, pageSize, hufenData.value.type)
|
||||||
|
console.log(res, 'res');
|
||||||
|
paging.value.complete(res.list.records)
|
||||||
|
} catch (error) {
|
||||||
|
paging.value.complete(false)
|
||||||
|
console.error('Failed to load book list:', error)
|
||||||
|
} finally {
|
||||||
|
firstLoad.value = false
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onLoad((options) => {
|
||||||
|
hufenData.value = options
|
||||||
|
console.log(hufenData);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.my-book-page {
|
||||||
|
background: #f7faf9;
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
.recharge-record {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
// padding: 20rpx;
|
||||||
|
margin: 20rpx;
|
||||||
|
|
||||||
|
.go-gecharge {
|
||||||
|
text-align: center;
|
||||||
|
background: linear-gradient(to right, #007bff, #17a2b8);
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
padding-left: 20rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
color: #007bff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-record-block {
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
padding: 20rpx;
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
color: #343434
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-record-block-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
// font-weight: 700;
|
||||||
|
color: #909090;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
69
pages/user/hufen/index.vue
Normal file
69
pages/user/hufen/index.vue
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<view class="recharge-page">
|
||||||
|
<nav-bar :title="$t('user.iHufen')"></nav-bar>
|
||||||
|
<view class="menu-section" v-if="hufenList.list.length > 0">
|
||||||
|
<wd-cell-group border class="menu-list">
|
||||||
|
<wd-cell v-for="item in hufenList.list" :key="item.type" :title="item.dict_value" is-link
|
||||||
|
@click="handleMenuClick(item)">
|
||||||
|
<text class="menu-list-hufen">{{item.score}}</text><text class="menu-list-hufen-text">{{$t('user.hufen')}}</text>
|
||||||
|
</wd-cell>
|
||||||
|
</wd-cell-group>
|
||||||
|
</view>
|
||||||
|
<view v-else><wd-divider>您还未获得湖分</wd-divider></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { getUserContributionData } from '@/api/modules/user'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const hufenList = ref([])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户湖分
|
||||||
|
*/
|
||||||
|
const getHufen = async () => {
|
||||||
|
hufenList.value = await getUserContributionData()
|
||||||
|
console.log(hufenList.value.list)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMenuClick = (item) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/user/hufen/forDetails?type=${item.type}&nameValue=${item.dict_value}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getHufen()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.recharge-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f7faf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-section {
|
||||||
|
padding: 20rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
.menu-list-hufen {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #007bff;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list-hufen-text {
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }">
|
<view class="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }" v-if="userStore.token">
|
||||||
<!-- 设置图标 -->
|
<!-- 设置图标 -->
|
||||||
<view class="settings-icon" :style="{ top: getNotchHeight() + 30 + 'px' }" @click="goSettings">
|
<view class="settings-icon" :style="{ top: getNotchHeight() + 30 + 'px' }" @click="goSettings">
|
||||||
<wd-icon name="setting1" size="24px" color="#666" />
|
<wd-icon name="setting1" size="24px" color="#666" />
|
||||||
@@ -23,18 +23,23 @@
|
|||||||
<view class="vip-card-title">{{ $t('user.vip') }}</view>
|
<view class="vip-card-title">{{ $t('user.vip') }}</view>
|
||||||
<view class="vip-card-content">
|
<view class="vip-card-content">
|
||||||
<view class="vip-item-list">
|
<view class="vip-item-list">
|
||||||
<view v-if="vipInfo?.length > 0" v-for="vip in vipInfo">{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
<view v-if="vipInfo?.length > 0" v-for="vip in vipInfo">
|
||||||
|
{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
||||||
<view v-else>办理课程VIP,畅享更多权益</view>
|
<view v-else>办理课程VIP,畅享更多权益</view>
|
||||||
</view>
|
</view>
|
||||||
<wd-button v-if="vipInfo?.length > 0" plain type="primary" size="small" @click="goCourseVipSub">{{ $t('vip.renewal') }}</wd-button>
|
<wd-button v-if="vipInfo?.length > 0" plain type="primary" size="small"
|
||||||
<wd-button v-else plain type="primary" size="small" @click="goCourseVipSub">{{ $t('vip.openVip') }}</wd-button>
|
@click="goCourseVipSub">{{ $t('vip.renewal') }}</wd-button>
|
||||||
|
<wd-button v-else plain type="primary" size="small"
|
||||||
|
@click="goCourseVipSub">{{ $t('vip.openVip') }}</wd-button>
|
||||||
</view>
|
</view>
|
||||||
<view class="vip-card-content">
|
<view class="vip-card-content">
|
||||||
<view class="vip-item-list">
|
<view class="vip-item-list">
|
||||||
<view v-if="vipInfoEbook?.length > 0" v-for="vip in vipInfoEbook">电子书VIP{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
<view v-if="vipInfoEbook?.length > 0" v-for="vip in vipInfoEbook">
|
||||||
|
电子书VIP{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
||||||
<view v-else>办理电子书VIP,畅享更多权益</view>
|
<view v-else>办理电子书VIP,畅享更多权益</view>
|
||||||
</view>
|
</view>
|
||||||
<wd-button v-if="!vipInfoEbook?.length" plain type="primary" size="small" @click="goSubscribe">{{ $t('vip.openVip') }}</wd-button>
|
<wd-button v-if="!vipInfoEbook?.length" plain type="primary" size="small"
|
||||||
|
@click="goSubscribe">{{ $t('vip.openVip') }}</wd-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -65,22 +70,28 @@
|
|||||||
<!-- 功能菜单列表 -->
|
<!-- 功能菜单列表 -->
|
||||||
<view class="menu-section">
|
<view class="menu-section">
|
||||||
<wd-cell-group border class="menu-list">
|
<wd-cell-group border class="menu-list">
|
||||||
<wd-cell v-for="item in menuItems" :key="item.id" :title="item.name" :label="item.desc" is-link @click="handleMenuClick(item)" />
|
<wd-cell v-for="item in menuItems" :key="item.id" :title="item.name" :label="item.desc" is-link
|
||||||
|
@click="handleMenuClick(item)">
|
||||||
|
<text v-if="item.hufenState" class="menu-list-hufen">{{hufenData.total ?? 0}}<text
|
||||||
|
style="margin-left: 6rpx;">湖分</text></text>
|
||||||
|
</wd-cell>
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<visitor v-else></visitor>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
import { useSysStore } from '@/stores/sys'
|
import { useSysStore } from '@/stores/sys'
|
||||||
import { getUserInfo, getVipInfo } from '@/api/modules/user'
|
import { getUserInfo, getVipInfo, getUserContributionData } from '@/api/modules/user'
|
||||||
import type { IVipInfo } from '@/types/user'
|
import type { IVipInfo } from '@/types/user'
|
||||||
import { getNotchHeight } from '@/utils/system'
|
import { getNotchHeight } from '@/utils/system'
|
||||||
import { parseTime } from '@/utils/index'
|
import { parseTime } from '@/utils/index'
|
||||||
import { t } from '@/utils/i18n'
|
import { t } from '@/utils/i18n'
|
||||||
import { onShow } from '@dcloudio/uni-app'
|
import { onShow } from '@dcloudio/uni-app'
|
||||||
|
import visitor from '@/pages/visitor/index.vue';
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const sysStore = useSysStore()
|
const sysStore = useSysStore()
|
||||||
@@ -140,7 +151,22 @@
|
|||||||
// desc: t('user.migrateSubtitle'),
|
// desc: t('user.migrateSubtitle'),
|
||||||
// type: 'pageJump'
|
// type: 'pageJump'
|
||||||
// }
|
// }
|
||||||
|
// {
|
||||||
|
// id: 7,
|
||||||
|
// name: t('user.certificate'),
|
||||||
|
// url: '/pages/user/certificate/index',
|
||||||
|
// type: 'pageJump'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
name: t('user.iHufen'),
|
||||||
|
url: '/pages/user/hufen/index',
|
||||||
|
type: 'pageJump',
|
||||||
|
hufenState: true
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
// 湖分
|
||||||
|
const hufenData = ref('')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取平台信息
|
* 获取平台信息
|
||||||
@@ -161,6 +187,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户湖分
|
||||||
|
*/
|
||||||
|
const getHufen = async () => {
|
||||||
|
hufenData.value = await getUserContributionData()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跳转到设置页面
|
* 跳转到设置页面
|
||||||
*/
|
*/
|
||||||
@@ -243,11 +276,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
getData()
|
console.log(userInfo, 'userInfo');
|
||||||
|
if (userStore.token) {
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPlatform()
|
console.log(userInfo, 'userInfo');
|
||||||
|
if (userStore.token) {
|
||||||
|
getPlatform()
|
||||||
|
getHufen()
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -394,6 +436,16 @@
|
|||||||
border-radius: 15rpx;
|
border-radius: 15rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
.menu-list-hufen {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #007bff;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chong_btn {
|
.chong_btn {
|
||||||
|
|||||||
138
pages/visitor/index.vue
Normal file
138
pages/visitor/index.vue
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<template>
|
||||||
|
<view class="visitor">
|
||||||
|
<view class="visitor-block">
|
||||||
|
<view style="display: flex;">
|
||||||
|
<image class="visitor_img" src="/static/logo.png" mode="aspectFil">
|
||||||
|
</image>
|
||||||
|
<text class="visitor-text" @click="gologin">立即登录</text>
|
||||||
|
</view>
|
||||||
|
<wd-cell-group border class="visitor-list">
|
||||||
|
<wd-cell v-for="item in menuItems" :title="item.name" is-link @click="handleMenuClick(item)">
|
||||||
|
</wd-cell>
|
||||||
|
</wd-cell-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<wd-action-sheet v-model="isShareSheetOpen" title="选择分享渠道" :panels="panels" @select="handleShare" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const menuItems = ref([
|
||||||
|
{
|
||||||
|
name: '分享APP'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '关于我们',
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const isShareSheetOpen = ref(false)
|
||||||
|
|
||||||
|
const panels = ref([
|
||||||
|
{
|
||||||
|
iconUrl: '/static/contact-person.png',
|
||||||
|
title: '微信消息'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
iconUrl: '/static/moments.png',
|
||||||
|
title: '朋友圈'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
// 打开分享菜单
|
||||||
|
const openShareSheet = () => {
|
||||||
|
isShareSheetOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择分享渠道后执行分享逻辑
|
||||||
|
const handleShare = (action) => {
|
||||||
|
console.log(action, 'action');
|
||||||
|
isShareSheetOpen.value = false // 关闭菜单
|
||||||
|
if (action.index == 0) {
|
||||||
|
// 分享到好友
|
||||||
|
uni.share({
|
||||||
|
provider: "weixin",
|
||||||
|
scene: "WXSceneSession",
|
||||||
|
type: 0,
|
||||||
|
href: '',
|
||||||
|
title: "吴门医述",
|
||||||
|
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
|
||||||
|
imageUrl: "static/icon/home_icon_logo.png",
|
||||||
|
success: function (res) {
|
||||||
|
console.log("success:" + JSON.stringify(res));
|
||||||
|
},
|
||||||
|
fail: function (err) {
|
||||||
|
console.log("fail:" + JSON.stringify(err));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (action.index == 1) {
|
||||||
|
// 分享到朋友圈
|
||||||
|
uni.share({
|
||||||
|
provider: "weixin",
|
||||||
|
scene: "WXSceneTimeline",
|
||||||
|
type: 0,
|
||||||
|
href: '',
|
||||||
|
title: "吴门医述",
|
||||||
|
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
|
||||||
|
imageUrl: "static/icon/home_icon_logo.png",
|
||||||
|
success: function (res) {
|
||||||
|
console.log("success:" + JSON.stringify(res));
|
||||||
|
},
|
||||||
|
fail: function (err) {
|
||||||
|
console.log("fail:" + JSON.stringify(err));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleMenuClick = (item : { name : string }) => {
|
||||||
|
if (item.name === '关于我们') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/user/about/index'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
isShareSheetOpen.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const gologin = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.visitor {
|
||||||
|
background: #f4f7ff;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visitor-block {
|
||||||
|
padding: 40rpx 20rpx;
|
||||||
|
|
||||||
|
.visitor_img {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visitor-text {
|
||||||
|
margin-top: 30rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 36rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.visitor-list {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
static/contact-person.png
Normal file
BIN
static/contact-person.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/moments.png
Normal file
BIN
static/moments.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Reference in New Issue
Block a user