3 changed files with 576 additions and 0 deletions
@ -0,0 +1,48 @@ |
|||||
|
/** |
||||
|
* 无处罚证明申请主表 api 封装 |
||||
|
* |
||||
|
* @Author: wzh |
||||
|
* @Date: 2026-01-07 21:36:44 |
||||
|
* @Copyright 1.0 |
||||
|
*/ |
||||
|
import { postRequest, getRequest } from '/@/lib/axios'; |
||||
|
|
||||
|
export const penaltyApplyApi = { |
||||
|
|
||||
|
/** |
||||
|
* 分页查询 @author wzh |
||||
|
*/ |
||||
|
queryPage : (param) => { |
||||
|
return postRequest('/penaltyApply/queryPage', param); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 增加 @author wzh |
||||
|
*/ |
||||
|
add: (param) => { |
||||
|
return postRequest('/penaltyApply/add', param); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 修改 @author wzh |
||||
|
*/ |
||||
|
update: (param) => { |
||||
|
return postRequest('/penaltyApply/update', param); |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 删除 @author wzh |
||||
|
*/ |
||||
|
delete: (id) => { |
||||
|
return getRequest(`/penaltyApply/delete/${id}`); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 批量删除 @author wzh |
||||
|
*/ |
||||
|
batchDelete: (idList) => { |
||||
|
return postRequest('/penaltyApply/batchDelete', idList); |
||||
|
}, |
||||
|
|
||||
|
}; |
||||
@ -0,0 +1,138 @@ |
|||||
|
<!-- |
||||
|
* 无处罚证明申请主表 |
||||
|
* |
||||
|
* @Author: wzh |
||||
|
* @Date: 2026-01-07 21:36:44 |
||||
|
* @Copyright 1.0 |
||||
|
--> |
||||
|
<template> |
||||
|
<a-modal |
||||
|
:title="form.id ? '编辑无处罚证明申请' : '新增无处罚证明申请'" |
||||
|
:width="500" |
||||
|
:open="visibleFlag" |
||||
|
@cancel="onClose" |
||||
|
:maskClosable="false" |
||||
|
:destroyOnClose="true" |
||||
|
> |
||||
|
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }" > |
||||
|
<a-form-item label="申请事由" name="usePurpose"> |
||||
|
<a-textarea v-model:value="form.usePurpose" placeholder="请输入申请事由" :rows="4" /> |
||||
|
</a-form-item> |
||||
|
</a-form> |
||||
|
|
||||
|
<template #footer> |
||||
|
<a-space> |
||||
|
<a-button @click="onClose">取消</a-button> |
||||
|
<a-button type="primary" @click="onSubmit">提交申请</a-button> |
||||
|
</a-space> |
||||
|
</template> |
||||
|
</a-modal> |
||||
|
</template> |
||||
|
<script setup> |
||||
|
import { reactive, ref, nextTick, computed } from 'vue'; |
||||
|
import _ from 'lodash'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import { SmartLoading } from '/@/components/framework/smart-loading'; |
||||
|
import { penaltyApplyApi } from '/@/api/business/penalty-apply/penalty-apply-api'; |
||||
|
import { smartSentry } from '/@/lib/smart-sentry'; |
||||
|
import { useUserStore } from '/@/store/modules/system/user'; |
||||
|
import DictSelect from '/@/components/support/dict-select/index.vue'; |
||||
|
|
||||
|
// ------------------------ 事件 ------------------------ |
||||
|
|
||||
|
const emits = defineEmits(['reloadList']); |
||||
|
|
||||
|
// ------------------------ 显示与隐藏 ------------------------ |
||||
|
// 是否显示 |
||||
|
const visibleFlag = ref(false); |
||||
|
|
||||
|
// ------------------------ 用户信息 ------------------------ |
||||
|
const userStore = useUserStore(); |
||||
|
|
||||
|
// 当前用户信息 |
||||
|
const currentUser = computed(() => ({ |
||||
|
userId: userStore.userId, |
||||
|
userName: userStore.actualName, |
||||
|
departmentName: userStore.departmentName |
||||
|
})); |
||||
|
|
||||
|
function show(rowData) { |
||||
|
Object.assign(form, formDefault); |
||||
|
|
||||
|
// 设置默认值 |
||||
|
if (!rowData || _.isEmpty(rowData)) { |
||||
|
// 新增时设置默认值 |
||||
|
form.userId = currentUser.value.userId; |
||||
|
form.userName = currentUser.value.userName; |
||||
|
form.status = 0; // 默认未提交状态 |
||||
|
} else { |
||||
|
// 编辑时加载数据 |
||||
|
Object.assign(form, rowData); |
||||
|
} |
||||
|
|
||||
|
visibleFlag.value = true; |
||||
|
nextTick(() => { |
||||
|
formRef.value.clearValidate(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function onClose() { |
||||
|
Object.assign(form, formDefault); |
||||
|
visibleFlag.value = false; |
||||
|
} |
||||
|
|
||||
|
// ------------------------ 表单 ------------------------ |
||||
|
|
||||
|
// 组件ref |
||||
|
const formRef = ref(); |
||||
|
|
||||
|
const formDefault = { |
||||
|
id: undefined, //申请ID |
||||
|
userId: undefined, //申请人ID |
||||
|
userName: undefined, //申请人姓名 |
||||
|
applyDate: undefined, //申请日期 |
||||
|
usePurpose: undefined, //申请事由 |
||||
|
proofMaterials: undefined, //证明材料 |
||||
|
status: undefined, //状态(0-未提交,1-已提交,2-审核中,3-已批准,5-已驳回) |
||||
|
approvalRemark: undefined, //审批意见 |
||||
|
createTime: undefined, //创建时间 |
||||
|
updateTime: undefined, //更新时间 |
||||
|
}; |
||||
|
|
||||
|
let form = reactive({ ...formDefault }); |
||||
|
|
||||
|
const rules = { |
||||
|
usePurpose: [{ required: true, message: '申请事由 必填' }], |
||||
|
}; |
||||
|
|
||||
|
// ------------------------ 提交申请 ------------------------ |
||||
|
|
||||
|
async function onSubmit() { |
||||
|
try { |
||||
|
await formRef.value.validateFields(); |
||||
|
SmartLoading.show(); |
||||
|
|
||||
|
// 提交申请,状态为1(已提交) |
||||
|
const submitData = { ...form }; |
||||
|
submitData.status = 1; |
||||
|
|
||||
|
if (submitData.id) { |
||||
|
await penaltyApplyApi.update(submitData); |
||||
|
message.success('提交申请成功'); |
||||
|
} else { |
||||
|
await penaltyApplyApi.add(submitData); |
||||
|
message.success('提交申请成功'); |
||||
|
} |
||||
|
onClose(); |
||||
|
emits('reloadList'); |
||||
|
} catch (err) { |
||||
|
smartSentry.captureError(err); |
||||
|
} finally { |
||||
|
SmartLoading.hide(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
defineExpose({ |
||||
|
show, |
||||
|
}); |
||||
|
</script> |
||||
@ -0,0 +1,390 @@ |
|||||
|
<!-- |
||||
|
* 无处罚证明申请主表 |
||||
|
* |
||||
|
* @Author: wzh |
||||
|
* @Date: 2026-01-07 21:36:44 |
||||
|
* @Copyright 1.0 |
||||
|
--> |
||||
|
<template> |
||||
|
<!---------- 查询表单form begin -----------> |
||||
|
<a-form class="smart-query-form"> |
||||
|
<a-row class="smart-query-form-row"> |
||||
|
<a-form-item label="申请人" class="smart-query-form-item"> |
||||
|
<a-input style="width: 150px" v-model:value="queryForm.userName" placeholder="请输入申请人" /> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="申请日期" class="smart-query-form-item"> |
||||
|
<a-range-picker style="width: 250px" v-model:value="applyDateRange" :placeholder="请选择申请日期" /> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="状态" class="smart-query-form-item"> |
||||
|
<a-select style="width: 150px" v-model:value="queryForm.status" placeholder="请选择状态"> |
||||
|
<a-select-option :value="undefined">全部</a-select-option> |
||||
|
<a-select-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value"> |
||||
|
{{ status.desc }} |
||||
|
</a-select-option> |
||||
|
</a-select> |
||||
|
</a-form-item> |
||||
|
<a-form-item class="smart-query-form-item"> |
||||
|
<a-button type="primary" @click="onSearch"> |
||||
|
<template #icon> |
||||
|
<SearchOutlined /> |
||||
|
</template> |
||||
|
查询 |
||||
|
</a-button> |
||||
|
<a-button @click="resetQuery" class="smart-margin-left10"> |
||||
|
<template #icon> |
||||
|
<ReloadOutlined /> |
||||
|
</template> |
||||
|
重置 |
||||
|
</a-button> |
||||
|
</a-form-item> |
||||
|
</a-row> |
||||
|
</a-form> |
||||
|
<!---------- 查询表单form end -----------> |
||||
|
|
||||
|
<a-card size="small" :bordered="false" :hoverable="true"> |
||||
|
<!---------- 表格操作行 begin -----------> |
||||
|
<a-row class="smart-table-btn-block"> |
||||
|
<div class="smart-table-operate-block"> |
||||
|
<a-button @click="showForm" type="primary"> |
||||
|
<template #icon> |
||||
|
<PlusOutlined /> |
||||
|
</template> |
||||
|
新建 |
||||
|
</a-button> |
||||
|
<a-button @click="confirmBatchDelete" type="primary" danger :disabled="selectedRowKeyList.length == 0"> |
||||
|
<template #icon> |
||||
|
<DeleteOutlined /> |
||||
|
</template> |
||||
|
批量删除 |
||||
|
</a-button> |
||||
|
</div> |
||||
|
<div class="smart-table-setting-block"> |
||||
|
<TableOperator v-model="columns" :tableId="null" :refresh="queryData" /> |
||||
|
</div> |
||||
|
</a-row> |
||||
|
<!---------- 表格操作行 end -----------> |
||||
|
|
||||
|
<!---------- 表格 begin -----------> |
||||
|
<a-table |
||||
|
size="small" |
||||
|
:scroll="{ y: 800 }" |
||||
|
:dataSource="tableData" |
||||
|
:columns="columns" |
||||
|
rowKey="id" |
||||
|
bordered |
||||
|
:loading="tableLoading" |
||||
|
:pagination="false" |
||||
|
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }" |
||||
|
> |
||||
|
<template #bodyCell="{ text, record, column }"> |
||||
|
<template v-if="column.dataIndex === 'action'"> |
||||
|
<div class="smart-table-operate"> |
||||
|
<a-space> |
||||
|
<a-button type="link" size="small" @click="showAuditModal(record)" :disabled="record.status !== 1">审批</a-button> |
||||
|
<a-button type="link" size="small" @click="handleDownload(record)" v-if="record.status === 3">下载</a-button> |
||||
|
<a-button type="link" size="small" danger @click="onDelete(record)">删除</a-button> |
||||
|
</a-space> |
||||
|
</div> |
||||
|
</template> |
||||
|
</template> |
||||
|
</a-table> |
||||
|
<!---------- 表格 end -----------> |
||||
|
|
||||
|
<div class="smart-query-table-page"> |
||||
|
<a-pagination |
||||
|
showSizeChanger |
||||
|
showQuickJumper |
||||
|
show-less-items |
||||
|
:pageSizeOptions="PAGE_SIZE_OPTIONS" |
||||
|
:defaultPageSize="queryForm.pageSize" |
||||
|
v-model:current="queryForm.pageNum" |
||||
|
v-model:pageSize="queryForm.pageSize" |
||||
|
:total="total" |
||||
|
@change="queryData" |
||||
|
@showSizeChange="queryData" |
||||
|
:show-total="(total) => `共${total}条`" |
||||
|
/> |
||||
|
</div> |
||||
|
|
||||
|
<PenaltyApplyForm ref="formRef" @reloadList="queryData"/> |
||||
|
|
||||
|
<!-- 审批弹框 --> |
||||
|
<a-modal |
||||
|
title="审批" |
||||
|
:width="500" |
||||
|
:open="auditModalVisible" |
||||
|
:confirm-loading="auditLoading" |
||||
|
@ok="handleAudit" |
||||
|
@cancel="handleAuditCancel" |
||||
|
:maskClosable="false" |
||||
|
> |
||||
|
<a-form :model="auditForm" :label-col="{ span: 6 }"> |
||||
|
<a-form-item label="审批结果" required> |
||||
|
<a-radio-group v-model:value="auditForm.auditResult"> |
||||
|
<a-radio :value="3">同意</a-radio> |
||||
|
<a-radio :value="4">拒绝</a-radio> |
||||
|
</a-radio-group> |
||||
|
</a-form-item> |
||||
|
</a-form> |
||||
|
</a-modal> |
||||
|
|
||||
|
</a-card> |
||||
|
</template> |
||||
|
<script setup> |
||||
|
import { reactive, ref, onMounted } from 'vue'; |
||||
|
import { message, Modal } from 'ant-design-vue'; |
||||
|
import { SmartLoading } from '/@/components/framework/smart-loading'; |
||||
|
import { penaltyApplyApi } from '/@/api/business/penalty-apply/penalty-apply-api'; |
||||
|
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const'; |
||||
|
import { REVIEW_ENUM } from '/@/constants/system/review-const'; |
||||
|
import { smartSentry } from '/@/lib/smart-sentry'; |
||||
|
import TableOperator from '/@/components/support/table-operator/index.vue'; |
||||
|
import PenaltyApplyForm from './penalty-apply-form.vue'; |
||||
|
|
||||
|
// ---------------------------- 表格列 ---------------------------- |
||||
|
|
||||
|
const columns = ref([ |
||||
|
|
||||
|
{ |
||||
|
title: '申请人', |
||||
|
dataIndex: 'userName', |
||||
|
ellipsis: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '申请日期', |
||||
|
dataIndex: 'applyDate', |
||||
|
ellipsis: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '使用用途', |
||||
|
dataIndex: 'usePurpose', |
||||
|
ellipsis: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '状态', |
||||
|
dataIndex: 'status', |
||||
|
ellipsis: true, |
||||
|
customRender: ({ text }) => { |
||||
|
const status = Object.values(REVIEW_ENUM).find(item => item.value === text); |
||||
|
return status ? status.desc : text; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '创建时间', |
||||
|
dataIndex: 'createTime', |
||||
|
ellipsis: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '操作', |
||||
|
dataIndex: 'action', |
||||
|
fixed: 'right', |
||||
|
width: 150, |
||||
|
}, |
||||
|
]); |
||||
|
|
||||
|
// ---------------------------- 查询数据表单和方法 ---------------------------- |
||||
|
|
||||
|
const queryFormState = { |
||||
|
pageNum: 1, |
||||
|
pageSize: 10, |
||||
|
userName: undefined, // 申请人 |
||||
|
applyDateStart: undefined, // 申请日期开始 |
||||
|
applyDateEnd: undefined, // 申请日期结束 |
||||
|
status: undefined, // 状态 |
||||
|
}; |
||||
|
// 查询表单form |
||||
|
const queryForm = reactive({ ...queryFormState }); |
||||
|
// 申请日期范围 |
||||
|
const applyDateRange = ref([]); |
||||
|
// 表格加载loading |
||||
|
const tableLoading = ref(false); |
||||
|
// 表格数据 |
||||
|
const tableData = ref([]); |
||||
|
// 总数 |
||||
|
const total = ref(0); |
||||
|
|
||||
|
// 重置查询条件 |
||||
|
function resetQuery() { |
||||
|
let pageSize = queryForm.pageSize; |
||||
|
Object.assign(queryForm, queryFormState); |
||||
|
queryForm.pageSize = pageSize; |
||||
|
applyDateRange.value = []; |
||||
|
queryData(); |
||||
|
} |
||||
|
|
||||
|
// 搜索 |
||||
|
function onSearch(){ |
||||
|
queryForm.pageNum = 1; |
||||
|
|
||||
|
// 处理申请日期范围 |
||||
|
if (applyDateRange.value && applyDateRange.value.length === 2) { |
||||
|
queryForm.applyDateStart = applyDateRange.value[0] ? applyDateRange.value[0].format('YYYY-MM-DD 00:00:00') : undefined; |
||||
|
queryForm.applyDateEnd = applyDateRange.value[1] ? applyDateRange.value[1].format('YYYY-MM-DD 23:59:59') : undefined; |
||||
|
} else { |
||||
|
queryForm.applyDateStart = undefined; |
||||
|
queryForm.applyDateEnd = undefined; |
||||
|
} |
||||
|
|
||||
|
queryData(); |
||||
|
} |
||||
|
|
||||
|
// 查询数据 |
||||
|
async function queryData() { |
||||
|
tableLoading.value = true; |
||||
|
try { |
||||
|
let queryResult = await penaltyApplyApi.queryPage(queryForm); |
||||
|
tableData.value = queryResult.data.list; |
||||
|
total.value = queryResult.data.total; |
||||
|
} catch (e) { |
||||
|
smartSentry.captureError(e); |
||||
|
} finally { |
||||
|
tableLoading.value = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
onMounted(queryData); |
||||
|
|
||||
|
// ---------------------------- 添加/修改 ---------------------------- |
||||
|
const formRef = ref(); |
||||
|
|
||||
|
function showForm(data) { |
||||
|
formRef.value.show(data); |
||||
|
} |
||||
|
|
||||
|
// ---------------------------- 单个删除 ---------------------------- |
||||
|
//确认删除 |
||||
|
function onDelete(data){ |
||||
|
Modal.confirm({ |
||||
|
title: '提示', |
||||
|
content: '确定要删除选吗?', |
||||
|
okText: '删除', |
||||
|
okType: 'danger', |
||||
|
onOk() { |
||||
|
requestDelete(data); |
||||
|
}, |
||||
|
cancelText: '取消', |
||||
|
onCancel() {}, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//请求删除 |
||||
|
async function requestDelete(data){ |
||||
|
SmartLoading.show(); |
||||
|
try { |
||||
|
let deleteForm = { |
||||
|
goodsIdList: selectedRowKeyList.value, |
||||
|
}; |
||||
|
await penaltyApplyApi.delete(data.id); |
||||
|
message.success('删除成功'); |
||||
|
queryData(); |
||||
|
} catch (e) { |
||||
|
smartSentry.captureError(e); |
||||
|
} finally { |
||||
|
SmartLoading.hide(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ---------------------------- 审批相关 ---------------------------- |
||||
|
// 审批相关状态 |
||||
|
const auditModalVisible = ref(false); |
||||
|
const auditLoading = ref(false); |
||||
|
const currentAuditRecord = ref(null); |
||||
|
const auditForm = reactive({ |
||||
|
auditResult: 3, // 默认同意 |
||||
|
auditRemark: '' |
||||
|
}); |
||||
|
|
||||
|
// 显示审批弹框 |
||||
|
function showAuditModal(record) { |
||||
|
currentAuditRecord.value = record; |
||||
|
auditForm.auditResult = 3; |
||||
|
auditForm.auditRemark = ''; |
||||
|
auditModalVisible.value = true; |
||||
|
} |
||||
|
|
||||
|
// 处理审批 |
||||
|
async function handleAudit() { |
||||
|
if (!currentAuditRecord.value) { |
||||
|
message.error('未选择审批记录'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
auditLoading.value = true; |
||||
|
|
||||
|
const auditData = { |
||||
|
id: currentAuditRecord.value.id, |
||||
|
status: auditForm.auditResult |
||||
|
}; |
||||
|
|
||||
|
if (auditForm.auditRemark) { |
||||
|
auditData.approvalRemark = auditForm.auditRemark; |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
await penaltyApplyApi.update(auditData); |
||||
|
message.success('审批成功'); |
||||
|
auditModalVisible.value = false; |
||||
|
queryData(); |
||||
|
} catch (error) { |
||||
|
message.error('审批失败'); |
||||
|
console.error('审批失败:', error); |
||||
|
} finally { |
||||
|
auditLoading.value = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 取消审批 |
||||
|
function handleAuditCancel() { |
||||
|
auditModalVisible.value = false; |
||||
|
currentAuditRecord.value = null; |
||||
|
auditForm.auditResult = 3; |
||||
|
auditForm.auditRemark = ''; |
||||
|
} |
||||
|
|
||||
|
// ---------------------------- 下载相关 ---------------------------- |
||||
|
// 处理下载 |
||||
|
function handleDownload(record) { |
||||
|
// 这里需要调用下载API |
||||
|
console.log('下载无处罚证明:', record); |
||||
|
message.info('下载功能待实现'); |
||||
|
} |
||||
|
|
||||
|
// ---------------------------- 批量删除 ---------------------------- |
||||
|
|
||||
|
// 选择表格行 |
||||
|
const selectedRowKeyList = ref([]); |
||||
|
|
||||
|
function onSelectChange(selectedRowKeys) { |
||||
|
selectedRowKeyList.value = selectedRowKeys; |
||||
|
} |
||||
|
|
||||
|
// 批量删除 |
||||
|
function confirmBatchDelete() { |
||||
|
Modal.confirm({ |
||||
|
title: '提示', |
||||
|
content: '确定要批量删除这些数据吗?', |
||||
|
okText: '删除', |
||||
|
okType: 'danger', |
||||
|
onOk() { |
||||
|
requestBatchDelete(); |
||||
|
}, |
||||
|
cancelText: '取消', |
||||
|
onCancel() {}, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//请求批量删除 |
||||
|
async function requestBatchDelete() { |
||||
|
try { |
||||
|
SmartLoading.show(); |
||||
|
await penaltyApplyApi.batchDelete(selectedRowKeyList.value); |
||||
|
message.success('删除成功'); |
||||
|
queryData(); |
||||
|
} catch (e) { |
||||
|
smartSentry.captureError(e); |
||||
|
} finally { |
||||
|
SmartLoading.hide(); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
Loading…
Reference in new issue