Przeglądaj źródła

feat: 新增出库增加锁定数量和可用数量列显示

liujt 1 tydzień temu
rodzic
commit
0b138b9a1d

+ 19 - 0
src/views/warehouseManagement/components/AssetsDialog.vue

@@ -440,6 +440,25 @@
             showOverflowTooltip: true,
             showOverflowTooltip: true,
             slot: 'outboundNum'
             slot: 'outboundNum'
           },
           },
+          {
+            prop: 'lockQuantity',
+            label: '锁定数量',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'availableQuantity',
+            label: '可用数量',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              // 使用整数运算避免浮点数精度丢失
+              const measure = Number(row.measureQuantity) || 0;
+              const lock = Number(row.lockQuantity) || 0;
+              const result = (measure * 100 - lock * 100) / 100;
+              return Math.round(result * 100) / 100;
+            }
+          },
           {
           {
             prop: 'inventoryCycle',
             prop: 'inventoryCycle',
             label: '存货周期(天)',
             label: '存货周期(天)',

+ 752 - 0
src/views/warehouseManagement/stockManagement/components/itemListed.vue

@@ -0,0 +1,752 @@
+<template>
+  <ele-modal
+    :visible.sync="visible"
+    title="上架"
+    :before-close="cancel"
+    width="80%"
+    :close-on-click-modal="false"
+    :maxable="true"
+    :append-to-body="true"
+    custom-class="ele-dialog-form"
+  >
+    <el-row :gutter="20">
+      <!-- 左侧:物品清单 -->
+      <el-col :span="10">
+        <div class="section-title">物品清单</div>
+        <div class="dimension-tabs">
+          <span class="dimension-label">维度:</span>
+          <el-radio-group v-model="dimension" @change="dimensionChange" size="small">
+            <el-radio-button :label="1">批次维度</el-radio-button>
+            <!-- <el-radio-button :label="2">物品维度</el-radio-button> -->
+            <el-radio-button :label="3">包装维度</el-radio-button>
+          </el-radio-group>
+        </div>
+        <el-table
+          ref="tableRef"
+          :data="tableData"
+          style="width: 100%"
+          max-height="300"
+          border
+          @selection-change="handleSelectionChange"
+        >
+          <el-table-column
+            type="selection"
+            width="50"
+            fixed="left"
+            align="center"
+            :selectable="checkSelectable"
+          />
+          <el-table-column type="index" label="序号" width="50" align="center" />
+          <el-table-column prop="categoryCode" label="物品编码" min-width="120" align="center" show-overflow-tooltip />
+          <el-table-column prop="categoryName" label="名称" min-width="120" align="center" show-overflow-tooltip />
+          <el-table-column prop="batchNo" label="批次号" min-width="140" align="center" show-overflow-tooltip />
+          <el-table-column prop="measureQuantity" label="数量" width="80" align="center" />
+          <el-table-column prop="measureUnit" label="单位" width="70" align="center" />
+          <el-table-column prop="packingQuantity" label="计量数量" width="90" align="center" />
+          <el-table-column prop="packingUnit" label="计量单位" width="90" align="center" />
+          <el-table-column prop="singleWeight" label="单重" width="80" align="center" />
+          <el-table-column prop="totalWeight" label="总重" width="80" align="center" />
+          <el-table-column prop="weightUnit" label="重量单位" width="90" align="center" />
+          <el-table-column prop="colorKey" label="颜色" width="80" align="center" show-overflow-tooltip />
+          <el-table-column prop="categoryModel" label="型号" width="100" align="center" show-overflow-tooltip />
+          <el-table-column prop="specification" label="规格" width="100" align="center" show-overflow-tooltip />
+          <el-table-column prop="gradeName" label="牌号" width="80" align="center" show-overflow-tooltip />
+          <el-table-column prop="voltage" label="电压" width="80" align="center" />
+          <el-table-column prop="approvalNumber" label="批准文号" width="120" align="center" show-overflow-tooltip />
+          <el-table-column prop="packingSpec" label="包装规格" width="100" align="center" show-overflow-tooltip />
+          <el-table-column prop="allowUnpack" label="允许拆包" width="90" align="center" />
+          <el-table-column prop="supplierName" label="供应商" min-width="120" align="center" show-overflow-tooltip />
+          <el-table-column prop="warehouseName" label="仓库" min-width="100" align="center" show-overflow-tooltip />
+          <el-table-column prop="productionDate" label="生产日期" width="110" align="center" />
+          <el-table-column prop="purchaseDate" label="采购日期" width="110" align="center" />
+          <el-table-column prop="expiryDate" label="失效日期" width="110" align="center" />
+        </el-table>
+      </el-col>
+
+      <!-- 右侧:上架信息 -->
+      <el-col :span="14">
+        <div class="section-title">上架信息</div>
+        <el-form :model="formData" label-width="100px">
+          <el-row>
+            <el-col :span="8">
+              <el-form-item label="选择仓库">
+                <el-select filterable disabled v-model="warehouse" @change="warehouseChange">
+                  <el-option
+                    v-for="(item, index) in warehouseList"
+                    :key="index"
+                    :label="item.name"
+                    :value="item.id"
+                    @click.native="changeWarehouse(item)"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="选择库区">
+                <el-select filterable v-model="area" @change="getshelvesList">
+                  <el-option
+                    v-for="(item, index) in areaList"
+                    :key="index"
+                    :label="item.name"
+                    :value="item.id"
+                    @click.native="formData.area = item"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="选择货架">
+                <el-select filterable v-model="formData.shelves" @change="changeshelvesList">
+                  <el-option
+                    v-for="(item, index) in shelvesList"
+                    :key="index"
+                    :label="item.goodsshelvesCode"
+                    :value="item.goodsshelvesCode"
+                    @click.native="formData.shelves = item"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+
+        <div class="status-legend">
+          <div v-for="(item, index) in locationStatusList" :key="index">
+            <span :style="{ 'background-color': item.color }"></span>{{ item.label }}
+          </div>
+        </div>
+
+        <div class="content-box">
+          <div
+            v-for="p in locationList"
+            :key="p.id"
+            class="box"
+            @click="handlCur(p)"
+            :class="{ selected: isLocationSelected(p.id) }"
+            :style="{
+              'background-color': getStatus(p.allocationStatus).color,
+              cursor: [1, 2].includes(p.allocationStatus) ? 'pointer' : 'not-allowed'
+            }"
+          >
+            {{ p.goodsAllocationCode }}
+          </div>
+          <div v-for="n in placeholderCount" :key="'ph-' + n" class="placeholder-box"></div>
+        </div>
+
+        <!-- 添加行 + 上架列表 -->
+        <div style="margin-top: 12px;">
+          <el-button type="primary" size="small" @click="addRow">添加行</el-button>
+        </div>
+        <el-table :data="shelvingList" style="width: 100%; margin-top: 8px;" border>
+          <el-table-column label="序号" type="index" width="50" align="center" />
+          <el-table-column label="货位位置" min-width="320" align="center">
+            <template slot-scope="scope">
+              <el-select
+                v-model="scope.row.cargoSpaceId"
+                filterable
+                placeholder="选择货位"
+                size="small"
+                style="width: 300px;"
+                @change="(val) => onLocationChange(val, scope.row)"
+              >
+                <el-option
+                  v-for="opt in locationOptions"
+                  :key="opt.value"
+                  :label="opt.label"
+                  :value="opt.value"
+                />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="物品批次" min-width="280" align="center">
+            <template slot-scope="scope">
+              <el-select
+                v-model="scope.row.itemKey"
+                filterable
+                placeholder="选择物品批次"
+                size="small"
+                style="width: 260px;"
+                @change="(val) => onItemChange(val, scope.row)"
+              >
+                <el-option
+                  v-for="opt in itemOptions"
+                  :key="opt.value"
+                  :label="opt.label"
+                  :value="opt.value"
+                />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="数量" width="160" align="center">
+            <template slot-scope="scope">
+              <el-input-number
+                v-model="scope.row.quantity"
+                :min="0"
+                :max="scope.row.maxQuantity"
+                size="small"
+                controls-position="right"
+                style="width: 130px;"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column width="80" label="操作" fixed="right" align="center">
+            <template slot-scope="scope">
+              <el-button type="text" @click="delItem(scope.$index)" size="small">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-col>
+    </el-row>
+
+    <div class="modal-footer">
+      <el-button @click="handleSelect" type="primary" :loading="confirmLoading">确认</el-button>
+      <el-button @click="cancel">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import storageApi from '@/api/warehouseManagement';
+  import warehouseDefinition from '@/api/warehouseManagement/warehouseDefinition';
+  import { useDict } from '@/utils/dict/index';
+
+  const locationStatusList = [
+    { code: 1, label: '空置', color: 'rgba(202, 249, 130, 1)' },
+    { code: 2, label: '在用', color: 'rgba(129, 211, 248, 1)' },
+    { code: 3, label: '已满', color: 'rgba(255, 14, 14, 1)' },
+    { code: 4, label: '失效', color: 'rgba(215, 215, 215, 1)' }
+  ];
+
+  export default {
+    name: 'ItemListed',
+    data() {
+      return {
+        locationStatusList,
+        visible: false,
+        rowData: null,
+        dimension: 1, // 1-批次维度 2-物品维度 3-包装维度
+
+        // 物品表格
+        tableLoading: false,
+        tableData: [],
+        allTableData: [],
+        selection: [],
+        shelvedItemKeys: [],
+
+        // 仓库选择
+        warehouseList: [],
+        areaList: [],
+        warehouse: '',
+        area: '',
+        shelves: '',
+        formData: {
+          warehouse: {},
+          area: {},
+          shelves: {}
+        },
+        shelvesList: [],
+        locationList: [],
+        selectedLocations: [],
+
+        // 上架清单
+        shelvingList: [],
+        confirmLoading: false
+      };
+    },
+
+    computed: {
+      locationOptions() {
+        return this.selectedLocations.map((l) => ({
+          label: `${l.warehouseName} - ${l.areaName} - ${l.shelfCode} - ${l.goodsAllocationCode}`,
+          value: l.id,
+          ...l
+        }));
+      },
+      itemOptions() {
+        return this.selection
+          .filter((it) => !it._shelved)
+          .map((it) => ({
+            label: `${it.categoryName || ''}${it.batchNo ? '/' + it.batchNo : ''}`,
+            value: this._getRowKey(it),
+            ...it
+          }));
+      },
+      placeholderCount() {
+        const perRow = 5;
+        const remainder = this.locationList.length % perRow;
+        return remainder === 0 ? 0 : perRow - remainder;
+      }
+    },
+
+    methods: {
+      // ==================== 打开/关闭 ====================
+      async open(row) {
+        console.log('open', row);
+        this.rowData = row;
+        this.dimension = 1;
+        this.selection = [];
+        this.shelvingList = [];
+        this.selectedLocations = [];
+        this.warehouse = '';
+        this.area = '';
+        this.shelves = '';
+        this.formData = { warehouse: {}, area: {}, shelves: {} };
+        this.locationList = [];
+        this.shelvesList = [];
+        this.shelvedItemKeys = [];
+        this.visible = true;
+        await this._getWarehouseList();
+        await this._loadTableData();
+
+        if (row?.warehouseId) {
+          this.warehouse = row.warehouseId;
+          const w = this.warehouseList.find((item) => item.id == row.warehouseId);
+          if (w) {
+            this.formData.warehouse = w;
+            await this.changeWarehouse(w);
+          }
+        }
+      },
+
+      cancel() {
+        this.rowData = null;
+        this.formData = { warehouse: {}, area: {}, shelves: {} };
+        this.warehouse = '';
+        this.area = '';
+        this.shelves = '';
+        this.tableData = [];
+        this.allTableData = [];
+        this.selection = [];
+        this.shelvingList = [];
+        this.selectedLocations = [];
+        this.visible = false;
+      },
+
+      // ==================== 维度切换 ====================
+      dimensionChange() {
+        this.selection = [];
+        if (this.$refs.tableRef) {
+          this.$refs.tableRef.clearSelection();
+        }
+        this.shelvingList = [];
+        this._loadTableData();
+      },
+
+      // ==================== 物品表格数据 ====================
+      async _loadTableData() {
+        if (!this.rowData?.id) return;
+        this.tableLoading = true;
+        try {
+          const res = await storageApi.getInboundDetailsById(this.rowData.id);
+          if (res) {
+            const items = this._parseRecords(res);
+            this.allTableData = items;
+            this.shelvedItemKeys = this._extractShelvedKeys(items);
+            this.tableData = items;
+          }
+        } catch (e) {
+          console.error('加载物品清单失败:', e);
+          this.$message.error('加载物品清单失败');
+        } finally {
+          this.tableLoading = false;
+        }
+      },
+
+      _parseRecords(res) {
+        const detailList = res.outInDetailList || [];
+        const extInfo = res.extInfo || {};
+        return detailList.map((item, index) => {
+          const recordList = item.outInDetailRecordRequestList || [];
+          const isUpper = recordList.some(
+            (r) => r.areaId && r.goodsShelfId && r.goodsAllocationId
+          );
+          return {
+            ...item,
+            _index: index,
+            _shelved: isUpper,
+            categoryCode: item.categoryCode || '',
+            categoryName: item.categoryName || '',
+            batchNo: item.batchNo || '',
+            measureQuantity: item.measureQuantity || 0,
+            measureUnit: item.measureUnit || '',
+            packingQuantity: item.packingQuantity || item.measureQuantity || 0,
+            packingUnit: item.packingUnit || item.measureUnit || '',
+            singleWeight: item.singleWeight || '',
+            totalWeight: item.totalWeight || '',
+            weightUnit: item.weightUnit || '',
+            colorKey: item.colorKey || '',
+            categoryModel: item.categoryModel || '',
+            specification: item.specification || '',
+            gradeName: item.gradeName || '',
+            voltage: item.voltage || '',
+            approvalNumber: item.approvalNumber || '',
+            packingSpec: item.packingSpec || '',
+            allowUnpack:
+              item.allowUnpack != null ? (item.allowUnpack ? '是' : '否') : '',
+            supplierName: item.supplierName || extInfo.supplierName || '',
+            warehouseName: item.warehouseName || '',
+            productionDate: item.productionDate || '',
+            purchaseDate: item.purchaseDate || '',
+            expiryDate: item.expiryDate || ''
+          };
+        });
+      },
+
+      _extractShelvedKeys(items) {
+        return items.filter((it) => it._shelved).map((it) => this._getRowKey(it));
+      },
+
+      _getRowKey(row) {
+        return `${row.categoryId || ''}_${row.batchNo || ''}`;
+      },
+
+      checkSelectable(row) {
+        return !this.shelvedItemKeys.includes(this._getRowKey(row));
+      },
+
+      handleSelectionChange(selection) {
+        this.selection = selection;
+        this.buildDefaultShelvingList();
+      },
+
+      // ==================== 自动匹配上架列表 ====================
+      buildDefaultShelvingList() {
+        const items = this.selection.filter((it) => !it._shelved);
+        const locs = this.selectedLocations;
+
+        if (items.length === 0 || locs.length === 0) {
+          this.shelvingList = [];
+          return;
+        }
+
+        let newList = null;
+
+        // ① 单个物品 + 单个货位
+        if (items.length === 1 && locs.length === 1) {
+          const item = items[0];
+          newList = [
+            {
+              cargoSpaceId: locs[0].id,
+              cargoSpaceCode: locs[0].goodsAllocationCode,
+              itemKey: this._getRowKey(item),
+              quantity: item.measureQuantity,
+              maxQuantity: item.measureQuantity
+            }
+          ];
+        }
+        // ② 多个物品 + 单个货位
+        else if (items.length > 1 && locs.length === 1) {
+          newList = items.map((item) => ({
+            cargoSpaceId: locs[0].id,
+            cargoSpaceCode: locs[0].goodsAllocationCode,
+            itemKey: this._getRowKey(item),
+            quantity: item.measureQuantity,
+            maxQuantity: item.measureQuantity
+          }));
+        }
+        // ③ 多个物品 + 多个货位,且数量相等
+        else if (items.length > 1 && locs.length > 1 && items.length === locs.length) {
+          newList = items.map((item, idx) => ({
+            cargoSpaceId: locs[idx].id,
+            cargoSpaceCode: locs[idx].goodsAllocationCode,
+            itemKey: this._getRowKey(item),
+            quantity: item.measureQuantity,
+            maxQuantity: item.measureQuantity
+          }));
+        }
+
+        if (newList) {
+          this.shelvingList = newList;
+        }
+        // ④ 其他情况:无法默认,保持现有内容(如果有)
+      },
+
+      // ==================== 仓库/库区/货架/货位 ====================
+      async _getWarehouseList() {
+        const res = await warehouseDefinition.list({});
+        this.warehouseList = res.map((item) => {
+          return { ...item, name: item.name };
+        });
+      },
+
+      warehouseChange() {
+        this.cur = {};
+        this.shelves = '';
+        this.locationList = [];
+        this.area = '';
+        this.selectedLocations = [];
+        this.shelvingList = [];
+      },
+
+      async changeWarehouse(val) {
+        this.formData.warehouse = val;
+        const res = await warehouseDefinition.getListByWarehouseId(val.id);
+        this.area = '';
+        this.shelves = '';
+        this.areaList = res || [];
+        this.selectedLocations = [];
+        this.shelvingList = [];
+      },
+
+      async getshelvesList(e) {
+        this.cur = {};
+        this.shelves = '';
+        this.locationList = [];
+        this.selectedLocations = [];
+        this.shelvingList = [];
+        const rep = await warehouseDefinition.getListByAreaId(e);
+        this.shelvesList = rep || [];
+      },
+
+      async changeshelvesList(id) {
+        this.cur = {};
+        this.selectedLocations = [];
+        this.shelvingList = [];
+        if (!this.shelvesList.length) {
+          this.locationList = [];
+          return;
+        }
+        const matched = this.shelvesList.find((item) => item.goodsshelvesCode == id);
+        if (!matched) {
+          this.locationList = [];
+          return;
+        }
+        const res = await warehouseDefinition.getListByGoodId(matched.id);
+        this.locationList = res || [];
+      },
+
+      getStatus: useDict(locationStatusList),
+
+      // ==================== 货位点击(多选) ====================
+      handlCur(row) {
+        if (![1, 2].includes(row.allocationStatus)) {
+          return;
+        }
+        const { area, shelves, warehouse } = this.formData;
+        if (!warehouse?.id || !area?.id || !shelves?.id) {
+          this.$message.warning('请先选择仓库、库区和货架');
+          return;
+        }
+
+        const idx = this.selectedLocations.findIndex((l) => l.id === row.id);
+        if (idx > -1) {
+          this.selectedLocations.splice(idx, 1);
+        } else {
+          this.selectedLocations.push({
+            id: row.id,
+            goodsAllocationCode: row.goodsAllocationCode,
+            warehouseId: warehouse.id,
+            warehouseName: warehouse.name,
+            areaId: area.id,
+            areaName: area.name,
+            shelfId: shelves.id,
+            shelfCode: shelves.goodsshelvesCode
+          });
+        }
+
+        this.buildDefaultShelvingList();
+      },
+
+      isLocationSelected(id) {
+        return this.selectedLocations.some((l) => l.id === id);
+      },
+
+      // ==================== 上架清单操作 ====================
+      addRow() {
+        this.shelvingList.push({
+          cargoSpaceId: '',
+          cargoSpaceCode: '',
+          itemKey: '',
+          quantity: 0,
+          maxQuantity: 0
+        });
+      },
+
+      delItem(index) {
+        this.shelvingList.splice(index, 1);
+      },
+
+      onLocationChange(val, row) {
+        const loc = this.selectedLocations.find((l) => l.id === val);
+        if (loc) {
+          row.cargoSpaceCode = loc.goodsAllocationCode;
+        }
+      },
+
+      onItemChange(val, row) {
+        const item = this.allTableData.find((it) => this._getRowKey(it) === val);
+        if (item) {
+          row.maxQuantity = parseFloat(item.measureQuantity) || 0;
+          if (row.quantity > row.maxQuantity) {
+            row.quantity = row.maxQuantity;
+          }
+        }
+      },
+
+      // ==================== 确认提交 ====================
+      handleSelect() {
+        const items = this.selection.filter((it) => !it._shelved);
+        if (items.length === 0) {
+          this.$message.error('请选择需要上架的物品');
+          return;
+        }
+
+        if (this.shelvingList.length === 0) {
+          this.$message.error('请配置上架信息');
+          return;
+        }
+
+        // 检查每行必填
+        for (let i = 0; i < this.shelvingList.length; i++) {
+          const row = this.shelvingList[i];
+          if (!row.cargoSpaceId) {
+            this.$message.error(`第 ${i + 1} 行未选择货位`);
+            return;
+          }
+          if (!row.itemKey) {
+            this.$message.error(`第 ${i + 1} 行未选择物品批次`);
+            return;
+          }
+          if (row.quantity === null || row.quantity === undefined || row.quantity <= 0) {
+            this.$message.error(`第 ${i + 1} 行数量必须大于0`);
+            return;
+          }
+        }
+
+        // 校验每个物品的总上架数量必须等于物品数量
+        const itemTotalMap = {};
+        this.shelvingList.forEach((row) => {
+          if (!itemTotalMap[row.itemKey]) itemTotalMap[row.itemKey] = 0;
+          itemTotalMap[row.itemKey] += parseFloat(row.quantity) || 0;
+        });
+
+        for (const item of items) {
+          const key = this._getRowKey(item);
+          const total = itemTotalMap[key] || 0;
+          const expect = parseFloat(item.measureQuantity) || 0;
+          if (total !== expect) {
+            this.$message.error(
+              `物品 ${item.categoryName || ''}(${item.batchNo || ''})的上架数量 ${total} 不等于物品数量 ${expect},请确认全部上架`
+            );
+            return;
+          }
+        }
+
+        // 组装提交数据
+        this.confirmLoading = true;
+        const outInDetailList = [];
+        this.shelvingList.forEach((row) => {
+          const matchedItem = this.allTableData.find(
+            (it) => this._getRowKey(it) === row.itemKey
+          );
+          const loc = this.selectedLocations.find((l) => l.id === row.cargoSpaceId);
+          if (matchedItem && loc) {
+            outInDetailList.push({
+              id: matchedItem.id,
+              warehouseId: loc.warehouseId,
+              warehouseName: loc.warehouseName,
+              areaId: loc.areaId,
+              areaName: loc.areaName,
+              goodsShelfId: loc.shelfId,
+              goodsShelfName: loc.shelfCode,
+              goodsAllocationId: row.cargoSpaceId,
+              goodsAllocationName: row.cargoSpaceCode,
+              measureQuantity: row.quantity,
+              categoryId: matchedItem.categoryId,
+              batchNo: matchedItem.batchNo
+            });
+          }
+        });
+
+        const payload = {
+          id: this.rowData.id,
+          outInDetailList
+        };
+
+        storageApi
+          .upperLowerShelves(payload)
+          .then(() => {
+            this.$message.success('上架成功');
+            this.$emit('done');
+            this.cancel();
+          })
+          .catch((e) => {
+            this.$message.error(e.message || '上架失败');
+          })
+          .finally(() => {
+            this.confirmLoading = false;
+          });
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .section-title {
+    font-weight: bold;
+    font-size: 14px;
+    margin-bottom: 10px;
+    border-left: 3px solid #409eff;
+    padding-left: 8px;
+  }
+
+  .dimension-tabs {
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+    .dimension-label {
+      font-weight: bold;
+      margin-right: 10px;
+    }
+  }
+
+  .status-legend {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin: 12px 0;
+    div {
+      margin: 0 12px;
+    }
+    span {
+      display: inline-block;
+      width: 13px;
+      height: 13px;
+      margin: 0 4px;
+    }
+  }
+
+  .content-box {
+    display: flex;
+    justify-content: space-between;
+    flex-wrap: wrap;
+    max-height: 40vh;
+    overflow: auto;
+    .box {
+      cursor: pointer;
+      width: 134px;
+      height: 64px;
+      background-clip: content-box;
+      margin-bottom: 4px;
+      line-height: 64px;
+      text-align: center;
+      font-size: 13px;
+      border: 2px solid transparent;
+      &:hover,
+      &.selected {
+        box-shadow: 2px 2px 2px 2px #ccc;
+      }
+      &.selected {
+        border-color: #409eff;
+      }
+    }
+    .placeholder-box {
+      width: 134px;
+    }
+  }
+
+  .modal-footer {
+    text-align: right;
+    margin-top: 16px;
+  }
+</style>

+ 6 - 1
src/views/warehouseManagement/stockManagement/index.vue

@@ -311,6 +311,7 @@
     <printStockEnter ref="printStockEnterRef" :groupName="groupName"></printStockEnter>
     <printStockEnter ref="printStockEnterRef" :groupName="groupName"></printStockEnter>
     <printTemplateTr ref="printTemplateTrRef" :groupName="groupName"></printTemplateTr>
     <printTemplateTr ref="printTemplateTrRef" :groupName="groupName"></printTemplateTr>
     <printStockEnterHt ref="printStockEnterHtRef" :groupName="groupName"></printStockEnterHt>
     <printStockEnterHt ref="printStockEnterHtRef" :groupName="groupName"></printStockEnterHt>
+    <ItemListed ref="itemListedRef" @done="search" />
     <!--  <priceMaintenanceDialog ref="priceMaintenanceDialogRef" /> -->
     <!--  <priceMaintenanceDialog ref="priceMaintenanceDialogRef" /> -->
   </div>
   </div>
 </template>
 </template>
@@ -328,6 +329,7 @@
   import printStockEnter from './components/printStockEnter.vue';
   import printStockEnter from './components/printStockEnter.vue';
   import printTemplateTr from './components/print-template-tr.vue';
   import printTemplateTr from './components/print-template-tr.vue';
   import printStockEnterHt from './components/printStockEnterHt.vue';
   import printStockEnterHt from './components/printStockEnterHt.vue';
+  import ItemListed from './components/itemListed.vue';
    import tabMixins from '@/mixins/tableColumnsMixin';
    import tabMixins from '@/mixins/tableColumnsMixin';
   import {
   import {
     warehousingType,
     warehousingType,
@@ -338,7 +340,7 @@
   import { enterprisePage } from '@/api/bpm/index.js';
   import { enterprisePage } from '@/api/bpm/index.js';
   export default {
   export default {
     mixins: [tabMixins],
     mixins: [tabMixins],
-    components: { printQRCode, printStockEnter, printTemplateTr, printStockEnterHt },
+    components: { printQRCode, printStockEnter, printTemplateTr, printStockEnterHt, ItemListed },
     data() {
     data() {
       return {
       return {
         cacheKeyUrl: '202606011119-wms-stockManagement-index',
         cacheKeyUrl: '202606011119-wms-stockManagement-index',
@@ -602,6 +604,9 @@
       shelves() {
       shelves() {
         console.log('上架');
         console.log('上架');
       },
       },
+      handleShelving(row) {
+        this.$refs.itemListedRef.open(row);
+      },
       unShelves() {
       unShelves() {
         console.log('下架');
         console.log('下架');
       },
       },