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