Browse Source

快递发货

ymy 1 year ago
parent
commit
6eaef98d53

+ 8 - 0
src/api/delivery.ts

@@ -79,4 +79,12 @@ export function queryByOrderNo(data?:any){
 		method: 'POST',
 		params: data
 	})
+}
+//快递发货
+export function express(data?:any){
+	return request({
+		url: '/omsOrder/omsShippingOrder/express',
+		method: 'POST',
+		data: data
+	})
 }

+ 1 - 1
src/views/oms/order/components/carpoolModal.vue

@@ -44,7 +44,7 @@ import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
 import { getMultipleToOnePrice,addMultipleToOne,getInventoryByStoreHouseIdAndSkuids } from  '@/api/delivery'
 import Format from '@/benyun/utils/dateFormat'
 @Component({components:{DeliveryGoodsInfo,DeliveryPrice}})
-export default class carpoolModal extends Vue {
+export default class CarpoolModal extends Vue {
   drawer=false;
   direction='rtl'
   checked=false;

+ 514 - 0
src/views/oms/order/components/expressDeliveryModal.vue

@@ -0,0 +1,514 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    title="快递发货"
+    :visible.sync="drawer"
+    :direction="direction"
+    size="50%">
+    <div class="content">
+      <div class="info">
+        <div class="edit">
+          <span @click="edit">编辑</span>
+        </div>
+        <div class="g-box">
+          <!-- <div class="info-row">
+            <div class="info-col">
+              <span class="label">单号:</span>
+              <span :title="value.tmsOrderNo">{{ value.tmsOrderNo }}</span>
+            </div>
+          </div> -->
+          <div class="info-row">
+            <div class="info-col">
+              <span class="label">业务员:</span>
+              <span :title="value.tmsBusinessMan">{{ value.tmsBusinessMan }}</span>
+            </div>
+            <div class="info-col">
+              <span class="label">业务员手机:</span>
+              <span :title="value.tmsBusinessPhone">{{ value.tmsBusinessPhone }}</span>
+            </div>
+          </div>
+          <div class="info-row">
+            <div class="info-col">
+              <span class="label">备注:</span>
+              <span :title="value.wmsRemark">{{ value.wmsRemark }}</span>
+            </div>
+          </div>
+        </div>
+        <div class="g-box">
+          <div class="goods-top">
+            <div class="g-label">物料信息</div>
+            <div class="g-cont">
+              <div class="g-total">
+                <span class="name-label">重量合计:</span>
+                <span class="total-num">{{totalWeight}}kg</span>
+              </div>
+            </div>
+          </div>
+          <div class="table">
+            <vxe-table
+              border
+              size="mini"
+              align="center"
+              header-cell-class-name="header-cell"
+              :data="value.subItem">
+              <vxe-column field="tmsGoodsCode" title="物料编码" width="130"></vxe-column>
+              <vxe-column field="name" title="物料名称" width="260"></vxe-column>
+              <vxe-column field="weight" title="重量"></vxe-column>
+              <vxe-column field="price" title="单价"></vxe-column>
+              <vxe-column field="tmsQuantity" title="数量"></vxe-column>
+              <vxe-column field="tmsGoodsTotalPrice" title="小计"></vxe-column>
+            </vxe-table>
+          </div>
+        </div>
+      </div>
+      <vxe-modal v-model="showModal" id="deliverInfoEdit" width="900" height="80%" @show="show" @hide="hide" title="编辑" resize show-zoom transfer show-footer>
+        <by-form :propConfig="config" ref="form" />
+        <template #footer>
+          <div class="btn">
+            <el-button plain size="small" @click="showModal = false">取消</el-button>
+            <el-button type="primary" size="small" @click="btnEdit">确定</el-button>
+          </div>
+        </template>
+      </vxe-modal>
+    </div>
+    <div class="space"></div>
+    <div class="deli-footer">
+      <div class="d-left">
+        <!-- <div class="estimate-total">
+          预计总价<span class="total">¥{{currentPrice.estimateFreight?currentPrice.estimateFreight:'0.00'}}</span> 
+        </div> -->
+        <div class="agreement">
+          <el-checkbox v-model="checked">已读并同意《XXX电子运单协议》</el-checkbox>
+        </div>
+      </div>
+      <div class="send-btn" @click="btn">确认发货</div>
+    </div>
+  </el-drawer>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import { getInventoryByStoreHouseIdAndSkuids,express } from  '@/api/delivery'
+@Component({components:{}})
+export default class ExpressDeliveryModal extends Vue {
+  drawer=false;
+  direction='rtl';
+  load=false;
+  checked=false;
+  stopHandle=false;
+  data:Array<any>=[]
+  totalWeight=0;
+  value:any = {}
+  showModal=false;
+  config:any={
+    size:'small',
+    labelWidth:'120px',
+    rules:{
+      tmsBusinessMan:[{
+        required: true, message: '业务员不能为空!', trigger: 'blur'
+      }],
+      tmsBusinessPhone:[{
+        required: true, message: '业务员手机不能为空!', trigger: 'blur'
+      }],
+      storeHouseId:[{
+        required: true, message: '请选择仓库!', trigger: 'change'
+      }]
+    },
+    columns:[
+      [{
+        label:'业务员',
+        prop:'tmsBusinessMan',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'业务员手机',
+        prop:'tmsBusinessPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'仓库',
+        prop:'storeHouseId',
+        component:'warehouse',
+        compConfig:{
+          attr:{
+            placeholder:'请选择仓库',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'物流',
+        prop:'wmsLogisticsCode',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            clearable:true,
+            data: [{
+              value:'EMS',
+              label:'EMS'
+            },{
+              value:'YTO',
+              label:'圆通'
+            },{
+              value:'STO',
+              label:'申通'
+            },{
+              value:'SF',
+              label:'顺丰'
+            },{
+              value:'YUNDA',
+              label:'韵达'
+            },{
+              value:'ZTO',
+              label:'中通'
+            },{
+              value:'ANE',
+              label:'安能'
+            },{
+              value:'DBWL',
+              label:'德邦物流'
+            },{
+              value:'UC',
+              label:'优速'
+            },{
+              value:'POSTB',
+              label:'邮政小包'
+            },{
+              value:'DBKD',
+              label:'德邦快递'
+            },{
+              value:'FENGWANG',
+              label:'丰网速运'
+            },{
+              value:'KYE',
+              label:'跨越物流'
+            },{
+              value:'ZTKY',
+              label:'中通快运'
+            },{
+              value:'JT',
+              label:'极兔'
+            },{
+              value:'JD',
+              label:'京东'
+            },{
+              value:'JGSD',
+              label:'京广速递'
+            },{
+              value:'XNEXPRESS',
+              label:'虚拟快递'
+            }]
+          }
+        }
+      }],
+      [{
+        label:'备注',
+        prop:'wmsRemark',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+
+  setShow(v:boolean){
+    this.drawer=v;
+  }
+  setValue(data:Array<any>){
+    this.data =data;
+    this.value={};
+    this.value.tmsBusinessMan = (this as any).$store.getters.userInfo.userName;
+    this.value.tmsBusinessPhone = (this as any).$store.getters.userInfo.phonenumber;
+    this.value.subItem=[];
+    this.checked = false;
+    const requestId =  new Date().getTime() + this.getUuid();
+    this.value.requestId = requestId;
+    this.totalWeight = 0;
+    for(let item of data){     
+      if(item.items){
+        for(const i of item.items){
+          let total:any = 0;
+          if(Number(i.qty) && Number(i.price)){
+            total = multiply(Number(i.qty),Number(i.price))
+          }
+          if(Number(i.weight)){
+            this.totalWeight = Number(i.weight)
+          }
+          this.value.subItem.push({
+            requestId:requestId,
+            omsOrderId:item.id,
+            omsOrderItemId:i.itemId,
+            tmsGoodsModel:i.styleId,
+            tmsGoodsCode:i.skuId,
+            tmsQuantity:Number(i.qty)?Number(i.qty):0,
+            tmsGoodsTotalPrice:total,
+            name:i.name,
+            price:i.price,
+            weight:i.weight
+          })
+        }
+      }
+    }
+  }
+  getUuid(){
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  btnEdit(){
+    if(this.$refs.form){
+      (this.$refs.form as any).validate().then(()=>{
+        this.value = (this.$refs.form as any).getValue();
+        this.getStoreCount(this.value);
+      })
+    }
+    this.showModal = false;
+  }
+  hide(){
+    this.drawer = true;
+  }
+  //查库存
+  getStoreCount(item:any){
+    let params:any={};
+    params.storeHouseId = item.storeHouseId;
+    params.skuIds=[]
+    if(item.subItem){
+      for(const i of item.subItem){
+        if(params.skuIds.indexOf(i.omsOrderItemId) == -1){
+          params.skuIds.push(i.omsOrderItemId)
+        }
+      }
+    }
+    this.load = true;
+    getInventoryByStoreHouseIdAndSkuids(params).then((res:any) => {
+      this.load = false;
+      let m='';
+      for(const i of item.subItem){
+        for(const d of res.data){
+          let s = Number(d.inventory) - Number(d.useInventory) - Number(i.tmsQuantity);
+          if(i.omsOrderItemId == d.skuid && s < 0){
+            m = m ? m + ',' + i.name : i.name;          
+          }else{
+            d.inventory = subtract(d.inventory, i.tmsQuantity);
+          }
+        }
+      }
+      if(m){
+        this.$message({
+          message:'商品“'+m+'”库存不足!',
+          type:'error'
+        })
+        this.stopHandle = true;
+        return
+      }
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  show(){
+    
+    this.$nextTick(()=>{
+      if(this.$refs.form){
+        (this.$refs.form as any).clearValue();
+        (this.$refs.form as any).setValue(this.value);
+      }
+    })
+  }
+  edit(){
+    this.showModal = true;
+    this.drawer = false;
+  }
+  
+  btn() {
+    if(this.stopHandle){
+      this.$message('库存不足!')
+      return
+    }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    let params:any=(this as any).$lodash.cloneDeep(this.value);
+    params.omsOrderIds=[]
+    for(const item of this.data){
+      params.omsOrderIds.push(item.id);
+    }
+    params.tmsMaterials=[];
+    if(this.value.subItem){
+      let skuIds:Array<any>=[];
+      for(const item of this.value.subItem){
+        if(skuIds.indexOf(item.omsOrderItemId) == -1){
+          skuIds.push(item.omsOrderItemId);
+          params.tmsMaterials.push({
+            storeHouseId:this.value.storeHouseId,
+            materialSkuId:item.omsOrderItemId
+          })
+        }
+        
+      }
+    }
+    delete params.subItem;
+    this.load = true;
+    express(params).then((res:any) => {
+      this.load = false;
+      if(res.code == 200){
+        this.$message({
+          message:'订单发货成功!',
+          type:'success'
+        })
+        this.$emit('handleSuccess');
+        this.drawer=false;
+      }
+    }).catch(()=>{  
+      this.load = false;
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .info{
+    width: 100%;
+    .edit{
+      width: 100%;
+      display: flex;
+      justify-content: flex-end;
+      padding-bottom: 8px;
+      span{
+        color: rgb(0, 119, 255);
+        font-size: 14px;
+        cursor: pointer;
+      }
+    }
+    .g-box{
+      width: 100%;
+      background-color: rgba(160,205,255,0.22);
+      margin-bottom: 16px;
+      padding:16px;
+      box-sizing: border-box;
+      .info-row{
+        width: 100%;
+        display: flex;
+        padding-bottom: 16px;
+        .info-col{
+          width: 100%;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          span{
+            font-size: 14px;
+          }
+          .label{
+            color: #666;
+          }
+          .time{
+            color: #F00;
+          }
+        }
+        .col-width{
+          width: 50%;
+        }
+      }
+      .info-row:last-child{
+        padding: 0;
+      }
+      .goods-top{
+        padding-bottom: 8px;
+        width: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .g-label{
+          font-size: 14px;
+        }
+        .g-cont{
+          width: 60%;
+          display: flex;
+          align-items: center;
+          justify-content: flex-end;
+          .g-total{
+            padding-left: 8px;
+            font-size: 12px;
+            .name-label{
+              color: #999;
+            }
+          }
+        }
+      }
+      .table{
+        width: 100%;
+      }
+    }
+    .btn{
+      width: 100%;
+      display: flex;
+      justify-content: flex-end;
+    }
+  }
+}
+.deli-footer{
+  height: 60px;
+  width: 100%;
+  padding: 0 16px;
+  box-sizing: border-box;
+  box-shadow: 0 -5px 10px #EEE;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  position: absolute;
+  background-color: #FFF;
+  left: 0;
+  bottom: 0;
+  z-index: 10;
+  .d-left{
+    width: 70%;
+    .estimate-total{
+      font-size: 14px;
+      padding-bottom: 4px;
+      .total{
+        font-size: 16px;
+        color: #F00;
+      }
+      .detail{
+        color: #1684FC;
+        padding-left: 16px;
+        cursor: pointer;
+      }
+    }
+  }
+  .send-btn{
+    width: 120px;
+    height: 40px;
+    line-height: 40px;
+    border-radius: 8px;
+    background: linear-gradient(129.2deg, rgba(22,132,252,1) 9.81%,rgba(93,167,249,1) 97.4%);
+    color: rgba(255, 255, 255, 100);
+    font-size: 14px;
+    text-align: center;
+    box-shadow: 0px 2px 6px 0px rgba(93, 167, 249, 100);
+    cursor: pointer;
+  }
+}
+.space{
+  height: 60px;
+  width: 100%;
+  margin-top: 16px;
+}
+</style>

+ 1 - 1
src/views/oms/order/components/orderTable.vue

@@ -125,7 +125,7 @@
       <template #default="{ row }">
         <el-button type="text" size="mini" v-if="showMerge(row)" @click="mergeHandle(row)">合并</el-button>
         <el-button type="text" size="mini" v-if="showSplit(row)" @click="splitHandle(row)">拆分</el-button>
-        <el-button type="text" size="mini" v-if="showSend(row)" @click="sendGoods(row)">发货</el-button>
+        <!-- <el-button type="text" size="mini" v-if="showSend(row)" @click="sendGoods(row)">发货</el-button> -->
         <el-button type="text" size="mini" v-if="row.status == 'Delivering'  || row.status == 'Sent'" @click="sendGoodsDetail(row)">发货明细</el-button>
       </template>
     </vxe-column>

+ 1 - 1
src/views/oms/order/components/orderTool.vue

@@ -46,7 +46,7 @@
     <el-button type="text" @click="handle('producePurchase')" title="选取已提交数据">生成采购单</el-button>
     <el-button type="text" @click="handle('orderFile')">订单归档</el-button>
     <div class="split"></div>
-    <el-button type="text" @click="handle('batchSendGoods')">批量发货</el-button>
+    <el-button type="text" @click="handle('batchSendGoods')">发货</el-button>
   </div>
 </template>
 

+ 7 - 0
src/views/oms/order/components/sendModeModal.vue

@@ -19,6 +19,13 @@
         <div class="msg">处理后形成多张物流单<br />优惠多多</div>
         <div class="moda-title">拼车/整车发货</div>
       </div>
+      <div class="moda-item" :class="{'onModal': mode==='2'}" @click="modeHandle('2')">
+        <div class="check">
+          <i class="el-icon-success"></i>
+        </div>
+        <div class="msg">处理后形成新物流单</div>
+        <div class="moda-title">快递发货</div>
+      </div>
     </div>
   </vxe-modal>
 </template>

+ 35 - 12
src/views/oms/order/index.vue

@@ -190,6 +190,8 @@
       <deliveryDetail ref="deliveryDetail" @handleSuccess="handleSuccess" @showLogistics="showLogistics" />
       <!-- 物流信息 -->
       <logisticsInfo ref="logisticsInfo" />
+      <!-- 快递发货 -->
+      <express-delivery-modal ref="expressDeliveryModal" @handleSuccess="handleSuccess" />
     </div>
   </div>
 </template>
@@ -223,11 +225,12 @@ import batchbyOneModal from './components/batchbyOneModal.vue'
 import carpoolModal from './components/carpoolModal.vue'
 import DeliveryDetail from "./components/deliveryDetail.vue";
 import LogisticsInfo from "./components/logisticsInfo.vue";
+import ExpressDeliveryModal from "./components/expressDeliveryModal.vue";
 import { query,getProvince,smt,unSmt,purchaseQty,unCancel,resetQuestion,archive } from '@/api/omsOrder'
 import { queryAll } from '@/api/question'
 @Component({components:{filterInput,OrderCheckbox,OrderRadio,filterDate,OrderTool,OrderTable,AddOrder,InputSelect,OrderProduct,
   filterMinMax,loadOrderModal,PurchaseModel,MergeModel,SplitModel,CancelOrderModel,QuestModel,SetQuesModal,UpdateRmkModal,UpdateSalerModal,
-  TabModal,AddProductModal,FreightModal,LabelsModal,SendModeModal,batchbyOneModal,carpoolModal,DeliveryDetail,LogisticsInfo}})
+  TabModal,AddProductModal,FreightModal,LabelsModal,SendModeModal,batchbyOneModal,carpoolModal,DeliveryDetail,LogisticsInfo,ExpressDeliveryModal}})
 export default class Order extends Vue {
   activeNames:Array<any>=['1','statusList']
   radio=''
@@ -547,18 +550,38 @@ export default class Order extends Vue {
   //发货模式
   modeChange(v:string){
     let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
-    if(v == '0'){
-      if(this.$refs.batchbyOneModal){
-        (this.$refs.batchbyOneModal as any).setShow(true);
-        (this.$refs.batchbyOneModal as any).setValue(data);
-      }
-    }
-    if(v == '1'){
-      if(this.$refs.carpoolModal){
-        (this.$refs.carpoolModal as any).setShow(true);
-        (this.$refs.carpoolModal as any).setValue(data);
-      }
+    switch(v){
+      case '0':
+        if(this.$refs.batchbyOneModal){
+          (this.$refs.batchbyOneModal as any).setShow(true);
+          (this.$refs.batchbyOneModal as any).setValue(data);
+        }
+        break;
+      case '1':
+        if(this.$refs.carpoolModal){
+          (this.$refs.carpoolModal as any).setShow(true);
+          (this.$refs.carpoolModal as any).setValue(data);
+        }
+        break;
+      case '2':
+        if(this.$refs.expressDeliveryModal){
+          (this.$refs.expressDeliveryModal as any).setShow(true);
+          (this.$refs.expressDeliveryModal as any).setValue(data);
+        }
     }
+
+    // if(v == '0'){
+    //   if(this.$refs.batchbyOneModal){
+    //     (this.$refs.batchbyOneModal as any).setShow(true);
+    //     (this.$refs.batchbyOneModal as any).setValue(data);
+    //   }
+    // }
+    // if(v == '1'){
+    //   if(this.$refs.carpoolModal){
+    //     (this.$refs.carpoolModal as any).setShow(true);
+    //     (this.$refs.carpoolModal as any).setValue(data);
+    //   }
+    // }
   }
   //z整车发货
   sendGoods(item:any){