ソースを参照

Merge commit '907475f3010bc2042a207913148f6dabf8bc09e6' into HEAD

gitadmin 1 日 前
コミット
13658b0e79
31 ファイル変更2326 行追加52 行削除
  1. BIN
      public/templ/批量上线导入模板.xlsx
  2. 1 1
      public/version.json
  3. 33 0
      src/api/product.js
  4. 0 1
      src/components/UploadFile/index.vue
  5. 73 0
      src/config/router.config.js
  6. 87 0
      src/layouts/MobileLayout.vue
  7. 87 0
      src/layouts/MobilePageLayout.vue
  8. 3 1
      src/layouts/index.js
  9. 54 0
      src/mobile/Home.vue
  10. 188 0
      src/mobile/inventoryManagement/inventoryQuery/detailModal.vue
  11. 334 0
      src/mobile/inventoryManagement/inventoryQuery/list.vue
  12. 300 0
      src/mobile/inventoryManagement/inventoryQuery/warehouseDetail.vue
  13. 146 0
      src/mobile/productManagement/productPricing/auditModal.vue
  14. 272 0
      src/mobile/productManagement/productPricing/editModal.vue
  15. 429 0
      src/mobile/productManagement/productPricing/list.vue
  16. 4 4
      src/router/index.js
  17. 15 0
      src/utils/util.js
  18. 28 8
      src/views/productManagement/productInfo/importGuideModal.vue
  19. 3 2
      src/views/productManagement/productInfo/list.vue
  20. 177 0
      src/views/productManagement/productInfo/onlineImportModal.vue
  21. 17 7
      src/views/reportData/dailyReport/table0.vue
  22. 28 2
      src/views/reportData/dailyReport/table3.vue
  23. 1 1
      src/views/salesManagement/salesQueryNew/comps/activeQueryPart.vue
  24. 1 1
      src/views/salesManagement/salesQueryNew/comps/queryPart.vue
  25. 14 2
      src/views/salesManagement/salesQueryNew/printModal.vue
  26. 0 2
      src/views/salesManagement/sendOutOrder/chooseImportModal.vue
  27. 21 7
      src/views/setting/removeSetting/baseModal.vue
  28. 2 2
      src/views/setting/removeSetting/index.vue
  29. 5 4
      src/views/setting/removeSetting/list.vue
  30. 2 6
      src/views/user/Login.vue
  31. 1 1
      vue.config.js

BIN
public/templ/批量上线导入模板.xlsx


+ 1 - 1
public/version.json

@@ -1,4 +1,4 @@
 {
-    "version": "2.2.063",
+    "version": "2.2.064",
     "message": "发现有新版本发布,确定更新系统?"
 }

+ 33 - 0
src/api/product.js

@@ -569,6 +569,39 @@ export const saveBatchImportProduct = (params) => {
   })
 }
 
+// 批量导入上线产品
+export const batchImportOnlineProduct = (params) => {
+  return axios({
+    url: '/product/importOnline',
+    data: params,
+    method: 'post',
+  })
+}
+
+// 导出错误项上线产品
+export const exportErrorOnlineProduct = (params) => {
+  return axios({
+    url: '/product/importOnlineError',
+    data: params,
+    method: 'post',
+    responseType: 'blob',
+    headers:{
+        'module': encodeURIComponent('导出错误项上线产品')
+    }
+  })
+}
+// 批量保存上线产品
+export const saveBatchImportOnlineProduct = (params) => {
+  return axios({
+    url: '/product/onlineBatch',
+    data: params,
+    method: 'post',
+    headers:{
+        'module': encodeURIComponent('批量导入上线产品')
+    }
+  })
+}
+
 // 价格变更状态
 export const priceChangeEnabled = (params) => {
   return axios({

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

@@ -234,7 +234,6 @@ export default {
               }
             }
           })
-          // console.log(temp)
           obj = JSON.stringify(temp)
         }
       }

+ 73 - 0
src/config/router.config.js

@@ -2,6 +2,8 @@
 import {
   UserLayout,
   BasicLayout,
+  MobileLayout,
+  MobilePageLayout,
   BlankLayout,
   BigScreen,
   PageView
@@ -82,6 +84,77 @@ export const asyncRouterMap = [
   }
 ]
 
+/**
+ * 移动端路由
+ * @type { *[] }
+ */
+export const asyncMobileRouterMap = [
+  {
+    path: '/',
+    name: 'index',
+    component: MobileLayout,
+    meta: {
+      title: '首页'
+    },
+    redirect: '/home',
+    children: [
+       {
+         path: '/home',
+         name: 'home',
+         component: () => import(/* webpackChunkName: "mobileRouter" */ '@/mobile/Home'),
+         meta: {
+           title: '首页',
+           icon: 'home',
+           hidden: true
+         }
+       }
+    ]
+  },
+  {
+    path: '/page',
+    name: 'page',
+    component: MobilePageLayout,
+    redirect: '/inventoryQuery',
+    children: [
+       {
+         path: '/inventoryQuery',
+         name: 'inventoryQuery',
+         component: () => import(/* webpackChunkName: "mobileRouter" */ '@/mobile/inventoryManagement/inventoryQuery/list.vue'),
+         meta: {
+           title: '库存查询',
+           icon: 'monitor',
+           permission: 'M_inventoryQueryList'
+         }
+       },
+       {
+         path: '/warehouseDetail/:sn/:warehouseSn',
+         name: 'inventoryQueryWarehouseDetail',
+         component: () => import(/* webpackChunkName: "mobileRouter" */ '@/mobile/inventoryManagement/inventoryQuery/warehouseDetail.vue'),
+         meta: {
+           title: '出入库明细',
+           icon: 'monitor',
+           permission: 'B_inventoryQuery_rkDetail'
+         }
+       },
+       {
+         path: '/productPricing',
+         name: 'productPricing',
+         component: () => import(/* webpackChunkName: "mobileRouter" */ '@/mobile/productManagement/productPricing/list.vue'),
+         meta: {
+           title: '产品定价',
+           icon: 'transaction',
+           permission: 'M_productPricingList'
+         }
+       }
+    ]
+  },
+  {
+    path: '*',
+    redirect: '/404',
+    hidden: true
+  }
+]
+
 /**
  * 基础路由
  * @type { *[] }

+ 87 - 0
src/layouts/MobileLayout.vue

@@ -0,0 +1,87 @@
+<script>
+import { mixin } from '@/utils/mixin'
+import { mapActions, mapGetters } from 'vuex'
+export default {
+  name: 'MobileLayout',
+  components: {
+  },
+  mixins: [mixin],
+  computed: {
+    ...mapGetters(['nickname', 'avatar'])
+  },
+  methods: {
+    ...mapActions(['Logout']),
+    handleLogout () {
+      this.$confirm({
+        title: '提示',
+        content: '确定要退出登录吗 ?',
+        centered: true,
+        onOk: () => {
+          return this.Logout({}).then(() => {
+            setTimeout(() => {
+              this.$router.push({ path: '/user/login' })
+            }, 16)
+          }).catch(err => {
+            this.$message.error({
+              title: '错误',
+              description: err.message
+            })
+          })
+        },
+        onCancel () {
+        }
+      })
+    },
+    handleToHome () {
+      this.$router.push({ name: 'home' })
+    }
+  }
+}
+</script>
+
+<template>
+  <a-layout id="components-layout-mobile-fixed">
+    <a-layout-header :style="{ position: 'fixed', zIndex: 1, width: '100%',padding:'0 10px' }">
+      <div class="logo">
+        <img src="@/assets/logo.png" height="30px">
+        运营中心系统
+      </div>
+      <div class="user-wrapper">
+        <a-icon type="user" />
+        <span style="margin: 0 5px;">{{ nickname }}</span>
+        <a href="javascript:;" style="margin-left: 10px;color: #ff5500;" @click="handleLogout">
+          <a-icon type="logout"/>
+          <span style="margin: 0 5px;">退出</span>
+        </a>
+      </div>
+    </a-layout-header>
+    <a-layout-content :style="{ padding: '0', marginTop: '64px' }">
+      <div style="padding:10px;">
+        <keep-alive>
+          <router-view :key="$route.name"></router-view>
+        </keep-alive>
+      </div>
+    </a-layout-content>
+  </a-layout>
+</template>
+<style>
+#components-layout-mobile-fixed{
+  height: 100%;
+  overflow: auto;
+}
+#components-layout-mobile-fixed .logo {
+  width: 140px;
+  height: 31px;
+  line-height:31px;
+  color: #fff;
+  margin: 16px 15px 16px 0;
+  float: left;
+  text-align: center;
+  font-weight: 900;
+}
+#components-layout-mobile-fixed .user-wrapper{
+  float: right;
+  z-index: 10000;
+  color: #fff;
+}
+</style>

+ 87 - 0
src/layouts/MobilePageLayout.vue

@@ -0,0 +1,87 @@
+<script>
+import { mixin } from '@/utils/mixin'
+import { mapActions, mapGetters } from 'vuex'
+export default {
+  name: 'MobilePageLayout',
+  components: {
+  },
+  mixins: [mixin],
+  computed: {
+    ...mapGetters(['nickname', 'avatar']),
+    title () {
+      return this.$route.meta.title
+    }
+  },
+  methods: {
+    ...mapActions(['Logout']),
+    handleLogout () {
+      this.$confirm({
+        title: '提示',
+        content: '确定要退出登录吗 ?',
+        centered: true,
+        onOk: () => {
+          return this.Logout({}).then(() => {
+            setTimeout(() => {
+              this.$router.push({ path: '/user/login' })
+            }, 16)
+          }).catch(err => {
+            this.$message.error({
+              title: '错误',
+              description: err.message
+            })
+          })
+        },
+        onCancel () {
+        }
+      })
+    },
+    handleToHome () {
+      this.$router.go(-1)
+    }
+  }
+}
+</script>
+
+<template>
+  <a-layout id="components-layout-mobile-page">
+    <a-layout-header :style="{ position: 'fixed', zIndex: 1, width: '100%',padding:'0 10px' }">
+      <a href="javascript:;" class="icon-back" style="margin:0 10px;color: #fff;" @click="handleToHome">
+        <a-icon type="left"/>
+        <span style="margin: 0 5px;">返回</span>
+      </a>
+      <div class="logo">
+        {{ title }}
+      </div>
+    </a-layout-header>
+    <a-layout-content :style="{ padding: '0', marginTop: '64px' }">
+      <div style="padding:10px;">
+        <keep-alive>
+          <router-view :key="$route.name"></router-view>
+        </keep-alive>
+      </div>
+    </a-layout-content>
+  </a-layout>
+</template>
+<style>
+#components-layout-mobile-page{
+  height: 100%;
+  overflow: auto;
+}
+#components-layout-mobile-page .logo {
+  width: 100px;
+  height: 31px;
+  line-height:31px;
+  color: #fff;
+  margin: 16px 15px 16px 0;
+  text-align: center;
+  font-weight: 900;
+  position: absolute;
+  width: 100%;
+  z-index: -1;
+}
+#components-layout-mobile-page .icon-back{
+  z-index: 10000;
+  color: #fff;
+  float: left;
+}
+</style>

+ 3 - 1
src/layouts/index.js

@@ -4,5 +4,7 @@ import BasicLayout from './BasicLayout'
 import RouteView from './RouteView'
 import PageView from './PageView'
 import BigScreen from './BigScreen'
+import MobileLayout from './MobileLayout'
+import MobilePageLayout from './MobilePageLayout'
 
-export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView, BigScreen }
+export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView, BigScreen, MobileLayout, MobilePageLayout }

+ 54 - 0
src/mobile/Home.vue

@@ -0,0 +1,54 @@
+<template>
+  <div class="home">
+    <div class="nav-items col-1" @click="toPage('inventoryQuery')" v-if="$hasPermissions('M_inventoryQueryList')">
+      <a-icon type="search" />
+      <div>库存查询</div>
+    </div>
+    <div class="nav-items col-2" @click="toPage('productPricing')" v-if="$hasPermissions('M_productPricingList')">
+      <a-icon type="euro" />
+      <div>产品定价</div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  methods: {
+    toPage (page) {
+      this.$router.push({ name: page })
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .home {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: calc(100vh - 84px);
+    padding: 0 50px;
+    .nav-items {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      margin-top: 20px;
+      color: #fff;
+      width: 100%;
+      border-radius: 10px;
+      padding: 20px;
+      div {
+        margin-left: 15px;
+        font-size: 20px;
+      }
+      font-size: 30px;
+    }
+    .col-1{
+      background-color: #55aa00;
+    }
+    .col-2{
+      background-color: #0055aa;
+    }
+  }
+</style>

+ 188 - 0
src/mobile/inventoryManagement/inventoryQuery/detailModal.vue

@@ -0,0 +1,188 @@
+<template>
+  <a-modal
+    centered
+    class="inventoryQueryDetail-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="库存详情"
+    v-model="isShow"
+    @cancel="isShow=false"
+    width="100%">
+    <!-- 合计 -->
+    <a-alert type="info" style="margin-bottom:10px">
+      <div class="ftext" slot="message">
+        可用库存总数量:<strong>{{ (currentStock&&(currentStock.currentStockQty || currentStock.currentStockQty==0)) ? currentStock.currentStockQty : '--' }}个</strong>;
+        <span v-if="$hasPermissions('B_inventoryQuery_detail_costPrice')">可用库存总成本:<strong>{{ (currentStock&&(currentStock.currentStockCost || currentStock.currentStockCost==0)) ? toThousands(currentStock.currentStockCost) : '--' }}</strong>。</span>
+      </div>
+    </a-alert>
+    <!-- 库存详情 -->
+    <s-table
+      v-if="openModal"
+      class="sTable"
+      ref="table"
+      size="small"
+      :rowKey="(record) => record.id"
+      :columns="columns"
+      :data="loadData"
+      :scroll="{ y: 500 }"
+    >
+      <template slot="productInfo" slot-scope="text, record">
+        <div class="tr-row">
+          <div class="tr-title">{{ record.productName }}</div>
+          <div>产品编码:<span class="code">{{ record.productCode }}</span></div>
+          <div>原厂编码:<span>{{ record.productOrigCode ||'--' }}</span></div>
+          <div>仓库仓位:<span>{{ record.warehouseName }}</span>><span>{{ record.warehouseLocationName }}</span></div>
+          <div>
+            库存数量:
+            <span style="vertical-align: middle;margin-right:5px;color:red"> {{ (record.currentQty ||record.currentQty==0)?record.currentQty:'--' }}</span>
+            <a-tooltip placement="bottom" v-if="record.lockFlag==1" >
+              <template slot="title">
+                采购入库的库存为锁定库存
+              </template>
+              <a-badge count="锁" v-if="record.lockFlag==1" :number-style="{ zoom:'80%' }"></a-badge>
+            </a-tooltip>
+          </div>
+          <div v-if="$hasPermissions('B_inventoryQuery_detail_costPrice')">成本单价:<span>{{ toThousands(record.putCost) }}</span></div>
+          <div>入库类型:<span>{{ record.putBizTypeDictValue }}</span></div>
+          <div>入库时间:<span>{{ record.putTime }}</span></div>
+        </div>
+      </template>
+    </s-table>
+    <div class="btn-cont">
+      <a-button id="inventoryQueryDetail-detail-modal-back" @click="isShow = false">返回列表</a-button>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable } from '@/components'
+import { stockDetailList, stockDetailCount } from '@/api/stock'
+export default {
+  name: 'InventoryQueryDetailModal',
+  mixins: [commonMixin],
+  components: { STable },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemId: {
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        return stockDetailList(Object.assign(parameter, { stockSn: this.itemId })).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+              data.list[i].productOrigCode = data.list[i].productOrigCode.trim()
+            }
+            this.disabled = false
+            // 总计
+            this.getTotal(Object.assign(parameter, { stockSn: this.itemId }))
+          }
+          return data
+        })
+      },
+      currentStock: { // 合计信息
+        currentQty: '',
+        putCost: ''
+      }
+    }
+  },
+  computed: {
+    stockQty () { //  库存总数量 合计
+      const currentStockQty = Number(this.currentStock.currentStockQty) || 0
+      const freezeStockQty = Number(this.currentStock.freezeStockQty) || 0
+      return currentStockQty + freezeStockQty
+    },
+    stockCost () { //  库存总成本 合计
+      const currentStockCost = Number(this.currentStock.currentStockCost) || 0
+      const freezeStockCost = Number(this.currentStock.freezeStockCost) || 0
+      return ((currentStockCost * 1000 + freezeStockCost * 1000) / 1000).toFixed(2)
+    },
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '40px', align: 'center' },
+        { title: '产品信息', scopedSlots: { customRender: 'productInfo' }, width: '90%', align: 'center' }
+      ]
+      return arr
+    }
+  },
+  methods: {
+    // 合计
+    getTotal (param) {
+      stockDetailCount(param).then(res => {
+        if (res.status == 200 && res.data) {
+          this.currentStock = res.data
+        } else {
+          this.currentStock = { // 合计信息
+            currentQty: '',
+            putCost: ''
+          }
+        }
+      })
+    },
+    // 重置
+    resetPage () {
+      this.currentStock = { // 合计信息
+        currentQty: '',
+        putCost: ''
+      }
+      this.$refs.table.clearTable()
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.resetPage()
+        this.$emit('close')
+        this.$store.state.app.curActionPermission = ''
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .inventoryQueryDetail-modal{
+    .btn-cont {
+      text-align: center;
+      margin: 5px 0 10px;
+    }
+    .tr-row{
+      text-align: left;
+      .tr-title{
+        font-weight: bold;
+      }
+      > div{
+        padding: 2px 0;
+        color: #666;
+        span{
+          color: #222;
+        }
+        .code{
+          color: #00aaff;
+        }
+        .nums{
+          color: #ff0000;
+        }
+      }
+    }
+  }
+</style>

+ 334 - 0
src/mobile/inventoryManagement/inventoryQuery/list.vue

@@ -0,0 +1,334 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div ref="tableSearch" class="table-page-search-wrapper">
+        <a-form layout="inline" id="inventoryQueryList-form" labelAlign="right" @keyup.enter.native="$refs.table.refresh(true)">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="产品编码">
+                <a-input id="inventoryQueryList-productCode" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="原厂编码">
+                <a-input id="inventoryQueryList-productOrigCode" v-model.trim="queryParam.productOrigCode" allowClear placeholder="请输入原厂编码"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="产品品牌">
+                <ProductBrand id="inventoryQueryList-productBrandSn" v-model="queryParam.productBrandSn"></ProductBrand>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="产品分类">
+                <ProductType id="inventoryQueryList-productType" placeholder="请选择产品分类" @change="changeProductType" v-model="productType"></ProductType>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品名称">
+                  <a-input id="inventoryQueryList-productName" v-model.trim="queryParam.productName" allowClear placeholder="请输入产品名称"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="仓库">
+                  <warehouse isPermission v-model="queryParam.warehouseSn" id="inventoryQueryList-warehouseSn" placeholder="请选择仓库" />
+                </a-form-item>
+              </a-col>
+              <a-col :md="4" :sm="24">
+                <a-form-item label="库存情况">
+                  <a-checkbox style="float:right" v-model="queryParam.zeroQtyFlag" id="inventoryQueryList-zeroQtyFlag">只查看有库存</a-checkbox>
+                </a-form-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24" style="text-align: center;">
+              <a-button type="primary" @click="$refs.table.refresh()" :disabled="disabled" id="inventoryQueryList-refresh">查询</a-button>
+              <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="inventoryQueryList-reset">重置</a-button>
+              <a @click="advanced=!advanced" style="margin-left: 5px" id="inventoryQueryList-advanced">
+                {{ advanced ? '收起' : '展开' }}
+                <a-icon :type="advanced ? 'up' : 'down'"/>
+              </a>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+    </a-card>
+
+    <a-card size="small" :bordered="false" class="inventoryQueryList-wrap">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 合计 -->
+        <div class="ftext tongji-bar">
+          <div>
+            可用库存总数量:<strong>{{ (currentStock&&(currentStock.currentStockQty || currentStock.currentStockQty==0)) ? currentStock.currentStockQty : '--' }}个</strong>;
+          </div>
+          <div v-if="$hasPermissions('M_inventoryQueryList_costPrice')">可用库存总成本:<strong>{{ (currentStock&&(currentStock.currentStockCost || currentStock.currentStockCost==0)) ? toThousands(currentStock.currentStockCost) : '--' }}</strong>。</div>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :pageSize="20"
+          :data="loadData"
+          :defaultLoadData="false"
+        >
+          <template slot="productInfo" slot-scope="text, record">
+            <div class="tr-row">
+              <div class="tr-title">{{ record.productName }}</div>
+              <div>产品编码:<span class="code">{{ record.productCode }}</span></div>
+              <div>仓库:<span>{{ record.warehouseName }}</span></div>
+              <div>产品品牌:<span>{{ record.productBrandName }}</span></div>
+              <div>可用库存数量:<span class="nums">{{ record.currentStockQty }}</span> {{ record.productUnit }}</div>
+              <div v-if="$hasPermissions('M_inventoryQueryList_costPrice')">可用库存成本:<span>{{ toThousands(record.currentStockCost) }}</span></div>
+              <div>货位编号:<span>{{ record.stackPlaceEntity && record.stackPlaceEntity.stackPlaceCode||'--' }}</span></div>
+              <div>最后入库时间:<span>{{ record.lastStockTime }}</span></div>
+            </div>
+          </template>
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              v-if="$hasPermissions('B_inventoryQuery_detail')"
+              size="small"
+              type="link"
+              class="button-success"
+              style="margin:10px 0;"
+              @click="goDetail(record)"
+              :id="'inventoryQueryList-detail-'+record.id">库存详情</a-button>
+            <a-button
+              v-if="$hasPermissions('B_inventoryQuery_rkDetail')"
+              size="small"
+              type="link"
+              class="button-warning"
+              @click="goWarehouseDetail(record)"
+              :id="'inventoryQueryList-whousedetail-'+record.id">出入库明细</a-button>
+            <span v-if="!$hasPermissions('B_inventoryQuery_detail')&&!$hasPermissions('B_inventoryQuery_rkDetail')">--</span>
+          </template>
+        </s-table>
+      </a-spin>
+      <!-- 库存详情 -->
+      <inventory-query-detail-modal v-drag :openModal="openModal" :itemId="itemId" @close="closeModal" />
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+// 组件
+import { STable, VSelect } from '@/components'
+import inventoryQueryDetailModal from './detailModal.vue'
+import ProductType from '@/views/common/productType.js'
+import ProductBrand from '@/views/common/productBrand.js'
+import warehouse from '@/views/common/chooseWarehouse.js'
+// 接口
+import { stockList, stockCount } from '@/api/stock'
+export default {
+  name: 'InventoryQueryList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, inventoryQueryDetailModal, ProductType, ProductBrand, warehouse },
+  data () {
+    return {
+      spinning: false,
+      advanced: false, // 高级搜索 展开/关闭
+      tableHeight: 0, // 表格高度
+      queryParam: { //  查询条件
+        productCode: '', //  产品编码
+        productName: '', //  产品名称
+        productOrigCode: '', //  原厂编码
+        productBrandSn: undefined, //  产品品牌
+        warehouseSn: undefined, // 仓库
+        productTypeSn1: '', //  产品分类1
+        productTypeSn2: '', //  产品分类2
+        productTypeSn3: '', //  产品分类3
+        zeroQtyFlag: false //  库存情况
+      },
+      productType: [], // 产品分类
+      exportLoading: false, // 导出loading
+      disabled: false, //  查询、重置按钮是否可操作
+      zeroQtyData: [ //  库存情况
+        { name: '库存数量为0', id: '1' },
+        { name: '库存数量不为0', id: '0' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        // 排序
+        if (parameter.sortOrder && parameter.sortField == 'currentStockQty') {
+          parameter.sortField = 'qty'
+          parameter.sortAlias = ''
+        }
+        if (parameter.sortOrder && parameter.sortField == 'currentStockCost') {
+          parameter.sortField = 'currentStockCost'
+          parameter.sortAlias = 'stock'
+        }
+        // 没有排序
+        if (!parameter.sortOrder) {
+          parameter.sortField = ''
+          parameter.sortAlias = ''
+        }
+
+        const params = Object.assign(parameter, this.queryParam)
+        if (params.zeroQtyFlag) {
+          params.zeroQtyFlag = '0'
+        } else {
+          params.zeroQtyFlag = ''
+        }
+        // 获取列表数据  有分页
+        return stockList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+            this.spinning = false
+            // 总计
+            this.getTotal(params)
+          }
+          return data
+        })
+      },
+      openModal: false, //  查看库存详情  弹框
+      itemId: '', //  当前库存记录id
+      currentStock: null // 可用库存合计
+    }
+  },
+  computed: {
+    // 表头
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '40px', align: 'center' },
+        { title: '产品信息', scopedSlots: { customRender: 'productInfo' }, width: '82%', align: 'center' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+      ]
+      return arr
+    }
+  },
+  methods: {
+    //  重置
+    resetSearchForm () {
+      this.queryParam.productBrandSn = undefined
+      this.queryParam.productTypeSn1 = ''
+      this.queryParam.productTypeSn2 = ''
+      this.queryParam.productTypeSn3 = ''
+      this.queryParam.productCode = ''
+      this.queryParam.productOrigCode = ''
+      this.queryParam.productName = ''
+      this.queryParam.warehouseSn = undefined
+      this.queryParam.zeroQtyFlag = false
+      this.productType = []
+      this.$refs.table.refresh(true)
+    },
+    // 获取表格数据
+    getTableData () {
+
+    },
+    // 合计
+    getTotal (param) {
+      stockCount(param).then(res => {
+        if (res.status == 200 && res.data) {
+          this.currentStock = res.data
+        } else {
+          this.currentStock = null
+        }
+      })
+    },
+    //  库存详情
+    goDetail (row) {
+      this.$store.state.app.curActionPermission = 'B_inventoryQuery_detail'
+      this.itemId = row.stockSn
+      this.openModal = true
+    },
+    //  关闭弹框
+    closeModal () {
+      this.itemId = ''
+      this.openModal = false
+    },
+    //  出入库明细
+    goWarehouseDetail (row) {
+      this.$router.push({ name: 'inventoryQueryWarehouseDetail', params: { sn: row.productSn, warehouseSn: row.warehouseSn } })
+    },
+    //  产品分类  change
+    changeProductType (val, opt) {
+      this.queryParam.productTypeSn1 = val[0] ? val[0] : ''
+      this.queryParam.productTypeSn2 = val[1] ? val[1] : ''
+      this.queryParam.productTypeSn3 = val[2] ? val[2] : ''
+    },
+    // 初始化页面
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 226
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+    }
+    // 仅刷新列表,不重置页面
+    if (this.$store.state.app.updateList) {
+      this.pageInit()
+      this.$refs.table.refresh()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+<style lang="less">
+  .inventoryQueryList-wrap{
+    margin-top: 10px;
+    .sTable{
+      margin-top: 10px;
+    }
+    .tr-row{
+      text-align: left;
+      .tr-title{
+        font-weight: bold;
+      }
+      > div{
+        padding: 2px 0;
+        color: #666;
+        span{
+          color: #222;
+        }
+        .code{
+          color: #00aaff;
+        }
+        .nums{
+          color: #ff0000;
+        }
+      }
+    }
+  }
+</style>

+ 300 - 0
src/mobile/inventoryManagement/inventoryQuery/warehouseDetail.vue

@@ -0,0 +1,300 @@
+<template>
+  <div class="inventoryQueryWarehouseDetail-wrap">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-card size="small" :bordered="false" class="inventoryQueryWarehouseDetail-cont">
+        <!-- 搜索条件 -->
+        <div ref="tableSearch" class="table-page-search-wrapper">
+          <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+            <a-row :gutter="15">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="单据审核时间">
+                  <rangeDate ref="rangeDate" @change="dateChange" />
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="关联单号">
+                  <a-input id="inventoryQueryWarehouseDetail-bizNo" v-model.trim="queryParam.bizNo" allowClear placeholder="请输入关联单号"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="下推单号">
+                  <a-input id="inventoryQueryWarehouseDetail-bizSubNo" v-model.trim="queryParam.bizSubNo" allowClear placeholder="请输入下推单号"/>
+                </a-form-item>
+              </a-col>
+              <template v-if="advanced">
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="变动类型">
+                    <v-select
+                      v-model="queryParam.flowType"
+                      ref="flowType"
+                      id="inventoryQueryWarehouseDetail-flowType"
+                      code="STOCK_FLOW_TYPE"
+                      placeholder="请选择变动类型"
+                      allowClear></v-select>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="单据类型">
+                    <v-select
+                      v-model="queryParam.bizType"
+                      ref="bizType"
+                      id="inventoryQueryWarehouseDetail-bizType"
+                      code="STOCK_FLOW_BIZ_TYPE"
+                      placeholder="请选择单据类型"
+                      allowClear></v-select>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="单位名称">
+                    <a-input id="inventoryQueryWarehouseDetail-unitName" v-model.trim="queryParam.unitName" allowClear placeholder="请输入单位名称"/>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="出入库状态">
+                    <v-select
+                      v-model="queryParam.state"
+                      ref="state"
+                      id="inventoryQueryWarehouseDetail-state"
+                      code="STOCK_FLOW_STATE"
+                      placeholder="请选择出入库状态"
+                      allowClear></v-select>
+                  </a-form-item>
+                </a-col>
+              </template>
+              <a-col :md="6" :sm="24" style="text-align:center;">
+                <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="inventoryQueryWarehouseDetail-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="inventoryQueryWarehouseDetail-reset">重置</a-button>
+                <a @click="advanced=!advanced" style="margin-left: 5px" id="inventoryQueryList-advanced">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'"/>
+                </a>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 合计 -->
+        <a-alert type="info" style="margin:10px 0">
+          <div class="ftext" slot="message">
+            当前库存总数量:<strong>{{ (productTotal&&(productTotal.totalQty || productTotal.totalQty==0)) ? productTotal.totalQty : '--' }}个</strong>;
+            入库总数量:<strong>{{ (productTotal&&(productTotal.totalPutQty || productTotal.totalPutQty==0)) ? productTotal.totalPutQty : '--' }}个</strong>;
+            出库总数量:<strong>{{ (productTotal&&(productTotal.totalOutQty || productTotal.totalOutQty==0)) ? productTotal.totalOutQty : '--' }}个</strong>;
+            <span v-if="$hasPermissions('B_inventoryQuery_rkDetail_costPrice')">当前库存总成本:<strong>{{ (productTotal&&(productTotal.totalCost || productTotal.totalCost==0)) ? toThousands(productTotal.totalCost) : '--' }}</strong>。</span>
+          </div>
+        </a-alert>
+        <!-- 列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          :defaultLoadData="false"
+        >
+          <template slot="productInfo" slot-scope="text, record">
+            <div class="tr-row">
+              <div class="tr-title">{{ record.productName }}</div>
+              <div>产品编码:<span class="code">{{ record.productCode }}</span></div>
+              <div>原厂编码:<span>{{ record.productOrigCode ||'--' }}</span></div>
+              <div>批次号:<span>{{ record.stockBatchNo ||'--' }}</span></div>
+              <div>单据类型:<span>{{ record.bizTypeDictValue ||'--' }}</span></div>
+              <div>关联单号:<span>{{ record.bizNo ||'--' }}</span></div>
+              <div>下推单号:<span>{{ record.bizSubNo ||'--' }}</span></div>
+              <div>单据审核时间:<span>{{ record.auditTime ||'--' }}</span></div>
+              <div>单位名称:<span>{{ record.unitName ||'--' }}</span></div>
+              <div>仓库仓位:<span>{{ record.warehouseName }}</span>><span>{{ record.warehouseLocationName }}</span></div>
+              <div style="display: flex;">
+                <div>数量:
+                  <span :class="record.flowType=='PUT' ? 'green':'red'" style="margin: 0;">
+                    <b v-if="record.qty!=0">{{ record.flowType=='PUT' ? '+':'-' }}</b>
+                    {{ record.qty }}
+                  </span>
+                </div>
+                <div style="margin-left: 15px;" v-if="$hasPermissions('B_inventoryQuery_rkDetail_costPrice')">
+                  总成本:<span>{{ toThousands(record.totalCost) }}</span>
+                </div>
+                <div style="margin-left: 15px;" v-if="$hasPermissions('B_inventoryQuery_rkDetail_salesPrice')">
+                  总售价:
+                  <span v-if="record.bizType!='SPARE_PARTS_RETURN'"> {{ toThousands(record.totalPrice) }}</span>
+                  <span v-else>--</span>
+                </div>
+              </div>
+              <div>出入库状态:<span>{{ record.stateDictValue }}</span></div>
+            </div>
+          </template>
+        </s-table>
+      </a-card>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import rangeDate from '@/views/common/rangeDate.vue'
+import { stockFlowCount, stockFlowList } from '@/api/stock'
+export default {
+  name: 'InventoryQueryWarehouseDetail',
+  mixins: [commonMixin],
+  components: { STable, VSelect, rangeDate },
+  data () {
+    return {
+      spinning: false,
+      advanced: false, // 高级搜索 展开/关闭
+      tableHeight: 0,
+      queryParam: { //  查询条件
+        beginDate: '', // 开始时间
+        endDate: '', // 结束时间
+        bizType: undefined, // 单据类型
+        flowType: undefined, // 变动类型
+        unitName: '', // 单位
+        bizNo: '', // 关联单号
+        bizSubNo: '', // 下推单号
+        warehouseSn: undefined, // 仓库sn
+        state: undefined // 单据状态
+      },
+      disabled: false, //  查询、重置按钮是否可操作
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam, { productSn: this.$route.params.sn, warehouseSn: this.$route.params.warehouseSn })
+        return stockFlowList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            this.getTotal(params)
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+              if (data.list[i].flowType == 'PUT') {
+                data.list[i].qty = data.list[i].putQty
+              } else if (data.list[i].flowType == 'OUT') {
+                data.list[i].qty = data.list[i].outQty
+              }
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      exportLoading: false, // 导出按钮loading
+      productTotal: null //  合计
+    }
+  },
+  computed: {
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '40px', align: 'center' },
+        { title: '产品信息', scopedSlots: { customRender: 'productInfo' }, width: '90%', align: 'center' }
+      ]
+      return arr
+    }
+  },
+  methods: {
+    //  创建时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
+    // 合计
+    getTotal (param) {
+      stockFlowCount(param).then(res => {
+        if (res.status == 200 && res.data) {
+          this.productTotal = res.data
+        } else {
+          this.productTotal = null
+        }
+      })
+    },
+    //  重置
+    resetSearchForm () {
+      this.$refs.rangeDate.resetDate()
+      this.queryParam.beginDate = ''
+      this.queryParam.endDate = ''
+      this.queryParam.bizType = undefined
+      this.queryParam.flowType = undefined
+      this.queryParam.unitName = ''
+      this.queryParam.bizSubNo = ''
+      this.queryParam.bizNo = ''
+      this.queryParam.warehouseSn = undefined
+      this.queryParam.state = undefined
+      this.$refs.table.refresh(true)
+    },
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 268
+    }
+  },
+  watch: {
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.resetSearchForm()
+      this.pageInit()
+    }
+  },
+  activated () {
+    // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
+    if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
+      this.resetSearchForm()
+      this.pageInit()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+
+<style lang="less">
+  .inventoryQueryWarehouseDetail-wrap{
+    .inventoryQueryWarehouseDetail-back{
+      margin-bottom: 6px;
+    }
+    .inventoryQueryWarehouseDetail-cont{
+      margin-bottom: 6px;
+    }
+    .tr-row{
+      text-align: left;
+      .tr-title{
+        font-weight: bold;
+      }
+      > div{
+        padding: 2px 0;
+        color: #666;
+        span{
+          color: #222;
+        }
+        .green{
+          color: #19be6b;
+        }
+        .red{
+          color: #ed1c24;
+        }
+        .code{
+          color: #00aaff;
+        }
+        .nums{
+          color: #ff0000;
+        }
+      }
+    }
+  }
+</style>

+ 146 - 0
src/mobile/productManagement/productPricing/auditModal.vue

@@ -0,0 +1,146 @@
+<template>
+  <a-modal
+    centered
+    class="productPricingAudit-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="定价审核"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="800">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <!-- 定价审核 -->
+      <div>
+        <a-descriptions bordered :column="1">
+          <a-descriptions-item label="成本价">
+            <div v-if="detailsData && detailsData.supplierProductList" style="margin-top: 8px;">
+              <p v-for="(item, index) in detailsData.supplierProductList" :key="index" style="margin: 0;">{{ ((item.cost || item.cost==0) ? toThousands(item.cost) : '--') + ' -- ' + (item.supplierName||'') + ';' }}</p>
+            </div>
+            <span v-else>--</span>
+          </a-descriptions-item>
+          <a-descriptions-item label="省级价">
+            {{ detailsData && (detailsData.afterProvincePrice || detailsData.afterProvincePrice==0) ? toThousands(detailsData.afterProvincePrice) : '--' }}
+            <span v-if="detailsData && (detailsData.afterProvincePrice != detailsData.beforeProvincePrice)">
+              (原{{ (detailsData.beforeProvincePrice || detailsData.beforeProvincePrice==0) ? toThousands(detailsData.beforeProvincePrice) : '--' }})
+            </span>
+          </a-descriptions-item>
+          <a-descriptions-item label="市级价">
+            {{ detailsData && (detailsData.afterCityPrice || detailsData.afterCityPrice==0) ? toThousands(detailsData.afterCityPrice) : '--' }}
+            <span v-if="detailsData && (detailsData.afterCityPrice != detailsData.beforeCityPrice)">
+              (原{{ (detailsData.beforeCityPrice || detailsData.beforeCityPrice==0) ? toThousands(detailsData.beforeCityPrice) : '--' }})
+            </span>
+          </a-descriptions-item>
+          <a-descriptions-item label="特约价">
+            {{ detailsData && (detailsData.afterSpecialPrice || detailsData.afterSpecialPrice==0) ? toThousands(detailsData.afterSpecialPrice) : '--' }}
+            <span v-if="detailsData && (detailsData.afterSpecialPrice != detailsData.beforeSpecialPrice)">
+              (原{{ (detailsData.beforeSpecialPrice || detailsData.beforeSpecialPrice==0) ? toThousands(detailsData.beforeSpecialPrice) : '--' }})
+            </span>
+          </a-descriptions-item>
+          <a-descriptions-item label="终端价">
+            {{ detailsData && (detailsData.afterTerminalPrice || detailsData.afterTerminalPrice==0) ? toThousands(detailsData.afterTerminalPrice) : '--' }}
+            <span v-if="detailsData && (detailsData.afterTerminalPrice != detailsData.beforeTerminalPrice)">
+              (原{{ (detailsData.beforeTerminalPrice || detailsData.beforeTerminalPrice==0) ? toThousands(detailsData.beforeTerminalPrice) : '--' }})
+            </span>
+          </a-descriptions-item>
+          <a-descriptions-item label="车主价">
+            {{ detailsData && (detailsData.afterCarOwnersPrice || detailsData.afterCarOwnersPrice==0) ? toThousands(detailsData.afterCarOwnersPrice) : '--' }}
+            <span v-if="detailsData && (detailsData.afterCarOwnersPrice != detailsData.beforeCarOwnersPrice)">
+              (原{{ (detailsData.beforeCarOwnersPrice || detailsData.beforeCarOwnersPrice==0) ? toThousands(detailsData.beforeCarOwnersPrice) : '--' }})
+            </span>
+          </a-descriptions-item>
+          <a-descriptions-item label="变更原因">{{ detailsData && detailsData.changeReason || '--' }}</a-descriptions-item>
+        </a-descriptions>
+        <div class="btn-cont">
+          <a-button type="primary" id="productPricingAudit-back" @click="handleAudit('AUDIT_REJECT')" style="margin-right: 15px;">审核不通过</a-button>
+          <a-button type="primary" class="button-info" id="productPricingAudit-save" @click="handleAudit('PRICED')">审核通过</a-button>
+        </div>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { toThousands } from '@/libs/tools.js'
+// 接口
+import { productPricingSnDetail, productPricingAudit } from '@/api/product'
+export default {
+  name: 'ProductPricingAuditModal',
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemSn: {// 审核sn
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      toThousands, // 金额 截取到两位函数 3位添加‘,’
+      isShow: this.openModal, //  是否打开弹框
+      detailsData: null //  详情数据
+    }
+  },
+  methods: {
+    //  获取详情数据
+    getDetail () {
+      productPricingSnDetail({ sn: this.itemSn }).then(res => {
+        if (res.status == 200) {
+          this.detailsData = res.data
+        } else {
+          this.detailsData = null
+        }
+      })
+    },
+    // 审核  type =='AUDIT_REJECT'?'不通过':'通过(PRICED)'
+    handleAudit (type) {
+      const ajaxData = {
+        id: this.detailsData.id,
+        productSn: this.detailsData.productSn,
+        auditState: type
+      }
+      this.spinning = true
+      productPricingAudit(ajaxData).then(res => {
+        if (res.status == 200) {
+          this.isShow = false
+          this.$emit('ok')
+          this.spinning = false
+        } else {
+          this.spinning = false
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      }
+    },
+    itemSn (newValue, oldValue) {
+      if (this.isShow && newValue) {
+        this.getDetail()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .productPricingAudit-modal{
+    .ant-modal-body {
+      padding: 40px 40px 24px;
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 35px 0 30px;
+    }
+  }
+</style>

+ 272 - 0
src/mobile/productManagement/productPricing/editModal.vue

@@ -0,0 +1,272 @@
+<template>
+  <a-modal
+    centered
+    class="productPricingEdit-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="编辑价格"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="800">
+    <!-- 编辑价格 -->
+    <div>
+      <a-spin :spinning="spinning" tip="Loading...">
+        <a-form-model
+          id="productPricingEdit-form"
+          ref="ruleForm"
+          :model="form"
+          :rules="rules"
+          :label-col="formItemLayout.labelCol"
+          :wrapper-col="formItemLayout.wrapperCol"
+        >
+          <a-form-model-item label="成本价">
+            <div v-if="detailData && detailData.supplierProductList" style="margin-top: 8px;">
+              <p v-for="(item, index) in detailData.supplierProductList" :key="index" style="margin: 0;line-height: 1.5em;">{{ ((item.cost || item.cost==0) ? item.cost.toFixed(2) : '--') + ' 元 -- ' + (item.supplierName||'') + ';' }}</p>
+            </div>
+            <span v-else>--</span>
+          </a-form-model-item>
+          <a-form-model-item label="省级价" prop="afterProvincePrice">
+            <a-input-number
+              id="productPricingEdit-afterProvincePrice"
+              v-model="form.afterProvincePrice"
+              :precision="2"
+              :min="0.01"
+              :max="99999999"
+              placeholder="请输入省级价"
+              ref="afterProvincePrice"
+              @keydown.enter.native="nextFocus('afterProvincePrice', 'afterCityPrice', $event)"
+              style="width: 100%;" />
+          </a-form-model-item>
+          <a-form-model-item label="市级价" prop="afterCityPrice">
+            <a-input-number
+              id="productPricingEdit-afterCityPrice"
+              v-model="form.afterCityPrice"
+              :precision="2"
+              :min="0.01"
+              :max="99999999"
+              placeholder="请输入市级价"
+              ref="afterCityPrice"
+              @keydown.enter.native="nextFocus('afterCityPrice', 'afterSpecialPrice', $event)"
+              style="width: 100%;" />
+          </a-form-model-item>
+          <a-form-model-item label="特约价" prop="afterSpecialPrice">
+            <a-input-number
+              id="productPricingEdit-afterSpecialPrice"
+              v-model="form.afterSpecialPrice"
+              :precision="2"
+              :min="0.01"
+              :max="99999999"
+              placeholder="请输入特约价"
+              ref="afterSpecialPrice"
+              @keydown.enter.native="nextFocus('afterSpecialPrice', 'afterTerminalPrice', $event)"
+              style="width: 100%;" />
+          </a-form-model-item>
+          <a-form-model-item label="终端价" prop="afterTerminalPrice">
+            <a-input-number
+              id="productPricingEdit-afterTerminalPrice"
+              v-model="form.afterTerminalPrice"
+              :precision="2"
+              :min="0.01"
+              :max="99999999"
+              placeholder="请输入终端价"
+              ref="afterTerminalPrice"
+              @keydown.enter.native="nextFocus('afterTerminalPrice', 'afterCarOwnersPrice', $event)"
+              style="width: 100%;" />
+          </a-form-model-item>
+          <a-form-model-item label="车主价" prop="afterCarOwnersPrice">
+            <a-input-number
+              id="productPricingEdit-afterCarOwnersPrice"
+              v-model="form.afterCarOwnersPrice"
+              :precision="2"
+              :min="0.01"
+              :max="99999999"
+              placeholder="请输入车主价"
+              ref="afterCarOwnersPrice"
+              @keydown.enter.native="nextFocus('afterCarOwnersPrice', 'changeReason', $event, 'vSelect')"
+              style="width: 100%;" />
+          </a-form-model-item>
+          <a-form-model-item label="变更原因" prop="changeReason">
+            <v-select
+              code="PRODUCT_PRICE_CHANGE_REASON"
+              id="productPricingEdit-changeReason"
+              v-model="form.changeReason"
+              allowClear
+              placeholder="请选择变更原因"
+              ref="changeReason"
+              @keydown.enter.native="nextFocus('changeReason', '', $event)"
+            ></v-select>
+          </a-form-model-item>
+        </a-form-model>
+        <div class="btn-cont">
+          <a-button id="productPricingEdit-cancel" @click="isShow = false" style="margin-right: 15px;">取消</a-button>
+          <a-button type="primary" id="productPricingEdit-save" @click="handleSave">保存</a-button>
+        </div>
+      </a-spin>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { VSelect } from '@/components'
+// 接口
+import { productPricingSnDetail, productPricingSave } from '@/api/product'
+export default {
+  name: 'ProductPricingEditModal',
+  components: { VSelect },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemSn: {// 定价产品sn
+      type: [Number, String],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      formItemLayout: {// 表单布局设置
+        labelCol: { span: 4 },
+        wrapperCol: { span: 17 }
+      },
+      form: {
+        afterProvincePrice: '', // 省级价
+        afterCityPrice: '', // 市级价
+        afterSpecialPrice: '', // 特约价
+        afterTerminalPrice: '', // 终端价
+        afterCarOwnersPrice: '', // 车主价
+        changeReason: undefined// 变更原因
+      },
+      rules: {
+        changeReason: [
+          { required: true, message: '请选择变更原因', trigger: 'change' }
+        ],
+        afterProvincePrice: [
+          { required: true, message: '请输入省级价', trigger: 'blur' }
+        ],
+        afterCityPrice: [
+          { required: true, message: '请输入市级价', trigger: 'blur' }
+        ],
+        afterSpecialPrice: [
+          { required: true, message: '请输入特约价', trigger: 'blur' }
+        ],
+        afterTerminalPrice: [
+          { required: true, message: '请输入终端价', trigger: 'blur' }
+        ],
+        afterCarOwnersPrice: [
+          { required: true, message: '请输入车主价', trigger: 'blur' }
+        ]
+      },
+      detailData: null //  数据详情
+    }
+  },
+  methods: {
+    //  获取详情
+    getDetail () {
+      productPricingSnDetail({ sn: this.itemSn }).then(res => {
+        if (res.status == 200) {
+          this.detailData = res.data
+          this.form.afterProvincePrice = res.data.afterProvincePrice || ''
+          this.form.afterCityPrice = res.data.afterCityPrice || ''
+          this.form.afterSpecialPrice = res.data.afterSpecialPrice || ''
+          this.form.afterTerminalPrice = res.data.afterTerminalPrice || ''
+          this.form.afterCarOwnersPrice = res.data.afterCarOwnersPrice || ''
+          this.form.changeReason = res.data.id && res.data.changeReason ? '价格修改' : '首次定价'
+        } else {
+          this.detailData = null
+          this.$refs.ruleForm.resetFields()
+        }
+      })
+    },
+    // 保存    定价规则==>省级价<市级价<特约价<终端价<车主价
+    handleSave () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          const newFormData = _this.form
+          if (newFormData.afterCityPrice * 1 < newFormData.afterProvincePrice * 1 || newFormData.afterCityPrice * 1 > newFormData.afterSpecialPrice * 1) {
+            _this.$message.error({ content: '价格设置规则:省级价≤市级价≤特约价', duration: 5 })
+            return
+          }
+          const form = JSON.parse(JSON.stringify(_this.form))
+          form.id = this.detailData.id || undefined
+          form.productSn = _this.itemSn
+          _this.spinning = true
+          productPricingSave(form).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              setTimeout(() => {
+                _this.$emit('ok')
+                _this.isShow = false
+                _this.spinning = false
+              }, 1000)
+            } else {
+              _this.spinning = false
+            }
+          })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    // 回车键快捷定位表单下一项
+    nextFocus (nowRef, nextRef, event, isComponent) {
+      const _this = this
+      if (_this.$refs[nowRef]) {
+        _this.$nextTick(() => {
+          if (_this.$refs[nextRef]) {
+            event.target.blur()
+            if (isComponent == 'vSelect') {
+              _this.$refs[nextRef].$children[0].focus()
+            } else {
+              _this.$refs[nextRef].focus()
+            }
+          }
+        })
+      }
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.costPrice = ''
+        this.$refs.ruleForm.resetFields()
+      } else {
+        // 默认首项获取焦点
+        const _this = this
+        setTimeout(() => {
+          if (_this.$refs['afterProvincePrice']) {
+            _this.$refs['afterProvincePrice'].focus()
+          }
+        }, 300)
+      }
+    },
+    itemSn (newValue, oldValue) {
+      if (this.isShow && newValue) {
+        this.getDetail()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .productPricingEdit-modal{
+    .ant-modal-body {
+      padding: 40px 40px 24px;
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 35px 0 30px;
+    }
+  }
+</style>

+ 429 - 0
src/mobile/productManagement/productPricing/list.vue

@@ -0,0 +1,429 @@
+<template>
+  <div>
+    <a-card size="small" :bordered="false" class="productPricingList-wrap searchBoxNormal">
+      <!-- 搜索条件 -->
+      <div ref="tableSearch" class="table-page-search-wrapper">
+        <a-form layout="inline" @keyup.enter.native="searchForm">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="定价时间">
+                <rangeDate id="productPricingList-rangeDate" ref="rangeDate" :value="time" @change="dateChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="产品编码/原厂编码">
+                <a-input id="productPricingList-queryWord" v-model.trim="queryParam.queryWord" allowClear placeholder="请输入产品编码/原厂编码"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="产品名称">
+                <a-input id="productPricingList-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="定价状态">
+                  <v-select code="PRICING_STATUS" id="productPricingList-pricingState" v-model="queryParam.pricingState" allowClear placeholder="请选择定价状态"></v-select>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="品牌">
+                  <ProductBrand id="productPricingList-productBrandSn" v-model="queryParam.productBrandSn"></ProductBrand>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品分类">
+                  <ProductType id="productPricingList-productType" placeholder="请选择产品分类" @change="changeProductType" v-model="productType"></ProductType>
+                </a-form-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24" style="margin-bottom: 0;text-align: center;">
+              <a-button type="primary" @click="searchForm" :disabled="disabled" id="productPricingList-refresh">查询</a-button>
+              <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productPricingList-reset">重置</a-button>
+              <a @click="advanced=!advanced" style="margin-left: 5px">
+                {{ advanced ? '收起' : '展开' }}
+                <a-icon :type="advanced ? 'up' : 'down'"/>
+              </a>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+    </a-card>
+    <a-card size="small" :bordered="false" style="margin-top: 10px;">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <!-- 操作按钮 -->
+        <div class="table-operator">
+          <a-button
+            id="productPricingList-batchAudit"
+            type="primary"
+            ghost
+            :loading="spinning"
+            @click="handleBatchAudit"
+            v-if="$hasPermissions('B_productPricing_audit')"
+            style="margin: 0 10px 0 0;">批量审核</a-button>
+          <span v-if="$hasPermissions('B_productPricing_audit')&&selTotal">已选{{ selTotal }}项</span>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          style="margin-top: 10px;"
+          class="sTable"
+          ref="table"
+          size="small"
+          :row-selection="$hasPermissions('B_productPricing_audit') ? { columnWidth: '4%', getCheckboxProps: record => ({ props: { disabled: record.pricingState!='WAIT_PRICING_AUDIT' } })}: null"
+          @rowSelection="rowSelectionFun"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          :defaultLoadData="false"
+        >
+          <template slot="productInfo" slot-scope="text, record">
+            <div class="tr-row">
+              <div class="tr-title">{{ record.name }}</div>
+              <div>创建时间':<span>{{ record.createDate ||'--' }}</span></div>
+              <div>产品编码:<span class="code">{{ record.code }}</span></div>
+              <div>原厂编码:<span>{{ record.origCode ||'--' }}</span></div>
+              <div>品牌:<span>{{ record.productBrandName ||'--' }}</span></div>
+              <div>产品分类:
+                <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
+                <span v-else>--</span>
+              </div>
+              <div>产品状态:<span style="margin-right: 10px;">{{ record.stateDictValue ||'--' }}</span> 定价状态:<span>{{ record.pricingStateDictValue ||'--' }}</span></div>
+              <div>定价时间:<span>{{ record.pricingTime ||'--' }}</span></div>
+              <div style="display: flex;">
+                成本价:
+                <div style="width:80%" v-if="record.supplierProductList">
+                  <p v-for="(item, index) in record.supplierProductList" :key="index" style="margin: 0;">
+                    <span class="red">{{ (item.cost || item.cost==0) ? item.cost.toFixed(2):'--' }}</span> 元
+                    ({{ (item.supplierName||'') }});
+                  </p>
+                </div>
+                <span v-else>--</span>
+              </div>
+              <div style="display: flex;flex-wrap: wrap;">
+                <div style="margin-right: 10px;">
+                  省级价:<span class="red">{{ toThousands(record.provincePrice) }}</span>
+                </div>
+                <div style="margin-right: 10px;">
+                  市级价:<span class="red">{{ toThousands(record.cityPrice) }}</span>
+                </div>
+                <div style="margin-right: 10px;">
+                  特约价:<span class="red">{{ toThousands(record.specialPrice) }}</span>
+                </div>
+                <div style="margin-right: 10px;">
+                  终端价:<span class="red">{{ toThousands(record.terminalPrice) }}</span>
+                </div>
+                <div>
+                  车主价:<span class="red">{{ toThousands(record.carOwnersPrice) }}</span>
+                </div>
+              </div>
+            </div>
+          </template>
+
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              size="small"
+              type="link"
+              v-if="record.pricingState=='WAIT_PRICING_AUDIT' && $hasPermissions('B_productPricing_audit')"
+              class="button-warning"
+              @click="handleAudit(record)"
+              :id="'productPricingList-audit-btn'+record.id">审核</a-button>
+            <a-button
+              size="small"
+              style="margin-top: 15px;"
+              type="link"
+              v-if="$hasPermissions('B_productPricing_edit')"
+              class="button-info"
+              @click="handleEdit(record)"
+              :id="'productPricingList-edit-btn'+record.id">编辑</a-button>
+            <span v-if="!(record.pricingState=='WAIT_PRICING_AUDIT' && $hasPermissions('B_productPricing_audit')) && !$hasPermissions('B_productPricing_edit')">--</span>
+          </template>
+        </s-table>
+      </a-spin>
+      <!-- 编辑价格 -->
+      <product-pricing-edit-modal v-drag :openModal="openModal" :itemSn="itemSn" @close="closeModal" @ok="$refs.table.refresh()" />
+      <!-- 审核价格 -->
+      <product-pricing-audit-modal v-drag :openModal="openPriceAuditModal" :itemSn="itemSn" @close="closeAuditModal" @ok="auditSuccess" />
+      <!-- 审核弹窗 -->
+      <a-modal
+        closable
+        v-model="openAuditModal"
+        :footer="null"
+        width="416px"
+        centered>
+        <div style="display:flex;margin:30px 0 20px 20px;">
+          <a-icon type="question-circle" :style="{fontSize:'23px',color:'#faad14'}"/>
+          <div style="margin-left:10px;">
+            <p style="font-size:16px;font-wight:bold;">提示</p>
+            <p>确认要审核吗?</p>
+          </div>
+        </div>
+        <!-- 按钮 -->
+        <div style="text-align: right;">
+          <a-button
+            id="auditModal-cancel"
+            type="primary"
+            @click="handleAuditModal('AUDIT_REJECT')"
+            style="margin-right: 15px;">审核不通过</a-button>
+          <a-button
+            type="primary"
+            id="auditModal-save"
+            class="button-info"
+            @click="handleAuditModal('PRICED')"
+          >审核通过</a-button>
+        </div>
+      </a-modal>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+// 组件
+import rangeDate from '@/views/common/rangeDate.vue'
+import { STable, VSelect } from '@/components'
+import productPricingEditModal from './editModal.vue'
+import productPricingAuditModal from './auditModal.vue'
+import ProductType from '@/views/common/productType.js'
+import ProductBrand from '@/views/common/productBrand.js'
+// 接口
+import { productPricingList, batchAuditPrice } from '@/api/product'
+export default {
+  name: 'ProductPricingList',
+  mixins: [commonMixin],
+  components: { STable, VSelect, rangeDate, productPricingEditModal, productPricingAuditModal, ProductBrand, ProductType },
+  data () {
+    return {
+      spinning: false,
+      advanced: false, // 高级搜索 展开/关闭
+      disabled: false, //  查询、重置按钮是否可操作
+      tableHeight: 0, // 表格高度
+      time: [], // 定价时间
+      //  查询条件
+      queryParam: {
+        name: '', //  产品名称
+        queryWord: '', // 产品编码/原厂编码
+        productBrandSn: undefined, //  产品品牌
+        productTypeSn1: '', //  产品一级分类
+        productTypeSn2: '', //  产品二级分类
+        productTypeSn3: '', //  产品三级分类
+        pricingState: undefined, //  定价状态
+        beginDate: undefined, // 定价开始时间
+        endDate: undefined// 定价结束时间
+      },
+      productType: [], // 产品分类
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        // 获取列表数据 有分页
+        return productPricingList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            // 计算表格序号
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.total = data.count || 0
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      total: 0, // 合计
+      openModal: false, //  编辑  弹框
+      openAuditModal: false, //  审核  弹框
+      openPriceAuditModal: false, // 价格审核 弹框
+      itemSn: '', //  当前产品sn
+      rowSelectionInfo: null// 选中的表格数据
+    }
+  },
+  computed: {
+    // 计算选中列表条数
+    selTotal () {
+      return this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys ? this.rowSelectionInfo.selectedRowKeys.length : 0
+    },
+    columns () {
+      const arr = [
+        { title: '序号', dataIndex: 'no', width: '40px', align: 'center' },
+        { title: '产品信息', scopedSlots: { customRender: 'productInfo' }, width: '82%', align: 'center' },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '8%', align: 'center' }
+      ]
+      return arr
+    }
+  },
+  methods: {
+    //  定价时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam.name = ''
+      this.queryParam.queryWord = ''
+      this.queryParam.productBrandSn = undefined
+      this.queryParam.productTypeSn1 = ''
+      this.queryParam.productTypeSn2 = ''
+      this.queryParam.productTypeSn3 = ''
+      this.queryParam.pricingState = undefined
+
+      this.queryParam.beginDate = undefined
+      this.queryParam.endDate = undefined
+      this.time = []
+      this.$refs.rangeDate.resetDate(this.time)
+      this.productType = []
+      this.$refs.table.clearSelected() // 清空表格选中项
+      this.$refs.table.refresh(true)
+    },
+    // 查询
+    searchForm () {
+      this.$refs.table.clearSelected() // 清空表格选中项
+      this.$refs.table.refresh(true)
+    },
+    // 审核
+    handleAudit (row) {
+      this.itemSn = row.productSn
+      this.openPriceAuditModal = true
+    },
+    // 价格审核成功
+    auditSuccess () {
+      this.$refs.table.clearSelected() // 清空表格选中项
+      this.$refs.table.refresh()
+    },
+    // 批量审核
+    handleBatchAudit () {
+      const _this = this
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请先选择产品!')
+        return
+      }
+      _this.openAuditModal = true
+    },
+    //  编辑
+    handleEdit (row) {
+      this.itemSn = row.productSn
+      this.openModal = true
+    },
+    //  关闭弹框
+    closeModal () {
+      this.itemSn = ''
+      this.openModal = false
+    },
+    //  关闭审核弹框
+    closeAuditModal () {
+      this.itemSn = ''
+      this.openPriceAuditModal = false
+    },
+    //  产品分类  change
+    changeProductType (val, opt) {
+      this.queryParam.productTypeSn1 = val[0] ? val[0] : ''
+      this.queryParam.productTypeSn2 = val[1] ? val[1] : ''
+      this.queryParam.productTypeSn3 = val[2] ? val[2] : ''
+    },
+    // 初始化数据
+    pageInit () {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    // 计算表格高度
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 240
+    },
+    // 批量审核
+    handleAuditModal (type) {
+      const _this = this
+      const productSnList = []
+      _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows.map(item => {
+        productSnList.push(item.productSn)
+      })
+      const ajaxData = {
+        productSnList: productSnList,
+        auditState: type
+      }
+      _this.spinning = true
+      batchAuditPrice(ajaxData).then(res => {
+        if (res.status == 200) {
+          _this.$refs.table.clearSelected() // 清空表格选中项
+          _this.$message.success(res.message)
+          _this.$refs.table.refresh()
+          _this.spinning = false
+          _this.openAuditModal = false
+        } else {
+          _this.spinning = false
+        }
+      })
+    }
+  },
+  watch: {
+    // 展开关闭 监听表格高度变化
+    advanced (newValue, oldValue) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.resetSearchForm()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.resetSearchForm()
+    }
+    // 仅刷新列表,不重置页面
+    if (this.$store.state.app.updateList) {
+      this.pageInit()
+      this.$refs.table.refresh()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+<style lang="less">
+  .tr-row{
+    text-align: left;
+    .tr-title{
+      font-weight: bold;
+    }
+    > div{
+      padding: 2px 0;
+      color: #666;
+      span{
+        color: #222;
+      }
+      .green{
+        color: #19be6b;
+      }
+      .red{
+        color: #ed1c24;
+      }
+      .code{
+        color: #00aaff;
+      }
+      .nums{
+        color: #ff0000;
+      }
+    }
+  }
+</style>

+ 4 - 4
src/router/index.js

@@ -1,7 +1,7 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-import { constantRouterMap, asyncRouterMap } from '@/config/router.config'
-
+import { constantRouterMap, asyncRouterMap, asyncMobileRouterMap } from '@/config/router.config'
+import { isMobileDevice } from '@/utils/util'
 // hack router push callback
 const originalPush = Router.prototype.push
 Router.prototype.push = function push (location, onResolve, onReject) {
@@ -10,10 +10,10 @@ Router.prototype.push = function push (location, onResolve, onReject) {
 }
 
 Vue.use(Router)
-
+console.log(isMobileDevice()?asyncMobileRouterMap:asyncRouterMap)
 export default new Router({
   mode: 'history',
   base: process.env.BASE_URL,
   scrollBehavior: () => ({ y: 0 }),
-  routes: constantRouterMap.concat(asyncRouterMap)
+  routes: constantRouterMap.concat(isMobileDevice()?asyncMobileRouterMap:asyncRouterMap)
 })

+ 15 - 0
src/utils/util.js

@@ -56,6 +56,21 @@ export const getBrowserType = function () {
   return browserType
 }
 
+export function isMobileDevice() {
+    // 方法1:通过userAgent检测
+    const userAgent = navigator.userAgent || navigator.vendor || window.opera;
+    const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
+    
+    // 方法2:通过屏幕宽度检测(通常移动端宽度小于768px)
+    const isSmallScreen = window.innerWidth < 768;
+    
+    // 方法3:检测触摸支持
+    const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
+    
+    // 综合判断
+    return mobileRegex.test(userAgent) || isSmallScreen || hasTouch;
+}
+
 export function timeFix () {
   const time = new Date()
   const hour = time.getHours()

+ 28 - 8
src/views/productManagement/productInfo/importGuideModal.vue

@@ -16,9 +16,9 @@
           </div>
           <ul>
             <li>1) 请先下载导入模板,模板中已标示出必填项</li>
-            <li>2) 产品编码具有唯一性,{{ guideType=='1'?'系统中已存在的无法导入':'下线导入,必须是系统中已存在的产品编码' }}</li>
+            <li>2) 产品编码具有唯一性,{{ guideType=='1'?'系统中已存在的无法导入':(guideType=='2'?'下线导入':'上线导入')+',必须是系统中已存在的产品编码' }}</li>
             <li v-if="guideType=='1'">3) 产品品牌、产品分类、单位、包装数单位、出库仓库、退货仓库,必须是系统中已经存在的值,否则无法导入</li>
-            <li v-if="guideType=='2'"><a :href="filePath" style="margin: 5px 0 0 15px;display: block;">
+            <li v-if="guideType=='2'||guideType=='3'"><a :href="guideType=='3' ? fileOnlinPath : filePath" style="margin: 5px 0 0 15px;display: block;">
               <a-icon type="download" style="padding-right: 5px;" />下载导入模板
             </a></li>
           </ul>
@@ -42,10 +42,11 @@
               ref="importUpload"
               :maxNums="1"
               fileType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
-              uploadType="import"
-              :action="attachAction"
+              :uploadType="guideType=='3' ? 'attach' : 'import'"
+              :action="guideType=='3' ? attachOnlinAction : attachAction"
               :uploadParams="uploadParams"
               upText="添加文件"
+              @remove="resetSearchForm"
               @change="changeImport"></Upload>
           </div>
         </div>
@@ -70,6 +71,7 @@
     <!-- 导入 -->
     <chooseImportModal :openModal="openImportModal" :paramsData="paramsData" @close="handleClose" @ok="hanldeOk" />
     <offlineImportModal :openModal="openOfflineImportModal" :paramsData="paramsData" @close="handleClose" @ok="hanldeOk" />
+    <onlineImportModal :openModal="openOnlineImportModal" :paramsData="paramsData" @close="handleClose" @ok="hanldeOk" />
   </a-modal>
 </template>
 
@@ -78,11 +80,12 @@ import { commonMixin } from '@/utils/mixin'
 // 组件
 import ChooseImportModal from './chooseImportModal.vue'
 import offlineImportModal from './offlineImportModal.vue'
+import onlineImportModal from './onlineImportModal.vue'
 import { Upload } from '@/components'
 export default {
   name: 'SalesImportGuideModal',
   mixins: [commonMixin],
-  components: { ChooseImportModal, offlineImportModal, Upload },
+  components: { ChooseImportModal, offlineImportModal, onlineImportModal, Upload },
   props: {
     openModal: { //  弹框显示状态
       type: Boolean,
@@ -98,24 +101,34 @@ export default {
       isShow: this.openModal, //  是否打开弹框
       openImportModal: false, //  打开新增产品导入弹框
       openOfflineImportModal: false, // 打开下线产品导入弹框
+      openOnlineImportModal: false, // 打开下线产品导入弹框
       attachAction: process.env.VUE_APP_API_BASE_URL + '/upload', // 上传地址
+      attachOnlinAction: process.env.VUE_APP_API_BASE_URL + '/product/importOnline',
       paramsData: null, // 导入参数
       uploadParams: {// 上传参数
         savePathType: 'local'
       },
       exportLoading: false, // 导出按钮加载状态
-      filePath: location.protocol + '//' + location.host + '/templ/批量下线导入模板.xlsx'// 模板地址
+      filePath: location.protocol + '//' + location.host + '/templ/批量下线导入模板.xlsx', // 模板地址
+      fileOnlinPath: location.protocol + '//' + location.host + '/templ/批量上线导入模板.xlsx'
     }
   },
   methods: {
+    // 清空数据
+    resetSearchForm () {
+      this.$refs.importUpload.setFileList() //  清空导入文件
+      this.paramsData = null //  清空上传数据
+    },
     // 下一步
     handlerNextStep () {
       const _this = this
       if (_this.paramsData) {
         if (_this.guideType == 1) {
           _this.openImportModal = true
-        } else {
+        } else if (_this.guideType == 2) {
           _this.openOfflineImportModal = true
+        } else {
+          _this.openOnlineImportModal = true
         }
       } else {
         _this.$message.warning('添加文件后再进行下一步操作!')
@@ -123,10 +136,16 @@ export default {
     },
     // 上传文件  change
     changeImport (file) {
-      if (file) {
+      if (file && this.guideType != 3) {
         this.paramsData = {
           path: file
         }
+      } else {
+        if (file && JSON.parse(file).length > 0) {
+          this.paramsData = Object.assign({}, JSON.parse(file)[0] || null)
+        } else {
+          this.paramsData = null
+        }
       }
     },
     // 导入
@@ -140,6 +159,7 @@ export default {
     handleClose () {
       this.openImportModal = false
       this.openOfflineImportModal = false
+      this.openOnlineImportModal = false
       this.isShow = false
     },
     // 下载模板

+ 3 - 2
src/views/productManagement/productInfo/list.vue

@@ -103,6 +103,7 @@
         <div class="table-operator">
           <a-button type="primary" id="productInfoList-add" v-if="$hasPermissions('B_productInfo_add')" @click="handleEdit()">新增</a-button>
           <a-button type="primary" id="productInfoList-addProduct" class="button-info" @click="handleMenuClick({key:'1'})" v-if="$hasPermissions('B_productInfo_batchImport')"> 新增产品导入</a-button>
+          <a-button type="primary" id="productInfoList-unline-import" class="button-info" @click="handleMenuClick({key:'3'})" v-if="$hasPermissions('B_offlineProduct_import')"> 上线产品导入</a-button>
           <a-button type="primary" id="productInfoList-import" class="button-info" @click="handleMenuClick({key:'2'})" v-if="$hasPermissions('B_offlineProduct_import')"> 下线产品导入</a-button>
           <a-button
             id="productInfoList-batchAudit"
@@ -258,7 +259,7 @@ import rangeDate from '@/views/common/rangeDate.vue'
 import importGuideModal from './importGuideModal.vue'
 import chooseWarehouse from '@/views/common/chooseWarehouse'
 // 接口
-import { productList, productAudit, productBatchAudit, productDel, productOnline, productBatchOnline, productExport, saveBatchImportProduct, importSaveBatch, updateHaltProdFlag } from '@/api/product'
+import { productList, productAudit, productBatchAudit, productDel, productOnline, productBatchOnline, productExport, saveBatchImportProduct, saveBatchImportOnlineProduct, importSaveBatch, updateHaltProdFlag } from '@/api/product'
 export default {
   name: 'ProductInfoList',
   mixins: [commonMixin],
@@ -367,7 +368,7 @@ export default {
     hanldeOk (obj) {
       this.spinning = true
       // importSaveBatch 下线导入
-      const ajaxName = obj && obj.type && obj.type == 'offline' ? importSaveBatch : saveBatchImportProduct
+      const ajaxName = obj && obj.type && obj.type == 'offline' ? importSaveBatch : (obj && obj.type && obj.type == 'online' ? saveBatchImportOnlineProduct : saveBatchImportProduct)
       ajaxName(obj).then(res => {
         if (res.status == 200) {
           this.resetSearchForm()

+ 177 - 0
src/views/productManagement/productInfo/onlineImportModal.vue

@@ -0,0 +1,177 @@
+<template>
+  <a-modal
+    centered
+    class="chooseImport-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="导入"
+    v-model="isShow"
+    @cancel="isShow=false"
+    width="80%">
+    <div class="chooseImport-con">
+      <!-- 可导入数据 -->
+      <p class="">可导入数据{{ loadData.length }}条,确认要批量上线吗?</p>
+      <a-table
+        class="sTable"
+        ref="table"
+        size="small"
+        :rowKey="(record) => record.allocateSn"
+        :columns="nowColumns"
+        :dataSource="loadData"
+        :loading="loading"
+        :scroll="{ y: 200}"
+        :pagination="false"
+        bordered>
+      </a-table>
+      <!-- 不可导入数据 -->
+      <p class="red">不可导入数据{{ unLoadData.length }}条</p>
+      <a-table
+        class="sTable"
+        ref="unTable"
+        size="small"
+        :rowKey="(record) => record.errorDesc"
+        :columns="nowUnColumns"
+        :dataSource="unLoadData"
+        :loading="loading"
+        :scroll="{ y: 200}"
+        :pagination="false"
+        bordered>
+      </a-table>
+      <!-- 按钮 -->
+      <div class="btn-con">
+        <a-button
+          type="primary"
+          id="chooseImport-submit"
+          size="large"
+          :class="loadData.length==0?'button-grey':'button-primary'"
+          @click="handleSubmit"
+          style="padding: 0 40px;">确认导入</a-button>
+        <a-button
+          id="chooseImport-cancel"
+          size="large"
+          class="button-cancel"
+          @click="isShow=false"
+          style="padding: 0 40px;margin-left: 15px;">取消</a-button>
+        <a-button
+          type="primary"
+          id="chooseImport-error"
+          size="large"
+          :class="unLoadData.length==0?'button-grey':'button-primary'"
+          class="button-error"
+          @click="handleError"
+          style="padding: 0 40px;margin-left: 15px;">导出错误项</a-button>
+      </div>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { hdExportExcel } from '@/libs/exportExcel'
+// 接口
+import { exportErrorOnlineProduct } from '@/api/product'
+export default {
+  name: 'SalesOnlineImportModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    paramsData: {// 导入数据
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      nowColumns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '95%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      loadData: [], // 可导入数据
+      nowUnColumns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '35%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '备注', dataIndex: 'remarks', width: '60%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      unLoadData: [], // 导入错误数据
+      loading: false// 列表加载状态
+    }
+  },
+  methods: {
+    formatData (data) {
+      data.map((item, index) => {
+        item.no = index + 1
+        item.id = new Date().getTime() + index
+      })
+      return data
+    },
+    getData () {
+      const paramsData = this.paramsData
+      this.loadData = this.formatData(paramsData.rightList || [])
+      this.unLoadData = this.formatData(paramsData.errorList || [])
+      console.log(this.loadData)
+      console.log(this.unLoadData)
+    },
+    // 确认导入
+    handleSubmit () {
+      if (this.loadData.length == 0) {
+        this.$message.warning('无可导入产品!')
+      } else {
+        this.loadData.type = 'online'
+        this.$emit('ok', this.loadData)
+        this.isShow = false
+      }
+    },
+    // 导出错误项
+    handleError () {
+      const _this = this
+      if (_this.unLoadData.length < 1) {
+        _this.$message.info('暂无可导出的错误项~')
+        return
+      }
+      _this.spinning = true
+      hdExportExcel(exportErrorOnlineProduct, _this.unLoadData, '导出上线产品错误项', function () {
+        _this.spinning = false
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.loadData = []
+        this.unLoadData = []
+      } else {
+        this.getData()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .chooseImport-modal{
+    .chooseImport-con{
+      .red{
+        color: #f30;
+      }
+      .btn-con{
+        text-align: center;
+        margin: 30px 0 20px;
+        .button-cancel,.button-error{
+          font-size: 12px;
+        }
+      }
+    }
+  }
+</style>

+ 17 - 7
src/views/reportData/dailyReport/table0.vue

@@ -19,11 +19,11 @@
             :key="cols+'td'"
             :width="cols==2?350:150"
             v-if="item['col'+cols]!==''"
-            :rowspan="hasRowspan(item['col'+cols])[1]"
-            :align="item['col'+cols].indexOf('.')>=0 ? (hasRate(item)&&cols>2?'center':'right'):'center'"
-            :class="item.key=='currRealFinish'||item.key=='currRealTireFinish'?'red':''"
+            :rowspan="hasRowspan(item['col'+cols])?hasRowspan(item['col'+cols])[1]:''"
+            :align="item['col'+cols]&&item['col'+cols].indexOf('.')>=0 ? (hasRate(item)&&cols>2?'center':'right'):'center'"
+            :class="item.key=='currRealFinish'||item.key=='currRealTireFinish'||item.key=='currNgkRealFinish'?'red':''"
           >
-            {{ hasRowspan(item['col'+cols])[1] ? hasRowspan(item['col'+cols])[0] : item['col'+cols] }}{{ hasRate(item)&&cols>2?'%':'' }}
+            {{ hasRowspan(item['col'+cols])&&hasRowspan(item['col'+cols])[1] ? hasRowspan(item['col'+cols])[0] : item['col'+cols] }}{{ hasRate(item)&&cols>2?'%':'' }}
           </td>
         </tr>
       </tbody>
@@ -72,6 +72,7 @@ export default {
     getmonths () {
       this.months = this.month.split('-')[1]
       this.dateStr = this.month.replace('-', '年') + '月'
+      console.log(this.dateStr)
     },
     // 是否显示截止日期
     getshowDz () {
@@ -112,7 +113,14 @@ export default {
         '预估完成|currExpectTireFinish',
         '离目标差额条数|currTargetTireDiff'
       ]
-      const row3 = ['本月实际销售额|totalCurrRealFinish', '本月预估完成|totalCurrExpectFinish']
+      const row3 = [
+        '截止1-' + (this.months - 1) + '月销售实际完成|histNgkSalesReal',
+        '累计' + this.months + '月销售实际截止完成|accuNgkSalesReal',
+        '本月实际销售|currNgkSalesReal',
+        '本月销售实际退货|currNgkReturnReal',
+        '本月销售实际完成|currNgkRealFinish'
+      ]
+      const row4 = ['本月实际销售额|totalCurrRealFinish', '本月预估完成|totalCurrExpectFinish']
       const getRows = function (row, arr, name) {
         row.forEach((item, i) => {
           const nameArr = item.split('|')
@@ -127,8 +135,10 @@ export default {
       getRows(row1, rets, '品牌')
       // 轮胎
       getRows(row2, rets, '轮胎')
-      // 品牌+轮胎
-      getRows(row3, rets, '品牌+轮胎')
+      // NGK
+      getRows(row3, rets, 'NGK')
+      // 品牌+轮胎+NGK
+      getRows(row4, rets, '品牌+轮胎+NGK')
       // 循环列
       rets.forEach(item => {
         this.tableData.forEach((cols, i) => {

+ 28 - 2
src/views/reportData/dailyReport/table3.vue

@@ -17,7 +17,8 @@
           </th>
           <th key="2" colspan="8" class="ant-table-align-center" style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">品牌</span><span class="ant-table-column-sorter"></span></div></span></th>
           <th key="3" colspan="4" class="ant-table-align-center" style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">轮胎</span><span class="ant-table-column-sorter"></span></div></span></th>
-          <th key="4" colspan="1" class="ant-table-align-center ant-table-row-cell-last" style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">品牌+轮胎</span><span class="ant-table-column-sorter"></span></div></span></th>
+          <th key="4" colspan="4" class="ant-table-align-center" style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">NGK</span><span class="ant-table-column-sorter"></span></div></span></th>
+          <th key="5" colspan="1" class="ant-table-align-center ant-table-row-cell-last" style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">品牌+轮胎+NGK</span><span class="ant-table-column-sorter"></span></div></span></th>
         </tr>
         <tr>
           <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">年度目标</span><span class="ant-table-column-sorter"></span></div></span></th>
@@ -32,6 +33,10 @@
           <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">{{ months }}月销售额截止达成</span><span class="ant-table-column-sorter"></span></div></span></th>
           <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">累计{{ months }}月截止完成</span><span class="ant-table-column-sorter"></span></div></span></th>
           <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">今日销售额</span><span class="ant-table-column-sorter"></span></div></span></th>
+          <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">截止1-{{ months-1 }}月销售额</span><span class="ant-table-column-sorter"></span></div></span></th>
+          <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">{{ months }}月销售额截止达成</span><span class="ant-table-column-sorter"></span></div></span></th>
+          <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">累计{{ months }}月截止完成</span><span class="ant-table-column-sorter"></span></div></span></th>
+          <th style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">今日销售额</span><span class="ant-table-column-sorter"></span></div></span></th>
           <th class="ant-table-align-center ant-table-row-cell-break-word ant-table-row-cell-last" style="text-align: center;"><span class="ant-table-header-column"><div><span class="ant-table-column-title">{{ months }}月销售额截止达成</span><span class="ant-table-column-sorter"></span></div></span></th>
         </tr>
       </thead>
@@ -46,7 +51,7 @@
             :colspan="index==list.length-1&&si==1?2:1"
             :style="index==list.length-1?'color: red;font-weight:bold;background:#dfdeff;border-color:#c7c7ff;':''"
           >
-            {{ si>1 ? Number(item[sitem.dataIndex]).toFixed(2) : item[sitem.dataIndex].toString() }}{{ sitem.title.indexOf('率')>=0?'%':'' }}
+            {{ si>1 ? Number(item[sitem.dataIndex]||0).toFixed(2) : item[sitem.dataIndex].toString() }}{{ sitem.title.indexOf('率')>=0?'%':'' }}
           </td>
         </tr>
       </tbody>
@@ -174,6 +179,27 @@ export default {
           align: 'center',
           width: '100'
         },
+        {
+          title: '截止1-' + (this.months - 1) + '月销售额',
+          dataIndex: 'histSalesRealNGKAmount',
+          align: 'center',
+          width: '100'
+        }, {
+          title: this.months + '月销售额截止达成',
+          dataIndex: 'currSalesNGKReal',
+          align: 'center',
+          width: '130'
+        }, {
+          title: '累计' + this.months + '月截止完成',
+          dataIndex: 'accuSalesRealNGKAmount',
+          align: 'center',
+          width: '100'
+        }, {
+          title: '今日销售额',
+          dataIndex: 'todaySalesNGKReal',
+          align: 'center',
+          width: '100'
+        },
         {
           title: this.months + '月销售额截止达成',
           dataIndex: 'totalCurrSalesTireReal',

+ 1 - 1
src/views/salesManagement/salesQueryNew/comps/activeQueryPart.vue

@@ -150,7 +150,7 @@ export default {
         this.disabled = true
         this.queryParam.dealerSn = this.buyerSn
         this.queryParam.promoProductClz = this.promoProductClz
-        return queryPromoProductPage(Object.assign(parameter, this.queryParam, { onlineFalg: '1' })).then(res => {
+        return queryPromoProductPage(Object.assign(parameter, this.queryParam, { onlineFalg: '1', productType3Flag: '1' })).then(res => {
           let data
           if (res.status == 200) {
             data = res.data

+ 1 - 1
src/views/salesManagement/salesQueryNew/comps/queryPart.vue

@@ -137,7 +137,7 @@ export default {
       loadData: parameter => {
         this.disabled = true
         this.queryParam.dealerSn = this.buyerSn
-        return queryStockProductPage(Object.assign(parameter, this.queryParam, { onlineFalg: '1' })).then(res => {
+        return queryStockProductPage(Object.assign(parameter, this.queryParam, { onlineFalg: '1', productType3Flag: '1' })).then(res => {
           let data
           if (res.status == 200) {
             data = res.data

+ 14 - 2
src/views/salesManagement/salesQueryNew/printModal.vue

@@ -71,6 +71,13 @@
             <a-radio :value="0">不导出</a-radio>
           </a-radio-group>
         </a-form-model-item>
+        <!-- 原厂编码 -->
+        <a-form-model-item label="原厂编码" prop="origCode" v-if="nowType=='export'">
+          <a-radio-group v-model="form.origCode">
+            <a-radio :value="1">导出</a-radio>
+            <a-radio :value="0">不导出</a-radio>
+          </a-radio-group>
+        </a-form-model-item>
       </a-form-model>
       <div class="btn-cont">
         <a-button id="sales-print-back" @click="cancel">取消</a-button>
@@ -109,7 +116,8 @@ export default {
         dataScope: 'all',
         priceType: undefined,
         orderBy: undefined,
-        averagePrice: undefined
+        averagePrice: undefined,
+        origCode: undefined
       },
       // 选项校验
       rules: {
@@ -117,7 +125,8 @@ export default {
         dataScope: [{ required: true, message: '请选择是否缺货产品', trigger: 'change' }],
         priceType: [{ required: true, message: '请选择产品售价', trigger: 'change' }],
         orderBy: [{ required: true, message: '请选择货位编号', trigger: 'change' }],
-        averagePrice: [{ required: true, message: '请选择平均公斤单价', trigger: 'change' }]
+        averagePrice: [{ required: true, message: '请选择平均公斤单价', trigger: 'change' }],
+        origCode: [{ required: true, message: '请选择原厂编码', trigger: 'change' }]
       },
       formItemLayout: {
         labelCol: { span: 6 },
@@ -196,6 +205,9 @@ export default {
             if (_this.form.averagePrice == '1') {
               _this.form.priceType += '_WEIGHT'
             }
+            if (_this.form.origCode == '1') {
+              _this.form.priceType += '_ORIG_CODE'
+            }
             const obj = {
               salesBillSn: _this.itemData.salesBillSn,
               priceType: _this.form.priceType,

+ 0 - 2
src/views/salesManagement/sendOutOrder/chooseImportModal.vue

@@ -185,8 +185,6 @@ export default {
       const paramsData = JSON.parse(JSON.stringify(this.paramsData))
       this.loadData = this.formatData(paramsData.rightList || [])
       this.unLoadData = this.formatData(paramsData.errorList || [])
-      console.log(this.loadData)
-      console.log(this.unLoadData)
     },
     // 确认导入
     handleSubmit () {

+ 21 - 7
src/views/setting/removeSetting/baseModal.vue

@@ -40,8 +40,18 @@
         </a-row>
         <a-row :gutter="15">
           <a-col :span="20">
-            <a-form-model-item label="运费、服务费" prop="tireSubsidyYfFwf">
-              <a-radio-group name="radioGroup" v-model="form.tireSubsidyYfFwf">
+            <a-form-model-item label="运费" prop="tireSubsidyYf">
+              <a-radio-group name="radioGroup" v-model="form.tireSubsidyYf">
+                <a-radio value="1">剔除</a-radio>
+                <a-radio value="0">不剔除</a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+        <a-row :gutter="15">
+          <a-col :span="20">
+            <a-form-model-item label="服务费" prop="tireSubsidyFwf">
+              <a-radio-group name="radioGroup" v-model="form.tireSubsidyFwf">
                 <a-radio value="1">剔除</a-radio>
                 <a-radio value="0">不剔除</a-radio>
               </a-radio-group>
@@ -107,14 +117,16 @@ export default {
         dealerSn: undefined,
         configType: 'TIRE_SUBSIDY',
         bizSn: undefined, // bizsn
-        tireSubsidyYfFwf: undefined,
+        tireSubsidyYf: undefined,
+        tireSubsidyFwf: undefined,
         tireSubsidyZl: undefined,
         tireSubsidyGc: undefined
       },
       rules: {
         bizNo: [{ required: true, message: '请输入业务单号', trigger: ['change', 'blur'] }],
         dealerSn: [{ required: true, message: '请选择客户', trigger: ['change', 'blur'] }],
-        tireSubsidyYfFwf: [{ required: true, message: '请选择', trigger: ['change', 'blur'] }],
+        tireSubsidyYf: [{ required: true, message: '请选择', trigger: ['change', 'blur'] }],
+        tireSubsidyFwf: [{ required: true, message: '请选择', trigger: ['change', 'blur'] }],
         tireSubsidyZl: [{ required: true, message: '请选择', trigger: ['change', 'blur'] }],
         tireSubsidyGc: [{ required: true, message: '请选择', trigger: ['change', 'blur'] }]
       },
@@ -183,7 +195,8 @@ export default {
         bizNo: '',
         dealerSn: undefined,
         bizSn: undefined, // bizsn
-        tireSubsidyYfFwf: undefined,
+        tireSubsidyYf: undefined,
+        tireSubsidyFwf: undefined,
         tireSubsidyZl: undefined,
         tireSubsidyGc: undefined
       }
@@ -194,13 +207,14 @@ export default {
     },
     getDetail () {
       bizRemoveConfigDetail({ bizSn: this.bizSn, configType: 'TIRE_SUBSIDY' }).then(res => {
-        const { bizSn, bizNo, dealerSn, dealerName, tireSubsidyYfFwf, tireSubsidyZl, tireSubsidyGc } = res.data
+        const { bizSn, bizNo, dealerSn, dealerName, tireSubsidyYf, tireSubsidyFwf, tireSubsidyZl, tireSubsidyGc } = res.data
         this.dealerData = { dealerName: dealerName }
         this.form = Object.assign(this.form, {
           bizNo: bizNo,
           dealerSn: dealerSn,
           bizSn: bizSn,
-          tireSubsidyYfFwf: tireSubsidyYfFwf,
+          tireSubsidyYf: tireSubsidyYf,
+          tireSubsidyFwf: tireSubsidyFwf,
           tireSubsidyZl: tireSubsidyZl,
           tireSubsidyGc: tireSubsidyGc
         })

+ 2 - 2
src/views/setting/removeSetting/index.vue

@@ -8,9 +8,9 @@
         <a-tab-pane key="2" tab="每日报表剔除" force-render>
           <list2></list2>
         </a-tab-pane>
-        <!-- <a-tab-pane key="3" tab="轮胎补贴剔除" force-render>
+        <a-tab-pane key="3" tab="轮胎补贴剔除" force-render>
           <list3></list3>
-        </a-tab-pane> -->
+        </a-tab-pane>
       </a-tabs>
     </a-card>
   </div>

+ 5 - 4
src/views/setting/removeSetting/list.vue

@@ -174,12 +174,13 @@ export default {
         { title: '业务单号', dataIndex: 'bizNo', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '业务状态', dataIndex: 'billStatusName', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '业务时间', dataIndex: 'bizDate', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '客户名称', dataIndex: 'dealerName', width: '18%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '运费、服务费', dataIndex: 'tireSubsidyYfFwf', width: '10%', align: 'center', customRender: function (text) { return a[text] } },
+        { title: '客户名称', dataIndex: 'dealerName', width: '16%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '运费', dataIndex: 'tireSubsidyYf', width: '8%', align: 'center', customRender: function (text) { return a[text] } },
+        { title: '服务费', dataIndex: 'tireSubsidyFwf', width: '8%', align: 'center', customRender: function (text) { return a[text] } },
         { title: '增量补贴', dataIndex: 'tireSubsidyZl', width: '8%', align: 'center', customRender: function (text) { return a[text] } },
-        { title: '供应商返利', dataIndex: 'tireSubsidyGc', width: '10%', align: 'center', customRender: function (text) { return a[text] } },
+        { title: '供应商返利', dataIndex: 'tireSubsidyGc', width: '8%', align: 'center', customRender: function (text) { return a[text] } },
         { title: '创建时间', dataIndex: 'createDate', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '8%', align: 'center' }
       ]
       return arr
     }

+ 2 - 6
src/views/user/Login.vue

@@ -116,12 +116,12 @@
 </template>
 
 <script>
-import md5 from 'md5'
+// import md5 from 'md5'
 import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
 import { mapActions } from 'vuex'
 import { timeFix } from '@/utils/util'
 import { getSmsCaptcha, get2step } from '@/api/login'
-import { updateTheme } from '@/components/SettingDrawer/settingConfig'
+// import { updateTheme } from '@/components/SettingDrawer/settingConfig'
 
 export default {
   components: {
@@ -159,7 +159,6 @@ export default {
     //   })
     // this.requiredTwoStepCaptcha = true
     const rem = this.$cookies.get('REMEMBER_ME')
-    console.log(rem)
     if (rem && rem.rememberMe) {
       this.username = rem.username
       this.password = rem.password
@@ -264,11 +263,9 @@ export default {
       })
     },
     loginSuccess (res) {
-      console.log(res)
       // check res.homePage define, set $router.push name res.homePage
       // Why not enter onComplete
       this.$router.push({ name: 'index' }, () => {
-        console.log('onComplete')
         this.$notification.success({
           message: '欢迎',
           description: `${timeFix()},欢迎回来`
@@ -277,7 +274,6 @@ export default {
       this.isLoginError = false
     },
     requestFailed (err) {
-      console.log(err, 'error')
       this.isLoginError = true
       this.$notification['error']({
         message: '提示',

+ 1 - 1
vue.config.js

@@ -107,7 +107,7 @@ const vueConfig = {
     // If you want to turn on the proxy, please remosve the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        // target: 'http://192.168.2.10/ocs-admin',
+        // target: 'http://192.168.2.132/ocs-admin',
         // target: 'https://t.ocs.360arrow.com/ocs-admin', //  练习
         target: 'https://p.ocs.360arrow.com/ocs-admin', //  预发布
         ws: false,