Bläddra i källkod

style(client):商家列表

yizhiyang 1 år sedan
förälder
incheckning
9ca6876888

+ 108 - 0
src/PageMine/setting/index copy.vue

@@ -0,0 +1,108 @@
+<template>
+  <view class="container">
+    <view class="main-out-box">
+      <view class="main-inner-box">
+        <u-cell-group :border="false">
+          <u-cell size="large" :border="false" icon="account-fill" title="个人信息" isLink
+            url="/PageMine/setting/personInformation" />
+          <!-- <u-cell size="large" :border="false" icon="fingerprint" title="安全中心" isLink
+            url="/pages/client/clientUser/mine/setting/personInfo" /> -->
+          <u-cell size="large" :border="false" icon="github-circle-fill" title="关于我们" isLink
+            url="/PageMine/setting/aboutUs" />
+          <u-cell size="large" :border="false" icon="file-text-fill" title="用户协议" isLink
+            url="/pages/webview/index?target=http://8.137.122.65:88/用户协议.html" />
+          <u-cell size="large" :border="false" icon="file-text" title="隐私政策" isLink
+            url="/pages/webview/index?target=http://8.137.122.65:88/隐私政策.html" />
+          <u-cell icon="integral-fill" title="版本信息" value="V0.0.1" />
+        </u-cell-group>
+      </view>
+    </view>
+
+    <!-- <view class="policy-out-box">
+      <view class="policy-inner-box">
+        <u-cell-group :border="false">
+          <u-cell size="large" :border="false" icon="level" title="切换身份" isLink @click="showSwitchDialog = true" />
+        </u-cell-group>
+      </view>
+    </view> -->
+
+    <u-modal :show="showSwitchDialog" :title="title" :content="content" @confirm="confirmSwitch"
+      @cancel="showSwitchDialog = false" :showCancelButton="true"></u-modal>
+
+    <view class="exit">
+      <u-button type="info" shape="circle" text="注销账号" class="button" />
+      <u-button type="primary" shape="circle" text="退出登录" @tap="logout" class="button" />
+    </view>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        showSwitchDialog: false,
+        title: '提醒',
+        content: '您确定要从用户端切换到商家端吗?',
+      };
+    },
+
+    methods: {
+      confirmSwitch() {
+        // this.showSwitchDialog = false;
+        // this.$store.dispatch('SwitchIdentity','MERCHANT')
+        // uni.navigateTo({
+        //   url: '/pages/merchant/mine/index',
+        // });
+      },
+      logout(){
+        this.$store.dispatch('Logout').then(()=>{
+          uni.navigateTo({
+            url: `pages/login/login`,
+          });
+        })
+      }
+    },
+  };
+</script>
+
+<style lang="scss" scoped>
+  .container {
+    min-height: 100vh;
+    background-color: #efefef;
+
+    .main-out-box {
+      padding: 20rpx 16rpx;
+      box-sizing: border-box;
+
+      .main-inner-box {
+        background-color: $uni-bg-color;
+        border-radius: 20rpx;
+      }
+    }
+
+    .policy-out-box {
+      padding: 50rpx 16rpx;
+      box-sizing: border-box;
+
+      .policy-inner-box {
+        background-color: $uni-bg-color;
+        border-radius: 20rpx;
+      }
+    }
+  }
+
+  .exit {
+    // display: flex;
+    // justify-content: space-around;
+    margin-top: 100rpx;
+  }
+
+  .button {
+    width: 500rpx;
+    margin-top: 45rpx;
+  }
+
+  ::v-deep .u-modal__title {
+    padding-top: 15px;
+  }
+</style>

+ 73 - 0
src/components/base-button/base-button.vue

@@ -0,0 +1,73 @@
+<template>
+  <view class="base-button" :style="baseButtonStyle">
+    <u-button
+      :customStyle="buttonCustomStyle"
+      :color="color"
+      v-bind="$attrs"
+      v-on="$listeners"
+    ></u-button>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    buttonStyle: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+    color: {
+      type: String,
+      default: '#2F7DCD',
+    },
+    left: {
+      type: String,
+      default: '',
+    },
+    right: {
+      type: String,
+      default: '',
+    },
+  },
+  data() {
+    return {
+      defStyle: {
+        borderRadius: '4rpx',
+        minWidth: '208rpx',
+        height: '88rpx',
+      },
+    };
+  },
+  computed: {
+    baseButtonStyle() {
+      return {
+        marginLeft: this.left,
+        marginRight: this.right,
+      };
+    },
+    buttonCustomStyle() {
+      return {
+        ...this.defStyle,
+        ...this.buttonStyle,
+      };
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.base-button {
+  width: 100%;
+  display: inline-block;
+
+  ::v-deep .u-button__text {
+    font-size: 34rpx !important;
+  }
+
+  ::v-deep .u-button--plain {
+    background-color: transparent;
+  }
+}
+</style>

+ 5 - 0
src/components/base-card/base-card.vue

@@ -1,3 +1,8 @@
+<!--
+ ****--@date 2024-06-07 09:48:38
+ ****--@author yizhiyang
+ ****--@description base card
+-->
 <template>
   <view class="base-card" :style="[cardStyle]">
     <slot></slot>

+ 6 - 0
src/components/base-img/base-img.vue

@@ -1,3 +1,9 @@
+<!--
+ ****--@date 2024-06-07 09:50:45
+ ****--@author yizhiyang
+ ****--@description base img
+-->
+
 <template>
   <view class="base-img">
     <image :src="src" :mode="mode" :style="{ width, height, borderRadius }"></image>

+ 92 - 3
src/components/base-list/base-list.vue

@@ -1,13 +1,102 @@
+<!--
+ ****--@date 2024-06-07 09:51:07
+ ****--@author yizhiyang
+ ****--@description 主要用于门店列表
+-->
+
 <template>
-  <view class="base-list"> 111111111111111 </view>
+  <view class="base-list">
+    <view
+      class="fl-flex list-main"
+      v-for="(item, index) in list"
+      :key="index"
+      @click="handelList(item)"
+    >
+      <base-img
+        :src="item.logo"
+        mode="aspectFill"
+        borderRadius="8rpx"
+        height="164rpx"
+        width="164rpx"
+      ></base-img>
+      <view class="u-m-l-16" style="flex: 1">
+        <view class="f-s-30 text-primary text-bold u-m-b-4" style="line-height: 48rpx">
+          {{ item.name }}
+        </view>
+        <view class="u-m-b-6">
+          <view class="fl-flex">
+            <u-rate v-model="value" active-color="#ffa033" readonly allowHalf gutter="1"></u-rate>
+            <view class="f-s-24 text-999 u-m-l-5">(1)</view>
+          </view>
+          <!-- <view class="f-s-26" style="color: #ffa033">暂无评分</view> -->
+          <!-- <view class="f-s-26 text-999">暂无评分</view> -->
+        </view>
+        <view class="fl-flex fl-align-center">
+          <view class="list-text">综合租车</view>
+          <view class="list-line"></view>
+          <view class="list-text">销量110</view>
+        </view>
+        <view class="fl-flex fl-justify-between">
+          <view class="fl-flex">
+            <view class="f-s-24" style="color: #39bd66">营业中</view>
+            <!-- <view class="f-s-24 text-999">已休息</view> -->
+            <view class="f-s-24 text-333 u-m-l-12">08:00 ~ 18:00</view>
+          </view>
+          <view class="f-s-24 text-999" v-if="item.distance">{{ item.distance | mToKm }}</view>
+        </view>
+      </view>
+    </view>
+  </view>
 </template>
 
 <script>
-export default {};
+export default {
+  props: {
+    borderRadius: {
+      type: String,
+      default: '',
+    },
+    list: {
+      type: Array,
+      default: [],
+    },
+  },
+  data() {
+    return {
+      value: 4,
+    };
+  },
+  filters: {
+    mToKm(v) {
+      return (Number(v) / 1000).toFixed(2) + 'km';
+    },
+  },
+  methods: {
+    handelList(item) {
+      this.$emit('click', item);
+      console.log(item, 'oooooooooo');
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
 .base-list {
-  border-radius: 8rpx;
+  .list-main {
+    padding: 16rpx;
+    border-radius: 8rpx;
+    margin-bottom: 24rpx;
+    background-color: #fff;
+  }
+  .list-text {
+    font-size: 24rpx;
+    color: #666666;
+  }
+  .list-line {
+    height: 22rpx;
+    width: 1rpx;
+    background-color: #666666;
+    margin: 12rpx;
+  }
 }
 </style>

+ 132 - 0
src/components/base-popup/base-popup.vue

@@ -0,0 +1,132 @@
+<template>
+  <view class="base-popup">
+    <u-popup
+      :show="show"
+      :round="10"
+      mode="center"
+      @close="close"
+      :customStyle="popupCustomStyle"
+      :closeOnClickOverlay="false"
+    >
+      <view class="header flex justify-between align-center">
+        <view class="u-font-16 u-font-500" :style="titleStyle">{{ title }}</view>
+        <u-icon :bold="true" name="close" color="#1E252B" size="16" @click="close()"></u-icon>
+      </view>
+      <view class="main">
+        <slot name="main"></slot>
+      </view>
+      <view class="footer flex justify-between">
+        <view>
+          <slot name="footerLeft"></slot>
+        </view>
+        <view class="flex align-center">
+          <u-button
+            class="u-m-r-16"
+            :customStyle="closeCustomStyle"
+            @click="close()"
+            v-if="cancelShow"
+            >{{ cancelText }}</u-button
+          >
+          <u-button type="primary" :customStyle="confirmCustomStyle" @click="confirm()">{{
+            confirmText
+          }}</u-button>
+        </view>
+      </view>
+    </u-popup>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'base-popup',
+  props: {
+    show: {
+      type: Boolean,
+      default: false,
+    },
+    title: {
+      type: String,
+      default: '标题',
+    },
+    width: {
+      type: String,
+      default: '520px',
+    },
+    fontWeight: {
+      type: String,
+      default: '',
+    },
+    cancelText: {
+      type: String,
+      default: '取消',
+    },
+    confirmText: {
+      type: String,
+      default: '确认',
+    },
+    cancelShow: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    titleStyle() {
+      let { fontWeight } = this;
+
+      return {
+        fontWeight,
+      };
+    },
+    popupCustomStyle() {
+      return {
+        width: this.width,
+      };
+    },
+    closeCustomStyle() {
+      return {
+        width: '84px',
+        height: '36px',
+        border: '1px solid #d3d6d8',
+        color: '#1E252B',
+      };
+    },
+    confirmCustomStyle() {
+      return {
+        width: '84px',
+        height: '36px',
+        background: '#2196F3',
+      };
+    },
+  },
+  methods: {
+    close() {
+      this.$emit('update:show', false);
+      this.$emit('close');
+    },
+    confirm() {
+      this.$emit('confirm');
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.base-popup {
+  .header {
+    padding: 16px 24px;
+  }
+
+  .main {
+    padding: 24px;
+    border-top: 1px solid #eaebec;
+    border-bottom: 1px solid #eaebec;
+  }
+
+  .footer {
+    padding: 16px 20px;
+  }
+}
+</style>

+ 64 - 0
src/components/base-text/base-text.vue

@@ -0,0 +1,64 @@
+<template>
+  <view class="base-text">
+    <view :style="textStyle">{{ text }}</view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'base-text',
+  props: {
+    text: {
+      type: String,
+      default: '',
+    },
+    width: {
+      type: String,
+      default: '62px',
+    },
+    height: {
+      type: String,
+      default: '26px',
+    },
+    fontSize: {
+      type: String,
+      default: '14px',
+    },
+    color: {
+      type: String,
+      default: '',
+    },
+    background: {
+      type: String,
+      default: '',
+    },
+    borderRadius: {
+      type: String,
+      default: '4px',
+    },
+    textAlign: {
+      type: String,
+      default: 'center',
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    textStyle() {
+      const { width, height, fontSize, color, background, borderRadius, textAlign } = this;
+
+      return {
+        width,
+        height,
+        fontSize,
+        color,
+        background,
+        borderRadius,
+        textAlign,
+        lineHeight: height,
+      };
+    },
+  },
+};
+</script>

+ 0 - 32
src/components/empty/index.vue

@@ -1,32 +0,0 @@
-<template>
-  <view class="empty">
-    <text>{{ text }}</text>
-  </view>
-</template>
-
-<script>
-export default {
-  props: {
-    text: {
-      type: String,
-      default: '暂无数据',
-    }
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.empty {
-  // height: 100vh;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-  // background-color: brown;
-  image {
-    width: 350rpx;
-    height: 400rpx;
-  }
-}
-</style>
->

+ 16 - 2
src/components/home-store/home-store.vue

@@ -1,3 +1,8 @@
+<!--
+ ****--@date 2024-06-07 09:52:38
+ ****--@author yizhiyang
+ ****--@description 首页门店
+-->
 <template>
   <view class="home-store">
     <view class="image-box">
@@ -19,9 +24,14 @@
     </view>
     <view class="home-list">
       <view class="fl-flex fl-self-center">
-        <view class="f-s-28 text-primary text-cut-1 u-m-b-14">{{ item.address }}</view>
+        <view class="f-s-28 text-primary text-cut-1 u-m-b-14">{{ item.name }}</view>
         <view class="u-m-t-12">
-          <u--image src="/static/pages/home/home-hot.png" width="24rpx" height="24rpx"></u--image>
+          <u--image
+            src="/static/pages/home/home-hot.png"
+            width="24rpx"
+            height="24rpx"
+            v-if="isType === 'hot'"
+          ></u--image>
         </view>
       </view>
       <view>
@@ -43,6 +53,10 @@ export default {
       type: Object,
       default: () => {},
     },
+    isType: {
+      type: String,
+      default: '',
+    },
   },
   filters: {
     mToKm(v) {

+ 30 - 0
src/components/load-more/load-more.vue

@@ -0,0 +1,30 @@
+<template>
+  <view class="load-more">
+    <u-loadmore :status="status" :line="line" v-bind="$attrs" v-on="$listeners" />
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    status: {
+      type: String,
+      default: 'loadmore',
+    },
+    line: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  name: 'load-more',
+  data() {
+    return {};
+  },
+};
+</script>
+
+<style lang="scss">
+.load-more {
+  padding: 20rpx 0;
+}
+</style>

+ 53 - 0
src/components/page-empty/page-empty.vue

@@ -0,0 +1,53 @@
+<template>
+  <view class="page-empty">
+    <u-empty
+      :textColor="textColor"
+      :textSize="textSize"
+      :iconColor="iconColor"
+      :width="width"
+      :height="height"
+      v-bind="$attrs"
+      v-on="$listeners"
+    />
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'page-empty',
+  props: {
+    textColor: {
+      type: String,
+      default: '#9B9B9B',
+    },
+    textSize: {
+      type: [String, Number],
+      default: '28rpx',
+    },
+    iconColor: {
+      type: String,
+      default: '#9B9B9B',
+    },
+    width: {
+      type: [String, Number],
+      default: '120',
+    },
+    height: {
+      type: [String, Number],
+      default: '120',
+    },
+  },
+  data() {
+    return {};
+  },
+};
+</script>
+
+<style lang="scss">
+.page-empty {
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+</style>

+ 6 - 1
src/components/page-navbar/page-navbar.vue

@@ -1,3 +1,8 @@
+<!--
+ ****--@date 2024-06-07 09:54:58
+ ****--@author yizhiyang
+ ****--@description 自定义导航栏
+-->
 <template>
   <view class="page-navbar">
     <u-navbar
@@ -137,7 +142,7 @@ export default {
     handleGoHome() {
       uni.$u.route({
         type: 'switchTab',
-        url: '/pages/home/index',
+        url: '/pages/tabbar/home.vue',
       });
     },
   },

+ 106 - 0
src/components/popup-confirm/popup-confirm.vue

@@ -0,0 +1,106 @@
+<template>
+  <view class="popup-confirm">
+    <u-popup
+      :show="show"
+      :round="10"
+      mode="center"
+      @close="close"
+      :customStyle="popupCustomStyle"
+      :closeOnClickOverlay="false"
+    >
+      <view class="main flex align-center">
+        <base-imgae class="u-m-r-10" :src="iconSrc" width="24px" height="24px"></base-imgae>
+        <view class="text u-font-16 text-title">{{ text }}</view>
+      </view>
+      <view class="footer flex justify-end">
+        <view class="flex">
+          <u-button class="u-m-r-16" :customStyle="closeCustomStyle" @click="close()"
+            >取消</u-button
+          >
+          <u-button type="primary" :customStyle="confirmCustomStyle" @click="confirm()">{{
+            confirmText
+          }}</u-button>
+        </view>
+      </view>
+    </u-popup>
+    <!-- 		<popup-confirm :show.sync="showLogout" @confirm="handleLogoutConfirm" text="确认退出登录吗?" confirm-text="确认退出"></popup-confirm>
+ -->
+  </view>
+</template>
+<script>
+export default {
+  name: 'popup-confirm',
+  props: {
+    show: {
+      type: Boolean,
+      default: false,
+    },
+    text: {
+      type: String,
+      default: '',
+    },
+    width: {
+      type: String,
+      default: '380px',
+    },
+    confirmText: {
+      type: String,
+      default: '确认',
+    },
+    type: {
+      type: String,
+      default: 'warning',
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    iconSrc() {
+      return `/static/components/popup-confirm/${this.type}.svg`;
+    },
+    popupCustomStyle() {
+      return {
+        width: this.width,
+      };
+    },
+    closeCustomStyle() {
+      return {
+        width: '60px',
+        height: '36px',
+        border: 'none',
+        color: '#1E252B',
+        background: '#eff2f4',
+      };
+    },
+    confirmCustomStyle() {
+      return {
+        width: '88px',
+        height: '36px',
+        background: '#2196F3',
+      };
+    },
+  },
+  methods: {
+    close() {
+      this.$emit('update:show', false);
+      this.$emit('close');
+    },
+    confirm() {
+      this.$emit('confirm');
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.popup-confirm {
+  .main {
+    padding: 24px;
+  }
+
+  .footer {
+    padding: 0 20px 20px;
+  }
+}
+</style>

+ 397 - 386
src/components/ren-calendar/ren-calendar.vue

@@ -1,424 +1,435 @@
 <template>
-    <view class="calendar-wrapper">
-        <view class="header" v-if="headerBar">
-            <view class="pre" @click="changeMonth('pre')">上个月</view>
-            <view>{{y+'年'+formatNum(m)+'月'}}</view>
-            <view class="next" @click="changeMonth('next')">下个月</view>
-        </view>
-        <view class="week">
-            <view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
-        </view>
-        <view :class="{ hide: !monthOpen }" class="content" :style="{ height: height }">
-            <view :style="{ top: positionTop + 'rpx' }" class="days">
-                <view class="item" v-for="(item, index) in dates" :key="index">
-                    <view
-                        class="day"
-                        @click="selectOne(item, $event)"
-                        :class="{
-                            choose: choose == `${item.year}-${item.month}-${item.date}`&&item.isCurM,
-                            nolm: !item.isCurM,
-                            today: isToday(item.year, item.month, item.date),
-                            isWorkDay: isWorkDay(item.year, item.month, item.date)
-                        }"
-                    >
-                        {{ Number(item.date) }}
-                    </view>
-                    <view class="markDay" v-if="isMarkDay(item.year, item.month, item.date)&&item.isCurM"></view>
-                    <!-- <view class="today-text" v-if="isToday(item.year, item.month, item.date)">今</view> -->
-                </view>
-            </view>
+  <view class="calendar-wrapper">
+    <view class="header" v-if="headerBar">
+      <view class="pre" @click="changeMonth('pre')">上个月</view>
+      <view>{{ y + '年' + formatNum(m) + '月' }}</view>
+      <view class="next" @click="changeMonth('next')">下个月</view>
+    </view>
+    <view class="week">
+      <view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
+    </view>
+    <view :class="{ hide: !monthOpen }" class="content" :style="{ height: height }">
+      <view :style="{ top: positionTop + 'rpx' }" class="days">
+        <view class="item" v-for="(item, index) in dates" :key="index">
+          <view
+            class="day"
+            @click="selectOne(item, $event)"
+            :class="{
+              choose: choose == `${item.year}-${item.month}-${item.date}` && item.isCurM,
+              nolm: !item.isCurM,
+              today: isToday(item.year, item.month, item.date),
+              isWorkDay: isWorkDay(item.year, item.month, item.date),
+            }"
+          >
+            {{ Number(item.date) }}
+          </view>
+          <view
+            class="markDay"
+            v-if="isMarkDay(item.year, item.month, item.date) && item.isCurM"
+          ></view>
+          <!-- <view class="today-text" v-if="isToday(item.year, item.month, item.date)">今</view> -->
         </view>
-        <image src="https://i.loli.net/2020/07/16/2MmZsucVTlRjSwK.png" mode="scaleToFill" v-if="collapsible" @click="toggle" class="weektoggle" :class="{ down: monthOpen }"></image>
+      </view>
     </view>
+    <image
+      src="https://i.loli.net/2020/07/16/2MmZsucVTlRjSwK.png"
+      mode="scaleToFill"
+      v-if="collapsible"
+      @click="toggle"
+      class="weektoggle"
+      :class="{ down: monthOpen }"
+    ></image>
+  </view>
 </template>
 
 <script>
 export default {
-    name: 'ren-calendar',
-    props: {
-        // 星期几为第一天(0为星期日)
-        weekstart: {
-            type: Number,
-            default: 0
-        },
-        // 标记的日期
-        markDays: {
-            type: Array,
-            default: ()=>{
-                return [];
-            }
-        },
-        //是否展示月份切换按钮
-        headerBar:{
-            type: Boolean,
-            default: true
-        },
-        // 是否展开
-        open: {
-            type: Boolean,
-            default: true
-        },
-        //是否可收缩
-        collapsible:{
-            type: Boolean,
-            default: true
-        },
-        //未来日期是否不可点击
-        disabledAfter: {
-            type: Boolean,
-            default: false
+  name: 'ren-calendar',
+  props: {
+    // 星期几为第一天(0为星期日)
+    weekstart: {
+      type: Number,
+      default: 0,
+    },
+    // 标记的日期
+    markDays: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    //是否展示月份切换按钮
+    headerBar: {
+      type: Boolean,
+      default: true,
+    },
+    // 是否展开
+    open: {
+      type: Boolean,
+      default: true,
+    },
+    //是否可收缩
+    collapsible: {
+      type: Boolean,
+      default: true,
+    },
+    //未来日期是否不可点击
+    disabledAfter: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      weektext: ['日', '一', '二', '三', '四', '五', '六'],
+      y: new Date().getFullYear(), // 年
+      m: new Date().getMonth() + 1, // 月
+      dates: [], // 当前月的日期数据
+      positionTop: 0,
+      monthOpen: true,
+      choose: '',
+    };
+  },
+  created() {
+    this.dates = this.monthDay(this.y, this.m);
+    !this.open && this.toggle();
+  },
+  mounted() {
+    this.choose = this.getToday().date;
+  },
+  computed: {
+    // 顶部星期栏
+    weekDay() {
+      return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart));
+    },
+    height() {
+      return (this.dates.length / 7) * 80 + 'rpx';
+    },
+  },
+  methods: {
+    formatNum(num) {
+      let res = Number(num);
+      return res < 10 ? '0' + res : res;
+    },
+    getToday() {
+      let date = new Date();
+      let y = date.getFullYear();
+      let m = date.getMonth();
+      let d = date.getDate();
+      let week = new Date().getDay();
+      let weekText = ['日', '一', '二', '三', '四', '五', '六'];
+      let formatWeek = '星期' + weekText[week];
+      let today = {
+        date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d),
+        week: formatWeek,
+      };
+      return today;
+    },
+    // 获取当前月份数据
+    monthDay(y, month) {
+      let dates = [];
+      let m = Number(month);
+      let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
+      let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
+      let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天
+      let weekstart = this.weekstart == 7 ? 0 : this.weekstart;
+      let startDay = (() => {
+        // 周初有几天是上个月的
+        if (firstDayOfMonth == weekstart) {
+          return 0;
+        } else if (firstDayOfMonth > weekstart) {
+          return firstDayOfMonth - weekstart;
+        } else {
+          return 7 - weekstart + firstDayOfMonth;
         }
+      })();
+      let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
+      for (let i = 1; i <= startDay; i++) {
+        dates.push({
+          date: this.formatNum(lastDayOfLastMonth - startDay + i),
+          day: weekstart + i - 1 || 7,
+          month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
+          year: m - 1 >= 0 ? y : y - 1,
+        });
+      }
+      for (let j = 1; j <= lastDateOfMonth; j++) {
+        dates.push({
+          date: this.formatNum(j),
+          day: (j % 7) + firstDayOfMonth - 1 || 7,
+          month: this.formatNum(m),
+          year: y,
+          isCurM: true, //是否当前月份
+        });
+      }
+      for (let k = 1; k <= endDay; k++) {
+        dates.push({
+          date: this.formatNum(k),
+          day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
+          month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
+          year: m + 1 <= 11 ? y : y + 1,
+        });
+      }
+      // console.log(dates);
+      return dates;
+    },
+    isWorkDay(y, m, d) {
+      //是否工作日
+      let ymd = `${y}/${m}/${d}`;
+      let formatDY = new Date(ymd.replace(/-/g, '/'));
+      let week = formatDY.getDay();
+      if (week == 0 || week == 6) {
+        return false;
+      } else {
+        return true;
+      }
+    },
+    isFutureDay(y, m, d) {
+      //是否未来日期
+      let ymd = `${y}/${m}/${d}`;
+      let formatDY = new Date(ymd.replace(/-/g, '/'));
+      let showTime = formatDY.getTime();
+      let curTime = new Date().getTime();
+      if (showTime > curTime) {
+        return true;
+      } else {
+        return false;
+      }
     },
-    data() {
-        return {
-            weektext: ['日', '一', '二', '三', '四', '五', '六'],
-            y: new Date().getFullYear(), // 年
-            m: new Date().getMonth() + 1, // 月
-            dates: [], // 当前月的日期数据
-            positionTop: 0,
-            monthOpen: true,
-            choose: ''
-        };
+    // 标记日期
+    isMarkDay(y, m, d) {
+      let flag = false;
+      for (let i = 0; i < this.markDays.length; i++) {
+        let dy = `${y}-${m}-${d}`;
+        if (this.markDays[i] == dy) {
+          flag = true;
+          break;
+        }
+      }
+      return flag;
     },
-    created() {
-        this.dates = this.monthDay(this.y, this.m);
-        !this.open && this.toggle();
+    isToday(y, m, d) {
+      let checkD = y + '-' + m + '-' + d;
+      let today = this.getToday().date;
+      if (checkD == today) {
+        return true;
+      } else {
+        return false;
+      }
     },
-    mounted() {
-        this.choose = this.getToday().date;
+    // 展开收起
+    toggle() {
+      this.monthOpen = !this.monthOpen;
+      if (this.monthOpen) {
+        this.positionTop = 0;
+      } else {
+        let index = -1;
+        this.dates.forEach((i, x) => {
+          this.isToday(i.year, i.month, i.date) && (index = x);
+        });
+        this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80;
+      }
     },
-    computed: {
-        // 顶部星期栏
-        weekDay() {
-            return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart));
-        },
-        height() {
-            return (this.dates.length / 7) * 80 + 'rpx';
+    // 点击回调
+    selectOne(i, event) {
+      let date = `${i.year}-${i.month}-${i.date}`;
+      let selectD = new Date(date).getTime();
+      let curTime = new Date().getTime();
+      let week = new Date(date).getDay();
+      let weekText = ['日', '一', '二', '三', '四', '五', '六'];
+      let formatWeek = '星期' + weekText[week];
+      let response = {
+        date: date,
+        week: formatWeek,
+      };
+      if (!i.isCurM) {
+        // console.log('不在当前月范围内');
+        return false;
+      }
+      if (selectD > curTime) {
+        if (this.disabledAfter) {
+          console.log('未来日期不可选');
+          return false;
+        } else {
+          this.choose = date;
+          this.$emit('onDayClick', response);
         }
+      } else {
+        this.choose = date;
+        this.$emit('onDayClick', response);
+      }
+      console.log(response);
+    },
+    //改变年月
+    changYearMonth(y, m) {
+      this.dates = this.monthDay(y, m);
+      this.y = y;
+      this.m = m;
     },
-    methods: {
-        formatNum(num) {
-            let res = Number(num);
-            return res < 10 ? '0' + res : res;
-        },
-        getToday() {
-            let date = new Date();
-            let y = date.getFullYear();
-            let m = date.getMonth();
-            let d = date.getDate();
-            let week = new Date().getDay();
-            let weekText = ['日', '一', '二', '三', '四', '五', '六'];
-            let formatWeek = '星期' + weekText[week];
-            let today = {
-                date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d),
-                week: formatWeek
-            };
-            return today;
-        },
-        // 获取当前月份数据
-        monthDay(y, month) {
-            let dates = [];
-            let m = Number(month);
-            let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
-            let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
-            let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天
-            let weekstart = this.weekstart == 7 ? 0 : this.weekstart;
-            let startDay = (() => {
-                // 周初有几天是上个月的
-                if (firstDayOfMonth == weekstart) {
-                    return 0;
-                } else if (firstDayOfMonth > weekstart) {
-                    return firstDayOfMonth - weekstart;
-                } else {
-                    return 7 - weekstart + firstDayOfMonth;
-                }
-            })();
-            let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
-            for (let i = 1; i <= startDay; i++) {
-                dates.push({
-                    date: this.formatNum(lastDayOfLastMonth - startDay + i),
-                    day: weekstart + i - 1 || 7,
-                    month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
-                    year: m - 1 >= 0 ? y : y - 1
-                });
-            }
-            for (let j = 1; j <= lastDateOfMonth; j++) {
-                dates.push({
-                    date: this.formatNum(j),
-                    day: (j % 7) + firstDayOfMonth - 1 || 7,
-                    month: this.formatNum(m),
-                    year: y,
-                    isCurM: true //是否当前月份
-                });
-            }
-            for (let k = 1; k <= endDay; k++) {
-                dates.push({
-                    date: this.formatNum(k),
-                    day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
-                    month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
-                    year: m + 1 <= 11 ? y : y + 1
-                });
-            }
-            // console.log(dates);
-            return dates;
-        },
-        isWorkDay(y, m, d) {
-            //是否工作日
-            let ymd = `${y}/${m}/${d}`;
-            let formatDY = new Date(ymd.replace(/-/g, '/'));
-            let week = formatDY.getDay();
-            if (week == 0 || week == 6) {
-                return false;
-            } else {
-                return true;
-            }
-        },
-        isFutureDay(y, m, d) {
-            //是否未来日期
-            let ymd = `${y}/${m}/${d}`;
-            let formatDY = new Date(ymd.replace(/-/g, '/'));
-            let showTime = formatDY.getTime();
-            let curTime = new Date().getTime();
-            if (showTime > curTime) {
-                return true;
-            } else {
-                return false;
-            }
-        },
-        // 标记日期
-        isMarkDay(y, m, d) {
-            let flag = false;
-            for (let i = 0; i < this.markDays.length; i++) {
-                let dy = `${y}-${m}-${d}`;
-                if (this.markDays[i] == dy) {
-                    flag = true;
-                    break;
-                }
-            }
-            return flag;
-        },
-        isToday(y, m, d) {
-            let checkD = y + '-' + m + '-' + d;
-            let today = this.getToday().date;
-            if (checkD == today) {
-                return true;
-            } else {
-                return false;
-            }
-        },
-        // 展开收起
-        toggle() {
-            this.monthOpen = !this.monthOpen;
-            if (this.monthOpen) {
-                this.positionTop = 0;
-            } else {
-                let index = -1;
-                this.dates.forEach((i, x) => {
-                    this.isToday(i.year, i.month, i.date) && (index = x);
-                });
-                this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80;
-            }
-        },
-        // 点击回调
-        selectOne(i, event) {
-            let date = `${i.year}-${i.month}-${i.date}`;
-            let selectD = new Date(date).getTime();
-            let curTime = new Date().getTime();
-            let week = new Date(date).getDay();
-            let weekText = ['日', '一', '二', '三', '四', '五', '六'];
-            let formatWeek = '星期' + weekText[week];
-            let response = {
-                date: date,
-                week: formatWeek
-            };
-            if (!i.isCurM) {
-                // console.log('不在当前月范围内');
-                return false;
-            }
-            if (selectD > curTime) {
-                if (this.disabledAfter) {
-                    console.log('未来日期不可选');
-                    return false;
-                } else {
-                    this.choose = date;
-                    this.$emit('onDayClick', response);
-                }
-            } else {
-                this.choose = date;
-                this.$emit('onDayClick', response);
-            }
-            console.log(response);
-        },
-        //改变年月
-        changYearMonth(y, m) {
-            this.dates = this.monthDay(y, m);
-            this.y = y;
-            this.m = m;
-        },
-        changeMonth(type){
-            if(type=='pre'){
-               if (this.m + 1 == 2) {
-                   this.m = 12;
-                   this.y = this.y - 1;
-               } else {
-                   this.m = this.m - 1;
-               } 
-            }else{
-                if (this.m + 1 == 13) {
-                    this.m = 1;
-                    this.y = this.y + 1;
-                } else {
-                    this.m = this.m + 1;
-                }
-            }
-            this.dates = this.monthDay(this.y, this.m);
+    changeMonth(type) {
+      if (type == 'pre') {
+        if (this.m + 1 == 2) {
+          this.m = 12;
+          this.y = this.y - 1;
+        } else {
+          this.m = this.m - 1;
         }
-    }
+      } else {
+        if (this.m + 1 == 13) {
+          this.m = 1;
+          this.y = this.y + 1;
+        } else {
+          this.m = this.m + 1;
+        }
+      }
+      this.dates = this.monthDay(this.y, this.m);
+    },
+  },
 };
 </script>
 
 <style lang="scss" scoped>
 .calendar-wrapper {
-    color: #bbb7b7;
-    font-size: 28rpx;
-    text-align: center;
-    background-color: #fff;
-    padding-bottom: 10rpx;
-    
-    .header{
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        height: 88rpx;
-        color: #42464A;
-        font-size: 32rpx;
-        font-weight: bold;
-        border-bottom: 2rpx solid #f2f2f2;
-        .pre,.next{
-              color: #4d7df9;
-              font-size: 28rpx;
-              font-weight: normal;
-              padding: 8rpx 15rpx;
-              border-radius: 10rpx;
-              border: 2rpx solid #dcdfe6;
-        }
-        .pre{
-            margin-right: 30rpx;
-        }
-        .next{
-            margin-left: 30rpx;
-        }
+  color: #bbb7b7;
+  font-size: 28rpx;
+  text-align: center;
+  background-color: #fff;
+  padding-bottom: 10rpx;
+
+  .header {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 88rpx;
+    color: #42464a;
+    font-size: 32rpx;
+    font-weight: bold;
+    border-bottom: 2rpx solid #f2f2f2;
+    .pre,
+    .next {
+      color: #4d7df9;
+      font-size: 28rpx;
+      font-weight: normal;
+      padding: 8rpx 15rpx;
+      border-radius: 10rpx;
+      border: 2rpx solid #dcdfe6;
+    }
+    .pre {
+      margin-right: 30rpx;
+    }
+    .next {
+      margin-left: 30rpx;
     }
+  }
 
-    .week {
-        display: flex;
-        align-items: center;
-        height: 80rpx;
-        line-height: 80rpx;
-        border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
+  .week {
+    display: flex;
+    align-items: center;
+    height: 80rpx;
+    line-height: 80rpx;
+    border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
 
-        view {
-            flex: 1;
-        }
+    view {
+      flex: 1;
     }
+  }
 
-    .content {
-        position: relative;
-        overflow: hidden;
-        transition: height 0.4s ease;
+  .content {
+    position: relative;
+    overflow: hidden;
+    transition: height 0.4s ease;
 
-        .days {
-            transition: top 0.3s;
-            display: flex;
-            align-items: center;
-            flex-wrap: wrap;
-            position: relative;
+    .days {
+      transition: top 0.3s;
+      display: flex;
+      align-items: center;
+      flex-wrap: wrap;
+      position: relative;
 
-            .item {
-                position: relative;
-                display: block;
-                height: 80rpx;
-                line-height: 80rpx;
-                width: calc(100% / 7);
+      .item {
+        position: relative;
+        display: block;
+        height: 80rpx;
+        line-height: 80rpx;
+        width: calc(100% / 7);
 
-                .day {
-                    font-style: normal;
-                    display: inline-block;
-                    vertical-align: middle;
-                    width: 60rpx;
-                    height: 60rpx;
-                    line-height: 60rpx;
-                    overflow: hidden;
-                    border-radius: 60rpx;
+        .day {
+          font-style: normal;
+          display: inline-block;
+          vertical-align: middle;
+          width: 60rpx;
+          height: 60rpx;
+          line-height: 60rpx;
+          overflow: hidden;
+          border-radius: 60rpx;
 
-                    &.choose {
-                        background-color: #4d7df9;
-                        color: #fff;
-                    }
+          &.choose {
+            background-color: #4d7df9;
+            color: #fff;
+          }
 
-                    &.nolm {
-                        color: #fff;
-                        opacity: 0.3;
-                    }
-                }
-                .isWorkDay {
-                    color: #42464a;
-                }
+          &.nolm {
+            color: #fff;
+            opacity: 0.3;
+          }
+        }
+        .isWorkDay {
+          color: #42464a;
+        }
 
-                .notSigned {
-                    font-style: normal;
-                    width: 8rpx;
-                    height: 8rpx;
-                    background: #fa7268;
-                    border-radius: 10rpx;
-                    position: absolute;
-                    left: 50%;
-                    bottom: 0;
-                    pointer-events: none;
-                }
-                .today {
-                    color: #fff;
-                    background-color: #a8c0ff;
-                }
-                .workDay {
-                    font-style: normal;
-                    width: 8rpx;
-                    height: 8rpx;
-                    background: #4d7df9;
-                    border-radius: 10rpx;
-                    position: absolute;
-                    left: 50%;
-                    bottom: 0;
-                    pointer-events: none;
-                }
-                .markDay{
-                    font-style: normal;
-                    width: 8rpx;
-                    height: 8rpx;
-                    background: #fc7a64;
-                    border-radius: 10rpx;
-                    position: absolute;
-                    left: 50%;
-                    bottom: 0;
-                    pointer-events: none;
-                }
-            }
+        .notSigned {
+          font-style: normal;
+          width: 8rpx;
+          height: 8rpx;
+          background: #fa7268;
+          border-radius: 10rpx;
+          position: absolute;
+          left: 50%;
+          bottom: 0;
+          pointer-events: none;
+        }
+        .today {
+          color: #fff;
+          background-color: #a8c0ff;
         }
+        .workDay {
+          font-style: normal;
+          width: 8rpx;
+          height: 8rpx;
+          background: #4d7df9;
+          border-radius: 10rpx;
+          position: absolute;
+          left: 50%;
+          bottom: 0;
+          pointer-events: none;
+        }
+        .markDay {
+          font-style: normal;
+          width: 8rpx;
+          height: 8rpx;
+          background: #fc7a64;
+          border-radius: 10rpx;
+          position: absolute;
+          left: 50%;
+          bottom: 0;
+          pointer-events: none;
+        }
+      }
     }
+  }
 
-    .hide {
-        height: 80rpx !important;
-    }
+  .hide {
+    height: 80rpx !important;
+  }
 
-    .weektoggle {
-        width: 85rpx;
-        height: 32rpx;
-        position: relative;
-        bottom: -42rpx;
-        &.down {
-            transform: rotate(180deg);
-            bottom: 0;
-        }
+  .weektoggle {
+    width: 85rpx;
+    height: 32rpx;
+    position: relative;
+    bottom: -42rpx;
+    &.down {
+      transform: rotate(180deg);
+      bottom: 0;
     }
+  }
 }
 </style>

+ 197 - 0
src/components/upload-img/index.vue

@@ -0,0 +1,197 @@
+<template>
+  <view class="view-bg min-page">
+    <view class="u-p-t-24">
+      <u-form labelPosition="left" :model="form" :rules="rules" ref="uForm">
+        <u-cell-group class="bg-white" :border="false">
+          <u-cell
+            :border="false"
+            class="complain-cell"
+            isLink
+            @click="showBuild = true"
+            size="large"
+          >
+            <view slot="title">
+              反馈类型
+              <text class="text-error u-m-l-10">*</text>
+            </view>
+            <template slot="value">
+              <view v-if="form.feedbackType" class="nowrap">{{ form.feedbackTypeNeme }}</view>
+              <view class="text-tip" v-else>请选择反馈类型</view>
+            </template>
+          </u-cell>
+          <u-cell :border="false" class="complain-cell" :isLink="false" size="large">
+            <view slot="title" style="width: 150rpx"> 联系电话 </view>
+            <view slot="value">
+              <u--input
+                v-model="form.createUserPhone"
+                type="number"
+                maxlength="11"
+                inputAlign="right"
+                placeholder="联系电话"
+                border="none"
+                confirmType="done"
+                suffixIcon="edit-pen"
+                suffixIconStyle="color:#86909C;font-size:44rpx;"
+              />
+            </view>
+          </u-cell>
+        </u-cell-group>
+        <u-cell-group class="bg-white u-m-t-24 u-p-t-30" :border="false">
+          <u-cell :border="false">
+            <view slot="title">
+              问题描述
+              <text class="text-error u-m-l-10">*</text>
+            </view>
+          </u-cell>
+          <view>
+            <view class="u-p-lr-20">
+              <u--textarea
+                v-model="form.feedbackContent"
+                placeholder="请描述你的问题或上传图片"
+                count
+                maxlength="300"
+                height="140"
+                style="background: #f7f8fa"
+                border="none"
+                confirmType="done"
+              />
+            </view>
+            <view class="u-m-tb-32 u-p-lr-16">
+              <upload-img
+                ref="uploadImgRef"
+                :limit="5"
+                :type="['image']"
+                :option="uploadImgValue"
+                @change="changeImg"
+              />
+            </view>
+          </view>
+        </u-cell-group>
+        <!-- 隐藏验证内容 -->
+        <view v-show="false">
+          <u-form-item prop="feedbackContent" labelWidth="0"></u-form-item>
+          <u-form-item prop="sericeType" labelWidth="0"></u-form-item>
+          <u-form-item prop="address" labelWidth="0"></u-form-item>
+        </view>
+      </u-form>
+
+      <view style="height: 280rpx"></view>
+      <view class="flex justify-center align-center bg-white u-p-40 footer">
+        <u-button
+          type="primary"
+          class="u-p-tb-20 jane-btn"
+          style="height: 88rpx"
+          @click="handleSubmit"
+          >提 交</u-button
+        >
+      </view>
+      <u-action-sheet
+        class="jane-model"
+        :actions="feedbackTypeList"
+        title="选择反馈类型"
+        :show="showBuild"
+        cancelText="取消"
+        @close="showBuild = false"
+        @select="selectBuild"
+      ></u-action-sheet>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      form: {
+        complaintAdviceId: '', //投诉建议ID
+        fileIdArr: [], //反馈文件id集合
+        createUserPhone: '', //联系电话
+        feedbackType: '', // 反馈类型
+        feedbackTypeNeme: '', //反馈类型 页面渲染
+        feedbackContent: '', // 反馈内容
+      },
+      rules: {
+        feedbackType: {
+          type: 'string',
+          required: true,
+          message: '请选择反馈类型',
+          trigger: ['change'],
+        },
+        feedbackContent: {
+          type: 'string',
+          required: true,
+          message: '请填写问题描述',
+          trigger: ['change', 'blur'],
+        },
+      },
+      showBuild: false,
+      feedbackTypeList: [],
+      uploadImgValue: {
+        imageList: [],
+        videoList: [],
+      },
+    };
+  },
+  onShow() {
+    this.handleGet();
+    const user = this.UserInfo;
+    if (user && user.mobile) {
+      this.form.createUserPhone = user.mobile;
+    }
+  },
+  methods: {
+    // 获取反馈类型
+    async handleGet() {
+      const data = await this.$API.SYS.getDictList('-130');
+      this.feedbackTypeList = data.map(item => {
+        return {
+          name: item.value,
+          key: item.key,
+        };
+      });
+    },
+    selectBuild(e) {
+      const { name, key } = e;
+      this.form.feedbackType = key;
+      this.form.feedbackTypeNeme = name;
+      this.showBuild = false;
+    },
+    // 选择图片
+    changeImg({ imageList = [] }) {
+      this.form.fileIdArr = imageList.map(item => item.sFid);
+    },
+    handleSubmit() {
+      this.$refs.uForm
+        .validate()
+        .then(res => {
+          if (this.form.feedbackType) {
+            this.$API.COMPLAIN_API.edit(this.form).then(res => {
+              uni.y.showToast('提交成功');
+              setTimeout(() => {
+                uni.redirectTo({
+                  url: '/pages/my/complain/index',
+                });
+              }, 2000);
+            });
+          } else {
+            uni.$u.toast('请选择反馈类型');
+          }
+        })
+        .catch(errors => {
+          if (errors && errors[0]) {
+            const msg = errors[0]['message'] || '';
+            uni.y.toast(msg);
+          }
+        });
+    },
+  },
+};
+</script>
+
+<style>
+.complain-cell {
+  .u-cell__body {
+    padding: 40rpx 32rpx 44rpx 32rpx;
+  }
+}
+</style>

+ 715 - 0
src/components/upload-img/upload-img.vue

@@ -0,0 +1,715 @@
+<template>
+  <view class="upload-page" v-if="show">
+    <template v-if="custom">
+      <slot name="top"></slot>
+      <view @tap="chooseVideoImage">
+        <slot></slot>
+      </view>
+      <slot name="bottom"></slot>
+    </template>
+    <view class="flex" v-else>
+      <view class="flex justify-center align-center upload" @tap="chooseVideoImage">
+        <!-- 自定义上传图片按钮样式 -->
+        <slot>
+          <view class="flex flex-direction justify-center align-center">
+            <u--image :src="uploadIcon" width="56rpx" height="56rpx" />
+            <view class="u-m-t-16 text-tip u-font-14" v-if="fileLen > 0"
+              >{{ fileLen }}/{{ limit }}</view
+            >
+            <view class="u-m-t-16 text-tip u-font-14" v-else>上传图片</view>
+          </view>
+        </slot>
+      </view>
+
+      <scroll-view scroll-x enable-flex class="navscroll u-m-l-20">
+        <!-- 图片 -->
+        <template v-for="(val, index) in imageList">
+          <view class="upload-item" :key="index">
+            <view class="icon-cuo" @tap="delect(index)">
+              <u-icon name="close" size="28rpx" color="white"></u-icon>
+            </view>
+            <image
+              class="img"
+              :src="val.url"
+              :data-src="val.url"
+              mode="aspectFill"
+              @tap="previewImage"
+            />
+          </view>
+        </template>
+
+        <!-- 视频 -->
+        <view class="upload-item" v-for="(val, index) in videoList" :key="index">
+          <view class="icon-cuo" @tap="delectVideo(index)">
+            <u-icon name="close" size="28rpx" color="white"></u-icon>
+          </view>
+          <video :src="val.url" class="video"></video>
+        </view>
+      </scroll-view>
+    </view>
+
+    <view v-for="(item, index) in tempFilePaths" :key="index" class="tempFile">
+      <canvas
+        :canvas-id="item.key"
+        :style="{
+          width: item.width ? `${item.width || 0}px` : '100%',
+          height: item.height ? `${item.height || 0}px` : '100%',
+        }"
+      ></canvas>
+    </view>
+  </view>
+</template>
+
+<script>
+import { UPLOAD_IMG_URL } from '@/common/api.js';
+export default {
+  props: {
+    // 回显数据
+    option: {
+      type: Object,
+      default: {
+        imageList: [], // 图片资源
+        videoList: [], // 视频资源
+      },
+    },
+    // 上传类型
+    type: {
+      type: Array,
+      default: () => ['image', 'video'], // 组件展示类型   image图片    video视频
+    },
+    // 最大允许上传个数
+    limit: {
+      type: Number,
+      default: 9,
+    },
+    // 上传图片大于4M进行压缩
+    maxSize: {
+      type: Number,
+      default: () => 1024 * 1024 * 4,
+    },
+    // 是否显示操作视图
+    isView: {
+      type: Boolean,
+      default: false,
+    },
+    // 是否压缩图片
+    isCompress: {
+      type: Boolean,
+      default: true,
+    },
+    // 是否自定义样式
+    custom: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      tempFilePaths: [],
+
+      show: true,
+      upload_url: UPLOAD_IMG_URL, // 上传地址
+
+      imageList: [], //图片
+      videoList: [], //视频存放
+      cameraIndex: 0,
+      cameraList: [
+        {
+          value: 'back',
+          name: '后置摄像头',
+          checked: 'true',
+        },
+        {
+          value: 'front',
+          name: '前置摄像头',
+        },
+      ],
+    };
+  },
+  watch: {
+    option: {
+      deep: true,
+      immediate: true,
+      handler(val) {
+        if (val.imageList !== undefined) {
+          this.imageList = val.imageList;
+        }
+        if (val.videoList !== undefined) {
+          this.videoList = val.videoList;
+        }
+      },
+    },
+  },
+  computed: {
+    fileLen() {
+      return this.imageList.length + this.videoList.length;
+    },
+    VideoOfImagesShow() {
+      let show = true;
+      if (this.fileLen >= this.limit) {
+        show = false;
+      }
+      return show;
+    },
+    uploadIcon() {
+      if (this.VideoOfImagesShow) {
+        return '/static/public/upload-icon.svg';
+      }
+      return '/static/public/upload-disabled.svg';
+    },
+    Token() {
+      return uni.getStorageSync(this.$store.STORE.TOKEN) || '';
+    },
+  },
+  methods: {
+    refersh(val) {
+      if (val.imageList !== undefined) {
+        this.imageList = val.imageList;
+      }
+      if (val.videoList !== undefined) {
+        this.videoList = val.videoList;
+      }
+      this.show = false;
+      this.$nextTick(() => {
+        this.show = true;
+      });
+    },
+    chooseVideoImage() {
+      // // 图片选满已在进行选择图片
+      if (this.fileLen >= this.limit) return;
+      if (this.type.length >= 2) {
+        uni.showActionSheet({
+          title: '选择上传类型',
+          itemList: ['图片', '视频'],
+          success: res => {
+            if (res.tapIndex == 0) {
+              this.chooseImages();
+            } else {
+              this.chooseVideo();
+            }
+          },
+        });
+      } else {
+        if (this.type.length == 1) {
+          // 只上传图片
+          if (this.type.includes('image')) {
+            this.chooseImages();
+          }
+          // 只上传视频
+          else if (this.type.includes('video')) {
+            this.chooseVideo();
+          }
+        }
+      }
+    },
+    // 上传图片
+    chooseImages() {
+      let _this = this;
+      let len = this.limit - this.fileLen; // 可选文件数量
+      uni.chooseImage({
+        count: len, //可以选择文件长度
+        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+        sourceType: ['album', 'camera'], //从相册选择
+        success: res => {
+          uni.showLoading({
+            title: '图片上传中',
+            mask: true,
+          });
+          res.tempFilePaths.forEach((filePath, index) => {
+            // 图片大小
+            const imgSize =
+              res.tempFiles[index] && res.tempFiles[index].size ? res.tempFiles[index].size : 0;
+
+            if (imgSize > this.maxSize && this.isCompress) {
+              console.log(
+                '图片大小 == ',
+                parseInt(imgSize / 1024) + 'KB',
+                parseInt(imgSize / 1024 / 1024) + 'M',
+              );
+              _this.compressImage(filePath, index);
+              // setTimeout(() => {
+              // 	uni.hideLoading();
+              // 	uni.showToast({
+              // 		title: '上传图片太大,不能超过2M',
+              // 		icon: 'none'
+              // 	});
+              // }, 1000);
+            } else {
+              _this.uploadimage(filePath, index);
+            }
+          });
+        },
+      });
+    },
+    // 选择视频
+    chooseVideo() {
+      let _this = this;
+      // 上传视频
+      uni.chooseVideo({
+        maxDuration: 60,
+        count: 1,
+        camera: _this.cameraList[_this.cameraIndex].value,
+        sourceType: ['album'],
+        compressed: false, //是否压缩所选的视频源文件,默认值为 true,需要压缩。
+        success: res => {
+          let filePath = res.tempFilePath;
+          // 大于10M压缩
+          console.log('视频压缩前大小---', parseInt(res.size / 1024 / 1024) + 'M');
+          if (res.size / 1024 > 1025 * 10 && this.isCompress) {
+            // _this.videoCompress(filePath);
+          } else {
+            _this.uploadVideo(filePath);
+          }
+        },
+      });
+    },
+
+    // 上传图片
+    uploadimage(filePath, index) {
+      console.log(filePath);
+      uni.hideLoading();
+      uni.showLoading({
+        title: '图片上传中',
+        mask: true,
+      });
+      let _this = this;
+      uni.uploadFile({
+        url: _this.upload_url,
+        method: 'POST',
+        name: 'file',
+        filePath: filePath,
+        header: {
+          token: this.Token,
+          Model: 'development',
+        },
+        success: res => {
+          const { data } = JSON.parse(res.data); //微信和头条支持
+          if (data) {
+            // console.log('uploadFile === ', data);
+            let obj = data || {};
+            if (obj.sFid) {
+              obj['id'] = obj.sFid;
+            }
+            if (obj.staticPath) {
+              obj['url'] = obj.staticPath;
+            }
+            _this.imageList.push(obj);
+            _this.changeFile();
+          } else {
+            uni.showToast({
+              title: '上传失败',
+              icon: 'none',
+            });
+          }
+        },
+        fail: () => {
+          setTimeout(() => {
+            uni.hideLoading();
+            uni.showToast({
+              title: '图片上传失败',
+              icon: 'none',
+            });
+          }, 1000);
+        },
+        // 接口调用结束的回调函数(调用成功、失败都会执行)
+        complete: () => {
+          if (index == _this.imageList.length - 1) {
+            setTimeout(() => {
+              uni.hideLoading();
+            }, 1000);
+          } else {
+            setTimeout(() => {
+              uni.hideLoading();
+            }, 1000 * _this.imageList.length);
+          }
+        },
+      });
+    },
+    // 上传视频
+    uploadVideo(filePath) {
+      uni.showLoading({
+        title: '视频上传中',
+        mask: true,
+      });
+      let _this = this;
+      uni.uploadFile({
+        url: _this.upload_url,
+        method: 'POST',
+        name: 'file',
+        filePath: filePath,
+        header: {
+          token: this.Token,
+          Model: 'development',
+        },
+        success: res => {
+          const { data } = JSON.parse(res.data); //微信和头条支持
+          let obj = data || {};
+          if (obj.sFid) {
+            obj['id'] = obj.sFid;
+          }
+          if (obj.staticPath) {
+            obj['url'] = obj.staticPath;
+          }
+          _this.videoList.push(obj);
+          _this.changeFile();
+        },
+        fail: () => {
+          setTimeout(() => {
+            uni.hideLoading();
+            uni.showToast({
+              title: '视频上传失败',
+              icon: 'none',
+            });
+          }, 1000);
+        },
+        // 接口调用结束的回调函数(调用成功、失败都会执行)
+        complete: () => {
+          setTimeout(() => {
+            uni.hideLoading();
+          }, 2000);
+        },
+      });
+    },
+    changeFile() {
+      this.$emit('change', {
+        videoList: this.videoList,
+        imageList: this.imageList,
+      });
+    },
+    previewImage: function (e) {
+      //预览图片
+      let current = e.target.dataset.src;
+      console.log('current == ', current);
+      uni.previewImage({
+        current: current,
+        urls: this.imageList.map(v => v.url),
+      });
+    },
+    delect(index) {
+      uni.showModal({
+        title: '提示',
+        content: '是否要删除此图片?',
+        success: res => {
+          if (res.confirm) {
+            this.imageList.splice(index, 1);
+            this.changeFile();
+          }
+        },
+      });
+    },
+    // base64转Blob
+    base64ToBlob(base64) {
+      var arr = base64.split(','),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]),
+        n = bstr.length,
+        u8arr = new Uint8Array(n);
+      while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], {
+        type: mime,
+      });
+    },
+    // 图片压缩
+    compressImage(src, index) {
+      let that = this;
+      uni.showLoading({
+        title: '图片压缩中',
+      });
+      var img = new Image(); //创建Image对象生成一个<img>标签
+      img.src = src; //将图片路径赋给<img>标签的src
+      img.onload = () => {
+        //onload在图片加载成功后触发,在onload中完成压缩功能
+        var h = img.height / 2; // 获取原本图片的宽高
+        var w = img.width / 2; //默认按比例压缩,根据需求修改
+        var canvas = document.createElement('canvas'); //创建画布
+        var ctx = canvas.getContext('2d'); //设置为2d效果
+        var width = document.createAttribute('width'); //创建属性节点
+        width.nodeValue = w; //设置属性值
+        var height = document.createAttribute('height');
+        height.nodeValue = h;
+        canvas.setAttributeNode(width); //设置画布宽高
+        canvas.setAttributeNode(height);
+        ctx.drawImage(img, 0, 0, w, h); //将图片贴到画布上
+        //img:图片 0,0:粘贴的位置 w,h:粘贴图片的大小
+        var base64 = canvas.toDataURL('image/png', 1);
+        // //'image/png':压缩返回图片的类型 scale:图片质量
+        // //如果要base64的流,可以直接将结果返回了
+        // canvas = null; //清除画布
+        // var blob = this.base64ToBlob(base64); //需要二进制流调用该方法拿到
+        // let blobUrl = window.URL.createObjectURL(blob); //blob地址
+        // console.log("blobUrl == ", blobUrl);
+        // console.log("base64 == ", base64);
+        uni.getFileInfo({
+          filePath: base64,
+          success(res) {
+            console.log('getFileInfo == ', res);
+            const imgSize = res.size / 1024;
+            console.log(
+              '压缩后大小---',
+              parseInt(imgSize / 1024) + 'KB',
+              parseInt(imgSize / 1024 / 1024) + 'M',
+            );
+            // 压缩后的大小仍大于所设大小继续压缩
+            if (imgSize > this.maxSize) {
+              // 图片太大,继续压缩
+              console.log('----- 图片太大,继续压缩  ------');
+              that.compressImage(base64, index);
+            } else {
+              that.uploadimage(base64, index);
+            }
+          },
+        });
+      };
+      // uni.getImageInfo({
+      // 	src,
+      // 	success(res) {
+      // 		let canvasWidth = res.width; //图片原始长宽
+      // 		let canvasHeight = res.height;
+
+      // 		let scale1 = 2;
+      // 		let scale2 = 2;
+      // 		if (res.width > res.height) {
+      // 			while (canvasWidth > 1024) {
+      // 				canvasWidth = Math.trunc(res.width / scale1);
+      // 				scale1++;
+      // 			}
+      // 			while (canvasHeight > 750) {
+      // 				canvasHeight = Math.trunc(res.height / scale2);
+      // 				scale2++;
+      // 			}
+      // 		} else if (res.width == res.height) {
+      // 			while (canvasWidth > 750) {
+      // 				canvasWidth = Math.trunc(res.width / scale1);
+      // 				canvasHeight = Math.trunc(res.height / scale1);
+      // 			}
+      // 		} else {
+      // 			while (canvasWidth > 750) {
+      // 				canvasWidth = Math.trunc(res.width / scale1);
+      // 				scale1++;
+      // 			}
+      // 			while (canvasHeight > 1024) {
+      // 				canvasHeight = Math.trunc(res.height / scale2);
+      // 				scale2++;
+      // 			}
+      // 		}
+      // 		let cId = `myCanvas_${index + 1}`;
+      // 		let info = that.tempFilePaths.find((v) => v.key == index);
+      // 		if (info) {
+      // 			cId = info.key;
+      // 		} else {
+      // 			that.tempFilePaths.push({
+      // 				key: cId,
+      // 				url: src,
+      // 				width: canvasWidth,
+      // 				height: canvasHeight
+      // 			});
+      // 		}
+      // 		console.log('that.tempFilePaths == ', that.tempFilePaths);
+
+      // 		let ctx = uni.createCanvasContext(cId, that);
+      // 		console.log('ctx == ', ctx);
+      // 		// ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight);
+      // 		ctx.drawImage(src, 0, 0, canvasWidth, canvasHeight);
+
+      // 		setTimeout(() => {
+      // 			ctx.draw(
+      // 				false,
+      // 				setTimeout(() => {
+      // 					console.log('cId == ', cId);
+      // 					uni.canvasToTempFilePath({
+      // 							canvasId: cId,
+      // 							fileType: 'jpg',
+      // 							success: function(res) {
+      // 								// res图片临时路径
+      // 								uni.getFileInfo({
+      // 									filePath: res
+      // 										.tempFilePath,
+      // 									success(ress) {
+      // 										// console.log(ress)    // 图片大小
+      // 										const imgSize =
+      // 											ress.size /
+      // 											1024;
+      // 										console.log(
+      // 											'压缩后大小---',
+      // 											parseInt(
+      // 												imgSize /
+      // 												1024) +
+      // 											'KB',
+      // 											parseInt(
+      // 												imgSize /
+      // 												1024 /
+      // 												1024) +
+      // 											'M');
+      // 										// 压缩后的大小仍大于所设大小继续压缩
+      // 										if (imgSize > this
+      // 											.maxSize) {
+      // 											// 图片太大,继续压缩
+      // 											console.log(
+      // 												'----- 图片太大,继续压缩  ------'
+      // 											);
+      // 											that.compressImage(
+      // 												res
+      // 												.tempFilePath,
+      // 												index);
+      // 										} else {
+      // 											uni.hideLoading();
+      // 											that.uploadimage(
+      // 												res
+      // 												.tempFilePath
+      // 											);
+      // 										}
+      // 									}
+      // 								});
+      // 							},
+      // 							fail: function(res) {
+      // 								console.log('图片压缩失败 == ', res
+      // 									.errMsg);
+      // 								uni.hideLoading();
+      // 								uni.showToast({
+      // 										title: '图片压缩失败',
+      // 										icon: 'none'
+      // 									},
+      // 									2000
+      // 								);
+      // 							}
+      // 						},
+      // 						that
+      // 					); // 这里是新增的this,只有在微信小程序中需要加入,不然会报错
+      // 				}, 1000)
+      // 			);
+      // 			//留一定的时间绘制canvas
+      // 		}, 1000);
+      // 	},
+      // 	fail(err) {
+      // 		console.log(err.errMsg);
+      // 		uni.hideLoading();
+      // 		uni.showToast({
+      // 				title: '图片压缩失败!',
+      // 				icon: 'none'
+      // 			},
+      // 			2000
+      // 		);
+      // 	}
+      // });
+    },
+    delectVideo(index) {
+      uni.showModal({
+        title: '提示',
+        content: '是否要删除此视频?',
+        success: res => {
+          if (res.confirm) {
+            this.videoList.splice(index, 1);
+            this.changeFile();
+          }
+        },
+      });
+    },
+    // 视频压缩 微信开发者工具需要ffepeg 在D盘
+    videoCompress(tempFilePath) {
+      uni.showLoading({
+        title: '视频压缩中',
+      });
+      let that = this;
+      uni.compressVideo(
+        {
+          src: tempFilePath,
+          quality: 'high', //'low':低,'medium':中,'high':高
+          success: function (res) {
+            // 压缩后的大小 大于10MB,继续压缩
+            console.log('压缩后大小---', res.size / 1024 / 1024 + 'M');
+            if (res.size / 1024 > 1025 * 10) {
+              console.log('------ 视频太大,再次压缩 ----- ');
+              that.videoCompress(res.tempFilePath);
+            } else {
+              that.uploadVideo(res.tempFilePath);
+            }
+          },
+          fail: function (err) {
+            console.log(err);
+            uni.showToast(
+              {
+                title: '视频压缩失败',
+                icon: 'none',
+              },
+              2000,
+            );
+          },
+          complete: () => {
+            setTimeout(() => {
+              uni.hideLoading();
+            }, 2000);
+          },
+        },
+        this,
+      );
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.upload-page {
+  .upload {
+    width: 160rpx !important;
+    height: 160rpx !important;
+    min-width: 160rpx !important;
+    background: #f7f8fa;
+    border: 1px dashed #e5e6eb;
+    border-radius: 10px;
+  }
+
+  .navscroll {
+    white-space: nowrap; // 必须要这个属性,否者不能出现横线滚动
+    height: 160rpx;
+    width: calc(100vw - 110px);
+    display: flex;
+  }
+
+  .upload-item {
+    width: 160rpx;
+    min-width: 160rpx !important;
+    height: 160rpx;
+    border: 1px solid #eee;
+    border-radius: 10px;
+    position: relative;
+    margin-right: 20rpx;
+    background: #f7f8fa;
+    display: inline-block;
+
+    .icon-cuo {
+      height: 36rpx;
+      width: 36rpx;
+      position: absolute;
+      top: 0;
+      right: 0;
+      z-index: 999;
+      background: rgba(0, 0, 0, 0.8);
+      border-radius: 4px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+
+    .video {
+      border-radius: 10px;
+    }
+
+    .video,
+    .img {
+      width: 100%;
+      height: 100%;
+      border-radius: 10px;
+    }
+  }
+
+  .tempFile {
+    visibility: hidden;
+    position: absolute;
+    z-index: -1;
+    left: -10000rpx;
+    top: -10000rpx;
+  }
+}
+</style>

+ 1 - 0
src/design/common.css

@@ -6,6 +6,7 @@
   display: flex;
 }
 
+/* 用于两个元素居中 */
 .direction {
   display: flex;
   flex-direction: column;

+ 13 - 7
src/main.js

@@ -1,18 +1,24 @@
 import Vue from 'vue';
 import App from './App';
-import uView from 'uview-ui';
 import store from '@/store';
-import cache from '@/mixin/cache';
-// import empty from '@/components/empty';
-// import tabbar from '@/components/tabbar';
-import { router, RouterMount } from '@/router'; //路径换成自己的
 App.mpType = 'app';
 
+// global mixin
+import GlobalMixin from '@/mixin/index.js';
+Vue.mixin(GlobalMixin);
+
+// router
+import { router, RouterMount } from '@/router';
 Vue.use(router);
+
+// uView
+import uView from 'uview-ui';
 Vue.use(uView);
+
+// cache
+import cache from '@/mixin/cache';
 Vue.mixin(cache);
-// Vue.component('empty', empty);
-// Vue.component('tabbar', tabbar);
+
 Vue.config.productionTip = false;
 
 App.mpType = 'app';

+ 38 - 0
src/mixin/image.js

@@ -0,0 +1,38 @@
+/**
+ ****--@date 2024-06-07 09:45:06
+ ****--@author yizhiyang
+ ****--@description 图片预览
+ **/
+
+module.exports = {
+  data() {
+    return {};
+  },
+  computed: {},
+  created() {},
+  methods: {
+    // 单张预览logourl图片地址
+    previewSingleImg(logourl) {
+      let imgsArray = [];
+      imgsArray[0] = logourl;
+      uni.previewImage({
+        current: 0,
+        urls: imgsArray,
+      });
+    },
+    // 预览图片多张imgUrlListt图片数组,index索引
+    previewImgArr(index, imgUrlList) {
+      let imgsArray = [];
+      for (let i = 0; i < imgUrlList.length; i++) {
+        let urlPath = imgUrlList[i].staticPath || imgUrlList[i];
+        imgsArray.push(urlPath);
+      }
+      uni.previewImage({
+        current: index,
+        urls: imgsArray,
+        indicator: 'number',
+        loop: true,
+      });
+    },
+  },
+};

+ 14 - 1
src/mixin/index.js

@@ -1,6 +1,19 @@
+/**
+ ****--@date 2024-06-07 09:45:52
+ ****--@author yizhiyang
+ ****--@description 全局mixin
+ **/
+
+import { mapGetters } from 'vuex';
+
 const globalMixins = {
   data() {
-    return {};
+    return {
+      str: '--',
+    };
+  },
+  computed: {
+    ...mapGetters(['userId', 'gender', 'avatar', 'nickname', 'invitationCode', 'location']),
   },
   methods: {},
 };

+ 47 - 58
src/mixin/list.js

@@ -1,46 +1,62 @@
-//别动我代码: list mixin
+/**
+ ****--@date 2024-06-07 09:47:03
+ ****--@author yizhiyang
+ ****--@description  list mixin 主要处理上拉加载和分页
+ **/
 module.exports = {
-  onShow() {
-    // console.log('list mixin show');
-  },
-  onReady() {},
-  onReachBottom() {
-    this.loadData();
-  },
   data() {
     return {
       total: 0,
       listData: [],
-      loadmoreStatus: 'loadmore', // loadmore loading nomore
+      // loadmore(加载前) loading(加载中) nomore(没有更多数据)
+      loadmoreStatus: 'loadmore',
       page: {
-        page: 1,
-        size: 10,
+        pageNum: 1,
+        pageSize: 10,
       },
       queryData: {},
     };
   },
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.loadData();
+  },
+  // 触底刷新
+  onReachBottom() {
+    let { pageNum, pageSize } = this.page;
+    if (pageNum * pageSize > this.total) return;
+    this.page.pageNum++;
+    this.initDataList(this.queryData, true);
+  },
+
   methods: {
     // 分页初始化数据isUp是否为上拉加载,默认false
-    initDataList(searchData = {}, isUp = false) {
+    initDataList(searchData = {}, isUp = true) {
       this.isListLoading = true;
+
       uni.showLoading({
         title: '加载中',
         mask: true,
       });
-      this.queryData = searchData;
-      if (!isUp) this.page.page = 1;
-      this.listApiName({
-        search: searchData,
-        page: this.page,
-      })
+
+      /* 参数的处理 */
+      this.queryData = Object.assign(
+        {},
+        { ...searchData },
+        {
+          paging: `${this.page.pageNum},${this.page.pageSize}`,
+        },
+      );
+      if (!isUp) this.page.pageNum = 1;
+
+      this.listApiName({ ...this.queryData })
         .then(res => {
           if (isUp) {
-            this.listData = this.listData.concat(res.data);
+            this.listData = this.listData.concat(res.data.records);
           } else {
-            this.listData = res.data;
-            // this.loadmoreStatus = 'nomore'
+            this.listData = res.data.records;
           }
-          this.total = res.page.total;
+          this.total = res.data.total;
 
           if (this.listData.length < this.total) {
             this.loadmoreStatus = 'loadmore';
@@ -48,9 +64,6 @@ module.exports = {
             this.loadmoreStatus = 'nomore';
           }
         })
-        .catch(err => {
-          throw err;
-        })
         .finally(() => {
           this.isListLoading = false;
           setTimeout(() => {
@@ -58,40 +71,16 @@ module.exports = {
           }, 1000);
         });
     },
-    //加载列表,上滑加载
+
     loadData() {
-      this.loadmoreStatus = 'loading';
-      if (this.listData.length < this.total) {
-        this.page.page++;
-        this.initDataList(this.queryData, true);
-      } else {
-        this.page.page = 1;
-        this.loadmoreStatus = 'nomore';
-      }
-    },
-    getListData(apiName, reqData, isLoadmore = false, isSearch = false) {
-      uni.y.showLoading('加载中');
-      this.loadmoreStatus = 'loading'; // 加载中
-      this[apiName](reqData)
-        .then(res => {
-          const listData = res.data || {};
-          const listTotal = res.page.total || 0;
-          if (isLoadmore) {
-            this.listData = this.listData.concat(listData);
-          } else {
-            this.listData = listData;
-          }
-          this.listTotal = listTotal;
-          if (this.listData.length === listTotal) {
-            this.loadmoreStatus = 'nomore';
-          } else {
-            this.loadmoreStatus = 'loadmore';
-          }
-          uni.hideLoading(1000);
-        })
-        .catch(() => {
-          uni.hideLoading(2000);
-        });
+      this.page.pageNum = 1;
+      this.initList = [];
+      this.initDataList(this.queryData);
+      this.loadmoreStatus = 'nomore';
+
+      setTimeout(function () {
+        uni.stopPullDownRefresh();
+      }, 2000);
     },
   },
 };

+ 5 - 11
src/pages.json

@@ -68,23 +68,17 @@
       "root": "pagesHome",
       "pages": [
         {
-          "path": "homeSearch",
+          "path": "homeSearch/index",
           "style": {
             "navigationBarTitleText": "商品搜索"
           }
         },
         {
-          "path": "home/popularRecommend",
+          "path": "popularNearby/index",
           "style": {
-            "navigationBarTitleText": "热门推荐",
-            "onReachBottomDistance": 0
-          }
-        },
-        {
-          "path": "home/nearbyBusiness",
-          "style": {
-            "navigationBarTitleText": "附近商家",
-            "onReachBottomDistance": 0
+            "navigationStyle": "custom",
+            "enablePullDownRefresh": true,
+            "onReachBottomDistance": 50
           }
         },
         {

+ 257 - 236
src/pages/tabbar/community.vue

@@ -2,22 +2,30 @@
   <view class="container">
     <u-sticky bgColor="#F8F8F8">
       <view class="top"> </view>
-      <u-tabs :list="list1" lineWidth="30" lineColor="#f56c6c" @change='tabChange' :activeStyle="{
-			            color: '#303133',
-			            fontWeight: 'bold',
-			            transform: 'scale(1.05)',
-						fontSize:'40rpx',
-						fontStyle: 'italic'
-			        }" :inactiveStyle="{
-			            color: '#606266',
-			            transform: 'scale(1)'
-			        }" itemStyle=" padding-left: 15px; padding-right: 15px; height: 34px;">
+      <u-tabs
+        :list="list1"
+        lineWidth="30"
+        lineColor="#f56c6c"
+        @change="tabChange"
+        :activeStyle="{
+          color: '#303133',
+          fontWeight: 'bold',
+          transform: 'scale(1.05)',
+          fontSize: '40rpx',
+          fontStyle: 'italic',
+        }"
+        :inactiveStyle="{
+          color: '#606266',
+          transform: 'scale(1)',
+        }"
+        itemStyle=" padding-left: 15px; padding-right: 15px; height: 34px;"
+      >
       </u-tabs>
       <view class="top-bottom"> </view>
     </u-sticky>
 
     <view class="center-box">
-      <view class="item-box" v-for="(item,index) of initList" :key='index'>
+      <view class="item-box" v-for="(item, index) of initList" :key="index">
         <view class="item-top">
           <view class="top-left">
             <u-avatar :src="item.userDTO.avatar" size="45" />
@@ -34,301 +42,314 @@
         <view class="item-center">
           <view class="center-text"> {{ item.textContent }} </view>
           <view class="center-img-box">
-            <image v-for="itm of item.resourceVos" :key="itm" class="center-img" :src="itm.resourceKey" @click='reviewImg(itm)'>
+            <image
+              v-for="itm of item.resourceVos"
+              :key="itm"
+              class="center-img"
+              :src="itm.resourceKey"
+              @click="reviewImg(itm)"
+            >
             </image>
           </view>
         </view>
         <view class="item-bottom">
           <view class="bottom-item">
-            <u-icon :name="item.clickStatus == 0 ? 'heart' : 'heart-fill'" :size='iconSize'
-              @click='handlerPraise(item)'></u-icon>
+            <u-icon
+              :name="item.clickStatus == 0 ? 'heart' : 'heart-fill'"
+              :size="iconSize"
+              @click="handlerPraise(item)"
+            ></u-icon>
             <view class="iconNUm">{{ item.goodNum }}</view>
           </view>
-          <view class="bottom-item" @click='handlerRequireComment(item)'>
-            <u-icon name="more-circle" :size='iconSize'></u-icon>
+          <view class="bottom-item" @click="handlerRequireComment(item)">
+            <u-icon name="more-circle" :size="iconSize"></u-icon>
             <view class="iconNUm">{{ item.commentNum }}</view>
           </view>
         </view>
-        <u-line margin='-20rpx 0' v-if="index!=initList.length-1"></u-line>
+        <u-line margin="-20rpx 0" v-if="index != initList.length - 1"></u-line>
       </view>
     </view>
 
-    <!-- <empty v-if="initList.length == 0" /> -->
-
     <view class="flex-box">
       <view class="flex" @click="handlerToPublish">
         <view class="flex-icon">
-          <u-icon name="edit-pen" color='#fff' size='26'></u-icon>
+          <u-icon name="edit-pen" color="#fff" size="26"></u-icon>
         </view>
         <view class=""> 发布 </view>
       </view>
     </view>
 
-   <u-popup :show="communityShow" @close="communityShow = false" mode='bottom' overlayOpacity='0.1' round="20">
-     <view class="pop-box">
+    <u-popup
+      :show="communityShow"
+      @close="communityShow = false"
+      mode="bottom"
+      overlayOpacity="0.1"
+      round="20"
+    >
+      <view class="pop-box">
         <!-- <communityPop :dynamicId='dynamicId' :dynamicUserId='dynamicUserId' @uploadComment='uploadComment' /> -->
       </view>
     </u-popup>
-
   </view>
 </template>
 
 <script>
-  import { clientContentList, addEvaulateRecords } from '@/api/client/community.js';
-  import communityPop from "./components/communityPop.vue"
-  import { GetDateToNewData } from "@/utils/tools.js"
-  export default {
-    components: { communityPop },
-    data() {
-      return {
-        communityShow: false,
-        list1: [{
-            name: '最新',
-            type: 'LATEST',
-          },
-          {
-            name: '关注',
-            type: 'ATTENTION',
-          },
-          {
-            name: '最热',
-            type: 'HOTTEST',
-          }
-        ],
-        iconSize: 24,
-        duration: 700,
-        params: {
-          pageNum: 1,
-          pageSize: 10,
+import { clientContentList, addEvaulateRecords } from '@/api/client/community.js';
+import communityPop from './components/communityPop.vue';
+import { GetDateToNewData } from '@/utils/tools.js';
+export default {
+  components: { communityPop },
+  data() {
+    return {
+      communityShow: false,
+      list1: [
+        {
+          name: '最新',
           type: 'LATEST',
-          keyWord: '',
         },
-        initList: [], // 初始化列表
-        userId: '',
-        dynamicId: 0,
-        dynamicUserId: 0,
-        total:0
+        {
+          name: '关注',
+          type: 'ATTENTION',
+        },
+        {
+          name: '最热',
+          type: 'HOTTEST',
+        },
+      ],
+      iconSize: 24,
+      duration: 700,
+      params: {
+        pageNum: 1,
+        pageSize: 10,
+        type: 'LATEST',
+        keyWord: '',
+      },
+      initList: [], // 初始化列表
+      userId: '',
+      dynamicId: 0,
+      dynamicUserId: 0,
+      total: 0,
+    };
+  },
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.params.pageNum = 1;
+    this.initList = [];
+    this.handlerInitList();
+    setTimeout(function () {
+      uni.stopPullDownRefresh();
+      this.uToast('刷新成功');
+    }, 1000);
+  },
+  // 触底刷新
+  onReachBottom() {
+    let { pageNum, pageSize } = this.params;
+    if (pageNum * pageSize > this.total) return this.uToast('没有更多啦');
+    this.params.pageNum++;
+    this.handlerInitList();
+  },
+  onShow() {
+    this.handlerInitList();
+  },
+  watch: {
+    communityShow(newValue) {
+      if (!newValue) {
+        this.dynamicId = null;
+        this.dynamicUserId = null;
       }
     },
-    // 下拉刷新
-    onPullDownRefresh() {
-      this.params.pageNum = 1
-      this.initList = []
-      this.handlerInitList()
-    	setTimeout(function () {
-    		uni.stopPullDownRefresh();
-        this.uToast('刷新成功')
-    	}, 1000);
+  },
+  mounted() {
+    this.userId = this.$store.state.user.userId;
+  },
+  methods: {
+    handlerInitList() {
+      clientContentList(this.params).then(res => {
+        res.data.records.map(rs => {
+          let time = GetDateToNewData(rs.createTime);
+          this.$set(rs, 'distanceTime', time);
+        });
+        this.total = res.data.total;
+        this.initList = [...this.initList, ...res.data.records];
+      });
     },
-    // 触底刷新
-    onReachBottom() {
-      let { pageNum , pageSize } = this.params
-      if( pageNum * pageSize > this.total ) return this.uToast('没有更多啦')
-      this.params.pageNum ++
-      this.handlerInitList()
+    // 切换顶部tabbar
+    tabChange(e) {
+      this.params.type = e.type;
+      this.params.pageNum = 1;
+      this.initList = [];
+      this.handlerInitList();
     },
-    onShow() {
-      this.handlerInitList()
+    // 点击发布按钮
+    handlerToPublish() {
+      uni.navigateTo({
+        url: '/pagesCustomer/communityPostReview',
+      });
     },
-    watch: {
-      communityShow(newValue) {
-        if (!newValue) {
-          this.dynamicId = null
-          this.dynamicUserId = null
+    // 点赞按钮
+    handlerPraise(item) {
+      let params = {
+        dynamicStatusType: 'GOOD', // 操作类型:1-点赞;2-踩 允许值: GOOD, BAD
+        recordType: 'DYNAMIC', // 内容类型:1-动态;2-评论/回复 允许值: DYNAMIC, COMMENT, USER
+        actionType: item.clickStatus == 0 ? 'ADD' : 'CANCEL', // 点击类型:1-点赞/踩;2-取消赞/取消踩   允许值: ADD, CANCEL
+        contentId: item.id,
+        targetUserId: item.userId,
+      };
+      addEvaulateRecords(params).then(res => {
+        if (res.code === 'OK') {
+          uni.showToast({
+            title: '关注成功',
+            icon: 'none',
+          });
+          this.handlerInitList();
+        } else {
+          uni.showToast({
+            title: res.msg,
+            icon: 'none',
+          });
+          return;
         }
-      }
+      });
     },
-    mounted() {
-      this.userId = this.$store.state.user.userId
+    // 查询动态评论
+    handlerRequireComment(item) {
+      this.dynamicId = item.id;
+      this.dynamicUserId = item.userId;
+      this.communityShow = true;
     },
-    methods: {
-      handlerInitList() {
-        clientContentList(this.params).then(res => {
-          res.data.records.map(rs => {
-            let time = GetDateToNewData(rs.createTime)
-            this.$set(rs, 'distanceTime', time)
-          })
-          this.total = res.data.total
-          this.initList = [...this.initList,...res.data.records]
-        })
-      },
-      // 切换顶部tabbar
-      tabChange(e) {
-        this.params.type = e.type
-        this.params.pageNum = 1
-        this.initList = []
-        this.handlerInitList()
-      },
-      // 点击发布按钮
-      handlerToPublish() {
-        uni.navigateTo({
-          url: "/pagesCustomer/communityPostReview"
-        })
-      },
-      // 点赞按钮
-      handlerPraise(item) {
-        let params = {
-          dynamicStatusType: 'GOOD', // 操作类型:1-点赞;2-踩 允许值: GOOD, BAD
-          recordType: 'DYNAMIC', // 内容类型:1-动态;2-评论/回复 允许值: DYNAMIC, COMMENT, USER
-          actionType: item.clickStatus == 0 ? 'ADD' : 'CANCEL', // 点击类型:1-点赞/踩;2-取消赞/取消踩   允许值: ADD, CANCEL
-          contentId: item.id,
-          targetUserId: item.userId
-        }
-        addEvaulateRecords(params).then(res => {
-          if (res.code === 'OK') {
-            uni.showToast({
-              title: '关注成功',
-              icon: 'none'
-            })
-            this.handlerInitList()
-          } else {
-            uni.showToast({
-              title: res.msg,
-              icon: 'none'
-            })
-            return
-          }
-        })
-      },
-      // 查询动态评论
-      handlerRequireComment(item) {
-        this.dynamicId = item.id
-        this.dynamicUserId = item.userId
-        this.communityShow = true
-      },
-      // 动态发布评论后 更新list
-      uploadComment() {
-        this.handlerInitList()
-      },
-      // 预览图片
-      reviewImg(itm) {
-        uni.previewImage({
-          urls: [itm.resourceKey]
-        })
-      }
-    }
-  }
+    // 动态发布评论后 更新list
+    uploadComment() {
+      this.handlerInitList();
+    },
+    // 预览图片
+    reviewImg(itm) {
+      uni.previewImage({
+        urls: [itm.resourceKey],
+      });
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  .container {
-    background-color: #F8F8F8;
-    min-height: calc(100vh);
-    .top {
-      height: 100rpx;
-    }
+.container {
+  background-color: #f8f8f8;
+  min-height: calc(100vh);
+  .top {
+    height: 100rpx;
+  }
 
-    .top-bottom {
-      height: 20rpx;
-    }
+  .top-bottom {
+    height: 20rpx;
+  }
 
-    .center-box {
-      font-size: 28rpx;
-      .item-box {
-        padding: 20rpx 20rpx 30rpx 20rpx;
-        background-color: #fff;
+  .center-box {
+    font-size: 28rpx;
+    .item-box {
+      padding: 20rpx 20rpx 30rpx 20rpx;
+      background-color: #fff;
 
-        .item-top {
-          display: flex;
-          align-items: center;
+      .item-top {
+        display: flex;
+        align-items: center;
 
-          .top-left {
-            .img {
-              width: 90rpx;
-              height: 90rpx;
-              border-radius: 50%;
-            }
+        .top-left {
+          .img {
+            width: 90rpx;
+            height: 90rpx;
+            border-radius: 50%;
           }
+        }
 
-          .top-right {
-            margin-left: 20rpx;
-
-            .right-title {
-              font-weight: bold;
-              font-size: 34rpx;
-            }
+        .top-right {
+          margin-left: 20rpx;
 
-            .right-address {
-              display: flex;
+          .right-title {
+            font-weight: bold;
+            font-size: 34rpx;
+          }
 
-              .marRight-20 {
-                margin-right: 20rpx;
-              }
+          .right-address {
+            display: flex;
 
-              color: #959595;
-              // font-style: italic;
-              // font-weight: bold;
-              font-size: 24rpx;
+            .marRight-20 {
+              margin-right: 20rpx;
             }
+
+            color: #959595;
+            // font-style: italic;
+            // font-weight: bold;
+            font-size: 24rpx;
           }
         }
+      }
 
-        .item-center {
-          margin-left: 100rpx;
-          margin-top: 20rpx;
+      .item-center {
+        margin-left: 100rpx;
+        margin-top: 20rpx;
 
-          .center-text {
-            font-size: 32rpx;
-          }
+        .center-text {
+          font-size: 32rpx;
+        }
 
-          .center-img-box {
-            margin-top: 20rpx;
-            display: grid;
-            grid-template-columns: 32% 32% 32%;
-            gap: 4% 1%;
-            margin-bottom: 10rpx;
+        .center-img-box {
+          margin-top: 20rpx;
+          display: grid;
+          grid-template-columns: 32% 32% 32%;
+          gap: 4% 1%;
+          margin-bottom: 10rpx;
 
-            .center-img {
-              width: 186rpx;
-              height: 186rpx;
-              border-radius: 6rpx;
-            }
+          .center-img {
+            width: 186rpx;
+            height: 186rpx;
+            border-radius: 6rpx;
           }
         }
+      }
 
-        .item-bottom {
-          display: flex;
-          // margin-top: 10rpx;
-          margin-bottom: 56rpx;
-          margin-right: 8rpx;
-          justify-content: flex-end;
+      .item-bottom {
+        display: flex;
+        // margin-top: 10rpx;
+        margin-bottom: 56rpx;
+        margin-right: 8rpx;
+        justify-content: flex-end;
 
-          .bottom-item {
-            display: flex;
-            align-items: center;
-            min-width: 100rpx;
+        .bottom-item {
+          display: flex;
+          align-items: center;
+          min-width: 100rpx;
 
-            .iconNUm {
-              margin-left: 7rpx;
-            }
+          .iconNUm {
+            margin-left: 7rpx;
           }
         }
       }
     }
+  }
 
-    .flex-box {
-      width: 120rpx;
-      height: 120rpx;
-      border-radius: 50%;
-      background-color: #000;
-      position: fixed;
-      bottom: 15%;
-      right: 5%;
-      box-shadow: 0 5rpx 15rpx 0 rgba(0, 0, 0, 0.5);
-      padding: 10rpx;
-      box-sizing: border-box;
-      text-align: center;
+  .flex-box {
+    width: 120rpx;
+    height: 120rpx;
+    border-radius: 50%;
+    background-color: #000;
+    position: fixed;
+    bottom: 15%;
+    right: 5%;
+    box-shadow: 0 5rpx 15rpx 0 rgba(0, 0, 0, 0.5);
+    padding: 10rpx;
+    box-sizing: border-box;
+    text-align: center;
 
-      .flex {
-        color: #fff;
-        font-size: 26rpx;
-        font-weight: bold;
+    .flex {
+      color: #fff;
+      font-size: 26rpx;
+      font-weight: bold;
 
-        .flex-icon {
-          display: flex;
-          justify-content: center;
-        }
+      .flex-icon {
+        display: flex;
+        justify-content: center;
       }
     }
   }
+}
 </style>

+ 6 - 8
src/pages/tabbar/components/communityPop.vue

@@ -35,8 +35,6 @@
       </view>
     </view>
 
-    <!-- <empty v-if="total == 0" /> -->
-
     <view class="bottom-box">
       <view class="bottom-item">
         <view class="item-left">
@@ -60,7 +58,7 @@
 import { addClientComment, clientCommentList } from '@/api/client/message.js';
 import { addEvaulateRecords } from '@/api/client/community.js';
 // import empty from '@/components/empty/index.vue';
-import { GetDateToNewData } from "@/utils/tools.js"
+import { GetDateToNewData } from '@/utils/tools.js';
 export default {
   // components: { empty },
   data() {
@@ -87,10 +85,10 @@ export default {
         userId: this.dynamicUserId,
       };
       clientCommentList(params).then(res => {
-		  res.data.records.map(rs=>{
-			  let time = GetDateToNewData(rs.createTime)
-			  this.$set(rs,'distanceTime',time)
-		  })
+        res.data.records.map(rs => {
+          let time = GetDateToNewData(rs.createTime);
+          this.$set(rs, 'distanceTime', time);
+        });
         this.init_list = res.data.records;
         this.total = res.data.total;
       });
@@ -99,7 +97,7 @@ export default {
     handlerPopPublishBtn() {
       let params = {
         dynamicId: this.dynamicId,
-        targetUserId:this.dynamicUserId,
+        targetUserId: this.dynamicUserId,
         parentId: 0,
         content: this.content,
         status: 0,

+ 3 - 6
src/pages/tabbar/home copy.vue

@@ -2,7 +2,7 @@
   <view class="container">
     <view class="container-top-box">
       <view class="top-title">
-       <view class="address" @click.stop="manualGetLocation">
+        <view class="address" @click.stop="manualGetLocation">
           <span>{{ nowAddress }}</span>
           <u-icon name="arrow-down-fill" color="#333333" size="16"></u-icon>
         </view>
@@ -14,7 +14,7 @@
           placeholder="请输入搜索内容"
           :showAction="false"
           v-model="keyword"
-          @click="$Router.push('/pagesHome/homeSearch')"
+          @click="$Router.push('/pagesHome/homeSearch/index')"
           bgColor="#fff"
           :disabled="true"
         />
@@ -156,10 +156,8 @@ export default {
     },
   },
   onShow() {
-
     // 如果 invitationCode 存在且不等于特殊值时执行代码
     if (this.invitationCode) {
-      
       let params = {
         userId: this.invitationCode,
         targetId: this.userId,
@@ -177,7 +175,6 @@ export default {
       });
       this.$store.commit('SET_INVITATIONCODE', '');
     } else {
-    
     }
   },
   mounted() {
@@ -265,7 +262,7 @@ export default {
           url: `/pagesHome/category/categoryStoreList?id=${item.id}&name=${item.name}`,
         });
       }
-      // 
+      //
     },
 
     /* 询价 */

+ 12 - 6
src/pages/tabbar/home.vue

@@ -14,7 +14,7 @@
           placeholder="请输入搜索内容"
           :showAction="false"
           v-model="keyword"
-          @click="$Router.push('/pagesHome/homeSearch')"
+          @click="$Router.push('/pagesHome/homeSearch/index')"
           bgColor="#fff"
           :disabled="true"
         />
@@ -45,7 +45,10 @@
       <view class="item-box">
         <view class="item-top">
           <view class="top-title">热门推荐</view>
-          <view class="top-more" @click="$Router.push('/pagesHome/home/popularRecommend')">
+          <view
+            class="top-more"
+            @click="$Router.push('/pagesHome/popularNearby/index?queryType=1')"
+          >
             <span>查看更多</span>
             <u-icon name="arrow-right" color="#999999" size="14"></u-icon>
           </view>
@@ -57,7 +60,7 @@
             :key="item.id"
             @click="$Router.push(`/pagesHome/marketer/index?id=${item.id}`)"
           >
-            <home-store v-if="index < 4" :item="item"></home-store>
+            <home-store v-if="index < 4" :item="item" isType="hot"></home-store>
           </view>
         </view>
       </view>
@@ -65,7 +68,10 @@
       <view class="item-box">
         <view class="item-top">
           <view class="top-title">附近商家</view>
-          <view class="top-more" @click="$Router.push('/pagesHome/home/nearbyBusiness')">
+          <view
+            class="top-more"
+            @click="$Router.push('/pagesHome/popularNearby/index?queryType=0')"
+          >
             <span>查看更多</span>
             <u-icon name="arrow-right" color="#999999" size="14"></u-icon>
           </view>
@@ -77,7 +83,7 @@
             :key="item.id"
             @click="$Router.push(`/pagesHome/marketer/index?id=${item.id}`)"
           >
-            <home-store v-if="index < 4" :item="item"></home-store>
+            <home-store v-if="index < 4" :item="item" isType="near"></home-store>
           </view>
         </view>
       </view>
@@ -299,7 +305,7 @@ export default {
     .tabar-box {
       width: 100%;
       border-radius: 20rpx;
-      padding: 12rpx 34rpx 32rpx;
+      padding: 26rpx;
       box-sizing: border-box;
       background-color: #fff;
       display: grid;

+ 1 - 1
src/pages/tabbar/mine/index.vue

@@ -251,6 +251,6 @@ export default {
   }
 }
 ::v-deep .u-cell__title-text {
-  line-height: 50rpx !important;
+  line-height: 55rpx !important;
 }
 </style>

+ 1 - 1
src/pages/tabbar/promotionCode.vue

@@ -34,7 +34,7 @@
             width="48rpx"
             height="48rpx"
           ></u--image>
-          <view class="f-s-28 text-primary u-m-t-16">分享到微信</view>
+          <view class="f-s-28 text-primary u-m-t-16">下载到相册</view>
         </view>
       </view>
     </base-card>

+ 37 - 29
src/pagesHome/homeSearch.vue → src/pagesHome/homeSearch/index.vue

@@ -1,14 +1,20 @@
 <template>
   <view class="search">
     <view class="search-item">
-      <u-search v-model="search_text" :clearabled="true"  @custom="handlerSearchBtn" @search="handlerSearchBtn" :actionStyle="{ color:'#215EBE' }" />
+      <u-search
+        v-model="search_text"
+        :clearabled="true"
+        @custom="handlerSearchBtn"
+        @search="handlerSearchBtn"
+        :actionStyle="{ color: '#215EBE' }"
+      />
       <!-- <button class="search-btn" @click="handlerSearchBtn">搜索</button> -->
     </view>
 
     <!-- 搜索历史 -->
     <view class="history" v-show="search_list.length != 0">
       <view class="history-top">
-        <view class='title'>搜索历史</view>
+        <view class="title">搜索历史</view>
         <view class="history-right" @click="handlerAllSearchRecord">
           <u-icon name="trash" />
           <!-- <text>删除记录</text> -->
@@ -21,11 +27,11 @@
           :text="item.name"
           plain
           closable
-          borderColor='#F5F6F8'
+          borderColor="#F5F6F8"
           :show="close2"
-          color='#0C1223'
-          bgColor='#F5F6F8'
-          :closable='false'
+          color="#0C1223"
+          bgColor="#F5F6F8"
+          :closable="false"
           @close="handlerCloseSearchItem(item, index)"
           @click="handlerSelctHistItem(item)"
         />
@@ -34,20 +40,22 @@
     <!-- 热门搜索 -->
     <view class="history">
       <view class="history-top">
-        <view class='title'>热门搜索</view>
+        <view class="title">热门搜索</view>
       </view>
       <view class="label">
         <u-tag
           v-for="(item, index) in popular_search_list"
           :text="item.name"
           :key="index"
-          borderColor='#F5F6F8'
+          borderColor="#F5F6F8"
           :show="close2"
-          :color=" index == 0 ? '#EB1010' :  (index == 1 ? '#FF5219' : (index == 2 ? '#FDA50C' : '#0C1223') ) "
-          bgColor='#F5F6F8'
-          :closable='false'
+          :color="
+            index == 0 ? '#EB1010' : index == 1 ? '#FF5219' : index == 2 ? '#FDA50C' : '#0C1223'
+          "
+          bgColor="#F5F6F8"
+          :closable="false"
           class="label-item"
-          v-if='index < 8'
+          v-if="index < 8"
           @click="$Router.push(`/pagesHome/marketer/index?id=${item.id}`)"
         />
       </view>
@@ -58,7 +66,7 @@
       <view class="popular-item">
         <view
           class="item-box layered"
-          v-for="(item, index) of favourite_list"
+          v-for="(item, index) of favorite_list"
           :key="index"
           @click="$Router.push(`/pagesHome/marketer/index?id=${item.id}`)"
         >
@@ -68,8 +76,8 @@
           <view class="item-right">
             <view class="item-title">{{ item.name }}</view>
             <view class="item-score">
-              <u-rate count="5" size='20' :value="item.score" active-color='#FFA033' readonly />
-              <span class="rate-text" v-if='item.score'>( {{ item.score.toFixed(1) }} )</span>
+              <u-rate count="5" size="20" :value="item.score" active-color="#FFA033" readonly />
+              <span class="rate-text" v-if="item.score">( {{ item.score.toFixed(1) }} )</span>
             </view>
             <view class="item-address"> {{ item.address }} </view>
           </view>
@@ -102,23 +110,23 @@ export default {
       search_list: [], // 搜索列表
 
       popular_search_list: [], //热门搜索列表
-      favourite_list: [], // 猜你喜欢列表
+      favorite_list: [], // 猜你喜欢列表
     };
   },
   computed: {
     ...mapGetters(['location']),
   },
-  watch:{
+  watch: {
     // 搜索历史 > 8 删除最后一项
-    search_list(newValue){
-      if(newValue.length > 8){
+    search_list(newValue) {
+      if (newValue.length > 8) {
         this.search_list.splice(newValue.length - 1, 1);
         uni.setStorageSync('searchItem', this.search_list);
       }
-    }
+    },
   },
   onShow() {
-    this.search_text = ''
+    this.search_text = '';
     if (uni.getStorageSync('searchItem')) {
       this.search_list = uni.getStorageSync('searchItem');
     }
@@ -129,13 +137,13 @@ export default {
   methods: {
     // 初始化热门搜索 猜你喜欢列表
     handlerInitList() {
-      listHotMerchant({...this.location}).then(res => {
+      listHotMerchant({ ...this.location }).then(res => {
         this.popular_search_list = res.data;
       });
 
       // 猜你喜欢列表
       likeMerchant({ ...this.location }).then(res => {
-        this.favourite_list = res.data;
+        this.favorite_list = res.data;
       });
     },
     // 点击搜索按钮
@@ -204,8 +212,8 @@ export default {
     justify-content: space-between;
     align-items: center;
     margin-bottom: 20rpx;
-    .title{
-      color:#0C1223;
+    .title {
+      color: #0c1223;
       font-size: 30rpx;
       font-weight: bold;
     }
@@ -251,15 +259,15 @@ export default {
       justify-content: space-around;
 
       .item-title {
-        color: #0C1223;
+        color: #0c1223;
         font-weight: bold;
         font-size: 28rpx;
       }
-      .item-score{
+      .item-score {
         display: flex;
         align-items: center;
-        .rate-text{
-          color: #9FA0A6;
+        .rate-text {
+          color: #9fa0a6;
           font-size: 24rpx;
           margin-left: 10rpx;
         }

+ 63 - 0
src/pagesHome/popularNearby/index.vue

@@ -0,0 +1,63 @@
+<template>
+  <view class="recommend-hot">
+    <page-navbar :hasBack="true" bgColor="#fff" :title="getTitle"></page-navbar>
+    <base-list :list="listData" @click="handlerRouterSkip"></base-list>
+    <!-- <load-more :status="loadmoreStatus" color="#ccc"></load-more> -->
+  </view>
+</template>
+
+<script>
+import { indexMerchantPaging } from '@/api/client/home';
+import ListMixin from '@/mixin/list.js';
+
+export default {
+  mixins: [ListMixin],
+  data() {
+    return {
+      queryData: {
+        region: null, //地区编码
+        longitude: null, //经度
+        latitude: null, //纬度
+        queryType: 1, //查询类型 0-附近商家 1- 推荐商家
+      },
+      listApiName: indexMerchantPaging,
+    };
+  },
+  onLoad(option) {
+    let { queryType } = option;
+    this.queryData.queryType = queryType;
+  },
+  computed: {
+    getTitle() {
+      return this.queryData.queryType == 1 ? '热门推荐' : '附近商家';
+    },
+  },
+  created() {
+    this.getInitData();
+  },
+  mounted() {
+    this.initDataList(this.queryData, true);
+  },
+  methods: {
+    getInitData() {
+      let { latitude, longitude, region } = this.location;
+      this.queryData.latitude = latitude;
+      this.queryData.longitude = longitude;
+      this.queryData.region = region;
+    },
+    handlerRouterSkip(item) {
+      console.log(item, 'item');
+      uni.navigateTo({
+        url: `/pagesHome/marketer/index?id=${item.id}`,
+      });
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.recommend-hot {
+  padding: 32rpx;
+  box-sizing: border-box;
+}
+</style>

BIN
src/static/img.jpg