make page

This commit is contained in:
zzc
2026-01-15 08:43:10 +08:00
parent f34899eb81
commit 3d2d20dd5f
21 changed files with 4315 additions and 737 deletions

16
api/card.js Normal file
View File

@@ -0,0 +1,16 @@
import { request } from "@/utils/request.js";
export const getCardDetail = async (shareToken) => {
return request({
url: "/api/blessing/card?shareToken=" + shareToken,
method: "GET",
});
};
export const createCardShareToken = async (data) => {
return request({
url: "/api/blessing/card/share",
method: "POST",
data,
});
};

17
api/make.js Normal file
View File

@@ -0,0 +1,17 @@
import { request } from "@/utils/request.js";
export const createCardTmp = async (data) => {
return request({
url: "/api/blessing/card/template",
method: "POST",
data,
});
};
export const updateCard = async (data) => {
return request({
url: "/api/blessing/card",
method: "PUT",
data,
});
};

View File

@@ -30,8 +30,6 @@ import { getPlatformProvider } from '@/utils/system'
import { apiLogin } from '@/api/auth.js'
import { wxLogin } from '@/utils/login.js'
// import { connectSocket, sendSocketMessage } from '@/utils/socket.js'
const popupRef = ref(null)
const avatarUrl = ref('')
const nickname = ref('')
@@ -61,17 +59,17 @@ const confirmLogin = async () => {
// console.log('准备登录:', { code, nickname: nickname.value, avatarUrl: 'http://tmp/HXhtcEwQ5A3B58476c91ba545ab67c6bf9c67d9c2559.jpeg' })
const fileKeyRes = await uni.uploadFile({
url: 'https://apis.lihailezzc.com/api/common/upload',
url: 'https://api.ai-meng.com/api/common/upload',
filePath: avatarUrl.value,
name: 'file', // 和后端接收文件字段名一致
header: {
'x-app-id': '6846f093fdf841f6189ef0b5',
'x-app-id': '69665538a49b8ae3be50fe5d',
},
})
if(fileKeyRes.statusCode < 400) {
const keyJson = JSON.parse(fileKeyRes.data)
const url = `https://file.lihailezzc.com/${keyJson?.data.key}`
const loginRes = await apiLogin({ code, nickname: nickname.value, avatarUrl: url })
const loginRes = await apiLogin({ code, nickname: nickname.value, avatarUrl: url, platform: 'wx' })
// 保存用户信息到store
userStore.setUserInfo({
nickName: loginRes?.user?.nickname || nickname.value,
@@ -85,8 +83,6 @@ const confirmLogin = async () => {
emit('logind')
popupRef.value.close()
// connectSocket()
// 重置临时变量
avatarUrl.value = ''
nickname.value = ''

View File

@@ -50,7 +50,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx397b136a586c5667",
"appid" : "wx3fcc07a061af049a",
"setting" : {
"urlCheck" : false
},

View File

@@ -6,7 +6,8 @@
"navigationBarTitleText": "新春祝福",
"enablePullDownRefresh": true,
"navigationStyle": "custom",
"backgroundColor": "#FFFFFF"
"backgroundColor": "#FFFFFF",
"enableShareAppMessage": true
}
},
{
@@ -24,6 +25,14 @@
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/detail/index",
"style": {
"navigationBarTitleText": "新春祝福详情",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
],
"globalStyle": {
@@ -45,7 +54,7 @@
"selectedIconPath": "static/images/tabBar/home_s.png"
},
{
"text": "讨论",
"text": "制作",
"pagePath": "pages/make/index",
"iconPath": "static/images/tabBar/message.png",
"selectedIconPath": "static/images/tabBar/message_s.png"

524
pages/detail/index.vue Normal file
View File

@@ -0,0 +1,524 @@
<template>
<view class="detail-page" :style="{ paddingTop: navBarHeight + 'px' }">
<!-- Custom Navigation Bar -->
<view
class="nav-bar"
:style="{
height: navBarHeight + 'px',
paddingTop: statusBarHeight + 'px',
}"
>
<text class="nav-title">新春祝福详情</text>
</view>
<scroll-view scroll-y class="content-scroll">
<view class="content-wrap">
<!-- User Info -->
<view class="user-header">
<image
class="avatar"
:src="
cardDetail?.from?.avatar ||
'https://file.lihailezzc.com/resource/b48c41054c2633c478463ac1b1f1ca23.png'
"
mode="aspectFill"
/>
<view class="user-meta">
<view class="user-name">{{ cardDetail?.blessingFrom }}</view>
<view class="user-msg">给你发来了一条新春祝福</view>
<view class="year-tag">
<text class="fire-icon">🎉</text> {{ cardDetail?.year || 2026 }}
{{ cardDetail?.festival || "丙午马年" }}
</view>
</view>
</view>
<!-- Card Preview Area -->
<view class="card-container">
<view class="card-inner">
<image
class="card-img"
:src="cardDetail?.imageUrl"
mode="widthFix"
/>
</view>
</view>
<!-- Action Buttons -->
<view class="action-buttons">
<button class="btn primary" @tap="makeGreeting">
<text class="btn-icon"></text> 我也要制作回赠祝福
</button>
<button class="btn secondary" @tap="saveCard">
<text class="btn-icon">📥</text> 保存这张精美贺卡
</button>
</view>
<!-- Recommendations -->
<view class="recommend-section">
<view class="section-header">
<text class="section-title">大家都在玩的头像挂饰</text>
<text class="more-link">查看更多</text>
</view>
<scroll-view scroll-x class="decor-scroll" show-scrollbar="false">
<view class="decor-list">
<view
class="decor-item"
v-for="(item, index) in decorList"
:key="index"
>
<view class="decor-img-box" :class="'style-' + (index % 3)">
<image :src="item.img" mode="aspectFit" class="decor-img" />
</view>
<text class="decor-name">{{ item.name }}</text>
</view>
</view>
</scroll-view>
</view>
<!-- Banner -->
<view class="banner-card">
<view class="banner-icon">
<image
src="/static/logo.png"
mode="aspectFit"
style="width: 100%; height: 100%"
v-if="false"
/>
<view class="placeholder-icon"></view>
</view>
<view class="banner-content">
<view class="banner-title">领取我的马年头像框</view>
<view class="banner-desc">定制专属新春社交形象</view>
</view>
<button class="banner-btn">去领取</button>
</view>
<!-- Footer -->
<view class="page-footer">
<view class="footer-line">
<text class="line"></text>
<text class="text">2026 HAPPY NEW YEAR</text>
<text class="line"></text>
</view>
<view class="footer-sub">新春祝福 · 传递温情</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getBavBarHeight } from "@/utils/system";
import { onLoad } from "@dcloudio/uni-app";
import { getCardDetail } from "@/api/card.js";
const navBarHeight = ref(44);
const statusBarHeight = ref(20);
const cardId = ref("");
const cardDetail = ref({});
onLoad(async (options) => {
if (options.shareToken) {
const card = await getCardDetail(options.shareToken);
cardId.value = card.id;
cardDetail.value = card;
}
});
onMounted(() => {
const sysInfo = uni.getSystemInfoSync();
statusBarHeight.value = sysInfo.statusBarHeight;
navBarHeight.value = getBavBarHeight();
});
const goBack = () => {
uni.navigateBack();
};
const makeGreeting = () => {
uni.switchTab({ url: "/pages/make/index" });
};
const saveCard = async () => {
uni.showLoading({ title: "保存中..." });
const localPath = await loadImage(cardDetail?.value?.imageUrl || "");
uni.saveImageToPhotosAlbum({
filePath: localPath,
success() {
uni.hideLoading();
uni.showToast({ title: "已保存到相册" });
},
fail(err) {
uni.hideLoading();
// handleSaveAuth(err);
},
});
};
const loadImage = (url) => {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: url,
success: (res) => {
resolve(res.path); // 本地路径
},
fail: (err) => {
reject(err);
},
});
});
};
const decorList = ref([
{
name: "如意马年",
img: "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
},
{
name: "大吉大利",
img: "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
},
{
name: "春意盎然",
img: "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
},
{
name: "万事顺遂",
img: "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
},
]);
</script>
<style lang="scss" scoped>
.detail-page {
min-height: 100vh;
background: #fff;
background-image: linear-gradient(to bottom, #fff6f6 0%, #fff 400rpx);
box-sizing: border-box;
}
.nav-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
align-items: center;
padding-left: 20rpx;
background: #fff6f6; /* Match page bg */
}
.nav-left {
padding: 10rpx 20rpx;
font-size: 48rpx;
line-height: 1;
}
.nav-title {
font-size: 32rpx;
font-weight: 600;
margin-left: 10rpx;
}
.content-scroll {
height: 100%;
}
.content-wrap {
padding: 20rpx 30rpx 60rpx;
}
/* User Header */
.user-header {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
margin-right: 24rpx;
border: 4rpx solid rgba(215, 180, 150, 0.3);
}
.user-meta {
display: flex;
flex-direction: column;
}
.user-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.user-msg {
font-size: 24rpx;
color: #666;
margin-top: 4rpx;
}
.year-tag {
display: inline-flex;
align-items: center;
margin-top: 8rpx;
font-size: 20rpx;
color: #ff3b30;
background: rgba(255, 59, 48, 0.08);
padding: 4rpx 12rpx;
border-radius: 8rpx;
align-self: flex-start;
}
.fire-icon {
margin-right: 6rpx;
}
/* Card Container */
.card-container {
background: #fff;
border-radius: 24rpx;
overflow: hidden;
box-shadow: 0 16rpx 40rpx rgba(0, 0, 0, 0.08);
margin-bottom: 40rpx;
margin: 24rpx auto;
}
.card-inner {
position: relative;
margin: 0 auto;
width: 540rpx;
height: 960rpx;
background: #f0f0f0;
}
.card-img {
width: 100%;
height: 100%;
}
.card-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 40rpx;
color: #fff;
background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
}
.card-year {
font-size: 36rpx;
letter-spacing: 10rpx;
opacity: 0.9;
text-align: center;
margin-bottom: 10rpx;
}
.card-sub {
font-size: 20rpx;
text-align: center;
opacity: 0.8;
margin-bottom: 40rpx;
}
.card-greeting-en {
font-size: 20rpx;
opacity: 0.8;
}
.card-greeting-cn {
font-size: 40rpx;
font-weight: bold;
line-height: 1.5;
margin-top: 10rpx;
}
.card-footer {
padding: 30rpx 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
}
.card-info {
display: flex;
flex-direction: column;
}
.card-info .label {
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
}
.card-info .value {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
.qr-code {
width: 80rpx;
height: 80rpx;
background: #ffecec;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
}
.qr-icon {
color: #ff3b30;
font-size: 40rpx;
}
/* Buttons */
.action-buttons {
margin-bottom: 50rpx;
}
.btn {
height: 96rpx;
border-radius: 999rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
font-weight: 600;
margin-bottom: 24rpx;
border: none;
}
.btn.primary {
background: #ff3b30;
color: #fff;
box-shadow: 0 12rpx 24rpx rgba(255, 59, 48, 0.3);
}
.btn.secondary {
background: #f5f5f5;
color: #333;
}
.btn-icon {
margin-right: 12rpx;
font-size: 36rpx;
}
/* Recommendations */
.recommend-section {
margin-bottom: 40rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
}
.section-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.more-link {
font-size: 24rpx;
color: #ff3b30;
}
.decor-list {
display: flex;
}
.decor-item {
margin-right: 24rpx;
display: flex;
flex-direction: column;
align-items: center;
width: 140rpx;
}
.decor-img-box {
width: 140rpx;
height: 140rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12rpx;
border: 4rpx solid transparent;
}
.style-0 {
border-color: #ff3b30;
background: #fff0f0;
}
.style-1 {
border-color: #d4a017;
background: #fffcf0;
}
.style-2 {
border-color: #ffadd2;
background: #fff0f5;
}
.decor-img {
width: 100rpx;
height: 100rpx;
}
.decor-name {
font-size: 22rpx;
color: #666;
}
/* Banner */
.banner-card {
background: #fff6f6;
border-radius: 24rpx;
padding: 24rpx;
display: flex;
align-items: center;
border: 2rpx solid #ffebeb;
margin-bottom: 60rpx;
}
.banner-icon {
width: 80rpx;
height: 80rpx;
background: #ff3b30;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
.placeholder-icon {
color: #fff;
font-size: 40rpx;
}
.banner-content {
flex: 1;
}
.banner-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
.banner-desc {
font-size: 22rpx;
color: #999;
margin-top: 4rpx;
}
.banner-btn {
background: #ff3b30;
color: #fff;
font-size: 24rpx;
padding: 10rpx 30rpx;
border-radius: 999rpx;
line-height: 1.5;
margin: 0;
}
/* Footer */
.page-footer {
text-align: center;
padding-bottom: 40rpx;
}
.footer-line {
display: flex;
align-items: center;
justify-content: center;
color: #ccc;
font-size: 24rpx;
font-weight: bold;
letter-spacing: 2rpx;
margin-bottom: 8rpx;
}
.line {
width: 60rpx;
height: 2rpx;
background: #ddd;
margin: 0 20rpx;
}
.footer-sub {
font-size: 20rpx;
color: #ccc;
}
</style>

View File

@@ -4,14 +4,14 @@
<view class="hero">
<view class="hero-badge">
<text class="badge-dot"></text>
<text class="badge-text">距春节还有 25 </text>
<text class="badge-text">距春节还有 30 </text>
</view>
<view class="hero-title">
<text class="year">2026</text>
<text class="main">新春祝福</text>
</view>
<text class="hero-sub">新年快乐万事如意!</text>
<image class="hero-decor" src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png" mode="aspectFill" />
<!-- <image class="hero-decor" src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png" mode="aspectFill" /> -->
</view>
<!-- 功能入口宫格 -->
@@ -22,9 +22,14 @@
class="feature-item"
@tap="onFeatureTap(item)"
>
<image class="feature-icon" :src="item.icon" mode="aspectFill" :style="{
backgroundColor: idx < 2 ? '#FEF2F2' : '#FFFBEC'
}"/>
<image
class="feature-icon"
:src="item.icon"
mode="aspectFill"
:style="{
backgroundColor: idx < 2 ? '#FEF2F2' : '#FFFBEC',
}"
/>
<view class="feature-texts">
<text class="feature-title">{{ item.title }}</text>
<text class="feature-sub">{{ item.subtitle }}</text>
@@ -53,10 +58,17 @@
<view class="use-right">
<view class="title-line">
<text class="use-title">{{ card.title }}</text>
<text v-if="card.tag" class="tag" :class="`tag--${card.tagType || 'default'}`">{{ card.tag }}</text>
<text
v-if="card.tag"
class="tag"
:class="`tag--${card.tagType || 'default'}`"
>{{ card.tag }}</text
>
</view>
<text class="use-desc">{{ card.desc }}</text>
<text class="use-cta" @tap.stop="onCta(card)">{{ card.cta }} ></text>
<text class="use-cta" @tap.stop="onCta(card)"
>{{ card.cta }} ></text
>
</view>
</view>
</view>
@@ -65,75 +77,112 @@
</template>
<script setup>
import { ref } from 'vue'
import { onPullDownRefresh } from '@dcloudio/uni-app'
import { getBavBarHeight } from '@/utils/system'
import { ref } from "vue";
import { onPullDownRefresh, onShareAppMessage } from "@dcloudio/uni-app";
import { getBavBarHeight } from "@/utils/system";
const features = ref([
{ title: '新春祝福卡片', subtitle: '定制专属贺卡', icon:'/static/icon/celebrate.png', type: 'card' },
{ title: '红包封面', subtitle: '获取新年红包封面', icon: '/static/icon/hongbao.png', type: 'video' },
{ title: '新春头像挂饰', subtitle: '焕上节日新饰', icon: '/static/icon/guashi.png', type: 'avatar_decor' },
{ title: '新年运势', subtitle: '抽取新年关键词', icon: '/static/icon/yunshi.png', type: 'avatar_frame' },
])
{
title: "新春祝福卡片",
subtitle: "定制专属贺卡",
icon: "/static/icon/celebrate.png",
type: "card",
},
{
title: "红包封面",
subtitle: "获取新年红包封面",
icon: "/static/icon/hongbao.png",
type: "video",
},
{
title: "新春头像挂饰",
subtitle: "焕上节日新饰",
icon: "/static/icon/guashi.png",
type: "avatar_decor",
},
{
title: "新年运势",
subtitle: "抽取新年关键词",
icon: "/static/icon/yunshi.png",
type: "avatar_frame",
},
]);
const popularCards = ref([
{
title: '招财进宝金框',
tag: '热门',
tagType: 'hot',
desc: '2026马年限定汉字金框金光闪烁财运亨通。适合送亲友的新春祝福。',
cta: '立即制作',
cover: 'https://file.lihailezzc.com/9a929a32-439f-453b-b603-fda7b04cbe08.png'
title: "招财进宝金框",
tag: "热门",
tagType: "hot",
desc: "2026马年限定汉字金框金光闪烁财运亨通。适合送亲友的新春祝福。",
cta: "立即制作",
cover:
"https://file.lihailezzc.com/9a929a32-439f-453b-b603-fda7b04cbe08.png",
},
{
title: '大吉大利卡片',
tag: '精选',
tagType: 'featured',
desc: '经典红色大拜年卡片,适合送长辈、老师、同学,传递满满的新春喜气。',
cta: '去写祝福',
cover: 'https://file.lihailezzc.com/b5fe8ffb-5901-48d2-94fb-48191e36cbf5.png'
title: "大吉大利卡片",
tag: "精选",
tagType: "featured",
desc: "经典红色大拜年卡片,适合送长辈、老师、同学,传递满满的新春喜气。",
cta: "去写祝福",
cover:
"https://file.lihailezzc.com/b5fe8ffb-5901-48d2-94fb-48191e36cbf5.png",
},
{
title: '合家团圆模板',
tag: '爆款',
tagType: 'hot2',
desc: '一键生成合家福贺图,支持换装、特效装饰、朋友圈海报等。',
cta: '开始创作',
cover: 'https://file.lihailezzc.com/91cd1611-bb87-442b-a338-24e9d79e4ee9.png',
type: 'video'
}
])
title: "合家团圆模板",
tag: "爆款",
tagType: "hot2",
desc: "一键生成合家福贺图,支持换装、特效装饰、朋友圈海报等。",
cta: "开始创作",
cover:
"https://file.lihailezzc.com/91cd1611-bb87-442b-a338-24e9d79e4ee9.png",
type: "video",
},
]);
const onFeatureTap = (item) => {
uni.showToast({ title: `进入:${item.title}`, icon: 'none' })
uni.showToast({ title: `进入:${item.title}`, icon: "none" });
// uni.navigateTo({ url: `/pages/${item.type}/index` })
}
};
const previewCard = (card) => {
uni.previewImage({ urls: [card.cover] })
}
uni.previewImage({ urls: [card.cover] });
};
const onMore = () => {
uni.showToast({ title: '更多模板即将上线~', icon: 'none' })
}
uni.showToast({ title: "更多模板即将上线~", icon: "none" });
};
const onCta = (card) => {
uni.showToast({ title: `${card.cta} · ${card.title}`, icon: 'none' })
}
uni.showToast({ title: `${card.cta} · ${card.title}`, icon: "none" });
};
onPullDownRefresh(() => {
setTimeout(() => {
uni.stopPullDownRefresh()
uni.showToast({ title: '已为你更新内容', icon: 'success' })
}, 600)
})
uni.stopPullDownRefresh();
uni.showToast({ title: "已为你更新内容", icon: "success" });
}, 600);
});
onShareAppMessage(() => {
return {
title: "新春祝福",
path: "/pages/detail/index",
imageUrl: "/static/images/bg.jpg",
success: function (res) {
uni.showToast({ title: "分享成功", icon: "success" });
},
fail: function (res) {
uni.showToast({ title: "分享失败", icon: "none" });
},
};
});
</script>
<style lang="scss" scoped>
.spring-page {
min-height: 100vh;
box-sizing: border-box;
background: #F8F6F6;
background: #f8f6f6;
}
/* 顶部 Banner */
@@ -152,23 +201,41 @@ onPullDownRefresh(() => {
.hero-badge {
display: inline-flex;
align-items: center;
background: rgba(255,255,255,0.2);
background: rgba(255, 255, 255, 0.2);
border-radius: 999rpx;
padding: 8rpx 16rpx;
font-size: 22rpx;
.badge-dot { margin-right: 8rpx; }
.badge-dot {
margin-right: 8rpx;
}
}
.hero-title {
margin-top: 24rpx;
display: flex;
align-items: baseline;
.year { font-size: 44rpx; font-weight: 700; margin-right: 12rpx; }
.main { font-size: 44rpx; font-weight: 700; }
.year {
font-size: 44rpx;
font-weight: 700;
margin-right: 12rpx;
}
.main {
font-size: 44rpx;
font-weight: 700;
}
}
.hero-sub {
margin-top: 8rpx;
font-size: 24rpx;
opacity: 0.9;
}
.hero-sub { margin-top: 8rpx; font-size: 24rpx; opacity: 0.9; }
.hero-decor {
position: absolute; right: 12rpx; bottom: 12rpx;
width: 160rpx; height: 160rpx; opacity: 0.3; border-radius: 16rpx;
position: absolute;
right: 12rpx;
bottom: 12rpx;
width: 160rpx;
height: 160rpx;
opacity: 0.3;
border-radius: 16rpx;
}
}
@@ -185,9 +252,10 @@ onPullDownRefresh(() => {
display: flex;
align-items: left;
flex-direction: column;
padding: 20rpx; border-radius: 18rpx;
padding: 20rpx;
border-radius: 18rpx;
background: #fff;
box-shadow: 0 6rpx 16rpx rgba(0,0,0,0.04);
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.04);
}
.feature-item::after {
content: "";
@@ -200,13 +268,13 @@ onPullDownRefresh(() => {
z-index: 1;
}
.feature-item:nth-child(1)::after,
.feature-item:nth-child(2)::after {
background: #FEF2F2; /* 可换成你的主题粉 */
}
.feature-item:nth-child(2)::after {
background: #fef2f2; /* 可换成你的主题粉 */
}
.feature-item:nth-child(3)::after,
.feature-item:nth-child(4)::after {
background: #FFFBEC; /* 温柔一点的黄 */
}
.feature-item:nth-child(4)::after {
background: #fffbec; /* 温柔一点的黄 */
}
.feature-icon {
width: 60rpx;
height: 60rpx;
@@ -217,47 +285,128 @@ onPullDownRefresh(() => {
margin-top: 20rpx;
display: flex;
flex-direction: column;
.feature-title { font-size: 28rpx; color: #222; font-weight: 600; }
.feature-sub { font-size: 22rpx; color: #888; margin-top: 4rpx; }
.feature-title {
font-size: 28rpx;
color: #222;
font-weight: 600;
}
.feature-sub {
font-size: 22rpx;
color: #888;
margin-top: 4rpx;
}
}
}
/* 通用区块标题 */
.section { margin-top: 28rpx; }
.section {
margin-top: 28rpx;
}
.section-header {
display: flex; align-items: center; padding: 0 24rpx;
.section-bar { width: 10rpx; height: 30rpx; border-radius: 6rpx; background: #ff3b30; margin-right: 12rpx; }
.section-title { font-size: 28rpx; color: #222; flex: 1; font-weight: 600; }
.section-more { font-size: 24rpx; color: #ff3b30; }
display: flex;
align-items: center;
padding: 0 24rpx;
.section-bar {
width: 10rpx;
height: 30rpx;
border-radius: 6rpx;
background: #ff3b30;
margin-right: 12rpx;
}
.section-title {
font-size: 28rpx;
color: #222;
flex: 1;
font-weight: 600;
}
.section-more {
font-size: 24rpx;
color: #ff3b30;
}
}
/* 大家都在用 - 竖向列表 */
.use-list { padding: 0 24rpx; margin-top: 16rpx; }
.use-list {
padding: 0 24rpx;
margin-top: 16rpx;
}
.use-row {
display: flex; align-items: center; background: #fff;
border-radius: 18rpx; box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.06);
padding: 16rpx; margin-bottom: 18rpx;
display: flex;
align-items: center;
background: #fff;
border-radius: 18rpx;
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.06);
padding: 16rpx;
margin-bottom: 18rpx;
}
.thumb-wrap {
position: relative; width: 120rpx; height: 120rpx;
border-radius: 16rpx; overflow: hidden; margin-right: 16rpx;
position: relative;
width: 120rpx;
height: 120rpx;
border-radius: 16rpx;
overflow: hidden;
margin-right: 16rpx;
}
.thumb {
width: 100%;
height: 100%;
}
.thumb { width: 100%; height: 100%; }
.thumb-play {
position: absolute; right: 8rpx; bottom: 8rpx;
width: 40rpx; height: 40rpx; border-radius: 50%;
background: rgba(0,0,0,0.55); color: #fff; font-size: 22rpx;
display: flex; align-items: center; justify-content: center;
position: absolute;
right: 8rpx;
bottom: 8rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: rgba(0, 0, 0, 0.55);
color: #fff;
font-size: 22rpx;
display: flex;
align-items: center;
justify-content: center;
}
.use-right {
flex: 1;
display: flex;
flex-direction: column;
}
.title-line {
display: flex;
align-items: center;
}
.use-title {
font-size: 28rpx;
color: #222;
font-weight: 600;
margin-right: 12rpx;
}
.use-right { flex: 1; display: flex; flex-direction: column; }
.title-line { display: flex; align-items: center; }
.use-title { font-size: 28rpx; color: #222; font-weight: 600; margin-right: 12rpx; }
.tag {
font-size: 22rpx; border-radius: 999rpx; padding: 4rpx 10rpx; margin-left: 4rpx;
&.tag--hot { color: #ff6a00; background: #fff4eb; }
&.tag--featured { color: #ff4d6d; background: #fff0f3; }
&.tag--hot2 { color: #7c4dff; background: #f3efff; }
font-size: 22rpx;
border-radius: 999rpx;
padding: 4rpx 10rpx;
margin-left: 4rpx;
&.tag--hot {
color: #ff6a00;
background: #fff4eb;
}
&.tag--featured {
color: #ff4d6d;
background: #fff0f3;
}
&.tag--hot2 {
color: #7c4dff;
background: #f3efff;
}
}
.use-desc {
margin-top: 6rpx;
font-size: 24rpx;
color: #777;
line-height: 1.5;
}
.use-cta {
margin-top: 10rpx;
font-size: 24rpx;
color: #ff3b30;
}
.use-desc { margin-top: 6rpx; font-size: 24rpx; color: #777; line-height: 1.5; }
.use-cta { margin-top: 10rpx; font-size: 24rpx; color: #ff3b30; }
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,69 +1,101 @@
<template>
<view class="mine-content">
<!-- 顶部区域 -->
<view class="mine-top-panel" :style="{ paddingTop: getBavBarHeight() + 'px' }">
<view class="user-info">
<!-- 根据登录状态显示不同内容 -->
<view v-if="isLoggedIn" class="user-logged-in">
<view class="mine-page">
<!-- Custom Navbar -->
<view class="nav-bar" :style="{ paddingTop: navBarTop + 'px', height: navBarHeight + 'px' }">
<!-- <text class="nav-title">我的</text> -->
</view>
<scroll-view scroll-y class="content-scroll" :style="{ paddingTop: (navBarTop + navBarHeight) + 'px' }">
<view class="content-wrap">
<!-- User Card -->
<view class="user-card" @tap="handleUserClick">
<view class="avatar-box">
<image :src="userInfo.avatarUrl" class="avatar" mode="aspectFill" />
<view class="user-logged-in-info">
<view class="red-badge"><text class="fire">🔥</text></view>
</view>
<view class="user-info">
<view class="row-1">
<text class="nickname">{{ userInfo.nickName }}</text>
<text class="phone">19969024553</text>
<view class="vip-tag" v-if="isLoggedIn">
<text class="vip-text">VIP 祥瑞会员</text>
</view>
</view>
<view class="row-2" v-if="isLoggedIn">
<text class="arrow-icon"></text>
<text class="stats-text">已发送 <text class="num">3</text> 条新春祝福</text>
</view>
<view class="row-2" v-else>
<text class="stats-text">点击登录解锁更多功能</text>
</view>
</view>
<view class="card-arrow"></view>
</view>
<!-- My Creations -->
<view class="section-title">我的创作</view>
<view class="menu-group">
<view class="menu-item" @tap="navTo('greetings')">
<view class="icon-box red-bg"><text>🧧</text></view>
<text class="menu-text">我的新春祝福</text>
<text class="arrow"></text>
</view>
<view class="menu-item" @tap="navTo('videos')">
<view class="icon-box orange-bg"><text>📹</text></view>
<text class="menu-text">我的拜年视频</text>
<text class="arrow"></text>
</view>
<view class="menu-item" @tap="navTo('decorations')">
<view class="icon-box pink-bg"><text></text></view>
<text class="menu-text">我的头像挂饰</text>
<text class="arrow"></text>
</view>
<view class="menu-item" @tap="navTo('frames')">
<view class="icon-box yellow-bg"><text>🖼</text></view>
<text class="menu-text">我的马年头像框</text>
<view class="new-badge">NEW</view>
<text class="arrow"></text>
</view>
</view>
<view v-else class="user-not-logged-in">
<image :src="defaultAvatarUrl" class="avatar" mode="aspectFill" />
<button class="login-button" @tap="openPopup">点击登录</button>
<!-- History -->
<view class="section-title">历史记录</view>
<view class="menu-group">
<view class="menu-item" @tap="navTo('history')">
<view class="icon-box gray-bg"><text>🕒</text></view>
<text class="menu-text">新春祝福记录</text>
<text class="arrow"></text>
</view>
<view class="menu-item" @tap="navTo('archive')">
<view class="icon-box gray-bg"><text>📂</text></view>
<text class="menu-text">历年祝福存档</text>
<text class="arrow"></text>
</view>
</view>
<view class="mine-middle-panel">
<view class="mine-info-panel">
<view>0.00</view>
<view>我的余额</view>
</view>
<view class="mine-info-panel">
<view>0</view>
<view>优惠卷</view>
</view>
<view class="mine-info-panel">
<view>0</view>
<view>积分</view>
</view>
<view class="mine-info-panel">
<view>0</view>
<view>我的收藏</view>
</view>
</view>
<!-- 登录弹窗 -->
<uni-popup ref="popupRef" type="bottom" :safe-area="false">
<view class="popup-container">
<view class="popup-header">
<text class="popup-title">登录授权</text>
</view>
<view class="avatar-nickname">
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar" class="avatar-selector">
<image v-if="avatarUrl" :src="avatarUrl" class="avatar-preview" />
<text v-else>获取头像</text>
<!-- Other Actions -->
<view class="menu-group mt-30">
<button class="menu-item share-btn" open-type="share">
<view class="icon-left"><text class="share-icon">🔗</text></view>
<text class="menu-text">分享给好友</text>
<text class="arrow"></text>
</button>
<input
class="nickname-input"
type="nickname"
v-model="nickname"
placeholder="请输入昵称"
/>
<view class="menu-item" @tap="navTo('help')">
<view class="icon-left"><text class="help-icon"></text></view>
<text class="menu-text">使用说明 / 帮助</text>
<text class="arrow"></text>
</view>
</view>
<button class="confirm-btn" @tap="confirmLogin">确认登录</button>
<!-- Footer -->
<view class="version-info">2026 丙午马年 · 新春助手 v1.0.2</view>
<!-- Bottom Spacer for TabBar -->
<view style="height: 120rpx;"></view>
</view>
</uni-popup>
</scroll-view>
<!-- Login Popup -->
<LoginPopup ref="loginPopupRef" @logind="handleLogind"/>
</view>
</template>
@@ -74,230 +106,261 @@ import { getPlatformProvider, getBavBarHeight } from '@/utils/system'
import { useUserStore } from '@/stores/user'
import { apiLogin } from '@/api/auth.js'
import LoginPopup from '@/components/LoginPopup/LoginPopup.vue'
const userStore = useUserStore()
const popupRef = ref(null)
const loginPopupRef = ref(null)
// 用户输入的临时信息
const avatarUrl = ref('')
const nickname = ref('')
// Navigation Bar
const navBarTop = ref(20)
const navBarHeight = ref(44)
// User Info
const defaultAvatarUrl = 'https://file.lihailezzc.com/resource/d9b329082b32f8305101f708593a4882.png'
// 从store获取用户信息改为计算属性
const userInfo = computed(() => ({
nickName: userStore.userInfo.nickName || '登录',
nickName: userStore.userInfo.nickName || '点击登录',
avatarUrl: userStore.userInfo.avatarUrl || defaultAvatarUrl
}))
// 判断用户是否已登录
const isLoggedIn = computed(() => !!userStore.userInfo.nickName)
// 默认头像
const defaultAvatarUrl = 'https://file.lihailezzc.com/resource/d9b329082b32f8305101f708593a4882.png'
// 获取状态栏高度
const bavBarHeight = ref(0)
onMounted(() => {
// 确保高度值在组件挂载后获取
bavBarHeight.value = getBavBarHeight()
const sysInfo = uni.getSystemInfoSync()
navBarTop.value = sysInfo.statusBarHeight
// Assuming standard nav bar height
navBarHeight.value = 44
})
const openPopup = () => {
popupRef.value.open()
}
const onChooseAvatar = (e) => {
avatarUrl.value = e.detail.avatarUrl
}
const confirmLogin = async () => {
if (!nickname.value || !avatarUrl.value) {
return uni.showToast({ title: '请填写完整信息', icon: 'none' })
}
try {
const platform = getPlatformProvider()
if (platform === 'mp-weixin') {
const code = await wxLogin()
console.log('准备登录:', { code, nickname: nickname.value, avatarUrl: avatarUrl.value })
// console.log('准备登录:', { code, nickname: nickname.value, avatarUrl: 'http://tmp/HXhtcEwQ5A3B58476c91ba545ab67c6bf9c67d9c2559.jpeg' })
const fileKeyRes = await uni.uploadFile({
url: 'https://apis.lihailezzc.com/api/common/upload',
filePath: avatarUrl.value,
name: 'file', // 和后端接收文件字段名一致
header: {
'x-app-id': '6846f093fdf841f6189ef0b5',
},
})
if(fileKeyRes.statusCode < 400) {
const keyJson = JSON.parse(fileKeyRes.data)
const url = `https://file.lihailezzc.com/${keyJson?.data.key}`
const loginRes = await apiLogin({ code, nickname: nickname.value, avatarUrl: url })
// 保存用户信息到store
userStore.setUserInfo({
nickName: nickname.value,
avatarUrl: avatarUrl.value,
})
userStore.setToken(loginRes.token)
uni.showToast({ title: '登录成功', icon: 'success' })
popupRef.value.close()
// 重置临时变量
avatarUrl.value = ''
nickname.value = ''
const handleUserClick = () => {
if (!isLoggedIn.value) {
loginPopupRef.value.open()
} else {
throw Error('获取失败')
// Navigate to profile details or do nothing
}
}
}
} catch (err) {
uni.showToast({ title: '登录失败', icon: 'none' })
console.error(err)
}
const handleLogind = async () => {
// Logic after successful login if needed
}
const navTo = (page) => {
uni.showToast({ title: '功能开发中', icon: 'none' })
}
</script>
<style lang="scss">
.mine-content {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
background: #F9F6F2;
button {
border: none;
outline: none;
background-color: transparent;
padding: 0;
margin: 0;
line-height: normal;
font-family: inherit;
}
button::after {
border: none;
}
.mine-top-panel{
width: 100vw;
height: 500rpx;
background-color: #beecd8;
border-bottom-left-radius: 50% 50rpx;
border-bottom-right-radius: 50% 50rpx;
overflow: hidden;
.user-info{
padding-left: 40rpx;
image {
width: 150rpx;
height: 150rpx;
border-radius: 50%;
}
.user-logged-in{
display: flex;
align-items: center;
.user-logged-in-info{
padding-left: 20rpx;
display: flex;
flex-direction: column;
.nickname{
color: #1a1a1a;
font-weight: 800;
}
.phone{
color: #000;
}
}
}
.user-not-logged-in{
display: flex;
align-items: center;
.login-button{
padding-left: 20rpx;
}
}
}
}
.mine-middle-panel{
width: 90vw;
height: 200rpx;
background-color: #fff;
margin-top: -100rpx;
border-radius: 20rpx; /* 四角小圆角 */
box-shadow: 0 8rpx 16rpx rgba(0, 0, 0, 0.05); /* 柔和阴影 */
display: flex;
justify-content: space-between;
padding-left: 20rpx;
padding-right: 20rpx;
.mine-info-panel{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 23%;
}
}
<style lang="scss" scoped>
.mine-page {
min-height: 100vh;
background: #f9f9f9;
box-sizing: border-box;
}
/* 弹窗样式 */
.popup-container {
background-color: #fff;
padding: 40rpx 30rpx 60rpx;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
.popup-header {
text-align: center;
margin-bottom: 30rpx;
.nav-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
background: #f9f9f9;
}
.nav-title {
font-size: 32rpx;
font-weight: bold;
color: #000;
}
.popup-title {
.content-scroll {
height: 100vh;
}
.content-wrap {
padding: 20rpx 30rpx 40rpx;
}
/* User Card */
.user-card {
background: #fff;
border-radius: 30rpx;
padding: 40rpx;
display: flex;
align-items: center;
margin-bottom: 40rpx;
position: relative;
box-shadow: 0 10rpx 30rpx rgba(0,0,0,0.03);
}
.avatar-box {
position: relative;
margin-right: 30rpx;
}
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 4rpx solid #fff;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
}
.red-badge {
position: absolute;
top: 0;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background: #ff3b30;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #fff;
}
.fire {
font-size: 24rpx;
color: #fff;
}
.user-info {
flex: 1;
}
.row-1 {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
.nickname {
font-size: 36rpx;
font-weight: bold;
}
}
.avatar-nickname {
color: #333;
margin-right: 16rpx;
}
.vip-tag {
background: #ffecec;
padding: 4rpx 16rpx;
border-radius: 999rpx;
}
.vip-text {
color: #ff3b30;
font-size: 20rpx;
font-weight: bold;
}
.row-2 {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30rpx;
}
.arrow-icon {
color: #ff3b30;
font-size: 20rpx;
margin-right: 8rpx;
}
.stats-text {
font-size: 24rpx;
color: #666;
}
.num {
font-weight: bold;
color: #333;
margin: 0 4rpx;
}
.card-arrow {
font-size: 40rpx;
color: #ccc;
margin-left: 10rpx;
}
.avatar-selector {
width: 145rpx;
height: 145rpx;
border-radius: 50%;
/* Section Title */
.section-title {
font-size: 26rpx;
font-weight: bold;
color: #999;
margin-bottom: 20rpx;
padding-left: 10rpx;
}
/* Menu Group */
.menu-group {
background: #fff;
border-radius: 24rpx;
overflow: hidden;
margin-bottom: 40rpx;
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.02);
}
.menu-group.mt-30 {
margin-top: 30rpx;
}
.menu-item {
display: flex;
align-items: center;
padding: 30rpx;
background: #fff;
position: relative;
}
.menu-item:active {
background: #f9f9f9;
}
/* For button reset */
.menu-item.share-btn {
width: 100%;
text-align: left;
line-height: normal;
border-radius: 0;
}
.menu-item.share-btn::after {
border: none;
}
.icon-box {
width: 72rpx;
height: 72rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
background-color: #eee;
}
margin-right: 24rpx;
font-size: 36rpx;
}
.red-bg { background: #fff0f0; color: #ff3b30; }
.orange-bg { background: #fff8e6; color: #ff9500; }
.pink-bg { background: #fff0f5; color: #ff2d55; }
.yellow-bg { background: #fffae0; color: #ffcc00; }
.gray-bg { background: #f5f5f5; color: #666; }
.avatar-preview {
width: 100%;
height: 100%;
border-radius: 50%;
}
.icon-left {
width: 40rpx;
display: flex;
justify-content: center;
margin-right: 24rpx;
margin-left: 16rpx;
}
.share-icon, .help-icon {
font-size: 36rpx;
color: #666;
}
.nickname-input {
width: 80%;
border: 1rpx solid #ccc;
border-radius: 20rpx;
padding: 20rpx;
font-size: 26rpx;
.menu-text {
flex: 1;
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.new-badge {
background: #ff3b30;
color: #fff;
font-size: 20rpx;
padding: 2rpx 10rpx;
border-radius: 8rpx;
margin-right: 16rpx;
}
.arrow {
color: #ccc;
font-size: 32rpx;
}
/* Version Info */
.version-info {
text-align: center;
}
}
.confirm-btn {
background-color: #07c160;
color: white;
font-size: 30rpx;
border-radius: 50rpx;
padding: 20rpx 0;
width: 100%;
}
color: #ccc;
font-size: 22rpx;
margin-top: 60rpx;
}
</style>

BIN
static/images/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,44 @@
## 2.0.122025-08-26
- 优化 uni-app x 下 size 类型问题
## 2.0.112025-08-18
- 修复 图标点击事件返回
## 2.0.92024-01-12
fix: 修复图标大小默认值错误的问题
## 2.0.82023-12-14
- 修复 项目未使用 ts 情况下打包报错的bug
## 2.0.72023-12-14
- 修复 size 属性为 string 时不加单位导致尺寸异常的bug
## 2.0.62023-12-11
- 优化 兼容老版本icon类型如 top bottom 等
## 2.0.52023-12-11
- 优化 兼容老版本icon类型如 top bottom 等
## 2.0.42023-12-06
- 优化 uni-app x 下示例项目图标排序
## 2.0.32023-12-06
- 修复 nvue下引入组件报错的bug
## 2.0.22023-12-05
-优化 size 属性支持单位
## 2.0.12023-12-05
- 新增 uni-app x 支持定义图标
## 1.3.52022-01-24
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.42022-01-24
- 优化 size 支持其他单位
## 1.3.32022-01-17
- 修复 nvue 有些图标不显示的bug兼容老版本图标
## 1.3.22021-12-01
- 优化 示例可复制图标名称
## 1.3.12021-11-23
- 优化 兼容旧组件 type 值
## 1.3.02021-11-19
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.72021-11-08
## 1.2.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.52021-05-12
- 新增 组件示例地址
## 1.1.42021-02-05
- 调整为uni_modules目录规范

View File

@@ -0,0 +1,91 @@
<template>
<text class="uni-icons" :style="styleObj">
<slot>{{unicode}}</slot>
</text>
</template>
<script>
import { fontData, IconsDataItem } from './uniicons_file'
/**
* Icons 图标
* @description 用于展示 icon 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: "uni-icons",
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {};
},
computed: {
unicode() : string {
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
if (codes !== null) {
return codes.unicode
}
return ''
},
iconSize() : string {
const size = this.size
if (typeof size == 'string') {
const reg = /^[0-9]*$/g
return reg.test(size as string) ? '' + size + 'px' : '' + size;
// return '' + this.size
}
return this.getFontSize(size as number)
},
styleObj() : UTSJSONObject {
if (this.fontFamily !== '') {
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
}
return { color: this.color, fontSize: this.iconSize }
}
},
created() { },
methods: {
/**
* 字体大小
*/
getFontSize(size : number) : string {
return size + 'px';
},
},
}
</script>
<style scoped>
@font-face {
font-family: UniIconsFontFamily;
src: url('./uniicons.ttf');
}
.uni-icons {
font-family: UniIconsFontFamily;
font-size: 18px;
font-style: normal;
color: #333;
}
</style>

View File

@@ -0,0 +1,110 @@
<template>
<!-- #ifdef APP-NVUE -->
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
<slot></slot>
</text>
<!-- #endif -->
</template>
<script>
import { fontData } from './uniicons_file_vue.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('" + iconUrl + "')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits: ['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ''
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {
icons: fontData
}
},
computed: {
unicode() {
let code = this.icons.find(v => v.font_class === this.type)
if (code) {
return code.unicode
}
return ''
},
iconSize() {
return getVal(this.size)
},
styleObj() {
if (this.fontFamily !== '') {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
}
return `color: ${this.color}; font-size: ${this.iconSize};`
}
},
methods: {
_onClick(e) {
this.$emit('click', e)
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';
@font-face {
font-family: uniicons;
src: url('./uniicons.ttf');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>

View File

@@ -0,0 +1,664 @@
.uniui-cart-filled:before {
content: "\e6d0";
}
.uniui-gift-filled:before {
content: "\e6c4";
}
.uniui-color:before {
content: "\e6cf";
}
.uniui-wallet:before {
content: "\e6b1";
}
.uniui-settings-filled:before {
content: "\e6ce";
}
.uniui-auth-filled:before {
content: "\e6cc";
}
.uniui-shop-filled:before {
content: "\e6cd";
}
.uniui-staff-filled:before {
content: "\e6cb";
}
.uniui-vip-filled:before {
content: "\e6c6";
}
.uniui-plus-filled:before {
content: "\e6c7";
}
.uniui-folder-add-filled:before {
content: "\e6c8";
}
.uniui-color-filled:before {
content: "\e6c9";
}
.uniui-tune-filled:before {
content: "\e6ca";
}
.uniui-calendar-filled:before {
content: "\e6c0";
}
.uniui-notification-filled:before {
content: "\e6c1";
}
.uniui-wallet-filled:before {
content: "\e6c2";
}
.uniui-medal-filled:before {
content: "\e6c3";
}
.uniui-fire-filled:before {
content: "\e6c5";
}
.uniui-refreshempty:before {
content: "\e6bf";
}
.uniui-location-filled:before {
content: "\e6af";
}
.uniui-person-filled:before {
content: "\e69d";
}
.uniui-personadd-filled:before {
content: "\e698";
}
.uniui-arrowthinleft:before {
content: "\e6d2";
}
.uniui-arrowthinup:before {
content: "\e6d3";
}
.uniui-arrowthindown:before {
content: "\e6d4";
}
.uniui-back:before {
content: "\e6b9";
}
.uniui-forward:before {
content: "\e6ba";
}
.uniui-arrow-right:before {
content: "\e6bb";
}
.uniui-arrow-left:before {
content: "\e6bc";
}
.uniui-arrow-up:before {
content: "\e6bd";
}
.uniui-arrow-down:before {
content: "\e6be";
}
.uniui-arrowthinright:before {
content: "\e6d1";
}
.uniui-down:before {
content: "\e6b8";
}
.uniui-bottom:before {
content: "\e6b8";
}
.uniui-arrowright:before {
content: "\e6d5";
}
.uniui-right:before {
content: "\e6b5";
}
.uniui-up:before {
content: "\e6b6";
}
.uniui-top:before {
content: "\e6b6";
}
.uniui-left:before {
content: "\e6b7";
}
.uniui-arrowup:before {
content: "\e6d6";
}
.uniui-eye:before {
content: "\e651";
}
.uniui-eye-filled:before {
content: "\e66a";
}
.uniui-eye-slash:before {
content: "\e6b3";
}
.uniui-eye-slash-filled:before {
content: "\e6b4";
}
.uniui-info-filled:before {
content: "\e649";
}
.uniui-reload:before {
content: "\e6b2";
}
.uniui-micoff-filled:before {
content: "\e6b0";
}
.uniui-map-pin-ellipse:before {
content: "\e6ac";
}
.uniui-map-pin:before {
content: "\e6ad";
}
.uniui-location:before {
content: "\e6ae";
}
.uniui-starhalf:before {
content: "\e683";
}
.uniui-star:before {
content: "\e688";
}
.uniui-star-filled:before {
content: "\e68f";
}
.uniui-calendar:before {
content: "\e6a0";
}
.uniui-fire:before {
content: "\e6a1";
}
.uniui-medal:before {
content: "\e6a2";
}
.uniui-font:before {
content: "\e6a3";
}
.uniui-gift:before {
content: "\e6a4";
}
.uniui-link:before {
content: "\e6a5";
}
.uniui-notification:before {
content: "\e6a6";
}
.uniui-staff:before {
content: "\e6a7";
}
.uniui-vip:before {
content: "\e6a8";
}
.uniui-folder-add:before {
content: "\e6a9";
}
.uniui-tune:before {
content: "\e6aa";
}
.uniui-auth:before {
content: "\e6ab";
}
.uniui-person:before {
content: "\e699";
}
.uniui-email-filled:before {
content: "\e69a";
}
.uniui-phone-filled:before {
content: "\e69b";
}
.uniui-phone:before {
content: "\e69c";
}
.uniui-email:before {
content: "\e69e";
}
.uniui-personadd:before {
content: "\e69f";
}
.uniui-chatboxes-filled:before {
content: "\e692";
}
.uniui-contact:before {
content: "\e693";
}
.uniui-chatbubble-filled:before {
content: "\e694";
}
.uniui-contact-filled:before {
content: "\e695";
}
.uniui-chatboxes:before {
content: "\e696";
}
.uniui-chatbubble:before {
content: "\e697";
}
.uniui-upload-filled:before {
content: "\e68e";
}
.uniui-upload:before {
content: "\e690";
}
.uniui-weixin:before {
content: "\e691";
}
.uniui-compose:before {
content: "\e67f";
}
.uniui-qq:before {
content: "\e680";
}
.uniui-download-filled:before {
content: "\e681";
}
.uniui-pyq:before {
content: "\e682";
}
.uniui-sound:before {
content: "\e684";
}
.uniui-trash-filled:before {
content: "\e685";
}
.uniui-sound-filled:before {
content: "\e686";
}
.uniui-trash:before {
content: "\e687";
}
.uniui-videocam-filled:before {
content: "\e689";
}
.uniui-spinner-cycle:before {
content: "\e68a";
}
.uniui-weibo:before {
content: "\e68b";
}
.uniui-videocam:before {
content: "\e68c";
}
.uniui-download:before {
content: "\e68d";
}
.uniui-help:before {
content: "\e679";
}
.uniui-navigate-filled:before {
content: "\e67a";
}
.uniui-plusempty:before {
content: "\e67b";
}
.uniui-smallcircle:before {
content: "\e67c";
}
.uniui-minus-filled:before {
content: "\e67d";
}
.uniui-micoff:before {
content: "\e67e";
}
.uniui-closeempty:before {
content: "\e66c";
}
.uniui-clear:before {
content: "\e66d";
}
.uniui-navigate:before {
content: "\e66e";
}
.uniui-minus:before {
content: "\e66f";
}
.uniui-image:before {
content: "\e670";
}
.uniui-mic:before {
content: "\e671";
}
.uniui-paperplane:before {
content: "\e672";
}
.uniui-close:before {
content: "\e673";
}
.uniui-help-filled:before {
content: "\e674";
}
.uniui-paperplane-filled:before {
content: "\e675";
}
.uniui-plus:before {
content: "\e676";
}
.uniui-mic-filled:before {
content: "\e677";
}
.uniui-image-filled:before {
content: "\e678";
}
.uniui-locked-filled:before {
content: "\e668";
}
.uniui-info:before {
content: "\e669";
}
.uniui-locked:before {
content: "\e66b";
}
.uniui-camera-filled:before {
content: "\e658";
}
.uniui-chat-filled:before {
content: "\e659";
}
.uniui-camera:before {
content: "\e65a";
}
.uniui-circle:before {
content: "\e65b";
}
.uniui-checkmarkempty:before {
content: "\e65c";
}
.uniui-chat:before {
content: "\e65d";
}
.uniui-circle-filled:before {
content: "\e65e";
}
.uniui-flag:before {
content: "\e65f";
}
.uniui-flag-filled:before {
content: "\e660";
}
.uniui-gear-filled:before {
content: "\e661";
}
.uniui-home:before {
content: "\e662";
}
.uniui-home-filled:before {
content: "\e663";
}
.uniui-gear:before {
content: "\e664";
}
.uniui-smallcircle-filled:before {
content: "\e665";
}
.uniui-map-filled:before {
content: "\e666";
}
.uniui-map:before {
content: "\e667";
}
.uniui-refresh-filled:before {
content: "\e656";
}
.uniui-refresh:before {
content: "\e657";
}
.uniui-cloud-upload:before {
content: "\e645";
}
.uniui-cloud-download-filled:before {
content: "\e646";
}
.uniui-cloud-download:before {
content: "\e647";
}
.uniui-cloud-upload-filled:before {
content: "\e648";
}
.uniui-redo:before {
content: "\e64a";
}
.uniui-images-filled:before {
content: "\e64b";
}
.uniui-undo-filled:before {
content: "\e64c";
}
.uniui-more:before {
content: "\e64d";
}
.uniui-more-filled:before {
content: "\e64e";
}
.uniui-undo:before {
content: "\e64f";
}
.uniui-images:before {
content: "\e650";
}
.uniui-paperclip:before {
content: "\e652";
}
.uniui-settings:before {
content: "\e653";
}
.uniui-search:before {
content: "\e654";
}
.uniui-redo-filled:before {
content: "\e655";
}
.uniui-list:before {
content: "\e644";
}
.uniui-mail-open-filled:before {
content: "\e63a";
}
.uniui-hand-down-filled:before {
content: "\e63c";
}
.uniui-hand-down:before {
content: "\e63d";
}
.uniui-hand-up-filled:before {
content: "\e63e";
}
.uniui-hand-up:before {
content: "\e63f";
}
.uniui-heart-filled:before {
content: "\e641";
}
.uniui-mail-open:before {
content: "\e643";
}
.uniui-heart:before {
content: "\e639";
}
.uniui-loop:before {
content: "\e633";
}
.uniui-pulldown:before {
content: "\e632";
}
.uniui-scan:before {
content: "\e62a";
}
.uniui-bars:before {
content: "\e627";
}
.uniui-checkbox:before {
content: "\e62b";
}
.uniui-checkbox-filled:before {
content: "\e62c";
}
.uniui-shop:before {
content: "\e62f";
}
.uniui-headphones:before {
content: "\e630";
}
.uniui-cart:before {
content: "\e631";
}

View File

@@ -0,0 +1,664 @@
export type IconsData = {
id : string
name : string
font_family : string
css_prefix_text : string
description : string
glyphs : Array<IconsDataItem>
}
export type IconsDataItem = {
font_class : string
unicode : string
}
export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
] as IconsDataItem[]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

View File

@@ -0,0 +1,649 @@
export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

View File

@@ -0,0 +1,111 @@
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "2.0.12",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
"uniui",
"icon",
"图标"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14",
"uni-app": "^4.08",
"uni-app-x": "^4.61"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue",
"darkmode": "x",
"i18n": "x",
"widescreen": "x"
},
"uni_modules": {
"dependencies": [
"uni-scss"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "x",
"aliyun": "x",
"alipay": "x"
},
"client": {
"uni-app": {
"vue": {
"vue2": "√",
"vue3": "√"
},
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"vue": "√",
"nvue": "-",
"android": {
"extVersion": "",
"minVersion": "29"
},
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√",
"alipay": "√",
"toutiao": "√",
"baidu": "√",
"kuaishou": "-",
"jd": "-",
"harmony": "-",
"qq": "√",
"lark": "-"
},
"quickapp": {
"huawei": "√",
"union": "√"
}
},
"uni-app-x": {
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"android": {
"extVersion": "",
"minVersion": "29"
},
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√"
}
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
## Icons 图标
> **组件名uni-icons**
> 代码块: `uIcons`
用于展示 icons 图标 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@@ -1,55 +1,138 @@
// const BASE_URL = 'https://apis.lihailezzc.com'
const BASE_URL = 'http://127.0.0.1:3999'
export const request = (config = {}) => {
// const BASE_URL = 'http://127.0.0.1:3999'
const BASE_URL = "http://192.168.1.3:3999";
import { useUserStore } from "@/stores/user";
// 环境区分
// const BASE_URL =
// process.env.NODE_ENV === 'production'
// ? 'https://apis.lihailezzc.com'
// : 'http://127.0.0.1:3999'
// 192.168.2.186
// 192.168.31.253
// const BASE_URL = 'https://apis.lihailezzc.com'
let isLoadingCount = 0; // 计数多次请求loading
function showLoadingFlag(loadingText) {
if (isLoadingCount === 0) {
uni.showLoading({ title: loadingText });
}
isLoadingCount++;
}
function hideLoading() {
isLoadingCount--;
if (isLoadingCount <= 0) {
isLoadingCount = 0;
uni.hideLoading();
}
}
function getHeaders() {
const headers = {
"x-app-id": "69665538a49b8ae3be50fe5d",
};
const userStore = useUserStore();
if (userStore.token) {
headers["Authorization"] = userStore.token;
}
return headers;
}
function handleError(err, showError = true) {
if (!showError) return;
let msg = "网络异常,请稍后重试";
if (typeof err === "string") {
msg = err;
} else if (err?.msg) {
msg = err.msg;
} else if (err?.message) {
msg = err.message;
}
uni.showModal({
title: "错误提示",
content: msg,
showCancel: false,
});
}
/**
* 请求函数支持自动加载状态、token、错误弹窗、重试等
* @param {Object} config 请求配置
* @param {string} config.url 请求路径(必填)
* @param {string} [config.method='GET'] 请求方法
* @param {Object} [config.data={}] 请求参数
* @param {Object} [config.header={}] 额外 headers
* @param {boolean} [config.showLoading=true] 是否自动显示加载提示
* @param {boolean} [config.showError=true] 是否自动弹错误提示
* @param {number} [config.timeout=10000] 请求超时,单位毫秒
* @param {number} [config.retry=1] 失败后自动重试次数
* @returns {Promise<any>} 返回接口 data
*/
export function request(config) {
if (!config || !config.url) {
return Promise.reject(new Error("请求缺少 url 参数"));
}
const {
url,
method="GET",
header={},
data={}
} = config
method = "GET",
data = {},
header = {},
showLoading = false,
showError = true,
retry = 1,
loadingText = "加载中",
} = config;
// 默认 header
const defaultHeader = {
'x-app-id': '68774dc2d7a1efe42086078a',
};
const finalHeader = { ...getHeaders(), ...header };
const upperMethod = method.toUpperCase();
// 合并 header用户传入的覆盖默认的
const finalHeader = {
...defaultHeader,
...header
};
let attempt = 0;
const doRequest = () =>
new Promise((resolve, reject) => {
if (showLoading) showLoadingFlag(loadingText);
return new Promise((reslove, reject) => {
uni.request({
url: BASE_URL + url,
method,
header: finalHeader,
method: upperMethod,
data,
success: res => {
if(res.statusCode === 200 || res.statusCode === 201) {
if(res?.data?.code === 200) {
reslove(res.data.data)
header: finalHeader,
success: (res) => {
if (showLoading) hideLoading();
const { statusCode, data: body } = res;
if (
(statusCode === 200 || statusCode === 201) &&
body?.code === 200
) {
resolve(body.data);
} else {
uni.showModal({
title: "错误提示",
content: res.data.msg || '',
showCancel: false
})
reject(res.data)
}
} else {
uni.showModal({
title: "错误提示",
content: res.data.errMsg,
showCancel: false
})
reject(res.data)
reject({
type: "business",
msg: body?.msg || "服务器错误",
data: body,
});
}
},
fail: err => {
reject(err)
}
})
})
fail: (err) => {
if (showLoading) hideLoading();
reject({ type: "network", msg: "网络请求失败", error: err });
},
});
});
// 自动重试
const tryRequest = () =>
doRequest().catch((err) => {
if (attempt < retry) {
attempt++;
return tryRequest();
}
if (showError) handleError(err.msg || err);
return Promise.reject(err);
});
return tryRequest();
}

View File

@@ -1,17 +1,16 @@
const SYSTEM = uni.getSystemInfoSync()
const SYSTEM = uni.getSystemInfoSync();
export const getStatusBarHeight = () => SYSTEM.statusBarHeight || 15
export const getStatusBarHeight = () => SYSTEM.statusBarHeight || 15;
export const getTitleBarHeight = () => {
if(uni.getMenuButtonBoundingClientRect) {
const { top, height } = uni.getMenuButtonBoundingClientRect()
return height + (top - getStatusBarHeight()) * 2
if (uni.getMenuButtonBoundingClientRect) {
const { top, height } = uni.getMenuButtonBoundingClientRect();
return height + (top - getStatusBarHeight()) * 2;
} else {
return 40
return 40;
}
}
};
export const getBavBarHeight = () => getStatusBarHeight() + getTitleBarHeight()
export const getBavBarHeight = () => getStatusBarHeight() + getTitleBarHeight();
export const getLeftIconLeft = () => {
// if(tt?.getMenuButtonBoundingClientRect) {
@@ -21,18 +20,19 @@ export const getLeftIconLeft = () => {
// return 0
// }
// #ifdef MP-TOUTIAO
const { leftIcon: {left, width}} = tt.getCustomButtonBoundingClientRect()
return left + parseInt(width)
const {
leftIcon: { left, width },
} = tt.getCustomButtonBoundingClientRect();
return left + parseInt(width);
// #endif
// #ifndef MP-TOUTIAO
return 0
return 0;
// #endif
}
};
export function getPlatformProvider() {
const platform = process.env.UNI_PLATFORM
return platform ?? 'mp-weixin'
const platform = process.env.UNI_PLATFORM;
return platform ?? "mp-weixin";
// const platform = uni.getSystemInfoSync().platform;
// console.log(1111111, platform)
// // H5 模拟器调试时使用 __wxConfig 环境变量判断
@@ -45,3 +45,19 @@ export function getPlatformProvider() {
// return typeof tt !== 'undefined' ? 'toutiao' : 'weixin';
}
export function getDeviceInfo() {
const info = uni.getSystemInfoSync();
return {
platform: info.platform,
brand: info.brand,
model: info.model,
system: info.system,
screenWidth: info.screenWidth,
screenHeight: info.screenHeight,
pixelRatio: info.pixelRatio,
language: info.language,
version: info.version,
SDKVersion: info.SDKVersion,
};
}