feat: 新增部门报餐和请假申请API及字典选择组件
新增部门报餐和员工请假申请的API接口文件,包含列表查询、详情获取、新增、修改和删除功能 添加可编辑的字典选择组件DictSelect,支持字典项的双击编辑、快速新增和刷新功能
This commit is contained in:
44
klp-ui/src/api/wms/leaveRequest.js
Normal file
44
klp-ui/src/api/wms/leaveRequest.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询员工请假申请列表
|
||||
export function listLeaveRequest(query) {
|
||||
return request({
|
||||
url: '/wms/leaveRequest/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询员工请假申请详细
|
||||
export function getLeaveRequest(leaveId) {
|
||||
return request({
|
||||
url: '/wms/leaveRequest/' + leaveId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增员工请假申请
|
||||
export function addLeaveRequest(data) {
|
||||
return request({
|
||||
url: '/wms/leaveRequest',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改员工请假申请
|
||||
export function updateLeaveRequest(data) {
|
||||
return request({
|
||||
url: '/wms/leaveRequest',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除员工请假申请
|
||||
export function delLeaveRequest(leaveId) {
|
||||
return request({
|
||||
url: '/wms/leaveRequest/' + leaveId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
44
klp-ui/src/api/wms/mealReport.js
Normal file
44
klp-ui/src/api/wms/mealReport.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询部门报餐主列表
|
||||
export function listMealReport(query) {
|
||||
return request({
|
||||
url: '/wms/mealReport/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询部门报餐主详细
|
||||
export function getMealReport(reportId) {
|
||||
return request({
|
||||
url: '/wms/mealReport/' + reportId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增部门报餐主
|
||||
export function addMealReport(data) {
|
||||
return request({
|
||||
url: '/wms/mealReport',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改部门报餐主
|
||||
export function updateMealReport(data) {
|
||||
return request({
|
||||
url: '/wms/mealReport',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除部门报餐主
|
||||
export function delMealReport(reportId) {
|
||||
return request({
|
||||
url: '/wms/mealReport/' + reportId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
317
klp-ui/src/components/DictSelect/index.vue
Normal file
317
klp-ui/src/components/DictSelect/index.vue
Normal file
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center;" v-loading="loading">
|
||||
<!-- 下拉选择器:绑定计算属性做双向绑定,保留原有样式+清空功能 -->
|
||||
<el-select v-model="innerValue" :placeholder="placeholder" clearable filterable style="width: 200px;">
|
||||
<el-option
|
||||
v-for="item in dictOptions"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictLabel"
|
||||
:value="item.dictValue"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
<!-- 编辑按钮:点击打开弹窗 -->
|
||||
<div
|
||||
v-if="editable"
|
||||
@click="openDictDialog"
|
||||
style="cursor: pointer; height: 24px; width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
|
||||
>
|
||||
<i class="el-icon-setting"></i>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="refresh"
|
||||
@click="handleRefresh"
|
||||
style="cursor: pointer; height: 24px; width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
|
||||
>
|
||||
<i class="el-icon-refresh"></i>
|
||||
</div>
|
||||
|
||||
<!-- 字典编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-if="editable"
|
||||
:visible.sync="open"
|
||||
title="字典数据配置"
|
||||
width="600px"
|
||||
append-to-body
|
||||
>
|
||||
<!-- 快捷新增表单区域【仅做新增,无编辑功能】 -->
|
||||
<el-form
|
||||
ref="dictFormRef"
|
||||
:model="form"
|
||||
:rules="dictRules"
|
||||
label-width="68px"
|
||||
label-position="left"
|
||||
style="margin-bottom: 20px;"
|
||||
>
|
||||
<el-row :gutter="15">
|
||||
<el-col :span="kisv ? 24 : 12">
|
||||
<el-form-item label="值/标签" prop="dictValue" v-if="kisv">
|
||||
<el-input v-model="form.dictValue" placeholder="请输入字典值(标签自动同步)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字典标签" prop="dictLabel" v-else>
|
||||
<el-input v-model="form.dictLabel" placeholder="请输入字典标签" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="!kisv">
|
||||
<el-form-item label="字典值" prop="dictValue">
|
||||
<el-input v-model="form.dictValue" placeholder="请输入字典值" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<el-button type="primary" size="small" @click="submitAddDict" :loading="btnLoading">新增字典项</el-button>
|
||||
<el-button size="small" @click="resetDictForm">清空表单</el-button>
|
||||
|
||||
<span style="margin-left: 10px;">提示:双击单元格中的文字可以快速编辑</span>
|
||||
</div>
|
||||
|
||||
<!-- 字典列表 ✅核心修改:双击单元格激活输入框,失焦还原文本 -->
|
||||
<el-table
|
||||
:data="dictOptions"
|
||||
border
|
||||
stripe
|
||||
size="mini"
|
||||
style="width: 100%;"
|
||||
empty-text="暂无字典数据"
|
||||
>
|
||||
<!-- 字典标签列:kisv=true隐藏,false正常展示 -->
|
||||
<el-table-column label="字典标签" align="center" v-if="!kisv">
|
||||
<template #default="scope">
|
||||
<!-- 双击span触发编辑,失焦/回车后变回span -->
|
||||
<span
|
||||
v-if="editRowId !== scope.row.dictCode"
|
||||
@dblclick.stop="handleDbEdit(scope.row)"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
{{ scope.row.dictLabel }}
|
||||
</span>
|
||||
<el-input
|
||||
v-else
|
||||
v-model="scope.row.dictLabel"
|
||||
size="mini"
|
||||
style="width: 100%;"
|
||||
@change="handleSaveRow(scope.row)"
|
||||
auto-focus
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 字典值列:kisv=true时标题合并 -->
|
||||
<el-table-column :label="kisv ? '字典值/标签' : '字典值'" align="center">
|
||||
<template #default="scope">
|
||||
<!-- ✅ 核心:默认文本,双击才显示输入框,失焦立刻消失 -->
|
||||
<span
|
||||
v-if="editRowId !== scope.row.dictCode"
|
||||
@dblclick.stop="handleDbEdit(scope.row)"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
{{ scope.row.dictValue }}
|
||||
</span>
|
||||
<el-input
|
||||
v-else
|
||||
v-model="scope.row.dictValue"
|
||||
size="mini"
|
||||
style="width: 100%;"
|
||||
@input="() => handleKisvTableSync(scope.row)"
|
||||
@change="handleSaveRow(scope.row)"
|
||||
auto-focus
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
type="text"
|
||||
text-danger
|
||||
@click="handleDelete(scope.row)"
|
||||
:loading="delBtnLoading === scope.row.dictCode"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDicts, addData, updateData, delData, listData } from '@/api/system/dict/data'
|
||||
import { listType } from '@/api/system/dict/type'
|
||||
|
||||
export default {
|
||||
name: 'DictSelectEdit',
|
||||
props: {
|
||||
dictType: { type: String, default: '' },
|
||||
editable: { type: Boolean, default: true },
|
||||
kisv: { type: Boolean, default: false },
|
||||
value: { type: String, default: '' },
|
||||
placeholder: { type: String, default: '请选择' },
|
||||
refresh: { type: Boolean, default: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
dictId: '',
|
||||
loading: false,
|
||||
btnLoading: false,
|
||||
delBtnLoading: '',
|
||||
open: false,
|
||||
editRowId: '', // 控制当前编辑行,为空则所有单元格都是文本状态
|
||||
form: {
|
||||
dictId: '',
|
||||
dictLabel: '',
|
||||
dictValue: '',
|
||||
dictType: '',
|
||||
sort: 0
|
||||
},
|
||||
dictRules: {
|
||||
dictLabel: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
|
||||
dictValue: [{ required: true, message: '请输入字典值', trigger: 'blur' }]
|
||||
},
|
||||
dictFormRef: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
innerValue: {
|
||||
get() { return this.value },
|
||||
set(val) { this.$emit('input', val) }
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dictType: {
|
||||
async handler(newVal) {
|
||||
if (newVal) {
|
||||
this.loading = true
|
||||
try {
|
||||
const dictId = await this.getDictId(newVal)
|
||||
await this.getDictOptions(dictId)
|
||||
} catch (err) {
|
||||
console.error('加载字典失败:', err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
'form.dictValue': {
|
||||
handler(val) {
|
||||
if (this.kisv && val) this.form.dictLabel = val
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getDictId(type) {
|
||||
const res = await listType({ dictType: type })
|
||||
if (res.rows?.length !== 1) {
|
||||
this.$message.error('字典类型异常,未查询到对应配置')
|
||||
return Promise.reject('字典类型异常')
|
||||
}
|
||||
this.dictId = res.rows[0].dictId
|
||||
return this.dictId
|
||||
},
|
||||
// 新增:刷新字典数据
|
||||
async handleRefresh() {
|
||||
this.loading = true
|
||||
try {
|
||||
await this.getDictOptions(this.dictId)
|
||||
} catch (err) {
|
||||
console.error('刷新字典失败:', err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async getDictOptions(dictId) {
|
||||
const res = await listData({ dictType: this.dictType, pageSize: 1000 })
|
||||
this.dictOptions = res.rows || []
|
||||
return this.dictOptions
|
||||
},
|
||||
openDictDialog() {
|
||||
this.open = true
|
||||
this.resetDictForm()
|
||||
this.form.dictId = this.dictId
|
||||
this.form.dictType = this.dictType
|
||||
this.editRowId = '' // 打开弹窗重置编辑状态
|
||||
},
|
||||
resetDictForm() {
|
||||
this.form = { dictId: this.dictId, dictLabel: '', dictValue: '', dictType: this.dictType, sort: 0 }
|
||||
this.$refs.dictFormRef && this.$refs.dictFormRef.clearValidate()
|
||||
},
|
||||
handleKisvTableSync(row) {
|
||||
if (this.kisv && row.dictValue) row.dictLabel = row.dictValue
|
||||
},
|
||||
async submitAddDict() {
|
||||
const valid = await this.$refs.dictFormRef.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
this.btnLoading = true
|
||||
try {
|
||||
await addData(this.form)
|
||||
this.$message.success('字典项新增成功!')
|
||||
await this.getDictOptions(this.dictId)
|
||||
this.resetDictForm()
|
||||
} catch (err) {
|
||||
this.$message.error('新增失败,请稍后重试')
|
||||
console.error(err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.btnLoading = false
|
||||
}
|
||||
},
|
||||
// ✅ 新增:双击单元格 激活编辑状态 核心方法
|
||||
handleDbEdit(row) {
|
||||
// 同一时间只允许编辑一行,双击其他行关闭当前行编辑
|
||||
this.editRowId = row.dictCode
|
||||
},
|
||||
// ✅ 核心完善:失去焦点/回车 保存数据 + 强制关闭编辑态 → 还原成普通单元格
|
||||
async handleSaveRow(row) {
|
||||
if (!row.dictLabel || !row.dictValue) {
|
||||
this.$message.warning('字典标签和字典值不能为空!')
|
||||
await this.getDictOptions(this.dictId)
|
||||
this.editRowId = '' // 校验失败,也必须还原单元格
|
||||
return
|
||||
}
|
||||
row.sort = 0
|
||||
this.loading = true
|
||||
try {
|
||||
await updateData(row)
|
||||
this.$message.success('字典项修改成功!')
|
||||
} catch (err) {
|
||||
this.$message.error('修改失败,请稍后重试')
|
||||
await this.getDictOptions(this.dictId)
|
||||
console.error(err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.editRowId = '' // ✅必加:保存完成,立刻关闭编辑态,变回文本
|
||||
}
|
||||
},
|
||||
async handleDelete(row) {
|
||||
const confirm = await this.$confirm('确定要删除该字典项吗?删除后不可恢复!', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).catch(() => false)
|
||||
if (!confirm) return
|
||||
this.loading = true
|
||||
this.delBtnLoading = row.dictCode
|
||||
try {
|
||||
await delData(row.dictCode)
|
||||
this.$message.success('删除成功!')
|
||||
await this.getDictOptions(this.dictId)
|
||||
} catch (err) {
|
||||
this.$message.error('删除失败,请稍后重试')
|
||||
console.error(err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.delBtnLoading = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user