| <template> | 
|   <TableLayout v-permissions="['ext:wstockext:query']"> | 
|     <!-- 搜索表单 --> | 
|     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" label-suffix=":" inline> | 
|       <el-form-item label="汇总依据" prop="groupType"> | 
|          <el-select v-model="searchForm.groupType" clearable placeholder="请选择" @change="search"> | 
|             <el-option | 
|               v-for="(item, index) in groupTypes" | 
|               :key="index" | 
|               :label="item.name" | 
|               :value="item.id"> | 
|             </el-option> | 
|           </el-select> | 
|       </el-form-item> | 
|       <el-form-item label="质量属性" prop="qualityType"> | 
|          <el-select v-model="searchForm.qualityType" clearable placeholder="请选择" @change="search"> | 
|             <el-option | 
|               v-for="(item, index) in qualityTypes" | 
|               :key="index" | 
|               :label="item.name" | 
|               :value="item.id"> | 
|             </el-option> | 
|           </el-select> | 
|       </el-form-item> | 
|       <!-- <el-form-item label="物料编码" prop="code"> | 
|         <el-input v-model="searchForm.code" placeholder="请输入物料编码" @keypress.enter.native="search"></el-input> | 
|       </el-form-item> --> | 
|       <el-form-item label="物料信息" prop="materialName"> | 
|         <el-input v-model="searchForm.materialName" placeholder="请输入物料名称/编码" @keypress.enter.native="search"></el-input> | 
|       </el-form-item> | 
|       <el-form-item label="批次号" prop="batch"> | 
|         <el-input v-model="searchForm.batch" placeholder="请输入批次号" @keypress.enter.native="search"></el-input> | 
|       </el-form-item> | 
|       <el-form-item label="工序名称" prop="procedureName"> | 
|         <el-input v-model="searchForm.procedureName" placeholder="请输入工序名称" @keypress.enter.native="search"></el-input> | 
|       </el-form-item> | 
|       <el-form-item label="所属仓库" prop="materialOrBatch"> | 
|         <el-input v-model="searchForm.materialOrBatch" placeholder="请输入仓库名称" @keypress.enter.native="search"></el-input> | 
|       </el-form-item> | 
|       <section> | 
|         <el-button type="primary" @click="search">搜索</el-button> | 
|         <el-button @click="reset">重置</el-button> | 
|       </section> | 
|     </el-form> | 
|     <!-- 表格和分页 --> | 
|     <template v-slot:table-wrap> | 
|       <ul class="toolbar"> | 
|         <!-- <li v-permissions="['ext:plansext:importExcel']"> | 
|           <ImportButton | 
|             text="导入" | 
|             template-name="stock_import_template.xlsx" | 
|             template-path="template/stock_import_template.xlsx" | 
|             action="/ext/wStockExt/importBatch" | 
|             @success="search" | 
|           /> | 
|         </li> --> | 
|         <li v-permissions="['ext:wstockext:exportExcel']"><el-button type="primary" @click="exportExcel">导出</el-button></li> | 
|       </ul> | 
|       <div style="display: flex;"> | 
|         <div class="tree-scroll"> | 
|           <!-- <Tree | 
|             :list="data" | 
|             :defaultProps="defaultProps" | 
|             @callback="callback" | 
|           ></Tree> --> | 
|           <el-tree  | 
|             :props="defaultProps" | 
|             :load="loadNode" | 
|             highlight-current | 
|             lazy | 
|             :accordion="true" | 
|             @node-click="handleNodeClick" | 
|           > | 
|             <template slot-scope="{ data }"> | 
|               <span class="long-title-style tree_item_label" :class="{'activeColor':isSelect(data)}" :title="data.name">{{ data.name }}</span> | 
|             </template> | 
|           </el-tree> | 
|         </div> | 
|         <!-- <div style="width: 1%; background-color: #f9f9f9;"></div> --> | 
|         <!-- v-loading="isWorking.search" --> | 
|         <div style="width: 80%;"> | 
|           <el-table | 
|             :data="tableData.list" | 
|             stripe | 
|             border | 
|             :summary-method="getSummaries" | 
|             show-summary | 
|             @selection-change="handleSelectionChange" | 
|           > | 
|             <el-table-column prop="materialCode" fixed="left" label="物料编码" min-width="160px"> | 
|               <template slot-scope="{row}"> | 
|                 {{ row.materialCode }} | 
|               </template> | 
|             </el-table-column> | 
|             <el-table-column prop="materialName" label="物料名称" show-overflow-tooltip min-width="100px"> | 
|               <template slot-scope="{row}"> | 
|                 <span class="long-title-style">{{ row.materialName }}</span> | 
|               </template> | 
|             </el-table-column> | 
|             <el-table-column prop="attr" label="规格" min-width="100px"></el-table-column> | 
|             <el-table-column v-if="searchForm.groupType == 3" prop="batch" label="批次号" min-width="100px"></el-table-column> | 
|             <el-table-column prop="procedureName" label="工序" min-width="100px"> | 
|               <template slot-scope="{row}"> | 
|                 <span >{{ row.procedureName || '-' }}</span> | 
|               </template> | 
|             </el-table-column> | 
|             <el-table-column label="质量属性" min-width="100px"> | 
|               <template slot-scope="{row}"> | 
|                 <span v-if="row.qualityType==0" class="valid-style">合格</span> | 
|                 <span v-else-if="row.qualityType==1" class="unvalid-style">不良</span> | 
|                 <span v-else-if="row.qualityType==2" class="scrap-style">报废</span> | 
|                 <span v-else>-</span> | 
|               </template> | 
|             </el-table-column> | 
|             <el-table-column v-if="searchForm.groupType != 1" prop="wareHouseName" label="仓库" show-overflow-tooltip min-width="100px"> | 
|               <template slot-scope="{row}"> | 
|                 <span class="long-title-style">{{ row.wareHouseName }}</span> | 
|               </template> | 
|             </el-table-column> | 
|             <el-table-column v-if="searchForm.groupType != 1" prop="locationName" label="货位" show-overflow-tooltip min-width="100px"> | 
|               <template slot-scope="{row}"> | 
|                 <span class="long-title-style">{{ row.locationName }}</span> | 
|               </template> | 
|             </el-table-column> | 
|             <el-table-column prop="num" fixed="right" label="库存数量" min-width="100px"> | 
|                <template slot-scope="{row}"> | 
|                 {{ row. num + row.unitName}} | 
|                </template> | 
|             </el-table-column> | 
|             <!-- <el-table-column prop="unitName" label="单位" min-width="100px"></el-table-column> --> | 
|           </el-table> | 
|           <pagination | 
|             @size-change="handleSizeChange" | 
|             @current-change="handlePageChange" | 
|             :pagination="tableData.pagination" | 
|           ></pagination> | 
|         </div> | 
|       </div> | 
|     </template> | 
|   </TableLayout> | 
| </template> | 
|   | 
| <script> | 
| import BaseTable from '@/components/base/BaseTable' | 
| import TableLayout from '@/layouts/TableLayout' | 
| import Pagination from '@/components/common/Pagination' | 
| import Tree from '@/components/common/Tree' | 
| import ImportButton from '@/components/common/ImportButton' | 
| import { queryWareHouserAndLocaltion } from '@/api/ext/warehouseExt' | 
| import { getListByWarehouseId } from '@/api/ext/warehouseLocationExt' | 
| // import { queryWarehouseAllData } from '@/api/ext/warehouseExt' | 
| import { addPrecision } from '@/utils/util' | 
| export default { | 
|   name: 'WStockExt', | 
|   extends: BaseTable, | 
|   components: { TableLayout, Pagination, Tree, ImportButton }, | 
|   data () { | 
|     return { | 
|       // 搜索 | 
|       searchForm: { | 
|         groupType: 3, | 
|         materialName: null, | 
|         warehouseId: null, | 
|         qualityType: null, | 
|         materialOrBatch: null, | 
|         locationId: null, | 
|         greaterZero: 1, | 
|         batch: null, | 
|         procedureName: null, | 
|       }, | 
|       tempWarehouseId: null, | 
|       tempLocaltionId: null, | 
|       groupTypes: [ | 
|         { name: '物料+仓库+批次号', id: 3 }, | 
|         { name: '物料+仓库', id: 2 }, | 
|         { name: '物料', id: 1 } | 
|       ], | 
|       warehouseType: [ | 
|         // 0原材料库 1半成品库 2成品库 3不良品库 4线边库 | 
|         { name: '原材料库', id: 0 }, | 
|         { name: '半成品库', id: 1 }, | 
|         { name: '成品库', id: 2 }, | 
|         { name: '不良品库', id: 3 }, | 
|         { name: '线边库', id: 4 } | 
|       ], | 
|       qualityTypes: [ | 
|         { name: '合格', id: 0 }, | 
|         { name: '不良', id: 1 }, | 
|         { name: '报废', id: 2 }, | 
|       ], | 
|       data: [], | 
|       defaultProps: { | 
|         children: 'warehouseLocationList', | 
|         label: 'name', | 
|         isLeaf: 'isLeaf', | 
|         id: 'id' | 
|       } | 
|     } | 
|   }, | 
|   created () { | 
|     this.config({ | 
|       module: '物料库存余额信息', | 
|       api: '/ext/wStockExt', | 
|       'field.id': 'id', | 
|       'field.main': 'name', | 
|       sorts: [{ direction: 'DESC', property: 'CREATE_TIME' }] | 
|     }) | 
|     this.search() | 
|   }, | 
|   methods: { | 
|     loadNode (node, resolve) { | 
|       console.log(node); | 
|       if (node.level === 0) { | 
|         queryWareHouserAndLocaltion({ status: 1 }) | 
|           .then(res => { | 
|             let wareHouse = this.tree(res, false) | 
|             return resolve(wareHouse) | 
|           }) | 
|           .catch(err => { | 
|             console.log(err) | 
|           }) | 
|       } else { | 
|         getListByWarehouseId(node.data.id, null) | 
|           .then(res => { | 
|             let houseLocation = this.tree(res, true) | 
|             return resolve(houseLocation) | 
|           }) | 
|           .catch(err => { | 
|   | 
|           }) | 
|          | 
|       } | 
|     }, | 
|     handleNodeClick (data) { | 
|       // debugger | 
|       if (data.isLeaf) { | 
|         this.searchForm.locationId = data.id | 
|       } else { | 
|         if (this.searchForm.warehouseId === data.id) { | 
|           this.searchForm.warehouseId = null | 
|         } else { | 
|           this.searchForm.warehouseId = data.id | 
|         } | 
|         this.searchForm.locationId = null | 
|       } | 
|       this.search() | 
|     }, | 
|     // callback (data, item) { | 
|     //   // console.log(data, item) | 
|     //   if (item.warehouseLocationList) { | 
|     //     // 点击的是仓库 | 
|     //     if (this.searchForm.warehouseId === data.id) { | 
|     //       this.searchForm.warehouseId = null | 
|     //     } else { | 
|     //       this.searchForm.warehouseId = data.id | 
|     //     } | 
|     //     this.searchForm.locationId = null | 
|     //   } else { | 
|     //     this.searchForm.locationId = data.id | 
|     //   } | 
|     //   // console.log(this.searchForm.warehouseId, this.searchForm.locationId); | 
|     //   this.search() | 
|     // }, | 
|     // 树数据处理 | 
|     tree (treeArray, isLeaf) { | 
|       const array = [] | 
|       for (const item of treeArray) { | 
|         if (!item.name) { | 
|           item.name = item.unionName | 
|         } | 
|         item.isLeaf = isLeaf | 
|         array.push(item) | 
|       } | 
|       // console.log(array) | 
|       return array | 
|     }, | 
|     typeToStr (type) { | 
|       for (const item of this.warehouseType) { | 
|         if (item.id === type) return item.name | 
|       } | 
|     }, | 
|     getNanme (row) { | 
|       // console.log('row', row); | 
|       return 'test' | 
|     }, | 
|     isSelect (data) { | 
|       // console.log('data',data.isLeaf, data.id); | 
|       // console.log('this.searchForm',this.searchForm.locationId, this.searchForm.warehouseId); | 
|       if (data.isLeaf) { | 
|         return data.id === this.searchForm.locationId | 
|       } else { | 
|         return data.id === this.searchForm.warehouseId && !this.searchForm.locationId | 
|       } | 
|     }, | 
|     add(num1, num2) { | 
|       const num1Digits = (num1.toString().split('.')[1] || '').length; | 
|       const num2Digits = (num2.toString().split('.')[1] || '').length; | 
|       const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits)); | 
|       return (num1 * baseNum + num2 * baseNum) / baseNum; | 
|     }, | 
|     getSummaries (param) { | 
|       const { columns, data } = param; | 
|       const sums = []; | 
|       columns.forEach((column, index) => { | 
|         if (index === 0) { | 
|           sums[index] = '合计'; | 
|           return; | 
|         } else if (index === 2 || index === 3 || index === 4 || index === 5 || index === 7) { | 
|           sums[index] = '-'; | 
|           return; | 
|         } | 
|         const values = data.map(item => Number(item[column.property])); | 
|         if (!values.every(value => isNaN(value))) { | 
|           sums[index] = 0 | 
|           values.forEach(item => { | 
|             sums[index] = addPrecision(item, sums[index]) | 
|           }) | 
|            | 
|         } else { | 
|           sums[index] = '-'; | 
|         } | 
|       }); | 
|       return sums | 
|     } | 
|   } | 
| } | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
| .tree-scroll { | 
|   width: 15%; | 
|   max-height: 560px; | 
|   overflow-y: scroll; | 
| } | 
|   | 
| // .tree-scroll::-webkit-scrollbar { | 
| //   // 滚动条整体部分,可以设置宽度等 | 
| //   width: 2px; | 
| //   height: 10px; | 
| //   // display: none; | 
| // } | 
| // .tree-scroll::-webkit-scrollbar-thumb { | 
| //   // 滚动条里面的滑块 | 
| //   border-radius: 5px; | 
| //   // display: none; | 
| // } | 
| // .tree-scroll::-webkit-scrollbar-button { | 
| //   // 滚动条轨道两端的按钮,允许通过点击以微调滑块的位置 | 
| //   width: 10px; | 
| //   border-radius: 50%; | 
| //   display: none; | 
| // } | 
| // .tree-scroll::-webkit-scrollbar-track { | 
| //   // 滚动条的轨道(里面装有thumb) | 
| //   box-shadow: inset 0 0 2px #333; | 
| //   border-radius: 5px; | 
| //   display: none; | 
| // } | 
| // .tree-scroll::-webkit-scrollbar-corner { | 
| //   // 当同时有垂直滚动条和水平滚动条时的交汇处 | 
| //   // background: springgreen; | 
| //   display: none; | 
| // } | 
| .tree_item_label { | 
|     font-size: 14px; | 
|     font-weight: 400; | 
|     color: #333333; | 
|     white-space: nowrap; | 
| } | 
| .activeColor { | 
|     color: #305ED5 !important; | 
| } | 
| </style> |