Browse Source

充值记录

shish 1 year ago
parent
commit
e2b84559ad

+ 7 - 0
mallApp/src/api/recharge/index.js

@@ -14,4 +14,11 @@ export const rechargeFn = data => {
 
 export const updateShop = data => {
     return https.post('/shop/update', data)
+}
+
+/** *
+ * 充值记录列表
+ */
+export const getRechargeList = data => {
+    return https.get('/recharge/list', data)
 }

+ 2 - 2
mallApp/src/ext.json

@@ -4,9 +4,9 @@
   "directCommit": false,
   "ext": {
     "account": 0,
-    "apiHost": "http://api.shop.theflorist.cn",
+    "apiHost": "https://api.shop.theflorist.cn",
     "socketApiHost": "api.shop.theflorist.cn",
-    "imgHost": "http://img.theflorist.cn",
+    "imgHost": "https://img.theflorist.cn",
     "name":"中花卉"
   }
 }

+ 8 - 1
mallApp/src/pages.json

@@ -45,7 +45,7 @@
         {
             "root": "pages/member",
             "pages": [
-                { "path": "recharge", "style": { "navigationBarTitleText": "充值活动" } },
+                { "path": "recharge", "style": { "navigationBarTitleText": "充值" } },
                 { "path": "rechargeResult", "style": { "navigationBarTitleText": "结果" } }
             ]
         },
@@ -110,6 +110,13 @@
             "pages": [
                 { "path": "affirmGhs", "style": { "navigationBarTitleText": "订单结算", "enablePullDownRefresh": true } }
             ]
+        },
+        {
+            "root": "pages/recharge",
+            "pages": [
+                { "path": "list", "style": { "navigationBarTitleText": "充值记录", "enablePullDownRefresh": true } },
+                { "path": "detail", "style": { "navigationBarTitleText": "充值详情" } }
+            ]
         }
     ],
     "globalStyle": {

+ 7 - 0
mallApp/src/pages/home/recent.vue

@@ -33,6 +33,10 @@
                     <view class="popup-item" @click="handlePopupAction('recharge', item)">
                       <text>{{ Number(item.balance) < 0 ? '结账' : '充值' }}</text>
                     </view>
+                    <view class="popup-item" @click="getRechargeList(item)">
+                      <text>充值记录</text>
+                    </view>
+
                   </view>
                 </view>
 
@@ -188,6 +192,9 @@ export default {
     hideMoreOptions() {
       this.activePopupIndex = -1;
     },
+    getRechargeList(item){
+      this.pageTo({ url:'/pages/recharge/list?account='+item.shopId+'&hdId='+item.id})
+    },
     handlePopupAction(action, item) {
       // 先关闭弹出菜单
       this.hideMoreOptions();

+ 375 - 0
mallApp/src/pages/recharge/detail.vue

@@ -0,0 +1,375 @@
+<template>
+  <div class="app-content">
+    <div class="page-top">
+      <div class="page-top-img">
+        <image mode="widthFix" :src="`${constant.imgUrl}/retail/order/bg.png`" alt />
+      </div>
+      <div class="page-top-det">
+        <div>
+          <div class="page-status">{{ getStatusName }}</div>
+        </div>
+        <div class="page-status-img">
+          <img :src="statusImg" alt />
+        </div>
+      </div>
+    </div>
+    
+    <div class="page-det">
+      <div class="module-com">
+        <div class="module-tit">充值信息</div>
+        <div class="module-det">
+          <div class="recharge-info">
+            <div class="amount-display">
+              <span class="currency">¥</span>
+              <span class="amount">{{ data.amount ? parseFloat(data.amount).toFixed(2) : '0.00' }}</span>
+            </div>
+            <div class="recharge-status">
+              <span class="status-tag" :class="getStatusClass">{{ getStatusName }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      
+      <div class="module-com order-msg">
+        <div class="module-tit">充值详情</div>
+        <div class="module-det">
+          <div class="order-msg-blo">
+            <div class="msg-list">
+              <div class="label">订单号</div>
+              <div class="value">{{ data.orderSn }}</div>
+            </div>
+            <div class="msg-list">
+              <div class="label">充值时间</div>
+              <div class="value">{{ data.createTime ? data.createTime.substring(5, 16) : '' }}</div>
+            </div>
+            <div class="msg-list" v-if="data.payTime && data.payTime != '0000-00-00 00:00:00'">
+              <div class="label">支付时间</div>
+              <div class="value">{{ data.payTime ? data.payTime.substring(5, 16) : '' }}</div>
+            </div>
+            <div class="msg-list">
+              <div class="label">支付方式</div>
+              <div class="value">{{ getPayMethodName }}</div>
+            </div>
+            <div class="msg-list" v-if="data.remark">
+              <div class="label">备注</div>
+              <div class="value">{{ data.remark }}</div>
+            </div>
+          </div>
+          
+          <div class="order-msg-blo" v-if="data.status == '3'">
+            <div class="msg-list">
+              <div class="label">失败原因</div>
+              <div class="value error-text">{{ data.failReason || '未知原因' }}</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    
+    <div class="page-btn app-footer" v-if="data.status == '1'">
+      <div class="flex-center">
+        <span>充值金额</span>
+        <span class="app-price">
+          <span>¥</span>
+          <span class="app-size-40">{{ data.amount ? parseFloat(data.amount).toFixed(2) : '0.00' }}</span>
+        </span>
+      </div>
+      <button class="button-com red" @click="retryRecharge">重新充值</button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getDetail } from "@/api/recharge";
+
+export default {
+  name: "recharge-detail",
+  data() {
+    return {
+      constant: this.$constant,
+      data: {}
+    };
+  },
+  computed: {
+    getStatusName() {
+      let statusName = "";
+      switch (this.data.status) {
+        case '1':
+          statusName = "充值中";
+          break;
+        case '2':
+          statusName = "充值成功";
+          break;
+        case '3':
+          statusName = "充值失败";
+          break;
+        default:
+          statusName = "未知状态";
+          break;
+      }
+      return statusName;
+    },
+    getStatusClass() {
+      let statusClass = "";
+      switch (this.data.status) {
+        case '1':
+          statusClass = "status-processing";
+          break;
+        case '2':
+          statusClass = "status-success";
+          break;
+        case '3':
+          statusClass = "status-failed";
+          break;
+        default:
+          statusClass = "status-default";
+          break;
+      }
+      return statusClass;
+    },
+    getPayMethodName() {
+      let methodName = "";
+      switch (this.data.payMethod) {
+        case '1':
+          methodName = "微信支付";
+          break;
+        case '2':
+          methodName = "支付宝";
+          break;
+        case '3':
+          methodName = "余额支付";
+          break;
+        default:
+          methodName = "未知方式";
+          break;
+      }
+      return methodName;
+    },
+    statusImg() {
+      let img = "";
+      if (this.data.status == '1') {
+        img = `${this.$constant.imgUrl}/retail/order/wait-pay.png`;
+      } else if (this.data.status == '2') {
+        img = `${this.$constant.imgUrl}/retail/order/order-confirm.png`;
+      } else if (this.data.status == '3') {
+        img = `${this.$constant.imgUrl}/retail/order/order-cancel.png`;
+      }
+      return img;
+    }
+  },
+  onLoad() {
+    this.init();
+  },
+  methods: {
+    init() {
+      this.getDetail();
+    },
+    getDetail() {
+      let form = {};
+      if (this.option.id) {
+        form.id = this.option.id;
+      } else if (this.option.orderSn) {
+        form.orderSn = this.option.orderSn;
+      }
+      return getDetail(form).then(res => {
+        this.data = res.data;
+      });
+    },
+    retryRecharge() {
+      uni.navigateTo({
+        url: `/pages/recharge/index?amount=${this.data.amount}&orderSn=${this.data.orderSn}`
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.app-content {
+  .page-top {
+    position: relative;
+    height: 300upx;
+    
+    .page-top-img {
+      width: 100%;
+      height: 100%;
+      
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    
+    .page-top-det {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      text-align: center;
+      color: #fff;
+      
+      .page-status {
+        font-size: 36upx;
+        font-weight: bold;
+        margin-bottom: 20upx;
+      }
+      
+      .page-status-img {
+        img {
+          width: 80upx;
+          height: 80upx;
+        }
+      }
+    }
+  }
+  
+  .page-det {
+    padding: 30upx;
+    
+    .module-com {
+      background: #fff;
+      border-radius: 20upx;
+      margin-bottom: 30upx;
+      overflow: hidden;
+      
+      .module-tit {
+        padding: 30upx;
+        font-size: 32upx;
+        font-weight: bold;
+        border-bottom: 1px solid #f0f0f0;
+      }
+      
+      .module-det {
+        padding: 30upx;
+        
+        .recharge-info {
+          text-align: center;
+          
+          .amount-display {
+            margin-bottom: 30upx;
+            
+            .currency {
+              font-size: 40upx;
+              color: #ff6b35;
+            }
+            
+            .amount {
+              font-size: 60upx;
+              font-weight: bold;
+              color: #ff6b35;
+            }
+          }
+          
+          .recharge-status {
+            .status-tag {
+              padding: 10upx 20upx;
+              border-radius: 30upx;
+              font-size: 24upx;
+              
+              &.status-processing {
+                color: #ff9500;
+                border: 1px solid #ff9500;
+                background-color: #fff7e6;
+              }
+              
+              &.status-success {
+                color: #52c41a;
+                border: 1px solid #52c41a;
+                background-color: #f6ffed;
+              }
+              
+              &.status-failed {
+                color: #ff4d4f;
+                border: 1px solid #ff4d4f;
+                background-color: #fff2f0;
+              }
+              
+              &.status-default {
+                color: #999999;
+                border: 1px solid #999999;
+                background-color: #f5f5f5;
+              }
+            }
+          }
+        }
+        
+        .order-msg-blo {
+          .msg-list {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 20upx 0;
+            border-bottom: 1px solid #f0f0f0;
+            
+            &:last-child {
+              border-bottom: none;
+            }
+            
+            .label {
+              color: #999;
+              font-size: 28upx;
+            }
+            
+            .value {
+              color: #333;
+              font-size: 28upx;
+              text-align: right;
+              flex: 1;
+              margin-left: 20upx;
+              
+              &.error-text {
+                color: #ff4d4f;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  .page-btn {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background: #fff;
+    padding: 30upx;
+    border-top: 1px solid #f0f0f0;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    
+    .flex-center {
+      display: flex;
+      align-items: center;
+      
+      span {
+        font-size: 28upx;
+        color: #333;
+      }
+      
+      .app-price {
+        color: #ff6b35;
+        margin-left: 20upx;
+        
+        .app-size-40 {
+          font-size: 40upx;
+          font-weight: bold;
+        }
+      }
+    }
+    
+    .button-com {
+      padding: 20upx 40upx;
+      border-radius: 10upx;
+      font-size: 28upx;
+      border: none;
+      
+      &.red {
+        background: #ff6b35;
+        color: #fff;
+      }
+    }
+  }
+}
+</style> 

+ 188 - 0
mallApp/src/pages/recharge/list.vue

@@ -0,0 +1,188 @@
+<template>
+  <view class="recharge-page">
+    <app-tabs :tabs="tabs" :isFixed="true" :currentTab="tabIndex" @change="change" itemWidth="20%"/>
+
+    <view style="margin-left:60upx;margin-top:110upx;padding-bottom:30upx;position: relative;">
+      <DateSelect @selectDateFn="selectDateFn" defaultShowName='时间' />
+      <button class="admin-button-com mini-btn blue" style="position: absolute;right:80upx;top:-8upx;" @click="resetSearch()">重置搜索</button>
+    </view>
+
+    <block v-if="!$util.isEmpty(list.data)">
+      <view class="recharge_list">
+        <RechargeItem v-for="(item, index) in list.data" :key="index" :info="item" @click="goToDetail"></RechargeItem>
+      </view>
+    </block>
+    <block v-else>
+      <view>
+        <AppWrapperEmpty title="暂无数据" :is-empty="$util.isEmpty(list.data)"/>
+      </view>
+    </block>
+
+  </view>
+</template>
+
+<script>
+import AppTabs from "@/components/plugin/tabs";
+import RechargeItem from "./rechargeItem";
+import { list } from "@/mixins";
+import AppWrapperEmpty from "@/components/app-wrapper-empty";
+import { getRechargeList } from "@/api/recharge";
+import DateSelect from "@/components/module/dateSelect";
+
+export default {
+  components: {
+    AppWrapperEmpty,
+    RechargeItem,
+    AppTabs,
+    DateSelect
+  },
+  mixins: [list],
+  data () {
+    return {
+      tabs: [
+        {
+          name: "全部",
+          value: 0,
+          key: '0'
+        },
+        {
+          name: "充值中",
+          value: 0,
+          key: '1'
+        },
+        {
+          name: "充值成功",
+          value: 0,
+          key: '2'
+        },
+        {
+          name: "充值失败",
+          value: 0,
+          key: '3'
+        }
+      ],
+      list: {
+        data: []
+      },
+      tabIndex: 0,
+      status: '0',
+      refreshPage: 0,
+      searchTime: '',
+      startTime: '',
+      endTime: ''
+    }
+  },
+  onReachBottom () {
+    if (!this.list.finished) {
+      this.getRechargeList().then(res => {
+        uni.stopPullDownRefresh()
+      });
+    } else {
+      uni.stopPullDownRefresh()
+    }
+  },
+  onPullDownRefresh () {
+    this.resetList();
+    this.getRechargeList().then(res => {
+      uni.stopPullDownRefresh()
+    })
+  },
+  onShow(){
+    if(this.refreshPage == 1){
+      this.resetList()
+      this.getRechargeList()
+      this.refreshPage = 0
+    }
+  },
+  onLoad() {
+    this.init()
+  },
+  methods: {
+    resetSearch(){
+      this.searchTime = ''
+      this.startTime = ''
+      this.endTime = ''
+      this.resetList()
+      this.getRechargeList()      
+    },
+    selectDateFn(val) {
+      this.searchTime = val.searchTime
+      this.startTime = val.startTime
+      this.endTime = val.endTime
+      this.resetList()
+      this.getRechargeList()
+    },	
+    change(e) {
+      if (this.tabIndex != e.index) {
+        uni.pageScrollTo({
+          scrollTop: 0,
+          duration: 0
+        });
+        this.resetList();
+        this.list.finished = true;
+        this.tabIndex = e.index;
+        this.status = e.item.key;
+        this.getRechargeList().then(() => {
+          this.list.finished = false;
+        });
+      }
+    },
+    init() {
+      this.getRechargeList()
+    },
+    getRechargeList () {
+      return getRechargeList({ 
+        status: this.status,
+        page: this.list.page,
+        searchTime: this.searchTime,
+        startTime: this.startTime,
+        endTime: this.endTime
+      }).then(res => {
+        this.completes(res)
+        if (this.$util.isEmpty(res.data)){
+          return false
+        }
+      })
+    },
+    goToDetail (val) {
+      uni.navigateTo({ url: '/pages/recharge/detail?id=' + val.id })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.recharge-page {
+  .tabs {
+    height: 80upx;
+    line-height: 80upx;
+    & > view {
+      width: 50%;
+      text-align: center;
+      font-size: 28upx;
+      color: #666;
+      display: inline-block;
+    }
+    & > .active {
+      position: relative;
+      color: #3385ff;
+      font-weight: 700;
+    }
+    & > .active::after {
+      content: "";
+      position: absolute;
+      bottom: 0;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 70upx;
+      height: 6upx;
+      background: #3385ff;
+    }
+  }
+  .recharge_list {
+    padding-top: 20upx;
+    padding-bottom: 100upx;
+    background-color: #f0f2f6;
+  }
+}
+</style> 

+ 229 - 0
mallApp/src/pages/recharge/rechargeItem.vue

@@ -0,0 +1,229 @@
+<template>
+  <view class="recharge-item-view" @click="clickItemEvent">
+    <view class="item-header">
+      <view class="title">
+        <image class="icon" src="/static/images/recharge-icon.png" alt="" />
+        <text class="name">充值记录</text>
+      </view>
+      <view class="status" :class="getStatusClass">{{ getStatusName }}</view>
+    </view>
+    <view class="item-main">
+      <view class="item-info">
+        <view class="info-row">
+          <text class="info-label">充值时间:</text>
+          <text class="info-value">{{ info.createTime ? info.createTime.substring(5, 16) : '' }}</text>
+        </view>
+
+        <view class="info-row" v-if="info.payTime && info.payTime != '0000-00-00 00:00:00'">
+          <text class="info-label">支付时间:</text>
+          <text class="info-value">{{ info.payTime ? info.payTime.substring(5, 16) : '' }}</text>
+        </view>
+
+        <view class="info-row">
+          <text class="info-label">订单号:</text>
+          <text class="info-value">{{ info.orderSn }}</text>
+        </view>
+
+        <view class="info-row">
+          <text class="info-label">支付方式:</text>
+          <text class="info-value">{{ getPayMethodName }}</text>
+        </view>
+
+        <view class="info-row" v-if="info.remark">
+          <text class="info-label">备注:</text>
+          <text class="info-value">{{ info.remark }}</text>
+        </view>
+      </view>
+      <view class="item-price">
+        <view class="amount">¥{{ info.amount ? parseFloat(info.amount).toFixed(2) : '0.00' }}</view>
+        <text class="iconfont iconxiangyou"></text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    info: {
+      required: true
+    }
+  },
+  computed: {
+    getStatusName () {
+      let statusName = "";
+      switch (this.info.status) {
+        case '1':
+          statusName = "充值中";
+          break;
+        case '2':
+          statusName = "充值成功";
+          break;
+        case '3':
+          statusName = "充值失败";
+          break;
+        default:
+          statusName = "未知状态";
+          break;
+      }
+      return statusName;
+    },
+    getStatusClass () {
+      let statusClass = "";
+      switch (this.info.status) {
+        case '1':
+          statusClass = "status-processing";
+          break;
+        case '2':
+          statusClass = "status-success";
+          break;
+        case '3':
+          statusClass = "status-failed";
+          break;
+        default:
+          statusClass = "status-default";
+          break;
+      }
+      return statusClass;
+    },
+    getPayMethodName () {
+      let methodName = "";
+      switch (this.info.payMethod) {
+        case '1':
+          methodName = "微信支付";
+          break;
+        case '2':
+          methodName = "支付宝";
+          break;
+        case '3':
+          methodName = "余额支付";
+          break;
+        default:
+          methodName = "未知方式";
+          break;
+      }
+      return methodName;
+    }
+  },
+  methods: {
+    clickItemEvent () {
+      this.$emit("click", this.info);
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.recharge-item-view {
+  padding: 30upx 0;
+  margin-bottom: 20upx;
+  width: 100%;
+  background-color: #fff;
+  
+  .item-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20upx;
+    
+    .title {
+      display: flex;
+      align-items: center;
+      flex: 1;
+      
+      .icon {
+        margin: 0 20upx;
+        width: 50upx;
+        height: 50upx;
+        border-radius: 25upx;
+      }
+      
+      .name {
+        font-size: 32upx;
+        font-weight: 600;
+        color: #333333;
+      }
+    }
+    
+    .status {
+      flex-shrink: 0;
+      margin-right: 20upx;
+      padding: 5upx 12upx;
+      border-radius: 20upx;
+      font-size: 20upx;
+      
+      &.status-processing {
+        color: #ff9500;
+        border: 1px solid #ff9500;
+        background-color: #fff7e6;
+      }
+      
+      &.status-success {
+        color: #52c41a;
+        border: 1px solid #52c41a;
+        background-color: #f6ffed;
+      }
+      
+      &.status-failed {
+        color: #ff4d4f;
+        border: 1px solid #ff4d4f;
+        background-color: #fff2f0;
+      }
+      
+      &.status-default {
+        color: #999999;
+        border: 1px solid #999999;
+        background-color: #f5f5f5;
+      }
+    }
+  }
+  
+  .item-main {
+    display: flex;
+    padding: 0 20upx;
+    box-sizing: border-box;
+    align-items: flex-end;
+    
+    .item-info {
+      flex: 1;
+      font-size: 26upx;
+      
+      .info-row {
+        margin-top: 12upx;
+        display: flex;
+        align-items: center;
+      }
+      
+      .info-label {
+        font-weight: 400;
+        color: #999999;
+        min-width: 140upx;
+      }
+      
+      .info-value {
+        font-weight: 400;
+        color: #333333;
+        flex: 1;
+      }
+    }
+    
+    .item-price {
+      display: flex;
+      align-items: center;
+      flex-shrink: 0;
+      
+      .amount {
+        font-size: 32upx;
+        font-weight: 600;
+        color: #ff6b35;
+      }
+      
+      .iconfont {
+        font-size: 28upx;
+        color: #999999;
+        margin-left: 10upx;
+      }
+    }
+  }
+}
+</style>