commit 49f4a1d6ccd728cf4630a78ce7c56b4880c71a38
Author: zzc <1761997216@qq.com>
Date: Fri Apr 24 10:20:50 2026 +0800
first commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ccaa112
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/unpackage
+unpackage
diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json
new file mode 100644
index 0000000..81f13f4
--- /dev/null
+++ b/.hbuilderx/launch.json
@@ -0,0 +1,16 @@
+{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+ // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+ "version": "0.0",
+ "configurations": [{
+ "default" :
+ {
+ "launchtype" : "local"
+ },
+ "mp-weixin" :
+ {
+ "launchtype" : "local"
+ },
+ "type" : "uniCloud"
+ }
+ ]
+}
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..ceaacbf
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,68 @@
+
+
+
diff --git a/api/auth.js b/api/auth.js
new file mode 100644
index 0000000..9adb7a8
--- /dev/null
+++ b/api/auth.js
@@ -0,0 +1,45 @@
+import { request } from "@/utils/request.js";
+
+export const apiLogin = async (data) => {
+ return request({
+ url: "/api/user/login",
+ method: "POST",
+ data,
+ });
+};
+
+export const getUserInfo = async () => {
+ return request({
+ url: "/api/user/info",
+ method: "GET",
+ });
+};
+
+export const updateUserInfo = async (body) => {
+ return request({
+ url: "/api/user/info",
+ method: "PUT",
+ data: body,
+ });
+};
+
+export const userOpenApp = async () => {
+ return request({
+ url: "/api/user/open-app",
+ method: "POST",
+ });
+};
+
+export const getUserAsset = async () => {
+ return request({
+ url: "/api/user/asset",
+ method: "GET",
+ });
+};
+
+export const reportPrivacy = async () => {
+ // return request({
+ // url: "/api/common/privacy/report",
+ // method: "POST",
+ // });
+};
diff --git a/api/mine.js b/api/mine.js
new file mode 100644
index 0000000..29be01a
--- /dev/null
+++ b/api/mine.js
@@ -0,0 +1,40 @@
+import { request } from "@/utils/request.js";
+
+export const sendFeedback = async (data) => {
+ return request({
+ url: "/api/common/feedback",
+ method: "POST",
+ data,
+ });
+};
+
+export const getMyCard = async (page = 1) => {
+ return request({
+ url: "/api/blessing/my/card?page=" + page,
+ method: "GET",
+ });
+};
+
+export const getMyWallpaper = async (page = 1) => {
+ return request({
+ url: "/api/blessing/my/wallpaper?page=" + page,
+ method: "GET",
+ });
+};
+
+export const getMyAvatar = async (page = 1) => {
+ return request({
+ url: "/api/blessing/my/avatar?page=" + page,
+ method: "GET",
+ });
+};
+
+export const userAvatarChange = async (imageUrl) => {
+ return request({
+ url: "/api/blessing/user/avatar/change",
+ method: "POST",
+ data: {
+ imageUrl,
+ },
+ });
+};
diff --git a/api/pay.js b/api/pay.js
new file mode 100644
index 0000000..5cac542
--- /dev/null
+++ b/api/pay.js
@@ -0,0 +1,16 @@
+import { request } from "@/utils/request.js";
+
+export const createOrder = async (data) => {
+ return request({
+ url: "/api/pay/order/v2/create",
+ method: "POST",
+ data,
+ });
+};
+
+export const getVipPlan = async () => {
+ return request({
+ url: "/api/blessing/vip/plan",
+ method: "GET",
+ });
+};
diff --git a/api/system.js b/api/system.js
new file mode 100644
index 0000000..d885837
--- /dev/null
+++ b/api/system.js
@@ -0,0 +1,85 @@
+import { request } from "@/utils/request.js";
+import { useUserStore } from "@/stores/user";
+
+export const createShareToken = async (data) => {
+ return request({
+ url: "/api/blessing/share/token",
+ method: "POST",
+ data,
+ });
+};
+
+export const getShareReward = async (data) => {
+ const res = await request({
+ url: "/api/reward/share",
+ method: "POST",
+ data,
+ });
+ console.log("getShareReward res", res);
+ if (res && res.success) {
+ const userStore = useUserStore();
+ userStore.fetchUserAssets();
+ }
+ return res;
+};
+
+export const saveRecord = async (data) => {
+ return request({
+ url: "/api/blessing/save/record",
+ method: "POST",
+ data,
+ });
+};
+
+export const viewRecord = async (data) => {
+ return request({
+ url: "/api/blessing/view/record",
+ method: "POST",
+ data,
+ });
+};
+
+export const getRecommendList = async (page = 1) => {
+ return request({
+ url: `/api/blessing/recommend/list?page=${page}`,
+ method: "get",
+ });
+};
+
+export const msgCheckApi = async (content) => {
+ return request({
+ url: "/api/common/msg-check?content=" + content,
+ method: "get",
+ });
+};
+
+export const createTracking = async (data) => {
+ return request({
+ url: "/api/common/tracking/create",
+ method: "POST",
+ data,
+ });
+};
+
+export const watchAdReward = async (token, scene, type, resourceId) => {
+ return request({
+ url: "/api/ad/reward",
+ method: "POST",
+ data: {
+ rewardToken: token,
+ scene,
+ type,
+ resourceId,
+ },
+ });
+};
+
+export const watchAdStart = async () => {
+ return request({
+ url: "/api/ad/start",
+ method: "POST",
+ data: {
+ adPlacementId: "adunit-d7a28e0357d98947",
+ },
+ });
+};
diff --git a/api/user.js b/api/user.js
new file mode 100644
index 0000000..c8daafc
--- /dev/null
+++ b/api/user.js
@@ -0,0 +1,8 @@
+import { request } from "@/utils/request.js";
+
+export const getUserSignInfo = async () => {
+ return request({
+ url: "/api/sign/info",
+ method: "GET",
+ });
+};
diff --git a/common/images/preview_small.webp b/common/images/preview_small.webp
new file mode 100644
index 0000000..716f2cb
Binary files /dev/null and b/common/images/preview_small.webp differ
diff --git a/common/style/base-style.scss b/common/style/base-style.scss
new file mode 100644
index 0000000..47da42e
--- /dev/null
+++ b/common/style/base-style.scss
@@ -0,0 +1,10 @@
+$brand-theme-color:#262626; //品牌主体红色
+
+$border-color:#e0e0e0; //边框颜色
+$border-color-light:#efefef; //边框亮色
+
+$text-font-color-1:#000; //文字主色
+$text-font-color-2:#676767; //副标题颜色
+$text-font-color-3:#a7a7a7; //浅色
+$text-font-color-4:#e4e4e4; //更浅
+$text-color: #B2B2B2
\ No newline at end of file
diff --git a/common/style/common-style.scss b/common/style/common-style.scss
new file mode 100644
index 0000000..7414c4b
--- /dev/null
+++ b/common/style/common-style.scss
@@ -0,0 +1,8 @@
+view, swiper, swiper-item{
+ box-sizing: border-box;
+}
+
+.pageBg{
+ background: $brand-theme-color;
+ min-height: 80vh;
+}
\ No newline at end of file
diff --git a/components/LoginPopup/LoginPopup.vue b/components/LoginPopup/LoginPopup.vue
new file mode 100644
index 0000000..f5809ef
--- /dev/null
+++ b/components/LoginPopup/LoginPopup.vue
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/NavBar/NavBar.vue b/components/NavBar/NavBar.vue
new file mode 100644
index 0000000..a6cf15c
--- /dev/null
+++ b/components/NavBar/NavBar.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+ ‹
+ {{ title }}
+
+
+
+
+
+
+
+
diff --git a/components/PrivacyPopup/PrivacyPopup.vue b/components/PrivacyPopup/PrivacyPopup.vue
new file mode 100644
index 0000000..6bd276e
--- /dev/null
+++ b/components/PrivacyPopup/PrivacyPopup.vue
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
diff --git a/components/RewardAd/RewardAd.vue b/components/RewardAd/RewardAd.vue
new file mode 100644
index 0000000..5b8b19f
--- /dev/null
+++ b/components/RewardAd/RewardAd.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
diff --git a/components/custom-content/custom-content.vue b/components/custom-content/custom-content.vue
new file mode 100644
index 0000000..c3788c9
--- /dev/null
+++ b/components/custom-content/custom-content.vue
@@ -0,0 +1,69 @@
+
+
+
+ {{title}}
+ {{enTitle}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/layout/layout.vue b/components/layout/layout.vue
new file mode 100644
index 0000000..66a42e3
--- /dev/null
+++ b/components/layout/layout.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c3ff205
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..db68db0
--- /dev/null
+++ b/main.js
@@ -0,0 +1,39 @@
+import './polyfill'
+import App from './App'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+import { createPinia } from 'pinia'
+
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+const pinia = createPinia()
+app.use(pinia)
+
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+import { createPinia } from 'pinia'
+import { trackRecord } from '@/utils/common.js' // 引入埋点方法
+
+export function createApp() {
+ const app = createSSRApp(App)
+ const pinia = createPinia()
+ app.use(pinia) // ✅ 这句是关键
+
+ // 挂载到全局配置,使得在 vue3 setup 中可以通过 proxy 或 app.config.globalProperties 访问
+ app.config.globalProperties.$trackRecord = trackRecord
+ // 同时也挂载到 uni 对象上,这样在任何地方都可以直接 uni.$trackRecord 调用
+ uni.$trackRecord = trackRecord
+
+ return {
+ app
+ }
+}
+// #endif
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..b9d7797
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,75 @@
+{
+ "name" : "tpl-mini",
+ "appid" : "",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {},
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "wx8d0a4bfb94c9a7f0",
+ "__usePrivacyCheck__" : true,
+ "setting" : {
+ "urlCheck" : false
+ },
+ "usingComponents" : true,
+ "lazyCodeLoading" : "requiredComponents"
+ },
+ "mp-alipay" : {
+ "usingComponents" : true,
+ "appid" : "2021006125616610"
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "3"
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..ffbbadf
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,105 @@
+{
+ "pages": [
+ {
+ "path": "pages/index/index",
+ "style": {
+ "navigationBarTitleText": "祝福 壁纸 头像",
+ "enablePullDownRefresh": true,
+ "navigationStyle": "custom",
+ "backgroundColor": "#FFFFFF"
+ }
+ },
+ {
+ "path": "pages/mine/help",
+ "style": {
+ "navigationBarTitleText": "帮助中心",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/mine/vip",
+ "style": {
+ "navigationBarTitleText": "会员中心",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/mine/profile",
+ "style": {
+ "navigationBarTitleText": "个人信息",
+ "navigationStyle": "custom",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/mine/mine",
+ "style": {
+ "navigationBarTitleText": "我的",
+ "enablePullDownRefresh": false,
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/creation/index",
+ "style": {
+ "navigationBarTitleText": "创作中心",
+ "navigationStyle": "custom",
+ "backgroundColor": "#fbfbfb"
+ }
+ },
+ {
+ "path": "pages/webview/index",
+ "style": {
+ "navigationBarTitleText": "加载中...",
+ "enablePullDownRefresh": false
+ }
+ },
+ {
+ "path": "pages/feedback/index",
+ "style": {
+ "navigationBarTitleText": "意见反馈",
+ "enablePullDownRefresh": false,
+ "navigationStyle": "custom"
+ }
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "uni-app",
+ "navigationBarBackgroundColor": "#F8F8F8",
+ "backgroundColor": "#F8F8F8",
+ "mp-alipay": {
+ "transparentTitle": "always",
+ "titlePenetrate": "YES"
+ }
+ },
+ "tabBar": {
+ "color": "#999999",
+ "selectedColor": "#ff3b30",
+ "backgroundColor": "#ffffff",
+ "iconWidth": "24px",
+ "list": [
+ {
+ "text": "首页",
+ "pagePath": "pages/index/index",
+ "iconPath": "static/images/tabBar/home.png",
+ "selectedIconPath": "static/images/tabBar/home_s.png"
+ },
+ {
+ "text": "创作",
+ "pagePath": "pages/creation/index",
+ "iconPath": "static/images/tabBar/creation.png",
+ "selectedIconPath": "static/images/tabBar/creation_s.png"
+ },
+ {
+ "text": "我的",
+ "pagePath": "pages/mine/mine",
+ "iconPath": "static/images/tabBar/me.png",
+ "selectedIconPath": "static/images/tabBar/me_s.png"
+ }
+ ]
+ },
+ "uniIdRouter": {}
+}
diff --git a/pages/.DS_Store b/pages/.DS_Store
new file mode 100644
index 0000000..8ef2d1b
Binary files /dev/null and b/pages/.DS_Store differ
diff --git a/pages/creation/index.vue b/pages/creation/index.vue
new file mode 100644
index 0000000..00745d5
--- /dev/null
+++ b/pages/creation/index.vue
@@ -0,0 +1,90 @@
+
+
+
+ 创作中心
+
+
+
+
+
+
+
diff --git a/pages/feedback/index.vue b/pages/feedback/index.vue
new file mode 100644
index 0000000..5ed0948
--- /dev/null
+++ b/pages/feedback/index.vue
@@ -0,0 +1,381 @@
+
+
+
+
+
+
+
+ 此投诉为本小程序自有投诉渠道,非微信官方投诉渠道
+
+
+
+
+ 反馈类型
+
+
+ {{ item.label }}
+
+
+
+
+
+
+ 反馈内容 *
+
+
+ {{ formData.content.length }}/200
+
+
+
+
+
+ 图片上传 (选填,最多3张)
+
+
+
+ ×
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..d6bf981
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/help.vue b/pages/mine/help.vue
new file mode 100644
index 0000000..74b4cf3
--- /dev/null
+++ b/pages/mine/help.vue
@@ -0,0 +1,441 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 制作贺卡
+
+
+
+
+
+
+
+
+ 佩戴挂饰
+
+
+
+
+
+
+
+
+ 送出祝福
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.q }}
+
+
+
+ {{ item.a }}
+
+
+
+
+
+
+
+
+
+
+ 没找到答案?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue
new file mode 100644
index 0000000..81636e0
--- /dev/null
+++ b/pages/mine/mine.vue
@@ -0,0 +1,510 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ userInfo.nickName }}
+
+ VIP 祥瑞会员
+
+
+
+
+
+
+
+ 点击登录解锁更多功能
+
+
+ ›
+
+
+
+
+
+
+
+
+
+
+ 祥瑞会员中心
+ DIAMOND
+
+ 开通会员解锁全部特权
+
+
+
+ 立即开通
+ ›
+
+
+
+
+ 我的xx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/profile.vue b/pages/mine/profile.vue
new file mode 100644
index 0000000..1586772
--- /dev/null
+++ b/pages/mine/profile.vue
@@ -0,0 +1,372 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 更换头像
+
+
+
+
+
+ 昵称
+
+ {{ form.nickName || "微信用户" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/vip.vue b/pages/mine/vip.vue
new file mode 100644
index 0000000..d8e8367
--- /dev/null
+++ b/pages/mine/vip.vue
@@ -0,0 +1,529 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ userInfo.nickName || "微信用户" }}
+ VIP 祥瑞会员
+ 普通用户
+
+
+ {{ userInfo.vipExpireAt }} 到期
+
+ 开通会员解锁专属权益
+
+
+
+
+ 选择会员方案
+
+
+
+ {{ plan.badge }}
+
+ {{ plan.name }}
+
+ ¥
+ {{ plan.price / 100 }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ benefit.name }}
+
+
+
+
+
+
+ 购买说明
+
+
+ •
+ {{ note }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/webview/index.vue b/pages/webview/index.vue
new file mode 100644
index 0000000..5b71d05
--- /dev/null
+++ b/pages/webview/index.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/polyfill.js b/polyfill.js
new file mode 100644
index 0000000..fba0a31
--- /dev/null
+++ b/polyfill.js
@@ -0,0 +1,53 @@
+// #ifdef MP-WEIXIN
+// 拦截 wx.getSystemInfoSync 和 wx.getSystemInfo,避免 uni-app 内部或第三方库调用导致微信原生警告
+if (typeof wx !== 'undefined' && wx.getSystemInfoSync) {
+ const originalGetSystemInfoSync = wx.getSystemInfoSync;
+ wx.getSystemInfoSync = function () {
+ if (wx.getWindowInfo && wx.getAppBaseInfo && wx.getDeviceInfo && wx.getAppAuthorizeSetting && wx.getSystemSetting) {
+ try {
+ const windowInfo = wx.getWindowInfo() || {};
+ const appBaseInfo = wx.getAppBaseInfo() || {};
+ const deviceInfo = wx.getDeviceInfo() || {};
+ const appAuthorizeSetting = wx.getAppAuthorizeSetting() || {};
+ const systemSetting = wx.getSystemSetting() || {};
+
+ let safeAreaInsets = undefined;
+ if (windowInfo.safeArea) {
+ safeAreaInsets = {
+ top: windowInfo.safeArea.top,
+ left: windowInfo.safeArea.left,
+ right: windowInfo.screenWidth - windowInfo.safeArea.right,
+ bottom: windowInfo.screenHeight - windowInfo.safeArea.bottom
+ };
+ }
+
+ return {
+ ...windowInfo,
+ ...appBaseInfo,
+ ...deviceInfo,
+ ...appAuthorizeSetting,
+ ...systemSetting,
+ safeAreaInsets,
+ system: deviceInfo.system,
+ platform: deviceInfo.platform,
+ model: deviceInfo.model
+ };
+ } catch (e) {
+ return originalGetSystemInfoSync.call(wx);
+ }
+ }
+ return originalGetSystemInfoSync.call(wx);
+ };
+ const originalGetSystemInfo = wx.getSystemInfo;
+ wx.getSystemInfo = function (options) {
+ if (wx.getSystemInfoAsync) {
+ try {
+ return wx.getSystemInfoAsync(options);
+ } catch (e) {
+ return originalGetSystemInfo.call(wx, options);
+ }
+ }
+ return originalGetSystemInfo.call(wx, options);
+ };
+}
+// #endif
diff --git a/static/.DS_Store b/static/.DS_Store
new file mode 100644
index 0000000..1fbacac
Binary files /dev/null and b/static/.DS_Store differ
diff --git a/static/images/.DS_Store b/static/images/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/static/images/.DS_Store differ
diff --git a/static/images/default-avatar.png b/static/images/default-avatar.png
new file mode 100644
index 0000000..931ea39
Binary files /dev/null and b/static/images/default-avatar.png differ
diff --git a/static/images/qrcode.jpg b/static/images/qrcode.jpg
new file mode 100644
index 0000000..d00772f
Binary files /dev/null and b/static/images/qrcode.jpg differ
diff --git a/static/images/tabBar/creation.png b/static/images/tabBar/creation.png
new file mode 100644
index 0000000..e2203fc
Binary files /dev/null and b/static/images/tabBar/creation.png differ
diff --git a/static/images/tabBar/creation_s.png b/static/images/tabBar/creation_s.png
new file mode 100644
index 0000000..42dc189
Binary files /dev/null and b/static/images/tabBar/creation_s.png differ
diff --git a/static/images/tabBar/home.png b/static/images/tabBar/home.png
new file mode 100644
index 0000000..36e857b
Binary files /dev/null and b/static/images/tabBar/home.png differ
diff --git a/static/images/tabBar/home_s.png b/static/images/tabBar/home_s.png
new file mode 100644
index 0000000..68e9952
Binary files /dev/null and b/static/images/tabBar/home_s.png differ
diff --git a/static/images/tabBar/me.png b/static/images/tabBar/me.png
new file mode 100644
index 0000000..c7b4b9a
Binary files /dev/null and b/static/images/tabBar/me.png differ
diff --git a/static/images/tabBar/me_s.png b/static/images/tabBar/me_s.png
new file mode 100644
index 0000000..760765d
Binary files /dev/null and b/static/images/tabBar/me_s.png differ
diff --git a/stores/user.js b/stores/user.js
new file mode 100644
index 0000000..c532398
--- /dev/null
+++ b/stores/user.js
@@ -0,0 +1,88 @@
+import { defineStore } from "pinia";
+import { wxLogin, wxGetUserProfile } from "@/utils/login.js";
+import { getPlatformProvider } from "@/utils/system";
+import { getUserInfo, getUserAsset } from "@/api/auth.js";
+
+export const useUserStore = defineStore("user", {
+ state: () => ({
+ token: "",
+ userInfo: {},
+ }),
+ actions: {
+ setToken(token) {
+ this.token = token;
+ uni.setStorageSync("token", token); // 持久化 tokenx
+ },
+ setUserInfo(userInfo) {
+ this.userInfo = userInfo;
+ uni.setStorageSync("userInfo", JSON.stringify(userInfo)); // 持久化用户信息
+ },
+ loadFromStorage() {
+ const token = uni.getStorageSync("token");
+ const userInfoStr = uni.getStorageSync("userInfo");
+ if (token) this.token = token;
+ if (userInfoStr) {
+ try {
+ this.userInfo = JSON.parse(userInfoStr);
+ } catch (e) {
+ this.userInfo = {};
+ }
+ }
+ },
+ clear() {
+ this.token = "";
+ this.userInfo = {};
+ uni.removeStorageSync("token");
+ uni.removeStorageSync("userInfo");
+ },
+ loadUserInfo() {
+ const userStr = uni.getStorageSync("userInfo");
+ if (userStr) {
+ try {
+ this.userInfo = JSON.parse(userStr);
+ } catch (e) {
+ this.userInfo = {};
+ }
+ }
+ },
+ async fetchUserInfo() {
+ try {
+ const res = await getUserInfo();
+ if (res) {
+ this.setUserInfo(res);
+ }
+ } catch (e) {
+ console.error("fetchUserInfo error", e);
+ }
+ },
+ async fetchUserAssets() {
+ try {
+ if (!this?.userInfo?.id) return;
+ const res = await getUserAsset();
+ if (res) {
+ const newInfo = { ...this.userInfo, ...res };
+ if (res.points !== undefined) {
+ newInfo.points = res.points;
+ }
+
+ if (res.exp !== undefined) {
+ newInfo.exp = res.exp;
+ }
+
+ if (res.level !== undefined) {
+ newInfo.level = res.level;
+ }
+ this.setUserInfo(newInfo);
+ }
+ } catch (e) {
+ console.error("fetchUserAssets error", e);
+ }
+ },
+ logout() {
+ this.userInfo = {};
+ this.token = "";
+ uni.removeStorageSync("userInfo");
+ uni.removeStorageSync("token");
+ },
+ },
+});
diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js
new file mode 100644
index 0000000..5fec4f3
--- /dev/null
+++ b/uni.promisify.adaptor.js
@@ -0,0 +1,13 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => {
+ if (!res) return resolve(res)
+ return res[0] ? reject(res[0]) : resolve(res[1])
+ });
+ });
+ },
+});
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..58e8e87
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+@import "@/common/style/base-style.scss";
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;
diff --git a/uni_modules/uni-icons/changelog.md b/uni_modules/uni-icons/changelog.md
new file mode 100644
index 0000000..62e7682
--- /dev/null
+++ b/uni_modules/uni-icons/changelog.md
@@ -0,0 +1,44 @@
+## 2.0.12(2025-08-26)
+- 优化 uni-app x 下 size 类型问题
+## 2.0.11(2025-08-18)
+- 修复 图标点击事件返回
+## 2.0.9(2024-01-12)
+fix: 修复图标大小默认值错误的问题
+## 2.0.8(2023-12-14)
+- 修复 项目未使用 ts 情况下,打包报错的bug
+## 2.0.7(2023-12-14)
+- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
+## 2.0.6(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.5(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.4(2023-12-06)
+- 优化 uni-app x 下示例项目图标排序
+## 2.0.3(2023-12-06)
+- 修复 nvue下引入组件报错的bug
+## 2.0.2(2023-12-05)
+-优化 size 属性支持单位
+## 2.0.1(2023-12-05)
+- 新增 uni-app x 支持定义图标
+## 1.3.5(2022-01-24)
+- 优化 size 属性可以传入不带单位的字符串数值
+## 1.3.4(2022-01-24)
+- 优化 size 支持其他单位
+## 1.3.3(2022-01-17)
+- 修复 nvue 有些图标不显示的bug,兼容老版本图标
+## 1.3.2(2021-12-01)
+- 优化 示例可复制图标名称
+## 1.3.1(2021-11-23)
+- 优化 兼容旧组件 type 值
+## 1.3.0(2021-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.7(2021-11-08)
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.5(2021-05-12)
+- 新增 组件示例地址
+## 1.1.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
new file mode 100644
index 0000000..53eb2ea
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
@@ -0,0 +1,91 @@
+
+
+ {{unicode}}
+
+
+
+
+
+
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.vue b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
new file mode 100644
index 0000000..1bd3d5e
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
@@ -0,0 +1,110 @@
+
+
+ {{unicode}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.css b/uni_modules/uni-icons/components/uni-icons/uniicons.css
new file mode 100644
index 0000000..0a6b6fe
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons.css
@@ -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";
+}
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.ttf b/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
new file mode 100644
index 0000000..14696d0
Binary files /dev/null and b/uni_modules/uni-icons/components/uni-icons/uniicons.ttf differ
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts b/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
new file mode 100644
index 0000000..98e93aa
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
@@ -0,0 +1,664 @@
+
+export type IconsData = {
+ id : string
+ name : string
+ font_family : string
+ css_prefix_text : string
+ description : string
+ glyphs : Array
+}
+
+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(fontDataJson)
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js b/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
new file mode 100644
index 0000000..1cd11e1
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
@@ -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(fontDataJson)
diff --git a/uni_modules/uni-icons/package.json b/uni_modules/uni-icons/package.json
new file mode 100644
index 0000000..60e45f0
--- /dev/null
+++ b/uni_modules/uni-icons/package.json
@@ -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": "√"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-icons/readme.md b/uni_modules/uni-icons/readme.md
new file mode 100644
index 0000000..86234ba
--- /dev/null
+++ b/uni_modules/uni-icons/readme.md
@@ -0,0 +1,8 @@
+## Icons 图标
+> **组件名:uni-icons**
+> 代码块: `uIcons`
+
+用于展示 icons 图标 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
diff --git a/uni_modules/uni-popup/changelog.md b/uni_modules/uni-popup/changelog.md
new file mode 100644
index 0000000..013272a
--- /dev/null
+++ b/uni_modules/uni-popup/changelog.md
@@ -0,0 +1,94 @@
+## 1.9.8(2025-04-16)
+- 修复 更新组件示例 ,解决更新数据或保存项目导致弹窗消失的问题
+## 1.9.7(2025-04-14)
+- 修复 uni-popup-dialog 弹出框在vue3中双向绑定问题
+## 1.9.6(2025-01-08)
+- 修复 示例中过期图片地址
+## 1.9.5(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.9.2(2024-09-21)
+- 修复 uni-popup在android上的重复点击弹出位置不正确的bug
+## 1.9.1(2024-04-02)
+- 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
+## 1.9.0(2024-03-28)
+- 修复 uni-popup-dialog 双向绑定时初始化逻辑修正
+## 1.8.9(2024-03-20)
+- 修复 uni-popup-dialog 数据输入时修正为双向绑定
+## 1.8.8(2024-02-20)
+- 修复 uni-popup 在微信小程序下出现文字向上闪动的bug
+## 1.8.7(2024-02-02)
+- 新增 uni-popup-dialog 新增属性focus:input模式下,是否自动自动聚焦
+## 1.8.6(2024-01-30)
+- 新增 uni-popup-dialog 新增属性maxLength:限制输入框字数
+## 1.8.5(2024-01-26)
+- 新增 uni-popup-dialog 新增属性showClose:控制关闭按钮的显示
+## 1.8.4(2023-11-15)
+- 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close`
+## 1.8.3(2023-04-17)
+- 修复 uni-popup 重复打开时的 bug
+## 1.8.2(2023-02-02)
+- uni-popup-dialog 组件新增 inputType 属性
+## 1.8.1(2022-12-01)
+- 修复 nvue 下 v-show 报错
+## 1.8.0(2022-11-29)
+- 优化 主题样式
+## 1.7.9(2022-04-02)
+- 修复 弹出层内部无法滚动的bug
+## 1.7.8(2022-03-28)
+- 修复 小程序中高度错误的bug
+## 1.7.7(2022-03-17)
+- 修复 快速调用open出现问题的Bug
+## 1.7.6(2022-02-14)
+- 修复 safeArea 属性不能设置为false的bug
+## 1.7.5(2022-01-19)
+- 修复 isMaskClick 失效的bug
+## 1.7.4(2022-01-19)
+- 新增 cancelText \ confirmText 属性 ,可自定义文本
+- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
+- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
+## 1.7.3(2022-01-13)
+- 修复 设置 safeArea 属性不生效的bug
+## 1.7.2(2021-11-26)
+- 优化 组件示例
+## 1.7.1(2021-11-26)
+- 修复 vuedoc 文字错误
+## 1.7.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
+## 1.6.2(2021-08-24)
+- 新增 支持国际化
+## 1.6.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.6.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.5.0(2021-06-23)
+- 新增 mask-click 遮罩层点击事件
+## 1.4.5(2021-06-22)
+- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+## 1.4.4(2021-06-18)
+- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+## 1.4.3(2021-06-08)
+- 修复 错误的 watch 字段
+- 修复 safeArea 属性不生效的问题
+- 修复 点击内容,再点击遮罩无法关闭的Bug
+## 1.4.2(2021-05-12)
+- 新增 组件示例地址
+## 1.4.1(2021-04-29)
+- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
+## 1.4.0 (2021-04-29)
+- 新增 type 属性的 left\right 值,支持左右弹出
+- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
+- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
+- 新增 safeArea 属性,是否适配底部安全区
+- 修复 App\h5\微信小程序底部安全区占位不对的Bug
+- 修复 App 端弹出等待的Bug
+- 优化 提升低配设备性能,优化动画卡顿问题
+- 优化 更简单的组件自定义方式
+## 1.2.9(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.2.8(2021-02-05)
+- 调整为uni_modules目录规范
+## 1.2.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 PC 端
+- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
diff --git a/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js b/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
new file mode 100644
index 0000000..6ef26a2
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+ name: 'Keypress',
+ props: {
+ disable: {
+ type: Boolean,
+ default: false
+ }
+ },
+ mounted () {
+ const keyNames = {
+ esc: ['Esc', 'Escape'],
+ tab: 'Tab',
+ enter: 'Enter',
+ space: [' ', 'Spacebar'],
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ delete: ['Backspace', 'Delete', 'Del']
+ }
+ const listener = ($event) => {
+ if (this.disable) {
+ return
+ }
+ const keyName = Object.keys(keyNames).find(key => {
+ const keyName = $event.key
+ const value = keyNames[key]
+ return value === keyName || (Array.isArray(value) && value.includes(keyName))
+ })
+ if (keyName) {
+ // 避免和其他按键事件冲突
+ setTimeout(() => {
+ this.$emit(keyName, {})
+ }, 0)
+ }
+ }
+ document.addEventListener('keyup', listener)
+ this.$once('hook:beforeDestroy', () => {
+ document.removeEventListener('keyup', listener)
+ })
+ },
+ render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue b/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
new file mode 100644
index 0000000..f5731d5
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
@@ -0,0 +1,327 @@
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue b/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
new file mode 100644
index 0000000..91370a8
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
@@ -0,0 +1,143 @@
+
+
+
+
+
+
diff --git a/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
new file mode 100644
index 0000000..c8945d5
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
@@ -0,0 +1,188 @@
+
+
+
+
+
+
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/en.json b/uni_modules/uni-popup/components/uni-popup/i18n/en.json
new file mode 100644
index 0000000..7f1bd06
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/en.json
@@ -0,0 +1,7 @@
+{
+ "uni-popup.cancel": "cancel",
+ "uni-popup.ok": "ok",
+ "uni-popup.placeholder": "pleace enter",
+ "uni-popup.title": "Hint",
+ "uni-popup.shareTitle": "Share to"
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/index.js b/uni_modules/uni-popup/components/uni-popup/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+ en,
+ 'zh-Hans': zhHans,
+ 'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
new file mode 100644
index 0000000..5e3003c
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
@@ -0,0 +1,7 @@
+{
+ "uni-popup.cancel": "取消",
+ "uni-popup.ok": "确定",
+ "uni-popup.placeholder": "请输入",
+ "uni-popup.title": "提示",
+ "uni-popup.shareTitle": "分享到"
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
new file mode 100644
index 0000000..13e39eb
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
@@ -0,0 +1,7 @@
+{
+ "uni-popup.cancel": "取消",
+ "uni-popup.ok": "確定",
+ "uni-popup.placeholder": "請輸入",
+ "uni-popup.title": "提示",
+ "uni-popup.shareTitle": "分享到"
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/keypress.js b/uni_modules/uni-popup/components/uni-popup/keypress.js
new file mode 100644
index 0000000..62dda46
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+ name: 'Keypress',
+ props: {
+ disable: {
+ type: Boolean,
+ default: false
+ }
+ },
+ mounted () {
+ const keyNames = {
+ esc: ['Esc', 'Escape'],
+ tab: 'Tab',
+ enter: 'Enter',
+ space: [' ', 'Spacebar'],
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ delete: ['Backspace', 'Delete', 'Del']
+ }
+ const listener = ($event) => {
+ if (this.disable) {
+ return
+ }
+ const keyName = Object.keys(keyNames).find(key => {
+ const keyName = $event.key
+ const value = keyNames[key]
+ return value === keyName || (Array.isArray(value) && value.includes(keyName))
+ })
+ if (keyName) {
+ // 避免和其他按键事件冲突
+ setTimeout(() => {
+ this.$emit(keyName, {})
+ }, 0)
+ }
+ }
+ document.addEventListener('keyup', listener)
+ // this.$once('hook:beforeDestroy', () => {
+ // document.removeEventListener('keyup', listener)
+ // })
+ },
+ render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-popup/components/uni-popup/popup.js b/uni_modules/uni-popup/components/uni-popup/popup.js
new file mode 100644
index 0000000..c4e5781
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/popup.js
@@ -0,0 +1,26 @@
+
+export default {
+ data() {
+ return {
+
+ }
+ },
+ created(){
+ this.popup = this.getParent()
+ },
+ methods:{
+ /**
+ * 获取父元素实例
+ */
+ getParent(name = 'uniPopup') {
+ let parent = this.$parent;
+ let parentName = parent.$options.name;
+ while (parentName !== name) {
+ parent = parent.$parent;
+ if (!parent) return false
+ parentName = parent.$options.name;
+ }
+ return parent;
+ },
+ }
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/uni-popup.uvue b/uni_modules/uni-popup/components/uni-popup/uni-popup.uvue
new file mode 100644
index 0000000..5eb8d5b
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/uni-popup.uvue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/uni-popup/components/uni-popup/uni-popup.vue b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
new file mode 100644
index 0000000..5af55e0
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
@@ -0,0 +1,518 @@
+
+
+
+
+
+
diff --git a/uni_modules/uni-popup/package.json b/uni_modules/uni-popup/package.json
new file mode 100644
index 0000000..d8bfb9f
--- /dev/null
+++ b/uni_modules/uni-popup/package.json
@@ -0,0 +1,90 @@
+{
+ "id": "uni-popup",
+ "displayName": "uni-popup 弹出层",
+ "version": "1.9.8",
+ "description": " Popup 组件,提供常用的弹层",
+ "keywords": [
+ "uni-ui",
+ "弹出层",
+ "弹窗",
+ "popup",
+ "弹框"
+ ],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "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"
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uni-scss",
+ "uni-transition"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y",
+ "app-harmony": "u",
+ "app-uvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-popup/readme.md b/uni_modules/uni-popup/readme.md
new file mode 100644
index 0000000..fdad4b3
--- /dev/null
+++ b/uni_modules/uni-popup/readme.md
@@ -0,0 +1,17 @@
+
+
+## Popup 弹出层
+> **组件名:uni-popup**
+> 代码块: `uPopup`
+> 关联组件:`uni-transition`
+
+
+弹出层组件,在应用中弹出一个消息提示窗口、提示框等
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+
+
+
+
+
diff --git a/uni_modules/uni-scss/changelog.md b/uni_modules/uni-scss/changelog.md
new file mode 100644
index 0000000..b863bb0
--- /dev/null
+++ b/uni_modules/uni-scss/changelog.md
@@ -0,0 +1,8 @@
+## 1.0.3(2022-01-21)
+- 优化 组件示例
+## 1.0.2(2021-11-22)
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
+## 1.0.1(2021-11-22)
+- 修复 vue3中scss语法兼容问题
+## 1.0.0(2021-11-18)
+- init
diff --git a/uni_modules/uni-scss/index.scss b/uni_modules/uni-scss/index.scss
new file mode 100644
index 0000000..1744a5f
--- /dev/null
+++ b/uni_modules/uni-scss/index.scss
@@ -0,0 +1 @@
+@import './styles/index.scss';
diff --git a/uni_modules/uni-scss/package.json b/uni_modules/uni-scss/package.json
new file mode 100644
index 0000000..7cc0ccb
--- /dev/null
+++ b/uni_modules/uni-scss/package.json
@@ -0,0 +1,82 @@
+{
+ "id": "uni-scss",
+ "displayName": "uni-scss 辅助样式",
+ "version": "1.0.3",
+ "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
+ "keywords": [
+ "uni-scss",
+ "uni-ui",
+ "辅助样式"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "category": [
+ "JS SDK",
+ "通用 SDK"
+ ],
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "n",
+ "联盟": "n"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/readme.md b/uni_modules/uni-scss/readme.md
new file mode 100644
index 0000000..b7d1c25
--- /dev/null
+++ b/uni_modules/uni-scss/readme.md
@@ -0,0 +1,4 @@
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/index.scss b/uni_modules/uni-scss/styles/index.scss
new file mode 100644
index 0000000..ffac4fe
--- /dev/null
+++ b/uni_modules/uni-scss/styles/index.scss
@@ -0,0 +1,7 @@
+@import './setting/_variables.scss';
+@import './setting/_border.scss';
+@import './setting/_color.scss';
+@import './setting/_space.scss';
+@import './setting/_radius.scss';
+@import './setting/_text.scss';
+@import './setting/_styles.scss';
diff --git a/uni_modules/uni-scss/styles/setting/_border.scss b/uni_modules/uni-scss/styles/setting/_border.scss
new file mode 100644
index 0000000..12a11c3
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_border.scss
@@ -0,0 +1,3 @@
+.uni-border {
+ border: 1px $uni-border-1 solid;
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_color.scss b/uni_modules/uni-scss/styles/setting/_color.scss
new file mode 100644
index 0000000..1ededd9
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_color.scss
@@ -0,0 +1,66 @@
+
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
+// @mixin get-styles($k,$c) {
+// @if $k == size or $k == weight{
+// font-#{$k}:#{$c}
+// }@else{
+// #{$k}:#{$c}
+// }
+// }
+$uni-ui-color:(
+ // 主色
+ primary: $uni-primary,
+ primary-disable: $uni-primary-disable,
+ primary-light: $uni-primary-light,
+ // 辅助色
+ success: $uni-success,
+ success-disable: $uni-success-disable,
+ success-light: $uni-success-light,
+ warning: $uni-warning,
+ warning-disable: $uni-warning-disable,
+ warning-light: $uni-warning-light,
+ error: $uni-error,
+ error-disable: $uni-error-disable,
+ error-light: $uni-error-light,
+ info: $uni-info,
+ info-disable: $uni-info-disable,
+ info-light: $uni-info-light,
+ // 中性色
+ main-color: $uni-main-color,
+ base-color: $uni-base-color,
+ secondary-color: $uni-secondary-color,
+ extra-color: $uni-extra-color,
+ // 背景色
+ bg-color: $uni-bg-color,
+ // 边框颜色
+ border-1: $uni-border-1,
+ border-2: $uni-border-2,
+ border-3: $uni-border-3,
+ border-4: $uni-border-4,
+ // 黑色
+ black:$uni-black,
+ // 白色
+ white:$uni-white,
+ // 透明
+ transparent:$uni-transparent
+) !default;
+@each $key, $child in $uni-ui-color {
+ .uni-#{"" + $key} {
+ color: $child;
+ }
+ .uni-#{"" + $key}-bg {
+ background-color: $child;
+ }
+}
+.uni-shadow-sm {
+ box-shadow: $uni-shadow-sm;
+}
+.uni-shadow-base {
+ box-shadow: $uni-shadow-base;
+}
+.uni-shadow-lg {
+ box-shadow: $uni-shadow-lg;
+}
+.uni-mask {
+ background-color:$uni-mask;
+}
diff --git a/uni_modules/uni-scss/styles/setting/_radius.scss b/uni_modules/uni-scss/styles/setting/_radius.scss
new file mode 100644
index 0000000..9a0428b
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_radius.scss
@@ -0,0 +1,55 @@
+@mixin radius($r,$d:null ,$important: false){
+ $radius-value:map-get($uni-radius, $r) if($important, !important, null);
+ // Key exists within the $uni-radius variable
+ @if (map-has-key($uni-radius, $r) and $d){
+ @if $d == t {
+ border-top-left-radius:$radius-value;
+ border-top-right-radius:$radius-value;
+ }@else if $d == r {
+ border-top-right-radius:$radius-value;
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == b {
+ border-bottom-left-radius:$radius-value;
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == l {
+ border-top-left-radius:$radius-value;
+ border-bottom-left-radius:$radius-value;
+ }@else if $d == tl {
+ border-top-left-radius:$radius-value;
+ }@else if $d == tr {
+ border-top-right-radius:$radius-value;
+ }@else if $d == br {
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == bl {
+ border-bottom-left-radius:$radius-value;
+ }
+ }@else{
+ border-radius:$radius-value;
+ }
+}
+
+@each $key, $child in $uni-radius {
+ @if($key){
+ .uni-radius-#{"" + $key} {
+ @include radius($key)
+ }
+ }@else{
+ .uni-radius {
+ @include radius($key)
+ }
+ }
+}
+
+@each $direction in t, r, b, l,tl, tr, br, bl {
+ @each $key, $child in $uni-radius {
+ @if($key){
+ .uni-radius-#{"" + $direction}-#{"" + $key} {
+ @include radius($key,$direction,false)
+ }
+ }@else{
+ .uni-radius-#{$direction} {
+ @include radius($key,$direction,false)
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/styles/setting/_space.scss b/uni_modules/uni-scss/styles/setting/_space.scss
new file mode 100644
index 0000000..3c89528
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_space.scss
@@ -0,0 +1,56 @@
+
+@mixin fn($space,$direction,$size,$n) {
+ @if $n {
+ #{$space}-#{$direction}: #{$size*$uni-space-root}px
+ } @else {
+ #{$space}-#{$direction}: #{-$size*$uni-space-root}px
+ }
+}
+@mixin get-styles($direction,$i,$space,$n){
+ @if $direction == t {
+ @include fn($space, top,$i,$n);
+ }
+ @if $direction == r {
+ @include fn($space, right,$i,$n);
+ }
+ @if $direction == b {
+ @include fn($space, bottom,$i,$n);
+ }
+ @if $direction == l {
+ @include fn($space, left,$i,$n);
+ }
+ @if $direction == x {
+ @include fn($space, left,$i,$n);
+ @include fn($space, right,$i,$n);
+ }
+ @if $direction == y {
+ @include fn($space, top,$i,$n);
+ @include fn($space, bottom,$i,$n);
+ }
+ @if $direction == a {
+ @if $n {
+ #{$space}:#{$i*$uni-space-root}px;
+ } @else {
+ #{$space}:#{-$i*$uni-space-root}px;
+ }
+ }
+}
+
+@each $orientation in m,p {
+ $space: margin;
+ @if $orientation == m {
+ $space: margin;
+ } @else {
+ $space: padding;
+ }
+ @for $i from 0 through 16 {
+ @each $direction in t, r, b, l, x, y, a {
+ .uni-#{$orientation}#{$direction}-#{$i} {
+ @include get-styles($direction,$i,$space,true);
+ }
+ .uni-#{$orientation}#{$direction}-n#{$i} {
+ @include get-styles($direction,$i,$space,false);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_styles.scss b/uni_modules/uni-scss/styles/setting/_styles.scss
new file mode 100644
index 0000000..689afec
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_styles.scss
@@ -0,0 +1,167 @@
+/* #ifndef APP-NVUE */
+
+$-color-white:#fff;
+$-color-black:#000;
+@mixin base-style($color) {
+ color: #fff;
+ background-color: $color;
+ border-color: mix($-color-black, $color, 8%);
+ &:not([hover-class]):active {
+ background: mix($-color-black, $color, 10%);
+ border-color: mix($-color-black, $color, 20%);
+ color: $-color-white;
+ outline: none;
+ }
+}
+@mixin is-color($color) {
+ @include base-style($color);
+ &[loading] {
+ @include base-style($color);
+ &::before {
+ margin-right:5px;
+ }
+ }
+ &[disabled] {
+ &,
+ &[loading],
+ &:not([hover-class]):active {
+ color: $-color-white;
+ border-color: mix(darken($color,10%), $-color-white);
+ background-color: mix($color, $-color-white);
+ }
+ }
+
+}
+@mixin base-plain-style($color) {
+ color:$color;
+ background-color: mix($-color-white, $color, 90%);
+ border-color: mix($-color-white, $color, 70%);
+ &:not([hover-class]):active {
+ background: mix($-color-white, $color, 80%);
+ color: $color;
+ outline: none;
+ border-color: mix($-color-white, $color, 50%);
+ }
+}
+@mixin is-plain($color){
+ &[plain] {
+ @include base-plain-style($color);
+ &[loading] {
+ @include base-plain-style($color);
+ &::before {
+ margin-right:5px;
+ }
+ }
+ &[disabled] {
+ &,
+ &:active {
+ color: mix($-color-white, $color, 40%);
+ background-color: mix($-color-white, $color, 90%);
+ border-color: mix($-color-white, $color, 80%);
+ }
+ }
+ }
+}
+
+
+.uni-btn {
+ margin: 5px;
+ color: #393939;
+ border:1px solid #ccc;
+ font-size: 16px;
+ font-weight: 200;
+ background-color: #F9F9F9;
+ // TODO 暂时处理边框隐藏一边的问题
+ overflow: visible;
+ &::after{
+ border: none;
+ }
+
+ &:not([type]),&[type=default] {
+ color: #999;
+ &[loading] {
+ background: none;
+ &::before {
+ margin-right:5px;
+ }
+ }
+
+
+
+ &[disabled]{
+ color: mix($-color-white, #999, 60%);
+ &,
+ &[loading],
+ &:active {
+ color: mix($-color-white, #999, 60%);
+ background-color: mix($-color-white,$-color-black , 98%);
+ border-color: mix($-color-white, #999, 85%);
+ }
+ }
+
+ &[plain] {
+ color: #999;
+ background: none;
+ border-color: $uni-border-1;
+ &:not([hover-class]):active {
+ background: none;
+ color: mix($-color-white, $-color-black, 80%);
+ border-color: mix($-color-white, $-color-black, 90%);
+ outline: none;
+ }
+ &[disabled]{
+ &,
+ &[loading],
+ &:active {
+ background: none;
+ color: mix($-color-white, #999, 60%);
+ border-color: mix($-color-white, #999, 85%);
+ }
+ }
+ }
+ }
+
+ &:not([hover-class]):active {
+ color: mix($-color-white, $-color-black, 50%);
+ }
+
+ &[size=mini] {
+ font-size: 16px;
+ font-weight: 200;
+ border-radius: 8px;
+ }
+
+
+
+ &.uni-btn-small {
+ font-size: 14px;
+ }
+ &.uni-btn-mini {
+ font-size: 12px;
+ }
+
+ &.uni-btn-radius {
+ border-radius: 999px;
+ }
+ &[type=primary] {
+ @include is-color($uni-primary);
+ @include is-plain($uni-primary)
+ }
+ &[type=success] {
+ @include is-color($uni-success);
+ @include is-plain($uni-success)
+ }
+ &[type=error] {
+ @include is-color($uni-error);
+ @include is-plain($uni-error)
+ }
+ &[type=warning] {
+ @include is-color($uni-warning);
+ @include is-plain($uni-warning)
+ }
+ &[type=info] {
+ @include is-color($uni-info);
+ @include is-plain($uni-info)
+ }
+}
+/* #endif */
diff --git a/uni_modules/uni-scss/styles/setting/_text.scss b/uni_modules/uni-scss/styles/setting/_text.scss
new file mode 100644
index 0000000..a34d08f
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_text.scss
@@ -0,0 +1,24 @@
+@mixin get-styles($k,$c) {
+ @if $k == size or $k == weight{
+ font-#{$k}:#{$c}
+ }@else{
+ #{$k}:#{$c}
+ }
+}
+
+@each $key, $child in $uni-headings {
+ /* #ifndef APP-NVUE */
+ .uni-#{$key} {
+ @each $k, $c in $child {
+ @include get-styles($k,$c)
+ }
+ }
+ /* #endif */
+ /* #ifdef APP-NVUE */
+ .container .uni-#{$key} {
+ @each $k, $c in $child {
+ @include get-styles($k,$c)
+ }
+ }
+ /* #endif */
+}
diff --git a/uni_modules/uni-scss/styles/setting/_variables.scss b/uni_modules/uni-scss/styles/setting/_variables.scss
new file mode 100644
index 0000000..557d3d7
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_variables.scss
@@ -0,0 +1,146 @@
+// @use "sass:math";
+@import '../tools/functions.scss';
+// 间距基础倍数
+$uni-space-root: 2 !default;
+// 边框半径默认值
+$uni-radius-root:5px !default;
+$uni-radius: () !default;
+// 边框半径断点
+$uni-radius: map-deep-merge(
+ (
+ 0: 0,
+ // TODO 当前版本暂时不支持 sm 属性
+ // 'sm': math.div($uni-radius-root, 2),
+ null: $uni-radius-root,
+ 'lg': $uni-radius-root * 2,
+ 'xl': $uni-radius-root * 6,
+ 'pill': 9999px,
+ 'circle': 50%
+ ),
+ $uni-radius
+);
+// 字体家族
+$body-font-family: 'Roboto', sans-serif !default;
+// 文本
+$heading-font-family: $body-font-family !default;
+$uni-headings: () !default;
+$letterSpacing: -0.01562em;
+$uni-headings: map-deep-merge(
+ (
+ 'h1': (
+ size: 32px,
+ weight: 300,
+ line-height: 50px,
+ // letter-spacing:-0.01562em
+ ),
+ 'h2': (
+ size: 28px,
+ weight: 300,
+ line-height: 40px,
+ // letter-spacing: -0.00833em
+ ),
+ 'h3': (
+ size: 24px,
+ weight: 400,
+ line-height: 32px,
+ // letter-spacing: normal
+ ),
+ 'h4': (
+ size: 20px,
+ weight: 400,
+ line-height: 30px,
+ // letter-spacing: 0.00735em
+ ),
+ 'h5': (
+ size: 16px,
+ weight: 400,
+ line-height: 24px,
+ // letter-spacing: normal
+ ),
+ 'h6': (
+ size: 14px,
+ weight: 500,
+ line-height: 18px,
+ // letter-spacing: 0.0125em
+ ),
+ 'subtitle': (
+ size: 12px,
+ weight: 400,
+ line-height: 20px,
+ // letter-spacing: 0.00937em
+ ),
+ 'body': (
+ font-size: 14px,
+ font-weight: 400,
+ line-height: 22px,
+ // letter-spacing: 0.03125em
+ ),
+ 'caption': (
+ 'size': 12px,
+ 'weight': 400,
+ 'line-height': 20px,
+ // 'letter-spacing': 0.03333em,
+ // 'text-transform': false
+ )
+ ),
+ $uni-headings
+);
+
+
+
+// 主色
+$uni-primary: #2979ff !default;
+$uni-primary-disable:lighten($uni-primary,20%) !default;
+$uni-primary-light: lighten($uni-primary,25%) !default;
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37 !default;
+$uni-success-disable:lighten($uni-success,20%) !default;
+$uni-success-light: lighten($uni-success,25%) !default;
+
+$uni-warning: #f3a73f !default;
+$uni-warning-disable:lighten($uni-warning,20%) !default;
+$uni-warning-light: lighten($uni-warning,25%) !default;
+
+$uni-error: #e43d33 !default;
+$uni-error-disable:lighten($uni-error,20%) !default;
+$uni-error-light: lighten($uni-error,25%) !default;
+
+$uni-info: #8f939c !default;
+$uni-info-disable:lighten($uni-info,20%) !default;
+$uni-info-light: lighten($uni-info,25%) !default;
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a !default; // 主要文字
+$uni-base-color: #6a6a6a !default; // 常规文字
+$uni-secondary-color: #909399 !default; // 次要文字
+$uni-extra-color: #c7c7c7 !default; // 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0 !default;
+$uni-border-2: #EDEDED !default;
+$uni-border-3: #DCDCDC !default;
+$uni-border-4: #B9B9B9 !default;
+
+// 常规色
+$uni-black: #000000 !default;
+$uni-white: #ffffff !default;
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
+
+// 背景色
+$uni-bg-color: #f7f7f7 !default;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px !default;
+$uni-spacing-base: 15px !default;
+$uni-spacing-lg: 30px !default;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
diff --git a/uni_modules/uni-scss/styles/tools/functions.scss b/uni_modules/uni-scss/styles/tools/functions.scss
new file mode 100644
index 0000000..ac6f63e
--- /dev/null
+++ b/uni_modules/uni-scss/styles/tools/functions.scss
@@ -0,0 +1,19 @@
+// 合并 map
+@function map-deep-merge($parent-map, $child-map){
+ $result: $parent-map;
+ @each $key, $child in $child-map {
+ $parent-has-key: map-has-key($result, $key);
+ $parent-value: map-get($result, $key);
+ $parent-type: type-of($parent-value);
+ $child-type: type-of($child);
+ $parent-is-map: $parent-type == map;
+ $child-is-map: $child-type == map;
+
+ @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
+ $result: map-merge($result, ( $key: $child ));
+ }@else {
+ $result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
+ }
+ }
+ @return $result;
+};
diff --git a/uni_modules/uni-scss/theme.scss b/uni_modules/uni-scss/theme.scss
new file mode 100644
index 0000000..80ee62f
--- /dev/null
+++ b/uni_modules/uni-scss/theme.scss
@@ -0,0 +1,31 @@
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+// 主色
+$uni-primary: #2979ff;
+// 辅助色
+$uni-success: #4cd964;
+// 警告色
+$uni-warning: #f0ad4e;
+// 错误色
+$uni-error: #dd524d;
+// 描述色
+$uni-info: #909399;
+// 中性色
+$uni-main-color: #303133;
+$uni-base-color: #606266;
+$uni-secondary-color: #909399;
+$uni-extra-color: #C0C4CC;
+// 背景色
+$uni-bg-color: #f5f5f5;
+// 边框颜色
+$uni-border-1: #DCDFE6;
+$uni-border-2: #E4E7ED;
+$uni-border-3: #EBEEF5;
+$uni-border-4: #F2F6FC;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
diff --git a/uni_modules/uni-scss/variables.scss b/uni_modules/uni-scss/variables.scss
new file mode 100644
index 0000000..1c062d4
--- /dev/null
+++ b/uni_modules/uni-scss/variables.scss
@@ -0,0 +1,62 @@
+@import './styles/setting/_variables.scss';
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+
+// 主色
+$uni-primary: #2979ff;
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
+$uni-primary-light: mix(#fff,$uni-primary,80%);
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37;
+$uni-success-disable:mix(#fff,$uni-success,50%);
+$uni-success-light: mix(#fff,$uni-success,80%);
+
+$uni-warning: #f3a73f;
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
+$uni-warning-light: mix(#fff,$uni-warning,80%);
+
+$uni-error: #e43d33;
+$uni-error-disable:mix(#fff,$uni-error,50%);
+$uni-error-light: mix(#fff,$uni-error,80%);
+
+$uni-info: #8f939c;
+$uni-info-disable:mix(#fff,$uni-info,50%);
+$uni-info-light: mix(#fff,$uni-info,80%);
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a; // 主要文字
+$uni-base-color: #6a6a6a; // 常规文字
+$uni-secondary-color: #909399; // 次要文字
+$uni-extra-color: #c7c7c7; // 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0;
+$uni-border-2: #EDEDED;
+$uni-border-3: #DCDCDC;
+$uni-border-4: #B9B9B9;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
+
+// 背景色
+$uni-bg-color: #f7f7f7;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px;
+$uni-spacing-base: 15px;
+$uni-spacing-lg: 30px;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4);
diff --git a/uni_modules/uni-transition/changelog.md b/uni_modules/uni-transition/changelog.md
new file mode 100644
index 0000000..2f2b10d
--- /dev/null
+++ b/uni_modules/uni-transition/changelog.md
@@ -0,0 +1,27 @@
+## 1.3.4(2025-04-16)
+- 修复 页面数据更新到底动画复原的问题
+- 修复 示例页面打开报错的问题
+## 1.3.3(2024-04-23)
+- 修复 当元素会受变量影响自动隐藏的bug
+## 1.3.2(2023-05-04)
+- 修复 NVUE 平台报错的问题
+## 1.3.1(2021-11-23)
+- 修复 init 方法初始化问题
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
+## 1.2.1(2021-09-27)
+- 修复 init 方法不生效的 Bug
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.1(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的 Bug
+## 1.1.0(2021-04-22)
+- 新增 通过方法自定义动画
+- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
+- 优化 动画触发逻辑,使动画更流畅
+- 优化 支持单独的动画类型
+- 优化 文档示例
+## 1.0.2(2021-02-05)
+- 调整为 uni_modules 目录规范
diff --git a/uni_modules/uni-transition/components/uni-transition/createAnimation.js b/uni_modules/uni-transition/components/uni-transition/createAnimation.js
new file mode 100644
index 0000000..8f89b18
--- /dev/null
+++ b/uni_modules/uni-transition/components/uni-transition/createAnimation.js
@@ -0,0 +1,131 @@
+// const defaultOption = {
+// duration: 300,
+// timingFunction: 'linear',
+// delay: 0,
+// transformOrigin: '50% 50% 0'
+// }
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+// #endif
+class MPAnimation {
+ constructor(options, _this) {
+ this.options = options
+ // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
+ this.animation = uni.createAnimation({
+ ...options
+ })
+ this.currentStepAnimates = {}
+ this.next = 0
+ this.$ = _this
+
+ }
+
+ _nvuePushAnimates(type, args) {
+ let aniObj = this.currentStepAnimates[this.next]
+ let styles = {}
+ if (!aniObj) {
+ styles = {
+ styles: {},
+ config: {}
+ }
+ } else {
+ styles = aniObj
+ }
+ if (animateTypes1.includes(type)) {
+ if (!styles.styles.transform) {
+ styles.styles.transform = ''
+ }
+ let unit = ''
+ if(type === 'rotate'){
+ unit = 'deg'
+ }
+ styles.styles.transform += `${type}(${args+unit}) `
+ } else {
+ styles.styles[type] = `${args}`
+ }
+ this.currentStepAnimates[this.next] = styles
+ }
+ _animateRun(styles = {}, config = {}) {
+ let ref = this.$.$refs['ani'].ref
+ if (!ref) return
+ return new Promise((resolve, reject) => {
+ nvueAnimation.transition(ref, {
+ styles,
+ ...config
+ }, res => {
+ resolve()
+ })
+ })
+ }
+
+ _nvueNextAnimate(animates, step = 0, fn) {
+ let obj = animates[step]
+ if (obj) {
+ let {
+ styles,
+ config
+ } = obj
+ this._animateRun(styles, config).then(() => {
+ step += 1
+ this._nvueNextAnimate(animates, step, fn)
+ })
+ } else {
+ this.currentStepAnimates = {}
+ typeof fn === 'function' && fn()
+ this.isEnd = true
+ }
+ }
+
+ step(config = {}) {
+ // #ifndef APP-NVUE
+ this.animation.step(config)
+ // #endif
+ // #ifdef APP-NVUE
+ this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+ this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+ this.next++
+ // #endif
+ return this
+ }
+
+ run(fn) {
+ // #ifndef APP-NVUE
+ this.$.animationData = this.animation.export()
+ this.$.timer = setTimeout(() => {
+ typeof fn === 'function' && fn()
+ }, this.$.durationTime)
+ // #endif
+ // #ifdef APP-NVUE
+ this.isEnd = false
+ let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
+ if(!ref) return
+ this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
+ this.next = 0
+ // #endif
+ }
+}
+
+
+const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+ 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+ 'translateZ'
+]
+const animateTypes2 = ['opacity', 'backgroundColor']
+const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+ MPAnimation.prototype[type] = function(...args) {
+ // #ifndef APP-NVUE
+ this.animation[type](...args)
+ // #endif
+ // #ifdef APP-NVUE
+ this._nvuePushAnimates(type, args)
+ // #endif
+ return this
+ }
+})
+
+export function createAnimation(option, _this) {
+ if(!_this) return
+ clearTimeout(_this.timer)
+ return new MPAnimation(option, _this)
+}
diff --git a/uni_modules/uni-transition/components/uni-transition/uni-transition.vue b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue
new file mode 100644
index 0000000..8772572
--- /dev/null
+++ b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue
@@ -0,0 +1,289 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-transition/package.json b/uni_modules/uni-transition/package.json
new file mode 100644
index 0000000..b76a3ab
--- /dev/null
+++ b/uni_modules/uni-transition/package.json
@@ -0,0 +1,87 @@
+{
+ "id": "uni-transition",
+ "displayName": "uni-transition 过渡动画",
+ "version": "1.3.4",
+ "description": "元素的简单过渡动画",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "动画",
+ "过渡",
+ "过渡动画"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "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"
+ },
+ "uni_modules": {
+ "dependencies": ["uni-scss"],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y",
+ "app-harmony": "u",
+ "app-uvue": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-transition/readme.md b/uni_modules/uni-transition/readme.md
new file mode 100644
index 0000000..2f8a77e
--- /dev/null
+++ b/uni_modules/uni-transition/readme.md
@@ -0,0 +1,11 @@
+
+
+## Transition 过渡动画
+> **组件名:uni-transition**
+> 代码块: `uTransition`
+
+
+元素过渡动画
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/utils/ability.js b/utils/ability.js
new file mode 100644
index 0000000..bc1b51d
--- /dev/null
+++ b/utils/ability.js
@@ -0,0 +1,92 @@
+import { abilityCheck } from "@/api/system";
+import adManager from "@/utils/adManager";
+
+/**
+ * Checks if a user has the ability to perform an action (e.g., download).
+ * Handles common blocking scenarios like "need_share" or "need_ad".
+ *
+ * @param {string} scene - The scene identifier for the ability check (e.g., "wallpaper_download").
+ * @returns {Promise} - Returns true if the action can proceed, false otherwise.
+ */
+export const checkAbilityAndHandle = async (scene) => {
+ try {
+ const abilityRes = await abilityCheck(scene);
+ if (abilityRes.canUse) {
+ return true;
+ }
+
+ if (
+ abilityRes?.blockType === "need_share" &&
+ abilityRes?.message === "分享可继续"
+ ) {
+ uni.showToast({
+ title: "分享给好友即可下载",
+ icon: "none",
+ });
+ return false;
+ }
+
+ if (
+ abilityRes?.blockType === "need_ad"
+ ) {
+ uni.showModal({
+ title: "积分不足",
+ content: "观看广告可获得50积分,继续下载",
+ success: (res) => {
+ if (res.confirm) {
+ adManager.showVideoAd();
+ }
+ },
+ });
+ return false;
+ }
+
+ if (abilityRes?.blockType === "need_vip") {
+ uni.showModal({
+ title: "会员激活",
+ content: "会员激活即可继续使用该功能,是否前往开通?",
+ success: (res) => {
+ if (res.confirm) {
+ uni.navigateTo({
+ url: "/pages/mine/vip",
+ });
+ }
+ },
+ });
+ return false;
+ }
+
+ uni.showToast({
+ title: "您今日下载次数已用完,明日再试",
+ icon: "none",
+ });
+ return false;
+ } catch (e) {
+ console.error("Ability check failed", e);
+ uni.showToast({ title: "系统繁忙,请稍后重试", icon: "none" });
+ return false;
+ }
+};
+
+/**
+ * Gets the display label for an unlock type.
+ * @param {string} unlockType - The unlock type identifier.
+ * @returns {string} - The display label.
+ */
+export const getUnlockLabel = (unlockType) => {
+ if (!unlockType) return "解锁";
+ switch (unlockType) {
+ case "sing3":
+ return "连续签到3天";
+ case "sing5":
+ return "连续签到5天";
+ case "sing7":
+ return "连续签到7天";
+ case "ad":
+ return "广告";
+ case "vip":
+ return "VIP";
+ default:
+ return "解锁";
+ }
+};
diff --git a/utils/adManager.js b/utils/adManager.js
new file mode 100644
index 0000000..89613ca
--- /dev/null
+++ b/utils/adManager.js
@@ -0,0 +1,199 @@
+import { watchAdStart, watchAdReward } from "@/api/system.js";
+import { useUserStore } from "@/stores/user";
+
+class AdManager {
+ constructor() {
+ this.videoAd = null;
+ this.rewardToken = "";
+ this.isLoaded = false;
+ this.isAdShowing = false; // 新增:标记广告是否正在展示
+ this.adUnitId = "adunit-d7a28e0357d98947"; // Default ID from RewardAd.vue
+
+ // 彻底废除预初始化。
+ // 在微信小程序中,如果在页面未完全就绪时调用 createRewardedVideoAd,
+ // 会导致底层寻找挂载点失败,抛出 `insertTextView:fail` 等严重渲染错误。
+ // 因此改为:只在用户真正点击“看广告”时才进行初始化。
+ }
+
+ /**
+ * Initializes the ad instance synchronously when needed.
+ * @param {string} adUnitId
+ */
+ _initSync(adUnitId) {
+ if (this.videoAd && this.adUnitId === adUnitId) {
+ return true; // Already initialized for this ID
+ }
+
+ this.adUnitId = adUnitId || this.adUnitId;
+
+ // #ifdef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-QQ
+ if (uni.createRewardedVideoAd) {
+ try {
+ // Destroy old instance if ID changed
+ if (this.videoAd) {
+ if (this.videoAd.destroy) {
+ try {
+ this.videoAd.destroy();
+ } catch (destroyErr) {
+ console.error("Ad Manager: destroy old ad failed", destroyErr);
+ }
+ }
+ this.videoAd = null;
+ }
+
+ // 核心修复:微信小程序官方建议使用单例,且多次调用 createRewardedVideoAd 传入相同的 adUnitId 会返回同一个实例。
+ // 但如果在短时间内销毁又立即创建,底层可能会发生不可预知的渲染报错(如找不到 parent 节点)。
+ // 因此,我们只需安全地获取实例,并重新绑定事件。
+ this.videoAd = uni.createRewardedVideoAd({
+ adUnitId: this.adUnitId
+ });
+
+ if (this.videoAd) {
+ // 清理之前可能存在的残留事件,防止重复触发和内存泄漏导致底层崩溃
+ if (this.videoAd.offLoad) this.videoAd.offLoad();
+ if (this.videoAd.offError) this.videoAd.offError();
+ if (this.videoAd.offClose) this.videoAd.offClose();
+
+ this.videoAd.onLoad(() => {
+ console.log("Ad Manager: Ad Loaded");
+ this.isLoaded = true;
+ });
+
+ this.videoAd.onError((err) => {
+ console.error("Ad Manager: Ad Load Error", err);
+ this.isLoaded = false;
+ });
+ return true;
+ }
+ } catch (e) {
+ console.error("Ad Manager Init Error", e);
+ return false;
+ }
+ }
+ // #endif
+ return false;
+ }
+
+ /**
+ * Show the rewarded video ad.
+ * Handles the full flow: start session -> show ad -> verify completion -> claim reward -> refresh assets.
+ * @param {string} [adUnitId] - Optional adUnitId to override the default.
+ * @param {string} [providedToken] - Optional token if watchAdStart was already called externally.
+ * @returns {Promise} Resolves with true if reward was claimed, false otherwise.
+ */
+ async showVideoAd(adUnitId, providedToken) {
+ if (this.isAdShowing || this.isStarting) {
+ console.log("Ad Manager: Ad is already starting or showing");
+ return false;
+ }
+
+ this.isStarting = true;
+
+ // 延迟到这一步才初始化,避开页面渲染期
+ const canInit = this._initSync(adUnitId);
+
+ if (!canInit || !this.videoAd) {
+ uni.showToast({ title: "当前环境不支持广告", icon: "none" });
+ this.isStarting = false;
+ return false;
+ }
+
+ try {
+ // Step 1: Start Ad Session (if not provided)
+ if (providedToken) {
+ this.rewardToken = providedToken;
+ } else {
+ const startRes = await watchAdStart();
+ if (!startRes || !startRes.rewardToken) {
+ uni.showToast({ title: "广告启动失败,请稍后再试", icon: "none" });
+ this.isStarting = false;
+ return false;
+ }
+ this.rewardToken = startRes.rewardToken;
+ }
+
+ // Step 2: Show Ad
+ try {
+ this.isAdShowing = true;
+ this.isStarting = false;
+ await this.videoAd.show();
+ } catch (e) {
+ // Retry load and show
+ try {
+ await this.videoAd.load();
+ await this.videoAd.show();
+ } catch (loadErr) {
+ this.isAdShowing = false;
+ console.error("Ad Manager: Retry load failed", loadErr);
+ throw loadErr;
+ }
+ }
+
+ // Step 3: Wait for Close
+ return new Promise((resolve) => {
+ const onCloseHandler = async (res) => {
+ // 延迟 500ms 释放状态,防止从广告返回页面时(onShow)立即触发 DOM 大量更新,导致底层 insertTextView:fail 崩溃
+ setTimeout(() => {
+ this.isAdShowing = false;
+ }, 500);
+
+ // 安全地解绑事件
+ try {
+ if (this.videoAd && this.videoAd.offClose) {
+ this.videoAd.offClose(onCloseHandler); // Clean up listener
+ }
+ } catch (offErr) {
+ console.error("Ad Manager: offClose error", offErr);
+ }
+
+ if (res && res.isEnded) {
+ // Step 4: Claim Reward
+ // Only claim if token wasn't provided externally (if provided, external component claims it)
+ if (!providedToken) {
+ await this._claimReward(this.rewardToken);
+ }
+ resolve(true);
+ } else {
+ uni.showToast({ title: "观看完整广告才能获取奖励哦", icon: "none" });
+ resolve(false);
+ }
+ };
+
+ try {
+ this.videoAd.onClose(onCloseHandler);
+ } catch (onErr) {
+ console.error("Ad Manager: onClose error", onErr);
+ resolve(false);
+ }
+ });
+
+ } catch (e) {
+ console.error("Ad Manager: Show failed", e);
+ uni.showToast({ title: "广告加载失败,请稍后再试", icon: "none" });
+ return false;
+ }
+ }
+
+ async _claimReward(token) {
+ try {
+ uni.showLoading({ title: "发放奖励中..." });
+ const res = await watchAdReward(token);
+ if (res) {
+ uni.showToast({
+ title: "获得50积分",
+ icon: "success",
+ });
+ // Refresh user assets
+ const userStore = useUserStore();
+ await userStore.fetchUserAssets();
+ }
+ } catch (e) {
+ console.error("Ad Manager: Reward claim failed", e);
+ uni.showToast({ title: "奖励发放失败", icon: "none" });
+ } finally {
+ uni.hideLoading();
+ }
+ }
+}
+
+export default new AdManager();
diff --git a/utils/common.js b/utils/common.js
new file mode 100644
index 0000000..1b404ec
--- /dev/null
+++ b/utils/common.js
@@ -0,0 +1,127 @@
+import { getDeviceInfo } from "@/utils/system";
+import {
+ saveRecord,
+ viewRecord,
+ createShareToken,
+ createTracking,
+} from "@/api/system";
+
+export const generateObjectId = (
+ m = Math,
+ d = Date,
+ h = 16,
+ s = (s) => m.floor(s).toString(h),
+) => s(d.now() / 1000) + " ".repeat(h).replace(/./g, () => s(m.random() * h));
+
+export const uploadImage = (filePath) => {
+ return new Promise((resolve, reject) => {
+ uni.uploadFile({
+ url: "https://api.ai-meng.com/api/common/upload",
+ filePath: filePath,
+ name: "file",
+ header: {
+ "x-app-id": "69665538a49b8ae3be50fe5d",
+ },
+ success: (res) => {
+ if (res.statusCode < 400) {
+ try {
+ const keyJson = JSON.parse(res.data);
+ if (keyJson?.data?.result === "auditFailed") {
+ reject("图片不符合发布规范,请稍作修改后再试");
+ } else {
+ const url = `https://file.lihailezzc.com/${keyJson?.data.key}`;
+ resolve(url);
+ }
+ } catch (e) {
+ reject(e);
+ }
+ } else {
+ reject(new Error("Upload failed"));
+ }
+ },
+ fail: (err) => {
+ reject(err);
+ },
+ });
+ });
+};
+
+export const saveRecordRequest = async (path, targetId, scene, imageUrl) => {
+ if (!imageUrl) {
+ imageUrl = await uploadImage(path);
+ }
+ const deviceInfo = getDeviceInfo();
+ saveRecord({
+ scene,
+ targetId,
+ imageUrl,
+ deviceInfo,
+ });
+};
+
+export const saveViewRequest = async (shareToken, scene, targetId = "") => {
+ const deviceInfo = getDeviceInfo();
+ viewRecord({
+ shareToken,
+ scene,
+ targetId,
+ deviceInfo,
+ });
+};
+
+export const saveRemoteImageToLocal = (imageUrl) => {
+ return new Promise((resolve, reject) => {
+ uni.downloadFile({
+ url: imageUrl,
+ success: (res) => {
+ if (res.statusCode === 200) {
+ uni.saveImageToPhotosAlbum({
+ filePath: res.tempFilePath,
+ success: () => {
+ resolve(true);
+ },
+ fail: (err) => {
+ reject(err);
+ },
+ });
+ } else {
+ reject(
+ new Error("Download failed with status code: " + res.statusCode),
+ );
+ }
+ },
+ fail: (err) => {
+ reject(err);
+ },
+ });
+ });
+};
+
+export const getShareToken = async (scene, targetId = "") => {
+ const deviceInfo = getDeviceInfo();
+ const shareTokenRes = await createShareToken({
+ scene,
+ targetId,
+ ...deviceInfo,
+ });
+ return shareTokenRes?.shareToken || "";
+};
+
+export const trackRecord = (event) => {
+ const pages = getCurrentPages();
+ // 核心修复:在小程序刚启动或页面尚未压栈时,pages 可能为空数组
+ const currentPage = pages && pages.length > 0 ? pages[pages.length - 1] : null;
+ const route = currentPage ? currentPage.route : "app_launch";
+
+ const deviceInfo = getDeviceInfo();
+ createTracking({
+ ...event,
+ page: route,
+ deviceInfo,
+ });
+};
+
+export const getThumbUrl = (url) => {
+ if (!url) return "";
+ return `${url}?imageView2/1/w/200/h/200/q/80`;
+};
\ No newline at end of file
diff --git a/utils/date.js b/utils/date.js
new file mode 100644
index 0000000..2ad46a7
--- /dev/null
+++ b/utils/date.js
@@ -0,0 +1,18 @@
+export function formatDate(isoString, format = 'YYYY-MM-DD HH:mm:ss') {
+ if (!isoString) return ''
+ const date = new Date(isoString)
+ if (isNaN(date.getTime())) return ''
+
+ const pad = (n) => n.toString().padStart(2, '0')
+
+ const map = {
+ YYYY: date.getFullYear().toString(),
+ MM: pad(date.getMonth() + 1),
+ DD: pad(date.getDate()),
+ HH: pad(date.getHours()),
+ mm: pad(date.getMinutes()),
+ ss: pad(date.getSeconds())
+ }
+
+ return format.replace(/YYYY|MM|DD|HH|mm|ss/g, token => map[token])
+}
\ No newline at end of file
diff --git a/utils/login.js b/utils/login.js
new file mode 100644
index 0000000..e1cb1c1
--- /dev/null
+++ b/utils/login.js
@@ -0,0 +1,53 @@
+export const wxLogin = () => {
+ return new Promise((resolve, reject) => {
+ wx.login({
+ success: (res) => {
+ if (res.code) {
+ resolve(res.code);
+ } else {
+ reject("登录失败:code为空");
+ }
+ },
+ fail: (err) => {
+ reject(err);
+ },
+ });
+ });
+};
+
+export const alipayLogin = () => {
+ return new Promise((resolve, reject) => {
+ // #ifdef MP-ALIPAY
+ my.getAuthCode({
+ scopes: "auth_user",
+ success: (res) => {
+ if (res.authCode) {
+ resolve(res.authCode);
+ } else {
+ reject("登录失败:authCode为空");
+ }
+ },
+ fail: (err) => {
+ reject(err);
+ },
+ });
+ // #endif
+ // #ifndef MP-ALIPAY
+ reject("当前非支付宝环境");
+ // #endif
+ });
+};
+
+export const wxGetUserProfile = () => {
+ return new Promise((resolve, reject) => {
+ wx.getUserProfile({
+ desc: "用于完善用户信息",
+ success: (res) => {
+ resolve(res);
+ },
+ fail: (err) => {
+ reject(err);
+ },
+ });
+ });
+};
diff --git a/utils/request.js b/utils/request.js
new file mode 100644
index 0000000..d951f40
--- /dev/null
+++ b/utils/request.js
@@ -0,0 +1,143 @@
+const BASE_URL = "https://api.ai-meng.com";
+// const BASE_URL = 'http://127.0.0.1:3999'
+// const BASE_URL = "http://192.168.1.2:3999";
+// const BASE_URL = "http://192.168.31.253:3999";
+import { useUserStore } from "@/stores/user";
+import { getPlatform } from "./system.js";
+const platform = getPlatform();
+
+// 环境区分
+// 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 userStore = useUserStore();
+ const headers = {
+ "x-app-id": "69665538a49b8ae3be50fe5d",
+ "x-platform": platform,
+ "x-user-id": userStore?.userInfo?.id || "",
+ };
+ 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} 返回接口 data
+ */
+export function request(config) {
+ if (!config || !config.url) {
+ return Promise.reject(new Error("请求缺少 url 参数"));
+ }
+
+ const {
+ url,
+ method = "GET",
+ data = {},
+ header = {},
+ showLoading = false,
+ showError = true,
+ retry = 1,
+ loadingText = "加载中",
+ } = config;
+
+ const finalHeader = { ...getHeaders(), ...header };
+ const upperMethod = method.toUpperCase();
+
+ let attempt = 0;
+
+ const doRequest = () =>
+ new Promise((resolve, reject) => {
+ if (showLoading) showLoadingFlag(loadingText);
+
+ uni.request({
+ url: BASE_URL + url,
+ method: upperMethod,
+ 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 {
+ reject({
+ type: "business",
+ msg: body?.msg || "服务器错误",
+ data: body,
+ });
+ }
+ },
+ 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();
+}
diff --git a/utils/system.js b/utils/system.js
new file mode 100644
index 0000000..2fe05be
--- /dev/null
+++ b/utils/system.js
@@ -0,0 +1,122 @@
+function getSafeSystemInfo() {
+ try {
+ // #ifdef MP-WEIXIN
+ // 优先使用原生 wx 新 API,避开 uni 包装层内部对 getSystemInfoSync 的兼容调用
+ if (
+ typeof wx !== "undefined" &&
+ wx.getWindowInfo &&
+ wx.getAppBaseInfo &&
+ wx.getDeviceInfo
+ ) {
+ return {
+ ...wx.getWindowInfo(),
+ ...wx.getAppBaseInfo(),
+ ...wx.getDeviceInfo(),
+ };
+ }
+ // #endif
+
+ if (uni.getWindowInfo && uni.getAppBaseInfo && uni.getDeviceInfo) {
+ return {
+ ...uni.getWindowInfo(),
+ ...uni.getAppBaseInfo(),
+ ...uni.getDeviceInfo(),
+ };
+ }
+ } catch (e) {
+ // fall through to legacy fallback
+ }
+
+ return uni.getSystemInfoSync();
+}
+
+let SYSTEM = getSafeSystemInfo();
+
+export const getStatusBarHeight = () => SYSTEM.statusBarHeight || 15;
+
+export const getTitleBarHeight = () => {
+ // #ifdef MP-ALIPAY
+ return 44;
+ // #endif
+
+ if (uni.getMenuButtonBoundingClientRect) {
+ try {
+ const rect = uni.getMenuButtonBoundingClientRect();
+ if (rect && rect.top && rect.height) {
+ return rect.height + (rect.top - getStatusBarHeight()) * 2;
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ return 44;
+};
+
+export const getBavBarHeight = () => getStatusBarHeight() + getTitleBarHeight();
+
+export const getLeftIconLeft = () => {
+ // if(tt?.getMenuButtonBoundingClientRect) {
+ // const { leftIcon: {left, width}} = tt.getMenuButtonBoundingClientRect
+ // return left + parseInt(width) + 5
+ // } else {
+ // return 0
+ // }
+ // #ifdef MP-TOUTIAO
+ const {
+ leftIcon: { left, width },
+ } = tt.getCustomButtonBoundingClientRect();
+ return left + parseInt(width);
+ // #endif
+ // #ifndef MP-TOUTIAO
+ return 0;
+ // #endif
+};
+
+export function getPlatform() {
+ return getPlatformProvider().replace("mp-", "");
+}
+
+export function getPlatformProvider() {
+ const platform = process.env.UNI_PLATFORM;
+ return platform || "mp-weixin";
+ // const platform = uni.getSystemInfoSync().platform;
+ // console.log(1111111, platform)
+ // // H5 模拟器调试时使用 __wxConfig 环境变量判断
+ // if (typeof __wxConfig !== 'undefined') return 'weixin';
+ // if (platform === 'devtools') {
+ // // 可以根据小程序环境变量判断
+ // // 抖音开发工具会定义 tt 对象
+ // return typeof tt !== 'undefined' ? 'toutiao' : 'weixin';
+ // }
+
+ // return typeof tt !== 'undefined' ? 'toutiao' : 'weixin';
+}
+
+export function getDeviceInfo() {
+ const info = getSafeSystemInfo();
+
+ 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,
+ appId: "69665538a49b8ae3be50fe5d",
+ };
+}
+
+/**
+ * 判断是否处于朋友圈单页模式
+ */
+export function isSinglePageMode() {
+ // #ifdef MP-WEIXIN
+ const launchOptions = uni.getLaunchOptionsSync();
+ return launchOptions.scene === 1154;
+ // #endif
+ return false;
+}
diff --git a/utils/track.js b/utils/track.js
new file mode 100644
index 0000000..73d597f
--- /dev/null
+++ b/utils/track.js
@@ -0,0 +1,121 @@
+import { request } from "@/utils/request";
+
+// 生成并缓存 device_id
+function getOrCreateDeviceId() {
+ let deviceId = uni.getStorageSync("device_id");
+ if (!deviceId) {
+ deviceId = Date.now() + "_" + Math.random().toString(36).substr(2, 9);
+ uni.setStorageSync("device_id", deviceId);
+ }
+ return deviceId;
+}
+
+// 获取网络类型
+function getNetworkType() {
+ return new Promise((resolve) => {
+ uni.getNetworkType({
+ success: (res) => resolve(res.networkType || "unknown"),
+ fail: () => resolve("unknown"),
+ });
+ });
+}
+
+// 获取系统平台
+function getSystemInfo() {
+ return new Promise((resolve) => {
+ uni.getSystemInfo({
+ success: (res) => resolve(res),
+ fail: () => resolve({}),
+ });
+ });
+}
+
+// 获取当前页面路径
+function getCurrentPagePath() {
+ const pages = getCurrentPages();
+ const currentPage = pages[pages.length - 1];
+ return currentPage?.route || "";
+}
+
+function getMiniProgramVersion() {
+ const platform = process.env.UNI_PLATFORM;
+ let version = "";
+ let envVersion = "";
+
+ try {
+ if (platform === "mp-weixin") {
+ // 微信小程序
+ const info = wx.getAccountInfoSync();
+ version = info?.miniProgram?.version || "";
+ envVersion = info?.miniProgram?.envVersion || "";
+ } else if (platform === "mp-alipay") {
+ // 支付宝小程序
+ const info = my.getAppInfoSync();
+ version = info?.version || "";
+ } else if (platform === "mp-toutiao" || platform === "mp-jd") {
+ // 抖音/头条/京东小程序
+ const info = tt.getAccountInfoSync?.();
+ version = info?.miniProgram?.version || "";
+ envVersion = info?.miniProgram?.envVersion || "";
+ } else if (platform === "mp-baidu") {
+ // 百度小程序(无标准方法获取版本号)
+ version = ""; // 百度不支持获取版本号
+ } else {
+ version = "";
+ }
+ } catch (e) {
+ version = "";
+ envVersion = "";
+ }
+
+ return {
+ platform, // 当前小程序平台
+ version, // 小程序版本号
+ envVersion, // develop / trial / release(微信等支持)
+ };
+}
+
+// 构造埋点对象
+async function buildEventData(
+ eventName,
+ eventType = "click",
+ customParams = {}
+) {
+ const deviceId = getOrCreateDeviceId();
+ const systemInfo = await getSystemInfo();
+ const networkType = await getNetworkType();
+ // const location = await getLocation()
+ const appVersion = typeof plus !== "undefined" ? plus?.runtime?.version : "";
+ const { envVersion, platform, version } = getMiniProgramVersion();
+
+ return {
+ userId: uni.getStorageSync("user_id") || null,
+ deviceId: deviceId,
+ eventName: eventName,
+ eventType: eventType,
+ eventTime: new Date(),
+ page: getCurrentPagePath(),
+ elementId: customParams.element_id || null,
+ elementContent: customParams.element_content || null,
+ customParams: customParams,
+ networkType: networkType,
+ os: systemInfo.platform || "unknown",
+ appVersion: version || "unknown",
+ envVersion: envVersion || "",
+ platform: platform || "",
+ };
+}
+
+// 发送埋点数据到服务器
+async function sendTrack(eventName, eventType = "click", customParams = {}) {
+ const eventData = await buildEventData(eventName, eventType, customParams);
+ request({
+ url: "/api/common/tracking/create",
+ method: "POST",
+ data: eventData,
+ });
+}
+
+export default {
+ sendTrack,
+};