廖泽勇 5 өдөр өмнө
parent
commit
ec35321e71

+ 72 - 0
src/manifest.json

@@ -0,0 +1,72 @@
+{
+  "name": "",
+  "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": [
+          "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+          "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+          "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+          "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+          "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+          "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+          "<uses-feature android:name=\"android.hardware.camera\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+        ]
+      },
+      /* ios打包配置 */
+      "ios": {},
+      /* SDK配置 */
+      "sdkConfigs": {}
+    }
+  },
+  /* 快应用特有相关 */
+  "quickapp": {},
+  /* 小程序特有相关 */
+  "mp-weixin": {
+    "appid": "wx4f6dc4ac1674547c",
+    "setting": {
+      "urlCheck": false
+    },
+    "usingComponents": true
+  },
+  "mp-alipay": {
+    "usingComponents": true
+  },
+  "mp-baidu": {
+    "usingComponents": true
+  },
+  "mp-toutiao": {
+    "usingComponents": true
+  },
+  "uniStatistics": {
+    "enable": false
+  },
+  "vueVersion": "3"
+}

+ 70 - 0
src/pages.json

@@ -0,0 +1,70 @@
+{
+  "easycom": {
+    "autoscan": true,
+    "custom": {
+      "^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue"
+    }
+  },
+  "pages": [
+    //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+    {
+      "path": "pages/index/index",
+      "style": {
+        // "navigationBarTitleText": "首页",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/my/index",
+      "style": {
+        "navigationBarTitleText": "我的"
+      }
+    }
+  ],
+  "subPackages": [
+    {
+      "root": "pagesOne",
+      "pages": [
+        {
+          "path": "winner/index",
+          "style": {
+            // "navigationBarTitleText": "首页",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "winner/uploadImage",
+          "style": {
+            "navigationBarTitleText": "批量上传照片"
+          }
+        }
+      ]
+    }
+  ],
+  "globalStyle": {
+    "navigationBarTextStyle": "black",
+    "navigationBarTitleText": "uni-app",
+    "navigationBarBackgroundColor": "#F8F8F8",
+    "backgroundColor": "#F8F8F8"
+  },
+  "tabBar": {
+    "color": "#A5AEC1",
+    "selectedColor": "#1D212A",
+    "backgroundColor": "#fff",
+    "borderStyle": "white",
+    "list": [
+      {
+        "text": "首页",
+        "pagePath": "pages/index/index",
+        "iconPath": "static/images/home_default.png",
+        "selectedIconPath": "static/images/home_selected.png"
+      },
+      {
+        "text": "我的",
+        "pagePath": "pages/my/index",
+        "iconPath": "static/images/user_default.png",
+        "selectedIconPath": "static/images/user_selected.png"
+      }
+    ]
+  }
+}

+ 71 - 0
src/pages/index/index.vue

@@ -0,0 +1,71 @@
+<template>
+  <view class="homeContent">
+    <wd-swiper
+      customClass="customSwiper"
+      :list="swiperList"
+      autoplay
+      :value="current"
+    >
+    </wd-swiper>
+    <image
+      class="enter-img"
+      src="https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/enter.png"
+      mode="scaleToFill"
+    />
+    <!-- <image class="logo" src="/static/logo.png" />
+    <view class="text-area"
+      <text class="title">{{ title }}</text>
+    </view>
+    <button hover-class="button-hover" @click="onLogin">登录</button>
+    <wd-button type="success">成功按钮</wd-button> -->
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref, getCurrentInstance } from "vue";
+const current = ref<number>(0);
+
+const swiperList = ref([
+  "https://registry.npmmirror.com/wot-design-uni-assets/*/files/redpanda.jpg",
+  "https://registry.npmmirror.com/wot-design-uni-assets/*/files/capybara.jpg",
+  "https://registry.npmmirror.com/wot-design-uni-assets/*/files/panda.jpg",
+  "https://registry.npmmirror.com/wot-design-uni-assets/*/files/moon.jpg",
+  "https://registry.npmmirror.com/wot-design-uni-assets/*/files/meng.jpg",
+]);
+function handleClick(e: any) {
+  console.log(e);
+}
+function onChange(e: any) {
+  console.log(e);
+}
+</script>
+
+<style lang="scss">
+.homeContent {
+  .customSwiper {
+    height: 662rpx;
+    width: 100%;
+  }
+  .wd-swiper__track {
+    height: 100% !important;
+    width: 100% !important;
+  }
+  .wd-swiper__image {
+    height: 100% !important;
+    width: 100% !important;
+  }
+  .wd-swiper-nav__item--dots {
+    background: rgba(0, 0, 0, 0.3) !important;
+    height: 16rpx !important;
+    width: 16rpx !important;
+    &.is-active {
+      background: rgba(0, 0, 0, 0.9) !important;
+    }
+  }
+  .enter-img {
+    width: 100%;
+    height: 176rpx;
+    margin-top: 24rpx;
+  }
+}
+</style>

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

@@ -0,0 +1,75 @@
+<template>
+  <view class="content">
+    <image class="logo" src="/static/logo.png" />
+    <view class="text-area">
+      <text class="title">{{ title }}</text>
+    </view>
+    <button hover-class="button-hover" @click="onLogin">登录</button>
+    <wd-button type="success">成功按钮</wd-button>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { postLoginAPI } from "@/services/task";
+
+import {
+  onShow,
+  onLoad,
+  onPageScroll,
+  onPullDownRefresh,
+} from "@dcloudio/uni-app";
+
+import { ref } from "vue";
+const title = ref("Hello");
+onLoad(() => {
+  uni.getUserInfo({
+    success: (success) => {
+      console.log(success);
+    },
+  });
+});
+
+const onLogin = async () => {
+  let form = {
+    mobile: "18927563000",
+    password: "123456",
+  };
+  let res: any = await postLoginAPI(form);
+  if (res.code == 200) {
+    console.log("1111111111111111");
+  } else {
+    return uni.showToast({
+      title: res.msg,
+      icon: "none",
+    });
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.logo {
+  height: 200rpx;
+  width: 200rpx;
+  margin-top: 200rpx;
+  margin-left: auto;
+  margin-right: auto;
+  margin-bottom: 50rpx;
+}
+
+.text-area {
+  display: flex;
+  justify-content: center;
+}
+
+.title {
+  font-size: 36rpx;
+  color: #8f8f94;
+}
+</style>

+ 57 - 0
src/pagesOne/winner/components/photoExamplePopup.vue

@@ -0,0 +1,57 @@
+<template>
+  <wd-popup
+    v-model="props.show"
+    custom-style="border-radius:10rpx;height:1000rpx; background: transparent;"
+    lock-scroll
+  >
+    <view class="exampleContent">
+      <image class="example" :src="imgObj.photoExp" mode="scaleToFill" />
+      <image
+        @click="handleClose"
+        class="closed"
+        :src="imgObj.close"
+        mode="scaleToFill"
+      />
+    </view>
+  </wd-popup>
+</template>
+
+<script lang="ts" setup>
+import { imgObj } from "../utils/source";
+
+const props = defineProps({
+  show: {
+    type: Boolean,
+    default: true,
+  },
+});
+
+const emit = defineEmits(["update:show"]);
+
+const handleClose = () => {
+  emit("update:show", false);
+};
+</script>
+
+<style lang="scss" scoped>
+.exampleContent {
+  //   background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/photoExp.png")
+  //     no-repeat center;
+  //   background-size: cover;
+  background: transparent;
+
+  .example {
+    width: 686rpx;
+    height: 798rpx;
+  }
+  .closed {
+    width: 56rpx;
+    height: 56rpx;
+    position: absolute;
+    top: 824rpx;
+    left: 0;
+    right: 0;
+    margin: auto;
+  }
+}
+</style>

+ 129 - 0
src/pagesOne/winner/components/uploadReceptPopop.vue

@@ -0,0 +1,129 @@
+<template>
+  <view class="uploadReceptPopup">
+    <wd-popup
+      v-model="props.show"
+      position="bottom"
+      :safe-area-inset-bottom="true"
+      custom-style="height: 922rpx;border-radius: 40rpx 40rpx 0 0;"
+      @close="handleClose"
+    >
+      <view class="topTitle">
+        <text>上传小票</text>
+        <text class="tips">(*先选择优惠力度再上传)</text>
+      </view>
+      <radio-group class="receptBox">
+        <label
+          v-for="item in list"
+          :key="item.id"
+          class="radioItem"
+          :class="item.checked ? 'active' : 'static'"
+        >
+          <view class="left">
+            <image class="icon" :src="imgObj.icon1" mode="scaleToFill" />
+            <text class="label">满25返8</text>
+          </view>
+          <radio
+            class="radio"
+            color="#225036"
+            :value="item.id"
+            style="transform: scale(0.9)"
+            :checked="item.checked"
+          />
+        </label>
+      </radio-group>
+
+      <view class="btnBox">
+        <view class="play">拍摄照片</view>
+        <view class="phone">从手机相册选择</view>
+        <wd-gap height="16rpx" bg-color="#F7F8F9"></wd-gap>
+        <view @click="handleClose">取消</view>
+      </view>
+    </wd-popup>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+import { imgObj } from "../utils/source";
+const props = defineProps({
+  show: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const emit = defineEmits(["update:show"]);
+const value = ref("1");
+
+const list = [
+  { name: "满25返8", id: "1", checked: false },
+  { name: "满25返8", id: "2", checked: false },
+  { name: "满25返8", id: "3", checked: true },
+  { name: "满25返8", id: "1", checked: false },
+  { name: "满25返8", id: "2", checked: false },
+];
+const handleClose = () => {
+  emit("update:show", false);
+};
+</script>
+
+<style lang="scss">
+.uploadReceptPopup {
+  .topTitle {
+    font-size: 36rpx;
+    color: #1f1f39;
+    height: 80rpx;
+    text-align: center;
+    margin-top: 26rpx;
+    .tips {
+      font-size: 20rpx;
+      color: #bfc8db;
+    }
+  }
+  .receptBox {
+    height: 390rpx;
+    overflow-y: scroll;
+  }
+  .radioItem {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 60rpx;
+    height: 80rpx;
+    box-sizing: border-box;
+    color: #333;
+    font-size: 28rpx;
+    .left {
+      display: flex;
+      align-items: center;
+    }
+    .icon {
+      width: 36rpx;
+      height: 36rpx;
+      margin-right: 20rpx;
+    }
+    &.active {
+      background-color: #f7f8f9;
+    }
+    &.static {
+      background-color: #fff;
+    }
+  }
+  .radioItem:focus {
+    background-color: pink;
+  }
+  .btnBox {
+    font-size: 36rpx;
+    color: #555d6c;
+    margin-top: 48rpx;
+    > view {
+      text-align: center;
+      width: 100%;
+      line-height: 108rpx;
+    }
+    .play {
+      background: #f7f8f9;
+    }
+  }
+}
+</style>

+ 80 - 0
src/pagesOne/winner/components/winRecordPopup.vue

@@ -0,0 +1,80 @@
+<template>
+  <view class="winRecordPopup">
+    <wd-popup
+      v-model="show"
+      custom-style="height: 880rpx;width:686rpx;background: transparent;"
+    >
+      <view class="content">
+        <view class="list">
+          <view v-for="item in 6" :key="item" class="record">
+            <text>活动力度:满26返6</text>
+            <text>奖励金额:5元</text>
+          </view>
+          <view v-for="item in 2" :key="item" class="record">
+            <text>活动力度:满26返61</text>
+            <text>奖励金额:5111111元</text>
+          </view>
+        </view>
+      </view>
+      <image class="closed" :src="imgObj.close" mode="scaleToFill" />
+    </wd-popup>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { imgObj } from "../utils/source";
+import { ref } from "vue";
+const show = ref(true);
+const handleClose = () => {
+  show.value = false;
+};
+</script>
+
+<style lang="scss" scoped>
+.winRecordPopup {
+  .content {
+    height: 798rpx;
+    width: 686rpx;
+    background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/winRecord.png")
+      no-repeat center;
+    background-size: 100% 100%;
+
+    box-sizing: border-box;
+    overflow: hidden;
+    .list {
+      font-size: 28rpx;
+      color: #666666;
+      overflow-y: scroll;
+      height: 70%;
+      box-sizing: border-box;
+      width: 75%;
+      margin: auto;
+      margin-top: 128rpx;
+      .record {
+        text-align: center;
+        text-align: left;
+        padding: 32rpx 0;
+        border-bottom: 1rpx solid rgba(191, 200, 219, 0.5);
+        > text {
+          &:last-of-type {
+            margin-left: 44rpx;
+          }
+        }
+        &:last-of-type {
+          border: none;
+        }
+      }
+    }
+  }
+  .closed {
+    width: 56rpx;
+    height: 56rpx;
+    margin: auto;
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    margin: auto;
+  }
+}
+</style>

+ 274 - 0
src/pagesOne/winner/index.vue

@@ -0,0 +1,274 @@
+<template>
+  <view class="winnerContent">
+    <image class="backImage" :src="imgObj.backImg" mode="scaleToFill" />
+    <view class="content">
+      <view class="floatWindow">
+        <image :src="imgObj.rule" mode="scaleToFill" />
+        <image :src="imgObj.record" mode="scaleToFill" />
+      </view>
+      <view class="recordBox">
+        <view @click="showExample = true">
+          <text>拍照示例</text>
+          <image :src="imgObj.photo" mode="scaleToFill" />
+        </view>
+        <view>
+          <text>上传记录</text>
+          <image :src="imgObj.book" mode="scaleToFill" />
+        </view>
+      </view>
+      <view class="uploadBox">
+        <view class="count">您还有0次奖励机会</view>
+        <view @click="showUpload = true" class="btnBox">
+          <image :src="gifObj.pointer" />
+        </view>
+        <view class="tip"
+          >上传有效购物小票,72小时内审核成功后,即可获得奖励</view
+        >
+      </view>
+      <view class="activityTimeBox">
+        <text class="bigTitle">活动时间</text>
+        <view class="timeBox">
+          <text>2025.03.01-2025.03.31 </text>
+          <text>限指定门店、指定商品使用</text>
+        </view>
+      </view>
+      <view class="goodsListBox">
+        <!-- <image :src="imgObj.square" class="square" /> -->
+        <view class="square">
+          <text class="bigTitle title">商品列表</text>
+        </view>
+        <view class="goodsList">
+          <view v-for="item in 6" :key="item" class="goodsItem">
+            <text class="money">8元</text>
+            <text class="content">满25返8</text>
+            <text class="name">满返红包</text>
+          </view>
+        </view>
+      </view>
+    </view>
+    <wd-gap bg-color="transparent"></wd-gap>
+    <photo-example-popup v-model:show="showExample"></photo-example-popup>
+    <upload-recept-popop v-model:show="showUpload"></upload-recept-popop>
+    <win-record-popup v-model:show="showRecord"></win-record-popup>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from "vue";
+import { imgObj, gifObj } from "./utils/source";
+import PhotoExamplePopup from "./components/photoExamplePopup.vue";
+import UploadReceptPopop from "./components/uploadReceptPopop.vue";
+import WinRecordPopup from "./components/winRecordPopup.vue";
+let showExample = ref<boolean>(false);
+let showUpload = ref<boolean>(false);
+let showRecord = ref<boolean>(false);
+</script>
+
+<style lang="scss" scoped>
+.winnerContent {
+  width: 100%;
+  min-height: 2524rpx;
+  overflow: hidden;
+  box-sizing: border-box;
+  position: relative;
+  font-family: PingFang SC;
+  .content {
+    width: 96%;
+    margin: auto;
+    position: relative;
+  }
+  .backImage {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    z-index: -1;
+  }
+  .floatWindow {
+    position: fixed;
+    z-index: 10;
+    right: 0;
+    top: 240rpx;
+    display: flex;
+    flex-direction: column;
+    image {
+      width: 158rpx;
+      height: 48rpx;
+      margin-bottom: 24rpx;
+    }
+  }
+  .recordBox {
+    // width: 100%;
+    height: 192rpx;
+    border-radius: 32rpx;
+    background: linear-gradient(
+      90deg,
+      #225036 0%,
+      #3b8e5e 45.92%,
+      #3d8f5f 100%
+    );
+    padding: 24rpx;
+    display: flex;
+    justify-content: space-between;
+    margin-top: 974rpx;
+    align-items: center;
+    box-sizing: border-box;
+    > view {
+      width: 306rpx;
+      height: 144rpx;
+      background: linear-gradient(180deg, #e5fff6 0%, #ffffff 100%);
+      border-radius: 24rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    image {
+      width: 92rpx;
+      height: 92rpx;
+      margin-left: 22rpx;
+    }
+  }
+  .uploadBox {
+    color: #c0630f;
+    margin-top: 32rpx;
+    .count {
+      width: 50%;
+      color: #c0630f;
+      font-size: 24rpx;
+      background: linear-gradient(
+        90deg,
+        #ffcd70 0%,
+        #ffe3b6 45.92%,
+        #fcc761 100%
+      );
+
+      border-top-left-radius: 16rpx;
+      border-top-right-radius: 16rpx;
+      text-align: center;
+      line-height: 50rpx;
+      margin: auto;
+      margin-bottom: -2rpx;
+    }
+    .btnBox {
+      width: 100%;
+      height: 178rpx;
+      background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/uploadBtn.png")
+        no-repeat center;
+      background-size: 100% 100%;
+      object-fit: cover;
+      position: relative;
+      image {
+        width: 150rpx;
+        height: 150rpx;
+        position: absolute;
+        right: -20rpx;
+        bottom: 0;
+      }
+    }
+    .tip {
+      font-size: 24rpx;
+      font-weight: 600;
+      text-align: center;
+      margin-top: 6rpx;
+    }
+  }
+  .bigTitle {
+    font-size: 44rpx;
+    font-weight: 700;
+    letter-spacing: 12rpx;
+    font-family: Alimama ShuHeiTi;
+    color: transparent;
+    background: linear-gradient(0deg, #fff6d8 0%, #ffffff 100%);
+    -webkit-background-clip: text;
+    display: inline-block;
+    width: 100%;
+    text-align: center;
+    margin-top: 12rpx;
+    // transform: translateX(-50%);
+    // margin-left: 200rpx;
+  }
+  .activityTimeBox {
+    width: 100%;
+    height: 210rpx;
+    background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/activeBg.png")
+      no-repeat center;
+    background-size: 100% 100%;
+    margin-top: 32rpx;
+
+    .timeBox {
+      font-size: 28rpx;
+      color: #333;
+      text-align: center;
+      margin-top: 20rpx;
+      font-size: 28rpx;
+      color: #333;
+
+      > text {
+        display: block;
+      }
+    }
+  }
+  .goodsListBox {
+    background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/goodsBg.png")
+      no-repeat center;
+    background-size: 100% 100%;
+    padding: 100rpx 50rpx;
+    height: 764rpx;
+    position: relative;
+    margin-top: 64rpx;
+    box-sizing: border-box;
+    .square {
+      width: 59%;
+      height: 88rpx;
+      position: absolute;
+      left: 0;
+      right: 0;
+      top: -68rpx;
+      margin: auto;
+      z-index: 0;
+      background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/square.png")
+        no-repeat center;
+      background-size: 100% 100%;
+      margin-top: 32rpx;
+    }
+    .title {
+      position: absolute;
+      z-index: 99;
+    }
+    .goodsList {
+      display: flex;
+      justify-content: space-between;
+      flex-wrap: wrap;
+    }
+    .goodsItem {
+      width: 172rpx;
+      height: 204rpx;
+      background: url("https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/redBag.png")
+        no-repeat center;
+      background-size: 100% 100%;
+      position: relative;
+      margin-bottom: 40rpx;
+      > text {
+        position: absolute;
+        left: 0;
+        right: 0;
+        text-align: center;
+      }
+      .money {
+        color: #c0630f;
+        font-size: 48rpx;
+        top: 20rpx;
+      }
+      .content {
+        color: #224f36;
+        font-size: 24rpx;
+        top: 88rpx;
+      }
+      .name {
+        color: #ffffff;
+        font-size: 28rpx;
+        bottom: 24rpx;
+      }
+    }
+  }
+}
+</style>

+ 68 - 0
src/pagesOne/winner/uploadImage.vue

@@ -0,0 +1,68 @@
+<template>
+  <view class="uploadImageBox">
+    <wd-upload
+      :file-list="fileList"
+      action="https://mockapi.eolink.com/zhTuw2P8c29bc981a741931bdd86eb04dc1e8fd64865cb5/upload"
+      @change="handleChange"
+      multiple
+      :limit="5"
+    >
+      <image
+        class="upload"
+        src="https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/upload.png"
+        mode="scaleToFill"
+      />
+    </wd-upload>
+    <view class="tips">最多上传5张照片</view>
+    <view class="btn">立即上传</view>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+const fileList = ref<any[]>([
+  {
+    url: "https://img12.360buyimg.com//n0/jfs/t1/29118/6/4823/55969/5c35c16bE7c262192/c9fdecec4b419355.jpg",
+  },
+]);
+const handleChange = (file: any) => {
+  console.log(file);
+};
+</script>
+
+<style lang="scss">
+.uploadImageBox {
+  padding: 40rpx 32rpx;
+  .wd-upload__picture {
+    width: 196rpx !important;
+    height: 196rpx !important;
+  }
+  .upload {
+    width: 196rpx;
+    height: 196rpx;
+  }
+  .tips {
+    font-size: 20rpx;
+    color: #bfc8db;
+  }
+  .btn {
+    width: 560rpx;
+    background: linear-gradient(
+      90deg,
+      #225036 0%,
+      #3b8e5e 45.92%,
+      #296141 100%
+    );
+    color: #fff;
+    font-size: 32rpx;
+    border-radius: 80rpx;
+    left: 0;
+    right: 0;
+    margin: auto;
+    text-align: center;
+    line-height: 100rpx;
+    position: fixed;
+    bottom: 154rpx;
+  }
+}
+</style>

+ 24 - 0
src/pagesOne/winner/utils/source.ts

@@ -0,0 +1,24 @@
+export const imgObj = {
+  backImg:
+    "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/Group%201.png",
+  rule: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/rule.png",
+  record: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/record.png",
+  photo: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/photo.png",
+  book: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/book.png",
+  redBag: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/redBag.png",
+  uploadBtn:
+    "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/uploadBtn.png",
+  activeBg:
+    "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/activeBg.png",
+  goodsBg:
+    "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/goodsBg.png",
+  square: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/square.png",
+  photoExp:
+    "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/photoExp.png",
+  close: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/close.png",
+  icon1: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/images/icon1.png",
+};
+
+export const gifObj = {
+  pointer: "https://qiuyu-daodian.oss-cn-beijing.aliyuncs.com/gifs/pointer.gif",
+};

+ 67 - 0
src/services/task.ts

@@ -0,0 +1,67 @@
+import { http } from "@/utils/http";
+/**
+ * 任务列表(旧)
+ */
+export const taskList = (data: any) => {
+  return http({
+    method: "GET",
+    url: "/customer/taskList",
+    data,
+  });
+};
+/**
+ * 任务门店列表(旧)
+ */
+export const storeListByTaskId = (taskId: string, data: any) => {
+  return http({
+    method: "GET",
+    url: "/customer/storeListByTaskId/" + taskId,
+    data,
+  });
+};
+/**
+ * 任务列表(新)
+ */
+export const todaysTask = (data: any) => {
+  return http({
+    method: "GET",
+    url: "/wx/taskInfo/todaysTask",
+    data,
+  });
+};
+/**
+ * 任务门店列表(新)
+ */
+export const taskDetail = (data: any) => {
+  return http({
+    method: "GET",
+    url: "/wx/taskInfo/taskDetail",
+    data,
+  });
+};
+/**
+ * 今日任务未读数量
+ */
+export const todaysTaskCount = () => {
+  return http({
+    method: "GET",
+    url: "/wx/taskInfo/todaysTaskCount",
+  });
+};
+/**
+ * 筛选渠道列表
+ */
+export const channelByUserId = () => {
+  return http({
+    method: "GET",
+    url: "/wx/taskInfo/getChannelByUserId",
+  });
+};
+
+export const postLoginAPI = (data: any) => {
+  return http({
+    method: "POST",
+    url: "/login",
+    data,
+  });
+};

+ 6 - 0
src/shime-uni.d.ts

@@ -0,0 +1,6 @@
+export {}
+
+declare module "vue" {
+  type Hooks = App.AppInstance & Page.PageInstance;
+  interface ComponentCustomOptions extends Hooks {}
+}

BIN
src/static/images/home_default.png


BIN
src/static/images/home_selected.png


BIN
src/static/images/user_default.png


BIN
src/static/images/user_selected.png


BIN
src/static/logo.png


+ 76 - 0
src/uni.scss

@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$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: #fff;
+$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: 16;
+
+/* 图片尺寸 */
+$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: #555; // 二级标题颜色
+$uni-font-size-subtitle: 18px;
+$uni-color-paragraph: #3f536e; // 文章段落颜色
+$uni-font-size-paragraph: 15px;

+ 16 - 0
src/utils/auth.ts

@@ -0,0 +1,16 @@
+/**
+ * @description 权限存储函数
+ */
+const authorizationKey = 'token'
+
+export function getAuthorization() {
+  return uni.getStorageSync(authorizationKey)
+}
+
+export function setAuthorization(authorization:string) {
+  return uni.setStorageSync(authorizationKey, authorization)
+}
+
+export function removeAuthorization(authorization:string) {
+  return uni.removeStorageSync(authorizationKey)
+}

+ 3 - 0
src/utils/custom.ts

@@ -0,0 +1,3 @@
+export const setSrc = (value: string) => {
+  return `../static/images/${value}.png`;
+};

+ 98 - 0
src/utils/http.ts

@@ -0,0 +1,98 @@
+/**
+ * 添加拦截器:
+ *   拦截 request 请求
+ * TODO:
+ *   1. 非 http 开头需拼接地址
+ *   2. 请求超时
+ *   3. 添加小程序端请求头标识
+ *   4. 添加 token 请求头标识
+ */
+
+// import { useInfoStore } from "@/stores";
+
+const baseURL = import.meta.env.VITE_API_URL;
+// const baseURL = import.meta.env.MODE === 'production' ? import.meta.env.VITE_API_URL + '/prod-api' : import.meta.env.VITE_API_URL
+// const baseURL = import.meta.env.VITE_API_URL + '/prod-api'
+// 添加拦截器
+const httpInterceptor = {
+  // 拦截前触发
+  invoke(options: UniApp.RequestOptions) {
+    // 1. 非 http 开头需拼接地址
+    if (!options.url.startsWith("http")) {
+      options.url = baseURL + options.url;
+    }
+    // 2. 请求超时, 默认 60s
+    options.timeout = 30000;
+    // 3. 添加小程序端请求头标识
+    options.header = {
+      ...options.header,
+      "source-client": "miniapp",
+    };
+    // 4. 添加 token 请求头标识
+    // const InfoStore = useInfoStore();
+    // const token = InfoStore?.token;
+    // if (token) {
+    //   options.header.Authorization = token;
+    // }
+  },
+};
+uni.addInterceptor("request", httpInterceptor);
+
+/**
+ * 请求函数
+ * @param  UniApp.RequestOptions
+ * @returns Promise
+ *  1. 返回 Promise 对象
+ *  2. 获取数据成功
+ *    2.1 提取核心数据 res.data
+ *  3. 获取数据失败
+ *    3.1 401错误  -> 清理用户信息,跳转到登录页
+ *    3.2 其他错误 -> 根据后端错误信息轻提示
+ *    3.3 网络错误 -> 提示用户换网络
+ */
+
+// 2.2 添加类型,支持泛型
+export const http = (options: UniApp.RequestOptions) => {
+  // 1. 返回 Promise 对象
+  return new Promise((resolve, reject) => {
+    uni.request({
+      ...options,
+      // 响应成功
+      success(res: any) {
+        // 状态码 2xx, axios 就是这样设计的
+        if (res.statusCode >= 200 && res.statusCode < 300) {
+          if (res.data.code == 401) {
+            // 401错误  -> 清理用户信息,跳转到登录页
+            // const InfoStore = useInfoStore();
+            // InfoStore.clearToken();
+            uni.redirectTo({ url: "/" });
+          } else {
+            // 2.1 提取核心数据 res.data
+            resolve(res.data);
+          }
+        } else if (res.statusCode === 401) {
+          // 401错误  -> 清理用户信息,跳转到登录页
+          //   const InfoStore = useInfoStore();
+          //   InfoStore.clearToken();
+          uni.redirectTo({ url: "/" });
+          reject(res);
+        } else {
+          // 其他错误 -> 根据后端错误信息轻提示
+          uni.showToast({
+            icon: "none",
+            title: res.data.msg || "请求错误",
+          });
+          reject(res);
+        }
+      },
+      // 响应失败
+      fail(err) {
+        uni.showToast({
+          icon: "none",
+          title: "网络错误,换个网络试试",
+        });
+        reject(err);
+      },
+    });
+  });
+};

+ 46 - 0
src/utils/permission.ts

@@ -0,0 +1,46 @@
+import { getAuthorization } from "@/utils/auth";
+
+// 白名单
+const whiteList = [
+  "/", // 注意入口页必须直接写 '/'
+];
+
+export default async function () {
+  const list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
+  // 用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器
+  list.forEach((item) => {
+    uni.addInterceptor(item, {
+      invoke(e) {
+        // 获取要跳转的页面路径(url去掉"?"和"?"后的参数)
+        const url = e.url.split("?")[0];
+        // 判断当前窗口是白名单,如果是则不重定向路由
+        let pass;
+        if (whiteList) {
+          pass = whiteList.some((item) => {
+            if (typeof item === "object" && item.pattern) {
+              return item.pattern.test(url);
+            }
+            return url === item;
+          });
+        }
+
+        // 不是白名单并且没有token
+        if (!pass && !getAuthorization()) {
+          // uni.showToast({
+          // 	title: '请先登录',
+          // 	icon: 'none'
+          // })
+          uni.redirectTo({
+            url: "/",
+          });
+          return false;
+        }
+        return e;
+      },
+      fail(err) {
+        // 失败回调拦截
+        console.log(err);
+      },
+    });
+  });
+}

+ 9 - 0
src/utils/time.ts

@@ -0,0 +1,9 @@
+export const time=[
+	['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'],
+	['00','01','02','03','04','05','06','07','08','09',
+	'10','11','12','13','14','15','16','17','18','19',
+	'20','21','22','23','24','25','26','27','28','29',
+	'30','31','32','33','34','35','36','37','38','39',
+	'40','41','42','43','44','45','46','47','48','49',
+	'50','51','52','53','54','55','56','57','58','59',]
+]