소스 검색

oms订单拆分B2B订单和B2C订单

ymy 1 년 전
부모
커밋
3f9f787a82
82개의 변경된 파일20306개의 추가작업 그리고 205개의 파일을 삭제
  1. 603 189
      package-lock.json
  2. 1 0
      package.json
  3. BIN
      public/favicon.ico
  4. BIN
      public/favicon2.ico
  5. BIN
      src/assets/logo/logo2.png
  6. 1 1
      src/benyun/utils/index.ts
  7. 0 1
      src/components/IconSelect/index.vue
  8. 14 4
      src/layout/components/Sidebar/Logo.vue
  9. 15 9
      src/permission.ts
  10. 1 1
      src/views/audit/productManagement/index.vue
  11. 1763 0
      src/views/oms/B2BOrder/components/addOrder.vue
  12. 253 0
      src/views/oms/B2BOrder/components/addProductModal.vue
  13. 65 0
      src/views/oms/B2BOrder/components/addQuest.vue
  14. 508 0
      src/views/oms/B2BOrder/components/batchbyOneModal.vue
  15. 188 0
      src/views/oms/B2BOrder/components/buyerInfoModal.vue
  16. 105 0
      src/views/oms/B2BOrder/components/cancelOrderModel.vue
  17. 354 0
      src/views/oms/B2BOrder/components/carpoolModal.vue
  18. 340 0
      src/views/oms/B2BOrder/components/deliveryDetail.vue
  19. 679 0
      src/views/oms/B2BOrder/components/deliveryGoodsInfo.vue
  20. 150 0
      src/views/oms/B2BOrder/components/deliveryPrice.vue
  21. 502 0
      src/views/oms/B2BOrder/components/editProductModal.vue
  22. 534 0
      src/views/oms/B2BOrder/components/expressDeliveryModal.vue
  23. 59 0
      src/views/oms/B2BOrder/components/filterDate.vue
  24. 52 0
      src/views/oms/B2BOrder/components/filterInput.vue
  25. 83 0
      src/views/oms/B2BOrder/components/filterMinMax.vue
  26. 78 0
      src/views/oms/B2BOrder/components/freightModal.vue
  27. 70 0
      src/views/oms/B2BOrder/components/inputSelect.vue
  28. 185 0
      src/views/oms/B2BOrder/components/labelsModal.vue
  29. 380 0
      src/views/oms/B2BOrder/components/loadOrderModal.vue
  30. 80 0
      src/views/oms/B2BOrder/components/logisticsInfo.vue
  31. 176 0
      src/views/oms/B2BOrder/components/mergeMedal.vue
  32. 99 0
      src/views/oms/B2BOrder/components/orderCheckbox.vue
  33. 41 0
      src/views/oms/B2BOrder/components/orderProduct.vue
  34. 57 0
      src/views/oms/B2BOrder/components/orderRadio.vue
  35. 309 0
      src/views/oms/B2BOrder/components/orderTable.vue
  36. 88 0
      src/views/oms/B2BOrder/components/orderTool.vue
  37. 321 0
      src/views/oms/B2BOrder/components/purchaseModel.vue
  38. 202 0
      src/views/oms/B2BOrder/components/questModel.vue
  39. 149 0
      src/views/oms/B2BOrder/components/sendModeModal.vue
  40. 95 0
      src/views/oms/B2BOrder/components/setQuesModal.vue
  41. 144 0
      src/views/oms/B2BOrder/components/shopModal.vue
  42. 169 0
      src/views/oms/B2BOrder/components/splitModal.vue
  43. 112 0
      src/views/oms/B2BOrder/components/tabModal.vue
  44. 89 0
      src/views/oms/B2BOrder/components/updateRmkModal.vue
  45. 76 0
      src/views/oms/B2BOrder/components/updateSalerModal.vue
  46. 1281 0
      src/views/oms/B2BOrder/index.vue
  47. 1763 0
      src/views/oms/B2COrder/components/addOrder.vue
  48. 253 0
      src/views/oms/B2COrder/components/addProductModal.vue
  49. 65 0
      src/views/oms/B2COrder/components/addQuest.vue
  50. 506 0
      src/views/oms/B2COrder/components/batchbyOneModal.vue
  51. 188 0
      src/views/oms/B2COrder/components/buyerInfoModal.vue
  52. 105 0
      src/views/oms/B2COrder/components/cancelOrderModel.vue
  53. 353 0
      src/views/oms/B2COrder/components/carpoolModal.vue
  54. 340 0
      src/views/oms/B2COrder/components/deliveryDetail.vue
  55. 677 0
      src/views/oms/B2COrder/components/deliveryGoodsInfo.vue
  56. 150 0
      src/views/oms/B2COrder/components/deliveryPrice.vue
  57. 502 0
      src/views/oms/B2COrder/components/editProductModal.vue
  58. 534 0
      src/views/oms/B2COrder/components/expressDeliveryModal.vue
  59. 59 0
      src/views/oms/B2COrder/components/filterDate.vue
  60. 52 0
      src/views/oms/B2COrder/components/filterInput.vue
  61. 83 0
      src/views/oms/B2COrder/components/filterMinMax.vue
  62. 78 0
      src/views/oms/B2COrder/components/freightModal.vue
  63. 70 0
      src/views/oms/B2COrder/components/inputSelect.vue
  64. 185 0
      src/views/oms/B2COrder/components/labelsModal.vue
  65. 380 0
      src/views/oms/B2COrder/components/loadOrderModal.vue
  66. 80 0
      src/views/oms/B2COrder/components/logisticsInfo.vue
  67. 176 0
      src/views/oms/B2COrder/components/mergeMedal.vue
  68. 99 0
      src/views/oms/B2COrder/components/orderCheckbox.vue
  69. 41 0
      src/views/oms/B2COrder/components/orderProduct.vue
  70. 57 0
      src/views/oms/B2COrder/components/orderRadio.vue
  71. 309 0
      src/views/oms/B2COrder/components/orderTable.vue
  72. 89 0
      src/views/oms/B2COrder/components/orderTool.vue
  73. 321 0
      src/views/oms/B2COrder/components/purchaseModel.vue
  74. 202 0
      src/views/oms/B2COrder/components/questModel.vue
  75. 149 0
      src/views/oms/B2COrder/components/sendModeModal.vue
  76. 95 0
      src/views/oms/B2COrder/components/setQuesModal.vue
  77. 144 0
      src/views/oms/B2COrder/components/shopModal.vue
  78. 169 0
      src/views/oms/B2COrder/components/splitModal.vue
  79. 112 0
      src/views/oms/B2COrder/components/tabModal.vue
  80. 89 0
      src/views/oms/B2COrder/components/updateRmkModal.vue
  81. 76 0
      src/views/oms/B2COrder/components/updateSalerModal.vue
  82. 1284 0
      src/views/oms/B2COrder/index.vue

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 603 - 189
package-lock.json


+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "js-cookie": "^3.0.1",
     "jsencrypt": "^3.3.2",
     "lodash": "^4.17.21",
+    "mathjs": "^12.1.0",
     "monaco-editor": "^0.39.0",
     "monaco-editor-locales-plugin": "^0.0.3",
     "monaco-editor-nls": "^3.1.0",

BIN
public/favicon.ico


BIN
public/favicon2.ico


BIN
src/assets/logo/logo2.png


+ 1 - 1
src/benyun/utils/index.ts

@@ -62,7 +62,7 @@ export function formatTime(time:any, option:any) {
  * @param {string} url
  * @returns {Object}
  */
-export function getQueryObject(url:string) {
+export function getQueryObject(url?:string) {
   url = url == null ? window.location.href : url
   const search = url.substring(url.lastIndexOf('?') + 1)
   const obj:any = {}

+ 0 - 1
src/components/IconSelect/index.vue

@@ -1,4 +1,3 @@
-<!-- @author young
 <template>
   <div class="icon-body">
     <el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons">

+ 14 - 4
src/layout/components/Sidebar/Logo.vue

@@ -2,11 +2,15 @@
   <div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
     <transition name="sidebarLogoFade">
       <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo" />
+        <div v-if="logo" class="sidebar-logo">
+          <img :src="logo" />
+        </div>
         <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
       </router-link>
       <router-link v-else key="expand" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo" />
+        <div class="sidebar-logo" v-if="logo">
+          <img :src="logo" />
+        </div>
         <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
       </router-link>
     </transition>
@@ -14,7 +18,7 @@
 </template>
 
 <script>
-import logoImg from '@/assets/logo/logo.png'
+import logoImg from '@/assets/logo/logo2.png'
 import variables from '@/assets/styles/variables.module.scss'
 
 export default {
@@ -60,7 +64,6 @@ export default {
   background: #2b2f3a;
   text-align: center;
   overflow: hidden;
-
   & .sidebar-logo-link {
     height: 100%;
     width: 100%;
@@ -70,6 +73,13 @@ export default {
       height: 32px;
       vertical-align: middle;
       margin-right: 2px;
+      border-radius: 50%;
+      display: inline-block;
+      overflow: hidden;
+      background-color: #fff;
+      >img{
+        width: 100%;
+      }
     }
 
     & .sidebar-title {

+ 15 - 9
src/permission.ts

@@ -5,7 +5,8 @@ import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 import {getToken} from '@/benyun/utils/auth'
 import {isRelogin} from '@/benyun/utils/request'
-import {getQueryString} from "@/benyun/utils/benyuntech";
+// import {getQueryString} from "@/benyun/utils/benyuntech";
+import {getQueryObject} from '@//benyun/utils'
 
 NProgress.configure({ showSpinner: false })
 
@@ -25,11 +26,14 @@ const infoHandle = (to:any, next:any) => {
       next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
     })
   }).catch(err => {
-      store.dispatch('LogOut').then(() => {
-        Message.error(err)
-        // next({ path: '/' })
-      })
-    })
+    MessageBox.alert(err, '提示', {
+      confirmButtonText: '确定',
+      callback: () => {
+        store.dispatch('LogOut').then(() => {})
+      }
+    });
+    
+  })
 }
 
 router.beforeEach((to:any, from:any, next:any) => {
@@ -48,8 +52,11 @@ router.beforeEach((to:any, from:any, next:any) => {
       }
     // }
   } else {
-    const ticket = getQueryString('ticket')
-    const ssoToken = getQueryString('ssoToken')
+    let params = getQueryObject();
+    const ticket = params.ticket;
+    const ssoToken = params.ssoToken;
+    // const ticket = getQueryString('ticket')
+    // const ssoToken = getQueryString('ssoToken')
 
     if(!ticket && !ssoToken){
       const redirect = location.origin
@@ -82,7 +89,6 @@ router.beforeEach((to:any, from:any, next:any) => {
             location.href = `${process.env.VUE_APP_LOGIN_URL}?&redirect=${encodeURIComponent(redirect)}`
           }
         });
-        // const redirect = location.href.replace(/\??ticket=[^&]*&?/g, '')
         
       })
       // next()

+ 1 - 1
src/views/audit/productManagement/index.vue

@@ -321,7 +321,7 @@
 					}
 				},
 				{
-					// width: '150px',
+					// width: '110px',
 					title: '69码-商品条码(必填项)',
 					field: 'barCode',
 					component: 'by-input',

+ 1763 - 0
src/views/oms/B2BOrder/components/addOrder.vue

@@ -0,0 +1,1763 @@
+<template>
+  <vxe-modal v-model="value" id="addOrder" @show="show" width="70%" height="80%" min-width="460" min-height="320" 
+    show-zoom resize transfer show-footer @hide="hide" v-loading="load">
+    <template #title>
+      <span>创建新订单</span>
+    </template>
+    <template #default>
+      <div class="order-step" v-if="orderValue.id">
+        <el-steps :active="stepActive" align-center finish-status="success" v-if="topStep.indexOf(orderValue.status) >= 0" size="mini">
+          <el-step title="1.待付款"></el-step>
+          <el-step title="2.已付款待审核"></el-step>
+          <!-- <el-step title="3.已客审待财审"></el-step>
+          <el-step title="4.等供销商|外仓发货"></el-step> -->
+          <el-step title="3.发货中"></el-step>
+        </el-steps>
+        <div class="other" v-if="stepTypeName(orderValue.status)">{{ stepTypeName(orderValue.status) }}</div>
+      </div>
+      <el-collapse v-model="activeNames">
+        <el-collapse-item title="基本信息" name="1" class="add-order-item">
+          <by-form :propConfig="baseConfig" ref="baseform" @formChange="formChangeBase">
+            <template v-slot:sourceFrom_desc='{ value }'>
+              {{ getFromText(value.operationFlag) }}
+            </template>
+            <template v-slot:shopName="{value}">
+              <el-input :placeholder="!orderValue.id?'请选择标签':''" :value="value.shopName" :disabled="orderValue.id?true:false" @clear="clearShop" size="small" class="myinpuy-with-select" clearable>
+                <el-button slot="append" v-if="!orderValue.id" icon="el-icon-more" @click="showShop"></el-button>
+              </el-input>
+            </template>
+            <template v-slot:labels="{value}">
+              <el-input :placeholder="!orderValue.id?'请选择标签':''" :value="value.labels" :disabled="orderValue.id?true:false" size="small" @clear="clearLabels" class="myinpuy-with-select" clearable>
+                <el-button slot="append" v-if="!orderValue.id" icon="el-icon-more" @click="showLabels"></el-button>
+              </el-input>
+            </template>
+          </by-form>
+        </el-collapse-item>
+        <el-collapse-item title="买家信息" name="2" class="add-order-item">
+          <by-form :propConfig="buyerInfoConfig" ref="infoform">
+            <template v-slot:buyerNickname="{value}">
+              <el-input placeholder="请选择买家'" :value="value.buyerNickname" @clear="clearBuyer" size="small" class="myinpuy-with-select" clearable>
+                <el-button slot="append" icon="el-icon-more" @click="showBuyer"></el-button>
+              </el-input>
+            </template>
+            <template v-slot:receiverProvinceCode_desc='{ value }'>
+              {{ value.receiverProvince + '-' + value.receiverCity + '-' + value.receiverDistrict + (value.receiverTown?'-'+value.receiverTown:'') }}
+            </template>
+          </by-form>
+        </el-collapse-item>
+        <el-collapse-item title="发票信息" name="5" class="add-order-item" v-if="orderValue.id">
+          <by-form :propConfig="newInvoicesConfig" ref="invoicesform"></by-form>
+        </el-collapse-item>
+        <div class="btn-save" v-if="orderValue.id && orderValue.isSubmitted != 1">
+          <el-button type="primary" size="small" @click="saveBase">保存基本信息及收获地址</el-button>
+        </div>
+        <el-collapse-item title="订单支付情况" name="4" class="add-order-item" v-if="orderValue.id">
+          <div class="pay-row" v-if="orderValue.status != 'Split' && orderValue.status != 'Merged' && orderValue.status != 'Cancelled'">
+            <!-- <el-button type="text" v-if="!orderValue.pays || orderValue.pays.length == 0">快速支付</el-button> -->
+            <div class="add-pay-btn" v-if="orderValue.status !== 'Delivering'  && orderValue.status !== 'Sent'">
+              <el-button type="text" v-if="!showPay" @click="showPay = true">添加手工支付</el-button>
+              <el-button v-else icon="el-icon-close" size="mini" circle @click="showPay = false"></el-button>
+            </div>
+            
+          </div>
+          <by-form v-if="showPay" :propConfig="payConfig" ref="payform"></by-form>
+          <div class="pay-row" v-if="showPay && orderValue.status != 'Split' && orderValue.status != 'Merged' && orderValue.status != 'Cancelled'">
+            <el-button type="primary" size="small" @click="addPay">添加</el-button>
+          </div>
+          <div class="pay-info">
+            <el-descriptions v-for="(item,index) of orderValue.pays" :key="index" :title="item.payment" size="mini" :column="4">
+              <el-descriptions-item label="单号">{{item.outerPayId}}</el-descriptions-item>
+              <el-descriptions-item label="金额">{{item.amount}}</el-descriptions-item>
+              <el-descriptions-item label="支付日期">{{item.payDate}}</el-descriptions-item>
+              <el-descriptions-item label="状态" v-if="orderValue.status !== 'Delivering' && orderValue.status !== 'Sent'">
+                <div class="payHandle" v-if="item.status == 'WaitConfirm'">
+                  <span @click="payStatusHandle(item,'Confirmed')">审核通过</span>
+                  <span @click="payStatusHandle(item,'Invalid')">作废</span>
+                </div>
+                <div class="payHandle" v-if="item.status == 'Confirmed'">
+                  <span @click="payStatusHandle(item,'WaitConfirm')">取消审核</span>
+                </div>
+                <el-tag v-if="item.status == 'Invalid'" type="info" size="mini">已失效</el-tag>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+          
+        </el-collapse-item>
+        <el-collapse-item title="商品订单" name="3" class="add-order-item">
+          <div class="addProductTool">
+            <by-tool :propConfig="toolConfig" v-if="orderValue.status !== 'Delivering' && orderValue.status !== 'Sent'" ref="tool"></by-tool>
+            <div class="preferential">
+              <div class="pre-title">抵扣金额<i class="el-icon-info" title="支持输入数字和百分比。若输入百分比,将自动计算折扣金额=商品成交总金额*百分比(举例:打9折,请输入10%),只在订单创建时计算一次,在订单创建后修改商品价格不会自动计算,运费不参与折扣。"></i>:</div>
+              <vxe-input v-if="!orderValue.id" v-model="freeAmount" class="freeAmount" placeholder="请输入" size="mini" @change="freeAmountChange"></vxe-input>
+              <span v-else>{{ freeAmount }}</span>
+            </div>
+          </div>
+          
+          <by-table :propConfig="tableConfig" ref="table">
+            <template v-slot:name='{ row }'>
+              <div class="product-cont">
+                <div class="product-name">{{ row.name }} <el-tag v-if="row.isGift == 1" size="mini" type="success">赠</el-tag></div>
+              </div>
+            </template>
+            <template v-slot:qty='{ row }'>
+              <vxe-input v-model="row.qty" v-if="!orderValue.id" placeholder="数量" align="center" size="mini" type="integer" @input="qtyChange($event, row)" >
+              </vxe-input>
+              <span v-else>{{ row.qty }}</span>
+            </template>
+            <template v-slot:price='{ row }'>
+              <span v-if="row.isGift == 1">0</span>
+              <vxe-input v-else-if="!orderValue.id" v-model="row.price" placeholder="单价" align="center" size="mini" type="number" @input="priceChange($event, row)" >
+              </vxe-input>
+              <span v-else>{{ row.price }}</span>
+            </template>
+          </by-table>
+          <div class="product-row">
+            <div class="p-left">数量:{{ num }}</div>
+            <div class="p-right">
+              <div class="amount-title">商品成交总金额:</div>
+              <div class="amount-price">¥{{ productTotal }}</div>
+            </div>
+          </div>
+          <div class="product-row">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">抵扣金额:</div>
+              <div class="amount-price">¥{{orderValue.freeAmount?orderValue.freeAmount:'0.00'}}</div>
+            </div>
+          </div>
+          <div class="product-row">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">运费:</div>
+              <div class="amount-price">¥{{orderValue.freight?orderValue.freight:'0.00'}}</div>
+            </div>
+          </div>
+          <div class="product-row">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">应付总金额:</div>
+              <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{orderValue.payAmount?orderValue.payAmount:'0.00'}}</div>
+            </div>
+          </div>
+          <div class="product-row" v-if="orderValue.paidAmount">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">实付总金额:</div>
+              <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{orderValue.paidAmount?orderValue.paidAmount:'0.00'}}</div>
+            </div>
+          </div>
+        </el-collapse-item>
+        <el-collapse-item title="订单支付情况" name="4" class="add-order-item" v-if="!orderValue.id">
+          <el-radio-group v-model="radioPay" @input="inputPay" class="payType">
+            <el-radio :label="0">待付款</el-radio>
+            <el-radio :label="1">快速支付&已付款</el-radio>
+            <el-radio :label="2">手工添加支付信息</el-radio>
+            <el-radio :label="3">货到付款</el-radio>
+          </el-radio-group>
+          <by-form v-if="radioPay == 2" :propConfig="payConfig" ref="payform"></by-form>
+        </el-collapse-item>
+        <el-collapse-item title="发票信息" name="5" class="add-order-item" v-if="!orderValue.id">
+          <by-form :propConfig="newInvoicesConfig" ref="invoicesform"></by-form>
+        </el-collapse-item>
+      </el-collapse>
+      <!-- 商品 -->
+      <product-sku-modal ref="product" :mulit="true" @confirm="confirmProduct" />
+      <!-- 赠品 -->
+      <product-sku-modal ref="productGift" :mulit="true" @confirm="confirmProductGift" />
+
+      <add-product-modal ref="addProductModal" @handleSuccess="handleSuccess" :mask="false" />
+      <edit-product-modal ref="editProductModal" @handleSuccess="handleSuccess" />
+      <!-- 店铺 -->
+      <shop-modal ref="shopModal" @shopSelect="shopSelect" />
+      <!-- 标签 -->
+      <labels-modal ref="labelsModal" @onChange="onChangeLabel" />
+      <!-- 买家 -->
+      <buyer-info-modal ref="buyerInfoModal" @confirm="confirmBuyerInfo" />
+      <el-drawer class="log-drawer" :size="600" append-to-body title="操作日志" :visible.sync="drawer" direction="rtl">
+        <byLog :propConfig="logConfig" ref="log" />
+      </el-drawer>
+    </template>
+    <template #footer>
+      <div class="btn">
+        <el-button type="primary" size="small" v-if="!orderValue.id" @click="btn('continue')">确定并继续</el-button>
+        <el-button type="primary" size="small" v-if="!orderValue.id" @click="btn">确定</el-button>
+        <el-button icon="el-icon-edit-outline" circle v-if="orderValue.id" @click="logShow"></el-button>
+      </div>
+    </template>
+    
+  </vxe-modal>
+  
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { addOrder,saveBaseOrder,single,delItem,addPay,updateStatus } from '@/api/omsOrder'
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import AddProductModal from "./addProductModal.vue";
+import EditProductModal from "./editProductModal.vue";
+import LabelsModal from "./labelsModal.vue";
+import ShopModal from "./shopModal.vue";
+import BuyerInfoModal from "./buyerInfoModal.vue";
+@Component({components:{AddProductModal,EditProductModal,LabelsModal,ShopModal,BuyerInfoModal}})
+export default class AddOrder extends Vue {
+  logConfig:any={
+    request:{
+      url:'/omsOrder/omsOrderOperateLog/page',
+      method:'GET'
+    }
+  };
+  drawer=false;
+  value=false;
+  num:any=0;
+  showPay = false;
+  load = false;
+  freeAmount="";
+  productTotal:any=0;
+  userInfo:any='';//用户信息
+  orderValue:any={}; //新增订单值
+  radioPay=1;
+  stepActive:number=0;
+  topStep=['WaitPay','WaitConfirm','Delivering']
+  stepCon=['WaitPay','WaitConfirm','WaitFConfirm','WaitOuterSent','Sent','Delivering']
+  activeNames:Array<any> =['1','2','3','4','5','save'];
+  operationFlag:any={
+    'ERP':'手工下单',
+    'COPY':'复制',
+    'MERGE':'合并',
+    'SPLIT':'拆分;拆分还原',
+    'MOBILE':'导入',
+    'drp-s':'供销推送',
+    'drp-d':'分销推送',
+    'KWAISHOP':'快手;微商城',
+    'PINDUODUO':'拼多多',
+    'TOUTIAOFXG':'头条放心购',
+    'JUSHUITAN':'聚水潭'
+  }
+  baseConfig:any={};
+  buyerInfoConfig:any={};
+  newInvoicesConfig:any={}
+  config:any={
+    attr:{
+      size:'small',
+      itemCount:4,
+      rules:{
+        orderDate:[{
+          required: true, message: '订单日期不能为空!', trigger: 'blur'
+        }]
+      }
+    },
+    columns:[
+      [{
+        span:6,
+        label:'订单来源',
+        prop:'upSourceName',
+        // slot:true,
+        component:'by-input',
+        compConfig:{
+          attr:{
+            readonly:true
+            // type:'integer',
+            // placeholder:'请输入店铺名称',
+            // clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'线上订单',
+        prop:'sourceId',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'自动生成',
+            readonly:true
+          }
+        }
+      },{
+        span:6,
+        label:'订单日期',
+        prop:'orderDate',
+        component:'by-date-picker',
+        compConfig:{
+          attr:{
+            // placeholder:'请输入订单日期',
+            clearable:true,
+            type:'datetime',
+            format:'yyyy-MM-dd HH:mm:ss',
+            defaultNow:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'运费',
+        prop:'freight',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入运费',
+            type:'number',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'快递公司',
+        prop:'logisticsCompany',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入快递公司',
+            clearable:true
+          }
+        }
+      },
+      {
+        span:6,
+        label:'业务员',
+        prop:'createBy',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入业务员',
+            // readonly:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'操作标记',
+        prop:'operationFlag',
+        descSlot:true,
+        component:'by-select',
+        colspan:2,
+        compConfig:{
+          attr:{
+            // placeholder:'请输入订单日期',
+            disabled:true,
+            data:[{
+              label:'手工下单',
+              value:'OMS'
+            },{
+              label:'复制',
+              value:'COPY'
+            },{
+              label:'合并',
+              value:'MERGE'
+            },{
+              label:'拆分;拆分还原',
+              value:'SPLIT'
+            },{
+              label:'手机',
+              value:'MOBILE'
+            },{
+              label:'导入',
+              value:'IMPORT'
+            },{
+              label:'供销推送',
+              value:'DRP-S'
+            },{
+              label:'分销推送',
+              value:'DRP-D'
+            },{
+              label:'快手;微商城',
+              value:'KWAISHOP'
+            },{
+              label:'拼多多',
+              value:'PINDUODUO'
+            },{
+              label:'头条放心购',
+              value:'TOUTIAOFXG'
+            },{
+              label:'聚水潭',
+              value:'JUSHUITAN'
+            }]
+          }
+        }
+      },{
+        label:'标签',
+        prop:'labels',
+        span:12,
+        colspan:2,
+        slot:true
+      }],
+      [{
+        label:'线下备注',
+        prop:'note',
+        component:'by-input',
+        colspan:2,
+        compConfig:{
+          attr:{
+            placeholder:'请输入线下备注',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'买家留言',
+        prop:'buyerMessage',
+        component:'by-input',
+        colspan:2,
+        compConfig:{
+          attr:{
+            placeholder:'请输入买家留言',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'卖家备注',
+        prop:'remark',
+        component:'by-input',
+        colspan:4,
+        compConfig:{
+          attr:{
+            placeholder:'请输入卖家备注',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  config2:any={
+    attr:{
+      size:'small',
+      itemCount:4,
+      rules:{
+        buyerNickname:[{
+          required: true, message: '买家账号不能为空!', trigger: 'blur'
+        }],
+        receiverDistrictCode:[{
+          required: true, message: '收货地址不能为空!', trigger: 'blur'
+        }],
+        receiverAddress:[{
+          required: true, message: '详细地址不能为空!', trigger: 'blur'
+        }],
+        receiverMobile:[{
+          required: true, message: '手机号不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }]
+      }
+    },
+    columns:[
+      [{
+        span:6,
+        label:'买家',
+        prop:'buyerNickname',
+        slot:true,
+        // component:'by-input',
+        // compConfig:{
+        //   attr:{
+        //     type:'integer'
+        //   }
+        // }
+      },{
+        span:6,
+        label:'收货人',
+        prop:'receiverName',
+        component:'by-input',
+        rules:[{
+          required: true, message: '收货人不能为空', trigger: 'blur'
+        }],
+        compConfig:{
+          attr:{
+            placeholder:'请输入收货人',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'手机',
+        prop:'receiverMobile',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入手机',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'固定电话',
+        prop:'receiverPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入电话',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'邮编',
+        prop:'receiverZip',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入邮编',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:24,
+        label:'收货地址',
+        // slot:true,
+        prop:'receiverProvinceCode',
+        component:'by-area',
+        colspan:2,
+        descSlot:true,
+        compConfig:{
+          attr:{
+            province:'receiverProvince', //省
+            provinceCode:'receiverProvinceCode', //省编码
+            city:'receiverCity',   //市
+            cityCode:'receiverCityCode',  //市编码
+            county:'receiverDistrict',  //县/区
+            countyCode:'receiverDistrictCode',   //县/区编码
+            townCode:'receiverTownCode',
+            town:'receiverTown',
+            // show:'county'
+          }
+        }
+      }],
+      [{
+        span:24,
+        label:'详细地址',
+        prop:'receiverAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入详细地址',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  tableConfig:any={
+    attr:{
+      size:'mini',
+      align:'center',
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      slot:true,
+      // width:300
+    },{
+      title:'数量',
+      field:'qty',
+      width:130,
+      slot:true
+    },{
+      title:'单价',
+      field:'price',
+      width:130,
+      slot:true
+    },{
+      title:'原价',
+      field:'basePrice',
+      width:120
+    },{
+      title:'成交金额',
+      field:'amount',
+      width:120
+    },
+    // {
+    //   title:'库存',
+    //   field:'stock',
+    //   width:100
+    // },
+    {
+      title:'操作',
+      action:true,
+      width:160,
+      plugins:[{
+        icon:'el-icon-delete',
+        name:'删除',
+        audit:'',
+        event:{
+          show:(row:any) => {
+            if(row.status == 'Merged' || row.status == 'Cancelled'){
+              return false
+            }else{
+              return true
+            }
+          },
+          click:(item:any) => {
+            this.deletaProduct(item);
+          }
+        }
+      }]
+    }]
+  }
+  toolConfig={
+    customTools:[
+      {
+        name: '新增商品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddProduct()
+          }
+        }
+      },
+      {
+        name: '添加赠品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddGift();
+            
+          }
+        }
+      }
+    ]
+  }
+  invoicesConfig:any={
+    attr:{
+      size:'small',
+      itemCount:4,
+    },
+    columns:[
+      [{
+        span:6,
+        label:'发票类型',
+        prop:'type',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            placeholder:'发票类型',
+            clearable:true,
+            data:[{
+              value: '个人电子普通',
+              label: '个人电子普通'
+            }, {
+              value: '单位电子普通',
+              label: '单位电子普通'
+            }, {
+              value: '个人纸质普通',
+              label: '个人纸质普通'
+            }, {
+              value: '单位纸质普通',
+              label: '单位纸质普通'
+            }, {
+              value: '个人电子增值税',
+              label: '个人电子增值税'
+            }, {
+              value: '单位电子增值税',
+              label: '单位电子增值税'
+            }, {
+              value: '个人纸质增值税',
+              label: '个人纸质增值税'
+            }, {
+              value: '单位纸质增值税',
+              label: '单位纸质增值税'
+            }]
+          }
+        }
+      },{
+        span:6,
+        label:'发票抬头',
+        prop:'title',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'发票税号',
+        prop:'taxNo',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'发票地址',
+        prop:'address',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'专票银行',
+        prop:'bank',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'发票电话',
+        prop:'phone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'专票账户',
+        prop:'account',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'专票邮箱',
+        prop:'email',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'专票人',
+        prop:'userName',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'专票电话',
+        prop:'userPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:12,
+        label:'专票地址',
+        prop:'userAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  payConfig:any={
+    // attr:{
+    //   size:'mini'
+    // },
+    columns:[
+      [{
+        span:6,
+        label:'支付方法',
+        prop:'payment',
+        component:'by-select',
+        rules:[
+          { required: true, message: '请选择支付方法', trigger: 'change' }
+        ],
+        compConfig:{
+          attr:{
+            placeholder:'支付方法',
+            clearable:true,
+            data:[{
+              value: '支付宝',
+              label: '支付宝'
+            }, {
+              value: '快钱',
+              label: '快钱'
+            }, {
+              value: '财付通',
+              label: '财付通'
+            }]
+          }
+        }
+      },{
+        span:6,
+        label:'支付日期',
+        prop:'payDate',
+        rules:[
+          { required: true, message: '请选择支付日期', trigger: 'change' }
+        ],
+        component:'by-date-picker',
+        compConfig:{
+          attr:{
+            type:'datetime',
+            format:'yyyy-MM-dd HH:mm:ss',
+            clearable:true,
+            defaultNow:true
+          }
+        }
+      },{
+        span:6,
+        label:'支付单号',
+        prop:'outerPayId',
+        component:'by-input',
+        rules:[
+          { required: true, message: '请输入支付单号', trigger: 'change' }
+        ],
+        compConfig:{
+          attr:{
+            placeholder:'支付单号',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'支付金额',
+        prop:'amount',
+        component:'by-input',
+        rules:[
+          { required: true, message: '请输入支付金额', trigger: 'blur' }
+        ],
+        compConfig:{
+          attr:{
+            type:'number',
+            placeholder:'支付金额',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'买家支付账号',
+        prop:'buyerAccount',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'买家账号',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'卖家收款账号',
+        prop:'sellerAccount',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'收款账号',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  //订单来源转换文字信息
+  getFromText(f:any){
+    let t='';
+    if(f){
+      let arr:Array<any>=f.split(',');
+      for(const item of arr){
+        if(this.operationFlag[item]){
+          if(t){
+            t = t + ' , ' + this.operationFlag[item]
+          }else{
+            t = this.operationFlag[item]
+          }
+        }
+      }
+    }
+    return t;
+  }
+  stepTypeName(n:string){
+    let t = '';
+    if(n == 'Merged'){
+      t = '被合并'
+    }
+    if(n == 'Question'){
+      t = '异常'
+    }
+    if(n == 'Split'){
+      t = '被拆分'
+    }
+    if(n == 'Cancelled'){
+      t = '已取消'
+    }
+    return t;
+  }
+  logShow() {
+    if(!this.orderValue.id) return
+    this.drawer = true;
+    let data = {
+      orderNumber:this.orderValue.id
+    }
+    this.$nextTick(() => {
+      if (this.$refs.log) {
+        (this.$refs.log as any).setBillValue(data);
+        (this.$refs.log as any).request();
+      }
+    })
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  showBuyer() {
+    (this.$refs.buyerInfoModal as any).setShow(true)
+  }
+  showShop(){
+    (this.$refs.shopModal as any).setShow(true);
+  }
+  shopSelect(data:any){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.shopId = data.id;
+    value.shopName = data.shopName;
+    (this.$refs.baseform as any).setValue(value);
+  }
+  clearShop(){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.shopId = '';
+    value.shopName = '';
+    (this.$refs.baseform as any).setValue(value);
+  }
+  clearBuyer(){
+    let value:any = (this.$refs.infoform as any).getValue();
+    value.buyerId = '';
+    value.buyerNickname = '';
+    (this.$refs.infoform as any).setValue(value);
+  }
+  setDetail(data:any){
+    this.orderValue = data;
+    this.radioPay = this.orderValue.isPay
+    if(this.orderValue.isCod == 1) {
+      this.radioPay = 3
+    }
+  }
+  //订单支付情况单选值
+  inputPay(v:number){
+    if(v === 3) {
+      this.orderValue.isCod = 1
+      this.orderValue.isPay = 0
+    }else{
+      this.orderValue.isPay = v;
+      this.orderValue.isCod = 0
+    }
+  }
+  created(){
+    this.userInfo = this.$store.getters.userInfo;
+  }
+  //标签弹窗信息
+  onChangeLabel(v:string){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.labels = v;
+    (this.$refs.baseform as any).setValue(value);
+  }
+  //显示标签弹窗
+  showLabels(){
+    if(this.$refs.labelsModal){
+      (this.$refs.labelsModal as any).setShow(true);
+    }
+  }
+  clearLabels(){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.labels = '';
+    (this.$refs.baseform as any).setValue(value);
+  }
+  handleSuccess(){
+    this.$emit('handleSuccess');
+    this.getData();
+  }
+  //修改支付单号
+  payStatusHandle(item:any,status:string){
+    if(status == 'Invalid'){
+      this.$confirm('此操作将永久作废单号为:'+item.outerPayId+' 的订单支付, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.payStatusRequest(item,status)
+      }).catch(() => {});
+    }else{
+      this.payStatusRequest(item,status)
+    }
+  }
+  payStatusRequest(item:any,status:string){
+    this.load = true;
+    updateStatus({id:item.id, status}).then((res:any)=>{
+      this.load = false;
+      if(res && res.code == 200){
+        this.$message({
+          message:'操作成功!',
+          type:'success'
+        })
+        item.status = status;
+        this.$forceUpdate();
+        this.$emit('handleSuccess');
+      }
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //添加手工支付
+  addPay(){
+    (this.$refs.payform as any).validate({noMsg:true}).then(()=>{
+      let payFormValue = (this.$refs.payform as any).getValue();
+      payFormValue.sellerId = this.userInfo.userId;
+      payFormValue.orderId = this.orderValue.id;
+      payFormValue.operationFlag = this.orderValue.operationFlag;
+      payFormValue.isOrderPay = 1;
+      payFormValue.buyerNickname = this.orderValue.buyerNickname;
+      payFormValue.status = this.orderValue.status;
+      this.load = true;
+      addPay(payFormValue).then(()=>{
+        this.load = false;
+        this.$message({
+          message:'操作成功',
+          type:'success'
+        });
+        this.showPay = false;
+        this.handleSuccess();
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+    
+  }
+  // 买家信息
+  confirmBuyerInfo(data:any) {
+    let v:any = {}
+    v.buyerNickname = data[0].name
+    v.buyerId = data[0].id
+    v.receiverName = data[0].contacts
+    v.receiverProvince = data[0].province
+    v.receiverProvinceCode = data[0].provinceCode
+    v.receiverCity = data[0].city
+    v.receiverCityCode = data[0].cityCode
+    v.receiverDistrict = data[0].region
+    v.receiverDistrictCode = data[0].regionCode
+    v.receiverTownCode = data[0].streetCode
+    v.receiverTown = data[0].street
+    v.receiverAddress = data[0].address
+    v.receiverMobile = data[0].telephone
+    v.receiverPhone = data[0].phonenum
+    if(this.$refs.infoform){
+      (this.$refs.infoform as any).setValue(v)
+    }
+  }
+  //添加商品
+  toolAddProduct(){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    if(this.orderValue.id){
+      (this.$refs.addProductModal as any).setBillValue(this.orderValue.id);
+      (this.$refs.addProductModal as any).setShow(true);
+      (this.$refs.addProductModal as any).setGift(false);
+    }else{
+      (this.$refs.product as any).setShow(true);
+    }
+  }
+  //添加赠品
+  toolAddGift(){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    if(this.orderValue.id){
+      (this.$refs.addProductModal as any).setBillValue([this.orderValue.id]);
+      (this.$refs.addProductModal as any).setShow(true);
+      (this.$refs.addProductModal as any).setGift(true);
+    }else{
+      (this.$refs.productGift as any).setShow(true);
+    }
+  }
+  //获取数据
+  getData(){
+    if(!this.orderValue.id){
+      return
+    }
+    this.load = true;
+    single({
+      id:this.orderValue.id
+    }).then((res:any) => {
+      this.load = false;
+      this.orderValue = res.data;
+      this.show();
+      this.$forceUpdate();
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  //商品编辑
+  editProduct(){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    let tableValue = (this.$refs.table as any).getValue();
+    (this.$refs.editProductModal as any).setShow(true);
+    (this.$refs.editProductModal as any).setOrderValue(this.orderValue);
+    (this.$refs.editProductModal as any).setTableValue(tableValue);
+  }
+  show(){
+    this.baseConfig = (this as any).$lodash.cloneDeep(this.config);
+    this.buyerInfoConfig = (this as any).$lodash.cloneDeep(this.config2);
+    this.newInvoicesConfig = (this as any).$lodash.cloneDeep(this.invoicesConfig);
+    if(this.$refs.tool){
+      (this.$refs.tool as any).initTools();
+    }
+    if(this.orderValue.id){
+      let data = this.orderValue;
+      this.freeAmount = this.orderValue.freeAmount;
+      //基本信息
+      let info:any={};
+      info.shopName = data.shopName;
+      info.sourceId = data.sourceId;
+      info.orderDate = data.orderDate;
+      info.freight = Number(data.freight)?Number(data.freight):0;
+      info.logisticsCompany = data.logisticsCompany;
+      info.createBy = data.createBy;
+      info.note = data.note;
+      info.buyerMessage = data.buyerMessage;
+      info.remark = data.remark;
+      info.labels = data.labels;
+      info.logisticsId = data.logisticsId;
+      info.operationFlag = data.operationFlag;
+      this.baseConfig.attr.data = info;
+      (this.$refs.baseform as any).setValue(info);
+      //买家
+      let buyerInfo:any={};
+      buyerInfo.buyerNickname = data.buyerNickname;
+      buyerInfo.receiverName = data.receiverName;
+      buyerInfo.receiverProvince=data.receiverProvince;//省
+      buyerInfo.receiverProvinceCode=data.receiverProvinceCode; //省编码
+      buyerInfo.receiverCity=data.receiverCity;   //市
+      buyerInfo.receiverCityCode=data.receiverCityCode;  //市编码
+      buyerInfo.receiverDistrict=data.receiverDistrict;  //县/区
+      buyerInfo.receiverDistrictCode=data.receiverDistrictCode;   //县/区编码
+      buyerInfo.receiverTownCode=data.receiverTownCode;
+      buyerInfo.receiverTown=data.receiverTown;
+      buyerInfo.receiverAddress = data.receiverAddress;
+      buyerInfo.receiverPhone = data.receiverPhone;
+      buyerInfo.receiverMobile = data.receiverMobile;
+      buyerInfo.receiverZip = data.receiverZip;
+      this.buyerInfoConfig.attr.data = buyerInfo;
+      (this.$refs.infoform as any).setValue(buyerInfo);
+      //商品
+      const productData:Array<any> = data.items ? data.items : [];
+      for(let dItem of productData){
+        dItem.status = this.orderValue.status
+      }
+      (this.$refs.table as any).setValue(productData);
+      if(this.orderValue.status == 'Merged' || this.orderValue.status == 'Cancelled'){
+        (this.$refs.tool as any).setTool([]);
+      }else{
+        if(this.$refs.tool) {
+          (this.$refs.tool as any).setCustomTools([{
+            name: '商品编辑', icon: 'el-icon-edit', event:{
+              click:()=>{
+                this.editProduct()
+              }
+            }
+          }])
+        }
+        
+
+      }
+      
+      //付款
+      this.orderValue.isPay = data.isPay;
+      this.radioPay = data.isPay
+      if(data.isCod == 1) {
+        this.radioPay == 3
+      }
+      //发票
+      if(data.invoices && data.invoices[0]){
+        (this.$refs.invoicesform as any).setValue(data.invoices[0]);
+      }
+      if(this.orderValue.isSubmitted == 1){
+        this.baseConfig.attr.showType='desc';
+        this.baseConfig.attr.size='medium';
+        this.baseConfig.columns[1].splice(2,0,{
+          label:'快递单号',
+          prop:'logisticsId'
+        })
+      }else{
+        for(let col of this.baseConfig.columns){
+          for(let item of col){
+            let disField:Array<string>=['freight','buyerMessage','remark'] 
+            if(!item.slot && disField.indexOf(item.prop) == -1){
+              if(!item.compConfig.attr) item.compConfig.attr = {};
+              item.compConfig.attr.disabled = true;
+            }
+          }
+        }
+      }
+
+      if(this.orderValue.isSubmitted == 1){
+        this.buyerInfoConfig.attr.showType='desc';
+        this.buyerInfoConfig.attr.size='medium';
+        this.newInvoicesConfig.attr.showType='desc';
+        this.newInvoicesConfig.attr.size='medium';
+      }
+
+      this.totalAmount();
+      this.amountChange();
+      // this.payAmountChange();
+      this.totalNum();
+      if(this.stepCon.indexOf(data.status) >=0 ){
+        this.stepActive = this.stepCon.indexOf(data.status) 
+      }
+    }else{
+      let value:any = (this.$refs.baseform as any).getValue();
+      value.createBy = this.userInfo.userName;
+      (this.$refs.baseform as any).setValue(value);
+    }
+    (this.$refs.baseform as any).setConfig(this.baseConfig);
+    (this.$refs.infoform as any).setConfig(this.buyerInfoConfig);
+    (this.$refs.invoicesform as any).setConfig(this.newInvoicesConfig);
+  }
+  hide(){
+    this.showPay = false;
+    this.clearValue();
+  }
+  //抵扣金额数值变化
+  freeAmountChange(v:any){
+    this.orderValue.freeAmount = 0;
+    this.amountChange();
+    this.payAmountChange();
+  }
+  //商品成交总金额
+  totalAmount(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.productTotal = 0;
+    for(const item of nowData){
+      if(Number(item.amount) && item.isGift != 1){
+        this.productTotal = add(item.amount, this.productTotal)
+      }
+    }
+    this.productTotal = this.productTotal.toFixed(2);
+  }
+  //具体折扣数目
+  amountChange(){
+    if(this.freeAmount){
+      if(Number(this.freeAmount) >= 0){
+        this.orderValue.freeAmount = Number(this.freeAmount)
+      }else{
+        let arr:Array<any> = this.freeAmount.split("%");
+        if(arr.length == 2 && Number(arr[0]) > 0){
+          const n = divide(Number(arr[0]),100)
+          this.orderValue.freeAmount = multiply(this.productTotal,n)
+        }
+      }
+      this.orderValue.freeAmount = this.orderValue.freeAmount?this.orderValue.freeAmount.toFixed(2):0;
+    }else{
+      this.orderValue.freeAmount = 0
+    }
+  }
+  //应付总金额
+  payAmountChange(){
+    const freight = Number(this.orderValue.freight)?Number(this.orderValue.freight):0;
+    const freeAmount = Number(this.orderValue.freeAmount)?Number(this.orderValue.freeAmount):0;
+    let t = subtract(this.productTotal, freeAmount);
+    this.orderValue.payAmount = add(t, freight);
+    this.orderValue.payAmount = this.orderValue.payAmount.toFixed(2);
+  }
+  //商品总数量
+  totalNum(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.num = 0;
+    for(const item of nowData){
+      if(Number(item.qty)){
+        this.num = add(Number(item.qty), Number(this.num))
+      }
+    }
+  }
+  //基本信息表单数据变化
+  formChangeBase(data:any){
+    if(!this.orderValue[data.code]){
+      Vue.set(this.orderValue, data.code, data.value);
+    }else{
+      this.orderValue[data.code] = data.value;
+    }
+    if(data.code == 'freight'){
+      this.payAmountChange();
+    }
+    if(data.code == 'shopName'){
+      this.orderValue.shopId = data.value;
+    }
+  }
+  //确定新增的商品
+  confirmProduct(data:Array<any>){
+    this.productHandle(data,false);
+  }
+  //新增赠品
+  confirmProductGift(data:Array<any>){
+    this.productHandle(data,true);
+  }
+  //商品处理
+  productHandle(data:Array<any>,isGift:boolean){
+    let nowData = (this.$refs.table as any).getValue();
+    let names='';
+    if(data.length > 0){
+      for(const item of data){
+        let t = true;
+        let v = isGift ? 1 : 0;
+        for(const t_item of nowData){
+          if(item.id == t_item.itemId && t_item.isGift == v){
+            if(!names){
+              names = item.skuTitle
+            }else{
+              names = names + ',' + item.skuTitle
+            }
+            t = false;
+            break;
+          }
+        }
+        if(t){
+          let obj:any={};
+          obj.name = item.skuTitle; //商品名称
+          obj.skuId = item.skuCode; //商品编码
+          obj.itemId = item.id;
+          obj.styleId = item.itemNumber; //款式编码
+          obj.qty = 1;
+          if(isGift){
+            obj.price = 0;  //单价
+            obj.isGift = 1;
+          }else{
+            obj.price = item.price;  //单价
+            obj.isGift = 0;
+          }
+          
+          obj.basePrice = item.price; //原价
+          obj.amount = item.price;
+          // obj.stock = item.stock;
+          nowData.push(obj)
+        }
+      }
+      (this.$refs.table as any).setValue(nowData);
+      if(!isGift){
+        this.totalAmount();
+        this.amountChange();
+        this.payAmountChange();
+      }
+      this.totalNum();
+      if(names){
+        let name = isGift ? '赠品' : '商品';
+        this.$alert(name+'“'+names+'”已存在,请在列表做调整!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {}
+        });
+      }
+    }
+  }
+  //删除商品
+  deletaProduct(row:any){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    let n = row.isGift == 1 ? '赠品' : '商品';
+    this.$confirm('此操作将删除'+n+'“'+row.name+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      let del=()=>{
+        let data = (this.$refs.table as any).getValue();
+        let index = -1;
+        for(const item of data){
+          index ++;
+          if(row.skuId == item.skuId && row.name == item.name && row.isGift == item.isGift){
+            break;
+          }
+        }
+        data.splice(index,1);
+        (this.$refs.table as any).setValue(data);
+        this.totalAmount();
+        this.amountChange();
+        this.payAmountChange();
+        this.totalNum();
+      }
+      if(row.id){
+        this.load = true;
+        delItem({
+          itemId:row.id,
+          id:this.orderValue.id
+        }).then(()=>{
+          this.load = false;
+          del();
+          this.$emit('handleSuccess');
+        }).catch(()=>{
+          this.load = false;
+        })
+      }else{
+        del();
+      }
+      
+    }).catch(() => { });
+  }
+  //数量的变化
+  qtyChange(v:any,row:any){
+    if(v.value && row.price){
+      row.amount = multiply(Number(v.value),Number(row.price))
+    }else{
+      row.amount = 0
+    }
+    this.totalAmount();
+    this.amountChange();
+    this.payAmountChange();
+    this.totalNum();
+  }
+  //单价的变化
+  priceChange(v:any,row:any){
+    if(v.value && row.qty){
+      row.amount =multiply(Number(v.value),Number(row.qty))
+    }else{
+      row.amount = 0
+    }
+    this.totalAmount();
+    this.amountChange();
+    this.payAmountChange();
+  }
+  //清除整个订单数据
+  clearValue(){
+    this.orderValue = {};
+    this.stepActive = 0;
+    (this.$refs.baseform as any).clearValue();
+    (this.$refs.baseform as any).clearValidate();
+    (this.$refs.infoform as any).clearValue();
+    (this.$refs.infoform as any).clearValidate();
+    (this.$refs.table as any).setValue([]);
+    if(this.$refs.payform){
+      (this.$refs.payform as any).clearValue();
+      (this.$refs.infoform as any).clearValidate();
+    }
+    (this.$refs.invoicesform as any).clearValue();
+
+    this.num = 0;
+    this.productTotal = 0;
+    this.radioPay = 1;
+    this.freeAmount = '';
+  }
+  getOrderValue(n?:string){
+    // this.orderValue = {};
+    return new Promise((resolve:Function, reject:Function) => {
+      let r = true;
+      //基本信息
+      (this.$refs.baseform as any).validate({noMsg:true}).then(()=>{
+        let baseInfo = (this.$refs.baseform as any).getValue();
+        for(const key in baseInfo){
+          this.orderValue[key] = baseInfo[key]
+        }
+        if(this.orderValue.freight){
+          this.orderValue.freight = Math.floor(Number(this.orderValue.freight) * 100) / 100;
+        }else{
+          this.orderValue.freight = 0
+        }
+        
+        //买家信息
+        (this.$refs.infoform as any).validate({noMsg:true}).then(()=>{
+          let infoValue = (this.$refs.infoform as any).getValue();
+          for(const key in infoValue){
+            this.orderValue[key] = infoValue[key]
+          }
+          if(n == 'base'){
+            resolve();
+            return
+          }
+          //商品
+          let productOrder:Array<any> = [];
+          if(this.$refs.table){
+            productOrder = (this.$refs.table as any).getValue();
+          
+          }
+          if(productOrder.length > 0){
+            this.orderValue.items = productOrder;
+          }else{
+            this.$message({
+              message: '商品订单不能为空!',
+              type: 'warning'
+            });
+            reject();
+          }
+          if(this.radioPay === 0 || this.radioPay === 1){
+            this.orderValue.isPay = this.radioPay;
+            this.orderValue.pays = []
+          }
+          if(this.radioPay == 2){
+            this.orderValue.isPay = this.radioPay;
+            (this.$refs.payform as any).validate({noMsg:true}).then(()=>{
+              this.orderValue.pays = [];
+              let payFormValue = (this.$refs.payform as any).getValue();
+              payFormValue.sellerId = this.userInfo.userId;
+              this.orderValue.pays.push(payFormValue);
+              resolve();
+            }).catch(()=>{
+              if(r){
+                (this as any).$message({
+                  message: '验证未通过,请检查!',
+                  type: 'warning',
+                })
+              }
+              r = false;
+              reject();
+            });
+          }else{
+            resolve();
+          }
+
+          
+        }).catch(()=>{
+          if(r){
+            (this as any).$message({
+              message: '验证未通过,请检查!',
+              type: 'warning',
+            })
+          }
+          r = false;
+          reject();
+        });
+      }).catch(()=>{
+        if(r){
+          (this as any).$message({
+            message: '验证未通过,请检查!',
+            type: 'warning',
+          })
+        }
+        r = false;
+        reject();
+      });
+
+      let invoiceValue = (this.$refs.invoicesform as any).getValue();
+      this.orderValue.invoices=[];
+      if(JSON.stringify(invoiceValue) !== '{}'){
+        this.orderValue.invoices.push(invoiceValue);
+      }
+    })
+  } 
+  //确定
+  btn(n?:string){
+    this.getOrderValue().then(()=>{
+      this.orderValue.receiverCountryCode = '0';
+      this.orderValue.receiverCountry="中国";
+      this.load = true;
+      this.orderValue.isCod = this.orderValue.isCod ? 1 : 0
+      this.orderValue.freeAmount = this.orderValue.freeAmount ? this.orderValue.freeAmount : 0;
+      addOrder(this.orderValue).then((res:any) => {
+        if(n != 'continue'){
+          this.value = false;
+        }else{
+          this.clearValue();
+          let value:any = (this.$refs.baseform as any).getValue();
+          value.createBy = this.userInfo.userName;
+          (this.$refs.baseform as any).setValue(value);
+        }
+        this.load = false;
+        (this as any).$message({
+          message: '订单添加成功!',
+          type: 'success',
+        })
+        this.$emit('handleSuccess');
+      }).catch((err:any) => {
+        this.load = false;
+      }).catch(()=>{
+        this.load = false
+      })
+    }).catch((err:any) => {})
+  }
+  
+  //保存基本信息及守护地址
+  saveBase(){
+    this.getOrderValue('base').then(()=>{
+      this.load = true;
+      this.orderValue.receiverCountryCode = '0';
+      this.orderValue.receiverCountry="中国";
+      saveBaseOrder(this.orderValue).then(() => {
+        this.load = false;
+        (this as any).$message({
+          message: '订单修改成功!',
+          type: 'success',
+        })
+        this.$emit('handleSuccess');
+      }).catch((err:any) => {
+        this.load = false;
+      })
+    })
+    
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+}
+.btn-save{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+  padding: 16px 0;
+  border-bottom: 1px solid #e6ebf5;
+}
+.updateBuyer{
+  padding: 0 16px;
+}
+.addProductTool{
+  width: 100%;
+  padding-bottom: 8px;
+  display: flex;
+  justify-content: flex-end;
+  .preferential{
+    width: 240px;
+    flex-shrink: 0;
+    display: flex;
+    align-items: center;
+    .pre-title{
+      width: 80px;
+      flex-shrink: 0;
+    }
+  }
+}
+.payType{
+  padding-bottom: 16px;
+}
+.product-cont{
+  width: 100%;
+  .product-name{
+    font-size: 12px;
+    // padding-bottom: 4px;
+    color: #000;
+  }
+  .other-info{
+    font-size: 12px;
+    span{
+      padding: 0 8px;
+    }
+  }
+}
+.product-row{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  font-size: 12px;
+  padding: 4px 0;
+  .p-left,.p-right{
+    width: 50%;
+  }
+  .p-left{
+    text-align: right;
+  }
+  .p-right{
+    display: flex;
+    align-items: center;
+    .amount-title{
+      width: 70%;
+      text-align: right;
+      box-sizing: border-box;
+      padding-right: 8px;
+    }
+    .amount-price{
+      width: 30%;
+    }
+  }
+}
+.pay-info{
+  width: 100%;
+}
+.pay-row{
+  display: flex;
+  justify-content: flex-end;
+  padding-bottom: 8px;
+}
+.order-step{
+  padding-bottom: 8px;
+  width: 100%;
+  .other{
+    height: 30px;
+    line-height: 30px;
+    width: 100%;
+    box-sizing: border-box;
+    padding: 0 16px;
+    font-size: 14px;
+    color: #FFF;
+    background-color: #198cf8;
+  }
+}
+.updata-btn-row{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+  padding-bottom: 8px;
+}
+.add-pay-btn{
+  padding-left: 8px;
+  display: flex;
+  align-items: center;
+}
+.payHandle{
+  display: flex;
+  align-items: center;
+  >span{
+    margin-left: 8px;
+    cursor: pointer;
+    font-size: 12px;
+    color: #198cf8;
+  }
+  >span:hover{
+    text-decoration: underline;
+  }
+}
+</style>
+
+<style lang="scss">
+.add-order-item{
+  .el-collapse-item__content{
+    padding-bottom: 0;
+  }
+}
+.pay-info{
+  .el-descriptions{
+    padding-bottom: 8px;
+    .el-descriptions__header{
+      margin-bottom: 0 !important;
+      .el-descriptions__title{
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 253 - 0
src/views/oms/B2BOrder/components/addProductModal.vue

@@ -0,0 +1,253 @@
+<template>
+  <vxe-modal v-model="value" id="addProductModal" width="70%" v-loading="load" :mask="mask" @hide="hide" height="80%" show-footer :title="title">
+    <by-tool :propConfig="toolConfig" class="add-ptool" ref="tool">
+      <template v-slot:tool-right>
+        <el-switch
+          v-if="!isGift"
+          v-model="isPay"
+          active-text="快速支付" />
+      </template>
+    </by-tool>
+    <by-table :propConfig="config" ref="table">
+      <template v-slot:price='{ row }'>
+        <span v-if="isGift">0</span>
+        <vxe-input v-else v-model="row.price" placeholder="单价" align="center" size="mini" type="number"></vxe-input>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+    <!-- 商品 -->
+    <product-sku-modal ref="product" :mulit="true" @confirm="confirmProduct" />
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { addItem,addGift } from '@/api/omsOrder'
+@Component({components:{}})
+export default class AddProductModal extends Vue {
+  @Prop()
+  mask?:boolean;
+  isGift=false
+  title='';
+  value=false;
+  load=false;
+  isPay = true;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      size:'small',
+      align:'center'
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      width:340
+    },{
+      title:'数量',
+      field:'qty',
+      width:120,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          placeholder:'数量',
+          type:'integer',
+          size:'mini',
+          align:'center'
+        }
+      }
+    },{
+      title:'单价',
+      field:'price',
+      width:120,
+      slot:true,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          type:'number',
+          size:'mini',
+          align:'center'
+        }
+      }
+    },{
+      title:'库存',
+      field:'stock',
+      width:100
+    },{
+      title:'操作',
+      action:true,
+      plugins:[{
+        icon:'el-icon-delete',
+        name:'删除',
+        audit:'',
+        event:{
+          click:(item:any) => {
+            this.deletaProduct(item);
+          }
+        }
+      }]
+    }]
+  }
+  toolConfig:any={
+    customTools:[
+      {
+        name: '新增商品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            (this.$refs.product as any).setShow(true);
+          }
+        }
+      }
+    ]
+  }
+  created(){
+    
+  }
+  setGift(v:boolean){
+    this.isGift = v;
+    this.title = this.isGift?'添加赠品':'添加商品';
+    this.toolConfig.customTools[0].name = this.title;
+    if(this.$refs.tool){
+      (this.$refs.tool as any).initTools();
+    }
+    
+  }
+  hide(){
+    this.isPay = true;
+    (this.$refs.table as any).setValue([]);
+  }
+  setShow(v:boolean){
+    this.value = v;
+    this.$nextTick(()=>{
+      (this.$refs.product as any).setShow(true);
+    })
+  }
+  setBillValue(data:any){
+    this.billValue = data;
+  }
+  giftHandle(){
+    let tlist=(this.$refs.table as any).getValue();
+    if(tlist.length == 0){
+      this.$message('请选择赠品!')
+      return
+    }
+    let parames:any={};
+    parames.idList = this.billValue;
+    parames.giftList=[];
+    for(const item of tlist){
+      parames.giftList.push({
+        itemId:item.itemId,
+        qty:item.qty
+      })
+    }
+    this.load = true;
+    addGift(parames).then(() => {
+      this.load = false;
+      this.$message({
+        message:'添加成功!',
+        type:'success'
+      });
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch((err:any)=>{
+      this.load = false;
+    })
+  }
+  productHandle(){
+    let tlist=(this.$refs.table as any).getValue();
+    let data:any={};
+    if(tlist.length == 0){
+      this.$message('请选择商品!')
+      return
+    }
+    data.id = this.billValue;
+    data.items=[];
+    data.isPay = this.isPay;
+    for(const item of tlist){
+      data.items.push({
+        itemId:item.itemId,
+        qty:Number(item.qty),
+        price:Number(item.price)
+      })
+    }
+    this.load = true
+    addItem(data).then(()=>{
+      this.load = false;
+      this.$message({
+        message:'添加成功!',
+        type:'success'
+      });
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  btn(){
+    if(this.isGift){
+      this.giftHandle()
+    }else{
+      this.productHandle()
+    }
+  }
+  confirmProduct(data:Array<any>){
+    let nowData = (this.$refs.table as any).getValue();
+    let names='';
+    if(data.length > 0){
+      for(const item of data){
+        let t = true;
+        for(const t_item of nowData){
+          if(item.id == t_item.itemId){
+            if(!names){
+              names = item.skuTitle
+            }else{
+              names = names + ',' + item.skuTitle
+            }
+            t = false;
+            break;
+          }
+        }
+        if(t){
+          let obj:any={};
+          obj.name = item.skuTitle; //商品名称
+          obj.itemId = item.id;
+          obj.qty = 1;
+          obj.price = this.isGift ? 0 : item.price;  //单价
+          
+          obj.stock = item.stock;
+          nowData.push(obj)
+        }
+      }
+      (this.$refs.table as any).setValue(nowData);
+      if(names){
+        let name = this.isGift ? '赠品' : '商品';
+        this.$alert(name+'“'+names+'”已存在!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {}
+        });
+      }
+    }
+  }
+  deletaProduct(item:any){
+    let data=(this.$refs.table as any).getValue();
+    let i = -1;
+    for(const v of data){
+      i++;
+      if(v.itemId == item.itemId){
+        break
+      }
+    }
+    data.splice(i,1);
+    (this.$refs.table as any).setValue(data);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.add-ptool{
+  padding-bottom: 8px;
+}
+</style>

+ 65 - 0
src/views/oms/B2BOrder/components/addQuest.vue

@@ -0,0 +1,65 @@
+<template>
+  <vxe-modal v-model="value" id="addQuest" width="400" v-loading="load" @show="show" @hide="hide" height="200" show-footer title="新增异常类型">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { save } from '@/api/question'
+@Component({components:{}})
+export default class AddQuestModel extends Vue {
+  value = false;
+  load = false;
+  config:any={
+    attr:{
+      rules:{
+        type: [
+          { required: true, message: '请输入类型', trigger: 'blur' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'类型',
+        prop:'type',
+        labelWidth:'80px',
+        component:'by-input'
+      }]
+    ]
+  }
+  show(){
+    
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      this.load = true
+      save(data).then(()=>{
+        this.load = false;
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 508 - 0
src/views/oms/B2BOrder/components/batchbyOneModal.vue

@@ -0,0 +1,508 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    :title="data.length <= 1 ? '订单发货' : '订单发货(批量逐一发货)'"
+    :visible.sync="drawer"
+    @close="close"
+    :direction="direction"
+    size="50%">
+    <div class="content">
+      <div class="order-top" v-if="data.length > 1">
+        <el-pagination
+          background
+          :page-size="1"
+          :current-page="currentOrder + 1"
+          layout="prev, pager, next"
+          @current-change="currentChange"
+          :total="data.length">
+        </el-pagination>
+      </div>
+      <deliveryGoodsInfo :hideOrderCode="true" @editState="editState" @editResult="editResult" ref="info" />
+      <!-- <deliveryPrice :data="priceObj[data[currentOrder].omsOrderIds]" ref="price" v-if="data[currentOrder] && priceObj[data[currentOrder].omsOrderIds]" 
+      @prichChange="prichChange" :currentValue="currentPrice[data[currentOrder].omsOrderIds]" /> -->
+    </div>
+    <div class="space"></div>
+    <div class="deli-footer">
+      <div class="d-left">
+        <div class="estimate-total">
+          订单小计<span class="total">¥{{data[currentOrder] && currentPrice[data[currentOrder].omsOrderIds]?currentPrice[data[currentOrder].omsOrderIds].estimateFreight:'0.00'}}</span> 
+          <!-- <span class="detail">明细></span> -->
+        </div>
+        <!-- <div class="estimate-total">
+          预计总价<span class="total">¥48.00</span>
+        </div> -->
+        <div class="agreement">
+          <el-checkbox v-model="checked">已读并同意《XXX电子运单协议》</el-checkbox>
+        </div>
+      </div>
+      <div class="btn-box">
+        <div class="send-btn" @click="nextBtn" :class="{'stopBtn':stopHandle}" v-if="data.length > 1">确认,下一单</div>
+        <div class="send-btn" @click="btn" :class="{'stopBtn':stopHandle}">一键发货</div>
+      </div>
+      
+    </div>
+  </el-drawer>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import DeliveryGoodsInfo from "./deliveryGoodsInfo.vue";
+import DeliveryPrice from "./deliveryPrice.vue";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import { queryPricePackage,addmultiple,getInventoryByStoreHouseIdAndSkuids } from  '@/api/delivery'
+import Format from '@/benyun/utils/dateFormat'
+
+@Component({components:{DeliveryGoodsInfo,DeliveryPrice}})
+export default class BatchbyOneModal extends Vue {
+  drawer=false;
+  direction='rtl'
+  checked=false;
+  data:Array<any>=[];
+  currentOrder=0;
+  isSuccess=false;
+  stopHandle=false;
+  load = false;
+  priceObj:any={};
+  currentPrice:any={};
+  setShow(v:boolean){
+    this.drawer=v;
+    this.priceObj={};
+    this.currentPrice={};
+    this.isSuccess = false;
+    this.stopHandle = false;
+    this.currentOrder = 0;
+    this.checked = false;
+  }
+  close(){
+    if(this.isSuccess){
+      this.$emit('handleSuccess');
+    }
+  }
+  editResult(v:any){
+    this.data[this.currentOrder] = v;
+    // this.getStoreCount(v);
+    // this.getPriceInfo(v);
+  }
+  prichChange(index:number){
+    this.currentPrice[this.data[this.currentOrder].omsOrderIds] = this.priceObj[this.data[this.currentOrder].omsOrderIds][index];
+    this.$forceUpdate();
+  }
+  currentChange(v:number){
+    this.currentOrder = v-1;
+    this.$forceUpdate();
+    this.$nextTick(()=>{
+      this.setInfo();
+    })
+  }
+  setInfo(){
+    (this.$refs.info as any).setValue(this.data[this.currentOrder]);
+  }
+  setValue(data:Array<any>){
+    this.data = [];
+    if(data && data.length > 0){
+      for(const item of data){
+        const requestId =  new Date().getTime() + this.getUuid()
+        let obj:any={
+          tmsTransportMethod:'零担',
+          // tmsBusinessMan: (this as any).$store.getters.userInfo.userName,
+          // tmsBusinessPhone: (this as any).$store.getters.userInfo.phonenumber,
+          requestId:requestId,
+          omsOrderIds:item.id,
+          weight:item.weight,
+          tmsUnloadingProvince:item.receiverProvince,
+          tmsUnloadingProvinceNo:item.receiverProvinceCode,
+          tmsUnloadingCity:item.receiverCity,
+          tmsUnloadingCityNo:item.receiverCityCode,
+          tmsUnloadingRegion:item.receiverDistrict,
+          tmsUnloadingRegionNo:item.receiverDistrictCode,
+          tmsUnloadingStreet:item.receiverTown,
+          tmsUnloadingStreetNo:item.receiverTownCode,
+          tmsUnloadingAddress:item.receiverAddress,
+          tmsUnloadingConsignor:item.receiverName,
+          tmsUnloadingContacts:item.receiverMobile
+        };
+
+        obj.subItem=[];
+        if(item.items && item.items.length > 0){
+          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))
+            }
+            
+            obj.subItem.push({
+              requestId:requestId,
+              omsOrderId:item.id,
+              omsOrderItemId:i.itemId,
+              // omsOrderItemSkuId:i.itemId,
+              tmsGoodsModel:i.styleId,
+              tmsGoodsCode:i.skuId,
+              tmsQuantity:i.qty,
+              tmsGoodsTotalPrice:total,
+              name:i.name,
+              price:i.price,
+              weight:i.weight
+            })
+          }
+        }
+        this.data.push(obj)
+      }
+    }else{
+      this.data = []
+    }
+    this.$nextTick(()=>{
+      (this.$refs.info as any).setValue(this.data[this.currentOrder]);
+      this.drawer = false;
+      (this.$refs.info as any).showModal = true;
+    })
+  }
+  getUuid(){
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  btn(){
+    this.noSentOrder();
+    if(!this.data[this.currentOrder]){
+      this.$message('没有需要发货的订单!')
+      return
+    }
+    // if(this.stopHandle){
+    //   this.$message('库存不足!')
+    //   return
+    // }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    if(!this.data[this.currentOrder].tmsShipmentConsignor || !this.data[this.currentOrder].tmsUnloadingAddress || !this.data[this.currentOrder].tmsUnloadingConsignor){
+      this.$message("订单信息不完善,请前往编辑!");
+      return
+    }
+    // if(!this.currentPrice[this.data[this.currentOrder].omsOrderIds]){
+    //   this.$message("请选择价格!");
+    //   return
+    // }
+    if(this.data.length > 1){
+      let ids='';
+      for(const item of this.data){
+        if(!item.tmsShipmentConsignor || !item.tmsUnloadingAddress || !item.tmsUnloadingConsignor){
+          ids = ids ? ids + ',' + item.omsOrderIds : String(item.omsOrderIds)
+        }
+      }
+      if(ids){
+        this.$confirm('订单'+ids + '未编辑,是否以第一条订单为基准', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.setOnEditOrderInfo(ids);
+          this.sendGoods(this.data[this.currentOrder]);
+
+        }).catch(() => {});
+      }else{
+        this.sendGoods(this.data[this.currentOrder]);
+      }
+    }else{
+      if(this.data[0].isSuccess){
+        this.$message('订单:'+this.data[0].omsOrderIds+'已执行过发货操作!');
+        return
+      }
+      this.sendGoods(this.data[0]);
+    }
+  }
+  nextBtn(){
+    if(this.currentOrder >= this.data.length){
+      this.$message('已经是最后一单!')
+      return
+    }
+    if(this.stopHandle){
+      this.$message('库存不足!')
+      return
+    }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    const _value = this.data[this.currentOrder];
+    if(!_value.tmsBusinessMan || !_value.tmsBusinessPhone || !_value.tmsShipmentConsignor || !_value.tmsShipmentContacts || !_value.tmsUnloadingConsignor || !_value.tmsUnloadingContacts || !_value.tmsUnloadingProvince || !_value.tmsUnloadingAddress || !_value.storeHouseId){
+      this.$message("请编辑订单信息");
+      return
+    }
+    // if(!this.currentPrice[_value.omsOrderIds]){
+    //   this.$message('请选择价格!')
+    //   return
+    // }
+    if(_value.isSuccess){
+      this.$message('订单:'+_value.omsOrderIds+'已执行过发货操作!');
+      return
+    }
+    this.sendGoods(_value,true);
+  }
+  //查库存
+  getStoreCount(item:any,callback?:Function){
+    if(!item){
+      return
+    }
+    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
+      }
+      if(callback) callback(item,this.sendGoods)
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //发货
+  sendGoods(item:any,isNext?:boolean){
+    if(!item){
+      this.$message('订单不存在!')
+      return
+    }
+    
+    let params:any=(this as any).$lodash.cloneDeep(item);
+    // if(this.priceObj[item.omsOrderIds]){
+    //   try{
+    //     params.pricePlan = JSON.stringify(this.priceObj[item.omsOrderIds])
+    //   }catch(e){}
+    // }
+    // if(this.currentPrice[item.omsOrderIds]){
+    //   params.priceId = this.currentPrice[item.omsOrderIds].id;
+    // }
+    params.omsOrderIds = [item.omsOrderIds];
+    params.tmsMaterials=[];
+    if(item.subItem){
+      for(const i of item.subItem){
+        params.tmsMaterials.push({
+          storeHouseId:item.storeHouseId,
+          materialSkuId:i.omsOrderItemId
+        })
+      }
+    }
+    delete params.subItem;
+    this.load = true;
+    addmultiple(params).then((res:any) => {
+      this.load = false;
+      if(res.code == 200){
+        this.isSuccess = true;
+        this.$message({
+          message:'订单:'+item.omsOrderIds+'发货成功!',
+          type:'success'
+        })
+        for(let it of this.data){
+          if(it.omsOrderIds == item.omsOrderIds){
+            it.isSuccess=true;
+            break;
+          }
+        }
+
+        if(!isNext){
+          //寻找未发货的订单
+          this.noSentOrder();
+          let _item:any = this.data[this.currentOrder];
+          //是否是最后一单
+            if(this.currentOrder >= this.data.length){
+              this.drawer = false;
+            }else{
+              this.sendGoods(_item);
+              // if(this.currentPrice[_item.omsOrderIds]){
+              //   this.sendGoods(_item);
+              // }
+              // else{
+              //   this.getPriceInfo(_item,this.sendGoods)
+              //   // this.getStoreCount(_item,this.getPriceInfo);
+              // }
+            }
+        }else{
+          if(this.currentOrder < this.data.length - 1) {
+            this.currentOrder ++;
+            this.setInfo();
+          }
+        }
+        this.$forceUpdate();
+      }
+    }).catch(() => {
+      this.load = false;
+    })
+  }
+  //寻找未发货订单
+  noSentOrder(){
+    this.currentOrder = this.data.length;
+    for(let i = 0; i < this.data.length; i++){
+      if(!this.data[i].isSuccess){
+        this.currentOrder = i;
+        break
+      }
+    }
+    // if(this.data[this.currentOrder]){
+      this.setInfo();
+    // } 
+  }
+  setOnEditOrderInfo(ids:string){
+    let _value = this.data[0]
+    for(const item of this.data){
+      if(ids.indexOf(item.omsOrderIds) > -1 && !item.isSuccess){
+        item.orderType = _value.orderType;
+        item.storeHouseId = _value.storeHouseId;
+        item.tmsArrivalDate = _value.tmsArrivalDate;
+        item.tmsDeliveryDate =_value.tmsDeliveryDate;
+        item.tmsTransportMethod = _value.tmsTransportMethod;
+        item.tmsBusinessMan = _value.tmsBusinessMan;
+        item.tmsBusinessPhone = _value.tmsBusinessPhone;
+        item.tmsShipmentConsignor = _value.tmsShipmentConsignor;
+        item.tmsShipmentContacts = _value.tmsShipmentContacts;
+        item.tmsShipmentProvince = _value.tmsShipmentProvince;
+        item.tmsShipmentProvinceNo = _value.tmsShipmentProvinceNo;
+        item.tmsShipmentCity = _value.tmsShipmentCity;
+        item.tmsShipmentCityNo = _value.tmsShipmentCityNo;
+        item.tmsShipmentRegion = _value.tmsShipmentRegion;
+        item.tmsShipmentRegionNo = _value.tmsShipmentRegionNo;
+        item.tmsShipmentStreetNo = _value.tmsShipmentStreetNo;
+        item.tmsShipmentStreet = _value.tmsShipmentStreet;
+        item.tmsShipmentAddress = _value.tmsShipmentAddress;
+        item.tmsUnloadingConsignor = _value.tmsUnloadingConsignor;
+        item.tmsUnloadingContacts = _value.tmsUnloadingContacts;
+        item.tmsUnloadingProvince = _value.tmsUnloadingProvince;
+        item.tmsUnloadingProvinceNo = _value.tmsUnloadingProvinceNo;
+        item.tmsUnloadingCity = _value.tmsUnloadingCity;
+        item.tmsUnloadingCityNo = _value.tmsUnloadingCityNo;
+        item.tmsUnloadingRegion = _value.tmsUnloadingRegion;
+        item.tmsUnloadingRegionNo = _value.tmsUnloadingRegionNo;
+        item.tmsUnloadingStreetNo = _value.tmsUnloadingStreetNo;
+        item.tmsUnloadingStreet = _value.tmsUnloadingStreet;
+        item.tmsUnloadingAddress = _value.tmsUnloadingAddress;
+      }
+    }
+  }
+  //获取价格
+  getPriceInfo(data:any,callback?:Function){
+    let params:any={};
+    params.startStoreHouseId = data.storeHouseId;
+    // params.startAddressCode = data.tmsShipmentCityNo + '00000';
+    params.endAddressCode = data.tmsUnloadingCityNo + '00000';
+    params.omsIds=[this.data[0].omsOrderIds];
+    params.planType = data.tmsTransportMethod;
+    this.load = true;
+    queryPricePackage(params).then((res:any) => {
+      this.load=false;
+      let current=null;
+      for(let item of res.data[0].data){
+        let d = new Date().getTime() + item.duration*60*60*1000;
+        item.endTime=Format(new Date(d),'MM月dd日 HH:mm');
+        if(!current) current = item;
+        if(Number(current.estimateFreight) > Number(item.estimateFreight)){
+          current = item
+        }
+      }
+      this.priceObj[data.omsOrderIds] = res.data[0].data;
+      this.currentPrice[data.omsOrderIds] = current;
+      this.$forceUpdate();
+      if(callback){
+        callback(data)
+      }
+    }).catch((err:any)=>{
+      this.load = false;
+    })
+  }
+  editState(v:boolean){
+    this.drawer = v
+  }
+}
+</script>
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .order-top{
+    padding-bottom: 16px;
+    display: flex;
+    justify-content: center;
+  }
+}
+.deli-footer{
+  height: 80px;
+  width: 100%;
+  box-shadow: 0 -5px 10px #EEE;
+  padding: 0 16px 8px;
+  box-sizing: border-box;
+  display: flex;
+  justify-content: space-between;
+  align-items:flex-end;
+  position: absolute;
+  background-color: #FFF;
+  left: 0;
+  bottom: 0;
+  z-index: 10;
+  .d-left{
+    width: 50%;
+    .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;
+    margin-left: 16px;
+    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;
+  }
+  .stopBtn{
+    opacity: 0.7;
+  }
+  .btn-box{
+    width: 50%;
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+  }
+}
+.space{
+  height: 80px;
+  width: 100%;
+  margin-top: 16px;
+}
+</style>

+ 188 - 0
src/views/oms/B2BOrder/components/buyerInfoModal.vue

@@ -0,0 +1,188 @@
+<template>
+  <vxe-modal v-model="value" id="buyerInfoModal" v-loading="load" :width="width?width+'px':'60%'" @show="show" :height="height?height+'px':'80%'" min-width="500" min-height="400" show-zoom resize transfer show-footer  :zIndex="zIndex">
+    <template #title>
+      <span>{{title?title:'选择买家'}}</span>
+    </template>
+    <template #default>
+      <module-view :propConfig="config" ref="view" @pagination="getList"  @search="getList" @onRefresh="getList" @resert="getList" />
+    </template>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="confirm">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class BuyerInfoModal extends Vue {
+  value=false
+  data:Array<any>=[]
+  time:any;
+  timeNum = 0;
+  load=false;
+
+  @Prop()
+  title?:string
+
+  @Prop()
+  width?:number
+
+  @Prop()
+  height?:number
+
+  @Prop()
+  mulit?:boolean
+	
+	@Prop()
+	zIndex?:number
+
+  config:any={
+    attr:{
+      calculateH:true
+    },
+    search:{
+      attr:{
+        size:'mini',
+        
+      },
+      columns:[
+        [{
+          labelWidth:'120px',
+          span:10,
+          label:'名称',
+          prop:'name',
+          component:'by-input',
+          compConfig:{
+            attr:{
+              clearable:true,
+              placeholder:'请输入名称'
+            }
+          }
+        },{
+          labelWidth:'120px',
+          span:10,
+          label:'负责人',
+          prop:'contacts',
+          component:'by-input',
+          compConfig:{
+            attr:{
+              clearable:true,
+              placeholder:'请输入负责人'
+            }
+          }
+        }]
+      ]
+    },
+    tool:{
+      tools:{
+        search:true,
+        refresh:true
+      }
+    },
+    table:{
+      attr:{
+        size:'mini',
+        seq:true,
+        radio: true,
+        align:'center',
+        triggerRowCheck:'row',
+        pageSize:10
+      },
+      columns:[{
+        title:'名称',
+        field:'name'
+      },{
+        title:'负责人',
+        field:'contacts'
+      },{
+        title:'手机号',
+        field:'telephone'
+      },{
+        title: '固定电话',
+        field: 'phonenum'
+      }]
+    },
+  }
+
+  setShow(v:boolean){
+    this.value = v;
+  }
+
+  created(){
+    if(this.mulit){
+      this.config.table.attr.checkbox = true
+    }else{
+      this.config.table.attr.radio = true
+    }
+  }
+
+  //确定
+  confirm(){
+    let data:Array<any>=this.getSelectdata();
+    if(data.length == 0){
+      this.$message('请选择买家!')
+      return
+    }
+    this.$emit('confirm',data);
+    this.value = false;
+  }
+  //获取已选中表格数据
+  getSelectdata(){
+    let data:Array<any>=[];
+    if(this.$refs.view){
+      data = (this.$refs.view as any).getSelectData()
+    }
+    return data;
+  }
+  //显示弹窗
+  show(){
+    if(this.data.length ==0){
+      this.getList()
+    }
+    if(this.$refs.view){
+      (this.$refs.view as any).clearCheckboxRow();
+    }
+  }
+  getList(){
+    if(!this.$refs.view){
+      if(this.timeNum > 5){
+        return
+      }
+      setTimeout(()=>{
+        this.getList()
+      },500) 
+      this.timeNum ++;
+      return
+    }
+    let query:any = (this.$refs.view as any).getQuery();
+    query.isLikeSearch = '1';
+    this.load = true;
+    (this as any).$request({
+      url: '/maindata/maindataMaterialDistributor/page',
+      method: 'get',
+      params:query
+    }).then((res:any) => {
+      this.load = false;
+      if(res.data.records){
+        (this.$refs.view as any).setTableValue(res.data.records);
+        this.data = res.data.records;
+        let page={
+          pageNo: res.data.current, //当前页
+          pageSize: res.data.size, //每页条数
+          total: res.data.total //总条数
+        };
+        (this.$refs.view as any).setPage(page)
+      }
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 105 - 0
src/views/oms/B2BOrder/components/cancelOrderModel.vue

@@ -0,0 +1,105 @@
+<template>
+  <vxe-modal v-model="value" id="purchaseModel" width="400" height="300" show-zoom resize transfer show-footer v-loading="load">
+    <div class="info">
+      <div class="label">类型:</div>
+      <el-select v-model="type" placeholder="请选择" size="mini" class="cancel-type" clearable>
+        <el-option
+          v-for="item in options"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+    </div>
+    <div class="info">
+      <div class="label">原因:</div>
+      <el-input v-model="reason" class="cancel-type" placeholder="请输入内容" type="textarea" :rows="3"></el-input>
+    </div>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { cancelOrder } from '@/api/omsOrder'
+@Component
+export default class CancelOrderModel extends Vue {
+  value = false;
+  load = false;
+  reason='';
+  ids:Array<any>=[]
+  options:Array<any>= [{
+    value: '商品缺货',
+    label: '商品缺货'
+  },{
+    value: '客户申请取消',
+    label: '客户申请取消'
+  },{
+    value: '重复订单',
+    label: '重复订单'
+  },{
+    value: '其他',
+    label: '其他'
+  }];
+  type= ''
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setData(d:any){
+    this.ids = d;
+  }
+  btn(){
+    if(!this.type){
+      this.$message('请选择取消类型!');
+      return
+    }
+    this.$confirm('取消订单后将无法恢复, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+      cancelOrder({
+        idList:this.ids,
+        cancelType:this.type,
+        remark:this.reason
+      }).then(()=>{
+        this.load = false;
+        this.$message({
+          message:'订单取消成功!',
+          type:'success'
+        });
+        this.value = false;
+        this.type='';
+        this.reason = '';
+        this.$emit('handleSuccess');
+      }).catch((err:any)=>{
+        this.load = false;
+      })
+    }).catch(() => {});
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.info{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 16px;
+  .label{
+    width: 80px;
+    text-align: right;
+    padding-right: 8px;
+    box-sizing: border-box;
+  }
+  .cancel-type{
+    width: calc(100% - 100px);
+  }
+}
+</style>

+ 354 - 0
src/views/oms/B2BOrder/components/carpoolModal.vue

@@ -0,0 +1,354 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    :title="'订单发货(共'+data.length+'单)'"
+    :visible.sync="drawer"
+    :direction="direction"
+    size="50%">
+    <div class="content">
+      <div class="order-cont" v-if="data && data[0]">
+        <div class="cont-left">
+          <div class="order-code">订单号:{{data[0].id}}</div>
+          <div class="order-other">
+            <div class="receive-name">姓名:{{data[0].receiverName}}</div>
+            <div class="address">目的地:<span>{{data[0].receiverProvince+'-'+data[0].receiverCity}}</span></div>
+            <!-- <div class="time">预计送达:8月6日 12:00前</div> -->
+          </div>
+        </div>
+        <!-- <i class="el-icon-arrow-right"></i> -->
+      </div>
+      <deliveryGoodsInfo :hideOrderCode="true" :sendState="true" @editState="editState" @editResult="editResult" ref="info" />
+      <!-- <deliveryPrice v-if="priceData && priceData.length > 0" :data="priceData" :currentValue="currentPrice" @prichChange="prichChange" /> -->
+    </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> 
+          <!-- <span class="detail">明细></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 DeliveryGoodsInfo from "./deliveryGoodsInfo.vue";
+import DeliveryPrice from "./deliveryPrice.vue";
+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 {
+  drawer=false;
+  direction='rtl'
+  checked=false;
+  stopHandle=false;
+  load=false;
+  onAct='1';
+  data:Array<any>=[];
+  priceData:Array<any>=[]
+  currentPrice:any={}
+  value:any={};
+  setShow(v:boolean){
+    this.drawer=v;
+    this.stopHandle = false;
+    this.priceData=[];
+    this.currentPrice={}
+  }
+  setValue(data:Array<any>){
+    this.data =data;
+    this.value={};
+    this.value.tmsTransportMethod = '整车';
+    // this.value.tmsBusinessMan = (this as any).$store.getters.userInfo.userName;
+    // this.value.tmsBusinessPhone = (this as any).$store.getters.userInfo.phonenumber;
+    this.value.subItem=[];
+    this.value.weight = data[0].weight;
+    this.value.tmsUnloadingProvince=data[0].receiverProvince;
+    this.value.tmsUnloadingProvinceNo=data[0].receiverProvinceCode;
+    this.value.tmsUnloadingCity=data[0].receiverCity;
+    this.value.tmsUnloadingCityNo=data[0].receiverCityCode;
+    this.value.tmsUnloadingRegion=data[0].receiverDistrict;
+    this.value.tmsUnloadingRegionNo=data[0].receiverDistrictCode;
+    this.value.tmsUnloadingStreet=data[0].receiverTown;
+    this.value.tmsUnloadingStreetNo=data[0].receiverTownCode;
+    this.value.tmsUnloadingAddress=data[0].receiverAddress;
+    this.value.tmsUnloadingConsignor=data[0].receiverName;
+    this.value.tmsUnloadingContacts=data[0].receiverMobile;
+    this.checked = false;
+    const requestId =  new Date().getTime() + this.getUuid();
+    this.value.requestId = requestId;
+    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))
+          }
+          this.value.subItem.push({
+            requestId:requestId,
+            omsOrderId:item.id,
+            omsOrderItemId:i.itemId,
+            tmsGoodsModel:i.styleId,
+            tmsGoodsCode:i.skuId,
+            // omsOrderItemSkuId:i.itemId,
+            tmsQuantity:Number(i.qty)?Number(i.qty):0,
+            tmsGoodsTotalPrice:total,
+            name:i.name,
+            price:i.price,
+            weight:i.weight
+          })
+        }
+      }
+    }
+    this.$nextTick(()=>{
+      (this.$refs.info as any).setValue(this.value);
+      this.drawer = false;
+      (this.$refs.info as any).showModal = true;
+    })
+  }
+  getUuid(){
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  prichChange(index:number){
+    this.currentPrice = this.priceData[index];
+    this.$forceUpdate();
+  }
+  getPriceInfo(data:any){
+    let params:any={};
+    params.startStoreHouseId = data.storeHouseId;
+    // params.startAddressCode = data.tmsShipmentCityNo + '00000';
+    params.endAddressCode = data.tmsUnloadingCityNo + '00000';
+    params.planType = data.tmsTransportMethod;
+    params.omsIds=[];
+    for(const item of this.data){
+      params.omsIds.push(item.id);
+    }
+    this.load = true;
+    getMultipleToOnePrice(params).then((res:any) => {
+      this.load=false;
+      let current=null;
+      for(let item of res.data[0].data){
+        let d = new Date().getTime() + item.duration*60*60*1000;
+        item.endTime=Format(new Date(d),'MM月dd日 HH:mm');
+        if(!current) current = item;
+        if(Number(current.estimateFreight) > Number(item.estimateFreight)){
+          current = item
+        }
+      }
+      this.priceData = res.data[0].data;
+      this.currentPrice = current;
+    }).catch((err:any)=>{
+      this.load = false;
+    })
+  }
+  btn(){
+    // if(this.stopHandle){
+    //   this.$message('库存不足!')
+    //   return
+    // }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    if(!this.value.tmsBusinessMan || !this.value.tmsBusinessPhone || !this.value.tmsShipmentConsignor || !this.value.tmsShipmentContacts || !this.value.tmsUnloadingConsignor || !this.value.tmsUnloadingContacts || !this.value.tmsUnloadingProvince || !this.value.tmsUnloadingAddress || !this.value.storeHouseId){
+      this.$message("请编辑订单信息");
+      return
+    }
+    let params:any=(this as any).$lodash.cloneDeep(this.value);
+    // if(this.priceData){
+    //   try{
+    //     params.pricePlan = JSON.stringify(this.priceData)
+    //   }catch(e){}
+    // }
+    // if(this.currentPrice){
+    //   params.priceId = this.currentPrice.id;
+    // }
+    params.omsOrderIds=[]
+    for(const item of this.data){
+      params.omsOrderIds.push(item.id);
+    }
+    params.tmsMaterials=[];
+    if(this.value.subItem){
+      for(const item of this.value.subItem){
+        params.tmsMaterials.push({
+          storeHouseId:this.value.storeHouseId,
+          materialSkuId:item.omsOrderItemId,
+          qty: item.tmsQuantity
+        })
+      }
+    }
+    delete params.subItem;
+    this.load = true;
+    addMultipleToOne(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;
+    })
+  }
+  //查库存
+  getStoreCount(item:any,callback?:Function){
+    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;
+    })
+  }
+  editResult(v:any){
+    this.value = v;
+    // this.getPriceInfo(v);
+    // this.getStoreCount(v);
+  }
+  editState(v:boolean){
+    this.drawer = v
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .order-cont{
+    height: 60px;
+    width: 100%;
+    box-sizing: border-box;
+    border:solid 1px #BBB;
+    border-radius: 5px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 16px;
+    margin-bottom: 16px;
+    cursor: pointer;
+    .cont-left{
+      // width: calc(100% - 40px);
+      width: 100%;
+      .order-code{
+        width: 100%;
+        font-size: 14px;
+        padding: 6px 0 4px;
+      }
+      .order-other{
+        width: 100%;
+        display: flex;
+        font-size: 14px;
+        .receive-name{
+          width: 150px;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+        .address{
+          width: calc(100% - 150px);
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          span{
+            color: #F00;
+          }
+        }
+        // .time{
+        //   width: calc(100% - 120px - 150px);
+        // }
+      }
+    }
+  }
+  .order-cont:hover,.onAct{
+    background-color: rgba(160,205,255,0.22);
+  }
+}
+.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>

+ 340 - 0
src/views/oms/B2BOrder/components/deliveryDetail.vue

@@ -0,0 +1,340 @@
+<template>
+  <el-drawer
+    append-to-body
+    title="发货详情"
+    v-loading="load"
+    :visible.sync="drawer"
+    @close="close"
+    :direction="direction"
+    size="50%">
+    <div class="content" v-if="value.orderType == 'B2B'">
+      <deliveryGoodsInfo :sendState="true" ref="info" :readOnly="true" />
+      <div class="send-box">
+        <div class="pri-title">
+          <!-- <div class="title-item">
+            预计送达和预计费用<span>明细></span>
+          </div> -->
+          <div class="title-item">
+            实际送达和实际费用
+          </div>
+        </div>
+        
+        <div class="send-type">
+          <el-popover
+            v-for="(item,index) of priceData" :key="index"
+            placement="top-start"
+            width="200"
+            trigger="hover">
+            <div class="price-info">
+              <div class="price-title">预估费用明细:</div>
+              <div class="price-row freight">
+                <span class="p-label">运费:</span>
+                <span class="p-value">¥{{item.estimateFreight}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">单价:</span>
+                <span class="p-value">¥{{item.unitprice}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">重量:</span>
+                <span class="p-value">{{item.weight}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">体积:</span>
+                <span class="p-value">{{item.volume}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">单位:</span>
+                <span class="p-value">{{item.unit}}</span>
+              </div>
+            </div>
+            <div slot="reference" class="send-item" :title="item.ruleName" :class="{'ont':value.priceId == item.id}" >
+              <div class="label-name">{{item.ruleName}}</div>
+              <div class="send-info">
+                <div class="s-time">{{item.endTime}}前</div>
+                <div class="send-price">¥{{item.estimateFreight}}</div>
+              </div>
+            </div>
+          </el-popover>
+        </div>
+      </div>
+      
+      <div class="space"></div>
+      <div class="deli-footer">
+        <div class="send-btn" @click="showLogistics">物流信息</div>
+        <div class="send-btn" @click="cancelDelivery">取消发货</div>
+      </div>
+    </div>
+    <div class="content" v-if="value.orderType == 'B2C'">
+      <div class="send-box">
+        <div class="s-row">
+          <div class="s-col width50">业务员:{{ value.tmsBusinessMan }}</div>
+          <div class="s-col width50">业务员手机:{{ value.tmsBusinessPhone }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">店铺名称:{{ value.wmsShopName }}</div>
+          <div class="s-col width50">快递单号:{{ value.wmsExpressCode }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">快递公司:{{ value.wmsLogisticsName }}</div>
+          <div class="s-col width50">快递公司编码:{{ value.wmsLogisticsCode }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">WMS销售订单号:{{ value.wmsSaleorderCode }}</div>
+          <div class="s-col width50">WMS总费用:{{ value.wmsTotalAmount }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">WMS订单类型:{{ value.wmsSendType }}</div>
+          <div class="s-col width50">WMS状态:{{ getWmsState(value.wmsOrderStatus) }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col">WMS取消订单的备注:{{ value.wmsRemark }}</div>
+        </div>
+      </div>
+    </div>
+  </el-drawer>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import DeliveryGoodsInfo from "./deliveryGoodsInfo.vue";
+import { queryOrderByOrderId,cancleSendOrder } from  '@/api/delivery'
+@Component({components:{DeliveryGoodsInfo}})
+export default class DeliveryDetail extends Vue {
+  drawer=false;
+  direction='rtl'
+  load = false;
+  priceData:Array<any>=[];
+  value:any={};
+  wmsState='';
+  setShow(v:boolean){
+    this.drawer=v;
+  }
+  showLogistics() {
+    this.drawer = false;
+    this.$emit('showLogistics',this.value.tmsOrderNo)
+  }
+  close(){
+    this.value={}
+    this.priceData=[];
+  }
+  getWmsState(s:any){
+    let n = '';
+    switch(s){
+      case 1:
+        n = '创建';
+        break;
+      case 2:
+        n = '确认';
+        break;
+      case 3:
+        n = '完成';
+        break;
+      case 4:
+        n = '取消';
+        break;
+    }
+    return n;
+  }
+  setData(v:any){
+    if(!v) {
+      this.$message('缺少订单id');
+      return
+    }
+    this.load = true;
+    queryOrderByOrderId({
+      omsOrderId:v
+    }).then((res:any) => {
+      this.value = res.data;
+      if(res.data.subItemList){
+        this.value.subItem=[];
+        for(const item of this.value.subItemList){
+          this.value.subItem.push({
+            tmsGoodsCode:item.tmsGoodsCode,
+            name:item.tmsGoodsName,
+            tmsGoodsTotalPrice:item.tmsGoodsTotalPrice,
+            price:item.tmsGoodsPrice,
+            weight:item.tmsWeight,
+            tmsQuantity:item.tmsQuantity
+          })
+        }
+      }
+      this.load = false;
+      if(res.data.pricePlan){
+        try{
+          this.priceData = JSON.parse(res.data.pricePlan);
+        }catch(e){
+          this.priceData = [];
+          console.error('价格列表数据转换错误!')
+        }
+        
+      }
+      setTimeout(()=>{
+        if(this.$refs.info){
+          (this.$refs.info as any).setValue(this.value)
+        }
+      },1000)
+      
+    }).catch(() => {
+      this.load = false;
+    })
+  }
+  cancelDelivery(){
+    let msg = '';
+    if(this.value.shippingType == 'MORE'){
+      msg = '此操作将导致整车订单的发货被取消,是否继续?'
+    }
+    if(this.value.shippingType == 'ONE'){
+      msg = '此操作将导致该订单的发货被取消,是否继续?'
+    }
+    if(msg){
+      this.$confirm(msg, '提示', {
+        confirmButtonText: '继续',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.load = true;
+        cancleSendOrder({orderNos:[this.value.tmsOrderNo]}).then((res:any) => {
+          this.drawer = false;
+          this.load =false;
+          this.$message({
+            message:'该订单的发货已被取消!',
+            type:'success'
+          })
+          this.$emit('handleSuccess');
+        }).catch(() => {
+          this.load = false;
+        })
+      }).catch(() => {});
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .send-box{
+    width: 100%;
+    box-sizing: border-box;
+    padding: 16px;
+    padding-bottom: 0;
+    margin-bottom: 16px;
+    background-color: rgba(160,205,255,0.22);
+    .pri-title{
+      width: 100%;
+      padding-bottom: 8px;
+      display: flex;
+      align-items: center;
+      .title-item{
+        width: 188px;
+        font-size: 12px;
+        span{
+          color: #1684FC;
+          padding-left: 8px;
+        }
+      }
+    }
+    .send-type{
+      width: 100%;
+      display: flex;
+      align-items: center;
+      flex-wrap:wrap;
+      .send-item{
+        width: 165px;
+        box-sizing: border-box;
+        border:solid 3px #999;
+        border-radius: 6px;
+        overflow: hidden;
+        margin-right: 32px;
+        margin-bottom: 16px;
+        // cursor: pointer;
+        .label-name{
+          background-color: #999;
+          color: #FFF;
+          font-size: 16px;
+          font-weight: 700;
+          padding: 2px 0 4px;
+          text-align: center;
+        }
+        .send-info{
+          padding: 8px 0;
+          text-align: center;
+          background-color: #FFF;
+          .s-time{
+            font-size: 14px;
+            color: #1684FC;
+          }
+          .send-price{
+            font-size: 20px;
+            padding-top: 4px;
+          }
+        }
+      }
+      .onSend{
+        border:solid 3px #1684FC;
+        .label-name{
+          background-color: #1684FC;
+        }
+      }
+      .ont{
+        border:solid 3px #FF0404;
+        .label-name{
+          background-color: #FF0404;
+        }
+      }
+    }
+    .s-row{
+      width: 100%;
+      display: flex;
+      align-items: center;
+      padding-bottom: 16px;
+      .s-col{
+        width: 100%;
+        font-size: 14px;
+      }
+      .width50{
+        width: 50%;
+      }
+    }
+    .s-row:last-child{
+      padding: 16;
+    }
+  }
+}
+.deli-footer{
+  height: 60px;
+  box-shadow: 0 -5px 10px #EEE;
+  width: 100%;
+  padding: 0 16px;
+  box-sizing: border-box;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  position: absolute;
+  background-color: #FFF;
+  left: 0;
+  bottom: 0;
+  z-index: 10;
+  .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);
+    margin-left: 16px;
+    cursor: pointer;
+  }
+}
+.space{
+  height: 60px;
+  width: 100%;
+  margin-top: 16px;
+}
+</style>

+ 679 - 0
src/views/oms/B2BOrder/components/deliveryGoodsInfo.vue

@@ -0,0 +1,679 @@
+<template>
+  <div class="info">
+    <div class="edit" v-if="!readOnly">
+      <span @click="edit">编辑</span>
+    </div>
+    <div class="g-box">
+      <div class="info-row" v-if="!hideOrderCode">
+        <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 col-width">
+          <span class="label">订单类型:</span>
+          <span :title="value.orderType">{{ value.orderType }}</span>
+        </div>
+      </div> -->
+      <div class="info-row">
+        <div class="info-col">
+          <span class="label">业务员:</span>
+          <span :title="value.tmsBusinessMan">{{ value.tmsBusinessMan }}</span>
+        </div>
+        
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">业务员手机:</span>
+          <span :title="value.tmsBusinessPhone">{{ value.tmsBusinessPhone }}</span>
+        </div>
+        <div class="info-col col-width" v-if="!sendState">
+          <span class="label">发货状态:</span>
+          <span>{{ value.isSuccess ? '发货中' : '' }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">运输方式:</span>
+          <span :title="value.tmsTransportMethod">{{ value.tmsTransportMethod }}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">备注:</span>
+          <span :title="value.tmsRemark">{{ value.tmsRemark }}</span>
+        </div>
+      </div>
+    </div>
+    <div class="g-box">
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货省:</span>
+          <span :title="value.tmsShipmentProvince">{{ value.tmsShipmentProvince }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货省:</span>
+          <span :title="value.tmsUnloadingProvince">{{ value.tmsUnloadingProvince }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货市:</span>
+          <span :title="value.tmsShipmentCity">{{ value.tmsShipmentCity }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货市:</span>
+          <span :title="value.tmsUnloadingCity">{{ value.tmsUnloadingCity }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货区(县):</span>
+          <span :title="value.tmsShipmentRegion">{{ value.tmsShipmentRegion }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货区(县):</span>
+          <span :title="value.tmsUnloadingRegion">{{ value.tmsUnloadingRegion }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货街道:</span>
+          <span :title="value.tmsShipmentStreet">{{ value.tmsShipmentStreet }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货街道:</span>
+          <span :title="value.tmsUnloadingStreet">{{ value.tmsUnloadingStreet }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货地址(详情):</span>
+          <span :title="value.tmsShipmentAddress">{{ value.tmsShipmentAddress }}</span>
+        </div> -->
+        <div class="info-col">
+          <span class="label">收货地址(详情):</span>
+          <span :title="value.tmsUnloadingAddress">{{ value.tmsUnloadingAddress }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">发货人:</span>
+          <span :title="value.tmsShipmentConsignor">{{ value.tmsShipmentConsignor }}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">收货人:</span>
+          <span :title="value.tmsUnloadingConsignor">{{ value.tmsUnloadingConsignor }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">发货人联系电话:</span>
+          <span :title="value.tmsShipmentContacts">{{ value.tmsShipmentContacts }}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">收货人联系电话:</span>
+          <span :title="value.tmsUnloadingContacts">{{ value.tmsUnloadingContacts }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">期望送达时间:</span>
+          <span class="time">{{value.tmsArrivalDate}}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">期望提货时间:</span>
+          <span class="time">{{value.tmsDeliveryDate}}</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">重量合计(kg):</span>
+            <span class="total-num">{{totalWeight}}</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="重量(g)"></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>
+    <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" v-if="showModal" ref="form" @formChange="formChange" />
+      <template #footer>
+        <div class="btn">
+          <el-button plain size="small" @click="showModal = false">取消</el-button>
+          <el-button type="primary" size="small" @click="btn">确定</el-button>
+        </div>
+      </template>
+    </vxe-modal>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+@Component
+export default class DeliveryGoodsInfo extends Vue {
+  @Prop()
+  hideOrderCode?:Boolean
+  @Prop()
+  sendState?:Boolean
+  @Prop()
+  readOnly?:Boolean
+
+  data:Array<any>=[];
+  value:any={};
+  showModal=false;
+  totalWeight:any=0;
+  config:any={
+    attr:{
+      size:'small',
+      labelWidth:'120px',
+      rules:{
+        // orderType:[{
+        //   required: true, message: '请选择订单类型!', trigger: 'change'
+        // }],
+        tmsBusinessMan:[
+          { required: true, message: '业务员不能为空!', trigger: 'blur' },
+          { min: 0, max: 5, message: '业务员名字不能超过10个字符!', trigger: 'blur' }
+        ],
+        tmsBusinessPhone:[{
+          required: true, message: '业务员手机不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur'
+        }],
+        tmsShipmentConsignor:[{
+          required: true, message: '发货人不能为空!', trigger: 'blur'
+        }],
+        tmsShipmentContacts:[{
+          required: true, message: '发货人电话不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }],
+        // tmsShipmentProvince:[{
+        //   required: true, message: '请选择发货地址!', trigger: 'change'
+        // }],
+        // tmsShipmentAddress:[{
+        //   required: true, message: '发货地址不能为空!', trigger: 'blur'
+        // }],
+        tmsUnloadingConsignor:[{
+          required: true, message: '收货人不能为空!', trigger: 'blur'
+        }],
+        tmsUnloadingContacts:[{
+          required: true, message: '收货人电话不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }],
+        tmsUnloadingProvince:[{
+          required: true, message: '请选择收货地址!', trigger: 'change'
+        }],
+        tmsUnloadingAddress:[{
+          required: true, message: '收货地址不能为空!', trigger: 'blur'
+        }],
+        storeHouseId:[{
+          required: true, message: '请选择仓库!', trigger: 'change'
+        }],
+        tmsArrivalDate:[{
+          required: true, message: '期望送达时间不能为空!', trigger: 'blur'
+        }],
+        tmsDeliveryDate:[{
+          required: true, message: '期望提货时间不能为空!', trigger: 'blur'
+        }],
+        // tmsTransportMethod: [{
+        //   required: true, message: '运输方式不能为空!', trigger: 'change'
+        // }],
+        wmsSendType: [{
+          required: true, message: '出库方式不能为空!', trigger: 'change'
+        }]
+      }
+    },
+    columns:[
+      // [
+      //   {
+      //   label:'订单类型',
+      //   prop:'orderType',
+      //   component:'by-select',
+      //   compConfig:{
+      //     attr:{
+      //       data: [{
+      //         label:'B2C',
+      //         value:'B2C'
+      //       },{
+      //         label:'B2B',
+      //         value:'B2B'
+      //       }],
+      //       clearable:true
+      //     }
+      //   }
+      // }
+      // ],
+      [{
+        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,
+            defaultIndex:0,
+            retConfig:{
+              tmsShipmentProvince: 'province',
+              tmsShipmentProvinceNo:'provinceCode',
+              tmsShipmentCity: 'city',
+              tmsShipmentCityNo: 'cityCode',
+              tmsShipmentRegion: 'region',
+              tmsShipmentRegionNo: 'regionCode',
+              tmsShipmentStreetNo: 'streetCode',
+              tmsShipmentStreet: 'street',
+              tmsShipmentAddress:'address',
+              storeHouseId: 'id'
+            }
+          }
+        }
+      },{
+        span:12,
+        label:'出库方式',
+        prop:'wmsSendType',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            // clearable:true,
+            data: [
+              // {
+              //   label:'越库出库',
+              //   value:'YKCK'
+              // },
+              {
+                label:'B2B出库',
+                value:'B2BCK'
+              },
+              // {
+              //   label:'B2C出库',
+              //   value:'B2CCK'
+              // }
+            ]
+          }
+        }
+      }
+      // ,{
+      //   label:'运输方式',
+      //   prop:'tmsTransportMethod',
+      //   component:'by-select',
+      //   compConfig:{
+      //     attr:{
+      //       clearable:true,
+      //       data: [{
+      //         label:'整车',
+      //         value:'整车'
+      //       },{
+      //         label:'零担',
+      //         value:'零担'
+      //       },{
+      //         label:'短驳',
+      //         value:'短驳'
+      //       }]
+      //     }
+      //   }
+      // }
+      ],
+      [{
+        label:'发货人',
+        prop:'tmsShipmentConsignor',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        label:'发货人电话',
+        prop:'tmsShipmentContacts',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      // [{
+      //   labelWidth:'120px',
+      //   label:'发货地址选择',
+      //   prop:'tmsShipmentProvince',
+      //   component:'by-area',
+      //   compConfig:{
+      //     attr:{
+      //       province:'tmsShipmentProvince', //省
+      //       provinceCode:'tmsShipmentProvinceNo', //省编码
+      //       city:'tmsShipmentCity',   //市
+      //       cityCode:'tmsShipmentCityNo',  //市编码
+      //       county:'tmsShipmentRegion',  //县/区
+      //       countyCode:'tmsShipmentRegionNo',   //县/区编码
+      //       townCode:'tmsShipmentStreetNo',
+      //       town:'tmsShipmentStreet',
+      //       broadcastConfig:{
+      //         name: 'warehouseChange',
+      //         // dataHandle: (data:any) => {
+      //         //   let v = (this as any).$lodash.cloneDeep(data)
+      //         //   delete v.storeHouseId
+      //         //   return v
+      //         // }
+      //       }
+      //     }
+      //   }
+      // }],
+      // [{
+      //   label:'发货地址',
+      //   prop:'tmsShipmentAddress',
+      //   component:'by-input',
+      //   compConfig:{
+      //     attr:{
+      //       clearable:true
+      //     }
+      //   }
+      // }],
+      [{
+        label:'收货人',
+        prop:'tmsUnloadingConsignor',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        label:'收货人电话',
+        prop:'tmsUnloadingContacts',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        labelWidth:'120px',
+        label:'收货地址选择',
+        prop:'tmsUnloadingProvince',
+        component:'by-area',
+        compConfig:{
+          attr:{
+            province:'tmsUnloadingProvince', //省
+            provinceCode:'tmsUnloadingProvinceNo', //省编码
+            city:'tmsUnloadingCity',   //市
+            cityCode:'tmsUnloadingCityNo',  //市编码
+            county:'tmsUnloadingRegion',  //县/区
+            countyCode:'tmsUnloadingRegionNo',   //县/区编码
+            townCode:'tmsUnloadingStreetNo',
+            town:'tmsUnloadingStreet'
+          }
+        }
+      }],
+      [{
+        label:'收货人地址',
+        prop:'tmsUnloadingAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'期望送达时间',
+        prop:'tmsArrivalDate',
+        component:'byDatePicker',
+        compConfig:{
+          attr:{
+            clearable:true,
+            type:'datetime'
+          }
+        }
+      },{
+        label:'期望提货时间',
+        prop:'tmsDeliveryDate',
+        component:'byDatePicker',
+        compConfig:{
+          attr:{
+            clearable:true,
+            type:'datetime'
+          }
+        }
+      }],
+      [{
+        label:'备注',
+        prop:'tmsRemark',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));                                                                                                             
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  setValue(v:any){
+    this.value = v ? v : {};
+    this.value.wmsSendType = 'B2BCK'
+    this.totalWeight = 0;
+    if(v.weight){
+      this.totalWeight = divide(v.weight,1000)
+    }
+    
+    // this.totalWeight = divide(v.weight,1000);
+    // if(this.value.subItem && this.value.subItem.length > 0){
+    //   for(const item of this.value.subItem){
+    //     if(Number(item.weight)){
+    //       let totalWeight = multiply(Number(item.weight),Number(item.tmsQuantity))
+    //       this.totalWeight = add(this.totalWeight,totalWeight);
+    //     }
+    //   }
+    //   this.totalWeight = divide(this.totalWeight,1000);
+    // }
+  }
+  hide(){
+    this.$emit('editState',true)
+  }
+  show(){
+    // this.value.tmsBusinessMan = (this as any).$store.getters.userInfo.userName;
+    // this.value.tmsBusinessPhone = (this as any).$store.getters.userInfo.phonenumber;
+    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.$emit('editState',false)
+  }
+  formChange(parames:any){
+    let data = (this.$refs.form as any).getValue();
+    if(data['tmsArrivalDate'] && data['tmsDeliveryDate']){
+      if(data['tmsArrivalDate'] > data['tmsDeliveryDate']){
+        this.$message({
+          message:'期望送达时间不能大于期望提货时间',
+          type:'warning'
+        })
+        if(parames.code == 'tmsArrivalDate'){
+          data['tmsArrivalDate'] = ''
+        }
+        if(parames.code == 'tmsDeliveryDate'){
+          data['tmsDeliveryDate'] = ''
+        }
+        // (this.$refs.form as any).clearValue();
+        (this.$refs.form as any).setValue(data);
+      }
+    }
+  }
+  btn() {
+    if(this.$refs.form){
+      (this.$refs.form as any).validate().then(()=>{
+        this.value = (this.$refs.form as any).getValue();
+        if(!this.value.tmsShipmentCity){
+          this.$message({
+            message:'请选择发货城市!',
+            type:'warning'
+          })
+          return
+        }
+        if(!this.value.tmsShipmentRegion){
+          this.$message({
+            message:'请选择发货区/县!',
+            type:'warning'
+          })
+          return
+        }
+        if(!this.value.tmsUnloadingCity){
+          this.$message({
+            message:'请选择收货城市!',
+            type:'warning'
+          })
+          return
+        }
+        if(!this.value.tmsUnloadingRegion){
+          this.$message({
+            message:'请选择收货区/县!',
+            type:'warning'
+          })
+          return
+        }
+        this.showModal = false;
+        this.$emit('editState',true);
+        this.$emit('editResult',this.value);
+      }).catch(()=>{})
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.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;
+  } 
+}
+</style>
+<style lang="scss">
+.header-cell{
+  background-color: rgba(160,205,255,0.48);
+}
+</style>

+ 150 - 0
src/views/oms/B2BOrder/components/deliveryPrice.vue

@@ -0,0 +1,150 @@
+<template>
+  <div class="send-box">
+    <div class="title-label">预计配送和预计费用</div>
+    <div class="send-type">
+      <el-popover
+        v-for="(item,index) of data" :key="index"
+        placement="top-start"
+        width="200"
+        trigger="hover">
+        <div class="price-info">
+          <div class="price-title">预估费用明细:</div>
+          <div class="price-row freight">
+            <span class="p-label">运费:</span>
+            <span class="p-value">¥{{item.estimateFreight}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">单价:</span>
+            <span class="p-value">¥{{item.unitprice}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">重量:</span>
+            <span class="p-value">{{item.weight}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">体积:</span>
+            <span class="p-value">{{item.volume}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">单位:</span>
+            <span class="p-value">{{item.unit}}</span>
+          </div>
+        </div>
+        <div slot="reference" class="send-item" :title="item.ruleName" :class="{'onSend':currentValue.id == item.id}" @click="priceHandle(index)" >
+          <div class="label-name">{{item.ruleName}}</div>
+          <div class="send-info">
+            <div class="s-time">{{item.endTime}}前</div>
+            <div class="send-price">¥{{item.estimateFreight}}</div>
+          </div>
+        </div>
+      </el-popover>
+      
+    </div>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component({components:{}})
+export default class DeliveryPrice extends Vue {
+  @Prop()
+  data?:Array<any>;
+
+  @Prop()
+  currentValue?:any;
+
+  onIndex:any=null;
+  mounted(){
+   
+  }
+  priceHandle(index:number){
+    // this.onIndex = item.id;
+    this.$emit('prichChange',index)
+  }
+
+}
+</script>
+<style lang="scss" scoped>
+.send-box{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 16px;
+  padding-bottom: 0;
+  background-color: rgba(255, 226, 160, 0.3);
+  .title-label{
+    font-size: 14px;
+    padding-bottom: 8px;
+  }
+  .send-type{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    flex-wrap:wrap;
+    .send-item{
+      width: 165px;
+      box-sizing: border-box;
+      border:solid 3px #999;
+      border-radius: 6px;
+      overflow: hidden;
+      margin-right: 32px;
+      cursor: pointer;
+      margin-bottom: 16px;
+      .label-name{
+        background-color: #999;
+        color: #FFF;
+        font-size: 16px;
+        font-weight: 700;
+        padding: 2px 0 4px;
+        text-align: center;
+        width: 100%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+      .send-info{
+        padding: 8px 0;
+        text-align: center;
+        background-color: #FFF;
+        .s-time{
+          font-size: 14px;
+          color: #1684FC;
+          font-weight: 700;
+        }
+        .send-price{
+          font-size: 20px;
+          padding-top: 4px;
+        }
+      }
+    }
+    .send-item:hover,.onSend{
+      border:solid 3px #1684FC;
+      .label-name{
+        background-color: #1684FC;
+      }
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.price-info{
+  width: 100%;
+  color: #000;
+  .price-title{
+    font-size: 16px;
+    font-weight: 700;
+    padding-bottom: 4px;
+  }
+  .price-row{
+    width: 100%;
+    display: flex;
+    font-size: 12px;
+    padding: 3px;
+    // display: flex;
+    // justify-content: space-between;
+  }
+  .freight{
+    font-size: 14px;
+    font-weight: 700;
+  }
+}
+</style>

+ 502 - 0
src/views/oms/B2BOrder/components/editProductModal.vue

@@ -0,0 +1,502 @@
+<template>
+  <vxe-modal v-model="value" id="editProductModal" width="70%" height="80%" @hide="hide" title="商品编辑" transfer show-footer v-loading="load">
+    <by-form :propConfig="form" ref="form" @formChange="formChange">
+      <template v-slot:isPay="{value}">
+        <el-switch
+          v-model="value.isPay">
+        </el-switch>
+      </template>
+      <template v-slot:freeAmount="{value}">
+        <vxe-input v-model="value.freeAmount" class="freeAmount" placeholder="保留两位小数或百分比输入" size="mini" @change="freeAmountChange"></vxe-input>
+      </template>
+    </by-form>
+    <div class="tool-comp">
+      <by-tool :propConfig="toolConfig" ref="tool"></by-tool>
+    </div>
+    <by-table :propConfig="tableConfig" ref="table">
+      <template v-slot:name='{ row }'>
+        <div class="product-cont">
+          <div class="product-name">
+            {{ row.name }}
+            <el-tag v-if="row.isGift == 1" size="mini" type="success">赠</el-tag>
+            <el-tag v-if="row.__status === 'delete'" size="mini" type="info" class="del-tag">待删除</el-tag>
+          </div>
+        </div>
+      </template>
+      <template v-slot:qty='{ row }'>
+        <span v-if="row.__status === 'delete'">{{ row.qty }}</span>
+        <vxe-input v-else v-model="row.qty"  placeholder="数量" align="center" size="mini" type="integer" @change="qtyChange($event, row)" >
+        </vxe-input>
+      </template>
+      <template v-slot:price='{ row }'>
+        <span v-if="row.isGift == 1">0</span>
+        <vxe-input v-else-if="row.__status !== 'delete'" v-model="row.price" placeholder="单价" align="center" size="mini" type="number" @change="priceChange($event, row)" >
+        </vxe-input>
+        <span v-else>{{ row.price }}</span>
+      </template>
+    </by-table>
+    <div class="product-row">
+      <div class="p-left">数量:{{ num }}</div>
+      <div class="p-right">
+        <div class="amount-title">商品成交总金额:</div>
+        <div class="amount-price">¥{{ productTotal }}</div>
+      </div>
+    </div>
+    <div class="product-row">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">抵扣金额:</div>
+        <div class="amount-price">¥{{freeAmount?freeAmount:'0.00'}}</div>
+      </div>
+    </div>
+    <div class="product-row">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">运费:</div>
+        <div class="amount-price">¥{{freight?freight:'0.00'}}</div>
+      </div>
+    </div>
+    <div class="product-row">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">应付总金额:</div>
+        <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{payAmount?payAmount:'0.00'}}</div>
+      </div>
+    </div>
+    <div class="product-row" v-if="orderValue.paidAmount">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">实付总金额:</div>
+        <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{orderValue.paidAmount?orderValue.paidAmount:'0.00'}}</div>
+      </div>
+    </div>
+    <product-sku-modal ref="product" :mulit="true" @confirm="confirmProduct" />
+    <product-sku-modal ref="productGift" :mulit="true" @confirm="confirmProductGift" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import { batchItem } from '@/api/omsOrder'
+@Component
+export default class EditProductModal extends Vue {
+  value=false;
+  load = false;
+  num:any=0;//数量
+  payAmount:any=0; //应付总金额
+  productTotal:any=0;//商品成交总金额
+  freeAmount:any=0;//抵扣
+  freight:any=0;//运费
+  orderValue:any={}
+  toolConfig={
+    customTools:[
+      {
+        name: '新增商品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddProduct()
+          }
+        }
+      },
+      {
+        name: '添加赠品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddGift();
+            
+          }
+        }
+      }
+    ]
+  }
+  form:any={
+    attr:{
+      size:'mini'
+    },
+    columns:[
+      [{
+        label:'运费',
+        prop:'freight',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'保留两位小数',
+            size:'mini',
+            type:'number'
+          }
+        }
+      },{
+        label:'抵扣金额',
+        prop:'freeAmount',
+        labelWidth:'100px',
+        slot:true,
+        // component:'by-input',
+        // compConfig:{
+        //   attr:{
+        //     placeholder:'保留两位小数',
+        //     size:'mini'
+        //   }
+        // }
+      },{
+        label:'快速支付',
+        prop:'isPay',
+        slot:true
+      }]
+    ]
+  }
+  tableConfig:any={
+    attr:{
+      size:'mini',
+      align:'center',
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      slot:true,
+      width:300
+    },{
+      title:'数量',
+      field:'qty',
+      width:100,
+      slot:true
+    },{
+      title:'单价',
+      field:'price',
+      width:100,
+      slot:true
+    },{
+      title:'原价',
+      field:'basePrice',
+      width:100
+    },{
+      title:'成交金额',
+      field:'amount',
+      width:100
+    },
+
+    {
+      title:'操作',
+      action:true,
+      plugins:[{
+        icon:'el-icon-delete',
+        name:'删除',
+        event:{
+          click:(item:any) => {
+            this.deletaProduct(item);
+          },
+          show:(item:any) => {
+            return item.__status !== 'delete'
+          }
+        }
+      },{
+        icon:'el-icon-refresh-left',
+        name:'恢复数据',
+        audit:'',
+        event:{
+          click:(item:any) => {
+            this.restoreData(item);
+          },
+          show:(item:any) => {
+            return item.__status === 'delete'
+          }
+        }
+      }]
+    }]
+  }
+  //添加商品
+  toolAddProduct(){
+    (this.$refs.product as any).setShow(true);
+  }
+  //添加赠品
+  toolAddGift(){
+    (this.$refs.productGift as any).setShow(true);
+  }
+  hide(){}
+  setShow(v:boolean){
+    this.value = v;
+  }
+  btn(){
+    let data = (this.$refs.table as any).getValue();
+    let formValue = (this.$refs.form as any).getValue();
+    let parames:any={};
+    parames.addItems=[];
+    parames.addGifts=[];
+    parames.delItems=[];
+    parames.editItems=[];
+    parames.id = this.orderValue.id;
+    parames.freight=formValue.freight;
+    parames.freeAmount=formValue.freeAmount;
+    parames.isPay = formValue.isPay?true:false;
+    for(const item of data){
+      if(!item.id){
+        if(item.isGift == 1){
+          parames.addGifts.push({
+            itemId:item.itemId,
+            qty:item.qty,
+            price:0
+          })
+        }else{
+          parames.addItems.push({
+            itemId:item.itemId,
+            qty:item.qty,
+            price:item.price
+          })
+        }
+      }else{
+        if(item.__status == 'delete'){
+          parames.delItems.push(item.id)
+        }else if(item.__status == 'modify'){
+          parames.editItems.push({
+            itemId:item.id,
+            qty:item.qty,
+            price:item.price
+          })
+        }
+      }
+    }
+    this.load = true;
+    batchItem(parames).then(()=>{
+      this.value = false;
+      this.load = false;
+      this.$emit('handleSuccess')
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  setOrderValue(v:any){
+    this.orderValue = v;
+    this.$nextTick(()=>{
+      let newValue:any = {};
+      newValue.freight = v.freight;
+      newValue.freeAmount = v.freeAmount;
+      newValue.isPay = false;
+      this.payAmount = v.payAmount;
+      this.freeAmount = v.freeAmount;
+      if(this.$refs.form){
+        (this.$refs.form as any).setValue(newValue)
+      }
+    })
+  }
+  setTableValue(v:any){
+    this.$nextTick(()=>{
+      if(this.$refs.table){
+        (this.$refs.table as any).setValue(v);
+        this.totalAmount();
+        this.totalNum();
+      }
+    })
+  }
+  //商品成交总金额
+  totalAmount(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.productTotal = 0;
+    for(const item of nowData){
+      if(Number(item.amount) && item.isGift != 1){
+        this.productTotal = add(item.amount, this.productTotal)
+      }
+    }
+    this.productTotal = this.productTotal.toFixed(2);
+  }
+  freeAmountChange(){
+    let data = (this.$refs.form as any).getValue()
+    if(data.freeAmount){
+      if(Number(data.freeAmount) >= 0){
+        this.freeAmount = Number(data.freeAmounte);
+      }else{
+        let arr:Array<any> = data.freeAmounte.split("%");
+        if(arr.length == 2 && Number(arr[0]) > 0){
+          const n = divide(Number(arr[0]),100)
+          this.freeAmount = multiply(this.productTotal,n)
+        }else{
+          this.freeAmount = 0;
+        }
+      }
+    }else{
+      this.freeAmount = 0;
+    }
+    this.payAmountChange();
+  }
+  //应付总金额
+  payAmountChange(){
+    let t = subtract(this.productTotal, this.freeAmount);
+    this.payAmount = add(t, this.freight);
+    this.payAmount = this.payAmount.toFixed(2);
+  }
+  //商品总数量
+  totalNum(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.num = 0;
+    for(const item of nowData){
+      if(Number(item.qty)){
+        this.num = add(Number(item.qty), Number(this.num))
+      }
+    }
+  }
+  formChange(data:any){
+    if(data.code == 'freight'){
+      this.freight = data.value?data.value:0;
+      this.payAmountChange();
+    }
+  }
+  //数量的变化
+  qtyChange(v:any,row:any){
+    if(v.value && row.price){
+      row.amount = multiply(Number(v.value),Number(row.price))
+    }else{
+      row.amount = 0
+    }
+    if(row.id){
+      row.__status='modify'
+    }
+    this.totalAmount();
+    this.freeAmountChange();
+    this.payAmountChange();
+    this.totalNum();
+  }
+  //单价的变化
+  priceChange(v:any,row:any){
+    if(v.value && row.qty){
+      row.amount =multiply(Number(v.value),Number(row.qty))
+    }else{
+      row.amount = 0
+    }
+    if(row.id){
+      row.__status='modify'
+    }
+    this.totalAmount();
+    this.freeAmountChange();
+    this.payAmountChange();
+  }
+  //确定新增的商品
+  confirmProduct(data:Array<any>){
+    this.productHandle(data,false);
+  }
+  //新增赠品
+  confirmProductGift(data:Array<any>){
+    this.productHandle(data,true);
+  }
+  //商品处理
+  productHandle(data:Array<any>,isGift:boolean){
+    let nowData = (this.$refs.table as any).getValue();
+    let names='';
+    if(data.length > 0){
+      for(const item of data){
+        let t = true;
+        let v = isGift ? 1 : 0;
+        for(const t_item of nowData){
+          if(item.id == t_item.itemId && t_item.isGift == v){
+            if(!names){
+              names = item.skuTitle
+            }else{
+              names = names + ',' + item.skuTitle
+            }
+            t = false;
+            break;
+          }
+        }
+        if(t){
+          let obj:any={};
+          obj.name = item.skuTitle; //商品名称
+          obj.skuId = item.skuCode; //商品编码
+          obj.itemId = item.id;
+          obj.styleId = item.itemNumber; //款式编码
+          obj.qty = 1;
+          if(isGift){
+            obj.price = 0;  //单价
+            obj.isGift = 1;
+          }else{
+            obj.price = item.price;  //单价
+            obj.isGift = 0;
+          }
+          
+          obj.basePrice = item.price; //原价
+          obj.amount = item.price;
+          nowData.push(obj)
+        }
+      }
+      (this.$refs.table as any).setValue(nowData);
+     
+      if(names){
+        let name = isGift ? '赠品' : '商品';
+        this.$alert(name+'“'+names+'”已存在,请在列表做调整!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {}
+        });
+      }
+    }
+  }
+  //删除商品
+  deletaProduct(row:any){
+    let data = (this.$refs.table as any).getValue();
+    let index = -1;
+    for(const item of data){
+      index ++;
+      if(row.skuId == item.skuId && row.name == item.name && row.isGift == item.isGift){
+        break;
+      }
+    }
+    if(row.id){
+      data[index].__status = 'delete'
+    }else{
+      data.splice(index,1);
+    }
+    
+    (this.$refs.table as any).setValue(data);
+  }
+  //恢复数据
+  restoreData(row:any){
+    let data = (this.$refs.table as any).getValue();
+    let index = -1;
+    for(const item of data){
+      index ++;
+      if(row.skuId == item.skuId && row.name == item.name && row.isGift == item.isGift){
+        break;
+      }
+    }
+    delete data[index].__status;
+    (this.$refs.table as any).setValue(data);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tool-comp{
+  width: 100%;
+  padding-bottom: 8px;
+}
+.del-tag{
+  margin-left: 8px;
+}
+.product-row{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  font-size: 12px;
+  padding: 4px 0;
+  .p-left,.p-right{
+    width: 50%;
+  }
+  .p-left{
+    text-align: right;
+  }
+  .p-right{
+    display: flex;
+    align-items: center;
+    .amount-title{
+      width: 70%;
+      text-align: right;
+      box-sizing: border-box;
+      padding-right: 8px;
+    }
+    .amount-price{
+      width: 30%;
+    }
+  }
+}
+</style>

+ 534 - 0
src/views/oms/B2BOrder/components/expressDeliveryModal.vue

@@ -0,0 +1,534 @@
+<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}}g</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="700" height="70%" @show="show" @hide="hide" title="编辑" resize show-zoom transfer show-footer>
+        <by-form :propConfig="config" v-if="showModal" 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={
+    attr:{
+      size:'small',
+      labelWidth:'120px',
+      rules:{
+        tmsBusinessMan:[{
+          required: true, message: '业务员不能为空!', trigger: 'blur'
+        },{ min: 0, max: 5, message: '业务员名字不能超过10个字符!', trigger: 'blur' }],
+        tmsBusinessPhone:[{
+          required: true, message: '业务员手机不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, 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:{
+            defaultIndex:0,
+            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
+          }
+        }
+      }]
+    ]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));                                                                                                             
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  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(add(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
+          })
+        }
+      }
+    }
+    this.$nextTick(() => {
+      this.edit()
+    })
+  }
+  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.showModal = false;
+        // this.getStoreCount(this.value);
+      }).catch(() => {})
+    }
+    
+  }
+  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>

+ 59 - 0
src/views/oms/B2BOrder/components/filterDate.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="filter-row">
+    <div class="label" v-if="title">{{title}}</div>
+    <div class="filter-cont">
+      <el-date-picker
+        v-model="value"
+        style="width: 100%;"
+        clearable
+        size="mini" 
+        type="datetimerange"
+        @change="change"
+        range-separator="-"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期">
+      </el-date-picker>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import Format from '@/benyun/utils/dateFormat'
+@Component
+export default class FilterInput extends Vue {
+  value:Array<any>=[]
+  @Prop()
+  title:string|undefined
+
+  clear(){
+    this.value = []
+  }
+
+  change(v:any){
+    this.value[0] = Format(v[0],'yyyy-MM-dd HH:mm:ss');
+    this.value[1] = Format(v[1],'yyyy-MM-dd HH:mm:ss');
+    this.$emit('change',this.value)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.filter-row{
+  width: 100%;
+  display: flex;
+  align-items: flex-start;
+  padding-bottom: 4px;
+  flex-direction: column;
+  .label{
+    // width: 80px;
+    flex-shrink: 0;
+    font-size: 14px;
+    text-align: right;
+  }
+  .filter-cont{
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 52 - 0
src/views/oms/B2BOrder/components/filterInput.vue

@@ -0,0 +1,52 @@
+<template>
+  <div class="filter-row">
+    <div class="label" v-if="title" :style="{width:labelWidth?labelWidth+'px':'70px'}">{{title}}</div>
+    <div class="filter-cont">
+      <el-input v-model="value" size="mini" :type="type" :placeholder="placeholder?placeholder:title" @input="input" clearable></el-input>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class FilterInput extends Vue {
+  value=''
+  @Prop()
+  title:string|undefined
+  @Prop()
+  placeholder?:string
+  @Prop()
+  type?:string
+  @Prop()
+  labelWidth?:number
+
+  clear(){
+    this.value = ''
+  }
+
+  input(v:any){
+    this.$emit('input',v)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.filter-row{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 4px;
+  .label{
+    width: 70px;
+    flex-shrink: 0;
+    font-size: 14px;
+    text-align: right;
+  }
+  .filter-cont{
+    width: 100%;
+    padding-left: 8px;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 83 - 0
src/views/oms/B2BOrder/components/filterMinMax.vue

@@ -0,0 +1,83 @@
+<template>
+  <div class="min-max">
+    <div v-if="title">{{title}}:</div>
+    <div class="munber-time">
+      <vxe-input v-model="value[minField]" class="number-input" size="mini" type="number" @input="mininput"></vxe-input>
+      <span class="split"> - </span>
+      <vxe-input v-model="value[maxField]" class="number-input" size="mini" type="number" @input="maxinput"></vxe-input>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderProduct extends Vue {
+  value:any={}
+
+  @Prop()
+  title!: string;
+  
+  @Prop()
+  minField!:string
+
+  @Prop()
+  maxField!:string
+  clear(){
+    this.value={}
+  }
+  mininput(){
+    const max = Number(this.value[this.maxField]);
+    const min = Number(this.value[this.minField]);
+    if(max < min){
+      this.$message({
+        message: '最小值不能超过最大值!',
+        type: 'warning'
+      })
+      this.value[this.minField] = null;
+      return
+    }
+    this.$emit('change',this.value)
+  }
+  maxinput(){
+    const max = Number(this.value[this.maxField]);
+    const min = Number(this.value[this.minField]);
+    if(max < min){
+      this.$message({
+        message: '最小值不能超过最大值!',
+        type: 'warning'
+      })
+      this.value[this.maxField] = null;
+      return
+    }
+    this.$emit('change',this.value)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.min-max{
+  width: 100%;
+  padding-bottom: 4px;
+  .munber-time{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    .split{
+      padding: 0 8px;
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.number-input{
+  width: 80px; 
+  flex-shrink: 0; 
+  padding: 0;
+  .el-input__inner{
+    padding: 0 !important;
+    text-align: center;
+  }
+}
+</style>

+ 78 - 0
src/views/oms/B2BOrder/components/freightModal.vue

@@ -0,0 +1,78 @@
+<template>
+  <vxe-modal v-model="value" id="freightModal" width="400" v-loading="load" @hide="hide" height="200" show-footer title="修改运费">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { editFreight } from '@/api/omsOrder'
+@Component({components:{}})
+export default class FreightModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      rules:{
+        freight: [
+          { required: true, message: '运费不能为空!', trigger: 'input' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'运费',
+        prop:'freight',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'保留两位小数',
+            type:'number'
+          }
+        }
+      }]
+    ]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  btn(){
+    (this.$refs.form as any).validate({noMsg:true}).then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      data.freight = Math.floor(Number(data.freight) * 100) / 100;
+      this.load = true
+      editFreight(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 70 - 0
src/views/oms/B2BOrder/components/inputSelect.vue

@@ -0,0 +1,70 @@
+<template>
+  <el-input :placeholder="placeholder" v-model="value" class="input-with-select" size="mini" @input="input" clearable>
+    <el-select v-model="select" slot="append" placeholder="请选择" @change="change">
+      <el-option v-for="(item,index) of options" :key="index" :label="item.label" :value="item.value"></el-option>
+    </el-select>
+  </el-input>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class InputSelect extends Vue {
+  value:any='';
+  select='';
+  placeholder='';
+  format:any=''
+  @Prop()
+  options!:Array<any>
+
+  mounted(){
+    if(this.options){
+      this.select = this.options[0].value;
+      this.placeholder = this.options[0].label;
+      this.format = this.options[0].format;
+    }
+  }
+
+  clear(){
+    this.value=""
+  }
+
+  change(v:any){
+    for(const item of this.options){
+      if(item.value == v){
+        this.placeholder = item.label;
+        this.format = item.format;
+      }
+    }
+  }
+  input(v:any){
+    console.log(v)
+    if(this.format && v){
+      this.value=v.replace(this.format,'');
+    }
+    let obj:any={};
+    obj[this.select] = this.value;
+    this.$emit('input',obj);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.input-with-select{
+  padding-bottom: 4px;
+  width: 100%;
+}
+</style>
+
+<style lang="scss">
+.input-with-select{
+  .el-input-group__append{
+    background-color: #fff !important;
+    width: 110px !important;
+  }  
+  .el-input__inner[type=number]{
+    padding-left: 15px !important;
+  }
+}
+
+</style>

+ 185 - 0
src/views/oms/B2BOrder/components/labelsModal.vue

@@ -0,0 +1,185 @@
+<template>
+  <vxe-modal v-model="value" id="labelsModal" width="70%" height="80%" @hide="hide" @show="show" title="选标签"  transfer show-footer v-loading="load">
+    <div class="labelBox" id="labelBox">
+      <by-tool :propConfig="tool" class="labelTool" @clickHandle="clickHandle" id="omsLabelTool" />
+      <by-table :propConfig="tableConfig" ref="table" >
+        <template v-slot:ordered="{row}">
+          <vxe-input v-if="row.isSystem != 1" v-model="row.ordered" size="small" type="number"></vxe-input>
+          <span v-else>{{ row.ordered }}</span>
+        </template>
+      </by-table>
+    </div>
+    <add-label ref="addLabel" @handleSuccess="getList" :isSystem="0" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import {queryAll, updateOrdered, del} from '@/api/omsLabel'
+import addLabel from '../../omsLabel/components/addLabel.vue'
+@Component({components:{addLabel}})
+export default class LabelsModal extends Vue {
+  value = false;
+  load = false;
+  tool={
+    tools:{
+      refresh:true
+    },
+    customTools:[{
+      name:'添加标签',
+      event:{
+        click:()=>{
+          (this.$refs.addLabel as any).setShow(true)
+        }
+      }
+    }],
+    audit:{}
+  }
+  tableConfig:any={
+    attr:{
+      triggerRowCheck:'row',
+      size:'mini',
+      align:'center',
+      seq:true,
+      checkbox:true
+    },
+    columns:[{
+      title:'名称',
+      field:'name'
+    },{
+      title:'排序',
+      field:'ordered',
+      width:150,
+      slot:true
+    },{
+      title:'操作',
+      action:true,
+      width:200,
+      plugins:[{
+        name:'排序',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.sortHandle(row);
+          }
+        }
+      },{
+        name:'删除',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.delHandle(row);
+          }
+        }
+      }]
+    }]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  show(){
+    this.$nextTick(()=>{
+      let height = (document.getElementById('labelBox') as any).parentNode.offsetHeight;
+      this.tableConfig.attr.height=height - 32 - 48;
+      if(this.$refs.table){
+        (this.$refs.table as any).setConfig(this.tableConfig);
+      }
+    })
+    this.getList()
+  }
+  getList(){
+    this.load = true;
+    queryAll().then((res:any) => {
+      this.load = false;
+      if(this.$refs.table){
+        (this.$refs.table as any).setValue(res.data);
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  hide(){
+    if(this.$refs.table){
+      (this.$refs.table as any).clearCheckboxRow();
+    }
+  }
+  sortHandle(row:any){
+    this.load = true;
+    updateOrdered({
+      id:row.id,
+      ordered:Number(row.ordered)
+    }).then(()=>{
+      this.load = false;
+      this.getList();
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  delHandle(row:any){
+    this.$confirm('此操作将删除“'+row.name+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+      del({
+        id:row.id
+      }).then(()=>{
+        this.load = false;
+        this.getList();
+      }).catch(()=>{
+        this.load = false
+      })
+    }).catch(()=>{})
+  }
+  btn(){
+    let data = (this.$refs.table as any).getSelectData();
+    let v='';
+    if(data.length == 0){
+      this.$message('请选择标签!')
+      return
+    }
+    if(data.length > 10){
+      this.$message('标签选择不能超过10个!')
+      return
+    }
+    for(const item of data){
+      if(v){
+        v = v + ','+item.name
+      }else{
+        v = item.name
+      }
+    }
+    this.value = false;
+    this.$emit('onChange',v);
+  }
+  clickHandle(e:string){
+    if(e == 'onAdd'){
+      (this.$refs.addLabel as any).setShow(true)
+    }
+    if(e == 'onRefresh'){
+      this.getList();
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.labelBox{
+  width: 100%;
+  height: 100%;
+}
+.labelTool{
+  padding-bottom: 16px;
+}
+</style>

+ 380 - 0
src/views/oms/B2BOrder/components/loadOrderModal.vue

@@ -0,0 +1,380 @@
+<template>
+  <vxe-modal v-model="value" id="synchronousOrderModal"  width="500" height="400" @hide="hide"  transfer show-footer v-loading="load">
+    <template #title>
+      <span>下载订单</span>
+    </template>
+    <template #default>
+      <div class="type">
+        <el-radio-group v-model="type">
+          <el-radio :label="1">按线上订单号</el-radio>
+          <el-radio :label="2">按时间段</el-radio>
+          <!-- <el-radio :label="3">按订单状态</el-radio> -->
+        </el-radio-group>
+      </div>
+      <div class="cont">
+        <div class="title"><span>* </span>上游平台:</div>
+        <div class="right-cont">
+          <el-select v-model="sourceId" size="mini" style="width:100%" placeholder="请选择" clearable @change="shopChange">
+            <el-option
+              v-for="item in sourceOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </div>
+      </div>
+      <template v-if="type == 1">
+        <div class="cont">
+          <div class="title"><span>* </span>线上订单:</div>
+          <div class="right-cont">
+            <el-input v-model="sourceIds" type="textarea" rows="4" size="mini" placeholder="每行一个单号,换行输入"></el-input>
+          </div>
+        </div>
+      </template>
+      <template v-if="type == 2">
+        <div class="cont">
+          <div class="title"><span>* </span>时间类型:</div>
+          <div class="right-cont">
+            <el-select v-model="dateType" size="mini" style="width:100%" placeholder="请选择" clearable>
+              <el-option
+                v-for="item in dateTypeOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="cont">
+          <div class="title"><span>* </span>时间:</div>
+          <div class="right-cont">
+            <el-date-picker
+              v-model="time"
+              style="width: 100%;"
+              size="mini"
+              type="datetimerange"
+              clearable
+              value-format="yyyy-MM-dd HH:mm:ss"
+              range-separator="-"
+              start-placeholder="开始日期"
+              @change="change"
+              end-placeholder="结束日期">
+            </el-date-picker>
+          </div>
+        </div>
+        <div class="cont">
+          <div class="title"><span></span>店铺名称:</div>
+          <div class="right-cont">
+            <el-select v-model="shopid" size="mini" style="width:100%" placeholder="请选择" clearable @change="shopChange">
+              <el-option
+                v-for="item in shopOpions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="cont">
+          <div class="title">订单状态:</div>
+          <div class="right-cont">
+            <el-select v-model="status" size="mini" style="width:100%" placeholder="请选择" clearable>
+              <el-option
+                v-for="item in statusOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+      </template>
+      <!-- <template v-if="type == 3">
+        <div class="cont">
+          <div class="title"><span>* </span>订单状态:</div>
+          <div class="right-cont">
+            <el-select v-model="status" size="mini" style="width:100%" placeholder="请选择" clearable>
+              <el-option
+                v-for="item in statusOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+      </template> -->
+    </template>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" plain @click="clear">清空</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { pullOrder } from '@/api/omsOrder'
+import { query,queryShop } from '@/api/sourceShop'
+@Component
+export default class LoadOrderModal extends Vue {
+  load = false;
+  value = false;
+  type=1;
+  sourceName = '';
+  sourceId:any = null;
+  sourceOptions:Array<any>=[
+    // {
+    // label:'犇云聚水潭店铺',
+    // value:2
+    // }
+  ]
+  shopid=''
+  shopOpions:Array<any>=[]
+  sourceIds=''; //线上订单号
+  dateType:any='';
+  dateTypeOptions=[{
+    label:'修改时间',
+    value:1
+  },{
+    label:'订单日期',
+    value:3
+  },{
+    label:'发货时间',
+    value:4
+  }]
+  beginDate='';
+  endDate='';
+  time:any=null;
+  status='';
+  statusOptions:Array<any>=[{
+    label:'待付款',
+    value:'WaitPay'
+  },{
+    label:'发货中',
+    value:'Delivering'
+  },{
+    label:'被合并',
+    value:'Merged'
+  },{
+    label:'异常',
+    value:'Question'
+  },{
+    label:'被拆分',
+    value:'Split'
+  },{
+    label:'等供销商|外仓发货',
+    value:'WaitOuterSent'
+  },{
+    label:'已付款待审核',
+    value:'WaitConfirm'
+  },{
+    label:'已客审待财审',
+    value:'WaitFConfirm'
+  },{
+    label:'已发货',
+    value:'Sent'
+  },{
+    label:'取消',
+    value:'Cancelled'
+  }]
+  setShow(v:boolean){
+    this.value = v;
+  }
+  change(v:any){
+    if(v){
+      this.beginDate = v[0];
+      this.endDate = v[1];
+    }else{
+      this.beginDate = '';
+      this.endDate = '';
+    }
+  }
+  shopChange(v:any){
+    if(v){
+      for(const item of this.sourceOptions){
+        if(item.value == v){
+          this.sourceName = item.label
+          break;
+        }
+      }
+      this.getSourceShopList()
+    }else{
+      this.sourceName=''
+      this.shopid=''
+      this.shopOpions=[]
+    }
+  }
+  btn(){
+    let value:any={};
+    let msg = '';
+    if(!this.sourceId){
+      msg = '上游平台'
+    }
+    value.sourceId = this.sourceId;
+    value.soueceName = this.sourceName;
+    value.type = this.type;
+    if(this.type == 1){
+      if(!this.sourceIds){
+        if(msg){
+          msg = msg + ',线上订单'
+        }else{
+          msg = '线上订单'
+        }
+      }
+      value.sourceIds = this.sourceIds.split('\n');
+    }else if(this.type == 2){
+      let isS=false;
+      value.shopId = this.shopid
+      for(const item of this.dateTypeOptions){
+        if(item.value == this.dateType){
+          isS = true;
+          break
+        }
+      }
+      // if(!this.status){
+      //   if(msg){
+      //     msg = msg + ',订单状态'
+      //   }else{
+      //     msg = '订单状态'
+      //   }
+      // }
+      value.status = this.status;
+      if(!isS){
+        if(msg){
+          msg = msg + ',时间类型'
+        }else{
+          msg = '时间类型'
+        }
+      }
+      if(!this.time){
+        if(msg){
+          msg = msg + ',时间'
+        }else{
+          msg = '时间'
+        }
+      }
+      value.dateType = Number(this.dateType) - 1;
+      value.beginDate = this.beginDate;
+      value.endDate = this.endDate;
+    }
+    if(msg){
+      this.$message({
+        message:msg + '不能为空!',
+        type: 'warning'
+      })
+      return
+    }
+    this.load = true;
+    pullOrder(value).then((res:any) => {
+      this.load = false;
+      this.value = false;
+      if(res.data > 0){
+        (this as any).$message({
+          message: '已同步到' + res.data + '条订单!',
+          type: 'success',
+        });
+        this.$emit('handleSuccess');
+      }else{
+        (this as any).$message({
+          message: '未更新数据!',
+          type: 'warning',
+        });
+      }
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+  hide(){
+    this.clear()
+  }
+  clear(){
+    this.type = 1;
+    this.sourceName = '';
+    this.sourceId = '';
+    this.sourceIds = '';
+    this.dateType = '';
+    this.beginDate = '';
+    this.endDate = '';
+    this.time = null;
+    this.status = '';
+    this.shopid = ''
+  }
+  //上游平台
+  getSourceList() {
+    this.sourceOptions = []
+    this.load = true
+    query({
+      pageNo: 1,
+      pageSize: 50
+    }).then((res:any) => {
+      this.load = false
+      if (res.data && res.data.records) {
+        for(const item of res.data.records) {
+          this.sourceOptions.push({
+            label: item.sourceName,
+            value: item.id
+          })
+        }
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  //店铺
+  getSourceShopList(){
+    this.shopOpions = []
+    queryShop({
+      sourceId:this.sourceId
+    }).then((res:any) => {
+      this.load = false
+      if (res.data) {
+        for(const item of res.data) {
+          this.shopOpions.push({
+            label: item.shopName,
+            value: item.shopId
+          })
+        }
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  created() {
+    this.getSourceList()
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+}
+.type{
+  width: 100%;
+  padding: 8px 0;
+}
+.cont{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding: 8px 0;
+  .title{
+    width: 100px;
+    text-align: right;
+    margin: 0 !important;
+    >span{
+      color: #F00;
+    }
+  }
+  .right-cont{
+    width: calc(100% - 100px);
+  }
+}
+</style>

+ 80 - 0
src/views/oms/B2BOrder/components/logisticsInfo.vue

@@ -0,0 +1,80 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    title="物流信息"
+    :visible.sync="drawer"
+    :direction="direction"
+    size="30%">
+    <div class="order-logistcs">
+      <el-timeline :reverse="true">
+        <el-timeline-item v-for="(item,index) of data" :key="index" :timestamp="item.tmsStatus + ' ' +item.createTime" placement="top">
+          <el-card>
+            <!-- <h4>{{item.tmsStatus}}</h4> -->
+            <p v-if="item.tmsOrderNo">单号:{{ item.tmsOrderNo }}</p>
+            <!-- <p v-if="item.tmsCarrierName">物流:{{ item.tmsCarrierName }}</p> -->
+            <p v-if="item.tmsPlateNumber">车牌:{{ item.tmsPlateNumber }}</p>
+            <p v-if="item.tmsDriverName">司机:{{ item.tmsDriverName }}</p>
+            <p v-if="item.tmsDriverPhone">电话:{{ item.tmsDriverPhone }}</p>
+          </el-card>
+        </el-timeline-item>
+      </el-timeline>
+    </div>
+      
+  </el-drawer>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { queryByOrderNo } from  '@/api/delivery'
+@Component({components:{}})
+export default class LogisticsInfo extends Vue {
+  drawer=false;
+  direction='rtl'
+  load = false;
+  data:Array<any>=[]
+
+  setShow(v:boolean){
+    this.drawer = v;
+  }
+  loadData(code:string){
+    if(!code){
+      this.$message('订单编号不能为空!')
+      return
+    }
+    this.load = true;
+    queryByOrderNo({orderNo:code}).then((res:any) => {
+      this.load = false;
+      this.data = []
+      if(res.data){
+        this.data = res.data;
+      }
+    }).catch(() => {
+      this.load = false;
+    })
+  }
+}
+</script>
+<style lang="scss" scoped>
+.order-logistcs{
+  width: 100%;
+  box-sizing: border-box;
+
+  padding: 0 16px;
+}
+.info{
+  width: 100%;
+  padding: 8px 16px;
+  box-sizing: border-box;
+  border-bottom: solid 1px #EEE;
+  .logistic-state{
+    font-size: 14px;
+  }
+  .logistic-time{
+    font-size: 12px;
+    padding-top: 8px;
+    color: #999;
+  }
+}
+.info:last-child{
+  border: none;
+}
+</style>

+ 176 - 0
src/views/oms/B2BOrder/components/mergeMedal.vue

@@ -0,0 +1,176 @@
+<template>
+  <vxe-modal v-model="value" id="mergeModel" title="合并订单" width="70%" height="80%" show-zoom resize transfer show-footer v-loading="load">
+    <by-table :propConfig="config" ref="table" id="merge-table">
+      <template v-slot:sourceId="{row}">
+        <span>{{ row.sourceId }}</span>
+        <div class="tag-main" v-if="row.isMain == 1">
+          <el-tag size="mini">主</el-tag>
+        </div>
+      </template>
+      <template v-slot:address="{row}">
+        <div class="addr">{{ row.receiverProvince + '-' + row.receiverCity + '-' + row.receiverDistrict + (row.receiverTown?'-'+row.receiverTown:'') }}</div>
+        <div class="de-addr">{{ row.receiverAddress }}</div>
+      </template>
+      <template v-slot:pay="{row}">
+        <div><el-tag type="success">已付款</el-tag></div>
+        <div>{{ row.payDate}}</div>
+      </template>
+      <template v-slot:product="{row}">
+        <el-badge :value="item.qty" class="item-pro" type="primary" :max="99" v-for="(item,index) of row.items" :key="index">
+          <el-image  style="width: 28px; height: 28px">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline"></i>
+            </div>
+          </el-image>
+        </el-badge>
+      </template>
+      <template v-slot:status="{row}">
+        <span v-if="row.status == 'WaitPay'">待付款</span>
+        <span v-if="row.status == 'Delivering'">发货中</span>
+        <span v-if="row.status == 'Merged'">被合并</span>
+        <span v-if="row.status == 'Question'" style="color:red">异常</span>
+        <span v-if="row.status == 'Split'">被拆分</span>
+        <span v-if="row.status == 'WaitOuterSent'">等供销商|外仓发货</span>
+        <span v-if="row.status == 'WaitConfirm'">已付款待审核</span>
+        <span v-if="row.status == 'WaitFConfirm'">已客审待财审</span>
+        <span v-if="row.status == 'Sent'">已发货</span>
+        <span v-if="row.status == 'Cancelled'">取消</span>
+      </template>
+      <template v-slot:msg="{row}">
+        <div class="buyer-msg">{{ row.buyerMessage }}</div>
+        <div>{{ row.remark }}</div>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { merge } from '@/api/omsOrder'
+@Component({components:{}})
+export default class MergeModel extends Vue {
+  value = false;
+  load = false;
+  config:any={
+    attr:{
+      size:'small',
+      checkbox:true,
+      seq:true,
+      visibleMethod:({row}:any) =>{
+        return row.isMain != 1
+      }
+    },
+    columns:[{
+      title:'订单号',
+      field:'sourceId',
+      fixed:'left',
+      slot:true,
+      width:140
+    },{
+      title:'买家',
+      field:'buyerNickname',
+      width:150
+    },{
+      title:'收货人',
+      field:'receiverName',
+      width:120
+    },{
+      title:'买家地址',
+      field:'address',
+      width:200,
+      slot:true
+    },{
+      title:'付款方式+时间',
+      field:'pay',
+      slot:true,
+      width:150
+    },{
+      title:'商品',
+      field:'product',
+      slot:true,
+      width:150
+    },{
+      title:'状态',
+      field:'status',
+      slot:true,
+      width:120
+    },{
+      title:'运费',
+      field:'freight',
+      width:80
+    },{
+      title:'重量',
+      field:'weight',
+      width:80
+    },{
+      title:'买家留言+卖家备注',
+      field:'msg',
+      width:160
+    }]
+  }
+  setShow(v:boolean){
+    this.value = v
+  }
+  setData(data:Array<any>){
+    this.$nextTick(()=>{
+      let height = (document.getElementById('merge-table') as any).parentNode.offsetHeight;
+      this.config.attr.height=height - 36;
+      if(this.$refs.table){
+        (this.$refs.table as any).setConfig(this.config);
+        (this.$refs.table as any).setValue(data);
+      }
+    })
+  }
+  btn(){
+    let va = (this.$refs.table as any).getValue();
+    let data = (this.$refs.table as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择需要合并的数据!')
+      return
+    }
+    let params:any={};
+    params.idList=[]
+    for(const item of va){
+      if(item.isMain == 1){
+        params.id = item.id;
+        break;
+      }
+    }
+    for(const item of data){
+      params.idList.push(item.id);
+    }
+    this.load = true;
+    merge(params).then((res:any)=>{
+      this.load = false;
+      this.$message({
+        message:'合并成功!',
+        type:'success'
+      })
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tag-main{
+  width: 100%;
+  display: flex;
+  // justify-content: flex-end;
+}
+.buyer-msg,.addr{
+  color: dodgerblue;
+}
+.addr,.de-addr{
+  font-size: 12px;
+}
+</style>

+ 99 - 0
src/views/oms/B2BOrder/components/orderCheckbox.vue

@@ -0,0 +1,99 @@
+<template>
+  <el-collapse-item :name="keyName">
+    <template slot="title">
+      <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" class="check-title">
+        <span class="check-title">{{title}}</span>
+      </el-checkbox>
+    </template>
+    <el-checkbox-group v-if="options.length > 0" v-model="value" @change="handleCheckedItemChange">
+      <template v-for="dataItem in options">
+        <br :key="'s'+dataItem.value"/>
+        <el-checkbox :label="dataItem.value || dataItem.value === 0?dataItem.value:dataItem.label" :key="dataItem.value">{{dataItem.label}}</el-checkbox>
+        <slot v-if="dataItem.slot" :name='dataItem.slotName' :item='dataItem'></slot>
+      </template>
+    </el-checkbox-group>
+  </el-collapse-item>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderCheckbox extends Vue {
+  value:Array<any>=[]
+  activeNames:Array<any>=[1]
+  checkAll= false
+  isIndeterminate= false
+
+  @Prop()
+  title:string|undefined
+
+  @Prop()
+  options!:Array<any>
+
+  @Prop()
+  keyName:any
+
+  @Prop()
+  retType?:string
+
+  clear(){
+    this.value = [];
+    this.checkAll = false;
+    this.isIndeterminate = false;
+  }
+
+  getValue(){
+    if(this.retType == 'string'){
+      let n='';
+      for(const item of this.value){
+        if(!n){
+          n = n + ',' + item
+        }else{
+          n = item
+        }
+      }
+      return n;
+    }else{
+      return this.value;
+    }
+  }
+
+  emitFun(a?:boolean){
+    let v:any = this.getValue();
+    if(a){
+      this.$emit('checkboxChange',[]);
+    }else{
+      this.$emit('checkboxChange',v);
+    }
+    
+  }
+
+  handleCheckAllChange(val:any){
+    this.value = []
+    if(val && this.options){
+      for(const item of this.options){
+        this.value.push(item.value)
+      }
+    }
+    this.isIndeterminate = false;
+    this.emitFun(true);
+  }
+
+  handleCheckedItemChange(value:any,config:any){
+    let checkedCount = value.length;
+    this.checkAll = checkedCount === this.options.length;
+    this.isIndeterminate = checkedCount > 0 && checkedCount < this.options.length;
+    this.emitFun();
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.check-title{
+  font-weight: 700;
+}
+.slot-box{
+  padding-left: 8px;
+}
+</style>

+ 41 - 0
src/views/oms/B2BOrder/components/orderProduct.vue

@@ -0,0 +1,41 @@
+<template>
+  <div class="order-product">
+    <el-input placeholder="商品" v-model="value" size="mini" class="product-with-select" clearable>
+      <el-button slot="append" icon="el-icon-more" @click="showProduct"></el-button>
+    </el-input>
+    <productDialog ref="product" @confirm="confirm" />
+  </div>
+  
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderProduct extends Vue {
+  value=''
+
+  showProduct(){
+    (this.$refs.product as any).setShow(true)
+  }
+  confirm(data:Array<any>){
+    
+  }
+}
+</script>
+<style lang="scss" scoped>
+.order-product{
+  width: 100%;
+}
+</style>
+<style lang="scss">
+.product-with-select{
+  margin-bottom: 4px;
+  .el-input-group__append{
+    background-color: #fff !important;
+    width: 40px !important;
+    .el-icon-more{
+      font-size: 20px;
+    }
+  }  
+}
+</style>

+ 57 - 0
src/views/oms/B2BOrder/components/orderRadio.vue

@@ -0,0 +1,57 @@
+<template>
+  <el-collapse-item :name="keyName" :title="title">
+    <el-radio-group v-model="value" v-if="options.length > 0" @input="input">
+      <el-radio label="" class="order-radio" v-if="noLimit">不限</el-radio>
+      <el-radio v-for="(item,index) in options" :label="item.value || item.value == 0?item.value:item.label" :key="index" class="order-radio">
+        {{item.label}}
+        <template v-if="item.slotName">
+          <slot :name="item.slotName" />
+        </template>
+      </el-radio>
+      <slot />
+    </el-radio-group>
+  </el-collapse-item>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderCheckbox extends Vue {
+  value:any=''
+  activeNames:Array<any>=[1]
+  checkAll= false
+  isIndeterminate= false
+
+  @Prop()
+  noLimit?:boolean
+
+  @Prop()
+  title:string|undefined
+
+  @Prop() 
+  options!:Array<any>
+
+  @Prop()
+  keyName:any
+
+  getValue(){
+    return this.value;
+  }
+
+  clear(){
+    this.value = ''
+  }
+
+  input(){
+    this.$emit('radioChange',this.value);
+  }
+
+
+}
+</script>
+
+<style lang="scss" scoped>
+.order-radio{
+  margin-bottom: 8px;
+}
+</style>

+ 309 - 0
src/views/oms/B2BOrder/components/orderTable.vue

@@ -0,0 +1,309 @@
+<template>
+  <vxe-table
+    size="mini"
+    border
+    stripe
+    ref="table"
+    :height="height"
+    :row-config="{isCurrent: true,isHover: true}"
+    :data="data">
+    <vxe-column type="checkbox" width="50" fixed="left"></vxe-column>
+    <!-- <vxe-column type="seq" width="60" title="序号" fixed="left"></vxe-column> -->
+    <vxe-column field="id" title="内部订单号" width="100" fixed="left">
+      <template #default="{ row }">
+        <div class="col-cont">
+          <span>{{ row.id }}</span>
+          <div class="update">
+            <div class="tag-update" @click="detail(row)">详</div>
+          </div>
+        </div>
+      </template>
+    </vxe-column>
+    <vxe-column field="rawSourceId" title="线上订单号" width="140"> </vxe-column>
+    <vxe-column field="isSubmitted" title="提交状态" width="100">
+      <template #default="{ row }">
+        <el-tag v-if="row.isSubmitted == 1" size="small">已提交</el-tag>
+        <el-tag v-else type="warning" size="small"> 未提交 </el-tag>
+      </template>
+    </vxe-column>
+    <vxe-column field="product" title="商品" width="140">
+      <template #default="{ row }">
+        <el-badge :value="item.qty" class="item-pro" type="primary" :max="99" v-for="(item,index) of row.items" :key="index">
+          <el-image  style="width: 28px; height: 28px">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline"></i>
+            </div>
+          </el-image>
+        </el-badge>
+      </template>
+    </vxe-column>
+    <!-- <vxe-column field="businessType" title="业务类型" width="80"></vxe-column> -->
+    <vxe-column field="orderType" title="订单类型" width="100">
+      <template #default="{ row }">
+        <span v-if="row.orderType == 'Common'">普通订单</span>
+        <span v-if="row.orderType == 'Reissue'">补发订单</span>
+        <span v-if="row.orderType == 'DistributionPlus'">分销Plus</span>
+        <span v-if="row.orderType == 'SupplyPlus'">供销Plus</span>
+        <span v-if="row.orderType == 'Exchange'">换货订单</span>
+      </template>
+    </vxe-column>
+    <vxe-column field="status" title="订单状态" width="120">
+      <template #default="{ row }">
+        <span v-if="row.status == 'WaitPay'">待付款</span>
+        <span v-if="row.status == 'Delivering'">发货中</span>
+        <span v-if="row.status == 'Merged'">被合并</span>
+        <span v-if="row.status == 'Question'" style="color:red">异常</span>
+        <span v-if="row.status == 'Split'">被拆分</span>
+        <span v-if="row.status == 'WaitOuterSent'">等供销商|外仓发货</span>
+        <span v-if="row.status == 'WaitConfirm'">已付款待审核</span>
+        <span v-if="row.status == 'WaitFConfirm'">已客审待财审</span>
+        <span v-if="row.status == 'Sent'">已发货</span>
+        <span v-if="row.status == 'Cancelled'">取消</span>
+      </template>
+    </vxe-column>
+    <vxe-column field="upSourceName" title="订单来源" width="110"></vxe-column>
+    <vxe-column field="operationFlag" title="操作标记" width="120">
+      <template #default="{ row }">
+        {{ getFromText(row.operationFlag) }}
+      </template>
+    </vxe-column>
+    <vxe-column field="shopName" title="店铺名称" width="140"></vxe-column>
+    <vxe-column field="orderDate" title="订单日期" width="140">
+      <!-- <template #default="{ row }">
+        {{ formatDate(row.orderDate) }}
+      </template> -->
+    </vxe-column>
+    <!-- <vxe-column field="shipment" title="跨境买家指定物流" width="120"></vxe-column> -->
+    <vxe-column field="chosenChannel" title="实发快递渠道" width="120"></vxe-column>
+    <vxe-column field="logisticsId" title="快递单号" width="120"></vxe-column>
+    <vxe-column field="logisticsCompany" title="快递公司" width="120"></vxe-column>
+    <vxe-column field="logisticsCompanyCode" title="物流公司编码" width="120"></vxe-column>
+    <!-- <vxe-column field="internationalLogisticsId" title="国际物流单号" width="120"></vxe-column> -->
+    <!-- <vxe-column field="skus" title="skus" width="120"></vxe-column> -->
+    <vxe-column field="weight" title="重量" width="70"></vxe-column>
+    <vxe-column field="isCod" title="是否货到付款" width="120">
+      <template #default="{ row }">
+        {{ row.isCod == 1 ? '是' :' 否' }}
+      </template>
+    </vxe-column>
+    <vxe-column field="sendDate" title="发货日期" width="120"></vxe-column>
+    <!-- <vxe-column field="signTime" title="预计送达时间" width="120"></vxe-column>
+    <vxe-column field="endTime" title="确认收货时间" width="120"></vxe-column> -->
+    <vxe-column field="receiverAddress" title="收货地址" show-overflow width="160"></vxe-column>
+    <vxe-column field="receiverName" title="收件人" show-overflow width="120"></vxe-column>
+    <vxe-column field="receiverMobile" title="手机" show-overflow width="120"></vxe-column>
+    <vxe-column field="buyerMessage" title="买家留言" show-overflow width="120"></vxe-column>
+    <!-- <vxe-column field="wmsCoId" title="发货仓编号" width="120"></vxe-column> -->
+    <vxe-column field="payDate" title="支付时间" width="140"></vxe-column>
+    <vxe-column field="freeAmount" title="抵扣金额" align="right" width="120"></vxe-column>
+    <vxe-column field="payAmount" title="应付+运费" align="right" width="120">
+      <template #default="{ row }">
+        <span>{{ row.payAmount }}</span> <br/>
+        <span style="color: #b9b8b8;">{{ row.freight?row.freight:0 }}</span>
+      </template>
+    </vxe-column>
+    <vxe-column field="paidAmount" title="实付金额" align="right" width="120"></vxe-column>
+    <vxe-column field="buyerNickname" title="买家昵称" show-overflow width="140"></vxe-column>
+    <!-- <vxe-column field="openId" title="平台买家唯一值" show-overflow width="140"></vxe-column> -->
+    <vxe-column field="buyerPaidAmount" title="总买家实付" width="120"></vxe-column>
+    <vxe-column field="sellerIncomeAmount" title="总卖家实收" width="120"></vxe-column>
+    <vxe-column field="questionType" title="问题类型" width="120"></vxe-column>
+    <vxe-column field="questionDesc" title="问题描述" width="120"></vxe-column>
+    <!-- <vxe-column field="invoiceType" title="发票类型" width="120"></vxe-column> -->
+    <vxe-column field="invoiceTitle" title="发票抬头+税号" width="120">
+      <template #default="{ row }">
+        <span>{{ row.invoiceTitle }}</span> <br/>
+        <span style="color: #b9b8b8;">{{ row.buyerTaxNo }}</span><br/>
+        <span>{{ row.invoiceType }}</span>
+      </template>
+    </vxe-column>
+    <!-- <vxe-column field="buyerTaxNo" title="发票税号" width="120"></vxe-column> -->
+    <!-- <vxe-column field="drpCoIdFrom" title="分销商编号" width="120"></vxe-column>
+    <vxe-column field="drpCoIdTo" title="供销商编号" width="120"></vxe-column> -->
+    <vxe-column field="remark" title="订单备注" width="120"></vxe-column>
+    <vxe-column field="note" title="线下备注" width="120"></vxe-column>
+    <vxe-column field="labels" title="标签" width="120"></vxe-column>
+    <vxe-column title="操作" width="120" fixed="right" align="center">
+      <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="row.status == 'Delivering'  || row.status == 'Sent'" @click="sendGoodsDetail(row)">发货明细</el-button>
+      </template>
+    </vxe-column>
+  </vxe-table>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import Format from '@/benyun/utils/dateFormat'
+@Component
+export default class OrderTable extends Vue {
+  @Prop()
+  data!:Array<any>
+  height=null
+
+  operationFlag:any={
+    'OMS':'手工下单',
+    'COPY':'复制',
+    'MERGE':'合并',
+    'SPLIT':'拆分;拆分还原',
+    'MOBILE':'导入',
+    'DRP-S':'供销推送',
+    'DRP-D':'分销推送',
+    'KWAISHOP':'快手;微商城',
+    'PINDUODUO':'拼多多',
+    'TOUTIAOFXG':'头条放心购',
+    'JUSHUITAN':'聚水潭'
+  }
+  //订单来源转换文字信息
+  getFromText(f:any){
+    let t='';
+    if(f){
+      let arr:Array<any>=f.split(',');
+      for(const item of arr){
+        if(this.operationFlag[item]){
+          if(t){
+            t = t + ' , ' + this.operationFlag[item]
+          }else{
+            t = this.operationFlag[item]
+          }
+        }
+      }
+    }
+    return t;
+  }
+  //是否显示发货
+  showSend(item:any){
+    let noStatus = ['WaitPay','Delivering','Merged','Split','Question','Sent','Cancelled'];
+    if(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && noStatus.indexOf(item.status) == -1){
+      return true
+    }
+    return false
+  }
+  //合并按钮是否显示
+  showMerge(item:any){
+    let r = false;
+    if(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && (!item.operationFlag || item.operationFlag.indexOf('MERGE') == -1 && item.operationFlag.indexOf('SPLIT') == -1 
+    && item.operationFlag.indexOf('JUSHUITAN') == -1)){
+      if(item.status == 'WaitConfirm' || item.status == 'Question'){
+        r = true;
+      }
+    }
+    return r;
+  }
+  showSplit(item:any){
+    let r = false;
+    if(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && (!item.operationFlag || item.operationFlag.indexOf('MERGE') == -1 && item.operationFlag.indexOf('SPLIT') == -1 
+    && item.operationFlag.indexOf('JUSHUITAN') == -1)){
+      let s=['WaitConfirm','Question','Split']
+      if(s.indexOf(item.status) >= 0){
+        r = true;
+      }
+    }
+    return r;
+  }
+
+  formatDate(v:string){
+    return Format(v,'yyyy-MM-dd');
+  }
+
+  mounted(){
+    this.$nextTick(() => {
+      this.height = (this as any).$el.offsetHeight;
+    })
+  }
+  detail(row:any){
+    this.$emit('detail',row)
+  }
+  getSelectData(){
+    let data = (this as any).$lodash.cloneDeep((this.$refs.table as any).getCheckboxRecords());
+    return data;
+  }
+  sendGoods(row:any){
+    this.$emit('sendGoods',row)
+  }
+  sendGoodsDetail(row:any){
+    this.$emit('sendGoodsDetail',row)
+  }
+  mergeHandle(row:any){
+    let v = (this as any).$lodash.cloneDeep(row);
+    v.isMain = 1;
+    let data:Array<any> = [];
+    data.push(v);
+    for(const item of this.data){
+      if(row.id != item.id && item.isSubmitted == 1 && row.shopId == item.shopId && row.shopName == item.shopName && row.buyerId == item.buyerId && 
+      row.receiverMobile == item.receiverMobile && row.receiverProvince == item.receiverProvince && row.receiverCity == item.receiverCity 
+      && row.receiverDistrict == item.receiverDistrict && row.receiverTown == item.receiverTown && row.receiverAddress == item.receiverAddress 
+      && item.pays && item.pays.length > 0 && item.operationFlag.indexOf('SPLIT') == -1 && item.operationFlag.indexOf('MERGE') == -1 && (item.status == 'WaitConfirm'
+      || item.status == 'Question')){
+        data.push(item);
+      }
+    }
+    this.$emit('mergeHandle',data);
+  }
+  splitHandle(row:any){
+    this.$emit('splitHandle',row);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.detail{
+  color: #0089ff;
+  cursor: pointer;
+}
+.col-cont{
+  // display: flex;
+  // justify-content: space-between;
+  // align-items: center;
+  // flex-direction: column;
+  .update{
+    display: flex;
+    justify-content: flex-end;
+    width: 100%;
+    visibility: hidden;
+  }
+  .tag-update{
+    height: 24px;
+    width: 24px;
+    font-size: 12px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border-radius: 50%;
+    background-color:#2d99f7;
+    color: #FFF;
+    flex-shrink: 0;
+    margin-left: 4px;
+    cursor: pointer;
+  }
+  .tag-update:hover{
+    opacity: 0.7;
+  }
+}
+</style>
+
+<style lang="scss">
+.row--hover{
+  .update{
+    visibility:visible !important;
+  }
+}
+.row--current{
+  .update{
+    visibility:visible !important;
+  }
+}
+.image-slot{
+  .el-icon-picture-outline{
+    font-size: 28px;
+    color: #999;
+  }
+}
+.item-pro{
+  .el-badge__content{
+    z-index: 1;
+  }
+}
+</style>

+ 88 - 0
src/views/oms/B2BOrder/components/orderTool.vue

@@ -0,0 +1,88 @@
+<template>
+  <div class="order-tool">
+    <!-- <el-dropdown split-button type="text" @click="handle('addOrder')" @command="handleCommand">
+      新增订单
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item command="loadOrder">手工下载</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown> -->
+    <el-button type="text" @click="handle('addOrder')">新增订单</el-button>
+    <div class="split"></div>
+    <el-dropdown split-button type="text" @click="handle('smt')" @command="handleCommand">
+        提交
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item command="reSmt">反提交</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown>
+    <!-- <el-button type="text">设快递</el-button>
+    <el-dropdown split-button type="text" class="dropdown">
+      设快递单号
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item>批量设置快递单号</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown> -->
+    <div class="split"></div>
+    <el-button type="text" @click="handle('changeQues')">转异常</el-button>
+    <el-button type="text" @click="handle('changeNormal')">转正常</el-button>
+    <el-button type="text" @click="handle('cancelOrder')">取消订单<i class="el-icon-info" title="只有[待付款,发货中,异常,已付款待审核,等供销商|外仓发货,已客审待财审]才可以取消订单"></i></el-button>
+    <!-- <el-dropdown split-button type="text" class="dropdown" @click="handle('cancelOrder')" @command="handleCommand">
+      取消订单
+      <i class="el-icon-info" title="只有[待付款,发货中,异常,已付款待审核,等供销商|外仓发货,已客审待财审]才可以取消订单"></i>
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item command="reCancelOrder">反取消订单</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown> -->
+    <div class="split"></div>
+    <el-dropdown split-button type="text" class="dropdown" @click="handle('addGift')" @command="handleCommand">
+      添加赠品
+      <el-dropdown-menu slot="dropdown">
+        <!-- <el-dropdown-item command="addProduct">添加商品</el-dropdown-item> -->
+        <!-- <el-dropdown-item command="addGift">添加赠品</el-dropdown-item> -->
+        <el-dropdown-item command="updateFreight">改运费</el-dropdown-item>
+        <el-dropdown-item command="updateTag">改标签</el-dropdown-item>
+        <el-dropdown-item command="updateRmk">改备注</el-dropdown-item>
+        <el-dropdown-item command="updateSalesman">设定业务员</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown>
+    <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>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderTool extends Vue {
+
+  handleCommand(n:string){
+    this.$emit(n)
+  }
+
+  handle(n:string){
+    this.$emit(n)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.order-tool{
+  height: 40px;
+  display: flex;
+  align-items: center;
+  width: 100%;
+  .order-tool-btn{
+    color: #333;
+  }
+  .split{
+    height: 10px;
+    width: 1px;
+    background-color: #CCC;
+    margin: 0 8px;
+  }
+  .dropdown{
+    padding-left: 8px;
+  }
+}
+</style>

+ 321 - 0
src/views/oms/B2BOrder/components/purchaseModel.vue

@@ -0,0 +1,321 @@
+<template>
+  <vxe-modal v-model="value" id="purchaseModel" @show="show" width="70%" height="80%" min-width="460" min-height="320" 
+    show-zoom resize transfer show-footer @hide="hide" v-loading="load">
+    <template #title>
+      <span>生成采购单</span>
+    </template>
+    <el-collapse v-model="activeNames">
+      <el-collapse-item title="基本信息" name="1" class="add-order-item">
+        <by-form :propConfig="baseConfig" ref="baseform">
+          <template v-slot:organizationName='{ value }'>
+            <el-input placeholder="请选择供应商" v-model="value.organizationName" @clear="organizationClear" class="input-organizationName" size="small" clearable>
+              <el-button slot="append" icon="el-icon-more" @click="handleSupplier"></el-button>
+            </el-input>
+          </template>
+        </by-form>
+      </el-collapse-item>
+
+      <el-collapse-item title="商品信息" name="2" class="add-order-item">
+        <by-table :propConfig="tableConfig" ref="table" @onChangeRow="onChangeRow"></by-table>
+      </el-collapse-item>
+    </el-collapse>
+    <supplier-modal ref="supplierModal" @confirm="confirm" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { toPurchaseOrder } from '@/api/omsOrder'
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+// import SupplierModal from "@/components/supplierModal/supplierModal.vue";
+@Component({components:{}})
+export default class PurchaseModel extends Vue {
+  value=false;
+  load = false;
+  activeNames:Array<any>=['1','2']
+  baseConfig:any={
+    attr:{
+      size:'small',
+      rules:{
+        organizationName:[{
+          required: true, message: '供应商不能为空!', trigger: ['blur','change']
+        }],
+        deliveryAddress:[{
+          required: true, message: '交货地点不能为空!', trigger: 'blur'
+        }],
+        deliveryData:[{
+          required: true, message: '交货时间不能为空!', trigger: 'blur'
+        }],
+        delivery:[{
+          required: true, message: '交货人不能为空!', trigger: 'blur'
+        }],
+        deliveryPhone:[{
+          required: true, message: '交货人不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }]
+      }
+    },
+    columns:[
+      [{
+        span:6,
+        label:'供应商',
+        prop:'organizationName',
+        slot:true
+      },{
+        span:6,
+        label:'交货地点',
+        prop:'deliveryAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货地点',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'交货时间',
+        prop:'deliveryData',
+        component:'by-date-picker',
+        compConfig:{
+          attr:{
+            placeholder:'交货时间',
+            type:'datetime',
+            defaultNow:true,
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'交货人',
+        prop:'delivery',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货人',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'交货人手机',
+        prop:'deliveryPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货人手机',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'交货方式',
+        prop:'deliveryWay',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货方式',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'物流分类',
+        prop:'logisticClass',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入物流分类',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+
+  tableConfig:any={
+    attr:{
+      size:'small',
+      align:'center',
+      seq:true
+    },
+    columns:[{
+      title:'商品',
+      field:'name',
+      // width:180,
+      // slot:true
+    },{
+      title:'数量',
+      field:'qty',
+      width:100,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          type:'integer',
+          min:0
+          // isPositiveNumber:true
+        }
+      }
+    },{
+      title:'价格',
+      field:'price',
+      width:100,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          type:'number'
+        }
+      }
+    },{
+      title:'可采购数量',
+      field:'residueQty',
+      width:100,
+    },{
+      action:true,
+      width:100,
+      title:'操作',
+      plugins:[{
+        name:'删除',
+        event:{
+          click:(row:any)=>{
+            this.del(row)
+          }
+        }
+      }]
+    }]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));  
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  del(row:any){
+    let data = (this.$refs.table as any).getValue();
+    let _index=-1
+    for(const item of data){
+      _index ++;
+      if(item.itemId == row.itemId && item.name == row.name){
+        break
+      }
+    }
+    if(_index >= 0){
+      data.splice(_index,1);
+    }
+    (this.$refs.table as any).setValue(data);
+  }
+  show(){
+    if(this.$refs.baseform){
+      (this.$refs.baseform as any).clearValue();
+    }
+  }
+  hide(){}
+
+  onChangeRow(row:any){
+    console.log(row,Number(row.qty),Number(row.residueQty))
+    if(Number(row.qty) > Number(row.residueQty)){
+      this.$message('数量不能大于可采购数量!');
+      row.qty = '0';
+      this.$forceUpdate()
+    }
+  }
+
+  setShow(v:boolean){
+    this.value = v;
+  }
+
+  setTableData(data:Array<any>){
+    let newData:Array<any>=[]
+    if(data.length > 0){
+      for(const item of data){
+        newData.push({
+          orderId:item.orderId,
+          itemId:item.id,
+          name:item.name,
+          residueQty:item.residueQty,
+          qty:item.residueQty,
+          price:item.price
+        })
+      }
+    }
+    this.$nextTick(()=>{
+      (this.$refs.table as any).setValue(newData);
+    })
+  }
+
+  handleSupplier(){
+    (this.$refs.supplierModal as any).setShow(true);
+  }
+
+  confirm(data:Array<any>){
+    if(data.length == 0){
+      this.$message('请选择供应商!')
+      return
+    }
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.organizationName = data[0].name;
+    value.organizationId = data[0].id;
+    (this.$refs.baseform as any).setValue(value);
+  }
+  organizationClear(){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.organizationName = '';
+    value.organizationId = '';
+    (this.$refs.baseform as any).setValue(value);
+  }
+  btn(){
+    (this.$refs.baseform as any).validate().then(()=>{
+      let value:any = (this.$refs.baseform as any).getValue();
+      let data:Array<any>=(this.$refs.table as any).getValue();
+      if(data.length > 0){
+        value.items = data;
+        this.load = true;
+        toPurchaseOrder(value).then((res:any)=>{
+          this.load = false;
+          this.value = false;
+          this.$message({
+            message:'采购单已生成!',
+            type:'success'
+          })
+          this.$emit('handleSuccess');
+        }).catch((err:any) => {
+          this.load = false;
+        })
+      }else{
+        this.$message({
+          message:'采购的商品不能为空!',
+          type:'warning'
+        })
+      }
+      
+    }).catch(() => {})
+    
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
+
+<style lang="scss">
+.input-organizationName{
+  .el-input-group__append{
+    background-color: #fff !important;
+  }  
+}
+</style>

+ 202 - 0
src/views/oms/B2BOrder/components/questModel.vue

@@ -0,0 +1,202 @@
+<template>
+  <vxe-modal v-model="value" id="questModel" width="70%" v-loading="load" @show="show" @hide="hide" height="80%" show-zoom resize transfer show-footer>
+    <template #title>
+      <span>异常类型</span>
+    </template>
+    <by-table :propConfig="tableConfig" ref="table" id="quest-table">
+      <template v-slot:ordered="{row}">
+        <span v-if="row.isSystem == 1">{{ row.ordered }}</span>
+        <vxe-input v-else v-model="row.ordered" size="small" type="number"></vxe-input>
+      </template>
+      <template v-slot:priority="{row}">
+        <span v-if="row.isSystem == 1">{{ row.priority }}</span>
+        <vxe-input v-else v-model="row.priority" size="small" type="number"></vxe-input>
+      </template>
+      <template v-slot:isShow="{row}">
+        <el-switch
+          v-model="row.isShow"
+          :active-value="1"
+          :inactive-value="0"
+          @change="changeShow($event,row)"
+          :disabled="row.isSystem == 1">
+        </el-switch>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="add">新增</el-button>
+      </div>
+    </template>
+    <add-quest-model ref="addQuestModel" @handleSuccess="handleSuccess" />
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { queryAll,updateOrdered,updatePriority,updateShow,del } from '@/api/question'
+import AddQuestModel from "./addQuest.vue";
+@Component({components:{AddQuestModel}})
+export default class QuestModel extends Vue {
+  value=false;
+  load=false;
+  tableConfig:any={
+    attr:{
+      size:'mini',
+      align:'center',
+      seq:true
+    },
+    columns:[{
+      title:'类型',
+      field:'type',
+      width:240
+    },{
+      title:'排序',
+      field:'ordered',
+      slot:true
+    },{
+      title:'优先级',
+      field:'priority',
+      slot:true
+    },{
+      title:'显示',
+      field:'isShow',
+      slot:true
+    },{
+      title:'操作',
+      action:true,
+      width:200,
+      plugins:[{
+        name:'排序',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.sortHandle(row);
+          }
+        }
+      },{
+        name:'优先级',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.priorityHandle(row)
+          }
+        }
+      },{
+        name:'删除',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.delHandle(row);
+          }
+        }
+      }]
+    }]
+  }
+  questData:Array<any>=[]
+  
+  mounted(){
+    
+  }
+  sortHandle(row:any){
+    this.load = true;
+    updateOrdered({
+      id:row.id,
+      ordered:row.ordered
+    }).then(()=>{
+      this.$message({message:'“'+row.type+'”'+'排序修改成功!',type:'success'})
+      this.load = false;
+      this.getQuestionList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  priorityHandle(row:any){
+    this.load = true;
+    updatePriority({
+      id:row.id,
+      priority:row.priority
+    }).then(()=>{
+      this.$message({message:'“'+row.type+'”'+'优先级修改成功!',type:'success'})
+      this.load = false;
+      this.getQuestionList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  changeShow(v:number,row:any){
+    this.load = true;
+    updateShow({
+      id:row.id,
+      isShow:v
+    }).then(()=>{
+      this.$message({message:'“'+row.type+'”'+'显示修改成功!',type:'success'})
+      this.load = false;
+      this.getQuestionList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  delHandle(row:any){
+    this.$confirm('此操作将删除“'+row.type+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+        del({
+          id:row.id,
+        }).then(()=>{
+          this.$message({message:'删除成功!',type:'success'})
+          this.load = false;
+          this.getQuestionList();
+        }).catch(()=>{
+          this.load = false;
+        })
+    }).catch(()=>{})
+  }
+  show(){
+    let height = (document.getElementById('quest-table') as any).parentNode.offsetHeight;
+    this.tableConfig.attr.height=height - 36;
+    (this.$refs.table as any).setConfig(this.tableConfig);
+    this.getQuestionList()
+  }
+  handleSuccess(){
+    this.getQuestionList()
+  }
+  //获取异常数据
+  getQuestionList(){
+    this.load = true;
+    queryAll().then((res:any) => {
+      this.questData = res.data;
+      if(this.$refs.table){
+        (this.$refs.table as any).setValue(this.questData);
+      }
+      this.load = false;
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+
+  setShow(v:boolean){
+    this.value = v;
+  }
+
+  add(){
+    (this.$refs.addQuestModel as any).setShow(true)
+  }
+  hide(){
+    this.$emit('questHide')
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 149 - 0
src/views/oms/B2BOrder/components/sendModeModal.vue

@@ -0,0 +1,149 @@
+<template>
+  <vxe-modal v-model="value" id="sendModeModal" :zIndex="9999" width="65%" height="60%" v-loading="load">
+    <template #title>
+      <span>订单发货模式选择</span>
+    </template>
+    <div class="mode">
+      <div class="moda-item" :class="{'onModal': mode==='0'}" @click="modeHandle('0')">
+        <div class="img-tag">
+          <img src="../../../../assets/images/img2.png" />
+        </div>
+        <div class="moda-title">
+          批量逐一发货
+          <div class="check">
+            <i class="el-icon-check"></i>
+          </div>
+        </div>
+        <div class="msg">处理后形成多张物流单</div>
+      </div>
+      <div class="moda-item" :class="{'onModal': mode==='1'}" @click="modeHandle('1')">
+        <div class="img-tag">
+          <img src="../../../../assets/images/img3.png" />
+        </div>
+        <div class="moda-title">
+          整车发货
+          <div class="check">
+            <i class="el-icon-check"></i>
+          </div>
+        </div>
+        <div class="msg">同一客户同一目的地订单形成一张物流单<br />优惠多多</div>
+      </div>
+      <!-- <div class="moda-item" :class="{'onModal': mode==='2'}" @click="modeHandle('2')">
+        <div class="img-tag">
+          <img src="../../../../assets/images/img1.png" />
+        </div>
+        <div class="moda-title">
+          快递发货
+          <div class="check">
+            <i class="el-icon-check"></i>
+          </div>
+        </div>
+        <div class="msg">处理后形成新物流单</div>
+      </div> -->
+    </div>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component({components:{}})
+export default class SendModeModal extends Vue {
+  load=false;
+  value=false;
+  mode='';
+  setShow(v:boolean){
+    this.mode = '';
+    this.value = v;
+  }
+  modeHandle(v:string){
+    this.mode = v;
+    this.value = false;
+    this.$emit('modeChange',v)
+  }
+  show(){
+    
+  }
+  hide(){}
+}
+</script>
+
+<style lang="scss" scoped>
+.mode{
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  .moda-item{
+    width: 244px;
+    height: 300px;
+    box-sizing: border-box;
+    // border:solid 1px #F54319;
+    display: flex;
+    flex-direction: column;
+    // justify-content: space-between;
+    // align-items: center;
+    margin: 0 32px;
+    padding: 16px;
+    border-radius: 5px;
+    background-color: #F4F7FA;
+    border:solid 1px #F4F7FA;
+    cursor: pointer;
+    .img-tag{
+      width: 100%;
+      >img{
+        width: 100%;
+        display: block;
+      }
+    }
+    .check{
+      // width: 100%;
+      // padding: 30px 16px 0;
+      display: flex;
+      justify-content: flex-end;
+      align-items: center;
+      font-size: 16px;
+      position: absolute;
+      padding: 0;
+      top: 30px;
+      right: 0;
+      border: solid 1px #333;
+      border-radius: 50%;
+      .el-icon-check{
+        font-size: 20px;
+        visibility: hidden;
+      }
+      span{
+        padding-left: 16px;
+      }
+    }
+    .msg{
+      font-size: 12px;
+      color: #999;
+      // text-align: center;
+    }
+    .moda-title{
+      font-size: 16px;
+      padding: 32px 0 8px;
+      width: 100%;
+      position: relative;
+      color: #000;
+    }
+  }
+  .moda-item:hover,.onModal{
+    background-color: #FFF;
+    border:solid 1px #0581FE;
+    .check{
+      border:solid 1px #0581FE;
+      background-color: #0581FE;
+      .el-icon-check{
+        visibility: visible;
+        color: #FFF;
+      }
+      span{
+        color: #F54319;
+      }
+    }
+  }
+}
+</style>

+ 95 - 0
src/views/oms/B2BOrder/components/setQuesModal.vue

@@ -0,0 +1,95 @@
+<template>
+  <vxe-modal v-model="value" id="setQuest" width="400" v-loading="load" @hide="hide" height="300" show-footer title="转异常单">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { setQuestions } from '@/api/omsOrder'
+@Component({components:{}})
+export default class SetQuesModal extends Vue {
+  value = false;
+  load = false;
+  billValue:Array<any>=[]
+  config:any={
+    attr:{
+      rules:{
+        questionType: [
+          { required: true, message: '请选择类型', trigger: 'change' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'类型',
+        prop:'questionType',
+        labelWidth:'80px',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            data:[],
+            label:'type',
+            value:'id'
+          }
+        }
+      }],
+      [{
+        label:'描述',
+        prop:'questionDesc',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            type:'textarea',
+            rows:3
+          }
+        }
+      }]
+    ]
+  }
+  show(){
+    
+  }
+  setQuestTypeData(data:Array<any>){
+    let c = this.config.columns[0][0].compConfig;
+    c.attr.data = data;
+    if(this.$refs.form){
+      (this.$refs.form as any).setCompConfig('questionType',c)
+    }
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      this.load = true
+      setQuestions(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>

+ 144 - 0
src/views/oms/B2BOrder/components/shopModal.vue

@@ -0,0 +1,144 @@
+<template>
+  <vxe-modal v-model="value" id="shopModel" title="选择店铺" width="70%" height="80%" show-zoom resize transfer show-footer v-loading="load">
+    <module-view :propConfig="config" ref="view" v-loading="load" @pagination="pagination" @onRefresh="getList" 
+    @resert="queryList" @search="queryList" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { query } from '@/api/shop'
+@Component({components:{}})
+export default class ShopModal extends Vue {
+  value=false;
+  load=false;
+  timeNum = 0;
+  isSearch=false;
+  config:any={
+    attr:{
+      calculateH:true
+    },
+    search:{
+      attr:{
+        size:'small'
+      },
+      columns:[
+        [{
+          label:'店铺名称',
+          prop:'shopName',
+          component:'by-input',
+          compConfig:{}
+        },{
+          label:'店铺简称',
+          prop:'shortName',
+          component:'by-input',
+          compConfig:{}
+        },{
+          label:'所属平台',
+          prop:'channelName',
+          component:'by-input',
+          compConfig:{}
+        }]
+      ]
+    },
+    tool:{
+      tools:{
+        search:true,
+        refresh:true
+      }
+    },
+    table:{
+      attr:{
+        triggerRowCheck:'row',
+        size:'mini',
+        seq:true,
+        radio:true,
+        align:'center',
+      },
+      columns:[{
+        title:'店铺名称',
+        field:'shopName'
+      },{
+        title:'店铺简称',
+        field:'shortName',
+
+      },{
+        title:'所属平台',
+        field:'channelName',
+      }]
+    }
+  }
+  mounted(){
+    
+  }
+  //分页
+  pagination(){
+    if(this.isSearch){
+      this.queryList();
+    }else{
+      this.getList()
+    }
+  }
+  //列表请求(只有分页,不包含搜素条件)
+  getList(){
+    if(!this.$refs.view){
+      if(this.timeNum > 5){
+        return
+      }
+      setTimeout(()=>{
+        this.getList()
+      },500) 
+      this.timeNum ++;
+      return
+    }
+    this.isSearch = false;
+    let data = (this.$refs.view as any).getPage();
+    this.requestList(data);
+  }
+  //列表请求(包含分页和搜素条件)
+  queryList(){
+    this.isSearch = true;
+    let data = (this.$refs.view as any).getQuery();
+    this.requestList(data);
+  }
+  requestList(data:any){
+    this.load = true;
+    query(data).then((res:any) => {
+      this.load = false;
+      (this.$refs.view as any).setTableValue(res.data.records);
+      let page = {
+        pageNo: res.data.current, //当前页
+        pageSize: res.data.size, //每页条数
+        total: res.data.total //总条数
+      };
+      (this.$refs.view as any).setPage(page)
+
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  setShow(v:boolean){
+    this.value = v;
+    this.getList();
+  }
+  btn(){
+    let data = (this.$refs.view as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择店铺!');
+      return
+    }
+    this.$emit('shopSelect',data[0]);
+    this.value = false;
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 169 - 0
src/views/oms/B2BOrder/components/splitModal.vue

@@ -0,0 +1,169 @@
+<template>
+  <vxe-modal v-model="value" id="splitModel" title="拆分订单" width="70%" height="80%" min-width="460" min-height="320" show-zoom resize transfer :show-footer="!hideBtn" v-loading="load">
+    <by-table :propConfig="config" ref="table" id="split-table"> 
+      <template v-slot:num="{row}">
+        <vxe-input v-model="row.num" v-if="row.splitNum > 0" placeholder="请输入" type="integer" @input="onChangeRow(row)"></vxe-input>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { splitQtyQuery,split } from '@/api/omsOrder'
+@Component({components:{}})
+export default class SplitModel extends Vue {
+  value=false;
+  load=false;
+  billData:any=null;
+  hideBtn=false;
+  data:Array<any>=[]
+  config:any={
+    attr:{
+      size:'small',
+      seq:true
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      width:300
+    },{
+      title:'价格',
+      field:'price',
+      width:130
+    },{
+      title:'商品数量',
+      field:'qty',
+      width:130
+    },{
+      title:'可拆分数量',
+      field:'splitNum',
+      width:130
+    },{
+      title:'拆分数量',
+      field:'num',
+      slot:true,
+      // component:'by-input',
+      // compConfig:{
+      //   attr:{
+      //     size:'mini',
+      //     type:'integer'
+      //   }
+      // }
+    }]
+  }
+
+  setShow(v:boolean){
+    this.hideBtn = false;
+    this.value = v;
+  }
+  setData(data:any){
+    if(data){
+      this.billData = data;
+      this.data = [];
+      if(data.items) {
+        for(const item of data.items){
+          item.splitNum = item.qty - item.splitQty
+          this.data.push(item)
+        }
+      }
+      // this.getSplitNum(data);
+    }else{
+      this.billData = null;
+      this.data = [];
+    }
+    this.$nextTick(()=>{
+      let height = (document.getElementById('split-table') as any).parentNode.offsetHeight;
+      this.config.attr.height=height - 36;
+      if(this.$refs.table){
+        (this.$refs.table as any).setConfig(this.config);
+        (this.$refs.table as any).setValue(this.data);
+      }
+    })
+  }
+//获取可拆分数量
+  getSplitNum(v:any){
+    if(!v) return;
+    let data = v.items?v.items:[];
+    if(data.length == 0) return;
+    this.load = true;
+    splitQtyQuery({id:v.id}).then((res:any) => {
+      this.load = false;
+      if(res.data){
+        let j = 0;
+        for(const item of data){
+          let n = Number(res.data[item.id]);
+          if(n){
+            item.splitNum = item.qty - n;
+          }else{
+            item.splitNum = item.qty;
+          }
+          this.data.push(item)
+          if(item.splitNum == 0){
+            j++
+          }
+        }
+        if(j == this.data.length){
+          this.hideBtn = true
+        }
+        (this.$refs.table as any).setValue(this.data);
+      }
+    }).catch((err:any) => {
+      this.load = false
+    })
+  }
+
+  btn(){
+    let data = (this.$refs.table as any).getValue();
+    let info:Array<any>=[];
+    if(data.length == 0){
+      this.$message('未有数据不能执行此操作!')
+      return
+    }
+    for(const item of data){
+      if(Number(item.num) > 0){
+        info.push({
+          qty:Number(item.num),
+          orderItemId:item.id
+        })
+      }
+    }
+    if(info.length == 0){
+      this.$message('请设置拆分数量!')
+      return
+    }
+    this.load = true;
+    split({
+      id:this.billData.id,
+      splitInfos:info
+    }).then((res:any) => {
+      this.load = false;
+      this.$message({
+        message:'拆分成功!',
+        type:'success'
+      })
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch(() => {
+      this.load = false
+    })
+  }
+
+  onChangeRow(row:any){
+    if(Number(row.splitNum) < Number(row.num)){
+      this.$message('拆分数量不能大于可拆分数量!');
+      row.num = 0;
+      this.$forceUpdate()
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 112 - 0
src/views/oms/B2BOrder/components/tabModal.vue

@@ -0,0 +1,112 @@
+<template>
+  <vxe-modal v-model="value" id="tagModal" width="60%" v-loading="load" @hide="hide" height="70%" show-footer title="修改标签">
+    <div class="type">
+      <el-radio-group v-model="actionType">
+        <el-radio :label="1">列表新增</el-radio>
+        <el-radio :label="2">列表移除</el-radio>
+      </el-radio-group>
+    </div>
+    <el-scrollbar class="label-group">
+      <el-checkbox-group v-model="labels" :max="10">
+        <div class="label-box">
+          <div class="label-item" v-for="(item,index) of labelData" :key="index">
+            <el-checkbox :label="item.name"></el-checkbox>
+          </div>
+        </div>
+      </el-checkbox-group>
+    </el-scrollbar>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { setLabels } from '@/api/omsOrder'
+import {queryAll, updateOrdered, del} from '@/api/omsLabel'
+@Component({components:{}})
+export default class TabModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  actionType:any=1
+  labels:Array<any>=[]
+  labelData:Array<any>=[]
+  mounted(){
+    this.getList()
+  }
+  hide(){
+    this.actionType = 1;
+    this.labels = [];
+  }
+  getList(){
+    this.load = true;
+    queryAll().then((res:any) => {
+      this.load = false;
+      this.labelData = []
+      if(res.data){
+        this.labelData = res.data
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  btn(){
+    let data:any = {};
+    data.actionType = this.actionType
+    data.labels = this.labels;
+    data.idList = this.billValue;
+    this.load = true
+    setLabels(data).then(()=>{
+      this.load = false;
+      (this.$message({
+        message:'操作成功!',
+        type:'success'
+      }));
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.type{
+  width: 100%;
+  padding-bottom: 16px;
+}
+.label-group{
+  .label-box{
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .label-item{
+    width: 33.3333%;
+  }
+}
+</style>
+
+<style lang="scss">
+.label-group{
+  width: 100%;
+  height: calc(100% - 37px);
+  div.el-scrollbar__wrap {
+    overflow-x: hidden;
+  }
+  .el-scrollbar__bar {
+    right: 0px;
+  }
+}
+</style>

+ 89 - 0
src/views/oms/B2BOrder/components/updateRmkModal.vue

@@ -0,0 +1,89 @@
+<template>
+  <vxe-modal v-model="value" id="updateRmkModal" width="400" v-loading="load" @show="show" @hide="hide" height="260" show-footer title="卖家备注">
+    <by-form :propConfig="config" ref="form">
+      <template v-slot:isAppend="{value}">
+        <el-switch
+          v-model="value.isAppend">
+        </el-switch>
+      </template>
+    </by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { updateRemark } from '@/api/omsOrder'
+@Component({components:{}})
+export default class UpdateRmkModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      rules:{
+        remark: [
+          { required: true, message: '卖家备注不能为空!', trigger: 'input' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'卖家备注',
+        prop:'remark',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            type:'textarea'
+          }
+        }
+      }],
+      [{
+        label:'追加备注',
+        prop:'isAppend',
+        labelWidth:'80px',
+        slot:true
+      }]
+    ]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  show(){}
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      this.load = true
+      updateRemark(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 76 - 0
src/views/oms/B2BOrder/components/updateSalerModal.vue

@@ -0,0 +1,76 @@
+<template>
+  <vxe-modal v-model="value" id="updateSalerModal" width="400" v-loading="load" @hide="hide" height="200" show-footer title="修改业务员">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { setCreateUser } from '@/api/omsOrder'
+@Component({components:{}})
+export default class UpdateSalerModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      rules:{
+        createUser: [
+          { required: true, message: '业务员不能为空!', trigger: 'input' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'业务员',
+        prop:'createUser',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入业务员'
+          }
+        }
+      }]
+    ]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      this.load = true
+      setCreateUser(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 1281 - 0
src/views/oms/B2BOrder/index.vue

@@ -0,0 +1,1281 @@
+<template>
+  <div class="order" v-loading="load">
+    <div class="order-left">
+      <el-scrollbar class="search-content">
+        <el-collapse v-model="activeNames" class="my-collapse">
+          <el-collapse-item name="1">
+            <template slot="title">
+              基本信息<i class="header-icon el-icon-info" title="精确搜索"></i>
+            </template>
+            <input-select :options="myOptions" @input="parameChange" ref="searchCom01" />
+            <input-select :options="outLineOptions" @input="parameChangeBase($event,'idType','idValue')" ref="searchCom02" />
+            <input-select :options="buyerOptions" @input="parameChangeInfo($event,'receiverInfo','receiverValue')" ref="searchCom03" />
+          </el-collapse-item>
+          <order-checkbox title="订单状态" keyName="statusList" ref="searchCom04" :options="statusOptions" noLimit @checkboxChange="onChange($event,'statusList')">
+            <template v-slot:question>
+              <div class="ques-box">
+                <div class="questtion-top" @click="showQues = !showQues">
+                  <div class="quest-title">
+                    <span>异常类型</span>
+                    <i class="el-icon-setting" @click.stop="showQuestType"></i>
+                  </div>
+                  <i class="el-icon-arrow-down"></i>
+                </div>
+                <el-collapse-transition>
+                  <div class="ques-list"  v-show="showQues">
+                    <template v-for="item of questData">
+                      <el-checkbox :label="item.id" v-if="item.isShow == 1" :key="item.value">{{item.type}}</el-checkbox>
+                    </template>
+                  </div>
+                </el-collapse-transition>
+              </div>
+            </template>
+          </order-checkbox>
+          <order-radio title="提交状态" keyName="isSubmitted" ref="searchComsubmitStatus" :options="submitOption" noLimit @radioChange="onChangeSmt" />
+          <order-radio title="买家留言" keyName="buyerMessageFilter" ref="searchCom05" :options="buyerMessageOptions" noLimit @radioChange="onChange($event,'buyerMessageFilter')">
+            <template v-slot:buyerMessage>
+              <el-input style="width: 140px;" v-model="value.buyerMessageContent" size="mini" placeholder="留言内容"></el-input>
+            </template>
+          </order-radio>
+          <order-radio title="卖家备注" keyName="remarkFilter" ref="searchCom06" :options="remarkFilterOptions" noLimit @radioChange="onChange($event,'remarkFilter')">
+            <template v-slot:remarkFilter>
+              <el-input style="width: 140px;" v-model="value.remarkContent" size="mini" placeholder="备注内容"></el-input>
+            </template>
+          </order-radio>
+          <el-collapse-item title="时间" name="time">
+            <div class="orderSelect">
+              <el-select v-model="value.dateType" placeholder="请选择时间类型" size="mini">
+                <el-option
+                  v-for="item in dateTypeOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+              <i class="el-icon-info" title="附加订单时间限制,许多仅限待发货订单的查询条件将自动取消限制"></i>
+            </div>
+            <filter-date @change="onChangeTime" ref="searchCom07" />
+            <!-- <div>付款后几小时未发货:</div>
+            <div class="order-time">
+              <vxe-input v-model="value.deliveryHours" class="deliveryHours-input" clearable type="number" size="mini"></vxe-input>
+              <i class="el-icon-info" title="单位小时,不支持小数位。如果数值大于0,强制为未发货订单。同时勾选店铺可以实现不同平台的未发货时效查询"></i>
+            </div>
+            <filterMinMax title="剩余发货时间(小时)" ref="searchCom08" minField="deliveryRemainingMin" maxField="deliveryRemainingMax" @change="parameChange" /> -->
+          </el-collapse-item>
+          <order-checkbox title="平台订单状态" ref="searchCom09" keyName="shopStatusList" :options="shopStatusListOption" noLimit @checkboxChange="onChange($event,'shopStatusList')" />
+          <order-radio title="线下备注" ref="searchCom10" keyName="noteFilter" :options="noteFilterOptions" noLimit @radioChange="onChange($event,'noteFilter')">
+            <template v-slot:noteContent>
+              <el-input style="width: 140px;" v-model="value.noteContent" size="mini" placeholder="备注内容"></el-input>
+            </template>
+          </order-radio>
+          <order-radio title="操作标记" keyName="operationFlag" ref="searchCom11" :options="sourceFromOptions" noLimit @radioChange="onChange($event,'operationFlag')" />
+          <order-checkbox title="订单类型" keyName="typeList" ref="searchCom12" :options="typeOption" noLimit @checkboxChange="onChange($event,'typeList')" />
+          <el-collapse-item title="付款方式 & 是否付款" name="codAndPay">
+            <div class="box01">
+              <el-radio-group v-model="radio" @input="colChange">
+                <el-radio label="0">不限</el-radio>
+                <el-radio label="1">在线支付</el-radio>
+                <el-radio label="2">货到付款</el-radio>
+              </el-radio-group>
+            </div>
+            <div class="box01">
+              <el-radio-group v-model="radio2" @input="payChange">
+                <el-radio label="0">不限</el-radio>
+                <el-radio label="1">未付款</el-radio>
+                <el-radio label="2">已付款</el-radio>
+              </el-radio-group>
+            </div>
+          </el-collapse-item>
+          <!-- <order-checkbox title="店铺" ref="searchCom13" keyName="shopIdList" :options="shopIdListOptions" @checkboxChange="onChange($event,'shopIdList')" /> -->
+
+          <order-checkbox title="省份" ref="searchCom14" keyName="receiverProvinceCode" :options="provinceOptions" @checkboxChange="onChange($event,'receiverProvinceCodeList')" />
+        </el-collapse>
+      </el-scrollbar>
+      <div class="searchHandle">
+        <el-button size="mini" @click="resert">重置</el-button>
+        <el-button type="primary" size="mini" @click="search">搜索</el-button>
+      </div>
+    </div>
+    <div class="order-right">
+      <div class="tool">
+        <order-tool @addOrder="addOrder" @smt="smtOrder" @reSmt="reSmt" @loadOrder="loadOrder" @producePurchase="producePurchase" @cancelOrder="cancelOrder" 
+        @reCancelOrder="reCancelOrder" @updateRmk="updateRmk" @changeQues="changeQues" @changeNormal="changeNormal" @updateSalesman="updateSalesman" 
+        @updateTag="updateTag" @addGift="addGift" @addProduct="addProduct" @updateFreight="updateFreight" @orderFile="orderFile" @batchSendGoods="batchSendGoods" />
+      </div>
+      <div class="table">
+        <order-table :data="data" ref="orderTable" class="order-table" @detail="detail" @mergeHandle="mergeHandle" @splitHandle="splitHandle" @sendGoods="sendGoods" 
+        @sendGoodsDetail="sendGoodsDetail"/>
+        <div class="page">
+          <el-pagination v-if="page.total > 0" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNo" :page-size="page.pageSize"
+            :layout="'total, sizes, prev, pager, next, jumper'" :total="page.total"></el-pagination>
+        </div>
+      </div>
+
+      <!-- 手工下单 -->
+      <add-order ref="addOrder" @handleSuccess="handleSuccess" />
+      <!-- 手工下载 -->
+      <load-order-modal ref="loadOrder" @handleSuccess="handleSuccess" />
+      <!-- 生成采购单 -->
+      <purchase-model ref="purchaseModel" @handleSuccess="handleSuccess" />
+      <!-- 合并 -->
+      <merge-model ref="mergeModel" @handleSuccess="handleSuccess" />
+      <!-- 拆分 -->
+      <split-model ref="splitModel" @handleSuccess="handleSuccess" />
+      <!-- 取消订单 -->
+      <cancel-order-model ref="cancelOrderModel" @handleSuccess="handleSuccess" />
+      <!-- 异常 -->
+      <quest-model ref="questModel" @questHide="getQuestionList" />
+      <!-- 转异常 -->
+      <set-ques-modal ref="setQuesModal" @handleSuccess="handleSuccess" />
+      <!-- 改卖家备注 -->
+      <update-rmk-modal ref="updateRmkModal" @handleSuccess="handleSuccess" />
+      <!-- 改业务员 -->
+      <update-saler-modal ref="updateSalerModal" @handleSuccess="handleSuccess" />
+      <!-- 改标签 -->
+      <tabModal ref="tabModal" @handleSuccess="handleSuccess" />
+      <!-- 添加赠品 -->
+      <add-product-modal ref="addProductModal" @handleSuccess="handleSuccess" />
+      <!-- 改运费 -->
+      <freight-modal ref="freightModal" @handleSuccess="handleSuccess" />
+      <!-- 标签 -->
+      <labels-modal ref="labelsModal" @onChange="onChangeLabel" />
+      <!-- 发货模式 -->
+      <send-mode-modal ref="sendModeModal" @modeChange="modeChange" />
+      <!-- 批量逐一发货 -->
+      <batchbyOneModal ref="batchbyOneModal" @handleSuccess="handleSuccess" />
+      <!-- 整车发货 -->
+      <carpoolModal ref="carpoolModal" @handleSuccess="handleSuccess" />
+      <!-- 发货单详情 -->
+      <deliveryDetail ref="deliveryDetail" @handleSuccess="handleSuccess" @showLogistics="showLogistics" />
+      <!-- 物流信息 -->
+      <logisticsInfo ref="logisticsInfo" />
+      <!-- 快递发货 -->
+      <!-- <express-delivery-modal ref="expressDeliveryModal" @handleSuccess="handleSuccess" /> -->
+    </div>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import filterInput from './components/filterInput.vue'
+import OrderCheckbox from "./components/orderCheckbox.vue";
+import OrderRadio from './components/orderRadio.vue'
+import filterDate from './components/filterDate.vue'
+import OrderTool from "./components/orderTool.vue";
+import OrderTable from "./components/orderTable.vue";
+import AddOrder from "./components/addOrder.vue"; //新增订单
+import InputSelect from "./components/inputSelect.vue";
+import OrderProduct from "./components/orderProduct.vue"; 
+import filterMinMax from './components/filterMinMax.vue'
+import loadOrderModal from './components/loadOrderModal.vue' //手工下载
+import PurchaseModel from "./components/purchaseModel.vue"; //生成采购单
+import MergeModel from "./components/mergeMedal.vue"; //合并
+import SplitModel from "./components/splitModal.vue"; //拆分
+import CancelOrderModel from "./components/cancelOrderModel.vue"; //取消订单
+import QuestModel from "./components/questModel.vue";
+import SetQuesModal from "./components/setQuesModal.vue";
+import UpdateRmkModal from "./components/updateRmkModal.vue";
+import UpdateSalerModal from "./components/updateSalerModal.vue";
+import TabModal from "./components/tabModal.vue";
+import AddProductModal from "./components/addProductModal.vue";
+import FreightModal from "./components/freightModal.vue";
+import LabelsModal from "./components/labelsModal.vue";
+import SendModeModal from "./components/sendModeModal.vue";
+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}})
+export default class Order extends Vue {
+  activeNames:Array<any>=['1','statusList']
+  radio=''
+  radio2=''
+  data:Array<any> = []
+  load = false;
+  showQues=false;
+  isContainLabel=true;
+  page:any={
+    pageNo: 1, //当前页
+    pageSize: 20, //每页条数
+    total: 0 //总条数
+  }
+  questData:Array<any>=[]
+  value:any={
+    // sourceId:'',  //线上订单号
+    // shopBuyerId:'', //买家昵称
+    // buyerId:'', //买家ID
+    // logisticsId:'', //快递单号
+    // logisticsCompany:'', //快递公司
+    // internationalLogisticsId:'', //国际物流单号
+    // isSubmitte:'', //数据是否已提交
+    // drpCoIdFrom:'', //分销商编号
+    // drpCoIdTo:'', //供销商编号
+    // sourceFrom:'', //订单来源
+    // dateType:1,//时间类型
+    // deliveryRemainingMin:0, //订单剩余发货时间(小时)-小于等于
+    // deliveryRemainingMax:null, //订单剩余发货时间(小时)-大于等于
+    // includeSkuType:1, //包含编码类型
+    // type:'', //订单类型
+    // status:'' , //订单状态
+    // excludeSkuType:1, //排除编码类型
+  }
+  myOptions=[{
+    label:'内部订单号',
+    value:'orderId',
+    format:/[^0-9,]*/g
+  }]
+  outLineOptions=[{
+    label:'线上订单号',
+    value:'sourceId'
+  },{
+    label:'支付单号',
+    value:'outerPayId'
+  }]
+  buyerOptions=[{
+    label:'买家账号',
+    value:'buyerId'
+  },{
+    label:'快递单号',
+    value:'logisticsId'
+  },{
+    label:'收件人-省',
+    value:'receiverProvince'
+  },{
+    label:'收件人-市',
+    value:'receiverCity'
+  },{
+    label:'收件人-区',
+    value:'receiverDistrict'
+  },{
+    label:'收货地址',
+    value:'receiverAddress'
+  },{
+    label:'收件人',
+    value:'receiverName'
+  },{
+    label:'手机号',
+    value:'receiverMobile'
+  },{
+    label:'固定电话',
+    value:'receiverPhone'
+  }]
+
+  //买家留言
+  buyerMessageOptions=[{
+    label:'无留言',
+    value:1
+  },{
+    label:'未处理的留言',
+    value:2
+  },{
+    slotName:'buyerMessage',
+    label:'有留言',
+    value:3
+  }]
+  //卖家备注
+  remarkFilterOptions=[{
+    label:'无备注',
+    value:1,
+  },{
+    label:'未处理的备注',
+    value:2,
+  },{
+    label:'有备注',
+    slotName:'remarkFilter',
+    value:3,
+  }]
+  //订单时间类型
+  dateTypeOptions=[{
+    label:'订单时间',
+    value:1
+  },{
+    label:'发货时间',
+    value:2
+  },{
+    label:'付款时间',
+    value:3
+  },{
+    label:'确认收货时间',
+    value:4
+  },{
+    label:'计划发货时间',
+    value:5
+  }]
+  //包含编码类型
+  includeSkuTypeOptions=[{
+    label:'包含任意商品编码',
+    value:1
+  },{
+    label:'包含任意款式编码',
+    value:2
+  },{
+    label:'包含全部商品编码',
+    value:3
+  },{
+    label:'包含全部款式编码',
+    value:4
+  },{
+    label:'仅包含指定商品编码',
+    value:5
+  },{
+    label:'仅包含指定款式编码',
+    value:6
+  },{
+    label:'包含任意店铺商品编码',
+    value:7
+  },{
+    label:'包含任意店铺款式编码',
+    value:8
+  }]
+  //排除编码类型
+  excludeSkuTypeOptions=[{
+    label:'排除任意商品编码',
+    value:1
+  },{
+    label:'排除任意款式编码',
+    value:2
+  }]
+  //平台订单状态
+  shopStatusListOption:Array<any>=[{
+    label:'没有创建支付宝交易',
+    value:1
+  },{
+    label:'等待买家付款',
+    value:2
+  }]
+
+  noteFilterOptions:Array<any>=[{
+    label:'无备注',
+    value:1,
+  },{
+    label:'有备注',
+    slotName:'noteContent',
+    value:2,
+  }]
+
+  //订单来源
+  sourceFromOptions:Array<any>=[{
+    label:'手工下单',
+    value:'OMS'
+  },{
+    label:'复制',
+    value:'COPY'
+  },{
+    label:'合并',
+    value:'MERGE'
+  },{
+    label:'拆分;拆分还原',
+    value:'SPLIT'
+  },{
+    label:'手机',
+    value:'MOBILE'
+  },{
+    label:'导入',
+    value:'IMPORT'
+  },{
+    label:'供销推送',
+    value:'DRP-S'
+  },{
+    label:'快手;微商城',
+    value:'KWAISHOP'
+  },{
+    label:'拼多多',
+    value:'PINDUODUO'
+  },{
+    label:'头条放心购',
+    value:'TOUTIAOFXG'
+  },{
+    label:'聚水潭',
+    value:'JUSHUITAN'
+  }]
+
+  //审批状态
+  submitOption:Array<any>=[{
+    label:'未提交',
+    value:0
+  },{
+    label:'已提交',
+    value:1
+  }]
+
+  //订单类型
+  typeOption:Array<any>=[{
+    label:'普通订单',
+    value:'Common'
+  },{
+    label:'补发订单',
+    value:'Reissue'
+  },{
+    label:'分销Plus',
+    value:'DistributionPlus'
+  },{
+    label:'供销Plus',
+    value:'SupplyPlus'
+  },{
+    label:'换货订单',
+    value:'Exchange'
+  }]
+
+  //订单状态 
+  statusOptions:Array<any>=[{
+    label:'待付款',
+    value:'WaitPay'
+  },{
+    label:'被合并',
+    value:'Merged'
+  },{
+    label:'被拆分',
+    value:'Split'
+  },{
+    label:'等供销商|外仓发货',
+    value:'WaitOuterSent'
+  },{
+    label:'已付款待审核',
+    value:'WaitConfirm'
+  },{
+    label:'已客审待财审',
+    value:'WaitFConfirm'
+  },{
+    label:'发货中',
+    value:'Delivering'
+  },{
+    label:'已发货',
+    value:'Sent'
+  },{
+    label:'取消',
+    value:'Cancelled'
+  },{
+    label:'异常',
+    value:'Question',
+    slot:true,
+    slotName:'question'
+  }]
+  shopIdListOptions:Array<any>=[]
+
+  //省份
+  provinceOptions:Array<any>=[]
+
+  mounted(){
+    this.getList();
+    this.getProvince();
+    this.getQuestionList();
+  }
+  //查看物流
+  showLogistics(code:string){
+    if(this.$refs.logisticsInfo){
+      (this.$refs.logisticsInfo as any).setShow(true);
+      (this.$refs.logisticsInfo as any).loadData(code);
+    }
+  }
+  //发货详情
+  sendGoodsDetail(row:any){
+    if(this.$refs.deliveryDetail){
+      (this.$refs.deliveryDetail as any).setShow(true);
+      (this.$refs.deliveryDetail as any).setData(row.id);
+    }
+  }
+  //批量发货
+  batchSendGoods(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:string='';
+    let noStatus = ['WaitPay','Delivering','Merged','Split','Question','Sent','Cancelled'];
+    for(const item of data){
+      if(!(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && noStatus.indexOf(item.status) == -1)){
+        ids = ids ? ids + ',' + item.id : item.id;
+      }
+    }
+    if(ids){
+      this.$message('订单“ ' + ids + ' ”不符合发货条件!');
+      return
+    }
+    // if(data.length == 1){
+
+    //   (this.$refs.deliveryModal as any).setShow(true);
+    // }else{
+      if(this.$refs.sendModeModal){
+        (this.$refs.sendModeModal as any).setShow(true);
+      }
+    // }
+    
+  }
+  //发货模式
+  modeChange(v:string){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    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': // 整车发货
+        let isShow = true
+        for (const item of data) {
+          if(!(data[0].buyerId === item.buyerId && data[0].receiverName === item.receiverName && data[0].receiverTownCode === item.receiverTownCode && data[0].receiverAddress === item.receiverAddress && data[0].receiverMobile === item.receiverMobile)) {
+            isShow = false;
+            break
+          }
+        }
+        if(!isShow) {
+          this.$message({
+            message: '整车发货必须是同一买家!',
+            type: 'warning'
+          })
+        }
+        if(this.$refs.carpoolModal && isShow){
+          (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);
+      //   }
+    }
+  }
+  //整车发货
+  sendGoods(item:any){
+    (this.$refs.batchbyOneModal as any).setShow(true);
+    (this.$refs.batchbyOneModal as any).setValue([item]);
+    // (this.$refs.deliveryModal as any).setShow(true);
+  }
+  //显示标签弹窗
+  showLabels(){
+    this.isContainLabel = true;
+    if(this.$refs.labelsModal){
+      (this.$refs.labelsModal as any).setShow(true);
+    }
+  }
+  showLabels2(){
+    this.isContainLabel = false;
+    if(this.$refs.labelsModal){
+      (this.$refs.labelsModal as any).setShow(true);
+    }
+  }
+  //标签弹窗返回信息
+  onChangeLabel(v:string){
+    if(this.isContainLabel){
+      if(this.value.includeLabels){
+        Vue.set(this.value, 'includeLabels', v);
+      }else{
+        this.value.includeLabels = v;
+      }
+      
+    }else{
+      if(this.value.excludeLabels){
+        Vue.set(this.value, 'excludeLabels', v);
+      }else{
+        this.value.excludeLabels = v;
+      }
+    }
+    this.$forceUpdate()
+  }
+  labelsClear(v?:boolean){
+    if(v){
+      delete this.value.includeLabels;
+    }else{
+      delete this.value.excludeLabels;
+    }
+    this.$forceUpdate()
+  }
+  //归档
+  orderFile(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids='';
+    let idsArr:Array<any>=[];
+    for(const item of data){
+      ids = ids ? ids + ',' + item.id : item.id;
+      idsArr.push(item.id)
+    }
+    this.$confirm('归档后数据无法恢复,您确定将订单“'+ ids +'”归档?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+      archive({idList:idsArr}).then((res:any) => {
+        this.$message({
+          message:res.msg ? res.msg : '归档成功!',
+          type:'success'
+        });
+        this.load = false;
+        this.getList();
+      }).catch(() => {
+        this.load = false;
+      })
+    }).catch(() => {  });
+  }
+  //改运费
+  updateFreight(){
+    this.updateHandleModal('freightModal');
+  }
+  //添加商品
+  addProduct(){
+    this.updateHandleModal('addProductModal');
+  }
+  //添加赠品
+  addGift(){
+    this.updateHandleModal('addProductModal');
+    (this.$refs.addProductModal as any).setGift(true);
+  }
+  
+  //改标签
+  updateTag(){
+    this.updateHandleModal('tabModal')
+  }
+  //改业务员
+  updateSalesman(){
+    this.updateHandleModal('updateSalerModal')
+  }
+  //改备注
+  updateRmk(){
+    this.updateHandleModal('updateRmkModal')
+  }
+  updateHandleModal(n:string){
+    let data = (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let billData:Array<any>=[]
+    for(const item of data){
+      billData.push(item.id);
+    }
+    (this.$refs[n] as any).setBillValue(billData);
+    (this.$refs[n] as any).setShow(true);
+  }
+  //转异常
+  changeQues(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let msg = '';
+    let billData:Array<any>=[]
+    for(const item of data){
+      billData.push(item.id);
+      if(item.status == 'Question'){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”状态异常,不能执行此操作!'
+      })
+      return
+    }
+    (this.$refs.setQuesModal as any).setBillValue(billData);
+    (this.$refs.setQuesModal as any).setQuestTypeData(this.questData);
+    (this.$refs.setQuesModal as any).setShow(true);
+  }
+  //转正常
+  changeNormal(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let msg = '';
+    let billData:Array<any>=[]
+    for(const item of data){
+      billData.push(item.id);
+      if(item.status != 'Question'){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”状态正常,不能执行此操作!'
+      })
+      return
+    }
+    this.load = true
+    resetQuestion({idList:billData}).then((res:any)=>{
+      this.load = false;
+      (this.$message({
+        message:res.msg?res.msg:'操作成功!',
+        type:'success'
+      }));
+      this.getList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //异常数据弹窗
+  showQuestType(){
+    (this.$refs.questModel as any).setShow(true);
+  }
+  //获取异常数据
+  getQuestionList(){
+    queryAll().then((res:any) => {
+      this.questData = res.data;
+    }).catch(() => { })
+  }
+
+  //生成采购单
+  producePurchase(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let msg:string='';
+    let ids:Array<any>=[];
+    for(const item of data){
+      if(item.isSubmitted != 1){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+      ids.push(item.id)
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”未提交,不能生成采购单!'
+      })
+      return
+    }
+    purchaseQty({
+      ids:ids
+    }).then((res:any) => {
+      let productData:Array<any>=[];
+      for(const item of data){
+        for(const childItem of item.items){
+          childItem.orderId = item.id;
+          childItem.residueQty = childItem.qty;
+          productData.push(childItem)
+        }
+      }
+      if(res.data.length){
+        for(const item of productData){
+          for(const _item of res.data){
+            if(item.id == _item.itemId){
+              item.residueQty = _item.residueQty >= 0 ?  _item.residueQty : item.qty
+            }
+          }
+        }
+      }
+      for(let i = productData.length - 1; i>=0; i--){
+        if(productData[i] && productData[i].residueQty == 0){
+          productData.splice(i,1)
+        }
+      }
+      (this.$refs.purchaseModel as any).setShow(true);
+      (this.$refs.purchaseModel as any).setTableData(productData);
+    })
+  }
+  //重置搜索数据
+  clearSearchValue(){
+    this.value={};
+    for(const key in this.$refs){
+      if(key.indexOf('searchCom') >= 0 && (this.$refs[key] as any).clear){
+        (this.$refs[key] as any).clear()
+      }
+    }
+    this.value.dateType = 1;
+    this.value.includeSkuType = 1;
+  }
+  resert(){
+    this.clearSearchValue();
+    this.radio = ''
+    this.radio2 = ''
+    this.page.pageNo = 1;
+    this.getList();
+  }
+  //搜索
+  search(){
+    this.page.pageNo = 1;
+    this.getList();
+  }
+  //合并操作
+  mergeHandle(data:Array<any>){
+    if(this.$refs.mergeModel){
+      (this.$refs.mergeModel as any).setShow(true);
+      (this.$refs.mergeModel as any).setData(data);
+    }
+  }
+  //拆单
+  splitHandle(row:any){
+    if(this.$refs.splitModel){
+      (this.$refs.splitModel as any).setShow(true);
+      (this.$refs.splitModel as any).setData((this as any).$lodash.cloneDeep(row));
+    }
+  }
+  addOrder(){
+    (this.$refs.addOrder as any).setShow(true)
+  }
+  smtOrder(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let msg = '';
+    let smtMst='';
+    for(const item of data){
+      if(item.isSubmitted == 1){
+        if(smtMst){
+          smtMst = smtMst + ',' + item.id
+        }else{
+          smtMst = item.id
+        }
+      }
+      if(!item.pays && item.pays.length == 0){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+      ids.push(item.id)
+    }
+    if(smtMst){
+      this.$message({
+        message:'订单“'+smtMst + '”已提交,不能重复操作!'
+      })
+      return
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”未付款,不能提交!'
+      })
+      return
+    }
+    this.load = true;
+    smt({
+      ids:ids
+    }).then((res:any) => {
+      this.load = false;
+        (this as any).$message({
+          message: res.msg?res.msg:'订单提交成功!',
+          type: 'success'
+        });
+      this.getList();
+    })
+  }
+  reSmt(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let smtMst:string='';
+    for(const item of data){
+      if(item.isSubmitted == 0){
+        if(smtMst){
+          smtMst = smtMst + ',' + item.id
+        }else{
+          smtMst = item.id
+        }
+      }
+      ids.push(item.id)
+    }
+    if(smtMst){
+      this.$message({
+        message:'订单“'+smtMst + '”未提交,不能进行此操作!'
+      })
+      return
+    }
+    this.load = true;
+    unSmt({
+      ids:ids
+    }).then((res:any) => {
+      this.load = false;
+        (this as any).$message({
+          message: res.msg?res.msg:'订单取消提交成功!',
+          type: 'success'
+        });
+      this.getList();
+    })
+  }
+  getProvince(){
+    this.provinceOptions = [];
+    getProvince({
+      pid:'0'
+    }).then((res:any) => {
+      if(res.data){
+        for(const item of res.data){
+          this.provinceOptions.push({
+            label:item.extName,
+            value:item.id
+          })
+        }
+      }
+    })
+  }
+
+  //组件返回事件
+  onChange(v:any,code:string){
+    this.value[code] = v;
+  }
+  parameChange(parames:any){
+    for(const key in parames){
+      if(parames[key]){
+        if(this.value[key]){
+          this.value[key] = parames[key].split(',')
+        }else{
+          Vue.set(this.value, key, parames[key].split(','));
+        }
+      }else{
+        delete this.value[key]
+      }
+    }
+  }
+  parameChangeBase(parames:any,n1:string,n2:string){
+    for(const key in parames){
+      if(parames[key]){
+        this.value[n1] = key;
+        this.value[n2] = parames[key].split(',');
+      }else{
+        this.value[n1] = '';
+        this.value[n2] = [];
+      }
+    }
+  }
+  parameChangeInfo(parames:any,n1:string,n2:string){
+    for(const key in parames){
+      if(parames[key]){
+        this.value[n1] = key;
+        this.value[n2] = parames[key];
+      }else{
+        this.value[n1] = '';
+        this.value[n2] = '';
+      }
+    }
+  }
+  onChangeSmt(v:any){
+    if(v == 1){
+      this.value.submitStatus = true
+    }else if(v == 0){
+      this.value.submitStatus = false
+    }
+  }
+  colChange(v:any){
+    if(v == 1){
+      this.value.isCod = false
+    }else if(v == 2){
+      this.value.isCod = true
+    }else{
+      this.value.isCod = null
+    }
+  }
+  payChange(v:any){
+    if(v == 1){
+      this.value.isPay = false
+    }else if(v == 2){
+      this.value.isPay = true
+    }else{
+      this.value.isPay = null
+    }
+  }
+  onChangeTime(v:Array<any>){
+    this.value.dateBegin = v[0];
+    this.value.dateEnd = v[1];
+  }
+  //获取订单列表数据
+  getList(){
+    let data:any = (this as any).$lodash.cloneDeep(this.value);
+    let params:any={};
+    if(data.includeLabels){
+      data.includeLabels = data.includeLabels.split(',');
+    }
+    if(data.excludeLabels){
+      data.excludeLabels = data.excludeLabels.split(',');
+    }
+    data.businessType = 'B2B'
+    params.pageNo = this.page.pageNo;
+    params.pageSize = this.page.pageSize;
+    this.load = true;
+    query(params,data).then((res:any) => {
+      this.data = res.data.records;
+      this.page.pageNo = res.data.current;
+      this.page.total = res.data.total;
+      this.load = false;
+      this.$forceUpdate();
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+  //订单操作成功刷新页面
+  handleSuccess(){
+    this.page.pageNo = 1;
+    this.clearSearchValue();
+    this.getList();
+  }
+  //订单详情
+  detail(row:any){
+    let data = (this as any).$lodash.cloneDeep(row);
+    (this.$refs.addOrder as any).setDetail(data); 
+    (this.$refs.addOrder as any).setShow(true);
+  }
+
+  handleSizeChange(v:number){
+    this.page.pageSize = v;
+    this.getList();
+  }
+  handleCurrentChange(v:number){
+    this.page.pageNo = v;
+    this.getList();
+  }
+  //取消订单
+  cancelOrder(){
+    let condi=['WaitPay','Delivering','Question','WaitOuterSent','WaitConfirm','WaitFConfirm'];
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let msgIds='';
+    for(const item of data){
+      if(condi.indexOf(item.status) >= 0){
+        ids.push(item.id)
+      }else{
+        if(msgIds){
+          msgIds = msgIds + ',' + item.id
+        }else{
+          msgIds = item.id
+        }
+      }
+    }
+    if(msgIds){
+      this.$message({
+        message:'订单“'+msgIds + '”不满足取消条件!'
+      })
+      return
+    }
+    (this.$refs.cancelOrderModel as any).setShow(true);
+    (this.$refs.cancelOrderModel as any).setData(ids);
+  }
+  //反取消订单
+  reCancelOrder(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let msgIds='';
+    for(const item of data){
+      if(item.status == 'Cancelled'){
+        ids.push(item.id)
+      }else{
+        if(msgIds){
+          msgIds = msgIds + ',' + item.id
+        }else{
+          msgIds = item.id
+        }
+      }
+    }
+    if(msgIds){
+      this.$message({
+        message:'订单“'+msgIds + '”订单未取消,不能执行此操作!'
+      })
+      return
+    }
+    this.load = true;
+    unCancel({idList:ids}).then((res:any)=>{
+      this.load = false;
+      this.$message({
+        message:res.msg?res.msg:'订单反取消成功!',
+        type:'success'
+      })
+      this.handleSuccess();
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+
+  //同步店铺订单
+  loadOrder(){
+    (this.$refs.loadOrder as any).setShow(true);
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.order{
+  width: 100%;
+  height: 100%;
+  display: flex;
+  overflow-y: hidden;
+  .order-left{
+    width: 260px;
+    height: 100%;
+    flex-shrink: 0;
+    background-color: #f0f0f0;
+    border-right: solid 1px #CCC;
+    box-sizing: border-box;
+    padding: 4px 4px 0;
+    position: relative;
+    .my-collapse{
+      padding: 0 4px;
+      background: #FFF;
+    }
+
+    .searchHandle{
+      display: flex;
+      justify-content: center;
+      width: 100%;
+      box-sizing: border-box;
+      padding: 8px;
+      background-color: #f0f0f0;
+    }
+    .box01{
+      width: 100%;
+      padding-bottom: 8px;
+    }
+  }
+  .filter-box{
+    width: calc(100% - 8px);
+    background-color: #FFF;
+    box-sizing: border-box;
+    padding: 8px;
+    border:solid 1px #EEE;
+    
+    .filter-row:last-child{
+      padding: 0;
+    }
+  }
+  .order-right{
+    width: calc(100% - 260px);
+    box-sizing: border-box;
+    padding-left: 8px;
+    height: 100%;
+    min-width: 850px;
+    overflow-x: auto;
+    .tool{
+      width: 100%;
+    }
+    .table{
+      width: 100%;
+      height: calc(100% - 40px);
+      .order-table{
+        width: 100%;
+        height: calc(100% - 48px);
+      }
+      .page{
+        width: 100%;
+        display: flex;
+        justify-content: flex-end;
+        padding: 8px;
+        box-sizing: border-box;
+      }
+    }
+  }
+  .el-icon-info{
+    font-size: 16px;
+    margin-left: 4px;
+  }
+}
+// .order-label{
+//   font-size: 12px;
+// }
+.orderSelect{
+  width: 100%;
+  margin-bottom: 4px;
+}
+.order-time{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 4px;
+}
+.ques-box{
+  .questtion-top{
+    height: 30px;
+    display: flex;
+    justify-content:space-between;
+    align-items: center;
+    padding: 0 16px;
+    background-color: #EEE;
+    cursor: pointer;
+    .quest-title{
+      height: 30px;
+      font-size: 12px;
+      display: flex;
+      align-items: center;
+    }
+    .el-icon-setting{
+      padding-right: 8px;
+      color: #2d99f7;
+      margin-left: 4px;
+    }
+    i{
+      font-size: 16px;
+      cursor: pointer;
+    }
+  }
+  .ques-list{
+    overflow: hidden;
+    padding-left: 16px;
+  }
+}
+</style>
+
+<style lang="scss">
+.order-left{
+  .el-collapse-item__content{
+    padding-bottom: 0;
+  }
+  .el-collapse-item__header{
+    font-weight: 700 !important;
+  }
+}
+.deliveryHours-input{
+  width: 80px; 
+  flex-shrink: 0; 
+  padding: 0;
+  .el-input__inner{
+    padding: 0 !important;
+    text-align: center;
+  }
+}
+.search-content{
+  height: calc(100% - 44px);
+  div.el-scrollbar__wrap {
+    overflow-x: hidden;
+  }
+  .el-scrollbar__bar {
+    right: 0px;
+  }
+}
+.labels-width-btn{
+  margin-bottom: 8px;
+  .el-input-group__append{
+    background-color: #fff !important;
+    width: 30px !important;
+    padding: 0 10px;
+    .el-icon-more{
+      font-size: 16px;
+    }
+  }  
+}
+</style>

+ 1763 - 0
src/views/oms/B2COrder/components/addOrder.vue

@@ -0,0 +1,1763 @@
+<template>
+  <vxe-modal v-model="value" id="addOrder" @show="show" width="70%" height="80%" min-width="460" min-height="320" 
+    show-zoom resize transfer show-footer @hide="hide" v-loading="load">
+    <template #title>
+      <span>创建新订单</span>
+    </template>
+    <template #default>
+      <div class="order-step" v-if="orderValue.id">
+        <el-steps :active="stepActive" align-center finish-status="success" v-if="topStep.indexOf(orderValue.status) >= 0" size="mini">
+          <el-step title="1.待付款"></el-step>
+          <el-step title="2.已付款待审核"></el-step>
+          <!-- <el-step title="3.已客审待财审"></el-step>
+          <el-step title="4.等供销商|外仓发货"></el-step> -->
+          <el-step title="3.发货中"></el-step>
+        </el-steps>
+        <div class="other" v-if="stepTypeName(orderValue.status)">{{ stepTypeName(orderValue.status) }}</div>
+      </div>
+      <el-collapse v-model="activeNames">
+        <el-collapse-item title="基本信息" name="1" class="add-order-item">
+          <by-form :propConfig="baseConfig" ref="baseform" @formChange="formChangeBase">
+            <template v-slot:sourceFrom_desc='{ value }'>
+              {{ getFromText(value.operationFlag) }}
+            </template>
+            <template v-slot:shopName="{value}">
+              <el-input :placeholder="!orderValue.id?'请选择标签':''" :value="value.shopName" :disabled="orderValue.id?true:false" @clear="clearShop" size="small" class="myinpuy-with-select" clearable>
+                <el-button slot="append" v-if="!orderValue.id" icon="el-icon-more" @click="showShop"></el-button>
+              </el-input>
+            </template>
+            <template v-slot:labels="{value}">
+              <el-input :placeholder="!orderValue.id?'请选择标签':''" :value="value.labels" :disabled="orderValue.id?true:false" size="small" @clear="clearLabels" class="myinpuy-with-select" clearable>
+                <el-button slot="append" v-if="!orderValue.id" icon="el-icon-more" @click="showLabels"></el-button>
+              </el-input>
+            </template>
+          </by-form>
+        </el-collapse-item>
+        <el-collapse-item title="买家信息" name="2" class="add-order-item">
+          <by-form :propConfig="buyerInfoConfig" ref="infoform">
+            <template v-slot:buyerNickname="{value}">
+              <el-input placeholder="请选择买家'" :value="value.buyerNickname" @clear="clearBuyer" size="small" class="myinpuy-with-select" clearable>
+                <el-button slot="append" icon="el-icon-more" @click="showBuyer"></el-button>
+              </el-input>
+            </template>
+            <template v-slot:receiverProvinceCode_desc='{ value }'>
+              {{ value.receiverProvince + '-' + value.receiverCity + '-' + value.receiverDistrict + (value.receiverTown?'-'+value.receiverTown:'') }}
+            </template>
+          </by-form>
+        </el-collapse-item>
+        <el-collapse-item title="发票信息" name="5" class="add-order-item" v-if="orderValue.id">
+          <by-form :propConfig="newInvoicesConfig" ref="invoicesform"></by-form>
+        </el-collapse-item>
+        <div class="btn-save" v-if="orderValue.id && orderValue.isSubmitted != 1">
+          <el-button type="primary" size="small" @click="saveBase">保存基本信息及收获地址</el-button>
+        </div>
+        <el-collapse-item title="订单支付情况" name="4" class="add-order-item" v-if="orderValue.id">
+          <div class="pay-row" v-if="orderValue.status != 'Split' && orderValue.status != 'Merged' && orderValue.status != 'Cancelled'">
+            <!-- <el-button type="text" v-if="!orderValue.pays || orderValue.pays.length == 0">快速支付</el-button> -->
+            <div class="add-pay-btn" v-if="orderValue.status !== 'Delivering'  && orderValue.status !== 'Sent'">
+              <el-button type="text" v-if="!showPay" @click="showPay = true">添加手工支付</el-button>
+              <el-button v-else icon="el-icon-close" size="mini" circle @click="showPay = false"></el-button>
+            </div>
+            
+          </div>
+          <by-form v-if="showPay" :propConfig="payConfig" ref="payform"></by-form>
+          <div class="pay-row" v-if="showPay && orderValue.status != 'Split' && orderValue.status != 'Merged' && orderValue.status != 'Cancelled'">
+            <el-button type="primary" size="small" @click="addPay">添加</el-button>
+          </div>
+          <div class="pay-info">
+            <el-descriptions v-for="(item,index) of orderValue.pays" :key="index" :title="item.payment" size="mini" :column="4">
+              <el-descriptions-item label="单号">{{item.outerPayId}}</el-descriptions-item>
+              <el-descriptions-item label="金额">{{item.amount}}</el-descriptions-item>
+              <el-descriptions-item label="支付日期">{{item.payDate}}</el-descriptions-item>
+              <el-descriptions-item label="状态" v-if="orderValue.status !== 'Delivering' && orderValue.status !== 'Sent'">
+                <div class="payHandle" v-if="item.status == 'WaitConfirm'">
+                  <span @click="payStatusHandle(item,'Confirmed')">审核通过</span>
+                  <span @click="payStatusHandle(item,'Invalid')">作废</span>
+                </div>
+                <div class="payHandle" v-if="item.status == 'Confirmed'">
+                  <span @click="payStatusHandle(item,'WaitConfirm')">取消审核</span>
+                </div>
+                <el-tag v-if="item.status == 'Invalid'" type="info" size="mini">已失效</el-tag>
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+          
+        </el-collapse-item>
+        <el-collapse-item title="商品订单" name="3" class="add-order-item">
+          <div class="addProductTool">
+            <by-tool :propConfig="toolConfig" v-if="orderValue.status !== 'Delivering' && orderValue.status !== 'Sent'" ref="tool"></by-tool>
+            <div class="preferential">
+              <div class="pre-title">抵扣金额<i class="el-icon-info" title="支持输入数字和百分比。若输入百分比,将自动计算折扣金额=商品成交总金额*百分比(举例:打9折,请输入10%),只在订单创建时计算一次,在订单创建后修改商品价格不会自动计算,运费不参与折扣。"></i>:</div>
+              <vxe-input v-if="!orderValue.id" v-model="freeAmount" class="freeAmount" placeholder="请输入" size="mini" @change="freeAmountChange"></vxe-input>
+              <span v-else>{{ freeAmount }}</span>
+            </div>
+          </div>
+          
+          <by-table :propConfig="tableConfig" ref="table">
+            <template v-slot:name='{ row }'>
+              <div class="product-cont">
+                <div class="product-name">{{ row.name }} <el-tag v-if="row.isGift == 1" size="mini" type="success">赠</el-tag></div>
+              </div>
+            </template>
+            <template v-slot:qty='{ row }'>
+              <vxe-input v-model="row.qty" v-if="!orderValue.id" placeholder="数量" align="center" size="mini" type="integer" @input="qtyChange($event, row)" >
+              </vxe-input>
+              <span v-else>{{ row.qty }}</span>
+            </template>
+            <template v-slot:price='{ row }'>
+              <span v-if="row.isGift == 1">0</span>
+              <vxe-input v-else-if="!orderValue.id" v-model="row.price" placeholder="单价" align="center" size="mini" type="number" @input="priceChange($event, row)" >
+              </vxe-input>
+              <span v-else>{{ row.price }}</span>
+            </template>
+          </by-table>
+          <div class="product-row">
+            <div class="p-left">数量:{{ num }}</div>
+            <div class="p-right">
+              <div class="amount-title">商品成交总金额:</div>
+              <div class="amount-price">¥{{ productTotal }}</div>
+            </div>
+          </div>
+          <div class="product-row">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">抵扣金额:</div>
+              <div class="amount-price">¥{{orderValue.freeAmount?orderValue.freeAmount:'0.00'}}</div>
+            </div>
+          </div>
+          <div class="product-row">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">运费:</div>
+              <div class="amount-price">¥{{orderValue.freight?orderValue.freight:'0.00'}}</div>
+            </div>
+          </div>
+          <div class="product-row">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">应付总金额:</div>
+              <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{orderValue.payAmount?orderValue.payAmount:'0.00'}}</div>
+            </div>
+          </div>
+          <div class="product-row" v-if="orderValue.paidAmount">
+            <div class="p-left"></div>
+            <div class="p-right">
+              <div class="amount-title">实付总金额:</div>
+              <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{orderValue.paidAmount?orderValue.paidAmount:'0.00'}}</div>
+            </div>
+          </div>
+        </el-collapse-item>
+        <el-collapse-item title="订单支付情况" name="4" class="add-order-item" v-if="!orderValue.id">
+          <el-radio-group v-model="radioPay" @input="inputPay" class="payType">
+            <el-radio :label="0">待付款</el-radio>
+            <el-radio :label="1">快速支付&已付款</el-radio>
+            <el-radio :label="2">手工添加支付信息</el-radio>
+            <el-radio :label="3">货到付款</el-radio>
+          </el-radio-group>
+          <by-form v-if="radioPay == 2" :propConfig="payConfig" ref="payform"></by-form>
+        </el-collapse-item>
+        <el-collapse-item title="发票信息" name="5" class="add-order-item" v-if="!orderValue.id">
+          <by-form :propConfig="newInvoicesConfig" ref="invoicesform"></by-form>
+        </el-collapse-item>
+      </el-collapse>
+      <!-- 商品 -->
+      <product-sku-modal ref="product" :mulit="true" @confirm="confirmProduct" />
+      <!-- 赠品 -->
+      <product-sku-modal ref="productGift" :mulit="true" @confirm="confirmProductGift" />
+
+      <add-product-modal ref="addProductModal" @handleSuccess="handleSuccess" :mask="false" />
+      <edit-product-modal ref="editProductModal" @handleSuccess="handleSuccess" />
+      <!-- 店铺 -->
+      <shop-modal ref="shopModal" @shopSelect="shopSelect" />
+      <!-- 标签 -->
+      <labels-modal ref="labelsModal" @onChange="onChangeLabel" />
+      <!-- 买家 -->
+      <buyer-info-modal ref="buyerInfoModal" @confirm="confirmBuyerInfo" />
+      <el-drawer class="log-drawer" :size="600" append-to-body title="操作日志" :visible.sync="drawer" direction="rtl">
+        <byLog :propConfig="logConfig" ref="log" />
+      </el-drawer>
+    </template>
+    <template #footer>
+      <div class="btn">
+        <el-button type="primary" size="small" v-if="!orderValue.id" @click="btn('continue')">确定并继续</el-button>
+        <el-button type="primary" size="small" v-if="!orderValue.id" @click="btn">确定</el-button>
+        <el-button icon="el-icon-edit-outline" circle v-if="orderValue.id" @click="logShow"></el-button>
+      </div>
+    </template>
+    
+  </vxe-modal>
+  
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { addOrder,saveBaseOrder,single,delItem,addPay,updateStatus } from '@/api/omsOrder'
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import AddProductModal from "./addProductModal.vue";
+import EditProductModal from "./editProductModal.vue";
+import LabelsModal from "./labelsModal.vue";
+import ShopModal from "./shopModal.vue";
+import BuyerInfoModal from "./buyerInfoModal.vue";
+@Component({components:{AddProductModal,EditProductModal,LabelsModal,ShopModal,BuyerInfoModal}})
+export default class AddOrder extends Vue {
+  logConfig:any={
+    request:{
+      url:'/omsOrder/omsOrderOperateLog/page',
+      method:'GET'
+    }
+  };
+  drawer=false;
+  value=false;
+  num:any=0;
+  showPay = false;
+  load = false;
+  freeAmount="";
+  productTotal:any=0;
+  userInfo:any='';//用户信息
+  orderValue:any={}; //新增订单值
+  radioPay=1;
+  stepActive:number=0;
+  topStep=['WaitPay','WaitConfirm','Delivering']
+  stepCon=['WaitPay','WaitConfirm','WaitFConfirm','WaitOuterSent','Sent','Delivering']
+  activeNames:Array<any> =['1','2','3','4','5','save'];
+  operationFlag:any={
+    'ERP':'手工下单',
+    'COPY':'复制',
+    'MERGE':'合并',
+    'SPLIT':'拆分;拆分还原',
+    'MOBILE':'导入',
+    'drp-s':'供销推送',
+    'drp-d':'分销推送',
+    'KWAISHOP':'快手;微商城',
+    'PINDUODUO':'拼多多',
+    'TOUTIAOFXG':'头条放心购',
+    'JUSHUITAN':'聚水潭'
+  }
+  baseConfig:any={};
+  buyerInfoConfig:any={};
+  newInvoicesConfig:any={}
+  config:any={
+    attr:{
+      size:'small',
+      itemCount:4,
+      rules:{
+        orderDate:[{
+          required: true, message: '订单日期不能为空!', trigger: 'blur'
+        }]
+      }
+    },
+    columns:[
+      [{
+        span:6,
+        label:'订单来源',
+        prop:'upSourceName',
+        // slot:true,
+        component:'by-input',
+        compConfig:{
+          attr:{
+            readonly:true
+            // type:'integer',
+            // placeholder:'请输入店铺名称',
+            // clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'线上订单',
+        prop:'sourceId',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'自动生成',
+            readonly:true
+          }
+        }
+      },{
+        span:6,
+        label:'订单日期',
+        prop:'orderDate',
+        component:'by-date-picker',
+        compConfig:{
+          attr:{
+            // placeholder:'请输入订单日期',
+            clearable:true,
+            type:'datetime',
+            format:'yyyy-MM-dd HH:mm:ss',
+            defaultNow:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'运费',
+        prop:'freight',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入运费',
+            type:'number',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'快递公司',
+        prop:'logisticsCompany',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入快递公司',
+            clearable:true
+          }
+        }
+      },
+      {
+        span:6,
+        label:'业务员',
+        prop:'createBy',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入业务员',
+            // readonly:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'操作标记',
+        prop:'operationFlag',
+        descSlot:true,
+        component:'by-select',
+        colspan:2,
+        compConfig:{
+          attr:{
+            // placeholder:'请输入订单日期',
+            disabled:true,
+            data:[{
+              label:'手工下单',
+              value:'OMS'
+            },{
+              label:'复制',
+              value:'COPY'
+            },{
+              label:'合并',
+              value:'MERGE'
+            },{
+              label:'拆分;拆分还原',
+              value:'SPLIT'
+            },{
+              label:'手机',
+              value:'MOBILE'
+            },{
+              label:'导入',
+              value:'IMPORT'
+            },{
+              label:'供销推送',
+              value:'DRP-S'
+            },{
+              label:'分销推送',
+              value:'DRP-D'
+            },{
+              label:'快手;微商城',
+              value:'KWAISHOP'
+            },{
+              label:'拼多多',
+              value:'PINDUODUO'
+            },{
+              label:'头条放心购',
+              value:'TOUTIAOFXG'
+            },{
+              label:'聚水潭',
+              value:'JUSHUITAN'
+            }]
+          }
+        }
+      },{
+        label:'标签',
+        prop:'labels',
+        span:12,
+        colspan:2,
+        slot:true
+      }],
+      [{
+        label:'线下备注',
+        prop:'note',
+        component:'by-input',
+        colspan:2,
+        compConfig:{
+          attr:{
+            placeholder:'请输入线下备注',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'买家留言',
+        prop:'buyerMessage',
+        component:'by-input',
+        colspan:2,
+        compConfig:{
+          attr:{
+            placeholder:'请输入买家留言',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'卖家备注',
+        prop:'remark',
+        component:'by-input',
+        colspan:4,
+        compConfig:{
+          attr:{
+            placeholder:'请输入卖家备注',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  config2:any={
+    attr:{
+      size:'small',
+      itemCount:4,
+      rules:{
+        buyerNickname:[{
+          required: true, message: '买家账号不能为空!', trigger: 'blur'
+        }],
+        receiverDistrictCode:[{
+          required: true, message: '收货地址不能为空!', trigger: 'blur'
+        }],
+        receiverAddress:[{
+          required: true, message: '详细地址不能为空!', trigger: 'blur'
+        }],
+        receiverMobile:[{
+          required: true, message: '手机号不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }]
+      }
+    },
+    columns:[
+      [{
+        span:6,
+        label:'买家',
+        prop:'buyerNickname',
+        slot:true,
+        // component:'by-input',
+        // compConfig:{
+        //   attr:{
+        //     type:'integer'
+        //   }
+        // }
+      },{
+        span:6,
+        label:'收货人',
+        prop:'receiverName',
+        component:'by-input',
+        rules:[{
+          required: true, message: '收货人不能为空', trigger: 'blur'
+        }],
+        compConfig:{
+          attr:{
+            placeholder:'请输入收货人',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'手机',
+        prop:'receiverMobile',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入手机',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'固定电话',
+        prop:'receiverPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入电话',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'邮编',
+        prop:'receiverZip',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入邮编',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:24,
+        label:'收货地址',
+        // slot:true,
+        prop:'receiverProvinceCode',
+        component:'by-area',
+        colspan:2,
+        descSlot:true,
+        compConfig:{
+          attr:{
+            province:'receiverProvince', //省
+            provinceCode:'receiverProvinceCode', //省编码
+            city:'receiverCity',   //市
+            cityCode:'receiverCityCode',  //市编码
+            county:'receiverDistrict',  //县/区
+            countyCode:'receiverDistrictCode',   //县/区编码
+            townCode:'receiverTownCode',
+            town:'receiverTown',
+            // show:'county'
+          }
+        }
+      }],
+      [{
+        span:24,
+        label:'详细地址',
+        prop:'receiverAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入详细地址',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  tableConfig:any={
+    attr:{
+      size:'mini',
+      align:'center',
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      slot:true,
+      // width:300
+    },{
+      title:'数量',
+      field:'qty',
+      width:130,
+      slot:true
+    },{
+      title:'单价',
+      field:'price',
+      width:130,
+      slot:true
+    },{
+      title:'原价',
+      field:'basePrice',
+      width:120
+    },{
+      title:'成交金额',
+      field:'amount',
+      width:120
+    },
+    // {
+    //   title:'库存',
+    //   field:'stock',
+    //   width:100
+    // },
+    {
+      title:'操作',
+      action:true,
+      width:160,
+      plugins:[{
+        icon:'el-icon-delete',
+        name:'删除',
+        audit:'',
+        event:{
+          show:(row:any) => {
+            if(row.status == 'Merged' || row.status == 'Cancelled'){
+              return false
+            }else{
+              return true
+            }
+          },
+          click:(item:any) => {
+            this.deletaProduct(item);
+          }
+        }
+      }]
+    }]
+  }
+  toolConfig={
+    customTools:[
+      {
+        name: '新增商品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddProduct()
+          }
+        }
+      },
+      {
+        name: '添加赠品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddGift();
+            
+          }
+        }
+      }
+    ]
+  }
+  invoicesConfig:any={
+    attr:{
+      size:'small',
+      itemCount:4,
+    },
+    columns:[
+      [{
+        span:6,
+        label:'发票类型',
+        prop:'type',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            placeholder:'发票类型',
+            clearable:true,
+            data:[{
+              value: '个人电子普通',
+              label: '个人电子普通'
+            }, {
+              value: '单位电子普通',
+              label: '单位电子普通'
+            }, {
+              value: '个人纸质普通',
+              label: '个人纸质普通'
+            }, {
+              value: '单位纸质普通',
+              label: '单位纸质普通'
+            }, {
+              value: '个人电子增值税',
+              label: '个人电子增值税'
+            }, {
+              value: '单位电子增值税',
+              label: '单位电子增值税'
+            }, {
+              value: '个人纸质增值税',
+              label: '个人纸质增值税'
+            }, {
+              value: '单位纸质增值税',
+              label: '单位纸质增值税'
+            }]
+          }
+        }
+      },{
+        span:6,
+        label:'发票抬头',
+        prop:'title',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'发票税号',
+        prop:'taxNo',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'发票地址',
+        prop:'address',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'专票银行',
+        prop:'bank',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'发票电话',
+        prop:'phone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'专票账户',
+        prop:'account',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'专票邮箱',
+        prop:'email',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'专票人',
+        prop:'userName',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'专票电话',
+        prop:'userPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        span:12,
+        label:'专票地址',
+        prop:'userAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  payConfig:any={
+    // attr:{
+    //   size:'mini'
+    // },
+    columns:[
+      [{
+        span:6,
+        label:'支付方法',
+        prop:'payment',
+        component:'by-select',
+        rules:[
+          { required: true, message: '请选择支付方法', trigger: 'change' }
+        ],
+        compConfig:{
+          attr:{
+            placeholder:'支付方法',
+            clearable:true,
+            data:[{
+              value: '支付宝',
+              label: '支付宝'
+            }, {
+              value: '快钱',
+              label: '快钱'
+            }, {
+              value: '财付通',
+              label: '财付通'
+            }]
+          }
+        }
+      },{
+        span:6,
+        label:'支付日期',
+        prop:'payDate',
+        rules:[
+          { required: true, message: '请选择支付日期', trigger: 'change' }
+        ],
+        component:'by-date-picker',
+        compConfig:{
+          attr:{
+            type:'datetime',
+            format:'yyyy-MM-dd HH:mm:ss',
+            clearable:true,
+            defaultNow:true
+          }
+        }
+      },{
+        span:6,
+        label:'支付单号',
+        prop:'outerPayId',
+        component:'by-input',
+        rules:[
+          { required: true, message: '请输入支付单号', trigger: 'change' }
+        ],
+        compConfig:{
+          attr:{
+            placeholder:'支付单号',
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'支付金额',
+        prop:'amount',
+        component:'by-input',
+        rules:[
+          { required: true, message: '请输入支付金额', trigger: 'blur' }
+        ],
+        compConfig:{
+          attr:{
+            type:'number',
+            placeholder:'支付金额',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'买家支付账号',
+        prop:'buyerAccount',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'买家账号',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'卖家收款账号',
+        prop:'sellerAccount',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'收款账号',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  //订单来源转换文字信息
+  getFromText(f:any){
+    let t='';
+    if(f){
+      let arr:Array<any>=f.split(',');
+      for(const item of arr){
+        if(this.operationFlag[item]){
+          if(t){
+            t = t + ' , ' + this.operationFlag[item]
+          }else{
+            t = this.operationFlag[item]
+          }
+        }
+      }
+    }
+    return t;
+  }
+  stepTypeName(n:string){
+    let t = '';
+    if(n == 'Merged'){
+      t = '被合并'
+    }
+    if(n == 'Question'){
+      t = '异常'
+    }
+    if(n == 'Split'){
+      t = '被拆分'
+    }
+    if(n == 'Cancelled'){
+      t = '已取消'
+    }
+    return t;
+  }
+  logShow() {
+    if(!this.orderValue.id) return
+    this.drawer = true;
+    let data = {
+      orderNumber:this.orderValue.id
+    }
+    this.$nextTick(() => {
+      if (this.$refs.log) {
+        (this.$refs.log as any).setBillValue(data);
+        (this.$refs.log as any).request();
+      }
+    })
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  showBuyer() {
+    (this.$refs.buyerInfoModal as any).setShow(true)
+  }
+  showShop(){
+    (this.$refs.shopModal as any).setShow(true);
+  }
+  shopSelect(data:any){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.shopId = data.id;
+    value.shopName = data.shopName;
+    (this.$refs.baseform as any).setValue(value);
+  }
+  clearShop(){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.shopId = '';
+    value.shopName = '';
+    (this.$refs.baseform as any).setValue(value);
+  }
+  clearBuyer(){
+    let value:any = (this.$refs.infoform as any).getValue();
+    value.buyerId = '';
+    value.buyerNickname = '';
+    (this.$refs.infoform as any).setValue(value);
+  }
+  setDetail(data:any){
+    this.orderValue = data;
+    this.radioPay = this.orderValue.isPay
+    if(this.orderValue.isCod == 1) {
+      this.radioPay = 3
+    }
+  }
+  //订单支付情况单选值
+  inputPay(v:number){
+    if(v === 3) {
+      this.orderValue.isCod = 1
+      this.orderValue.isPay = 0
+    }else{
+      this.orderValue.isPay = v;
+      this.orderValue.isCod = 0
+    }
+  }
+  created(){
+    this.userInfo = this.$store.getters.userInfo;
+  }
+  //标签弹窗信息
+  onChangeLabel(v:string){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.labels = v;
+    (this.$refs.baseform as any).setValue(value);
+  }
+  //显示标签弹窗
+  showLabels(){
+    if(this.$refs.labelsModal){
+      (this.$refs.labelsModal as any).setShow(true);
+    }
+  }
+  clearLabels(){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.labels = '';
+    (this.$refs.baseform as any).setValue(value);
+  }
+  handleSuccess(){
+    this.$emit('handleSuccess');
+    this.getData();
+  }
+  //修改支付单号
+  payStatusHandle(item:any,status:string){
+    if(status == 'Invalid'){
+      this.$confirm('此操作将永久作废单号为:'+item.outerPayId+' 的订单支付, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.payStatusRequest(item,status)
+      }).catch(() => {});
+    }else{
+      this.payStatusRequest(item,status)
+    }
+  }
+  payStatusRequest(item:any,status:string){
+    this.load = true;
+    updateStatus({id:item.id, status}).then((res:any)=>{
+      this.load = false;
+      if(res && res.code == 200){
+        this.$message({
+          message:'操作成功!',
+          type:'success'
+        })
+        item.status = status;
+        this.$forceUpdate();
+        this.$emit('handleSuccess');
+      }
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //添加手工支付
+  addPay(){
+    (this.$refs.payform as any).validate({noMsg:true}).then(()=>{
+      let payFormValue = (this.$refs.payform as any).getValue();
+      payFormValue.sellerId = this.userInfo.userId;
+      payFormValue.orderId = this.orderValue.id;
+      payFormValue.operationFlag = this.orderValue.operationFlag;
+      payFormValue.isOrderPay = 1;
+      payFormValue.buyerNickname = this.orderValue.buyerNickname;
+      payFormValue.status = this.orderValue.status;
+      this.load = true;
+      addPay(payFormValue).then(()=>{
+        this.load = false;
+        this.$message({
+          message:'操作成功',
+          type:'success'
+        });
+        this.showPay = false;
+        this.handleSuccess();
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+    
+  }
+  // 买家信息
+  confirmBuyerInfo(data:any) {
+    let v:any = {}
+    v.buyerNickname = data[0].name
+    v.buyerId = data[0].id
+    v.receiverName = data[0].contacts
+    v.receiverProvince = data[0].province
+    v.receiverProvinceCode = data[0].provinceCode
+    v.receiverCity = data[0].city
+    v.receiverCityCode = data[0].cityCode
+    v.receiverDistrict = data[0].region
+    v.receiverDistrictCode = data[0].regionCode
+    v.receiverTownCode = data[0].streetCode
+    v.receiverTown = data[0].street
+    v.receiverAddress = data[0].address
+    v.receiverMobile = data[0].telephone
+    v.receiverPhone = data[0].phonenum
+    if(this.$refs.infoform){
+      (this.$refs.infoform as any).setValue(v)
+    }
+  }
+  //添加商品
+  toolAddProduct(){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    if(this.orderValue.id){
+      (this.$refs.addProductModal as any).setBillValue(this.orderValue.id);
+      (this.$refs.addProductModal as any).setShow(true);
+      (this.$refs.addProductModal as any).setGift(false);
+    }else{
+      (this.$refs.product as any).setShow(true);
+    }
+  }
+  //添加赠品
+  toolAddGift(){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    if(this.orderValue.id){
+      (this.$refs.addProductModal as any).setBillValue([this.orderValue.id]);
+      (this.$refs.addProductModal as any).setShow(true);
+      (this.$refs.addProductModal as any).setGift(true);
+    }else{
+      (this.$refs.productGift as any).setShow(true);
+    }
+  }
+  //获取数据
+  getData(){
+    if(!this.orderValue.id){
+      return
+    }
+    this.load = true;
+    single({
+      id:this.orderValue.id
+    }).then((res:any) => {
+      this.load = false;
+      this.orderValue = res.data;
+      this.show();
+      this.$forceUpdate();
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  //商品编辑
+  editProduct(){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    let tableValue = (this.$refs.table as any).getValue();
+    (this.$refs.editProductModal as any).setShow(true);
+    (this.$refs.editProductModal as any).setOrderValue(this.orderValue);
+    (this.$refs.editProductModal as any).setTableValue(tableValue);
+  }
+  show(){
+    this.baseConfig = (this as any).$lodash.cloneDeep(this.config);
+    this.buyerInfoConfig = (this as any).$lodash.cloneDeep(this.config2);
+    this.newInvoicesConfig = (this as any).$lodash.cloneDeep(this.invoicesConfig);
+    if(this.$refs.tool){
+      (this.$refs.tool as any).initTools();
+    }
+    if(this.orderValue.id){
+      let data = this.orderValue;
+      this.freeAmount = this.orderValue.freeAmount;
+      //基本信息
+      let info:any={};
+      info.shopName = data.shopName;
+      info.sourceId = data.sourceId;
+      info.orderDate = data.orderDate;
+      info.freight = Number(data.freight)?Number(data.freight):0;
+      info.logisticsCompany = data.logisticsCompany;
+      info.createBy = data.createBy;
+      info.note = data.note;
+      info.buyerMessage = data.buyerMessage;
+      info.remark = data.remark;
+      info.labels = data.labels;
+      info.logisticsId = data.logisticsId;
+      info.operationFlag = data.operationFlag;
+      this.baseConfig.attr.data = info;
+      (this.$refs.baseform as any).setValue(info);
+      //买家
+      let buyerInfo:any={};
+      buyerInfo.buyerNickname = data.buyerNickname;
+      buyerInfo.receiverName = data.receiverName;
+      buyerInfo.receiverProvince=data.receiverProvince;//省
+      buyerInfo.receiverProvinceCode=data.receiverProvinceCode; //省编码
+      buyerInfo.receiverCity=data.receiverCity;   //市
+      buyerInfo.receiverCityCode=data.receiverCityCode;  //市编码
+      buyerInfo.receiverDistrict=data.receiverDistrict;  //县/区
+      buyerInfo.receiverDistrictCode=data.receiverDistrictCode;   //县/区编码
+      buyerInfo.receiverTownCode=data.receiverTownCode;
+      buyerInfo.receiverTown=data.receiverTown;
+      buyerInfo.receiverAddress = data.receiverAddress;
+      buyerInfo.receiverPhone = data.receiverPhone;
+      buyerInfo.receiverMobile = data.receiverMobile;
+      buyerInfo.receiverZip = data.receiverZip;
+      this.buyerInfoConfig.attr.data = buyerInfo;
+      (this.$refs.infoform as any).setValue(buyerInfo);
+      //商品
+      const productData:Array<any> = data.items ? data.items : [];
+      for(let dItem of productData){
+        dItem.status = this.orderValue.status
+      }
+      (this.$refs.table as any).setValue(productData);
+      if(this.orderValue.status == 'Merged' || this.orderValue.status == 'Cancelled'){
+        (this.$refs.tool as any).setTool([]);
+      }else{
+        if(this.$refs.tool) {
+          (this.$refs.tool as any).setCustomTools([{
+            name: '商品编辑', icon: 'el-icon-edit', event:{
+              click:()=>{
+                this.editProduct()
+              }
+            }
+          }])
+        }
+        
+
+      }
+      
+      //付款
+      this.orderValue.isPay = data.isPay;
+      this.radioPay = data.isPay
+      if(data.isCod == 1) {
+        this.radioPay == 3
+      }
+      //发票
+      if(data.invoices && data.invoices[0]){
+        (this.$refs.invoicesform as any).setValue(data.invoices[0]);
+      }
+      if(this.orderValue.isSubmitted == 1){
+        this.baseConfig.attr.showType='desc';
+        this.baseConfig.attr.size='medium';
+        this.baseConfig.columns[1].splice(2,0,{
+          label:'快递单号',
+          prop:'logisticsId'
+        })
+      }else{
+        for(let col of this.baseConfig.columns){
+          for(let item of col){
+            let disField:Array<string>=['freight','buyerMessage','remark'] 
+            if(!item.slot && disField.indexOf(item.prop) == -1){
+              if(!item.compConfig.attr) item.compConfig.attr = {};
+              item.compConfig.attr.disabled = true;
+            }
+          }
+        }
+      }
+
+      if(this.orderValue.isSubmitted == 1){
+        this.buyerInfoConfig.attr.showType='desc';
+        this.buyerInfoConfig.attr.size='medium';
+        this.newInvoicesConfig.attr.showType='desc';
+        this.newInvoicesConfig.attr.size='medium';
+      }
+
+      this.totalAmount();
+      this.amountChange();
+      // this.payAmountChange();
+      this.totalNum();
+      if(this.stepCon.indexOf(data.status) >=0 ){
+        this.stepActive = this.stepCon.indexOf(data.status) 
+      }
+    }else{
+      let value:any = (this.$refs.baseform as any).getValue();
+      value.createBy = this.userInfo.userName;
+      (this.$refs.baseform as any).setValue(value);
+    }
+    (this.$refs.baseform as any).setConfig(this.baseConfig);
+    (this.$refs.infoform as any).setConfig(this.buyerInfoConfig);
+    (this.$refs.invoicesform as any).setConfig(this.newInvoicesConfig);
+  }
+  hide(){
+    this.showPay = false;
+    this.clearValue();
+  }
+  //抵扣金额数值变化
+  freeAmountChange(v:any){
+    this.orderValue.freeAmount = 0;
+    this.amountChange();
+    this.payAmountChange();
+  }
+  //商品成交总金额
+  totalAmount(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.productTotal = 0;
+    for(const item of nowData){
+      if(Number(item.amount) && item.isGift != 1){
+        this.productTotal = add(item.amount, this.productTotal)
+      }
+    }
+    this.productTotal = this.productTotal.toFixed(2);
+  }
+  //具体折扣数目
+  amountChange(){
+    if(this.freeAmount){
+      if(Number(this.freeAmount) >= 0){
+        this.orderValue.freeAmount = Number(this.freeAmount)
+      }else{
+        let arr:Array<any> = this.freeAmount.split("%");
+        if(arr.length == 2 && Number(arr[0]) > 0){
+          const n = divide(Number(arr[0]),100)
+          this.orderValue.freeAmount = multiply(this.productTotal,n)
+        }
+      }
+      this.orderValue.freeAmount = this.orderValue.freeAmount?this.orderValue.freeAmount.toFixed(2):0;
+    }else{
+      this.orderValue.freeAmount = 0
+    }
+  }
+  //应付总金额
+  payAmountChange(){
+    const freight = Number(this.orderValue.freight)?Number(this.orderValue.freight):0;
+    const freeAmount = Number(this.orderValue.freeAmount)?Number(this.orderValue.freeAmount):0;
+    let t = subtract(this.productTotal, freeAmount);
+    this.orderValue.payAmount = add(t, freight);
+    this.orderValue.payAmount = this.orderValue.payAmount.toFixed(2);
+  }
+  //商品总数量
+  totalNum(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.num = 0;
+    for(const item of nowData){
+      if(Number(item.qty)){
+        this.num = add(Number(item.qty), Number(this.num))
+      }
+    }
+  }
+  //基本信息表单数据变化
+  formChangeBase(data:any){
+    if(!this.orderValue[data.code]){
+      Vue.set(this.orderValue, data.code, data.value);
+    }else{
+      this.orderValue[data.code] = data.value;
+    }
+    if(data.code == 'freight'){
+      this.payAmountChange();
+    }
+    if(data.code == 'shopName'){
+      this.orderValue.shopId = data.value;
+    }
+  }
+  //确定新增的商品
+  confirmProduct(data:Array<any>){
+    this.productHandle(data,false);
+  }
+  //新增赠品
+  confirmProductGift(data:Array<any>){
+    this.productHandle(data,true);
+  }
+  //商品处理
+  productHandle(data:Array<any>,isGift:boolean){
+    let nowData = (this.$refs.table as any).getValue();
+    let names='';
+    if(data.length > 0){
+      for(const item of data){
+        let t = true;
+        let v = isGift ? 1 : 0;
+        for(const t_item of nowData){
+          if(item.id == t_item.itemId && t_item.isGift == v){
+            if(!names){
+              names = item.skuTitle
+            }else{
+              names = names + ',' + item.skuTitle
+            }
+            t = false;
+            break;
+          }
+        }
+        if(t){
+          let obj:any={};
+          obj.name = item.skuTitle; //商品名称
+          obj.skuId = item.skuCode; //商品编码
+          obj.itemId = item.id;
+          obj.styleId = item.itemNumber; //款式编码
+          obj.qty = 1;
+          if(isGift){
+            obj.price = 0;  //单价
+            obj.isGift = 1;
+          }else{
+            obj.price = item.price;  //单价
+            obj.isGift = 0;
+          }
+          
+          obj.basePrice = item.price; //原价
+          obj.amount = item.price;
+          // obj.stock = item.stock;
+          nowData.push(obj)
+        }
+      }
+      (this.$refs.table as any).setValue(nowData);
+      if(!isGift){
+        this.totalAmount();
+        this.amountChange();
+        this.payAmountChange();
+      }
+      this.totalNum();
+      if(names){
+        let name = isGift ? '赠品' : '商品';
+        this.$alert(name+'“'+names+'”已存在,请在列表做调整!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {}
+        });
+      }
+    }
+  }
+  //删除商品
+  deletaProduct(row:any){
+    if (this.orderValue.status == 'Delivering' || this.orderValue.status == 'Sent') {
+      this.$message({
+        message:'该订单已发货不能进行修改!',
+        type:'warning'
+      })
+      return
+    }
+    let n = row.isGift == 1 ? '赠品' : '商品';
+    this.$confirm('此操作将删除'+n+'“'+row.name+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      let del=()=>{
+        let data = (this.$refs.table as any).getValue();
+        let index = -1;
+        for(const item of data){
+          index ++;
+          if(row.skuId == item.skuId && row.name == item.name && row.isGift == item.isGift){
+            break;
+          }
+        }
+        data.splice(index,1);
+        (this.$refs.table as any).setValue(data);
+        this.totalAmount();
+        this.amountChange();
+        this.payAmountChange();
+        this.totalNum();
+      }
+      if(row.id){
+        this.load = true;
+        delItem({
+          itemId:row.id,
+          id:this.orderValue.id
+        }).then(()=>{
+          this.load = false;
+          del();
+          this.$emit('handleSuccess');
+        }).catch(()=>{
+          this.load = false;
+        })
+      }else{
+        del();
+      }
+      
+    }).catch(() => { });
+  }
+  //数量的变化
+  qtyChange(v:any,row:any){
+    if(v.value && row.price){
+      row.amount = multiply(Number(v.value),Number(row.price))
+    }else{
+      row.amount = 0
+    }
+    this.totalAmount();
+    this.amountChange();
+    this.payAmountChange();
+    this.totalNum();
+  }
+  //单价的变化
+  priceChange(v:any,row:any){
+    if(v.value && row.qty){
+      row.amount =multiply(Number(v.value),Number(row.qty))
+    }else{
+      row.amount = 0
+    }
+    this.totalAmount();
+    this.amountChange();
+    this.payAmountChange();
+  }
+  //清除整个订单数据
+  clearValue(){
+    this.orderValue = {};
+    this.stepActive = 0;
+    (this.$refs.baseform as any).clearValue();
+    (this.$refs.baseform as any).clearValidate();
+    (this.$refs.infoform as any).clearValue();
+    (this.$refs.infoform as any).clearValidate();
+    (this.$refs.table as any).setValue([]);
+    if(this.$refs.payform){
+      (this.$refs.payform as any).clearValue();
+      (this.$refs.infoform as any).clearValidate();
+    }
+    (this.$refs.invoicesform as any).clearValue();
+
+    this.num = 0;
+    this.productTotal = 0;
+    this.radioPay = 1;
+    this.freeAmount = '';
+  }
+  getOrderValue(n?:string){
+    // this.orderValue = {};
+    return new Promise((resolve:Function, reject:Function) => {
+      let r = true;
+      //基本信息
+      (this.$refs.baseform as any).validate({noMsg:true}).then(()=>{
+        let baseInfo = (this.$refs.baseform as any).getValue();
+        for(const key in baseInfo){
+          this.orderValue[key] = baseInfo[key]
+        }
+        if(this.orderValue.freight){
+          this.orderValue.freight = Math.floor(Number(this.orderValue.freight) * 100) / 100;
+        }else{
+          this.orderValue.freight = 0
+        }
+        
+        //买家信息
+        (this.$refs.infoform as any).validate({noMsg:true}).then(()=>{
+          let infoValue = (this.$refs.infoform as any).getValue();
+          for(const key in infoValue){
+            this.orderValue[key] = infoValue[key]
+          }
+          if(n == 'base'){
+            resolve();
+            return
+          }
+          //商品
+          let productOrder:Array<any> = [];
+          if(this.$refs.table){
+            productOrder = (this.$refs.table as any).getValue();
+          
+          }
+          if(productOrder.length > 0){
+            this.orderValue.items = productOrder;
+          }else{
+            this.$message({
+              message: '商品订单不能为空!',
+              type: 'warning'
+            });
+            reject();
+          }
+          if(this.radioPay === 0 || this.radioPay === 1){
+            this.orderValue.isPay = this.radioPay;
+            this.orderValue.pays = []
+          }
+          if(this.radioPay == 2){
+            this.orderValue.isPay = this.radioPay;
+            (this.$refs.payform as any).validate({noMsg:true}).then(()=>{
+              this.orderValue.pays = [];
+              let payFormValue = (this.$refs.payform as any).getValue();
+              payFormValue.sellerId = this.userInfo.userId;
+              this.orderValue.pays.push(payFormValue);
+              resolve();
+            }).catch(()=>{
+              if(r){
+                (this as any).$message({
+                  message: '验证未通过,请检查!',
+                  type: 'warning',
+                })
+              }
+              r = false;
+              reject();
+            });
+          }else{
+            resolve();
+          }
+
+          
+        }).catch(()=>{
+          if(r){
+            (this as any).$message({
+              message: '验证未通过,请检查!',
+              type: 'warning',
+            })
+          }
+          r = false;
+          reject();
+        });
+      }).catch(()=>{
+        if(r){
+          (this as any).$message({
+            message: '验证未通过,请检查!',
+            type: 'warning',
+          })
+        }
+        r = false;
+        reject();
+      });
+
+      let invoiceValue = (this.$refs.invoicesform as any).getValue();
+      this.orderValue.invoices=[];
+      if(JSON.stringify(invoiceValue) !== '{}'){
+        this.orderValue.invoices.push(invoiceValue);
+      }
+    })
+  } 
+  //确定
+  btn(n?:string){
+    this.getOrderValue().then(()=>{
+      this.orderValue.receiverCountryCode = '0';
+      this.orderValue.receiverCountry="中国";
+      this.load = true;
+      this.orderValue.isCod = this.orderValue.isCod ? 1 : 0
+      this.orderValue.freeAmount = this.orderValue.freeAmount ? this.orderValue.freeAmount : 0;
+      addOrder(this.orderValue).then((res:any) => {
+        if(n != 'continue'){
+          this.value = false;
+        }else{
+          this.clearValue();
+          let value:any = (this.$refs.baseform as any).getValue();
+          value.createBy = this.userInfo.userName;
+          (this.$refs.baseform as any).setValue(value);
+        }
+        this.load = false;
+        (this as any).$message({
+          message: '订单添加成功!',
+          type: 'success',
+        })
+        this.$emit('handleSuccess');
+      }).catch((err:any) => {
+        this.load = false;
+      }).catch(()=>{
+        this.load = false
+      })
+    }).catch((err:any) => {})
+  }
+  
+  //保存基本信息及守护地址
+  saveBase(){
+    this.getOrderValue('base').then(()=>{
+      this.load = true;
+      this.orderValue.receiverCountryCode = '0';
+      this.orderValue.receiverCountry="中国";
+      saveBaseOrder(this.orderValue).then(() => {
+        this.load = false;
+        (this as any).$message({
+          message: '订单修改成功!',
+          type: 'success',
+        })
+        this.$emit('handleSuccess');
+      }).catch((err:any) => {
+        this.load = false;
+      })
+    })
+    
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+}
+.btn-save{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+  padding: 16px 0;
+  border-bottom: 1px solid #e6ebf5;
+}
+.updateBuyer{
+  padding: 0 16px;
+}
+.addProductTool{
+  width: 100%;
+  padding-bottom: 8px;
+  display: flex;
+  justify-content: flex-end;
+  .preferential{
+    width: 240px;
+    flex-shrink: 0;
+    display: flex;
+    align-items: center;
+    .pre-title{
+      width: 80px;
+      flex-shrink: 0;
+    }
+  }
+}
+.payType{
+  padding-bottom: 16px;
+}
+.product-cont{
+  width: 100%;
+  .product-name{
+    font-size: 12px;
+    // padding-bottom: 4px;
+    color: #000;
+  }
+  .other-info{
+    font-size: 12px;
+    span{
+      padding: 0 8px;
+    }
+  }
+}
+.product-row{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  font-size: 12px;
+  padding: 4px 0;
+  .p-left,.p-right{
+    width: 50%;
+  }
+  .p-left{
+    text-align: right;
+  }
+  .p-right{
+    display: flex;
+    align-items: center;
+    .amount-title{
+      width: 70%;
+      text-align: right;
+      box-sizing: border-box;
+      padding-right: 8px;
+    }
+    .amount-price{
+      width: 30%;
+    }
+  }
+}
+.pay-info{
+  width: 100%;
+}
+.pay-row{
+  display: flex;
+  justify-content: flex-end;
+  padding-bottom: 8px;
+}
+.order-step{
+  padding-bottom: 8px;
+  width: 100%;
+  .other{
+    height: 30px;
+    line-height: 30px;
+    width: 100%;
+    box-sizing: border-box;
+    padding: 0 16px;
+    font-size: 14px;
+    color: #FFF;
+    background-color: #198cf8;
+  }
+}
+.updata-btn-row{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+  padding-bottom: 8px;
+}
+.add-pay-btn{
+  padding-left: 8px;
+  display: flex;
+  align-items: center;
+}
+.payHandle{
+  display: flex;
+  align-items: center;
+  >span{
+    margin-left: 8px;
+    cursor: pointer;
+    font-size: 12px;
+    color: #198cf8;
+  }
+  >span:hover{
+    text-decoration: underline;
+  }
+}
+</style>
+
+<style lang="scss">
+.add-order-item{
+  .el-collapse-item__content{
+    padding-bottom: 0;
+  }
+}
+.pay-info{
+  .el-descriptions{
+    padding-bottom: 8px;
+    .el-descriptions__header{
+      margin-bottom: 0 !important;
+      .el-descriptions__title{
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 253 - 0
src/views/oms/B2COrder/components/addProductModal.vue

@@ -0,0 +1,253 @@
+<template>
+  <vxe-modal v-model="value" id="addProductModal" width="70%" v-loading="load" :mask="mask" @hide="hide" height="80%" show-footer :title="title">
+    <by-tool :propConfig="toolConfig" class="add-ptool" ref="tool">
+      <template v-slot:tool-right>
+        <el-switch
+          v-if="!isGift"
+          v-model="isPay"
+          active-text="快速支付" />
+      </template>
+    </by-tool>
+    <by-table :propConfig="config" ref="table">
+      <template v-slot:price='{ row }'>
+        <span v-if="isGift">0</span>
+        <vxe-input v-else v-model="row.price" placeholder="单价" align="center" size="mini" type="number"></vxe-input>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+    <!-- 商品 -->
+    <product-sku-modal ref="product" :mulit="true" @confirm="confirmProduct" />
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { addItem,addGift } from '@/api/omsOrder'
+@Component({components:{}})
+export default class AddProductModal extends Vue {
+  @Prop()
+  mask?:boolean;
+  isGift=false
+  title='';
+  value=false;
+  load=false;
+  isPay = true;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      size:'small',
+      align:'center'
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      width:340
+    },{
+      title:'数量',
+      field:'qty',
+      width:120,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          placeholder:'数量',
+          type:'integer',
+          size:'mini',
+          align:'center'
+        }
+      }
+    },{
+      title:'单价',
+      field:'price',
+      width:120,
+      slot:true,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          type:'number',
+          size:'mini',
+          align:'center'
+        }
+      }
+    },{
+      title:'库存',
+      field:'stock',
+      width:100
+    },{
+      title:'操作',
+      action:true,
+      plugins:[{
+        icon:'el-icon-delete',
+        name:'删除',
+        audit:'',
+        event:{
+          click:(item:any) => {
+            this.deletaProduct(item);
+          }
+        }
+      }]
+    }]
+  }
+  toolConfig:any={
+    customTools:[
+      {
+        name: '新增商品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            (this.$refs.product as any).setShow(true);
+          }
+        }
+      }
+    ]
+  }
+  created(){
+    
+  }
+  setGift(v:boolean){
+    this.isGift = v;
+    this.title = this.isGift?'添加赠品':'添加商品';
+    this.toolConfig.customTools[0].name = this.title;
+    if(this.$refs.tool){
+      (this.$refs.tool as any).initTools();
+    }
+    
+  }
+  hide(){
+    this.isPay = true;
+    (this.$refs.table as any).setValue([]);
+  }
+  setShow(v:boolean){
+    this.value = v;
+    this.$nextTick(()=>{
+      (this.$refs.product as any).setShow(true);
+    })
+  }
+  setBillValue(data:any){
+    this.billValue = data;
+  }
+  giftHandle(){
+    let tlist=(this.$refs.table as any).getValue();
+    if(tlist.length == 0){
+      this.$message('请选择赠品!')
+      return
+    }
+    let parames:any={};
+    parames.idList = this.billValue;
+    parames.giftList=[];
+    for(const item of tlist){
+      parames.giftList.push({
+        itemId:item.itemId,
+        qty:item.qty
+      })
+    }
+    this.load = true;
+    addGift(parames).then(() => {
+      this.load = false;
+      this.$message({
+        message:'添加成功!',
+        type:'success'
+      });
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch((err:any)=>{
+      this.load = false;
+    })
+  }
+  productHandle(){
+    let tlist=(this.$refs.table as any).getValue();
+    let data:any={};
+    if(tlist.length == 0){
+      this.$message('请选择商品!')
+      return
+    }
+    data.id = this.billValue;
+    data.items=[];
+    data.isPay = this.isPay;
+    for(const item of tlist){
+      data.items.push({
+        itemId:item.itemId,
+        qty:Number(item.qty),
+        price:Number(item.price)
+      })
+    }
+    this.load = true
+    addItem(data).then(()=>{
+      this.load = false;
+      this.$message({
+        message:'添加成功!',
+        type:'success'
+      });
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  btn(){
+    if(this.isGift){
+      this.giftHandle()
+    }else{
+      this.productHandle()
+    }
+  }
+  confirmProduct(data:Array<any>){
+    let nowData = (this.$refs.table as any).getValue();
+    let names='';
+    if(data.length > 0){
+      for(const item of data){
+        let t = true;
+        for(const t_item of nowData){
+          if(item.id == t_item.itemId){
+            if(!names){
+              names = item.skuTitle
+            }else{
+              names = names + ',' + item.skuTitle
+            }
+            t = false;
+            break;
+          }
+        }
+        if(t){
+          let obj:any={};
+          obj.name = item.skuTitle; //商品名称
+          obj.itemId = item.id;
+          obj.qty = 1;
+          obj.price = this.isGift ? 0 : item.price;  //单价
+          
+          obj.stock = item.stock;
+          nowData.push(obj)
+        }
+      }
+      (this.$refs.table as any).setValue(nowData);
+      if(names){
+        let name = this.isGift ? '赠品' : '商品';
+        this.$alert(name+'“'+names+'”已存在!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {}
+        });
+      }
+    }
+  }
+  deletaProduct(item:any){
+    let data=(this.$refs.table as any).getValue();
+    let i = -1;
+    for(const v of data){
+      i++;
+      if(v.itemId == item.itemId){
+        break
+      }
+    }
+    data.splice(i,1);
+    (this.$refs.table as any).setValue(data);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.add-ptool{
+  padding-bottom: 8px;
+}
+</style>

+ 65 - 0
src/views/oms/B2COrder/components/addQuest.vue

@@ -0,0 +1,65 @@
+<template>
+  <vxe-modal v-model="value" id="addQuest" width="400" v-loading="load" @show="show" @hide="hide" height="200" show-footer title="新增异常类型">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { save } from '@/api/question'
+@Component({components:{}})
+export default class AddQuestModel extends Vue {
+  value = false;
+  load = false;
+  config:any={
+    attr:{
+      rules:{
+        type: [
+          { required: true, message: '请输入类型', trigger: 'blur' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'类型',
+        prop:'type',
+        labelWidth:'80px',
+        component:'by-input'
+      }]
+    ]
+  }
+  show(){
+    
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      this.load = true
+      save(data).then(()=>{
+        this.load = false;
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 506 - 0
src/views/oms/B2COrder/components/batchbyOneModal.vue

@@ -0,0 +1,506 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    :title="data.length <= 1 ? '订单发货' : '订单发货(批量逐一发货)'"
+    :visible.sync="drawer"
+    @close="close"
+    :direction="direction"
+    size="50%">
+    <div class="content">
+      <div class="order-top" v-if="data.length > 1">
+        <el-pagination
+          background
+          :page-size="1"
+          :current-page="currentOrder + 1"
+          layout="prev, pager, next"
+          @current-change="currentChange"
+          :total="data.length">
+        </el-pagination>
+      </div>
+      <deliveryGoodsInfo :hideOrderCode="true" @editState="editState" @editResult="editResult" ref="info" />
+      <deliveryPrice :data="priceObj[data[currentOrder].omsOrderIds]" ref="price" v-if="data[currentOrder] && priceObj[data[currentOrder].omsOrderIds]" 
+      @prichChange="prichChange" :currentValue="currentPrice[data[currentOrder].omsOrderIds]" />
+    </div>
+    <div class="space"></div>
+    <div class="deli-footer">
+      <div class="d-left">
+        <div class="estimate-total">
+          订单小计<span class="total">¥{{data[currentOrder] && currentPrice[data[currentOrder].omsOrderIds]?currentPrice[data[currentOrder].omsOrderIds].estimateFreight:'0.00'}}</span> 
+          <!-- <span class="detail">明细></span> -->
+        </div>
+        <!-- <div class="estimate-total">
+          预计总价<span class="total">¥48.00</span>
+        </div> -->
+        <div class="agreement">
+          <el-checkbox v-model="checked">已读并同意《XXX电子运单协议》</el-checkbox>
+        </div>
+      </div>
+      <div class="btn-box">
+        <div class="send-btn" @click="nextBtn" :class="{'stopBtn':stopHandle}" v-if="data.length > 1">确认,下一单</div>
+        <div class="send-btn" @click="btn" :class="{'stopBtn':stopHandle}">一键发货</div>
+      </div>
+      
+    </div>
+  </el-drawer>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import DeliveryGoodsInfo from "./deliveryGoodsInfo.vue";
+import DeliveryPrice from "./deliveryPrice.vue";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import { queryPricePackage,addmultiple,getInventoryByStoreHouseIdAndSkuids } from  '@/api/delivery'
+import Format from '@/benyun/utils/dateFormat'
+
+@Component({components:{DeliveryGoodsInfo,DeliveryPrice}})
+export default class BatchbyOneModal extends Vue {
+  drawer=false;
+  direction='rtl'
+  checked=false;
+  data:Array<any>=[];
+  currentOrder=0;
+  isSuccess=false;
+  stopHandle=false;
+  load = false;
+  priceObj:any={};
+  currentPrice:any={};
+  setShow(v:boolean){
+    this.drawer=v;
+    this.priceObj={};
+    this.currentPrice={};
+    this.isSuccess = false;
+    this.stopHandle = false;
+    this.currentOrder = 0;
+    this.checked = false;
+  }
+  close(){
+    if(this.isSuccess){
+      this.$emit('handleSuccess');
+    }
+  }
+  editResult(v:any){
+    this.data[this.currentOrder] = v;
+    // this.getStoreCount(v);
+    this.getPriceInfo(v);
+  }
+  prichChange(index:number){
+    this.currentPrice[this.data[this.currentOrder].omsOrderIds] = this.priceObj[this.data[this.currentOrder].omsOrderIds][index];
+    this.$forceUpdate();
+  }
+  currentChange(v:number){
+    this.currentOrder = v-1;
+    this.$forceUpdate();
+    this.$nextTick(()=>{
+      this.setInfo();
+    })
+  }
+  setInfo(){
+    (this.$refs.info as any).setValue(this.data[this.currentOrder]);
+  }
+  setValue(data:Array<any>){
+    this.data = [];
+    if(data && data.length > 0){
+      for(const item of data){
+        const requestId =  new Date().getTime() + this.getUuid()
+        let obj:any={
+          tmsTransportMethod:'零担',
+          // tmsBusinessMan: (this as any).$store.getters.userInfo.userName,
+          // tmsBusinessPhone: (this as any).$store.getters.userInfo.phonenumber,
+          requestId:requestId,
+          omsOrderIds:item.id,
+          tmsUnloadingProvince:item.receiverProvince,
+          tmsUnloadingProvinceNo:item.receiverProvinceCode,
+          tmsUnloadingCity:item.receiverCity,
+          tmsUnloadingCityNo:item.receiverCityCode,
+          tmsUnloadingRegion:item.receiverDistrict,
+          tmsUnloadingRegionNo:item.receiverDistrictCode,
+          tmsUnloadingStreet:item.receiverTown,
+          tmsUnloadingStreetNo:item.receiverTownCode,
+          tmsUnloadingAddress:item.receiverAddress,
+          tmsUnloadingConsignor:item.receiverName,
+          tmsUnloadingContacts:item.receiverMobile
+        };
+
+        obj.subItem=[];
+        if(item.items && item.items.length > 0){
+          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))
+            }
+            
+            obj.subItem.push({
+              requestId:requestId,
+              omsOrderId:item.id,
+              omsOrderItemId:i.itemId,
+              // omsOrderItemSkuId:i.itemId,
+              tmsGoodsModel:i.styleId,
+              tmsGoodsCode:i.skuId,
+              tmsQuantity:i.qty,
+              tmsGoodsTotalPrice:total,
+              name:i.name,
+              price:i.price,
+              weight:i.weight
+            })
+          }
+        }
+        this.data.push(obj)
+      }
+    }else{
+      this.data = []
+    }
+    this.$nextTick(()=>{
+      (this.$refs.info as any).setValue(this.data[this.currentOrder]);
+      this.drawer = false;
+      (this.$refs.info as any).showModal = true;
+    })
+  }
+  getUuid(){
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  btn(){
+    this.noSentOrder();
+    if(!this.data[this.currentOrder]){
+      this.$message('没有需要发货的订单!')
+      return
+    }
+    // if(this.stopHandle){
+    //   this.$message('库存不足!')
+    //   return
+    // }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    if(!this.data[this.currentOrder].tmsShipmentConsignor || !this.data[this.currentOrder].tmsUnloadingAddress || !this.data[this.currentOrder].tmsUnloadingConsignor){
+      this.$message("订单信息不完善,请前往编辑!");
+      return
+    }
+    if(!this.currentPrice[this.data[this.currentOrder].omsOrderIds]){
+      this.$message("请选择价格!");
+      return
+    }
+    if(this.data.length > 1){
+      let ids='';
+      for(const item of this.data){
+        if(!item.tmsShipmentConsignor || !item.tmsUnloadingAddress || !item.tmsUnloadingConsignor){
+          ids = ids ? ids + ',' + item.omsOrderIds : String(item.omsOrderIds)
+        }
+      }
+      if(ids){
+        this.$confirm('订单'+ids + '未编辑,是否以第一条订单为基准', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.setOnEditOrderInfo(ids);
+          this.sendGoods(this.data[this.currentOrder]);
+
+        }).catch(() => {});
+      }else{
+        this.sendGoods(this.data[this.currentOrder]);
+      }
+    }else{
+      if(this.data[0].isSuccess){
+        this.$message('订单:'+this.data[0].omsOrderIds+'已执行过发货操作!');
+        return
+      }
+      this.sendGoods(this.data[0]);
+    }
+  }
+  nextBtn(){
+    if(this.currentOrder >= this.data.length){
+      this.$message('已经是最后一单!')
+      return
+    }
+    if(this.stopHandle){
+      this.$message('库存不足!')
+      return
+    }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    const _value = this.data[this.currentOrder];
+    if(!_value.tmsBusinessMan || !_value.tmsBusinessPhone || !_value.tmsShipmentConsignor || !_value.tmsShipmentContacts || !_value.tmsUnloadingConsignor || !_value.tmsUnloadingContacts || !_value.tmsUnloadingProvince || !_value.tmsUnloadingAddress || !_value.storeHouseId){
+      this.$message("请编辑订单信息");
+      return
+    }
+    if(!this.currentPrice[_value.omsOrderIds]){
+      this.$message('请选择价格!')
+      return
+    }
+    if(_value.isSuccess){
+      this.$message('订单:'+_value.omsOrderIds+'已执行过发货操作!');
+      return
+    }
+    this.sendGoods(_value,true);
+  }
+  //查库存
+  getStoreCount(item:any,callback?:Function){
+    if(!item){
+      return
+    }
+    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
+      }
+      if(callback) callback(item,this.sendGoods)
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //发货
+  sendGoods(item:any,isNext?:boolean){
+    if(!item){
+      this.$message('订单不存在!')
+      return
+    }
+    
+    let params:any=(this as any).$lodash.cloneDeep(item);
+    if(this.priceObj[item.omsOrderIds]){
+      try{
+        params.pricePlan = JSON.stringify(this.priceObj[item.omsOrderIds])
+      }catch(e){}
+    }
+    if(this.currentPrice[item.omsOrderIds]){
+      params.priceId = this.currentPrice[item.omsOrderIds].id;
+    }
+    params.omsOrderIds = [item.omsOrderIds];
+    params.tmsMaterials=[];
+    if(item.subItem){
+      for(const i of item.subItem){
+        params.tmsMaterials.push({
+          storeHouseId:item.storeHouseId,
+          materialSkuId:i.omsOrderItemId
+        })
+      }
+    }
+    delete params.subItem;
+    this.load = true;
+    addmultiple(params).then((res:any) => {
+      this.load = false;
+      if(res.code == 200){
+        this.isSuccess = true;
+        this.$message({
+          message:'订单:'+item.omsOrderIds+'发货成功!',
+          type:'success'
+        })
+        for(let it of this.data){
+          if(it.omsOrderIds == item.omsOrderIds){
+            it.isSuccess=true;
+            break;
+          }
+        }
+
+        if(!isNext){
+          //寻找未发货的订单
+          this.noSentOrder();
+          let _item:any = this.data[this.currentOrder];
+          //是否是最后一单
+            if(this.currentOrder >= this.data.length){
+              this.drawer = false;
+            }else{
+              if(this.currentPrice[_item.omsOrderIds]){
+                this.sendGoods(_item);
+              }
+              else{
+                this.getPriceInfo(_item,this.sendGoods)
+                // this.getStoreCount(_item,this.getPriceInfo);
+              }
+            }
+        }else{
+          if(this.currentOrder < this.data.length - 1) {
+            this.currentOrder ++;
+            this.setInfo();
+          }
+        }
+        this.$forceUpdate();
+      }
+    }).catch(() => {
+      this.load = false;
+    })
+  }
+  //寻找未发货订单
+  noSentOrder(){
+    this.currentOrder = this.data.length;
+    for(let i = 0; i < this.data.length; i++){
+      if(!this.data[i].isSuccess){
+        this.currentOrder = i;
+        break
+      }
+    }
+    // if(this.data[this.currentOrder]){
+      this.setInfo();
+    // } 
+  }
+  setOnEditOrderInfo(ids:string){
+    let _value = this.data[0]
+    for(const item of this.data){
+      if(ids.indexOf(item.omsOrderIds) > -1 && !item.isSuccess){
+        item.orderType = _value.orderType;
+        item.storeHouseId = _value.storeHouseId;
+        item.tmsArrivalDate = _value.tmsArrivalDate;
+        item.tmsDeliveryDate =_value.tmsDeliveryDate;
+        item.tmsTransportMethod = _value.tmsTransportMethod;
+        item.tmsBusinessMan = _value.tmsBusinessMan;
+        item.tmsBusinessPhone = _value.tmsBusinessPhone;
+        item.tmsShipmentConsignor = _value.tmsShipmentConsignor;
+        item.tmsShipmentContacts = _value.tmsShipmentContacts;
+        item.tmsShipmentProvince = _value.tmsShipmentProvince;
+        item.tmsShipmentProvinceNo = _value.tmsShipmentProvinceNo;
+        item.tmsShipmentCity = _value.tmsShipmentCity;
+        item.tmsShipmentCityNo = _value.tmsShipmentCityNo;
+        item.tmsShipmentRegion = _value.tmsShipmentRegion;
+        item.tmsShipmentRegionNo = _value.tmsShipmentRegionNo;
+        item.tmsShipmentStreetNo = _value.tmsShipmentStreetNo;
+        item.tmsShipmentStreet = _value.tmsShipmentStreet;
+        item.tmsShipmentAddress = _value.tmsShipmentAddress;
+        item.tmsUnloadingConsignor = _value.tmsUnloadingConsignor;
+        item.tmsUnloadingContacts = _value.tmsUnloadingContacts;
+        item.tmsUnloadingProvince = _value.tmsUnloadingProvince;
+        item.tmsUnloadingProvinceNo = _value.tmsUnloadingProvinceNo;
+        item.tmsUnloadingCity = _value.tmsUnloadingCity;
+        item.tmsUnloadingCityNo = _value.tmsUnloadingCityNo;
+        item.tmsUnloadingRegion = _value.tmsUnloadingRegion;
+        item.tmsUnloadingRegionNo = _value.tmsUnloadingRegionNo;
+        item.tmsUnloadingStreetNo = _value.tmsUnloadingStreetNo;
+        item.tmsUnloadingStreet = _value.tmsUnloadingStreet;
+        item.tmsUnloadingAddress = _value.tmsUnloadingAddress;
+      }
+    }
+  }
+  //获取价格
+  getPriceInfo(data:any,callback?:Function){
+    let params:any={};
+    params.startStoreHouseId = data.storeHouseId;
+    // params.startAddressCode = data.tmsShipmentCityNo + '00000';
+    params.endAddressCode = data.tmsUnloadingCityNo + '00000';
+    params.omsIds=[this.data[0].omsOrderIds];
+    params.planType = data.tmsTransportMethod;
+    this.load = true;
+    queryPricePackage(params).then((res:any) => {
+      this.load=false;
+      let current=null;
+      for(let item of res.data[0].data){
+        let d = new Date().getTime() + item.duration*60*60*1000;
+        item.endTime=Format(new Date(d),'MM月dd日 HH:mm');
+        if(!current) current = item;
+        if(Number(current.estimateFreight) > Number(item.estimateFreight)){
+          current = item
+        }
+      }
+      this.priceObj[data.omsOrderIds] = res.data[0].data;
+      this.currentPrice[data.omsOrderIds] = current;
+      this.$forceUpdate();
+      if(callback){
+        callback(data)
+      }
+    }).catch((err:any)=>{
+      this.load = false;
+    })
+  }
+  editState(v:boolean){
+    this.drawer = v
+  }
+}
+</script>
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .order-top{
+    padding-bottom: 16px;
+    display: flex;
+    justify-content: center;
+  }
+}
+.deli-footer{
+  height: 80px;
+  width: 100%;
+  box-shadow: 0 -5px 10px #EEE;
+  padding: 0 16px 8px;
+  box-sizing: border-box;
+  display: flex;
+  justify-content: space-between;
+  align-items:flex-end;
+  position: absolute;
+  background-color: #FFF;
+  left: 0;
+  bottom: 0;
+  z-index: 10;
+  .d-left{
+    width: 50%;
+    .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;
+    margin-left: 16px;
+    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;
+  }
+  .stopBtn{
+    opacity: 0.7;
+  }
+  .btn-box{
+    width: 50%;
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+  }
+}
+.space{
+  height: 80px;
+  width: 100%;
+  margin-top: 16px;
+}
+</style>

+ 188 - 0
src/views/oms/B2COrder/components/buyerInfoModal.vue

@@ -0,0 +1,188 @@
+<template>
+  <vxe-modal v-model="value" id="buyerInfoModal" v-loading="load" :width="width?width+'px':'60%'" @show="show" :height="height?height+'px':'80%'" min-width="500" min-height="400" show-zoom resize transfer show-footer  :zIndex="zIndex">
+    <template #title>
+      <span>{{title?title:'选择买家'}}</span>
+    </template>
+    <template #default>
+      <module-view :propConfig="config" ref="view" @pagination="getList"  @search="getList" @onRefresh="getList" @resert="getList" />
+    </template>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="confirm">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class BuyerInfoModal extends Vue {
+  value=false
+  data:Array<any>=[]
+  time:any;
+  timeNum = 0;
+  load=false;
+
+  @Prop()
+  title?:string
+
+  @Prop()
+  width?:number
+
+  @Prop()
+  height?:number
+
+  @Prop()
+  mulit?:boolean
+	
+	@Prop()
+	zIndex?:number
+
+  config:any={
+    attr:{
+      calculateH:true
+    },
+    search:{
+      attr:{
+        size:'mini',
+        
+      },
+      columns:[
+        [{
+          labelWidth:'120px',
+          span:10,
+          label:'名称',
+          prop:'name',
+          component:'by-input',
+          compConfig:{
+            attr:{
+              clearable:true,
+              placeholder:'请输入名称'
+            }
+          }
+        },{
+          labelWidth:'120px',
+          span:10,
+          label:'负责人',
+          prop:'contacts',
+          component:'by-input',
+          compConfig:{
+            attr:{
+              clearable:true,
+              placeholder:'请输入负责人'
+            }
+          }
+        }]
+      ]
+    },
+    tool:{
+      tools:{
+        search:true,
+        refresh:true
+      }
+    },
+    table:{
+      attr:{
+        size:'mini',
+        seq:true,
+        radio: true,
+        align:'center',
+        triggerRowCheck:'row',
+        pageSize:10
+      },
+      columns:[{
+        title:'名称',
+        field:'name'
+      },{
+        title:'负责人',
+        field:'contacts'
+      },{
+        title:'手机号',
+        field:'telephone'
+      },{
+        title: '固定电话',
+        field: 'phonenum'
+      }]
+    },
+  }
+
+  setShow(v:boolean){
+    this.value = v;
+  }
+
+  created(){
+    if(this.mulit){
+      this.config.table.attr.checkbox = true
+    }else{
+      this.config.table.attr.radio = true
+    }
+  }
+
+  //确定
+  confirm(){
+    let data:Array<any>=this.getSelectdata();
+    if(data.length == 0){
+      this.$message('请选择买家!')
+      return
+    }
+    this.$emit('confirm',data);
+    this.value = false;
+  }
+  //获取已选中表格数据
+  getSelectdata(){
+    let data:Array<any>=[];
+    if(this.$refs.view){
+      data = (this.$refs.view as any).getSelectData()
+    }
+    return data;
+  }
+  //显示弹窗
+  show(){
+    if(this.data.length ==0){
+      this.getList()
+    }
+    if(this.$refs.view){
+      (this.$refs.view as any).clearCheckboxRow();
+    }
+  }
+  getList(){
+    if(!this.$refs.view){
+      if(this.timeNum > 5){
+        return
+      }
+      setTimeout(()=>{
+        this.getList()
+      },500) 
+      this.timeNum ++;
+      return
+    }
+    let query:any = (this.$refs.view as any).getQuery();
+    query.isLikeSearch = '1';
+    this.load = true;
+    (this as any).$request({
+      url: '/maindata/maindataMaterialDistributor/page',
+      method: 'get',
+      params:query
+    }).then((res:any) => {
+      this.load = false;
+      if(res.data.records){
+        (this.$refs.view as any).setTableValue(res.data.records);
+        this.data = res.data.records;
+        let page={
+          pageNo: res.data.current, //当前页
+          pageSize: res.data.size, //每页条数
+          total: res.data.total //总条数
+        };
+        (this.$refs.view as any).setPage(page)
+      }
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 105 - 0
src/views/oms/B2COrder/components/cancelOrderModel.vue

@@ -0,0 +1,105 @@
+<template>
+  <vxe-modal v-model="value" id="purchaseModel" width="400" height="300" show-zoom resize transfer show-footer v-loading="load">
+    <div class="info">
+      <div class="label">类型:</div>
+      <el-select v-model="type" placeholder="请选择" size="mini" class="cancel-type" clearable>
+        <el-option
+          v-for="item in options"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+    </div>
+    <div class="info">
+      <div class="label">原因:</div>
+      <el-input v-model="reason" class="cancel-type" placeholder="请输入内容" type="textarea" :rows="3"></el-input>
+    </div>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { cancelOrder } from '@/api/omsOrder'
+@Component
+export default class CancelOrderModel extends Vue {
+  value = false;
+  load = false;
+  reason='';
+  ids:Array<any>=[]
+  options:Array<any>= [{
+    value: '商品缺货',
+    label: '商品缺货'
+  },{
+    value: '客户申请取消',
+    label: '客户申请取消'
+  },{
+    value: '重复订单',
+    label: '重复订单'
+  },{
+    value: '其他',
+    label: '其他'
+  }];
+  type= ''
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setData(d:any){
+    this.ids = d;
+  }
+  btn(){
+    if(!this.type){
+      this.$message('请选择取消类型!');
+      return
+    }
+    this.$confirm('取消订单后将无法恢复, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+      cancelOrder({
+        idList:this.ids,
+        cancelType:this.type,
+        remark:this.reason
+      }).then(()=>{
+        this.load = false;
+        this.$message({
+          message:'订单取消成功!',
+          type:'success'
+        });
+        this.value = false;
+        this.type='';
+        this.reason = '';
+        this.$emit('handleSuccess');
+      }).catch((err:any)=>{
+        this.load = false;
+      })
+    }).catch(() => {});
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.info{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 16px;
+  .label{
+    width: 80px;
+    text-align: right;
+    padding-right: 8px;
+    box-sizing: border-box;
+  }
+  .cancel-type{
+    width: calc(100% - 100px);
+  }
+}
+</style>

+ 353 - 0
src/views/oms/B2COrder/components/carpoolModal.vue

@@ -0,0 +1,353 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    :title="'订单发货(共'+data.length+'单)'"
+    :visible.sync="drawer"
+    :direction="direction"
+    size="50%">
+    <div class="content">
+      <div class="order-cont" v-if="data && data[0]">
+        <div class="cont-left">
+          <div class="order-code">订单号:{{data[0].id}}</div>
+          <div class="order-other">
+            <div class="receive-name">姓名:{{data[0].receiverName}}</div>
+            <div class="address">目的地:<span>{{data[0].receiverProvince+'-'+data[0].receiverCity}}</span></div>
+            <!-- <div class="time">预计送达:8月6日 12:00前</div> -->
+          </div>
+        </div>
+        <!-- <i class="el-icon-arrow-right"></i> -->
+      </div>
+      <deliveryGoodsInfo :hideOrderCode="true" :sendState="true" @editState="editState" @editResult="editResult" ref="info" />
+      <deliveryPrice v-if="priceData && priceData.length > 0" :data="priceData" :currentValue="currentPrice" @prichChange="prichChange" />
+    </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> 
+          <!-- <span class="detail">明细></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 DeliveryGoodsInfo from "./deliveryGoodsInfo.vue";
+import DeliveryPrice from "./deliveryPrice.vue";
+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 {
+  drawer=false;
+  direction='rtl'
+  checked=false;
+  stopHandle=false;
+  load=false;
+  onAct='1';
+  data:Array<any>=[];
+  priceData:Array<any>=[]
+  currentPrice:any={}
+  value:any={};
+  setShow(v:boolean){
+    this.drawer=v;
+    this.stopHandle = false;
+    this.priceData=[];
+    this.currentPrice={}
+  }
+  setValue(data:Array<any>){
+    this.data =data;
+    this.value={};
+    this.value.tmsTransportMethod = '整车';
+    // this.value.tmsBusinessMan = (this as any).$store.getters.userInfo.userName;
+    // this.value.tmsBusinessPhone = (this as any).$store.getters.userInfo.phonenumber;
+    this.value.subItem=[];
+    this.value.tmsUnloadingProvince=data[0].receiverProvince;
+    this.value.tmsUnloadingProvinceNo=data[0].receiverProvinceCode;
+    this.value.tmsUnloadingCity=data[0].receiverCity;
+    this.value.tmsUnloadingCityNo=data[0].receiverCityCode;
+    this.value.tmsUnloadingRegion=data[0].receiverDistrict;
+    this.value.tmsUnloadingRegionNo=data[0].receiverDistrictCode;
+    this.value.tmsUnloadingStreet=data[0].receiverTown;
+    this.value.tmsUnloadingStreetNo=data[0].receiverTownCode;
+    this.value.tmsUnloadingAddress=data[0].receiverAddress;
+    this.value.tmsUnloadingConsignor=data[0].receiverName;
+    this.value.tmsUnloadingContacts=data[0].receiverMobile;
+    this.checked = false;
+    const requestId =  new Date().getTime() + this.getUuid();
+    this.value.requestId = requestId;
+    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))
+          }
+          this.value.subItem.push({
+            requestId:requestId,
+            omsOrderId:item.id,
+            omsOrderItemId:i.itemId,
+            tmsGoodsModel:i.styleId,
+            tmsGoodsCode:i.skuId,
+            // omsOrderItemSkuId:i.itemId,
+            tmsQuantity:Number(i.qty)?Number(i.qty):0,
+            tmsGoodsTotalPrice:total,
+            name:i.name,
+            price:i.price,
+            weight:i.weight
+          })
+        }
+      }
+    }
+    this.$nextTick(()=>{
+      (this.$refs.info as any).setValue(this.value);
+      this.drawer = false;
+      (this.$refs.info as any).showModal = true;
+    })
+  }
+  getUuid(){
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  prichChange(index:number){
+    this.currentPrice = this.priceData[index];
+    this.$forceUpdate();
+  }
+  getPriceInfo(data:any){
+    let params:any={};
+    params.startStoreHouseId = data.storeHouseId;
+    // params.startAddressCode = data.tmsShipmentCityNo + '00000';
+    params.endAddressCode = data.tmsUnloadingCityNo + '00000';
+    params.planType = data.tmsTransportMethod;
+    params.omsIds=[];
+    for(const item of this.data){
+      params.omsIds.push(item.id);
+    }
+    this.load = true;
+    getMultipleToOnePrice(params).then((res:any) => {
+      this.load=false;
+      let current=null;
+      for(let item of res.data[0].data){
+        let d = new Date().getTime() + item.duration*60*60*1000;
+        item.endTime=Format(new Date(d),'MM月dd日 HH:mm');
+        if(!current) current = item;
+        if(Number(current.estimateFreight) > Number(item.estimateFreight)){
+          current = item
+        }
+      }
+      this.priceData = res.data[0].data;
+      this.currentPrice = current;
+    }).catch((err:any)=>{
+      this.load = false;
+    })
+  }
+  btn(){
+    // if(this.stopHandle){
+    //   this.$message('库存不足!')
+    //   return
+    // }
+    if(!this.checked){
+      this.$message('请阅读并同意运单协议!')
+      return
+    }
+    if(!this.value.tmsBusinessMan || !this.value.tmsBusinessPhone || !this.value.tmsShipmentConsignor || !this.value.tmsShipmentContacts || !this.value.tmsUnloadingConsignor || !this.value.tmsUnloadingContacts || !this.value.tmsUnloadingProvince || !this.value.tmsUnloadingAddress || !this.value.storeHouseId){
+      this.$message("请编辑订单信息");
+      return
+    }
+    let params:any=(this as any).$lodash.cloneDeep(this.value);
+    if(this.priceData){
+      try{
+        params.pricePlan = JSON.stringify(this.priceData)
+      }catch(e){}
+    }
+    if(this.currentPrice){
+      params.priceId = this.currentPrice.id;
+    }
+    params.omsOrderIds=[]
+    for(const item of this.data){
+      params.omsOrderIds.push(item.id);
+    }
+    params.tmsMaterials=[];
+    if(this.value.subItem){
+      for(const item of this.value.subItem){
+        params.tmsMaterials.push({
+          storeHouseId:this.value.storeHouseId,
+          materialSkuId:item.omsOrderItemId,
+          qty: item.tmsQuantity
+        })
+      }
+    }
+    delete params.subItem;
+    this.load = true;
+    addMultipleToOne(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;
+    })
+  }
+  //查库存
+  getStoreCount(item:any,callback?:Function){
+    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;
+    })
+  }
+  editResult(v:any){
+    this.value = v;
+    this.getPriceInfo(v);
+    // this.getStoreCount(v);
+  }
+  editState(v:boolean){
+    this.drawer = v
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .order-cont{
+    height: 60px;
+    width: 100%;
+    box-sizing: border-box;
+    border:solid 1px #BBB;
+    border-radius: 5px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 16px;
+    margin-bottom: 16px;
+    cursor: pointer;
+    .cont-left{
+      // width: calc(100% - 40px);
+      width: 100%;
+      .order-code{
+        width: 100%;
+        font-size: 14px;
+        padding: 6px 0 4px;
+      }
+      .order-other{
+        width: 100%;
+        display: flex;
+        font-size: 14px;
+        .receive-name{
+          width: 150px;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+        .address{
+          width: calc(100% - 150px);
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          span{
+            color: #F00;
+          }
+        }
+        // .time{
+        //   width: calc(100% - 120px - 150px);
+        // }
+      }
+    }
+  }
+  .order-cont:hover,.onAct{
+    background-color: rgba(160,205,255,0.22);
+  }
+}
+.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>

+ 340 - 0
src/views/oms/B2COrder/components/deliveryDetail.vue

@@ -0,0 +1,340 @@
+<template>
+  <el-drawer
+    append-to-body
+    title="发货详情"
+    v-loading="load"
+    :visible.sync="drawer"
+    @close="close"
+    :direction="direction"
+    size="50%">
+    <div class="content" v-if="value.orderType == 'B2B'">
+      <deliveryGoodsInfo :sendState="true" ref="info" :readOnly="true" />
+      <div class="send-box">
+        <div class="pri-title">
+          <!-- <div class="title-item">
+            预计送达和预计费用<span>明细></span>
+          </div> -->
+          <div class="title-item">
+            实际送达和实际费用
+          </div>
+        </div>
+        
+        <div class="send-type">
+          <el-popover
+            v-for="(item,index) of priceData" :key="index"
+            placement="top-start"
+            width="200"
+            trigger="hover">
+            <div class="price-info">
+              <div class="price-title">预估费用明细:</div>
+              <div class="price-row freight">
+                <span class="p-label">运费:</span>
+                <span class="p-value">¥{{item.estimateFreight}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">单价:</span>
+                <span class="p-value">¥{{item.unitprice}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">重量:</span>
+                <span class="p-value">{{item.weight}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">体积:</span>
+                <span class="p-value">{{item.volume}}</span>
+              </div>
+              <div class="price-row">
+                <span class="p-label">单位:</span>
+                <span class="p-value">{{item.unit}}</span>
+              </div>
+            </div>
+            <div slot="reference" class="send-item" :title="item.ruleName" :class="{'ont':value.priceId == item.id}" >
+              <div class="label-name">{{item.ruleName}}</div>
+              <div class="send-info">
+                <div class="s-time">{{item.endTime}}前</div>
+                <div class="send-price">¥{{item.estimateFreight}}</div>
+              </div>
+            </div>
+          </el-popover>
+        </div>
+      </div>
+      
+      <div class="space"></div>
+      <div class="deli-footer">
+        <div class="send-btn" @click="showLogistics">物流信息</div>
+        <div class="send-btn" @click="cancelDelivery">取消发货</div>
+      </div>
+    </div>
+    <div class="content" v-if="value.orderType == 'B2C'">
+      <div class="send-box">
+        <div class="s-row">
+          <div class="s-col width50">业务员:{{ value.tmsBusinessMan }}</div>
+          <div class="s-col width50">业务员手机:{{ value.tmsBusinessPhone }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">店铺名称:{{ value.wmsShopName }}</div>
+          <div class="s-col width50">快递单号:{{ value.wmsExpressCode }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">快递公司:{{ value.wmsLogisticsName }}</div>
+          <div class="s-col width50">快递公司编码:{{ value.wmsLogisticsCode }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">WMS销售订单号:{{ value.wmsSaleorderCode }}</div>
+          <div class="s-col width50">WMS总费用:{{ value.wmsTotalAmount }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col width50">WMS订单类型:{{ value.wmsSendType }}</div>
+          <div class="s-col width50">WMS状态:{{ getWmsState(value.wmsOrderStatus) }}</div>
+        </div>
+        <div class="s-row">
+          <div class="s-col">WMS取消订单的备注:{{ value.wmsRemark }}</div>
+        </div>
+      </div>
+    </div>
+  </el-drawer>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import DeliveryGoodsInfo from "./deliveryGoodsInfo.vue";
+import { queryOrderByOrderId,cancleSendOrder } from  '@/api/delivery'
+@Component({components:{DeliveryGoodsInfo}})
+export default class DeliveryDetail extends Vue {
+  drawer=false;
+  direction='rtl'
+  load = false;
+  priceData:Array<any>=[];
+  value:any={};
+  wmsState='';
+  setShow(v:boolean){
+    this.drawer=v;
+  }
+  showLogistics() {
+    this.drawer = false;
+    this.$emit('showLogistics',this.value.tmsOrderNo)
+  }
+  close(){
+    this.value={}
+    this.priceData=[];
+  }
+  getWmsState(s:any){
+    let n = '';
+    switch(s){
+      case 1:
+        n = '创建';
+        break;
+      case 2:
+        n = '确认';
+        break;
+      case 3:
+        n = '完成';
+        break;
+      case 4:
+        n = '取消';
+        break;
+    }
+    return n;
+  }
+  setData(v:any){
+    if(!v) {
+      this.$message('缺少订单id');
+      return
+    }
+    this.load = true;
+    queryOrderByOrderId({
+      omsOrderId:v
+    }).then((res:any) => {
+      this.value = res.data;
+      if(res.data.subItemList){
+        this.value.subItem=[];
+        for(const item of this.value.subItemList){
+          this.value.subItem.push({
+            tmsGoodsCode:item.tmsGoodsCode,
+            name:item.tmsGoodsName,
+            tmsGoodsTotalPrice:item.tmsGoodsTotalPrice,
+            price:item.tmsGoodsPrice,
+            weight:item.tmsWeight,
+            tmsQuantity:item.tmsQuantity
+          })
+        }
+      }
+      this.load = false;
+      if(res.data.pricePlan){
+        try{
+          this.priceData = JSON.parse(res.data.pricePlan);
+        }catch(e){
+          this.priceData = [];
+          console.error('价格列表数据转换错误!')
+        }
+        
+      }
+      setTimeout(()=>{
+        if(this.$refs.info){
+          (this.$refs.info as any).setValue(this.value)
+        }
+      },1000)
+      
+    }).catch(() => {
+      this.load = false;
+    })
+  }
+  cancelDelivery(){
+    let msg = '';
+    if(this.value.shippingType == 'MORE'){
+      msg = '此操作将导致整车订单的发货被取消,是否继续?'
+    }
+    if(this.value.shippingType == 'ONE'){
+      msg = '此操作将导致该订单的发货被取消,是否继续?'
+    }
+    if(msg){
+      this.$confirm(msg, '提示', {
+        confirmButtonText: '继续',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.load = true;
+        cancleSendOrder({orderNos:[this.value.tmsOrderNo]}).then((res:any) => {
+          this.drawer = false;
+          this.load =false;
+          this.$message({
+            message:'该订单的发货已被取消!',
+            type:'success'
+          })
+          this.$emit('handleSuccess');
+        }).catch(() => {
+          this.load = false;
+        })
+      }).catch(() => {});
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.content{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 16px;
+  background-color: #FFF;
+  .send-box{
+    width: 100%;
+    box-sizing: border-box;
+    padding: 16px;
+    padding-bottom: 0;
+    margin-bottom: 16px;
+    background-color: rgba(160,205,255,0.22);
+    .pri-title{
+      width: 100%;
+      padding-bottom: 8px;
+      display: flex;
+      align-items: center;
+      .title-item{
+        width: 188px;
+        font-size: 12px;
+        span{
+          color: #1684FC;
+          padding-left: 8px;
+        }
+      }
+    }
+    .send-type{
+      width: 100%;
+      display: flex;
+      align-items: center;
+      flex-wrap:wrap;
+      .send-item{
+        width: 165px;
+        box-sizing: border-box;
+        border:solid 3px #999;
+        border-radius: 6px;
+        overflow: hidden;
+        margin-right: 32px;
+        margin-bottom: 16px;
+        // cursor: pointer;
+        .label-name{
+          background-color: #999;
+          color: #FFF;
+          font-size: 16px;
+          font-weight: 700;
+          padding: 2px 0 4px;
+          text-align: center;
+        }
+        .send-info{
+          padding: 8px 0;
+          text-align: center;
+          background-color: #FFF;
+          .s-time{
+            font-size: 14px;
+            color: #1684FC;
+          }
+          .send-price{
+            font-size: 20px;
+            padding-top: 4px;
+          }
+        }
+      }
+      .onSend{
+        border:solid 3px #1684FC;
+        .label-name{
+          background-color: #1684FC;
+        }
+      }
+      .ont{
+        border:solid 3px #FF0404;
+        .label-name{
+          background-color: #FF0404;
+        }
+      }
+    }
+    .s-row{
+      width: 100%;
+      display: flex;
+      align-items: center;
+      padding-bottom: 16px;
+      .s-col{
+        width: 100%;
+        font-size: 14px;
+      }
+      .width50{
+        width: 50%;
+      }
+    }
+    .s-row:last-child{
+      padding: 16;
+    }
+  }
+}
+.deli-footer{
+  height: 60px;
+  box-shadow: 0 -5px 10px #EEE;
+  width: 100%;
+  padding: 0 16px;
+  box-sizing: border-box;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  position: absolute;
+  background-color: #FFF;
+  left: 0;
+  bottom: 0;
+  z-index: 10;
+  .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);
+    margin-left: 16px;
+    cursor: pointer;
+  }
+}
+.space{
+  height: 60px;
+  width: 100%;
+  margin-top: 16px;
+}
+</style>

+ 677 - 0
src/views/oms/B2COrder/components/deliveryGoodsInfo.vue

@@ -0,0 +1,677 @@
+<template>
+  <div class="info">
+    <div class="edit" v-if="!readOnly">
+      <span @click="edit">编辑</span>
+    </div>
+    <div class="g-box">
+      <div class="info-row" v-if="!hideOrderCode">
+        <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 col-width">
+          <span class="label">订单类型:</span>
+          <span :title="value.orderType">{{ value.orderType }}</span>
+        </div>
+      </div> -->
+      <div class="info-row">
+        <div class="info-col">
+          <span class="label">业务员:</span>
+          <span :title="value.tmsBusinessMan">{{ value.tmsBusinessMan }}</span>
+        </div>
+        
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">业务员手机:</span>
+          <span :title="value.tmsBusinessPhone">{{ value.tmsBusinessPhone }}</span>
+        </div>
+        <div class="info-col col-width" v-if="!sendState">
+          <span class="label">发货状态:</span>
+          <span>{{ value.isSuccess ? '发货中' : '' }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">运输方式:</span>
+          <span :title="value.tmsTransportMethod">{{ value.tmsTransportMethod }}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">备注:</span>
+          <span :title="value.tmsRemark">{{ value.tmsRemark }}</span>
+        </div>
+      </div>
+    </div>
+    <div class="g-box">
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货省:</span>
+          <span :title="value.tmsShipmentProvince">{{ value.tmsShipmentProvince }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货省:</span>
+          <span :title="value.tmsUnloadingProvince">{{ value.tmsUnloadingProvince }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货市:</span>
+          <span :title="value.tmsShipmentCity">{{ value.tmsShipmentCity }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货市:</span>
+          <span :title="value.tmsUnloadingCity">{{ value.tmsUnloadingCity }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货区(县):</span>
+          <span :title="value.tmsShipmentRegion">{{ value.tmsShipmentRegion }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货区(县):</span>
+          <span :title="value.tmsUnloadingRegion">{{ value.tmsUnloadingRegion }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货街道:</span>
+          <span :title="value.tmsShipmentStreet">{{ value.tmsShipmentStreet }}</span>
+        </div> -->
+        <div class="info-col col-width">
+          <span class="label">收货街道:</span>
+          <span :title="value.tmsUnloadingStreet">{{ value.tmsUnloadingStreet }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <!-- <div class="info-col col-width">
+          <span class="label">发货地址(详情):</span>
+          <span :title="value.tmsShipmentAddress">{{ value.tmsShipmentAddress }}</span>
+        </div> -->
+        <div class="info-col">
+          <span class="label">收货地址(详情):</span>
+          <span :title="value.tmsUnloadingAddress">{{ value.tmsUnloadingAddress }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">发货人:</span>
+          <span :title="value.tmsShipmentConsignor">{{ value.tmsShipmentConsignor }}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">收货人:</span>
+          <span :title="value.tmsUnloadingConsignor">{{ value.tmsUnloadingConsignor }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">发货人联系电话:</span>
+          <span :title="value.tmsShipmentContacts">{{ value.tmsShipmentContacts }}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">收货人联系电话:</span>
+          <span :title="value.tmsUnloadingContacts">{{ value.tmsUnloadingContacts }}</span>
+        </div>
+      </div>
+      <div class="info-row">
+        <div class="info-col col-width">
+          <span class="label">期望送达时间:</span>
+          <span class="time">{{value.tmsArrivalDate}}</span>
+        </div>
+        <div class="info-col col-width">
+          <span class="label">期望提货时间:</span>
+          <span class="time">{{value.tmsDeliveryDate}}</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">重量合计(kg):</span>
+            <span class="total-num">{{totalWeight}}</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="重量(g)"></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>
+    <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" v-if="showModal" ref="form" @formChange="formChange" />
+      <template #footer>
+        <div class="btn">
+          <el-button plain size="small" @click="showModal = false">取消</el-button>
+          <el-button type="primary" size="small" @click="btn">确定</el-button>
+        </div>
+      </template>
+    </vxe-modal>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+@Component
+export default class DeliveryGoodsInfo extends Vue {
+  @Prop()
+  hideOrderCode?:Boolean
+  @Prop()
+  sendState?:Boolean
+  @Prop()
+  readOnly?:Boolean
+
+  data:Array<any>=[];
+  value:any={};
+  showModal=false;
+  totalWeight:any=0;
+  config:any={
+    attr:{
+      size:'small',
+      labelWidth:'120px',
+      rules:{
+        // orderType:[{
+        //   required: true, message: '请选择订单类型!', trigger: 'change'
+        // }],
+        tmsBusinessMan:[
+          { required: true, message: '业务员不能为空!', trigger: 'blur' },
+          { min: 0, max: 5, message: '业务员名字不能超过10个字符!', trigger: 'blur' }
+        ],
+        tmsBusinessPhone:[{
+          required: true, message: '业务员手机不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur'
+        }],
+        tmsShipmentConsignor:[{
+          required: true, message: '发货人不能为空!', trigger: 'blur'
+        }],
+        tmsShipmentContacts:[{
+          required: true, message: '发货人电话不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }],
+        // tmsShipmentProvince:[{
+        //   required: true, message: '请选择发货地址!', trigger: 'change'
+        // }],
+        // tmsShipmentAddress:[{
+        //   required: true, message: '发货地址不能为空!', trigger: 'blur'
+        // }],
+        tmsUnloadingConsignor:[{
+          required: true, message: '收货人不能为空!', trigger: 'blur'
+        }],
+        tmsUnloadingContacts:[{
+          required: true, message: '收货人电话不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }],
+        tmsUnloadingProvince:[{
+          required: true, message: '请选择收货地址!', trigger: 'change'
+        }],
+        tmsUnloadingAddress:[{
+          required: true, message: '收货地址不能为空!', trigger: 'blur'
+        }],
+        storeHouseId:[{
+          required: true, message: '请选择仓库!', trigger: 'change'
+        }],
+        tmsArrivalDate:[{
+          required: true, message: '期望送达时间不能为空!', trigger: 'blur'
+        }],
+        tmsDeliveryDate:[{
+          required: true, message: '期望提货时间不能为空!', trigger: 'blur'
+        }],
+        // tmsTransportMethod: [{
+        //   required: true, message: '运输方式不能为空!', trigger: 'change'
+        // }],
+        wmsSendType: [{
+          required: true, message: '出库方式不能为空!', trigger: 'change'
+        }]
+      }
+    },
+    columns:[
+      // [
+      //   {
+      //   label:'订单类型',
+      //   prop:'orderType',
+      //   component:'by-select',
+      //   compConfig:{
+      //     attr:{
+      //       data: [{
+      //         label:'B2C',
+      //         value:'B2C'
+      //       },{
+      //         label:'B2B',
+      //         value:'B2B'
+      //       }],
+      //       clearable:true
+      //     }
+      //   }
+      // }
+      // ],
+      [{
+        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,
+            defaultIndex:0,
+            retConfig:{
+              tmsShipmentProvince: 'province',
+              tmsShipmentProvinceNo:'provinceCode',
+              tmsShipmentCity: 'city',
+              tmsShipmentCityNo: 'cityCode',
+              tmsShipmentRegion: 'region',
+              tmsShipmentRegionNo: 'regionCode',
+              tmsShipmentStreetNo: 'streetCode',
+              tmsShipmentStreet: 'street',
+              tmsShipmentAddress:'address',
+              storeHouseId: 'id'
+            }
+          }
+        }
+      },{
+        span:12,
+        label:'出库方式',
+        prop:'wmsSendType',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            // clearable:true,
+            data: [
+              // {
+              //   label:'越库出库',
+              //   value:'YKCK'
+              // },
+              // {
+              //   label:'B2B出库',
+              //   value:'B2BCK'
+              // },
+              {
+                label:'B2C出库',
+                value:'B2CCK'
+              }
+            ]
+          }
+        }
+      }
+      // ,{
+      //   label:'运输方式',
+      //   prop:'tmsTransportMethod',
+      //   component:'by-select',
+      //   compConfig:{
+      //     attr:{
+      //       clearable:true,
+      //       data: [{
+      //         label:'整车',
+      //         value:'整车'
+      //       },{
+      //         label:'零担',
+      //         value:'零担'
+      //       },{
+      //         label:'短驳',
+      //         value:'短驳'
+      //       }]
+      //     }
+      //   }
+      // }
+      ],
+      [{
+        label:'发货人',
+        prop:'tmsShipmentConsignor',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        label:'发货人电话',
+        prop:'tmsShipmentContacts',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      // [{
+      //   labelWidth:'120px',
+      //   label:'发货地址选择',
+      //   prop:'tmsShipmentProvince',
+      //   component:'by-area',
+      //   compConfig:{
+      //     attr:{
+      //       province:'tmsShipmentProvince', //省
+      //       provinceCode:'tmsShipmentProvinceNo', //省编码
+      //       city:'tmsShipmentCity',   //市
+      //       cityCode:'tmsShipmentCityNo',  //市编码
+      //       county:'tmsShipmentRegion',  //县/区
+      //       countyCode:'tmsShipmentRegionNo',   //县/区编码
+      //       townCode:'tmsShipmentStreetNo',
+      //       town:'tmsShipmentStreet',
+      //       broadcastConfig:{
+      //         name: 'warehouseChange',
+      //         // dataHandle: (data:any) => {
+      //         //   let v = (this as any).$lodash.cloneDeep(data)
+      //         //   delete v.storeHouseId
+      //         //   return v
+      //         // }
+      //       }
+      //     }
+      //   }
+      // }],
+      // [{
+      //   label:'发货地址',
+      //   prop:'tmsShipmentAddress',
+      //   component:'by-input',
+      //   compConfig:{
+      //     attr:{
+      //       clearable:true
+      //     }
+      //   }
+      // }],
+      [{
+        label:'收货人',
+        prop:'tmsUnloadingConsignor',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      },{
+        label:'收货人电话',
+        prop:'tmsUnloadingContacts',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        labelWidth:'120px',
+        label:'收货地址选择',
+        prop:'tmsUnloadingProvince',
+        component:'by-area',
+        compConfig:{
+          attr:{
+            province:'tmsUnloadingProvince', //省
+            provinceCode:'tmsUnloadingProvinceNo', //省编码
+            city:'tmsUnloadingCity',   //市
+            cityCode:'tmsUnloadingCityNo',  //市编码
+            county:'tmsUnloadingRegion',  //县/区
+            countyCode:'tmsUnloadingRegionNo',   //县/区编码
+            townCode:'tmsUnloadingStreetNo',
+            town:'tmsUnloadingStreet'
+          }
+        }
+      }],
+      [{
+        label:'收货人地址',
+        prop:'tmsUnloadingAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }],
+      [{
+        label:'期望送达时间',
+        prop:'tmsArrivalDate',
+        component:'byDatePicker',
+        compConfig:{
+          attr:{
+            clearable:true,
+            type:'datetime'
+          }
+        }
+      },{
+        label:'期望提货时间',
+        prop:'tmsDeliveryDate',
+        component:'byDatePicker',
+        compConfig:{
+          attr:{
+            clearable:true,
+            type:'datetime'
+          }
+        }
+      }],
+      [{
+        label:'备注',
+        prop:'tmsRemark',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));                                                                                                             
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  setValue(v:any){
+    this.value = v ? v : {};
+    this.value.wmsSendType = 'B2BCK'
+    this.totalWeight = 0;
+    if(v.weight){
+      this.totalWeight = divide(v.weight,1000)
+    }
+    // if(this.value.subItem && this.value.subItem.length > 0){
+    //   for(const item of this.value.subItem){
+    //     if(Number(item.weight)){
+    //       let totalWeight = multiply(Number(item.weight),Number(item.tmsQuantity))
+    //       this.totalWeight = add(this.totalWeight,totalWeight);
+    //       this.totalWeight = divide(this.totalWeight,1000)
+    //     }
+    //   }
+    // }
+  }
+  hide(){
+    this.$emit('editState',true)
+  }
+  show(){
+    // this.value.tmsBusinessMan = (this as any).$store.getters.userInfo.userName;
+    // this.value.tmsBusinessPhone = (this as any).$store.getters.userInfo.phonenumber;
+    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.$emit('editState',false)
+  }
+  formChange(parames:any){
+    let data = (this.$refs.form as any).getValue();
+    if(data['tmsArrivalDate'] && data['tmsDeliveryDate']){
+      if(data['tmsArrivalDate'] > data['tmsDeliveryDate']){
+        this.$message({
+          message:'期望送达时间不能大于期望提货时间',
+          type:'warning'
+        })
+        if(parames.code == 'tmsArrivalDate'){
+          data['tmsArrivalDate'] = ''
+        }
+        if(parames.code == 'tmsDeliveryDate'){
+          data['tmsDeliveryDate'] = ''
+        }
+        // (this.$refs.form as any).clearValue();
+        (this.$refs.form as any).setValue(data);
+      }
+    }
+  }
+  btn() {
+    if(this.$refs.form){
+      (this.$refs.form as any).validate().then(()=>{
+        this.value = (this.$refs.form as any).getValue();
+        if(!this.value.tmsShipmentCity){
+          this.$message({
+            message:'请选择发货城市!',
+            type:'warning'
+          })
+          return
+        }
+        if(!this.value.tmsShipmentRegion){
+          this.$message({
+            message:'请选择发货区/县!',
+            type:'warning'
+          })
+          return
+        }
+        if(!this.value.tmsUnloadingCity){
+          this.$message({
+            message:'请选择收货城市!',
+            type:'warning'
+          })
+          return
+        }
+        if(!this.value.tmsUnloadingRegion){
+          this.$message({
+            message:'请选择收货区/县!',
+            type:'warning'
+          })
+          return
+        }
+        this.showModal = false;
+        this.$emit('editState',true);
+        this.$emit('editResult',this.value);
+      }).catch(()=>{})
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.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;
+  } 
+}
+</style>
+<style lang="scss">
+.header-cell{
+  background-color: rgba(160,205,255,0.48);
+}
+</style>

+ 150 - 0
src/views/oms/B2COrder/components/deliveryPrice.vue

@@ -0,0 +1,150 @@
+<template>
+  <div class="send-box">
+    <div class="title-label">预计配送和预计费用</div>
+    <div class="send-type">
+      <el-popover
+        v-for="(item,index) of data" :key="index"
+        placement="top-start"
+        width="200"
+        trigger="hover">
+        <div class="price-info">
+          <div class="price-title">预估费用明细:</div>
+          <div class="price-row freight">
+            <span class="p-label">运费:</span>
+            <span class="p-value">¥{{item.estimateFreight}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">单价:</span>
+            <span class="p-value">¥{{item.unitprice}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">重量:</span>
+            <span class="p-value">{{item.weight}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">体积:</span>
+            <span class="p-value">{{item.volume}}</span>
+          </div>
+          <div class="price-row">
+            <span class="p-label">单位:</span>
+            <span class="p-value">{{item.unit}}</span>
+          </div>
+        </div>
+        <div slot="reference" class="send-item" :title="item.ruleName" :class="{'onSend':currentValue.id == item.id}" @click="priceHandle(index)" >
+          <div class="label-name">{{item.ruleName}}</div>
+          <div class="send-info">
+            <div class="s-time">{{item.endTime}}前</div>
+            <div class="send-price">¥{{item.estimateFreight}}</div>
+          </div>
+        </div>
+      </el-popover>
+      
+    </div>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component({components:{}})
+export default class DeliveryPrice extends Vue {
+  @Prop()
+  data?:Array<any>;
+
+  @Prop()
+  currentValue?:any;
+
+  onIndex:any=null;
+  mounted(){
+   
+  }
+  priceHandle(index:number){
+    // this.onIndex = item.id;
+    this.$emit('prichChange',index)
+  }
+
+}
+</script>
+<style lang="scss" scoped>
+.send-box{
+  width: 100%;
+  box-sizing: border-box;
+  padding: 16px;
+  padding-bottom: 0;
+  background-color: rgba(255, 226, 160, 0.3);
+  .title-label{
+    font-size: 14px;
+    padding-bottom: 8px;
+  }
+  .send-type{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    flex-wrap:wrap;
+    .send-item{
+      width: 165px;
+      box-sizing: border-box;
+      border:solid 3px #999;
+      border-radius: 6px;
+      overflow: hidden;
+      margin-right: 32px;
+      cursor: pointer;
+      margin-bottom: 16px;
+      .label-name{
+        background-color: #999;
+        color: #FFF;
+        font-size: 16px;
+        font-weight: 700;
+        padding: 2px 0 4px;
+        text-align: center;
+        width: 100%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+      .send-info{
+        padding: 8px 0;
+        text-align: center;
+        background-color: #FFF;
+        .s-time{
+          font-size: 14px;
+          color: #1684FC;
+          font-weight: 700;
+        }
+        .send-price{
+          font-size: 20px;
+          padding-top: 4px;
+        }
+      }
+    }
+    .send-item:hover,.onSend{
+      border:solid 3px #1684FC;
+      .label-name{
+        background-color: #1684FC;
+      }
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.price-info{
+  width: 100%;
+  color: #000;
+  .price-title{
+    font-size: 16px;
+    font-weight: 700;
+    padding-bottom: 4px;
+  }
+  .price-row{
+    width: 100%;
+    display: flex;
+    font-size: 12px;
+    padding: 3px;
+    // display: flex;
+    // justify-content: space-between;
+  }
+  .freight{
+    font-size: 14px;
+    font-weight: 700;
+  }
+}
+</style>

+ 502 - 0
src/views/oms/B2COrder/components/editProductModal.vue

@@ -0,0 +1,502 @@
+<template>
+  <vxe-modal v-model="value" id="editProductModal" width="70%" height="80%" @hide="hide" title="商品编辑" transfer show-footer v-loading="load">
+    <by-form :propConfig="form" ref="form" @formChange="formChange">
+      <template v-slot:isPay="{value}">
+        <el-switch
+          v-model="value.isPay">
+        </el-switch>
+      </template>
+      <template v-slot:freeAmount="{value}">
+        <vxe-input v-model="value.freeAmount" class="freeAmount" placeholder="保留两位小数或百分比输入" size="mini" @change="freeAmountChange"></vxe-input>
+      </template>
+    </by-form>
+    <div class="tool-comp">
+      <by-tool :propConfig="toolConfig" ref="tool"></by-tool>
+    </div>
+    <by-table :propConfig="tableConfig" ref="table">
+      <template v-slot:name='{ row }'>
+        <div class="product-cont">
+          <div class="product-name">
+            {{ row.name }}
+            <el-tag v-if="row.isGift == 1" size="mini" type="success">赠</el-tag>
+            <el-tag v-if="row.__status === 'delete'" size="mini" type="info" class="del-tag">待删除</el-tag>
+          </div>
+        </div>
+      </template>
+      <template v-slot:qty='{ row }'>
+        <span v-if="row.__status === 'delete'">{{ row.qty }}</span>
+        <vxe-input v-else v-model="row.qty"  placeholder="数量" align="center" size="mini" type="integer" @change="qtyChange($event, row)" >
+        </vxe-input>
+      </template>
+      <template v-slot:price='{ row }'>
+        <span v-if="row.isGift == 1">0</span>
+        <vxe-input v-else-if="row.__status !== 'delete'" v-model="row.price" placeholder="单价" align="center" size="mini" type="number" @change="priceChange($event, row)" >
+        </vxe-input>
+        <span v-else>{{ row.price }}</span>
+      </template>
+    </by-table>
+    <div class="product-row">
+      <div class="p-left">数量:{{ num }}</div>
+      <div class="p-right">
+        <div class="amount-title">商品成交总金额:</div>
+        <div class="amount-price">¥{{ productTotal }}</div>
+      </div>
+    </div>
+    <div class="product-row">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">抵扣金额:</div>
+        <div class="amount-price">¥{{freeAmount?freeAmount:'0.00'}}</div>
+      </div>
+    </div>
+    <div class="product-row">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">运费:</div>
+        <div class="amount-price">¥{{freight?freight:'0.00'}}</div>
+      </div>
+    </div>
+    <div class="product-row">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">应付总金额:</div>
+        <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{payAmount?payAmount:'0.00'}}</div>
+      </div>
+    </div>
+    <div class="product-row" v-if="orderValue.paidAmount">
+      <div class="p-left"></div>
+      <div class="p-right">
+        <div class="amount-title">实付总金额:</div>
+        <div class="amount-price" style="color:#F00; font-size: 14px;">¥{{orderValue.paidAmount?orderValue.paidAmount:'0.00'}}</div>
+      </div>
+    </div>
+    <product-sku-modal ref="product" :mulit="true" @confirm="confirmProduct" />
+    <product-sku-modal ref="productGift" :mulit="true" @confirm="confirmProductGift" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+import { batchItem } from '@/api/omsOrder'
+@Component
+export default class EditProductModal extends Vue {
+  value=false;
+  load = false;
+  num:any=0;//数量
+  payAmount:any=0; //应付总金额
+  productTotal:any=0;//商品成交总金额
+  freeAmount:any=0;//抵扣
+  freight:any=0;//运费
+  orderValue:any={}
+  toolConfig={
+    customTools:[
+      {
+        name: '新增商品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddProduct()
+          }
+        }
+      },
+      {
+        name: '添加赠品', icon: 'el-icon-plus', event:{
+          click:()=>{
+            this.toolAddGift();
+            
+          }
+        }
+      }
+    ]
+  }
+  form:any={
+    attr:{
+      size:'mini'
+    },
+    columns:[
+      [{
+        label:'运费',
+        prop:'freight',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'保留两位小数',
+            size:'mini',
+            type:'number'
+          }
+        }
+      },{
+        label:'抵扣金额',
+        prop:'freeAmount',
+        labelWidth:'100px',
+        slot:true,
+        // component:'by-input',
+        // compConfig:{
+        //   attr:{
+        //     placeholder:'保留两位小数',
+        //     size:'mini'
+        //   }
+        // }
+      },{
+        label:'快速支付',
+        prop:'isPay',
+        slot:true
+      }]
+    ]
+  }
+  tableConfig:any={
+    attr:{
+      size:'mini',
+      align:'center',
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      slot:true,
+      width:300
+    },{
+      title:'数量',
+      field:'qty',
+      width:100,
+      slot:true
+    },{
+      title:'单价',
+      field:'price',
+      width:100,
+      slot:true
+    },{
+      title:'原价',
+      field:'basePrice',
+      width:100
+    },{
+      title:'成交金额',
+      field:'amount',
+      width:100
+    },
+
+    {
+      title:'操作',
+      action:true,
+      plugins:[{
+        icon:'el-icon-delete',
+        name:'删除',
+        event:{
+          click:(item:any) => {
+            this.deletaProduct(item);
+          },
+          show:(item:any) => {
+            return item.__status !== 'delete'
+          }
+        }
+      },{
+        icon:'el-icon-refresh-left',
+        name:'恢复数据',
+        audit:'',
+        event:{
+          click:(item:any) => {
+            this.restoreData(item);
+          },
+          show:(item:any) => {
+            return item.__status === 'delete'
+          }
+        }
+      }]
+    }]
+  }
+  //添加商品
+  toolAddProduct(){
+    (this.$refs.product as any).setShow(true);
+  }
+  //添加赠品
+  toolAddGift(){
+    (this.$refs.productGift as any).setShow(true);
+  }
+  hide(){}
+  setShow(v:boolean){
+    this.value = v;
+  }
+  btn(){
+    let data = (this.$refs.table as any).getValue();
+    let formValue = (this.$refs.form as any).getValue();
+    let parames:any={};
+    parames.addItems=[];
+    parames.addGifts=[];
+    parames.delItems=[];
+    parames.editItems=[];
+    parames.id = this.orderValue.id;
+    parames.freight=formValue.freight;
+    parames.freeAmount=formValue.freeAmount;
+    parames.isPay = formValue.isPay?true:false;
+    for(const item of data){
+      if(!item.id){
+        if(item.isGift == 1){
+          parames.addGifts.push({
+            itemId:item.itemId,
+            qty:item.qty,
+            price:0
+          })
+        }else{
+          parames.addItems.push({
+            itemId:item.itemId,
+            qty:item.qty,
+            price:item.price
+          })
+        }
+      }else{
+        if(item.__status == 'delete'){
+          parames.delItems.push(item.id)
+        }else if(item.__status == 'modify'){
+          parames.editItems.push({
+            itemId:item.id,
+            qty:item.qty,
+            price:item.price
+          })
+        }
+      }
+    }
+    this.load = true;
+    batchItem(parames).then(()=>{
+      this.value = false;
+      this.load = false;
+      this.$emit('handleSuccess')
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  setOrderValue(v:any){
+    this.orderValue = v;
+    this.$nextTick(()=>{
+      let newValue:any = {};
+      newValue.freight = v.freight;
+      newValue.freeAmount = v.freeAmount;
+      newValue.isPay = false;
+      this.payAmount = v.payAmount;
+      this.freeAmount = v.freeAmount;
+      if(this.$refs.form){
+        (this.$refs.form as any).setValue(newValue)
+      }
+    })
+  }
+  setTableValue(v:any){
+    this.$nextTick(()=>{
+      if(this.$refs.table){
+        (this.$refs.table as any).setValue(v);
+        this.totalAmount();
+        this.totalNum();
+      }
+    })
+  }
+  //商品成交总金额
+  totalAmount(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.productTotal = 0;
+    for(const item of nowData){
+      if(Number(item.amount) && item.isGift != 1){
+        this.productTotal = add(item.amount, this.productTotal)
+      }
+    }
+    this.productTotal = this.productTotal.toFixed(2);
+  }
+  freeAmountChange(){
+    let data = (this.$refs.form as any).getValue()
+    if(data.freeAmount){
+      if(Number(data.freeAmount) >= 0){
+        this.freeAmount = Number(data.freeAmounte);
+      }else{
+        let arr:Array<any> = data.freeAmounte.split("%");
+        if(arr.length == 2 && Number(arr[0]) > 0){
+          const n = divide(Number(arr[0]),100)
+          this.freeAmount = multiply(this.productTotal,n)
+        }else{
+          this.freeAmount = 0;
+        }
+      }
+    }else{
+      this.freeAmount = 0;
+    }
+    this.payAmountChange();
+  }
+  //应付总金额
+  payAmountChange(){
+    let t = subtract(this.productTotal, this.freeAmount);
+    this.payAmount = add(t, this.freight);
+    this.payAmount = this.payAmount.toFixed(2);
+  }
+  //商品总数量
+  totalNum(){
+    let nowData = (this.$refs.table as any).getValue();
+    this.num = 0;
+    for(const item of nowData){
+      if(Number(item.qty)){
+        this.num = add(Number(item.qty), Number(this.num))
+      }
+    }
+  }
+  formChange(data:any){
+    if(data.code == 'freight'){
+      this.freight = data.value?data.value:0;
+      this.payAmountChange();
+    }
+  }
+  //数量的变化
+  qtyChange(v:any,row:any){
+    if(v.value && row.price){
+      row.amount = multiply(Number(v.value),Number(row.price))
+    }else{
+      row.amount = 0
+    }
+    if(row.id){
+      row.__status='modify'
+    }
+    this.totalAmount();
+    this.freeAmountChange();
+    this.payAmountChange();
+    this.totalNum();
+  }
+  //单价的变化
+  priceChange(v:any,row:any){
+    if(v.value && row.qty){
+      row.amount =multiply(Number(v.value),Number(row.qty))
+    }else{
+      row.amount = 0
+    }
+    if(row.id){
+      row.__status='modify'
+    }
+    this.totalAmount();
+    this.freeAmountChange();
+    this.payAmountChange();
+  }
+  //确定新增的商品
+  confirmProduct(data:Array<any>){
+    this.productHandle(data,false);
+  }
+  //新增赠品
+  confirmProductGift(data:Array<any>){
+    this.productHandle(data,true);
+  }
+  //商品处理
+  productHandle(data:Array<any>,isGift:boolean){
+    let nowData = (this.$refs.table as any).getValue();
+    let names='';
+    if(data.length > 0){
+      for(const item of data){
+        let t = true;
+        let v = isGift ? 1 : 0;
+        for(const t_item of nowData){
+          if(item.id == t_item.itemId && t_item.isGift == v){
+            if(!names){
+              names = item.skuTitle
+            }else{
+              names = names + ',' + item.skuTitle
+            }
+            t = false;
+            break;
+          }
+        }
+        if(t){
+          let obj:any={};
+          obj.name = item.skuTitle; //商品名称
+          obj.skuId = item.skuCode; //商品编码
+          obj.itemId = item.id;
+          obj.styleId = item.itemNumber; //款式编码
+          obj.qty = 1;
+          if(isGift){
+            obj.price = 0;  //单价
+            obj.isGift = 1;
+          }else{
+            obj.price = item.price;  //单价
+            obj.isGift = 0;
+          }
+          
+          obj.basePrice = item.price; //原价
+          obj.amount = item.price;
+          nowData.push(obj)
+        }
+      }
+      (this.$refs.table as any).setValue(nowData);
+     
+      if(names){
+        let name = isGift ? '赠品' : '商品';
+        this.$alert(name+'“'+names+'”已存在,请在列表做调整!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {}
+        });
+      }
+    }
+  }
+  //删除商品
+  deletaProduct(row:any){
+    let data = (this.$refs.table as any).getValue();
+    let index = -1;
+    for(const item of data){
+      index ++;
+      if(row.skuId == item.skuId && row.name == item.name && row.isGift == item.isGift){
+        break;
+      }
+    }
+    if(row.id){
+      data[index].__status = 'delete'
+    }else{
+      data.splice(index,1);
+    }
+    
+    (this.$refs.table as any).setValue(data);
+  }
+  //恢复数据
+  restoreData(row:any){
+    let data = (this.$refs.table as any).getValue();
+    let index = -1;
+    for(const item of data){
+      index ++;
+      if(row.skuId == item.skuId && row.name == item.name && row.isGift == item.isGift){
+        break;
+      }
+    }
+    delete data[index].__status;
+    (this.$refs.table as any).setValue(data);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tool-comp{
+  width: 100%;
+  padding-bottom: 8px;
+}
+.del-tag{
+  margin-left: 8px;
+}
+.product-row{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  font-size: 12px;
+  padding: 4px 0;
+  .p-left,.p-right{
+    width: 50%;
+  }
+  .p-left{
+    text-align: right;
+  }
+  .p-right{
+    display: flex;
+    align-items: center;
+    .amount-title{
+      width: 70%;
+      text-align: right;
+      box-sizing: border-box;
+      padding-right: 8px;
+    }
+    .amount-price{
+      width: 30%;
+    }
+  }
+}
+</style>

+ 534 - 0
src/views/oms/B2COrder/components/expressDeliveryModal.vue

@@ -0,0 +1,534 @@
+<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}}g</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="700" height="70%" @show="show" @hide="hide" title="编辑" resize show-zoom transfer show-footer>
+        <by-form :propConfig="config" v-if="showModal" 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={
+    attr:{
+      size:'small',
+      labelWidth:'120px',
+      rules:{
+        tmsBusinessMan:[{
+          required: true, message: '业务员不能为空!', trigger: 'blur'
+        },{ min: 0, max: 5, message: '业务员名字不能超过10个字符!', trigger: 'blur' }],
+        tmsBusinessPhone:[{
+          required: true, message: '业务员手机不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, 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:{
+            defaultIndex:0,
+            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
+          }
+        }
+      }]
+    ]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));                                                                                                             
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  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(add(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
+          })
+        }
+      }
+    }
+    this.$nextTick(() => {
+      this.edit()
+    })
+  }
+  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.showModal = false;
+        // this.getStoreCount(this.value);
+      }).catch(() => {})
+    }
+    
+  }
+  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>

+ 59 - 0
src/views/oms/B2COrder/components/filterDate.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="filter-row">
+    <div class="label" v-if="title">{{title}}</div>
+    <div class="filter-cont">
+      <el-date-picker
+        v-model="value"
+        style="width: 100%;"
+        clearable
+        size="mini" 
+        type="datetimerange"
+        @change="change"
+        range-separator="-"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期">
+      </el-date-picker>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import Format from '@/benyun/utils/dateFormat'
+@Component
+export default class FilterInput extends Vue {
+  value:Array<any>=[]
+  @Prop()
+  title:string|undefined
+
+  clear(){
+    this.value = []
+  }
+
+  change(v:any){
+    this.value[0] = Format(v[0],'yyyy-MM-dd HH:mm:ss');
+    this.value[1] = Format(v[1],'yyyy-MM-dd HH:mm:ss');
+    this.$emit('change',this.value)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.filter-row{
+  width: 100%;
+  display: flex;
+  align-items: flex-start;
+  padding-bottom: 4px;
+  flex-direction: column;
+  .label{
+    // width: 80px;
+    flex-shrink: 0;
+    font-size: 14px;
+    text-align: right;
+  }
+  .filter-cont{
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 52 - 0
src/views/oms/B2COrder/components/filterInput.vue

@@ -0,0 +1,52 @@
+<template>
+  <div class="filter-row">
+    <div class="label" v-if="title" :style="{width:labelWidth?labelWidth+'px':'70px'}">{{title}}</div>
+    <div class="filter-cont">
+      <el-input v-model="value" size="mini" :type="type" :placeholder="placeholder?placeholder:title" @input="input" clearable></el-input>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class FilterInput extends Vue {
+  value=''
+  @Prop()
+  title:string|undefined
+  @Prop()
+  placeholder?:string
+  @Prop()
+  type?:string
+  @Prop()
+  labelWidth?:number
+
+  clear(){
+    this.value = ''
+  }
+
+  input(v:any){
+    this.$emit('input',v)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.filter-row{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 4px;
+  .label{
+    width: 70px;
+    flex-shrink: 0;
+    font-size: 14px;
+    text-align: right;
+  }
+  .filter-cont{
+    width: 100%;
+    padding-left: 8px;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 83 - 0
src/views/oms/B2COrder/components/filterMinMax.vue

@@ -0,0 +1,83 @@
+<template>
+  <div class="min-max">
+    <div v-if="title">{{title}}:</div>
+    <div class="munber-time">
+      <vxe-input v-model="value[minField]" class="number-input" size="mini" type="number" @input="mininput"></vxe-input>
+      <span class="split"> - </span>
+      <vxe-input v-model="value[maxField]" class="number-input" size="mini" type="number" @input="maxinput"></vxe-input>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderProduct extends Vue {
+  value:any={}
+
+  @Prop()
+  title!: string;
+  
+  @Prop()
+  minField!:string
+
+  @Prop()
+  maxField!:string
+  clear(){
+    this.value={}
+  }
+  mininput(){
+    const max = Number(this.value[this.maxField]);
+    const min = Number(this.value[this.minField]);
+    if(max < min){
+      this.$message({
+        message: '最小值不能超过最大值!',
+        type: 'warning'
+      })
+      this.value[this.minField] = null;
+      return
+    }
+    this.$emit('change',this.value)
+  }
+  maxinput(){
+    const max = Number(this.value[this.maxField]);
+    const min = Number(this.value[this.minField]);
+    if(max < min){
+      this.$message({
+        message: '最小值不能超过最大值!',
+        type: 'warning'
+      })
+      this.value[this.maxField] = null;
+      return
+    }
+    this.$emit('change',this.value)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.min-max{
+  width: 100%;
+  padding-bottom: 4px;
+  .munber-time{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    .split{
+      padding: 0 8px;
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.number-input{
+  width: 80px; 
+  flex-shrink: 0; 
+  padding: 0;
+  .el-input__inner{
+    padding: 0 !important;
+    text-align: center;
+  }
+}
+</style>

+ 78 - 0
src/views/oms/B2COrder/components/freightModal.vue

@@ -0,0 +1,78 @@
+<template>
+  <vxe-modal v-model="value" id="freightModal" width="400" v-loading="load" @hide="hide" height="200" show-footer title="修改运费">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { editFreight } from '@/api/omsOrder'
+@Component({components:{}})
+export default class FreightModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      rules:{
+        freight: [
+          { required: true, message: '运费不能为空!', trigger: 'input' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'运费',
+        prop:'freight',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'保留两位小数',
+            type:'number'
+          }
+        }
+      }]
+    ]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  btn(){
+    (this.$refs.form as any).validate({noMsg:true}).then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      data.freight = Math.floor(Number(data.freight) * 100) / 100;
+      this.load = true
+      editFreight(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 70 - 0
src/views/oms/B2COrder/components/inputSelect.vue

@@ -0,0 +1,70 @@
+<template>
+  <el-input :placeholder="placeholder" v-model="value" class="input-with-select" size="mini" @input="input" clearable>
+    <el-select v-model="select" slot="append" placeholder="请选择" @change="change">
+      <el-option v-for="(item,index) of options" :key="index" :label="item.label" :value="item.value"></el-option>
+    </el-select>
+  </el-input>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class InputSelect extends Vue {
+  value:any='';
+  select='';
+  placeholder='';
+  format:any=''
+  @Prop()
+  options!:Array<any>
+
+  mounted(){
+    if(this.options){
+      this.select = this.options[0].value;
+      this.placeholder = this.options[0].label;
+      this.format = this.options[0].format;
+    }
+  }
+
+  clear(){
+    this.value=""
+  }
+
+  change(v:any){
+    for(const item of this.options){
+      if(item.value == v){
+        this.placeholder = item.label;
+        this.format = item.format;
+      }
+    }
+  }
+  input(v:any){
+    console.log(v)
+    if(this.format && v){
+      this.value=v.replace(this.format,'');
+    }
+    let obj:any={};
+    obj[this.select] = this.value;
+    this.$emit('input',obj);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.input-with-select{
+  padding-bottom: 4px;
+  width: 100%;
+}
+</style>
+
+<style lang="scss">
+.input-with-select{
+  .el-input-group__append{
+    background-color: #fff !important;
+    width: 110px !important;
+  }  
+  .el-input__inner[type=number]{
+    padding-left: 15px !important;
+  }
+}
+
+</style>

+ 185 - 0
src/views/oms/B2COrder/components/labelsModal.vue

@@ -0,0 +1,185 @@
+<template>
+  <vxe-modal v-model="value" id="labelsModal" width="70%" height="80%" @hide="hide" @show="show" title="选标签"  transfer show-footer v-loading="load">
+    <div class="labelBox" id="labelBox">
+      <by-tool :propConfig="tool" class="labelTool" @clickHandle="clickHandle" id="omsLabelTool" />
+      <by-table :propConfig="tableConfig" ref="table" >
+        <template v-slot:ordered="{row}">
+          <vxe-input v-if="row.isSystem != 1" v-model="row.ordered" size="small" type="number"></vxe-input>
+          <span v-else>{{ row.ordered }}</span>
+        </template>
+      </by-table>
+    </div>
+    <add-label ref="addLabel" @handleSuccess="getList" :isSystem="0" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import {queryAll, updateOrdered, del} from '@/api/omsLabel'
+import addLabel from '../../omsLabel/components/addLabel.vue'
+@Component({components:{addLabel}})
+export default class LabelsModal extends Vue {
+  value = false;
+  load = false;
+  tool={
+    tools:{
+      refresh:true
+    },
+    customTools:[{
+      name:'添加标签',
+      event:{
+        click:()=>{
+          (this.$refs.addLabel as any).setShow(true)
+        }
+      }
+    }],
+    audit:{}
+  }
+  tableConfig:any={
+    attr:{
+      triggerRowCheck:'row',
+      size:'mini',
+      align:'center',
+      seq:true,
+      checkbox:true
+    },
+    columns:[{
+      title:'名称',
+      field:'name'
+    },{
+      title:'排序',
+      field:'ordered',
+      width:150,
+      slot:true
+    },{
+      title:'操作',
+      action:true,
+      width:200,
+      plugins:[{
+        name:'排序',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.sortHandle(row);
+          }
+        }
+      },{
+        name:'删除',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.delHandle(row);
+          }
+        }
+      }]
+    }]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  show(){
+    this.$nextTick(()=>{
+      let height = (document.getElementById('labelBox') as any).parentNode.offsetHeight;
+      this.tableConfig.attr.height=height - 32 - 48;
+      if(this.$refs.table){
+        (this.$refs.table as any).setConfig(this.tableConfig);
+      }
+    })
+    this.getList()
+  }
+  getList(){
+    this.load = true;
+    queryAll().then((res:any) => {
+      this.load = false;
+      if(this.$refs.table){
+        (this.$refs.table as any).setValue(res.data);
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  hide(){
+    if(this.$refs.table){
+      (this.$refs.table as any).clearCheckboxRow();
+    }
+  }
+  sortHandle(row:any){
+    this.load = true;
+    updateOrdered({
+      id:row.id,
+      ordered:Number(row.ordered)
+    }).then(()=>{
+      this.load = false;
+      this.getList();
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  delHandle(row:any){
+    this.$confirm('此操作将删除“'+row.name+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+      del({
+        id:row.id
+      }).then(()=>{
+        this.load = false;
+        this.getList();
+      }).catch(()=>{
+        this.load = false
+      })
+    }).catch(()=>{})
+  }
+  btn(){
+    let data = (this.$refs.table as any).getSelectData();
+    let v='';
+    if(data.length == 0){
+      this.$message('请选择标签!')
+      return
+    }
+    if(data.length > 10){
+      this.$message('标签选择不能超过10个!')
+      return
+    }
+    for(const item of data){
+      if(v){
+        v = v + ','+item.name
+      }else{
+        v = item.name
+      }
+    }
+    this.value = false;
+    this.$emit('onChange',v);
+  }
+  clickHandle(e:string){
+    if(e == 'onAdd'){
+      (this.$refs.addLabel as any).setShow(true)
+    }
+    if(e == 'onRefresh'){
+      this.getList();
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.labelBox{
+  width: 100%;
+  height: 100%;
+}
+.labelTool{
+  padding-bottom: 16px;
+}
+</style>

+ 380 - 0
src/views/oms/B2COrder/components/loadOrderModal.vue

@@ -0,0 +1,380 @@
+<template>
+  <vxe-modal v-model="value" id="synchronousOrderModal"  width="500" height="400" @hide="hide"  transfer show-footer v-loading="load">
+    <template #title>
+      <span>下载订单</span>
+    </template>
+    <template #default>
+      <div class="type">
+        <el-radio-group v-model="type">
+          <el-radio :label="1">按线上订单号</el-radio>
+          <el-radio :label="2">按时间段</el-radio>
+          <!-- <el-radio :label="3">按订单状态</el-radio> -->
+        </el-radio-group>
+      </div>
+      <div class="cont">
+        <div class="title"><span>* </span>上游平台:</div>
+        <div class="right-cont">
+          <el-select v-model="sourceId" size="mini" style="width:100%" placeholder="请选择" clearable @change="shopChange">
+            <el-option
+              v-for="item in sourceOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value">
+            </el-option>
+          </el-select>
+        </div>
+      </div>
+      <template v-if="type == 1">
+        <div class="cont">
+          <div class="title"><span>* </span>线上订单:</div>
+          <div class="right-cont">
+            <el-input v-model="sourceIds" type="textarea" rows="4" size="mini" placeholder="每行一个单号,换行输入"></el-input>
+          </div>
+        </div>
+      </template>
+      <template v-if="type == 2">
+        <div class="cont">
+          <div class="title"><span>* </span>时间类型:</div>
+          <div class="right-cont">
+            <el-select v-model="dateType" size="mini" style="width:100%" placeholder="请选择" clearable>
+              <el-option
+                v-for="item in dateTypeOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="cont">
+          <div class="title"><span>* </span>时间:</div>
+          <div class="right-cont">
+            <el-date-picker
+              v-model="time"
+              style="width: 100%;"
+              size="mini"
+              type="datetimerange"
+              clearable
+              value-format="yyyy-MM-dd HH:mm:ss"
+              range-separator="-"
+              start-placeholder="开始日期"
+              @change="change"
+              end-placeholder="结束日期">
+            </el-date-picker>
+          </div>
+        </div>
+        <div class="cont">
+          <div class="title"><span></span>店铺名称:</div>
+          <div class="right-cont">
+            <el-select v-model="shopid" size="mini" style="width:100%" placeholder="请选择" clearable @change="shopChange">
+              <el-option
+                v-for="item in shopOpions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="cont">
+          <div class="title">订单状态:</div>
+          <div class="right-cont">
+            <el-select v-model="status" size="mini" style="width:100%" placeholder="请选择" clearable>
+              <el-option
+                v-for="item in statusOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+      </template>
+      <!-- <template v-if="type == 3">
+        <div class="cont">
+          <div class="title"><span>* </span>订单状态:</div>
+          <div class="right-cont">
+            <el-select v-model="status" size="mini" style="width:100%" placeholder="请选择" clearable>
+              <el-option
+                v-for="item in statusOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+      </template> -->
+    </template>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" plain @click="clear">清空</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { pullOrder } from '@/api/omsOrder'
+import { query,queryShop } from '@/api/sourceShop'
+@Component
+export default class LoadOrderModal extends Vue {
+  load = false;
+  value = false;
+  type=1;
+  sourceName = '';
+  sourceId:any = null;
+  sourceOptions:Array<any>=[
+    // {
+    // label:'犇云聚水潭店铺',
+    // value:2
+    // }
+  ]
+  shopid=''
+  shopOpions:Array<any>=[]
+  sourceIds=''; //线上订单号
+  dateType:any='';
+  dateTypeOptions=[{
+    label:'修改时间',
+    value:1
+  },{
+    label:'订单日期',
+    value:3
+  },{
+    label:'发货时间',
+    value:4
+  }]
+  beginDate='';
+  endDate='';
+  time:any=null;
+  status='';
+  statusOptions:Array<any>=[{
+    label:'待付款',
+    value:'WaitPay'
+  },{
+    label:'发货中',
+    value:'Delivering'
+  },{
+    label:'被合并',
+    value:'Merged'
+  },{
+    label:'异常',
+    value:'Question'
+  },{
+    label:'被拆分',
+    value:'Split'
+  },{
+    label:'等供销商|外仓发货',
+    value:'WaitOuterSent'
+  },{
+    label:'已付款待审核',
+    value:'WaitConfirm'
+  },{
+    label:'已客审待财审',
+    value:'WaitFConfirm'
+  },{
+    label:'已发货',
+    value:'Sent'
+  },{
+    label:'取消',
+    value:'Cancelled'
+  }]
+  setShow(v:boolean){
+    this.value = v;
+  }
+  change(v:any){
+    if(v){
+      this.beginDate = v[0];
+      this.endDate = v[1];
+    }else{
+      this.beginDate = '';
+      this.endDate = '';
+    }
+  }
+  shopChange(v:any){
+    if(v){
+      for(const item of this.sourceOptions){
+        if(item.value == v){
+          this.sourceName = item.label
+          break;
+        }
+      }
+      this.getSourceShopList()
+    }else{
+      this.sourceName=''
+      this.shopid=''
+      this.shopOpions=[]
+    }
+  }
+  btn(){
+    let value:any={};
+    let msg = '';
+    if(!this.sourceId){
+      msg = '上游平台'
+    }
+    value.sourceId = this.sourceId;
+    value.soueceName = this.sourceName;
+    value.type = this.type;
+    if(this.type == 1){
+      if(!this.sourceIds){
+        if(msg){
+          msg = msg + ',线上订单'
+        }else{
+          msg = '线上订单'
+        }
+      }
+      value.sourceIds = this.sourceIds.split('\n');
+    }else if(this.type == 2){
+      let isS=false;
+      value.shopId = this.shopid
+      for(const item of this.dateTypeOptions){
+        if(item.value == this.dateType){
+          isS = true;
+          break
+        }
+      }
+      // if(!this.status){
+      //   if(msg){
+      //     msg = msg + ',订单状态'
+      //   }else{
+      //     msg = '订单状态'
+      //   }
+      // }
+      value.status = this.status;
+      if(!isS){
+        if(msg){
+          msg = msg + ',时间类型'
+        }else{
+          msg = '时间类型'
+        }
+      }
+      if(!this.time){
+        if(msg){
+          msg = msg + ',时间'
+        }else{
+          msg = '时间'
+        }
+      }
+      value.dateType = Number(this.dateType) - 1;
+      value.beginDate = this.beginDate;
+      value.endDate = this.endDate;
+    }
+    if(msg){
+      this.$message({
+        message:msg + '不能为空!',
+        type: 'warning'
+      })
+      return
+    }
+    this.load = true;
+    pullOrder(value).then((res:any) => {
+      this.load = false;
+      this.value = false;
+      if(res.data > 0){
+        (this as any).$message({
+          message: '已同步到' + res.data + '条订单!',
+          type: 'success',
+        });
+        this.$emit('handleSuccess');
+      }else{
+        (this as any).$message({
+          message: '未更新数据!',
+          type: 'warning',
+        });
+      }
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+  hide(){
+    this.clear()
+  }
+  clear(){
+    this.type = 1;
+    this.sourceName = '';
+    this.sourceId = '';
+    this.sourceIds = '';
+    this.dateType = '';
+    this.beginDate = '';
+    this.endDate = '';
+    this.time = null;
+    this.status = '';
+    this.shopid = ''
+  }
+  //上游平台
+  getSourceList() {
+    this.sourceOptions = []
+    this.load = true
+    query({
+      pageNo: 1,
+      pageSize: 50
+    }).then((res:any) => {
+      this.load = false
+      if (res.data && res.data.records) {
+        for(const item of res.data.records) {
+          this.sourceOptions.push({
+            label: item.sourceName,
+            value: item.id
+          })
+        }
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  //店铺
+  getSourceShopList(){
+    this.shopOpions = []
+    queryShop({
+      sourceId:this.sourceId
+    }).then((res:any) => {
+      this.load = false
+      if (res.data) {
+        for(const item of res.data) {
+          this.shopOpions.push({
+            label: item.shopName,
+            value: item.shopId
+          })
+        }
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  created() {
+    this.getSourceList()
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn{
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+}
+.type{
+  width: 100%;
+  padding: 8px 0;
+}
+.cont{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding: 8px 0;
+  .title{
+    width: 100px;
+    text-align: right;
+    margin: 0 !important;
+    >span{
+      color: #F00;
+    }
+  }
+  .right-cont{
+    width: calc(100% - 100px);
+  }
+}
+</style>

+ 80 - 0
src/views/oms/B2COrder/components/logisticsInfo.vue

@@ -0,0 +1,80 @@
+<template>
+  <el-drawer
+    v-loading="load"
+    title="物流信息"
+    :visible.sync="drawer"
+    :direction="direction"
+    size="30%">
+    <div class="order-logistcs">
+      <el-timeline :reverse="true">
+        <el-timeline-item v-for="(item,index) of data" :key="index" :timestamp="item.tmsStatus + ' ' +item.createTime" placement="top">
+          <el-card>
+            <!-- <h4>{{item.tmsStatus}}</h4> -->
+            <p v-if="item.tmsOrderNo">单号:{{ item.tmsOrderNo }}</p>
+            <!-- <p v-if="item.tmsCarrierName">物流:{{ item.tmsCarrierName }}</p> -->
+            <p v-if="item.tmsPlateNumber">车牌:{{ item.tmsPlateNumber }}</p>
+            <p v-if="item.tmsDriverName">司机:{{ item.tmsDriverName }}</p>
+            <p v-if="item.tmsDriverPhone">电话:{{ item.tmsDriverPhone }}</p>
+          </el-card>
+        </el-timeline-item>
+      </el-timeline>
+    </div>
+      
+  </el-drawer>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { queryByOrderNo } from  '@/api/delivery'
+@Component({components:{}})
+export default class LogisticsInfo extends Vue {
+  drawer=false;
+  direction='rtl'
+  load = false;
+  data:Array<any>=[]
+
+  setShow(v:boolean){
+    this.drawer = v;
+  }
+  loadData(code:string){
+    if(!code){
+      this.$message('订单编号不能为空!')
+      return
+    }
+    this.load = true;
+    queryByOrderNo({orderNo:code}).then((res:any) => {
+      this.load = false;
+      this.data = []
+      if(res.data){
+        this.data = res.data;
+      }
+    }).catch(() => {
+      this.load = false;
+    })
+  }
+}
+</script>
+<style lang="scss" scoped>
+.order-logistcs{
+  width: 100%;
+  box-sizing: border-box;
+
+  padding: 0 16px;
+}
+.info{
+  width: 100%;
+  padding: 8px 16px;
+  box-sizing: border-box;
+  border-bottom: solid 1px #EEE;
+  .logistic-state{
+    font-size: 14px;
+  }
+  .logistic-time{
+    font-size: 12px;
+    padding-top: 8px;
+    color: #999;
+  }
+}
+.info:last-child{
+  border: none;
+}
+</style>

+ 176 - 0
src/views/oms/B2COrder/components/mergeMedal.vue

@@ -0,0 +1,176 @@
+<template>
+  <vxe-modal v-model="value" id="mergeModel" title="合并订单" width="70%" height="80%" show-zoom resize transfer show-footer v-loading="load">
+    <by-table :propConfig="config" ref="table" id="merge-table">
+      <template v-slot:sourceId="{row}">
+        <span>{{ row.sourceId }}</span>
+        <div class="tag-main" v-if="row.isMain == 1">
+          <el-tag size="mini">主</el-tag>
+        </div>
+      </template>
+      <template v-slot:address="{row}">
+        <div class="addr">{{ row.receiverProvince + '-' + row.receiverCity + '-' + row.receiverDistrict + (row.receiverTown?'-'+row.receiverTown:'') }}</div>
+        <div class="de-addr">{{ row.receiverAddress }}</div>
+      </template>
+      <template v-slot:pay="{row}">
+        <div><el-tag type="success">已付款</el-tag></div>
+        <div>{{ row.payDate}}</div>
+      </template>
+      <template v-slot:product="{row}">
+        <el-badge :value="item.qty" class="item-pro" type="primary" :max="99" v-for="(item,index) of row.items" :key="index">
+          <el-image  style="width: 28px; height: 28px">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline"></i>
+            </div>
+          </el-image>
+        </el-badge>
+      </template>
+      <template v-slot:status="{row}">
+        <span v-if="row.status == 'WaitPay'">待付款</span>
+        <span v-if="row.status == 'Delivering'">发货中</span>
+        <span v-if="row.status == 'Merged'">被合并</span>
+        <span v-if="row.status == 'Question'" style="color:red">异常</span>
+        <span v-if="row.status == 'Split'">被拆分</span>
+        <span v-if="row.status == 'WaitOuterSent'">等供销商|外仓发货</span>
+        <span v-if="row.status == 'WaitConfirm'">已付款待审核</span>
+        <span v-if="row.status == 'WaitFConfirm'">已客审待财审</span>
+        <span v-if="row.status == 'Sent'">已发货</span>
+        <span v-if="row.status == 'Cancelled'">取消</span>
+      </template>
+      <template v-slot:msg="{row}">
+        <div class="buyer-msg">{{ row.buyerMessage }}</div>
+        <div>{{ row.remark }}</div>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { merge } from '@/api/omsOrder'
+@Component({components:{}})
+export default class MergeModel extends Vue {
+  value = false;
+  load = false;
+  config:any={
+    attr:{
+      size:'small',
+      checkbox:true,
+      seq:true,
+      visibleMethod:({row}:any) =>{
+        return row.isMain != 1
+      }
+    },
+    columns:[{
+      title:'订单号',
+      field:'sourceId',
+      fixed:'left',
+      slot:true,
+      width:140
+    },{
+      title:'买家',
+      field:'buyerNickname',
+      width:150
+    },{
+      title:'收货人',
+      field:'receiverName',
+      width:120
+    },{
+      title:'买家地址',
+      field:'address',
+      width:200,
+      slot:true
+    },{
+      title:'付款方式+时间',
+      field:'pay',
+      slot:true,
+      width:150
+    },{
+      title:'商品',
+      field:'product',
+      slot:true,
+      width:150
+    },{
+      title:'状态',
+      field:'status',
+      slot:true,
+      width:120
+    },{
+      title:'运费',
+      field:'freight',
+      width:80
+    },{
+      title:'重量',
+      field:'weight',
+      width:80
+    },{
+      title:'买家留言+卖家备注',
+      field:'msg',
+      width:160
+    }]
+  }
+  setShow(v:boolean){
+    this.value = v
+  }
+  setData(data:Array<any>){
+    this.$nextTick(()=>{
+      let height = (document.getElementById('merge-table') as any).parentNode.offsetHeight;
+      this.config.attr.height=height - 36;
+      if(this.$refs.table){
+        (this.$refs.table as any).setConfig(this.config);
+        (this.$refs.table as any).setValue(data);
+      }
+    })
+  }
+  btn(){
+    let va = (this.$refs.table as any).getValue();
+    let data = (this.$refs.table as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择需要合并的数据!')
+      return
+    }
+    let params:any={};
+    params.idList=[]
+    for(const item of va){
+      if(item.isMain == 1){
+        params.id = item.id;
+        break;
+      }
+    }
+    for(const item of data){
+      params.idList.push(item.id);
+    }
+    this.load = true;
+    merge(params).then((res:any)=>{
+      this.load = false;
+      this.$message({
+        message:'合并成功!',
+        type:'success'
+      })
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tag-main{
+  width: 100%;
+  display: flex;
+  // justify-content: flex-end;
+}
+.buyer-msg,.addr{
+  color: dodgerblue;
+}
+.addr,.de-addr{
+  font-size: 12px;
+}
+</style>

+ 99 - 0
src/views/oms/B2COrder/components/orderCheckbox.vue

@@ -0,0 +1,99 @@
+<template>
+  <el-collapse-item :name="keyName">
+    <template slot="title">
+      <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" class="check-title">
+        <span class="check-title">{{title}}</span>
+      </el-checkbox>
+    </template>
+    <el-checkbox-group v-if="options.length > 0" v-model="value" @change="handleCheckedItemChange">
+      <template v-for="dataItem in options">
+        <br :key="'s'+dataItem.value"/>
+        <el-checkbox :label="dataItem.value || dataItem.value === 0?dataItem.value:dataItem.label" :key="dataItem.value">{{dataItem.label}}</el-checkbox>
+        <slot v-if="dataItem.slot" :name='dataItem.slotName' :item='dataItem'></slot>
+      </template>
+    </el-checkbox-group>
+  </el-collapse-item>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderCheckbox extends Vue {
+  value:Array<any>=[]
+  activeNames:Array<any>=[1]
+  checkAll= false
+  isIndeterminate= false
+
+  @Prop()
+  title:string|undefined
+
+  @Prop()
+  options!:Array<any>
+
+  @Prop()
+  keyName:any
+
+  @Prop()
+  retType?:string
+
+  clear(){
+    this.value = [];
+    this.checkAll = false;
+    this.isIndeterminate = false;
+  }
+
+  getValue(){
+    if(this.retType == 'string'){
+      let n='';
+      for(const item of this.value){
+        if(!n){
+          n = n + ',' + item
+        }else{
+          n = item
+        }
+      }
+      return n;
+    }else{
+      return this.value;
+    }
+  }
+
+  emitFun(a?:boolean){
+    let v:any = this.getValue();
+    if(a){
+      this.$emit('checkboxChange',[]);
+    }else{
+      this.$emit('checkboxChange',v);
+    }
+    
+  }
+
+  handleCheckAllChange(val:any){
+    this.value = []
+    if(val && this.options){
+      for(const item of this.options){
+        this.value.push(item.value)
+      }
+    }
+    this.isIndeterminate = false;
+    this.emitFun(true);
+  }
+
+  handleCheckedItemChange(value:any,config:any){
+    let checkedCount = value.length;
+    this.checkAll = checkedCount === this.options.length;
+    this.isIndeterminate = checkedCount > 0 && checkedCount < this.options.length;
+    this.emitFun();
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.check-title{
+  font-weight: 700;
+}
+.slot-box{
+  padding-left: 8px;
+}
+</style>

+ 41 - 0
src/views/oms/B2COrder/components/orderProduct.vue

@@ -0,0 +1,41 @@
+<template>
+  <div class="order-product">
+    <el-input placeholder="商品" v-model="value" size="mini" class="product-with-select" clearable>
+      <el-button slot="append" icon="el-icon-more" @click="showProduct"></el-button>
+    </el-input>
+    <productDialog ref="product" @confirm="confirm" />
+  </div>
+  
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderProduct extends Vue {
+  value=''
+
+  showProduct(){
+    (this.$refs.product as any).setShow(true)
+  }
+  confirm(data:Array<any>){
+    
+  }
+}
+</script>
+<style lang="scss" scoped>
+.order-product{
+  width: 100%;
+}
+</style>
+<style lang="scss">
+.product-with-select{
+  margin-bottom: 4px;
+  .el-input-group__append{
+    background-color: #fff !important;
+    width: 40px !important;
+    .el-icon-more{
+      font-size: 20px;
+    }
+  }  
+}
+</style>

+ 57 - 0
src/views/oms/B2COrder/components/orderRadio.vue

@@ -0,0 +1,57 @@
+<template>
+  <el-collapse-item :name="keyName" :title="title">
+    <el-radio-group v-model="value" v-if="options.length > 0" @input="input">
+      <el-radio label="" class="order-radio" v-if="noLimit">不限</el-radio>
+      <el-radio v-for="(item,index) in options" :label="item.value || item.value == 0?item.value:item.label" :key="index" class="order-radio">
+        {{item.label}}
+        <template v-if="item.slotName">
+          <slot :name="item.slotName" />
+        </template>
+      </el-radio>
+      <slot />
+    </el-radio-group>
+  </el-collapse-item>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderCheckbox extends Vue {
+  value:any=''
+  activeNames:Array<any>=[1]
+  checkAll= false
+  isIndeterminate= false
+
+  @Prop()
+  noLimit?:boolean
+
+  @Prop()
+  title:string|undefined
+
+  @Prop() 
+  options!:Array<any>
+
+  @Prop()
+  keyName:any
+
+  getValue(){
+    return this.value;
+  }
+
+  clear(){
+    this.value = ''
+  }
+
+  input(){
+    this.$emit('radioChange',this.value);
+  }
+
+
+}
+</script>
+
+<style lang="scss" scoped>
+.order-radio{
+  margin-bottom: 8px;
+}
+</style>

+ 309 - 0
src/views/oms/B2COrder/components/orderTable.vue

@@ -0,0 +1,309 @@
+<template>
+  <vxe-table
+    size="mini"
+    border
+    stripe
+    ref="table"
+    :height="height"
+    :row-config="{isCurrent: true,isHover: true}"
+    :data="data">
+    <vxe-column type="checkbox" width="50" fixed="left"></vxe-column>
+    <!-- <vxe-column type="seq" width="60" title="序号" fixed="left"></vxe-column> -->
+    <vxe-column field="id" title="内部订单号" width="100" fixed="left">
+      <template #default="{ row }">
+        <div class="col-cont">
+          <span>{{ row.id }}</span>
+          <div class="update">
+            <div class="tag-update" @click="detail(row)">详</div>
+          </div>
+        </div>
+      </template>
+    </vxe-column>
+    <vxe-column field="rawSourceId" title="线上订单号" width="140"> </vxe-column>
+    <vxe-column field="isSubmitted" title="提交状态" width="100">
+      <template #default="{ row }">
+        <el-tag v-if="row.isSubmitted == 1" size="small">已提交</el-tag>
+        <el-tag v-else type="warning" size="small"> 未提交 </el-tag>
+      </template>
+    </vxe-column>
+    <vxe-column field="product" title="商品" width="140">
+      <template #default="{ row }">
+        <el-badge :value="item.qty" class="item-pro" type="primary" :max="99" v-for="(item,index) of row.items" :key="index">
+          <el-image  style="width: 28px; height: 28px">
+            <div slot="error" class="image-slot">
+              <i class="el-icon-picture-outline"></i>
+            </div>
+          </el-image>
+        </el-badge>
+      </template>
+    </vxe-column>
+    <!-- <vxe-column field="businessType" title="业务类型" width="80"></vxe-column> -->
+    <vxe-column field="orderType" title="订单类型" width="100">
+      <template #default="{ row }">
+        <span v-if="row.orderType == 'Common'">普通订单</span>
+        <span v-if="row.orderType == 'Reissue'">补发订单</span>
+        <span v-if="row.orderType == 'DistributionPlus'">分销Plus</span>
+        <span v-if="row.orderType == 'SupplyPlus'">供销Plus</span>
+        <span v-if="row.orderType == 'Exchange'">换货订单</span>
+      </template>
+    </vxe-column>
+    <vxe-column field="status" title="订单状态" width="120">
+      <template #default="{ row }">
+        <span v-if="row.status == 'WaitPay'">待付款</span>
+        <span v-if="row.status == 'Delivering'">发货中</span>
+        <span v-if="row.status == 'Merged'">被合并</span>
+        <span v-if="row.status == 'Question'" style="color:red">异常</span>
+        <span v-if="row.status == 'Split'">被拆分</span>
+        <span v-if="row.status == 'WaitOuterSent'">等供销商|外仓发货</span>
+        <span v-if="row.status == 'WaitConfirm'">已付款待审核</span>
+        <span v-if="row.status == 'WaitFConfirm'">已客审待财审</span>
+        <span v-if="row.status == 'Sent'">已发货</span>
+        <span v-if="row.status == 'Cancelled'">取消</span>
+      </template>
+    </vxe-column>
+    <vxe-column field="upSourceName" title="订单来源" width="110"></vxe-column>
+    <vxe-column field="operationFlag" title="操作标记" width="120">
+      <template #default="{ row }">
+        {{ getFromText(row.operationFlag) }}
+      </template>
+    </vxe-column>
+    <vxe-column field="shopName" title="店铺名称" width="140"></vxe-column>
+    <vxe-column field="orderDate" title="订单日期" width="140">
+      <!-- <template #default="{ row }">
+        {{ formatDate(row.orderDate) }}
+      </template> -->
+    </vxe-column>
+    <!-- <vxe-column field="shipment" title="跨境买家指定物流" width="120"></vxe-column> -->
+    <vxe-column field="chosenChannel" title="实发快递渠道" width="120"></vxe-column>
+    <vxe-column field="logisticsId" title="快递单号" width="120"></vxe-column>
+    <vxe-column field="logisticsCompany" title="快递公司" width="120"></vxe-column>
+    <vxe-column field="logisticsCompanyCode" title="物流公司编码" width="120"></vxe-column>
+    <!-- <vxe-column field="internationalLogisticsId" title="国际物流单号" width="120"></vxe-column> -->
+    <!-- <vxe-column field="skus" title="skus" width="120"></vxe-column> -->
+    <vxe-column field="weight" title="重量" width="70"></vxe-column>
+    <vxe-column field="isCod" title="是否货到付款" width="120">
+      <template #default="{ row }">
+        {{ row.isCod == 1 ? '是' :' 否' }}
+      </template>
+    </vxe-column>
+    <vxe-column field="sendDate" title="发货日期" width="120"></vxe-column>
+    <!-- <vxe-column field="signTime" title="预计送达时间" width="120"></vxe-column>
+    <vxe-column field="endTime" title="确认收货时间" width="120"></vxe-column> -->
+    <vxe-column field="receiverAddress" title="收货地址" show-overflow width="160"></vxe-column>
+    <vxe-column field="receiverName" title="收件人" show-overflow width="120"></vxe-column>
+    <vxe-column field="receiverMobile" title="手机" show-overflow width="120"></vxe-column>
+    <vxe-column field="buyerMessage" title="买家留言" show-overflow width="120"></vxe-column>
+    <!-- <vxe-column field="wmsCoId" title="发货仓编号" width="120"></vxe-column> -->
+    <vxe-column field="payDate" title="支付时间" width="140"></vxe-column>
+    <vxe-column field="freeAmount" title="抵扣金额" align="right" width="120"></vxe-column>
+    <vxe-column field="payAmount" title="应付+运费" align="right" width="120">
+      <template #default="{ row }">
+        <span>{{ row.payAmount }}</span> <br/>
+        <span style="color: #b9b8b8;">{{ row.freight?row.freight:0 }}</span>
+      </template>
+    </vxe-column>
+    <vxe-column field="paidAmount" title="实付金额" align="right" width="120"></vxe-column>
+    <vxe-column field="buyerNickname" title="买家昵称" show-overflow width="140"></vxe-column>
+    <!-- <vxe-column field="openId" title="平台买家唯一值" show-overflow width="140"></vxe-column> -->
+    <vxe-column field="buyerPaidAmount" title="总买家实付" width="120"></vxe-column>
+    <vxe-column field="sellerIncomeAmount" title="总卖家实收" width="120"></vxe-column>
+    <vxe-column field="questionType" title="问题类型" width="120"></vxe-column>
+    <vxe-column field="questionDesc" title="问题描述" width="120"></vxe-column>
+    <!-- <vxe-column field="invoiceType" title="发票类型" width="120"></vxe-column> -->
+    <vxe-column field="invoiceTitle" title="发票抬头+税号" width="120">
+      <template #default="{ row }">
+        <span>{{ row.invoiceTitle }}</span> <br/>
+        <span style="color: #b9b8b8;">{{ row.buyerTaxNo }}</span><br/>
+        <span>{{ row.invoiceType }}</span>
+      </template>
+    </vxe-column>
+    <!-- <vxe-column field="buyerTaxNo" title="发票税号" width="120"></vxe-column> -->
+    <!-- <vxe-column field="drpCoIdFrom" title="分销商编号" width="120"></vxe-column>
+    <vxe-column field="drpCoIdTo" title="供销商编号" width="120"></vxe-column> -->
+    <vxe-column field="remark" title="订单备注" width="120"></vxe-column>
+    <vxe-column field="note" title="线下备注" width="120"></vxe-column>
+    <vxe-column field="labels" title="标签" width="120"></vxe-column>
+    <vxe-column title="操作" width="120" fixed="right" align="center">
+      <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="row.status == 'Delivering'  || row.status == 'Sent'" @click="sendGoodsDetail(row)">发货明细</el-button>
+      </template>
+    </vxe-column>
+  </vxe-table>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import Format from '@/benyun/utils/dateFormat'
+@Component
+export default class OrderTable extends Vue {
+  @Prop()
+  data!:Array<any>
+  height=null
+
+  operationFlag:any={
+    'OMS':'手工下单',
+    'COPY':'复制',
+    'MERGE':'合并',
+    'SPLIT':'拆分;拆分还原',
+    'MOBILE':'导入',
+    'DRP-S':'供销推送',
+    'DRP-D':'分销推送',
+    'KWAISHOP':'快手;微商城',
+    'PINDUODUO':'拼多多',
+    'TOUTIAOFXG':'头条放心购',
+    'JUSHUITAN':'聚水潭'
+  }
+  //订单来源转换文字信息
+  getFromText(f:any){
+    let t='';
+    if(f){
+      let arr:Array<any>=f.split(',');
+      for(const item of arr){
+        if(this.operationFlag[item]){
+          if(t){
+            t = t + ' , ' + this.operationFlag[item]
+          }else{
+            t = this.operationFlag[item]
+          }
+        }
+      }
+    }
+    return t;
+  }
+  //是否显示发货
+  showSend(item:any){
+    let noStatus = ['WaitPay','Delivering','Merged','Split','Question','Sent','Cancelled'];
+    if(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && noStatus.indexOf(item.status) == -1){
+      return true
+    }
+    return false
+  }
+  //合并按钮是否显示
+  showMerge(item:any){
+    let r = false;
+    if(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && (!item.operationFlag || item.operationFlag.indexOf('MERGE') == -1 && item.operationFlag.indexOf('SPLIT') == -1 
+    && item.operationFlag.indexOf('JUSHUITAN') == -1)){
+      if(item.status == 'WaitConfirm' || item.status == 'Question'){
+        r = true;
+      }
+    }
+    return r;
+  }
+  showSplit(item:any){
+    let r = false;
+    if(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && (!item.operationFlag || item.operationFlag.indexOf('MERGE') == -1 && item.operationFlag.indexOf('SPLIT') == -1 
+    && item.operationFlag.indexOf('JUSHUITAN') == -1)){
+      let s=['WaitConfirm','Question','Split']
+      if(s.indexOf(item.status) >= 0){
+        r = true;
+      }
+    }
+    return r;
+  }
+
+  formatDate(v:string){
+    return Format(v,'yyyy-MM-dd');
+  }
+
+  mounted(){
+    this.$nextTick(() => {
+      this.height = (this as any).$el.offsetHeight;
+    })
+  }
+  detail(row:any){
+    this.$emit('detail',row)
+  }
+  getSelectData(){
+    let data = (this as any).$lodash.cloneDeep((this.$refs.table as any).getCheckboxRecords());
+    return data;
+  }
+  sendGoods(row:any){
+    this.$emit('sendGoods',row)
+  }
+  sendGoodsDetail(row:any){
+    this.$emit('sendGoodsDetail',row)
+  }
+  mergeHandle(row:any){
+    let v = (this as any).$lodash.cloneDeep(row);
+    v.isMain = 1;
+    let data:Array<any> = [];
+    data.push(v);
+    for(const item of this.data){
+      if(row.id != item.id && item.isSubmitted == 1 && row.shopId == item.shopId && row.shopName == item.shopName && row.buyerId == item.buyerId && 
+      row.receiverMobile == item.receiverMobile && row.receiverProvince == item.receiverProvince && row.receiverCity == item.receiverCity 
+      && row.receiverDistrict == item.receiverDistrict && row.receiverTown == item.receiverTown && row.receiverAddress == item.receiverAddress 
+      && item.pays && item.pays.length > 0 && item.operationFlag.indexOf('SPLIT') == -1 && item.operationFlag.indexOf('MERGE') == -1 && (item.status == 'WaitConfirm'
+      || item.status == 'Question')){
+        data.push(item);
+      }
+    }
+    this.$emit('mergeHandle',data);
+  }
+  splitHandle(row:any){
+    this.$emit('splitHandle',row);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.detail{
+  color: #0089ff;
+  cursor: pointer;
+}
+.col-cont{
+  // display: flex;
+  // justify-content: space-between;
+  // align-items: center;
+  // flex-direction: column;
+  .update{
+    display: flex;
+    justify-content: flex-end;
+    width: 100%;
+    visibility: hidden;
+  }
+  .tag-update{
+    height: 24px;
+    width: 24px;
+    font-size: 12px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border-radius: 50%;
+    background-color:#2d99f7;
+    color: #FFF;
+    flex-shrink: 0;
+    margin-left: 4px;
+    cursor: pointer;
+  }
+  .tag-update:hover{
+    opacity: 0.7;
+  }
+}
+</style>
+
+<style lang="scss">
+.row--hover{
+  .update{
+    visibility:visible !important;
+  }
+}
+.row--current{
+  .update{
+    visibility:visible !important;
+  }
+}
+.image-slot{
+  .el-icon-picture-outline{
+    font-size: 28px;
+    color: #999;
+  }
+}
+.item-pro{
+  .el-badge__content{
+    z-index: 1;
+  }
+}
+</style>

+ 89 - 0
src/views/oms/B2COrder/components/orderTool.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="order-tool">
+    <el-button type="text" @click="handle('loadOrder')">手工下载</el-button>
+    <!-- <el-dropdown split-button type="text" @click="handle('addOrder')" @command="handleCommand">
+      新增订单
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item command="loadOrder">手工下载</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown> -->
+    <!-- <el-button type="text" @click="handle('addOrder')">新增订单</el-button> -->
+    <div class="split"></div>
+    <el-dropdown split-button type="text" @click="handle('smt')" @command="handleCommand">
+        提交
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item command="reSmt">反提交</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown>
+    <!-- <el-button type="text">设快递</el-button>
+    <el-dropdown split-button type="text" class="dropdown">
+      设快递单号
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item>批量设置快递单号</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown> -->
+    <div class="split"></div>
+    <el-button type="text" @click="handle('changeQues')">转异常</el-button>
+    <el-button type="text" @click="handle('changeNormal')">转正常</el-button>
+    <el-button type="text" @click="handle('cancelOrder')">取消订单<i class="el-icon-info" title="只有[待付款,发货中,异常,已付款待审核,等供销商|外仓发货,已客审待财审]才可以取消订单"></i></el-button>
+    <!-- <el-dropdown split-button type="text" class="dropdown" @click="handle('cancelOrder')" @command="handleCommand">
+      取消订单
+      <i class="el-icon-info" title="只有[待付款,发货中,异常,已付款待审核,等供销商|外仓发货,已客审待财审]才可以取消订单"></i>
+      <el-dropdown-menu slot="dropdown">
+        <el-dropdown-item command="reCancelOrder">反取消订单</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown> -->
+    <div class="split"></div>
+    <el-dropdown split-button type="text" class="dropdown" @click="handle('addGift')" @command="handleCommand">
+      添加赠品
+      <el-dropdown-menu slot="dropdown">
+        <!-- <el-dropdown-item command="addProduct">添加商品</el-dropdown-item> -->
+        <!-- <el-dropdown-item command="addGift">添加赠品</el-dropdown-item> -->
+        <el-dropdown-item command="updateFreight">改运费</el-dropdown-item>
+        <el-dropdown-item command="updateTag">改标签</el-dropdown-item>
+        <el-dropdown-item command="updateRmk">改备注</el-dropdown-item>
+        <el-dropdown-item command="updateSalesman">设定业务员</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown>
+    <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>
+  </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component
+export default class OrderTool extends Vue {
+
+  handleCommand(n:string){
+    this.$emit(n)
+  }
+
+  handle(n:string){
+    this.$emit(n)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.order-tool{
+  height: 40px;
+  display: flex;
+  align-items: center;
+  width: 100%;
+  .order-tool-btn{
+    color: #333;
+  }
+  .split{
+    height: 10px;
+    width: 1px;
+    background-color: #CCC;
+    margin: 0 8px;
+  }
+  .dropdown{
+    padding-left: 8px;
+  }
+}
+</style>

+ 321 - 0
src/views/oms/B2COrder/components/purchaseModel.vue

@@ -0,0 +1,321 @@
+<template>
+  <vxe-modal v-model="value" id="purchaseModel" @show="show" width="70%" height="80%" min-width="460" min-height="320" 
+    show-zoom resize transfer show-footer @hide="hide" v-loading="load">
+    <template #title>
+      <span>生成采购单</span>
+    </template>
+    <el-collapse v-model="activeNames">
+      <el-collapse-item title="基本信息" name="1" class="add-order-item">
+        <by-form :propConfig="baseConfig" ref="baseform">
+          <template v-slot:organizationName='{ value }'>
+            <el-input placeholder="请选择供应商" v-model="value.organizationName" @clear="organizationClear" class="input-organizationName" size="small" clearable>
+              <el-button slot="append" icon="el-icon-more" @click="handleSupplier"></el-button>
+            </el-input>
+          </template>
+        </by-form>
+      </el-collapse-item>
+
+      <el-collapse-item title="商品信息" name="2" class="add-order-item">
+        <by-table :propConfig="tableConfig" ref="table" @onChangeRow="onChangeRow"></by-table>
+      </el-collapse-item>
+    </el-collapse>
+    <supplier-modal ref="supplierModal" @confirm="confirm" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { toPurchaseOrder } from '@/api/omsOrder'
+import { add,multiply,subtract,divide } from '@/benyun/utils/accuracy'
+// import SupplierModal from "@/components/supplierModal/supplierModal.vue";
+@Component({components:{}})
+export default class PurchaseModel extends Vue {
+  value=false;
+  load = false;
+  activeNames:Array<any>=['1','2']
+  baseConfig:any={
+    attr:{
+      size:'small',
+      rules:{
+        organizationName:[{
+          required: true, message: '供应商不能为空!', trigger: ['blur','change']
+        }],
+        deliveryAddress:[{
+          required: true, message: '交货地点不能为空!', trigger: 'blur'
+        }],
+        deliveryData:[{
+          required: true, message: '交货时间不能为空!', trigger: 'blur'
+        }],
+        delivery:[{
+          required: true, message: '交货人不能为空!', trigger: 'blur'
+        }],
+        deliveryPhone:[{
+          required: true, message: '交货人不能为空!', trigger: 'blur'
+        },{
+          validator: this.validatePhone, trigger: 'blur' 
+        }]
+      }
+    },
+    columns:[
+      [{
+        span:6,
+        label:'供应商',
+        prop:'organizationName',
+        slot:true
+      },{
+        span:6,
+        label:'交货地点',
+        prop:'deliveryAddress',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货地点',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'交货时间',
+        prop:'deliveryData',
+        component:'by-date-picker',
+        compConfig:{
+          attr:{
+            placeholder:'交货时间',
+            type:'datetime',
+            defaultNow:true,
+            clearable:true
+          }
+        }
+      }],
+      [{
+        span:6,
+        label:'交货人',
+        prop:'delivery',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货人',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'交货人手机',
+        prop:'deliveryPhone',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货人手机',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'交货方式',
+        prop:'deliveryWay',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入交货方式',
+            clearable:true
+          }
+        }
+      },{
+        span:6,
+        label:'物流分类',
+        prop:'logisticClass',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入物流分类',
+            clearable:true
+          }
+        }
+      }]
+    ]
+  }
+
+  tableConfig:any={
+    attr:{
+      size:'small',
+      align:'center',
+      seq:true
+    },
+    columns:[{
+      title:'商品',
+      field:'name',
+      // width:180,
+      // slot:true
+    },{
+      title:'数量',
+      field:'qty',
+      width:100,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          type:'integer',
+          min:0
+          // isPositiveNumber:true
+        }
+      }
+    },{
+      title:'价格',
+      field:'price',
+      width:100,
+      component:'by-input',
+      compConfig:{
+        attr:{
+          type:'number'
+        }
+      }
+    },{
+      title:'可采购数量',
+      field:'residueQty',
+      width:100,
+    },{
+      action:true,
+      width:100,
+      title:'操作',
+      plugins:[{
+        name:'删除',
+        event:{
+          click:(row:any)=>{
+            this.del(row)
+          }
+        }
+      }]
+    }]
+  }
+  validatePhone(rule:any, value:any, callback:any){
+    if (value) {
+      if(!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(value)) {
+        callback(new Error('手机号格式不正确!'));  
+      }else{
+        callback();
+      }
+      
+    } else {
+      callback();
+    }
+  }
+  del(row:any){
+    let data = (this.$refs.table as any).getValue();
+    let _index=-1
+    for(const item of data){
+      _index ++;
+      if(item.itemId == row.itemId && item.name == row.name){
+        break
+      }
+    }
+    if(_index >= 0){
+      data.splice(_index,1);
+    }
+    (this.$refs.table as any).setValue(data);
+  }
+  show(){
+    if(this.$refs.baseform){
+      (this.$refs.baseform as any).clearValue();
+    }
+  }
+  hide(){}
+
+  onChangeRow(row:any){
+    console.log(row,Number(row.qty),Number(row.residueQty))
+    if(Number(row.qty) > Number(row.residueQty)){
+      this.$message('数量不能大于可采购数量!');
+      row.qty = '0';
+      this.$forceUpdate()
+    }
+  }
+
+  setShow(v:boolean){
+    this.value = v;
+  }
+
+  setTableData(data:Array<any>){
+    let newData:Array<any>=[]
+    if(data.length > 0){
+      for(const item of data){
+        newData.push({
+          orderId:item.orderId,
+          itemId:item.id,
+          name:item.name,
+          residueQty:item.residueQty,
+          qty:item.residueQty,
+          price:item.price
+        })
+      }
+    }
+    this.$nextTick(()=>{
+      (this.$refs.table as any).setValue(newData);
+    })
+  }
+
+  handleSupplier(){
+    (this.$refs.supplierModal as any).setShow(true);
+  }
+
+  confirm(data:Array<any>){
+    if(data.length == 0){
+      this.$message('请选择供应商!')
+      return
+    }
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.organizationName = data[0].name;
+    value.organizationId = data[0].id;
+    (this.$refs.baseform as any).setValue(value);
+  }
+  organizationClear(){
+    let value:any = (this.$refs.baseform as any).getValue();
+    value.organizationName = '';
+    value.organizationId = '';
+    (this.$refs.baseform as any).setValue(value);
+  }
+  btn(){
+    (this.$refs.baseform as any).validate().then(()=>{
+      let value:any = (this.$refs.baseform as any).getValue();
+      let data:Array<any>=(this.$refs.table as any).getValue();
+      if(data.length > 0){
+        value.items = data;
+        this.load = true;
+        toPurchaseOrder(value).then((res:any)=>{
+          this.load = false;
+          this.value = false;
+          this.$message({
+            message:'采购单已生成!',
+            type:'success'
+          })
+          this.$emit('handleSuccess');
+        }).catch((err:any) => {
+          this.load = false;
+        })
+      }else{
+        this.$message({
+          message:'采购的商品不能为空!',
+          type:'warning'
+        })
+      }
+      
+    }).catch(() => {})
+    
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
+
+<style lang="scss">
+.input-organizationName{
+  .el-input-group__append{
+    background-color: #fff !important;
+  }  
+}
+</style>

+ 202 - 0
src/views/oms/B2COrder/components/questModel.vue

@@ -0,0 +1,202 @@
+<template>
+  <vxe-modal v-model="value" id="questModel" width="70%" v-loading="load" @show="show" @hide="hide" height="80%" show-zoom resize transfer show-footer>
+    <template #title>
+      <span>异常类型</span>
+    </template>
+    <by-table :propConfig="tableConfig" ref="table" id="quest-table">
+      <template v-slot:ordered="{row}">
+        <span v-if="row.isSystem == 1">{{ row.ordered }}</span>
+        <vxe-input v-else v-model="row.ordered" size="small" type="number"></vxe-input>
+      </template>
+      <template v-slot:priority="{row}">
+        <span v-if="row.isSystem == 1">{{ row.priority }}</span>
+        <vxe-input v-else v-model="row.priority" size="small" type="number"></vxe-input>
+      </template>
+      <template v-slot:isShow="{row}">
+        <el-switch
+          v-model="row.isShow"
+          :active-value="1"
+          :inactive-value="0"
+          @change="changeShow($event,row)"
+          :disabled="row.isSystem == 1">
+        </el-switch>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="add">新增</el-button>
+      </div>
+    </template>
+    <add-quest-model ref="addQuestModel" @handleSuccess="handleSuccess" />
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { queryAll,updateOrdered,updatePriority,updateShow,del } from '@/api/question'
+import AddQuestModel from "./addQuest.vue";
+@Component({components:{AddQuestModel}})
+export default class QuestModel extends Vue {
+  value=false;
+  load=false;
+  tableConfig:any={
+    attr:{
+      size:'mini',
+      align:'center',
+      seq:true
+    },
+    columns:[{
+      title:'类型',
+      field:'type',
+      width:240
+    },{
+      title:'排序',
+      field:'ordered',
+      slot:true
+    },{
+      title:'优先级',
+      field:'priority',
+      slot:true
+    },{
+      title:'显示',
+      field:'isShow',
+      slot:true
+    },{
+      title:'操作',
+      action:true,
+      width:200,
+      plugins:[{
+        name:'排序',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.sortHandle(row);
+          }
+        }
+      },{
+        name:'优先级',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.priorityHandle(row)
+          }
+        }
+      },{
+        name:'删除',
+        event:{
+          show:(row:any) => {
+            return row.isSystem != 1
+          },
+          click:(row:any) => {
+            this.delHandle(row);
+          }
+        }
+      }]
+    }]
+  }
+  questData:Array<any>=[]
+  
+  mounted(){
+    
+  }
+  sortHandle(row:any){
+    this.load = true;
+    updateOrdered({
+      id:row.id,
+      ordered:row.ordered
+    }).then(()=>{
+      this.$message({message:'“'+row.type+'”'+'排序修改成功!',type:'success'})
+      this.load = false;
+      this.getQuestionList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  priorityHandle(row:any){
+    this.load = true;
+    updatePriority({
+      id:row.id,
+      priority:row.priority
+    }).then(()=>{
+      this.$message({message:'“'+row.type+'”'+'优先级修改成功!',type:'success'})
+      this.load = false;
+      this.getQuestionList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  changeShow(v:number,row:any){
+    this.load = true;
+    updateShow({
+      id:row.id,
+      isShow:v
+    }).then(()=>{
+      this.$message({message:'“'+row.type+'”'+'显示修改成功!',type:'success'})
+      this.load = false;
+      this.getQuestionList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  delHandle(row:any){
+    this.$confirm('此操作将删除“'+row.type+'”, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+        del({
+          id:row.id,
+        }).then(()=>{
+          this.$message({message:'删除成功!',type:'success'})
+          this.load = false;
+          this.getQuestionList();
+        }).catch(()=>{
+          this.load = false;
+        })
+    }).catch(()=>{})
+  }
+  show(){
+    let height = (document.getElementById('quest-table') as any).parentNode.offsetHeight;
+    this.tableConfig.attr.height=height - 36;
+    (this.$refs.table as any).setConfig(this.tableConfig);
+    this.getQuestionList()
+  }
+  handleSuccess(){
+    this.getQuestionList()
+  }
+  //获取异常数据
+  getQuestionList(){
+    this.load = true;
+    queryAll().then((res:any) => {
+      this.questData = res.data;
+      if(this.$refs.table){
+        (this.$refs.table as any).setValue(this.questData);
+      }
+      this.load = false;
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+
+  setShow(v:boolean){
+    this.value = v;
+  }
+
+  add(){
+    (this.$refs.addQuestModel as any).setShow(true)
+  }
+  hide(){
+    this.$emit('questHide')
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 149 - 0
src/views/oms/B2COrder/components/sendModeModal.vue

@@ -0,0 +1,149 @@
+<template>
+  <vxe-modal v-model="value" id="sendModeModal" :zIndex="9999" width="65%" height="60%" v-loading="load">
+    <template #title>
+      <span>订单发货模式选择</span>
+    </template>
+    <div class="mode">
+      <div class="moda-item" :class="{'onModal': mode==='0'}" @click="modeHandle('0')">
+        <div class="img-tag">
+          <img src="../../../../assets/images/img2.png" />
+        </div>
+        <div class="moda-title">
+          批量逐一发货
+          <div class="check">
+            <i class="el-icon-check"></i>
+          </div>
+        </div>
+        <div class="msg">处理后形成多张物流单</div>
+      </div>
+      <div class="moda-item" :class="{'onModal': mode==='1'}" @click="modeHandle('1')">
+        <div class="img-tag">
+          <img src="../../../../assets/images/img3.png" />
+        </div>
+        <div class="moda-title">
+          整车发货
+          <div class="check">
+            <i class="el-icon-check"></i>
+          </div>
+        </div>
+        <div class="msg">同一客户同一目的地订单形成一张物流单<br />优惠多多</div>
+      </div>
+      <div class="moda-item" :class="{'onModal': mode==='2'}" @click="modeHandle('2')">
+        <div class="img-tag">
+          <img src="../../../../assets/images/img1.png" />
+        </div>
+        <div class="moda-title">
+          快递发货
+          <div class="check">
+            <i class="el-icon-check"></i>
+          </div>
+        </div>
+        <div class="msg">处理后形成新物流单</div>
+      </div>
+    </div>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+@Component({components:{}})
+export default class SendModeModal extends Vue {
+  load=false;
+  value=false;
+  mode='';
+  setShow(v:boolean){
+    this.mode = '';
+    this.value = v;
+  }
+  modeHandle(v:string){
+    this.mode = v;
+    this.value = false;
+    this.$emit('modeChange',v)
+  }
+  show(){
+    
+  }
+  hide(){}
+}
+</script>
+
+<style lang="scss" scoped>
+.mode{
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  .moda-item{
+    width: 244px;
+    height: 300px;
+    box-sizing: border-box;
+    // border:solid 1px #F54319;
+    display: flex;
+    flex-direction: column;
+    // justify-content: space-between;
+    // align-items: center;
+    margin: 0 32px;
+    padding: 16px;
+    border-radius: 5px;
+    background-color: #F4F7FA;
+    border:solid 1px #F4F7FA;
+    cursor: pointer;
+    .img-tag{
+      width: 100%;
+      >img{
+        width: 100%;
+        display: block;
+      }
+    }
+    .check{
+      // width: 100%;
+      // padding: 30px 16px 0;
+      display: flex;
+      justify-content: flex-end;
+      align-items: center;
+      font-size: 16px;
+      position: absolute;
+      padding: 0;
+      top: 30px;
+      right: 0;
+      border: solid 1px #333;
+      border-radius: 50%;
+      .el-icon-check{
+        font-size: 20px;
+        visibility: hidden;
+      }
+      span{
+        padding-left: 16px;
+      }
+    }
+    .msg{
+      font-size: 12px;
+      color: #999;
+      // text-align: center;
+    }
+    .moda-title{
+      font-size: 16px;
+      padding: 32px 0 8px;
+      width: 100%;
+      position: relative;
+      color: #000;
+    }
+  }
+  .moda-item:hover,.onModal{
+    background-color: #FFF;
+    border:solid 1px #0581FE;
+    .check{
+      border:solid 1px #0581FE;
+      background-color: #0581FE;
+      .el-icon-check{
+        visibility: visible;
+        color: #FFF;
+      }
+      span{
+        color: #F54319;
+      }
+    }
+  }
+}
+</style>

+ 95 - 0
src/views/oms/B2COrder/components/setQuesModal.vue

@@ -0,0 +1,95 @@
+<template>
+  <vxe-modal v-model="value" id="setQuest" width="400" v-loading="load" @hide="hide" height="300" show-footer title="转异常单">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { setQuestions } from '@/api/omsOrder'
+@Component({components:{}})
+export default class SetQuesModal extends Vue {
+  value = false;
+  load = false;
+  billValue:Array<any>=[]
+  config:any={
+    attr:{
+      rules:{
+        questionType: [
+          { required: true, message: '请选择类型', trigger: 'change' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'类型',
+        prop:'questionType',
+        labelWidth:'80px',
+        component:'by-select',
+        compConfig:{
+          attr:{
+            data:[],
+            label:'type',
+            value:'id'
+          }
+        }
+      }],
+      [{
+        label:'描述',
+        prop:'questionDesc',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            type:'textarea',
+            rows:3
+          }
+        }
+      }]
+    ]
+  }
+  show(){
+    
+  }
+  setQuestTypeData(data:Array<any>){
+    let c = this.config.columns[0][0].compConfig;
+    c.attr.data = data;
+    if(this.$refs.form){
+      (this.$refs.form as any).setCompConfig('questionType',c)
+    }
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      this.load = true
+      setQuestions(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>

+ 144 - 0
src/views/oms/B2COrder/components/shopModal.vue

@@ -0,0 +1,144 @@
+<template>
+  <vxe-modal v-model="value" id="shopModel" title="选择店铺" width="70%" height="80%" show-zoom resize transfer show-footer v-loading="load">
+    <module-view :propConfig="config" ref="view" v-loading="load" @pagination="pagination" @onRefresh="getList" 
+    @resert="queryList" @search="queryList" />
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { query } from '@/api/shop'
+@Component({components:{}})
+export default class ShopModal extends Vue {
+  value=false;
+  load=false;
+  timeNum = 0;
+  isSearch=false;
+  config:any={
+    attr:{
+      calculateH:true
+    },
+    search:{
+      attr:{
+        size:'small'
+      },
+      columns:[
+        [{
+          label:'店铺名称',
+          prop:'shopName',
+          component:'by-input',
+          compConfig:{}
+        },{
+          label:'店铺简称',
+          prop:'shortName',
+          component:'by-input',
+          compConfig:{}
+        },{
+          label:'所属平台',
+          prop:'channelName',
+          component:'by-input',
+          compConfig:{}
+        }]
+      ]
+    },
+    tool:{
+      tools:{
+        search:true,
+        refresh:true
+      }
+    },
+    table:{
+      attr:{
+        triggerRowCheck:'row',
+        size:'mini',
+        seq:true,
+        radio:true,
+        align:'center',
+      },
+      columns:[{
+        title:'店铺名称',
+        field:'shopName'
+      },{
+        title:'店铺简称',
+        field:'shortName',
+
+      },{
+        title:'所属平台',
+        field:'channelName',
+      }]
+    }
+  }
+  mounted(){
+    
+  }
+  //分页
+  pagination(){
+    if(this.isSearch){
+      this.queryList();
+    }else{
+      this.getList()
+    }
+  }
+  //列表请求(只有分页,不包含搜素条件)
+  getList(){
+    if(!this.$refs.view){
+      if(this.timeNum > 5){
+        return
+      }
+      setTimeout(()=>{
+        this.getList()
+      },500) 
+      this.timeNum ++;
+      return
+    }
+    this.isSearch = false;
+    let data = (this.$refs.view as any).getPage();
+    this.requestList(data);
+  }
+  //列表请求(包含分页和搜素条件)
+  queryList(){
+    this.isSearch = true;
+    let data = (this.$refs.view as any).getQuery();
+    this.requestList(data);
+  }
+  requestList(data:any){
+    this.load = true;
+    query(data).then((res:any) => {
+      this.load = false;
+      (this.$refs.view as any).setTableValue(res.data.records);
+      let page = {
+        pageNo: res.data.current, //当前页
+        pageSize: res.data.size, //每页条数
+        total: res.data.total //总条数
+      };
+      (this.$refs.view as any).setPage(page)
+
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  setShow(v:boolean){
+    this.value = v;
+    this.getList();
+  }
+  btn(){
+    let data = (this.$refs.view as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择店铺!');
+      return
+    }
+    this.$emit('shopSelect',data[0]);
+    this.value = false;
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 169 - 0
src/views/oms/B2COrder/components/splitModal.vue

@@ -0,0 +1,169 @@
+<template>
+  <vxe-modal v-model="value" id="splitModel" title="拆分订单" width="70%" height="80%" min-width="460" min-height="320" show-zoom resize transfer :show-footer="!hideBtn" v-loading="load">
+    <by-table :propConfig="config" ref="table" id="split-table"> 
+      <template v-slot:num="{row}">
+        <vxe-input v-model="row.num" v-if="row.splitNum > 0" placeholder="请输入" type="integer" @input="onChangeRow(row)"></vxe-input>
+      </template>
+    </by-table>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { splitQtyQuery,split } from '@/api/omsOrder'
+@Component({components:{}})
+export default class SplitModel extends Vue {
+  value=false;
+  load=false;
+  billData:any=null;
+  hideBtn=false;
+  data:Array<any>=[]
+  config:any={
+    attr:{
+      size:'small',
+      seq:true
+    },
+    columns:[{
+      title:'名称',
+      field:'name',
+      width:300
+    },{
+      title:'价格',
+      field:'price',
+      width:130
+    },{
+      title:'商品数量',
+      field:'qty',
+      width:130
+    },{
+      title:'可拆分数量',
+      field:'splitNum',
+      width:130
+    },{
+      title:'拆分数量',
+      field:'num',
+      slot:true,
+      // component:'by-input',
+      // compConfig:{
+      //   attr:{
+      //     size:'mini',
+      //     type:'integer'
+      //   }
+      // }
+    }]
+  }
+
+  setShow(v:boolean){
+    this.hideBtn = false;
+    this.value = v;
+  }
+  setData(data:any){
+    if(data){
+      this.billData = data;
+      this.data = [];
+      if(data.items) {
+        for(const item of data.items){
+          item.splitNum = item.qty - item.splitQty
+          this.data.push(item)
+        }
+      }
+      // this.getSplitNum(data);
+    }else{
+      this.billData = null;
+      this.data = [];
+    }
+    this.$nextTick(()=>{
+      let height = (document.getElementById('split-table') as any).parentNode.offsetHeight;
+      this.config.attr.height=height - 36;
+      if(this.$refs.table){
+        (this.$refs.table as any).setConfig(this.config);
+        (this.$refs.table as any).setValue(this.data);
+      }
+    })
+  }
+//获取可拆分数量
+  getSplitNum(v:any){
+    if(!v) return;
+    let data = v.items?v.items:[];
+    if(data.length == 0) return;
+    this.load = true;
+    splitQtyQuery({id:v.id}).then((res:any) => {
+      this.load = false;
+      if(res.data){
+        let j = 0;
+        for(const item of data){
+          let n = Number(res.data[item.id]);
+          if(n){
+            item.splitNum = item.qty - n;
+          }else{
+            item.splitNum = item.qty;
+          }
+          this.data.push(item)
+          if(item.splitNum == 0){
+            j++
+          }
+        }
+        if(j == this.data.length){
+          this.hideBtn = true
+        }
+        (this.$refs.table as any).setValue(this.data);
+      }
+    }).catch((err:any) => {
+      this.load = false
+    })
+  }
+
+  btn(){
+    let data = (this.$refs.table as any).getValue();
+    let info:Array<any>=[];
+    if(data.length == 0){
+      this.$message('未有数据不能执行此操作!')
+      return
+    }
+    for(const item of data){
+      if(Number(item.num) > 0){
+        info.push({
+          qty:Number(item.num),
+          orderItemId:item.id
+        })
+      }
+    }
+    if(info.length == 0){
+      this.$message('请设置拆分数量!')
+      return
+    }
+    this.load = true;
+    split({
+      id:this.billData.id,
+      splitInfos:info
+    }).then((res:any) => {
+      this.load = false;
+      this.$message({
+        message:'拆分成功!',
+        type:'success'
+      })
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch(() => {
+      this.load = false
+    })
+  }
+
+  onChangeRow(row:any){
+    if(Number(row.splitNum) < Number(row.num)){
+      this.$message('拆分数量不能大于可拆分数量!');
+      row.num = 0;
+      this.$forceUpdate()
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 112 - 0
src/views/oms/B2COrder/components/tabModal.vue

@@ -0,0 +1,112 @@
+<template>
+  <vxe-modal v-model="value" id="tagModal" width="60%" v-loading="load" @hide="hide" height="70%" show-footer title="修改标签">
+    <div class="type">
+      <el-radio-group v-model="actionType">
+        <el-radio :label="1">列表新增</el-radio>
+        <el-radio :label="2">列表移除</el-radio>
+      </el-radio-group>
+    </div>
+    <el-scrollbar class="label-group">
+      <el-checkbox-group v-model="labels" :max="10">
+        <div class="label-box">
+          <div class="label-item" v-for="(item,index) of labelData" :key="index">
+            <el-checkbox :label="item.name"></el-checkbox>
+          </div>
+        </div>
+      </el-checkbox-group>
+    </el-scrollbar>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { setLabels } from '@/api/omsOrder'
+import {queryAll, updateOrdered, del} from '@/api/omsLabel'
+@Component({components:{}})
+export default class TabModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  actionType:any=1
+  labels:Array<any>=[]
+  labelData:Array<any>=[]
+  mounted(){
+    this.getList()
+  }
+  hide(){
+    this.actionType = 1;
+    this.labels = [];
+  }
+  getList(){
+    this.load = true;
+    queryAll().then((res:any) => {
+      this.load = false;
+      this.labelData = []
+      if(res.data){
+        this.labelData = res.data
+      }
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+  btn(){
+    let data:any = {};
+    data.actionType = this.actionType
+    data.labels = this.labels;
+    data.idList = this.billValue;
+    this.load = true
+    setLabels(data).then(()=>{
+      this.load = false;
+      (this.$message({
+        message:'操作成功!',
+        type:'success'
+      }));
+      this.$emit('handleSuccess');
+      this.value = false;
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.type{
+  width: 100%;
+  padding-bottom: 16px;
+}
+.label-group{
+  .label-box{
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .label-item{
+    width: 33.3333%;
+  }
+}
+</style>
+
+<style lang="scss">
+.label-group{
+  width: 100%;
+  height: calc(100% - 37px);
+  div.el-scrollbar__wrap {
+    overflow-x: hidden;
+  }
+  .el-scrollbar__bar {
+    right: 0px;
+  }
+}
+</style>

+ 89 - 0
src/views/oms/B2COrder/components/updateRmkModal.vue

@@ -0,0 +1,89 @@
+<template>
+  <vxe-modal v-model="value" id="updateRmkModal" width="400" v-loading="load" @show="show" @hide="hide" height="260" show-footer title="卖家备注">
+    <by-form :propConfig="config" ref="form">
+      <template v-slot:isAppend="{value}">
+        <el-switch
+          v-model="value.isAppend">
+        </el-switch>
+      </template>
+    </by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { updateRemark } from '@/api/omsOrder'
+@Component({components:{}})
+export default class UpdateRmkModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      rules:{
+        remark: [
+          { required: true, message: '卖家备注不能为空!', trigger: 'input' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'卖家备注',
+        prop:'remark',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            type:'textarea'
+          }
+        }
+      }],
+      [{
+        label:'追加备注',
+        prop:'isAppend',
+        labelWidth:'80px',
+        slot:true
+      }]
+    ]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  show(){}
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      this.load = true
+      updateRemark(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 76 - 0
src/views/oms/B2COrder/components/updateSalerModal.vue

@@ -0,0 +1,76 @@
+<template>
+  <vxe-modal v-model="value" id="updateSalerModal" width="400" v-loading="load" @hide="hide" height="200" show-footer title="修改业务员">
+    <by-form :propConfig="config" ref="form"></by-form>
+    <template #footer>
+      <div class="btn">
+        <el-button plain size="small" @click="value = false">取消</el-button>
+        <el-button type="primary" size="small" @click="btn">确定</el-button>
+      </div>
+    </template>
+  </vxe-modal>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import { setCreateUser } from '@/api/omsOrder'
+@Component({components:{}})
+export default class UpdateSalerModal extends Vue {
+  value=false;
+  load=false;
+  billValue:Array<any>=[];
+  config:any={
+    attr:{
+      rules:{
+        createUser: [
+          { required: true, message: '业务员不能为空!', trigger: 'input' }
+        ]
+      }
+    },
+    columns:[
+      [{
+        label:'业务员',
+        prop:'createUser',
+        labelWidth:'80px',
+        component:'by-input',
+        compConfig:{
+          attr:{
+            placeholder:'请输入业务员'
+          }
+        }
+      }]
+    ]
+  }
+  setShow(v:boolean){
+    this.value = v;
+  }
+  setBillValue(data:Array<any>){
+    this.billValue = data;
+  }
+  hide(){
+    (this.$refs.form as any).clearValidate();
+    (this.$refs.form as any).clearValue();
+  }
+  btn(){
+    (this.$refs.form as any).validate().then(()=>{
+      let data = (this.$refs.form as any).getValue();
+      data.idList = this.billValue;
+      this.load = true
+      setCreateUser(data).then(()=>{
+        this.load = false;
+        (this.$message({
+          message:'操作成功!',
+          type:'success'
+        }));
+        this.$emit('handleSuccess');
+        this.value = false;
+      }).catch(()=>{
+        this.load = false;
+      })
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 1284 - 0
src/views/oms/B2COrder/index.vue

@@ -0,0 +1,1284 @@
+<template>
+  <div class="order" v-loading="load">
+    <div class="order-left">
+      <el-scrollbar class="search-content">
+        <el-collapse v-model="activeNames" class="my-collapse">
+          <el-collapse-item name="1">
+            <template slot="title">
+              基本信息<i class="header-icon el-icon-info" title="精确搜索"></i>
+            </template>
+            <input-select :options="myOptions" @input="parameChange" ref="searchCom01" />
+            <input-select :options="outLineOptions" @input="parameChangeBase($event,'idType','idValue')" ref="searchCom02" />
+            <input-select :options="buyerOptions" @input="parameChangeInfo($event,'receiverInfo','receiverValue')" ref="searchCom03" />
+          </el-collapse-item>
+          <order-checkbox title="订单状态" keyName="statusList" ref="searchCom04" :options="statusOptions" noLimit @checkboxChange="onChange($event,'statusList')">
+            <template v-slot:question>
+              <div class="ques-box">
+                <div class="questtion-top" @click="showQues = !showQues">
+                  <div class="quest-title">
+                    <span>异常类型</span>
+                    <i class="el-icon-setting" @click.stop="showQuestType"></i>
+                  </div>
+                  <i class="el-icon-arrow-down"></i>
+                </div>
+                <el-collapse-transition>
+                  <div class="ques-list"  v-show="showQues">
+                    <template v-for="item of questData">
+                      <el-checkbox :label="item.id" v-if="item.isShow == 1" :key="item.value">{{item.type}}</el-checkbox>
+                    </template>
+                  </div>
+                </el-collapse-transition>
+              </div>
+            </template>
+          </order-checkbox>
+          <order-radio title="提交状态" keyName="isSubmitted" ref="searchComsubmitStatus" :options="submitOption" noLimit @radioChange="onChangeSmt" />
+          <order-radio title="买家留言" keyName="buyerMessageFilter" ref="searchCom05" :options="buyerMessageOptions" noLimit @radioChange="onChange($event,'buyerMessageFilter')">
+            <template v-slot:buyerMessage>
+              <el-input style="width: 140px;" v-model="value.buyerMessageContent" size="mini" placeholder="留言内容"></el-input>
+            </template>
+          </order-radio>
+          <order-radio title="卖家备注" keyName="remarkFilter" ref="searchCom06" :options="remarkFilterOptions" noLimit @radioChange="onChange($event,'remarkFilter')">
+            <template v-slot:remarkFilter>
+              <el-input style="width: 140px;" v-model="value.remarkContent" size="mini" placeholder="备注内容"></el-input>
+            </template>
+          </order-radio>
+          <el-collapse-item title="时间" name="time">
+            <div class="orderSelect">
+              <el-select v-model="value.dateType" placeholder="请选择时间类型" size="mini">
+                <el-option
+                  v-for="item in dateTypeOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+              <i class="el-icon-info" title="附加订单时间限制,许多仅限待发货订单的查询条件将自动取消限制"></i>
+            </div>
+            <filter-date @change="onChangeTime" ref="searchCom07" />
+            <!-- <div>付款后几小时未发货:</div>
+            <div class="order-time">
+              <vxe-input v-model="value.deliveryHours" class="deliveryHours-input" clearable type="number" size="mini"></vxe-input>
+              <i class="el-icon-info" title="单位小时,不支持小数位。如果数值大于0,强制为未发货订单。同时勾选店铺可以实现不同平台的未发货时效查询"></i>
+            </div>
+            <filterMinMax title="剩余发货时间(小时)" ref="searchCom08" minField="deliveryRemainingMin" maxField="deliveryRemainingMax" @change="parameChange" /> -->
+          </el-collapse-item>
+          <order-checkbox title="平台订单状态" ref="searchCom09" keyName="shopStatusList" :options="shopStatusListOption" noLimit @checkboxChange="onChange($event,'shopStatusList')" />
+          <order-radio title="线下备注" ref="searchCom10" keyName="noteFilter" :options="noteFilterOptions" noLimit @radioChange="onChange($event,'noteFilter')">
+            <template v-slot:noteContent>
+              <el-input style="width: 140px;" v-model="value.noteContent" size="mini" placeholder="备注内容"></el-input>
+            </template>
+          </order-radio>
+          <order-radio title="操作标记" keyName="operationFlag" ref="searchCom11" :options="sourceFromOptions" noLimit @radioChange="onChange($event,'operationFlag')" />
+          <order-checkbox title="订单类型" keyName="typeList" ref="searchCom12" :options="typeOption" noLimit @checkboxChange="onChange($event,'typeList')" />
+          <el-collapse-item title="付款方式 & 是否付款" name="codAndPay">
+            <div class="box01">
+              <el-radio-group v-model="radio" @input="colChange">
+                <el-radio label="0">不限</el-radio>
+                <el-radio label="1">在线支付</el-radio>
+                <el-radio label="2">货到付款</el-radio>
+              </el-radio-group>
+            </div>
+            <div class="box01">
+              <el-radio-group v-model="radio2" @input="payChange">
+                <el-radio label="0">不限</el-radio>
+                <el-radio label="1">未付款</el-radio>
+                <el-radio label="2">已付款</el-radio>
+              </el-radio-group>
+            </div>
+          </el-collapse-item>
+          <!-- <order-checkbox title="店铺" ref="searchCom13" keyName="shopIdList" :options="shopIdListOptions" @checkboxChange="onChange($event,'shopIdList')" /> -->
+
+          <order-checkbox title="省份" ref="searchCom14" keyName="receiverProvinceCode" :options="provinceOptions" @checkboxChange="onChange($event,'receiverProvinceCodeList')" />
+        </el-collapse>
+      </el-scrollbar>
+      <div class="searchHandle">
+        <el-button size="mini" @click="resert">重置</el-button>
+        <el-button type="primary" size="mini" @click="search">搜索</el-button>
+      </div>
+    </div>
+    <div class="order-right">
+      <div class="tool">
+        <order-tool @addOrder="addOrder" @smt="smtOrder" @reSmt="reSmt" @loadOrder="loadOrder" @producePurchase="producePurchase" @cancelOrder="cancelOrder" 
+        @reCancelOrder="reCancelOrder" @updateRmk="updateRmk" @changeQues="changeQues" @changeNormal="changeNormal" @updateSalesman="updateSalesman" 
+        @updateTag="updateTag" @addGift="addGift" @addProduct="addProduct" @updateFreight="updateFreight" @orderFile="orderFile" @batchSendGoods="batchSendGoods" />
+      </div>
+      <div class="table">
+        <order-table :data="data" ref="orderTable" class="order-table" @detail="detail" @mergeHandle="mergeHandle" @splitHandle="splitHandle" @sendGoods="sendGoods" 
+        @sendGoodsDetail="sendGoodsDetail"/>
+        <div class="page">
+          <el-pagination v-if="page.total > 0" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNo" :page-size="page.pageSize"
+            :layout="'total, sizes, prev, pager, next, jumper'" :total="page.total"></el-pagination>
+        </div>
+      </div>
+
+      <!-- 手工下单 -->
+      <add-order ref="addOrder" @handleSuccess="handleSuccess" />
+      <!-- 手工下载 -->
+      <load-order-modal ref="loadOrder" @handleSuccess="handleSuccess" />
+      <!-- 生成采购单 -->
+      <purchase-model ref="purchaseModel" @handleSuccess="handleSuccess" />
+      <!-- 合并 -->
+      <merge-model ref="mergeModel" @handleSuccess="handleSuccess" />
+      <!-- 拆分 -->
+      <split-model ref="splitModel" @handleSuccess="handleSuccess" />
+      <!-- 取消订单 -->
+      <cancel-order-model ref="cancelOrderModel" @handleSuccess="handleSuccess" />
+      <!-- 异常 -->
+      <quest-model ref="questModel" @questHide="getQuestionList" />
+      <!-- 转异常 -->
+      <set-ques-modal ref="setQuesModal" @handleSuccess="handleSuccess" />
+      <!-- 改卖家备注 -->
+      <update-rmk-modal ref="updateRmkModal" @handleSuccess="handleSuccess" />
+      <!-- 改业务员 -->
+      <update-saler-modal ref="updateSalerModal" @handleSuccess="handleSuccess" />
+      <!-- 改标签 -->
+      <tabModal ref="tabModal" @handleSuccess="handleSuccess" />
+      <!-- 添加赠品 -->
+      <add-product-modal ref="addProductModal" @handleSuccess="handleSuccess" />
+      <!-- 改运费 -->
+      <freight-modal ref="freightModal" @handleSuccess="handleSuccess" />
+      <!-- 标签 -->
+      <labels-modal ref="labelsModal" @onChange="onChangeLabel" />
+      <!-- 发货模式 -->
+      <!-- <send-mode-modal ref="sendModeModal" @modeChange="modeChange" /> -->
+      <!-- 批量逐一发货 -->
+      <!-- <batchbyOneModal ref="batchbyOneModal" @handleSuccess="handleSuccess" /> -->
+      <!-- 整车发货 -->
+      <!-- <carpoolModal ref="carpoolModal" @handleSuccess="handleSuccess" /> -->
+      <!-- 发货单详情 -->
+      <deliveryDetail ref="deliveryDetail" @handleSuccess="handleSuccess" @showLogistics="showLogistics" />
+      <!-- 物流信息 -->
+      <logisticsInfo ref="logisticsInfo" />
+      <!-- 快递发货 -->
+      <express-delivery-modal ref="expressDeliveryModal" @handleSuccess="handleSuccess" />
+    </div>
+  </div>
+</template>
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "vue-property-decorator";
+import filterInput from './components/filterInput.vue'
+import OrderCheckbox from "./components/orderCheckbox.vue";
+import OrderRadio from './components/orderRadio.vue'
+import filterDate from './components/filterDate.vue'
+import OrderTool from "./components/orderTool.vue";
+import OrderTable from "./components/orderTable.vue";
+import AddOrder from "./components/addOrder.vue"; //新增订单
+import InputSelect from "./components/inputSelect.vue";
+import OrderProduct from "./components/orderProduct.vue"; 
+import filterMinMax from './components/filterMinMax.vue'
+import loadOrderModal from './components/loadOrderModal.vue' //手工下载
+import PurchaseModel from "./components/purchaseModel.vue"; //生成采购单
+import MergeModel from "./components/mergeMedal.vue"; //合并
+import SplitModel from "./components/splitModal.vue"; //拆分
+import CancelOrderModel from "./components/cancelOrderModel.vue"; //取消订单
+import QuestModel from "./components/questModel.vue";
+import SetQuesModal from "./components/setQuesModal.vue";
+import UpdateRmkModal from "./components/updateRmkModal.vue";
+import UpdateSalerModal from "./components/updateSalerModal.vue";
+import TabModal from "./components/tabModal.vue";
+import AddProductModal from "./components/addProductModal.vue";
+import FreightModal from "./components/freightModal.vue";
+import LabelsModal from "./components/labelsModal.vue";
+import SendModeModal from "./components/sendModeModal.vue";
+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,ExpressDeliveryModal}})
+export default class Order extends Vue {
+  activeNames:Array<any>=['1','statusList']
+  radio=''
+  radio2=''
+  data:Array<any> = []
+  load = false;
+  showQues=false;
+  isContainLabel=true;
+  page:any={
+    pageNo: 1, //当前页
+    pageSize: 20, //每页条数
+    total: 0 //总条数
+  }
+  questData:Array<any>=[]
+  value:any={
+    // sourceId:'',  //线上订单号
+    // shopBuyerId:'', //买家昵称
+    // buyerId:'', //买家ID
+    // logisticsId:'', //快递单号
+    // logisticsCompany:'', //快递公司
+    // internationalLogisticsId:'', //国际物流单号
+    // isSubmitte:'', //数据是否已提交
+    // drpCoIdFrom:'', //分销商编号
+    // drpCoIdTo:'', //供销商编号
+    // sourceFrom:'', //订单来源
+    // dateType:1,//时间类型
+    // deliveryRemainingMin:0, //订单剩余发货时间(小时)-小于等于
+    // deliveryRemainingMax:null, //订单剩余发货时间(小时)-大于等于
+    // includeSkuType:1, //包含编码类型
+    // type:'', //订单类型
+    // status:'' , //订单状态
+    // excludeSkuType:1, //排除编码类型
+  }
+  myOptions=[{
+    label:'内部订单号',
+    value:'orderId',
+    format:/[^0-9,]*/g
+  }]
+  outLineOptions=[{
+    label:'线上订单号',
+    value:'sourceId'
+  },{
+    label:'支付单号',
+    value:'outerPayId'
+  }]
+  buyerOptions=[{
+    label:'买家账号',
+    value:'buyerId'
+  },{
+    label:'快递单号',
+    value:'logisticsId'
+  },{
+    label:'收件人-省',
+    value:'receiverProvince'
+  },{
+    label:'收件人-市',
+    value:'receiverCity'
+  },{
+    label:'收件人-区',
+    value:'receiverDistrict'
+  },{
+    label:'收货地址',
+    value:'receiverAddress'
+  },{
+    label:'收件人',
+    value:'receiverName'
+  },{
+    label:'手机号',
+    value:'receiverMobile'
+  },{
+    label:'固定电话',
+    value:'receiverPhone'
+  }]
+
+  //买家留言
+  buyerMessageOptions=[{
+    label:'无留言',
+    value:1
+  },{
+    label:'未处理的留言',
+    value:2
+  },{
+    slotName:'buyerMessage',
+    label:'有留言',
+    value:3
+  }]
+  //卖家备注
+  remarkFilterOptions=[{
+    label:'无备注',
+    value:1,
+  },{
+    label:'未处理的备注',
+    value:2,
+  },{
+    label:'有备注',
+    slotName:'remarkFilter',
+    value:3,
+  }]
+  //订单时间类型
+  dateTypeOptions=[{
+    label:'订单时间',
+    value:1
+  },{
+    label:'发货时间',
+    value:2
+  },{
+    label:'付款时间',
+    value:3
+  },{
+    label:'确认收货时间',
+    value:4
+  },{
+    label:'计划发货时间',
+    value:5
+  }]
+  //包含编码类型
+  includeSkuTypeOptions=[{
+    label:'包含任意商品编码',
+    value:1
+  },{
+    label:'包含任意款式编码',
+    value:2
+  },{
+    label:'包含全部商品编码',
+    value:3
+  },{
+    label:'包含全部款式编码',
+    value:4
+  },{
+    label:'仅包含指定商品编码',
+    value:5
+  },{
+    label:'仅包含指定款式编码',
+    value:6
+  },{
+    label:'包含任意店铺商品编码',
+    value:7
+  },{
+    label:'包含任意店铺款式编码',
+    value:8
+  }]
+  //排除编码类型
+  excludeSkuTypeOptions=[{
+    label:'排除任意商品编码',
+    value:1
+  },{
+    label:'排除任意款式编码',
+    value:2
+  }]
+  //平台订单状态
+  shopStatusListOption:Array<any>=[{
+    label:'没有创建支付宝交易',
+    value:1
+  },{
+    label:'等待买家付款',
+    value:2
+  }]
+
+  noteFilterOptions:Array<any>=[{
+    label:'无备注',
+    value:1,
+  },{
+    label:'有备注',
+    slotName:'noteContent',
+    value:2,
+  }]
+
+  //订单来源
+  sourceFromOptions:Array<any>=[{
+    label:'手工下单',
+    value:'OMS'
+  },{
+    label:'复制',
+    value:'COPY'
+  },{
+    label:'合并',
+    value:'MERGE'
+  },{
+    label:'拆分;拆分还原',
+    value:'SPLIT'
+  },{
+    label:'手机',
+    value:'MOBILE'
+  },{
+    label:'导入',
+    value:'IMPORT'
+  },{
+    label:'供销推送',
+    value:'DRP-S'
+  },{
+    label:'快手;微商城',
+    value:'KWAISHOP'
+  },{
+    label:'拼多多',
+    value:'PINDUODUO'
+  },{
+    label:'头条放心购',
+    value:'TOUTIAOFXG'
+  },{
+    label:'聚水潭',
+    value:'JUSHUITAN'
+  }]
+
+  //审批状态
+  submitOption:Array<any>=[{
+    label:'未提交',
+    value:0
+  },{
+    label:'已提交',
+    value:1
+  }]
+
+  //订单类型
+  typeOption:Array<any>=[{
+    label:'普通订单',
+    value:'Common'
+  },{
+    label:'补发订单',
+    value:'Reissue'
+  },{
+    label:'分销Plus',
+    value:'DistributionPlus'
+  },{
+    label:'供销Plus',
+    value:'SupplyPlus'
+  },{
+    label:'换货订单',
+    value:'Exchange'
+  }]
+
+  //订单状态 
+  statusOptions:Array<any>=[{
+    label:'待付款',
+    value:'WaitPay'
+  },{
+    label:'被合并',
+    value:'Merged'
+  },{
+    label:'被拆分',
+    value:'Split'
+  },{
+    label:'等供销商|外仓发货',
+    value:'WaitOuterSent'
+  },{
+    label:'已付款待审核',
+    value:'WaitConfirm'
+  },{
+    label:'已客审待财审',
+    value:'WaitFConfirm'
+  },{
+    label:'发货中',
+    value:'Delivering'
+  },{
+    label:'已发货',
+    value:'Sent'
+  },{
+    label:'取消',
+    value:'Cancelled'
+  },{
+    label:'异常',
+    value:'Question',
+    slot:true,
+    slotName:'question'
+  }]
+  shopIdListOptions:Array<any>=[]
+
+  //省份
+  provinceOptions:Array<any>=[]
+
+  mounted(){
+    this.getList();
+    this.getProvince();
+    this.getQuestionList();
+  }
+  //查看物流
+  showLogistics(code:string){
+    if(this.$refs.logisticsInfo){
+      (this.$refs.logisticsInfo as any).setShow(true);
+      (this.$refs.logisticsInfo as any).loadData(code);
+    }
+  }
+  //发货详情
+  sendGoodsDetail(row:any){
+    if(this.$refs.deliveryDetail){
+      (this.$refs.deliveryDetail as any).setShow(true);
+      (this.$refs.deliveryDetail as any).setData(row.id);
+    }
+  }
+  //批量发货
+  batchSendGoods(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:string='';
+    let noStatus = ['WaitPay','Delivering','Merged','Split','Question','Sent','Cancelled'];
+    for(const item of data){
+      if(!(item.isSubmitted == 1 && item.pays && item.pays.length > 0 && noStatus.indexOf(item.status) == -1)){
+        ids = ids ? ids + ',' + item.id : item.id;
+      }
+    }
+    if(ids){
+      this.$message('订单“ ' + ids + ' ”不符合发货条件!');
+      return
+    }
+    // if(data.length == 1){
+
+    //   (this.$refs.deliveryModal as any).setShow(true);
+    // }else{
+      // if(this.$refs.sendModeModal){
+      //   (this.$refs.sendModeModal as any).setShow(true);
+      // }
+    // }
+    if(this.$refs.expressDeliveryModal){
+      (this.$refs.expressDeliveryModal as any).setShow(true);
+      (this.$refs.expressDeliveryModal as any).setValue(data);
+    }
+  }
+  //发货模式
+  modeChange(v:string){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    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': // 整车发货
+        let isShow = true
+        for (const item of data) {
+          if(!(data[0].buyerId === item.buyerId && data[0].receiverName === item.receiverName && data[0].receiverTownCode === item.receiverTownCode && data[0].receiverAddress === item.receiverAddress && data[0].receiverMobile === item.receiverMobile)) {
+            isShow = false;
+            break
+          }
+        }
+        if(!isShow) {
+          this.$message({
+            message: '整车发货必须是同一买家!',
+            type: 'warning'
+          })
+        }
+        if(this.$refs.carpoolModal && isShow){
+          (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);
+        }
+    }
+  }
+  //整车发货
+  sendGoods(item:any){
+    (this.$refs.batchbyOneModal as any).setShow(true);
+    (this.$refs.batchbyOneModal as any).setValue([item]);
+    // (this.$refs.deliveryModal as any).setShow(true);
+  }
+  //显示标签弹窗
+  showLabels(){
+    this.isContainLabel = true;
+    if(this.$refs.labelsModal){
+      (this.$refs.labelsModal as any).setShow(true);
+    }
+  }
+  showLabels2(){
+    this.isContainLabel = false;
+    if(this.$refs.labelsModal){
+      (this.$refs.labelsModal as any).setShow(true);
+    }
+  }
+  //标签弹窗返回信息
+  onChangeLabel(v:string){
+    if(this.isContainLabel){
+      if(this.value.includeLabels){
+        Vue.set(this.value, 'includeLabels', v);
+      }else{
+        this.value.includeLabels = v;
+      }
+      
+    }else{
+      if(this.value.excludeLabels){
+        Vue.set(this.value, 'excludeLabels', v);
+      }else{
+        this.value.excludeLabels = v;
+      }
+    }
+    this.$forceUpdate()
+  }
+  labelsClear(v?:boolean){
+    if(v){
+      delete this.value.includeLabels;
+    }else{
+      delete this.value.excludeLabels;
+    }
+    this.$forceUpdate()
+  }
+  //归档
+  orderFile(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids='';
+    let idsArr:Array<any>=[];
+    for(const item of data){
+      ids = ids ? ids + ',' + item.id : item.id;
+      idsArr.push(item.id)
+    }
+    this.$confirm('归档后数据无法恢复,您确定将订单“'+ ids +'”归档?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      this.load = true;
+      archive({idList:idsArr}).then((res:any) => {
+        this.$message({
+          message:res.msg ? res.msg : '归档成功!',
+          type:'success'
+        });
+        this.load = false;
+        this.getList();
+      }).catch(() => {
+        this.load = false;
+      })
+    }).catch(() => {  });
+  }
+  //改运费
+  updateFreight(){
+    this.updateHandleModal('freightModal');
+  }
+  //添加商品
+  addProduct(){
+    this.updateHandleModal('addProductModal');
+  }
+  //添加赠品
+  addGift(){
+    this.updateHandleModal('addProductModal');
+    (this.$refs.addProductModal as any).setGift(true);
+  }
+  
+  //改标签
+  updateTag(){
+    this.updateHandleModal('tabModal')
+  }
+  //改业务员
+  updateSalesman(){
+    this.updateHandleModal('updateSalerModal')
+  }
+  //改备注
+  updateRmk(){
+    this.updateHandleModal('updateRmkModal')
+  }
+  updateHandleModal(n:string){
+    let data = (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let billData:Array<any>=[]
+    for(const item of data){
+      billData.push(item.id);
+    }
+    (this.$refs[n] as any).setBillValue(billData);
+    (this.$refs[n] as any).setShow(true);
+  }
+  //转异常
+  changeQues(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let msg = '';
+    let billData:Array<any>=[]
+    for(const item of data){
+      billData.push(item.id);
+      if(item.status == 'Question'){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”状态异常,不能执行此操作!'
+      })
+      return
+    }
+    (this.$refs.setQuesModal as any).setBillValue(billData);
+    (this.$refs.setQuesModal as any).setQuestTypeData(this.questData);
+    (this.$refs.setQuesModal as any).setShow(true);
+  }
+  //转正常
+  changeNormal(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let msg = '';
+    let billData:Array<any>=[]
+    for(const item of data){
+      billData.push(item.id);
+      if(item.status != 'Question'){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”状态正常,不能执行此操作!'
+      })
+      return
+    }
+    this.load = true
+    resetQuestion({idList:billData}).then((res:any)=>{
+      this.load = false;
+      (this.$message({
+        message:res.msg?res.msg:'操作成功!',
+        type:'success'
+      }));
+      this.getList();
+    }).catch(()=>{
+      this.load = false;
+    })
+  }
+  //异常数据弹窗
+  showQuestType(){
+    (this.$refs.questModel as any).setShow(true);
+  }
+  //获取异常数据
+  getQuestionList(){
+    queryAll().then((res:any) => {
+      this.questData = res.data;
+    }).catch(() => { })
+  }
+
+  //生成采购单
+  producePurchase(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let msg:string='';
+    let ids:Array<any>=[];
+    for(const item of data){
+      if(item.isSubmitted != 1){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+      ids.push(item.id)
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”未提交,不能生成采购单!'
+      })
+      return
+    }
+    purchaseQty({
+      ids:ids
+    }).then((res:any) => {
+      let productData:Array<any>=[];
+      for(const item of data){
+        for(const childItem of item.items){
+          childItem.orderId = item.id;
+          childItem.residueQty = childItem.qty;
+          productData.push(childItem)
+        }
+      }
+      if(res.data.length){
+        for(const item of productData){
+          for(const _item of res.data){
+            if(item.id == _item.itemId){
+              item.residueQty = _item.residueQty >= 0 ?  _item.residueQty : item.qty
+            }
+          }
+        }
+      }
+      for(let i = productData.length - 1; i>=0; i--){
+        if(productData[i] && productData[i].residueQty == 0){
+          productData.splice(i,1)
+        }
+      }
+      (this.$refs.purchaseModel as any).setShow(true);
+      (this.$refs.purchaseModel as any).setTableData(productData);
+    })
+  }
+  //重置搜索数据
+  clearSearchValue(){
+    this.value={};
+    for(const key in this.$refs){
+      if(key.indexOf('searchCom') >= 0 && (this.$refs[key] as any).clear){
+        (this.$refs[key] as any).clear()
+      }
+    }
+    this.value.dateType = 1;
+    this.value.includeSkuType = 1;
+  }
+  resert(){
+    this.clearSearchValue();
+    this.radio = ''
+    this.radio2 = ''
+    this.page.pageNo = 1;
+    this.getList();
+  }
+  //搜索
+  search(){
+    this.page.pageNo = 1;
+    this.getList();
+  }
+  //合并操作
+  mergeHandle(data:Array<any>){
+    if(this.$refs.mergeModel){
+      (this.$refs.mergeModel as any).setShow(true);
+      (this.$refs.mergeModel as any).setData(data);
+    }
+  }
+  //拆单
+  splitHandle(row:any){
+    if(this.$refs.splitModel){
+      (this.$refs.splitModel as any).setShow(true);
+      (this.$refs.splitModel as any).setData((this as any).$lodash.cloneDeep(row));
+    }
+  }
+  addOrder(){
+    (this.$refs.addOrder as any).setShow(true)
+  }
+  smtOrder(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let msg = '';
+    let smtMst='';
+    for(const item of data){
+      if(item.isSubmitted == 1){
+        if(smtMst){
+          smtMst = smtMst + ',' + item.id
+        }else{
+          smtMst = item.id
+        }
+      }
+      if(!item.pays && item.pays.length == 0){
+        if(msg){
+          msg = msg + ',' + item.id
+        }else{
+          msg = item.id
+        }
+      }
+      ids.push(item.id)
+    }
+    if(smtMst){
+      this.$message({
+        message:'订单“'+smtMst + '”已提交,不能重复操作!'
+      })
+      return
+    }
+    if(msg){
+      this.$message({
+        message:'订单“'+msg + '”未付款,不能提交!'
+      })
+      return
+    }
+    this.load = true;
+    smt({
+      ids:ids
+    }).then((res:any) => {
+      this.load = false;
+        (this as any).$message({
+          message: res.msg?res.msg:'订单提交成功!',
+          type: 'success'
+        });
+      this.getList();
+    })
+  }
+  reSmt(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let smtMst:string='';
+    for(const item of data){
+      if(item.isSubmitted == 0){
+        if(smtMst){
+          smtMst = smtMst + ',' + item.id
+        }else{
+          smtMst = item.id
+        }
+      }
+      ids.push(item.id)
+    }
+    if(smtMst){
+      this.$message({
+        message:'订单“'+smtMst + '”未提交,不能进行此操作!'
+      })
+      return
+    }
+    this.load = true;
+    unSmt({
+      ids:ids
+    }).then((res:any) => {
+      this.load = false;
+        (this as any).$message({
+          message: res.msg?res.msg:'订单取消提交成功!',
+          type: 'success'
+        });
+      this.getList();
+    })
+  }
+  getProvince(){
+    this.provinceOptions = [];
+    getProvince({
+      pid:'0'
+    }).then((res:any) => {
+      if(res.data){
+        for(const item of res.data){
+          this.provinceOptions.push({
+            label:item.extName,
+            value:item.id
+          })
+        }
+      }
+    })
+  }
+
+  //组件返回事件
+  onChange(v:any,code:string){
+    this.value[code] = v;
+  }
+  parameChange(parames:any){
+    for(const key in parames){
+      if(parames[key]){
+        if(this.value[key]){
+          this.value[key] = parames[key].split(',')
+        }else{
+          Vue.set(this.value, key, parames[key].split(','));
+        }
+      }else{
+        delete this.value[key]
+      }
+    }
+  }
+  parameChangeBase(parames:any,n1:string,n2:string){
+    for(const key in parames){
+      if(parames[key]){
+        this.value[n1] = key;
+        this.value[n2] = parames[key].split(',');
+      }else{
+        this.value[n1] = '';
+        this.value[n2] = [];
+      }
+    }
+  }
+  parameChangeInfo(parames:any,n1:string,n2:string){
+    for(const key in parames){
+      if(parames[key]){
+        this.value[n1] = key;
+        this.value[n2] = parames[key];
+      }else{
+        this.value[n1] = '';
+        this.value[n2] = '';
+      }
+    }
+  }
+  onChangeSmt(v:any){
+    if(v == 1){
+      this.value.submitStatus = true
+    }else if(v == 0){
+      this.value.submitStatus = false
+    }
+  }
+  colChange(v:any){
+    if(v == 1){
+      this.value.isCod = false
+    }else if(v == 2){
+      this.value.isCod = true
+    }else{
+      this.value.isCod = null
+    }
+  }
+  payChange(v:any){
+    if(v == 1){
+      this.value.isPay = false
+    }else if(v == 2){
+      this.value.isPay = true
+    }else{
+      this.value.isPay = null
+    }
+  }
+  onChangeTime(v:Array<any>){
+    this.value.dateBegin = v[0];
+    this.value.dateEnd = v[1];
+  }
+  //获取订单列表数据
+  getList(){
+    let data:any = (this as any).$lodash.cloneDeep(this.value);
+    let params:any={};
+    if(data.includeLabels){
+      data.includeLabels = data.includeLabels.split(',');
+    }
+    if(data.excludeLabels){
+      data.excludeLabels = data.excludeLabels.split(',');
+    }
+    data.businessType = 'B2C'
+    params.pageNo = this.page.pageNo;
+    params.pageSize = this.page.pageSize;
+    this.load = true;
+    query(params,data).then((res:any) => {
+      this.data = res.data.records;
+      this.page.pageNo = res.data.current;
+      this.page.total = res.data.total;
+      this.load = false;
+      this.$forceUpdate();
+    }).catch((err:any) => {
+      this.load = false;
+    })
+  }
+  //订单操作成功刷新页面
+  handleSuccess(){
+    this.page.pageNo = 1;
+    this.clearSearchValue();
+    this.getList();
+  }
+  //订单详情
+  detail(row:any){
+    let data = (this as any).$lodash.cloneDeep(row);
+    (this.$refs.addOrder as any).setDetail(data); 
+    (this.$refs.addOrder as any).setShow(true);
+  }
+
+  handleSizeChange(v:number){
+    this.page.pageSize = v;
+    this.getList();
+  }
+  handleCurrentChange(v:number){
+    this.page.pageNo = v;
+    this.getList();
+  }
+  //取消订单
+  cancelOrder(){
+    let condi=['WaitPay','Delivering','Question','WaitOuterSent','WaitConfirm','WaitFConfirm'];
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let msgIds='';
+    for(const item of data){
+      if(condi.indexOf(item.status) >= 0){
+        ids.push(item.id)
+      }else{
+        if(msgIds){
+          msgIds = msgIds + ',' + item.id
+        }else{
+          msgIds = item.id
+        }
+      }
+    }
+    if(msgIds){
+      this.$message({
+        message:'订单“'+msgIds + '”不满足取消条件!'
+      })
+      return
+    }
+    (this.$refs.cancelOrderModel as any).setShow(true);
+    (this.$refs.cancelOrderModel as any).setData(ids);
+  }
+  //反取消订单
+  reCancelOrder(){
+    let data:Array<any>= (this.$refs.orderTable as any).getSelectData();
+    if(data.length == 0){
+      this.$message('请选择订单!');
+      return
+    }
+    let ids:Array<any>=[];
+    let msgIds='';
+    for(const item of data){
+      if(item.status == 'Cancelled'){
+        ids.push(item.id)
+      }else{
+        if(msgIds){
+          msgIds = msgIds + ',' + item.id
+        }else{
+          msgIds = item.id
+        }
+      }
+    }
+    if(msgIds){
+      this.$message({
+        message:'订单“'+msgIds + '”订单未取消,不能执行此操作!'
+      })
+      return
+    }
+    this.load = true;
+    unCancel({idList:ids}).then((res:any)=>{
+      this.load = false;
+      this.$message({
+        message:res.msg?res.msg:'订单反取消成功!',
+        type:'success'
+      })
+      this.handleSuccess();
+    }).catch(()=>{
+      this.load = false
+    })
+  }
+
+  //同步店铺订单
+  loadOrder(){
+    (this.$refs.loadOrder as any).setShow(true);
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.order{
+  width: 100%;
+  height: 100%;
+  display: flex;
+  overflow-y: hidden;
+  .order-left{
+    width: 260px;
+    height: 100%;
+    flex-shrink: 0;
+    background-color: #f0f0f0;
+    border-right: solid 1px #CCC;
+    box-sizing: border-box;
+    padding: 4px 4px 0;
+    position: relative;
+    .my-collapse{
+      padding: 0 4px;
+      background: #FFF;
+    }
+
+    .searchHandle{
+      display: flex;
+      justify-content: center;
+      width: 100%;
+      box-sizing: border-box;
+      padding: 8px;
+      background-color: #f0f0f0;
+    }
+    .box01{
+      width: 100%;
+      padding-bottom: 8px;
+    }
+  }
+  .filter-box{
+    width: calc(100% - 8px);
+    background-color: #FFF;
+    box-sizing: border-box;
+    padding: 8px;
+    border:solid 1px #EEE;
+    
+    .filter-row:last-child{
+      padding: 0;
+    }
+  }
+  .order-right{
+    width: calc(100% - 260px);
+    box-sizing: border-box;
+    padding-left: 8px;
+    height: 100%;
+    min-width: 850px;
+    overflow-x: auto;
+    .tool{
+      width: 100%;
+    }
+    .table{
+      width: 100%;
+      height: calc(100% - 40px);
+      .order-table{
+        width: 100%;
+        height: calc(100% - 48px);
+      }
+      .page{
+        width: 100%;
+        display: flex;
+        justify-content: flex-end;
+        padding: 8px;
+        box-sizing: border-box;
+      }
+    }
+  }
+  .el-icon-info{
+    font-size: 16px;
+    margin-left: 4px;
+  }
+}
+// .order-label{
+//   font-size: 12px;
+// }
+.orderSelect{
+  width: 100%;
+  margin-bottom: 4px;
+}
+.order-time{
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 4px;
+}
+.ques-box{
+  .questtion-top{
+    height: 30px;
+    display: flex;
+    justify-content:space-between;
+    align-items: center;
+    padding: 0 16px;
+    background-color: #EEE;
+    cursor: pointer;
+    .quest-title{
+      height: 30px;
+      font-size: 12px;
+      display: flex;
+      align-items: center;
+    }
+    .el-icon-setting{
+      padding-right: 8px;
+      color: #2d99f7;
+      margin-left: 4px;
+    }
+    i{
+      font-size: 16px;
+      cursor: pointer;
+    }
+  }
+  .ques-list{
+    overflow: hidden;
+    padding-left: 16px;
+  }
+}
+</style>
+
+<style lang="scss">
+.order-left{
+  .el-collapse-item__content{
+    padding-bottom: 0;
+  }
+  .el-collapse-item__header{
+    font-weight: 700 !important;
+  }
+}
+.deliveryHours-input{
+  width: 80px; 
+  flex-shrink: 0; 
+  padding: 0;
+  .el-input__inner{
+    padding: 0 !important;
+    text-align: center;
+  }
+}
+.search-content{
+  height: calc(100% - 44px);
+  div.el-scrollbar__wrap {
+    overflow-x: hidden;
+  }
+  .el-scrollbar__bar {
+    right: 0px;
+  }
+}
+.labels-width-btn{
+  margin-bottom: 8px;
+  .el-input-group__append{
+    background-color: #fff !important;
+    width: 30px !important;
+    padding: 0 10px;
+    .el-icon-more{
+      font-size: 16px;
+    }
+  }  
+}
+</style>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.