Prechádzať zdrojové kódy

充值、网点、设备修改

zuypeng 1 rok pred
rodič
commit
79c86ab21d

+ 2 - 2
src/App.vue

@@ -23,8 +23,8 @@ export default <any>{
       username: "15071072750"
     },
     isLogin: false,
-    normalCode: "",
-    device: null
+    last:{},
+    device: null,
   },
   onLaunch() {
     uni.getSystemInfo({

+ 1 - 1
src/components/station/index.vue

@@ -65,7 +65,7 @@ const handleNavMap = (station:any) => {
 }
 
 const handleNavStation = (station: any) => {
-  getApp<any>().globalData.pageData = {station}
+  getApp<any>().globalData.last.station = station
   uni.navigateTo({
     url: '/pages-wash/station/index?id='+station.id
   })

+ 4 - 4
src/components/tab-bar/index.vue

@@ -146,11 +146,11 @@ view {
 }
 .tabbar-container {
   position: fixed;
-  bottom: 0;
+  bottom: 20rpx;
   left: 0;
   width: 100%;
   height: 110rpx;
-  box-shadow: 0 0 5px #999;
+  box-shadow: 0 0 3px #999;
   display: flex;
   align-items: center;
   padding: 5rpx 0;
@@ -182,10 +182,10 @@ view {
   width: 100rpx;
   height: 100rpx;
   position: absolute;
-  top: -50rpx;
+  top: -60rpx;
   left: calc(50% - 50rpx);
   border-radius: 50%;
-  box-shadow: 0 0 5px #999;
+  box-shadow: 0 -1px 0 0 #999;
   background-color: #ffffff;
 }
 .tabbar-container .tabbar-item .item-top image {

+ 116 - 185
src/pages-user/wallet/recharge.vue

@@ -1,219 +1,150 @@
 <template>
-  <view class="pl-30 pr-30">
-    <view class="pay">
-      <view class="title pt-30 pb-30">充值金额</view>
-      <view class="flex-wrap">
-        <view
-            :class="[
-            'option',
-            'flex-center',
-            `option-${index === payOption && !payValue ? 'active' : ''}`,
-          ]"
-            v-for="(item, index) in payOptions"
-            :key="index"
-            @click="changeOption(index)">
-          <image
-              v-if="payOptionsDiscount[index]"
-              src="/static/images/coupon-center.png"
-              mode="widthFix"
-              class="tag fs-24 color-fff fw-500  width-40"
-          />
-          <!--          <view
-                        class="tag fs-24 color-fff fw-500"
-                        v-if="payOptionsDiscount[index]">{{ payOptionsDiscount[index] }}
-                    </view>-->
-          {{ item }}
+  <view class="page">
+    <view class="recharge">
+      <view v-for="(recharge,idx) in state.configList" :key="idx"
+            @click="handleRechargeClick(recharge,idx)"
+            class="recharge-item" :class="idx===state.chosenIdx?'active':''">
+        <view class="recharge-item_amt">{{ recharge.rechargeAmount }}</view>
+        <view class="recharge-item_grant" v-if="recharge.grantsAmount>0">
+          <uv-icon name="gift" :color="idx===state.chosenIdx?'#19A497':'#2b2b2b'"></uv-icon>
+          {{ recharge.grantsAmount }}元
         </view>
       </view>
-      <view v-if="payOptionsDiscountDay[payOption]" class="flex-align-center">
-        <view class="fs-30 color-666">
-          {{ (payOptionsDiscount[payOption] && payOptionsDiscount[payOption] > 0) ? `享服务费${payOptionsDiscount[payOption]}折,` : '' }}权益有效期{{
-            payOptionsDiscountDay[payOption]
-          }}天
-        </view>
-        <view
-            class="ml-12 color-primary fs-30"
-            @click="to(`/pages-common/activity/activity?id=${activityId}`)">
-          <text>详细规则</text>
-          <text class="fs-24 ml-6">>></text>
-        </view>
-      </view>
-      <view class="title pt-60 pb-30">自定义金额</view>
-      <style-input
-          :value="payValue > 0 ? payValue : ''"
-          title="金额"
-          type="digit"
-          @input="input"/>
+    </view>
+    <view class="recharge-pay">
+      <uv-button type="primary" iconColor="white" color="#19A497" text="充值" @click="debounceConfirm"></uv-button>
     </view>
   </view>
 
-  <style-bottom-view>
-    <view class="pl-60 pr-60 pb-20">
-      <style-button size="small" type="primary" @click="debounceConfirm">充值</style-button>
-    </view>
-  </style-bottom-view>
 </template>
 
 <script setup lang="ts">
-import {ref} from "vue";
-import {onLoad} from "@dcloudio/uni-app";
-import {back, to} from "@/utils/navigate";
+import {reactive, ref} from "vue";
+import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
 import {debounce} from "@/utils/common";
+import {get, post,body} from "@/utils/https";
 
-const balance = ref(0);
-const payOption = ref(3);
-const payOptions = ref([30, 50, 100, 200, 500, 1000]);
-const payOptionsDiscount = ref(["", "", "", "", "", ""]);
-const payOptionsDiscountDay = ref([0, 0, 0, 0, 0, 0]);
-const payValue = ref(0);
-const activityId = ref();
-const rechargeRightsId = ref();
-const rechargeRightsList = ref([]);
-const needBack = ref(false);
-const input = (e: any) => {
-  payValue.value = e.value;
-  rechargeRightsId.value = 0;
-};
-const changeOption = (index: number) => {
-  payValue.value = 0;
-  payOption.value = index;
-  let find = rechargeRightsList.value.find((k:any) => (k.amountMin || 0) / 100 === payOptions.value[index]);
-  if (find) {
-    rechargeRightsId.value = find?.id;
-  }
-};
+const initState = () => ({
+  configList: [],
+  chosenIdx: -1
+})
+
+const state = reactive(initState())
+
+onShow(() => {
+  loadRechargeConfig();
+})
+
+onHide(() => {
+  Object.assign(state, initState());
+})
+
+const handleRechargeClick = (recharge: any, idx: number) => {
+  state.chosenIdx = idx;
+}
+
+const loadRechargeConfig = () => {
+  get(`/common/rechargeConfig`).then((res: any) => {
+    state.configList = res;
+  })
+}
 
 const debounceConfirm = debounce(() => {
   confirm();
 }, 500)
 
 const confirm = () => {
-  if (payValue.value && !/^[0-9]*(\.\d{1,2})?$/.test(`${payValue.value}`)) {
-    uni.showModal({
-      title: "温馨提示",
-      content: "请输入正确的金额",
-      showCancel: false,
-      confirmColor: "#2d9e95",
-    });
-    return;
-  }
-  const params = payValue.value
-      ? Number(payValue.value)
-      : payOptions.value[payOption.value];
-  if (params > 10000 || params <= 0) {
-    uni.showModal({
-      title: "温馨提示",
-      content: "每次最大充值金额10000,请修改金额",
-      showCancel: false,
-      confirmColor: "#2d9e95",
-    });
+  if (state.chosenIdx < 0) {
     return;
   }
   uni.showLoading({
-    title: "加载中",
+    title: "",
   });
-  insertMoney(params, rechargeRightsId.value)
-      .then(() => {
-        return fetchProfile();
-      })
-      .then((res) => {
-        payValue.value = 0;
-        balance.value = res.balance;
-        uni.hideLoading();
-        uni.showToast({
-          title: "已支付",
-          icon: "success",
-        });
-        setTimeout(() => {
-          if (needBack.value) {
-            back();
-          } else {
-            to("/pages-user/wallet/wallet");
-          }
-        }, 2000);
-      })
-      .catch((err) => {
-        if (/cancel/.test(err.errMsg)) {
-          return;
-        }
-        uni.showModal({
-          content: `${err.errMsg},请重试`,
-        });
-      });
-};
-
-
-onLoad((options: any) => {
-  console.log(options)
-  if (options.value) {
-    payOption.value = payOptions.value.findIndex(
-        (item) => item === Number((Number(options.value) / 100).toFixed(2))
-    );
-    needBack.value = !!options.back;
-  }
 
-  if (options.discount) {
-    payValue.value = Number((Number(options.discount) / 100).toFixed(2));
-  }
-  fetchProfile().then((res) => {
-    // console.log(res);
-    balance.value = res.balance;
-    if (res && res.activityList && res.activityList.length) {
-      res.activityList[0].rechargeRightsList.forEach((item: any) => {
-        const val = Number((Number(item.amountMin) / 100).toFixed(2));
-        const fi = payOptions.value.findIndex((o) => o === val);
-        if (fi >= 0) {
-          payOptionsDiscount.value[fi] = ((item.discount || 0) / 10).toFixed(1);
-          payOptionsDiscountDay.value[fi] = item.validity > 0 ? item.validity : 1;
-        }
-      });
-      if (res.activityList && res.activityList[0].rechargeRightsList && res.activityList[0].rechargeRightsList.length > 0) {
-        rechargeRightsList.value = res?.activityList[0]?.rechargeRightsList
-      }
-      activityId.value = res.activityList[0].id;
-    }
+  let recharge = state.configList[state.chosenIdx]
+  body("/payment/wxPay", {amount: parseInt(`${1 * 100}`)}).then((res: any) => {
+    // #ifdef MP-WEIXIN
+    wx.requestPayment({
+      timeStamp: `${res.timeStamp}`,
+      nonceStr: res.nonceStr,
+      package: res.packageVal,
+      signType: res.signType,
+      paySign: res.paySign,
+      success:function (res: any) {
+        console.log(res)
+        uni.redirectTo({
+          url:'/pages-user/wallet/index'
+        })
+      },
+      fail: function (e)  {
+        console.error(e)
+      },
+    });
+    // #endif
+    // #ifndef MP-WEIXIN
+    uni.showToast({title: '目前仅支持微信支付'})
+    // #endif
   });
-});
+}
+
+
 </script>
 
-<style lang="scss">
-.pay {
-  .title {
-    font-weight: 500;
-    font-size: 32rpx;
-    color: #000;
-  }
+<style lang="scss" scoped>
+.page {
+  min-height: 100vh;
+  width: 100%;
+  background-color: #fff;
+}
+
+.recharge {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: end;
+  align-items: start;
+  align-content: center;
+
+  &-item {
+    display: flex;
+    flex-direction: column;
+    width: 200rpx;
+    height: 100rpx;
+    background-color: #efefef;
+    margin: 20rpx auto;
+    padding: 20rpx;
 
-  .option {
-    position: relative;
-    width: 214rpx;
-    height: 140rpx;
-    background: var(--color-sec);
-    border-radius: 10rpx;
-    margin-left: 20rpx;
-    margin-bottom: 20rpx;
-    font-size: 36rpx;
-    color: #000;
-    font-weight: 500;
-    //overflow: hidden;
-
-    &:nth-child(3n + 1) {
-      margin-left: 0;
+    &_amt {
+      font-size: 20px;
     }
 
-    .tag {
-      position: absolute;
-      top: -9px;
-      right: -10px;
-      padding: 2rpx 2rpx;
+    &_grant {
+      font-size: 12px;
+      margin-top: 20rpx;
+      display: inline-flex;
     }
   }
+}
+
+
+.active {
+  border-radius: 1px solid $uni-color-primary;
+
+  .recharge-item {
+    &_amt {
+      color: $uni-color-primary;
+    }
 
-  .option-active {
-    color: var(--color-primary);
-    //border-color: var(--color-primary);
-    //color: #fff;
-    font-weight: 700;
+    &_grant {
+      color: $uni-color-primary;
+    }
   }
 }
+
+.recharge-pay {
+  width: calc(100vw - 40rpx);
+  position: fixed;
+  bottom: 10rpx;
+  left: 20rpx;
+}
+
 </style>

+ 83 - 41
src/pages-wash/device/index.vue

@@ -1,32 +1,37 @@
 <template>
   <view :class="['page']">
-      <view class="device-header">
-        <view class="device-header_name">
-          <text>洗车机编号:{{state.device.name}}</text>
-        </view>
-        <view class="device-header_fun">
-          <uv-tags v-for="(f,i) in state.device.funcs" :key="i" size="mini" type="primary">{{f}}</uv-tags>
-        </view>
+    <view class="device-header">
+      <view class="device-header_name">
+        <text>洗车机编号:{{ state.device.deviceName }}</text>
       </view>
-      <view class="device-body">
-        <view class="device-body_ops" @click="handleClickDevice">
-          <text v-if="state.device.isRunning">停止</text>
-          <text >启动</text>
-        </view>
-        <view class="device-body_ops-time">{{state.time}}</view>
+      <view class="device-header_fun">
+        <uv-tags plain size="mini" type="info" :text="f" v-for="(f,i) in state.device.functions.split('\\|')" :key="i"></uv-tags>
       </view>
+      <view class="device-header_fun">
+        <uv-tags plain size="mini" type="primary" :text="state.device.state"></uv-tags>
+      </view>
+
+    </view>
+    <view class="device-body">
+      <view class="device-body_ops" @click="debounceStartStopDevice">
+        <text v-if="state.device.state==='idle'">启动</text>
+        <text v-else>停止</text>
+      </view>
+      <view class="device-body_ops-time">{{ state.time }}</view>
+    </view>
   </view>
 </template>
 
-<script setup lang="ts" >
+<script setup lang="ts">
 import {onHide, onLoad, onShow} from "@dcloudio/uni-app";
 import {reactive, ref} from "vue";
-import {get} from "@/utils/https";
+import {debounce} from "@/utils/common";
+import {get, post} from "@/utils/https";
 
 const initState = () => ({
-  device:{},
-  time:"00:00:00",
-  start:new Date()
+  device: {},
+  time: "00:00:00",
+  start: new Date()
 })
 
 const state = reactive(initState())
@@ -36,39 +41,67 @@ onHide(() => {
 })
 
 onLoad((options) => {
-  console.log("detail show>>>>",options)
-  let id = options?.id;
-  if(!id){
+  console.log("device onLoad>>>>", options)
+  let id = options?.shortId;
+  if (!id) {
     return;
   }
+  state.device = getApp<any>().globalData.last.device;
+  console.log(state.device)
   loadDeviceDetail(id);
 });
 
 
-const loadDeviceDetail = (id:number) => {
-  get(`/wash-device/queryDevice/${id}`).then((res:any)=>{
+const loadDeviceDetail = (id: number) => {
+  get(`/wash-device/queryDevice/${id}`).then((res: any) => {
     state.device = res;
+  }).catch(e => {
+    console.error(e)
   })
   countTime();
 }
 
-const handleClickDevice = () => {
+const handleNavigateBack = () => {
+  uni.navigateBack();
+}
+
+const debounceStartStopDevice = debounce(()=>{
+  handleClickDevice();
+},600)
 
+const handleClickDevice = () => {
+    if(state.device?.state==='idle'){
+      uni.showLoading({
+        title: "启动中",
+        mask: true,
+      });
+      post(`/wash-device/startDevice/${state.device.shortId}`).then((res:any)=>{
+        uni.hideLoading()
+      })
+    }else{
+      uni.showLoading({
+        title: "停止中",
+        mask: true,
+      });
+      post(`/wash-device/stopDevice/${state.device.shortId}`).then((res:any)=>{
+        uni.hideLoading()
+      })
+    }
 }
 
-const countTime= ()=>{
-  setInterval(()=>{
+const countTime = () => {
+  setInterval(() => {
     let delta = new Date().getTime() - state.start.getTime();
-    delta = delta/1000;
-    let hour = (delta/3600).toFixed(0);
-    let min = ((delta%3600)/60).toFixed(0);
-    let second =  ((delta%3600)%60).toFixed(0);
+    delta = delta / 1000;
+    let hour = (delta / 3600).toFixed(0);
+    let min = ((delta % 3600) / 60).toFixed(0);
+    let second = ((delta % 3600) % 60).toFixed(0);
     state.time = [
-        Number(hour)>9?hour:`0${hour}`,
-        Number(min)>9?min:`0${min}`,
-        Number(second)>9?second:`0${second}`
+      Number(hour) > 9 ? hour : `0${hour}`,
+      Number(min) > 9 ? min : `0${min}`,
+      Number(second) > 9 ? second : `0${second}`
     ].join(":")
-  },1000)
+  }, 1000)
 }
 
 
@@ -76,23 +109,32 @@ const countTime= ()=>{
 
 <style lang="scss" scoped>
 .page {
-  min-height: 100vh;
+  height: 100vh;
   width: 100%;
   background-color: #f6f7fa;
 }
 
-.device-header{
+.device-header {
   padding: 20rpx;
   display: flex;
   flex-direction: column;
+  justify-content: center;
+  align-items: center;
 
-  &_name{
+  &_name {
     font-weight: 500;
+    margin: 15rpx 0;
+  }
+
+  &_fun {
+    font-size: 13px;
+    color: #7a7a7a;
+    margin: 10rpx 0;
   }
 
 }
 
-.device-body{
+.device-body {
   flex-grow: 1;
   margin-top: 60rpx;
   display: flex;
@@ -101,7 +143,7 @@ const countTime= ()=>{
   align-items: center;
   align-content: center;
 
-  &_ops{
+  &_ops {
     display: flex;
     justify-content: center;
     align-items: center;
@@ -111,8 +153,8 @@ const countTime= ()=>{
     border-radius: 50%;
     background-color: $uni-color-primary;
     color: white;
-    font-size: 32px;
-    font-weight: 600;
+    font-size: 28px;
+    font-weight: 500;
   }
 }
 </style>

+ 2 - 2
src/pages-wash/scan/index.vue

@@ -133,9 +133,9 @@ const handleScancode = (e: any) => {
     uni.vibrateShort({});
     if (e.detail && e.detail.result) {
       console.log(e)
-      let {id} = e.detail.result;
+      let {shortId} = e.detail.result;
       uni.navigateTo({
-        url:'/pages-wash/device/index?id='+id
+        url:'/pages-wash/device/index?shortId='+shortId
       })
     }
     setTimeout(()=>{

+ 29 - 12
src/pages-wash/station/index.vue

@@ -12,17 +12,17 @@
       <view class="device-item" v-for="device in state.deviceList" :key="device.id" @click="handleClickDevice(device)">
         <view class="device-item_header">
           <text>{{ device.deviceName }}</text>
-          <text class="device-item_header-status">{{ getDictName('WashDevice.state',device.state) }}</text>
+          <text class="device-item_header-status">{{ getDictName('WashDevice.state', device.state) }}</text>
         </view>
         <view class="device-item_func">
-          <text class="device-item_func-label">{{device.functions}}</text>
+          <text class="device-item_func-label">{{ device.functions }}</text>
         </view>
       </view>
 
     </view>
 
     <view class="scan-btn">
-    <uv-button type="primary" icon="scan" iconColor="var(uni-color-primary)" text="扫码洗车"></uv-button>
+      <uv-button type="primary" icon="scan"  iconColor="white"  color="#19A497" text="扫码洗车" @click="handleClickScan"></uv-button>
     </view>
   </view>
 </template>
@@ -47,16 +47,32 @@ onHide(() => {
   Object.assign(state, initState());
 })
 
-onLoad((options) => {
-  console.log("detail show>>>>", options)
+/*onLoad((options) => {
   state.station.id = options?.id;
-  let {station} = getApp<any>().globalData.pageData;
+  let station = getApp<any>().globalData.last.station;
   if (station) {
     state.station = station;
   }
-  loadStationDeviceList();
-});
+  if (options?.id) {
+    loadStationDeviceList();
+  }
+});*/
+
+onShow((options) => {
+  let station = getApp<any>().globalData.last.station;
+  if (station) {
+    state.station = station;
+    state.station.id = station.id;
+    loadStationDeviceList();
+  }
+})
+
 
+const handleClickScan = () => {
+  uni.navigateTo({
+    url:'/pages-wash/scan/index'
+  })
+}
 
 const loadStationDeviceList = () => {
   if (!state.station.id) {
@@ -71,9 +87,10 @@ const handleNavStation = () => {
 
 }
 
-const handleClickDevice = (device:any) => {
+const handleClickDevice = (device: any) => {
+  getApp<any>().globalData.last.device = device;
   uni.navigateTo({
-    url:'/pages-wash/device/index?id='+device.id
+    url: '/pages-wash/device/index?shortId=' + device.shortId
   })
 }
 
@@ -132,14 +149,14 @@ const handleClickDevice = (device:any) => {
 
   &_func {
 
-    &-label{
+    &-label {
       font-size: 24rpx;
       color: #aaa;
     }
   }
 }
 
-.scan-btn{
+.scan-btn {
   width: calc(100vw - 40rpx);
   position: fixed;
   bottom: 10rpx;

+ 1 - 1
src/pages.json

@@ -9,7 +9,7 @@
     {
       "path": "pages/index/index",
       "style": {
-        "navigationBarTitleText": "洗车小程序"
+        "navigationBarTitleText": "iWash洗车"
       }
     },
     {

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

@@ -128,6 +128,10 @@ const handleMenuClick = (menu:any) => {
     uni.navigateTo({
       url:'/pages-wash/scan/index'
     })
+  }else  if(menu.title==='充值'){
+    uni.navigateTo({
+      url:'/pages-user/wallet/recharge'
+    })
   }
 }
 

+ 1 - 1
src/utils/https.ts

@@ -16,7 +16,7 @@ isDevelopment = e === "develop" || e === "trial";
 let env: string = isDevelopment ? "dev" : "prd";
 const apis = {
     dev: {
-        serverUrl: "http://localhost:8088/api",
+        serverUrl: "http://192.168.5.7:9099/api",
         fileUrl: "https://zyp-1258963180.cos.ap-guangzhou.myqcloud.com/"
     },
     prd: {