vue2版本的ruoyi-ui使用vxe-modal封装物料参照组件

文章目录

目标

使用 vxe-modal 封装一个可以在 vxe-table 表格中使用的物料参照组件,解决物料的数据过多导致 vxe-table 的可编辑渲染 vxe-select下拉选择和 vxe-table-select 无法满足分页搜索展示物料详细信息并选取的问题。

步骤一:创建组件

创建一个组件(如 src/views/sc/components/ProductReference.vue),如下:

javascript 复制代码
// ruoyi-ui/src/views/sc/components/ProductReference.vue
<template>
    <div>
        <vxe-modal v-model="visible" :title="title" :width="720" :height="600" show-footer show-confirm-button
            show-cancel-button @confirm="productnameSearchConfirmEvent" @cancel="productnameSearchCancelEvent"
            @hide="productnameModalHideEvent" @show="productnameModalShowEvent">
            <el-row>
                <el-card shadow="always">
                    <vxe-input ref="productnameSearchInputRef" v-model="productSearchValue" type="search"
                        placeholder="搜索物料名称" @search-click="productnameSearchClickHandler"
                        @keyup="productnameInputKeyup2"></vxe-input>
                </el-card>
            </el-row>
            <el-row>
                <vxe-table ref="productSearchTableRef" border show-overflow height="360" :data="productnameOptions"
                    :loading="searchTableLoading" :row-config="{ isCurrent: true, isHover: true }"
                    :radio-config="{ labelField: 'name', trigger: 'row' }"
                    @cell-dblclick="productnameSearchTableDblClickEvent">
                    <vxe-column field="radio" type="radio" width="40"></vxe-column>
                    <vxe-column field="seq" type="seq" width="50"></vxe-column>
                    <vxe-column field="productcode" title="物料编码" width="auto"></vxe-column>
                    <vxe-column field="productname" title="物料" width="auto"></vxe-column>
                    <vxe-column field="modeldescription" title="规格" width="auto" show-overflow></vxe-column>
                    <vxe-column field="model" title="型号" width="auto"></vxe-column>
                    <vxe-column field="unitname" title="单位" width="auto"></vxe-column>
                    <vxe-column field="productclasscode" title="物料分类编码" width="auto"></vxe-column>
                    <vxe-column field="productclassname" title="物料分类" width="auto"></vxe-column>
                </vxe-table>
                <vxe-pager :current-page.sync="pageVO.currentPage" :page-size.sync="pageVO.pageSize"
                    :total="pageVO.total" @page-change="productSearchTablePageChangeEvent">
                </vxe-pager>
            </el-row>
        </vxe-modal>
    </div>
</template>

<script>
import { listProduct } from "@/api/sc/product";

export default {
    name: 'ProductReference',
    props: {
        showPopup: {
            type: Boolean,
            required: true
        },
        title: {
            type: String,
            default: '物料选择'
        },
        searchValue: {
            type: String,
            required: true
        },
        productnameSelectRender: {
            type: Object,
            required: true,
            validator: function (value) {
                return value.hasOwnProperty('options') && Array.isArray(value.options);
            },
        },
    },
    data() {
        return {
            searchTableLoading: false,
            pageVO: {
                currentPage: 1,
                pageSize: 10,
                total: 0
            },
            productnameOptions: [],

        }
    },
    watch: {
        productSearchValue(newVal, oldVal) {
            // this.handlePageData(newVal);
            //console.log('物料查询参数0:', newVal, oldVal);
        }
    },
    computed: {
        productSearchValue: {
            get() {
                return this.searchValue;
            },
            set(value) {
                this.$emit('update:searchValue', value);
            }
        },
        visible: {
            get() {
                return this.showPopup;
            },
            set(value) {
                this.$emit('update:showPopup', value);
            }
        },
    },
    methods: {
        handlePageData(value) {
            console.log('物料查询参数1:', value);
            const { pageSize, currentPage } = this.pageVO;
            this.searchTableLoading = true;
            listProduct({ pageNum: currentPage, pageSize: pageSize, productname: value }).then(response => {
                this.productSearchValue = value;
                this.productnameSelectRender.options = response.rows;
                this.productnameOptions = response.rows;
                this.pageVO.total = response.total;
                this.searchTableLoading = false;
            });
        },
        productnameSearchClickHandler() {
            this.pageVO.currentPage = 1;
            this.pageVO.pageSize = 10;
            this.handlePageData(this.productSearchValue);
        },
        productnameSearchTableDblClickEvent() {
            const selectedRow = this.$refs.productSearchTableRef.getCurrentRecord(true);
            if (selectedRow) {
                this.$emit('productname-selected-event', selectedRow);
                this.pageVO.currentPage = 1;
                this.pageVO.pageSize = 10;
            }
        },
        productSearchTablePageChangeEvent({ pageSize, currentPage }) {
            this.pageVO.currentPage = currentPage;
            this.pageVO.pageSize = pageSize;
            this.handlePageData(this.productSearchValue);
        },
        productnameInputKeyup2(event) {
            if (event.key === 'Enter') {
                this.pageVO.currentPage = 1;
                this.pageVO.pageSize = 10;
                this.handlePageData(this.productSearchValue);
            }
        },
        focus: function () {
            this.$refs.productnameSearchInputRef.focus()
        },
        productnameSearchConfirmEvent() {
            const $table = this.$refs.productSearchTableRef;
            const record = $table.getRadioRecord(true);
            if (record) {
                const selectedProduct = this.productnameOptions.find(item => item.id === record.id);
                if (selectedProduct) {
                    this.$emit('productname-selected-event', selectedProduct);
                    this.pageVO.currentPage = 1;
                    this.pageVO.pageSize = 10;
                }
                this.visible = false;
            } else {
                this.$modal.msgWarning("请选择一条数据");
            }
        },
        productnameSearchCancelEvent() {

        },
        productnameModalHideEvent() {
            this.pageVO.currentPage = 1;
            this.pageVO.pageSize = 10;
        },
        productnameModalShowEvent() {
            this.focus();
            this.productnameSearchClickHandler();
        },
    },
}
</script>

步骤二:使用组件

在 src/views/sc/instockbill/index.vue 中使用物料参照组件,如下:

javascript 复制代码
// ruoyi-ui/src/views/sc/instockbill/index.vue
<style lang="scss" scoped>
::v-deep .vue-treeselect__control {
  max-width: 415px;
}

.el-row {
  margin-bottom: 2px;

  &:last-child {
    margin-bottom: 0;
  }
}

/*
// .custom-dialog .el-dialog__body {
//   margin-top: 100px !important;
// }
*/
</style>

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="单据编号" prop="billcode">
        <el-input v-model="queryParams.billcode" placeholder="请输入单据编号" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="业务主体" prop="orgname">
        <el-input v-model="queryParams.orgname" placeholder="请输入业务主体" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="部门" prop="depname">
        <el-input v-model="queryParams.depname" placeholder="请输入部门" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="仓库" prop="warehousename">
        <el-input v-model="queryParams.warehousename" placeholder="请输入仓库" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="物料" prop="productname">
        <el-input v-model="queryParams.productname" placeholder="请输入物料" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="创建人" prop="createBynick">
        <el-input v-model="queryParams.createBynick" placeholder="请输入创建人" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="queryParams.remark" placeholder="请输入备注" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item v-if="false" label="单据日期" prop="vouchdate">
        <el-date-picker clearable v-model="queryParams.vouchdate" type="date" format="yyyy-MM-dd"
          value-format="yyyy-MM-dd" placeholder="请选择单据日期" :picker-options="pickerOptions">
        </el-date-picker>
      </el-form-item>
      <el-form-item label="开始日期" prop="vouchdatestart">
        <el-date-picker clearable v-model="queryParams.vouchdatestart" type="date" format="yyyy-MM-dd"
          value-format="yyyy-MM-dd" placeholder="请选择单据开始日期" :picker-options="pickerOptions">
        </el-date-picker>
      </el-form-item>
      <el-form-item label="结束日期" prop="vouchdateend">
        <el-date-picker clearable v-model="queryParams.vouchdateend" type="date" format="yyyy-MM-dd"
          value-format="yyyy-MM-dd" placeholder="请选择单据结束日期" :picker-options="pickerOptions">
        </el-date-picker>
      </el-form-item>
      <el-form-item label="单据状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="单据状态" clearable>
          <el-option :key="null" label="全部" :value="null" />
          <el-option key="0" label="开立" value="0" />
          <el-option key="1" label="已审核" value="1" />
          <el-option key="3" label="已提交" value="3" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="16">
        <el-radio-group v-model="radio">
          <el-radio :label="0">表头</el-radio>
          <el-radio :label="1">表头+明细</el-radio>
        </el-radio-group>
      </el-col>
      <el-col :span="1.5">
        <!-- <el-button type="primary" plain icon="el-icon-plus" size="mini"
          @click="handleAdd"
          v-hasPermi="['sc:instockbill:add']"
        >新增</el-button> -->
        <el-dropdown split-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
          @command="handleAddCommand" v-hasPermi="['sc:instockbill:add']">
          新增
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="new">空白新增</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </el-col>
      <el-col :span="1.5">
        <el-dropdown split-button icon="el-icon-plus" size="mini" :disabled="single" @click="handleSubmit"
          @command="handleSubmitCommand" v-hasPermi="['sc:instockbill:submit']">
          提交
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="submit">提交单据</el-dropdown-item>
            <el-dropdown-item command="unsubmit">撤销提交</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </el-col>
      <el-col :span="1.5">
        <el-dropdown split-button icon="el-icon-plus" size="mini" :disabled="single" @click="handleAudit"
          @command="handleAuditCommand" v-hasPermi="['sc:instockbill:audit']">
          审核
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="audit">审核单据</el-dropdown-item>
            <el-dropdown-item command="unaudit">弃审单据</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['sc:instockbill:edit']">修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['sc:instockbill:remove']">删除</el-button>
      </el-col>
      <!-- <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini"
          @click="handleExport"
          v-hasPermi="['sc:instockbill:export']"
        >导出</el-button>
      </el-col> -->
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-if="radio == 0" v-loading="loading" :data="instockbillList" @selection-change="handleSelectionChange"
      height="640" highlight-selection-row>
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column v-if="false" label="自增ID" align="center" prop="id" />
      <el-table-column v-if="false" label="单据ID" align="center" prop="billid" />
      <el-table-column label="单据日期" align="center" prop="vouchdate" width="100" fixed sortable>
        <template v-slot="scope">
          <span>{{ parseTime(scope.row.vouchdate, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="单据编号" width="200" align="center" prop="billcode" fixed>
        <template #default="{ row }">
          <el-link type="primary" :underline="false" @click="getBillcodeClickHandler(row)">{{ row.billcode }}</el-link>
        </template>
      </el-table-column>
      <el-table-column v-if="false" label="业务主体ID" align="center" prop="orgid" />
      <el-table-column v-if="false" label="业务主体编码" align="center" prop="orgcode" />
      <el-table-column label="业务主体" width="120" align="center" prop="orgname" />
      <el-table-column v-if="false" label="部门ID" align="center" prop="depid" />
      <el-table-column v-if="false" label="部门编码" align="center" prop="depcode" />
      <el-table-column label="部门" min-width="120" align="center" prop="depname" />
      <el-table-column v-if="false" label="单据类型" align="center" prop="vouchtype" />
      <el-table-column v-if="false" label="仓库ID" align="center" prop="warehouseid" />
      <el-table-column v-if="false" label="仓库编码" align="center" prop="warehousecode" />
      <el-table-column label="仓库" min-width="200" align="center" prop="warehousename" />
      <el-table-column label="单据状态" align="center" prop="status">
        <template v-slot:default="scope">
          <el-tag v-if="scope.row.status === 0" type="primary">开立</el-tag>
          <el-tag v-else-if="scope.row.status === 1" type="success">已审核</el-tag>
          <el-tag v-else-if="scope.row.status === 3" type="warning">已提交</el-tag>
        </template>
      </el-table-column>
      <el-table-column v-if="false" label="审核状态" align="center" prop="verifyState" />
      <el-table-column label="备注" align="center" prop="remark" />
      <el-table-column label="创建人" align="center" prop="createBynick" />
      <el-table-column label="创建时间" width="200" align="center" prop="createTime" />
      <el-table-column label="修改人" align="center" prop="updateBynick" />
      <el-table-column label="修改时间" width="200" align="center" prop="updateTime" />
      <el-table-column v-if="false" label="创建人ID" align="center" prop="createByid" />
      <el-table-column v-if="false" label="修改人ID" align="center" prop="updateByid" />
      <el-table-column v-if="false" label="审批人ID" align="center" prop="auditorid" />
      <el-table-column label="审批人" align="center" prop="auditorname" />
      <el-table-column label="审批时间" align="center" prop="auditortime" width="180" v-slot="scope">
        <span>{{ parseTime(scope.row.auditortime, '{y}-{m}-{d}') }}</span>
      </el-table-column>
      <el-table-column v-if="false" label="时间戳" align="center" prop="pubts" />
      <el-table-column v-if="false" label="是否流程审批控制" align="center" prop="iswfcontrolled" v-slot:default="scope">
        <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.iswfcontrolled" />
      </el-table-column>
      <el-table-column v-if="false" label="工作流ID" align="center" prop="wfid" />
      <el-table-column v-if="false" label="打印次数" align="center" prop="printcount" />
      <el-table-column v-if="false" label="打印时间" align="center" prop="printtime" />
      <el-table-column v-if="false" label="来源单据类型" align="center" prop="srcbilltype" />
      <el-table-column v-if="false" label="来源单据ID" align="center" prop="srcbillid" />
      <el-table-column v-if="false" label="来源单据编号" align="center" prop="srcbillcode" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" v-slot="scope" fixed="right">
        <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
          v-hasPermi="['sc:instockbill:edit']">修改</el-button>
        <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
          v-hasPermi="['sc:instockbill:remove']">删除</el-button>
      </el-table-column>
    </el-table>

    <el-table v-if="radio == 1" v-loading="loading" :data="instockbilllistList"
      @selection-change="handleSelectionChange" height="640" highlight-selection-row>
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column v-if="false" label="自增ID" align="center" prop="id" />
      <el-table-column v-if="false" label="单据ID" align="center" prop="billid" />
      <el-table-column label="单据日期" align="center" prop="vouchdate" width="100" fixed sortable>
        <template v-slot="scope">
          <span>{{ parseTime(scope.row.vouchdate, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="单据编号" width="200" align="center" prop="billcode" fixed>
        <template #default="{ row }">
          <el-link type="primary" :underline="false" @click="getBillcodeClickHandler(row)">{{ row.billcode }}</el-link>
        </template>
      </el-table-column>
      <el-table-column v-if="false" label="业务主体ID" align="center" prop="orgid" />
      <el-table-column v-if="false" label="业务主体编码" align="center" prop="orgcode" />
      <el-table-column label="业务主体" width="120" align="center" prop="orgname" />
      <el-table-column v-if="false" label="部门ID" align="center" prop="depid" />
      <el-table-column v-if="false" label="部门编码" align="center" prop="depcode" />
      <el-table-column label="部门" min-width="120" align="center" prop="depname" />
      <el-table-column v-if="false" label="单据类型" align="center" prop="vouchtype" />
      <el-table-column v-if="false" label="仓库ID" align="center" prop="warehouseid" />
      <el-table-column v-if="false" label="仓库编码" align="center" prop="warehousecode" />
      <el-table-column label="仓库" min-width="200" align="center" prop="warehousename" />
      <el-table-column label="单据状态" align="center" prop="status">
        <template v-slot:default="scope">
          <el-tag v-if="scope.row.status === 0" type="primary">开立</el-tag>
          <el-tag v-else-if="scope.row.status === 1" type="success">已审核</el-tag>
          <el-tag v-else-if="scope.row.status === 3" type="warning">已提交</el-tag>
        </template>
      </el-table-column>
      <el-table-column v-if="false" label="审核状态" align="center" prop="verifyState" />
      <el-table-column label="行号" align="center" prop="lineno" />
      <el-table-column label="物料编码" align="center" prop="productid" />
      <el-table-column label="物料" align="center" prop="productname" min-width="120" />
      <el-table-column label="物料描述" align="center" prop="productdesc" min-width="120" />
      <el-table-column label="型号" align="center" prop="model" />
      <el-table-column label="数量" align="center" prop="qty" />
      <el-table-column label="单位编码" align="center" prop="unitcode" />
      <el-table-column label="单位" align="center" prop="unitname" />
      <el-table-column label="仓库编码" align="center" prop="warehousecode" />
      <el-table-column label="仓库" align="center" prop="warehousename" min-width="120" />
      <el-table-column label="货位编码" align="center" prop="goodspositioncode" />
      <el-table-column label="货位" align="center" prop="goodspositionname" min-width="120" />
      <el-table-column label="项目" align="center" prop="projectname" />
      <el-table-column label="批次号" align="center" prop="batchno" />
      <el-table-column label="行备注" align="center" prop="subremark" />
      <el-table-column label="备注" align="center" prop="remark" />
      <el-table-column label="创建人" align="center" prop="createBynick" />
      <el-table-column label="创建时间" width="200" align="center" prop="createTime" />
      <el-table-column label="修改人" align="center" prop="updateBynick" />
      <el-table-column label="修改时间" width="200" align="center" prop="updateTime" />
      <el-table-column v-if="false" label="创建人ID" align="center" prop="createByid" />
      <el-table-column v-if="false" label="修改人ID" align="center" prop="updateByid" />
      <el-table-column v-if="false" label="审批人ID" align="center" prop="auditorid" />
      <el-table-column label="审批人" align="center" prop="auditorname" />
      <el-table-column label="审批时间" align="center" prop="auditortime" width="180" v-slot="scope">
        <span>{{ parseTime(scope.row.auditortime, '{y}-{m}-{d}') }}</span>
      </el-table-column>
      <el-table-column v-if="false" label="时间戳" align="center" prop="pubts" />
      <el-table-column v-if="false" label="是否流程审批控制" align="center" prop="iswfcontrolled" v-slot:default="scope">
        <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.iswfcontrolled" />
      </el-table-column>
      <el-table-column v-if="false" label="工作流ID" align="center" prop="wfid" />
      <el-table-column v-if="false" label="打印次数" align="center" prop="printcount" />
      <el-table-column v-if="false" label="打印时间" align="center" prop="printtime" />
      <el-table-column v-if="false" label="来源单据类型" align="center" prop="srcbilltype" />
      <el-table-column v-if="false" label="来源单据ID" align="center" prop="srcbillid" />
      <el-table-column v-if="false" label="来源单据编号" align="center" prop="srcbillcode" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" v-slot="scope" fixed="right">
        <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
          v-hasPermi="['sc:instockbill:edit']">修改</el-button>
        <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
          v-hasPermi="['sc:instockbill:remove']">删除</el-button>
      </el-table-column>
    </el-table>

    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改入库单对话框 -->
    <el-dialog class="custom-dialog" title="title" :visible.sync="open" width="500px" :appendToBody="true" :modal="true"
      :fullscreen="true" :modal-append-to-body="false">
      <template #title>
        <div
          style="padding: 0 0 0 0; margin-top: 0px; margin-bottom: 0px; font-size: 16px !important; font-weight: bold;">
          {{ title }}
        </div>
      </template>
      <div class="card-wrapper">
        <el-row :disabled="isDisabled">
          <el-card class="card-item" shadow="always">
            <el-form ref="form" :model="form" :rules="rules" label-width="80px" :disabled="isDisabled">
              <el-row :gutter="12">
                <el-col :span="4">
                  <el-form-item label="单据编号" prop="billcode">
                    <el-input v-model="form.billcode" type="input" placeholder="请输入单据编号" :disabled="true" />
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item label="业务主体" prop="orgid">
                    <treeselect v-model="form.orgid" :options="orgTreeSelOptions" :load-options="loadOrgTreeSelOptions"
                      @select="orgTreeSelectEvent" :normalizer="normalizer" search-nested placeholder="选择业务主体"
                      disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="入库部门" prop="depid">
                    <treeselect v-model="form.depid" :options="orgTreeSelOptions" :load-options="loadOrgTreeSelOptions"
                      :appendToBody="true" z-index="999999" @select="depTreeSelectEvent" :normalizer="normalizer"
                      search-nested placeholder="选择入库部门" :disabled="isDisabled" />
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item label="仓库" prop="warehouseid">
                    <el-select v-model="form.warehouseid" filterable remote reserve-keyword placeholder="请输入关键词"
                      clearable :remote-method="remoteSearchWarehouseMethod" @change="handleWarehouseSelectChange"
                      :loading="loading">
                      <el-option v-for="(item, index) in warehouseOptions" :key="index" :label="item.warehousename"
                        :value="String(item.id)">
                      </el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="4">
                  <el-form-item label="单据日期" prop="vouchdate">
                    <el-date-picker clearable v-model="form.vouchdate" type="date" value-format="yyyy-MM-dd"
                      placeholder="请选择单据日期">
                    </el-date-picker>
                  </el-form-item>
                </el-col>
                <el-col :span="10">
                  <el-form-item label="备注" prop="remark">
                    <el-input v-model="form.remark" type="input" placeholder="请输入内容" />
                  </el-form-item>
                </el-col>
                <el-col :span="10">
                  <el-form-item>
                    <el-button v-if="false" type="primary" @click="onSetFormOrgId">设置业务主体</el-button>
                  </el-form-item>
                </el-col>
              </el-row>
              <!-- <el-form-item label="审批时间" prop="auditortime">
                <el-date-picker clearable v-model="form.auditortime" type="date" value-format="yyyy-MM-dd"
                  placeholder="请选择审批时间">
                </el-date-picker>
              </el-form-item>
              <el-form-item label="是否流程审批控制" prop="iswfcontrolled">
                <el-radio-group v-model="form.iswfcontrolled">
                  <el-radio v-for="dict in dict.type.sys_yes_no" :key="dict.value" :label="parseInt(dict.value)">{{
                    dict.label
                  }}</el-radio>
                </el-radio-group>
              </el-form-item> -->
            </el-form>
          </el-card>
        </el-row>
        <el-row>
          <el-card class="card-item" shadow="always">
            <vxe-toolbar ref="toolbarRef" custom size="mini">
              <template #buttons>
                <vxe-button status="primary" icon="vxe-icon-add" @click="addEvent"
                  :disabled="isDisabled">新增</vxe-button>
                <vxe-button v-if="false" status="error" icon="vxe-icon-no-drop" @click="pendingSelect(true)"
                  :disabled="isDisabled">标记删除</vxe-button>
                <vxe-button v-if="false" status="error" icon="vxe-icon-no-drop" @click="pendingSelect(false)"
                  :disabled="isDisabled">取消标记</vxe-button>
                <vxe-button v-if="false" status="success" icon="vxe-icon-save" @click="saveEvent"
                  :disabled="isDisabled">保存</vxe-button>
              </template>
            </vxe-toolbar>
            <vxe-table ref="tableRef" border size="small" height="500" show-overflow :loading="loading"
              :custom-config="customConfig" :edit-config="{ mode: 'row', trigger: 'click' }" :edit-rules="validRules"
              @edit-activated="editActivatedEvent" @edit-closed="editClosedEvent" :data="tableData" :row-config="{}">
              <vxe-column field="seq" type="seq" fixed="left" width="60"></vxe-column>
              <vxe-column field="checkbox" type="checkbox" fixed="left" width="60"></vxe-column>
              <vxe-column field="rowno" title="行号" min-width="80" :visible="false"></vxe-column>
              <vxe-column field="productid" title="物料ID" min-width="80" :visible="false"></vxe-column>
              <vxe-column field="productcode" title="物料编码" min-width="200" :edit-render="productcodeSelectRender"
                :visible="false" :clearable="true" :filterable="true" :transfer="true"></vxe-column>
              <!-- <vxe-column field="productname" title="物料" min-width="200" :edit-render="productnameSelectRender"
                :clearable="true" :filterable="true" :transfer="true"></vxe-column> -->
              <!-- <vxe-column field="productname" title="物料" min-width="200" :edit-render="{}">
                <template #edit="{ row, column }">
                  <vxe-select v-model="row.productname" placeholder="请选择" :options="productnameOptions"
                    :remote-config="productnameRemoteConfig" :loading="loading"
                    :option-props="{ value: 'id', label: 'productname' }" :disabled="isDisabled" :remote="true"
                    @change="setRowProductInfo2(row, column, $event)" :clearable="true" :filterable="true"
                    :transfer="true"></vxe-select>
                </template>
                <template #default="{ row }">
                  <span>{{ formatProductnameLabel(row) }}</span>
                </template>
              </vxe-column> -->
              <!-- <vxe-column field="productname" title="物料" width="200" :edit-render="{}">
                <template #edit="{ row, column }">
                  <vxe-table-select v-model="row.productname" :options="productnameOptions"
                    :columns="productnameColumns" :option-props="{ value: 'id', label: 'productname' }"
                    @change="setRowProductInfo2(row, column, $event)" :disabled="isDisabled"></vxe-table-select>
                </template>
                <template #default="{ row }">
                  <span>{{ formatProductnameLabel(row) }}</span>
                </template>
              </vxe-column> -->
              <vxe-column field="productname" title="物料" , width="200" :edit-render="{}">
                <template #edit="{ row }">
                  <!-- <vxe-input ref="productnameInputRef" v-model="row.productname" type="search" suffix-icon="vxe-icon-menu"> -->
                  <vxe-input ref="productnameInputRef" v-model="row.productname" @keyup="productnameInputKeyup"
                    :disabled="isDisabled" :editable="false">
                    <template #suffix>
                      <vxe-button mode="text" :suffix-tooltip="{ icon: 'vxe-icon-menu' }"
                        @click="productnameIconBtnClick"></vxe-button>
                    </template>
                  </vxe-input>
                </template>
              </vxe-column>
              <vxe-column field="productdesc" title="规格说明" min-width="200" :edit-render="productdescInputRender"
                :clearable="true" :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="model" title="型号" min-width="200" :edit-render="modelInputRender" :clearable="true"
                :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="unitid" title="单位ID" min-width="80" :visible="false"></vxe-column>
              <vxe-column field="unitcode" title="单位编码" min-width="200" :edit-render="unitcodeSelectRender"
                :visible="false" :clearable="true" :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="unitname" title="单位" min-width="120" :edit-render="unitnameSelectRender"
                :clearable="true" :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="qty" title="数量" min-width="200"
                :edit-render="{ name: 'VxeNumberInput', props: { type: 'number', disabled: isDisabled } }"></vxe-column>
              <vxe-column field="goodspositionid" title="货位ID" min-width="80" :visible="false"></vxe-column>
              <vxe-column field="goodspositioncode" title="货位编码" min-width="200"
                :edit-render="goodspositioncodeSelectRender" :clearable="true" :filterable="true" :visible="false"
                :transfer="true"></vxe-column>
              <vxe-column field="goodspositionname" title="货位" min-width="200"
                :edit-render="goodspositionnameSelectRender" :clearable="true" :filterable="true"
                :transfer="true"></vxe-column>
              <vxe-column field="projectname" title="项目" min-width="200"
                :edit-render="{ name: 'VxeInput', props: { disabled: isDisabled } }" :clearable="true"
                :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="batchno" title="批次" min-width="200"
                :edit-render="{ name: 'VxeInput', props: { disabled: isDisabled } }" :clearable="true"
                :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="remark" title="备注" min-width="200"
                :edit-render="{ name: 'VxeInput', props: { disabled: isDisabled } }" :clearable="true"
                :filterable="true" :transfer="true"></vxe-column>
              <vxe-column field="active" title="操作" fixed="right" width="80">
                <template v-slot="{ row }">
                  <vxe-button mode="text" status="error" icon="vxe-icon-delete" @click="removeRow(row)"
                    :disabled="isDisabled"></vxe-button>
                </template>
              </vxe-column>
            </vxe-table>
          </el-card>
        </el-row>
        <!-- <el-page-header @back="goBack" content="详情页面">
      </el-page-header> -->
        <el-row>
          <el-card class="card-item" shadow="always"
            :body-style="{ paddingTop: '0px', paddingBottom: '0px', marginBottom: '0px' }">
            <el-col :span="4">
              <div>创建人 {{ form.createBynick }}</div>
            </el-col>
            <el-col :span="6">
              <div>创建时间 {{ form.createTime }}</div>
            </el-col>
            <el-col :span="4">
              <div>审核人 {{ form.auditorname }}</div>
            </el-col>
            <el-col :span="6">
              <div>审核时间 {{ form.auditortime }}</div>
            </el-col>
          </el-card>
        </el-row>
      </div>
      <template #footer>
        <div style="padding: 0 0 0 0; margin-top: 0px; margin-bottom: 0px;">
          <el-button type="primary" size="small" @click="submitForm" :disabled="isDisabled">确 定</el-button>
          <el-button size="small" @click="cancel">取 消</el-button>
        </div>
      </template>
      <!-- <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div> -->

      <ProductReference ref="productnameRef" :showPopup.sync="showPopup" :searchValue.sync="productnameSearchVal"
        :productnameSelectRender.sync="productnameSelectRender" @productname-selected-event="productnameSelectedEvent">
      </ProductReference>
    </el-dialog>
  </div>
</template>

<script>
import { listInstockbill, getInstockbill, delInstockbill, addInstockbill, updateInstockbill, submitInstockbill, unsubmitInstockbill, auditInstockbill, unauditInstockbill } from "@/api/sc/instockbill";
import { listInstockbilllist } from "@/api/sc/instockbilllist";
import { genBillNumber } from "@/api/sc/billseqlog";
import { listWarehouse } from "@/api/sc/warehouse";
import { listProduct } from "@/api/sc/product";
import { listUnit } from "@/api/sc/unit";
import { listGoodsposition } from "@/api/sc/goodsposition";
import { orgTreeSelect } from "@/api/system/dept";
import { VxeUI } from 'vxe-table';
import { Treeselect, LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS, ASYNC_SEARCH } from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { debounce } from 'lodash'
import * as Big from 'bigdecimal';
import ProductReference from "../components/ProductReference/index.vue";
// import { sassFalse } from "sass";

export default {
  name: "Instockbill",
  dicts: ['sys_yes_no'],
  components: { Treeselect, ProductReference },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 入库单表格数据
      instockbillList: [],
      // 入库单列表表格数据
      instockbilllistList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        depname: null,
        billcode: null,
        vouchdate: null,
        vouchdatestart: null,
        vouchdateend: null,
        remark: null,
        createBy: null,
        createBynick: null,
        warehousename: null,
        orgname: null,
        productname: null,
        status: null,
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        depid: [
          { required: true, message: "部门不能为空", trigger: "blur" }
        ],
        depname: [
          { required: true, message: "部门不能为空", trigger: "blur" }
        ],
        billcode: [
          { required: true, message: "单据编号不能为空", trigger: "blur" }
        ],
        vouchdate: [
          { required: true, message: "单据日期不能为空", trigger: "blur" }
        ],
        // remark: [
        //   { required: true, message: "备注不能为空", trigger: "blur" }
        // ],
        createBynick: [
          { required: true, message: "创建人不能为空", trigger: "blur" }
        ],
        warehouseid: [
          { required: true, message: "仓库不能为空", trigger: "blur" }
        ],
        warehousename: [
          { required: true, message: "仓库不能为空", trigger: "blur" }
        ],
        orgid: [
          { required: true, message: "业务主体不能为空", trigger: "blur" }
        ],
        orgname: [
          { required: true, message: "业务主体不能为空", trigger: "blur" }
        ],
        // details: [
        //   { required: true, message: "表体不能为空", trigger: "blur" }
        // ],
      },

      // 自定义数据
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() > Date.now();
        },
      },
      orgTreeSelOptions: [],
      warehouseOptions: [],
      tableLoading: false,
      tableData: [],
      customConfig: {
        allowVisible: true,
        allowFixed: true,
        allowResizable: true,
        allowSort: true
      },
      validRules: {
        productcode: [
          { required: true, message: '必须填写' }
        ],
        productname: [
          { required: true, message: '必须填写' }
        ],
        unitcode: [
          { required: true, message: '必须填写' }
        ],
        unitname: [
          { required: true, message: '必须填写' }
        ],
        qty: [
          { required: true, message: '必须填写' }
        ],
        goodspositioncode: [
          { required: true, message: '必须填写' }
        ],
        goodspositionname: [
          { required: true, message: '必须填写' }
        ]
      },
      isDisabled: false,
      productcodeSelectRender: {
        name: 'VxeSelect',
        props: {
          multiple: false,
          filterable: true,
          disabled: true,
        },
        options: [],
        optionProps: {
          value: 'id',
          label: 'productcode',
        },
        events: {
          change: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('物料编码', row[column.field]);
            ////console.log('物料编码cellParams', cellParams);
            ////console.log('物料编码targetParams', targetParams);
            ////row['productcode'] = ''; // 清空物料编码
          }
        }
      },
      productnameSelectRender: {
        name: 'VxeSelect',
        props: {
          multiple: false,
          filterable: true,
          disabled: false,
          remote: true,
        },
        options: [],
        optionProps: {
          value: 'id',
          label: 'productname',
        },
        events: {
          change: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('物料名称row', row);
            ////console.log('物料名称col', column);
            ////console.log('物料名称', row[column.field]);
            ////console.log('物料名称cellParams', cellParams);
            ////console.log('物料名称targetParams', targetParams);
            ////console.log('表格', this.$refs.tableRef);
            this.setRowProductInfo(row, column); // 设置表体行物料信息
          }
        }
      },
      productnameOptions: [], // 
      productnameColumns: [{ field: 'productcode', title: '物料编码' },
      { field: 'productname', title: '物料' },
      { field: 'model', title: '型号' },
      { field: 'modeldescription', title: '规格' }],
      debounceGetProductnameMethod: null,
      productnameRemoteConfig: {},
      productdescInputRender: {
        name: 'VxeInput',
        props: {
          filterable: true,
          disabled: true,
        },
        events: {
          input: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('规格说明', row, column.field, cellParams, targetParams);
          }
        }
      },
      modelInputRender: {
        name: 'VxeInput',
        props: {
          filterable: true,
          disabled: true,
        },
        events: {
          input: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('型号', row, column.field, cellParams, targetParams);
          }
        }
      },
      unitcodeSelectRender: {
        name: 'VxeSelect',
        props: {
          multiple: false,
          filterable: true,
          disabled: true,
        },
        options: [],
        optionProps: {
          value: 'id',
          label: 'unitcode',
        },
        events: {
          change: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('单位编码', row[column.field]);
            ////console.log('单位编码cellParams', cellParams);
            ////console.log('单位编码targetParams', targetParams);
            ////row['productcode'] = ''; // 清空物料编码
          }
        }
      },
      unitnameSelectRender: {
        name: 'VxeSelect',
        props: {
          multiple: false,
          filterable: true,
          disabled: true,
        },
        options: [],
        optionProps: {
          value: 'id',
          label: 'unit',
        },
        events: {
          change: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('单位名称', row[column.field]);
            ////console.log('单位名称cellParams', cellParams);
            ////console.log('单位名称targetParams', targetParams);
            this.setRowUnitInfo(row, column); // 设置表体行单位信息
          }
        }
      },
      goodspositioncodeSelectRender: {
        name: 'VxeSelect',
        props: {
          multiple: false,
          filterable: true,
          disabled: true,
        },
        options: [],
        optionProps: {
          value: 'id',
          label: 'goodspositioncode',
        },
        events: {
          change: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('货位编码', row[column.field]);
            ////console.log('货位编码cellParams', cellParams);
            ////console.log('货位编码targetParams', targetParams);
            ////row['productcode'] = ''; // 清空物料编码
          }
        }
      },
      goodspositionnameSelectRender: {
        name: 'VxeSelect',
        props: {
          multiple: false,
          filterable: true
        },
        options: [],
        optionProps: {
          value: 'id',
          label: 'goodspositionname',
        },
        events: {
          change: (cellParams, targetParams) => {
            const { row, column } = cellParams;
            ////console.log('货位名称', row[column.field]);
            ////console.log('货位名称cellParams', cellParams);
            ////console.log('货位名称targetParams', targetParams);
            this.setRowGoodspositionInfo(row, column); // 设置表体行货位信息
          }
        }
      },
      // 查询方式 0-表头 1-表头+明细
      radio: 1,
      // 物料名称搜索值
      productnameSearchVal: '',
      pageVO: {
        total: 0,
        currentPage: 1,
        pageSize: 10
      },
      showPopup: false,
      searchTableLoading: false,
      currentEditRow: null, // 当前编辑的行数据
      currentEditColumn: null, // 当前编辑的列数据
    };
  },
  watch: {
    isDisabled(newVal) {
      this.productnameSelectRender.props.disabled = newVal;
      // this.unitnameSelectRender.props.disabled = newVal;
      this.goodspositionnameSelectRender.props.disabled = newVal;
    },
    'goodspositionnameSelectRender.options'(newVal) {
      ////console.log('货位名称下拉配置变化', newVal);
      if (newVal && newVal.length > 0) {
        this.validRules.goodspositioncode[0].required = true; // 如果货位选项有数据,则设置为必填,否则不必填
        this.validRules.goodspositionname[0].required = true; // 如果货位选项有数据,则设置为必填,否则不必填
      } else if (newVal && newVal.length === 0) {
        this.validRules.goodspositioncode[0].required = false;
        this.validRules.goodspositionname[0].required = false;
      }
    },
  },
  beforeCreate() {
    ////console.log('入库单页面即将创建');
  },
  created() {
    ////console.log('入库单页面创建完成');
    ////this.queryParams.vouchdate = this.formatDate(new Date());
    const date = new Date();
    date.setDate(date.getDate() - 15);
    this.queryParams.vouchdatestart = this.formatDate(date);
    ////console.log(this.queryParams.vouchdatestart, '单据开始日期');
    this.getList();
    this.getOrgRootOptions();
    // this.getProductOptions();
    this.getUnitOptions();
    ////this.getGoodspositionOptions(null);
    VxeUI.setConfig({
      zIndex: 99999999, // 全局 zIndex 起始值,如果项目的的 z-index 样式值过大时就需要跟随设置更大,避免被遮挡;新版本可以使用 dom-zindex 共享配置;解决 vxe-select 弹窗被遮挡问题
    });

    this.debounceGetProductnameMethod = debounce(async ({ searchValue, value }) => {
      console.log(searchValue, '物料远程搜索searchValue');
      console.log(value, '物料远程搜索value');
      return new Promise(resolve => {
        this.getProductOptions(searchValue);
        resolve();
      });
    }, 2000);
    this.productnameRemoteConfig = {
      queryMethod: this.debounceGetProductnameMethod,
    }
  },
  mounted() {
    ////console.log('入库单页面挂载完成');
    const $table = this.$refs.tableRef;
    const $toolbar = this.$refs.toolbarRef;
    if ($table && $toolbar) {
      $table.connect($toolbar);
    }

    this.$nextTick(function () {
      // 仅在整个视图都被渲染之后才会运行的代码
      this.onSetFormOrgId();
    });
  },
  methods: {
    /** 查询入库单列表 */
    getList() {
      this.loading = true;
      this.queryParams.orderByColumn = "CreateTime";
      this.queryParams.isAsc = "desc";
      ////console.log(this.queryParams, '查询参数');
      if (this.radio == 0) {
        listInstockbill(this.queryParams).then(response => {
          this.instockbillList = response.rows;
          this.total = response.total;
          this.loading = false;
        });
      } else if (this.radio == 1) {
        listInstockbilllist(this.queryParams).then(response => {
          this.instockbilllistList = response.rows;
          this.total = response.total;
          this.loading = false;
        });
      }
    },
    /* 查询业务主体 */
    getOrgRootOptions() {
      this.loading = true;
      // productClassTreeSelect({ ilevel: 1 }).then(response => {
      orgTreeSelect({}).then(response => {
        this.orgTreeSelOptions = response.data;
        this.loading = false;
        // ////console.log('业务主体树形下拉数据', this.orgTreeSelOptions);
      });
    },
    // async getOrgRootOptions() {
    //    orgTreeSelect({}).then(response => {
    //     this.orgTreeSelOptions = response.data;
    //   });
    // },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        billid: null,
        billcode: null,
        vouchdate: null,
        vouchtype: null,
        createBy: null,
        createBynick: null,
        createTime: null,
        updateBy: null,
        updateBynick: null,
        updateTime: null,
        createByid: null,
        updateByid: null,
        remark: null,
        status: null,
        verifyState: null,
        auditorid: null,
        auditorname: null,
        auditortime: null,
        pubts: null,
        iswfcontrolled: null,
        wfid: null,
        warehouseid: null,
        warehousecode: null,
        warehousename: null,
        orgid: null,
        orgcode: null,
        orgname: null,
        depid: null,
        depcode: null,
        depname: null,
        printcount: null,
        printtime: null,
        srcbillid: null,
        srcbillcode: null,
        srcbilltype: null,
        details: null,
      };
      this.resetForm("form");
      this.tableData = [];
      this.isDisabled = false;
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      if (this.radio == 0) {
        this.getList();
      } else if (this.radio == 1) {
        this.getList();
      }
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      genBillNumber({ billtype: "RK" }).then(response => {
        this.form.billcode = response.data;
        ////////console.log('生成单据编号', this.form.billcode);
      });
      this.open = true;
      this.title = "添加入库单";

      // 设置默认业务主体和单据日期
      this.onSetFormOrgId();
      this.form.vouchdate = this.parseTime(new Date(), '{y}-{m}-{d}');

      // 设置默认创建人和创建时间
      if (this.form.createBynick == null || this.form.createBynick === '') {
        this.form.createBynick = this.$store.state.user.nickname;
      }
      this.form.createTime = this.parseTime(new Date(), '{y}-{m}-{d}');
    },
    /* 新增下拉按钮指令 */
    handleAddCommand(command) {
      this.$message('click on item ' + command);
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      console.log('修改入库单ID', id);
      let currBill = null;
      if (this.radio == '0') {
        currBill = Array.isArray(id)
          ? this.instockbillList.find(item => id.includes(item.id))
          : this.instockbillList.find(item => item.id === id);
      } else if (this.radio == '1') {
        currBill = Array.isArray(id)
          ? this.instockbilllistList.find(item => id.includes(item.id))
          : this.instockbilllistList.find(item => item.id === id);
      }

      console.log('当前修改的入库单', currBill);
      if (currBill && currBill.status !== 0) {
        this.$modal.msgWarning("只有状态为【开立】的入库单才能修改");
        return;
      }

      this.loading = true;
      getInstockbill(id).then(response => {
        const $table = this.$refs.tableRef;
        this.form = response.data;
        this.form.updateBynick = this.$store.state.user.nickname;
        ////console.log('修改时加载的表单数据', this.form);
        this.open = true;
        this.title = "修改入库单";
        this.onSetFormOrgId();
        listWarehouse({ pageNum: 1, pageSize: 1000, warehousename: this.form.warehousename, stopstatus: 0 }).then(response => {
          this.warehouseOptions = response.rows;
        }).then(() => {
          const selected = this.warehouseOptions.find(item => item.id === this.form.warehouseid)
          if (selected) {
            // 设置仓库编码和名称
            this.form.warehouseid = selected.id;
            console.log(this.form.warehouseid, '选择仓库');
            this.form.warehousecode = selected.warehousecode;
            this.form.warehousename = selected.warehousename;
            // 清除货位信息
            const $table = this.$refs.tableRef;
            let { tableData: tableData } = $table.getTableData();
            tableData.forEach(row => {
              row['goodspositioncode'] = '';
              row['goodspositionname'] = '';
            });
            listGoodsposition({ pageNum: 1, pageSize: 2000, warehouseid: this.form.warehouseid, stopstatus: 0 }).then(response => {
              this.goodspositionnameSelectRender.options = response.rows;
              this.tableData = this.form.details;
              this.loading = false;
            });
          }
        });
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.saveEvent().then((result) => {
            if (result == null) {
              // 结果为null表示验证未通过,保存事件内部已经有提示信息了,这里直接返回
              return;
            }

            if (this.form.details == null || this.form.details.length === 0) {
              this.$modal.msgError("表体不能为空");
              return;
            } else {
              this.form.details.forEach(row => {
                // 更新表体行物料名称
                ////console.log('保存处理表体行物料名称', row);
                if (row.productid != null && row.productid !== undefined) {
                  const product = this.productnameSelectRender.options.find(item => item.id === row.productid);
                  ////console.log('找到的物料', product);
                  if (product) {
                    row.productname = product.productname;
                  }
                }

                // 更新表体行单位名称
                ////console.log('保存处理表体行单位名称', row);
                if (row.unitid != null && row.unitid !== undefined) {
                  const unit = this.unitnameSelectRender.options.find(item => item.id === row.unitid);
                  ////console.log('找到的单位', unit);
                  if (unit) {
                    row.unitname = unit.unit;
                  }
                }

                // 更新表体行货位名称
                ////console.log('保存处理表体行货位名称', row);
                if (row.goodspositionid != null && row.goodspositionid !== undefined) {
                  const goodsposition = this.goodspositionnameSelectRender.options.find(item => item.id === row.goodspositionid);
                  ////console.log('找到的货位', goodsposition);
                  if (goodsposition) {
                    row.goodspositionname = goodsposition.goodspositionname;
                  }
                }

                // 批次号处理
                if (row.batchno == null || row.batchno === undefined) {
                  row.batchno = "";
                }
              });

              ////console.log('修改后的提交的表单数据', this.form);
            }

            // 表头表体验证通过后再进行保存操作
            if (this.form.id != null) {
              updateInstockbill(this.form).then(response => {
                this.$modal.msgSuccess("修改成功");
                this.open = false;
                this.getList();
              });
            } else {
              addInstockbill(this.form).then(response => {
                this.$modal.msgSuccess("新增成功");
                this.open = false;
                this.getList();
              });
            }
          });
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      const currBill = Array.isArray(ids)
        ? this.instockbillList.find(item => ids.includes(item.id))
        : this.instockbillList.find(item => item.id === ids);
      ////console.log('当前删除的入库单', currBill);
      if (currBill && currBill.status !== 0) {
        this.$modal.msgWarning("只有状态为【开立】的入库单才能删除");
        return;
      }

      this.$modal.confirm('是否确认删除@Model.FunctionName)编号为"' + ids + '"的数据项?').then(function () {
        return delInstockbill(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => { });
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('sc/instockbill/export', {
        ...this.queryParams
      }, `instockbill_${new Date().getTime()}.xlsx`)
    },

    // 自定义方法
    /* 提交按钮操作 */
    handleSubmit() {
      this.handleSubmitCommand('submit');
    },
    /* 提交下拉按钮操作 */
    handleSubmitCommand(command) {
      ////this.$message('click on item ' + command);
      const ids = this.ids;
      console.log('选中的单据ids', ids, JSON.stringify(ids));
      if (!ids || ids.length === 0) {
        this.$modal.msgWarning("请选择要操作的数据");
        return;
      }

      const currBill = Array.isArray(ids)
        ? this.instockbillList.find(item => ids.includes(item.id))
        : this.instockbillList.find(item => item.id === ids);
      ////console.log('当前提交的入库单', currBill);
      if (command === 'submit') {
        // 提交单据操作 
        if (currBill && currBill.status !== 0) {
          this.$modal.msgWarning("只有状态为【开立】的入库单才能提交");
          return;
        }

        submitInstockbill({ ids: ids }).then(response => {
          this.$modal.msgSuccess("提交成功");
          this.open = false;
          this.getList();
        });
      } else if (command === 'unsubmit') {
        // 撤销提交操作
        if (currBill && currBill.status !== 3) {
          this.$modal.msgWarning("只有状态为【提交】的入库单才能撤销");
          return;
        }

        unsubmitInstockbill({ ids: ids }).then(response => {
          this.$modal.msgSuccess("撤销成功");
          this.open = false;
          this.getList();
        });
      }
    },
    /* 审核按钮操作 */
    handleAudit() {
      this.handleAuditCommand('audit');
    },
    /* 审核下拉按钮操作 */
    handleAuditCommand(command) {
      // this.$message('click on item ' + command);
      const ids = this.ids;
      if (!ids || ids.length === 0) {
        this.$modal.msgWarning("请选择要操作的数据");
        return;
      }

      const currBill = Array.isArray(ids)
        ? this.instockbillList.find(item => ids.includes(item.id))
        : this.instockbillList.find(item => item.id === ids);
      ////console.log('当前审核的入库单', currBill);
      if (command === 'audit') {
        // 审核单据操作 
        if (currBill && currBill.status !== 3) {
          this.$modal.msgWarning("只有状态为【提交】的入库单才能审核");
          return;
        }

        auditInstockbill({ ids: ids, auditorname: this.$store.state.user.nickname }).then(response => {
          this.$modal.msgSuccess("审核成功");
          this.open = false;
          this.getList();
        });
      } else if (command === 'unaudit') {
        // 撤销审核操作
        if (currBill && currBill.status !== 1) {
          this.$modal.msgWarning("只有状态为【审核】的入库单才能撤销审核");
          return;
        }

        unauditInstockbill({ ids: ids, auditorname: this.$store.state.user.nickname }).then(response => {
          this.$modal.msgSuccess("撤销审核成功");
          this.open = false;
          this.getList();
        });
      }

    },
    /* 页头返回 */
    goBack() {
      this.open = false;
    },
    /* 自定义键名,转换物料分类数据结构 */
    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children;
      }
      return {
        id: node.id,
        label: node.label,
        children: node.children
      };
    },
    /* 部门树形下拉列表延迟加载 */
    loadOrgTreeSelOptions({ action, parentNode, callback }) {
      // ////console.log('loadOptions action', action);
      // ////console.log('loadOptions parentNode', parentNode);
      // ////console.log('loadOptions callback', callback);
      if (action === LOAD_CHILDREN_OPTIONS) {
        orgTreeSelect({ parentid: parentNode.id }).then(response => {
          parentNode.children = response.data;
          callback();
        });
      }
    },
    /* 仓库下拉列表远程搜索 */
    remoteSearchWarehouseMethod(query) {
      if (query !== undefined && query !== '') {
        this.loading = true;
        listWarehouse({ pageNum: 1, pageSize: 1000, warehousename: query, stopstatus: 0 }).then(response => {
          response.rows.forEach(item => {
            // console.log(item.id, '处理前warehouseid');
            item.id = new Big.BigDecimal(item.id).toString(); // 处理number(20)精度丢失问题
            // console.log(item.id, '处理后warehouseid');
          });
          this.warehouseOptions = response.rows;
          console.log('远程查询仓库结果', this.warehouseOptions);
          // console.log(2257978742855434248.0, '测试打印numer(20)'); // 会打印出2257978742855434200 
          // console.log(String(2257978742855434248.0), '测试打印numer(20)转String'); // 也会打印出2257978742855434200 
          // console.log(BigInt(2257978742855434248n), '测试打印numer(20)转BigInt'); // 也会打印出2257978742855434240n
          // console.log(Number(2257978742855434248.0), '测试打印numer(20)转Number'); // 也会打印出2257978742855434200
          console.log(new Big.BigDecimal('2257978742855434248.0').toString(), '测试打印numer(20)转BigDecimal'); // 也会打印出2257978742855434240n
          this.loading = false;
        });
      } else {
        this.warehouseOptions = [];
      }
    },
    /* 仓库下拉列表选项改变事件 */
    handleWarehouseSelectChange(value) {
      console.log('触发仓库下拉选中', value);
      const selected = this.warehouseOptions.find(item => item.id === value)
      if (selected) {
        // 设置仓库编码和名称
        this.form.warehouseid = selected.id;
        console.log(this.form.warehouseid, '选择仓库');
        this.form.warehousecode = selected.warehousecode;
        this.form.warehousename = selected.warehousename;
        // 清除货位信息
        const $table = this.$refs.tableRef;
        let { tableData: tableData } = $table.getTableData();
        tableData.forEach(row => {
          row['goodspositioncode'] = '';
          row['goodspositionname'] = '';
        });
        this.getGoodspositionOptions(this.form.warehouseid);
        //// ////console.log('处理选择仓库', selected);
      }
    },
    /* 业务主体树形下拉列表选择事件 */
    orgTreeSelectEvent(node, instanceId) {
      ////console.log('业务主体node', node);
      ////console.log('业务主体instanceId', instanceId);
      ////console.log('选择业务主体ID', node.id);
      ////console.log('选择业务主体', node.label);
      let orgCodeName = node.label.split(' ');
      if (orgCodeName.length > 1) {
        this.form.orgcode = orgCodeName[0];
        this.form.orgname = orgCodeName[1];
      }
      else {
        this.form.orgcode = '';
        this.form.orgname = orgCodeName[0];
      }
      ////console.log('打印当前表单', this.form);
    },
    /* 入库部门树形下拉列表选择事件 */
    depTreeSelectEvent(node, instanceId) {
      ////console.log('入库部门node', node);
      ////console.log('入库部门instanceId', instanceId);
      ////console.log('选择入库部门ID', node.id);
      ////console.log('选择入库部门', node.label);
      let depCodeName = node.label.split(' ');
      if (depCodeName.length > 1) {
        this.form.depcode = depCodeName[0];
        this.form.depname = depCodeName[1];
      }
      else {
        this.form.depcode = '';
        this.form.depname = depCodeName[0];
      }
      ////console.log('打印当前表单', this.form);
    },
    /* Vxe表格添加按钮事件 */
    async addEvent() {
      const $table = this.$refs.tableRef;
      if (this.form.warehouseid == undefined || this.form.warehouseid == null) {
        VxeUI.modal.message({
          content: '请先选择仓库',
          status: 'info'
        });
        return;
      }

      if ($table && this.form.warehouseid != null) {
        const record = {};
        const { row: newRow, rows: tableRows } = await $table.insertAt(record, -1);
        ////console.log('newRow', newRow);
        ////console.log('tableRows', tableRows);
        newRow.rowno = $table.getRowSeq(newRow); // 设置行号
        await $table.setEditRow(newRow);
        ////this.getGoodspositionOptions(this.form.warehouseid);
      }
    },
    /* Vxe表格标记按钮事件 */
    async pendingSelect(checked) {
      const $table = this.$refs.tableRef;
      if ($table) {
        const selectRecords = $table.getCheckboxRecords();
        if (selectRecords.length) {
          $table.setPendingRow(selectRecords, checked);
          $table.clearCheckboxRow();
        }
        else {
          VxeUI.modal.message({
            content: '未选中数据',
            status: 'info'
          });
        }
      }
    },
    /* Vxe表格删除按钮事件 */
    async removeRow(row) {
      const $table = this.$refs.tableRef;
      if ($table) {
        await $table.remove(row);
      }
    },
    /* Vxe表格保存按钮事件 */
    async saveEvent() {
      const $table = this.$refs.tableRef;
      ////console.log('$table', $table);
      ////console.log('tableData', $table.tableData);
      if ($table) {
        const errMap = await $table.validate(true);
        if (errMap) {
          return null;
        }

        const { insertRecords, updateRecords, removeRecords } = $table.getRecordset();
        const pendingRecords = $table.getPendingRecords();
        ////console.log('表格新增', insertRecords);
        ////console.log('表格修改', updateRecords);
        ////console.log('表格删除', removeRecords);
        ////console.log('表格待删', pendingRecords);
        // // VxeUI.modal.alert({
        // //     title: 'CRUD 管理器',
        // //     content: `新增:${insertRecords.length} 行,已删除:${removeRecords.length} 行,待删除:${pendingRecords.length} 行,修改:${updateRecords.length} 行`
        // // });
        if ($table.tableData.length == 0) {
          return null
        }
        else {
          this.form.details = $table.tableData;
          ////console.log('保存时表体数据', this.form.details);
          ////this.
          return '1';
        }
      }
    },
    /* Vxe表格编辑激活事件 */
    editActivatedEvent({ row, column }) {
      this.currentEditRow = row;
      this.currentEditColumn = column;
    },
    /* Vxe表格编辑结束事件 */
    async editClosedEvent({ column, row }) {
      ////console.log(`编辑结束 field=${column.field} 值=${row[column.field]}`);
      // const $table = this.$refs.tableRef;
      // if ($table) {
      //   const errMap = await $table.validate();
      //   if (errMap) {
      //     VxeUI.modal.message({ status: 'error', content: '校验不通过!' });
      //   }
      // }
    },
    /* 测试设置业务主体 */
    onSetFormOrgId() {
      this.form.orgid = "100"; // 默认业务主体为安丰钢铁集团
      ////console.log('设置业务主体ID', this.form.orgid);
      ////console.log('业务主体下拉数据111', this.orgTreeSelOptions);
      let selected = this.findNodeByIdIterative(this.orgTreeSelOptions, this.form.orgid);
      if (selected) {
        let orgCodeName = selected.label.split(' ');
        if (orgCodeName.length > 1) {
          this.form.orgcode = orgCodeName[0];
          this.form.orgname = orgCodeName[1];
        }
        else {
          this.form.orgcode = '';
          this.form.orgname = orgCodeName[0];
        }
        ////console.log('处理选择业务主体', selected);
      }

      ////console.log('打印当前表单', this.form);
    },
    /* 迭代查找树形下拉列表节点 */
    findNodeByIdIterative(treeData, targetId) {
      let stack = [...treeData]; // 初始化堆栈为顶层节点
      while (stack.length > 0) {
        const node = stack.pop(); // 从堆栈顶部取出节点
        if (node.id === targetId) {
          return node;
        }
        if (node.children && node.children.length > 0) {
          stack.push(...node.children); // 将子节点压入堆栈
        }
      }
      return null;
    },
    /* 获取物料下拉数据 */
    getProductOptions(searchValue) {
      this.loading = true;
      listProduct({ pageNum: 1, pageSize: 2000, productname: searchValue }).then(response => {
        this.productnameSelectRender.options = response.rows;
        this.productnameOptions = response.rows;
        this.loading = false;
        ////console.log('物料列表下拉数据', this.productnameSelectRender.options);
        ////console.log('物料列表下拉数据', this.productnameOptions);
      });
    },
    /* 获取单位下拉数据 */
    getUnitOptions() {
      this.loading = true;
      listUnit({ pageNum: 1, pageSize: 2000 }).then(response => {
        this.unitnameSelectRender.options = response.rows;
        this.loading = false;
        ////console.log('单位列表下拉数据', this.unitnameSelectRender.options);
      });
    },
    /* 获取货位下拉数据 */
    getGoodspositionOptions(warehouseid) {
      this.loading = true;
      listGoodsposition({ pageNum: 1, pageSize: 2000, warehouseid: warehouseid, stopstatus: 0 }).then(response => {
        this.goodspositionnameSelectRender.options = response.rows;
        this.loading = false;
        ////console.log('货位列表下拉数据', this.goodspositionnameSelectRender.options);
      });
    },
    /* VxeTable移除行 */
    async removeRow(row) {
      const $table = this.$refs.tableRef;
      if ($table) {
        await $table.remove(row);
      }
    },
    /* 设置表体行物料信息 */
    setRowProductInfo(row, column) {
      console.log(row, column, '表体行物料选择改变');
      // 设置物料编码下拉选项
      this.productcodeSelectRender.options = [this.productnameSelectRender.options.find(item => item.id === row[column.field])];
      ////console.log('物料编码options', this.productcodeSelectRender.options);
      const productcodeCol = this.$refs.tableRef.getColumnByField('productcode');
      ////console.log('物料编码列', productcodeCol);
      // 设置物料编码单元格的值
      row.productcode = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].productcode : '';
      row.productdesc = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].modeldescription : '';
      row.model = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].model : '';
      row.productid = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].id : '';
      ////console.log('设置物料编码单元格值后row', row);
      // 设置物料单位下拉选项的值
      row.unitid = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].unitid : '';
      row.unitcode = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].unitcode : '';
      row.unitname = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].unitname : '';
      ////console.log('设置物料单位单元格值后row', row);
      ////row['productcode'] = ''; // 清空物料编码
    },
    setRowProductInfo2(row, column, event) {
      console.log(row, column, '表体行物料选择改变row column');
      console.log(event, '表体行物料选择改变');
      // 设置物料编码下拉选项
      this.productcodeSelectRender.options = [event.option];
      row.productcode = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].productcode : '';
      row.productdesc = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].modeldescription : '';
      row.model = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].model : '';
      row.productid = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].id : '';
      ////console.log('设置物料编码单元格值后row', row);
      // 设置物料单位下拉选项的值
      row.unitid = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].unitid : '';
      row.unitcode = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].unitcode : '';
      row.unitname = this.productcodeSelectRender.options.length > 0 ? this.productcodeSelectRender.options[0].unitname : '';
      ////console.log('设置物料单位单元格值后row', row);
      ////row['productcode'] = ''; // 清空物料编码
    },
    /* 设置表体行单位信息 */
    setRowUnitInfo(row, column) {
      // 设置单位编码下拉选项
      this.unitcodeSelectRender.options = [this.unitnameSelectRender.options.find(item => item.id === row[column.field])];
      // 设置单位编码单元格的值
      row.unitcode = this.unitcodeSelectRender.options.length > 0 ? this.unitcodeSelectRender.options[0].unitcode : '';
      row.unitid = this.unitcodeSelectRender.options.length > 0 ? this.unitcodeSelectRender.options[0].id : '';
      ////row['productcode'] = ''; // 清空物料编码
    },
    /* 设置表体行货位信息 */
    setRowGoodspositionInfo(row, column) {
      // 设置货位编码下拉选项
      this.goodspositioncodeSelectRender.options = [this.goodspositionnameSelectRender.options.find(item => item.id === row[column.field])];
      // 设置货位编码单元格的值
      row.goodspositioncode = this.goodspositioncodeSelectRender.options.length > 0 ? this.goodspositioncodeSelectRender.options[0].goodspositioncode : '';
      row.goodspositionid = this.goodspositioncodeSelectRender.options.length > 0 ? this.goodspositioncodeSelectRender.options[0].id : '';
      ////row['productcode'] = ''; // 清空物料编码
    },
    // 单据编号点击事件
    getBillcodeClickHandler(row) {
      event.preventDefault();
      ////console.log('点击了单据号:', row.billcode);
      this.reset();
      const id = row.id || this.ids;
      ////console.log('查看入库单ID', id);
      getInstockbill(id).then(response => {
        this.form = response.data;
        ////console.log('查看时加载的表单数据', this.form);
        this.open = true;
        this.title = "查看入库单";
        this.isDisabled = true;
        this.onSetFormOrgId();
        this.remoteSearchWarehouseMethod(this.form.warehousename); // 加载仓库下拉选项
        this.handleWarehouseSelectChange(this.form.warehouseid); // 设置仓库相关信息
        this.tableData = this.form.details;
        ////console.log('查看时加载的表体数据', this.tableData);
        ////console.log('查看时表格对象then', $table);
        ////$table.reloadData(this.tableData);
      });
    },
    // 日期格式化
    formatDate(date) {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      return `${year}-${month}-${day}`;
    },
    // 格式化物料下拉框
    formatProductnameLabel(row) {
      // console.log('格式化物料下拉框', row);
      const item = this.productnameOptions.find(item => item.id == row.productid);
      // console.log('格式化物料下拉框2', item);
      return item ? item.productname : '';
    },
    productnameIconBtnClick(event) {
      const inputRef = this.$refs.productnameInputRef;
      if (inputRef) {
        this.productnameSearchVal = inputRef.value ? inputRef.value.trim() : '';
      }
      this.showPopup = true;
    },
    productnameInputKeyup(value, event) {
      if (value.key === 'Enter') {
        this.productnameIconBtnClick();
      }
    },
    productnameSelectedEvent(selectedRow) {
      console.log('选中行', selectedRow);
      if (selectedRow) {
        const currentRow = this.currentEditRow;
        currentRow.productid = selectedRow.id;
        currentRow.productcode = selectedRow.productcode;
        currentRow.productname = selectedRow.productname;
        currentRow.model = selectedRow.model;
        currentRow.productdesc = selectedRow.modeldescription;
        currentRow.unitid = selectedRow.unitid;
        currentRow.unitcode = selectedRow.unitcode;
        currentRow.unitname = selectedRow.unitname;
        this.showPopup = false;
      }
    },
  }
};
</script>

以上代码主要关注:

javascript 复制代码
<vxe-column field="productname" title="物料" , width="200" :edit-render="{}">
  <template #edit="{ row }">
     <!-- <vxe-input ref="productnameInputRef" v-model="row.productname" type="search" suffix-icon="vxe-icon-menu"> -->
     <vxe-input ref="productnameInputRef" v-model="row.productname" @keyup="productnameInputKeyup"
       :disabled="isDisabled" :editable="false">
       <template #suffix>
         <vxe-button mode="text" :suffix-tooltip="{ icon: 'vxe-icon-menu' }"
           @click="productnameIconBtnClick"></vxe-button>
       </template>
     </vxe-input>
   </template>
 </vxe-column>
javascript 复制代码
<ProductReference ref="productnameRef" :showPopup.sync="showPopup" :searchValue.sync="productnameSearchVal"
  :productnameSelectRender.sync="productnameSelectRender" @productname-selected-event="productnameSelectedEvent">
</ProductReference>

效果如下:

相关推荐
大猩猩X12 天前
vue 甘特图 vxe-gantt 设置每个进度条分为计划和实际两条,实现上下分布任务条
vue.js·甘特图·vxe-table·vxe-gantt
daols8823 天前
vue2 甘特图 vxe-gantt 一行渲染多个子任务的配置
vue.js·甘特图·vxe-table
阿奇__24 天前
.sync使用
前端·javascript·vue2
暴富的Tdy1 个月前
【前端开发-循序渐进转向全栈开发】
vue2·web·全栈
chenhdowue1 个月前
vue表单vxe-form如何对一个规则同时多字段联动校验,对一个控件校验多个关联字段
vue.js·vxe-table·vxe-ui
大猩猩X1 个月前
vxe-table 表格 vue 单元格渲染上传附件,显示图片列表,适配上传附件样式的用法
vue.js·vxe-table
daols881 个月前
vue2 表格如何使用 vxe-table 带列头复制单元格内容同步到 excel 中
vue.js·excel·vxe-table
daols881 个月前
vue表格 vxe-table 如何实现键盘导航时,按回车健向右移动,并到最后一行时按回车自动新增一行
vue.js·vxe-table
码农研究僧1 个月前
ruoyi+vue2的前端Demo(不分页、前端分页、后端分页)
前端·vue2·ruoyi