CycleCountDetailChiIdModal.vue 11.9 KB
<template>
  <j-modal
    :title="title"
    :width="width"
    :visible="visible"
    :confirmLoading="confirmLoading"
    switchFullscreen
    @ok="handleOk"
    @cancel="handleCancel"
    cancelText="关闭">
    <a-spin :spinning="confirmLoading">
      <a-form-model ref="form" :model="model" :rules="validatorRules">
        <a-row>
          <a-col :xs="24">
            <a-form-model-item label="物料1" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialCode">
              <j-search-select-tag
                v-model="model.materialCode"
                async
                :dict="`material,name,code`"
                :pageSize="10"
                placeholder="输入物料编码模糊查询"
                @change="handleMaterialChange"
              showSearch
              labelInValue
              :filterOption="false"
              allowClear
              >
              </j-search-select-tag>
            </a-form-model-item>
          </a-col>

          <a-col :xs="24">
            <a-form-model-item label="实盘数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="countedQty">
              <a-input v-model="model.countedQty" placeholder="请输入实盘数量"></a-input>
            </a-form-model-item>
          </a-col>

          <a-col :span="24">
            <a-form-model-item label="长度" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="length">
              <a-input v-model="model.length" placeholder="请输入长度"></a-input>
            </a-form-model-item>
          </a-col>

          <a-col :span="24">
            <a-form-model-item label="宽度" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="width">
              <a-input v-model="model.width" placeholder="请输入宽度"></a-input>
            </a-form-model-item>
          </a-col>

          <!-- 2. 库存状态选择框:变更后触发批次加载(新增@change事件) -->
          <a-col :span="24">
            <a-form-model-item label="库存状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="inventoryStatus">
              <j-dict-select-tag
                type="list"
                v-model="model.inventoryStatus"
                dictCode="inventory_status"
                @change="handleInventoryStatusChange"
              placeholder="请选择库存状态"/>
            </a-form-model-item>
          </a-col>

          <!-- 3. 批次下拉框:替换为带搜索+分页的版本 -->
          <a-col :xs="24">
            <a-form-model-item label="批次" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="batch">
              <a-select
                show-search
                placeholder="请选择批次"
                option-filter-prop="children"
                v-model="model.batch"
                :loading="batchLoading"
              :not-found-content="batchLoading ? '加载中...' : ''"
              @search="handleBatchSearch"
              @popupScroll="handleBatchScroll"
              >
              <a-select-option v-for="item in batchOptions" :key="item.batch" :value="item.batch">
                {{ item.batch }}
              </a-select-option>
              <a-spin v-if="loadingMore" size="small" style="display: block; margin: 10px auto;" />
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </a-spin>
  </j-modal>
</template>

<script>
// 1. 导入所需API(新增searchMaterialByCodeAndBatch)
import { createManyEmptyIn, getMaterialList, increaseInInventoryGain, searchMaterialByCode, searchMaterialByCodeAndBatch } from '@/api/api'
import Utils from '../../../../components/jeecgbiz/JButtonBizComponent/util.js';

export default {
  name: "CycleCountDetailChiIdModal",
  components: {},
  props: {
    id: {
      type: String | Number,
      default: ''
    }
  },
  data() {
    return {
      title: "操作",
      width: 500,
      visible: false,
      selectedMaterial: null,
      model: {
        cycleCountDetailid: this.id,
        materialCode: '',  // 注意:若j-search-select-tag用labelInValue,需存储{key:编码, label:名称}
        batch: '',
        countedQty: '',
        length: '',
        width: '',
        inventoryStatus: 'good'  // 默认库存状态(与发货页面一致)
      },
      materialList: [],
      querySource: {},
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
      confirmLoading: false,
      validatorRules: {
        materialCode: [
          { required: true, message: '请输入物料信息!' },
        ],
        countedQty: [
          { required: true, message: '请输入实盘数量!' },
        ],
        batch: [
          { required: true, message: '请选择批次!' },
        ],
        inventoryStatus: [
          { required: true, message: '请选择库存状态!' },
        ],
      },
      url: {
        add: "/cycleCountDetail/cycleCountDetail/increaseInInventoryGain",
      },
      modelDefault: {},

      // 2. 新增批次下拉框相关变量(与发货页面完全一致)
      batchOptions: [],       // 批次选项列表
      batchLoading: false,    // 批次加载中状态
      loadingMore: false,     // 加载更多状态
      batchSearchKey: '',     // 批次搜索关键词
      batchPage: 1,           // 批次当前页码
      batchPageSize: 20,      // 批次每页条数
      hasMoreBatch: true      // 是否还有更多批次数据
    }
  },

  watch: {
    id: {
      immediate: true,
      handler(newVal) {
        this.model.cycleCountDetailid = newVal;
      }
    },
    // 3. 监听物料编码格式(若用labelInValue,自动提取编码)
    'model.materialCode': {
      handler(newVal) {
        // 若组件返回{key:编码, label:名称},则提取key作为物料编码
        if (newVal && typeof newVal === 'object' && newVal.key) {
          this.model.materialCode = newVal.key; // 覆盖为纯编码
        }
      }
    }
  },

  created() {
    this.modelDefault = JSON.parse(JSON.stringify(this.model));
  },

  methods: {
    // 4. 新增:物料编码变更事件(清空批次+加载新批次)
    handleMaterialChange() {
      this.model.batch = ''; // 清空原有批次
      this.resetBatchSelector(); // 重置批次选择器状态
      // 物料编码+库存状态都存在时,才加载批次
      if (this.model.materialCode && this.model.inventoryStatus) {
        this.$nextTick(() => this.loadBatchData());
      }
    },

    // 5. 新增:库存状态变更事件(清空批次+加载新批次)
    handleInventoryStatusChange() {
      this.model.batch = ''; // 清空原有批次
      this.resetBatchSelector(); // 重置批次选择器状态
      // 物料编码+库存状态都存在时,才加载批次
      if (this.model.materialCode && this.model.inventoryStatus) {
        this.$nextTick(() => this.loadBatchData());
      }
    },

    // 6. 新增:重置批次选择器状态(与发货页面一致)
    resetBatchSelector() {
      this.batchOptions = [];
      this.batchPage = 1;
      this.hasMoreBatch = true;
      this.batchSearchKey = '';
    },

    // 7. 新增:批次搜索事件(与发货页面一致)
    handleBatchSearch(keyword) {
      this.batchSearchKey = keyword;
      this.batchPage = 1; // 重置页码
      this.batchOptions = []; // 清空选项
      this.hasMoreBatch = true;
      this.loadBatchData(); // 加载搜索结果
    },

    // 8. 新增:滚动加载更多批次(与发货页面一致)
    handleBatchScroll(e) {
      const target = e.target;
      // 滚动到底部100px内时加载更多
      if (target.scrollHeight - target.scrollTop <= target.clientHeight + 100 &&
        !this.batchLoading &&
        !this.loadingMore &&
        this.hasMoreBatch) {
        this.loadMoreBatch();
      }
    },

    // 9. 新增:加载批次数据(调用后端searchMaterialByCodeAndBatch接口)
    loadBatchData() {
      // 必传参数校验(避免无效请求)
      if (!this.model.materialCode || !this.model.inventoryStatus) {
        this.batchOptions = [];
        this.batchLoading = false;
        return;
      }

      this.batchLoading = true;
      // 构造请求参数(与发货页面一致,包含库存状态)
      const params = {
        materialCode: this.model.materialCode,
        inventoryStatus: this.model.inventoryStatus, // 库存状态(后端需支持该参数)
        batchKeyword: this.batchSearchKey,
        page: this.batchPage,
        pageSize: this.batchPageSize
      };

      // 调用封装的API接口(与发货页面一致)
      searchMaterialByCodeAndBatch(params).then(res => {
        if (res.success) {
          const newOptions = res.result.list || []; // 后端返回的批次列表(需与后端字段匹配)
          // 第一页替换,后续页追加
          this.batchOptions = this.batchPage === 1 ? newOptions : [...this.batchOptions, ...newOptions];
          // 判断是否还有更多数据(当前页数量=页大小则认为有更多)
          this.hasMoreBatch = newOptions.length === this.batchPageSize;
        } else {
          this.batchOptions = [];
          this.$message.warning(res.message || '获取批次列表失败');
        }
      }).finally(() => {
        this.batchLoading = false;
        this.loadingMore = false;
      });
    },

    // 10. 新增:加载更多批次(与发货页面一致)
    loadMoreBatch() {
      if (!this.hasMoreBatch) return;
      this.loadingMore = true;
      this.batchPage++; // 页码+1
      this.loadBatchData(); // 加载下一页
    },

    // 11. 原有方法:清空物料搜索逻辑(无需修改,若未使用可删除)
    searchMaterial() {
      const that = this;
      that.querySource.code = that.model.materialCode;
      getMaterialList(that.querySource).then(res => {
        that.materialList = res.result;
      });
    },

    // 12. 原有方法:关闭弹窗(新增重置批次状态)
    close() {
      this.$emit('close');
      this.visible = false;
      this.$refs.form && this.$refs.form.clearValidate();
      this.model = JSON.parse(JSON.stringify(this.modelDefault));
      this.materialList = [];
      this.resetBatchSelector(); // 关闭时重置批次选择器
    },

    // 13. 原有方法:新增弹窗(无需修改)
    add() {
      this.model = JSON.parse(JSON.stringify(this.modelDefault));
      this.materialList = [];
      this.resetBatchSelector(); // 新增时重置批次选择器
      this.$refs.form && this.$refs.form.clearValidate();
      this.visible = true;
    },

    // 14. 原有方法:编辑弹窗(新增加载批次逻辑)
    edit() {
      this.visible = true;
      this.model.cycleCountDetailid = this.id;
      this.$refs.form && this.$refs.form.clearValidate();
      this.model.countedQty = '';
      this.model.batch = '';
      // 编辑时若有物料编码+库存状态,自动加载批次
      if (this.model.materialCode && this.model.inventoryStatus) {
        this.$nextTick(() => this.loadBatchData());
      }
    },

    // 15. 原有方法:提交逻辑(无需修改)
    handleOk() {
      const that = this;
      this.$refs.form.validate(valid => {
        if (valid) {
          console.log("传给后端的参数:", that.model);
          that.confirmLoading = true;
          increaseInInventoryGain(this.model).then((res) => {
            if (res.success) {
              that.$message.success(res.message);
              that.$emit('ok');
              that.model.containerCode = '';
              that.model.toLocationCode = '';
              Utils.$emit('methodB', res.result);
            } else {
              that.$message.warning(res.message);
            }
          }).finally(() => {
            that.confirmLoading = false;
            that.close();
          })
        } else {
          return false;
        }
      })
    },

    // 16. 原有方法:取消逻辑(无需修改)
    handleCancel() {
      this.close();
    }
  }
}
</script>