-
实现页面新增、编辑、详情等不同数据操作权限在同一dialog上实现,定义一个参数来控制。
-
主从表(带明细表),通过parentId关联主表,后端对明细表的数据二次处理,附上这个主表的主键进行保存修改。修改是先删除,再重新新增(可自己优化)
-
仿百度模糊查询,可模糊检索数据,并将数据插入到明细表中进行编辑操作
-
效果图:
-
Vue源码
<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="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入申请人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申请部门" prop="deptId">
<el-input
v-model="queryParams.deptId"
placeholder="请输入申请部门"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="场所" prop="placeId">
<el-input
v-model="queryParams.placeId"
placeholder="请输入场所"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申请原因" prop="applyReason">
<el-input
v-model="queryParams.applyReason"
placeholder="请输入申请原因"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申请状态" prop="applyStatus">
<el-select v-model="queryParams.applyStatus" placeholder="请选择申请状态" clearable>
<el-option
v-for="dict in dict.type.material_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</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="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['psi:materialApply:add']"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['psi:materialApply: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="['psi:materialApply: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="['psi:materialApply:export']"
>导出
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="materialApplyList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="序号" align="center" prop="index" width="50">
<template slot-scope="scope">
<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="主键" align="center" prop="id" v-if="false"/>
<el-table-column label="申请人" align="center" prop="userName"/>
<el-table-column label="申请部门" align="center" prop="deptName"/>
<el-table-column label="场所" align="center" prop="placeName"/>
<el-table-column label="申请原因" align="center" prop="applyReason"/>
<el-table-column label="备注" align="center" prop="remark"/>
<el-table-column label="申请状态" align="center" prop="applyStatus">
<template slot-scope="scope">
<dict-tag :options="dict.type.material_status" :value="scope.row.applyStatus"/>
</template>
</el-table-column>
<el-table-column label="提交时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160px">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['psi:materialApply:edit']"
v-if="scope.row.applyStatus===0 || scope.row.applyStatus===9"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleDetail(scope.row)"
v-hasPermi="['psi:materialApply:edit']"
>详情
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['psi:materialApply:remove']"
v-if="scope.row.applyStatus===0 || scope.row.applyStatus===9"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改物料申请对话框 -->
<el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="申请人" prop="userId">
<el-input v-model="form.userId" placeholder="请输入申请人" v-show="false"/>
<el-input v-model="form.userName" placeholder="请输入申请人" readonly/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="申请部门" prop="deptId">
<el-input v-model="form.deptId" placeholder="请输入申请部门" v-show="false"/>
<el-input v-model="form.leader" v-show="false"/>
<el-input v-model="form.deptName" placeholder="请输入申请部门" readonly/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="场所" prop="placeId">
<el-select v-model="form.placeId" :disabled="showModel" placeholder="请选择">
<el-option
v-for="item in placeList"
:key="item.id"
:label="item.placeName"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提交日期" prop="createTime">
<el-input v-model="form.createTime" placeholder="请输入提交日期" readonly/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="申请原因" prop="applyReason">
<el-input v-model="form.applyReason" type="textarea" placeholder="请输入内容" :readonly="showModel"/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :readonly="showModel"/>
</el-form-item>
<el-divider content-position="center">明细信息</el-divider>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-select v-model="searchCode"
id="codeSearch"
filterable
remote
reserve-keyword
clearable
placeholder="物料编码检索并新增"
:remote-method="remoteSearchByCode"
:loading="loadingCodeData"
@focus="clearOldOptions"
@change="handleAddApplyDetail"
size="mini"
v-if="!showModel"
>
<el-option
v-for="item in materialCodeOptions"
:key="item.materialId"
:label="item.materialName+'--'+item.materialCode+'--'+item.materialVarious+'--'+item.materialUnit"
:value="item.materialId"
>
</el-option>
</el-select>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
@click="handleDeleteApplyDetail"
v-hasPermi="['psi:materialApplyDetail:remove']"
v-if="!showModel"
>删除
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="applyDetailList" :row-class-name="applyDetailIndex"
@selection-change="handleApplyDetailSelectionChange" row-key="index" ref="detailTable"
>
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="序号" align="center" prop="index" width="50">
</el-table-column>
<el-table-column label="主键" align="center" prop="id" v-if="false"/>
<el-table-column label="物料名称" align="center" prop="materialName">
<template slot-scope="scope">
<el-input v-model="scope.row.materialId" v-show="false"/>
<span>{{scope.row.materialName}}</span>
</template>
</el-table-column>
<el-table-column label="物料编号" align="center" prop="materialSn">
<template slot-scope="scope">
<span>{{scope.row.materialSn}}</span>
</template>
</el-table-column>
<el-table-column label="规格型号" align="center" prop="materialVarious">
<template slot-scope="scope">
<span>{{scope.row.materialVarious}}</span>
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="materialUnit">
<template slot-scope="scope">
<span>{{scope.row.materialUnit}}</span>
</template>
</el-table-column>
<el-table-column label="申请数量" align="center" prop="applyNumber">
<template slot-scope="scope">
<el-input v-model="scope.row.applyNumber" placeholder="申请数量" v-if="!showModel"/>
<span v-else>{{scope.row.applyNumber}}</span>
</template>
</el-table-column>
</el-table>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm" v-if="!showModel">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listMaterialApply,
getMaterialApply,
delMaterialApply,
addMaterialApply,
updateMaterialApply
} from '@/api/psi/materialApply'
import { listMaterialByCode } from '@/api/psi/material'
import { listConfigPlaceByDeptId } from '@/api/psi/configPlace'
import { parseTime } from '@/utils/ruoyi'
export default {
name: 'MaterialApply',
dicts: ['material_status'],
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
searchCode: "",
loadingCodeData: false,
// 总条数
total: 0,
// 物料申请表格数据
materialApplyList: [],
// 场所维护表格数据
placeList: [],
// 物料列表,供新增界面详情下拉选择
materialCodeOptions: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 物料申请明细数据
applyDetailList: [],
// 详情明细表中选中数据
checkedApplyDetail: [],
// 用来判断详情页面是否显示某些编辑控件
showModel: false,
// 获得完整物料编码后,查询materialCodeOptions获取完整数据,用以赋值行
singleFullData: {},
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn: 'id',
isAsc: 'desc',
userId: undefined,
deptId: undefined,
placeId: undefined,
applyReason: undefined,
applyStatus: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {
userId: [
{ required: true, message: '申请人不能为空', trigger: 'blur' }
],
deptId: [
{ required: true, message: '申请部门不能为空', trigger: 'blur' }
],
placeId: [
{ required: true, message: '场所不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getList()
this.getPlaceListByDeptId()
},
methods: {
/** 查询物料申请列表 */
getList() {
this.loading = true
listMaterialApply(this.queryParams).then(response => {
this.materialApplyList = response.rows
this.total = response.total
this.loading = false
})
},
/** 查询场所维护列表 */
getPlaceListByDeptId() {
listConfigPlaceByDeptId().then(response => {
this.placeList = response.data
})
},
remoteSearchByCode(code) {
if (code !== '') {
this.loadingCodeData = true
setTimeout(() => {
this.loadingCodeData = false
listMaterialByCode(code.toLowerCase()).then(res => {
this.materialCodeOptions = res.data
})
}, 200)
} else {
this.materialCodeOptions = []
}
},
// 取消按钮
cancel() {
this.open = false
this.showModel=false
this.reset()
},
// 表单重置
reset() {
this.form = {
id: undefined,
userId: undefined,
userName: undefined,
deptId: undefined,
placeId: undefined,
applyReason: undefined,
remark: undefined,
applyStatus: undefined,
createBy: undefined,
createTime: undefined,
updateBy: undefined,
updateTime: undefined,
delFlag: undefined
}
this.applyDetailList = []
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 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()
this.showModel=false
this.open = true
this.title = '添加物料申请'
this.form.userId = this.$store.state.user.id
this.form.userName = this.$store.state.user.nickName
this.form.deptId = this.$store.state.user.deptId
this.form.deptName = this.$store.state.user.deptName
this.form.createTime = parseTime(new Date())
this.form.leader = this.$store.state.user.leader
if(this.form.leader==="" || this.form.leader===undefined) {
this.$modal.msgError('本部门未设置部门领导,请先联系管理员设置部门领导!')
this.open = false
}
},
/** 修改按钮操作 */
handleUpdate(row) {
this.showModel=false
this.loading = true
this.reset()
const id = row.id || this.ids
getMaterialApply(id).then(response => {
this.loading = false
this.form = response.data
this.applyDetailList=this.form.materialApplyDetailList;
this.open = true
this.title = '修改物料申请'
})
},
/** 详情按钮操作 */
handleDetail(row) {
this.loading = true
this.reset()
this.showModel=true
const id = row.id || this.ids
getMaterialApply(id).then(response => {
this.loading = false
this.form = response.data
this.applyDetailList=this.form.materialApplyDetailList;
this.open = true
this.title = '修改物料申请'
})
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
this.buttonLoading = true
this.form.materialApplyDetailList = this.applyDetailList
if (this.form.id != null) {
updateMaterialApply(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
}).finally(() => {
this.buttonLoading = false
})
} else {
addMaterialApply(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
}).finally(() => {
this.buttonLoading = false
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除选择的数据项?').then(() => {
this.loading = true
return delMaterialApply(ids)
}).then(() => {
this.loading = false
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
}).finally(() => {
this.loading = false
})
},
/** 导出按钮操作 */
handleExport() {
this.download('psi/materialApply/export', {
...this.queryParams
}, `materialApply_${new Date().getTime()}.xlsx`)
},
applyDetailIndex({ row, rowIndex }) {
row.index = rowIndex + 1
},
/** applyDetail添加按钮操作 */
handleAddApplyDetail() {
if(this.searchCode===""){
alert("请先筛选要添加的物料!");
return;
}
this.singleFullData=this.materialCodeOptions.find(item => item.materialId===this.searchCode);
let obj = {}
obj.materialCode = this.singleFullData.materialCode;
obj.materialName = this.singleFullData.materialName;
obj.materialSn = this.singleFullData.materialSn;
obj.materialId = this.singleFullData.materialId;
obj.materialVarious = this.singleFullData.materialVarious;
obj.materialUnit = this.singleFullData.materialUnit;
obj.applyNumber = '';
obj.id = '';
obj.parentId = '';
this.applyDetailList.push(obj);
this.searchCode="";
this.clearOldOptions();
},
/** detail明细删除按钮操作 */
handleDeleteApplyDetail() {
if (this.checkedApplyDetail.length === 0) {
this.$modal.msgError('请先选择要删除的数据')
} else {
const applyDetailList = this.applyDetailList
const checkedApplyDetail = this.checkedApplyDetail
this.applyDetailList = applyDetailList.filter(function(item) {
return checkedApplyDetail.indexOf(item.index) === -1
})
}
},
/** 复选框选中数据 */
handleApplyDetailSelectionChange(selection) {
this.checkedApplyDetail = selection.map(item => item.index)
},
// 清除筛选数据,避免出现直接展示上次的数据
clearOldOptions(){
this.materialCodeOptions=[];
},
}
}
</script>
<style>
#codeSearch {
width: 300px;
}
</style>