Pārlūkot izejas kodu

build: delete locale + demo

菲鸽 2 gadi atpakaļ
vecāks
revīzija
adb67da1a7
37 mainītis faili ar 23 papildinājumiem un 2507 dzēšanām
  1. 2 8
      pages.config.ts
  2. 0 12
      src/locale/README.md
  3. 0 4
      src/locale/en.json
  4. 0 37
      src/locale/index.ts
  5. 0 4
      src/locale/zh-Hans.json
  6. 0 2
      src/main.ts
  7. 0 12
      src/pages/demo/base/auto-import.vue
  8. 0 21
      src/pages/demo/base/enum.vue
  9. 0 42
      src/pages/demo/base/mp-weixin-share.vue
  10. 0 19
      src/pages/demo/base/navbar.vue
  11. 0 40
      src/pages/demo/base/pinia.vue
  12. 0 67
      src/pages/demo/base/request.vue
  13. 0 145
      src/pages/demo/base/throughout.vue
  14. 0 16
      src/pages/demo/base/uni-ui-icons.vue
  15. 0 14
      src/pages/demo/base/uni-ui.vue
  16. 0 20
      src/pages/demo/base/unocss-icons.vue
  17. 0 15
      src/pages/demo/base/unocss.vue
  18. 0 49
      src/pages/demo/base/uv-ui.vue
  19. 0 22
      src/pages/demo/base/vconsole.vue
  20. 0 81
      src/pages/demo/index.vue
  21. 0 130
      src/pages/demo/page/clock.vue
  22. 0 152
      src/pages/demo/page/clock2.vue
  23. 0 88
      src/pages/demo/page/floating-bubble.vue
  24. 0 84
      src/pages/demo/page/i18n.vue
  25. 0 38
      src/pages/demo/page/img-min/index.vue
  26. BIN
      src/pages/demo/page/img-min/test-bg.png
  27. 0 127
      src/pages/demo/page/lottery.vue
  28. 0 216
      src/pages/demo/page/lottery/big-wheel.vue
  29. 0 196
      src/pages/demo/page/lottery/nine-grid.vue
  30. 0 181
      src/pages/demo/page/lottery2.vue
  31. 0 266
      src/pages/demo/page/sign.vue
  32. 0 188
      src/pages/demo/page/waterfall.vue
  33. 21 0
      src/pages/index/about.vue
  34. 0 82
      src/pages/index/i18n.vue
  35. 0 55
      src/pages/index/request.vue
  36. 0 39
      src/pages/my/components/wx-login.vue
  37. 0 35
      src/pages/my/index.vue

+ 2 - 8
pages.config.ts

@@ -34,14 +34,8 @@ export default defineUniPages({
       {
         iconPath: 'static/tabbar/example.png',
         selectedIconPath: 'static/tabbar/exampleHL.png',
-        pagePath: 'pages/demo/index',
-        text: '示例',
-      },
-      {
-        iconPath: 'static/tabbar/personal.png',
-        selectedIconPath: 'static/tabbar/personalHL.png',
-        pagePath: 'pages/my/index',
-        text: '我的',
+        pagePath: 'pages/index/about',
+        text: '关于',
       },
     ],
   },

+ 0 - 12
src/locale/README.md

@@ -1,12 +0,0 @@
-# 注意事项
-
-> 文件夹名字必须为 `locale`, 这是 `uniapp` 官方约定的,如果改为别的,标题将不能正常切换多语言(其他内容还是正常)。
->
-> `xxx.json` 的 `xxx` 多语言标识必须与 `uniapp` 官方约定的一致,否则也会出现 BUG。
->
-> 查看截图 `screenshots/i18n.png`。
-
-## 参考文档
-
-[uniapp 国际化开发指南](https://uniapp.dcloud.net.cn/tutorial/i18n.html)
-[uniapp 国际化-注意事项](https://uniapp.dcloud.net.cn/api/ui/locale.html#onlocalechange) 最下面的注意事项

+ 0 - 4
src/locale/en.json

@@ -1,4 +0,0 @@
-{
-  "weight": "{heavy}KG",
-  "app.name": "En Title"
-}

+ 0 - 37
src/locale/index.ts

@@ -1,37 +0,0 @@
-import { createI18n } from 'vue-i18n'
-
-import en from './en.json'
-import zhHans from './zh-Hans.json' // 简体中文
-
-const messages = {
-  en,
-  'zh-Hans': zhHans, // key 不能乱写,查看截图 screenshots/i18n.png
-}
-
-const i18n = createI18n({
-  locale: uni.getLocale(), // 获取已设置的语言,fallback 语言需要再 manifest.config.ts 中设置
-  messages,
-})
-
-console.log(uni.getLocale())
-console.log(i18n.global.locale)
-
-/**
- * 非 vue 文件使用这个方法
- * @param { string } localeKey 多语言的key,eg: "app.name"
- */
-export const translate = (localeKey: string) => {
-  if (!localeKey) {
-    console.error(`[i18n] Function translate(), localeKey param is required`)
-    return ''
-  }
-  const locale = uni.getLocale()
-  console.log('locale:', locale)
-
-  const message = messages[locale]
-  if (Object.keys(message).includes(localeKey)) {
-    return message[localeKey]
-  }
-  return localeKey
-}
-export default i18n

+ 0 - 4
src/locale/zh-Hans.json

@@ -1,4 +0,0 @@
-{
-  "app.name": "中文标题",
-  "weight": "{heavy}公斤"
-}

+ 0 - 2
src/main.ts

@@ -2,7 +2,6 @@ import { createSSRApp } from 'vue'
 import uvUI from '@climblee/uv-ui'
 import App from './App.vue'
 import store from './store'
-import i18n from './locale/index'
 import 'virtual:svg-icons-register'
 import 'virtual:uno.css'
 import '@/style/index.scss'
@@ -10,7 +9,6 @@ import '@/style/index.scss'
 export function createApp() {
   const app = createSSRApp(App)
   app.use(store)
-  app.use(i18n)
   app.use(uvUI)
   return {
     app,

+ 0 - 12
src/pages/demo/base/auto-import.vue

@@ -1,12 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: 'auto import component' },
-}
-</route>
-<template>
-  <div>
-    <h1>欢迎使用 vitess-uni-app</h1>
-    <AppTest> 这个组件会自动导入 </AppTest>
-  </div>
-</template>

+ 0 - 21
src/pages/demo/base/enum.vue

@@ -1,21 +0,0 @@
-<route lang="json5" type="page">
-{
-  style: { navigationBarTitleText: 'enum' },
-}
-</route>
-
-<template>
-  <view class="">enum</view>
-</template>
-
-<script lang="ts" setup>
-import { TestEnum } from '@/typings.d'
-
-type T = TestEnum.A
-const a = 'a' as T
-console.log(a)
-</script>
-
-<style lang="scss" scoped>
-//
-</style>

+ 0 - 42
src/pages/demo/base/mp-weixin-share.vue

@@ -1,42 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '微信分享' },
-}
-</route>
-
-<template>
-  <view class="text-green">微信分享页</view>
-  <view class="text-green-500">请在微信小程序中体验,或者开发者工具</view>
-  <view>1) 默认是不激活”发送给朋友“和”分享到朋友圈“的,如下图</view>
-  <image
-    src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/wx-share/wx-share-before.png"
-    mode="widthFix"
-  />
-  <view>2) 增加了onShareAppMessage和onShareTimeline后,就可以微信分享了,如下图</view>
-  <image
-    src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/wx-share/wx-share-after.png"
-    mode="widthFix"
-  />
-</template>
-
-<script lang="ts" setup>
-import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-/** 激活“分享给好友” */
-onShareAppMessage((options: Page.ShareAppMessageOption): Page.CustomShareContent => {
-  console.log('options:', options)
-  return {
-    title: '自定义分享标题',
-    path: '/pages/index/index?id=xxx',
-    imageUrl:
-      'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/pretty-girl.png',
-  }
-})
-/** 激活“分享到朋友圈”, 注意:需要先激活“分享给好友” */
-onShareTimeline((): Page.ShareTimelineContent => {
-  return {
-    title: '自定义分享标题',
-    query: 'a=1&b=2',
-  }
-})
-</script>

+ 0 - 19
src/pages/demo/base/navbar.vue

@@ -1,19 +0,0 @@
-<route lang="json5">
-{
-  style: { navigationBarTitleText: '自定义导航栏', navigationStyle: 'custom' },
-}
-</route>
-
-<template>
-  <fly-navbar />
-  <view class="bg-green-300 min-h-20" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
-    <view class="p-4"> 自定义导航栏,设置"navigationStyle":"custom" </view>
-    <view class="p-4"> 通常页面顶部有一个图片或背景色 </view>
-  </view>
-  <fly-content :line="20" />
-</template>
-
-<script lang="ts" setup>
-// 获取屏幕边界到安全区域距离
-const { safeAreaInsets } = uni.getSystemInfoSync()
-</script>

+ 0 - 40
src/pages/demo/base/pinia.vue

@@ -1,40 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: 'pinia+持久化' },
-}
-</route>
-
-<template>
-  <view class="flex justify-center items-center text-blue-500 mt-4 mb-4">
-    <view class="w-20">Count: {{ countStore.count }}</view>
-    <button class="ml-2 mr-2" @click="countStore.decrement">-1</button>
-    <button class="ml-2 mr-2" @click="countStore.increment">+1</button>
-    <button class="ml-2 mr-2" @click="countStore.reset">重置</button>
-  </view>
-  <view class="m-8 text-4 leading-8">
-    <view class="text-center">{{ userStore.userInfo }}</view>
-    <view class="text-center">请观察小程序的store,可以看到是可以正常设置的</view>
-    <button @click="setUserInfo">设置UserInfo</button>
-    <button @click="clearUserInfo" class="mt-4">清除UserInfo</button>
-    <button @click="resetUserStore" class="mt-4">reset UserStore</button>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { useCountStore, useUserStore } from '@/store'
-
-const countStore = useCountStore()
-
-const userStore = useUserStore()
-
-const setUserInfo = () => {
-  userStore.setUserInfo({ nickname: 'fly', avatar: '', token: 'abcdef' })
-}
-const clearUserInfo = () => {
-  userStore.clearUserInfo()
-}
-const resetUserStore = () => {
-  userStore.reset()
-}
-</script>

+ 0 - 67
src/pages/demo/base/request.vue

@@ -1,67 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: {
-    navigationBarTitleText: '请求',
-  },
-}
-</route>
-
-<template>
-  <view class="mt-6">
-    <!-- http://localhost:9100/#/pages/index/request -->
-    <button @click="getFoo" class="my-4">测试 GET 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view class="text-green h-10">{{ JSON.stringify(data) }}</view>
-    <view class="text-xl">完整数据</view>
-    <view class="text-green h-20">{{ JSON.stringify(originalData) }}</view>
-    <button @click="postFoo" class="my-4">测试 POST 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view class="text-green h-10">{{ JSON.stringify(data2) }}</view>
-
-    <button class="my-8" type="warn" @click="reset">一键清空数据</button>
-
-    <view class="my-2">使用的是 laf 云后台</view>
-    <view class="text-green-400">我的推荐码,可以获得佣金</view>
-    <!-- #ifdef H5 -->
-    <view class="my-2 text-center">
-      <a class="my-2 text-center" :href="recommendUrl" target="_blank">{{ recommendUrl }}</a>
-    </view>
-    <!-- #endif -->
-
-    <!-- #ifndef H5 -->
-    <view class="my-2 text-left text-sm">{{ recommendUrl }}</view>
-    <!-- #endif -->
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { getFooAPI, postFooAPI, IFooItem } from '@/service/foo'
-import { IResData } from '@/typings'
-
-const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX')
-
-onLoad(() => {
-  getFoo()
-  postFoo()
-})
-const originalData = ref<IResData<IFooItem>>()
-const data = ref<IFooItem>()
-const getFoo = async () => {
-  const res = await getFooAPI('菲鸽')
-  data.value = res.result
-  originalData.value = res
-}
-
-const data2 = ref<IFooItem>()
-const postFoo = async () => {
-  const res = await postFooAPI('菲鸽2')
-  data2.value = res.result
-}
-
-const reset = () => {
-  data.value = undefined
-  data2.value = undefined
-  originalData.value = undefined
-}
-</script>

+ 0 - 145
src/pages/demo/base/throughout.vue

@@ -1,145 +0,0 @@
-<route lang="json5">
-{
-  style: {
-    navigationBarTitleText: '通屏+下拉刷新+自定义导航栏',
-    enablePullDownRefresh: false,
-    backgroundColor: '#23c09c', // 这个背景色要与页面的.top-section的背景图差不多,这样下拉刷新看起来才比较协调
-    'app-plus': {
-      titleNView: {
-        type: 'transparent',
-      },
-    },
-    'mp-weixin': {
-      navigationStyle: 'custom',
-    },
-  },
-}
-</route>
-
-<template>
-  <!-- #ifdef MP-WEIXIN -->
-  <view class="fly-navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
-    <!-- 1/3,多于1个页面,用返回图标 -->
-    <navigator v-if="pages.length > 1" open-type="navigateBack" class="left-icon">
-      <view class="i-carbon-chevron-left text-current"></view>
-    </navigator>
-    <!-- 2/3,只有1个页面,如果不是tabbar,需要首页图标 -->
-    <!-- 这种情况一般出现在用户直接打开分享出去的详情页面,或者使用redirectTo等API -->
-    <navigator
-      v-else-if="!isTabbar"
-      open-type="switchTab"
-      url="/pages/index/index"
-      class="left-icon"
-    >
-      <view class="i-carbon-home text-current"></view>
-    </navigator>
-    <!-- 3/3,如果当前页就是tabbar页,不用去首页,也就是什么图标都不需要 -->
-    <view class="title">{{ '我是标题' }}</view>
-  </view>
-  <!-- #endif -->
-
-  <scroll-view
-    enable-back-to-top
-    scroll-y
-    class="scroll-view-bg flex-1 h-full"
-    id="scroller"
-    refresher-enabled
-    @scrolltolower="onScrollToLower"
-    @refresherrefresh="onRefresherRefresh"
-    :refresher-triggered="isTriggered"
-  >
-    <view class="top-section" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
-      <view class="pt-1">顶部区域</view>
-      <view>可以是标题,也可以是个人中心头像等</view>
-      <view>建议本区域高度不低于200rpx</view>
-    </view>
-    <view class="p-2 leading-6 bg-white">
-      注意,上面的导航栏渐变效果仅微信端支持,且上面的导航栏无法抽为组件引入使用,否则滚动效果没有了。如果不只是微信小程序使用,可以
-      onPageScroll 实现全端效果一样,另外如果是app端,还可以配置 titleNView。参考
-      https://uniapp.dcloud.net.cn/tutorial/page.html#onpagescroll 。
-    </view>
-    <view class="bg-white">
-      <fly-content :line="30" />
-    </view>
-  </scroll-view>
-</template>
-
-<script lang="ts" setup>
-import useNavbarWeixin from '@/hooks/useNavbarWeixin'
-import { onPullDownRefresh } from '@dcloudio/uni-app'
-
-const { pages, isTabbar, onScrollToLower, safeAreaInsets } = useNavbarWeixin()
-
-// 发现原生下拉刷新效果并不好,在微信里面只有顶部导航栏下拉才生效,页面区域下拉不生效,体验不好,结合自定义下拉刷新效果很好
-onPullDownRefresh(() => {
-  setTimeout(function fn() {
-    console.log('refresh - onPullDownRefresh')
-    // 关闭动画
-    uni.stopPullDownRefresh()
-  }, 1000)
-})
-
-// 当前下拉刷新状态
-const isTriggered = ref(false)
-// 自定义下拉刷新被触发
-const onRefresherRefresh = async () => {
-  // 开始动画
-  isTriggered.value = true
-  setTimeout(function fn() {
-    console.log('refresh - onRefresherRefresh')
-    // 关闭动画
-    isTriggered.value = false
-  }, 1000)
-}
-</script>
-
-<style lang="scss">
-.scroll-view-bg {
-  // 这个背景色要与.top-section的背景图差不多,这样下拉刷新看起来才比较协调
-  background-color: #23c09c;
-}
-
-// 这个区域最好要大于200rpx,效果会更好
-.top-section {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  min-height: 200rpx;
-  padding: 40rpx 0;
-  line-height: 2;
-  color: #fff;
-  background-image: url('https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/top-bg.png');
-  background-size: cover;
-}
-
-.fly-navbar {
-  position: fixed;
-  top: 0;
-  left: 0;
-  z-index: 9;
-  width: 750rpx;
-  color: #000;
-  background-color: transparent;
-
-  .left-icon {
-    position: absolute;
-    left: 0;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    width: 44px;
-    height: 44px;
-    font-size: 44rpx;
-    color: #000;
-  }
-
-  .title {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    height: 44px;
-    font-size: 32rpx;
-    color: transparent;
-  }
-}
-</style>

+ 0 - 16
src/pages/demo/base/uni-ui-icons.vue

@@ -1,16 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: 'UniUI Icons 使用' },
-}
-</route>
-
-<template>
-  <view class="m-4">
-    <uni-icons type="contact" size="30"></uni-icons>
-    <uni-icons type="contact" size="30" color="red"></uni-icons>
-    <view class="text-blue-300"
-      >注意在微信小程序中,不支持改颜色,即设置了颜色也会变成默认的#333, BUG</view
-    >
-  </view>
-</template>

+ 0 - 14
src/pages/demo/base/uni-ui.vue

@@ -1,14 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: 'UniUI 使用' },
-}
-</route>
-
-<template>
-  <uni-card>
-    <text>这是一个基础卡片示例,内容较少,此示例展示了一个没有任何属性不带阴影的卡片。</text>
-  </uni-card>
-  <view>微信里面下面的 uni-badge 显示不出来,BUG</view>
-  <uni-badge text="99"></uni-badge>
-</template>

+ 0 - 20
src/pages/demo/base/unocss-icons.vue

@@ -1,20 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: 'UnoCss Icons 使用' },
-}
-</route>
-
-<template>
-  <view class="m-4">
-    <view class="mb-2">
-      这里只装了carbon的图表库,网址:
-      <a href="https://icones.js.org/collection/carbon" target="_blank"
-        >https://icones.js.org/collection/carbon </a
-      >(非H5环境,请使用浏览器打开)
-    </view>
-    <view class="i-carbon-car" />
-    <view class="i-carbon-car text-red" />
-    <button class="i-carbon-sun dark:i-carbon-moon" />
-  </view>
-</template>

+ 0 - 15
src/pages/demo/base/unocss.vue

@@ -1,15 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: 'UnoCss 使用' },
-}
-</route>
-
-<template>
-  <view class="flex flex-col justify-center items-center text-5 h-8 leading-8 mt-20">
-    <view class="text-green-500">文字颜色 text-light-50</view>
-    <view class="text-red-500">文字颜色 text-red-500</view>
-    <view class="bg-green-500">背景色 bg-light-50</view>
-    <view class="bg-red-500">背景色 bg-red-500</view>
-  </view>
-</template>

+ 0 - 49
src/pages/demo/base/uv-ui.vue

@@ -1,49 +0,0 @@
-<route lang="json5" type="page">
-{
-  style: { navigationBarTitleText: 'uv ui' },
-}
-</route>
-
-<template>
-  <view class="mt-10">
-    <uv-button type="primary" @click="remakeQc">重新生成二维码</uv-button>
-    <view class="center mt-8">
-      <uv-qrcode
-        ref="qrcode"
-        size="200px"
-        value="https://h5.uvui.cn"
-        :options="options"
-      ></uv-qrcode>
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup>
-console.log(uni.$uv.os())
-console.log(uni.$uv.sys())
-console.log(uni.$uv.trim(' abc ')) // 去除两端空格
-console.log(uni.$uv.random(1, 3)) // 获取随机数
-const qrcode = ref(null)
-const options = reactive({
-  size: 300,
-  useDynamicSize: false,
-  margin: 10,
-  backgroundColor: '#fff',
-  // 指定二维码前景,一般可在中间放logo
-  foregroundImageSrc: '/static/logo.svg',
-})
-const remakeQc = () => {
-  qrcode.value.remake({
-    success: () => {
-      console.log('生成成功')
-    },
-    fail: (err) => {
-      console.log(err)
-    },
-  })
-}
-</script>
-
-<style lang="scss" scoped>
-//
-</style>

+ 0 - 22
src/pages/demo/base/vconsole.vue

@@ -1,22 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '开启 vConsole' },
-}
-</route>
-
-<template>
-  <view class="text-5 h-8 leading-8">
-    <view class="text-red-500">在非正式版小程序里面已经集成了VConsole</view>
-    <view class="text-blue-500 mb-2">开启方式如下面</view>
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/vconsole/1.png"
-      mode="widthFix"
-    />
-    <view class="text-blue-500 m-2">然后页面上会出现一个 `vConsole` 的调试按钮,如下图</view>
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/vconsole/2.png"
-      mode="widthFix"
-    />
-  </view>
-</template>

+ 0 - 81
src/pages/demo/index.vue

@@ -1,81 +0,0 @@
-<template>
-  <view class="bg-slate-100 p-4">
-    <view class="bg-slate-100 w-full" v-for="item in listData" :key="item.id">
-      <view class="font-800">{{ item.title }}</view>
-      <view v-for="itemDetail in item.list" :key="itemDetail.path" class="mt-3">
-        <view
-          class="flex bg-white items-center justify-between p-3 mb-2"
-          @click="goDetailPage(itemDetail.path)"
-        >
-          <text class="flex-1 text-4 text-dark">{{ itemDetail.title }}</text>
-          <text class="i-carbon-chevron-right"></text>
-        </view>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script setup lang="ts" name="TestIndex">
-import pagesJson from '@/pages.json'
-
-/** 基本功能 */
-const baseDemos = pagesJson.pages
-  .filter((e) => e.path.startsWith('pages/demo/base'))
-  .map((e) => ({
-    title: e.style?.navigationBarTitleText || '默认页面标题',
-    path: e.path,
-  }))
-
-/** 页面功能 */
-const pageDemos = pagesJson.pages
-  .filter((e) => e.path.startsWith('pages/demo/page'))
-  .map((e) => ({
-    title: e.style?.navigationBarTitleText || '默认页面标题',
-    path: e.path,
-  }))
-
-const listData = reactive([
-  {
-    id: 1,
-    title: '基础功能',
-    list: baseDemos,
-  },
-  {
-    id: 2,
-    title: '页面功能',
-    list: pageDemos,
-  },
-])
-
-const goDetailPage = (path: string) => {
-  const url = `/${path}`
-  uni.navigateTo({
-    url,
-  })
-}
-</script>
-
-<style>
-.content {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-}
-
-.logo {
-  width: 200rpx;
-  height: 200rpx;
-  margin: 200rpx auto 50rpx;
-}
-
-.text-area {
-  display: flex;
-  justify-content: center;
-}
-
-.title {
-  font-size: 36rpx;
-  color: #8f8f94;
-}
-</style>

+ 0 - 130
src/pages/demo/page/clock.vue

@@ -1,130 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '动态时钟' },
-}
-</route>
-
-<template>
-  <view class="mt-4 h-10 text-center">动态时钟</view>
-  <view class="clock-box">
-    <view class="clock" :style="{ '--ds': ds, '--dm': dm, '--dh': dh }">
-      <view class="clock-pane">
-        <text class="clock-num" :style="{ '--i': n }" v-for="n in 12" :key="n">{{ n }}</text>
-      </view>
-      <view class="clock-hour"></view>
-      <view class="clock-min"></view>
-      <view class="clock-sec"></view>
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup>
-const d = new Date()
-const h = d.getHours()
-const m = d.getMinutes()
-const s = d.getSeconds()
-const ds = ref(s)
-const dm = ref(m + s / 60)
-const dh = ref(h + m / 60 + s / 3600)
-</script>
-
-<style lang="scss">
-.clock-box {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.clock {
-  position: relative;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 350px;
-  height: 350px;
-  font-size: 24px;
-  border-radius: 20px;
-  box-shadow: 2px 2px 20px #0000001a;
-  --step: 60s;
-}
-
-.clock::before {
-  position: absolute;
-  width: 300px;
-  height: 300px;
-  content: '';
-  background: repeating-conic-gradient(from -0.5deg, #333 0 1deg, transparent 0deg 30deg),
-    repeating-conic-gradient(from -0.5deg, #ccc 0 1deg, transparent 0deg 6deg);
-  border-radius: 50%;
-  mask: radial-gradient(transparent 145px, red 0);
-}
-
-.clock-pane {
-  position: absolute;
-  width: 250px;
-  height: 250px;
-  transform: translateX(-125px);
-}
-
-.clock-num {
-  position: absolute;
-  offset-path: path(
-    'M250 125c0 69.036-55.964 125-125 125S0 194.036 0 125 55.964 0 125 0s125 55.964 125 125z'
-  );
-  offset-distance: calc(var(--i) * 10% / 1.2 - 25%);
-  offset-rotate: 0deg;
-}
-
-.clock-hour {
-  position: absolute;
-  width: 4px;
-  height: 60px;
-  background: #333;
-  transform: translateY(-50%) rotate(0);
-  transform-origin: center bottom;
-  animation: clock calc(var(--step) * 60 * 12) infinite linear;
-  animation-delay: calc(-1 * var(--step) * var(--dh) * 60);
-}
-
-.clock-min {
-  position: absolute;
-  width: 4px;
-  height: 90px;
-  background: #333;
-  transform: translateY(-50%) rotate(0);
-  transform-origin: center bottom;
-  animation: clock calc(var(--step) * 60) infinite linear;
-  animation-delay: calc(-1 * var(--step) * var(--dm));
-}
-
-.clock-sec {
-  position: absolute;
-  width: 2px;
-  height: 120px;
-  background: red;
-  transform: translateY(-50%) rotate(0);
-  transform-origin: center bottom;
-  animation: clock var(--step) infinite steps(60);
-  animation-delay: calc(-1 * var(--step) * var(--ds) / 60);
-}
-
-.clock-sec::after {
-  position: absolute;
-  bottom: 0;
-  left: 50%;
-  width: 10px;
-  height: 10px;
-  content: '';
-  background: #fff;
-  border: 4px solid #333;
-  border-radius: 50%;
-  transform: translate(-50%, 50%);
-}
-
-@keyframes clock {
-  to {
-    transform: translateY(-50%) rotate(360deg);
-  }
-}
-</style>

+ 0 - 152
src/pages/demo/page/clock2.vue

@@ -1,152 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '动态时钟-抗锯齿' },
-}
-</route>
-
-<template>
-  <view class="mt-4 h-10 text-center">动态时钟</view>
-  <view class="clock-box">
-    <view class="clock" :style="{ '--ds': ds, '--dm': dm, '--dh': dh }">
-      <view class="clock-pane">
-        <text class="clock-num" :style="{ '--i': n }" v-for="n in 12" :key="n">{{ n }}</text>
-      </view>
-      <view class="clock-scales">
-        <text class="clock-scale" :style="{ '--i': n }" v-for="n in 60" :key="n"></text>
-      </view>
-
-      <view class="clock-hour"></view>
-      <view class="clock-min"></view>
-      <view class="clock-sec"></view>
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup>
-const d = new Date()
-const h = d.getHours()
-const m = d.getMinutes()
-const s = d.getSeconds()
-const ds = ref(s)
-const dm = ref(m + s / 60)
-const dh = ref(h + m / 60 + s / 3600)
-</script>
-
-<style lang="scss">
-.clock-box {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.clock {
-  position: relative;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 350px;
-  height: 350px;
-  font-size: 24px;
-  border-radius: 20px;
-  box-shadow: 2px 2px 20px #0000001a;
-  --step: 60s;
-}
-
-.clock-pane {
-  position: absolute;
-  width: 250px;
-  height: 250px;
-  transform: translateX(-125px);
-}
-
-.clock-scales {
-  position: absolute;
-  width: 250px;
-  height: 250px;
-  transform: translate(125px, -25px);
-}
-
-.clock-scale {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 2px;
-  height: 4px;
-  background: #ccc;
-  transform-origin: 0 150px;
-
-  &:nth-child(5n + 1) {
-    width: 4px;
-    height: 6px;
-    background: #333;
-  }
-}
-
-@for $i from 1 through 60 {
-  .clock-scale:nth-child(#{$i}) {
-    transform: rotate(#{($i - 1) * 6deg});
-  }
-}
-
-.clock-num {
-  position: absolute;
-  offset-path: path(
-    'M250 125c0 69.036-55.964 125-125 125S0 194.036 0 125 55.964 0 125 0s125 55.964 125 125z'
-  );
-  offset-distance: calc(var(--i) * 10% / 1.2 - 25%);
-  offset-rotate: 0deg;
-}
-
-.clock-hour {
-  position: absolute;
-  width: 4px;
-  height: 60px;
-  background: #333;
-  transform: translateY(-50%) rotate(0);
-  transform-origin: center bottom;
-  animation: clock calc(var(--step) * 60 * 12) infinite linear;
-  animation-delay: calc(-1 * var(--step) * var(--dh) * 60);
-}
-
-.clock-min {
-  position: absolute;
-  width: 4px;
-  height: 90px;
-  background: #333;
-  transform: translateY(-50%) rotate(0);
-  transform-origin: center bottom;
-  animation: clock calc(var(--step) * 60) infinite linear;
-  animation-delay: calc(-1 * var(--step) * var(--dm));
-}
-
-.clock-sec {
-  position: absolute;
-  width: 2px;
-  height: 120px;
-  background: red;
-  transform: translateY(-50%) rotate(0);
-  transform-origin: center bottom;
-  animation: clock var(--step) infinite steps(60);
-  animation-delay: calc(-1 * var(--step) * var(--ds) / 60);
-}
-
-.clock-sec::after {
-  position: absolute;
-  bottom: 0;
-  left: 50%;
-  width: 10px;
-  height: 10px;
-  content: '';
-  background: #fff;
-  border: 4px solid #333;
-  border-radius: 50%;
-  transform: translate(-50%, 50%);
-}
-
-@keyframes clock {
-  to {
-    transform: translateY(-50%) rotate(360deg);
-  }
-}
-</style>

+ 0 - 88
src/pages/demo/page/floating-bubble.vue

@@ -1,88 +0,0 @@
-<route lang="json5">
-{
-  layout: 'default',
-  style: { navigationBarTitleText: '页面悬浮球' },
-}
-</route>
-
-<template>
-  <view>
-    <movable-area class="movable-area">
-      <movable-view
-        :style="`--size:${ballSize}px`"
-        class="movable-view"
-        direction="all"
-        :x="x"
-        :y="y"
-        @change="onChange"
-        @touchend.prevent="onTouchEnd"
-      >
-        <view class="w-full h-full rounded-full bg-green-400"></view>
-      </movable-view>
-    </movable-area>
-    <view>页面其他元素</view>
-    <view>可以正常触发点击事件吗?答案是可以的</view>
-    <button @click="onClick">按钮</button>
-    <view>{{ x }}</view>
-    <view>{{ y }}</view>
-    <view @click="onSet">点击设置</view>
-  </view>
-</template>
-
-<script lang="ts" setup name="FloatingBubble">
-const { windowHeight, windowWidth } = uni.getSystemInfoSync()
-
-const ballSize = 60
-const x = ref(windowWidth - ballSize) // 靠右侧
-const y = ref(windowHeight - ballSize - 20) // 距离底部20px
-
-const middleX = (windowWidth - ballSize) / 2
-
-const onChange: UniHelper.MovableViewOnChange = (e) => {
-  const { x: _x, y: _y } = e.detail
-  x.value = _x
-  y.value = _y
-}
-// TODO: 期望最终落点不靠左右两边时,会自动回到两边,有一定的动画效果
-const onTouchEnd = (e) => {
-  console.log('onTouchEnd', e)
-  // TODO:为啥这里设置的不生效了,原生不会移动到设置的地方,onSet里面可以。这里直接执行onSet也不行
-  // 这里被我解决了
-  const tid = setTimeout(() => {
-    if (x.value < middleX) {
-      x.value = 0
-    } else {
-      x.value = windowWidth - ballSize
-    }
-    clearTimeout(tid)
-  }, 0)
-}
-
-const onClick = () => {
-  uni.showToast({
-    title: 'yes',
-    icon: 'none',
-  })
-}
-const onSet = () => {
-  x.value = 100
-  y.value = 100
-}
-</script>
-
-<style lang="scss">
-.movable-area {
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: 100;
-  width: 100%;
-  height: 100%;
-  pointer-events: none; // 设置area元素不可点击,则事件便会下移至页面下层元素
-  .movable-view {
-    width: var(--size);
-    height: var(--size);
-    pointer-events: auto; // 必须设置,否则无法点击
-  }
-}
-</style>

+ 0 - 84
src/pages/demo/page/i18n.vue

@@ -1,84 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: {
-    navigationBarTitleText: '%app.name%',
-  },
-}
-</route>
-
-<template>
-  <view class="center flex-col mt-6">
-    <view class="text-green-500">多语言测试</view>
-    <view class="m-4">{{ $t('app.name') }}</view>
-    <view class="m-4">{{ $t('weight', { heavy: 100 }) }}</view>
-
-    <view class="text-green-500 mt-12">切换语言 </view>
-    <view class="uni-list">
-      <radio-group @change="radioChange" class="radio-group">
-        <label class="uni-list-cell uni-list-cell-pd" v-for="item in languages" :key="item.value">
-          <view>
-            <radio :value="item.value" :checked="item.value === current" />
-          </view>
-          <view>{{ item.name }}</view>
-        </label>
-      </radio-group>
-    </view>
-
-    <!-- http://localhost:9100/#/pages/index/i18n -->
-    <button @click="testI18n" class="mt-20 mb-44">测试弹窗</button>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import i18n from '@/locale/index'
-import { testI18n } from '@/utils/index'
-
-const current = ref(uni.getLocale())
-const languages = [
-  {
-    value: 'zh-Hans',
-    name: '中文',
-    checked: 'true',
-  },
-  {
-    value: 'en',
-    name: '英文',
-  },
-]
-
-const radioChange = (evt) => {
-  // console.log(evt)
-  current.value = evt.detail.value
-  // 下面2句缺一不可!!!
-  uni.setLocale(evt.detail.value)
-  i18n.global.locale = evt.detail.value
-}
-</script>
-
-<style lang="scss">
-.uni-list {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  width: 100%;
-  background-color: #fff;
-  border-radius: 12px;
-}
-
-.radio-group {
-  width: 200px;
-  margin: 10px auto;
-  border-radius: 12px;
-}
-
-.uni-list-cell {
-  position: relative;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  justify-content: space-between;
-  padding: 10px;
-  background-color: #bcecd1;
-}
-</style>

+ 0 - 38
src/pages/demo/page/img-min/index.vue

@@ -1,38 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '图片压缩' },
-}
-</route>
-
-<script setup lang="ts">
-import testBgImg from './test-bg.png'
-</script>
-
-<template>
-  <view class="m-4 text-center">
-    <view class="mb-2 text-orange-500">
-      原始图片是一个很大的,2.5M,build之后生成的图片只有1.1M,体积下降 56%
-    </view>
-    <!-- #ifdef MP -->
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/img-min/bg-1.png"
-      mode="scaleToFill"
-    />
-    <!-- #endif -->
-    <!-- #ifndef MP -->
-    <image :src="testBgImg" mode="scaleToFill" />
-    <!-- #endif -->
-    <view class="mb-4">对比图如下2图,如果看不清请看代码原图</view>
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/img-min/before.png"
-      mode="widthFix"
-      class="w-full"
-    />
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/img-min/after.png"
-      mode="widthFix"
-      class="w-full"
-    />
-  </view>
-</template>

BIN
src/pages/demo/page/img-min/test-bg.png


+ 0 - 127
src/pages/demo/page/lottery.vue

@@ -1,127 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '九宫格抽奖' },
-}
-</route>
-
-<template>
-  <view class="mt-4 h-10 text-center">九宫格抽奖</view>
-  <view class="lottery-box">
-    <view class="lottery-list">
-      <view
-        class="lottery-item"
-        :class="{
-          active: n === activeIndex,
-          btn: n === btnIndex, // 最中间那个是展示按钮
-        }"
-        v-for="n in numList"
-        :key="n"
-        @click="handleClick(n)"
-      >
-        <view v-if="n === btnIndex">点击抽奖</view>
-        <view v-else> {{ n }}</view>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { reactive, computed } from 'vue'
-
-const giftLen = 8 // 九宫格有8个礼物
-const loop = 4 // 设置转多少圈,在最后一圈会慢下来
-const totalStep = giftLen * loop // 总的步数 32
-const lastLoopStep = totalStep - giftLen // 最后一圈,24
-const numList = [1, 2, 3, 8, -1, 4, 7, 6, 5]
-const btnIndex = numList[4] // 最中间那个是展示按钮
-
-const state = reactive({
-  lottery: 0, // 奖品
-  step: -1, // 目前转动的步数
-  stopStep: totalStep, // 停下来的时需要走的步数
-  speed: 2, // 转动速度,我们是通过定时器去实现转动效果的,所以这也就是定时器的执行频率
-  timer: null, // 定时器ID
-  loading: false,
-})
-// 通过目前转动的步数来对8取模得到当前转到的格子索引
-const activeIndex = computed(() => {
-  return (state.step % 8) + 1
-})
-
-function run() {
-  // 当前步数大于等于目标步数
-  if (state.step >= state.stopStep) {
-    // 清空定时器,停止转动
-    clearTimeout(state.timer)
-    // 将初始化步数为最终奖品的步数,转动速度也置为初始速度,下次才能正确转动
-    state.step = state.lottery
-    state.speed = 2
-    state.loading = false
-    console.log(`恭喜获得${activeIndex.value}号奖品`)
-    uni.showModal({
-      title: `恭喜获得${activeIndex.value}号奖品`,
-    })
-    return
-  }
-  // 转动到最后一圈时,增加speed,也就是定时器执行间隔时间变长,转动速度变慢
-  if (state.step > lastLoopStep + state.lottery) {
-    state.speed++
-  }
-  // 抽奖函数每执行一次,当前步数加一
-  state.step++
-  // 重新开启定时器执行抽奖函数
-  state.timer = setTimeout(run, state.speed * 30)
-}
-// 点击抽奖之后调用的函数
-function handleClick(n) {
-  if (n !== btnIndex) {
-    return
-  }
-  if (state.loading) return
-  state.loading = true
-  // 最终获得的奖品,实际业务中是通过接口获取的,这里使用随机数来模拟下
-  state.lottery = Math.ceil(Math.random() * giftLen)
-  console.log(state.lottery)
-  // 计算总共要转动的步数,转4圈后再转到奖品处
-  state.stopStep = state.lottery + totalStep
-  // 执行抽奖函数
-  run()
-}
-</script>
-
-<style lang="css">
-.lottery-box {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.lottery-list {
-  --size: 100px;
-
-  display: flex;
-  flex-wrap: wrap;
-  width: calc(3 * var(--size) + 3px);
-  border-right: 1px solid #ccc;
-  border-bottom: 1px solid #ccc;
-}
-
-.lottery-item {
-  width: var(--size);
-  height: var(--size);
-  line-height: var(--size);
-  text-align: center;
-  border-top: 1px solid #ccc;
-  border-left: 1px solid #ccc;
-}
-
-.lottery-item.active {
-  color: #fff;
-  background-color: red;
-}
-
-.lottery-item.btn {
-  cursor: pointer;
-}
-</style>

+ 0 - 216
src/pages/demo/page/lottery/big-wheel.vue

@@ -1,216 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '大转盘抽奖' },
-}
-</route>
-
-<template>
-  <view class="text-center">
-    <view class="container">
-      <view class="prize-list" :style="styleObj">
-        <view
-          class="prize-item"
-          v-for="(item, index) in prizeList"
-          :key="item.id"
-          :style="prizeStyle(index)"
-        >
-          <image :src="item.pic" class="gift-img" />
-          <text class="gift-name">{{ item.name }}</text>
-        </view>
-      </view>
-      <view class="lottery-btn" @click="start"> </view>
-    </view>
-    <view class="text-blue-600 my-2">目标是实现如下的效果,但是我感觉只用css还是太难了</view>
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery/target.png"
-      mode="widthFix"
-      width="552px"
-    />
-    <!-- <image :src="targetImg" mode="widthFix" width="552px" /> -->
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { ref, computed } from 'vue'
-// TODO: fix 微信小程序里面会报错
-// import targetImg from 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery/target.png'
-
-// 后台配置的奖品数据
-const prizeList = [
-  {
-    id: 0,
-    name: '双肩包',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/backpack.jpg',
-  },
-  {
-    id: 1,
-    name: '积木',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/jimu.jpg',
-  },
-  {
-    id: 2,
-    name: '红包',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/red-envelope.jpg',
-  },
-  {
-    id: 3,
-    name: '茶具',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tea-set.jpg',
-  },
-  {
-    id: 4,
-    name: '可爱脸',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tushetou.jpg',
-  },
-  {
-    id: 5,
-    name: '挖掘机',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/wajueji.jpg',
-  },
-  {
-    id: 6,
-    name: '无辜脸',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/xiaolian.jpg',
-  },
-  {
-    id: 7,
-    name: '烟灰缸',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/yanhuigang.jpg',
-  },
-]
-let isRunning = false // 是否正在抽奖
-const baseRunAngle = 360 * 5 // 总共转动角度 至少5圈
-let prizeId = 0 // 中奖id
-
-// 平均每个奖品角度
-const rotateAngle = computed(() => {
-  const _degree = 360 / prizeList.length
-  return _degree
-})
-// 要执行总角度数
-const totalRunAngle = ref(baseRunAngle - (prizeId + 0.5) * rotateAngle.value)
-
-// 计算绘制转盘背景
-const bgColor = (() => {
-  const [c1, c2] = ['#5352b3', '#363589']
-  // repeating-conic-gradient(red 0 15deg, blue  15deg 30deg);
-  return `background: repeating-conic-gradient(${c1} 0 ${rotateAngle.value}deg,
-  ${c2} ${rotateAngle.value}deg ${2 * rotateAngle.value}deg);`
-})()
-
-const styleObj = ref(bgColor)
-// 每个奖品布局
-const prizeStyle = computed(() => {
-  const _degree = rotateAngle.value
-  return (i) => {
-    // 外框大小设置为90vw,里面是一半,45vw
-    return `
-              width: ${2 * 45 * Math.sin(((_degree / 2) * Math.PI) / 180)}vw;
-              height: 45vw;
-              transform: rotate(${_degree * i + _degree / 2}deg);
-              transform-origin: 50% 100%;
-            `
-  }
-})
-
-// 获取随机数
-const getRandomNum = () => {
-  const num = Math.floor(Math.random() * prizeList.length)
-  return num
-}
-
-const stopRun = () => {
-  isRunning = false
-  const prizeName = prizeList.find((e) => e.id === prizeId)!.name
-  uni.showModal({
-    title: `恭喜你中奖 ${prizeName}`,
-    success() {
-      styleObj.value = `${bgColor} transform: rotate(0deg);`
-    },
-  })
-}
-
-const startRun = () => {
-  console.log(isRunning, totalRunAngle.value)
-  // 设置动效
-  styleObj.value = `${bgColor} transform: rotate(${totalRunAngle.value}deg); transition: all 4s ease;`
-  setTimeout(stopRun, 4000)
-}
-const start = () => {
-  if (!isRunning) {
-    isRunning = true
-
-    console.log('开始抽奖,后台请求中奖奖品')
-    // 请求返回的奖品编号 这里使用随机数
-    prizeId = getRandomNum()
-    totalRunAngle.value = baseRunAngle - (prizeId + 0.5) * rotateAngle.value
-    console.log('中奖ID>>>', prizeId, prizeList[prizeId], totalRunAngle.value)
-    nextTick(() => {
-      startRun()
-    })
-  }
-}
-</script>
-
-<style lang="scss">
-.container {
-  position: relative;
-  width: 90vw;
-  height: 90vw;
-  margin: 20px auto;
-  border: 10px solid #98d3fc;
-  border-radius: 50%;
-}
-
-.prize-list {
-  box-sizing: border-box;
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-  border-radius: 50%;
-
-  // 使用outline代替border可以省很多定位的问题
-  // outline: 10px solid #98d3fc;
-}
-
-.prize-item {
-  position: absolute;
-  top: 0;
-  right: 0;
-  left: 0;
-  display: flex;
-  flex-direction: column;
-  margin: auto;
-
-  // border: 2px solid red;
-}
-
-.prize-item .gift-img {
-  display: block;
-  width: 30%;
-  height: 20%;
-  margin: 20px auto 10px;
-  border-radius: 50%;
-}
-
-.prize-item .gift-name {
-  font-size: 12px;
-  line-height: 20px;
-  color: #fff;
-  text-align: center;
-}
-
-.lottery-btn {
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  width: 80px;
-  height: 96px;
-  margin: auto;
-  cursor: pointer;
-  background: url('https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/btn-enable.png')
-    no-repeat center / 100% 100%;
-  transform: translate(-50%, -50%);
-}
-</style>

+ 0 - 196
src/pages/demo/page/lottery/nine-grid.vue

@@ -1,196 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '九宫格抽奖' },
-}
-</route>
-<template>
-  <view>
-    <view class="container">
-      <view
-        class="gift-item"
-        :class="{ active: currentIndex === index }"
-        v-for="(item, index) in prizeList"
-        :key="index"
-        @click="start(index)"
-      >
-        <image :src="item.pic" class="gift-img" />
-        <text v-if="index !== 4" class="gift-name">{{ item.name }}</text>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { ref, computed } from 'vue'
-
-const currentIndex = ref(0) // 当前位置
-// 后台配置的奖品数据
-const prizeList = [
-  {
-    id: 0,
-    name: '双肩包',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/backpack.jpg',
-  },
-  {
-    id: 1,
-    name: '积木',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/jimu.jpg',
-  },
-  {
-    id: 2,
-    name: '红包',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/red-envelope.jpg',
-  },
-  {
-    id: 3,
-    name: '茶具',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tea-set.jpg',
-  },
-  {
-    id: 5,
-    name: '可爱脸',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/tushetou.jpg',
-  },
-  {
-    id: 6,
-    name: '挖掘机',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/wajueji.jpg',
-  },
-  {
-    id: 7,
-    name: '无辜脸',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/xiaolian.jpg',
-  },
-  {
-    id: 8,
-    name: '烟灰缸',
-    pic: 'https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery-prize/yanhuigang.jpg',
-  },
-]
-const startBtn = {
-  id: 4,
-  name: '开始按钮',
-  pic: 'https://img2.baidu.com/it/u=1497996119,382735686&fm=253',
-}
-// 九宫格中间位置插入开始按钮
-prizeList.splice(4, 0, startBtn)
-
-// 奖品高亮顺序
-const prizeSort = [0, 1, 2, 5, 8, 7, 6, 3]
-
-// 获取随机数
-const getRandomNum = () => prizeSort[Math.floor(Math.random() * prizeSort.length)]
-
-let isRunning = false // 是否正在抽奖
-let speed = 10 // 抽奖转动速度
-let timerIns = null // 定时器实例
-let currentRunCount = 0 // 已跑次数
-const totalRunCount = 32 // 总共跑动次数,8的倍数即可
-let prizeId = 0 // 中奖id(0-8,不能是4)
-
-// 要执行总步数
-const totalRunStep = computed(() => {
-  return totalRunCount + prizeSort.indexOf(prizeId)
-})
-
-const stopRun = () => {
-  // eslint-disable-next-line no-unused-expressions
-  timerIns && clearTimeout(timerIns)
-}
-const startRun = () => {
-  stopRun()
-  console.log(currentRunCount, totalRunStep.value)
-  // 要执行总步数
-  // 已走步数超过
-  if (currentRunCount > totalRunStep.value) {
-    isRunning = false
-    const prizeName = prizeList.find((e) => e.id === prizeId)!.name
-    uni.showModal({
-      title: `恭喜你中奖 ${prizeName}`,
-    })
-    return
-  }
-  currentIndex.value = prizeSort[currentRunCount % 8]
-  // 如果当前步数超过了2/3则速度慢下来
-  if (currentRunCount > Math.floor((totalRunCount * 2) / 3)) {
-    speed += Math.floor(currentRunCount / 3)
-    console.log('速度>>>>', speed)
-  }
-
-  timerIns = setTimeout(() => {
-    currentRunCount++
-    startRun()
-  }, speed)
-}
-
-const start = (i) => {
-  if (i === 4 && !isRunning) {
-    // 重置数据
-    currentRunCount = 0
-    speed = 100
-    isRunning = true
-
-    console.log('开始抽奖,后台请求中奖奖品')
-    // 请求返回的奖品编号 这里使用随机数 但不能为4
-    // const prizeId = getRandomNum()
-    // console.log('中奖ID>>>', prizeId, prizeList[prizeId])
-    // prizeId = prizeId
-    // 模拟接口延时返回 如果接口突然报错如何处理?直接调用stopRun()方法停止转动
-    setTimeout(() => {
-      prizeId = getRandomNum()
-      console.log('中奖ID>>>', prizeId, prizeList[prizeId])
-      // 拿到数据才可以跑
-    }, 2000)
-    startRun()
-  }
-}
-</script>
-<style lang="scss">
-.container {
-  display: flex;
-  flex-wrap: wrap;
-  align-items: center;
-  justify-content: space-around;
-  width: 90vw;
-  height: 90vw;
-  margin: 20px auto;
-  background: #98d3fc;
-  border: 1px solid #98d3fc;
-}
-
-.gift-item {
-  position: relative;
-  box-sizing: border-box;
-  width: 30vw;
-  height: 30vw;
-  border: 2px solid #fff;
-}
-
-.gift-item:nth-of-type(5) {
-  cursor: pointer;
-}
-
-.gift-item .gift-img {
-  width: 100%;
-  height: 100%;
-}
-
-.gift-item .gift-name {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  width: 100%;
-  height: 20px;
-  font-size: 12px;
-  line-height: 20px;
-  color: #fff;
-  text-align: center;
-  background: rgb(0 0 0 / 50%);
-}
-
-.active {
-  border: 2px solid red;
-  box-shadow: 2px 2px 30px #fff;
-}
-</style>

+ 0 - 181
src/pages/demo/page/lottery2.vue

@@ -1,181 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: { navigationBarTitleText: '大转盘抽奖' },
-}
-</route>
-
-<template>
-  <view class="mt-4 h-10 text-center">大转盘抽奖</view>
-  <div class="lottery-box">
-    <div class="lottery-list">
-      <div class="lottery-item" v-for="(n, index) in giftLen" :key="n">
-        <div class="lottery-item-inner">
-          <div class="lottery-item-gift">奖品{{ index + 1 }}</div>
-        </div>
-      </div>
-      <div
-        class="pointer"
-        @click="handleClick"
-        :style="{ transform: `rotate(${state.stopDeg}deg)` }"
-      >
-        <div>开始</div>
-        <div>抽奖</div>
-      </div>
-    </div>
-  </div>
-  <view class="leading-8">
-    <view class="mt-8 text-center text-green-600">下面是调试过程图片</view>
-    <view class="mb-8 text-center text-green-600">欢迎感兴趣的玩家继续优化</view>
-    <view class="text-center text-blue-600">计算lottery-item-inner节点的padding-left值</view>
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery/lottery2-1.png"
-      mode="widthFix"
-      class="w-full"
-    />
-    <view class="text-center text-blue-600">调整lottery-item-gift节点</view>
-    <image
-      src="https://cip-shopping-page-0eysug01066a9e-1302818703.tcloudbaseapp.com/fly/lottery/lottery2-2.png"
-      mode="widthFix"
-      class="w-full"
-    />
-  </view>
-</template>
-
-<script lang="ts" setup>
-const giftLen = 8
-const deg = 360 / giftLen // 每份的角度
-const loop = 4 // 转多少圈,4圈
-const state = reactive({
-  lottery: 0, // 本次抽奖的奖品索引
-  lastLottery: 0, // 上一次抽奖的奖品索引
-  stopDeg: 0, // 最终要旋转的角度
-  loading: false,
-})
-
-function handleClick() {
-  if (state.loading) return
-  state.loading = true
-  // 最终获得的奖品索引,实际业务中是通过接口获取的,这里使用随机数0~9来模拟下
-  state.lottery = Math.floor(Math.random() * giftLen)
-  console.log(state.lottery)
-  // 最终的旋转角度,指针指向本次奖品的旋转角度+指针从上一次的奖品指向回归0的旋转角度+ 默认转动三圈
-  state.stopDeg += (state.lottery + (giftLen - state.lastLottery)) * deg + loop * 360
-
-  // uni不支持addEventListener所以改用下面的
-  setTimeout(() => {
-    state.lastLottery = state.lottery
-    state.loading = false
-    // alert(`恭喜获得奖品${state.lottery + 1}`)
-    uni.showModal({
-      title: `恭喜获得奖品${state.lottery + 1}`,
-    })
-  }, 3000)
-}
-</script>
-
-<style lang="scss">
-.lottery-box {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.lottery-list {
-  --size: 600rpx;
-  --half: calc(var(--size) / 2);
-  --len: 8; // 与代码 giftLen 长度一致
-  --deg: calc(360 / var(--len) * 1deg);
-  --deg-num: calc(360 / var(--len));
-
-  position: relative;
-  width: var(--size);
-  height: var(--size);
-  border: 2px solid #f55;
-  border-radius: 50%;
-}
-
-.lottery-item {
-  position: absolute;
-  top: 0;
-  left: var(--half);
-  width: var(--half);
-  height: var(--size);
-  overflow: hidden; // 把这个注释掉可以看到最初的模样
-  // background-color: #ff5350a1; // 放开这个可以看到最初的模样
-  transform-origin: left center;
-}
-
-.lottery-item-inner {
-  position: absolute;
-  top: 0;
-  left: calc(-1 * var(--half));
-  box-sizing: border-box;
-  width: var(--half);
-  height: var(--size);
-  padding-left: calc(((1 - sin(var(--deg-num))) * var(--size)));
-  font-size: 12px;
-  border-radius: var(--half) 0 0 var(--half);
-  transform: rotate(var(--deg));
-  transform-origin: right center;
-}
-
-.lottery-item-inner .lottery-item-gift {
-  display: block;
-  text-align: center;
-  transform: rotate(calc(-0.5 * var(--deg))) translateY(16px)
-    translateX(calc(0.5 * var(--half) * (1 - 1 / cos(0.5 * var(--deg)))));
-  transform-origin: center;
-}
-
-.lottery-item:nth-child(2n + 1) .lottery-item-inner {
-  background: #fef6e0a1;
-}
-
-.lottery-item:nth-child(2n) .lottery-item-inner {
-  background: #ffffffa1;
-}
-
-// TIPS: 与上面的--len一致
-@for $i from 1 through 8 {
-  .lottery-item:nth-child(#{$i}) {
-    transform: rotate(calc(($i - 1 - 0.5) * var(--deg)));
-  }
-}
-
-.pointer {
-  --pointer-size: 40px;
-  --pointer-padding: calc(var(--pointer-size) / 5);
-
-  position: absolute;
-  top: calc(var(--half) - var(--pointer-size) / 2 - var(--pointer-padding));
-  left: calc(var(--half) - var(--pointer-size) / 2 - var(--pointer-padding));
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  width: var(--pointer-size);
-  height: var(--pointer-size);
-  padding: var(--pointer-padding);
-  font-size: 12px;
-  text-align: center;
-  background-color: #ffffffd1;
-  border: 1px solid #ff5350;
-  border-radius: 50%;
-  transition: transform 3s cubic-bezier(0.2, 0.93, 0.43, 1);
-}
-
-.pointer::after {
-  --caret-size: 8px;
-
-  position: absolute;
-  bottom: calc(var(--pointer-size) + var(--pointer-padding) * 2);
-  left: calc(var(--pointer-size) / 2 - var(-caret-size) / 2);
-  content: '';
-  border-color: transparent;
-  border-style: solid;
-  border-width: calc(var(--caret-size) * 2) var(--caret-size);
-  border-bottom-color: #ff5350;
-  transform-origin: center;
-}
-</style>

+ 0 - 266
src/pages/demo/page/sign.vue

@@ -1,266 +0,0 @@
-<route lang="json5">
-{
-  layout: 'default',
-  style: { navigationBarTitleText: '签字板' },
-}
-</route>
-
-<template>
-  <view class="canvas-box flex flex-col box-border p-3" :class="{ 'full-screen': isFullScreen }">
-    <canvas
-      canvas-id="canvas"
-      class="w-full b b-dashed b-rd b-gray-300 canvas"
-      :disable-scroll="true"
-      @touchstart="touchStart"
-      @touchmove="touchMove"
-      @touchend="touchEnd"
-      @mousedown="touchStart"
-      @mousemove="touchMove"
-      @mouseup="touchEnd"
-    />
-    <view class="btns flex justify-between text-center box-border">
-      <view class="btn-box flex">
-        <view class="btn bg-gray-100 b-rd b-gray-300 c-gray-500 p-1" @click="handFullScreen">
-          {{ isFullScreen ? '退出全屏' : '全屏' }}
-        </view>
-        <view class="btn bg-gray-100 b-rd b-gray-300 c-gray-500 p-1 ml-2" @click="clear">清空</view>
-        <view class="btn bg-gray-100 b-rd b-gray-300 c-gray-500 p-1 ml-2" @click="withdraw">
-          撤回
-        </view>
-      </view>
-      <view class="btn-box flex">
-        <view class="btn bg-sky-500 b-rd c-white p-1" @click="save">保存</view>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script lang="ts" setup name="sign">
-const isFullScreen = ref(false)
-const isSigned = ref(false)
-let ctx = null
-let isButtonDown = false
-let points = []
-let allPoints = []
-
-// 初始化画布
-function initCanvas() {
-  ctx = uni.createCanvasContext('canvas')
-  // 设置画笔样式
-  ctx.lineWidth = 4
-  ctx.lineCap = 'round'
-  ctx.lineJoin = 'round'
-}
-
-// 重设画板大小
-function onResize() {
-  initCanvas() // 重新初始化canvas
-}
-
-// 绘画
-function draw(w?) {
-  const point1 = points[0]
-  const point2 = points[1]
-
-  if (!w) {
-    allPoints[allPoints.length - 1].push(JSON.parse(JSON.stringify(points)))
-  }
-
-  points.shift()
-  ctx.moveTo(point1.X, point1.Y)
-  ctx.lineTo(point2.X, point2.Y)
-  ctx.stroke()
-  ctx.draw(true)
-  isSigned.value = true
-}
-
-// 触摸开始,获取到起点
-function touchStart() {
-  allPoints.push([])
-  ctx.beginPath() // 每次触摸开始,开启新的路径
-  isButtonDown = true
-}
-
-// 触摸移动,获取到路径点
-function touchMove(e) {
-  if (isButtonDown) {
-    let movePoint = {}
-    if (e.changedTouches[0].x) {
-      movePoint = { X: e.changedTouches[0].x, Y: e.changedTouches[0].y }
-    } else {
-      const X = e.changedTouches[0].pageX - e.currentTarget.offsetLeft
-      const Y = e.changedTouches[0].pageY - e.currentTarget.offsetTop
-      movePoint = { X, Y }
-    }
-    points.push(movePoint) // 存点
-    const len = points.length
-    if (len >= 2) {
-      draw() // 绘制路径
-    }
-  }
-}
-
-// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
-function touchEnd() {
-  allPoints = allPoints.filter((e) => {
-    return e.length > 0
-  })
-  points = []
-  isButtonDown = false
-}
-
-// 清空, 传入true表示清空全部,不传传表示撤回一步
-function clear(reset?: boolean) {
-  if (reset) allPoints = []
-  ctx.clearRect(0, 0, 1000, 1000)
-  ctx.draw(true)
-  isSigned.value = false
-}
-
-// 全屏
-function handFullScreen() {
-  clear(true)
-  isFullScreen.value = !isFullScreen.value
-  const tid = setTimeout(() => {
-    onResize()
-    clearTimeout(tid)
-  }, 100)
-}
-
-// 撤回
-function withdraw() {
-  // 清除画布
-  clear()
-  if (allPoints.length <= 1) {
-    allPoints = []
-    points = []
-    return
-  }
-  // 删除最后一个路径
-  allPoints.pop()
-  // 循环路径,重新绘制
-  allPoints.forEach((e) => {
-    e.forEach((r) => {
-      points = JSON.parse(JSON.stringify(r))
-      draw(1)
-    })
-  })
-}
-
-// h5保存方法
-function saveCanvasAsImage(dataURL, imageName?) {
-  // 创建一个Image元素
-  const img = new Image()
-
-  // 设置img的src属性为数据URL
-  img.src = dataURL
-
-  // 创建一个链接元素用于下载图片
-  const link = document.createElement('a')
-
-  // 设置下载的文件名
-  link.download = imageName || 'canvas-image'
-
-  // 触发点击,下载图片
-  link.href = img.src
-  link.click()
-}
-
-// 保存
-const save = () => {
-  if (!isSigned.value) {
-    uni.showToast({
-      title: '请签名',
-      icon: 'none',
-    })
-    return
-  }
-
-  uni.canvasToTempFilePath({
-    canvasId: 'canvas',
-    success: (res) => {
-      // 获取图片路径
-      const { tempFilePath } = res
-      // 保存图片到相册
-      // #ifdef H5
-      const name = `sign-${new Date().getTime()}`
-      saveCanvasAsImage(tempFilePath, name)
-      // #endif
-
-      // #ifndef H5
-      uni.saveImageToPhotosAlbum({
-        filePath: tempFilePath,
-        success: () => {
-          uni.showToast({
-            title: '图片保存成功',
-          })
-        },
-        fail: (err) => {
-          console.error(err)
-
-          uni.showToast({
-            title: '图片保存失败',
-            icon: 'none',
-          })
-        },
-      })
-      // #endif
-    },
-    fail: () => {
-      uni.showToast({
-        title: '转换图片失败',
-        icon: 'none',
-      })
-    },
-  })
-}
-
-onMounted(() => {
-  initCanvas()
-})
-</script>
-
-<style lang="scss" scoped>
-$padding: 30rpx;
-
-.canvas-box {
-  .canvas {
-    height: 300rpx;
-    transition: height 0.3s;
-  }
-
-  .btns {
-    margin-top: 10rpx;
-    transition: transform 0.3s;
-
-    .btn {
-      width: auto;
-      height: 50rpx;
-    }
-  }
-}
-
-.full-screen {
-  flex-direction: row;
-  height: calc(100vh - 88rpx);
-
-  .canvas {
-    width: calc(100% - 100rpx);
-    height: 100%;
-    margin-left: 100rpx;
-  }
-
-  .btns {
-    position: absolute;
-    align-items: center;
-    width: calc(100vh - (88rpx + $padding * 2));
-    height: 100rpx;
-    transform: translate(100rpx, 0) rotate(90deg);
-    transform-origin: top left;
-
-    .btn-box {
-      flex-direction: row;
-    }
-  }
-}
-</style>

+ 0 - 188
src/pages/demo/page/waterfall.vue

@@ -1,188 +0,0 @@
-<route lang="json5" type="page">
-{
-  style: { navigationBarTitleText: 'waterfall' },
-}
-</route>
-
-<template>
-  <view class="waterfall">
-    <uv-waterfall
-      ref="waterfall"
-      v-model="list"
-      :add-time="10"
-      :left-gap="leftGap"
-      :right-gap="rightGap"
-      :column-gap="columnGap"
-      @changeList="changeList"
-    >
-      <!-- 第一列数据 -->
-      <template v-slot:list1>
-        <!-- 为了磨平部分平台的BUG,必须套一层view -->
-        <view>
-          <view v-for="item in lists.list1" :key="item.id" class="waterfall-item">
-            <view class="waterfall-item__image" :style="[imageStyle(item)]">
-              <image
-                :src="item.image"
-                mode="widthFix"
-                :style="{ width: item.width + 'px' }"
-              ></image>
-            </view>
-            <view class="waterfall-item__ft">
-              <view class="waterfall-item__ft__title">
-                <text class="value">{{ item.title }}</text>
-              </view>
-              <view class="waterfall-item__ft__desc uv-line-2">
-                <text class="value">{{ item.desc }}</text>
-              </view>
-            </view>
-          </view>
-        </view>
-      </template>
-      <!-- 第二列数据 -->
-      <template v-slot:list2>
-        <!-- 为了磨平部分平台的BUG,必须套一层view -->
-        <view>
-          <view v-for="item in lists.list2" :key="item.id" class="waterfall-item">
-            <view class="waterfall-item__image" :style="[imageStyle(item)]">
-              <image
-                :src="item.image"
-                mode="widthFix"
-                :style="{ width: item.width + 'px' }"
-              ></image>
-            </view>
-            <view class="waterfall-item__ft">
-              <view class="waterfall-item__ft__title">
-                <text class="value">{{ item.title }}</text>
-              </view>
-              <view class="waterfall-item__ft__desc uv-line-2">
-                <text class="value">{{ item.desc }}</text>
-              </view>
-            </view>
-          </view>
-        </view>
-      </template>
-    </uv-waterfall>
-  </view>
-</template>
-
-<script lang="ts" setup>
-const list = ref([]) // 瀑布流全部数据
-const lists = reactive({
-  list1: [], // 瀑布流第一列数据
-  list2: [], // 瀑布流第二列数据
-})
-const leftGap = ref(10)
-const rightGap = ref(10)
-const columnGap = ref(10)
-
-const imageStyle = computed(() => {
-  return (item) => {
-    const v = uni.upx2px(750) - leftGap.value - rightGap.value - columnGap.value
-    const w = v / 2
-    const rate = w / item.w
-    const h = rate * item.h
-    return {
-      width: `${w}px`,
-      height: `${h}px`,
-    }
-  }
-})
-
-onLoad(async () => {
-  const { data } = await getData()
-  list.value = data
-})
-
-const waterfall = ref()
-// 如果页面还没渲染结束,页面就跳走,但此时@changeList回调还在返回数据,可能会造成渲染出错,所以要想办法停止渲染
-onHide(() => {
-  waterfall.value.clear()
-})
-// 这点非常重要:e.name在这里返回是list1或list2,要手动将数据追加到相应列
-const changeList = (e: { name: 'list1' | 'list2'; value: any }) => {
-  lists[e.name].push(e.value)
-}
-// 模拟的后端数据6
-const getData = (): Promise<{ data: any[] }> => {
-  return new Promise((resolve) => {
-    const imgs = [
-      { url: 'https://via.placeholder.com/100x110.png/3c9cff/fff', width: 100, height: 110 },
-      { url: 'https://via.placeholder.com/200x220.png/f9ae3d/fff', width: 200, height: 220 },
-      { url: 'https://via.placeholder.com/300x340.png/5ac725/fff', width: 300, height: 340 },
-      { url: 'https://via.placeholder.com/400x400.png/f56c6c/fff', width: 400, height: 400 },
-      { url: 'https://via.placeholder.com/500x510.png/909399/fff', width: 500, height: 510 },
-      { url: 'https://via.placeholder.com/600x606.png/3c9cff/fff', width: 600, height: 606 },
-      { url: 'https://via.placeholder.com/310x422.png/f1a532/fff', width: 310, height: 422 },
-      { url: 'https://via.placeholder.com/320x430.png/3c9cff/fff', width: 320, height: 430 },
-      { url: 'https://via.placeholder.com/330x424.png/f9ae3d/fff', width: 330, height: 424 },
-      { url: 'https://via.placeholder.com/340x435.png/5ac725/fff', width: 340, height: 435 },
-      { url: 'https://via.placeholder.com/350x440.png/f56c6c/fff', width: 350, height: 440 },
-      { url: 'https://via.placeholder.com/380x470.png/909399/fff', width: 380, height: 470 },
-    ]
-    const arr = []
-    const doFn = (i: number) => {
-      const randomIndex = Math.floor(Math.random() * 10)
-      return {
-        id: uni.$uv.guid(),
-        allowEdit: i === 0,
-        image: imgs[randomIndex].url,
-        w: imgs[randomIndex].width,
-        h: imgs[randomIndex].height,
-        title:
-          i % 2 === 0
-            ? `(${list.value.length + i + 1})体验uv-ui框架`
-            : `(${list.value.length + i + 1})uv-ui支持多平台`,
-        desc:
-          i % 2 === 0
-            ? `(${list.value.length + i + 1})欢迎使用uv-ui,uni-app生态专用的UI框架`
-            : `(${list.value.length + i})开发者编写一套代码, 可发布到iOS、Android、H5、以及各种小程序`,
-      }
-    }
-    // 模拟异步
-    setTimeout(() => {
-      for (let i = 0; i < 20; i++) {
-        arr.push(doFn(i))
-      }
-      resolve({ data: arr })
-    }, 200)
-  })
-}
-</script>
-<style>
-page {
-  background: #f1f1f1;
-}
-</style>
-
-<style lang="scss" scoped>
-.waterfall-item {
-  margin-top: 10px;
-  overflow: hidden;
-  border-radius: 6px;
-  /* stylelint-disable-next-line selector-class-pattern */
-  .waterfall-item__ft {
-    padding: 20rpx;
-    background: #fff;
-
-    &__title {
-      margin-bottom: 10rpx;
-      font-weight: 700;
-      line-height: 48rpx;
-
-      .value {
-        font-size: 32rpx;
-        color: #303133;
-      }
-    }
-
-    &__desc .value {
-      font-size: 28rpx;
-      color: #606266;
-    }
-
-    &__btn {
-      padding: 10px 0;
-    }
-  }
-}
-</style>

+ 21 - 0
src/pages/index/about.vue

@@ -0,0 +1,21 @@
+<route lang="json5">
+{
+  style: {
+    navigationBarTitleText: '关于',
+  },
+}
+</route>
+
+<template>
+  <view
+    class="bg-white h-full overflow-hidden pt-2 px-4"
+    :style="{ marginTop: safeAreaInsets?.top + 'px' }"
+  >
+    <view class="text-center text-4xl mt-4">关于页面</view>
+  </view>
+</template>
+
+<script lang="ts" setup>
+// 获取屏幕边界到安全区域距离
+const { safeAreaInsets } = uni.getSystemInfoSync()
+</script>

+ 0 - 82
src/pages/index/i18n.vue

@@ -1,82 +0,0 @@
-<route lang="json">
-{
-  "style": {
-    "navigationBarTitleText": "%app.name%"
-  }
-}
-</route>
-
-<template>
-  <view class="center flex-col mt-6">
-    <view class="text-green-500">多语言测试</view>
-    <view class="m-4">{{ $t('app.name') }}</view>
-
-    <view class="text-green-500 mt-12">切换语言 </view>
-    <view class="uni-list">
-      <radio-group @change="radioChange" class="radio-group">
-        <label class="uni-list-cell uni-list-cell-pd" v-for="item in languages" :key="item.value">
-          <view>
-            <radio :value="item.value" :checked="item.value === current" />
-          </view>
-          <view>{{ item.name }}</view>
-        </label>
-      </radio-group>
-    </view>
-
-    <!-- http://localhost:9000/#/pages/index/i18n -->
-    <button @click="testI18n" class="mt-20 mb-44">测试弹窗</button>
-  </view>
-</template>
-
-<script lang="ts" setup>
-import i18n from '@/locale/index'
-import { testI18n } from '@/utils/index'
-
-const current = ref(uni.getLocale())
-const languages = [
-  {
-    value: 'zh-Hans',
-    name: '中文',
-    checked: 'true',
-  },
-  {
-    value: 'en',
-    name: '英文',
-  },
-]
-
-const radioChange = (evt) => {
-  // console.log(evt)
-  current.value = evt.detail.value
-  // 下面2句缺一不可!!!
-  uni.setLocale(evt.detail.value)
-  i18n.global.locale = evt.detail.value
-}
-</script>
-
-<style lang="scss">
-.uni-list {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  width: 100%;
-  background-color: #fff;
-  border-radius: 12px;
-}
-
-.radio-group {
-  width: 200px;
-  margin: 10px auto;
-  border-radius: 12px;
-}
-
-.uni-list-cell {
-  position: relative;
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  justify-content: space-between;
-  padding: 10px;
-  background-color: #bcecd1;
-}
-</style>

+ 0 - 55
src/pages/index/request.vue

@@ -1,55 +0,0 @@
-<route lang="json5">
-{
-  layout: 'demo',
-  style: {
-    navigationBarTitleText: '请求',
-  },
-}
-</route>
-
-<template>
-  <view class="mt-6">
-    <!-- http://localhost:9000/#/pages/index/request -->
-    <button @click="getFoo" class="my-4">测试 GET 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view class="text-green h-10">{{ JSON.stringify(data) }}</view>
-    <button @click="postFoo" class="my-4">测试 POST 请求</button>
-    <view class="text-xl">请求数据如下</view>
-    <view class="text-green h-10">{{ JSON.stringify(data2) }}</view>
-
-    <view class="my-2">使用的是 laf 云后台</view>
-    <view class="text-green-400">我的推荐码,可以获得佣金</view>
-    <!-- #ifdef H5 -->
-    <view class="my-2 text-center">
-      <a class="my-2 text-center" :href="recommendUrl" target="_blank">{{ recommendUrl }}</a>
-    </view>
-    <!-- #endif -->
-
-    <!-- #ifndef H5 -->
-    <view class="my-2 text-left text-sm">{{ recommendUrl }}</view>
-    <!-- #endif -->
-  </view>
-</template>
-
-<script lang="ts" setup>
-import { getFooAPI, postFooAPI, IFooItem } from '@/service/foo'
-
-const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX')
-
-onLoad(() => {
-  getFoo()
-  postFoo()
-})
-
-const data = ref<IFooItem>()
-const getFoo = async () => {
-  const res = await getFooAPI('菲鸽')
-  data.value = res.result
-}
-
-const data2 = ref<IFooItem>()
-const postFoo = async () => {
-  const res = await postFooAPI('菲鸽2')
-  data2.value = res.result
-}
-</script>

+ 0 - 39
src/pages/my/components/wx-login.vue

@@ -1,39 +0,0 @@
-<route lang="json5">
-{
-  style: { navigationBarTitleText: '登录' },
-}
-</route>
-
-<template>
-  <view class="p-4">
-    <view class="flex items-center leading-6" v-if="hasLogin">
-      <image class="w-8 h-8 rounded-full" :src="userStore.userInfo?.avatar"></image>
-      <view class="ml-2">{{ userStore.userInfo?.nickname }}</view>
-    </view>
-    <view class="flex items-center leading-6" v-else @click="show = true">
-      <view class="i-carbon-user-avatar"></view>
-      <view class="ml-2">点击显示微信头像</view>
-    </view>
-    <fly-login v-model="show" />
-    <fly-content :line="10" />
-    <button v-if="hasLogin" class="mt-2" @click="logout">退出登录</button>
-  </view>
-</template>
-
-<script lang="ts" setup name="WxLogin">
-import { useUserStore } from '@/store'
-
-const show = ref(false)
-const userStore = useUserStore()
-const hasLogin = computed(() => userStore.userInfo?.nickname)
-const logout = () => {
-  uni.showModal({
-    title: '确认退出当前账号?',
-    success: (res) => {
-      if (res.confirm) {
-        userStore.clearUserInfo()
-      }
-    },
-  })
-}
-</script>

+ 0 - 35
src/pages/my/index.vue

@@ -1,35 +0,0 @@
-<route lang="json5">
-{
-  style: { navigationBarTitleText: '我的' },
-}
-</route>
-<template>
-  <view class="ml-4">wx的openid: </view>
-  <view class="ml-4">{{ openId }}</view>
-  <wx-login />
-</template>
-
-<script lang="ts" setup>
-import { useUserStore } from '@/store'
-import { http } from '@/utils/http'
-import WxLogin from './components/wx-login.vue'
-
-const userStore = useUserStore()
-const openId = ref('')
-
-// 用户登录,获取openId
-uni.login({
-  provider: 'weixin',
-  success: async ({ code }) => {
-    const res = await http<{ session_key: string; openid: string }>({
-      method: 'GET',
-      url: '/weixin/jscode2session',
-      data: {
-        code,
-      },
-    })
-    openId.value = res.result.openid
-    userStore.setUserInfo({ openid: res.result.openid })
-  },
-})
-</script>