linwenxin vor 8 Monaten
Ursprung
Commit
841bf18a3d

+ 364 - 0
src/packageMaterial/pages/newSale/index.vue

@@ -0,0 +1,364 @@
+<template>
+  <!-- #ifdef H5 -->
+  <zj-page-layout :hasFooter="true">
+    <view class="form-container">
+      <view class="item" v-if="type == 'P'" @tap="isShowCategoryDialog = true">
+        <view class="label"><text>*</text>产品大类</view>
+        <view class="picker">
+          <text class="value" v-if="category">{{ category.name }}</text>
+          <text class="placeholder" v-else>请选择</text>
+          <text class="iconfont icon-jinru"></text>
+        </view>
+      </view>
+      <u-gap height="10" bgColor="#F7F8FF"></u-gap>
+      <view class="item">
+        <view class="label"><text>*</text>客户电话</view>
+        <u--input :maxlength="11" placeholder="请输入" border="none" inputAlign="right" v-model="userMobile"></u--input>
+      </view>
+      <view class="item">
+        <view class="label">工单单号</view>
+        <u--input :readonly="hasOid" placeholder="请输入" border="none" inputAlign="right" v-model="orderNo"></u--input>
+      </view>
+      <view class="item" @tap="hasOid ? '' : (isShowWebsitDialog = true)">
+        <view class="label"><text>*</text>所属网点</view>
+        <view class="picker">
+          <text class="value" v-if="websit">{{ websit.name }}</text>
+          <text class="placeholder" v-else>请选择工单所属网点</text>
+          <text class="iconfont icon-jinru"></text>
+        </view>
+      </view>
+      <!-- ------------------------------------ -->
+      <view v-for="(item, index) in peijianList" :key="index">
+        <u-gap height="10" bgColor="#F7F8FF"></u-gap>
+        <view class="item">
+          <view class="label" style="font-weight: bold">配件信息{{ index + 1 }}</view>
+          <view class="label" style="color: red; margin-right: 10rpx" @click="delpeijian(index)">删除</view>
+        </view>
+        <view class="item">
+          <view class="label"><text>*</text>是否质量问题</view>
+          <u--input
+            :maxlength="11"
+            placeholder="请输入"
+            border="none"
+            inputAlign="right"
+            v-model="userMobile"
+          ></u--input>
+        </view>
+        <view class="item">
+          <view class="label"><text>*</text>旧配件编号</view>
+          <u--input
+            :readonly="hasOid"
+            placeholder="请输入"
+            border="none"
+            inputAlign="right"
+            v-model="orderNo"
+          ></u--input>
+        </view>
+        <view class="item">
+          <view class="label"><text>*</text>旧配件名称</view>
+          <u--input
+            :readonly="hasOid"
+            placeholder="请输入"
+            border="none"
+            inputAlign="right"
+            v-model="orderNo"
+          ></u--input>
+        </view>
+        <view class="item" @tap="toChooseProduct(index)">
+          <view class="label"><text>*</text>新配件名称</view>
+          <view class="picker">
+            <text class="value" v-if="item">{{ item.name }}</text>
+            <text class="placeholder" v-else>选择产品</text>
+            <text class="iconfont icon-jinru"></text>
+          </view>
+        </view>
+        <view class="item">
+          <view class="label"><text>*</text>新配件编号</view>
+          <u--input
+            :readonly="hasOid"
+            placeholder="请输入"
+            border="none"
+            inputAlign="right"
+            v-model="orderNo"
+          ></u--input>
+        </view>
+      </view>
+      <u-gap height="10" bgColor="#F7F8FF"></u-gap>
+      <u-button class="btnloukong" text="添加配件" @click="addpeijian"></u-button>
+      <u-gap height="10" bgColor="#F7F8FF"></u-gap>
+    </view>
+
+    <template slot="footer">
+      <view class="footer-btn-group">
+        <u-button
+          text="历史记录"
+          @click="$navToPage({ url: `/packageMaterial/pages/sale/orderList?type=${type}` })"
+        ></u-button>
+        <u-button type="primary" text="提交" @click="submitData"></u-button>
+      </view>
+    </template>
+
+    <zjDialogPicker
+      ref="brandDialog"
+      :isShow="isShowBrandDialog"
+      :multiple="false"
+      :styleType="2"
+      :title="'品牌'"
+      :list="brandList"
+      :keyName="'brandName'"
+      @cancel="isShowBrandDialog = false"
+      @confirm="confirmBrandDialog"
+    >
+    </zjDialogPicker>
+
+    <zjDialogPicker
+      ref="categoryDialog"
+      :isShow="isShowCategoryDialog"
+      :multiple="false"
+      :styleType="2"
+      :title="'产品大类'"
+      :list="categoryList"
+      :keyName="'name'"
+      @cancel="isShowCategoryDialog = false"
+      @confirm="confirmCategoryDialog"
+    >
+    </zjDialogPicker>
+
+    <zjDialogPicker
+      ref="websitDialog"
+      :isShow="isShowWebsitDialog"
+      :multiple="false"
+      :styleType="2"
+      :title="'所属网点'"
+      :list="websitList"
+      :keyName="'name'"
+      @cancel="isShowWebsitDialog = false"
+      @confirm="confirmWebsitDialog"
+    >
+    </zjDialogPicker>
+  </zj-page-layout>
+  <!-- #endif -->
+
+  <!-- #ifndef H5 -->
+  <web-view
+    :src="webViewHref(`/packageMaterial/pages/sale/index`, pam, crossPagePam)"
+    @message="crossPage.$listener"
+  ></web-view>
+  <!-- #endif -->
+</template>
+
+<script>
+ // #ifdef H5
+import zjDialogPicker from "@/components/zj-dialog/zj-dialog-picker.vue";
+
+ export default {
+   components: {
+   	zjDialogPicker
+   },
+
+   data() {
+     return {
+       hasOid: false,
+       wbId: null, // 维保工单
+       wbIsAllFee: null, // 维保工单是否包含全部费用
+       wbPayType: null, // 维保工单费用支付方式
+       type: 'M',
+       userMobile: '',
+       orderNo: '',
+       salesType: 'OUT',
+       brand: null,
+       brandList: [],
+       isShowBrandDialog: false,
+       category: null,
+       categoryList: [],
+       isShowCategoryDialog: false,
+       websit: null,
+       websitList: [],
+       isShowWebsitDialog: false,
+       peijianList:[]
+     }
+   },
+
+   onLoad({type, oid = ''}) {
+     this.type = type;
+     this.hasOid = oid.length > 0;
+     uni.setNavigationBarTitle({
+      title: type == 'M' ? '辅材收款' : '配件收款'
+     })
+     this.getBrandList();
+     this.getWebsitList();
+     if(type == 'P') {
+       this.getCategoryList();
+     }
+     if(this.hasOid) {
+       this.$api.post('/pg/order/base/detail', {
+         orderBaseId: oid,
+       }).then((res) => {
+         const data = res.data;
+         this.orderNo = oid;
+         this.userMobile = data.userMobile;
+         this.websit = {
+           websitId: data.websitId,
+           name: data.websitName,
+         }
+         if(data.pgOrderProducts && data.pgOrderProducts.length > 0) {
+           this.brand = {
+             id: data.pgOrderProducts[0].brandId,
+             brandName: data.pgOrderProducts[0].brandName
+           }
+         }
+         this.wbId = data.rpProjectRepairId || '';
+         this.wbIsAllFee = data.isAllFee || '';
+         this.wbPayType = data.feePayMethod || '';
+       })
+     }
+  },
+
+  onShow() {
+    var data = this.$getStorage('materialSaleData')
+    if (data.dijiIndex !== undefined && this.peijianList[data.dijiIndex]) {
+      console.log(data)
+    }
+    this.$removeStorage('materialSaleData')
+  },
+
+  methods: {
+    addpeijian() {
+      this.peijianList.push({})
+    },
+
+    delpeijian(index) {
+      this.peijianList.splice(index, 1)
+    },
+
+     getBrandList() {
+       this.$api.post('/pay/getBrand')
+       .then(res => {
+         this.brandList = res.data;
+       })
+     },
+
+     getCategoryList() {
+       this.$api.post('/pay/getCategoryList')
+       .then(res => {
+         this.categoryList = res.data;
+       })
+     },
+
+     getWebsitList() {
+       this.$api.get('/user/apply/websit')
+       .then(res => {
+         this.websitList = res.data;
+       })
+     },
+
+     confirmBrandDialog(e) {
+       this.brand = this.brandList[e[0]];
+       this.isShowBrandDialog = false;
+     },
+
+     confirmCategoryDialog(e) {
+       this.category = this.categoryList[e[0]];
+       this.isShowCategoryDialog = false;
+     },
+
+     confirmWebsitDialog(e) {
+       this.websit = this.websitList[e[0]];
+       this.isShowWebsitDialog = false;
+     },
+
+    toChooseProduct(index) {
+      if(this.type == 'P' && !this.category) return this.$toast('请选择产品大类');
+      if(!this.websit) return this.$toast('请选择所属网点');
+      if(!this.userMobile) return this.$toast('请输入客户电话');
+      if(!(/^1[3456789]\d{9}$/.test(this.userMobile)) || this.userMobile.length != 11) return this.$toast('请填写正确的客户电话');
+      this.$navToPage({
+        url: `/packageMaterial/pages/sale/product?dijiIndex=${index}&type=${this.type}&categoryId=${this.type=='P'?this.category.categoryId:''}&categoryName=${this.type=='P'?this.category.name:''}&userMobile=${this.userMobile}&orderNo=${this.orderNo}&websitId=${this.websit.websitId}&websitName=${this.websit.name}&wbId=${this.wbId||''}&wbIsAllFee=${this.wbIsAllFee||''}&wbPayType=${this.wbPayType||''}`
+      })
+    },
+
+    submitData() {
+      if(this.peijianList.length < 1) return this.$toast('请选择');
+      this.$setStorage('materialSaleDataZhiFu', {
+        type: this.type,
+        categoryId: this.type == 'P' ? this.category.categoryId : '',
+        categoryName: this.type == 'P' ? this.category.name : '',
+        salesType: 'OUT',
+        brandId: null,
+        brandName: null,
+        websitId: this.websit.websitId,
+        websitName: this.websit.websitName,
+        userMobile: this.userMobile,
+        orderNo: this.orderNo,
+        wbId: this.wbId,
+        wbIsAllFee: this.wbIsAllFee,
+        wbPayType: this.wbPayType,
+        goodsList: this.peijianList
+      });
+      this.$navToPage({
+        url: `/packageMaterial/pages/sale/order`
+      })
+    },
+  },
+}
+
+ // #endif
+ // #ifndef H5
+ export default {
+   data() {
+     return {
+       pam: {},
+     }
+   },
+   onLoad(pam) {
+     this.pam = pam;
+   }
+ }
+ // #endif
+</script>
+
+<style lang="scss" scoped>
+.form-container {
+  background: #ffffff;
+  margin-top: 20rpx;
+  border-top: 1px solid #f5f5f5;
+  .btnloukong {
+    height: 72rpx;
+    border: 2rpx solid #005ef4;
+    margin: 0;
+    background: transparent;
+    font-size: 28rpx;
+    line-height: 72rpx;
+    color: #0268fa;
+  }
+  .item {
+    height: 108rpx;
+    border-bottom: 1px solid #f5f5f5;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 20rpx;
+    .label {
+      margin-right: 30rpx;
+      text {
+        color: $error-color;
+      }
+    }
+    .picker {
+      .placeholder {
+        color: $sec-font;
+      }
+      .iconfont {
+        margin-left: 12rpx;
+        color: $sec-font;
+      }
+    }
+    ::v-deep .u-radio-group {
+      flex: unset;
+      .u-radio {
+        margin-left: 50rpx;
+      }
+    }
+  }
+}
+</style>

+ 368 - 0
src/packageMaterial/pages/newSale/order.vue

@@ -0,0 +1,368 @@
+<template>
+  <!-- #ifdef H5 -->
+  <zj-page-layout :hasFooter="true">
+    <view class="all-container">
+      <view class="common-title">产品信息</view>
+      <view class="product-container card">
+        <view class="it" v-for="(item, index) in goodsList" :key="index">
+          <view class="name"
+            >{{ item.goodsName }}<text>×{{ item.num }}{{ item.goodsUnit }}</text></view
+          >
+          <view class="price">¥{{ (item.goodsAmount * item.num) | priceFilter }}</view>
+        </view>
+        <view class="total">
+          <view class="text">合计:</view>
+          <view class="price">¥{{ totalPrice | priceFilter }}</view>
+        </view>
+      </view>
+
+      <block v-if="type == 'P' && serviceList.length > 0">
+        <view class="common-title">服务费用</view>
+        <view class="form-container card">
+          <view class="item" v-for="(item, index) in serviceList" :key="index">
+            <view class="label"
+              >{{ item.goodsName }}<text>×{{ item.num }}</text></view
+            >
+            <u--input placeholder="请输入单价" border="none" inputAlign="right" v-model="item.goodsAmount"></u--input>
+          </view>
+          <view class="total">
+            <view class="text">合计:</view>
+            <view class="price">¥{{ totalServicePrice | priceFilter }}</view>
+          </view>
+        </view>
+      </block>
+
+      <view class="common-title">备注</view>
+      <view class="remark-container card">
+        <u--textarea v-model="remark" placeholder="请输入内容" border="none" autoHeight></u--textarea>
+      </view>
+    </view>
+
+    <template slot="footer">
+      <view class="bottom-container">
+        <view class="left">
+          <view class="text">共{{ totalNum }}件,合计:</view>
+          <view class="price" v-if="type == 'P' && serviceList.length > 0"
+            >¥{{ (totalPrice + totalServicePrice) | priceFilter }}</view
+          >
+          <view class="price" v-else>¥{{ totalPrice | priceFilter }}</view>
+        </view>
+        <view class="btn">
+          <u-button
+            type="primary"
+            text="确认订单"
+            @click="submitData(1)"
+            v-if="!wbId || (wbId && wbIsAllFee == 'NO' && wbPayType == 'SITE')"
+          ></u-button>
+          <u-button type="primary" text="提交申请" @click="submitData(2)" v-else></u-button>
+        </view>
+      </view>
+    </template>
+  </zj-page-layout>
+  <!-- #endif -->
+
+  <!-- #ifndef H5 -->
+  <web-view
+    :src="webViewHref(`/packageMaterial/pages/sale/order`, pam, crossPagePam)"
+    @message="crossPage.$listener"
+  ></web-view>
+  <!-- #endif -->
+</template>
+
+<script>
+// #ifdef H5
+export default {
+  data() {
+    return {
+      type: 'M',
+      userMobile: '',
+      orderNo: '',
+      // salesType: 'OUT',
+      salesType: null,
+      brandId: null,
+      brandName: null,
+      categoryId: null,
+      categoryName: null,
+      websitId: null,
+      websitName: null,
+      wbId: null, // 维保工单
+      wbIsAllFee: null, // 维保工单是否包含全部费用
+      wbPayType: null, // 维保工单费用支付方式
+      goodsList: [],
+      serviceList: [],
+
+      remark: '',
+    }
+  },
+
+  computed: {
+    totalNum() {
+      // let val = 0;
+      // this.goodsList.forEach(item => {
+      //   val = val + item.num;
+      // })
+      return this.goodsList.length;
+    },
+    totalPrice() {
+      let val = 0;
+      this.goodsList.forEach(item => {
+        val = val + (item.num * (item.goodsAmount * 100) / 100);
+      })
+      return  val;
+    },
+    totalServicePrice() {
+      let val = 0;
+      this.serviceList.forEach(item => {
+        val = val + (item.num * (item.goodsAmount * 100) / 100);
+      })
+      return  val;
+    },
+  },
+
+  onLoad() {
+    let data = this.$getStorage('materialSaleData');
+    if(data) {
+      this.type = data.type;
+      this.userMobile = data.userMobile;
+      this.orderNo = data.orderNo;
+      // this.salesType = data.salesType;
+      // this.brandId = data.brandId;
+      // this.brandName = data.brandName;
+      this.categoryId = data.categoryId;
+      this.categoryName = data.categoryName;
+      this.websitId = data.websitId;
+      this.websitName = data.websitName;
+      this.wbId = data.wbId;
+      this.wbIsAllFee = data.wbIsAllFee;
+      this.wbPayType = data.wbPayType;
+      if(this.type == 'P') {
+        this.goodsList = data.goodsList.filter(o => o.normType == 'M');
+        this.serviceList = data.goodsList.filter(o => o.normType == 'S');
+        this.serviceList.forEach(o => {
+          o.goodsAmount = '';
+        })
+      }else {
+        this.goodsList = data.goodsList;
+      }
+    }
+    this.$removeStorage('materialSaleData');
+
+  },
+
+  methods: {
+    confirmPartsDialog(e) {
+      this.parts = this.partsList[e[0]];
+      this.isShowPartsDialog = false;
+    },
+
+    submitData(type) {
+      let serviceList = JSON.parse(JSON.stringify(this.serviceList));
+      if(this.type == 'P') {
+        for(let i = 0; i < serviceList.length; i++) {
+          if(!serviceList[i].goodsAmount && serviceList[i].goodsAmount !== 0) {
+            return this.$toast('请输入服务费用价格');
+          }
+        }
+        serviceList.forEach(item => {
+          item.normAmount = Number(item.goodsAmount);
+        })
+      }
+      let goodsList = [
+        ...JSON.parse(JSON.stringify(this.goodsList)),
+        ...serviceList
+      ];
+
+      let url = '', params = {};
+      if(type == 1) {
+        if(this.wbId) {
+          url = '/engin/material/buy';
+          params.rpMaterialOrderItemList = goodsList;
+        }else {
+          url = '/pay/buy';
+          params.workerOrderItems = goodsList;
+        }
+      }
+      else {
+        url = '/engin/material/apply';
+        params.rpMaterialOrderItemList = goodsList;
+      }
+
+      this.$api.postJson(url, {
+        // brand: this.brandName,
+        settlementType: this.salesType,
+        goodsType: this.type,
+        remark: this.remark,
+        userMobile: this.userMobile,
+        workerOrderId: this.orderNo,
+        categoryId: this.categoryId || '',
+        categoryName: this.categoryName || '',
+        websitId: this.websitId,
+        websitName: this.websitName,
+        ...params,
+      }).then(res => {
+        if(type == 1) {
+          this.$navToPage({
+            url: `/packageMaterial/pages/sale/pay?handleOrderId=${res.data}&wbId=${this.wbId}`
+          })
+        } else {
+          this.$successToast();
+          setTimeout(() => {
+            this.$navToPage({
+              url: `/packageHome/pages/maintenance/applyList`
+            }, 'reLaunch')
+          }, 500)
+        }
+      })
+    },
+  },
+}
+
+// #endif
+// #ifndef H5
+export default {
+  data() {
+    return {
+      pam: {},
+    }
+  },
+  onLoad(pam) {
+    this.pam = pam;
+  }
+}
+// #endif
+</script>
+
+<style lang="scss" scoped>
+.all-container {
+  padding: 0 20rpx;
+}
+.common-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  margin-top: 30rpx;
+}
+.card {
+  @include zj-card;
+  margin-top: 20rpx;
+  padding: 30rpx;
+}
+.product-container {
+  .it {
+    display: flex;
+    align-items: flex-end;
+    margin-bottom: 20rpx;
+    .name {
+      flex: 1;
+      font-size: 28rpx;
+      font-weight: 500;
+      text {
+        color: $sec-font;
+        margin-left: 12rpx;
+        font-weight: normal;
+      }
+    }
+    .price {
+      margin-left: 30rpx;
+      font-size: 28rpx;
+      font-weight: 500;
+    }
+  }
+  .total {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 30rpx;
+    .text {
+      font-size: 28rpx;
+      color: $sec-font;
+    }
+    .price {
+      font-size: 28rpx;
+      color: $minor-color;
+      font-weight: 500;
+    }
+  }
+}
+
+.remark-container {
+  padding: 0;
+  ::v-deep .u-textarea {
+    padding: 20rpx 30rpx;
+    min-height: 200rpx;
+  }
+}
+
+.form-container {
+  .item {
+    height: 50rpx;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 30rpx;
+    &:first-child {
+      margin-top: 0;
+    }
+    .label {
+      margin-right: 30rpx;
+      flex-shrink: 0;
+      text {
+        color: $sec-font;
+        margin-left: 12rpx;
+        font-weight: normal;
+      }
+    }
+    .picker {
+      display: flex;
+      align-items: center;
+      .placeholder {
+        color: $sec-font;
+      }
+      .iconfont {
+        margin-left: 12rpx;
+        color: $sec-font;
+      }
+    }
+    .value {
+      flex: 1;
+      text-align: right;
+    }
+  }
+  .total {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 30rpx;
+    .text {
+      font-size: 28rpx;
+      color: $sec-font;
+    }
+    .price {
+      font-size: 28rpx;
+      color: $minor-color;
+      font-weight: 500;
+    }
+  }
+}
+.bottom-container {
+  padding: 20rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .left {
+    display: flex;
+    align-items: center;
+    .text {
+      font-size: 28rpx;
+      color: $sec-font;
+    }
+    .price {
+      font-size: 32rpx;
+      color: $minor-color;
+      font-weight: 500;
+    }
+  }
+  .btn {
+    width: 180rpx;
+  }
+}
+</style>

+ 310 - 0
src/packageMaterial/pages/newSale/orderDetail.vue

@@ -0,0 +1,310 @@
+<template>
+  <!-- #ifdef H5 -->
+  <view class="all-container">
+    <view class="bg"></view>
+    <Loading
+    	:type="3"
+    	:loadStatus="loadStatus"
+    	:showText="errorText"
+    />
+    <zj-page-layout
+      v-if="detail"
+      :hasFooter="true"
+      :isScroll="true"
+      :refresherTriggered="refresherTriggered"
+      @refresherrefresh="refresherrefresh">
+      <view class="content-container">
+        <view class="status-container">{{detail.payStatus | statusFilter}}</view>
+        <view class="product-container card">
+          <view class="title">产品信息</view>
+          <view class="product">
+            <view class="it" v-for="(item, index) in detail.workerOrderItems" :key="index">
+              <view class="name">{{item.goodsName}}<text>×{{item.num}}{{item.unit}}</text></view>
+              <view class="price">¥{{item.totalAmount | priceFilter}}</view>
+            </view>
+            <view class="total">
+              <view class="text">合计:</view>
+              <view class="price">¥{{detail.totalAmount | priceFilter}}</view>
+            </view>
+          </view>
+        </view>
+        <view class="info-container card">
+          <view class="title">下单信息</view>
+          <view class="row">
+            <view class="label">订单单号</view>
+            <view class="value">{{detail.orderId}}</view>
+            <view class="tag" @tap="$copy(detail.orderId)">复制</view>
+          </view>
+          <view class="row">
+            <view class="label">关联工单</view>
+            <view class="value">{{detail.workerOrderId}}</view>
+            <view class="tag" @tap="$copy(detail.workerOrderId)">复制</view>
+          </view>
+          <view class="row">
+            <view class="label">客户电话</view>
+            <view class="value">{{detail.userMobile}}</view>
+          </view>
+          <view class="row">
+            <view class="label">销售方式</view>
+            <view class="value">{{detail.settlementType | salesTypeFilter}}</view>
+          </view>
+          <view class="row">
+            <view class="label">所属网点</view>
+            <view class="value">{{detail.websitName}}</view>
+          </view>
+          <view class="row">
+            <view class="label">下单人员</view>
+            <view class="value">{{detail.workerName}}</view>
+          </view>
+          <view class="row">
+            <view class="label">下单时间</view>
+            <view class="value">{{detail.createTime}}</view>
+          </view>
+          <view class="row">
+            <view class="label">支付方式</view>
+            <view class="value">{{detail.payType | payTypeFilter}}</view>
+          </view>
+          <view class="row">
+            <view class="label">备注信息</view>
+            <view class="value">{{detail.remark}}</view>
+          </view>
+        </view>
+      </view>
+      <template slot="footer">
+        <view class="bottom-container" v-if="detail.payStatus == 'WAIT'">
+          <view class="left"></view>
+          <view class="right">
+            <u-button text="取消订单" @click="cancelOrder"></u-button>
+          </view>
+        </view>
+      </template>
+    </zj-page-layout>
+  </view>
+  <!-- #endif -->
+
+  <!-- #ifndef H5 -->
+  <web-view :src="webViewHref(`/packageMaterial/pages/sale/orderDetail`, pam, crossPagePam)" @message="crossPage.$listener"></web-view>
+  <!-- #endif -->
+</template>
+
+<script>
+  // #ifdef H5
+  export default {
+    filters: {
+      statusFilter(val) {
+        const MAP = {
+          WAIT: '待支付',
+          PAID: '已支付',
+          CANCEL: '已取消',
+        }
+        return MAP[val];
+      },
+      salesTypeFilter(val) {
+        const MAP = {
+          OWN: '自有出库',
+          OUT: '外购销售',
+        }
+        return MAP[val];
+      },
+      payTypeFilter(val) {
+        const MAP = {
+          WECHAT: '微信支付',
+          LINE: '线下支付',
+        }
+        return MAP[val];
+      }
+    },
+
+    data() {
+      return {
+        id: null,
+        refresherTriggered: false,
+        loadStatus: 0,
+				errorText: '',
+        detail: null,
+      }
+    },
+
+    onLoad({id}) {
+      this.id = id;
+      this.getDetail();
+    },
+
+    methods: {
+      getDetail() {
+        this.$api.post('/pay/getOrder', {
+          orderId: this.id
+        }).then(res => {
+          this.detail = res.data;
+          this.loadStatus = 0;
+        }).catch(res => {
+      		this.errorText = res.message;
+      		this.loadStatus = 2;
+      	}).finally(res => {
+      		this.refresherTriggered = false;
+      	})
+      },
+
+      // 下拉刷新
+      refresherrefresh() {
+        this.refresherTriggered = true;
+        this.getDetail();
+      },
+
+      // 取消订单
+      cancelOrder() {
+        this.$modal({
+          content: '确认取消订单吗?'
+        }).then(() => {
+          this.$api.post('/pay/cancel', {
+            orderId: this.id
+          }).then(res => {
+            this.$successToast();
+            this.getDetail();
+          })
+        }).catch(() => {})
+      }
+    },
+  }
+
+  // #endif
+  // #ifndef H5
+  export default {
+    data() {
+      return {
+        pam: {},
+      }
+    },
+    onLoad(pam) {
+      this.pam = pam;
+    }
+  }
+  // #endif
+</script>
+
+<style lang="scss" scoped>
+.all-container {
+  position: relative;
+}
+.bg {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 300rpx;
+  background: linear-gradient(179.48deg, rgba(200,224,251,1) 0.45%,rgba(247,247,247,1) 98.96%);
+}
+.card {
+  @include zj-card;
+  margin-top: 30rpx;
+  padding: 30rpx;
+  .title {
+    font-size: 32rpx;
+    font-weight: 600;
+  }
+}
+.content-container {
+  padding: 20rpx;
+}
+.status-container {
+  font-size: 36rpx;
+  font-weight: 500;
+  margin-left: 30rpx;
+  text {
+    margin-left: 12rpx;
+  }
+}
+.product-container {
+  .title {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .left {
+      font-size: 32rpx;
+      font-weight: 600;
+    }
+    .right {
+      font-size: 28rpx;
+      color: $theme-color;
+    }
+  }
+  .product {
+    background: #f5f5f5;
+    border-radius: 12rpx;
+    padding: 20rpx;
+    margin-top: 20rpx;
+    .it {
+      display: flex;
+      align-items: flex-end;
+      margin-bottom: 20rpx;
+      .name {
+        flex: 1;
+        font-size: 28rpx;
+        font-weight: 500;
+        text {
+          color: $sec-font;
+          margin-left: 12rpx;
+          font-weight: normal;
+        }
+      }
+      .price {
+        margin-left: 30rpx;
+        font-size: 28rpx;
+        font-weight: 500;
+      }
+    }
+    .total {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      margin-top: 30rpx;
+      .text {
+        font-size: 28rpx;
+        color: $sec-font;
+      }
+      .price {
+        font-size: 28rpx;
+        color: $minor-color;
+        font-weight: 500;
+      }
+    }
+  }
+}
+.info-container {
+  .row {
+    display: flex;
+    align-items: center;
+    margin-top: 20rpx;
+    .label {
+      font-size: 28rpx;
+      color: $sec-font;
+      margin-right: 20rpx;
+    }
+    .value {
+      flex: 1;
+      font-size: 28rpx;
+      text {
+        color: $minor-color;
+      }
+      &.price {
+        color: $theme-color;
+      }
+    }
+    .tag {
+      font-size: 28rpx;
+      color: $theme-color;
+    }
+  }
+}
+.bottom-container {
+  padding: 20rpx;
+  display: flex;
+  justify-content: space-between;
+  .right {
+    display: flex;
+    ::v-deep .u-button {
+      margin-left: 20rpx;
+    }
+  }
+}
+</style>

+ 376 - 0
src/packageMaterial/pages/newSale/orderList.vue

@@ -0,0 +1,376 @@
+<template>
+  <!-- #ifdef H5 -->
+  <zj-page-layout
+    :isScroll="true"
+    :refresherTriggered="refresherTriggered"
+    @refresherrefresh="refresherrefresh"
+    @scrolltolower="scrolltolower"
+  >
+    <template slot="header">
+      <view class="tab-container">
+        <u-tabs
+          :scrollable="false"
+          :list="tabList"
+          :current="tabCurrent"
+          @click="changeTab"
+          lineColor="#3D8FFD"
+          :activeStyle="{
+            color: '#3D8FFD'
+          }"
+          :inactiveStyle="{
+            color: '#666666'
+          }"
+          itemStyle="padding-left: 0; padding-right: 0; height: 88rpx;"
+        >
+        </u-tabs>
+      </view>
+      <view class="screen-container">
+        <!-- <u-tabs
+      		:scrollable="true"
+      		:list="salesTypeList"
+      		:current="salesTypeCurrent"
+      		@click="changeSalesType"
+      		lineColor="#3D8FFD"
+      		:activeStyle="{
+      			color: '#3D8FFD'
+      		}"
+      		:inactiveStyle="{
+      			color: '#666666'
+      		}"
+      		itemStyle="height: 88rpx;">
+      	</u-tabs> -->
+        <view></view>
+        <view class="date" @tap="isShowDatePicker = true">
+          <view class="text">{{ date || '请选择月份' }}</view>
+          <u-icon name="arrow-down" size="12"></u-icon>
+        </view>
+      </view>
+    </template>
+
+    <view class="list-container">
+      <view class="item" v-for="(item, index) in dataList" :key="index" @tap="toDetail(item)">
+        <view class="row top">
+          <view class="label">制单时间</view>
+          <view class="value">{{ item.createTime }}</view>
+          <view class="status" v-if="item.refundStatus == 'YES'">已退款</view>
+          <view class="status" v-else>{{ item.payStatus | statusFilter }}</view>
+        </view>
+        <view class="row">
+          <view class="label">订单单号</view>
+          <view class="value">{{ item.orderId }}</view>
+          <view class="tag">{{ item.goodsType == 'M' ? '辅材' : '配件' }}</view>
+        </view>
+        <view class="row">
+          <view class="label">关联工单</view>
+          <view class="value">{{ item.workerOrderId }}</view>
+        </view>
+        <view class="row">
+          <view class="label">客户电话</view>
+          <view class="value">{{ item.userMobile }}</view>
+        </view>
+        <!-- <view class="row">
+          <view class="label">销售方式</view>
+          <view class="value">{{ item.settlementType | salesTypeFilter }}</view>
+        </view> -->
+        <view class="row">
+          <view class="label">产品数量</view>
+          <view class="value">{{ item.num }}</view>
+        </view>
+        <view class="row">
+          <view class="label">订单金额</view>
+          <view class="value price">{{ item.totalAmount | priceFilter }}元</view>
+        </view>
+        <view class="btns" v-if="item.payStatus == 'WAIT'" @tap.stop>
+          <u-button text="取消订单" @click="cancelOrder(item)"></u-button>
+        </view>
+      </view>
+    </view>
+    <Loading :loadStatus="loadStatus" :dataList="dataList" />
+
+    <u-datetime-picker
+      :show="isShowDatePicker"
+      v-model="datePickerValue"
+      mode="year-month"
+      cancelText="重置"
+      closeOnClickOverlay
+      @cancel="resetDate"
+      @close="isShowDatePicker = false"
+      @confirm="confirmDate"
+    ></u-datetime-picker>
+  </zj-page-layout>
+  <!-- #endif -->
+
+  <!-- #ifndef H5 -->
+  <web-view
+    :src="webViewHref(`/packageMaterial/pages/sale/orderList`, pam, crossPagePam)"
+    @message="crossPage.$listener"
+  ></web-view>
+  <!-- #endif -->
+</template>
+
+<script>
+// #ifdef H5
+export default {
+  filters: {
+    statusFilter(val) {
+      const MAP = {
+        WAIT: '待支付',
+        PAID: '已支付',
+        CANCEL: '已取消',
+      }
+      return MAP[val];
+    },
+    salesTypeFilter(val) {
+      const MAP = {
+        OWN: '自有出库',
+        OUT: '外购销售',
+      }
+      return MAP[val];
+    },
+  },
+
+  data() {
+    return {
+      type: 'M',
+		dataList: [],
+		pageNum: 1,
+		loadStatus: 0,
+      refresherTriggered: false,
+      tabList: [
+        {name: '全部', value: '', badge: {value: 0}},
+        {name: '待支付', value: 'WAIT', badge: {value: 0}},
+        {name: '已支付', value: 'PAID', badge: {value: 0}},
+        {name: '已取消', value: 'CANCEL', badge: {value: 0}},
+      ],
+      tabCurrent: 0,
+      status: '',
+      salesTypeList: [
+        {name: '全部', value: ''},
+        {name: '自有仓库', value: 'OWN'},
+        {name: '外购销售', value: 'OUT'},
+      ],
+      salesTypeCurrent: 0,
+      salesType: '',
+      isShowDatePicker: false,
+      datePickerValue: Number(new Date()),
+      date: '',
+    }
+  },
+
+  onLoad({type}) {
+    this.type = type;
+    this.getCount();
+    this.getList();
+  },
+
+  methods: {
+    getCount() {
+    	this.$api.post('/pay/orderCount', {
+        goodsType: this.type,
+      }).then(res => {
+        if(!res.data) return false;
+    		this.tabList[0].badge.value = res.data.qb || 0;
+    		this.tabList[1].badge.value = res.data.dzf || 0;
+    		this.tabList[2].badge.value = res.data.yzf || 0;
+    		this.tabList[3].badge.value = res.data.yqx || 0;
+    	})
+    },
+
+    getList() {
+    	this.loadStatus = 1;
+    	this.$api.post('/pay/orderPage', {
+        pageNum: this.pageNum,
+        pageSize: 10,
+        payStatus: this.status,
+        yearMonth: this.date,
+        goodsType: this.type,
+        settlementType: this.salesType
+    	}).then(res => {
+    		this.loadStatus = 0;
+    		let list = res.data.records;
+    		if (list.length < 10) {
+    		  this.loadStatus = 2;
+    		}
+    		this.dataList = this.dataList.concat(list);
+    	}).catch(() => {
+    		this.loadStatus = 2;
+    	}).finally(res => {
+    		this.refresherTriggered = false;
+    	})
+    },
+
+    changeTab(e) {
+    	this.tabCurrent = e.index;
+    	this.status = e.value;
+      this.refreshList();
+    },
+
+    changeSalesType(e) {
+      this.salesTypeCurrent = e.index;
+      this.salesType = e.value;
+      this.refreshList();
+    },
+
+    resetDate() {
+      this.isShowDatePicker = false;
+      this.date = '';
+      this.refreshList();
+    },
+
+    confirmDate(e) {
+      this.isShowDatePicker = false;
+      let time = new Date(e.value)
+      let y = time.getFullYear();
+      let m = (time.getMonth()+1) < 10 ? '0' + (time.getMonth()+1) : time.getMonth()+1;
+      this.date = `${y}-${m}`;
+      this.refreshList();
+    },
+
+    refreshList() {
+    	this.dataList = [];
+    	this.pageNum = 1;
+    	this.getList();
+    },
+
+    // 滚动到底部
+    scrolltolower(e) {
+    	if (this.loadStatus === 0) {
+    		this.pageNum++;
+    		this.getList();
+    	}
+    },
+
+    // 触发下拉刷新
+    refresherrefresh(e) {
+    	this.refresherTriggered = true;
+      this.getCount();
+    	this.refreshList();
+    },
+
+    toDetail(item) {
+      this.$navToPage({
+        url: `/packageMaterial/pages/sale/orderDetail?id=${item.orderId}`
+      })
+    },
+
+    // 取消订单
+    cancelOrder(item) {
+      this.$modal({
+        content: '确认取消订单吗?'
+      }).then(() => {
+        this.$api.post('/pay/cancel', {
+          orderId: item.orderId
+        }).then(res => {
+          this.$successToast();
+          this.getCount();
+          this.refreshList();
+        })
+      }).catch(() => {})
+    },
+  },
+}
+
+// #endif
+// #ifndef H5
+export default {
+  data() {
+    return {
+      pam: {},
+    }
+  },
+  onLoad(pam) {
+    this.pam = pam;
+  }
+}
+// #endif
+</script>
+
+<style lang="scss" scoped>
+.tab-container {
+  background: #ffffff;
+}
+.screen-container {
+  margin-top: 1px;
+  background: #ffffff;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 20rpx;
+  ::v-deep .u-tabs {
+    flex: 1;
+  }
+  .date {
+    width: 180rpx;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-left: 40rpx;
+    padding: 0 12rpx 0 20rpx;
+    border: 1px solid #eaeaea;
+    border-radius: 8rpx;
+    height: 52rpx;
+    .text {
+      font-size: 28rpx;
+    }
+  }
+}
+
+.list-container {
+  padding: 0 20rpx;
+  .item {
+    @include zj-card;
+    margin-top: 20rpx;
+    padding: 30rpx;
+    .row {
+      display: flex;
+      align-items: center;
+      margin-top: 20rpx;
+      &:first-child {
+        margin-top: 0;
+      }
+      .label {
+        font-size: 28rpx;
+        color: $sec-font;
+        margin-right: 20rpx;
+      }
+      .value {
+        flex: 1;
+        font-size: 28rpx;
+        text {
+          color: $minor-color;
+        }
+        &.price {
+          color: $theme-color;
+        }
+      }
+      .tag {
+        font-size: 28rpx;
+        color: $theme-color;
+      }
+      &.top {
+        .label {
+          color: $main-font;
+          font-weight: 500;
+        }
+        .value {
+          font-weight: 500;
+        }
+        .status {
+          font-size: 28rpx;
+          color: $warning-color;
+        }
+      }
+    }
+    .btns {
+      display: flex;
+      justify-content: flex-end;
+      margin-top: 30rpx;
+      ::v-deep .u-button {
+        width: 200rpx;
+        margin: 0;
+        margin-left: 20rpx;
+      }
+    }
+  }
+}
+</style>

+ 380 - 0
src/packageMaterial/pages/newSale/pay.vue

@@ -0,0 +1,380 @@
+<template>
+  <view>
+    <Loading :type="3" :loadStatus="loadStatus" :showText="errorText" />
+    <zj-page-layout :hasFooter="true" v-if="detail">
+      <view style="padding: 1rpx 30rpx">
+        <view class="materials-container card mt30">
+          <view class="title">
+            <view class="t1">支付金额</view>
+            <view class="t2"
+              >¥<text>{{ detail.totalAmount | priceFilter }}</text></view
+            >
+          </view>
+          <view class="id"><text>订单号:</text>{{ detail.orderId }}</view>
+          <view class="product">
+            <view
+              class="it"
+              v-for="(item, index) in wbId ? detail.rpMaterialOrderItems : detail.workerOrderItems"
+              :key="index"
+            >
+              <view class="name"
+                >{{ item.goodsName }}<text>×{{ item.num }}{{ item.unit }}</text></view
+              >
+              <view class="price">¥{{ item.totalAmount | priceFilter }}</view>
+            </view>
+            <view class="total">
+              <view class="text">合计:</view>
+              <view class="price">¥{{ detail.totalAmount | priceFilter }}</view>
+            </view>
+          </view>
+          <view class="row"><text>备注:</text>{{ detail.remark }}</view>
+          <view class="row"><text>操作人:</text>{{ detail.workerName }}</view>
+        </view>
+
+        <!-- <view class="pay-container card mt30">
+          <view class="top">请选择客户支付方式</view>
+          <view class="item" @tap="payType = 1">
+            <view class="left">
+              <text class="iconfont icon-weixinzhifu" style="color: #43c93e"></text>
+              <text class="text">微信支付</text>
+            </view>
+            <view class="right">
+              <text class="iconfont" :class="payType === 1 ? 'icon-danxuan2 active' : 'icon-danxuan'"></text>
+            </view>
+          </view>
+          <view class="item" @tap="payType = 2">
+            <view class="left">
+              <text class="iconfont icon-xianxiazhifu" style="color: #0379ff"></text>
+              <text class="text">线下支付</text>
+            </view>
+            <view class="right">
+              <text class="iconfont" :class="payType === 2 ? 'icon-danxuan2 active' : 'icon-danxuan'"></text>
+            </view>
+          </view>
+        </view> -->
+      </view>
+
+      <template slot="footer">
+        <view class="footer-btn-group">
+          <u-button text="取消订单" @click="cancelOrder"></u-button>
+          <u-button text="扫码支付" type="primary" @click="scanCode"></u-button>
+          <!-- <u-button text="扫码支付" type="primary" @click="scanCode" v-if="payType === 1"></u-button> -->
+          <!-- <u-button text="确定支付" type="primary" @click="confirmPay" v-else></u-button> -->
+        </view>
+      </template>
+    </zj-page-layout>
+  </view>
+</template>
+
+<script>
+import { wxScanCode } from '@/common/utils/util.js'
+
+export default {
+  data() {
+    return {
+      orderId: null,
+      wbId: null,
+      refresherTriggered: false,
+      loadStatus: 0,
+      errorText: '',
+      detail: null,
+      canScanCode: 0,
+      timeout: null,
+      timeoutNum: 0,
+
+      payType: 1
+    }
+  },
+
+  onLoad({ handleOrderId, wbId }) {
+    this.orderId = handleOrderId
+    this.wbId = wbId
+    this.getDetail()
+
+    this.crossPage.$on('reScanCode', () => {
+      this.scanCode()
+    })
+  },
+
+  onUnload() {
+    clearTimeout(this.timeout)
+  },
+
+  methods: {
+    getDetail() {
+      let url = '',
+        params = {}
+      if (this.wbId) {
+        url = '/engin/material/detail'
+        params.id = this.orderId
+      } else {
+        url = '/pay/getOrder'
+        params.orderId = this.orderId
+      }
+      this.$api
+        .post(url, params)
+        .then(res => {
+          this.detail = res.data
+          this.loadStatus = 0
+        })
+        .catch(res => {
+          this.errorText = res.message
+          this.loadStatus = 2
+        })
+        .finally(res => {
+          this.refresherTriggered = false
+        })
+    },
+
+    // 取消订单
+    cancelOrder() {
+      this.$modal({
+        content: '确认取消订单吗?'
+      })
+        .then(() => {
+          this.$api
+            .post('/pay/cancel', {
+              orderId: this.orderId
+            })
+            .then(res => {
+              this.$successToast()
+              this.$navToPage(
+                {
+                  delta: 1
+                },
+                'navigateBack'
+              )
+            })
+        })
+        .catch(() => {})
+    },
+
+    // 扫码
+    async scanCode() {
+      if (this.canScanCode > 0) return this.$toast(`请等待${this.canScanCode}秒后重试`)
+      var codeVal = await wxScanCode()
+      this.submitData(codeVal)
+    },
+
+    // 下单
+    submitData(code) {
+      let url = ''
+      if (this.wbId) {
+        url = '/engin/material/paid'
+      } else {
+        url = '/pay/paid'
+      }
+
+      this.$api
+        .post(url, {
+          authCode: code,
+          orderId: this.orderId,
+          payType: 'WECHAT'
+        })
+        .then(res => {
+          // 返回true,则支付成功
+          if (res.data) {
+            this.timeoutNum = 0
+            clearTimeout(this.timeout)
+
+            this.$navToPage({
+              url: `/packageMaterial/pages/sale/result?handleOrderId=${this.orderId}&result=1&wbId=${this.wbId || ''}`
+            })
+          }
+          // 返回false,轮询3次
+          else {
+            if (this.timeoutNum < 4) {
+              this.timeoutNum = this.timeoutNum + 1
+              this.timeout = setTimeout(() => {
+                this.submitData(code)
+              }, 1000)
+            } else {
+              this.timeoutNum = 0
+              clearTimeout(this.timeout)
+              this.$navToPage({
+                url: `/packageMaterial/pages/sale/result?handleOrderId=${this.orderId}&result=0&wbId=${this.wbId || ''}`
+              })
+            }
+          }
+        })
+        .catch(res => {
+          this.timeoutNum = 0
+          clearTimeout(this.timeout)
+          this.$tips(res.message)
+        })
+        .finally(() => {
+          this.canScanCode = 15
+          let time = setInterval(() => {
+            if (this.canScanCode > 0) {
+              this.canScanCode = this.canScanCode - 1
+            } else {
+              clearInterval(time)
+            }
+          }, 1000)
+        })
+    },
+
+    confirmPay() {
+      let url = ''
+      if (this.wbId) {
+        url = '/engin/material/paid'
+      } else {
+        url = '/pay/paid'
+      }
+
+      this.$api
+        .post(url, {
+          authCode: '',
+          orderId: this.orderId,
+          payType: 'LINE'
+        })
+        .then(res => {
+          if (res.data) {
+            this.$navToPage({
+              url: `/packageMaterial/pages/sale/result?handleOrderId=${this.orderId}&result=1&wbId=${this.wbId || ''}`
+            })
+          } else {
+            this.$navToPage({
+              url: `/packageMaterial/pages/sale/result?handleOrderId=${this.orderId}&result=0&wbId=${this.wbId || ''}`
+            })
+          }
+        })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.card {
+  @include zj-card;
+}
+
+.materials-container {
+  padding: 30rpx;
+
+  .title {
+    text-align: center;
+    margin-top: 30rpx;
+
+    .t1 {
+      font-size: 32rpx;
+      font-weight: 500;
+    }
+
+    .t2 {
+      font-size: 40rpx;
+      color: $minor-color;
+      margin-top: 20rpx;
+
+      text {
+        font-size: 56rpx;
+        font-weight: 500;
+      }
+    }
+  }
+
+  .id {
+    margin-top: 50rpx;
+
+    text {
+      color: $sec-font;
+    }
+  }
+
+  .product {
+    background: #f5f5f5;
+    border-radius: 12rpx;
+    padding: 20rpx;
+    margin-top: 20rpx;
+    .it {
+      display: flex;
+      align-items: flex-end;
+      margin-bottom: 20rpx;
+      .name {
+        flex: 1;
+        font-size: 28rpx;
+        font-weight: 500;
+        text {
+          color: $sec-font;
+          margin-left: 12rpx;
+          font-weight: normal;
+        }
+      }
+      .price {
+        margin-left: 30rpx;
+        font-size: 28rpx;
+        font-weight: 500;
+      }
+    }
+    .total {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      margin-top: 30rpx;
+      .text {
+        font-size: 28rpx;
+        color: $sec-font;
+      }
+      .price {
+        font-size: 28rpx;
+        color: $minor-color;
+        font-weight: 500;
+      }
+    }
+  }
+
+  .row {
+    margin-top: 20rpx;
+    line-height: 40rpx;
+    display: flex;
+    font-size: 28rpx;
+
+    text {
+      color: $sec-font;
+      flex-shrink: 0;
+      line-height: 40rpx;
+    }
+  }
+}
+
+.pay-container {
+  padding: 30rpx;
+
+  .top {
+    margin-bottom: 40rpx;
+  }
+
+  .item {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin: 30rpx 0;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .iconfont {
+        font-size: 44rpx;
+        color: #43c93e;
+      }
+
+      .text {
+        margin-left: 18rpx;
+        font-size: 32rpx;
+      }
+    }
+
+    .right {
+      .iconfont {
+        font-size: 40rpx;
+        color: $sec-font;
+
+        &.active {
+          color: $theme-color;
+        }
+      }
+    }
+  }
+}
+</style>

+ 530 - 0
src/packageMaterial/pages/newSale/product.vue

@@ -0,0 +1,530 @@
+<template>
+  <!-- #ifdef H5 -->
+  <zj-page-layout :hasFooter="true">
+    <template slot="header">
+      <view class="search-container">
+        <u-search
+          shape="round"
+          :showAction="false"
+          placeholder="输入分类名称进行搜索"
+          v-model="keyword"
+          @search="searchData"
+          @clear="searchData"
+        >
+        </u-search>
+      </view>
+    </template>
+
+    <view class="main-container">
+      <view class="left-list" v-if="type == 'M'">
+        <block v-for="(item, index) in leftList" :key="index">
+          <view
+            class="item ellipsis"
+            :class="leftCurrent == item.categoryId ? 'current' : ''"
+            @tap="changeLeft(item.categoryId)"
+            >{{ item.categoryName }}</view
+          >
+        </block>
+      </view>
+      <view class="right-list">
+        <scroll-view scroll-y style="height: 100%">
+          <view class="item" v-for="(item, index) in rightList" :key="index" @click="selectId = item.goodsCode">
+            <view class="name">{{ item.goodsName }}</view>
+            <view class="text">代码:{{ item.goodsCode }}</view>
+            <view class="bottom">
+              <view class="price"
+                >¥{{ item.goodsAmount | priceFilter }}<text>/{{ item.goodsUnit }}</text></view
+              >
+              <view
+                :style="`width: 50rpx; height: 50rpx; border-radius: 50%;background: ${
+                  selectId == item.goodsCode ? '#0379FF' : '#ebebeb'
+                };display: flex;justify-content: center;align-items: center;color:#fff`"
+                ><text>✔</text></view
+              >
+            </view>
+          </view>
+          <Loading :type="2" :loadStatus="loadStatus" :dataList="rightList" v-if="type == 'M'" />
+          <view class="empty-container" v-if="type == 'P' && rightList.length < 1">
+            <image src="@/packageMaterial/static/empty.jpg" mode="widthFix"></image>
+            <view class="title">该产品大类下暂无可售配件商品</view>
+            <view class="text">请联系网点在后台“辅材配件”-“配件资料管理”维护配件商品收费标准,再操作!</view>
+          </view>
+        </scroll-view>
+      </view>
+    </view>
+
+    <template slot="footer">
+      <view class="bottom-container">
+        <u-button type="primary" text="保存" @click="submitData"></u-button>
+      </view>
+    </template>
+  </zj-page-layout>
+  <!-- #endif -->
+
+  <!-- #ifndef H5 -->
+  <web-view
+    :src="webViewHref(`/packageMaterial/pages/sale/product`, pam, crossPagePam)"
+    @message="crossPage.$listener"
+  ></web-view>
+  <!-- #endif -->
+</template>
+
+<script>
+// #ifdef H5
+export default {
+  data() {
+    return {
+      type: 'M',
+      userMobile: '',
+      orderNo: '',
+      salesType: 'OUT',
+      brandId: null,
+      brandName: null,
+      categoryId: null,
+      categoryName: null,
+      wbId: null, // 维保工单
+      wbIsAllFee: null, // 维保工单是否包含全部费用
+      wbPayType: null, // 维保工单费用支付方式
+      keyword: '',
+      leftList: [],
+      leftCurrent: 0,
+      rightList: [],
+      loadStatus: 0,
+      cartList: [],
+      selectId: "",
+      dijiIndex: 0
+    }
+  },
+
+  onLoad({dijiIndex, type, userMobile, orderNo, salesType, brandId, brandName, categoryId, categoryName, websitId, websitName, wbId, wbIsAllFee, wbPayType}) {
+    this.dijiIndex = dijiIndex;
+    this.type = type;
+    this.userMobile = userMobile;
+    this.orderNo = orderNo;
+    // this.salesType = salesType;
+    // this.brandId = brandId;
+    // this.brandName = brandName;
+    this.categoryId = categoryId;
+    this.categoryName = categoryName;
+    this.websitId = websitId;
+    this.websitName = websitName;
+    this.wbId = wbId;
+    this.wbIsAllFee = wbIsAllFee;
+    this.wbPayType = wbPayType;
+
+    uni.setNavigationBarTitle({
+     title: type == 'M' ? '选择辅材' : '选择配件'
+    })
+    if(type === 'M') {
+      this.getLeftList();
+    }else {
+      this.getRightList();
+    }
+  },
+
+  methods: {
+    // 获取左侧分类
+    getLeftList() {
+    	this.$api.post('/pay/websitCategoryList', {
+        pageNum: 1,
+        pageSize: -1,
+      }).then(res => {
+    		this.leftList = res.data.records;
+    		this.leftCurrent = res.data.records.length > 0 ? res.data.records[0].categoryId : 0;
+    		this.getRightList();
+    	})
+    },
+
+    // 获取右侧产品
+    getRightList() {
+    	this.loadStatus = 1;
+      let url = '', params = {};
+      if(this.type === 'M') {
+        url = '/pay/chargeList';
+        params = {
+          categoryId: this.leftCurrent,
+          orderId: this.orderNo,
+        }
+      }else {
+        url = '/pay/websitGoodsList';
+        params = {
+          categoryName: this.categoryName,
+          brand: this.brandName,
+          orderId: this.orderNo,
+          // normType: 'M'
+        }
+      }
+
+    	this.$api.post(url, {
+        pageNum: 1,
+        pageSize: -1,
+        name: this.keyword,
+        ...params
+    	}).then(res => {
+    		this.loadStatus = 0;
+        let list = res.data.records.map(item => {
+          return this.type === 'M' ? {
+            goodsId: item.normId,
+            goodsName: item.normName,
+            goodsCode: item.normCode,
+            goodsUnit: item.unit,
+            goodsAmount: item.normAmount,
+            num: 0
+          } : {
+            goodsId: item.goodsId,
+            goodsName: item.goodsName,
+            goodsCode: item.goodsCode,
+            goodsUnit: item.goodsSalesUnit,
+            goodsAmount: item.normAmount,
+            normType: item.normType,
+            num: 0
+          }
+        });
+        for(let i = 0; i < list.length; i++) {
+          for(let j = 0; j < this.cartList.length; j++) {
+            if(list[i].goodsId == this.cartList[j].goodsId) {
+              list[i].num = this.cartList[j].num;
+            }
+          }
+        }
+    		if(list.length < 1){
+    			this.loadStatus = 2;
+    		}
+    		this.rightList = list;
+    	}).catch(() => {
+    		this.loadStatus = 2;
+    	})
+    },
+
+    // 切换一级菜单
+    changeLeft(pid) {
+    	this.leftCurrent = pid;
+    	this.getRightList();
+    },
+
+    // 搜索
+    searchData() {
+      this.getRightList();
+    },
+
+    changeNum(e) {
+      let obj = this.rightList.find((item) => item.goodsId === e.name);
+      if(e.unit && e.unit != '米') {
+        e.value = Math.floor(e.value);
+        obj.num = Math.floor(obj.num);
+      }
+      // 判断对象数组中是否存在该对象
+      let index = this.cartList.findIndex((item) => item.goodsId === obj.goodsId);
+      // 如果是0,就删除
+      if(index !== -1 && e.value == 0) {
+        this.cartList.splice(index, 1);
+      }
+      // 如果有就替换,没有就添加
+      else if (index !== -1) {
+      	this.cartList.splice(index, 1, obj);
+      }
+      else {
+        if(e.value > 0) {
+          this.cartList.push(obj);
+        }
+      }
+    },
+
+    changeCartNum(e) {
+      let obj = this.cartList.find((item) => item.goodsId === e.name);
+      if(e.unit && e.unit != '米') {
+        e.value = Math.floor(e.value);
+        obj.num = Math.floor(obj.num);
+      }
+      let index = this.cartList.findIndex((item) => item.goodsId === obj.goodsId);
+      this.cartList.splice(index, 1, obj);
+
+      this.getRightList();
+    },
+
+    overlimitFun(index) {
+      this.$modal({
+        content: '把该产品从购物车移除?'
+      }).then(() => {
+        this.cartList.splice(index, 1);
+        this.getRightList();
+      }).catch(() => {})
+    },
+
+    clearCart() {
+      this.$modal({
+        content: '确定清空购物车?'
+      }).then(() => {
+        this.cartList = [];
+        this.getRightList();
+      }).catch(() => {})
+    },
+
+    submitData() {
+
+      var data = this.rightList.find(item => item.goodsCode == this.selectId)
+      if (data) {
+        this.$setStorage('materialSaleData', {...data, dijiIndex: this.dijiIndex});
+        this.$navToPage({
+          delta: 1
+        },"navigateBack")
+      } else {
+        this.$toast('请选择');
+      }
+    },
+
+  },
+}
+
+// #endif
+// #ifndef H5
+export default {
+  data() {
+    return {
+      pam: {},
+    }
+  },
+  onLoad(pam) {
+    this.pam = pam;
+  }
+}
+// #endif
+</script>
+
+<style lang="scss" scoped>
+.search-container {
+  background: #ffffff;
+  padding: 0 20rpx 20rpx;
+  ::v-deep .u-search {
+    height: 60rpx;
+    input {
+      background: #f7f8ff !important;
+    }
+    .u-search__content {
+      background: #f7f8ff !important;
+      height: 60rpx;
+    }
+  }
+}
+.empty-container {
+  height: 100%;
+  background: #ffffff;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 0 100rpx;
+  image {
+    width: 300rpx;
+    margin-top: 100rpx;
+  }
+  .title {
+    font-size: 32rpx;
+  }
+  .text {
+    margin-top: 20rpx;
+    font-size: 28rpx;
+    line-height: 32rpx;
+    color: $sec-font;
+    text-align: center;
+  }
+}
+.main-container {
+  display: flex;
+  height: 100%;
+  .left-list {
+    width: 220rpx;
+    height: 100%;
+    overflow-y: scroll;
+    box-sizing: border-box;
+    flex-shrink: 0;
+    .item {
+      font-size: 28rpx;
+      color: #333333;
+      height: 88rpx;
+      display: flex;
+      align-items: center;
+      padding: 0 20rpx;
+      &.current {
+        color: #ffffff;
+        background: $theme-color;
+      }
+    }
+  }
+  .right-list {
+    flex: 1;
+    background: #ffffff;
+    background: #ffffff;
+    height: 100%;
+    box-sizing: border-box;
+    .item {
+      padding: 20rpx;
+      border-bottom: 1px solid #f5f5f5;
+      .name {
+        font-size: 32rpx;
+        font-weight: 500;
+      }
+      .text {
+        font-size: 28rpx;
+        color: $sec-font;
+        margin-top: 12rpx;
+      }
+      .bottom {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-top: 12rpx;
+        .price {
+          font-size: 28rpx;
+          font-weight: 500;
+          color: $minor-color;
+          text {
+            font-weight: normal;
+            color: $sec-font;
+            margin-left: 8rpx;
+          }
+        }
+        .input {
+          width: 50rpx;
+          text-align: center;
+          padding: 0 10px;
+        }
+        .ctrl {
+          width: 40rpx;
+          height: 40rpx;
+          background-color: $theme-color;
+          border-radius: 50%;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+      }
+    }
+  }
+}
+.bottom-container {
+  display: flex;
+  align-items: center;
+  padding: 20rpx;
+  .cart {
+    flex-shrink: 0;
+    width: 110rpx;
+    height: 110rpx;
+    border-radius: 50%;
+    background: $theme-color;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-top: -40rpx;
+    .iconfont {
+      font-size: 52rpx;
+      color: #ffffff;
+      font-weight: 600;
+    }
+  }
+  .price {
+    margin-left: 20rpx;
+    flex: 1;
+    font-size: 32rpx;
+    color: $minor-color;
+    font-weight: 500;
+    text {
+      font-weight: normal;
+      color: $sec-font;
+    }
+  }
+  .btn {
+    width: 180rpx;
+    // ::v-deep .u-button {
+    //   height: 60rpx;
+    // }
+  }
+}
+.dialog-mark {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba($color: #000000, $alpha: 0.6);
+}
+.dialog-container {
+  width: 100%;
+  box-sizing: border-box;
+  background: #ffffff;
+  position: fixed;
+  bottom: 100rpx;
+  left: 0;
+  padding: 30rpx;
+  .top {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .left {
+      font-size: 32rpx;
+      font-weight: 500;
+    }
+    .right {
+      display: flex;
+      align-items: center;
+      font-size: 28rpx;
+      color: $sec-font;
+      text {
+        font-size: 32rpx;
+        margin-right: 8rpx;
+      }
+    }
+  }
+  .list {
+    max-height: 400rpx;
+    overflow-y: scroll;
+    margin-top: 20rpx;
+    .item {
+      padding: 20rpx 0;
+      border-bottom: 1px solid #f5f5f5;
+      &:last-child {
+        border: none;
+      }
+      .name {
+        font-size: 32rpx;
+        font-weight: 500;
+      }
+      .text {
+        font-size: 28rpx;
+        color: $sec-font;
+        margin-top: 12rpx;
+      }
+      .bottom {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-top: 12rpx;
+        .price {
+          font-size: 28rpx;
+          font-weight: 500;
+          color: $minor-color;
+          text {
+            font-weight: normal;
+            color: $sec-font;
+            margin-left: 8rpx;
+          }
+        }
+        .input {
+          width: 50rpx;
+          text-align: center;
+          padding: 0 10px;
+        }
+        .ctrl {
+          width: 40rpx;
+          height: 40rpx;
+          background-color: $theme-color;
+          border-radius: 50%;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+      }
+    }
+  }
+}
+</style>

+ 218 - 0
src/packageMaterial/pages/newSale/result.vue

@@ -0,0 +1,218 @@
+<template>
+  <!-- #ifdef H5 -->
+  <view>
+    <Loading
+      :type="3"
+    	:loadStatus="loadStatus"
+    	:showText="errorText"
+    />
+
+    <zj-page-layout v-if="detail" :hasFooter="true">
+      <view style="padding: 1rpx 30rpx">
+        <view class="top-container card mt30">
+          <view class="icon">
+            <text class="iconfont icon-chenggong true" v-if="result === 1"></text>
+            <text class="iconfont icon-shibai false" v-if="result === 0"></text>
+          </view>
+          <view class="title" v-if="result === 1">支付成功</view>
+          <view class="title" v-if="result === 0">支付失败</view>
+          <view class="price"
+            >¥<text>{{detail.totalAmount | priceFilter}}</text></view
+          >
+        </view>
+
+        <view class="pay-container card mt30" v-if="result === 1">
+          <view class="title">支付信息</view>
+          <view class="row">
+            <view class="label">支付单号:</view>
+            <view class="value">{{ orderId }}</view>
+          </view>
+          <view class="row">
+            <view class="label">支付金额:</view>
+            <view class="price">¥{{ detail.totalAmount | priceFilter }}</view>
+          </view>
+          <view class="row">
+            <view class="label">支付时间:</view>
+            <view class="value">{{ detail.payTime || '' }}</view>
+          </view>
+          <view class="row">
+            <view class="label">支付方式:</view>
+            <view class="value">{{ detail.payType | payTypeFilter }}</view>
+          </view>
+          <view class="row">
+            <view class="label">支付结果:</view>
+            <view class="value" v-if="result === 1">成功</view>
+            <view class="value" v-if="result === 0">失败</view>
+          </view>
+        </view>
+      </view>
+
+      <template slot="footer">
+        <view class="footer-btn-group">
+          <u-button
+            text="返回订单"
+            type="primary"
+            size="large"
+            @click="toOrderDetail"
+            v-if="result === 1"
+          ></u-button>
+          <u-button
+            text="重新扫码"
+            type="primary"
+            size="large"
+            @click="backPage"
+            v-if="result === 0"
+          ></u-button>
+        </view>
+      </template>
+    </zj-page-layout>
+  </view>
+  <!-- #endif -->
+
+  <!-- #ifndef H5 -->
+  <web-view :src="webViewHref(`/packageMaterial/pages/sale/result`, pam, crossPagePam)" @message="crossPage.$listener"></web-view>
+  <!-- #endif -->
+</template>
+
+<script>
+  // #ifdef H5
+  export default {
+    filters: {
+      payTypeFilter(val) {
+        const MAP = {
+          WECHAT: '微信支付',
+          LINE: '线下支付',
+        }
+        return MAP[val];
+      }
+    },
+
+    data() {
+      return {
+        orderId: null,
+        wbId: null,
+        refresherTriggered: false,
+        loadStatus: 0,
+        errorText: '',
+        detail: null,
+        result: 0
+      };
+    },
+
+    onLoad({ handleOrderId, result, wbId }) {
+      this.orderId = handleOrderId;
+      this.result = Number(result);
+      this.wbId = wbId;
+      this.getDetail();
+    },
+
+    methods: {
+      getDetail() {
+        let url = '', params = {};
+        if(this.wbId) {
+          url = '/engin/material/detail';
+          params.id = this.orderId;
+        }else {
+          url = '/pay/getOrder';
+          params.orderId = this.orderId;
+        }
+        this.$api.post(url, params).then(res => {
+          this.detail = res.data;
+          this.loadStatus = 0;
+        }).catch(res => {
+          this.errorText = res.message;
+          this.loadStatus = 2;
+        }).finally(res => {
+          this.refresherTriggered = false;
+        })
+      },
+
+      toOrderDetail() {
+        this.$navToPage({
+          url: `/packageMaterial/pages/index`,
+        }, 'reLaunch');
+      },
+
+      backPage() {
+        this.crossPage.$emit('reScanCode', '');
+        this.$navToPage({
+          delta: 1
+        }, 'navigateBack')
+      }
+    },
+  };
+  // #endif
+  // #ifndef H5
+  export default {
+    data() {
+      return {
+        pam: {},
+      }
+    },
+    onLoad(pam) {
+      this.pam = pam;
+    }
+  }
+  // #endif
+</script>
+
+<style lang="scss" scoped>
+.card {
+  background: #ffffff;
+  box-shadow: -10rpx 12rpx 96rpx 2rpx rgba(31, 36, 99, 0.05);
+  border-radius: 20rpx;
+  overflow: hidden;
+}
+
+.top-container {
+  padding: 50rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  .icon {
+    text {
+      font-size: 110rpx;
+      &.true {
+        color: $success-color;
+      }
+      &.false {
+        color: $minor-color;
+      }
+    }
+  }
+  .title {
+    font-size: 32rpx;
+    margin-top: 20rpx;
+    font-weight: 500;
+  }
+  .price {
+    font-size: 32rpx;
+    margin-top: 12rpx;
+    font-weight: 500;
+    text {
+      font-size: 48rpx;
+    }
+  }
+}
+
+.pay-container {
+  padding: 30rpx;
+  .title {
+    font-size: 32rpx;
+    font-weight: 500;
+  }
+  .row {
+    display: flex;
+    align-items: center;
+    margin-top: 30rpx;
+    .label {
+      color: $sec-font;
+    }
+    .price {
+      color: $minor-color;
+      font-weight: 500;
+    }
+  }
+}
+</style>