活动介绍

vue中 <el-form-item prop="date_de"> <el-date-picker v-model="table.search" type="daterange" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /> </el-form-item>如何使用el-data-picker 传两个变量的值

时间: 2024-04-11 11:33:21 浏览: 387
对于el-form-item中的el-date-picker组件,可以通过v-model指令来实现传递两个变量的值。你可以将v-model绑定到一个对象上,并在该对象中定义两个属性来存储选择的日期范围。下面是一个示例: ```html <el-form-item prop="date_de"> <el-date-picker v-model="table.search.dateRange" type="daterange" value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /> </el-form-item> ``` 在Vue的data属性中,定义一个table对象,并在该对象中定义一个search属性,用于存储日期范围: ```javascript data() { return { table: { search: { dateRange: [] // 存储日期范围的数组 } } }; }, ``` 这样,当用户选择日期范围时,`table.search.dateRange`将会被更新为选择的开始日期和结束日期的数组。你可以通过访问`this.table.search.dateRange[0]`获取开始日期,通过访问`this.table.search.dateRange[1]`获取结束日期。 注意:在el-date-picker组件中,`value-format`属性用于指定日期值的格式,请确保它与你的需求相匹配。 希望这能帮到你!如有任何问题,请随时提问。
阅读全文

相关推荐

<template> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="150px"> <el-form-item label="采集数据提交的时间"> <el-date-picker v-model="daterangeTime" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" ></el-date-picker> </el-form-item> <el-form-item label="采集数据提交的地点" prop="position"> <el-input v-model="queryParams.position" placeholder="请输入采集数据提交的地点" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <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="sgdw"> <el-input v-model="queryParams.sgdw" placeholder="请输入施工单位" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="监理单位" prop="jldw"> <el-input v-model="queryParams.jldw" placeholder="请输入监理单位" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="合同号" prop="hth"> <el-input v-model="queryParams.hth" placeholder="请输入合同号" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="编号" prop="bh"> <el-input v-model="queryParams.bh" placeholder="请输入编号" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="工程名称" prop="gcmc"> <el-input v-model="queryParams.gcmc" placeholder="请输入工程名称" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="施工时间"> <el-date-picker v-model="daterangeSgsj" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" ></el-date-picker> </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="['gjstjgjlb:sj32: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="['gjstjgjlb:sj32: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="['gjstjgjlb:sj32: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="['gjstjgjlb:sj32:export']" >导出</el-button> </el-col> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="sj32List" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-table-column label="ID" align="center" prop="id" /> <el-table-column label="采集数据提交的时间" align="center" prop="time" width="180"> <template slot-scope="scope"> {{ parseTime(scope.row.time, '{y}-{m}-{d}') }} </template> </el-table-column> <el-table-column label="采集数据提交的地点" align="center" prop="position" /> <el-table-column label="采集人员编号" align="center" prop="userid" /> <el-table-column label="施工单位" align="center" prop="sgdw" /> <el-table-column label="监理单位" align="center" prop="jldw" /> <el-table-column label="合同号" align="center" prop="hth" /> <el-table-column label="编号" align="center" prop="bh" /> <el-table-column label="工程名称" align="center" prop="gcmc" /> <el-table-column label="施工时间" align="center" prop="sgsj" width="180"> <template slot-scope="scope"> {{ parseTime(scope.row.sgsj, '{y}-{m}-{d}') }} </template> </el-table-column> <el-table-column label="工程部位-桩号" align="center" prop="gcbwZh" /> <el-table-column label="工程部位-墩台号" align="center" prop="gcbwDth" /> <el-table-column label="工程部位-孔号" align="center" prop="gcbwKh" /> <el-table-column label="钢筋规格" align="center" prop="gjgg" /> <el-table-column label="抽检数量" align="center" prop="cjsl" /> <el-table-column label="代表数量" align="center" prop="dbsl" /> <el-table-column label="生产日期" align="center" prop="scrq" width="180"> <template slot-scope="scope"> {{ parseTime(scope.row.scrq, '{y}-{m}-{d}') }} </template> </el-table-column> <el-table-column label="施工员" align="center" prop="sgy" /> <el-table-column label="专业工程师" align="center" prop="zygcs" /> <el-table-column label="检验结论" align="center" prop="jyjl" /> <el-table-column label="不合格处理" align="center" prop="bhgcl" /> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['gjstjgjlb:sj32:edit']" >修改</el-button> <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['gjstjgjlb:sj32:remove']" >删除</el-button> <el-button size="mini" type="text" icon="el-icon-edit" @click="handleMyExport(scope.row)" >导出</el-button> </template> </el-table-column> </el-table> 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body> <template slot="title"> 钢筋丝头加工记录表 </template> <el-form ref="form" :model="form" :rules="rules" label-width="0"> 施工单位: <el-input v-model="form.sgdw" placeholder="请输入施工单位"></el-input> 合同号: <el-input v-model="form.hth" placeholder="请输入合同号"></el-input> 监理单位: <el-input v-model="form.jldw" placeholder="请输入监理单位"></el-input> 编号: <el-input v-model="form.bh" placeholder="请输入编号"></el-input> 工程名称: <el-input v-model="form.gcmc" placeholder="请输入工程名称"></el-input> 施工时间: <el-date-picker v-model="form.sgsj" type="date" placeholder="选择施工时间" style="width: 100%;"></el-date-picker> 工程部位(桩号、墩台号、孔号): <el-input v-model="form.gcbwZh" placeholder="桩号" style="width: 120px;"></el-input> - <el-input v-model="form.gcbwDth" placeholder="墩台号" style="width: 120px;"></el-input> - <el-input v-model="form.gcbwKh" placeholder="孔号" style="width: 120px;"></el-input> 钢筋规格: <el-input v-model="form.gjgg" placeholder="请输入钢筋规格"></el-input> 抽检数量(根): <el-input-number v-model="form.cjsl" :placeholder="form.cjsl ? '' : '数量'" style="width: 100%;"></el-input-number> 生产日期: <el-date-picker v-model="form.scrq" type="date" placeholder="选择生产日期" style="width: 100%;"></el-date-picker> 代表数量(根): <el-input-number v-model="form.dbsl" :placeholder="form.dbsl ? '' : '数量'" style="width: 100%;"></el-input-number> 施工实际情况 <el-table :data="sgsjqkList" :row-class-name="rowSgsjqkIndex" @selection-change="handleSgsjqkSelectionChange" ref="sgsjqk" style="width: 100%"> <el-table-column type="selection" width="50" align="center" /> <el-table-column label="序号" align="center" prop="index" width="90"/> <el-table-column prop="gjzj" label="钢筋直径" width="130" align="center"> <template slot-scope="scope"> <el-input v-model="scope.row.gjzj" size="small" placeholder="直径(mm)"></el-input> </template> </el-table-column> <el-table-column label="丝头螺纹检验" align="center"> <el-table-column prop="htg" label="环通规" width="110" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.htg" size="small" placeholder="√/×" style="width: 60px;"> <el-option label="√" value="√"></el-option> <el-option label="×" value="×"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="hzg" label="环止规" width="110" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.hzg" size="small" placeholder="√/×" style="width: 60px;"> <el-option label="√" value="√"></el-option> <el-option label="×" value="×"></el-option> </el-select> </template> </el-table-column> </el-table-column> <el-table-column label="丝头外观检验" align="center"> <el-table-column prop="yxlwcd" label="有效螺纹长度" width="120" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.yxlwcd" size="small" placeholder="√/×" style="width: 60px;"> <el-option label="√" value="√"></el-option> <el-option label="×" value="×"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="bwzlw" label="不完整螺纹" width="120" align="center"> <template slot-scope="scope"> <el-select v-model="scope.row.bwzlw" size="small" placeholder="√/×" style="width: 60px;"> <el-option label="√" value="√"></el-option> <el-option label="×" value="×"></el-option> </el-select> </template> </el-table-column> <el-table-column prop="wgjc" label="外观检查" width="150" align="center"> <template slot-scope="scope"> <el-input v-model="scope.row.wgjc" size="small" placeholder="外观情况"></el-input> </template> </el-table-column> </el-table-column> </el-table> 检验结论: <el-input v-model="form.jyjl" placeholder="检验结论"></el-input> 不合格处理: <el-input v-model="form.bhgcl" placeholder="不合格处理"></el-input> <el-col :span="1.5"> <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddSgsjqk">添加</el-button> </el-col> <el-col :span="1.5"> <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDeleteSgsjqk">删除</el-button> </el-col> 施工员: <el-input v-model="form.sgy" placeholder="姓名" style="width: 120px; margin-right: 40px;"></el-input> 专业工程师: <el-input v-model="form.zygcs" placeholder="姓名" style="width: 120px;"></el-input> </el-form> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </el-dialog> </template> <script> import { listSj32, getSj32, delSj32, addSj32, updateSj32, exportMyExcel } from "@/api/gjstjgjlb/sj32" export default { name: "Sj32", dicts: ['sys_dui_nodui'], data() { return { // 遮罩层 loading: true, // 选中数组 ids: [], // 子表选中数据 checkedSgsjqk: [], // 非单个禁用 single: true, // 非多个禁用 multiple: true, // 显示搜索条件 showSearch: true, // 总条数 total: 0, // 钢筋丝头加工记录表表格数据 sj32List: [], // 施工实际情况表格数据 sgsjqkList: [], // 弹出层标题 title: "", // 是否显示弹出层 open: false, // 外键时间范围 daterangeTime: [], // 外键时间范围 daterangeSgsj: [], // 查询参数 queryParams: { pageNum: 1, pageSize: 10, time: null, position: null, userid: null, sgdw: null, jldw: null, hth: null, bh: null, gcmc: null, sgsj: null, }, // 表单参数 form: {}, // 表单校验 rules: { } } }, created() { this.getList() }, methods: { /** 查询钢筋丝头加工记录表列表 */ getList() { this.loading = true this.queryParams.params = {} if (null != this.daterangeTime && '' != this.daterangeTime) { this.queryParams.params["beginTime"] = this.daterangeTime[0] this.queryParams.params["endTime"] = this.daterangeTime[1] } if (null != this.daterangeSgsj && '' != this.daterangeSgsj) { this.queryParams.params["beginSgsj"] = this.daterangeSgsj[0] this.queryParams.params["endSgsj"] = this.daterangeSgsj[1] } listSj32(this.queryParams).then(response => { this.sj32List = response.rows this.total = response.total this.loading = false }) }, // 取消按钮 cancel() { this.open = false this.reset() }, // 表单重置 reset() { this.form = { id: null, time: null, position: null, userid: null, sgdw: null, jldw: null, hth: null, bh: null, gcmc: null, sgsj: null, gcbwZh: null, gcbwDth: null, gcbwKh: null, gjgg: null, cjsl: null, dbsl: null, scrq: null, sgy: null, zygcs: null, jyjl: null, bhgcl: null } this.sgsjqkList = [] this.resetForm("form") }, /** 搜索按钮操作 */ handleQuery() { this.queryParams.pageNum = 1 this.getList() }, /** 重置按钮操作 */ resetQuery() { this.daterangeTime = [] this.daterangeSgsj = [] 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.open = true this.title = "添加钢筋丝头加工记录表" }, /** 修改按钮操作 */ handleUpdate(row) { this.reset() const id = row.id || this.ids getSj32(id).then(response => { this.form = response.data this.sgsjqkList = response.data.sgsjqkList this.open = true this.title = "修改钢筋丝头加工记录表" }) }, /** 提交按钮 */ submitForm() { this.$refs["form"].validate(valid => { if (valid) { this.form.sgsjqkList = this.sgsjqkList if (this.form.id != null) { updateSj32(this.form).then(response => { this.$modal.msgSuccess("修改成功") this.open = false this.getList() }) } else { addSj32(this.form).then(response => { this.$modal.msgSuccess("新增成功") this.open = false this.getList() }) } } }) }, /** 删除按钮操作 */ handleDelete(row) { const ids = row.id || this.ids this.$modal.confirm('是否确认删除钢筋丝头加工记录表编号为"' + ids + '"的数据项?').then(function() { return delSj32(ids) }).then(() => { this.getList() this.$modal.msgSuccess("删除成功") }).catch(() => {}) }, /** 施工实际情况序号 */ rowSgsjqkIndex({ row, rowIndex }) { row.index = rowIndex + 1 }, /** 施工实际情况添加按钮操作 */ handleAddSgsjqk() { let obj = {} obj.gjzj = "" obj.htg = "" obj.hzg = "" obj.yxlwcd = "" obj.bwzlw = "" obj.wgjc = "" this.sgsjqkList.push(obj) }, /** 施工实际情况删除按钮操作 */ handleDeleteSgsjqk() { if (this.checkedSgsjqk.length == 0) { this.$modal.msgError("请先选择要删除的施工实际情况数据") } else { const sgsjqkList = this.sgsjqkList const checkedSgsjqk = this.checkedSgsjqk this.sgsjqkList = sgsjqkList.filter(function(item) { return checkedSgsjqk.indexOf(item.index) == -1 }) } }, /** 复选框选中数据 */ handleSgsjqkSelectionChange(selection) { this.checkedSgsjqk = selection.map(item => item.index) }, /** 导出按钮操作 */ handleExport() { this.download('gjstjgjlb/sj32/export', { ...this.queryParams }, sj32_${new Date().getTime()}.xlsx) }, handleMyExport(row) { const id = row.id exportMyExcel(id).then(response => { this.$modal.msgSuccess("导出成功"); }); } } } </script> 分析以上代码

<template> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> <el-form-item label="姓名" prop="name"> <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model="queryParams.age" placeholder="请输入年龄" clearable @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="用车开始时间" prop="carUseStartTime"> <el-date-picker clearable v-model="queryParams.carUseStartTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择用车开始时间"> </el-date-picker> </el-form-item> <el-form-item label="用车结束时间" prop="carUseEndTime"> <el-date-picker clearable v-model="queryParams.carUseEndTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择用车结束时间"> </el-date-picker> </el-form-item> <el-form-item label="创建时间" prop="createdAt"> <el-date-picker clearable v-model="queryParams.createdAt" type="date" value-format="yyyy-MM-dd" placeholder="请选择创建时间"> </el-date-picker> </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="['system:car: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="['system:car: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="['system:car: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="['system:car:export']" >导出</el-button> </el-col> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="carList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-table-column label="${comment}" align="center" prop="id" /> <el-table-column label="姓名" align="center" prop="name" /> <el-table-column label="年龄" align="center" prop="age" /> <el-table-column label="用车开始时间" align="center" prop="carUseStartTime" width="180"> <template slot-scope="scope"> {{ parseTime(scope.row.carUseStartTime, '{y}-{m}-{d}') }} </template> </el-table-column> <el-table-column label="用车结束时间" align="center" prop="carUseEndTime" width="180"> <template slot-scope="scope"> {{ parseTime(scope.row.carUseEndTime, '{y}-{m}-{d}') }} </template> </el-table-column> <el-table-column label="创建时间" align="center" prop="createdAt" width="180"> <template slot-scope="scope"> {{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }} </template> </el-table-column> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:car:edit']" >修改</el-button> <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:car:remove']" >删除</el-button> </template> </el-table-column> </el-table> 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" placeholder="请输入姓名" /> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model="form.age" placeholder="请输入年龄" /> </el-form-item> <el-form-item label="用车开始时间" prop="carUseStartTime"> <el-date-picker clearable v-model="form.carUseStartTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择用车开始时间"> </el-date-picker> </el-form-item> <el-form-item label="用车结束时间" prop="carUseEndTime"> <el-date-picker clearable v-model="form.carUseEndTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择用车结束时间"> </el-date-picker> </el-form-item> <el-form-item label="创建时间" prop="createdAt"> <el-date-picker clearable v-model="form.createdAt" type="date" value-format="yyyy-MM-dd" placeholder="请选择创建时间"> </el-date-picker> </el-form-item> </el-form> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </el-dialog> </template> <script> import { listCar, getCar, delCar, addCar, updateCar } from "@/api/system/car" export default { name: "Car", data() { return { // 遮罩层 loading: true, // 选中数组 ids: [], // 非单个禁用 single: true, // 非多个禁用 multiple: true, // 显示搜索条件 showSearch: true, // 总条数 total: 0, // 用户用车信息表格数据 carList: [], // 弹出层标题 title: "", // 是否显示弹出层 open: false, // 查询参数 queryParams: { pageNum: 1, pageSize: 10, name: null, age: null, carUseStartTime: null, carUseEndTime: null, createdAt: null }, // 表单参数 form: {}, // 表单校验 rules: { name: [ { required: true, message: "姓名不能为空", trigger: "blur" } ], age: [ { required: true, message: "年龄不能为空", trigger: "blur" } ], carUseStartTime: [ { required: true, message: "用车开始时间不能为空", trigger: "blur" } ], carUseEndTime: [ { required: true, message: "用车结束时间不能为空", trigger: "blur" } ], } } }, created() { this.getList() }, methods: { /** 查询用户用车信息列表 */ getList() { this.loading = true listCar(this.queryParams).then(response => { this.carList = response.rows this.total = response.total this.loading = false }) }, // 取消按钮 cancel() { this.open = false this.reset() }, // 表单重置 reset() { this.form = { id: null, name: null, age: null, carUseStartTime: null, carUseEndTime: null, createdAt: null } 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.open = true this.title = "添加用户用车信息" }, /** 修改按钮操作 */ handleUpdate(row) { this.reset() const id = row.id || this.ids getCar(id).then(response => { this.form = response.data this.open = true this.title = "修改用户用车信息" }) }, /** 提交按钮 */ submitForm() { this.$refs["form"].validate(valid => { if (valid) { if (this.form.id != null) { updateCar(this.form).then(response => { this.$modal.msgSuccess("修改成功") this.open = false this.getList() }) } else { addCar(this.form).then(response => { this.$modal.msgSuccess("新增成功") this.open = false this.getList() }) } } }) }, /** 删除按钮操作 */ handleDelete(row) { const ids = row.id || this.ids this.$modal.confirm('是否确认删除用户用车信息编号为"' + ids + '"的数据项?').then(function() { return delCar(ids) }).then(() => { this.getList() this.$modal.msgSuccess("删除成功") }).catch(() => {}) }, /** 导出按钮操作 */ handleExport() { this.download('system/car/export', { ...this.queryParams }, car_${new Date().getTime()}.xlsx) } } } </script> 生成增删改查的文件

<template> <el-container style="height: 100vh"> <el-aside width="200px"> <el-menu default-active="1" class="el-menu-vertical-demo"> <el-menu-item index="1">员工管理</el-menu-item> </el-menu> </el-aside> <el-container> <el-header> 员工管理系统 </el-header> <el-main> <el-row :gutter="20" style="margin-bottom: 20px;"> <el-col :span="4"> <el-input v-model="queryParams.name" placeholder="请输入姓名" /> </el-col> <el-col :span="4"> <el-select v-model="queryParams.gender" placeholder="请选择性别"> <el-option label="男" :value="0"></el-option> <el-option label="女" :value="1"></el-option> </el-select> </el-col> <el-col :span="4"> <el-select v-model="queryParams.job" placeholder="请选择职位"> <el-option label="班主任" :value="1"></el-option> <el-option label="讲师" :value="2"></el-option> <el-option label="学工主管" :value="3"></el-option> <el-option label="教研主管" :value="4"></el-option> <el-option label="咨询师" :value="5"></el-option> </el-select> </el-col> <el-col :span="6"> <el-date-picker v-model="queryParams.dateRange" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" /> </el-col> <el-col :span="4"> <el-button type="primary" @click="fetchData">搜索</el-button> <el-button type="success" @click="showAddDialog">新增</el-button> <el-button type="danger" @click="batchDelete">批量删除</el-button> </el-col> </el-row> <el-table :data="tableData" border style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" /> <el-table-column prop="id" label="ID" width="80" /> <el-table-column prop="name" label="姓名" /> <el-table-column prop="gender" label="性别" width="80"> <template #default="scope"> {{ scope.row.gender === 0 ? '男' : '女' }} </template> </el-table-column> <el-table-column prop="job" label="职位" width="120"> <template #default="scope"> {{ jobMap[scope.row.job] || '未知' }} </template> </el-table-column> <el-table-column prop="entrydate" label="入职时间" width="120" /> <el-table-column label="头像" width="100"> <template #default="scope"> <el-image v-if="scope.row.image" :src="scope.row.image" style="width: 50px; height: 50px; border-radius: 50%;" :preview-src-list="[scope.row.image]" /> 暂无图片 </template> </el-table-column> <el-table-column prop="createTime" label="创建时间" width="150" /> <el-table-column label="操作" width="200"> <template #default="scope"> <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination layout="prev, pager, next" :total="total" :page-size="queryParams.pageSize" v-model:current-page="queryParams.pageNum" @current-change="fetchData" /> </el-main> </el-container> </el-container> <el-dialog v-model="dialogVisible" :title="dialogTitle"> <el-form :model="form" label-width="100px"> <el-form-item label="姓名"> <el-input v-model="form.name" /> </el-form-item> <el-form-item label="用户名"> <el-input v-model="form.username" /> </el-form-item> <el-form-item label="密码"> <el-input v-model="form.password" show-password /> </el-form-item> <el-form-item label="性别"> <el-select v-model="form.gender" placeholder="请选择性别"> <el-option label="男" :value="0"></el-option> <el-option label="女" :value="1"></el-option> </el-select> </el-form-item> <el-form-item label="职位"> <el-select v-model="form.job" placeholder="请选择职位"> <el-option label="班主任" :value="1"></el-option> <el-option label="讲师" :value="2"></el-option> <el-option label="学工主管" :value="3"></el-option> <el-option label="教研主管" :value="4"></el-option> <el-option label="咨询师" :value="5"></el-option> </el-select> </el-form-item> <el-form-item label="头像链接"> <el-input v-model="form.image" /> </el-form-item> <el-form-item label="入职时间"> <el-date-picker v-model="form.entrydate" type="date" placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" /> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> <el-button @click="dialogVisible = false">取消</el-button> </el-form-item> </el-form> </el-dialog> </template> <script setup> import { ref, onMounted } from 'vue'; import axios from 'axios'; // 设置 axios 实例 const apiClient = axios.create({ baseURL: 'http://localhost:8080/emps', timeout: 5000, }); // 表格数据 const tableData = ref([]); const total = ref(0); const selectedRows = ref([]); // 查询参数 const queryParams = ref({ pageNum: 1, pageSize: 5, name: '', gender: null, job: null, dateRange: [] }); // 表单数据 const form = ref({ id: null, username: '', password: '', name: '', gender: null, job: null, image: '', entrydate: '' }); // 对话框控制 const dialogVisible = ref(false); const dialogTitle = ref('新增员工'); const isEdit = ref(false); // 职位映射表 const jobMap = { 1: '班主任', 2: '讲师', 3: '学工主管', 4: '教研主管', 5: '咨询师' }; // 获取数据 const fetchData = async () => { const params = { page: queryParams.value.pageNum, pageSize: queryParams.value.pageSize, name: queryParams.value.name, gender: queryParams.value.gender, job: queryParams.value.job, begin: queryParams.value.dateRange[0] || '', end: queryParams.value.dateRange[1] || '' }; try { const res = await apiClient.get('', { params }); if (res.data.code === 1) { tableData.value = res.data.data.rows; total.value = res.data.data.total; } else { alert('获取数据失败:' + res.data.msg); } } catch (error) { console.error('请求出错:', error); alert('网络请求失败,请检查后端是否运行正常'); } }; // 显示新增对话框 const showAddDialog = () => { dialogTitle.value = '新增员工'; isEdit.value = false; form.value = { id: null, username: '', password: '', name: '', gender: null, job: null, image: '', entrydate: '' }; dialogVisible.value = true; }; // 显示编辑对话框 const handleEdit = (row) => { dialogTitle.value = '编辑员工'; isEdit.value = true; form.value = { ...row }; dialogVisible.value = true; }; // 提交表单 const submitForm = async () => { try { if (isEdit.value) { await apiClient.put('', form.value); } else { await apiClient.post('', form.value); } dialogVisible.value = false; fetchData(); } catch (error) { console.error('保存失败:', error); alert('操作失败,请查看控制台日志'); } }; // 删除员工 const handleDelete = async (id) => { if (!confirm(确认删除ID为 ${id} 的员工吗?)) return; try { await apiClient.delete(/${[id]}); fetchData(); } catch (error) { console.error('删除失败:', error); alert('删除失败,请查看控制台日志'); } }; // 批量删除 const batchDelete = () => { if (selectedRows.value.length === 0) { alert('请至少选择一条记录'); return; } const ids = selectedRows.value.map(item => item.id); if (!confirm(确认删除选中的 ${ids.length} 条员工吗?)) return; try { apiClient.delete(/${ids}); fetchData(); } catch (error) { console.error('批量删除失败:', error); alert('删除失败,请查看控制台日志'); } }; // 表格选择监听 const handleSelectionChange = (rows) => { selectedRows.value = rows; }; // 初始化加载数据 onMounted(() => { fetchData(); }); </script> <style scoped> .el-header { background-color: #f5f7fa; display: flex; align-items: center; } </style> 帮我优化一下代码,使代码更简洁,美化一下页面,把头像列放到名字列后面

<template> <el-form :inline="true" :model="dataForm" ref="dataForm" @keyup.enter.native="onSubmit(0)"> <el-form-item label="项目" prop="projectId" v-if="projectIdShow" style="margin-left: 0.05rem;"> <el-select v-model="dataForm.projectId" placeholder="请选择项目" > <el-option v-for="item in projectIds" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item label="电池编码" prop="deviceId"> <el-autocomplete style="width:3.3rem" size="normal" v-model="dataForm.deviceId" :popper-append-to-body="false" :fetch-suggestions="querySearchAsync" @select="handleSelect" placeholder="电池编码,如U231221040200001"> </el-autocomplete> </el-form-item> <el-form-item label="数据来源" prop="flag"> <el-select v-model="dataForm.flag" placeholder="请选择" clearable> <el-option v-for="item in flagIds" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item label="上报时间"> <el-date-picker v-model="dataForm.starttime" type="datetime" placeholder="选择起始时间" align="right" :picker-options="pickerOptions" clearable> </el-date-picker> 至 <el-date-picker v-model="dataForm.endtime" type="datetime" placeholder="选择结束时间" default-time="00:00:00" clearable> </el-date-picker> </el-form-item> <el-form-item label="SN码" prop="sn"> <el-input v-model="dataForm.sn" placeholder="输入sn码" clearable></el-input> </el-form-item> <el-form-item> <el-input v-model="dataForm.key" placeholder="其他参数名" clearable></el-input> </el-form-item> </el-form-item> <el-form-item label="电池类型" style="margin-left: 0.25rem;"> <el-select v-model="dataForm.batteryKind" placeholder="电池类型" clearable style="width:1.5rem"> <el-option v-for="item in batteryKindOptions" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled"> </el-option> </el-select> </el-form-item> <el-form-item> <el-button @click="onSubmit(0)" type="success" icon="el-icon-search">查询</el-button> <el-button @click="reset()" type="primary" icon="el-icon-refresh">重置</el-button> <el-button v-if="isAuth('maya:mybatteryinfolastest:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除</el-button> <el-button v-if="isAuth('maya:mybatteryinfolastest:list')" type="info" @click="list2Export()">导出</el-button> </el-form-item> </el-form> <el-table :height="tableHeight" :data="dataList" border v-loading="dataListLoading" @selection-change="selectionChangeHandle" style="width: 100%;"> <el-table-column type="selection" header-align="center" align="center" width="50"> </el-table-column> <el-table-column prop="batteryId" header-align="center" align="center" label="电池编码" width="140"> </el-table-column> <el-table-column prop="sn" header-align="center" align="center" label="sn码" show-overflow-tooltip> </el-table-column> <el-table-column align="center" prop="batteryKind" label="电池类型"> <template slot-scope="scope"> <el-button class="custom-size-my" :stroke-width="5" :type="getBatteryKindStyle(scope.row.batteryKind)" size="mini" round > {{ getBatteryKindText(scope.row.batteryKind) }} </el-button> </template> </el-table-column> <el-table-column prop="uploadTime" header-align="center" align="center" label="上报时间" width="140"> </el-table-column> <el-table-column prop="batteryVoltage" header-align="center" align="center" label="电压(mV)"> </el-table-column> <el-table-column prop="cellVoltage" header-align="center" align="center" label="电芯电压" show-overflow-tooltip> </el-table-column> <el-table-column prop="batteryCurrent" header-align="center" align="center" label="电流(mA)"> </el-table-column> <el-table-column prop="batterySoc" header-align="center" align="center" label="SOC(%)"> </el-table-column> <el-table-column prop="batteryHardVersion" header-align="center" align="center" label="硬件版本"> </el-table-column> <el-table-column prop="batterySoftVersion" header-align="center" align="center" label="软件版本" width="120"> </el-table-column> <el-table-column prop="batteryWorkModeValue" header-align="center" align="center" label="电池状态" width="140"> </el-table-column> <el-table-column prop="batteryProtectCode" header-align="center" align="center" label="保护状态"> </el-table-column> <el-table-column prop="batteryErrorCode" header-align="center" align="center" label="电池故障码" width="100" show-overflow-tooltip> </el-table-column> <el-table-column prop="batteryTemperatureMax" header-align="center" align="center" label="电芯最高温度(℃)" width="140"> </el-table-column> <el-table-column prop="batteryTemperatureMin" header-align="center" align="center" label="电芯最低温度(℃)" width="140"> </el-table-column> <el-table-column prop="batteryVoltageMax" header-align="center" align="center" label="电芯最高电压" width="140"> </el-table-column> <el-table-column prop="batteryVoltageMin" header-align="center" align="center" label="电芯最低电压" width="140"> </el-table-column> <el-table-column prop="mosStatus" header-align="center" align="center" label="MOS状态"> </el-table-column> <el-table-column prop="mosTemp" header-align="center" align="center" label="MOS温度(℃)" width="100"> </el-table-column> <el-table-column prop="batteryCycleTimes" header-align="center" align="center" label="循环次数"> </el-table-column> <el-table-column prop="soh" header-align="center" align="center" label="SOH"> </el-table-column> <el-table-column prop="batteryTemperatureAvg" header-align="center" align="center" label="平均温度(℃)" width="100"> </el-table-column> <el-table-column prop="chargeMode" header-align="center" align="center" label="充电模式" :formatter = "chargeModeFormat" > </el-table-column> <el-table-column prop="lowBatteryWarn" header-align="center" align="center" label="低电量提示" width="100" :formatter = "lowBatteryWarnFormat" > </el-table-column> <el-table-column prop="chargeCurrentMax" header-align="center" align="center" label="最大充电电流(mA)" width="140"> </el-table-column> <el-table-column prop="dischargeCurrentMax" header-align="center" align="center" label="最大放电电流(mA)" width="140"> </el-table-column> <el-table-column prop="chargeCurrentAvg" header-align="center" align="center" label="平均充电电流(mA)" width="140"> </el-table-column> <el-table-column prop="dischargeCurrentAvg" header-align="center" align="center" label="平均放电电流(mA)" width="140"> </el-table-column> <el-table-column prop="steadyStatus" header-align="center" align="center" label="均衡状态"> </el-table-column> <el-table-column prop="imei" header-align="center" align="center" label="IMEI" width="150"> </el-table-column> <el-table-column prop="imsi" header-align="center" align="center" label="IMSI" width="150"> </el-table-column> <el-table-column prop="iccid" header-align="center" align="center" label="ICCID" width="160"> </el-table-column> <el-table-column prop="trackerSoftwareVersion" header-align="center" align="center" label="tracker软件版本" width="200"> </el-table-column> <el-table-column prop="locationMode" header-align="center" align="center" label="定位模式"> </el-table-column> <el-table-column prop="longitude" header-align="center" align="center" label="经度" width="150"> </el-table-column> <el-table-column prop="longitudeDirection" header-align="center" align="center" label="经度方向"> </el-table-column> <el-table-column prop="latitude" header-align="center" align="center" label="纬度" width="150"> </el-table-column> <el-table-column prop="latitudeDirection" header-align="center" align="center" label="纬度方向"> </el-table-column> <el-table-column prop="gpsCog" header-align="center" align="center" label="对地航向角(°)" width="120"> </el-table-column> <el-table-column prop="gpsSpeed" header-align="center" align="center" label="gps速度(Km/h)" width="120"> </el-table-column> <el-table-column prop="gpsSignal" header-align="center" align="center" label="gps信号强度" width="120"> </el-table-column> <el-table-column prop="satelliteNum" header-align="center" align="center" label="定位卫星数" width="100"> </el-table-column> <el-table-column prop="flag" header-align="center" align="center" label="数据来源" :formatter = "flagFormat"> </el-table-column> <el-table-column prop="createTime" header-align="center" align="center" label="创建时间" width="140"> </el-table-column> <el-table-column prop="updateTime" header-align="center" align="center" label="更新时间" width="140"> </el-table-column> <el-table-column fixed="right" header-align="center" align="center" width="150" label="操作"> <template slot-scope="scope"> <el-button v-if="isAuth('maya:mybatteryinfolastest:update')" type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">修改</el-button> <el-button v-if="isAuth('maya:mybatteryinfolastest:delete')" type="text" size="small" @click="deleteHandle(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" :current-page="pageIndex" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" :total="totalPage" layout="total, sizes, prev, pager, next, jumper"> </el-pagination> <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update> </template> <script> import AddOrUpdate from './mybatteryinfolastest-add-or-update' import { debounce } from '@/utils' // 表格滚动 export default { data () { return { clientHeight: document.documentElement.clientHeight, tableHeight:640,// 定义table高度 // 1:设备主动请求或上报 2:平台主动推送或下指令 3:平台指令反馈的结果 flagIds:[ { value: '1', label: '设备主动请求或上报' }, // { // value: '2', // label: '平台主动推送或下指令' // }, { value: '3', label: '平台指令反馈的结果' }], batteryKindOptions: [ { value: '0', label: '运营' },{ value: '1', label: '售后' },{ value: '2', label: '内测' },{ value: '3', label: '报废' }], dataForm: { sn: '', starttime: '', endtime: '', batteryKind: '', flag: '', deviceId: '', key: '', projectId: '' }, projectIdShow: true, snExportShow: false, projectIds:[], dataList: [], pageIndex: 1, pageSize: 10, totalPage: 0, dataListLoading: false, dataListSelections: [], addOrUpdateVisible: false, updateVisible: false, resultShowVisible: false, pickerOptions: { shortcuts: [{ text: '今天', onClick(picker) { picker.$emit('pick', new Date()); } }, { text: '昨天', onClick(picker) { const date = new Date(); date.setTime(date.getTime() - 3600 * 1000 * 24); picker.$emit('pick', date); } }, { text: '一周前', onClick(picker) { const date = new Date(); date.setTime(date.getTime() - 3600 * 1000 * 24 * 7); picker.$emit('pick', date); } }, { text: '一个月前', onClick(picker) { const date = new Date(); date.setTime(date.getTime() - 3600 * 1000 * 24 * 30); picker.$emit('pick', date); } }, { text: '三个月前', onClick(picker) { const date = new Date(); date.setTime(date.getTime() - 3600 * 1000 * 24 * 90); picker.$emit('pick', date); } }] } } }, components: { AddOrUpdate }, activated () { this.getQueryMenus() this.getDataList() }, methods: { getQueryMenus () { this.$http({ url: this.$http.adornUrl(/battery/bmsbatteryinfo/getmenus), method: 'get', params: this.$http.adornParams() }).then(({data}) => { if (data && data.code === 0) { // this.provices = data.data.provices // this.sysStatuses = data.data.sysStatuses // this.alarmStatuses = data.data.alarmStatuses if(data.data.projectPerm===1){ this.dataForm.projectId = data.data.projectPermData //data.data.projectPerm this.projectIdShow = false // 这里只为马牙项目设置了导出功能,项目ID==38 if(data.data.projectPermData === 38 || data.data.projectPermData==='38' || data.data.projectPermData === 39 || data.data.projectPermData==='39' || data.data.projectPermData === 40 || data.data.projectPermData==='40'){ this.snExportShow = true }else{ this.snExportShow = false } }else{ this.dataForm.projectId = data.data.projectPermData //data.data.projectPerm this.projectIds = data.data.projectIds this.projectIdShow = true // 这里只为马牙项目设置了导出功能,项目ID==38 if(data.data.projectPermData === 38 || data.data.projectPermData==='38' || data.data.projectPermData === 39 || data.data.projectPermData==='39' || data.data.projectPermData === 40 || data.data.projectPermData==='40'){ this.snExportShow = true }else{ this.snExportShow = false } } if(this.dataForm.projectId === '' || this.dataForm.projectId === undefined || this.dataForm.projectId === null){ this.dataForm.projectId = 38; this.snExportShow = true } // this.customIds = data.data.customIds } }) }, // 充电模式 1--标准充;2--快充;3--盲充; chargeModeFormat (row, column) { console.log(row.chargeMode) if (row.chargeMode === 1) { return '标准充' } else if (row.chargeMode === 2) { return '快充' }else if (row.chargeMode === 3) { return '盲充' }else{ return '未知' } }, lowBatteryWarnFormat (row, column) { console.log(row.lowBatteryWarn) if (row.lowBatteryWarn === 1) { return '告警' } else{ return '否' } }, flagFormat (row, column) { console.log(row.flag) if (row.flag === 1) { return '设备上报' } else if (row.flag === 2) { return '平台指令' } }, reset(){ this.dataForm = { key: undefined, deviceId: undefined, starttime: undefined, endtime: undefined, flag: undefined, projectId: undefined, }; this.$refs["dataForm"].resetFields(); this.onSubmit(0) }, querySearchAsync(queryString, cb) { clearTimeout(1000); var results = [] // alert('queryString='+queryString) if (queryString == '') { cb(results); } else { //掉接口需要的参数 this.$http({ url: this.$http.adornUrl('/mqtt/mqtttriad/getDeviceIds'), method: 'get', params: this.$http.adornParams({ 'deviceId': queryString, 'projectParameter': this.dataForm.projectParameter }) }).then(({data}) => { if (data && data.code === 0) { // alert(data.data.length) var result = data.data //循环放到一个远程搜索需要的数组 for (let i = 0; i < result.length; i++) { const element = result[i]; // alert(element) results.push({ value: element, id: i }) } cb(results); } else { console.log('没有数据的显示') results = [] cb(results); } }) } }, //点击出现搜索后点击的每一项 handleSelect(item) { this.id = item.id this.name = item.value }, onSubmit(pgindex) { //alert("刷新一下") // 添加参数判断,防止总是跳到第一页 if (pgindex==1) { // alert(pgindex); this.getDataList() }else{ // alert(pgindex); this.pageIndex = 1 this.getDataList() } }, formatJson(filterVal, jsonData) { return jsonData.map(v => filterVal.map(j => v[j])) }, // 导出当前列表 list2Export() { this.$confirm(确定对数据进行导出操作?, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.$http({ url: this.$http.adornUrl('/maya/mybatteryinfolastest/list2Export'), method: 'get', params: this.$http.adornParams({ 'key': this.dataForm.key, 'deviceId': this.dataForm.deviceId, 'starttime': this.dataForm.starttime, 'endtime': this.dataForm.endtime, 'sn': this.dataForm.sn, 'flag': this.dataForm.flag, 'projectId': this.dataForm.projectId }) }).then(({data}) => { if (data && data.code === 0) { this.exportList = data.data require.ensure([], () => { const { export_json_to_excel } = require('../../../vendor/Export2Excel') // const tHeader = ['ID','设备ID','IMEI','ICCID','IMSI','CSQ','经度标识','经度','纬度标识','纬度','GPS行驶速度(km/h)','BMS软件版本号','tracker软件版本','信号强度','GPS定位卫星数','SOC(%)','循环次数','温度最高(电芯℃)','温度最低(电芯℃)','均衡状态','MOS温度(℃)','MOS状态','电池整包电压(mV)','电压最高(单节电芯mV)','电压最低(单节电芯mV)','全电芯电压(mV)','电池包状态','电流(mA)','上传时间','保护状态码','原始数据','故障码','入库时间','更新时间']; // const filterVal = ['id','batteryId','imei','iccid','imsi','csq','longitudeDirection','longitude','latitudeDirection','latitude','gpsSpeed','batterySoftVersion','trackerSoftwareVersion','gpsSignal','satelliteNum','batterySoc','batteryCycleTimes','batteryTemperatureMax','batteryTemperatureMin','steadyStatus','mosTemp','mosStatus','batteryVoltage','batteryVoltageMax','batteryVoltageMin','cellVoltage','batteryWorkMode','batteryCurrent','uploadTime','batteryProtectCode','payload','batteryErrorCode','createTime','updateTime']; const tHeader = ['ID','设备ID','SN码','项目ID','IMEI','ICCID','IMSI','CSQ','经度标识','经度','纬度标识','纬度','GPS行驶速度(km/h)','对地航向角(°)','BMS软件版本号','tracker软件版本','信号强度','GPS定位卫星数','SOC(%)','循环次数','温度最高(电芯℃)','温度最低(电芯℃)','均衡状态','MOS温度(℃)','MOS状态','电池整包电压(mV)','电压最高(单节电芯mV)','电压最低(单节电芯mV)','全电芯电压(mV)','电池包状态','电流(mA)','上传时间','保护状态码','故障码','SOH','平均温度','充电模式(1标准充2快充3盲充)','低电量提示','最大充电电流','最大放电电流','平均充电电流','平均放电电流','入库时间','更新时间']; const filterVal = ['id','batteryId','sn','projectId','imei','iccid','imsi','csq','longitudeDirection','longitude','latitudeDirection','latitude','gpsSpeed','gpsCog','batterySoftVersion','trackerSoftwareVersion','gpsSignal','satelliteNum','batterySoc','batteryCycleTimes','batteryTemperatureMax','batteryTemperatureMin','steadyStatus','mosTemp','mosStatus','batteryVoltage','batteryVoltageMax','batteryVoltageMin','cellVoltage','batteryWorkMode','batteryCurrent','uploadTime','batteryProtectCode','batteryErrorCode','soh','batteryTemperatureAvg','chargeMode','lowBatteryWarn','chargeCurrentMax','dischargeCurrentMax','chargeCurrentAvg','dischargeCurrentAvg','createTime','updateTime']; const list = this.exportList; const data = this.formatJson(filterVal,list); export_json_to_excel(tHeader, data, '马牙电池最新数据导出-('+this.dataForm.key+'_'+this.dataForm.starttime+'-'+this.dataForm.endtime+')'); }) } else { this.$message.error(data.msg) } }) }) }, // 获取数据列表 getDataList () { this.dataListLoading = true this.$http({ url: this.$http.adornUrl('/maya/mybatteryinfolastest/list'), method: 'get', params: this.$http.adornParams({ 'page': this.pageIndex, 'limit': this.pageSize, 'key': this.dataForm.key, 'deviceId': this.dataForm.deviceId, 'starttime': this.dataForm.starttime, 'endtime': this.dataForm.endtime, 'sn': this.dataForm.sn, 'batteryKind': this.dataForm.batteryKind, 'flag': this.dataForm.flag, 'projectId': this.dataForm.projectId }) }).then(({data}) => { if (data && data.code === 0) { this.dataList = data.page.list this.totalPage = data.page.totalCount } else { this.dataList = [] this.totalPage = 0 } this.dataListLoading = false }) }, // 每页数 sizeChangeHandle (val) { this.pageSize = val this.pageIndex = 1 this.getDataList() }, // 当前页 currentChangeHandle (val) { this.pageIndex = val this.getDataList() }, // 多选 selectionChangeHandle (val) { this.dataListSelections = val }, // 新增 / 修改 addOrUpdateHandle (id) { this.addOrUpdateVisible = true this.$nextTick(() => { this.$refs.addOrUpdate.init(id) }) }, getBatteryKindStyle(kind) { const styleMap = { 0: 'success', 1: 'warning', 2: 'primary', 3: 'danger' }; return styleMap[kind] || 'info'; }, getBatteryKindText(kind) { const map = { 0: '运营', 1: '售后', 2: '内测', 3: '报废' }; return map[kind] || '未知类型'; }, // 删除 deleteHandle (id) { var ids = id ? [id] : this.dataListSelections.map(item => { return item.id }) this.$confirm(确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.$http({ url: this.$http.adornUrl('/maya/mybatteryinfolastest/delete'), method: 'post', data: this.$http.adornData(ids, false) }).then(({data}) => { if (data && data.code === 0) { this.$message({ message: '操作成功', type: 'success', duration: 1500, onClose: () => { this.getDataList() } }) } else { this.$message.error(data.msg) } }) }) } } } </script> 新增一个导入excel按钮,以deviceId为第一列,batteryKind为第二列,解析后以map传入后台,excel不需要表头

<template> <el-card class="search-card"> <el-form :inline="true" :model="searchForm"> <el-form-item label="班级"> <el-select v-model="searchForm.clazzId" placeholder="请选择班级" clearable> <el-option v-for="clazz in clazzOptions" :key="clazz.id" :label="clazz.name" :value="clazz.id" /> </el-select> </el-form-item> <el-form-item label="学历"> <el-select v-model="searchForm.degree" placeholder="请选择学历" clearable> <el-option v-for="degree in degreeOptions" :key="degree.value" :label="degree.label" :value="degree.value" /> </el-select> </el-form-item> <el-form-item label="姓名"> <el-input v-model="searchForm.name" placeholder="请输入姓名" clearable /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleSearch">查询</el-button> <el-button @click="resetSearch">重置</el-button> </el-form-item> </el-form> </el-card> <el-button type="primary" @click="handleAdd">新增学员</el-button> <el-button type="danger" :disabled="!selectedRows.length" @click="handleBatchDelete"> 批量删除 </el-button> <el-card> <el-table :data="studentList" border stripe @selection-change="handleSelectionChange" v-loading="loading" > <el-table-column type="selection" width="55" align="center" /> <el-table-column prop="no" label="学号" width="120" align="center" /> <el-table-column prop="name" label="姓名" width="100" align="center" /> <el-table-column label="性别" width="80" align="center"> <template #default="{ row }"> {{ row.gender === 1 ? '男' : '女' }} </template> </el-table-column> <el-table-column prop="phone" label="手机号" width="130" align="center" /> <el-table-column prop="idCard" label="身份证号" width="180" align="center" /> <el-table-column label="学历" width="100" align="center"> <template #default="{ row }"> {{ getDegreeLabel(row.degree) }} </template> </el-table-column> <el-table-column prop="clazzName" label="班级" width="150" align="center" /> <el-table-column label="违纪情况" width="120" align="center"> <template #default="{ row }"> <el-tag v-if="row.violationCount > 0" type="danger"> {{ row.violationCount }}次({{ row.violationScore }}分) </el-tag> <el-tag v-else type="success">无违纪</el-tag> </template> </el-table-column> <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> <el-table-column label="操作" fixed="right" width="250" align="center"> <template #default="{ row }"> <el-button size="small" @click="handleEdit(row)">编辑</el-button> <el-button size="small" type="danger" @click="handleDelete(row.id)">删除</el-button> <el-button size="small" type="warning" @click="handleViolation(row)" :disabled="row.violationScore >= 100" > 违纪处理 </el-button> </template> </el-table-column> </el-table> <el-pagination class="pagination" v-model:current-page="pagination.current" v-model:page-size="pagination.size" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </el-card> <el-dialog v-model="dialogVisible" :title="isEdit ? '编辑学员信息' : '新增学员'" width="600px"> <el-form ref="studentFormRef" :model="studentForm" :rules="rules" label-width="100px"> <el-form-item label="姓名" prop="name"> <el-input v-model="studentForm.name" placeholder="请输入姓名" /> </el-form-item> <el-form-item label="学号" prop="no"> <el-input v-model="studentForm.no" placeholder="请输入学号" /> </el-form-item> <el-form-item label="性别" prop="gender"> <el-radio-group v-model="studentForm.gender"> <el-radio :label="1">男</el-radio> <el-radio :label="2">女</el-radio> </el-radio-group> </el-form-item> <el-form-item label="手机号" prop="phone"> <el-input v-model="studentForm.phone" placeholder="请输入手机号" /> </el-form-item> <el-form-item label="身份证号" prop="idCard"> <el-input v-model="studentForm.idCard" placeholder="请输入身份证号" /> </el-form-item> <el-form-item label="是否院校" prop="isCollege"> <el-radio-group v-model="studentForm.isCollege"> <el-radio :label="1">是</el-radio> <el-radio :label="0">否</el-radio> </el-radio-group> </el-form-item> <el-form-item label="学历" prop="degree"> <el-select v-model="studentForm.degree" placeholder="请选择学历" style="width: 100%"> <el-option v-for="degree in degreeOptions" :key="degree.value" :label="degree.label" :value="degree.value" /> </el-select> </el-form-item> <el-form-item label="毕业时间" prop="graduationDate"> <el-date-picker v-model="studentForm.graduationDate" type="date" placeholder="选择毕业日期" style="width: 100%" /> </el-form-item> <el-form-item label="班级" prop="clazzId"> <el-select v-model="studentForm.clazzId" placeholder="请选择班级" style="width: 100%"> <el-option v-for="clazz in clazzOptions" :key="clazz.id" :label="clazz.name" :value="clazz.id" /> </el-select> </el-form-item> <el-form-item label="联系地址" prop="address"> <el-input v-model="studentForm.address" type="textarea" placeholder="请输入联系地址" /> </el-form-item> </el-form> <template #footer> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">确定</el-button> </template> </el-dialog> <el-dialog v-model="violationDialogVisible" title="违纪处理" width="400px"> <el-form :model="violationForm" label-width="80px"> <el-form-item label="学员姓名"> <el-input :value="currentStudent?.name" disabled /> </el-form-item> <el-form-item label="当前扣分"> <el-input :value="currentStudent?.violationScore" disabled /> </el-form-item> <el-form-item label="扣分数" prop="score"> <el-input-number v-model="violationForm.score" :min="1" :max="100" controls-position="right" /> </el-form-item> </el-form> <template #footer> <el-button @click="violationDialogVisible = false">取消</el-button> <el-button type="primary" @click="handleViolationSubmit">确定</el-button> </template> </el-dialog> </template> <script setup lang="ts"> import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus' import { queryPageApi, addApi, updateApi, deleteApi, handleViolationApi, type StudentModel, type StudentQueryParams, type ViolationHandleParams, type PageResultModel, type ResultModel, Gender, DegreeType, CollegeFlag, } from '@/api/stu' // 搜索表单 const searchForm = reactive<StudentQueryParams>({ clazzId: null, degree: null, name: '', page: 1, pageSize: 10, }) // 分页信息 const pagination = reactive({ current: 1, size: 10, total: 0, }) // 学员列表 const studentList = ref<StudentModel[]>([]) const selectedRows = ref<StudentModel[]>([]) const loading = ref(false) // 学历选项 const degreeOptions = [ { value: DegreeType.JUNIOR, label: '初中' }, { value: DegreeType.HIGH_SCHOOL, label: '高中' }, { value: DegreeType.COLLEGE, label: '大专' }, { value: DegreeType.BACHELOR, label: '本科' }, { value: DegreeType.MASTER, label: '硕士' }, { value: DegreeType.DOCTOR, label: '博士' }, ] // 班级选项(模拟数据) const clazzOptions = ref([ { id: 11, name: 'JavaEE就业169期' }, { id: 12, name: 'JavaEE就业422期' }, { id: 13, name: '江苏花果山' }, ]) // 表单相关 const dialogVisible = ref(false) const violationDialogVisible = ref(false) const isEdit = ref(false) const studentFormRef = ref<FormInstance>() const currentStudent = ref<StudentModel | null>(null) // 学生表单 const studentForm = reactive>({ name: '', no: '', gender: Gender.MALE, phone: '', idCard: '', isCollege: CollegeFlag.IS_COLLEGE, address: '', degree: undefined, graduationDate: '', clazzId: undefined, }) // 违纪表单 const violationForm = reactive({ score: 1, }) // 表单验证规则 const rules = reactive<FormRules>({ name: [{ required: true, message: '请输入姓名', trigger: 'blur' }], no: [{ required: true, message: '请输入学号', trigger: 'blur' }], gender: [{ required: true, message: '请选择性别', trigger: 'change' }], phone: [ { required: true, message: '请输入手机号', trigger: 'blur' }, { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }, ], idCard: [ { required: true, message: '请输入身份证号', trigger: 'blur' }, { pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证号格式不正确', trigger: 'blur', }, ], clazzId: [{ required: true, message: '请选择班级', trigger: 'change' }], }) // 获取学历标签 const getDegreeLabel = (degree?: number | null) => { if (!degree) return '-' const degreeOption = degreeOptions.find((opt) => opt.value === degree) return degreeOption ? degreeOption.label : '-' } // 获取学员列表 const fetchStudents = async () => { try { loading.value = true const params: StudentQueryParams = { ...searchForm, page: pagination.current, pageSize: pagination.size, } const response: PageResultModel<StudentModel> = await queryPageApi(params) if (response.code === 1) { studentList.value = response.data.rows pagination.total = response.data.total } else { console.error('获取学员列表失败:', response.msg) } } catch (error) { console.error('获取学员列表出错:', error) } finally { loading.value = false } } // 搜索处理 const handleSearch = () => { pagination.current = 1 fetchStudents() } // 重置搜索 const resetSearch = () => { searchForm.clazzId = null searchForm.degree = null searchForm.name = '' handleSearch() } // 分页大小变化 const handleSizeChange = (size: number) => { pagination.size = size pagination.current = 1 fetchStudents() } // 当前页变化 const handleCurrentChange = (current: number) => { pagination.current = current fetchStudents() } // 表格选择变化 const handleSelectionChange = (rows: StudentModel[]) => { selectedRows.value = rows } // 新增学员 const handleAdd = () => { isEdit.value = false // 重置表单 Object.assign(studentForm, { name: '', no: '', gender: Gender.MALE, phone: '', idCard: '', isCollege: CollegeFlag.IS_COLLEGE, address: '', degree: undefined, graduationDate: '', clazzId: undefined, }) dialogVisible.value = true } // 编辑学员 const handleEdit = (student: StudentModel) => { isEdit.value = true currentStudent.value = student // 填充表单数据 Object.assign(studentForm, { ...student }) dialogVisible.value = true } // 提交表单 const submitForm = async () => { if (!studentFormRef.value) return try { await studentFormRef.value.validate() if (isEdit.value) { // 编辑学员 const response: ResultModel = await updateApi(studentForm as StudentModel) if (response.code === 1) { ElMessage.success('学员信息更新成功') dialogVisible.value = false fetchStudents() } else { ElMessage.error(更新失败: ${response.msg}) } } else { // 新增学员 const response: ResultModel<number> = await addApi(studentForm as Omit<StudentModel, 'id'>) if (response.code === 1) { ElMessage.success(学员添加成功,ID: ${response.data}) dialogVisible.value = false fetchStudents() } else { ElMessage.error(添加失败: ${response.msg}) } } } catch (error) { console.error('表单提交失败:', error) } } // 删除学员 const handleDelete = async (id: number) => { try { await ElMessageBox.confirm('确定要删除该学员吗?', '警告', { type: 'warning', confirmButtonText: '确定', cancelButtonText: '取消', }) const response: ResultModel = await deleteApi([id]) if (response.code === 1) { ElMessage.success('学员删除成功') fetchStudents() } else { ElMessage.error(删除失败: ${response.msg}) } } catch (error) { console.log('删除操作已取消') } } // 批量删除 const handleBatchDelete = async () => { if (!selectedRows.value.length) return try { const ids = selectedRows.value.map((row) => row.id) await ElMessageBox.confirm(确定要删除选中的 ${ids.length} 位学员吗?, '警告', { type: 'warning', confirmButtonText: '确定', cancelButtonText: '取消', }) const response: ResultModel = await deleteApi(ids) if (response.code === 1) { ElMessage.success(成功删除 ${ids.length} 位学员) selectedRows.value = [] fetchStudents() } else { ElMessage.error(批量删除失败: ${response.msg}) } } catch (error) { console.log('批量删除操作已取消') } } // 违纪处理 const handleViolation = (student: StudentModel) => { currentStudent.value = student violationForm.score = 1 violationDialogVisible.value = true } // 提交违纪处理 const handleViolationSubmit = async () => { if (!currentStudent.value) return try { const params: ViolationHandleParams = { id: currentStudent.value.id, score: violationForm.score, } const response: ResultModel = await handleViolationApi(params) if (response.code === 1) { ElMessage.success('违纪处理成功') violationDialogVisible.value = false fetchStudents() } else { ElMessage.error(违纪处理失败: ${response.msg}) } } catch (error) { console.error('违纪处理出错:', error) } } // 初始化加载数据 onMounted(() => { fetchStudents() }) </script> <style scoped> .student-management { padding: 20px; } .search-card { margin-bottom: 20px; } .action-buttons { margin-bottom: 15px; } .pagination { margin-top: 20px; justify-content: flex-end; } </style> import request from '@/utils/request' // 定义枚举类型(与后端一致) export enum Gender { MALE = 1, FEMALE = 2, } export enum DegreeType { JUNIOR = 1, // 初中 HIGH_SCHOOL = 2, // 高中 COLLEGE = 3, // 大专 BACHELOR = 4, // 本科 MASTER = 5, // 硕士 DOCTOR = 6, // 博士 } export enum CollegeFlag { NOT_COLLEGE = 0, IS_COLLEGE = 1, } // 学生实体接口(匹配后端返回的JSON字段名) export interface StudentModel { id: number name: string no: string gender: Gender phone: string idCard: string // 注意后端返回的是驼峰命名 isCollege: CollegeFlag address?: string | null degree?: DegreeType | null graduationDate?: string | null // ISO 8601格式日期字符串 clazzId: number violationCount: number violationScore: number createTime?: string // ISO 8601格式日期时间字符串 updateTime?: string // ISO 8601格式日期时间字符串 clazzName?: string | null // 分页查询时返回的班级名称 } // 学生查询参数接口 export interface StudentQueryParams { clazzId?: number | null degree?: DegreeType | null name?: string | null page: number pageSize: number } // 违纪处理参数接口 export interface ViolationHandleParams { id: number score: number } // 删除参数接口 export interface DeleteParams { ids: number[] // 数组形式接收 } // 统一响应结果接口(泛型增强) export interface ResultModel<T = any> { code: number msg: string data: T } // 分页结果接口 export interface PageModel<T = any> { total: number rows: T[] } // 分页响应结果接口 export interface PageResultModel<T = any> extends ResultModel> {} // 单学生响应结果接口 export interface StudentResultModel extends ResultModel<StudentModel> {} // API 函数类型定义 ------------------------------------------------- // 分页条件查询 export const queryPageApi = ( params: StudentQueryParams, ): Promise> => { const { clazzId, degree, name, page, pageSize } = params // 构建查询字符串(处理可选参数) const queryParams = new URLSearchParams() if (clazzId) queryParams.append('clazzId', clazzId.toString()) if (degree) queryParams.append('degree', degree.toString()) if (name) queryParams.append('name', name) queryParams.append('page', page.toString()) queryParams.append('pageSize', pageSize.toString()) return request.get(/students?${queryParams.toString()}) } // 新增学生 export const addApi = (stu: Omit<StudentModel, 'id' | 'clazzName'>): Promise<ResultModel<number>> => request.post('/students', stu) // 根据ID查询学生 export const queryInfoApi = (id: number): Promise<StudentResultModel> => request.get(/students/${id}) // 修改学生 export const updateApi = (stu: StudentModel): Promise<ResultModel> => request.put(/students, stu) // 删除学生(注意后端接收的是路径参数) export const deleteApi = (ids: number[]): Promise<ResultModel> => { // 将数组转换为逗号分隔的字符串,如 "1,2,3" const idsString = ids.join(',') return request.delete(/students/${idsString}) } // 违纪处理 export const handleViolationApi = (params: ViolationHandleParams): Promise<ResultModel> => request.put(/students/violation/${params.id}/${params.score}) // 根据ID查询班级 export const queryInfoClazzApi = (id: number) => request.get<any, ResultModel>(/clazzs/${id}) 新增一个根据ID查询班级Api,班级选项逻辑可以优化下,学员列表的身份证号可以不用展示出来,创建时间更换为最后修改时间,搜索区域再优化下

<template> <el-container style="height: 100vh; overflow: hidden;"> <el-aside width="200px" style="background-color: #304156;"> <el-menu default-active="1" class="el-menu-vertical-demo" background-color="#304156" text-color="#bfcbd9" active-text-color="#409EFF"> <el-menu-item index="1"> 员工管理 </el-menu-item> </el-menu> </el-aside> <el-container> <el-header class="app-header"> 员工管理系统 </el-header> <el-main class="app-content"> <el-row :gutter="20"> <el-col :span="4"> <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable /> </el-col> <el-col :span="4"> <el-select v-model="queryParams.gender" placeholder="请选择性别" clearable> <el-option label="男" :value="0" /> <el-option label="女" :value="1" /> </el-select> </el-col> <el-col :span="4"> <el-select v-model="queryParams.job" placeholder="请选择职位" clearable> <el-option v-for="item in jobOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-col> <el-col :span="6"> <el-date-picker v-model="queryParams.dateRange" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" /> </el-col> <el-col :span="6" class="action-buttons"> <el-button type="primary" @click="fetchData" icon="el-icon-search">搜索</el-button> <el-button type="success" @click="showAddDialog" icon="el-icon-plus">新增</el-button> <el-button type="danger" @click="batchDelete" icon="el-icon-delete">批量删除</el-button> </el-col> </el-row> <el-table :data="tableData" border stripe style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-table-column prop="id" label="ID" width="80" align="center" /> <el-table-column prop="name" label="姓名" width="120" /> <el-table-column label="头像" width="100" align="center"> <template #default="scope"> <el-avatar v-if="scope.row.image" :src="scope.row.image" :size="50" shape="square" :preview-src-list="[scope.row.image]" /> <el-avatar v-else :size="50" shape="square"> </el-avatar> </template> </el-table-column> <el-table-column prop="gender" label="性别" width="80" align="center"> <template #default="scope"> <el-tag :type="scope.row.gender === 0 ? 'primary' : 'danger'"> {{ scope.row.gender === 0 ? '男' : '女' }} </el-tag> </template> </el-table-column> <el-table-column prop="job" label="职位" width="150"> <template #default="scope"> <el-tag :type="getJobTagType(scope.row.job)"> {{ jobMap[scope.row.job] || '未知' }} </el-tag> </template> </el-table-column> <el-table-column prop="entrydate" label="入职时间" width="120" align="center" /> <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> <el-table-column prop="updateTime" label="最后修改时间" width="180" align="center" /> <el-table-column label="操作" width="200" align="center" fixed="right"> <template #default="scope"> <el-button size="small" type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="small" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination background layout="total, prev, pager, next, sizes" :total="total" :page-sizes="[5, 10, 20, 50]" :page-size="queryParams.pageSize" v-model:current-page="queryParams.pageNum" @current-change="fetchData" @size-change="handleSizeChange" /> </el-main> </el-container> </el-container> <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px" :close-on-click-modal="false"> <el-form :model="form" ref="formRef" :rules="formRules" label-width="100px" label-position="left"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="用户名" prop="username"> <el-input v-model="form.username" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="性别" prop="gender"> <el-select v-model="form.gender" placeholder="请选择性别" style="width: 100%"> <el-option label="男" :value="0" /> <el-option label="女" :value="1" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="职位" prop="job"> <el-select v-model="form.job" placeholder="请选择职位" style="width: 100%"> <el-option v-for="item in jobOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="密码" prop="password" v-if="!isEdit"> <el-input v-model="form.password" show-password /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="入职时间" prop="entrydate"> <el-date-picker v-model="form.entrydate" type="date" placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-form-item label="头像链接" prop="image"> <el-input v-model="form.image" placeholder="请输入图片URL" /> <el-image :src="form.image" fit="cover" style="width: 100px; height: 100px; margin-top: 10px;" :preview-src-list="[form.image]" /> </el-form-item> <el-form-item class="form-actions"> <el-button type="primary" @click="submitForm">提交</el-button> <el-button @click="dialogVisible = false">取消</el-button> </el-form-item> </el-form> </el-dialog> </template> <script setup> import { ref, reactive, onMounted } from 'vue'; import axios from 'axios'; import { ElMessage, ElMessageBox } from 'element-plus'; // 设置 axios 实例 const apiClient = axios.create({ baseURL: 'http://localhost:8080/emps', timeout: 5000, }); // 表格数据 const tableData = ref([]); const total = ref(0); const selectedRows = ref([]); const formRef = ref(null); // 查询参数 const queryParams = reactive({ pageNum: 1, pageSize: 5, name: '', gender: null, job: null, dateRange: [] }); // 表单数据 const form = reactive({ id: null, username: '', password: '', name: '', gender: null, job: null, image: '', entrydate: '' }); // 表单验证规则 const formRules = { name: [{ required: true, message: '请输入姓名', trigger: 'blur' }], username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], gender: [{ required: true, message: '请选择性别', trigger: 'change' }], job: [{ required: true, message: '请选择职位', trigger: 'change' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }], entrydate: [{ required: true, message: '请选择入职日期', trigger: 'change' }] }; // 对话框控制 const dialogVisible = ref(false); const dialogTitle = ref('新增员工'); const isEdit = ref(false); // 职位映射表 const jobMap = { 1: '班主任', 2: '讲师', 3: '学工主管', 4: '教研主管', 5: '咨询师' }; // 职位选项 const jobOptions = [ { label: '班主任', value: 1 }, { label: '讲师', value: 2 }, { label: '学工主管', value: 3 }, { label: '教研主管', value: 4 }, { label: '咨询师', value: 5 } ]; // 获取职位标签类型 const getJobTagType = (job) => { const types = ['', 'success', 'warning', 'danger', 'info', 'primary']; return types[job] || 'info'; }; // 获取数据 const fetchData = async () => { const params = { page: queryParams.pageNum, pageSize: queryParams.pageSize, name: queryParams.name, gender: queryParams.gender, job: queryParams.job, begin: queryParams.dateRange[0] || '', end: queryParams.dateRange[1] || '' }; try { const res = await apiClient.get('', { params }); if (res.data.code === 1) { tableData.value = res.data.data.rows.map(item => ({ ...item, // 格式化最后修改时间 updateTime: formatDateTime(item.updateTime) })); total.value = res.data.data.total; } else { ElMessage.error('获取数据失败:' + res.data.msg); } } catch (error) { console.error('请求出错:', error); ElMessage.error('网络请求失败,请检查后端是否运行正常'); } }; // 时间格式化函数 const formatDateTime = (dateTime) => { if (!dateTime) return ''; // 如果是字符串直接返回 if (typeof dateTime === 'string') { // 尝试解析ISO格式时间 try { const date = new Date(dateTime); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\//g, '-'); } catch (e) { return dateTime; } } // 如果是Date对象或时间戳 const date = new Date(dateTime); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\//g, '-'); }; // 显示新增对话框 const showAddDialog = () => { dialogTitle.value = '新增员工'; isEdit.value = false; Object.assign(form, { id: null, username: '', password: '', name: '', gender: null, job: null, image: '', entrydate: '' }); dialogVisible.value = true; }; // 显示编辑对话框 const handleEdit = (row) => { dialogTitle.value = '编辑员工'; isEdit.value = true; Object.assign(form, { ...row }); dialogVisible.value = true; }; // 提交表单 const submitForm = async () => { try { await formRef.value.validate(); if (isEdit.value) { await apiClient.put('', form); ElMessage.success('员工信息更新成功'); } else { await apiClient.post('', form); ElMessage.success('员工添加成功'); } dialogVisible.value = false; fetchData(); } catch (error) { if (error.name !== 'Error') { console.error('保存失败:', error); ElMessage.error('操作失败:' + (error.response?.data?.message || error.message)); } } }; // 删除员工 const handleDelete = async (id) => { try { await ElMessageBox.confirm(确认删除ID为 ${id} 的员工吗?, '删除确认', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }); await apiClient.delete(/${[id]}); ElMessage.success('删除成功'); fetchData(); } catch (error) { if (error !== 'cancel') { console.error('删除失败:', error); ElMessage.error('删除失败:' + (error.response?.data?.message || error.message)); } } }; // 批量删除 const batchDelete = async () => { if (selectedRows.value.length === 0) { ElMessage.warning('请至少选择一条记录'); return; } try { const ids = selectedRows.value.map(item => item.id); await ElMessageBox.confirm(确认删除选中的 ${ids.length} 条员工吗?, '批量删除确认', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }); await apiClient.delete(/${ids}); ElMessage.success(成功删除 ${ids.length} 条记录); fetchData(); } catch (error) { if (error !== 'cancel') { console.error('批量删除失败:', error); ElMessage.error('删除失败:' + (error.response?.data?.message || error.message)); } } }; // 表格选择监听 const handleSelectionChange = (rows) => { selectedRows.value = rows; }; // 处理分页大小变化 const handleSizeChange = (size) => { queryParams.pageSize = size; fetchData(); }; // 初始化加载数据 onMounted(() => { fetchData(); }); </script> <style scoped> /* 全局样式 */ .app-header { background-color: #fff; box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); display: flex; align-items: center; padding: 0 20px; z-index: 1; } .app-title { margin: 0; font-size: 18px; font-weight: 600; color: #333; } .app-content { padding: 20px; background-color: #f0f2f5; height: calc(100vh - 60px); overflow-y: auto; } .query-section { background: #fff; padding: 20px; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .table-section { background: #fff; padding: 20px; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .pagination-section { display: flex; justify-content: center; background: #fff; padding: 15px 0; border-radius: 4px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .action-buttons { display: flex; justify-content: flex-end; } .form-actions { display: flex; justify-content: center; margin-top: 20px; } .avatar-preview { display: flex; justify-content: center; margin-top: 10px; } .el-avatar { background-color: #f5f7fa; display: flex; align-items: center; justify-content: center; } .el-avatar i { color: #909399; } /* 优化对话框样式 */ .el-dialog__body { padding: 20px 25px; } /* 调整操作列按钮间距 */ .el-table .el-button { margin: 0 5px; } /* 确保选择器宽度100% */ .el-select { width: 100%; } </style> 优化一下代码使代码量减少,更简洁,解决表格右侧空白的问题

<template> <el-container style="height: 100vh; overflow: hidden;"> <el-aside width="200px" style="background-color: #304156;"> <el-menu default-active="1" class="el-menu-vertical-demo" background-color="#304156" text-color="#bfcbd9" active-text-color="#409EFF"> <el-menu-item index="1"> 员工管理 </el-menu-item> </el-menu> </el-aside> <el-container> <el-header class="app-header"> 员工管理系统 </el-header> <el-main class="app-content"> <el-row :gutter="20"> <el-col :span="4"> <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable /> </el-col> <el-col :span="4"> <el-select v-model="queryParams.gender" placeholder="请选择性别" clearable> <el-option label="男" :value="0" /> <el-option label="女" :value="1" /> </el-select> </el-col> <el-col :span="4"> <el-select v-model="queryParams.job" placeholder="请选择职位" clearable> <el-option v-for="item in jobOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-col> <el-col :span="6"> <el-date-picker v-model="queryParams.dateRange" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" /> </el-col> <el-col :span="6" class="action-buttons"> <el-button type="primary" @click="fetchData" icon="el-icon-search">搜索</el-button> <el-button type="success" @click="showAddDialog" icon="el-icon-plus">新增</el-button> <el-button type="danger" @click="batchDelete" icon="el-icon-delete">批量删除</el-button> </el-col> </el-row> <el-table :data="tableData" border stripe style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-table-column prop="id" label="ID" width="80" align="center" /> <el-table-column prop="name" label="姓名" width="120" /> <el-table-column label="头像" width="100" align="center"> <template #default="scope"> <el-avatar v-if="scope.row.image" :src="scope.row.image" :size="50" shape="square" :preview-src-list="[scope.row.image]" /> <el-avatar v-else :size="50" shape="square"> </el-avatar> </template> </el-table-column> <el-table-column prop="gender" label="性别" width="80" align="center"> <template #default="scope"> <el-tag :type="scope.row.gender === 0 ? 'primary' : 'danger'"> {{ scope.row.gender === 0 ? '男' : '女' }} </el-tag> </template> </el-table-column> <el-table-column prop="job" label="职位" width="150"> <template #default="scope"> <el-tag :type="getJobTagType(scope.row.job)"> {{ jobMap[scope.row.job] || '未知' }} </el-tag> </template> </el-table-column> <el-table-column prop="entrydate" label="入职时间" width="120" align="center" /> <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> <el-table-column prop="updateTime" label="最后修改时间" width="180" align="center" /> <el-table-column label="操作" width="200" align="center" fixed="right"> <template #default="scope"> <el-button size="small" type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="small" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination background layout="total, prev, pager, next, sizes" :total="total" :page-sizes="[5, 10, 20, 50]" :page-size="queryParams.pageSize" v-model:current-page="queryParams.pageNum" @current-change="fetchData" @size-change="handleSizeChange" /> </el-main> </el-container> </el-container> <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px" :close-on-click-modal="false"> <el-form :model="form" ref="formRef" :rules="formRules" label-width="100px" label-position="left"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="用户名" prop="username"> <el-input v-model="form.username" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="性别" prop="gender"> <el-select v-model="form.gender" placeholder="请选择性别" style="width: 100%"> <el-option label="男" :value="0" /> <el-option label="女" :value="1" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="职位" prop="job"> <el-select v-model="form.job" placeholder="请选择职位" style="width: 100%"> <el-option v-for="item in jobOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="密码" prop="password" v-if="!isEdit"> <el-input v-model="form.password" show-password /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="入职时间" prop="entrydate"> <el-date-picker v-model="form.entrydate" type="date" placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-form-item label="头像链接" prop="image"> <el-input v-model="form.image" placeholder="请输入图片URL" /> <el-image :src="form.image" fit="cover" style="width: 100px; height: 100px; margin-top: 10px;" :preview-src-list="[form.image]" /> </el-form-item> <el-form-item class="form-actions"> <el-button type="primary" @click="submitForm">提交</el-button> <el-button @click="dialogVisible = false">取消</el-button> </el-form-item> </el-form> </el-dialog> </template> <script setup> import { ref, reactive, onMounted } from 'vue'; import axios from 'axios'; import { ElMessage, ElMessageBox } from 'element-plus'; // 设置 axios 实例 const apiClient = axios.create({ baseURL: 'http://localhost:8080/emps', timeout: 5000, }); // 表格数据 const tableData = ref([]); const total = ref(0); const selectedRows = ref([]); const formRef = ref(null); // 查询参数 const queryParams = reactive({ pageNum: 1, pageSize: 5, name: '', gender: null, job: null, dateRange: [] }); // 表单数据 const form = reactive({ id: null, username: '', password: '', name: '', gender: null, job: null, image: '', entrydate: '' }); // 表单验证规则 const formRules = { name: [{ required: true, message: '请输入姓名', trigger: 'blur' }], username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], gender: [{ required: true, message: '请选择性别', trigger: 'change' }], job: [{ required: true, message: '请选择职位', trigger: 'change' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }], entrydate: [{ required: true, message: '请选择入职日期', trigger: 'change' }] }; // 对话框控制 const dialogVisible = ref(false); const dialogTitle = ref('新增员工'); const isEdit = ref(false); // 职位映射表 const jobMap = { 1: '班主任', 2: '讲师', 3: '学工主管', 4: '教研主管', 5: '咨询师' }; // 职位选项 const jobOptions = [ { label: '班主任', value: 1 }, { label: '讲师', value: 2 }, { label: '学工主管', value: 3 }, { label: '教研主管', value: 4 }, { label: '咨询师', value: 5 } ]; // 获取职位标签类型 const getJobTagType = (job) => { const types = ['', 'success', 'warning', 'danger', 'info', 'primary']; return types[job] || 'info'; }; // 获取数据 const fetchData = async () => { const params = { page: queryParams.pageNum, pageSize: queryParams.pageSize, name: queryParams.name, gender: queryParams.gender, job: queryParams.job, begin: queryParams.dateRange[0] || '', end: queryParams.dateRange[1] || '' }; try { const res = await apiClient.get('', { params }); if (res.data.code === 1) { tableData.value = res.data.data.rows.map(item => ({ ...item, // 格式化最后修改时间 updateTime: formatDateTime(item.updateTime) })); total.value = res.data.data.total; } else { ElMessage.error('获取数据失败:' + res.data.msg); } } catch (error) { console.error('请求出错:', error); ElMessage.error('网络请求失败,请检查后端是否运行正常'); } }; // 时间格式化函数 const formatDateTime = (dateTime) => { if (!dateTime) return ''; // 如果是字符串直接返回 if (typeof dateTime === 'string') { // 尝试解析ISO格式时间 try { const date = new Date(dateTime); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\//g, '-'); } catch (e) { return dateTime; } } // 如果是Date对象或时间戳 const date = new Date(dateTime); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\//g, '-'); }; // 显示新增对话框 const showAddDialog = () => { dialogTitle.value = '新增员工'; isEdit.value = false; Object.assign(form, { id: null, username: '', password: '', name: '', gender: null, job: null, image: '', entrydate: '' }); dialogVisible.value = true; }; // 显示编辑对话框 const handleEdit = (row) => { dialogTitle.value = '编辑员工'; isEdit.value = true; Object.assign(form, { ...row }); dialogVisible.value = true; }; // 提交表单 const submitForm = async () => { try { await formRef.value.validate(); if (isEdit.value) { await apiClient.put('', form); ElMessage.success('员工信息更新成功'); } else { await apiClient.post('', form); ElMessage.success('员工添加成功'); } dialogVisible.value = false; fetchData(); } catch (error) { if (error.name !== 'Error') { console.error('保存失败:', error); ElMessage.error('操作失败:' + (error.response?.data?.message || error.message)); } } }; // 删除员工 const handleDelete = async (id) => { try { await ElMessageBox.confirm(确认删除ID为 ${id} 的员工吗?, '删除确认', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }); await apiClient.delete(/${[id]}); ElMessage.success('删除成功'); fetchData(); } catch (error) { if (error !== 'cancel') { console.error('删除失败:', error); ElMessage.error('删除失败:' + (error.response?.data?.message || error.message)); } } }; // 批量删除 const batchDelete = async () => { if (selectedRows.value.length === 0) { ElMessage.warning('请至少选择一条记录'); return; } try { const ids = selectedRows.value.map(item => item.id); await ElMessageBox.confirm(确认删除选中的 ${ids.length} 条员工吗?, '批量删除确认', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }); await apiClient.delete(/${ids}); ElMessage.success(成功删除 ${ids.length} 条记录); fetchData(); } catch (error) { if (error !== 'cancel') { console.error('批量删除失败:', error); ElMessage.error('删除失败:' + (error.response?.data?.message || error.message)); } } }; // 表格选择监听 const handleSelectionChange = (rows) => { selectedRows.value = rows; }; // 处理分页大小变化 const handleSizeChange = (size) => { queryParams.pageSize = size; fetchData(); }; // 初始化加载数据 onMounted(() => { fetchData(); }); </script> <style scoped> /* 全局样式 */ .app-header { background-color: #fff; box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); display: flex; align-items: center; padding: 0 20px; z-index: 1; } .app-title { margin: 0; font-size: 18px; font-weight: 600; color: #333; } .app-content { padding: 20px; background-color: #f0f2f5; height: calc(100vh - 60px); overflow-y: auto; } .query-section { background: #fff; padding: 20px; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .table-section { background: #fff; padding: 20px; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .pagination-section { display: flex; justify-content: center; background: #fff; padding: 15px 0; border-radius: 4px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .action-buttons { display: flex; justify-content: flex-end; } .form-actions { display: flex; justify-content: center; margin-top: 20px; } .avatar-preview { display: flex; justify-content: center; margin-top: 10px; } .el-avatar { background-color: #f5f7fa; display: flex; align-items: center; justify-content: center; } .el-avatar i { color: #909399; } /* 优化对话框样式 */ .el-dialog__body { padding: 20px 25px; } /* 调整操作列按钮间距 */ .el-table .el-button { margin: 0 5px; } /* 确保选择器宽度100% */ .el-select { width: 100%; } </style> 优化一下代码去除无用代码使代码更简洁,优化一下样式,创建时间和最后修改时间显示的效果不同 创建时间2025-06-26T09:12:34 最后修改时间2025-06-29 21:47:21 优化成最后修改时间这种显示效果

<script setup lang="ts"> import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus' import { queryPageApi, addApi, queryInfoApi, updateApi, deleteApi } from '@/api/clazz' // 类型定义 interface Clazz { id?: number name: string room: string beginDate: string endDate: string masterId: number | null subject: number masterName?: string status?: string } // 表单引用 const formRef = ref<FormInstance>() // 响应式数据 const loading = ref(false) const dialogVisible = ref(false) const dialogTitle = ref('新增班级') const currentPage = ref(1) const pageSize = ref(10) const total = ref(0) const selectedIds = ref<number[]>([]) // 存储选中的班级ID // 查询条件 const queryParams = reactive({ begin: '', end: '', name: '', }) // 班级表单数据 const clazzForm = reactive<Clazz>({ name: '', room: '', beginDate: '', endDate: '', masterId: null, subject: 1, }) // 班级列表 const clazzList = ref<Clazz[]>([]) // 学科选项 const subjectOptions = [ { label: 'Java', value: 1 }, { label: '前端', value: 2 }, { label: '大数据', value: 3 }, { label: 'Python', value: 4 }, { label: 'Go', value: 5 }, { label: '嵌入式', value: 6 }, ] // 计算是否选择了班级 const hasSelection = computed(() => selectedIds.value.length > 0) // 加载班级数据 const loadClazzData = async () => { loading.value = true try { const res = await queryPageApi( queryParams.begin, queryParams.end, queryParams.name, currentPage.value, pageSize.value, ) if (res.code === 1) { clazzList.value = res.data.rows total.value = res.data.total // 重置选中状态 selectedIds.value = [] } else { ElMessage.error(res.msg || '数据加载失败') } } catch (error) { console.error('加载数据出错:', error) ElMessage.error('网络请求异常') } finally { loading.value = false } } // 处理查询 const handleQuery = () => { currentPage.value = 1 loadClazzData() } // 重置查询 const resetQuery = () => { queryParams.begin = '' queryParams.end = '' queryParams.name = '' handleQuery() } // 打开新增对话框 const openAddDialog = () => { dialogTitle.value = '新增班级' Object.assign(clazzForm, { id: undefined, name: '', room: '', beginDate: '', endDate: '', masterId: null, subject: 1, }) dialogVisible.value = true } // 打开编辑对话框 const openEditDialog = async (id: number) => { dialogTitle.value = '编辑班级' try { const res = await queryInfoApi(id) if (res.code === 1) { Object.assign(clazzForm, res.data) dialogVisible.value = true } else { ElMessage.error('获取班级信息失败') } } catch (error) { console.error('获取班级信息出错:', error) ElMessage.error('网络请求异常') } } // 提交表单 const submitForm = async () => { if (!formRef.value) return try { await formRef.value.validate() if (clazzForm.id) { // 更新 const res = await updateApi(clazzForm) if (res.code === 1) { ElMessage.success('更新成功') dialogVisible.value = false loadClazzData() } else { ElMessage.error(res.msg || '更新失败') } } else { // 新增 const res = await addApi(clazzForm) if (res.code === 1) { ElMessage.success('新增成功') dialogVisible.value = false loadClazzData() } else { ElMessage.error(res.msg || '新增失败') } } } catch (error) { console.error('表单验证失败:', error) } } // 处理选择变化 const handleSelectionChange = (selection: Clazz[]) => { selectedIds.value = selection.map((item) => item.id!) as number[] } // 删除班级(单个或批量) const handleDelete = (ids: number | number[]) => { const deleteIds = Array.isArray(ids) ? ids : [ids] const message = deleteIds.length > 1 ? 确定要删除选中的 ${deleteIds.length} 个班级吗? : '确定要删除该班级吗?' ElMessageBox.confirm(message, '警告', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', }) .then(async () => { const res = await deleteApi(deleteIds) if (res.code === 1) { ElMessage.success('删除成功') loadClazzData() } else { ElMessage.error(res.msg || '删除失败') } }) .catch(() => {}) } // 分页变化处理 const handleSizeChange = (val: number) => { pageSize.value = val loadClazzData() } const handleCurrentChange = (val: number) => { currentPage.value = val loadClazzData() } // 初始化加载数据 onMounted(() => { loadClazzData() }) </script> <template> 班级管理 <el-form :model="queryParams" inline class="query-form"> <el-form-item label="班级名称"> <el-input v-model="queryParams.name" placeholder="请输入班级名称" clearable @keyup.enter="handleQuery" /> </el-form-item> <el-form-item label="开课时间"> <el-date-picker v-model="queryParams.begin" type="date" placeholder="选择开始日期" value-format="YYYY-MM-DD" /> </el-form-item> <el-form-item label="结课时间"> <el-date-picker v-model="queryParams.end" type="date" placeholder="选择结束日期" value-format="YYYY-MM-DD" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery">查询</el-button> <el-button @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-button type="primary" @click="openAddDialog"> 新增班级 </el-button> <el-button type="danger" :disabled="!hasSelection" @click="handleDelete(selectedIds)"> 批量删除 </el-button> <el-table :data="clazzList" v-loading="loading" border stripe highlight-current-row @selection-change="handleSelectionChange" class="data-table" > <el-table-column type="selection" width="55" align="center" /> <el-table-column type="index" label="序号" width="80" align="center" /> <el-table-column prop="name" label="班级名称" min-width="150" align="center" /> <el-table-column prop="room" label="教室" width="120" align="center" /> <el-table-column prop="beginDate" label="开课时间" width="120" align="center" /> <el-table-column prop="endDate" label="结课时间" width="120" align="center" /> <el-table-column prop="masterName" label="班主任" width="120" align="center" /> <el-table-column label="学科" width="100" align="center"> <template #default="{ row }"> <el-tag effect="plain" type="info"> {{ subjectOptions.find((item) => item.value === row.subject)?.label || '未知' }} </el-tag> </template> </el-table-column> <el-table-column label="状态" width="100" align="center"> <template #default="{ row }"> <el-tag :type="row.status || '未开始'"> {{ row.status || '未开始' }} </el-tag> </template> </el-table-column> <el-table-column label="操作" width="180" align="center" fixed="right"> <template #default="{ row }"> <el-button type="primary" size="small" @click="openEditDialog(row.id)" ><el-icon><edit /></el-icon>编辑</el-button > <el-button type="danger" size="small" @click="handleDelete(row.id)" ><el-delete><edit /></el-delete>删除</el-button > </template> </el-table-column> </el-table> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[5, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" @closed="formRef?.resetFields()" > <el-form ref="formRef" :model="clazzForm" label-width="100px" :rules="{ name: [{ required: true, message: '请输入班级名称', trigger: 'blur' }], room: [{ required: true, message: '请输入教室', trigger: 'blur' }], beginDate: [{ required: true, message: '请选择开课时间', trigger: 'change' }], endDate: [{ required: true, message: '请选择结课时间', trigger: 'change' }], subject: [{ required: true, message: '请选择学科', trigger: 'change' }], }" > <el-form-item label="班级名称" prop="name"> <el-input v-model="clazzForm.name" placeholder="请输入班级名称" /> </el-form-item> <el-form-item label="教室" prop="room"> <el-input v-model="clazzForm.room" placeholder="请输入教室" /> </el-form-item> <el-form-item label="开课时间" prop="beginDate"> <el-date-picker v-model="clazzForm.beginDate" type="date" placeholder="选择开课日期" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> <el-form-item label="结课时间" prop="endDate"> <el-date-picker v-model="clazzForm.endDate" type="date" placeholder="选择结课日期" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> <el-form-item label="学科" prop="subject"> <el-select v-model="clazzForm.subject" placeholder="请选择学科" style="width: 100%"> <el-option v-for="item in subjectOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> <el-form-item label="班主任ID"> <el-input v-model.number="clazzForm.masterId" type="number" placeholder="请输入班主任ID" /> </el-form-item> </el-form> <template #footer> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">确定</el-button> </template> </el-dialog> </template> <style scoped> .app-container { padding: 20px; background-color: #f5f7fa; } .header-container { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); } .page-title { margin: 0 0 20px 0; padding-bottom: 15px; border-bottom: 1px solid #ebeef5; color: #303133; font-size: 18px; } .operation-container { display: flex; flex-direction: column; gap: 15px; } .query-form { display: flex; flex-wrap: wrap; gap: 10px; } .action-buttons { display: flex; gap: 10px; } .data-table { width: 100%; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); } .pagination-container { display: flex; justify-content: flex-end; margin-top: 20px; padding: 15px; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); } .el-form-item { margin-bottom: 18px; } .el-table :deep(.el-table__cell) { padding: 12px 0; } .el-tag { font-weight: 500; } </style> 优化一下整体代码逻辑,使代码更简洁,优化一下样式,美化一下页面

<script setup lang="ts"> import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus' import { queryPageApi, addApi, queryInfoApi, updateApi, deleteApi } from '@/api/clazz' // 导入API方法 // 类型定义 interface Clazz { id?: number name: string room: string beginDate: string endDate: string masterId: number | null subject: number masterName?: string status?: string } // 表单引用 const formRef = ref<FormInstance>() // 响应式数据 const loading = ref(false) const dialogVisible = ref(false) const dialogTitle = ref('新增班级') const currentPage = ref(1) const pageSize = ref(10) const total = ref(0) // 查询条件 const queryParams = reactive({ begin: '', end: '', name: '', }) // 班级表单数据 const clazzForm = reactive<Clazz>({ name: '', room: '', beginDate: '', endDate: '', masterId: null, subject: 1, }) // 班级列表 const clazzList = ref<Clazz[]>([]) // 学科选项 const subjectOptions = [ { label: 'Java', value: 1 }, { label: '前端', value: 2 }, { label: '大数据', value: 3 }, { label: 'Python', value: 4 }, { label: 'Go', value: 5 }, { label: '嵌入式', value: 6 }, ] // 加载班级数据 const loadClazzData = async () => { loading.value = true try { const res = await queryPageApi( queryParams.begin, queryParams.end, queryParams.name, currentPage.value, pageSize.value, ) if (res.code === 1) { clazzList.value = res.data.rows total.value = res.data.total } else { ElMessage.error(res.msg || '数据加载失败') } } catch (error) { console.error('加载数据出错:', error) ElMessage.error('网络请求异常') } finally { loading.value = false } } // 处理查询 const handleQuery = () => { currentPage.value = 1 loadClazzData() } // 重置查询 const resetQuery = () => { queryParams.begin = '' queryParams.end = '' queryParams.name = '' handleQuery() } // 打开新增对话框 const openAddDialog = () => { dialogTitle.value = '新增班级' Object.assign(clazzForm, { id: undefined, name: '', room: '', beginDate: '', endDate: '', masterId: null, subject: 1, }) dialogVisible.value = true } // 打开编辑对话框 const openEditDialog = async (id: number) => { dialogTitle.value = '编辑班级' try { const res = await queryInfoApi(id) if (res.code === 1) { Object.assign(clazzForm, res.data) dialogVisible.value = true } else { ElMessage.error('获取班级信息失败') } } catch (error) { console.error('获取班级信息出错:', error) ElMessage.error('网络请求异常') } } // 提交表单 const submitForm = async () => { if (!formRef.value) return try { await formRef.value.validate() if (clazzForm.id) { // 更新 const res = await updateApi(clazzForm) if (res.code === 1) { ElMessage.success('更新成功') dialogVisible.value = false loadClazzData() } else { ElMessage.error(res.msg || '更新失败') } } else { // 新增 const res = await addApi(clazzForm) if (res.code === 1) { ElMessage.success('新增成功') dialogVisible.value = false loadClazzData() } else { ElMessage.error(res.msg || '新增失败') } } } catch (error) { console.error('表单验证失败:', error) } } // 删除班级 const handleDelete = (id: number[]) => { ElMessageBox.confirm('确定要删除该班级吗?', '警告', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', }) .then(async () => { const res = await deleteApi(id) if (res.code === 1) { ElMessage.success('删除成功') loadClazzData() } else { ElMessage.error(res.msg || '删除失败') } }) .catch(() => {}) } // 分页变化处理 const handleSizeChange = (val: number) => { pageSize.value = val loadClazzData() } const handleCurrentChange = (val: number) => { currentPage.value = val loadClazzData() } // 初始化加载数据 onMounted(() => { loadClazzData() }) </script> <template> <el-form :model="queryParams" inline> <el-form-item label="班级名称"> <el-input v-model="queryParams.name" placeholder="请输入班级名称" clearable /> </el-form-item> <el-form-item label="开课时间"> <el-date-picker v-model="queryParams.begin" type="date" placeholder="选择开始日期" value-format="YYYY-MM-DD" /> </el-form-item> <el-form-item label="结课时间"> <el-date-picker v-model="queryParams.end" type="date" placeholder="选择结束日期" value-format="YYYY-MM-DD" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery">查询</el-button> <el-button @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-button type="primary" @click="openAddDialog">新增班级</el-button> <el-table :data="clazzList" v-loading="loading" border> <el-table-column type="index" label="序号" width="80" align="center" /> <el-table-column prop="name" label="班级名称" min-width="150" /> <el-table-column prop="room" label="教室" width="120" align="center" /> <el-table-column prop="beginDate" label="开课时间" width="120" align="center" /> <el-table-column prop="endDate" label="结课时间" width="120" align="center" /> <el-table-column prop="masterName" label="班主任" width="120" align="center" /> <el-table-column label="学科" width="100" align="center"> <template #default="{ row }"> {{ subjectOptions.find((item) => item.value === row.subject)?.label || '未知' }} </template> </el-table-column> <el-table-column prop="status" label="状态" width="100" align="center" /> <el-table-column label="操作" width="150" align="center" fixed="right"> <template #default="{ row }"> <el-button type="primary" size="small" @click="openEditDialog(row.id)">编辑</el-button> <el-button type="danger" size="small" @click="handleDelete(row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[5, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" @closed="formRef?.resetFields()" > <el-form ref="formRef" :model="clazzForm" label-width="100px" :rules="{ name: [{ required: true, message: '请输入班级名称', trigger: 'blur' }], room: [{ required: true, message: '请输入教室', trigger: 'blur' }], beginDate: [{ required: true, message: '请选择开课时间', trigger: 'change' }], endDate: [{ required: true, message: '请选择结课时间', trigger: 'change' }], subject: [{ required: true, message: '请选择学科', trigger: 'change' }], }" > <el-form-item label="班级名称" prop="name"> <el-input v-model="clazzForm.name" placeholder="请输入班级名称" /> </el-form-item> <el-form-item label="教室" prop="room"> <el-input v-model="clazzForm.room" placeholder="请输入教室" /> </el-form-item> <el-form-item label="开课时间" prop="beginDate"> <el-date-picker v-model="clazzForm.beginDate" type="date" placeholder="选择开课日期" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> <el-form-item label="结课时间" prop="endDate"> <el-date-picker v-model="clazzForm.endDate" type="date" placeholder="选择结课日期" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> <el-form-item label="学科" prop="subject"> <el-select v-model="clazzForm.subject" placeholder="请选择学科" style="width: 100%"> <el-option v-for="item in subjectOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> <el-form-item label="班主任ID"> <el-input v-model.number="clazzForm.masterId" type="number" placeholder="请输入班主任ID" /> </el-form-item> </el-form> <template #footer> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">确定</el-button> </template> </el-dialog> </template> <style scoped> .app-container { padding: 20px; } .mb-4 { margin-bottom: 16px; } .mt-4 { margin-top: 16px; } </style> import request from ‘@/utils/request’ import type { ResultModel } from ‘./model/model’ // 分页条件查询 export const queryPageApi = ( begin: string, end: string, name: string, page: number, pageSize: number, ) => request.get<any, ResultModel>( /clazzs?begin=${begin}&end=${end}&name=${name}&page=${page}&pageSize=${pageSize}, ) // 新增班级 export const addApi = (clazz: any) => request.post<any, ResultModel>(‘/clazzs’, clazz) // 根据ID查询班级 export const queryInfoApi = (id: number) => request.get<any, ResultModel>(/clazzs/${id}) // 更新班级 export const updateApi = (clazz: any) => request.put<any, ResultModel>(/clazzs, clazz) // 批量删除班级 export const deleteApi = (ids: number[]) => request.delete<any, ResultModel>('/clazzs', { params: { ids: ids.join(',') } }) // 查询全部班级信息 export const queryAllApi = () => request.get<any, ResultModel>(‘/clazzs/list’) 根据api优化一下项目优化一下班级表格, 美化一下页面效果,增加批量删除功能

<template> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> <el-form-item label="状态" prop="status"> <el-select v-model="queryParams.status"> <el-option v-for="dict in dict.type.status" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> <el-form-item label="排查时间" prop="regDate"> <el-date-picker v-model="regDate" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /> </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="['safety:pitfall:record: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="['safety:pitfall:record: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="['safety:pitfall:record: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="['safety:pitfall:record:export']">导出</el-button> </el-col> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="RECORDList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-button type=“text” @click=“handleMore(scope.row)”> {{ scope.row.riskEventName }} <el-button size=“mini” type=“text” icon=“el-icon-s-promotion” @click=" ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …: { companyId: store.getters.companyId }, }) " v-hasPermi=“[‘safety:pitfall:record:edit’]”>整改 <el-button size=“mini” type=“text” icon=“el-icon-edit” @click=“handleUpdate(scope.row)” v-hasPermi=“[‘safety:pitfall:record:edit’]”>修改 <el-button size=“mini” type=“text” icon=“el-icon-delete” @click=“handleDelete(scope.row)” v-hasPermi=“[‘safety:pitfall:record:remove’]”>删除 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-form ref="form" :model="form" :rules="rules" size="small" label-width="150px"> <el-form-item label="任务名称" prop="taskId"> <el-select v-model="form.taskId" clearable filterable> <el-option v-for="dict in taskList" :key="dict.taskId" :label="dict.riskEventName" :value="dict.taskId" /> </el-select> </el-form-item> <el-form-item label="状态" prop="status"> <el-select v-model="form.status"> <el-option v-for="dict in dict.type.status" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> <el-form-item label="负责人名称" prop="userName"> <el-input v-model="form.userName" /> </el-form-item> <el-form-item label="排查时间" prop="createTime"> <el-date-picker v-model="form.createTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期" /> </el-form-item> </el-form> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </el-dialog> <el-drawer :title="detail.title" :visible.sync="detail.show" direction="rtl"> <el-descriptions :column="1" size='small' border> <el-descriptions-item label="任务名称"> {{ detail.record.riskEventName }} </el-descriptions-item> <el-descriptions-item label="企业名称"> <el-button type="text" size="small" @click=" $ router.push('/safety/enterprise/' + detail.record.companyId) "> {{ detail.record.companyName }} </el-button> </el-descriptions-item> <el-descriptions-item label="风险分析单元"> {{ detail.record.riskUnit }} </el-descriptions-item> <el-descriptions-item label="管控措施分类"> {{ detail.record.controlCategory }} </el-descriptions-item> <el-descriptions-item label="管控措施描述"> {{ detail.record.controlDesc }} </el-descriptions-item> <el-descriptions-item label="排查内容"> {{ detail.record.inspectionContent }} </el-descriptions-item> <el-descriptions-item label="巡检周期"> {{ detail.record.inspectionCycle }} </el-descriptions-item> <el-descriptions-item label="工作日类型"> <dict-tag :options="dict.type.workday_type" :value="detail.record.workdayType" /> </el-descriptions-item> <el-descriptions-item label="工作开始时间"> {{ detail.record.workEndTime }} </el-descriptions-item> <el-descriptions-item label="工作结束时间"> {{ detail.record.workEndTime }} </el-descriptions-item> <el-descriptions-item label="任务类型"> <dict-tag :options="dict.type.task_type" :value="detail.record.taskType" /> </el-descriptions-item> <el-descriptions-item label="包保任务对应项"> {{ detail.record.relatedItem }} </el-descriptions-item> <el-descriptions-item label="状态"> <dict-tag :options="dict.type.status" :value="detail.record.status" /> </el-descriptions-item> <el-descriptions-item label="创建时间"> {{ detail.record.createTime }} </el-descriptions-item> <el-descriptions-item label="更新时间"> {{ detail.record.updateTime }} </el-descriptions-item> </el-descriptions> </el-drawer> </template> <script> import dayjs from "dayjs"; import { listRECORD, getRECORD, delRECORD, addRECORD, updateRECORD, } from "@/api/system/riskInspectionTaskRecord"; import { taskList } from "@/api/system/TASK"; export default { name: "record", dicts: ["status"], data() { return { // 遮罩层 loading: true, // 选中数组 ids: [], // 非单个禁用 single: true, // 非多个禁用 multiple: true, // 显示搜索条件 showSearch: true, // 总条数 total: 0, // 隐患排查任务记录表格数据 RECORDList: [], // 关联任务列表 taskList: [], // 弹出层标题 title: "", // 是否显示弹出层 open: false, regDate: [], // 查询参数 queryParams: { pageNum: 1, pageSize: 10, taskId: null, enterpriseId: null, enterpriseName: null, riskEventName: null, userId: null, userName: null, status: null, createTime: null, }, // 表单参数 form: {}, // 表单校验 rules: { taskId: [ { required: true, message: "任务ID不能为空", trigger: "blur" }, ], enterpriseId: [ { required: true, message: "企业ID不能为空", trigger: "blur" }, ], enterpriseName: [ { required: true, message: "企业名称不能为空", trigger: "blur" }, ], riskEventName: [ { required: true, message: "风险事件名称不能为空", trigger: "blur" }, ], // userId: [ // { required: true, message: "负责人id不能为空", trigger: "blur" } // ], // userName: [ // { required: true, message: "负责人名称不能为空", trigger: "blur" } // ], }, detail: { show: false, title: "详情", record: {}, }, }; }, async created() { await this.getTaskList(); this.getList(); }, methods: { handleMore({ riskEventName, taskId }) { const record = this.taskList.find((item) => item.taskId === taskId); this.detail = { show: true, title: riskEventName + "详情", record, }; }, getTaskList() { return new Promise((resolve, reject) => { taskList().then((response) => { this.taskList = response.data; resolve(); }); }); }, /** 查询隐患排查任务记录列表 */ getList() { this.loading = true; listRECORD(this.queryParams).then((response) => { this.RECORDList = response.rows; console.log(this.RECORDList) this.total = response.total; this.loading = false; }); }, // 取消按钮 cancel() { this.open = false; this.reset(); }, // 表单重置 reset() { this.form = { recordId: null, taskId: null, enterpriseId: null, enterpriseName: null, riskEventName: null, userId: null, userName: null, status: null, createTime: null, }; this.resetForm("form"); }, /** 搜索按钮操作 */ handleQuery() { this.queryParams.pageNum = 1; const [startTime, endTime] = this.regDate; this.queryParams.createStartTime = startTime ? dayjs(startTime).startOf("day").format("YYYY-MM-DD HH:mm:ss") : null; this.queryParams.createEndTime = endTime ? dayjs(endTime).endOf("day").format("YYYY-MM-DD HH:mm:ss") : null; this.getList(); }, /** 重置按钮操作 */ resetQuery() { this.regDate = [] this.resetForm("queryForm"); this.handleQuery(); }, // 多选框选中数据 handleSelectionChange(selection) { this.ids = selection.map((item) => item.recordId); this.single = selection.length !== 1; this.multiple = !selection.length; }, /** 新增按钮操作 */ handleAdd() { this.reset(); this.open = true; this.title = "添加隐患排查任务记录"; }, /** 修改按钮操作 */ handleUpdate(row) { this.reset(); const recordId = row.recordId || this.ids; getRECORD(recordId).then((response) => { this.form = response.data; this.open = true; this.title = "修改隐患排查任务记录"; }); }, /** 提交按钮 */ submitForm() { this.$ refs["form"].validate((valid) => { if (valid) { if (this.form.recordId != null) { updateRECORD(this.form).then((response) => { this.$ modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addRECORD(this.form).then((response) => { this.$ modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); } } }); }, /** 删除按钮操作 */ handleDelete(row) { const recordIds = row.recordId || this.ids; this.$ modal .confirm( '是否确认删除隐患排查任务记录编号为"' + recordIds + '"的数据项?' ) .then(function () { return delRECORD(recordIds); }) .then(() => { this.getList(); this.$ modal.msgSuccess("删除成功"); }) .catch(() => { }); }, /** 导出按钮操作 */ handleExport() { if (this.RECORDList.length === 0) { this.$ modal.msgWarning("没有数据可导出"); return; } try { const XLSX = require("xlsx"); // 明确指定需要导出的字段及对应的中文表头 const exportFields = [ { key: 'riskEventName', label: '任务名称' }, { key: 'userName', label: '负责人名称' }, { key: 'status', label: '状态' }, { key: 'createTime', label: '排查时间' }, ]; // 生成表头 const headers = exportFields.map(field => field.label); // 生成数据行 const rows = this.RECORDList.map(item => { return exportFields.map(field => { // 处理可能不存在的字段或null值 const value = item[field.key] || ''; // 特殊处理日期格式(根据实际需要调整) if (field.key === 'regDate' && value) { return dayjs(value).format('YYYY-MM-DD'); } return value; }); }); // 合并表头和数据 const exportData = [headers, ...rows]; // 创建 workbook 和 worksheet const wb = XLSX.utils.book_new(); const ws = XLSX.utils.aoa_to_sheet(exportData); // 设置列宽(可选) const colWidths = [ { wch: 40 }, { wch: 25 }, { wch: 15 }, { wch: 30 }, ]; ws['!cols'] = colWidths; XLSX.utils.book_append_sheet(wb, ws, "排查任务记录"); XLSX.writeFile(wb, 排查任务记录_${new Date().getTime()}.xlsx); } catch (error) { console.error("导出失败:", error); this.$ modal.msgError("导出失败,请稍后重试"); } } }, }; </script>前端哪里需要改能解决上面那个报错

<script setup lang="ts"> import { ref, onMounted } from 'vue' /* 导入部门类型 */ /* 导入部门类型 */ import type { DeptModelArray } from '@/api/model/model' import { addApi, queryAllApi } from '@/api/api' import { ElMessage } from 'element-plus' /* 表格数据 ref<指定的类型> 指定的类型:可以通过interface定义出来 */ const tableData = ref<DeptModelArray>([]) /* mock云端假数据:前端测试的时候,后端还没写好,就可以先用mock造一些假数据 */ /* 在页面启动时候通过钩子函数获取数据,渲染到前端页面 */ const deptSearch = async () => { const result = await queryAllApi() tableData.value = result.data } onMounted(() => { deptSearch() }) const dialogFormVisible = ref(false) const addDept = () => { dialogFormVisible.value = true //当添加部门数据时候,就清除上一次的记录 form.value = { name: '' } } const form = ref({ name: '', }) const submitDept = async () => { const result = await addApi(form.value) dialogFormVisible.value = false if (result.code == 1) { ElMessage.success('部门添加成功') deptSearch() } else { ElMessage.error(result.msg) } } </script> <template> 部门管理 <el-button type="primary"> <el-icon><Search /></el-icon> 搜索 </el-button> <el-button type="success" @click="addDept"> <el-icon></el-icon>新增 </el-button> <el-button type="danger"> <el-icon><delete /></el-icon>批量删除 </el-button>

<el-table :data="tableData" border stripe> <el-table-column type="selection" width="45" align="center" /> <el-table-column type="index" label="序号" width="70" align="center" /> <el-table-column prop="name" label="部门名称" min-width="100" /> <el-table-column prop="createTime" label="创建时间" min-width="160" align="center" /> <el-table-column prop="updateTime" label="最后修改" min-width="160" align="center" /> <el-table-column label="操作" align="center" fixed="right"> <template #default=""> <el-button size="small" type="primary"> <el-icon><edit /></el-icon>编辑 </el-button> <el-button size="small" type="danger"> <el-icon><delete /></el-icon>删除 </el-button> </template> </el-table-column> </el-table> <el-dialog v-model="dialogFormVisible" title="添加部门" width="500"> <el-form :model="form"> <el-form-item label="部门名称"> <el-input v-model="form.name" autocomplete="off" /> </el-form-item> </el-form> <template #footer> <el-button @click="dialogFormVisible = false">取消</el-button> <el-button type="primary" @click="submitDept"> 添加 </el-button> </template> </el-dialog> </template> <style scoped></style> 我的项目是vue3+element-plus构建的,帮我完善剩下的功能,美化样式

业务一览画面:<template> <el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" /> <el-table-column label="产品名称" width="220"> <template #default="scope"> <el-link type="primary" :underline="false" @click="goToProductDetail(scope.row.id)"> {{ scope.row.name }} </el-link> </template> </el-table-column> <el-table-column property="categoryName" label="产品分类" width="120" /> <el-table-column property="price" label="产品单价" width="120" /> <el-table-column property="createAt" label="生产日期" width="250" /> <el-table-column property="price" label="单价" width="120" /> <el-table-column property="stock" label="库存" width="120" /> <el-table-column label="购买数量" width="180"> <template #default="scope"> <el-input-number v-model="scope.row.number" :min="0" :max="scope.row.stock" size="small" controls-position="right" /> </template> </el-table-column> <el-table-column label="合计" width="120"> <template #default="scope"> ¥{{ (scope.row.price * scope.row.number) }} </template> </el-table-column> <el-table-column label="操作" width="180"> <template #default="scope"> <el-button size="small" @click="handleEdit(scope.$index, scope.row)"> 编辑 </el-button> <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"> 删除 </el-button> </template> </el-table-column> </el-table> <el-button type="primary" round @click="addToCart">加入购物车</el-button> 总金额: ¥{{ (totalAmount) }} </template> <script setup> const router = useRouter(); const user = "aaa" import productApi from '@/api/products' import { ref, computed } from 'vue'; import { ElMessageBox, ElMessage } from 'element-plus' const tableData = ref([]); const goToProductDetail = (productId) => { router.push({ path: /home/test/${productId}, query: { type: 'view' } }) } // 编辑详情页 const handleEdit = (index, row) => { router.push({ path: /home/test/${row.id}, // 添加查询参数表示编辑模式 query: { type: 'edit' } }) } // 删除操作 const handleDelete = (index, row) => { ElMessageBox.confirm( '确定要删除该商品吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' } ).then(() => { // 调用 API 删除商品 productApi.delete(row.id).then(res => { // 删除成功后从前端移除 tableData.value.splice(index, 1) ElMessage.success('删除成功') }).catch(err => { console.error('删除失败:', err) ElMessage.error('删除失败,请重试') }) }).catch(() => { // 用户点击取消 ElMessage.info('已取消删除') }) } // 获取商品数据 function getProduct() { productApi.getAll(user).then(res => { tableData.value = res.data.map(item => ({ ...item, number: item.number || 0, })); }); } // 创建一个响应式数组,用于存储选中的项 const allcheckbox = ref([]) function handleSelectionChange(selection) { // 当选择变化时更新存储的选中项 allcheckbox.value = selection } // 计算总金额 const totalAmount = computed(() => { return allcheckbox.value.reduce((sum, row) => { const price = parseFloat(row.price) || 0; const number = parseInt(row.number) || 0; return sum + (price * number); }, 0); }); // 加入购物车 const addToCart = () => { const selectedItems = allcheckbox.value; if (!selectedItems.length) { ElMessage.warning('请先选择要加入购物车的商品'); return; } selectedItems.forEach(item => { const payload = { name: item.name, price: item.price, category: item.category, quantity: item.number, user: user }; productApi.addCarItem(payload) .then(res => { ElMessage.success(${item.name} 加入购物车成功); }) .catch(error => { console.error(添加 ${item.name} 到购物车失败, error); ElMessage.error(添加 ${item.name} 失败); }); }); getProduct(); // 刷新商品列表 allcheckbox.value = []; }; onMounted(() => { getProduct(); }); </script> <style scoped> .summary { float: right; margin-top: 55px; margin-right: 50px; } .footer { float: right; margin-top: 50px; margin-right: 280px; } </style> 商品详情画面:<template> <el-form ref="ruleFormRef" style="margin-top: 20px;max-width: 600px" :model="ruleForm" :rules="rules" label-width="auto" :disabled="pageMode === 'view'"> <el-form-item label="产品名称:" prop="name"> <el-input v-model="ruleForm.name" /> </el-form-item> <el-form-item label="产品描述:" prop="description"> <el-input v-model="ruleForm.description" type="textarea"/> </el-form-item> <el-form-item label="产品分类:" prop="category" style="width: 50%;"> <el-select v-model="ruleForm.category" placeholder="请选择分类"> <el-option v-for="item in categorys" :label="item.name" :value="item.id" :key="item.id" /> </el-select> </el-form-item> <el-form-item label="产品单价:" prop="price"> <el-input v-model.number="ruleForm.price" type="number" style="width: 240px" /> </el-form-item> <el-form-item label="产品库存:" prop="stock"> <el-input v-model.number="ruleForm.stock" type="number" style="width: 240px" /> </el-form-item> <el-form-item label="生产厂家:" prop="manufacturer"> <el-input v-model="ruleForm.manufacturer" /> </el-form-item> <el-form-item label="产地:" required> <el-col :span="12"> <el-form-item prop="originProvince"> <el-select v-model="ruleForm.originProvince" placeholder="省" style="flex: 1; margin-right: 10px"> <el-option v-for="item in originProvinces" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item prop="originCity"> <el-select v-model="ruleForm.originCity" placeholder="市" style="flex: 1 " :disabled="!ruleForm.originProvince"> <el-option v-for="item in originCitys" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-col> </el-form-item> <el-form-item label="发货地:" required> <el-col :span="12"> <el-form-item prop="shippingProvince"> <el-select v-model="ruleForm.shippingProvince" placeholder="省" style="flex: 1; margin-right: 10px"> <el-option v-for="item in originProvinces" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item prop="shippingCity"> <el-select v-model="ruleForm.shippingCity" placeholder="市" style="flex: 1" :disabled="!ruleForm.shippingProvince"> <el-option v-for="item in shippingCities" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-col> </el-form-item> <el-form-item label="生产日期" required> <el-col :span="11"> <el-form-item prop="createAt"> <el-date-picker v-model="ruleForm.createAt" type="date" aria-label="Pick a date" placeholder="Pick a date" style="width: 100%" /> </el-form-item> </el-col> </el-form-item> <el-form-item> <el-button v-if="pageMode === 'default'" style="margin-left: 18px;" type="primary" @click="submitForm(ruleFormRef, ruleForm)"> 登录 </el-button> <el-button v-if="pageMode === 'edit'" style="margin-left: 30px;" type="primary" @click="updateForm(ruleFormRef)"> 更新 </el-button> <el-button v-if="pageMode === 'edit' || pageMode === 'default'" style="margin-left: 30px;" type="primary" @click="resetForm(ruleFormRef)"> 重置 </el-button> </el-form-item> </el-form> </template> <script setup> import { ref, reactive, onMounted } from 'vue'; import productApi from '@/api/products' import placeApi from '@/api/place' import { useRouter } from 'vue-router' import { ElLoading, ElMessage } from 'element-plus' const pageMode = ref('') // 可选值: 'view', 'edit', 'default' const router = useRouter(); const ruleFormRef = ref() const categorys = ref([])// 产品分类 const originProvinces = ref([]) // 省份数据 const originCitys = ref([]) // 城市数据 const shippingCities = ref([]) // 发货地城市数据 const ruleForm = reactive({ name: '', description: '', category: '', price: '', stock: '', manufacturer: '', originProvince: '', originCity: '', shippingProvince: '', shippingCity: '', createAt: '', user: 'aaa', delivery: false, type: [], }) const rules = reactive({ name: [ { required: true, message: '请输入产品名称', trigger: 'blur' }, { max: 10, message: '长度超过10位', trigger: 'blur' }, ], description: [ { required: true, message: '请输入产品描述', trigger: 'blur' }, { max: 200, message: '长度超过200位', trigger: 'blur' }, ], category: [ { required: true, message: '请选择产品分类', trigger: 'change', }, ], price: [ { required: true, message: '请输入产品单价', trigger: ['blur', 'change'] }, { validator: (rule, value, callback) => { if (value === null || value === '') { callback(new Error('请输入产品单价')) } else if (value <= 0) { callback(new Error('单价必须大于 0')) } else if (value > 10000) { callback(new Error('单价不能大于 10000')) } else { callback() } }, trigger: ['blur', 'change'] } ], stock: [ { required: true, message: '请输入产品库存', trigger: ['blur', 'change'] }, { validator: (rule, value, callback) => { if (value === null || value === '') { callback(new Error('请输入商品单价')) } else if (value <= 0) { callback(new Error('单价必须大于 0')) } else if (value > 10000) { callback(new Error('单价不能大于 10000')) } else { callback() } }, trigger: ['blur', 'change'] } ], manufacturer: [ { required: true, message: '请输入生产厂家', trigger: 'blur' }, ], originProvince: { validator: (rule, value, callback) => { if (!value) { callback(new Error('请选择产地省份')) } else { callback() } }, trigger: 'change' }, originCity:{ validator: (rule, value, callback) => { if (!value) { callback(new Error('请选择产地城市')) } else { callback() } }, trigger: 'change' }, shippingProvince: { validator: (rule, value, callback) => { if (!value) { callback(new Error('请选择发货省份')) } else { callback() } }, trigger: 'change' }, shippingCity:{ validator: (rule, value, callback) => { if (!value) { callback(new Error('请选择发货城市')) } else { callback() } }, trigger: 'change' }, createAt: [ { type: 'date', required: true, message: '请输入日期', trigger: 'change', }, ], }) // 重置表单操作 const resetForm = (formEl) => { if (!formEl) return formEl.resetFields() } //产品分类 function getCategory() { productApi.getCategory().then(res => { categorys.value = res.data; }) } // 获取商品详情 function getProductDetail(productId) { productApi.getById(productId).then(res => { const data = res.data // 先赋值整个对象 Object.assign(ruleForm, data) }).catch(error => { console.error('获取商品详情失败:', error); }); } // 获取省份 function getProvinces() { placeApi.getProvince().then(res => { originProvinces.value = res.data }).catch(error => { console.error('获取省份失败:', error) }) } // 监听产地省份变化,加载城市 watch( () => ruleForm.originProvince, (newVal) => { if (newVal) { placeApi.getCity(newVal).then(res => { originCitys.value = res.data }).catch(() => { originCitys.value = [] }) } else { // 如果省份为空,则清空城市列表和当前选中的城市字段 originCitys.value = [] ruleForm.originCity = '' } } ) // 监听发货地省份变化,加载城市 watch( () => ruleForm.shippingProvince, (newVal) => { if (newVal) { placeApi.getCity(newVal).then(res => { shippingCities.value = res.data }).catch(() => { shippingCities.value = [] }) } else { // 如果省份为空,则清空城市列表和当前选中的城市字段 shippingCities.value = [] ruleForm.shippingCity = '' } } ) // 更新操作 const updateForm = async (formEl) => { if (!formEl) return const loading = ElLoading.service({ fullscreen: true }) await formEl.validate((valid, fields) => { if (valid) { console.log('开始提交...') // 调用 API 更新商品信息 productApi.update(ruleForm).then(res => { ElMessage.success('更新成功') router.push('/home/test1') // 可选跳转回列表页 }).catch(error => { console.error('更新失败:', error) ElMessage.error('更新失败,请重试') }).finally(() => { loading.close() }) } else { console.log('表单验证失败:', fields) ElMessage.error('请检查输入内容') loading.close() return false } }) } // 登录操作 const submitForm = async (formEl, ruleForm) => { if (!formEl) return await formEl.validate((valid, fields) => { if (valid) { console.log('开始提交商品...') const loading = ElLoading.service({ fullscreen: true }) productApi.addProduct(ruleForm).then(res => { ElMessage.success('登录成功') router.push('/home/test1') }).catch(error => { console.error('登录失败:', error) ElMessage.error('登录失败,请重试') }).finally(() => { loading.close() }) } else { console.log('表单验证失败:', fields) ElMessage.error('请检查输入内容') loading.close() return false } }) } onMounted(() => { getCategory() getProvinces() // 获取当前路由信息 const route = router.currentRoute.value // 判断页面是查看、编辑还是新增模式 const type = route.query.type const productId = route.params.id || route.query.id if (type === 'view') { pageMode.value = 'view' // 查看模式:不显示按钮 } else if (type === 'edit') { pageMode.value = 'edit' // 编辑模式:显示“更新”、“重置” } else { pageMode.value = 'default' // 默认模式:显示“登录”、“重置” } // 如果存在商品 ID,则调用接口获取商品详情并填充表单 if (productId) { getProductDetail(productId) } }) </script> <style> .location-selectors { display: flex; justify-content: space-between; width: 100%; } </style> 购物车画面:<template> <el-table :data="tableData" style="width: 100%"> <el-table-column property="name" label="产品名称" width="220"/> <el-table-column property="categoryName" label="产品分类" width="120" /> <el-table-column property="price" label="产品单价" width="120" /> <el-table-column property="createAt" label="生产日期" width="250" /> <el-table-column property="price" label="单价" width="120" /> <el-table-column property="quantity" label="购买数量" width="180"> <template #default="scope"> <el-input-number v-model="scope.row.number" :min="0" :max="scope.row.stock" size="small" controls-position="right" /> </template> </el-table-column> <el-table-column label="合计" width="120"> <template #default="scope"> ¥{{ (scope.row.price * scope.row.number) }} </template> </el-table-column> <el-table-column label="操作" width="180"> <template #default="scope"> <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)"> 删除 </el-button> </template> </el-table-column> </el-table> <el-button type="primary" round>结算</el-button> 总金额: ¥{{ (totalAmount) }} </template> <script setup> const router = useRouter(); const user = "aaa" import productApi from '@/api/products' import { ref, computed } from 'vue'; import { ElMessageBox, ElMessage } from 'element-plus' const tableData = ref([]); // 删除操作 const handleDelete = (index, row) => { ElMessageBox.confirm( '确定要删除该商品吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' } ).then(() => { // 调用 API 删除商品 productApi.deleteCar(row.id).then(res => { // 删除成功后从前端移除 tableData.value.splice(index, 1) ElMessage.success('删除成功') }).catch(err => { console.error('删除失败:', err) ElMessage.error('删除失败,请重试') }) }).catch(() => { // 用户点击取消 ElMessage.info('已取消删除') }) } function getProduct() { productApi.getCartAll(user).then(res => { tableData.value = res.data.map(item => ({ ...item, number: item.quantity || 0 })); }); } // 计算总金额 const totalAmount = computed(() => { return tableData.value.reduce((sum, row) => { const price = parseFloat(row.price) || 0; const number = parseInt(row.number) || 0; return sum + (price * number); }, 0); }); onMounted(() => { getProduct(); }); </script> <style scoped> .summary { float: right; margin-top: 55px; margin-right: 50px; } .footer { float: right; margin-top: 50px; margin-right: 510px; } </style> 现在我想将商品详情画面拆成像之前的4层组件结构,而购物车和商品一览画面保持不变,只将商品详情画面的form表单拆成自定义组件功能保持不变

让左侧部门树和右侧用户表格区域高度独立计算,实现各自区域内的滚动互不影响。<template> <el-row :gutter="20" type="flex"> <el-col style="flex: 0 0 auto; max-width: 350px; min-width: 200px;" :xs="24" > <ContentWrap class="h-1/1"> <DeptTree @node-click="handleDeptNodeClick" /> </ContentWrap> </el-col> <el-col style="flex: 1; min-width: 0;" :xs="24"> <ContentWrap> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px" > <el-form-item label="用户账号" prop="username"> <el-input v-model="queryParams.username" placeholder="请输入用户账号" clearable @keyup.enter="handleQuery" class="!w-240px" /> </el-form-item> <el-form-item label="手机号码" prop="mobile"> <el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery" class="!w-240px" /> </el-form-item> <el-form-item label="状态" prop="status"> <el-select v-model="queryParams.status" placeholder="请选择用户状态" clearable class="!w-240px" > <el-option v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> <el-form-item label="创建时间" prop="createTime"> <el-date-picker v-model="queryParams.createTime" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" start-placeholder="开始日期" end-placeholder="结束日期" class="!w-240px" /> </el-form-item> <el-form-item> <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button> <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button> <el-button type="primary" plain @click="openForm('create')" v-hasPermi="['system:user:create']" > <Icon icon="ep:plus" /> 新增 </el-button> <el-button type="warning" plain @click="handleImport" v-hasPermi="['system:user:import']" > <Icon icon="ep:upload" /> 导入 </el-button> <el-button type="success" plain @click="handleExport" :loading="exportLoading" v-hasPermi="['system:user:export']" > <Icon icon="ep:download" />导出 </el-button> </el-form-item> </el-form> </ContentWrap> <ContentWrap> <el-table v-loading="loading" :data="list"> <el-table-column label="用户编号" align="center" key="id" prop="id" /> <el-table-column label="用户账号" align="center" prop="username" :show-overflow-tooltip="true" /> <el-table-column label="用户昵称" align="center" prop="nickname" :show-overflow-tooltip="true" /> <el-table-column label="部门" align="center" key="deptName" prop="deptName" :show-overflow-tooltip="true" /> <el-table-column label="手机号码" align="center" prop="mobile" width="120" /> <el-table-column label="状态" key="status"> <template #default="scope"> <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)" :disabled="!checkPermi(['system:user:update'])" /> </template> </el-table-column> <el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180" /> <el-table-column label="操作" align="center" width="160"> <template #default="scope"> <el-button type="primary" link @click="openForm('update', scope.row.id)" v-hasPermi="['system:user:update']" > <Icon icon="ep:edit" />修改 </el-button> <el-dropdown @command="(command) => handleCommand(command, scope.row)" v-hasPermi="[ 'system:user:delete', 'system:user:update-password', 'system:permission:assign-user-role' ]" > <el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button> <template #dropdown> <el-dropdown-menu> <el-dropdown-item command="handleDelete" v-if="checkPermi(['system:user:delete'])" > <Icon icon="ep:delete" />删除 </el-dropdown-item> <el-dropdown-item command="handleResetPwd" v-if="checkPermi(['system:user:update-password'])" > <Icon icon="ep:key" />重置密码 </el-dropdown-item> <el-dropdown-item command="handleRole" v-if="checkPermi(['system:permission:assign-user-role'])" > <Icon icon="ep:circle-check" />分配角色 </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </template> </el-table-column> </el-table> </ContentWrap> </el-col> </el-row> <UserForm ref="formRef" @success="getList" /> <UserImportForm ref="importFormRef" @success="getList" /> <UserAssignRoleForm ref="assignRoleFormRef" @success="getList" /> </template> <script lang="ts" setup> import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { checkPermi } from '@/utils/permission' import { dateFormatter } from '@/utils/formatTime' import download from '@/utils/download' import { CommonStatusEnum } from '@/utils/constants' import * as UserApi from '@/api/system/user' import UserForm from './UserForm.vue' import UserImportForm from './UserImportForm.vue' import UserAssignRoleForm from './UserAssignRoleForm.vue' import DeptTree from './DeptTree.vue' defineOptions({ name: 'SystemUser' }) const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 const loading = ref(true) // 列表的加载中 const total = ref(0) // 列表的总页数 const list = ref([]) // 列表的数 const queryParams = reactive({ pageNo: 1, pageSize: 10, username: undefined, mobile: undefined, status: undefined, deptId: undefined, createTime: [] }) const queryFormRef = ref() // 搜索的表单 /** 查询列表 */ const getList = async () => { loading.value = true try { const data = await UserApi.getUserPage(queryParams) list.value = data.list total.value = data.total } finally { loading.value = false } } /** 搜索按钮操作 */ const handleQuery = () => { queryParams.pageNo = 1 getList() } /** 重置按钮操作 */ const resetQuery = () => { queryFormRef.value?.resetFields() handleQuery() } /** 处理部门被点击 */ const handleDeptNodeClick = async (row) => { queryParams.deptId = row.id await getList() } /** 添加/修改操作 */ const formRef = ref() const openForm = (type: string, id?: number) => { formRef.value.open(type, id) } /** 用户导入 */ const importFormRef = ref() const handleImport = () => { importFormRef.value.open() } /** 修改用户状态 */ const handleStatusChange = async (row: UserApi.UserVO) => { try { // 修改状态的二次确认 const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用' await message.confirm('确认要"' + text + '""' + row.username + '"用户吗?') // 发起修改状态 await UserApi.updateUserStatus(row.id, row.status) // 刷新列表 await getList() } catch { // 取消后,进行恢复按钮 row.status = row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE } } /** 导出按钮操作 */ const exportLoading = ref(false) const handleExport = async () => { try { // 导出的二次确认 await message.exportConfirm() // 发起导出 exportLoading.value = true const data = await UserApi.exportUser(queryParams) download.excel(data, '用户数据.xlsx') } catch { } finally { exportLoading.value = false } } /** 操作分发 */ const handleCommand = (command: string, row: UserApi.UserVO) => { switch (command) { case 'handleDelete': handleDelete(row.id) break case 'handleResetPwd': handleResetPwd(row) break case 'handleRole': handleRole(row) break default: break } } /** 删除按钮操作 */ const handleDelete = async (id: number) => { try { // 删除的二次确认 await message.delConfirm() // 发起删除 await UserApi.deleteUser(id) message.success(t('common.delSuccess')) // 刷新列表 await getList() } catch {} } /** 重置密码 */ const handleResetPwd = async (row: UserApi.UserVO) => { try { // 重置的二次确认 const result = await message.prompt( '请输入"' + row.username + '"的新密码', t('common.reminder') ) const password = result.value // 发起重置 await UserApi.resetUserPassword(row.id, password) message.success('修改成功,新密码是:' + password) } catch {} } /** 分配角色 */ const assignRoleFormRef = ref() const handleRole = (row: UserApi.UserVO) => { assignRoleFormRef.value.open(row) } /** 初始化 */ onMounted(() => { getList() }) </script>

大家在看

recommend-type

西安市行政区划(区县)

西安市行政区划的矢量文件,WGS 1984 坐标系,到乡镇区一级。 如果想要其他的地区的可以留言,可以上传。
recommend-type

ansys后处理的教程

很好的ansys后处理教程,同大伙分享一下
recommend-type

基于matlab的第三代SNN脉冲神经网络的仿真,含仿真操作录像

1.版本:matlab2021a,包含仿真操作录像,操作录像使用windows media player播放。 2.领域:SNN脉冲神经网络 3.内容:基于matlab的第三代SNN脉冲神经网络的仿真。 epoch = T/ms; for i = 1:floor(epoch/4) for j = 1:4 loc = fix(4*(i-1)*ms + find(input(1,:) == 1) * ms); inputSpikes(1, loc) = 1; loc = fix(4*(i-1)*ms + find(input(2,:) == 1) * ms); inputSpikes(2, loc) = 1; loc = fix(4*(i-1)*ms + find(output(1,:) == 1) * ms); outputSpikes(1, loc) = 1; 4.注意事项:注意MATLAB左侧当前文件夹路径,必须是程序所在文件夹位置,具体可以参考视频录。
recommend-type

新工创项目-基于树莓派5+ROS2的智能物流小车视觉系统(源码+使用教程+模型文件).zip

新工创项目-基于树莓派5+ROS2的智能物流小车视觉系统(源码+使用教程+模型文件) 【项目介绍】 基于 ROS2 的智能物流小车视觉系统。 主要功能 基于 Raspberry Pi 5 和 Ubuntu 24.04 的运行环境 使用 OpenCV 和 YOLO 进行物体检测和跟踪 集成了 usb_cam 和 yolo_ros 等重要依赖包 提供了一键启动和手动启动的方式 操作系统: Raspberry Pi 5, Ubuntu 24.04 编程语言: Python 3.12, C++ 框架/库: ROS2-jazzy, OpenCV, YOLO 【运行】 编译 colcon build 运行节点 一键启动 source install/setup.bash ros2 launch launch/start_all.launch.py
recommend-type

PyPDF2-1.26.0.tar.gz

Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

最新推荐

recommend-type

光子学领域基于连续域束缚态的铌酸锂二次谐波超表面COMSOL模拟研究 - 二次谐波

内容概要:本文探讨了基于连续域束缚态(BICs)的铌酸锂二次谐波超表面的COMSOL光子晶体模拟。首先介绍了BICs的概念及其在光学领域的应用潜力,然后详细描述了在COMSOL中建立的三维模型,包括周期性晶格结构和BICs模式。接着分析了模拟结果,展示了光子在铌酸锂超表面上的传播行为变化,特别是二次谐波效应的显著提升。最后讨论了代码实现和模拟结果的可视化方法,并展望了未来优化方向和其他潜在应用。 适合人群:从事光子学、光学工程及相关领域的研究人员和学生。 使用场景及目标:适用于希望深入了解BICs在铌酸锂二次谐波中的应用机制,以及希望通过COMSOL进行类似模拟实验的人群。 其他说明:文中涉及大量COMSOL建模和仿真细节,对于初学者可能有一定难度,建议先掌握相关基础知识再进行深入学习。
recommend-type

Abaqus仿真技术在PCB板钻削加工中的应用:铜箔与纤维复合材料建模及本构关系研究

Abaqus仿真技术在PCB板钻削加工中的应用,重点讨论了铜箔和纤维复合材料的建模及其本构关系。首先,文章阐述了铜箔采用J-C本构模型进行模拟的原因及其优势,能够准确预测加工过程中的变形和应力。其次,针对纤维复合材料,文章提出了两种建模方式:二维壳单元Hashin准则和三维Hashin子程序,分别适用于不同的应用场景。此外,还探讨了有限元方法在PCB钻削加工仿真的应用,强调了结合实验数据和实际工艺参数的重要性。最后,文章指出,合理的仿真技术和材料选择有助于提升加工效率和产品质量。 适合人群:从事PCB板制造及相关领域的工程师和技术人员,尤其是对仿真技术有一定了解并希望深入掌握Abaqus应用的人群。 使用场景及目标:① 提高对PCB板钻削加工仿真技术的理解;② 掌握铜箔和纤维复合材料的建模方法;③ 学习如何结合实验数据和实际工艺参数优化仿真效果。 其他说明:本文不仅提供了理论指导,还结合了实际案例,使读者能够在实践中更好地应用所学知识。
recommend-type

langchain4j-test-1.1.0-beta7.jar中文-英文对照文档.zip

1、压缩文件中包含: 中文-英文对照文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。 2、使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 3、特殊说明: (1)本文档为人性化翻译,精心制作,请放心使用; (2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; (3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 4、温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件。 5、本文件关键字: jar中文-英文对照文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。
recommend-type

langchain4j-coherence-0.36.2.jar中文文档.zip

1、压缩文件中包含: 中文文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。 2、使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 3、特殊说明: (1)本文档为人性化翻译,精心制作,请放心使用; (2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; (3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 4、温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件。 5、本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。
recommend-type

COMSOL电弧模型:多物理场联合仿真的电场、磁场、温度场、气流场分析及其应用

COMSOL电弧模型的多物理场联合仿真技术,涵盖电场、磁场、温度场、气流场等多个方面的仿真分析。文章首先概述了仿真技术在工业领域尤其是电力和电气工程中的重要性,接着具体阐述了COMSOL电弧模型的功能特点,如电场仿真分析、烧蚀仿真、多物理场联合仿真等。此外,文章还列举了该模型的具体应用场景,包括磁流体动力学模型、瞬态电弧、气吹电弧、磁吹电弧和断路器电弧的仿真,强调了其在理解和预测电弧动态演化过程中的重要作用。 适合人群:从事电力工程、电气工程及相关领域的工程师和技术研究人员。 使用场景及目标:适用于需要深入了解电弧动态特性的科研项目和产品研发,旨在提高产品的设计、优化和改进能力,确保电力系统稳定运行。 其他说明:掌握COMSOL电弧模型的多物理场仿真技术有助于解决实际工程中的复杂问题,提升工作效率和产品质量。
recommend-type

Webdiy.net新闻系统v1.0企业版发布:功能强大、易操作

标题中提到的"Webdiy.net新闻系统 v1.0 企业版"是一个针对企业级应用开发的新闻内容管理系统,是基于.NET框架构建的。从描述中我们可以提炼出以下知识点: 1. **系统特性**: - **易用性**:系统设计简单,方便企业用户快速上手和操作。 - **可定制性**:用户可以轻松修改网站的外观和基本信息,例如网页标题、页面颜色、页眉和页脚等,以符合企业的品牌形象。 2. **数据库支持**: - **Access数据库**:作为轻量级数据库,Access对于小型项目和需要快速部署的场景非常合适。 - **Sql Server数据库**:适用于需要强大数据处理能力和高并发支持的企业级应用。 3. **性能优化**: - 系统针对Access和Sql Server数据库进行了特定的性能优化,意味着它能够提供更为流畅的用户体验和更快的数据响应速度。 4. **编辑器功能**: - **所见即所得编辑器**:类似于Microsoft Word,允许用户进行图文混排编辑,这样的功能对于非技术人员来说非常友好,因为他们可以直观地编辑内容而无需深入了解HTML或CSS代码。 5. **图片管理**: - 新闻系统中包含在线图片上传、浏览和删除的功能,这对于新闻编辑来说是非常必要的,可以快速地为新闻内容添加相关图片,并且方便地进行管理和更新。 6. **内容发布流程**: - **审核机制**:后台发布新闻后,需经过审核才能显示到网站上,这样可以保证发布的内容质量,减少错误和不当信息的传播。 7. **内容排序与类别管理**: - 用户可以按照不同的显示字段对新闻内容进行排序,这样可以突出显示最新或最受欢迎的内容。 - 新闻类别的动态管理及自定义显示顺序,可以灵活地对新闻内容进行分类,方便用户浏览和查找。 8. **前端展示**: - 系统支持Javascript前端页面调用,这允许开发者将系统内容嵌入到其他网页或系统中。 - 支持iframe调用,通过这种HTML元素可以将系统内容嵌入到网页中,实现了内容的跨域展示。 9. **安全性**: - 提供了默认的管理账号和密码(webdiy / webdiy.net),对于企业应用来说,这些默认的凭证需要被替换,以保证系统的安全性。 10. **文件结构**: - 压缩包文件名称为"webdiynetnews",这可能是系统的根目录名称或主要安装文件。 11. **技术栈**: - 系统基于ASP.NET技术构建,这表明它使用.NET框架开发,并且可以利用.NET生态中的各种库和工具来实现功能的扩展和维护。 在实施和部署这样的系统时,企业可能还需要考虑以下方面: - **可扩展性**:随着业务的增长,系统应该能容易地扩展,以支持更多的用户和内容。 - **安全性**:除了更改为安全的管理员凭证外,还需考虑防止SQL注入、XSS攻击等网络安全问题。 - **备份和恢复**:定期备份数据库和内容是很重要的,以防数据丢失或需要恢复到先前的状态。 - **多用户和权限管理**:企业环境可能需要多级用户权限设置,以适应不同的团队和角色。 - **SEO优化**:系统应支持良好的搜索引擎优化实践,以便于内容在搜索引擎中的排名和发现。 - **移动适应性**:由于移动设备的广泛使用,系统应具备良好的响应式设计,以提供良好的移动用户体验。 根据描述,该系统似乎是一个成熟的解决方案,适用于需要快速搭建新闻网站的企业用户,但同时也应该注意定期的维护和更新,以确保系统的稳定性和安全性。
recommend-type

【Windows 11用户的福音】:一步到位解决GX Works2安装问题,让兼容性不再是问题!

# 1. GX Works2简介与Windows 11兼容性问题 ## 简介GX Works2 GX Works2是由三菱电机开发的一款针对其PLC(可编程逻辑控制器)产品的编程和调试软件。该软件以其直观的用户界面和强大的编程功能闻名于工业自动化领域,支持从简单的逻辑控制到复杂的系统集成项目。随着Windows操作系统的迭代升级,尤其是新推
recommend-type

电磁加热双边谐振和单边谐振的区别

<think>我们正在处理关于电磁加热技术中双边谐振与单边谐振的工作原理及区别的问题。 首先,需要明确用户意图是了解这两种谐振方式的区别以及它们的工作原理。 我们将通过以下步骤进行: 1. 调用网络搜索工具,检索关于电磁加热中双边谐振和单边谐振的信息。 2. 整合检索到的内容,按照要求生成回答,包括工作原理和区别,并组织成多个方法或步骤(但避免使用步骤词汇,用换行分隔)。 3. 在回答中,如果有公式或代码,按照指定格式处理。 4. 最后,添加相关问题部分。 注意:避免使用第一人称,避免步骤词汇,引用内容不集中末尾,而是融入回答中。 根据搜索,电磁加热中的谐振通常指的是感应加
recommend-type

EnvMan源代码压缩包内容及功能解析

根据给定文件信息,我们需要生成关于“EnvMan-source.zip”这一压缩包的知识点。首先,由于提供的信息有限,我们无法直接得知EnvMan-source.zip的具体内容和功能,但可以通过标题、描述和标签中的信息进行推断。文件名称列表只有一个“EnvMan”,这暗示了压缩包可能包含一个名为EnvMan的软件或项目源代码。以下是一些可能的知识点: ### EnvMan软件/项目概览 EnvMan可能是一个用于环境管理的工具或框架,其源代码被打包并以“EnvMan-source.zip”的形式进行分发。通常,环境管理相关的软件用于构建、配置、管理和维护应用程序的运行时环境,这可能包括各种操作系统、服务器、中间件、数据库等组件的安装、配置和版本控制。 ### 源代码文件说明 由于只有一个名称“EnvMan”出现在文件列表中,我们可以推测这个压缩包可能只包含一个与EnvMan相关的源代码文件夹。源代码文件夹可能包含以下几个部分: - **项目结构**:展示EnvMan项目的基本目录结构,通常包括源代码文件(.c, .cpp, .java等)、头文件(.h, .hpp等)、资源文件(图片、配置文件等)、文档(说明文件、开发者指南等)、构建脚本(Makefile, build.gradle等)。 - **开发文档**:可能包含README文件、开发者指南或者项目wiki,用于说明EnvMan的功能、安装、配置、使用方法以及可能的API说明或开发者贡献指南。 - **版本信息**:在描述中提到了版本号“-1101”,这表明我们所见的源代码包是EnvMan的1101版本。通常版本信息会详细记录在版本控制文件(如ChangeLog或RELEASE_NOTES)中,说明了本次更新包含的新特性、修复的问题、已知的问题等。 ### 压缩包的特点 - **命名规范**:标题、描述和标签中的一致性表明这是一个正式发布的软件包。通常,源代码包的命名会遵循一定的规范,如“项目名称-版本号-类型”,在这里类型是“source”。 - **分发形式**:以.zip格式的压缩包进行分发,是一种常见的软件源代码分发方式。虽然较现代的版本控制系统(如Git、Mercurial)通常支持直接从仓库克隆源代码,但打包成zip文件依然是一种便于存储和传输的手段。 ### 可能的应用场景 - **开发环境配置**:EnvMan可能是用于创建、配置和管理开发环境的工具,这种工具在开发人员设置新的开发机或新的项目环境时非常有用。 - **自动化部署**:EnvMan可能包含自动化部署环境的脚本或命令,使得部署流程变得快捷且高效。 - **监控与维护**:作为环境管理工具,EnvMan可能还支持对环境的监控功能,包括系统资源监控、服务状态检查等,以保证生产环境的稳定性。 ### 总结 尽管以上知识点是基于有限的信息进行的假设性推论,但EnvMan-source.zip包可能是一个用于环境管理的软件或项目的源代码包。该软件或项目可能包含构建和部署自动化环境的能力,以及对运行时环境的监控和维护。文件命名的一致性暗示这是一个正式的版本发布。如果要深入了解EnvMan的功能与用法,建议直接查看压缩包中的文档或源代码注释。同时,考虑到源代码的开发,我们还应该探究该项目所使用的技术栈、编程语言以及版本控制工具等,这将有助于进一步了解EnvMan的技术细节。
recommend-type

【Windows 11终极解决方案】:彻底攻克GX Works2安装中难缠的.Net Framework 3.5障碍!

# 1. Windows 11与GX Works2简介 ## 1.1 Windows 11操作系统概览 Windows 11,作为微软最新的操作系统,不仅仅提供了一种现代的用户体验,而且加强了在企业环境中的安全性与生产力工具。其引入了全新的界面设计、改进的多任务处理以及对Android应用的支持,使它成为IT专业人