Files
education/frontend/src/views/textbook/index.vue
T

1552 lines
62 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container textbook-page">
<el-tabs v-model="activeTab" type="border-card" class="textbook-tabs">
<!-- 教材信息 -->
<el-tab-pane label="教材信息" name="info">
<!-- 查询条件 -->
<el-card shadow="never" class="search-card">
<el-form :model="searchForm" label-width="90px" class="search-form">
<el-row :gutter="0">
<el-col :span="6">
<el-form-item label="教材名称">
<el-input v-model="searchForm.mc" placeholder="请输入教材名称" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="作者">
<el-input v-model="searchForm.zz" placeholder="请输入作者" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="出版社">
<el-input v-model="searchForm.cbs" placeholder="请输入出版社" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="ISBN">
<el-input v-model="searchForm.isbn" placeholder="请输入ISBN" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="教材分类">
<el-select v-model="searchForm.jcfl" placeholder="全部" clearable class="w-full">
<el-option v-for="item in jcflOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="教材类型">
<el-select v-model="searchForm.jclx" placeholder="全部" clearable class="w-full">
<el-option v-for="item in jclxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="停用">
<el-radio-group v-model="searchForm.ty">
<el-radio :label="false"></el-radio>
<el-radio :label="true"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="search-actions">
<el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button>
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
</div>
</el-card>
<!-- 教材信息列表 -->
<div class="list-title">教材信息列表</div>
<div class="list-toolbar">
<div class="left-group">
<el-button type="primary" icon="el-icon-plus" @click="handleNew">新建教材信息</el-button>
<el-button icon="el-icon-download" @click="handleDownloadList">下载教材列表</el-button>
<el-button icon="el-icon-folder-opened" @click="handleDownloadZip">所选文件资料打包ZIP下载</el-button>
</div>
<div class="right-group">
<el-button icon="el-icon-download" @click="handleDownloadTemplate">教材数据文件模板下载</el-button>
<div class="file-input">
<input ref="fileInput" type="file" accept=".xls,.xlsx" style="display: none" @change="handleFileChange" />
<el-button icon="el-icon-folder-opened" @click="handleChooseFile">选择文件</el-button>
<span class="file-name">{{ fileName }}</span>
<el-button type="primary" icon="el-icon-upload2" @click="handleImport">上传数据</el-button>
</div>
</div>
</div>
<el-card shadow="never" class="table-card">
<el-table v-loading="loading" :data="tableData" stripe border highlight-current-row>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="mc" label="教材名称" min-width="150" show-overflow-tooltip />
<el-table-column prop="zz" label="作者" min-width="120" show-overflow-tooltip />
<el-table-column prop="cbs" label="出版社" min-width="130" show-overflow-tooltip />
<el-table-column prop="cbrq" label="出版日期" min-width="100" align="center" :formatter="formatDate" />
<el-table-column prop="isbn" label="ISBN" min-width="140" show-overflow-tooltip />
<el-table-column prop="jclx" label="教材类型" min-width="100" align="center" />
<el-table-column prop="jcfl" label="教材分类" min-width="100" align="center" />
<el-table-column prop="jcbxlx" label="编写类型" min-width="100" align="center" />
<el-table-column prop="jcly" label="教材来源" min-width="130" align="center" />
<el-table-column label="停用" min-width="80" align="center">
<template slot-scope="{ row }">
<el-tag :type="row.ty ? 'danger' : 'success'" size="small">{{ row.ty ? '是' : '否' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center" fixed="right">
<template slot-scope="{ row }">
<el-button type="text" size="small" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" size="small" class="danger-text" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!loading && tableData.length === 0" description="暂无教材数据" :image-size="60" />
<div class="pagination-wrap">
<el-pagination
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
</el-tab-pane>
<!-- 教材库存单 -->
<el-tab-pane label="教材库存单" name="stock">
<el-card shadow="never" class="search-card">
<el-form :model="stockSearchForm" label-width="90px" class="search-form">
<el-row :gutter="0">
<el-col :span="6">
<el-form-item label="编号"><el-input v-model="stockSearchForm.bh" placeholder="请输入编号" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="名称"><el-input v-model="stockSearchForm.mc" placeholder="请输入名称" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="类别"><el-input v-model="stockSearchForm.lb" placeholder="请输入类别" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="字别"><el-input v-model="stockSearchForm.zb" placeholder="请输入字别" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="状态"><el-input v-model="stockSearchForm.zt" placeholder="请输入状态" clearable /></el-form-item>
</el-col>
</el-row>
</el-form>
<div class="search-actions">
<el-button type="primary" icon="el-icon-search" @click="handleStockSearch">查询</el-button>
<el-button icon="el-icon-refresh" @click="handleStockReset">重置</el-button>
</div>
</el-card>
<div class="list-title">教材库存单列表</div>
<div class="list-toolbar">
<div class="left-group">
<el-button type="primary" icon="el-icon-plus" @click="handleStockNew">新增库存单</el-button>
</div>
</div>
<el-card shadow="never" class="table-card">
<el-table v-loading="stockLoading" :data="stockTableData" stripe border highlight-current-row>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="mc" label="名称" min-width="130" show-overflow-tooltip />
<el-table-column prop="qksm" label="情况说明" min-width="130" show-overflow-tooltip />
<el-table-column prop="lb" label="类别" min-width="90" align="center" />
<el-table-column prop="zb" label="字别" min-width="90" align="center" />
<el-table-column prop="cbbmbh" label="承办部门编号" min-width="110" show-overflow-tooltip />
<el-table-column prop="cbrbh" label="承办人编号" min-width="100" align="center" />
<el-table-column prop="bgybh" label="保管员编号" min-width="100" align="center" />
<el-table-column prop="sprbh" label="审批人编号" min-width="100" align="center" />
<el-table-column prop="zt" label="状态" min-width="90" align="center" />
<el-table-column label="创建时间" min-width="150" align="center">
<template slot-scope="{ row }">{{ fmtDateTime(row.cjsj) || '-' }}</template>
</el-table-column>
<el-table-column label="修改时间" min-width="150" align="center">
<template slot-scope="{ row }">{{ fmtDateTime(row.xgsj) || '-' }}</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" fixed="right">
<template slot-scope="{ row }">
<el-button type="text" size="small" icon="el-icon-view" @click="handleStockDetail(row)">详情</el-button>
<el-button type="text" size="small" icon="el-icon-edit" @click="handleStockEdit(row)">编辑</el-button>
<el-button type="text" size="small" class="danger-text" @click="handleStockDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!stockLoading && stockTableData.length === 0" description="暂无库存单数据" :image-size="60" />
<div class="pagination-wrap">
<el-pagination
:current-page="stockPageNum"
:page-size="stockPageSize"
:total="stockTotal"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleStockSizeChange"
@current-change="handleStockCurrentChange"
/>
</div>
</el-card>
</el-tab-pane>
<!-- 教材库存明细项 -->
<el-tab-pane label="教材库存明细项" name="detail">
<el-card shadow="never" class="search-card">
<el-form :model="detailSearchForm" label-width="110px" class="search-form">
<el-row :gutter="0">
<el-col :span="6">
<el-form-item label="编号"><el-input v-model="detailSearchForm.bh" placeholder="请输入编号" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="库存单编号"><el-input v-model="detailSearchForm.jckcdbbh" placeholder="请输入库存单编号" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="教材信息编号"><el-input v-model="detailSearchForm.jcxxbh" placeholder="请输入教材信息编号" clearable /></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="还回完毕">
<el-select v-model="detailSearchForm.hwbwType" class="w-full">
<el-option label="全部" value="" />
<el-option label="未还回" value="0" />
<el-option label="已还回" value="1" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="search-actions">
<el-button type="primary" icon="el-icon-search" @click="handleDetailSearch">查询</el-button>
<el-button icon="el-icon-refresh" @click="handleDetailReset">重置</el-button>
</div>
</el-card>
<div class="list-title">教材库存明细项列表</div>
<div class="list-toolbar">
<div class="left-group">
<el-button type="primary" icon="el-icon-plus" @click="handleDetailNew">新增库存明细项</el-button>
</div>
</div>
<el-card shadow="never" class="table-card">
<el-table v-loading="detailLoading" :data="detailTableData" stripe border highlight-current-row>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="jckcdbbh" label="库存单编号" min-width="100" align="center" />
<el-table-column prop="jcxxbh" label="教材信息编号" min-width="110" align="center" />
<el-table-column prop="sl" label="数量" min-width="80" align="center" />
<el-table-column prop="qzkcmxxbh" label="前置库存明细项编号" min-width="130" show-overflow-tooltip />
<el-table-column label="还回完毕" min-width="90" align="center">
<template slot-scope="{ row }">
<el-tag :type="row.hwbw ? 'success' : 'info'" size="small">{{ row.hwbw ? '是' : '否' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="还回完毕时间" min-width="150" align="center">
<template slot-scope="{ row }">{{ fmtDateTime(row.hwbwsj) || '-' }}</template>
</el-table-column>
<el-table-column prop="bz" label="备注" min-width="120" show-overflow-tooltip />
<el-table-column label="操作" width="150" align="center" fixed="right">
<template slot-scope="{ row }">
<el-button type="text" size="small" icon="el-icon-view" @click="handleDetailView(row)">详情</el-button>
<el-button type="text" size="small" icon="el-icon-edit" @click="handleDetailEdit(row)">编辑</el-button>
<el-button type="text" size="small" class="danger-text" @click="handleDetailDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!detailLoading && detailTableData.length === 0" description="暂无库存明细项数据" :image-size="60" />
<div class="pagination-wrap">
<el-pagination
:current-page="detailPageNum"
:page-size="detailPageSize"
:total="detailTotal"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleDetailSizeChange"
@current-change="handleDetailCurrentChange"
/>
</div>
</el-card>
</el-tab-pane>
</el-tabs>
<!-- 新建教材对话框 -->
<el-dialog
:visible="addDialogVisible"
title="新建教材"
width="780px"
:close-on-click-modal="false"
@update:visible="val => addDialogVisible = val"
>
<el-form ref="addFormRef" :model="addForm" :rules="formRules" label-width="140px" class="add-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材名称" prop="mc"><el-input v-model="addForm.mc" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="编写类型" prop="jcbxlx">
<el-select v-model="addForm.jcbxlx" placeholder="请选择" style="width:100%">
<el-option v-for="item in jcbxlxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="作者"><el-input v-model="addForm.zz" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出版社"><el-input v-model="addForm.cbs" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="ISBN"><el-input v-model="addForm.isbn" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出版日期">
<el-date-picker v-model="addForm.cbrq" type="date" value-format="yyyy-MM-dd" placeholder="选择" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材分类">
<el-select v-model="addForm.jcfl" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jcflOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材类型">
<el-select v-model="addForm.jclx" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jclxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="重点类型">
<el-select v-model="addForm.jczdlx" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jczdlxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材来源">
<el-select v-model="addForm.jcly" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jclyOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材层次">
<el-select v-model="addForm.jccc" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jcccOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出版方式">
<el-select v-model="addForm.cbfs" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in cbfsOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="版次"><el-input v-model="addForm.bc" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开本"><el-input v-model="addForm.kb" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="单价"><el-input-number v-model="addForm.dj" :min="0" :precision="2" style="width:100%" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计量单位">
<el-select v-model="addForm.jldw" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jldwOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="责任教员联系方式"><el-input v-model="addForm.zrjyjlxff" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材代码"><el-input v-model="addForm.jcdm" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材密级">
<el-select v-model="addForm.jcmj" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jcmjOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="编写单位"><el-input v-model="addForm.bxdw" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="备注"><el-input v-model="addForm.bz" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="属性">
<el-checkbox v-model="addForm.xcy">需彩印</el-checkbox>
<el-checkbox v-model="addForm.ty" class="margin-left-10">停用</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer">
<el-button @click="addDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="addSaving" @click="handleAddConfirm">确定</el-button>
</div>
</el-dialog>
<!-- 编辑教材对话框 -->
<el-dialog
:visible="editDialogVisible"
title="编辑教材"
width="780px"
:close-on-click-modal="false"
@update:visible="val => editDialogVisible = val"
>
<div v-loading="editLoading">
<el-form ref="editFormRef" :model="editForm" :rules="formRules" label-width="140px" class="add-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="编号"><el-input v-model="editForm.bh" disabled /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材名称" prop="mc"><el-input v-model="editForm.mc" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="编写类型" prop="jcbxlx">
<el-select v-model="editForm.jcbxlx" placeholder="请选择" style="width:100%">
<el-option v-for="item in jcbxlxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="作者"><el-input v-model="editForm.zz" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="出版社"><el-input v-model="editForm.cbs" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="ISBN"><el-input v-model="editForm.isbn" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="出版日期">
<el-date-picker v-model="editForm.cbrq" type="date" value-format="yyyy-MM-dd" placeholder="选择" style="width:100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材分类">
<el-select v-model="editForm.jcfl" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jcflOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材类型">
<el-select v-model="editForm.jclx" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jclxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重点类型">
<el-select v-model="editForm.jczdlx" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jczdlxOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材来源">
<el-select v-model="editForm.jcly" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jclyOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材层次">
<el-select v-model="editForm.jccc" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jcccOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="出版方式">
<el-select v-model="editForm.cbfs" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in cbfsOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="版次"><el-input v-model="editForm.bc" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="开本"><el-input v-model="editForm.kb" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单价"><el-input-number v-model="editForm.dj" :min="0" :precision="2" style="width:100%" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="计量单位">
<el-select v-model="editForm.jldw" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jldwOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="责任教员联系方式"><el-input v-model="editForm.zrjyjlxff" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材代码"><el-input v-model="editForm.jcdm" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="教材密级">
<el-select v-model="editForm.jcmj" placeholder="请选择" clearable style="width:100%">
<el-option v-for="item in jcmjOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="编写单位"><el-input v-model="editForm.bxdw" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注"><el-input v-model="editForm.bz" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="属性">
<el-checkbox v-model="editForm.xcy">需彩印</el-checkbox>
<el-checkbox v-model="editForm.ty" class="margin-left-10">停用</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div slot="footer">
<el-button @click="editDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="editSaving" @click="handleEditConfirm">保存</el-button>
</div>
</el-dialog>
<!-- 库存单新增/编辑对话框 -->
<el-dialog
:visible="stockFormDialogVisible"
:title="isStockAdd ? '新增库存单' : '编辑库存单'"
width="640px"
:close-on-click-modal="false"
@update:visible="val => stockFormDialogVisible = val"
>
<div v-loading="stockFormLoading">
<el-form ref="stockFormRef" :model="stockForm" :rules="stockFormRules" label-width="120px" class="add-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="编号" v-if="!isStockAdd"><el-input v-model="stockForm.bh" disabled /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称" prop="mc"><el-input v-model="stockForm.mc" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="类别"><el-input v-model="stockForm.lb" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="字别"><el-input v-model="stockForm.zb" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="承办部门编号"><el-input v-model="stockForm.cbbmbh" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="承办人编号"><el-input v-model="stockForm.cbrbh" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="保管员编号"><el-input v-model="stockForm.bgybh" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="审批人编号"><el-input v-model="stockForm.sprbh" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="状态"><el-input v-model="stockForm.zt" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="情况说明"><el-input v-model="stockForm.qksm" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="备注"><el-input v-model="stockForm.bz" type="textarea" :rows="2" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="JSONZD"><el-input v-model="stockForm.jsonzd" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div slot="footer">
<el-button @click="stockFormDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="stockSaving" @click="handleStockFormConfirm">确定</el-button>
</div>
</el-dialog>
<!-- 库存单详情对话框 -->
<el-dialog
:visible="stockDetailDialogVisible"
title="库存单详情"
width="640px"
:close-on-click-modal="false"
@update:visible="val => stockDetailDialogVisible = val"
>
<el-descriptions :column="2" border size="medium">
<el-descriptions-item label="编号">{{ stockDetailData.bh || '-' }}</el-descriptions-item>
<el-descriptions-item label="名称">{{ stockDetailData.mc || '-' }}</el-descriptions-item>
<el-descriptions-item label="类别">{{ stockDetailData.lb || '-' }}</el-descriptions-item>
<el-descriptions-item label="字别">{{ stockDetailData.zb || '-' }}</el-descriptions-item>
<el-descriptions-item label="情况说明" :span="2">{{ stockDetailData.qksm || '-' }}</el-descriptions-item>
<el-descriptions-item label="承办部门编号">{{ stockDetailData.cbbmbh || '-' }}</el-descriptions-item>
<el-descriptions-item label="承办人编号">{{ stockDetailData.cbrbh || '-' }}</el-descriptions-item>
<el-descriptions-item label="保管员编号">{{ stockDetailData.bgybh || '-' }}</el-descriptions-item>
<el-descriptions-item label="审批人编号">{{ stockDetailData.sprbh || '-' }}</el-descriptions-item>
<el-descriptions-item label="状态">{{ stockDetailData.zt || '-' }}</el-descriptions-item>
<el-descriptions-item label="备注">{{ stockDetailData.bz || '-' }}</el-descriptions-item>
<el-descriptions-item label="JSONZD">{{ stockDetailData.jsonzd || '-' }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ fmtDateTime(stockDetailData.cjsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="修改时间">{{ fmtDateTime(stockDetailData.xgsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="提交时间">{{ fmtDateTime(stockDetailData.tjsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="审批时间">{{ fmtDateTime(stockDetailData.spsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="执行时间">{{ fmtDateTime(stockDetailData.zxsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ fmtDateTime(stockDetailData.jssj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="退回意见">{{ stockDetailData.thyj || '-' }}</el-descriptions-item>
<el-descriptions-item label="退回时间">{{ fmtDateTime(stockDetailData.thsj) || '-' }}</el-descriptions-item>
</el-descriptions>
<div slot="footer">
<el-button @click="stockDetailDialogVisible = false">关闭</el-button>
</div>
</el-dialog>
<!-- 库存明细项新增/编辑对话框 -->
<el-dialog
:visible="detailFormDialogVisible"
:title="isDetailAdd ? '新增库存明细项' : '编辑库存明细项'"
width="640px"
:close-on-click-modal="false"
@update:visible="val => detailFormDialogVisible = val"
>
<div v-loading="detailFormLoading">
<el-form ref="detailFormRef" :model="detailForm" :rules="detailFormRules" label-width="140px" class="add-form">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="编号" v-if="!isDetailAdd"><el-input v-model="detailForm.bh" disabled /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="库存单编号" prop="jckcdbbh"><el-input v-model="detailForm.jckcdbbh" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="教材信息编号" prop="jcxxbh"><el-input v-model="detailForm.jcxxbh" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数量" prop="sl"><el-input-number v-model="detailForm.sl" :min="0" :precision="0" style="width:100%" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="前置库存明细项编号"><el-input v-model="detailForm.qzkcmxxbh" placeholder="请输入" /></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="还回完毕">
<el-switch v-model="detailForm.hwbw" active-text="是" inactive-text="否" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="还回完毕时间">
<el-date-picker v-model="detailForm.hwbwsj" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="备注"><el-input v-model="detailForm.bz" type="textarea" :rows="2" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="JSONZD"><el-input v-model="detailForm.jsonzd" placeholder="请输入" /></el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div slot="footer">
<el-button @click="detailFormDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="detailSaving" @click="handleDetailFormConfirm">确定</el-button>
</div>
</el-dialog>
<!-- 库存明细项详情对话框 -->
<el-dialog
:visible="detailViewDialogVisible"
title="库存明细项详情"
width="640px"
:close-on-click-modal="false"
@update:visible="val => detailViewDialogVisible = val"
>
<el-descriptions :column="2" border size="medium">
<el-descriptions-item label="编号">{{ detailViewData.bh || '-' }}</el-descriptions-item>
<el-descriptions-item label="库存单编号">{{ detailViewData.jckcdbbh || '-' }}</el-descriptions-item>
<el-descriptions-item label="教材信息编号">{{ detailViewData.jcxxbh || '-' }}</el-descriptions-item>
<el-descriptions-item label="数量">{{ fmtVal(detailViewData.sl) }}</el-descriptions-item>
<el-descriptions-item label="前置库存明细项编号" :span="2">{{ detailViewData.qzkcmxxbh || '-' }}</el-descriptions-item>
<el-descriptions-item label="还回完毕">
<el-tag :type="detailViewData.hwbw ? 'success' : 'info'" size="small">{{ detailViewData.hwbw ? '是' : '否' }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="还回完毕时间">{{ fmtDateTime(detailViewData.hwbwsj) || '-' }}</el-descriptions-item>
<el-descriptions-item label="备注">{{ detailViewData.bz || '-' }}</el-descriptions-item>
<el-descriptions-item label="JSONZD">{{ detailViewData.jsonzd || '-' }}</el-descriptions-item>
<el-descriptions-item label="快照_事务后库存数量">{{ fmtVal(detailViewData.kzswHkcsl) }}</el-descriptions-item>
<el-descriptions-item label="快照_事务后借出数量">{{ fmtVal(detailViewData.kzswHjcsl) }}</el-descriptions-item>
<el-descriptions-item label="快照_事务前库存数量">{{ fmtVal(detailViewData.kzswQkcsl) }}</el-descriptions-item>
<el-descriptions-item label="快照_事务前借出数量">{{ fmtVal(detailViewData.kzswQjcsl) }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ fmtDateTime(detailViewData.createTime) || '-' }}</el-descriptions-item>
<el-descriptions-item label="更新时间">{{ fmtDateTime(detailViewData.updateTime) || '-' }}</el-descriptions-item>
</el-descriptions>
<div slot="footer">
<el-button @click="detailViewDialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { saveAs } from 'file-saver'
import {
listTeachingMaterial,
getTeachingMaterialById,
addTeachingMaterial,
updateTeachingMaterial,
deleteTeachingMaterial,
downloadTeachingMaterialTemplate,
importTeachingMaterial
} from '@/api/textbook/teachingMaterial'
import {
listTeachingStock,
getTeachingStock,
addTeachingStock,
updateTeachingStock,
deleteTeachingStock,
listTeachingStockDetail,
getTeachingStockDetail,
addTeachingStockDetail,
updateTeachingStockDetail,
deleteTeachingStockDetail
} from '@/api/textbook/teachingStock'
export default {
name: 'TextbookIndex',
data() {
return {
activeTab: 'info',
// ==================== 查询表单(仅后端 Mapper 支持的字段) ====================
searchForm: {
mc: '', zz: '', cbs: '', isbn: '',
jcfl: '', jclx: '', ty: false
},
// ==================== 下拉选项 ====================
jcflOptions: ['基本教材', '辅助教材', '参考资料'],
jclxOptions: ['国家规划', '军队规划', '院校自编'],
jcbxlxOptions: ['自编', '选用'],
jczdlxOptions: ['一般教材', '重点教材', '规划教材'],
jclyOptions: ['教研保障中心外购', '自购', '上级配发'],
jcccOptions: ['无', '本科', '研究生'],
cbfsOptions: ['公开出版', '内部出版'],
jcmjOptions: ['公开', '内部', '秘密'],
jldwOptions: ['本', '册'],
// ==================== 表格数据 ====================
loading: false,
tableData: [],
pageNum: 1,
pageSize: 20,
total: 0,
// ==================== 新建教材 ====================
addDialogVisible: false,
addSaving: false,
addForm: this.createEmptyForm(),
// ==================== 编辑教材 ====================
editDialogVisible: false,
editLoading: false,
editSaving: false,
editForm: this.createEmptyForm(),
// ==================== 表单校验 ====================
formRules: {
mc: [{ required: true, message: '请输入教材名称', trigger: 'blur' }],
jcbxlx: [{ required: true, message: '请选择编写类型', trigger: 'change' }]
},
// ==================== 导入 ====================
selectedFile: null,
// ==================== 教材库存单(JCKCD ====================
stockSearchForm: { bh: '', mc: '', lb: '', zb: '', zt: '' },
stockLoading: false,
stockTableData: [],
stockPageNum: 1,
stockPageSize: 20,
stockTotal: 0,
stockFormDialogVisible: false,
stockFormLoading: false,
stockSaving: false,
isStockAdd: true,
stockForm: this.createEmptyStockForm(),
stockFormRules: {
mc: [{ required: true, message: '请输入名称', trigger: 'blur' }]
},
stockDetailDialogVisible: false,
stockDetailData: {},
// ==================== 教材库存明细项(JCKCMXX ====================
detailSearchForm: { bh: '', jckcdbbh: '', jcxxbh: '', hwbwType: '' },
detailLoading: false,
detailTableData: [],
detailPageNum: 1,
detailPageSize: 20,
detailTotal: 0,
detailFormDialogVisible: false,
detailFormLoading: false,
detailSaving: false,
isDetailAdd: true,
detailForm: this.createEmptyDetailForm(),
detailFormRules: {
jckcdbbh: [{ required: true, message: '请输入库存单编号', trigger: 'blur' }],
jcxxbh: [{ required: true, message: '请输入教材信息编号', trigger: 'blur' }],
sl: [{ required: true, message: '请输入数量', trigger: 'change' }]
},
detailViewDialogVisible: false,
detailViewData: {}
}
},
computed: {
fileName() {
return (this.selectedFile && this.selectedFile.name) || '未选择任何文件'
}
},
mounted() {
this.fetchList()
},
methods: {
/** 表格日期格式化 */
formatDate(row, column, cellValue) {
return cellValue ? String(cellValue).slice(0, 10) : ''
},
/** 统一格式化后端 LocalDateTime(去除 T、截断到秒) */
fmtDateTime(val) {
if (val === null || val === undefined || val === '') return ''
return String(val).replace('T', ' ').slice(0, 19)
},
/** 空值显示为 '-'Vue 2 模板表达式不支持 ?? 运算符) */
fmtVal(val) {
return (val === null || val === undefined || val === '') ? '-' : val
},
/** 创建空白教材表单 */
createEmptyForm() {
return {
mc: '', zz: '', cbs: '', isbn: '', cbrq: '', jcfl: '', jclx: '',
jcbxlx: '', jczdlx: '', jcly: '', jccc: '', bc: '', kb: '', dj: null,
jldw: '本', zrjyjlxff: '', jcdm: '', cbfs: '', jcmj: '', bxdw: '',
bz: '', xcy: false, ty: false
}
},
/** 创建空白库存单表单 */
createEmptyStockForm() {
return {
mc: '', qksm: '', lb: '', zb: '', cbbmbh: '', cbrbh: '',
bgybh: '', sprbh: '', zt: '', bz: '', jsonzd: ''
}
},
/** 创建空白库存明细项表单 */
createEmptyDetailForm() {
return {
jckcdbbh: '', jcxxbh: '', sl: null, qzkcmxxbh: '',
hwbw: false, hwbwsj: '', bz: '', jsonzd: ''
}
},
/** 移除空值 */
cleanPayload(obj) {
const payload = {}
Object.keys(obj).forEach(key => {
const value = obj[key]
if (value !== '' && value !== null && value !== undefined) {
payload[key] = value
}
})
return payload
},
// ==================== 列表加载 ====================
buildQuery() {
const params = {}
;['mc', 'zz', 'cbs', 'isbn', 'jcfl', 'jclx'].forEach(key => {
const value = this.searchForm[key]
if (value !== '' && value !== null && value !== undefined) {
params[key] = String(value).trim()
}
})
params.ty = this.searchForm.ty
return params
},
fetchList() {
this.loading = true
const params = {
pageNum: this.pageNum,
pageSize: this.pageSize,
...this.buildQuery()
}
listTeachingMaterial(params).then(response => {
const data = response.data || {}
this.tableData = data.records || []
this.total = data.total || 0
this.loading = false
}).catch(() => {
this.tableData = []
this.total = 0
this.loading = false
})
},
// ==================== 查询 / 重置 ====================
handleSearch() {
this.pageNum = 1
this.fetchList()
},
handleReset() {
this.searchForm = {
mc: '', zz: '', cbs: '', isbn: '',
jcfl: '', jclx: '', ty: false
}
this.pageNum = 1
this.fetchList()
},
handleSizeChange(size) {
this.pageSize = size
this.pageNum = 1
this.fetchList()
},
handleCurrentChange(page) {
this.pageNum = page
this.fetchList()
},
// ==================== 无后端接口的操作 ====================
handleDownloadList() {
this.$message.info('后端暂未提供该接口')
},
handleDownloadZip() {
this.$message.info('后端暂未提供该接口')
},
// ==================== 新建教材 ====================
handleNew() {
this.addForm = this.createEmptyForm()
this.$nextTick(() => {
this.$refs.addFormRef && this.$refs.addFormRef.clearValidate()
})
this.addDialogVisible = true
},
handleAddConfirm() {
this.$refs.addFormRef.validate(valid => {
if (!valid) return
this.addSaving = true
addTeachingMaterial(this.buildPayload(this.addForm)).then(() => {
this.$message.success('新增成功')
this.addDialogVisible = false
this.fetchList()
}).catch(() => {
}).finally(() => {
this.addSaving = false
})
})
},
// ==================== 编辑教材 ====================
handleEdit(row) {
this.editDialogVisible = true
this.editLoading = true
getTeachingMaterialById(row.id).then(response => {
const data = response.data || {}
const form = this.createEmptyForm()
Object.keys(form).forEach(key => {
if (data[key] !== undefined && data[key] !== null) form[key] = data[key]
})
// 日期字段截断适配 date 控件
if (form.cbrq) form.cbrq = String(form.cbrq).slice(0, 10)
form.id = data.id
form.bh = data.bh
this.editForm = form
this.editLoading = false
}).catch(() => {
this.editDialogVisible = false
this.editLoading = false
})
},
handleEditConfirm() {
this.$refs.editFormRef.validate(valid => {
if (!valid) return
const payload = this.buildPayload(this.editForm)
if (!this.editForm.id) {
this.$message.warning('缺少记录ID,无法保存')
return
}
payload.id = this.editForm.id
payload.bh = this.editForm.bh
this.editSaving = true
updateTeachingMaterial(payload).then(() => {
this.$message.success('保存成功')
this.editDialogVisible = false
this.fetchList()
}).catch(() => {
}).finally(() => {
this.editSaving = false
})
})
},
/** 组装新增/编辑请求体(JCXX 实体,仅传非空字段) */
buildPayload(form) {
const payload = this.cleanPayload({
mc: form.mc,
zz: form.zz,
cbs: form.cbs,
isbn: form.isbn,
jcfl: form.jcfl,
jclx: form.jclx,
jcbxlx: form.jcbxlx,
jczdlx: form.jczdlx,
jcly: form.jcly,
jccc: form.jccc,
bc: form.bc,
kb: form.kb,
jldw: form.jldw,
zrjyjlxff: form.zrjyjlxff,
jcdm: form.jcdm,
cbfs: form.cbfs,
jcmj: form.jcmj,
bxdw: form.bxdw,
bz: form.bz,
xcy: !!form.xcy,
ty: !!form.ty
})
// 日期字段转 ISO(后端 cbrq 为 LocalDateTime
if (form.cbrq) payload.cbrq = form.cbrq + 'T00:00:00'
// 数值字段
if (form.dj !== '' && form.dj !== null && form.dj !== undefined) {
payload.dj = Number(form.dj)
}
return payload
},
// ==================== 删除 ====================
handleDelete(row) {
if (!row.id) {
this.$message.warning('当前行缺少ID')
return
}
this.$confirm(`确定要删除教材「${row.mc || row.bh}」吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteTeachingMaterial(row.id).then(() => {
this.$message.success('删除成功')
this.fetchList()
}).catch(() => {})
}).catch(() => {})
},
// ==================== 模板下载 / 导入 ====================
handleDownloadTemplate() {
downloadTeachingMaterialTemplate().then(blob => {
saveAs(blob, '教材管理导入模板.xls')
this.$message.success('模板下载成功')
}).catch(() => {})
},
handleChooseFile() {
this.$refs.fileInput && this.$refs.fileInput.click()
},
handleFileChange(e) {
const input = e.target
if (input.files && input.files.length > 0) {
this.selectedFile = input.files[0]
}
},
handleImport() {
if (!this.selectedFile) {
this.$message.warning('请先选择文件')
return
}
importTeachingMaterial(this.selectedFile).then(response => {
const count = (response && response.data) || 0
this.$message.success(`导入成功,共导入 ${count}`)
this.selectedFile = null
if (this.$refs.fileInput) this.$refs.fileInput.value = ''
this.fetchList()
}).catch(() => {})
},
// ==================== 教材库存单 ====================
buildStockQuery() {
const params = {}
;['bh', 'mc', 'lb', 'zb', 'zt'].forEach(key => {
const value = this.stockSearchForm[key]
if (value !== '' && value !== null && value !== undefined) {
params[key] = String(value).trim()
}
})
return params
},
fetchStockList() {
this.stockLoading = true
const params = {
pageNum: this.stockPageNum,
pageSize: this.stockPageSize,
...this.buildStockQuery()
}
listTeachingStock(params).then(response => {
const data = response.data || {}
this.stockTableData = data.records || []
this.stockTotal = data.total || 0
this.stockLoading = false
}).catch(() => {
this.stockTableData = []
this.stockTotal = 0
this.stockLoading = false
})
},
handleStockSearch() {
this.stockPageNum = 1
this.fetchStockList()
},
handleStockReset() {
this.stockSearchForm = { bh: '', mc: '', lb: '', zb: '', zt: '' }
this.stockPageNum = 1
this.fetchStockList()
},
handleStockSizeChange(size) {
this.stockPageSize = size
this.stockPageNum = 1
this.fetchStockList()
},
handleStockCurrentChange(page) {
this.stockPageNum = page
this.fetchStockList()
},
handleStockNew() {
this.isStockAdd = true
this.stockForm = this.createEmptyStockForm()
this.$nextTick(() => {
this.$refs.stockFormRef && this.$refs.stockFormRef.clearValidate()
})
this.stockFormDialogVisible = true
},
handleStockEdit(row) {
this.isStockAdd = false
this.stockFormDialogVisible = true
this.stockFormLoading = true
getTeachingStock(row.id).then(response => {
const data = response.data || {}
const form = this.createEmptyStockForm()
Object.keys(form).forEach(key => {
if (data[key] !== undefined && data[key] !== null) form[key] = data[key]
})
form.id = data.id
form.bh = data.bh
this.stockForm = form
this.stockFormLoading = false
}).catch(() => {
this.stockFormDialogVisible = false
this.stockFormLoading = false
})
},
buildStockPayload() {
const f = this.stockForm
const payload = this.cleanPayload({
mc: f.mc,
qksm: f.qksm,
lb: f.lb,
zb: f.zb,
cbbmbh: f.cbbmbh,
cbrbh: f.cbrbh,
bgybh: f.bgybh,
sprbh: f.sprbh,
zt: f.zt,
bz: f.bz,
jsonzd: f.jsonzd
})
return payload
},
handleStockFormConfirm() {
this.$refs.stockFormRef.validate(valid => {
if (!valid) return
const payload = this.buildStockPayload()
if (!this.isStockAdd) {
if (!this.stockForm.id) {
this.$message.warning('缺少记录ID,无法保存')
return
}
payload.id = this.stockForm.id
payload.bh = this.stockForm.bh
}
this.stockSaving = true
const request = this.isStockAdd ? addTeachingStock(payload) : updateTeachingStock(payload)
request.then(() => {
this.$message.success(this.isStockAdd ? '新增成功' : '修改成功')
this.stockFormDialogVisible = false
this.fetchStockList()
}).catch(() => {
}).finally(() => {
this.stockSaving = false
})
})
},
handleStockDetail(row) {
this.stockDetailData = row
this.stockDetailDialogVisible = true
},
handleStockDelete(row) {
if (!row.id) {
this.$message.warning('当前行缺少ID')
return
}
this.$confirm(`确定要删除库存单「${row.mc || row.bh}」吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteTeachingStock(row.id).then(() => {
this.$message.success('删除成功')
this.fetchStockList()
}).catch(() => {})
}).catch(() => {})
},
// ==================== 教材库存明细项 ====================
buildDetailQuery() {
const params = {}
;['bh', 'jckcdbbh', 'jcxxbh'].forEach(key => {
const value = this.detailSearchForm[key]
if (value !== '' && value !== null && value !== undefined) {
params[key] = String(value).trim()
}
})
if (this.detailSearchForm.hwbwType === '0') params.hwbw = false
else if (this.detailSearchForm.hwbwType === '1') params.hwbw = true
return params
},
fetchDetailList() {
this.detailLoading = true
const params = {
pageNum: this.detailPageNum,
pageSize: this.detailPageSize,
...this.buildDetailQuery()
}
listTeachingStockDetail(params).then(response => {
const data = response.data || {}
this.detailTableData = data.records || []
this.detailTotal = data.total || 0
this.detailLoading = false
}).catch(() => {
this.detailTableData = []
this.detailTotal = 0
this.detailLoading = false
})
},
handleDetailSearch() {
this.detailPageNum = 1
this.fetchDetailList()
},
handleDetailReset() {
this.detailSearchForm = { bh: '', jckcdbbh: '', jcxxbh: '', hwbwType: '' }
this.detailPageNum = 1
this.fetchDetailList()
},
handleDetailSizeChange(size) {
this.detailPageSize = size
this.detailPageNum = 1
this.fetchDetailList()
},
handleDetailCurrentChange(page) {
this.detailPageNum = page
this.fetchDetailList()
},
handleDetailNew() {
this.isDetailAdd = true
this.detailForm = this.createEmptyDetailForm()
this.$nextTick(() => {
this.$refs.detailFormRef && this.$refs.detailFormRef.clearValidate()
})
this.detailFormDialogVisible = true
},
handleDetailEdit(row) {
this.isDetailAdd = false
this.detailFormDialogVisible = true
this.detailFormLoading = true
getTeachingStockDetail(row.id).then(response => {
const data = response.data || {}
const form = this.createEmptyDetailForm()
Object.keys(form).forEach(key => {
if (data[key] !== undefined && data[key] !== null) form[key] = data[key]
})
if (form.hwbwsj) form.hwbwsj = String(form.hwbwsj).replace('T', ' ').slice(0, 19)
form.id = data.id
form.bh = data.bh
this.detailForm = form
this.detailFormLoading = false
}).catch(() => {
this.detailFormDialogVisible = false
this.detailFormLoading = false
})
},
buildDetailPayload() {
const f = this.detailForm
const payload = this.cleanPayload({
jckcdbbh: f.jckcdbbh,
jcxxbh: f.jcxxbh,
qzkcmxxbh: f.qzkcmxxbh,
hwbw: !!f.hwbw,
bz: f.bz,
jsonzd: f.jsonzd
})
if (f.sl !== '' && f.sl !== null && f.sl !== undefined) {
payload.sl = Number(f.sl)
}
// 还回完毕时间为 LocalDateTime,转 ISO
if (f.hwbwsj) payload.hwbwsj = f.hwbwsj.replace(' ', 'T')
return payload
},
handleDetailFormConfirm() {
this.$refs.detailFormRef.validate(valid => {
if (!valid) return
const payload = this.buildDetailPayload()
if (!this.isDetailAdd) {
if (!this.detailForm.id) {
this.$message.warning('缺少记录ID,无法保存')
return
}
payload.id = this.detailForm.id
payload.bh = this.detailForm.bh
}
this.detailSaving = true
const request = this.isDetailAdd ? addTeachingStockDetail(payload) : updateTeachingStockDetail(payload)
request.then(() => {
this.$message.success(this.isDetailAdd ? '新增成功' : '修改成功')
this.detailFormDialogVisible = false
this.fetchDetailList()
}).catch(() => {
}).finally(() => {
this.detailSaving = false
})
})
},
handleDetailView(row) {
this.detailViewData = row
this.detailViewDialogVisible = true
},
handleDetailDelete(row) {
if (!row.id) {
this.$message.warning('当前行缺少ID')
return
}
this.$confirm(`确定要删除库存明细项「${row.bh}」吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteTeachingStockDetail(row.id).then(() => {
this.$message.success('删除成功')
this.fetchDetailList()
}).catch(() => {})
}).catch(() => {})
}
}
}
</script>
<style scoped lang="scss">
.app-container {
padding: 20px;
}
.textbook-tabs {
.search-card {
margin-bottom: 16px;
.search-form {
.w-full {
width: 100%;
}
.el-form-item {
margin-bottom: 0;
padding: 10px 12px;
}
}
.search-actions {
display: flex;
justify-content: flex-end;
padding: 12px;
border-top: 1px solid #ebeef5;
}
}
.list-title {
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 12px;
}
.list-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 16px;
.left-group,
.right-group {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.file-input {
display: flex;
align-items: center;
gap: 8px;
.file-name {
font-size: 14px;
color: #606266;
min-width: 120px;
}
}
}
.table-card {
margin-bottom: 16px;
::v-deep(.el-table) {
width: 100%;
}
.pagination-wrap {
display: flex;
justify-content: flex-end;
margin-top: 16px;
}
}
.margin-left-10 {
margin-left: 10px;
}
// 表格操作按钮文字颜色
.danger-text {
color: #f56c6c;
padding: 0;
}
}
</style>