fix
This commit is contained in:
@@ -1,236 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="qualificationName" label="学历名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalacademicqualificationsconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="qualificationName" label="学历名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="学历名称" prop="qualificationName">
|
||||
<el-input
|
||||
v-model="form.qualificationName"
|
||||
placeholder="请输入学历名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="学历名称" prop="qualificationName">
|
||||
<el-input v-model="form.qualificationName" placeholder="请输入学历名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/academicqualificationsconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/academicqualificationsconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
qualificationName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
qualificationName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
qualificationName: [
|
||||
{ required: true, message: '请输入学历名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
qualificationName: [{ required: true, message: '请输入学历名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
qualificationName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
qualificationName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
qualificationName: row.qualificationName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
qualificationName: row.qualificationName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,51 +1,50 @@
|
||||
<template>
|
||||
<div>
|
||||
<multi-upload
|
||||
ref="commonUploadPicRef"
|
||||
@pushListData="pushListData"
|
||||
@delListData="delListData"
|
||||
:params="params"
|
||||
:fileList="fileList"
|
||||
:limitNums="limitNums"
|
||||
:accept-file="acceptFile"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<multi-upload
|
||||
ref="commonUploadPicRef"
|
||||
@pushListData="pushListData"
|
||||
@delListData="delListData"
|
||||
:params="params"
|
||||
:fileList="fileList"
|
||||
:limitNums="limitNums"
|
||||
:accept-file="acceptFile"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineAsyncComponent } from 'vue';
|
||||
const multiUpload = defineAsyncComponent(() => import('./multiUpload.vue'))
|
||||
const multiUpload = defineAsyncComponent(() => import('./multiUpload.vue'));
|
||||
|
||||
// Props
|
||||
const props = defineProps<{
|
||||
fileList: any[]
|
||||
type?: string
|
||||
params?: any
|
||||
limitNums?: number
|
||||
acceptFile?: string
|
||||
}>()
|
||||
fileList: any[];
|
||||
type?: string;
|
||||
params?: any;
|
||||
limitNums?: number;
|
||||
acceptFile?: string;
|
||||
}>();
|
||||
|
||||
// 组件引用
|
||||
const commonUploadPicRef = ref()
|
||||
const commonUploadPicRef = ref();
|
||||
|
||||
// 推送列表数据
|
||||
const pushListData = (data: { name: string; url: string }) => {
|
||||
props.fileList.push(data)
|
||||
}
|
||||
props.fileList.push(data);
|
||||
};
|
||||
|
||||
// 删除列表数据
|
||||
const delListData = (file: string) => {
|
||||
const index = props.fileList.findIndex((item: any) => item.url === file)
|
||||
if (index > -1) {
|
||||
props.fileList.splice(index, 1)
|
||||
}
|
||||
}
|
||||
const index = props.fileList.findIndex((item: any) => item.url === file);
|
||||
if (index > -1) {
|
||||
props.fileList.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
commonUploadPic: commonUploadPicRef
|
||||
})
|
||||
commonUploadPic: commonUploadPicRef,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -49,36 +49,36 @@ const visible = ref(false);
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
TENANT_ID: Session.getTenant()
|
||||
TENANT_ID: Session.getTenant(),
|
||||
};
|
||||
});
|
||||
|
||||
const uploadUrl = ref('')
|
||||
const currentType = ref('')
|
||||
const uploadRef = ref<{ clearFiles?: () => void }>()
|
||||
const uploadUrl = ref('');
|
||||
const currentType = ref('');
|
||||
const uploadRef = ref<{ clearFiles?: () => void }>();
|
||||
const titleMap: Record<string, string> = {
|
||||
titleRelation: '职称信息导入',
|
||||
quaRelation: '职业资格信息导入',
|
||||
cerRelation: '教师资格证信息导入',
|
||||
eduDegree: '学历学位信息导入',
|
||||
quaRelation: '职业资格信息导入',
|
||||
cerRelation: '教师资格证信息导入',
|
||||
eduDegree: '学历学位信息导入',
|
||||
partyChange: '党组织变动信息导入',
|
||||
honor: '综合表彰信息导入'
|
||||
}
|
||||
honor: '综合表彰信息导入',
|
||||
};
|
||||
// 方法
|
||||
const init = (type: any) => {
|
||||
currentType.value = type
|
||||
uploadUrl.value = '/professional/file/importTeacherOtherInfo?type=' + type
|
||||
title.value = titleMap[type] || '信息导入'
|
||||
visible.value = true
|
||||
currentType.value = type;
|
||||
uploadUrl.value = '/professional/file/importTeacherOtherInfo?type=' + type;
|
||||
title.value = titleMap[type] || '信息导入';
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
uploadRef.value?.clearFiles()
|
||||
})
|
||||
}
|
||||
uploadRef.value?.clearFiles();
|
||||
});
|
||||
};
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
const handleUploadSuccess = () => {
|
||||
visible.value = false;
|
||||
@@ -88,7 +88,7 @@ const handleUploadSuccess = () => {
|
||||
type: 'success',
|
||||
});
|
||||
|
||||
emit('refreshData')
|
||||
emit('refreshData');
|
||||
};
|
||||
|
||||
const handleAvatarError = (err: any) => {
|
||||
@@ -103,8 +103,8 @@ const handleAvatarError = (err: any) => {
|
||||
};
|
||||
|
||||
const handleDownloadTemplate = () => {
|
||||
downBlobFile('/professional/file/exportTeacherInfoTemplate', { type: currentType.value || 'titleRelation' }, title.value+'模板.xlsx')
|
||||
}
|
||||
downBlobFile('/professional/file/exportTeacherInfoTemplate', { type: currentType.value || 'titleRelation' }, title.value + '模板.xlsx');
|
||||
};
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button type="success" icon="view" size="small" @click="handlePdfPreview">预览</el-button>
|
||||
<el-dialog v-model="visible" width="90%" append-to-body destroy-on-close>
|
||||
<auth-img :authSrc="url" style="height:1000px;" v-if="visible" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="success" icon="view" size="small" @click="handlePdfPreview">预览</el-button>
|
||||
<el-dialog v-model="visible" width="90%" append-to-body destroy-on-close>
|
||||
<auth-img :authSrc="url" style="height: 1000px" v-if="visible" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineAsyncComponent } from 'vue'
|
||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'))
|
||||
import { ref, defineAsyncComponent } from 'vue';
|
||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'));
|
||||
|
||||
// Props
|
||||
defineProps<{
|
||||
url: string
|
||||
}>()
|
||||
url: string;
|
||||
}>();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 预览PDF
|
||||
const handlePdfPreview = () => {
|
||||
visible.value = true
|
||||
}
|
||||
visible.value = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -1,115 +1,114 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="/professional/file/teacherAboutInfoUpload"
|
||||
:data="params"
|
||||
:headers="headers"
|
||||
:before-upload="beforeUpload"
|
||||
:on-remove="handleRemove"
|
||||
:on-success="handleUploadSuccess"
|
||||
:file-list="fileList"
|
||||
:accept="realAcceptFile"
|
||||
:limit="realLimitNums"
|
||||
list-type="picture">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<el-tag>仅支持{{realAcceptFile}}后缀的文件上传,且文件大小不能超过5M!最大上传数量限制为{{realLimitNums}}.</el-tag>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div>
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="/professional/file/teacherAboutInfoUpload"
|
||||
:data="params"
|
||||
:headers="headers"
|
||||
:before-upload="beforeUpload"
|
||||
:on-remove="handleRemove"
|
||||
:on-success="handleUploadSuccess"
|
||||
:file-list="fileList"
|
||||
:accept="realAcceptFile"
|
||||
:limit="realLimitNums"
|
||||
list-type="picture"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<el-tag>仅支持{{ realAcceptFile }}后缀的文件上传,且文件大小不能超过5M!最大上传数量限制为{{ realLimitNums }}.</el-tag>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
|
||||
// Props
|
||||
const props = defineProps<{
|
||||
params?: any
|
||||
fileList?: any[]
|
||||
limitNums?: number
|
||||
acceptFile?: string
|
||||
}>()
|
||||
// Props
|
||||
const props = defineProps<{
|
||||
params?: any;
|
||||
fileList?: any[];
|
||||
limitNums?: number;
|
||||
acceptFile?: string;
|
||||
}>();
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
delListData: [url: string]
|
||||
pushListData: [obj: { name: string; url: string }]
|
||||
}>()
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
delListData: [url: string];
|
||||
pushListData: [obj: { name: string; url: string }];
|
||||
}>();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
// 消息提示 hooks
|
||||
const message = useMessage();
|
||||
|
||||
// 响应式数据
|
||||
const realLimitNums = ref(0)
|
||||
const realAcceptFile = ref('.jpg,.jpeg,.png,.pdf')
|
||||
const fileName = ref('')
|
||||
// 响应式数据
|
||||
const realLimitNums = ref(0);
|
||||
const realAcceptFile = ref('.jpg,.jpeg,.png,.pdf');
|
||||
const fileName = ref('');
|
||||
|
||||
// Computed
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
// Computed
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
if (props.limitNums) {
|
||||
realLimitNums.value = props.limitNums
|
||||
} else {
|
||||
realLimitNums.value = 5
|
||||
}
|
||||
if (props.acceptFile) {
|
||||
realAcceptFile.value = props.acceptFile
|
||||
} else {
|
||||
realAcceptFile.value = ".jpg,.jpeg,.png,.pdf"
|
||||
}
|
||||
})
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
if (props.limitNums) {
|
||||
realLimitNums.value = props.limitNums;
|
||||
} else {
|
||||
realLimitNums.value = 5;
|
||||
}
|
||||
if (props.acceptFile) {
|
||||
realAcceptFile.value = props.acceptFile;
|
||||
} else {
|
||||
realAcceptFile.value = '.jpg,.jpeg,.png,.pdf';
|
||||
}
|
||||
});
|
||||
|
||||
// 方法
|
||||
// const handleUploadLimit = () => {
|
||||
// message.error('最多只能上传1张图片')
|
||||
// }
|
||||
// 方法
|
||||
// const handleUploadLimit = () => {
|
||||
// message.error('最多只能上传1张图片')
|
||||
// }
|
||||
|
||||
const beforeUpload = (file: any) => {
|
||||
let fileNameStr = file.name
|
||||
const pos = fileNameStr.lastIndexOf(".")
|
||||
fileNameStr = fileNameStr.substring(pos + 1, fileNameStr.length)
|
||||
fileNameStr = fileNameStr.toLowerCase()
|
||||
const extension = fileNameStr === 'jpg'
|
||||
const extension2 = fileNameStr === 'png'
|
||||
const extension3 = fileNameStr === 'jpeg'
|
||||
const extension4 = fileNameStr === 'bmp'
|
||||
const extension5 = fileNameStr === 'gif'
|
||||
const extension6 = fileNameStr === 'pdf'
|
||||
const isLt2M = file.size / 1024 / 1024 < 5
|
||||
if (!extension && !extension2 && !extension3 && !extension4 && !extension5 && !extension6) {
|
||||
message.warning('请检查文件上传格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传图片大小不能超过 5MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
return true // 返回false不会自动上传
|
||||
}
|
||||
const beforeUpload = (file: any) => {
|
||||
let fileNameStr = file.name;
|
||||
const pos = fileNameStr.lastIndexOf('.');
|
||||
fileNameStr = fileNameStr.substring(pos + 1, fileNameStr.length);
|
||||
fileNameStr = fileNameStr.toLowerCase();
|
||||
const extension = fileNameStr === 'jpg';
|
||||
const extension2 = fileNameStr === 'png';
|
||||
const extension3 = fileNameStr === 'jpeg';
|
||||
const extension4 = fileNameStr === 'bmp';
|
||||
const extension5 = fileNameStr === 'gif';
|
||||
const extension6 = fileNameStr === 'pdf';
|
||||
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||
if (!extension && !extension2 && !extension3 && !extension4 && !extension5 && !extension6) {
|
||||
message.warning('请检查文件上传格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传图片大小不能超过 5MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
return true; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
const handleRemove = (file: any) => {
|
||||
emit("delListData", file.url)
|
||||
}
|
||||
const handleRemove = (file: any) => {
|
||||
emit('delListData', file.url);
|
||||
};
|
||||
|
||||
// const handleUploadError = () => {
|
||||
// message.error('文件上传失败,请检查文件上传格式与大小')
|
||||
// }
|
||||
// const handleUploadError = () => {
|
||||
// message.error('文件上传失败,请检查文件上传格式与大小')
|
||||
// }
|
||||
|
||||
const handleUploadSuccess = (res: any) => {
|
||||
message.success('文件上传成功')
|
||||
const obj = { name: res.data.name, url: res.data.url }
|
||||
emit("pushListData", obj)
|
||||
}
|
||||
const handleUploadSuccess = (res: any) => {
|
||||
message.success('文件上传成功');
|
||||
const obj = { name: res.data.name, url: res.data.url };
|
||||
emit('pushListData', obj);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,158 +1,151 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="驳回" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="姓名 / 工号:">
|
||||
<el-tag>{{ dataForm.name }} - {{ dataForm.teacherNo }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型:">
|
||||
<el-input v-model="typeName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="驳回理由">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="dataForm.backReason"
|
||||
:rows="3"
|
||||
placeholder="请输入驳回理由"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog v-model="visible" title="驳回" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="姓名 / 工号:">
|
||||
<el-tag>{{ dataForm.name }} - {{ dataForm.teacherNo }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型:">
|
||||
<el-input v-model="typeName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="驳回理由">
|
||||
<el-input type="textarea" v-model="dataForm.backReason" :rows="3" placeholder="请输入驳回理由" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button @click="saveData" :loading="loading" type="primary">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button @click="saveData" :loading="loading" type="primary">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { examObj as editTitle } from '/@/api/professional/professionaluser/professionaltitlerelation'
|
||||
import { examObj as editQua } from '/@/api/professional/professionaluser/professionalqualificationrelation'
|
||||
import { examObj as editCer } from '/@/api/professional/professionaluser/professionalteachercertificaterelation'
|
||||
import { examObj as editEducation } from '/@/api/professional/professionaluser/professionalteacheracademicrelation'
|
||||
import { examObj as editHonor } from '/@/api/professional/professionaluser/professionalteacherhonor'
|
||||
import { examObj as editPaper } from '/@/api/professional/professionalteacherpaper'
|
||||
import { examObj as editMaterial } from '/@/api/professional/professionalteachingmaterial'
|
||||
import { examObj as editTopic } from '/@/api/professional/professionaltopiclist'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { examObj as editTitle } from '/@/api/professional/professionaluser/professionaltitlerelation';
|
||||
import { examObj as editQua } from '/@/api/professional/professionaluser/professionalqualificationrelation';
|
||||
import { examObj as editCer } from '/@/api/professional/professionaluser/professionalteachercertificaterelation';
|
||||
import { examObj as editEducation } from '/@/api/professional/professionaluser/professionalteacheracademicrelation';
|
||||
import { examObj as editHonor } from '/@/api/professional/professionaluser/professionalteacherhonor';
|
||||
import { examObj as editPaper } from '/@/api/professional/professionalteacherpaper';
|
||||
import { examObj as editMaterial } from '/@/api/professional/professionalteachingmaterial';
|
||||
import { examObj as editTopic } from '/@/api/professional/professionaltopiclist';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
const loading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
name: '',
|
||||
id: null as string | number | null,
|
||||
backReason: '',
|
||||
teacherNo: ''
|
||||
})
|
||||
name: '',
|
||||
id: null as string | number | null,
|
||||
backReason: '',
|
||||
teacherNo: '',
|
||||
});
|
||||
|
||||
// 类型名称
|
||||
const typeName = ref('')
|
||||
const typeName = ref('');
|
||||
|
||||
// 类型
|
||||
const type = ref('')
|
||||
const type = ref('');
|
||||
|
||||
// 类型映射
|
||||
const typeMap: Record<string, string> = {
|
||||
title: '职称',
|
||||
qua: '职业资格',
|
||||
cer: '教师资格证',
|
||||
education: '学历学位',
|
||||
honor: '综合表彰',
|
||||
paper: '教师论文',
|
||||
material: '教材',
|
||||
topic: '课题'
|
||||
}
|
||||
title: '职称',
|
||||
qua: '职业资格',
|
||||
cer: '教师资格证',
|
||||
education: '学历学位',
|
||||
honor: '综合表彰',
|
||||
paper: '教师论文',
|
||||
material: '教材',
|
||||
topic: '课题',
|
||||
};
|
||||
|
||||
// API 方法映射
|
||||
const apiMethodMap: Record<string, any> = {
|
||||
title: editTitle,
|
||||
qua: editQua,
|
||||
cer: editCer,
|
||||
education: editEducation,
|
||||
honor: editHonor,
|
||||
paper: editPaper,
|
||||
material: editMaterial,
|
||||
topic: editTopic
|
||||
}
|
||||
title: editTitle,
|
||||
qua: editQua,
|
||||
cer: editCer,
|
||||
education: editEducation,
|
||||
honor: editHonor,
|
||||
paper: editPaper,
|
||||
material: editMaterial,
|
||||
topic: editTopic,
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = (row: any, typeValue: string) => {
|
||||
type.value = typeValue
|
||||
typeName.value = typeMap[typeValue] || ''
|
||||
dataForm.name = row.realName || ''
|
||||
dataForm.teacherNo = row.teacherNo || ''
|
||||
dataForm.id = row.id || null
|
||||
dataForm.backReason = ''
|
||||
visible.value = true
|
||||
}
|
||||
type.value = typeValue;
|
||||
typeName.value = typeMap[typeValue] || '';
|
||||
dataForm.name = row.realName || '';
|
||||
dataForm.teacherNo = row.teacherNo || '';
|
||||
dataForm.id = row.id || null;
|
||||
dataForm.backReason = '';
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 保存数据
|
||||
const saveData = async () => {
|
||||
if (!dataForm.backReason.trim()) {
|
||||
message.warning('请填写驳回理由')
|
||||
return
|
||||
}
|
||||
if (!dataForm.backReason.trim()) {
|
||||
message.warning('请填写驳回理由');
|
||||
return;
|
||||
}
|
||||
|
||||
const apiMethod = apiMethodMap[type.value]
|
||||
if (!apiMethod) {
|
||||
message.error('未知的类型')
|
||||
return
|
||||
}
|
||||
const apiMethod = apiMethodMap[type.value];
|
||||
if (!apiMethod) {
|
||||
message.error('未知的类型');
|
||||
return;
|
||||
}
|
||||
|
||||
await saveDataMethod(apiMethod)
|
||||
}
|
||||
await saveDataMethod(apiMethod);
|
||||
};
|
||||
|
||||
// 保存数据方法
|
||||
const saveDataMethod = async (method: any) => {
|
||||
const data = {
|
||||
id: dataForm.id,
|
||||
state: '-2',
|
||||
backReason: dataForm.backReason
|
||||
}
|
||||
const data = {
|
||||
id: dataForm.id,
|
||||
state: '-2',
|
||||
backReason: dataForm.backReason,
|
||||
};
|
||||
|
||||
try {
|
||||
await messageBox.confirm(`确认驳回, ${dataForm.name}的${typeName.value}申请?`)
|
||||
loading.value = true
|
||||
await method(data)
|
||||
message.success('操作成功')
|
||||
visible.value = false
|
||||
emit('refreshData')
|
||||
} catch (error: any) {
|
||||
// 用户取消或请求失败
|
||||
if (error !== 'cancel') {
|
||||
message.error(error?.msg || '操作失败')
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
try {
|
||||
await messageBox.confirm(`确认驳回, ${dataForm.name}的${typeName.value}申请?`);
|
||||
loading.value = true;
|
||||
await method(data);
|
||||
message.success('操作成功');
|
||||
visible.value = false;
|
||||
emit('refreshData');
|
||||
} catch (error: any) {
|
||||
// 用户取消或请求失败
|
||||
if (error !== 'cancel') {
|
||||
message.error(error?.msg || '操作失败');
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,45 +2,45 @@
|
||||
<el-dialog append-to-body v-model="visible" width="90%" height="700px" :title="title">
|
||||
<el-tabs v-model="activeName" type="border-card" tab-position="left">
|
||||
<el-tab-pane label="获奖证书" name="awardImg" v-if="imageData.awardImg">
|
||||
<auth-img v-for="src in imageData.awardImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.awardImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="知网截图" name="knowdgeImg" v-if="imageData.knowdgeImg">
|
||||
<auth-img v-for="src in imageData.knowdgeImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.knowdgeImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="刊物封面" name="pubCover" v-if="imageData.pubCover">
|
||||
<auth-img v-for="src in imageData.pubCover" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.pubCover" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="目录页" name="cateImg" v-if="imageData.cateImg">
|
||||
<auth-img v-for="src in imageData.cateImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.cateImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="内容页" name="contentImg" v-if="imageData.contentImg">
|
||||
<auth-img v-for="src in imageData.contentImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.contentImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="教材封面" name="mateCover" v-if="imageData.mateCover">
|
||||
<auth-img v-for="src in imageData.mateCover" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.mateCover" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="出版页" name="pubImg" v-if="imageData.pubImg">
|
||||
<auth-img v-for="src in imageData.pubImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.pubImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="立项申报书" name="projectApp" v-if="imageData.projectApp">
|
||||
<auth-img v-for="src in imageData.projectApp" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.projectApp" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="结题证书" name="conclusionBook" v-if="imageData.conclusionBook">
|
||||
<auth-img v-for="src in imageData.conclusionBook" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.conclusionBook" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="结题报告" name="conclusionReport" v-if="imageData.conclusionReport">
|
||||
<auth-img v-for="src in imageData.conclusionReport" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.conclusionReport" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="其他材料" name="otherImg" v-if="imageData.otherImg">
|
||||
<auth-img v-for="src in imageData.otherImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
||||
<auth-img v-for="src in imageData.otherImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
<script setup lang="ts" name="showEvidence">
|
||||
import { ref, reactive, nextTick, defineAsyncComponent } from 'vue';
|
||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'))
|
||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'));
|
||||
|
||||
interface ImageItem {
|
||||
url: string;
|
||||
@@ -150,6 +150,4 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,74 +1,72 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" width="90%" append-to-body title="综合表彰材料">
|
||||
<auth-img v-for="src in imgUrl" :key="src.title" :authSrc="src.url" style="height:1000px;"></auth-img>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" width="90%" append-to-body title="综合表彰材料">
|
||||
<auth-img v-for="src in imgUrl" :key="src.title" :authSrc="src.url" style="height: 1000px"></auth-img>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, defineAsyncComponent } from 'vue';
|
||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'))
|
||||
import { ref, nextTick, defineAsyncComponent } from 'vue';
|
||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'));
|
||||
|
||||
interface ImageItem {
|
||||
title: string
|
||||
url: string
|
||||
}
|
||||
interface ImageItem {
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const visible = ref(false)
|
||||
const row = ref<any>({})
|
||||
const pdfSrc = ref('')
|
||||
const imgUrl = ref<ImageItem[]>([])
|
||||
// 响应式数据
|
||||
const visible = ref(false);
|
||||
const row = ref<any>({});
|
||||
const pdfSrc = ref('');
|
||||
const imgUrl = ref<ImageItem[]>([]);
|
||||
|
||||
// 方法(保留以备将来使用)
|
||||
// const checkIsImg = (url: string) => {
|
||||
// if ((url.indexOf('.jpg') == -1)
|
||||
// && (url.indexOf('.jpeg') == -1)
|
||||
// && (url.indexOf('.png') == -1)
|
||||
// && (url.indexOf('.JPG') == -1)
|
||||
// && (url.indexOf('.JPEG') == -1)
|
||||
// && (url.indexOf('.PNG') == -1)) {
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
// 方法(保留以备将来使用)
|
||||
// const checkIsImg = (url: string) => {
|
||||
// if ((url.indexOf('.jpg') == -1)
|
||||
// && (url.indexOf('.jpeg') == -1)
|
||||
// && (url.indexOf('.png') == -1)
|
||||
// && (url.indexOf('.JPG') == -1)
|
||||
// && (url.indexOf('.JPEG') == -1)
|
||||
// && (url.indexOf('.PNG') == -1)) {
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
|
||||
// const downLoadFileForLook = (fileUrl: string, teacherNo: string) => {
|
||||
// const index = fileUrl.indexOf('fileName')
|
||||
// const firstIndex = index + 'fileName'.length + 1
|
||||
// const lastIndex = fileUrl.indexOf('&')
|
||||
// const fileName = fileUrl.substr(firstIndex, lastIndex - firstIndex)
|
||||
// pdfSrc.value = "/professional/file/showPdf?fileName=" + fileName + "&type=attachment&teacherNo=" + teacherNo
|
||||
// }
|
||||
// const downLoadFileForLook = (fileUrl: string, teacherNo: string) => {
|
||||
// const index = fileUrl.indexOf('fileName')
|
||||
// const firstIndex = index + 'fileName'.length + 1
|
||||
// const lastIndex = fileUrl.indexOf('&')
|
||||
// const fileName = fileUrl.substr(firstIndex, lastIndex - firstIndex)
|
||||
// pdfSrc.value = "/professional/file/showPdf?fileName=" + fileName + "&type=attachment&teacherNo=" + teacherNo
|
||||
// }
|
||||
|
||||
const init = (rowData: any) => {
|
||||
row.value = rowData
|
||||
pdfSrc.value = ''
|
||||
imgUrl.value = []
|
||||
nextTick(() => {
|
||||
const obj: ImageItem = {
|
||||
title: "",
|
||||
url: row.value.attachment
|
||||
}
|
||||
imgUrl.value.push(obj)
|
||||
// if(checkIsImg(rowData.attachment)){
|
||||
// const obj: ImageItem = {
|
||||
// title: "",
|
||||
// url: row.value.attachment
|
||||
// }
|
||||
// imgUrl.value.push(obj)
|
||||
// }else{
|
||||
// downLoadFileForLook(rowData.attachment, rowData.teacherNo)
|
||||
// }
|
||||
visible.value = true
|
||||
})
|
||||
}
|
||||
const init = (rowData: any) => {
|
||||
row.value = rowData;
|
||||
pdfSrc.value = '';
|
||||
imgUrl.value = [];
|
||||
nextTick(() => {
|
||||
const obj: ImageItem = {
|
||||
title: '',
|
||||
url: row.value.attachment,
|
||||
};
|
||||
imgUrl.value.push(obj);
|
||||
// if(checkIsImg(rowData.attachment)){
|
||||
// const obj: ImageItem = {
|
||||
// title: "",
|
||||
// url: row.value.attachment
|
||||
// }
|
||||
// imgUrl.value.push(obj)
|
||||
// }else{
|
||||
// downLoadFileForLook(rowData.attachment, rowData.teacherNo)
|
||||
// }
|
||||
visible.value = true;
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 空组件,保留用于未来扩展
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,282 +1,242 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input
|
||||
v-model="state.queryForm.companyName"
|
||||
placeholder="请输入单位名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList">
|
||||
查询
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input v-model="state.queryForm.companyName" placeholder="请输入单位名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList"> 查询 </el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_outercompany_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="允许时段" min-width="250" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime">
|
||||
{{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" align="center" />
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input
|
||||
v-model="form.companyName"
|
||||
placeholder="请输入单位名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="开始时段" prop="allowStartTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowStartTime"
|
||||
type="date"
|
||||
placeholder="请选择开始时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="截止时段" prop="allowEndTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowEndTime"
|
||||
type="date"
|
||||
placeholder="请选择截止时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column label="允许时段" min-width="250" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime"> {{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }} </span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" align="center" />
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_outercompany_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_outercompany_del')" icon="delete" link type="danger" @click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input v-model="form.companyName" placeholder="请输入单位名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="开始时段" prop="allowStartTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowStartTime"
|
||||
type="date"
|
||||
placeholder="请选择开始时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="截止时段" prop="allowEndTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowEndTime"
|
||||
type="date"
|
||||
placeholder="请选择截止时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const queryRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
const queryRef = ref();
|
||||
|
||||
// 搜索显示
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '0'
|
||||
})
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '0',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
companyName: [
|
||||
{ required: true, message: '请输入单位名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
companyName: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '0'
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {
|
||||
companyName: ''
|
||||
}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '0',
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {
|
||||
companyName: '',
|
||||
},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields()
|
||||
getDataList()
|
||||
}
|
||||
queryRef.value?.resetFields();
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '0'
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '0',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
try {
|
||||
const response = await getObj(row.id)
|
||||
Object.assign(form, {
|
||||
id: response.data.id,
|
||||
companyName: response.data.companyName || '',
|
||||
allowStartTime: response.data.allowStartTime || '',
|
||||
allowEndTime: response.data.allowEndTime || '',
|
||||
companyType: response.data.companyType || '0'
|
||||
})
|
||||
dialogVisible.value = true
|
||||
} catch (error) {
|
||||
// 获取详情失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getObj(row.id);
|
||||
Object.assign(form, {
|
||||
id: response.data.id,
|
||||
companyName: response.data.companyName || '',
|
||||
allowStartTime: response.data.allowStartTime || '',
|
||||
allowEndTime: response.data.allowEndTime || '',
|
||||
companyType: response.data.companyType || '0',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
} catch (error) {
|
||||
// 获取详情失败
|
||||
}
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,288 +1,248 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input
|
||||
v-model="state.queryForm.companyName"
|
||||
placeholder="请输入单位名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList">
|
||||
查询
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input v-model="state.queryForm.companyName" placeholder="请输入单位名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList"> 查询 </el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
<!-- <right-toolbar
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_outercompany_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
<!-- <right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10"
|
||||
style="float: right; margin-right: 20px"
|
||||
@queryTable="getDataList"
|
||||
></right-toolbar> -->
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="允许时段" min-width="250" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime">
|
||||
{{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" align="center" />
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input
|
||||
v-model="form.companyName"
|
||||
placeholder="请输入单位名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="开始时段" prop="allowStartTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowStartTime"
|
||||
type="date"
|
||||
placeholder="请选择开始时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="截止时段" prop="allowEndTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowEndTime"
|
||||
type="date"
|
||||
placeholder="请选择截止时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column label="允许时段" min-width="250" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime"> {{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }} </span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" align="center" />
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_outercompany_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_outercompany_del')" icon="delete" link type="danger" @click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input v-model="form.companyName" placeholder="请输入单位名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="开始时段" prop="allowStartTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowStartTime"
|
||||
type="date"
|
||||
placeholder="请选择开始时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="截止时段" prop="allowEndTime">
|
||||
<el-date-picker
|
||||
v-model="form.allowEndTime"
|
||||
type="date"
|
||||
placeholder="请选择截止时段"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const queryRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
const queryRef = ref();
|
||||
|
||||
// 搜索显示
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '2'
|
||||
})
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '2',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
companyName: [
|
||||
{ required: true, message: '请输入单位名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
companyName: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '2'
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {
|
||||
companyName: ''
|
||||
}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '2',
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {
|
||||
companyName: '',
|
||||
},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields()
|
||||
getDataList()
|
||||
}
|
||||
queryRef.value?.resetFields();
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '2'
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
companyName: '',
|
||||
allowStartTime: '',
|
||||
allowEndTime: '',
|
||||
companyType: '2',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
try {
|
||||
const response = await getObj(row.id)
|
||||
Object.assign(form, {
|
||||
id: response.data.id,
|
||||
companyName: response.data.companyName || '',
|
||||
allowStartTime: response.data.allowStartTime || '',
|
||||
allowEndTime: response.data.allowEndTime || '',
|
||||
companyType: response.data.companyType || '2'
|
||||
})
|
||||
dialogVisible.value = true
|
||||
} catch (error) {
|
||||
// 获取详情失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getObj(row.id);
|
||||
Object.assign(form, {
|
||||
id: response.data.id,
|
||||
companyName: response.data.companyName || '',
|
||||
allowStartTime: response.data.allowStartTime || '',
|
||||
allowEndTime: response.data.allowEndTime || '',
|
||||
companyType: response.data.companyType || '2',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
} catch (error) {
|
||||
// 获取详情失败
|
||||
}
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,52 +1,44 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input
|
||||
v-model="state.queryForm.companyName"
|
||||
placeholder="请输入单位名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList">
|
||||
查询
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="单位名称" prop="companyName">
|
||||
<el-input v-model="state.queryForm.companyName" placeholder="请输入单位名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList"> 查询 </el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="允许时段" min-width="250" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime">
|
||||
{{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" align="center" />
|
||||
|
||||
<!-- 操作列已注释,此页面为只读 -->
|
||||
<!-- <el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="允许时段" min-width="250" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime"> {{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }} </span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" align="center" />
|
||||
|
||||
<!-- 操作列已注释,此页面为只读 -->
|
||||
<!-- <el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompany_edit')"
|
||||
@@ -65,58 +57,52 @@
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { fetchList } from '/@/api/professional/stayschool/outercompany'
|
||||
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList } from '/@/api/professional/stayschool/outercompany';
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const queryRef = ref()
|
||||
const tableRef = ref();
|
||||
const queryRef = ref();
|
||||
|
||||
// 搜索显示
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '1'
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {
|
||||
companyName: ''
|
||||
}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '1',
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {
|
||||
companyName: '',
|
||||
},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields()
|
||||
getDataList()
|
||||
}
|
||||
queryRef.value?.resetFields();
|
||||
getDataList();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,309 +1,243 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="formData.id ? '修改' : '新增'"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
class="form-content"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="单位名称" prop="companyId">
|
||||
<el-select
|
||||
v-model="formData.companyId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择单位"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in companyList"
|
||||
:key="item.id"
|
||||
:label="item.companyName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职员编号" prop="employeeNo">
|
||||
<el-input
|
||||
v-model="formData.employeeNo"
|
||||
placeholder="系统自动生成"
|
||||
disabled
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="formData.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证" prop="idCard">
|
||||
<el-input
|
||||
v-model="formData.idCard"
|
||||
placeholder="请输入身份证号"
|
||||
clearable
|
||||
maxlength="18"
|
||||
@input="handleIdCardInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input
|
||||
v-model="formData.mobile"
|
||||
type="number"
|
||||
placeholder="请输入手机号"
|
||||
clearable
|
||||
maxlength="11"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职位" prop="position">
|
||||
<el-input
|
||||
v-model="formData.position"
|
||||
placeholder="请输入职位"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="家庭地址" prop="address">
|
||||
<el-input
|
||||
v-model="formData.address"
|
||||
placeholder="请输入家庭地址"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="允许进出" prop="inoutFlag">
|
||||
<el-select
|
||||
v-model="formData.inoutFlag"
|
||||
clearable
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in yesNoDict"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="formData.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="formData.id ? '修改' : '新增'"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" class="form-content">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="单位名称" prop="companyId">
|
||||
<el-select v-model="formData.companyId" filterable clearable placeholder="请选择单位">
|
||||
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职员编号" prop="employeeNo">
|
||||
<el-input v-model="formData.employeeNo" placeholder="系统自动生成" disabled clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="formData.realName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证" prop="idCard">
|
||||
<el-input v-model="formData.idCard" placeholder="请输入身份证号" clearable maxlength="18" @input="handleIdCardInput" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="formData.mobile" type="number" placeholder="请输入手机号" clearable maxlength="11" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职位" prop="position">
|
||||
<el-input v-model="formData.position" placeholder="请输入职位" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="家庭地址" prop="address">
|
||||
<el-input v-model="formData.address" placeholder="请输入家庭地址" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="允许进出" prop="inoutFlag">
|
||||
<el-select v-model="formData.inoutFlag" clearable placeholder="请选择">
|
||||
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="formData.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, putObj } from '/@/api/professional/stayschool/outercompanyemployee'
|
||||
import { ref, watch } from 'vue';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { addObj, putObj } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
formData: {
|
||||
id?: string
|
||||
companyId?: string
|
||||
companyName?: string
|
||||
employeeNo?: string
|
||||
realName?: string
|
||||
idCard?: string
|
||||
mobile?: string
|
||||
position?: string
|
||||
address?: string
|
||||
inoutFlag?: string
|
||||
remarks?: string
|
||||
}
|
||||
companyList: any[]
|
||||
saveApi?: (data: any) => Promise<any> // 自定义保存 API 函数(用于培训单位、二期单位等)
|
||||
modelValue: boolean;
|
||||
formData: {
|
||||
id?: string;
|
||||
companyId?: string;
|
||||
companyName?: string;
|
||||
employeeNo?: string;
|
||||
realName?: string;
|
||||
idCard?: string;
|
||||
mobile?: string;
|
||||
position?: string;
|
||||
address?: string;
|
||||
inoutFlag?: string;
|
||||
remarks?: string;
|
||||
};
|
||||
companyList: any[];
|
||||
saveApi?: (data: any) => Promise<any>; // 自定义保存 API 函数(用于培训单位、二期单位等)
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
formData: () => ({
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
position: '',
|
||||
address: '',
|
||||
inoutFlag: '',
|
||||
remarks: ''
|
||||
}),
|
||||
companyList: () => [],
|
||||
saveApi: undefined
|
||||
})
|
||||
modelValue: false,
|
||||
formData: () => ({
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
position: '',
|
||||
address: '',
|
||||
inoutFlag: '',
|
||||
remarks: '',
|
||||
}),
|
||||
companyList: () => [],
|
||||
saveApi: undefined,
|
||||
});
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'success'): void
|
||||
}>()
|
||||
(e: 'update:modelValue', value: boolean): void;
|
||||
(e: 'success'): void;
|
||||
}>();
|
||||
|
||||
// 字典数据
|
||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const formRef = ref();
|
||||
|
||||
// 提交加载状态
|
||||
const submitLoading = ref(false)
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 弹窗显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
})
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val;
|
||||
}
|
||||
);
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
emit('update:modelValue', val);
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
companyId: [
|
||||
{ required: true, message: '请选择单位', trigger: 'change' }
|
||||
],
|
||||
realName: [
|
||||
{ required: true, message: '请填写姓名', trigger: 'blur' }
|
||||
],
|
||||
idCard: [
|
||||
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
||||
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
||||
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' }
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: '请填写家庭住址', trigger: 'blur' }
|
||||
],
|
||||
inoutFlag: [
|
||||
{ required: true, message: '请选择是否允许进出', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
companyId: [{ required: true, message: '请选择单位', trigger: 'change' }],
|
||||
realName: [{ required: true, message: '请填写姓名', trigger: 'blur' }],
|
||||
idCard: [
|
||||
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
||||
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
||||
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' },
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
|
||||
],
|
||||
address: [{ required: true, message: '请填写家庭住址', trigger: 'blur' }],
|
||||
inoutFlag: [{ required: true, message: '请选择是否允许进出', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
visible.value = false;
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
|
||||
// 身份证号输入限制:只允许数字和X/x,最大长度18
|
||||
const handleIdCardInput = (value: string) => {
|
||||
// 只保留数字和X/x
|
||||
const filtered = value.replace(/[^\dXx]/g, '')
|
||||
if (filtered !== value) {
|
||||
props.formData.idCard = filtered
|
||||
}
|
||||
}
|
||||
// 只保留数字和X/x
|
||||
const filtered = value.replace(/[^\dXx]/g, '');
|
||||
if (filtered !== value) {
|
||||
props.formData.idCard = filtered;
|
||||
}
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 设置单位名称
|
||||
const selectedCompany = props.companyList.find(item => item.id === props.formData.companyId)
|
||||
const submitData = {
|
||||
...props.formData,
|
||||
companyName: selectedCompany?.companyName || ''
|
||||
}
|
||||
|
||||
if (props.formData.id) {
|
||||
await putObj(submitData)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
// 如果提供了自定义保存函数,使用它;否则使用默认的 addObj
|
||||
if (props.saveApi) {
|
||||
await props.saveApi(submitData)
|
||||
} else {
|
||||
await addObj(submitData)
|
||||
}
|
||||
message.success('添加成功')
|
||||
}
|
||||
handleClose()
|
||||
emit('success')
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '操作失败')
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 设置单位名称
|
||||
const selectedCompany = props.companyList.find((item) => item.id === props.formData.companyId);
|
||||
const submitData = {
|
||||
...props.formData,
|
||||
companyName: selectedCompany?.companyName || '',
|
||||
};
|
||||
|
||||
if (props.formData.id) {
|
||||
await putObj(submitData);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
// 如果提供了自定义保存函数,使用它;否则使用默认的 addObj
|
||||
if (props.saveApi) {
|
||||
await props.saveApi(submitData);
|
||||
} else {
|
||||
await addObj(submitData);
|
||||
}
|
||||
message.success('添加成功');
|
||||
}
|
||||
handleClose();
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '操作失败');
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-content {
|
||||
:deep(.el-row) {
|
||||
margin-bottom: 18px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
:deep(.el-row) {
|
||||
margin-bottom: 18px;
|
||||
|
||||
:deep(.el-row .el-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-row .el-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,282 +1,226 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="formData.id ? '修改' : '新增'"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
class="form-content"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班级名称" prop="companyId">
|
||||
<el-select
|
||||
v-model="formData.companyId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择班级"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in companyList"
|
||||
:key="item.id"
|
||||
:label="item.companyName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学员编号" prop="employeeNo">
|
||||
<el-input
|
||||
v-model="formData.employeeNo"
|
||||
placeholder="系统自动生成"
|
||||
disabled
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="formData.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证" prop="idCard">
|
||||
<el-input
|
||||
v-model="formData.idCard"
|
||||
placeholder="请输入身份证号"
|
||||
clearable
|
||||
maxlength="18"
|
||||
@input="handleIdCardInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input
|
||||
v-model="formData.mobile"
|
||||
type="number"
|
||||
placeholder="请输入手机号"
|
||||
clearable
|
||||
maxlength="11"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="允许进出" prop="inoutFlag">
|
||||
<el-select
|
||||
v-model="formData.inoutFlag"
|
||||
clearable
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in yesNoDict"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="formData.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="formData.id ? '修改' : '新增'"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" class="form-content">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班级名称" prop="companyId">
|
||||
<el-select v-model="formData.companyId" filterable clearable placeholder="请选择班级">
|
||||
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学员编号" prop="employeeNo">
|
||||
<el-input v-model="formData.employeeNo" placeholder="系统自动生成" disabled clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="formData.realName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证" prop="idCard">
|
||||
<el-input v-model="formData.idCard" placeholder="请输入身份证号" clearable maxlength="18" @input="handleIdCardInput" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="formData.mobile" type="number" placeholder="请输入手机号" clearable maxlength="11" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="允许进出" prop="inoutFlag">
|
||||
<el-select v-model="formData.inoutFlag" clearable placeholder="请选择">
|
||||
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="formData.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { putObj } from '/@/api/professional/stayschool/outercompanyemployee'
|
||||
import { ref, watch } from 'vue';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { putObj } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
formData: {
|
||||
id?: string
|
||||
companyId?: string
|
||||
companyName?: string
|
||||
employeeNo?: string
|
||||
realName?: string
|
||||
idCard?: string
|
||||
mobile?: string
|
||||
inoutFlag?: string
|
||||
remarks?: string
|
||||
}
|
||||
companyList: any[]
|
||||
saveApi?: (data: any) => Promise<any> // 自定义保存 API 函数
|
||||
modelValue: boolean;
|
||||
formData: {
|
||||
id?: string;
|
||||
companyId?: string;
|
||||
companyName?: string;
|
||||
employeeNo?: string;
|
||||
realName?: string;
|
||||
idCard?: string;
|
||||
mobile?: string;
|
||||
inoutFlag?: string;
|
||||
remarks?: string;
|
||||
};
|
||||
companyList: any[];
|
||||
saveApi?: (data: any) => Promise<any>; // 自定义保存 API 函数
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
formData: () => ({
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
inoutFlag: '',
|
||||
remarks: ''
|
||||
}),
|
||||
companyList: () => [],
|
||||
saveApi: undefined
|
||||
})
|
||||
modelValue: false,
|
||||
formData: () => ({
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
inoutFlag: '',
|
||||
remarks: '',
|
||||
}),
|
||||
companyList: () => [],
|
||||
saveApi: undefined,
|
||||
});
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'success'): void
|
||||
}>()
|
||||
(e: 'update:modelValue', value: boolean): void;
|
||||
(e: 'success'): void;
|
||||
}>();
|
||||
|
||||
// 字典数据
|
||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const formRef = ref();
|
||||
|
||||
// 提交加载状态
|
||||
const submitLoading = ref(false)
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 弹窗显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
})
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val;
|
||||
}
|
||||
);
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
emit('update:modelValue', val);
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
companyId: [
|
||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||||
],
|
||||
realName: [
|
||||
{ required: true, message: '请填写姓名', trigger: 'blur' }
|
||||
],
|
||||
idCard: [
|
||||
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
||||
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
||||
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' }
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
||||
],
|
||||
inoutFlag: [
|
||||
{ required: true, message: '请选择是否允许进出', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
companyId: [{ required: true, message: '请选择班级', trigger: 'change' }],
|
||||
realName: [{ required: true, message: '请填写姓名', trigger: 'blur' }],
|
||||
idCard: [
|
||||
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
||||
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
||||
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' },
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
|
||||
],
|
||||
inoutFlag: [{ required: true, message: '请选择是否允许进出', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
visible.value = false;
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
|
||||
// 身份证号输入限制:只允许数字和X/x,最大长度18
|
||||
const handleIdCardInput = (value: string) => {
|
||||
// 只保留数字和X/x
|
||||
const filtered = value.replace(/[^\dXx]/g, '')
|
||||
if (filtered !== value) {
|
||||
props.formData.idCard = filtered
|
||||
}
|
||||
}
|
||||
// 只保留数字和X/x
|
||||
const filtered = value.replace(/[^\dXx]/g, '');
|
||||
if (filtered !== value) {
|
||||
props.formData.idCard = filtered;
|
||||
}
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 设置班级名称
|
||||
const selectedCompany = props.companyList.find(item => item.id === props.formData.companyId)
|
||||
const submitData = {
|
||||
...props.formData,
|
||||
companyName: selectedCompany?.companyName || ''
|
||||
}
|
||||
|
||||
if (props.formData.id) {
|
||||
await putObj(submitData)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
// 使用自定义保存函数
|
||||
if (props.saveApi) {
|
||||
await props.saveApi(submitData)
|
||||
} else {
|
||||
message.error('请提供保存 API 函数')
|
||||
return
|
||||
}
|
||||
message.success('添加成功')
|
||||
}
|
||||
handleClose()
|
||||
emit('success')
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '操作失败')
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 设置班级名称
|
||||
const selectedCompany = props.companyList.find((item) => item.id === props.formData.companyId);
|
||||
const submitData = {
|
||||
...props.formData,
|
||||
companyName: selectedCompany?.companyName || '',
|
||||
};
|
||||
|
||||
if (props.formData.id) {
|
||||
await putObj(submitData);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
// 使用自定义保存函数
|
||||
if (props.saveApi) {
|
||||
await props.saveApi(submitData);
|
||||
} else {
|
||||
message.error('请提供保存 API 函数');
|
||||
return;
|
||||
}
|
||||
message.success('添加成功');
|
||||
}
|
||||
handleClose();
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '操作失败');
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-content {
|
||||
:deep(.el-row) {
|
||||
margin-bottom: 18px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
:deep(.el-row) {
|
||||
margin-bottom: 18px;
|
||||
|
||||
:deep(.el-row .el-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-row .el-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,92 +1,44 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
||||
<el-form-item label="单位名称" prop="companyId">
|
||||
<el-select
|
||||
v-model="state.queryForm.companyId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择单位"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in companyList"
|
||||
:key="item.id"
|
||||
:label="item.companyName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="职员编号" prop="employeeNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.employeeNo"
|
||||
placeholder="请输入职员编号"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="state.queryForm.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证" prop="idCard">
|
||||
<el-input
|
||||
v-model="state.queryForm.idCard"
|
||||
placeholder="请输入身份证"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input
|
||||
v-model="state.queryForm.mobile"
|
||||
placeholder="请输入手机"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="允许进出" prop="inoutFlag">
|
||||
<el-select
|
||||
v-model="state.queryForm.inoutFlag"
|
||||
clearable
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in yesNoDict"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row shadow="hover" v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
||||
<el-form-item label="单位名称" prop="companyId">
|
||||
<el-select v-model="state.queryForm.companyId" filterable clearable placeholder="请选择单位">
|
||||
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="职员编号" prop="employeeNo">
|
||||
<el-input v-model="state.queryForm.employeeNo" placeholder="请输入职员编号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="state.queryForm.realName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证" prop="idCard">
|
||||
<el-input v-model="state.queryForm.idCard" placeholder="请输入身份证" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="state.queryForm.mobile" placeholder="请输入手机" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="允许进出" prop="inoutFlag">
|
||||
<el-select v-model="state.queryForm.inoutFlag" clearable placeholder="请选择">
|
||||
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompanyemployee_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
class="ml10"
|
||||
@click="handleExportIn"
|
||||
v-if="permission.scope == '1'"
|
||||
>导 入
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button v-if="hasAuth('professional_outercompanyemployee_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
<el-button type="primary" plain icon="UploadFilled" class="ml10" @click="handleExportIn" v-if="permission.scope == '1'">导 入 </el-button>
|
||||
<!-- <el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@@ -101,497 +53,476 @@
|
||||
class="ml10"
|
||||
@click="batchDelect">批量删除
|
||||
</el-button> -->
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="employeeNo" label="职员编号" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realName" label="姓名" min-width="100" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="idCard" label="身份证" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="mobile" label="手机" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
v-if="scope.row.inoutFlag"
|
||||
:type="scope.row.inoutFlag === '1' ? 'success' : 'danger'"
|
||||
>
|
||||
{{ getDictLabel(scope.row.inoutFlag) }}
|
||||
</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="头像" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Picture"
|
||||
@click="handlePictureCardPreview(scope.row.employeeNo)"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column prop="updateTime" label="更新时间" width="180" align="center" /> -->
|
||||
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompanyemployee_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
||||
icon="RefreshLeft"
|
||||
link
|
||||
type="primary"
|
||||
@click="resetPassword(scope.row)">重置密码
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="companyName" label="单位名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="employeeNo" label="职员编号" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realName" label="姓名" min-width="100" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="idCard" label="身份证" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="mobile" label="手机" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.inoutFlag" :type="scope.row.inoutFlag === '1' ? 'success' : 'danger'">
|
||||
{{ getDictLabel(scope.row.inoutFlag) }}
|
||||
</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="头像" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="Picture" @click="handlePictureCardPreview(scope.row.employeeNo)"> 查看 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column prop="updateTime" label="更新时间" width="180" align="center" /> -->
|
||||
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_outercompanyemployee_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
||||
icon="RefreshLeft"
|
||||
link
|
||||
type="primary"
|
||||
@click="resetPassword(scope.row)"
|
||||
>重置密码
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
v-if="hasAuth('professional_outercompanyemployee_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<form-dialog
|
||||
v-model="dialogVisible"
|
||||
:form-data="form"
|
||||
:company-list="companyList"
|
||||
@success="handleFormSuccess"
|
||||
/>
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<form-dialog v-model="dialogVisible" :form-data="form" :company-list="companyList" @success="handleFormSuccess" />
|
||||
|
||||
<!-- 头像预览对话框 -->
|
||||
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
||||
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain;" />
|
||||
</el-dialog>
|
||||
<!-- 头像预览对话框 -->
|
||||
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
||||
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain" />
|
||||
</el-dialog>
|
||||
|
||||
<!-- 导入对话框 -->
|
||||
<el-dialog v-model="dialogViewVisible" title="导入文件" append-to-body>
|
||||
<el-upload
|
||||
class="upload-container"
|
||||
ref="uploadFormRef"
|
||||
action="doUpload"
|
||||
:limit="1"
|
||||
:file-list="filesList"
|
||||
:before-upload="fileUpload"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button type="primary">选取文件</el-button>
|
||||
</template>
|
||||
<a href="outercomanyemployee.xlsx" rel="external nofollow" download="模板" style="margin-left: 20px">
|
||||
<el-button type="success">下载模板</el-button>
|
||||
</a>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传excel文件,且不超过5MB</div>
|
||||
<div class="el-upload__tip">{{ fileName }}</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogViewVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitUpload">导入</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 导入对话框 -->
|
||||
<el-dialog v-model="dialogViewVisible" title="导入文件" append-to-body>
|
||||
<el-upload
|
||||
class="upload-container"
|
||||
ref="uploadFormRef"
|
||||
action="doUpload"
|
||||
:limit="1"
|
||||
:file-list="filesList"
|
||||
:before-upload="fileUpload"
|
||||
:auto-upload="false"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button type="primary">选取文件</el-button>
|
||||
</template>
|
||||
<a href="outercomanyemployee.xlsx" rel="external nofollow" download="模板" style="margin-left: 20px">
|
||||
<el-button type="success">下载模板</el-button>
|
||||
</a>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传excel文件,且不超过5MB</div>
|
||||
<div class="el-upload__tip">{{ fileName }}</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogViewVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitUpload">导入</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { validateNull } from '/@/utils/validate'
|
||||
import axios from 'axios'
|
||||
import request from '/@/utils/request'
|
||||
import {
|
||||
fetchList,
|
||||
getObj,
|
||||
delObj,
|
||||
batchDel,
|
||||
resetPassWord
|
||||
} from '/@/api/professional/stayschool/outercompanyemployee'
|
||||
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany'
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'))
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { validateNull } from '/@/utils/validate';
|
||||
import axios from 'axios';
|
||||
import request from '/@/utils/request';
|
||||
import { fetchList, getObj, delObj, batchDel, resetPassWord } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany';
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 字典数据
|
||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||
|
||||
// 获取字典标签的辅助函数
|
||||
const getDictLabel = (value: string | number) => {
|
||||
const item = yesNoDict.value.find((i: any) => i.value === value)
|
||||
return item ? item.label : ''
|
||||
}
|
||||
const item = yesNoDict.value.find((i: any) => i.value === value);
|
||||
return item ? item.label : '';
|
||||
};
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const queryRef = ref()
|
||||
const uploadFormRef = ref()
|
||||
const tableRef = ref();
|
||||
const queryRef = ref();
|
||||
const uploadFormRef = ref();
|
||||
|
||||
// 搜索显示
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const dialogUploadVisible = ref(false)
|
||||
const dialogViewVisible = ref(false)
|
||||
const exportLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const dialogUploadVisible = ref(false);
|
||||
const dialogViewVisible = ref(false);
|
||||
const exportLoading = ref(false);
|
||||
|
||||
// 选中的行数据
|
||||
const selectList = ref<any[]>([])
|
||||
const selectList = ref<any[]>([]);
|
||||
const permission = reactive({
|
||||
hasPermission: "0",
|
||||
scope: "0"
|
||||
})
|
||||
hasPermission: '0',
|
||||
scope: '0',
|
||||
});
|
||||
|
||||
// 单位列表
|
||||
const companyList = ref<any[]>([])
|
||||
const companyList = ref<any[]>([]);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
position: '',
|
||||
address: '',
|
||||
inoutFlag: '',
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
position: '',
|
||||
address: '',
|
||||
inoutFlag: '',
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 头像相关
|
||||
const dialogImageUrl = ref('')
|
||||
const dialogImageUrl = ref('');
|
||||
|
||||
// 导入相关
|
||||
const fileName = ref('')
|
||||
const filesList = ref<any[]>([])
|
||||
let files: File | null = null
|
||||
|
||||
const fileName = ref('');
|
||||
const filesList = ref<any[]>([]);
|
||||
let files: File | null = null;
|
||||
|
||||
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '0'
|
||||
})
|
||||
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
||||
const dataList = response.data?.data?.dataList || response.data?.dataList || {}
|
||||
permission.hasPermission = response.data?.data?.permission?.hasPermission || "0"
|
||||
permission.scope = response.data?.data?.permission?.scope || "0"
|
||||
return {
|
||||
data: {
|
||||
records: dataList.records || [],
|
||||
total: dataList.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {
|
||||
companyId: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
inoutFlag: ''
|
||||
}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList({
|
||||
...params,
|
||||
companyType: '0',
|
||||
});
|
||||
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
||||
const dataList = response.data?.data?.dataList || response.data?.dataList || {};
|
||||
permission.hasPermission = response.data?.data?.permission?.hasPermission || '0';
|
||||
permission.scope = response.data?.data?.permission?.scope || '0';
|
||||
return {
|
||||
data: {
|
||||
records: dataList.records || [],
|
||||
total: dataList.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {
|
||||
companyId: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
inoutFlag: '',
|
||||
},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 获取单位列表
|
||||
const loadCompanyList = async () => {
|
||||
try {
|
||||
const response = await getCompanyList({ companyType: '0' })
|
||||
companyList.value = response.data || []
|
||||
} catch (error) {
|
||||
// 获取单位列表失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getCompanyList({ companyType: '0' });
|
||||
companyList.value = response.data || [];
|
||||
} catch (error) {
|
||||
// 获取单位列表失败
|
||||
}
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields()
|
||||
getDataList()
|
||||
}
|
||||
queryRef.value?.resetFields();
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 处理搜索
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 多选变化
|
||||
const handleSelectionChange = (selection: any[]) => {
|
||||
selectList.value = selection
|
||||
}
|
||||
selectList.value = selection;
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
position: '',
|
||||
address: '',
|
||||
inoutFlag: '',
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
companyId: '',
|
||||
companyName: '',
|
||||
employeeNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
mobile: '',
|
||||
position: '',
|
||||
address: '',
|
||||
inoutFlag: '',
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
try {
|
||||
const response = await getObj(row.id)
|
||||
const data = response.data
|
||||
Object.assign(form, {
|
||||
id: data.id,
|
||||
companyId: data.companyId || '',
|
||||
companyName: data.companyName || '',
|
||||
employeeNo: data.employeeNo || '',
|
||||
realName: data.realName || '',
|
||||
idCard: data.idCard || '',
|
||||
mobile: data.mobile || '',
|
||||
position: data.position || '',
|
||||
address: data.address || '',
|
||||
inoutFlag: data.inoutFlag || '',
|
||||
remarks: data.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
} catch (error) {
|
||||
// 获取详情失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getObj(row.id);
|
||||
const data = response.data;
|
||||
Object.assign(form, {
|
||||
id: data.id,
|
||||
companyId: data.companyId || '',
|
||||
companyName: data.companyName || '',
|
||||
employeeNo: data.employeeNo || '',
|
||||
realName: data.realName || '',
|
||||
idCard: data.idCard || '',
|
||||
mobile: data.mobile || '',
|
||||
position: data.position || '',
|
||||
address: data.address || '',
|
||||
inoutFlag: data.inoutFlag || '',
|
||||
remarks: data.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
} catch (error) {
|
||||
// 获取详情失败
|
||||
}
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 批量删除
|
||||
const batchDelect = () => {
|
||||
if (selectList.value.length === 0) {
|
||||
message.warning('请至少选择一条数据')
|
||||
return
|
||||
}
|
||||
messageBox.confirm('是否确认删除').then(async () => {
|
||||
await batchDel(selectList.value)
|
||||
message.success('删除成功')
|
||||
selectList.value = []
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
if (selectList.value.length === 0) {
|
||||
message.warning('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除')
|
||||
.then(async () => {
|
||||
await batchDel(selectList.value);
|
||||
message.success('删除成功');
|
||||
selectList.value = [];
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 重置密码
|
||||
const resetPassword = (row: any) => {
|
||||
messageBox.confirm('是否确定重置密码?').then(async () => {
|
||||
try {
|
||||
const response = await resetPassWord(row)
|
||||
const pw = response.data
|
||||
if (!validateNull(pw)) {
|
||||
messageBox.info('重置后密码为: ' + pw)
|
||||
} else {
|
||||
messageBox.error('系统繁忙,请重试')
|
||||
}
|
||||
} catch (error) {
|
||||
// 重置密码失败
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确定重置密码?')
|
||||
.then(async () => {
|
||||
try {
|
||||
const response = await resetPassWord(row);
|
||||
const pw = response.data;
|
||||
if (!validateNull(pw)) {
|
||||
messageBox.info('重置后密码为: ' + pw);
|
||||
} else {
|
||||
messageBox.error('系统繁忙,请重试');
|
||||
}
|
||||
} catch (error) {
|
||||
// 重置密码失败
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 表单提交成功回调
|
||||
const handleFormSuccess = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 获取图片 URL
|
||||
const getImageView = (employeeNo: string) => {
|
||||
const timestamp = Date.parse(new Date().toString())
|
||||
const baseUrl = import.meta.env.VITE_API_URL || ''
|
||||
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`
|
||||
}
|
||||
const timestamp = Date.parse(new Date().toString());
|
||||
const baseUrl = import.meta.env.VITE_API_URL || '';
|
||||
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`;
|
||||
};
|
||||
|
||||
// 预览头像
|
||||
const handlePictureCardPreview = (employeeNo: string) => {
|
||||
dialogImageUrl.value = getImageView(employeeNo)
|
||||
dialogUploadVisible.value = true
|
||||
}
|
||||
|
||||
dialogImageUrl.value = getImageView(employeeNo);
|
||||
dialogUploadVisible.value = true;
|
||||
};
|
||||
|
||||
// 导入
|
||||
const handleExportIn = () => {
|
||||
fileName.value = ""
|
||||
filesList.value = []
|
||||
files = null
|
||||
dialogViewVisible.value = true
|
||||
}
|
||||
fileName.value = '';
|
||||
filesList.value = [];
|
||||
files = null;
|
||||
dialogViewVisible.value = true;
|
||||
};
|
||||
|
||||
// 文件上传验证
|
||||
const fileUpload = (file: File) => {
|
||||
const fileLast = file.name.split('.')
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
||||
const isLt2M = file.size / 1024 / 1024 < 5
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 5MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
files = file
|
||||
return false // 返回false不会自动上传
|
||||
}
|
||||
const fileLast = file.name.split('.');
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 5MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
files = file;
|
||||
return false; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
// 提交导入
|
||||
const submitUpload = async () => {
|
||||
if (!fileName.value || !files) {
|
||||
message.warning('请选择要上传的文件!')
|
||||
return
|
||||
}
|
||||
|
||||
const fileFormData = new FormData()
|
||||
fileFormData.append('file', files, fileName.value)
|
||||
|
||||
try {
|
||||
const response = await request({
|
||||
url: `/professional/file/exportOuterCompanyEmployee?companyType=0`,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (response.code === 0) {
|
||||
message.success('操作成功')
|
||||
dialogViewVisible.value = false
|
||||
getDataList()
|
||||
} else {
|
||||
message.error(response.msg || '导入失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败')
|
||||
}
|
||||
}
|
||||
if (!fileName.value || !files) {
|
||||
message.warning('请选择要上传的文件!');
|
||||
return;
|
||||
}
|
||||
|
||||
const fileFormData = new FormData();
|
||||
fileFormData.append('file', files, fileName.value);
|
||||
|
||||
try {
|
||||
const response = await request({
|
||||
url: `/professional/file/exportOuterCompanyEmployee?companyType=0`,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.code === 0) {
|
||||
message.success('操作成功');
|
||||
dialogViewVisible.value = false;
|
||||
getDataList();
|
||||
} else {
|
||||
message.error(response.msg || '导入失败');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExportScore = async () => {
|
||||
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
||||
message.warning('请选择导出条件')
|
||||
return
|
||||
}
|
||||
|
||||
exportLoading.value = true
|
||||
try {
|
||||
const params = {
|
||||
...state.queryForm,
|
||||
companyType: "0"
|
||||
}
|
||||
|
||||
const response = await axios({
|
||||
method: 'post',
|
||||
url: '/professional/outercompanyemployee/export',
|
||||
data: params,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
const blob = new Blob([response.data])
|
||||
const fileName = '驻校单位人员导出表.xls'
|
||||
const elink = document.createElement('a')
|
||||
elink.download = fileName
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href)
|
||||
document.body.removeChild(elink)
|
||||
message.success('导出成功')
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导出失败')
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
||||
message.warning('请选择导出条件');
|
||||
return;
|
||||
}
|
||||
|
||||
exportLoading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
...state.queryForm,
|
||||
companyType: '0',
|
||||
};
|
||||
|
||||
const response = await axios({
|
||||
method: 'post',
|
||||
url: '/professional/outercompanyemployee/export',
|
||||
data: params,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
const blob = new Blob([response.data]);
|
||||
const fileName = '驻校单位人员导出表.xls';
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
message.success('导出成功');
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导出失败');
|
||||
} finally {
|
||||
exportLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadCompanyList()
|
||||
})
|
||||
loadCompanyList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-container {
|
||||
:deep(.el-upload) {
|
||||
width: 100%;
|
||||
}
|
||||
:deep(.el-upload) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,237 +1,203 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicdegreeconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalacademicdegreeconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="degreeName" label="学位名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicdegreeconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicdegreeconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="degreeName" label="学位名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="学位名称" prop="degreeName">
|
||||
<el-input
|
||||
v-model="form.degreeName"
|
||||
placeholder="请输入学位名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicdegreeconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademicdegreeconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="学位名称" prop="degreeName">
|
||||
<el-input v-model="form.degreeName" placeholder="请输入学位名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalacademicdegreeconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalacademicdegreeconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
degreeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
degreeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
degreeName: [
|
||||
{ required: true, message: '请输入学位名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
degreeName: [{ required: true, message: '请输入学位名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
degreeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
degreeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
degreeName: row.degreeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
degreeName: row.degreeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,237 +1,203 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademiceducationtypeconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalacademiceducationtypeconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="name" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademiceducationtypeconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademiceducationtypeconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="name" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="类型名称" prop="name">
|
||||
<el-input
|
||||
v-model="form.name"
|
||||
placeholder="请输入类型名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademiceducationtypeconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalacademiceducationtypeconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="类型名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入类型名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalacademiceducationtypeconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalacademiceducationtypeconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入类型名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
name: [{ required: true, message: '请输入类型名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
name: row.name || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
name: row.name || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,102 +1,95 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="4">
|
||||
<el-collapse v-model="activeNames">
|
||||
<el-collapse-item title="汇总" name="1">
|
||||
<div v-for="(item, index) in infoList" :key="index">
|
||||
{{ item }}
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-col>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="4">
|
||||
<el-collapse v-model="activeNames">
|
||||
<el-collapse-item title="汇总" name="1">
|
||||
<div v-for="(item, index) in infoList" :key="index">
|
||||
{{ item }}
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="20">
|
||||
<el-tabs v-model="tabsActiveName" @tab-click="handleClick">
|
||||
<el-tab-pane name="1" label="学历"></el-tab-pane>
|
||||
<el-tab-pane name="2" label="职称"></el-tab-pane>
|
||||
<el-tab-pane name="3" label="职业资格"></el-tab-pane>
|
||||
<el-tab-pane name="4" label="教师资格"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-col :span="20">
|
||||
<el-tabs v-model="tabsActiveName" @tab-click="handleClick">
|
||||
<el-tab-pane name="1" label="学历"></el-tab-pane>
|
||||
<el-tab-pane name="2" label="职称"></el-tab-pane>
|
||||
<el-tab-pane name="3" label="职业资格"></el-tab-pane>
|
||||
<el-tab-pane name="4" label="教师资格"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-table :data="tableData" show-summary style="height: 800px; overflow-y: auto;" border>
|
||||
<el-table-column prop="deptName" label="部门/资质(人数)" min-width="150" align="center" />
|
||||
|
||||
<el-table-column
|
||||
v-for="(item, index) in tableHead"
|
||||
:key="index"
|
||||
:prop="item"
|
||||
:label="item"
|
||||
min-width="120"
|
||||
align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row[item] ? scope.row[item] : 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="tableData" show-summary style="height: 800px; overflow-y: auto" border>
|
||||
<el-table-column prop="deptName" label="部门/资质(人数)" min-width="150" align="center" />
|
||||
|
||||
<el-table-column v-for="(item, index) in tableHead" :key="index" :prop="item" :label="item" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row[item] ? scope.row[item] : 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { countInfo } from '/@/api/professional/professionaluser/professionalteacheracademicrelation'
|
||||
import { titleCountInfo } from '/@/api/professional/professionaluser/professionaltitlerelation'
|
||||
import { quaCountInfo } from '/@/api/professional/professionaluser/professionalqualificationrelation'
|
||||
import { cerCountInfo } from '/@/api/professional/professionaluser/professionalteachercertificaterelation'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { countInfo } from '/@/api/professional/professionaluser/professionalteacheracademicrelation';
|
||||
import { titleCountInfo } from '/@/api/professional/professionaluser/professionaltitlerelation';
|
||||
import { quaCountInfo } from '/@/api/professional/professionaluser/professionalqualificationrelation';
|
||||
import { cerCountInfo } from '/@/api/professional/professionaluser/professionalteachercertificaterelation';
|
||||
|
||||
const activeNames = ref(['1'])
|
||||
const tabsActiveName = ref('1')
|
||||
const tableData = ref<any[]>([])
|
||||
const tableHead = ref<string[]>([])
|
||||
const infoList = ref<string[]>([])
|
||||
const activeNames = ref(['1']);
|
||||
const tabsActiveName = ref('1');
|
||||
const tableData = ref<any[]>([]);
|
||||
const tableHead = ref<string[]>([]);
|
||||
const infoList = ref<string[]>([]);
|
||||
|
||||
const init = async () => {
|
||||
try {
|
||||
const res = await countInfo()
|
||||
tableData.value = res.data.data.tableData || []
|
||||
tableHead.value = res.data.data.tableHead || []
|
||||
infoList.value = res.data.data.infoList || []
|
||||
} catch (error) {
|
||||
console.error('Failed to load data:', error)
|
||||
}
|
||||
}
|
||||
try {
|
||||
const res = await countInfo();
|
||||
tableData.value = res.data.data.tableData || [];
|
||||
tableHead.value = res.data.data.tableHead || [];
|
||||
infoList.value = res.data.data.infoList || [];
|
||||
} catch (error) {
|
||||
console.error('Failed to load data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = (tab: any) => {
|
||||
tableData.value = []
|
||||
tableHead.value = []
|
||||
infoList.value = []
|
||||
|
||||
if (tab.name === '1') {
|
||||
init()
|
||||
} else if (tab.name === '2') {
|
||||
titleCountInfo().then(res => {
|
||||
tableData.value = res.data.data.tableData || []
|
||||
tableHead.value = res.data.data.tableHead || []
|
||||
infoList.value = res.data.data.infoList || []
|
||||
})
|
||||
} else if (tab.name === '3') {
|
||||
quaCountInfo().then(res => {
|
||||
tableData.value = res.data.data.tableData || []
|
||||
tableHead.value = res.data.data.tableHead || []
|
||||
infoList.value = res.data.data.infoList || []
|
||||
})
|
||||
} else if (tab.name === '4') {
|
||||
cerCountInfo().then(res => {
|
||||
tableData.value = res.data.data.tableData || []
|
||||
tableHead.value = res.data.data.tableHead || []
|
||||
infoList.value = res.data.data.infoList || []
|
||||
})
|
||||
}
|
||||
}
|
||||
tableData.value = [];
|
||||
tableHead.value = [];
|
||||
infoList.value = [];
|
||||
|
||||
if (tab.name === '1') {
|
||||
init();
|
||||
} else if (tab.name === '2') {
|
||||
titleCountInfo().then((res) => {
|
||||
tableData.value = res.data.data.tableData || [];
|
||||
tableHead.value = res.data.data.tableHead || [];
|
||||
infoList.value = res.data.data.infoList || [];
|
||||
});
|
||||
} else if (tab.name === '3') {
|
||||
quaCountInfo().then((res) => {
|
||||
tableData.value = res.data.data.tableData || [];
|
||||
tableHead.value = res.data.data.tableHead || [];
|
||||
infoList.value = res.data.data.infoList || [];
|
||||
});
|
||||
} else if (tab.name === '4') {
|
||||
cerCountInfo().then((res) => {
|
||||
tableData.value = res.data.data.tableData || [];
|
||||
tableHead.value = res.data.data.tableHead || [];
|
||||
infoList.value = res.data.data.infoList || [];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -1,237 +1,196 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalatstation_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalatstation_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="atStationName" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalatstation_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalatstation_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="atStationName" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="类型名称" prop="atStationName">
|
||||
<el-input
|
||||
v-model="form.atStationName"
|
||||
placeholder="请输入类型名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalatstation_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalatstation_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="类型名称" prop="atStationName">
|
||||
<el-input v-model="form.atStationName" placeholder="请输入类型名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalatstation'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalatstation';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
atStationName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
atStationName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
atStationName: [
|
||||
{ required: true, message: '请输入类型名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
atStationName: [{ required: true, message: '请输入类型名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
atStationName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
atStationName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
atStationName: row.atStationName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
atStationName: row.atStationName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,237 +1,203 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalemploymentnature_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalemploymentnature_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="employmentNatureName" label="用工性质" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalemploymentnature_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalemploymentnature_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="employmentNatureName" label="用工性质" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="用工性质" prop="employmentNatureName">
|
||||
<el-input
|
||||
v-model="form.employmentNatureName"
|
||||
placeholder="请输入用工性质"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalemploymentnature_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalemploymentnature_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="用工性质" prop="employmentNatureName">
|
||||
<el-input v-model="form.employmentNatureName" placeholder="请输入用工性质" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalemploymentnature'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalemploymentnature';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
employmentNatureName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
employmentNatureName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
employmentNatureName: [
|
||||
{ required: true, message: '请输入用工性质', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
employmentNatureName: [{ required: true, message: '请输入用工性质', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
employmentNatureName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
employmentNatureName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
employmentNatureName: row.employmentNatureName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
employmentNatureName: row.employmentNatureName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,238 +1,196 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalmajorstation_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalmajorstation_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="majorStationName" label="职称职务" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalmajorstation_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalmajorstation_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="majorStationName" label="职称职务" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="职称职务" prop="majorStationName">
|
||||
<el-input
|
||||
v-model="form.majorStationName"
|
||||
placeholder="请输入职称职务"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalmajorstation_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalmajorstation_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="职称职务" prop="majorStationName">
|
||||
<el-input v-model="form.majorStationName" placeholder="请输入职称职务" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalmajorstation'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalmajorstation';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
majorStationName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
majorStationName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
majorStationName: [
|
||||
{ required: true, message: '请输入职称职务', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
majorStationName: [{ required: true, message: '请输入职称职务', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
majorStationName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
majorStationName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
majorStationName: row.majorStationName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
majorStationName: row.majorStationName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,237 +1,195 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpaperconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalpaperconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="typeName" label="论文类型" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpaperconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpaperconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="typeName" label="论文类型" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="论文类型" prop="typeName">
|
||||
<el-input
|
||||
v-model="form.typeName"
|
||||
placeholder="请输入论文类型"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalpaperconfig_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpaperconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="论文类型" prop="typeName">
|
||||
<el-input v-model="form.typeName" placeholder="请输入论文类型" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalpaperconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalpaperconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
typeName: [
|
||||
{ required: true, message: '请输入论文类型', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
typeName: [{ required: true, message: '请输入论文类型', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,237 +1,190 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpartybranch_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalpartybranch_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="name" label="类别名字" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注信息" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpartybranch_edit')"
|
||||
type="primary"
|
||||
link
|
||||
icon="EditPen"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalpartybranch_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="Delete"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="name" label="类别名字" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="类别名字" prop="name">
|
||||
<el-input
|
||||
v-model="form.name"
|
||||
placeholder="请输入类别名字"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注信息" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注信息" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalpartybranch_edit')" type="primary" link icon="EditPen" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_professionalpartybranch_del')" type="danger" link icon="Delete" @click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="类别名字" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入类别名字" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注信息" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注信息" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalpartybranch'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalpartybranch';
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入类别名字', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
name: [{ required: true, message: '请输入类别名字', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
name: row.name || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
name: row.name || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,164 +1,147 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
clearable
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="用户名" prop="realName">
|
||||
<el-input v-model="search.realName" clearable placeholder="请输入用户名" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息</el-button
|
||||
>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="oldBranchName" label="原支部名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="branchName" label="现支部名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="partyFee" label="党费" width="120" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.partyFee ? Number(scope.row.partyFee).toFixed(2) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="changeTime" label="变动时间" width="180" align="center" />
|
||||
|
||||
<!-- <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> -->
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="oldBranchName" label="原支部名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="branchName" label="现支部名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="partyFee" label="党费" width="120" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.partyFee ? Number(scope.row.partyFee).toFixed(2) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="changeTime" label="变动时间" width="180" align="center" />
|
||||
|
||||
<!-- <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> -->
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { fetchList } from '/@/api/professional/professionaluser/professionalpartychange'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList } from '/@/api/professional/professionaluser/professionalpartychange';
|
||||
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'));
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
|
||||
// 导入加载状态
|
||||
const exportLoading = ref(false)
|
||||
const importTeacherOtherInfoRef = ref()
|
||||
const exportLoading = ref(false);
|
||||
const importTeacherOtherInfoRef = ref();
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开导入弹窗
|
||||
const handleImportDialog = () => {
|
||||
importTeacherOtherInfoRef.value?.init('partyChange')
|
||||
}
|
||||
importTeacherOtherInfoRef.value?.init('partyChange');
|
||||
};
|
||||
|
||||
// 表格数据由 useTable(createdIsNeed 默认 true)在挂载时自动请求
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,237 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalqualificationconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="levelName" label="等级名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="levelName" label="等级名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="等级名称" prop="levelName">
|
||||
<el-input
|
||||
v-model="form.levelName"
|
||||
placeholder="请输入等级名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="等级名称" prop="levelName">
|
||||
<el-input v-model="form.levelName" placeholder="请输入等级名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalqualificationconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalqualificationconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
levelName: [
|
||||
{ required: true, message: '请输入等级名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
levelName: [{ required: true, message: '请输入等级名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
levelName: row.levelName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
levelName: row.levelName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,313 +1,274 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="修改职业资格" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="职业工种" prop="worker">
|
||||
<el-select
|
||||
v-model="dataForm.worker"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择职业工种"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in workTypeList"
|
||||
:key="item.id"
|
||||
:label="item.workName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-dialog v-model="dialogVisible" title="修改职业资格" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form ref="formRef" :model="dataForm" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="职业工种" prop="worker">
|
||||
<el-select v-model="dataForm.worker" filterable clearable placeholder="请选择职业工种" style="width: 100%">
|
||||
<el-option v-for="item in workTypeList" :key="item.id" :label="item.workName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="等级" prop="qualificationConfigId">
|
||||
<el-select
|
||||
v-model="dataForm.qualificationConfigId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择等级"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in qualificationList"
|
||||
:key="item.id"
|
||||
:label="item.levelName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="等级" prop="qualificationConfigId">
|
||||
<el-select v-model="dataForm.qualificationConfigId" filterable clearable placeholder="请选择等级" style="width: 100%">
|
||||
<el-option v-for="item in qualificationList" :key="item.id" :label="item.levelName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="取证时间" prop="certificateTime">
|
||||
<el-date-picker
|
||||
v-model="dataForm.certificateTime"
|
||||
type="date"
|
||||
placeholder="请选择取证时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="取证时间" prop="certificateTime">
|
||||
<el-date-picker
|
||||
v-model="dataForm.certificateTime"
|
||||
type="date"
|
||||
placeholder="请选择取证时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
clearable
|
||||
show-word-limit
|
||||
maxlength="32"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
clearable
|
||||
show-word-limit
|
||||
maxlength="32"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="材料1" prop="materialA">
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-form-item label="材料1" prop="materialA">
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalqualificationrelation'
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock'
|
||||
import { getLevelList } from '/@/api/professional/rsbase/professionalqualificationconfig'
|
||||
import { getWorkTypeList } from '/@/api/professional/rsbase/professionalworktype'
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalqualificationrelation';
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock';
|
||||
import { getLevelList } from '/@/api/professional/rsbase/professionalqualificationconfig';
|
||||
import { getWorkTypeList } from '/@/api/professional/rsbase/professionalworktype';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref();
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 对话框显示状态(内部管理)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
worker: '',
|
||||
qualificationConfigId: '',
|
||||
certificateTime: '',
|
||||
certificateNumber: '',
|
||||
materialA: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
worker: '',
|
||||
qualificationConfigId: '',
|
||||
certificateTime: '',
|
||||
certificateNumber: '',
|
||||
materialA: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
worker: [
|
||||
{ required: true, message: '请选择职业工种', trigger: 'change' }
|
||||
],
|
||||
qualificationConfigId: [
|
||||
{ required: true, message: '请选择等级', trigger: 'change' }
|
||||
],
|
||||
certificateTime: [
|
||||
{ required: true, message: '请选择取证时间', trigger: 'change' }
|
||||
],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' }
|
||||
],
|
||||
materialA: [
|
||||
{ required: true, message: '请上传证明材料', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
worker: [{ required: true, message: '请选择职业工种', trigger: 'change' }],
|
||||
qualificationConfigId: [{ required: true, message: '请选择等级', trigger: 'change' }],
|
||||
certificateTime: [{ required: true, message: '请选择取证时间', trigger: 'change' }],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' },
|
||||
],
|
||||
materialA: [{ required: true, message: '请上传证明材料', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 基础信息
|
||||
const baseInfoAbout = reactive<{
|
||||
workTypeList: any[]
|
||||
qualificationList: any[]
|
||||
workTypeList: any[];
|
||||
qualificationList: any[];
|
||||
}>({
|
||||
workTypeList: [],
|
||||
qualificationList: []
|
||||
})
|
||||
workTypeList: [],
|
||||
qualificationList: [],
|
||||
});
|
||||
|
||||
// 上传相关
|
||||
const url = ref('')
|
||||
const fileList = ref<any[]>([])
|
||||
const url = ref('');
|
||||
const fileList = ref<any[]>([]);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 显示表单标志
|
||||
const showForm = ref(false)
|
||||
const showForm = ref(false);
|
||||
|
||||
// 计算属性:职业工种列表
|
||||
const workTypeList = computed(() => baseInfoAbout.workTypeList as any[])
|
||||
const workTypeList = computed(() => baseInfoAbout.workTypeList as any[]);
|
||||
|
||||
// 计算属性:资格列表
|
||||
const qualificationList = computed(() => baseInfoAbout.qualificationList as any[])
|
||||
const qualificationList = computed(() => baseInfoAbout.qualificationList as any[]);
|
||||
|
||||
// 初始化字典数据
|
||||
const initDicData = async () => {
|
||||
try {
|
||||
// 使用专门的 API 获取数据(与 index.vue 保持一致)
|
||||
const [levelRes, workRes] = await Promise.all([
|
||||
getLevelList(),
|
||||
getWorkTypeList()
|
||||
])
|
||||
|
||||
// 处理资格等级列表(与 index.vue 保持一致)
|
||||
if (levelRes && levelRes.data) {
|
||||
baseInfoAbout.qualificationList = levelRes.data
|
||||
}
|
||||
|
||||
// 处理工种列表(与 index.vue 保持一致)
|
||||
if (workRes && workRes.data) {
|
||||
baseInfoAbout.workTypeList = workRes.data
|
||||
}
|
||||
} catch (error) {
|
||||
// 获取字典数据失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 使用专门的 API 获取数据(与 index.vue 保持一致)
|
||||
const [levelRes, workRes] = await Promise.all([getLevelList(), getWorkTypeList()]);
|
||||
|
||||
// 处理资格等级列表(与 index.vue 保持一致)
|
||||
if (levelRes && levelRes.data) {
|
||||
baseInfoAbout.qualificationList = levelRes.data;
|
||||
}
|
||||
|
||||
// 处理工种列表(与 index.vue 保持一致)
|
||||
if (workRes && workRes.data) {
|
||||
baseInfoAbout.workTypeList = workRes.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// 获取字典数据失败
|
||||
}
|
||||
};
|
||||
|
||||
// 证书编号输入处理(只允许英文和数字)
|
||||
const handleCertificateNumberInput = (value: string) => {
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '')
|
||||
}
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '');
|
||||
};
|
||||
|
||||
// 文件上传成功
|
||||
const materiaUploadSuccess = (response: any) => {
|
||||
if (response.data && response.data.code === "-1") {
|
||||
message.error("当前不允许上传文件")
|
||||
return
|
||||
}
|
||||
dataForm.evidenceA = response.data.url
|
||||
dataForm.materialA = response.data.url
|
||||
// 上传成功后清除该字段的验证错误
|
||||
formRef.value?.clearValidate('materialA')
|
||||
}
|
||||
if (response.data && response.data.code === '-1') {
|
||||
message.error('当前不允许上传文件');
|
||||
return;
|
||||
}
|
||||
dataForm.evidenceA = response.data.url;
|
||||
dataForm.materialA = response.data.url;
|
||||
// 上传成功后清除该字段的验证错误
|
||||
formRef.value?.clearValidate('materialA');
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openDialog = async (row?: any) => {
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('job')
|
||||
if (lockResponse.data) {
|
||||
message.warning("新增功能已锁定,暂不允许操作")
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=3`
|
||||
fileList.value = []
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
Object.assign(dataForm, {
|
||||
worker: row.worker || '',
|
||||
qualificationConfigId: row.qualificationConfigId || '',
|
||||
certificateTime: row.certificateTime || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
materialA: row.materialA || '',
|
||||
evidenceA: row.evidenceA || '',
|
||||
state: row.state || '',
|
||||
id: row.id || ''
|
||||
})
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
worker: '',
|
||||
qualificationConfigId: '',
|
||||
certificateTime: '',
|
||||
certificateNumber: '',
|
||||
materialA: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
}
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData()
|
||||
showForm.value = true
|
||||
dialogVisible.value = true
|
||||
}
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('job');
|
||||
if (lockResponse.data) {
|
||||
message.warning('新增功能已锁定,暂不允许操作');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=3`;
|
||||
fileList.value = [];
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
Object.assign(dataForm, {
|
||||
worker: row.worker || '',
|
||||
qualificationConfigId: row.qualificationConfigId || '',
|
||||
certificateTime: row.certificateTime || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
materialA: row.materialA || '',
|
||||
evidenceA: row.evidenceA || '',
|
||||
state: row.state || '',
|
||||
id: row.id || '',
|
||||
});
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
worker: '',
|
||||
qualificationConfigId: '',
|
||||
certificateTime: '',
|
||||
certificateNumber: '',
|
||||
materialA: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
}
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData();
|
||||
showForm.value = true;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const dialogSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用同一个接口)
|
||||
// 确保 evidenceA 或 materialA 有值
|
||||
if (!dataForm.evidenceA && dataForm.materialA) {
|
||||
dataForm.evidenceA = dataForm.materialA
|
||||
}
|
||||
|
||||
await addObj(dataForm)
|
||||
message.success(dataForm.id ? "修改成功" : "提交成功")
|
||||
dialogVisible.value = false
|
||||
emit('refreshData')
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用同一个接口)
|
||||
// 确保 evidenceA 或 materialA 有值
|
||||
if (!dataForm.evidenceA && dataForm.materialA) {
|
||||
dataForm.evidenceA = dataForm.materialA;
|
||||
}
|
||||
|
||||
await addObj(dataForm);
|
||||
message.success(dataForm.id ? '修改成功' : '提交成功');
|
||||
dialogVisible.value = false;
|
||||
emit('refreshData');
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化方法(保持兼容性)
|
||||
const init = () => {
|
||||
// 新版本不再需要初始化配置
|
||||
}
|
||||
// 新版本不再需要初始化配置
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog,
|
||||
init
|
||||
})
|
||||
openDialog,
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,445 +1,419 @@
|
||||
<template>
|
||||
<div class="page-cards">
|
||||
<div class="page-wrapper">
|
||||
<!-- 筛选卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<search-form
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select
|
||||
v-model="search.state"
|
||||
clearable
|
||||
placeholder="请选择审核状态"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in professionalState"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
</el-card>
|
||||
<div class="page-cards">
|
||||
<div class="page-wrapper">
|
||||
<!-- 筛选卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<search-form :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select v-model="search.state" clearable placeholder="请选择审核状态">
|
||||
<el-option v-for="item in professionalState" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" clearable placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 列表内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Medal /></el-icon>
|
||||
职业资格信息
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<div class="action-group">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd"
|
||||
>新增</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading"
|
||||
>导出信息</el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息</el-button>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<RightToolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getDataList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 列表内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Medal /></el-icon>
|
||||
职业资格信息
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<div class="action-group">
|
||||
<el-button v-if="hasAuth('professional_professionalqualificationrelation_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading"
|
||||
>导出信息</el-button
|
||||
>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<RightToolbar v-model:showSearch="showSearch" @queryTable="getDataList" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
stripe
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="qualificationConfigId" label="资格等级" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getQualificationLevelName(scope.row.qualificationConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="worker" label="工种" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getWorkTypeName(scope.row.worker) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.evidenceA && scope.row.evidenceA !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.srcList)">查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
stripe
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file
|
||||
v-for="src in imgUrl"
|
||||
:key="src.title"
|
||||
:authSrc="src.url"
|
||||
dialog-title="职业资格材料"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
<el-table-column prop="qualificationConfigId" label="资格等级" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getQualificationLevelName(scope.row.qualificationConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="worker" label="工种" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getWorkTypeName(scope.row.worker) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.evidenceA && scope.row.evidenceA !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.srcList)"
|
||||
>查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalqualificationrelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file v-for="src in imgUrl" :key="src.title" :authSrc="src.url" dialog-title="职业资格材料" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import {
|
||||
fetchList,
|
||||
examObj,
|
||||
delObj} from '/@/api/professional/professionaluser/professionalqualificationrelation'
|
||||
import { getLevelList } from '/@/api/professional/rsbase/professionalqualificationconfig'
|
||||
import { getWorkTypeList } from '/@/api/professional/rsbase/professionalworktype'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { fetchList, examObj, delObj } from '/@/api/professional/professionaluser/professionalqualificationrelation';
|
||||
import { getLevelList } from '/@/api/professional/rsbase/professionalqualificationconfig';
|
||||
import { getWorkTypeList } from '/@/api/professional/rsbase/professionalworktype';
|
||||
import { makeExportTeacherInfoByTypeTask } from '/@/api/professional/professionalfile';
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { Medal } from '@element-plus/icons-vue'
|
||||
const RightToolbar = defineAsyncComponent(() => import('/@/components/RightToolbar/index.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'))
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { Medal } from '@element-plus/icons-vue';
|
||||
const RightToolbar = defineAsyncComponent(() => import('/@/components/RightToolbar/index.vue'));
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'));
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'));
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'));
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'));
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'));
|
||||
|
||||
// 审核状态选项
|
||||
const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS
|
||||
const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS;
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 字典数据
|
||||
const { professional_state: professionalState } = useDict('professional_state')
|
||||
const { professional_state: professionalState } = useDict('professional_state');
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const dataFormRef = ref()
|
||||
const backReasonRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
const backReasonRef = ref();
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
|
||||
// 材料预览
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([])
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([]);
|
||||
|
||||
// 导出/导入加载状态
|
||||
const exportLoading = ref(false)
|
||||
const importTeacherOtherInfoRef = ref()
|
||||
const exportLoading = ref(false);
|
||||
const importTeacherOtherInfoRef = ref();
|
||||
|
||||
// 资格等级和工种列表
|
||||
const qualificationLevelList = ref<any[]>([])
|
||||
const workTypeList = ref<any[]>([])
|
||||
const qualificationLevelList = ref<any[]>([]);
|
||||
const workTypeList = ref<any[]>([]);
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
const records = response.data.records || []
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
v.srcList = []
|
||||
if (v.evidenceA != null) {
|
||||
v.srcList.push(v.evidenceA)
|
||||
}
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
const records = response.data.records || [];
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
v.srcList = [];
|
||||
if (v.evidenceA != null) {
|
||||
v.srcList.push(v.evidenceA);
|
||||
}
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 预览材料
|
||||
// 预览材料
|
||||
const handlePreview = (list: string[]) => {
|
||||
imgUrl.value = []
|
||||
nextTick(() => {
|
||||
list.forEach(v => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
imgUrl.value = [];
|
||||
nextTick(() => {
|
||||
list.forEach((v) => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 审核状态变更
|
||||
const changeState = (row: any, val: number) => {
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过'
|
||||
messageBox.confirm(`是否确认${str}${row.realName}的申请`).then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val
|
||||
})
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {})
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
backReasonRef.value?.init(row, 'qua')
|
||||
}
|
||||
}
|
||||
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过';
|
||||
messageBox
|
||||
.confirm(`是否确认${str}${row.realName}的申请`)
|
||||
.then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val,
|
||||
});
|
||||
message.success('操作成功');
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
backReasonRef.value?.init(row, 'qua');
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
dataFormRef.value?.openDialog()
|
||||
}
|
||||
dataFormRef.value?.openDialog();
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = (row: any) => {
|
||||
dataFormRef.value?.openDialog(row)
|
||||
}
|
||||
dataFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleDownLoadWord = async () => {
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20003' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20003' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
};
|
||||
|
||||
// 获取资格等级名称
|
||||
const getQualificationLevelName = (id: string | number) => {
|
||||
const item = qualificationLevelList.value.find((item: any) => item.id === id)
|
||||
return item ? item.levelName : '-'
|
||||
}
|
||||
const item = qualificationLevelList.value.find((item: any) => item.id === id);
|
||||
return item ? item.levelName : '-';
|
||||
};
|
||||
|
||||
// 获取工种名称
|
||||
const getWorkTypeName = (id: string | number) => {
|
||||
const item = workTypeList.value.find((item: any) => item.id === id)
|
||||
return item ? item.workName : '-'
|
||||
}
|
||||
const item = workTypeList.value.find((item: any) => item.id === id);
|
||||
return item ? item.workName : '-';
|
||||
};
|
||||
|
||||
// 打开导入弹窗
|
||||
const handleImportDialog = () => {
|
||||
importTeacherOtherInfoRef.value?.init('quaRelation')
|
||||
}
|
||||
importTeacherOtherInfoRef.value?.init('quaRelation');
|
||||
};
|
||||
|
||||
// 加载字典数据
|
||||
const loadDictData = async () => {
|
||||
try {
|
||||
// 加载资格等级列表
|
||||
const levelRes = await getLevelList()
|
||||
if (levelRes && levelRes.data) {
|
||||
qualificationLevelList.value = levelRes.data
|
||||
}
|
||||
|
||||
// 加载工种列表
|
||||
const workRes = await getWorkTypeList()
|
||||
if (workRes && workRes.data) {
|
||||
workTypeList.value = workRes.data
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 加载资格等级列表
|
||||
const levelRes = await getLevelList();
|
||||
if (levelRes && levelRes.data) {
|
||||
qualificationLevelList.value = levelRes.data;
|
||||
}
|
||||
|
||||
// 加载工种列表
|
||||
const workRes = await getWorkTypeList();
|
||||
if (workRes && workRes.data) {
|
||||
workTypeList.value = workRes.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化:仅加载下拉字典,表格数据由 useTable(createdIsNeed 默认 true)自动请求
|
||||
onMounted(async () => {
|
||||
await loadDictData()
|
||||
})
|
||||
await loadDictData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,82 +1,80 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 页面标题 -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="margin: 0; font-size: 20px; font-weight: 600; color: #303133;">资格等级统计</h2>
|
||||
</div>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 页面标题 -->
|
||||
<div style="margin-bottom: 20px">
|
||||
<h2 style="margin: 0; font-size: 20px; font-weight: 600; color: #303133">资格等级统计</h2>
|
||||
</div>
|
||||
|
||||
<!-- 图表统计 -->
|
||||
<div style="width: 100%">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="chartRef" style="width: 100%; height: 400px;" :option="chartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="chartData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="name" label="等级" width="180" align="center" />
|
||||
<el-table-column prop="value" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="占比" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图表统计 -->
|
||||
<div style="width: 100%">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="chartRef" style="width: 100%; height: 400px" :option="chartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="chartData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="name" label="等级" width="180" align="center" />
|
||||
<el-table-column prop="value" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="占比" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
import { PieChart } from 'echarts/charts'
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { getChartOption } from '/@/api/professional/professionaluser/professionalqualificationrelation'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import VChart from 'vue-echarts';
|
||||
import { use } from 'echarts/core';
|
||||
import { PieChart } from 'echarts/charts';
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { getChartOption } from '/@/api/professional/professionaluser/professionalqualificationrelation';
|
||||
|
||||
// 注册 ECharts 组件
|
||||
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer])
|
||||
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer]);
|
||||
|
||||
// 图表引用
|
||||
const chartRef = ref()
|
||||
const chartRef = ref();
|
||||
|
||||
// 图表数据
|
||||
const chartOption = ref<any>({})
|
||||
const chartData = ref<any[]>([])
|
||||
const chartOption = ref<any>({});
|
||||
const chartData = ref<any[]>([]);
|
||||
|
||||
// 初始化图表
|
||||
const initChartOption = async () => {
|
||||
try {
|
||||
const response = await getChartOption()
|
||||
chartOption.value = response.data.data.option || {}
|
||||
|
||||
let total = 0
|
||||
if (chartOption.value.series && chartOption.value.series[0] && chartOption.value.series[0].data) {
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
total += item.value || 0
|
||||
})
|
||||
|
||||
chartData.value = []
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = total > 0 ? Number((item.value / total * 100).toFixed(1)) : 0
|
||||
chartData.value.push({
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
rate: `${rate}%`
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load chart data
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getChartOption();
|
||||
chartOption.value = response.data.data.option || {};
|
||||
|
||||
let total = 0;
|
||||
if (chartOption.value.series && chartOption.value.series[0] && chartOption.value.series[0].data) {
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
total += item.value || 0;
|
||||
});
|
||||
|
||||
chartData.value = [];
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = total > 0 ? Number(((item.value / total) * 100).toFixed(1)) : 0;
|
||||
chartData.value.push({
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
rate: `${rate}%`,
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load chart data
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时初始化图表
|
||||
onMounted(() => {
|
||||
initChartOption()
|
||||
})
|
||||
initChartOption();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,236 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationdutylevel_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalstationdutylevel_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="stationDutyLevelName" label="职务级别名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationdutylevel_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationdutylevel_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="stationDutyLevelName" label="职务级别名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="职务级别名称" prop="stationDutyLevelName">
|
||||
<el-input
|
||||
v-model="form.stationDutyLevelName"
|
||||
placeholder="请输入职务级别名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationdutylevel_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationdutylevel_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="职务级别名称" prop="stationDutyLevelName">
|
||||
<el-input v-model="form.stationDutyLevelName" placeholder="请输入职务级别名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalstationdutylevel'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalstationdutylevel';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
stationDutyLevelName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
stationDutyLevelName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
stationDutyLevelName: [
|
||||
{ required: true, message: '请输入职务级别名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
stationDutyLevelName: [{ required: true, message: '请输入职务级别名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
stationDutyLevelName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
stationDutyLevelName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
stationDutyLevelName: row.stationDutyLevelName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
stationDutyLevelName: row.stationDutyLevelName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,236 +1,195 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationtype_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalstationtype_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="typeName" label="岗位类别名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationtype_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationtype_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="typeName" label="岗位类别名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="岗位类别名称" prop="typeName">
|
||||
<el-input
|
||||
v-model="form.typeName"
|
||||
placeholder="请输入岗位类别名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalstationtype_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalstationtype_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="岗位类别名称" prop="typeName">
|
||||
<el-input v-model="form.typeName" placeholder="请输入岗位类别名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalstationtype'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalstationtype';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
typeName: [
|
||||
{ required: true, message: '请输入岗位类别名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
typeName: [{ required: true, message: '请输入岗位类别名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,467 +1,404 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="修改学历学位" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="formRules"
|
||||
:validate-on-rule-change="false"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="毕业时间" prop="graduateTime">
|
||||
<el-date-picker
|
||||
v-model="dataForm.graduateTime"
|
||||
type="date"
|
||||
placeholder="请选择毕业时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-dialog v-model="dialogVisible" title="修改学历学位" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form ref="formRef" :model="dataForm" :rules="formRules" :validate-on-rule-change="false" label-width="120px">
|
||||
<el-form-item label="毕业时间" prop="graduateTime">
|
||||
<el-date-picker
|
||||
v-model="dataForm.graduateTime"
|
||||
type="date"
|
||||
placeholder="请选择毕业时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="教育类型" prop="type">
|
||||
<el-select
|
||||
v-model="dataForm.type"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择教育类型"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in educationTypeList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="教育类型" prop="type">
|
||||
<el-select v-model="dataForm.type" filterable clearable placeholder="请选择教育类型">
|
||||
<el-option v-for="item in educationTypeList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="学历" prop="qualificationConfigId">
|
||||
<el-select
|
||||
v-model="dataForm.qualificationConfigId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择学历"
|
||||
@change="handleQualificationChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in qualificationList"
|
||||
:key="item.id"
|
||||
:label="item.qualificationName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学历" prop="qualificationConfigId">
|
||||
<el-select v-model="dataForm.qualificationConfigId" filterable clearable placeholder="请选择学历" @change="handleQualificationChange">
|
||||
<el-option v-for="item in qualificationList" :key="item.id" :label="item.qualificationName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="学位" prop="degreeConfigId">
|
||||
<el-select
|
||||
v-model="dataForm.degreeConfigId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择学位"
|
||||
@change="handleDegreeChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in degreeList"
|
||||
:key="item.id"
|
||||
:label="item.degreeName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学位" prop="degreeConfigId">
|
||||
<el-select v-model="dataForm.degreeConfigId" filterable clearable placeholder="请选择学位" @change="handleDegreeChange">
|
||||
<el-option v-for="item in degreeList" :key="item.id" :label="item.degreeName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="毕业学校" prop="graduateSchool">
|
||||
<el-input
|
||||
v-model="dataForm.graduateSchool"
|
||||
placeholder="请输入毕业学校"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="毕业学校" prop="graduateSchool">
|
||||
<el-input v-model="dataForm.graduateSchool" placeholder="请输入毕业学校" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所学专业" prop="major">
|
||||
<el-input
|
||||
v-model="dataForm.major"
|
||||
placeholder="请输入所学专业"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="所学专业" prop="major">
|
||||
<el-input v-model="dataForm.major" placeholder="请输入所学专业" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
clearable
|
||||
show-word-limit
|
||||
maxlength="100"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
clearable
|
||||
show-word-limit
|
||||
maxlength="100"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="needQualificationImg" label="学历证书" prop="qualificationImg" required>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="needQualificationImg" label="学历证书" prop="qualificationImg" required>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="needDegreeImg" label="学位证书" prop="degreeImg" required>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileListB"
|
||||
:on-success="materiaUploadSuccessB"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-form-item v-if="needDegreeImg" label="学位证书" prop="degreeImg" required>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileListB"
|
||||
:on-success="materiaUploadSuccessB"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, nextTick } from 'vue'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalteacheracademicrelation'
|
||||
import { getAllTypeList } from '/@/api/professional/rsbase/professionalacademiceducationtypeconfig'
|
||||
import { getQualificationList } from '/@/api/professional/rsbase/academicqualificationsconfig'
|
||||
import { getDegreeList } from '/@/api/professional/rsbase/professionalacademicdegreeconfig'
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock'
|
||||
import { ref, reactive, computed, nextTick } from 'vue';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalteacheracademicrelation';
|
||||
import { getAllTypeList } from '/@/api/professional/rsbase/professionalacademiceducationtypeconfig';
|
||||
import { getQualificationList } from '/@/api/professional/rsbase/academicqualificationsconfig';
|
||||
import { getDegreeList } from '/@/api/professional/rsbase/professionalacademicdegreeconfig';
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref();
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 对话框显示状态(内部管理)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
graduateTime: '',
|
||||
type: '',
|
||||
qualificationConfigId: '',
|
||||
degreeConfigId: '',
|
||||
graduateSchool: '',
|
||||
major: '',
|
||||
certificateNumber: '',
|
||||
qualificationImg: '',
|
||||
degreeImg: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
graduateTime: '',
|
||||
type: '',
|
||||
qualificationConfigId: '',
|
||||
degreeConfigId: '',
|
||||
graduateSchool: '',
|
||||
major: '',
|
||||
certificateNumber: '',
|
||||
qualificationImg: '',
|
||||
degreeImg: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
// 计算属性:是否需要学历证书(选择了学历)
|
||||
const needQualificationImg = computed(() => {
|
||||
return !!dataForm.qualificationConfigId
|
||||
})
|
||||
return !!dataForm.qualificationConfigId;
|
||||
});
|
||||
|
||||
// 计算属性:是否需要学位证书(选择了学位且不等于 -1 或"无")
|
||||
const needDegreeImg = computed(() => {
|
||||
if (!dataForm.degreeConfigId) return false
|
||||
// 检查是否为 -1 或"无"(处理类型转换)
|
||||
const degreeId = String(dataForm.degreeConfigId)
|
||||
if (degreeId === '-1') return false
|
||||
// 检查学位列表中是否有名称为"无"的选项
|
||||
const degreeItem = degreeList.value.find(item => String(item.id) === degreeId)
|
||||
if (degreeItem && degreeItem.degreeName === '无') return false
|
||||
return true
|
||||
})
|
||||
if (!dataForm.degreeConfigId) return false;
|
||||
// 检查是否为 -1 或"无"(处理类型转换)
|
||||
const degreeId = String(dataForm.degreeConfigId);
|
||||
if (degreeId === '-1') return false;
|
||||
// 检查学位列表中是否有名称为"无"的选项
|
||||
const degreeItem = degreeList.value.find((item) => String(item.id) === degreeId);
|
||||
if (degreeItem && degreeItem.degreeName === '无') return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// 验证规则
|
||||
const formRules = computed(() => {
|
||||
const rules: any = {
|
||||
graduateTime: [
|
||||
{ required: true, message: '请选择毕业时间', trigger: 'blur' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择教育类型', trigger: 'blur' }
|
||||
],
|
||||
graduateSchool: [
|
||||
{ required: true, message: '请输入毕业学校', trigger: 'blur' }
|
||||
],
|
||||
major: [
|
||||
{ required: true, message: '请输入所学专业', trigger: 'blur' }
|
||||
],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 只有当需要学历证书时才添加验证规则
|
||||
if (needQualificationImg.value) {
|
||||
rules.qualificationImg = [
|
||||
{ required: true, message: '请上传学历证书', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 只有当需要学位证书时才添加验证规则
|
||||
if (needDegreeImg.value) {
|
||||
rules.degreeImg = [
|
||||
{ required: true, message: '请上传学位证书', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
return rules
|
||||
})
|
||||
const rules: any = {
|
||||
graduateTime: [{ required: true, message: '请选择毕业时间', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '请选择教育类型', trigger: 'blur' }],
|
||||
graduateSchool: [{ required: true, message: '请输入毕业学校', trigger: 'blur' }],
|
||||
major: [{ required: true, message: '请输入所学专业', trigger: 'blur' }],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' },
|
||||
],
|
||||
};
|
||||
|
||||
// 只有当需要学历证书时才添加验证规则
|
||||
if (needQualificationImg.value) {
|
||||
rules.qualificationImg = [{ required: true, message: '请上传学历证书', trigger: 'blur' }];
|
||||
}
|
||||
|
||||
// 只有当需要学位证书时才添加验证规则
|
||||
if (needDegreeImg.value) {
|
||||
rules.degreeImg = [{ required: true, message: '请上传学位证书', trigger: 'blur' }];
|
||||
}
|
||||
|
||||
return rules;
|
||||
});
|
||||
|
||||
// 下拉列表数据
|
||||
const educationTypeList = ref<any[]>([])
|
||||
const qualificationList = ref<any[]>([])
|
||||
const degreeList = ref<any[]>([])
|
||||
const educationTypeList = ref<any[]>([]);
|
||||
const qualificationList = ref<any[]>([]);
|
||||
const degreeList = ref<any[]>([]);
|
||||
|
||||
// 基础信息(简化,只保留需要的)
|
||||
|
||||
// 上传相关
|
||||
const url = ref('')
|
||||
const fileList = ref<any[]>([])
|
||||
const fileListB = ref<any[]>([])
|
||||
const url = ref('');
|
||||
const fileList = ref<any[]>([]);
|
||||
const fileListB = ref<any[]>([]);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 显示表单标志
|
||||
const showForm = ref(false)
|
||||
const showForm = ref(false);
|
||||
|
||||
// 初始化字典数据
|
||||
const initDicData = async () => {
|
||||
try {
|
||||
// 使用专门的 API 获取数据(与 index.vue 保持一致)
|
||||
const [eduRes, quaRes, degRes] = await Promise.all([
|
||||
getAllTypeList(),
|
||||
getQualificationList(),
|
||||
getDegreeList()
|
||||
])
|
||||
|
||||
// 获取教育类型列表
|
||||
if (eduRes && eduRes.data) {
|
||||
educationTypeList.value = eduRes.data
|
||||
}
|
||||
|
||||
// 获取学历列表
|
||||
if (quaRes && quaRes.data) {
|
||||
qualificationList.value = quaRes.data
|
||||
}
|
||||
|
||||
// 获取学位列表
|
||||
if (degRes && degRes.data) {
|
||||
degreeList.value = degRes.data
|
||||
}
|
||||
} catch (error) {
|
||||
// 获取字典数据失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 使用专门的 API 获取数据(与 index.vue 保持一致)
|
||||
const [eduRes, quaRes, degRes] = await Promise.all([getAllTypeList(), getQualificationList(), getDegreeList()]);
|
||||
|
||||
// 获取教育类型列表
|
||||
if (eduRes && eduRes.data) {
|
||||
educationTypeList.value = eduRes.data;
|
||||
}
|
||||
|
||||
// 获取学历列表
|
||||
if (quaRes && quaRes.data) {
|
||||
qualificationList.value = quaRes.data;
|
||||
}
|
||||
|
||||
// 获取学位列表
|
||||
if (degRes && degRes.data) {
|
||||
degreeList.value = degRes.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// 获取字典数据失败
|
||||
}
|
||||
};
|
||||
|
||||
// 证书编号输入处理(只允许英文和数字)
|
||||
const handleCertificateNumberInput = (value: string) => {
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '')
|
||||
}
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '');
|
||||
};
|
||||
|
||||
// 学历改变时的处理
|
||||
const handleQualificationChange = () => {
|
||||
// 如果不需要学历证书,清除学历证书字段、文件列表和验证错误
|
||||
if (!needQualificationImg.value) {
|
||||
dataForm.qualificationImg = ''
|
||||
fileList.value = []
|
||||
formRef.value?.clearValidate('qualificationImg')
|
||||
} else {
|
||||
// 如果需要学历证书,延迟清除验证(等字段显示后)
|
||||
nextTick(() => {
|
||||
formRef.value?.clearValidate('qualificationImg')
|
||||
})
|
||||
}
|
||||
}
|
||||
// 如果不需要学历证书,清除学历证书字段、文件列表和验证错误
|
||||
if (!needQualificationImg.value) {
|
||||
dataForm.qualificationImg = '';
|
||||
fileList.value = [];
|
||||
formRef.value?.clearValidate('qualificationImg');
|
||||
} else {
|
||||
// 如果需要学历证书,延迟清除验证(等字段显示后)
|
||||
nextTick(() => {
|
||||
formRef.value?.clearValidate('qualificationImg');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 学位改变时的处理
|
||||
const handleDegreeChange = () => {
|
||||
// 如果不需要学位证书,清除学位证书字段、文件列表和验证错误
|
||||
if (!needDegreeImg.value) {
|
||||
dataForm.degreeImg = ''
|
||||
fileListB.value = []
|
||||
formRef.value?.clearValidate('degreeImg')
|
||||
} else {
|
||||
// 如果需要学位证书,延迟清除验证(等字段显示后)
|
||||
nextTick(() => {
|
||||
formRef.value?.clearValidate('degreeImg')
|
||||
})
|
||||
}
|
||||
}
|
||||
// 如果不需要学位证书,清除学位证书字段、文件列表和验证错误
|
||||
if (!needDegreeImg.value) {
|
||||
dataForm.degreeImg = '';
|
||||
fileListB.value = [];
|
||||
formRef.value?.clearValidate('degreeImg');
|
||||
} else {
|
||||
// 如果需要学位证书,延迟清除验证(等字段显示后)
|
||||
nextTick(() => {
|
||||
formRef.value?.clearValidate('degreeImg');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 文件上传成功 - 学历证书
|
||||
const materiaUploadSuccess = (response: any) => {
|
||||
if (response.data && response.data.code === "-1") {
|
||||
message.error("当前不允许上传文件")
|
||||
return
|
||||
}
|
||||
dataForm.qualificationImg = response.data.url
|
||||
// 清除验证错误
|
||||
formRef.value?.clearValidate('qualificationImg')
|
||||
}
|
||||
if (response.data && response.data.code === '-1') {
|
||||
message.error('当前不允许上传文件');
|
||||
return;
|
||||
}
|
||||
dataForm.qualificationImg = response.data.url;
|
||||
// 清除验证错误
|
||||
formRef.value?.clearValidate('qualificationImg');
|
||||
};
|
||||
|
||||
// 文件上传成功 - 学位证书
|
||||
const materiaUploadSuccessB = (response: any) => {
|
||||
if (response.data && response.data.code === "-1") {
|
||||
message.error("当前不允许上传文件")
|
||||
return
|
||||
}
|
||||
dataForm.degreeImg = response.data.url
|
||||
// 清除验证错误
|
||||
formRef.value?.clearValidate('degreeImg')
|
||||
}
|
||||
if (response.data && response.data.code === '-1') {
|
||||
message.error('当前不允许上传文件');
|
||||
return;
|
||||
}
|
||||
dataForm.degreeImg = response.data.url;
|
||||
// 清除验证错误
|
||||
formRef.value?.clearValidate('degreeImg');
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openDialog = async (row?: any) => {
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('acade')
|
||||
if (lockResponse.data) {
|
||||
message.warning("新增功能已锁定,暂不允许操作")
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=1`
|
||||
fileList.value = []
|
||||
fileListB.value = []
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
// 确保类型匹配(将 id 转换为字符串或数字,与选项列表保持一致)
|
||||
Object.assign(dataForm, {
|
||||
graduateTime: row.graduateTime || '',
|
||||
type: row.type !== null && row.type !== undefined ? String(row.type) : '',
|
||||
qualificationConfigId: row.qualificationConfigId !== null && row.qualificationConfigId !== undefined ? String(row.qualificationConfigId) : '',
|
||||
degreeConfigId: row.degreeConfigId !== null && row.degreeConfigId !== undefined ? String(row.degreeConfigId) : '',
|
||||
graduateSchool: row.graduateSchool || '',
|
||||
major: row.major || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
qualificationImg: row.qualificationImg || '',
|
||||
degreeImg: row.degreeImg || '',
|
||||
state: row.state || '',
|
||||
id: row.id || ''
|
||||
})
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
graduateTime: '',
|
||||
type: '',
|
||||
qualificationConfigId: '',
|
||||
degreeConfigId: '',
|
||||
graduateSchool: '',
|
||||
major: '',
|
||||
certificateNumber: '',
|
||||
qualificationImg: '',
|
||||
degreeImg: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
}
|
||||
|
||||
// 公共操作:先加载字典数据,再显示对话框
|
||||
await initDicData()
|
||||
// 等待字典数据加载完成后再显示表单,确保选项列表已准备好
|
||||
await nextTick()
|
||||
showForm.value = true
|
||||
dialogVisible.value = true
|
||||
// 对话框打开后,清除所有验证错误,避免立即显示验证提示
|
||||
await nextTick()
|
||||
formRef.value?.clearValidate()
|
||||
}
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('acade');
|
||||
if (lockResponse.data) {
|
||||
message.warning('新增功能已锁定,暂不允许操作');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=1`;
|
||||
fileList.value = [];
|
||||
fileListB.value = [];
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
// 确保类型匹配(将 id 转换为字符串或数字,与选项列表保持一致)
|
||||
Object.assign(dataForm, {
|
||||
graduateTime: row.graduateTime || '',
|
||||
type: row.type !== null && row.type !== undefined ? String(row.type) : '',
|
||||
qualificationConfigId: row.qualificationConfigId !== null && row.qualificationConfigId !== undefined ? String(row.qualificationConfigId) : '',
|
||||
degreeConfigId: row.degreeConfigId !== null && row.degreeConfigId !== undefined ? String(row.degreeConfigId) : '',
|
||||
graduateSchool: row.graduateSchool || '',
|
||||
major: row.major || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
qualificationImg: row.qualificationImg || '',
|
||||
degreeImg: row.degreeImg || '',
|
||||
state: row.state || '',
|
||||
id: row.id || '',
|
||||
});
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
graduateTime: '',
|
||||
type: '',
|
||||
qualificationConfigId: '',
|
||||
degreeConfigId: '',
|
||||
graduateSchool: '',
|
||||
major: '',
|
||||
certificateNumber: '',
|
||||
qualificationImg: '',
|
||||
degreeImg: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
}
|
||||
|
||||
// 公共操作:先加载字典数据,再显示对话框
|
||||
await initDicData();
|
||||
// 等待字典数据加载完成后再显示表单,确保选项列表已准备好
|
||||
await nextTick();
|
||||
showForm.value = true;
|
||||
dialogVisible.value = true;
|
||||
// 对话框打开后,清除所有验证错误,避免立即显示验证提示
|
||||
await nextTick();
|
||||
formRef.value?.clearValidate();
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const dialogSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用)
|
||||
const submitData: any = {
|
||||
graduateTime: dataForm.graduateTime,
|
||||
type: dataForm.type,
|
||||
qualificationConfigId: dataForm.qualificationConfigId,
|
||||
degreeConfigId: dataForm.degreeConfigId,
|
||||
graduateSchool: dataForm.graduateSchool,
|
||||
major: dataForm.major,
|
||||
certificateNumber: dataForm.certificateNumber,
|
||||
qualificationImg: dataForm.qualificationImg,
|
||||
degreeImg: dataForm.degreeImg,
|
||||
state: '' // 待审核
|
||||
}
|
||||
|
||||
// 编辑时需要传递 id
|
||||
if (dataForm.id) {
|
||||
submitData.id = dataForm.id
|
||||
}
|
||||
|
||||
await addObj(submitData)
|
||||
message.success(dataForm.id ? "修改成功" : "提交成功")
|
||||
dialogVisible.value = false
|
||||
emit('refreshData')
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用)
|
||||
const submitData: any = {
|
||||
graduateTime: dataForm.graduateTime,
|
||||
type: dataForm.type,
|
||||
qualificationConfigId: dataForm.qualificationConfigId,
|
||||
degreeConfigId: dataForm.degreeConfigId,
|
||||
graduateSchool: dataForm.graduateSchool,
|
||||
major: dataForm.major,
|
||||
certificateNumber: dataForm.certificateNumber,
|
||||
qualificationImg: dataForm.qualificationImg,
|
||||
degreeImg: dataForm.degreeImg,
|
||||
state: '', // 待审核
|
||||
};
|
||||
|
||||
// 编辑时需要传递 id
|
||||
if (dataForm.id) {
|
||||
submitData.id = dataForm.id;
|
||||
}
|
||||
|
||||
await addObj(submitData);
|
||||
message.success(dataForm.id ? '修改成功' : '提交成功');
|
||||
dialogVisible.value = false;
|
||||
emit('refreshData');
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化方法(保持兼容性)
|
||||
const init = () => {
|
||||
// 新版本不再需要初始化配置
|
||||
}
|
||||
// 新版本不再需要初始化配置
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog,
|
||||
init
|
||||
})
|
||||
openDialog,
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,484 +1,457 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select
|
||||
v-model="search.state"
|
||||
clearable
|
||||
placeholder="请选择审核状态"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in professionalState"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select v-model="search.state" clearable placeholder="请选择审核状态">
|
||||
<el-option v-for="item in professionalState" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" clearable placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading">导出信息
|
||||
</el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog">导入信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalteacheracademicrelation_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading"
|
||||
>导出信息
|
||||
</el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="graduateTime" label="毕业时间" width="180" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.graduateTime ? scope.row.graduateTime.split(' ')[0] : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="type" label="教育类型" min-width="120" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getEducationTypeName(scope.row.type) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="qualificationConfigId" label="学历" min-width="120" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getQualificationName(scope.row.qualificationConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="degreeConfigId" label="学位" min-width="120" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getDegreeName(scope.row.degreeConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<!-- <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> -->
|
||||
|
||||
<el-table-column label="学历证书附件" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.qualificationImg && scope.row.qualificationImg !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.qiList, 1)">查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="学位证书附件" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.degreeImg && scope.row.degreeImg !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.deList, 2)">查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file
|
||||
v-for="src in imgUrl"
|
||||
:key="src.title"
|
||||
:authSrc="src.url"
|
||||
:dialog-title="dialogTitle"
|
||||
/>
|
||||
<el-table-column prop="graduateTime" label="毕业时间" width="180" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.graduateTime ? scope.row.graduateTime.split(' ')[0] : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="type" label="教育类型" min-width="120" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getEducationTypeName(scope.row.type) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="qualificationConfigId" label="学历" min-width="120" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getQualificationName(scope.row.qualificationConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="degreeConfigId" label="学位" min-width="120" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getDegreeName(scope.row.degreeConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column prop="createTime" label="创建时间" width="180" align="center" /> -->
|
||||
|
||||
<el-table-column label="学历证书附件" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.qualificationImg && scope.row.qualificationImg !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.qiList, 1)"
|
||||
>查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="学位证书附件" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.degreeImg && scope.row.degreeImg !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.deList, 2)"
|
||||
>查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)"
|
||||
>编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacheracademicrelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file v-for="src in imgUrl" :key="src.title" :authSrc="src.url" :dialog-title="dialogTitle" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import {
|
||||
fetchList,
|
||||
examObj,
|
||||
delObj} from '/@/api/professional/professionaluser/professionalteacheracademicrelation'
|
||||
import { getDegreeList } from '/@/api/professional/rsbase/professionalacademicdegreeconfig'
|
||||
import { getQualificationList } from '/@/api/professional/rsbase/academicqualificationsconfig'
|
||||
import { getAllTypeList } from '/@/api/professional/rsbase/professionalacademiceducationtypeconfig'
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import {makeExportTeacherInfoByTypeTask} from "/@/api/professional/professionalfile";
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'))
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { fetchList, examObj, delObj } from '/@/api/professional/professionaluser/professionalteacheracademicrelation';
|
||||
import { getDegreeList } from '/@/api/professional/rsbase/professionalacademicdegreeconfig';
|
||||
import { getQualificationList } from '/@/api/professional/rsbase/academicqualificationsconfig';
|
||||
import { getAllTypeList } from '/@/api/professional/rsbase/professionalacademiceducationtypeconfig';
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { makeExportTeacherInfoByTypeTask } from '/@/api/professional/professionalfile';
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'));
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'));
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'));
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'));
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'));
|
||||
|
||||
// 审核状态选项
|
||||
const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS
|
||||
const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS;
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 字典数据
|
||||
const { professional_state: professionalState } = useDict('professional_state')
|
||||
const { professional_state: professionalState } = useDict('professional_state');
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const dataFormRef = ref()
|
||||
const backReasonRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
const backReasonRef = ref();
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
|
||||
// 材料预览
|
||||
const dialogTitle = ref('')
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([])
|
||||
const dialogTitle = ref('');
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([]);
|
||||
|
||||
// 导出加载状态
|
||||
const exportLoading = ref(false)
|
||||
const importTeacherOtherInfoRef = ref()
|
||||
const exportLoading = ref(false);
|
||||
const importTeacherOtherInfoRef = ref();
|
||||
|
||||
// 学位、学历和教育类型列表
|
||||
const degreeList = ref<any[]>([])
|
||||
const qualificationList = ref<any[]>([])
|
||||
const educationTypeList = ref<any[]>([])
|
||||
const degreeList = ref<any[]>([]);
|
||||
const qualificationList = ref<any[]>([]);
|
||||
const educationTypeList = ref<any[]>([]);
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
const records = response.data.records || []
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
if (v.qualificationImg != null) {
|
||||
v.qiList = [v.qualificationImg]
|
||||
} else {
|
||||
v.qiList = []
|
||||
}
|
||||
if (v.degreeImg != null) {
|
||||
v.deList = [v.degreeImg]
|
||||
} else {
|
||||
v.deList = []
|
||||
}
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
const records = response.data.records || [];
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
if (v.qualificationImg != null) {
|
||||
v.qiList = [v.qualificationImg];
|
||||
} else {
|
||||
v.qiList = [];
|
||||
}
|
||||
if (v.degreeImg != null) {
|
||||
v.deList = [v.degreeImg];
|
||||
} else {
|
||||
v.deList = [];
|
||||
}
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 预览材料
|
||||
const handlePreview = (list: string[], type: number) => {
|
||||
imgUrl.value = []
|
||||
nextTick(() => {
|
||||
list.forEach(v => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v
|
||||
})
|
||||
})
|
||||
|
||||
if (type === 1) {
|
||||
dialogTitle.value = '学历证书附件'
|
||||
} else if (type === 2) {
|
||||
dialogTitle.value = '学位证书附件'
|
||||
}
|
||||
})
|
||||
}
|
||||
imgUrl.value = [];
|
||||
nextTick(() => {
|
||||
list.forEach((v) => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v,
|
||||
});
|
||||
});
|
||||
|
||||
if (type === 1) {
|
||||
dialogTitle.value = '学历证书附件';
|
||||
} else if (type === 2) {
|
||||
dialogTitle.value = '学位证书附件';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 审核状态变更
|
||||
const changeState = (row: any, val: number) => {
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过'
|
||||
messageBox.confirm(`是否确认${str}${row.realName}的申请`).then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val
|
||||
})
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
}).catch(() => {})
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
backReasonRef.value?.init(row, 'education')
|
||||
}
|
||||
}
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过';
|
||||
messageBox
|
||||
.confirm(`是否确认${str}${row.realName}的申请`)
|
||||
.then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val,
|
||||
});
|
||||
message.success('操作成功');
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
backReasonRef.value?.init(row, 'education');
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
dataFormRef.value?.openDialog()
|
||||
}
|
||||
dataFormRef.value?.openDialog();
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = (row: any) => {
|
||||
dataFormRef.value?.openDialog(row)
|
||||
}
|
||||
dataFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleDownLoadWord = async () => {
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20005' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
}
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20005' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
};
|
||||
|
||||
// 获取学位名称
|
||||
const getDegreeName = (id: string | number) => {
|
||||
const item = degreeList.value.find((item: any) => item.id === id)
|
||||
return item ? item.degreeName : '-'
|
||||
}
|
||||
const item = degreeList.value.find((item: any) => item.id === id);
|
||||
return item ? item.degreeName : '-';
|
||||
};
|
||||
|
||||
// 获取学历名称
|
||||
const getQualificationName = (id: string | number) => {
|
||||
const item = qualificationList.value.find((item: any) => item.id === id)
|
||||
return item ? item.qualificationName : '-'
|
||||
}
|
||||
const item = qualificationList.value.find((item: any) => item.id === id);
|
||||
return item ? item.qualificationName : '-';
|
||||
};
|
||||
|
||||
// 获取教育类型名称
|
||||
const getEducationTypeName = (id: string | number | undefined) => {
|
||||
if (!id) return '-'
|
||||
const item = educationTypeList.value.find((item: any) => item.id === id || String(item.id) === String(id))
|
||||
return item ? item.name : '-'
|
||||
}
|
||||
if (!id) return '-';
|
||||
const item = educationTypeList.value.find((item: any) => item.id === id || String(item.id) === String(id));
|
||||
return item ? item.name : '-';
|
||||
};
|
||||
|
||||
// 打开导入弹窗
|
||||
const handleImportDialog = () => {
|
||||
importTeacherOtherInfoRef.value?.init('eduDegree')
|
||||
}
|
||||
importTeacherOtherInfoRef.value?.init('eduDegree');
|
||||
};
|
||||
|
||||
// 加载字典数据
|
||||
const loadDictData = async () => {
|
||||
try {
|
||||
// 并行加载所有字典数据
|
||||
const [degreeRes, qualRes, eduTypeRes] = await Promise.all([
|
||||
getDegreeList(),
|
||||
getQualificationList(),
|
||||
getAllTypeList()
|
||||
])
|
||||
|
||||
// 加载学位列表
|
||||
if (degreeRes && degreeRes.data) {
|
||||
degreeList.value = degreeRes.data
|
||||
}
|
||||
|
||||
// 加载学历列表
|
||||
if (qualRes && qualRes.data) {
|
||||
qualificationList.value = qualRes.data
|
||||
}
|
||||
|
||||
// 加载教育类型列表
|
||||
if (eduTypeRes && eduTypeRes.data) {
|
||||
educationTypeList.value = eduTypeRes.data
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 并行加载所有字典数据
|
||||
const [degreeRes, qualRes, eduTypeRes] = await Promise.all([getDegreeList(), getQualificationList(), getAllTypeList()]);
|
||||
|
||||
// 加载学位列表
|
||||
if (degreeRes && degreeRes.data) {
|
||||
degreeList.value = degreeRes.data;
|
||||
}
|
||||
|
||||
// 加载学历列表
|
||||
if (qualRes && qualRes.data) {
|
||||
qualificationList.value = qualRes.data;
|
||||
}
|
||||
|
||||
// 加载教育类型列表
|
||||
if (eduTypeRes && eduTypeRes.data) {
|
||||
educationTypeList.value = eduTypeRes.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化:仅加载下拉字典,表格数据由 useTable(createdIsNeed 默认 true)自动请求
|
||||
onMounted(async () => {
|
||||
await loadDictData()
|
||||
})
|
||||
await loadDictData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,83 +1,81 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 页面标题 -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="margin: 0; font-size: 20px; font-weight: 600; color: #303133;">学历统计</h2>
|
||||
</div>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 页面标题 -->
|
||||
<div style="margin-bottom: 20px">
|
||||
<h2 style="margin: 0; font-size: 20px; font-weight: 600; color: #303133">学历统计</h2>
|
||||
</div>
|
||||
|
||||
<!-- 图表统计 -->
|
||||
<div style="width: 100%">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="chartRef" style="width: 100%; height: 400px;" :option="chartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="chartData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="xl" label="学历" width="180" align="center" />
|
||||
<el-table-column prop="total" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="占比" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图表统计 -->
|
||||
<div style="width: 100%">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="chartRef" style="width: 100%; height: 400px" :option="chartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="chartData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="xl" label="学历" width="180" align="center" />
|
||||
<el-table-column prop="total" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="占比" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
import { PieChart } from 'echarts/charts'
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { getChartOption } from '/@/api/professional/professionaluser/professionalteacheracademicrelation'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import VChart from 'vue-echarts';
|
||||
import { use } from 'echarts/core';
|
||||
import { PieChart } from 'echarts/charts';
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { getChartOption } from '/@/api/professional/professionaluser/professionalteacheracademicrelation';
|
||||
|
||||
// 注册 ECharts 组件
|
||||
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer])
|
||||
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer]);
|
||||
|
||||
// 图表引用
|
||||
const chartRef = ref()
|
||||
const chartRef = ref();
|
||||
|
||||
// 图表数据
|
||||
const chartOption = ref<any>({})
|
||||
const chartData = ref<any[]>([])
|
||||
const chartOption = ref<any>({});
|
||||
const chartData = ref<any[]>([]);
|
||||
|
||||
// 初始化图表
|
||||
const initChartOption = async () => {
|
||||
try {
|
||||
const response = await getChartOption()
|
||||
chartOption.value = response.data.data || {}
|
||||
|
||||
// 处理图表数据
|
||||
if (chartOption.value.series && chartOption.value.series[0] && chartOption.value.series[0].data) {
|
||||
let total = 0
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
total += item.value || 0
|
||||
})
|
||||
|
||||
chartData.value = []
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = total > 0 ? Number((item.value / total * 100).toFixed(1)) : 0
|
||||
chartData.value.push({
|
||||
xl: item.name,
|
||||
total: item.value,
|
||||
rate: `${rate}%`
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load chart data
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getChartOption();
|
||||
chartOption.value = response.data.data || {};
|
||||
|
||||
// 处理图表数据
|
||||
if (chartOption.value.series && chartOption.value.series[0] && chartOption.value.series[0].data) {
|
||||
let total = 0;
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
total += item.value || 0;
|
||||
});
|
||||
|
||||
chartData.value = [];
|
||||
chartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = total > 0 ? Number(((item.value / total) * 100).toFixed(1)) : 0;
|
||||
chartData.value.push({
|
||||
xl: item.name,
|
||||
total: item.value,
|
||||
rate: `${rate}%`,
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load chart data
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时初始化图表
|
||||
onMounted(() => {
|
||||
initChartOption()
|
||||
})
|
||||
initChartOption();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,236 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificateconf_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalteachercertificateconf_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="cretificateName" label="资格证名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificateconf_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificateconf_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="cretificateName" label="资格证名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="资格证名称" prop="cretificateName">
|
||||
<el-input
|
||||
v-model="form.cretificateName"
|
||||
placeholder="请输入资格证名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificateconf_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificateconf_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="资格证名称" prop="cretificateName">
|
||||
<el-input v-model="form.cretificateName" placeholder="请输入资格证名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalteachercertificateconf'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalteachercertificateconf';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
cretificateName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
cretificateName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
cretificateName: [
|
||||
{ required: true, message: '请输入资格证名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
cretificateName: [{ required: true, message: '请输入资格证名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
cretificateName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
cretificateName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
cretificateName: row.cretificateName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
cretificateName: row.cretificateName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,249 +1,230 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="编辑教师资格证" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="类型" prop="certificateConfId">
|
||||
<el-select
|
||||
v-model="dataForm.certificateConfId"
|
||||
placeholder="请选择类型"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in teacherCertificateList"
|
||||
:key="item.id"
|
||||
:label="item.cretificateName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-dialog v-model="dialogVisible" title="编辑教师资格证" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form ref="formRef" :model="dataForm" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="类型" prop="certificateConfId">
|
||||
<el-select v-model="dataForm.certificateConfId" placeholder="请选择类型" style="width: 100%">
|
||||
<el-option v-for="item in teacherCertificateList" :key="item.id" :label="item.cretificateName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
show-word-limit
|
||||
maxlength="64"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
show-word-limit
|
||||
maxlength="64"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证明材料" prop="evidenceA" required>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-form-item label="证明材料" prop="evidenceA" required>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalteachercertificaterelation'
|
||||
import { getTeacherCertificateList } from '/@/api/professional/rsbase/professionalteachercertificateconf'
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock'
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalteachercertificaterelation';
|
||||
import { getTeacherCertificateList } from '/@/api/professional/rsbase/professionalteachercertificateconf';
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref();
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 对话框显示状态(内部管理)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
certificateConfId: '',
|
||||
certificateNumber: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
certificateConfId: '',
|
||||
certificateNumber: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
certificateConfId: [
|
||||
{ required: true, message: '请选择类型', trigger: 'change' }
|
||||
],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' }
|
||||
],
|
||||
evidenceA: [
|
||||
{ required: true, message: '请上传证明材料', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
certificateConfId: [{ required: true, message: '请选择类型', trigger: 'change' }],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' },
|
||||
],
|
||||
evidenceA: [{ required: true, message: '请上传证明材料', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 教师资格证列表
|
||||
const teacherCertificateList = ref<any[]>([])
|
||||
const teacherCertificateList = ref<any[]>([]);
|
||||
|
||||
// 基础信息(简化,只保留需要的)
|
||||
|
||||
// 上传相关
|
||||
const url = ref('')
|
||||
const fileList = ref<any[]>([])
|
||||
const url = ref('');
|
||||
const fileList = ref<any[]>([]);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 显示表单标志
|
||||
const showForm = ref(false)
|
||||
const showForm = ref(false);
|
||||
|
||||
// 初始化字典数据
|
||||
const initDicData = async () => {
|
||||
try {
|
||||
const res = await getTeacherCertificateList()
|
||||
teacherCertificateList.value = res.data || []
|
||||
} catch (error) {
|
||||
// 获取字典数据失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const res = await getTeacherCertificateList();
|
||||
teacherCertificateList.value = res.data || [];
|
||||
} catch (error) {
|
||||
// 获取字典数据失败
|
||||
}
|
||||
};
|
||||
|
||||
// 证书编号输入处理(只允许英文和数字)
|
||||
const handleCertificateNumberInput = (value: string) => {
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '')
|
||||
}
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '');
|
||||
};
|
||||
|
||||
// 文件上传成功
|
||||
const materiaUploadSuccess = (response: any) => {
|
||||
if (response.data && response.data.code === "-1") {
|
||||
message.error("当前不允许上传文件")
|
||||
return
|
||||
}
|
||||
dataForm.evidenceA = response.data.url
|
||||
// 清除验证错误
|
||||
formRef.value?.clearValidate('evidenceA')
|
||||
}
|
||||
if (response.data && response.data.code === '-1') {
|
||||
message.error('当前不允许上传文件');
|
||||
return;
|
||||
}
|
||||
dataForm.evidenceA = response.data.url;
|
||||
// 清除验证错误
|
||||
formRef.value?.clearValidate('evidenceA');
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openDialog = async (row?: any) => {
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('teacherTitle')
|
||||
if (lockResponse.data) {
|
||||
message.warning("新增功能已锁定,暂不允许操作")
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=0`
|
||||
fileList.value = []
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
Object.assign(dataForm, {
|
||||
certificateConfId: row.certificateConfId || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
evidenceA: row.evidenceA || '',
|
||||
state: row.state || '',
|
||||
id: row.id || ''
|
||||
})
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
certificateConfId: '',
|
||||
certificateNumber: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
}
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData()
|
||||
showForm.value = true
|
||||
dialogVisible.value = true
|
||||
}
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('teacherTitle');
|
||||
if (lockResponse.data) {
|
||||
message.warning('新增功能已锁定,暂不允许操作');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=0`;
|
||||
fileList.value = [];
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
Object.assign(dataForm, {
|
||||
certificateConfId: row.certificateConfId || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
evidenceA: row.evidenceA || '',
|
||||
state: row.state || '',
|
||||
id: row.id || '',
|
||||
});
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
certificateConfId: '',
|
||||
certificateNumber: '',
|
||||
evidenceA: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
}
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData();
|
||||
showForm.value = true;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const dialogSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用)
|
||||
const submitData: any = {
|
||||
certificateConfId: dataForm.certificateConfId,
|
||||
certificateNumber: dataForm.certificateNumber,
|
||||
evidenceA: dataForm.evidenceA,
|
||||
state: '' // 待审核
|
||||
}
|
||||
|
||||
// 编辑时需要传递 id
|
||||
if (dataForm.id) {
|
||||
submitData.id = dataForm.id
|
||||
}
|
||||
|
||||
await addObj(submitData)
|
||||
message.success(dataForm.id ? "修改成功" : "提交成功")
|
||||
dialogVisible.value = false
|
||||
emit('refreshData')
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用)
|
||||
const submitData: any = {
|
||||
certificateConfId: dataForm.certificateConfId,
|
||||
certificateNumber: dataForm.certificateNumber,
|
||||
evidenceA: dataForm.evidenceA,
|
||||
state: '', // 待审核
|
||||
};
|
||||
|
||||
// 编辑时需要传递 id
|
||||
if (dataForm.id) {
|
||||
submitData.id = dataForm.id;
|
||||
}
|
||||
|
||||
await addObj(submitData);
|
||||
message.success(dataForm.id ? '修改成功' : '提交成功');
|
||||
dialogVisible.value = false;
|
||||
emit('refreshData');
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化方法(保持兼容性)
|
||||
const init = () => {
|
||||
// 新版本不再需要初始化配置
|
||||
}
|
||||
// 新版本不再需要初始化配置
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog,
|
||||
init
|
||||
})
|
||||
openDialog,
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,413 +1,389 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select
|
||||
v-model="search.state"
|
||||
clearable
|
||||
placeholder="请选择审核状态"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in professionalState"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select v-model="search.state" clearable placeholder="请选择审核状态">
|
||||
<el-option v-for="item in professionalState" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" clearable placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading">导出信息
|
||||
</el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog">导入信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalteachercertificaterelation_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading"
|
||||
>导出信息
|
||||
</el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="certificateConfId" label="关联资格证书" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getCertificateName(scope.row.certificateConfId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="certificateNumber" label="证书编号" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.evidenceA && scope.row.evidenceA !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.srcList)">查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file
|
||||
v-for="src in imgUrl"
|
||||
:key="src.title"
|
||||
:authSrc="src.url"
|
||||
dialog-title="教师资格材料"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="certificateConfId" label="关联资格证书" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getCertificateName(scope.row.certificateConfId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="certificateNumber" label="证书编号" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.evidenceA && scope.row.evidenceA !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.srcList)"
|
||||
>查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)"
|
||||
>编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachercertificaterelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file v-for="src in imgUrl" :key="src.title" :authSrc="src.url" dialog-title="教师资格材料" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { getTeacherCertificateList } from '/@/api/professional/rsbase/professionalteachercertificateconf'
|
||||
import {
|
||||
fetchList,
|
||||
examObj,
|
||||
delObj
|
||||
} from '/@/api/professional/professionaluser/professionalteachercertificaterelation'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { getTeacherCertificateList } from '/@/api/professional/rsbase/professionalteachercertificateconf';
|
||||
import { fetchList, examObj, delObj } from '/@/api/professional/professionaluser/professionalteachercertificaterelation';
|
||||
import { makeExportTeacherInfoByTypeTask } from '/@/api/professional/professionalfile';
|
||||
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'))
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'));
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'));
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'));
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'));
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'));
|
||||
|
||||
// 审核状态选项(独立定义,防止其他页面修改时被波及)
|
||||
import type { StateOption } from '/@/components/AuditState/index.vue'
|
||||
const auditStateOptions: StateOption[] = PROFESSIONAL_AUDIT_STATE_OPTIONS
|
||||
import type { StateOption } from '/@/components/AuditState/index.vue';
|
||||
const auditStateOptions: StateOption[] = PROFESSIONAL_AUDIT_STATE_OPTIONS;
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 字典数据
|
||||
const { professional_state: professionalState } = useDict('professional_state')
|
||||
const { professional_state: professionalState } = useDict('professional_state');
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const dataFormRef = ref()
|
||||
const backReasonRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
const backReasonRef = ref();
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
|
||||
// 材料预览
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([])
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([]);
|
||||
|
||||
// 导出加载状态
|
||||
const exportLoading = ref(false)
|
||||
const importTeacherOtherInfoRef = ref()
|
||||
const exportLoading = ref(false);
|
||||
const importTeacherOtherInfoRef = ref();
|
||||
|
||||
// 证书列表
|
||||
const certificateList = ref<any[]>([])
|
||||
const certificateList = ref<any[]>([]);
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
const records = response.data.records || []
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
v.srcList = []
|
||||
if (v.evidenceA != null) {
|
||||
v.srcList.push(v.evidenceA)
|
||||
}
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
const records = response.data.records || [];
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
v.srcList = [];
|
||||
if (v.evidenceA != null) {
|
||||
v.srcList.push(v.evidenceA);
|
||||
}
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 预览材料
|
||||
const handlePreview = (list: string[]) => {
|
||||
imgUrl.value = []
|
||||
nextTick(() => {
|
||||
list.forEach(v => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
imgUrl.value = [];
|
||||
nextTick(() => {
|
||||
list.forEach((v) => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 审核状态变更
|
||||
const changeState = (row: any, val: number) => {
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过'
|
||||
messageBox.confirm(`是否确认${str}${row.realName}的申请`).then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val
|
||||
})
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {})
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
backReasonRef.value?.init(row, 'cer')
|
||||
}
|
||||
}
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过';
|
||||
messageBox
|
||||
.confirm(`是否确认${str}${row.realName}的申请`)
|
||||
.then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val,
|
||||
});
|
||||
message.success('操作成功');
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
backReasonRef.value?.init(row, 'cer');
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
dataFormRef.value?.openDialog()
|
||||
}
|
||||
dataFormRef.value?.openDialog();
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = (row: any) => {
|
||||
dataFormRef.value?.openDialog(row)
|
||||
}
|
||||
dataFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleDownLoadWord = async () => {
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20004' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20004' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
};
|
||||
|
||||
// 获取证书名称
|
||||
const getCertificateName = (id: string | number) => {
|
||||
const item = certificateList.value.find((item: any) => item.id === id)
|
||||
return item ? item.cretificateName : '-'
|
||||
}
|
||||
const item = certificateList.value.find((item: any) => item.id === id);
|
||||
return item ? item.cretificateName : '-';
|
||||
};
|
||||
|
||||
// 打开导入弹窗
|
||||
const handleImportDialog = () => {
|
||||
importTeacherOtherInfoRef.value?.init('cerRelation')
|
||||
}
|
||||
importTeacherOtherInfoRef.value?.init('cerRelation');
|
||||
};
|
||||
|
||||
// 加载字典数据
|
||||
const loadDictData = async () => {
|
||||
try {
|
||||
// 加载证书列表
|
||||
const certRes = await getTeacherCertificateList()
|
||||
if (certRes && certRes.data) {
|
||||
certificateList.value = certRes.data
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 加载证书列表
|
||||
const certRes = await getTeacherCertificateList();
|
||||
if (certRes && certRes.data) {
|
||||
certificateList.value = certRes.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化:仅加载下拉字典,表格数据由 useTable(createdIsNeed 默认 true)自动请求
|
||||
onMounted(async () => {
|
||||
await loadDictData()
|
||||
})
|
||||
await loadDictData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,292 +1,273 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :title="title" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="荣誉" prop="honor">
|
||||
<el-input v-model="dataForm.honor" placeholder="请输入荣誉" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="表彰单位" prop="honorCompany">
|
||||
<el-input v-model="dataForm.honorCompany" placeholder="请输入表彰单位" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="year">
|
||||
<el-date-picker
|
||||
v-model="dataForm.year"
|
||||
type="year"
|
||||
placeholder="请选择年份"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证明材料" prop="attachment" required>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:before-upload="beforeUpload"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="handleExceed"
|
||||
:file-list="fileList"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog v-model="dialogVisible" :title="title" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="dataForm" :rules="dataRules" label-width="120px">
|
||||
<el-form-item label="荣誉" prop="honor">
|
||||
<el-input v-model="dataForm.honor" placeholder="请输入荣誉" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button @click="dialogSubmit" type="primary" :loading="submitLoading">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-form-item label="表彰单位" prop="honorCompany">
|
||||
<el-input v-model="dataForm.honorCompany" placeholder="请输入表彰单位" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="year">
|
||||
<el-date-picker v-model="dataForm.year" type="year" placeholder="请选择年份" format="YYYY" value-format="YYYY" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证明材料" prop="attachment" required>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:before-upload="beforeUpload"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="handleExceed"
|
||||
:file-list="fileList"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button @click="dialogSubmit" type="primary" :loading="submitLoading">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, nextTick } from 'vue'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalteacherhonor'
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock'
|
||||
import { ref, reactive, computed, nextTick } from 'vue';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionalteacherhonor';
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const uploadRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref();
|
||||
const uploadRef = ref();
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 对话框显示状态(内部管理)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
honor: '',
|
||||
honorCompany: '',
|
||||
year: '',
|
||||
materialA: '',
|
||||
attachment: '',
|
||||
state: '',
|
||||
teacherName: '',
|
||||
id: ''
|
||||
})
|
||||
honor: '',
|
||||
honorCompany: '',
|
||||
year: '',
|
||||
materialA: '',
|
||||
attachment: '',
|
||||
state: '',
|
||||
teacherName: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const dataRules = {
|
||||
honor: [
|
||||
{ required: true, message: '请填写荣誉', trigger: 'blur' }
|
||||
],
|
||||
honorCompany: [
|
||||
{ required: true, message: '请填写表彰单位', trigger: 'blur' }
|
||||
],
|
||||
year: [
|
||||
{ required: true, message: '请选择年份', trigger: 'change' }
|
||||
],
|
||||
attachment: [
|
||||
{ required: true, message: '请上传证明材料', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
honor: [{ required: true, message: '请填写荣誉', trigger: 'blur' }],
|
||||
honorCompany: [{ required: true, message: '请填写表彰单位', trigger: 'blur' }],
|
||||
year: [{ required: true, message: '请选择年份', trigger: 'change' }],
|
||||
attachment: [{ required: true, message: '请上传证明材料', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 基础信息(简化,只保留需要的)
|
||||
|
||||
// 上传相关
|
||||
const url = ref('')
|
||||
const fileList = ref<any[]>([])
|
||||
const url = ref('');
|
||||
const fileList = ref<any[]>([]);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 显示表单标志
|
||||
const showForm = ref(false)
|
||||
const showForm = ref(false);
|
||||
|
||||
// 标题
|
||||
const title = ref('')
|
||||
const title = ref('');
|
||||
|
||||
// 初始化字典数据(简化,不需要加载字典数据)
|
||||
const initDicData = async () => {
|
||||
// 综合表彰不需要额外的字典数据
|
||||
}
|
||||
// 综合表彰不需要额外的字典数据
|
||||
};
|
||||
|
||||
// 上传前的处理
|
||||
const beforeUpload = () => {
|
||||
return true
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// 文件超出限制时的处理(当 limit=1 且已有文件时,用户上传新文件会触发此事件)
|
||||
// 根据 Element Plus 官方文档,在 on-exceed 中清空文件列表并添加新文件
|
||||
const handleExceed = (files: File[]) => {
|
||||
// 清空当前文件列表
|
||||
uploadRef.value?.clearFiles()
|
||||
fileList.value = []
|
||||
dataForm.attachment = ''
|
||||
|
||||
// 等待 DOM 更新后,手动触发新文件的上传
|
||||
nextTick(() => {
|
||||
const newFile = files[0]
|
||||
if (newFile && uploadRef.value) {
|
||||
// 通过 input 元素手动触发文件上传
|
||||
const input = uploadRef.value.$el?.querySelector('input[type="file"]')
|
||||
if (input) {
|
||||
// 创建新的 DataTransfer 对象并添加新文件
|
||||
const dataTransfer = new DataTransfer()
|
||||
dataTransfer.items.add(newFile)
|
||||
input.files = dataTransfer.files
|
||||
|
||||
// 触发 change 事件,让 Element Plus 自动处理上传
|
||||
const changeEvent = new Event('change', { bubbles: true })
|
||||
input.dispatchEvent(changeEvent)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 清空当前文件列表
|
||||
uploadRef.value?.clearFiles();
|
||||
fileList.value = [];
|
||||
dataForm.attachment = '';
|
||||
|
||||
// 等待 DOM 更新后,手动触发新文件的上传
|
||||
nextTick(() => {
|
||||
const newFile = files[0];
|
||||
if (newFile && uploadRef.value) {
|
||||
// 通过 input 元素手动触发文件上传
|
||||
const input = uploadRef.value.$el?.querySelector('input[type="file"]');
|
||||
if (input) {
|
||||
// 创建新的 DataTransfer 对象并添加新文件
|
||||
const dataTransfer = new DataTransfer();
|
||||
dataTransfer.items.add(newFile);
|
||||
input.files = dataTransfer.files;
|
||||
|
||||
// 触发 change 事件,让 Element Plus 自动处理上传
|
||||
const changeEvent = new Event('change', { bubbles: true });
|
||||
input.dispatchEvent(changeEvent);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 文件上传成功
|
||||
const materiaUploadSuccess = (response: any, file: any) => {
|
||||
if (response.data && response.data.code === "-1") {
|
||||
message.error("当前不允许上传文件")
|
||||
// 上传失败,移除文件
|
||||
fileList.value = []
|
||||
uploadRef.value?.clearFiles()
|
||||
return
|
||||
}
|
||||
if (response.data && response.data.url) {
|
||||
dataForm.attachment = response.data.url
|
||||
// 更新文件列表,确保显示新上传的文件(替换旧文件)
|
||||
fileList.value = [{
|
||||
name: file.name || '证明材料',
|
||||
url: response.data.url,
|
||||
uid: file.uid || Date.now(),
|
||||
status: 'success'
|
||||
}]
|
||||
formRef.value?.clearValidate('attachment')
|
||||
}
|
||||
}
|
||||
if (response.data && response.data.code === '-1') {
|
||||
message.error('当前不允许上传文件');
|
||||
// 上传失败,移除文件
|
||||
fileList.value = [];
|
||||
uploadRef.value?.clearFiles();
|
||||
return;
|
||||
}
|
||||
if (response.data && response.data.url) {
|
||||
dataForm.attachment = response.data.url;
|
||||
// 更新文件列表,确保显示新上传的文件(替换旧文件)
|
||||
fileList.value = [
|
||||
{
|
||||
name: file.name || '证明材料',
|
||||
url: response.data.url,
|
||||
uid: file.uid || Date.now(),
|
||||
status: 'success',
|
||||
},
|
||||
];
|
||||
formRef.value?.clearValidate('attachment');
|
||||
}
|
||||
};
|
||||
|
||||
// 文件删除处理
|
||||
const handleRemove = () => {
|
||||
dataForm.attachment = ''
|
||||
fileList.value = []
|
||||
formRef.value?.clearValidate('attachment')
|
||||
}
|
||||
dataForm.attachment = '';
|
||||
fileList.value = [];
|
||||
formRef.value?.clearValidate('attachment');
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openDialog = async (row?: any) => {
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('remix')
|
||||
if (lockResponse.data) {
|
||||
message.warning("新增功能已锁定,暂不允许操作")
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
title.value = row.teacherName || ''
|
||||
Object.assign(dataForm, {
|
||||
honor: row.honor || '',
|
||||
honorCompany: row.honorCompany || '',
|
||||
year: row.year ? String(row.year) : '',
|
||||
materialA: row.materialA || '',
|
||||
attachment: row.attachment || '',
|
||||
state: row.state || '',
|
||||
teacherName: row.teacherName || '',
|
||||
id: row.id || ''
|
||||
})
|
||||
// 回显已上传的证明材料
|
||||
fileList.value = dataForm.attachment
|
||||
? [{ name: '证明材料', url: dataForm.attachment }]
|
||||
: []
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
title.value = '新增综合表彰'
|
||||
Object.assign(dataForm, {
|
||||
honor: '',
|
||||
honorCompany: '',
|
||||
year: '',
|
||||
attachment: '',
|
||||
state: '',
|
||||
teacherName: '',
|
||||
id: ''
|
||||
})
|
||||
fileList.value = []
|
||||
}
|
||||
|
||||
// 公共设置:每次打开都重置上传地址
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=4`
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData()
|
||||
showForm.value = true
|
||||
dialogVisible.value = true
|
||||
}
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('remix');
|
||||
if (lockResponse.data) {
|
||||
message.warning('新增功能已锁定,暂不允许操作');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
title.value = row.teacherName || '';
|
||||
Object.assign(dataForm, {
|
||||
honor: row.honor || '',
|
||||
honorCompany: row.honorCompany || '',
|
||||
year: row.year ? String(row.year) : '',
|
||||
materialA: row.materialA || '',
|
||||
attachment: row.attachment || '',
|
||||
state: row.state || '',
|
||||
teacherName: row.teacherName || '',
|
||||
id: row.id || '',
|
||||
});
|
||||
// 回显已上传的证明材料
|
||||
fileList.value = dataForm.attachment ? [{ name: '证明材料', url: dataForm.attachment }] : [];
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
title.value = '新增综合表彰';
|
||||
Object.assign(dataForm, {
|
||||
honor: '',
|
||||
honorCompany: '',
|
||||
year: '',
|
||||
attachment: '',
|
||||
state: '',
|
||||
teacherName: '',
|
||||
id: '',
|
||||
});
|
||||
fileList.value = [];
|
||||
}
|
||||
|
||||
// 公共设置:每次打开都重置上传地址
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=4`;
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData();
|
||||
showForm.value = true;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const dialogSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用同一个接口)
|
||||
await addObj(dataForm)
|
||||
message.success(dataForm.id ? "修改成功" : "提交成功")
|
||||
dialogVisible.value = false
|
||||
emit('refreshData')
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用同一个接口)
|
||||
await addObj(dataForm);
|
||||
message.success(dataForm.id ? '修改成功' : '提交成功');
|
||||
dialogVisible.value = false;
|
||||
emit('refreshData');
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化方法(保持兼容性)
|
||||
const init = () => {
|
||||
// 新版本不再需要初始化配置
|
||||
}
|
||||
// 新版本不再需要初始化配置
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog,
|
||||
init
|
||||
})
|
||||
openDialog,
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,413 +1,371 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select
|
||||
v-model="search.state"
|
||||
clearable
|
||||
placeholder="请选择审核状态"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in professionalState"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select v-model="search.state" clearable placeholder="请选择审核状态">
|
||||
<el-option v-for="item in professionalState" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="teacherName">
|
||||
<el-input
|
||||
v-model="search.teacherName"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="姓名" prop="teacherName">
|
||||
<el-input v-model="search.teacherName" clearable placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading">导出信息
|
||||
</el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog">导入信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalteacherhonor_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleDownLoadWord" :loading="exportLoading">导出信息 </el-button>
|
||||
<el-button
|
||||
v-auth="'professional_teacherinfo_import'"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
:loading="exportLoading"
|
||||
@click="handleImportDialog"
|
||||
>导入信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="state" label="审核状态" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<DetailPopover
|
||||
v-if="scope.row.state === '-2' && scope.row.backReason"
|
||||
title="审核详情"
|
||||
placement="top"
|
||||
:width="300"
|
||||
:items="[
|
||||
{ label: '审核状态', layout: 'horizontal', content: getAuditStateTagConfig(scope.row.state)?.label },
|
||||
{ label: '驳回理由', content: scope.row.backReason, contentClass: 'reason-content' }
|
||||
]"
|
||||
>
|
||||
<template #reference>
|
||||
<ClickableTag
|
||||
:type="getAuditStateTagConfig(scope.row.state)?.type || 'danger'"
|
||||
:left-icon="getAuditStateTagConfig(scope.row.state)?.leftIcon"
|
||||
:effect="getAuditStateTagConfig(scope.row.state)?.effect || 'dark'"
|
||||
>
|
||||
{{ getAuditStateTagConfig(scope.row.state)?.label || '已驳回' }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
<template #content-0>
|
||||
<ClickableTag
|
||||
:type="getAuditStateTagConfig(scope.row.state)?.type || 'danger'"
|
||||
:left-icon="getAuditStateTagConfig(scope.row.state)?.leftIcon"
|
||||
:effect="getAuditStateTagConfig(scope.row.state)?.effect || 'dark'"
|
||||
:right-icon="null"
|
||||
>
|
||||
{{ getAuditStateTagConfig(scope.row.state)?.label || '已驳回' }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
<template #content-1>
|
||||
<div class="reason-content">
|
||||
<el-icon class="reason-icon"><Warning /></el-icon>
|
||||
<span>{{ scope.row.backReason }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</DetailPopover>
|
||||
<AuditState v-else :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="honor" label="荣誉" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="honorCompany" label="表彰单位" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="year" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment && scope.row.attachment !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="showEdvince(scope.row)">查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="state" label="审核状态" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<DetailPopover
|
||||
v-if="scope.row.state === '-2' && scope.row.backReason"
|
||||
title="审核详情"
|
||||
placement="top"
|
||||
:width="300"
|
||||
:items="[
|
||||
{ label: '审核状态', layout: 'horizontal', content: getAuditStateTagConfig(scope.row.state)?.label },
|
||||
{ label: '驳回理由', content: scope.row.backReason, contentClass: 'reason-content' },
|
||||
]"
|
||||
>
|
||||
<template #reference>
|
||||
<ClickableTag
|
||||
:type="getAuditStateTagConfig(scope.row.state)?.type || 'danger'"
|
||||
:left-icon="getAuditStateTagConfig(scope.row.state)?.leftIcon"
|
||||
:effect="getAuditStateTagConfig(scope.row.state)?.effect || 'dark'"
|
||||
>
|
||||
{{ getAuditStateTagConfig(scope.row.state)?.label || '已驳回' }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
<template #content-0>
|
||||
<ClickableTag
|
||||
:type="getAuditStateTagConfig(scope.row.state)?.type || 'danger'"
|
||||
:left-icon="getAuditStateTagConfig(scope.row.state)?.leftIcon"
|
||||
:effect="getAuditStateTagConfig(scope.row.state)?.effect || 'dark'"
|
||||
:right-icon="null"
|
||||
>
|
||||
{{ getAuditStateTagConfig(scope.row.state)?.label || '已驳回' }}
|
||||
</ClickableTag>
|
||||
</template>
|
||||
<template #content-1>
|
||||
<div class="reason-content">
|
||||
<el-icon class="reason-icon"><Warning /></el-icon>
|
||||
<span>{{ scope.row.backReason }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</DetailPopover>
|
||||
<AuditState v-else :state="scope.row.state" :options="auditStateOptions" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file
|
||||
v-for="src in imgUrl"
|
||||
:key="src.title"
|
||||
:authSrc="src.url"
|
||||
dialog-title="综合表彰材料"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="honor" label="荣誉" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="honorCompany" label="表彰单位" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="year" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button v-if="scope.row.attachment && scope.row.attachment !== ''" type="primary" link icon="Document" @click="showEdvince(scope.row)"
|
||||
>查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteacherhonor_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>部门驳回
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_professionalteacherhonor_del')" type="danger" link icon="delete" @click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file v-for="src in imgUrl" :key="src.title" :authSrc="src.url" dialog-title="综合表彰材料" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import {
|
||||
fetchList,
|
||||
examObj,
|
||||
delObj
|
||||
} from '/@/api/professional/professionaluser/professionalteacherhonor'
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS, getStatusConfig } from '/@/config/global'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import {makeExportTeacherInfoByTypeTask} from "/@/api/professional/professionalfile";
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
||||
const ClickableTag = defineAsyncComponent(() => import('/@/components/ClickableTag/index.vue'))
|
||||
const DetailPopover = defineAsyncComponent(() => import('/@/components/DetailPopover/index.vue'))
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'))
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { fetchList, examObj, delObj } from '/@/api/professional/professionaluser/professionalteacherhonor';
|
||||
import { PROFESSIONAL_AUDIT_STATE_OPTIONS, getStatusConfig } from '/@/config/global';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { makeExportTeacherInfoByTypeTask } from '/@/api/professional/professionalfile';
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'));
|
||||
const ClickableTag = defineAsyncComponent(() => import('/@/components/ClickableTag/index.vue'));
|
||||
const DetailPopover = defineAsyncComponent(() => import('/@/components/DetailPopover/index.vue'));
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'));
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'));
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'));
|
||||
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'));
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 字典数据
|
||||
const { professional_state: professionalState } = useDict('professional_state')
|
||||
const { professional_state: professionalState } = useDict('professional_state');
|
||||
|
||||
// 审核状态选项
|
||||
const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS
|
||||
const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS;
|
||||
|
||||
// 审核状态转 ClickableTag 配置(用 options 的 icon 字符串,与 AuditState 一致为实心)
|
||||
const getAuditStateTagConfig = (state: string | number) => {
|
||||
const opt = getStatusConfig(auditStateOptions, state)
|
||||
if (!opt) return null
|
||||
return { type: opt.type, label: opt.label, leftIcon: opt.icon, effect: opt.effect || 'dark' }
|
||||
}
|
||||
const opt = getStatusConfig(auditStateOptions, state);
|
||||
if (!opt) return null;
|
||||
return { type: opt.type, label: opt.label, leftIcon: opt.icon, effect: opt.effect || 'dark' };
|
||||
};
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const backReasonRef = ref()
|
||||
const dataFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const backReasonRef = ref();
|
||||
const dataFormRef = ref();
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
teacherName: ''
|
||||
})
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
});
|
||||
|
||||
// 材料预览
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([])
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([]);
|
||||
|
||||
// 导出加载状态
|
||||
const exportLoading = ref(false)
|
||||
const importTeacherOtherInfoRef = ref()
|
||||
const exportLoading = ref(false);
|
||||
const importTeacherOtherInfoRef = ref();
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 查看证明材料:构造预览列表,交给 auth-img 处理
|
||||
const showEdvince = (row: any) => {
|
||||
imgUrl.value = []
|
||||
nextTick(() => {
|
||||
const list = row.attachment ? [row.attachment] : []
|
||||
list.forEach(v => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
imgUrl.value = [];
|
||||
nextTick(() => {
|
||||
const list = row.attachment ? [row.attachment] : [];
|
||||
list.forEach((v) => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 审核状态变更
|
||||
const changeState = (row: any, val: number) => {
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过'
|
||||
messageBox.confirm(`是否确认${str}${row.teacherName || row.realName}的申请`).then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val
|
||||
})
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {})
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
const newRow = JSON.parse(JSON.stringify(row))
|
||||
backReasonRef.value?.init(newRow, 'honor')
|
||||
}
|
||||
}
|
||||
if (val === 1) {
|
||||
// 通过
|
||||
const str = '通过';
|
||||
messageBox
|
||||
.confirm(`是否确认${str}${row.teacherName || row.realName}的申请`)
|
||||
.then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val,
|
||||
});
|
||||
message.success('操作成功');
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (val === -2) {
|
||||
// 驳回
|
||||
const newRow = JSON.parse(JSON.stringify(row));
|
||||
backReasonRef.value?.init(newRow, 'honor');
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
teacherName: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
dataFormRef.value?.openDialog()
|
||||
}
|
||||
dataFormRef.value?.openDialog();
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = (row: any) => {
|
||||
dataFormRef.value?.openDialog(row)
|
||||
}
|
||||
dataFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleDownLoadWord = async () => {
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20006' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
}
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20006' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
};
|
||||
|
||||
// 打开导入弹窗
|
||||
const handleImportDialog = () => {
|
||||
importTeacherOtherInfoRef.value?.init('honor')
|
||||
}
|
||||
importTeacherOtherInfoRef.value?.init('honor');
|
||||
};
|
||||
|
||||
// 表格数据由 useTable(createdIsNeed 默认 true)在挂载时自动请求
|
||||
</script>
|
||||
@@ -415,27 +373,27 @@ const handleImportDialog = () => {
|
||||
<style lang="scss" scoped>
|
||||
/* 驳回理由展示(与 backSchoolCheckin 一致) */
|
||||
.reason-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
background-color: #fef0f0;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid #f56c6c;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
background-color: #fef0f0;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid #f56c6c;
|
||||
|
||||
.reason-icon {
|
||||
color: #f56c6c;
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.reason-icon {
|
||||
color: #f56c6c;
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #f56c6c;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
}
|
||||
span {
|
||||
color: #f56c6c;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,152 +1,129 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="teacherName">
|
||||
<el-input
|
||||
v-model="search.teacherName"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="姓名" prop="teacherName">
|
||||
<el-input v-model="search.teacherName" clearable placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 操作按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.teacherName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="oldDeptName" label="原部门名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="newDeptName" label="现部门名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="changeDate" label="调令日期" min-width="120" align="center" />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Printer"
|
||||
@click="doPrint(scope.row)">打印部门调令
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.teacherName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="oldDeptName" label="原部门名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="newDeptName" label="现部门名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="changeDate" label="调令日期" min-width="120" align="center" />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="Printer" @click="doPrint(scope.row)">打印部门调令 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { fetchList } from '/@/api/professional/professionaluser/professionalteacherstationchange'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList } from '/@/api/professional/professionaluser/professionalteacherstationchange';
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
teacherNo: '',
|
||||
teacherName: ''
|
||||
})
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
});
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
teacherName: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打印部门调令
|
||||
const doPrint = (row: any) => {
|
||||
// 直接使用固定路径跳转到 print 页面
|
||||
const routeData = router.resolve({
|
||||
path: '/professional/professionalteacherstationchange/print',
|
||||
query: { id: row.id } // 使用 query 参数传递 id
|
||||
})
|
||||
window.open(routeData.href, '_blank')
|
||||
}
|
||||
// 直接使用固定路径跳转到 print 页面
|
||||
const routeData = router.resolve({
|
||||
path: '/professional/professionalteacherstationchange/print',
|
||||
query: { id: row.id }, // 使用 query 参数传递 id
|
||||
});
|
||||
window.open(routeData.href, '_blank');
|
||||
};
|
||||
|
||||
// 表格数据由 useTable(createdIsNeed 默认 true)在挂载时自动请求
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,515 +1,515 @@
|
||||
<template>
|
||||
<div class="print-container" id="print-container" ref="printContainerRef">
|
||||
<div class="print-content" v-loading="loading" ref="printContentRef">
|
||||
<!-- 上半部分:存根 -->
|
||||
<div class="stub-section">
|
||||
<!-- 大标题 -->
|
||||
<div class="main-title">江苏省常州技师学院调令</div>
|
||||
|
||||
<!-- 副标题和编号 -->
|
||||
<div class="subtitle-row">
|
||||
<div class="subtitle">
|
||||
<div class="subtitle-text">校内调配通知单</div>
|
||||
<div class="stub-label">(存根)</div>
|
||||
</div>
|
||||
<div class="doc-number">编号:</div>
|
||||
</div>
|
||||
|
||||
<!-- 存根内容 -->
|
||||
<div class="stub-content">
|
||||
<div class="content-line">
|
||||
<span class="underline-field">{{ detailData.fromDeptName || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室):</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line indent">
|
||||
<span class="text">经学校研究决定,调配</span>
|
||||
<span class="underline-field">{{ detailData.realName || '________' }}</span>
|
||||
<span class="text">同志到</span>
|
||||
<span class="underline-field">{{ detailData.toDeptName1 || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室)</span>
|
||||
<span class="underline-field">{{ detailData.pos || '________' }}</span>
|
||||
<span class="text">(专技、管理、工勤)岗位工作,请做好移交或安排。</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line">
|
||||
<span class="text">限</span>
|
||||
<span class="underline-field">{{ detailData.year1 || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month1 || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day1 || '____' }}</span>
|
||||
<span class="text">日前离岗。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 存根底部 -->
|
||||
<div class="stub-footer">
|
||||
<div class="footer-right">
|
||||
<div class="dept-name">组织人事处</div>
|
||||
<div class="date-line">
|
||||
<span class="underline-field">{{ detailData.year || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day || '____' }}</span>
|
||||
<span class="text">日</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<div class="divider-line"></div>
|
||||
|
||||
<!-- 下半部分:正式通知单 -->
|
||||
<div class="notice-section">
|
||||
<!-- 顶部横线 -->
|
||||
<div class="top-line"></div>
|
||||
|
||||
<!-- 标题和编号 -->
|
||||
<div class="notice-title-row">
|
||||
<div class="notice-title">校内调配通知单</div>
|
||||
<div class="doc-number">编号:</div>
|
||||
</div>
|
||||
|
||||
<!-- 通知单内容 -->
|
||||
<div class="notice-content">
|
||||
<div class="content-line">
|
||||
<span class="underline-field">{{ detailData.fromDeptName || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室):</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line indent">
|
||||
<span class="text">经学校研究决定,调配</span>
|
||||
<span class="underline-field">{{ detailData.realName || '________' }}</span>
|
||||
<span class="text">同志到</span>
|
||||
<span class="underline-field">{{ detailData.toDeptName1 || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室)</span>
|
||||
<span class="underline-field">{{ detailData.pos || '________' }}</span>
|
||||
<span class="text">(专技、管理、工勤)岗位工作,请做好工作安排。</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line">
|
||||
<span class="text">限</span>
|
||||
<span class="underline-field">{{ detailData.year1 || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month1 || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day1 || '____' }}</span>
|
||||
<span class="text">日前报到,并将该单交财务处。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 通知单底部 -->
|
||||
<div class="notice-footer">
|
||||
<div class="footer-center">
|
||||
<div class="dept-name-bold">组织人事处</div>
|
||||
<div class="date-line">
|
||||
<span class="underline-field">{{ detailData.year || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day || '____' }}</span>
|
||||
<span class="text">日</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 签字栏 -->
|
||||
<div class="signature-section">
|
||||
<div class="signature-left">
|
||||
<div class="signature-label">调配(出)部门领导签字/日期:</div>
|
||||
</div>
|
||||
<div class="signature-right">
|
||||
<div class="signature-label">接收部门领导签字/日期:</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 打印按钮 -->
|
||||
<div class="print-actions" v-if="!loading">
|
||||
<el-button type="primary" icon="Printer" @click="handlePrint">打印</el-button>
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="print-container" id="print-container" ref="printContainerRef">
|
||||
<div class="print-content" v-loading="loading" ref="printContentRef">
|
||||
<!-- 上半部分:存根 -->
|
||||
<div class="stub-section">
|
||||
<!-- 大标题 -->
|
||||
<div class="main-title">江苏省常州技师学院调令</div>
|
||||
|
||||
<!-- 副标题和编号 -->
|
||||
<div class="subtitle-row">
|
||||
<div class="subtitle">
|
||||
<div class="subtitle-text">校内调配通知单</div>
|
||||
<div class="stub-label">(存根)</div>
|
||||
</div>
|
||||
<div class="doc-number">编号:</div>
|
||||
</div>
|
||||
|
||||
<!-- 存根内容 -->
|
||||
<div class="stub-content">
|
||||
<div class="content-line">
|
||||
<span class="underline-field">{{ detailData.fromDeptName || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室):</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line indent">
|
||||
<span class="text">经学校研究决定,调配</span>
|
||||
<span class="underline-field">{{ detailData.realName || '________' }}</span>
|
||||
<span class="text">同志到</span>
|
||||
<span class="underline-field">{{ detailData.toDeptName1 || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室)</span>
|
||||
<span class="underline-field">{{ detailData.pos || '________' }}</span>
|
||||
<span class="text">(专技、管理、工勤)岗位工作,请做好移交或安排。</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line">
|
||||
<span class="text">限</span>
|
||||
<span class="underline-field">{{ detailData.year1 || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month1 || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day1 || '____' }}</span>
|
||||
<span class="text">日前离岗。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 存根底部 -->
|
||||
<div class="stub-footer">
|
||||
<div class="footer-right">
|
||||
<div class="dept-name">组织人事处</div>
|
||||
<div class="date-line">
|
||||
<span class="underline-field">{{ detailData.year || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day || '____' }}</span>
|
||||
<span class="text">日</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<div class="divider-line"></div>
|
||||
|
||||
<!-- 下半部分:正式通知单 -->
|
||||
<div class="notice-section">
|
||||
<!-- 顶部横线 -->
|
||||
<div class="top-line"></div>
|
||||
|
||||
<!-- 标题和编号 -->
|
||||
<div class="notice-title-row">
|
||||
<div class="notice-title">校内调配通知单</div>
|
||||
<div class="doc-number">编号:</div>
|
||||
</div>
|
||||
|
||||
<!-- 通知单内容 -->
|
||||
<div class="notice-content">
|
||||
<div class="content-line">
|
||||
<span class="underline-field">{{ detailData.fromDeptName || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室):</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line indent">
|
||||
<span class="text">经学校研究决定,调配</span>
|
||||
<span class="underline-field">{{ detailData.realName || '________' }}</span>
|
||||
<span class="text">同志到</span>
|
||||
<span class="underline-field">{{ detailData.toDeptName1 || '________' }}</span>
|
||||
<span class="text">(院、部、中心、处室)</span>
|
||||
<span class="underline-field">{{ detailData.pos || '________' }}</span>
|
||||
<span class="text">(专技、管理、工勤)岗位工作,请做好工作安排。</span>
|
||||
</div>
|
||||
|
||||
<div class="content-line">
|
||||
<span class="text">限</span>
|
||||
<span class="underline-field">{{ detailData.year1 || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month1 || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day1 || '____' }}</span>
|
||||
<span class="text">日前报到,并将该单交财务处。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 通知单底部 -->
|
||||
<div class="notice-footer">
|
||||
<div class="footer-center">
|
||||
<div class="dept-name-bold">组织人事处</div>
|
||||
<div class="date-line">
|
||||
<span class="underline-field">{{ detailData.year || '____' }}</span>
|
||||
<span class="text">年</span>
|
||||
<span class="underline-field">{{ detailData.month || '____' }}</span>
|
||||
<span class="text">月</span>
|
||||
<span class="underline-field">{{ detailData.day || '____' }}</span>
|
||||
<span class="text">日</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 签字栏 -->
|
||||
<div class="signature-section">
|
||||
<div class="signature-left">
|
||||
<div class="signature-label">调配(出)部门领导签字/日期:</div>
|
||||
</div>
|
||||
<div class="signature-right">
|
||||
<div class="signature-label">接收部门领导签字/日期:</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 打印按钮 -->
|
||||
<div class="print-actions" v-if="!loading">
|
||||
<el-button type="primary" icon="Printer" @click="handlePrint">打印</el-button>
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { print } from '/@/api/professional/professionaluser/professionalteacherstationchange'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { print } from '/@/api/professional/professionaluser/professionalteacherstationchange';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const message = useMessage()
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const message = useMessage();
|
||||
|
||||
const loading = ref(false)
|
||||
const detailData = ref<any>({})
|
||||
const printContainerRef = ref<HTMLElement>()
|
||||
const printContentRef = ref<HTMLElement>()
|
||||
const loading = ref(false);
|
||||
const detailData = ref<any>({});
|
||||
const printContainerRef = ref<HTMLElement>();
|
||||
const printContentRef = ref<HTMLElement>();
|
||||
|
||||
// 解析日期
|
||||
const parseDate = (dateStr: string) => {
|
||||
if (!dateStr) return { year: '', month: '', day: '' }
|
||||
const date = new Date(dateStr)
|
||||
return {
|
||||
year: date.getFullYear().toString(),
|
||||
month: (date.getMonth() + 1).toString().padStart(2, '0'),
|
||||
day: date.getDate().toString().padStart(2, '0')
|
||||
}
|
||||
}
|
||||
if (!dateStr) return { year: '', month: '', day: '' };
|
||||
const date = new Date(dateStr);
|
||||
return {
|
||||
year: date.getFullYear().toString(),
|
||||
month: (date.getMonth() + 1).toString().padStart(2, '0'),
|
||||
day: date.getDate().toString().padStart(2, '0'),
|
||||
};
|
||||
};
|
||||
|
||||
// 签发日期
|
||||
const issueDate = computed(() => {
|
||||
return parseDate(detailData.value.changeDate || '')
|
||||
})
|
||||
return parseDate(detailData.value.changeDate || '');
|
||||
});
|
||||
|
||||
const issueYear = computed(() => issueDate.value.year)
|
||||
const issueMonth = computed(() => issueDate.value.month)
|
||||
const issueDay = computed(() => issueDate.value.day)
|
||||
const issueYear = computed(() => issueDate.value.year);
|
||||
const issueMonth = computed(() => issueDate.value.month);
|
||||
const issueDay = computed(() => issueDate.value.day);
|
||||
|
||||
// 报到日期(假设是调令日期,可根据实际需求调整)
|
||||
const reportDate = computed(() => {
|
||||
return parseDate(detailData.value.changeDate || '')
|
||||
})
|
||||
return parseDate(detailData.value.changeDate || '');
|
||||
});
|
||||
|
||||
const reportYear = computed(() => reportDate.value.year)
|
||||
const reportMonth = computed(() => reportDate.value.month)
|
||||
const reportDay = computed(() => reportDate.value.day)
|
||||
const reportYear = computed(() => reportDate.value.year);
|
||||
const reportMonth = computed(() => reportDate.value.month);
|
||||
const reportDay = computed(() => reportDate.value.day);
|
||||
|
||||
// 获取详情数据
|
||||
const fetchDetail = async () => {
|
||||
// 优先从 params 获取,如果没有则从 query 获取
|
||||
const id = (route.params.id || route.query.id) as string
|
||||
if (!id) {
|
||||
message.error('缺少调令ID')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await print(id)
|
||||
if (response && response.data) {
|
||||
detailData.value = response.data
|
||||
} else {
|
||||
message.error('获取调令信息失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取调令详情失败:', error)
|
||||
message.error('获取调令信息失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
// 优先从 params 获取,如果没有则从 query 获取
|
||||
const id = (route.params.id || route.query.id) as string;
|
||||
if (!id) {
|
||||
message.error('缺少调令ID');
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await print(id);
|
||||
if (response && response.data) {
|
||||
detailData.value = response.data;
|
||||
} else {
|
||||
message.error('获取调令信息失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取调令详情失败:', error);
|
||||
message.error('获取调令信息失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 打印
|
||||
const handlePrint = () => {
|
||||
// 使用 ref 直接操作元素
|
||||
if (printContainerRef.value) {
|
||||
printContainerRef.value.style.display = 'flex'
|
||||
printContainerRef.value.style.visibility = 'visible'
|
||||
printContainerRef.value.style.opacity = '1'
|
||||
}
|
||||
if (printContentRef.value) {
|
||||
printContentRef.value.style.display = 'block'
|
||||
printContentRef.value.style.visibility = 'visible'
|
||||
printContentRef.value.style.opacity = '1'
|
||||
}
|
||||
|
||||
// 隐藏左侧菜单等元素
|
||||
const asideElements = document.querySelectorAll('.layout-aside, .layout-header, .layout-navbars, .layout-tags-view, .layout-breadcrumb')
|
||||
asideElements.forEach((el: any) => {
|
||||
if (el) {
|
||||
el.style.display = 'none'
|
||||
}
|
||||
})
|
||||
|
||||
// 调整主内容区
|
||||
const mainElements = document.querySelectorAll('.layout-main')
|
||||
mainElements.forEach((el: any) => {
|
||||
if (el) {
|
||||
el.style.marginLeft = '0'
|
||||
el.style.width = '100%'
|
||||
}
|
||||
})
|
||||
|
||||
// 延迟打印,确保样式已应用
|
||||
setTimeout(() => {
|
||||
window.print()
|
||||
}, 200)
|
||||
}
|
||||
// 使用 ref 直接操作元素
|
||||
if (printContainerRef.value) {
|
||||
printContainerRef.value.style.display = 'flex';
|
||||
printContainerRef.value.style.visibility = 'visible';
|
||||
printContainerRef.value.style.opacity = '1';
|
||||
}
|
||||
if (printContentRef.value) {
|
||||
printContentRef.value.style.display = 'block';
|
||||
printContentRef.value.style.visibility = 'visible';
|
||||
printContentRef.value.style.opacity = '1';
|
||||
}
|
||||
|
||||
// 隐藏左侧菜单等元素
|
||||
const asideElements = document.querySelectorAll('.layout-aside, .layout-header, .layout-navbars, .layout-tags-view, .layout-breadcrumb');
|
||||
asideElements.forEach((el: any) => {
|
||||
if (el) {
|
||||
el.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// 调整主内容区
|
||||
const mainElements = document.querySelectorAll('.layout-main');
|
||||
mainElements.forEach((el: any) => {
|
||||
if (el) {
|
||||
el.style.marginLeft = '0';
|
||||
el.style.width = '100%';
|
||||
}
|
||||
});
|
||||
|
||||
// 延迟打印,确保样式已应用
|
||||
setTimeout(() => {
|
||||
window.print();
|
||||
}, 200);
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
router.back()
|
||||
}
|
||||
router.back();
|
||||
};
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
fetchDetail()
|
||||
})
|
||||
fetchDetail();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 全局打印样式,用于隐藏 layout 元素 -->
|
||||
<style lang="scss">
|
||||
/* 打印时隐藏左侧菜单和其他 layout 元素 */
|
||||
@media print {
|
||||
/* 只隐藏左侧菜单和头部,不影响其他内容 */
|
||||
.layout-aside,
|
||||
.layout-columns-aside,
|
||||
.layout-header,
|
||||
.layout-navbars,
|
||||
.layout-tags-view,
|
||||
.layout-breadcrumb,
|
||||
.el-backtop {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 确保主内容区全宽 */
|
||||
.layout-main {
|
||||
margin-left: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* 隐藏打印按钮 */
|
||||
.print-actions {
|
||||
display: none !important;
|
||||
}
|
||||
/* 只隐藏左侧菜单和头部,不影响其他内容 */
|
||||
.layout-aside,
|
||||
.layout-columns-aside,
|
||||
.layout-header,
|
||||
.layout-navbars,
|
||||
.layout-tags-view,
|
||||
.layout-breadcrumb,
|
||||
.el-backtop {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 确保主内容区全宽 */
|
||||
.layout-main {
|
||||
margin-left: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* 隐藏打印按钮 */
|
||||
.print-actions {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.print-container {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.print-content {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
padding: 40px 60px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
padding: 40px 60px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
/* 上半部分:存根 */
|
||||
.stub-section {
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.main-title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
letter-spacing: 2px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.subtitle-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle-text {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.stub-label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.doc-number {
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.stub-content {
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.content-line {
|
||||
margin-bottom: 15px;
|
||||
line-height: 2;
|
||||
|
||||
&.indent {
|
||||
padding-left: 2em;
|
||||
}
|
||||
margin-bottom: 15px;
|
||||
line-height: 2;
|
||||
|
||||
&.indent {
|
||||
padding-left: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.underline-field {
|
||||
display: inline-block;
|
||||
min-width: 80px;
|
||||
border-bottom: 1px solid #333;
|
||||
text-align: center;
|
||||
padding: 0 5px;
|
||||
margin: 0 3px;
|
||||
font-weight: 500;
|
||||
display: inline-block;
|
||||
min-width: 80px;
|
||||
border-bottom: 1px solid #333;
|
||||
text-align: center;
|
||||
padding: 0 5px;
|
||||
margin: 0 3px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #333;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.stub-footer {
|
||||
margin-top: 40px;
|
||||
text-align: right;
|
||||
margin-top: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.footer-right {
|
||||
display: inline-block;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.footer-center {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dept-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dept-name-bold {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.date-line {
|
||||
font-size: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 分隔线 */
|
||||
.divider-line {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #ddd;
|
||||
margin: 30px 0;
|
||||
border-top: 1px dashed #999;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #ddd;
|
||||
margin: 30px 0;
|
||||
border-top: 1px dashed #999;
|
||||
}
|
||||
|
||||
/* 下半部分:正式通知单 */
|
||||
.notice-section {
|
||||
margin-top: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.top-line {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #333;
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.notice-title-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.notice-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.notice-content {
|
||||
margin-bottom: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.notice-footer {
|
||||
margin-top: 50px;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.signature-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 60px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 60px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.signature-left,
|
||||
.signature-right {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.signature-label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 40px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.print-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
/* 打印容器样式 - 确保正常显示 */
|
||||
.print-container {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
background: #fff !important;
|
||||
padding: 20px !important;
|
||||
margin: 0 !important;
|
||||
width: 100% !important;
|
||||
min-height: auto !important;
|
||||
}
|
||||
|
||||
.print-content {
|
||||
display: block !important;
|
||||
background: #fff !important;
|
||||
box-shadow: none !important;
|
||||
padding: 40px 60px !important;
|
||||
margin: 0 0 20px 0 !important;
|
||||
max-width: 800px !important;
|
||||
width: 100% !important;
|
||||
font-size: 16px !important;
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
|
||||
.divider-line {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* 隐藏打印按钮 */
|
||||
.print-actions {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1.5cm;
|
||||
}
|
||||
|
||||
/* 确保上下两部分在同一页 */
|
||||
.stub-section,
|
||||
.notice-section {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
/* 打印容器样式 - 确保正常显示 */
|
||||
.print-container {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
background: #fff !important;
|
||||
padding: 20px !important;
|
||||
margin: 0 !important;
|
||||
width: 100% !important;
|
||||
min-height: auto !important;
|
||||
}
|
||||
|
||||
.print-content {
|
||||
display: block !important;
|
||||
background: #fff !important;
|
||||
box-shadow: none !important;
|
||||
padding: 40px 60px !important;
|
||||
margin: 0 0 20px 0 !important;
|
||||
max-width: 800px !important;
|
||||
width: 100% !important;
|
||||
font-size: 16px !important;
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
|
||||
.divider-line {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* 隐藏打印按钮 */
|
||||
.print-actions {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 1.5cm;
|
||||
}
|
||||
|
||||
/* 确保上下两部分在同一页 */
|
||||
.stub-section,
|
||||
.notice-section {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,237 +1,195 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachertype_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalteachertype_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="typeName" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachertype_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachertype_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="typeName" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="类型名称" prop="typeName">
|
||||
<el-input
|
||||
v-model="form.typeName"
|
||||
placeholder="请输入类型名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalteachertype_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachertype_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="类型名称" prop="typeName">
|
||||
<el-input v-model="form.typeName" placeholder="请输入类型名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalteachertype'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalteachertype';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
typeName: [
|
||||
{ required: true, message: '请输入类型名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
typeName: [{ required: true, message: '请输入类型名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,237 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachingmaterialconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionalteachingmaterialconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="typeName" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachingmaterialconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachingmaterialconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="typeName" label="类型名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="类型名称" prop="typeName">
|
||||
<el-input
|
||||
v-model="form.typeName"
|
||||
placeholder="请输入类型名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachingmaterialconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalteachingmaterialconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="类型名称" prop="typeName">
|
||||
<el-input v-model="form.typeName" placeholder="请输入类型名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalteachingmaterialconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalteachingmaterialconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
typeName: [
|
||||
{ required: true, message: '请输入类型名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
typeName: [{ required: true, message: '请输入类型名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
typeName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
typeName: row.typeName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,236 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlelevelconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionaltitlelevelconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="professionalTitle" label="职称等级名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlelevelconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlelevelconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="professionalTitle" label="职称等级名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="职称等级名称" prop="professionalTitle">
|
||||
<el-input
|
||||
v-model="form.professionalTitle"
|
||||
placeholder="请输入职称等级名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlelevelconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlelevelconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="职称等级名称" prop="professionalTitle">
|
||||
<el-input v-model="form.professionalTitle" placeholder="请输入职称等级名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionaltitlelevelconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionaltitlelevelconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
professionalTitle: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
professionalTitle: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
professionalTitle: [
|
||||
{ required: true, message: '请输入职称等级名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
professionalTitle: [{ required: true, message: '请输入职称等级名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
professionalTitle: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
professionalTitle: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
professionalTitle: row.professionalTitle || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
professionalTitle: row.professionalTitle || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,329 +1,292 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" title="修改职称" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="职称等级" prop="professionalTitleConfigId">
|
||||
<el-select
|
||||
v-model="dataForm.professionalTitleConfigId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择职称等级"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in proTitleList"
|
||||
:key="item.id"
|
||||
:label="item.professionalTitle"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-dialog v-model="dialogVisible" title="修改职称" width="600px" append-to-body :close-on-click-modal="false" destroy-on-close>
|
||||
<div v-if="showForm">
|
||||
<el-form ref="formRef" :model="dataForm" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="职称等级" prop="professionalTitleConfigId">
|
||||
<el-select v-model="dataForm.professionalTitleConfigId" filterable clearable placeholder="请选择职称等级">
|
||||
<el-option v-for="item in proTitleList" :key="item.id" :label="item.professionalTitle" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专业技术职务" prop="majorStation">
|
||||
<el-select
|
||||
v-model="dataForm.majorStation"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择专业技术职务"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in majorStationList"
|
||||
:key="item.id"
|
||||
:label="item.majorStationName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="专业技术职务" prop="majorStation">
|
||||
<el-select v-model="dataForm.majorStation" filterable clearable placeholder="请选择专业技术职务">
|
||||
<el-option v-for="item in majorStationList" :key="item.id" :label="item.majorStationName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="取证时间" prop="certificateTime">
|
||||
<el-date-picker
|
||||
v-model="dataForm.certificateTime"
|
||||
type="date"
|
||||
placeholder="请选择取证时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="取证时间" prop="certificateTime">
|
||||
<el-date-picker
|
||||
v-model="dataForm.certificateTime"
|
||||
type="date"
|
||||
placeholder="请选择取证时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="职称任职时间" prop="inOfficeDate">
|
||||
<el-date-picker
|
||||
v-model="dataForm.inOfficeDate"
|
||||
type="date"
|
||||
placeholder="请选择职称任职时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="职称任职时间" prop="inOfficeDate">
|
||||
<el-date-picker
|
||||
v-model="dataForm.inOfficeDate"
|
||||
type="date"
|
||||
placeholder="请选择职称任职时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
clearable
|
||||
show-word-limit
|
||||
maxlength="32"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input
|
||||
v-model="dataForm.certificateNumber"
|
||||
placeholder="请输入证书编号(仅支持英文和数字)"
|
||||
clearable
|
||||
show-word-limit
|
||||
maxlength="32"
|
||||
@input="handleCertificateNumberInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证明材料" prop="evidence">
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px;">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-form-item label="证明材料" prop="evidence">
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
:limit="1"
|
||||
:action="url"
|
||||
:file-list="fileList"
|
||||
:on-success="materiaUploadSuccess"
|
||||
:accept="'.jpg,.jpeg,.png,.pdf'"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="margin-top: 8px">
|
||||
<el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { getProfessionalTitleList } from '/@/api/professional/rsbase/professionaltitlelevelconfig'
|
||||
import { getMajorStationList } from '/@/api/professional/rsbase/professionalmajorstation'
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionaltitlerelation'
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock'
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { getProfessionalTitleList } from '/@/api/professional/rsbase/professionaltitlelevelconfig';
|
||||
import { getMajorStationList } from '/@/api/professional/rsbase/professionalmajorstation';
|
||||
import { addObj } from '/@/api/professional/professionaluser/professionaltitlerelation';
|
||||
import { checkLocked } from '/@/api/professional/professionalstatuslock';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref();
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 对话框显示状态(内部管理)
|
||||
const dialogVisible = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const dataForm = reactive({
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: '',
|
||||
certificateTime: '',
|
||||
inOfficeDate: '',
|
||||
certificateNumber: '',
|
||||
evidence: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: '',
|
||||
certificateTime: '',
|
||||
inOfficeDate: '',
|
||||
certificateNumber: '',
|
||||
evidence: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
professionalTitleConfigId: [
|
||||
{ required: true, message: '请选择职称等级', trigger: 'change' }
|
||||
],
|
||||
majorStation: [
|
||||
{ required: true, message: '请选择专业技术职务', trigger: 'change' }
|
||||
],
|
||||
certificateTime: [
|
||||
{ required: true, message: '请选择取证时间', trigger: 'change' }
|
||||
],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' }
|
||||
],
|
||||
evidence: [
|
||||
{ required: true, message: '请上传证明材料', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
professionalTitleConfigId: [{ required: true, message: '请选择职称等级', trigger: 'change' }],
|
||||
majorStation: [{ required: true, message: '请选择专业技术职务', trigger: 'change' }],
|
||||
certificateTime: [{ required: true, message: '请选择取证时间', trigger: 'change' }],
|
||||
certificateNumber: [
|
||||
{ required: true, message: '请输入证书编号', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '证书编号只能包含英文和数字', trigger: 'blur' },
|
||||
],
|
||||
evidence: [{ required: true, message: '请上传证明材料', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 基础信息
|
||||
const baseInfoAbout = reactive<{
|
||||
proTitleList: any[]
|
||||
majorStationList: any[]
|
||||
proTitleList: any[];
|
||||
majorStationList: any[];
|
||||
}>({
|
||||
proTitleList: [],
|
||||
majorStationList: []
|
||||
})
|
||||
proTitleList: [],
|
||||
majorStationList: [],
|
||||
});
|
||||
|
||||
// 上传相关
|
||||
const url = ref('')
|
||||
const fileList = ref<any[]>([])
|
||||
const url = ref('');
|
||||
const fileList = ref<any[]>([]);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 显示表单标志
|
||||
const showForm = ref(false)
|
||||
const showForm = ref(false);
|
||||
|
||||
// 计算属性:职称列表
|
||||
const proTitleList = computed(() => baseInfoAbout.proTitleList as any[])
|
||||
const proTitleList = computed(() => baseInfoAbout.proTitleList as any[]);
|
||||
|
||||
// 计算属性:专业技术职务列表
|
||||
const majorStationList = computed(() => baseInfoAbout.majorStationList as any[])
|
||||
const majorStationList = computed(() => baseInfoAbout.majorStationList as any[]);
|
||||
|
||||
// 初始化字典数据
|
||||
const initDicData = async () => {
|
||||
try {
|
||||
const [titleResponse, stationResponse] = await Promise.all([
|
||||
getProfessionalTitleList(),
|
||||
getMajorStationList()
|
||||
])
|
||||
|
||||
// 处理职称列表(与 index.vue 保持一致)
|
||||
if (titleResponse && titleResponse.data) {
|
||||
baseInfoAbout.proTitleList = titleResponse.data
|
||||
}
|
||||
|
||||
// 处理专业技术职务列表(与 index.vue 保持一致)
|
||||
if (stationResponse && stationResponse.data) {
|
||||
baseInfoAbout.majorStationList = stationResponse.data
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('获取字典数据失败')
|
||||
}
|
||||
}
|
||||
try {
|
||||
const [titleResponse, stationResponse] = await Promise.all([getProfessionalTitleList(), getMajorStationList()]);
|
||||
|
||||
// 处理职称列表(与 index.vue 保持一致)
|
||||
if (titleResponse && titleResponse.data) {
|
||||
baseInfoAbout.proTitleList = titleResponse.data;
|
||||
}
|
||||
|
||||
// 处理专业技术职务列表(与 index.vue 保持一致)
|
||||
if (stationResponse && stationResponse.data) {
|
||||
baseInfoAbout.majorStationList = stationResponse.data;
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('获取字典数据失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 证书编号输入处理(只允许英文和数字)
|
||||
const handleCertificateNumberInput = (value: string) => {
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '')
|
||||
}
|
||||
dataForm.certificateNumber = value.replace(/[^A-Za-z0-9]/g, '');
|
||||
};
|
||||
|
||||
// 文件上传成功
|
||||
const materiaUploadSuccess = (response: any) => {
|
||||
if (response.data && response.data.code === "-1") {
|
||||
message.error("当前不允许上传文件")
|
||||
return
|
||||
}
|
||||
// 统一使用 evidence 字段存储证明材料URL(与后端API一致)
|
||||
dataForm.evidence = response.data.url
|
||||
// 上传成功后清除该字段的验证错误
|
||||
formRef.value?.clearValidate('evidence')
|
||||
}
|
||||
if (response.data && response.data.code === '-1') {
|
||||
message.error('当前不允许上传文件');
|
||||
return;
|
||||
}
|
||||
// 统一使用 evidence 字段存储证明材料URL(与后端API一致)
|
||||
dataForm.evidence = response.data.url;
|
||||
// 上传成功后清除该字段的验证错误
|
||||
formRef.value?.clearValidate('evidence');
|
||||
};
|
||||
|
||||
// 打开对话框
|
||||
const openDialog = async (row?: any) => {
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('title')
|
||||
if (lockResponse.data) {
|
||||
message.warning("新增功能已锁定,暂不允许操作")
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=2`
|
||||
fileList.value = []
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
Object.assign(dataForm, {
|
||||
professionalTitleConfigId: row.professionalTitleConfigId || '',
|
||||
majorStation: row.majorStation || '',
|
||||
certificateTime: row.certificateTime || '',
|
||||
inOfficeDate: row.inOfficeDate || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
evidence: row.evidence || '',
|
||||
state: row.state || '',
|
||||
id: row.id || ''
|
||||
})
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: '',
|
||||
certificateTime: '',
|
||||
inOfficeDate: '',
|
||||
certificateNumber: '',
|
||||
evidence: '',
|
||||
state: '',
|
||||
id: ''
|
||||
})
|
||||
}
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData()
|
||||
showForm.value = true
|
||||
dialogVisible.value = true
|
||||
}
|
||||
// 新增模式:先检查是否锁定
|
||||
if (!row || !row.id) {
|
||||
try {
|
||||
const lockResponse = await checkLocked('title');
|
||||
if (lockResponse.data) {
|
||||
message.warning('新增功能已锁定,暂不允许操作');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 公共设置
|
||||
url.value = `/professional/file/teacherAboutInfoUpload?type=2`;
|
||||
fileList.value = [];
|
||||
|
||||
// 根据是否有 row 设置不同的表单数据
|
||||
if (row && row.id) {
|
||||
// 编辑模式:使用传入的数据
|
||||
Object.assign(dataForm, {
|
||||
professionalTitleConfigId: row.professionalTitleConfigId || '',
|
||||
majorStation: row.majorStation || '',
|
||||
certificateTime: row.certificateTime || '',
|
||||
inOfficeDate: row.inOfficeDate || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
evidence: row.evidence || '',
|
||||
state: row.state || '',
|
||||
id: row.id || '',
|
||||
});
|
||||
} else {
|
||||
// 新增模式:重置为空
|
||||
Object.assign(dataForm, {
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: '',
|
||||
certificateTime: '',
|
||||
inOfficeDate: '',
|
||||
certificateNumber: '',
|
||||
evidence: '',
|
||||
state: '',
|
||||
id: '',
|
||||
});
|
||||
}
|
||||
|
||||
// 公共操作:加载字典数据并显示对话框
|
||||
await initDicData();
|
||||
showForm.value = true;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const dialogSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用)
|
||||
const submitData: any = {
|
||||
professionalTitleConfigId: dataForm.professionalTitleConfigId,
|
||||
majorStation: dataForm.majorStation,
|
||||
certificateTime: dataForm.certificateTime,
|
||||
inOfficeDate: dataForm.inOfficeDate,
|
||||
certificateNumber: dataForm.certificateNumber,
|
||||
evidence: dataForm.evidence,
|
||||
state: '' // 待审核
|
||||
}
|
||||
|
||||
// 编辑时需要传递 id
|
||||
if (dataForm.id) {
|
||||
submitData.id = dataForm.id
|
||||
}
|
||||
|
||||
await addObj(submitData)
|
||||
message.success(dataForm.id ? "修改成功" : "提交成功")
|
||||
dialogVisible.value = false
|
||||
emit('refreshData')
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
// 统一使用 addObj 接口(新增和编辑都使用)
|
||||
const submitData: any = {
|
||||
professionalTitleConfigId: dataForm.professionalTitleConfigId,
|
||||
majorStation: dataForm.majorStation,
|
||||
certificateTime: dataForm.certificateTime,
|
||||
inOfficeDate: dataForm.inOfficeDate,
|
||||
certificateNumber: dataForm.certificateNumber,
|
||||
evidence: dataForm.evidence,
|
||||
state: '', // 待审核
|
||||
};
|
||||
|
||||
// 编辑时需要传递 id
|
||||
if (dataForm.id) {
|
||||
submitData.id = dataForm.id;
|
||||
}
|
||||
|
||||
await addObj(submitData);
|
||||
message.success(dataForm.id ? '修改成功' : '提交成功');
|
||||
dialogVisible.value = false;
|
||||
emit('refreshData');
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化方法(保持兼容性)
|
||||
const init = () => {
|
||||
// 新版本不再需要初始化配置
|
||||
}
|
||||
// 新版本不再需要初始化配置
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog,
|
||||
init
|
||||
})
|
||||
openDialog,
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,466 +1,409 @@
|
||||
<template>
|
||||
<div class="page-cards">
|
||||
<div class="page-wrapper">
|
||||
<!-- 筛选卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<search-form
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
:show-filter-title="false"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
class="filter-input"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
clearable
|
||||
placeholder="请输入工号"
|
||||
class="filter-input"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select
|
||||
v-model="search.state"
|
||||
clearable
|
||||
placeholder="请选择审核状态"
|
||||
class="filter-select"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in professionalState"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="职称" prop="professionalTitleConfigId">
|
||||
<el-select
|
||||
v-model="search.professionalTitleConfigId"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择职称"
|
||||
class="filter-select"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in professionalTitleList"
|
||||
:key="item.id"
|
||||
:label="item.professionalTitle"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="专业技术职务" prop="majorStation">
|
||||
<el-select
|
||||
v-model="search.majorStation"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择专业技术职务"
|
||||
class="filter-select"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in majorStationList"
|
||||
:key="item.id"
|
||||
:label="item.majorStationName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
</el-card>
|
||||
<div class="page-cards">
|
||||
<div class="page-wrapper">
|
||||
<!-- 筛选卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<search-form :model="search" ref="searchFormRef" :show-filter-title="false" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" clearable placeholder="请输入姓名" class="filter-input" />
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" clearable placeholder="请输入工号" class="filter-input" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态" prop="state">
|
||||
<el-select v-model="search.state" clearable placeholder="请选择审核状态" class="filter-select">
|
||||
<el-option v-for="item in professionalState" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="职称" prop="professionalTitleConfigId">
|
||||
<el-select v-model="search.professionalTitleConfigId" clearable filterable placeholder="请选择职称" class="filter-select">
|
||||
<el-option v-for="item in professionalTitleList" :key="item.id" :label="item.professionalTitle" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="专业技术职务" prop="majorStation">
|
||||
<el-select v-model="search.majorStation" clearable filterable placeholder="请选择专业技术职务" class="filter-select">
|
||||
<el-option v-for="item in majorStationList" :key="item.id" :label="item.majorStationName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 列表内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Medal /></el-icon>
|
||||
职称关系
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<div class="action-group">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd"
|
||||
>新增</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading"
|
||||
>导出信息</el-button>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<RightToolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getDataList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 列表内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Medal /></el-icon>
|
||||
职称关系
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<div class="action-group">
|
||||
<el-button v-if="hasAuth('professional_professionaltitlerelation_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_teacherbase_export')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleDownLoadWord"
|
||||
:loading="exportLoading"
|
||||
>导出信息</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<RightToolbar v-model:showSearch="showSearch" @queryTable="getDataList" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
stripe
|
||||
class="titlerelation-table"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="professionalTitleConfigId" label="职称" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getProfessionalTitleName(scope.row.professionalTitleConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="majorStation" label="专业技术职务" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getMajorStationName(scope.row.majorStation) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
stripe
|
||||
class="titlerelation-table"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.evidence && scope.row.evidence !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.srcList)">查看
|
||||
</el-button>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="state" label="审核状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<AuditState :state="scope.row.state" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="op-cell">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)">部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)">部门驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_del')"
|
||||
type="danger"
|
||||
link
|
||||
icon="delete"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-table-column prop="professionalTitleConfigId" label="职称" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getProfessionalTitleName(scope.row.professionalTitleConfigId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file
|
||||
v-for="src in imgUrl"
|
||||
:key="src.title"
|
||||
:authSrc="src.url"
|
||||
dialog-title="职称材料"
|
||||
/>
|
||||
<el-table-column prop="majorStation" label="专业技术职务" min-width="150" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getMajorStationName(scope.row.majorStation) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<MultiDialog ref="multiDialogRef" @getList="getDataList" :page="state.pagination" :nowRow="null" />
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
<el-table-column label="证明材料" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.evidence && scope.row.evidence !== ''"
|
||||
type="primary"
|
||||
link
|
||||
icon="Document"
|
||||
@click="handlePreview(scope.row.srcList)"
|
||||
>查看
|
||||
</el-button>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="backReason" label="驳回理由" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="op-cell">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_edit') && (scope.row.state === '0' || scope.row.state === '-2')"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit-pen"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canDeptExam"
|
||||
type="success"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="changeState(scope.row, 1)"
|
||||
>部门通过
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltitlerelation_exam') && scope.row.canDeptBack"
|
||||
type="danger"
|
||||
link
|
||||
icon="CircleClose"
|
||||
@click="changeState(scope.row, -2)"
|
||||
>部门驳回
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_professionaltitlerelation_del')" type="danger" link icon="delete" @click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 材料预览:图片直接显示,PDF 在组件内部 dialog 中显示 -->
|
||||
<preview-file v-for="src in imgUrl" :key="src.title" :authSrc="src.url" dialog-title="职称材料" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<MultiDialog ref="multiDialogRef" @getList="getDataList" :page="state.pagination" :nowRow="null" />
|
||||
<DataForm ref="dataFormRef" @refreshData="handleFilter" />
|
||||
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { useDict } from '/@/hooks/dict'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
// 接口
|
||||
import {
|
||||
fetchList,
|
||||
examObj,
|
||||
delObj
|
||||
} from '/@/api/professional/professionaluser/professionaltitlerelation'
|
||||
import { getProfessionalTitleList } from '/@/api/professional/rsbase/professionaltitlelevelconfig'
|
||||
import { getMajorStationList } from '/@/api/professional/rsbase/professionalmajorstation'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { Medal } from '@element-plus/icons-vue'
|
||||
import { fetchList, examObj, delObj } from '/@/api/professional/professionaluser/professionaltitlerelation';
|
||||
import { getProfessionalTitleList } from '/@/api/professional/rsbase/professionaltitlelevelconfig';
|
||||
import { getMajorStationList } from '/@/api/professional/rsbase/professionalmajorstation';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { Medal } from '@element-plus/icons-vue';
|
||||
import { makeExportTeacherInfoByTypeTask } from '/@/api/professional/professionalfile';
|
||||
// 子组件
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'))
|
||||
const MultiDialog = defineAsyncComponent(() => import('/@/views/professional/teacherbase/multiDialog.vue'))
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'))
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue'));
|
||||
const MultiDialog = defineAsyncComponent(() => import('/@/views/professional/teacherbase/multiDialog.vue'));
|
||||
const DataForm = defineAsyncComponent(() => import('./form.vue'));
|
||||
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'));
|
||||
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'));
|
||||
|
||||
// 无权限即无节点:使用 useAuth + v-if
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 字典数据
|
||||
const { professional_state: professionalState } = useDict('professional_state')
|
||||
const { professional_state: professionalState } = useDict('professional_state');
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const multiDialogRef = ref()
|
||||
const dataFormRef = ref()
|
||||
const backReasonRef = ref()
|
||||
const showSearch = ref(true) // 方案 F:默认收起筛选,首屏仅一张大卡片
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const multiDialogRef = ref();
|
||||
const dataFormRef = ref();
|
||||
const backReasonRef = ref();
|
||||
const showSearch = ref(true); // 方案 F:默认收起筛选,首屏仅一张大卡片
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: ''
|
||||
})
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: '',
|
||||
});
|
||||
|
||||
// 材料预览
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([])
|
||||
const imgUrl = ref<Array<{ title: string; url: string }>>([]);
|
||||
|
||||
// 导出加载状态
|
||||
const exportLoading = ref(false)
|
||||
const exportLoading = ref(false);
|
||||
|
||||
// 职称和专业技术职务列表
|
||||
const professionalTitleList = ref<any[]>([])
|
||||
const majorStationList = ref<any[]>([])
|
||||
const professionalTitleList = ref<any[]>([]);
|
||||
const majorStationList = ref<any[]>([]);
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
const records = response.data.records || []
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
if (v.evidence != null) {
|
||||
v.srcList = [v.evidence]
|
||||
} else {
|
||||
v.srcList = []
|
||||
}
|
||||
})
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
const records = response.data.records || [];
|
||||
// 处理证明材料列表
|
||||
records.forEach((v: any) => {
|
||||
if (v.evidence != null) {
|
||||
v.srcList = [v.evidence];
|
||||
} else {
|
||||
v.srcList = [];
|
||||
}
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
records,
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 预览材料
|
||||
const handlePreview = (list: string[]) => {
|
||||
imgUrl.value = []
|
||||
nextTick(() => {
|
||||
list.forEach(v => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
imgUrl.value = [];
|
||||
nextTick(() => {
|
||||
list.forEach((v) => {
|
||||
imgUrl.value.push({
|
||||
title: '',
|
||||
url: v,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 审核状态变更
|
||||
const changeState = (row: any, val: number) => {
|
||||
if (val === 1) {
|
||||
const str = '通过'
|
||||
messageBox.confirm(`是否确认${str}${row.realName}的申请`).then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val
|
||||
})
|
||||
message.success('操作成功')
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
}).catch(() => {})
|
||||
} else if (val === -2) {
|
||||
backReasonRef.value?.init(row, 'title')
|
||||
}
|
||||
}
|
||||
if (val === 1) {
|
||||
const str = '通过';
|
||||
messageBox
|
||||
.confirm(`是否确认${str}${row.realName}的申请`)
|
||||
.then(async () => {
|
||||
try {
|
||||
await examObj({
|
||||
id: row.id,
|
||||
state: val,
|
||||
});
|
||||
message.success('操作成功');
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (val === -2) {
|
||||
backReasonRef.value?.init(row, 'title');
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList()
|
||||
}
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: ''
|
||||
})
|
||||
getDataList()
|
||||
}
|
||||
Object.assign(search, {
|
||||
state: '',
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
professionalTitleConfigId: '',
|
||||
majorStation: '',
|
||||
});
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
dataFormRef.value?.openDialog()
|
||||
}
|
||||
dataFormRef.value?.openDialog();
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = (row: any) => {
|
||||
dataFormRef.value?.openDialog(row)
|
||||
}
|
||||
dataFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleDownLoadWord = async () => {
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20002' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
}
|
||||
exportLoading.value = true;
|
||||
let params = Object.assign(search, { type: 'P20002' });
|
||||
makeExportTeacherInfoByTypeTask(params).then((res: any) => {
|
||||
message.success('后台下载进行中,请稍后查看任务列表');
|
||||
});
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
}, 3000); // 5分钟后自动关闭
|
||||
};
|
||||
|
||||
// 获取职称名称
|
||||
const getProfessionalTitleName = (id: string | number) => {
|
||||
const item = professionalTitleList.value.find((item: any) => item.id === id)
|
||||
return item ? item.professionalTitle : '-'
|
||||
}
|
||||
const item = professionalTitleList.value.find((item: any) => item.id === id);
|
||||
return item ? item.professionalTitle : '-';
|
||||
};
|
||||
|
||||
// 获取专业技术职务名称
|
||||
const getMajorStationName = (id: string | number) => {
|
||||
const item = majorStationList.value.find((item: any) => item.id === id)
|
||||
return item ? item.majorStationName : '-'
|
||||
}
|
||||
const item = majorStationList.value.find((item: any) => item.id === id);
|
||||
return item ? item.majorStationName : '-';
|
||||
};
|
||||
|
||||
// 加载字典数据
|
||||
const loadDictData = async () => {
|
||||
try {
|
||||
// 加载职称列表
|
||||
const titleRes = await getProfessionalTitleList()
|
||||
if (titleRes && titleRes.data) {
|
||||
professionalTitleList.value = titleRes.data
|
||||
}
|
||||
|
||||
// 加载专业技术职务列表
|
||||
const majorRes = await getMajorStationList()
|
||||
if (majorRes && majorRes.data) {
|
||||
majorStationList.value = majorRes.data
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 加载职称列表
|
||||
const titleRes = await getProfessionalTitleList();
|
||||
if (titleRes && titleRes.data) {
|
||||
professionalTitleList.value = titleRes.data;
|
||||
}
|
||||
|
||||
// 加载专业技术职务列表
|
||||
const majorRes = await getMajorStationList();
|
||||
if (majorRes && majorRes.data) {
|
||||
majorStationList.value = majorRes.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load dict data
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化:仅加载下拉字典,表格数据由 useTable 在 createdIsNeed: true 时自动请求
|
||||
onMounted(async () => {
|
||||
await loadDictData()
|
||||
})
|
||||
await loadDictData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -468,107 +411,107 @@ onMounted(async () => {
|
||||
|
||||
/* 筛选:内容区最上方,无上外边距;与下方标题栏间距用 margin-bottom */
|
||||
.content-block__filter {
|
||||
padding: 16px 20px 5px 20px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
background: var(--el-fill-color-light);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px 5px 20px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
background: var(--el-fill-color-light);
|
||||
border-radius: 8px;
|
||||
|
||||
:deep(.filter-input),
|
||||
:deep(.filter-select) {
|
||||
width: 180px;
|
||||
}
|
||||
:deep(.filter-input),
|
||||
:deep(.filter-select) {
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 职称关系区域:无卡片,表头 + 表格 + 分页 */
|
||||
.content-block {
|
||||
background: var(--el-bg-color);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
background: var(--el-bg-color);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.content-block__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding-bottom: 14px;
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding-bottom: 14px;
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-primary);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-primary);
|
||||
|
||||
.title-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.title-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* header-actions / action-group / header-right 的基础布局来自 page-cards.scss */
|
||||
|
||||
/* 表格 */
|
||||
.titlerelation-table {
|
||||
:deep(.el-table__body td) {
|
||||
transition: background-color 0.12s ease;
|
||||
}
|
||||
:deep(.el-button + .el-button) {
|
||||
margin-left: 0;
|
||||
}
|
||||
:deep(.el-table__body td) {
|
||||
transition: background-color 0.12s ease;
|
||||
}
|
||||
:deep(.el-button + .el-button) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 操作列 */
|
||||
.op-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 8px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: var(--el-text-color-secondary, #909399);
|
||||
color: var(--el-text-color-secondary, #909399);
|
||||
}
|
||||
|
||||
/* 表格与分页间距 */
|
||||
.content-block .titlerelation-table {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 0;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.content-block .titlerelation-table + * {
|
||||
margin-top: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
/* 响应式 */
|
||||
@media (max-width: 1200px) {
|
||||
.titlerelation-page {
|
||||
padding: 8px;
|
||||
}
|
||||
.card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.header-actions {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.titlerelation-page {
|
||||
padding: 8px;
|
||||
}
|
||||
.card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.header-actions {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.action-group {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
.el-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.action-group {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
.el-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,119 +1,117 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 页面标题 -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h2 style="margin: 0; font-size: 20px; font-weight: 600; color: #303133;">职称统计</h2>
|
||||
</div>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 页面标题 -->
|
||||
<div style="margin-bottom: 20px">
|
||||
<h2 style="margin: 0; font-size: 20px; font-weight: 600; color: #303133">职称统计</h2>
|
||||
</div>
|
||||
|
||||
<!-- 图表统计 -->
|
||||
<div style="width: 100%">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="titleChartRef" style="width: 100%; height: 400px;" :option="titleChartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="titleChartTableData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="name" label="职称" width="180" align="center" />
|
||||
<el-table-column prop="value" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="比例" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 图表统计 -->
|
||||
<div style="width: 100%">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="titleChartRef" style="width: 100%; height: 400px" :option="titleChartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="titleChartTableData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="name" label="职称" width="180" align="center" />
|
||||
<el-table-column prop="value" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="比例" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24" style="margin-top: 20px;">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="techChartRef" style="width: 100%; height: 400px;" :option="techChartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="techChartTableData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="name" label="技术职务" width="180" align="center" />
|
||||
<el-table-column prop="value" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="比例" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-row :gutter="24" style="margin-top: 20px">
|
||||
<el-col :span="12">
|
||||
<v-chart ref="techChartRef" style="width: 100%; height: 400px" :option="techChartOption" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-table :data="techChartTableData" border show-summary style="width: 100%">
|
||||
<el-table-column prop="name" label="技术职务" width="180" align="center" />
|
||||
<el-table-column prop="value" label="人数" width="180" align="center" />
|
||||
<el-table-column prop="rate" label="比例" width="180" align="center" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
import { PieChart } from 'echarts/charts'
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { getChartOption } from '/@/api/professional/professionaluser/professionaltitlerelation'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import VChart from 'vue-echarts';
|
||||
import { use } from 'echarts/core';
|
||||
import { PieChart } from 'echarts/charts';
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { getChartOption } from '/@/api/professional/professionaluser/professionaltitlerelation';
|
||||
|
||||
// 注册 ECharts 组件
|
||||
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer])
|
||||
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer]);
|
||||
|
||||
// 图表引用
|
||||
const titleChartRef = ref()
|
||||
const techChartRef = ref()
|
||||
const titleChartRef = ref();
|
||||
const techChartRef = ref();
|
||||
|
||||
// 图表数据
|
||||
const titleChartOption = ref<any>({})
|
||||
const titleChartTableData = ref<any[]>([])
|
||||
const techChartOption = ref<any>({})
|
||||
const techChartTableData = ref<any[]>([])
|
||||
const titleChartOption = ref<any>({});
|
||||
const titleChartTableData = ref<any[]>([]);
|
||||
const techChartOption = ref<any>({});
|
||||
const techChartTableData = ref<any[]>([]);
|
||||
|
||||
// 初始化图表
|
||||
const initChartOption = async () => {
|
||||
try {
|
||||
const response = await getChartOption()
|
||||
const data = response.data.data || {}
|
||||
|
||||
// 职称图表
|
||||
titleChartOption.value = data.titleOption || {}
|
||||
let titleTotal = 0
|
||||
if (titleChartOption.value.series && titleChartOption.value.series[0] && titleChartOption.value.series[0].data) {
|
||||
titleChartOption.value.series[0].data.forEach((item: any) => {
|
||||
titleTotal += item.value || 0
|
||||
})
|
||||
|
||||
titleChartTableData.value = []
|
||||
titleChartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = titleTotal > 0 ? Number((item.value / titleTotal * 100).toFixed(1)) : 0
|
||||
titleChartTableData.value.push({
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
rate: `${rate}%`
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 技术职务图表
|
||||
techChartOption.value = data.techOption || {}
|
||||
let techTotal = 0
|
||||
if (techChartOption.value.series && techChartOption.value.series[0] && techChartOption.value.series[0].data) {
|
||||
techChartOption.value.series[0].data.forEach((item: any) => {
|
||||
techTotal += item.value || 0
|
||||
})
|
||||
|
||||
techChartTableData.value = []
|
||||
techChartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = techTotal > 0 ? Number((item.value / techTotal * 100).toFixed(1)) : 0
|
||||
techChartTableData.value.push({
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
rate: `${rate}%`
|
||||
})
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load chart data
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getChartOption();
|
||||
const data = response.data.data || {};
|
||||
|
||||
// 职称图表
|
||||
titleChartOption.value = data.titleOption || {};
|
||||
let titleTotal = 0;
|
||||
if (titleChartOption.value.series && titleChartOption.value.series[0] && titleChartOption.value.series[0].data) {
|
||||
titleChartOption.value.series[0].data.forEach((item: any) => {
|
||||
titleTotal += item.value || 0;
|
||||
});
|
||||
|
||||
titleChartTableData.value = [];
|
||||
titleChartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = titleTotal > 0 ? Number(((item.value / titleTotal) * 100).toFixed(1)) : 0;
|
||||
titleChartTableData.value.push({
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
rate: `${rate}%`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 技术职务图表
|
||||
techChartOption.value = data.techOption || {};
|
||||
let techTotal = 0;
|
||||
if (techChartOption.value.series && techChartOption.value.series[0] && techChartOption.value.series[0].data) {
|
||||
techChartOption.value.series[0].data.forEach((item: any) => {
|
||||
techTotal += item.value || 0;
|
||||
});
|
||||
|
||||
techChartTableData.value = [];
|
||||
techChartOption.value.series[0].data.forEach((item: any) => {
|
||||
const rate = techTotal > 0 ? Number(((item.value / techTotal) * 100).toFixed(1)) : 0;
|
||||
techChartTableData.value.push({
|
||||
name: item.name,
|
||||
value: item.value,
|
||||
rate: `${rate}%`,
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Failed to load chart data
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时初始化图表
|
||||
onMounted(() => {
|
||||
initChartOption()
|
||||
})
|
||||
initChartOption();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,236 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopiclevelconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionaltopiclevelconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="levelName" label="课题等级名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopiclevelconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopiclevelconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="levelName" label="课题等级名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="课题等级名称" prop="levelName">
|
||||
<el-input
|
||||
v-model="form.levelName"
|
||||
placeholder="请输入课题等级名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopiclevelconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopiclevelconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="课题等级名称" prop="levelName">
|
||||
<el-input v-model="form.levelName" placeholder="请输入课题等级名称" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionaltopiclevelconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionaltopiclevelconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
levelName: [
|
||||
{ required: true, message: '请输入课题等级名称', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
levelName: [{ required: true, message: '请输入课题等级名称', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
levelName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
levelName: row.levelName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
levelName: row.levelName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,236 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopicsourceconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_professionaltopicsourceconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||
>新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="sourceName" label="课题来源" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopicsourceconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopicsourceconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="sourceName" label="课题来源" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="课题来源" prop="sourceName">
|
||||
<el-input
|
||||
v-model="form.sourceName"
|
||||
placeholder="请输入课题来源"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopicsourceconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionaltopicsourceconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="课题来源" prop="sourceName">
|
||||
<el-input v-model="form.sourceName" placeholder="请输入课题来源" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionaltopicsourceconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionaltopicsourceconfig';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
sourceName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
sourceName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
sourceName: [
|
||||
{ required: true, message: '请输入课题来源', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
sourceName: [{ required: true, message: '请输入课题来源', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
sourceName: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
sourceName: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
sourceName: row.sourceName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
sourceName: row.sourceName || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,204 +1,176 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_worktype_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_worktype_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="workName" label="工种名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" align="center" />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_worktype_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_worktype_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="workName" label="工种名称" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="工种名称" prop="workName">
|
||||
<el-input
|
||||
v-model="form.workName"
|
||||
placeholder="请输入工种名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" align="center" />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_worktype_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_worktype_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="工种名称" prop="workName">
|
||||
<el-input v-model="form.workName" placeholder="请输入工种名称" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalworktype'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/professionalworktype';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
workName: ''
|
||||
})
|
||||
id: '',
|
||||
workName: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
workName: [
|
||||
{ required: true, message: '请输入工种名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
workName: [{ required: true, message: '请输入工种名称', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
workName: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
workName: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
workName: row.workName || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
workName: row.workName || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,319 +1,249 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.teacherName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="year" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="salary" label="13月工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="assessmentTarget" label="重点考核目标" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="specialPerformance1" label="专项绩效1" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="specialPerformance2" label="专项绩效2" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="meritpay" label="年终奖励性绩效" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalyearbounds_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalyearbounds_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.teacherName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="form.teacherNo"
|
||||
placeholder="请输入工号"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="teacherName">
|
||||
<el-input
|
||||
v-model="form.teacherName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="year">
|
||||
<el-date-picker
|
||||
v-model="form.year"
|
||||
type="year"
|
||||
placeholder="请选择年份"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="13月工资" prop="salary">
|
||||
<el-input-number
|
||||
v-model="form.salary"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入13月工资"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="重点考核目标" prop="assessmentTarget">
|
||||
<el-input-number
|
||||
v-model="form.assessmentTarget"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入重点考核目标"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专项绩效1" prop="specialPerformance1">
|
||||
<el-input-number
|
||||
v-model="form.specialPerformance1"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入专项绩效1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专项绩效2" prop="specialPerformance2">
|
||||
<el-input-number
|
||||
v-model="form.specialPerformance2"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入专项绩效2"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年终奖励性绩效" prop="meritpay">
|
||||
<el-input-number
|
||||
v-model="form.meritpay"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入年终奖励性绩效"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="year" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="salary" label="13月工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="assessmentTarget" label="重点考核目标" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="specialPerformance1" label="专项绩效1" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="specialPerformance2" label="专项绩效2" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="meritpay" label="年终奖励性绩效" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_professionalyearbounds_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalyearbounds_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="800px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="form.teacherNo" placeholder="请输入工号" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="teacherName">
|
||||
<el-input v-model="form.teacherName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="year">
|
||||
<el-date-picker v-model="form.year" type="year" placeholder="请选择年份" format="YYYY" value-format="YYYY" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="13月工资" prop="salary">
|
||||
<el-input-number v-model="form.salary" :min="0" :precision="2" placeholder="请输入13月工资" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="重点考核目标" prop="assessmentTarget">
|
||||
<el-input-number v-model="form.assessmentTarget" :min="0" :precision="2" placeholder="请输入重点考核目标" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专项绩效1" prop="specialPerformance1">
|
||||
<el-input-number v-model="form.specialPerformance1" :min="0" :precision="2" placeholder="请输入专项绩效1" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="专项绩效2" prop="specialPerformance2">
|
||||
<el-input-number v-model="form.specialPerformance2" :min="0" :precision="2" placeholder="请输入专项绩效2" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年终奖励性绩效" prop="meritpay">
|
||||
<el-input-number v-model="form.meritpay" :min="0" :precision="2" placeholder="请输入年终奖励性绩效" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/salaries/professionalyearbounds'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/salaries/professionalyearbounds';
|
||||
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const { hasAuth } = useAuth()
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
year: '',
|
||||
salary: null as number | null,
|
||||
assessmentTarget: null as number | null,
|
||||
specialPerformance1: null as number | null,
|
||||
specialPerformance2: null as number | null,
|
||||
meritpay: null as number | null
|
||||
})
|
||||
id: '',
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
year: '',
|
||||
salary: null as number | null,
|
||||
assessmentTarget: null as number | null,
|
||||
specialPerformance1: null as number | null,
|
||||
specialPerformance2: null as number | null,
|
||||
meritpay: null as number | null,
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
teacherNo: [
|
||||
{ required: true, message: '请输入工号', trigger: 'blur' }
|
||||
],
|
||||
teacherName: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' }
|
||||
],
|
||||
year: [
|
||||
{ required: true, message: '请选择年份', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
teacherNo: [{ required: true, message: '请输入工号', trigger: 'blur' }],
|
||||
teacherName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
year: [{ required: true, message: '请选择年份', trigger: 'change' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
year: '',
|
||||
salary: null,
|
||||
assessmentTarget: null,
|
||||
specialPerformance1: null,
|
||||
specialPerformance2: null,
|
||||
meritpay: null
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
teacherNo: '',
|
||||
teacherName: '',
|
||||
year: '',
|
||||
salary: null,
|
||||
assessmentTarget: null,
|
||||
specialPerformance1: null,
|
||||
specialPerformance2: null,
|
||||
meritpay: null,
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id || '',
|
||||
teacherNo: row.teacherNo || '',
|
||||
teacherName: row.teacherName || '',
|
||||
year: row.year || '',
|
||||
salary: row.salary || null,
|
||||
assessmentTarget: row.assessmentTarget || null,
|
||||
specialPerformance1: row.specialPerformance1 || null,
|
||||
specialPerformance2: row.specialPerformance2 || null,
|
||||
meritpay: row.meritpay || null
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id || '',
|
||||
teacherNo: row.teacherNo || '',
|
||||
teacherName: row.teacherName || '',
|
||||
year: row.year || '',
|
||||
salary: row.salary || null,
|
||||
assessmentTarget: row.assessmentTarget || null,
|
||||
specialPerformance1: row.specialPerformance1 || null,
|
||||
specialPerformance2: row.specialPerformance2 || null,
|
||||
meritpay: row.meritpay || null,
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
getDataList(false) // 删除后保持当前页
|
||||
} catch (error: any) {
|
||||
message.error(error.msg)
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
getDataList(false); // 删除后保持当前页
|
||||
} catch (error: any) {
|
||||
message.error(error.msg);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList(false) // 提交后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList(false); // 提交后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.data-table {
|
||||
width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,172 +1,148 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="薪资年份" prop="salaryYear">
|
||||
<el-date-picker
|
||||
v-model="search.salaryYear"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择薪资年份"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="薪资年份" prop="salaryYear">
|
||||
<el-date-picker v-model="search.salaryYear" type="year" format="YYYY" value-format="YYYY" placeholder="请选择薪资年份" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="薪资月份" prop="salaryMonth">
|
||||
<el-date-picker
|
||||
v-model="search.salaryMonth"
|
||||
type="month"
|
||||
format="M"
|
||||
value-format="M"
|
||||
placeholder="请选择薪资月份"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="薪资月份" prop="salaryMonth">
|
||||
<el-date-picker v-model="search.salaryMonth" type="month" format="M" value-format="M" placeholder="请选择薪资月份" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="createTime" label="导出时间" min-width="180" align="center" />
|
||||
|
||||
<el-table-column prop="salaryYear" label="薪资年份" min-width="120" align="center" />
|
||||
|
||||
<el-table-column prop="salaryMonth" label="薪资月份" min-width="120" align="center" />
|
||||
|
||||
<el-table-column prop="confirm" label="劳务日期锁定" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.confirm === '1' ? 'success' : 'info'">
|
||||
{{ scope.row.confirm === '1' ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="80" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salaryexportrecord_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
row-key="id"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="createTime" label="导出时间" min-width="180" align="center" />
|
||||
|
||||
<el-table-column prop="salaryYear" label="薪资年份" min-width="120" align="center" />
|
||||
|
||||
<el-table-column prop="salaryMonth" label="薪资月份" min-width="120" align="center" />
|
||||
|
||||
<el-table-column prop="confirm" label="劳务日期锁定" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.confirm === '1' ? 'success' : 'info'">
|
||||
{{ scope.row.confirm === '1' ? '是' : '否' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="80" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_salaryexportrecord_del')" icon="delete" link type="primary" @click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, delObj } from '/@/api/professional/salaries/salaryexportrecord'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, delObj } from '/@/api/professional/salaries/salaryexportrecord';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
|
||||
// 搜索表单显示状态
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
salaryYear: '',
|
||||
salaryMonth: ''
|
||||
})
|
||||
salaryYear: '',
|
||||
salaryMonth: '',
|
||||
});
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList() // 查询后跳转到第一页
|
||||
}
|
||||
getDataList(); // 查询后跳转到第一页
|
||||
};
|
||||
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
Object.assign(search, {
|
||||
salaryYear: '',
|
||||
salaryMonth: ''
|
||||
})
|
||||
handleFilter()
|
||||
}
|
||||
searchFormRef.value?.formRef?.resetFields();
|
||||
Object.assign(search, {
|
||||
salaryYear: '',
|
||||
salaryMonth: '',
|
||||
});
|
||||
handleFilter();
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('确认删除?').then(async () => {
|
||||
try {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
getDataList(false) // 删除后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
messageBox
|
||||
.confirm('确认删除?')
|
||||
.then(async () => {
|
||||
try {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
getDataList(false); // 删除后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.data-table {
|
||||
width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,171 +1,166 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="薪资导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="年份">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年份"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button
|
||||
v-if="hasAuth('teacher_award_import')"
|
||||
size="small"
|
||||
type="primary">选择文件
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="薪资导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="年份">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年份"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button v-if="hasAuth('teacher_award_import')" size="small" type="primary">选择文件 </el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { ref, computed } from 'vue';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const url = ref('')
|
||||
const showUpload = ref(false)
|
||||
const fileList = ref<any[]>([])
|
||||
const btnLoading = ref(false)
|
||||
const fileName = ref('')
|
||||
const files = ref<File | null>(null)
|
||||
const chooseDate = ref('');
|
||||
const url = ref('');
|
||||
const showUpload = ref(false);
|
||||
const fileList = ref<any[]>([]);
|
||||
const btnLoading = ref(false);
|
||||
const fileName = ref('');
|
||||
const files = ref<File | null>(null);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 年份改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true
|
||||
url.value = `/professional/file/importAwardTax?chooseDate=${chooseDate.value}`
|
||||
} else {
|
||||
showUpload.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true;
|
||||
url.value = `/professional/file/importAwardTax?chooseDate=${chooseDate.value}`;
|
||||
} else {
|
||||
showUpload.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
fileList.value = []
|
||||
files.value = null
|
||||
fileName.value = ''
|
||||
btnLoading.value = false
|
||||
chooseDate.value = ''
|
||||
showUpload.value = false
|
||||
visible.value = true
|
||||
}
|
||||
fileList.value = [];
|
||||
files.value = null;
|
||||
fileName.value = '';
|
||||
btnLoading.value = false;
|
||||
chooseDate.value = '';
|
||||
showUpload.value = false;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 上传前验证
|
||||
const beforeUpload = (file: File) => {
|
||||
files.value = file
|
||||
const fileLast = file.name.split('.')
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
||||
const isLt2M = file.size / 1024 / 1024 < 20
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
return false // 返回false不会自动上传
|
||||
}
|
||||
files.value = file;
|
||||
const fileLast = file.name.split('.');
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||
const isLt2M = file.size / 1024 / 1024 < 20;
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
return false; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
// 导入提交
|
||||
const submitUpload = async () => {
|
||||
btnLoading.value = true
|
||||
if (fileName.value === "") {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const fileFormData = new FormData()
|
||||
fileFormData.append('file', files.value, fileName.value)
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (res.data.code == 200) {
|
||||
message.success("导入成功")
|
||||
visible.value = false
|
||||
emit('refreshData')
|
||||
} else {
|
||||
message.error(res.data.msg || '导入失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
btnLoading.value = true;
|
||||
if (fileName.value === '') {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileFormData = new FormData();
|
||||
fileFormData.append('file', files.value, fileName.value);
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.code == 200) {
|
||||
message.success('导入成功');
|
||||
visible.value = false;
|
||||
emit('refreshData');
|
||||
} else {
|
||||
message.error(res.data.msg || '导入失败');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,172 +1,143 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
placeholder="请输入工号"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" placeholder="请输入工号" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="year">
|
||||
<el-date-picker
|
||||
v-model="search.year"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年份"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="年份" prop="year">
|
||||
<el-date-picker v-model="search.year" type="year" format="YYYY" value-format="YYYY" placeholder="请选择年份" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button
|
||||
v-if="hasAuth('teacher_award_import')"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
@click="handleImportBaseSalary">绩效导入
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button v-if="hasAuth('teacher_award_import')" type="primary" plain icon="UploadFilled" @click="handleImportBaseSalary"
|
||||
>绩效导入
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:row-key="(row: any) => row.id ?? String(row.teacherNo) + row.year"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="startDate" label="开始日期" width="120" align="center" />
|
||||
|
||||
<el-table-column prop="endDate" label="结束日期" width="120" align="center" />
|
||||
|
||||
<el-table-column prop="year" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="income" label="累计应纳税所得额" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="taxRate" label="税率" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="deductMoney" label="速算扣除" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realMoney" label="应补(退)税额" min-width="130" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:row-key="(row: any) => row.id ?? String(row.teacherNo) + row.year"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 导入组件 -->
|
||||
<import-award-tax ref="importAwardTaxRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="startDate" label="开始日期" width="120" align="center" />
|
||||
|
||||
<el-table-column prop="endDate" label="结束日期" width="120" align="center" />
|
||||
|
||||
<el-table-column prop="year" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="income" label="累计应纳税所得额" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="taxRate" label="税率" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="deductMoney" label="速算扣除" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realMoney" label="应补(退)税额" min-width="130" align="center" show-overflow-tooltip />
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 导入组件 -->
|
||||
<import-award-tax ref="importAwardTaxRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { fetchList } from '/@/api/professional/salaries/teacherawardtax'
|
||||
const ImportAwardTax = defineAsyncComponent(() => import('./importAwardTax.vue'))
|
||||
const { hasAuth } = useAuth()
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { fetchList } from '/@/api/professional/salaries/teacherawardtax';
|
||||
const ImportAwardTax = defineAsyncComponent(() => import('./importAwardTax.vue'));
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const importAwardTaxRef = ref()
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const importAwardTaxRef = ref();
|
||||
|
||||
// 搜索表单显示状态
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
year: ''
|
||||
})
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
year: '',
|
||||
});
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList() // 查询后跳转到第一页
|
||||
}
|
||||
getDataList(); // 查询后跳转到第一页
|
||||
};
|
||||
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
Object.assign(search, {
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
year: ''
|
||||
})
|
||||
handleFilter()
|
||||
}
|
||||
searchFormRef.value?.formRef?.resetFields();
|
||||
Object.assign(search, {
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
year: '',
|
||||
});
|
||||
handleFilter();
|
||||
};
|
||||
|
||||
// 导入
|
||||
const handleImportBaseSalary = () => {
|
||||
importAwardTaxRef.value?.init()
|
||||
}
|
||||
importAwardTaxRef.value?.init();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -224,12 +224,12 @@ const exportTeacherInfo = async () => {
|
||||
teacherBaseDTO: searchData,
|
||||
};
|
||||
|
||||
makeExportTeacherInfoBySelfTask(params).then((res:any)=>{
|
||||
ElNotification.success({
|
||||
title: '下载后台进行中',
|
||||
message: '操作成功'
|
||||
})
|
||||
});
|
||||
makeExportTeacherInfoBySelfTask(params).then((res: any) => {
|
||||
ElNotification.success({
|
||||
title: '下载后台进行中',
|
||||
message: '操作成功',
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
exportLoading.value = false;
|
||||
|
||||
@@ -1,100 +1,93 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="导入职工信息" width="600" append-to-body>
|
||||
<el-alert
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
style="margin-bottom: 20px;">
|
||||
<template #title>
|
||||
<span> 可先导出教职工信息,按照导出信息的模板填入职工数据,再执行导入</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-dialog v-model="visible" title="导入职工信息" width="600" append-to-body>
|
||||
<el-alert type="warning" :closable="false" show-icon style="margin-bottom: 20px">
|
||||
<template #title>
|
||||
<span> 可先导出教职工信息,按照导出信息的模板填入职工数据,再执行导入</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
||||
<!-- <div style="text-align: center; margin-bottom: 20px;">-->
|
||||
<!-- <a href="excel/dictlist.xlsx" rel="external nofollow" download="职工信息字典下载" style="text-decoration: none;">-->
|
||||
<!-- <el-button type="success" :icon="Download">下载字典文件</el-button>-->
|
||||
<!-- </a>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div style="text-align: center; margin-bottom: 20px;">-->
|
||||
<!-- <a href="excel/dictlist.xlsx" rel="external nofollow" download="职工信息字典下载" style="text-decoration: none;">-->
|
||||
<!-- <el-button type="success" :icon="Download">下载字典文件</el-button>-->
|
||||
<!-- </a>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
class="upload-demo"
|
||||
action="/professional/file/makeImportTeacherInfoSimpleTask"
|
||||
:headers="headers"
|
||||
:accept="'.xls,.xlsx'"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleAvatarError"
|
||||
:limit="1"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 .xls 或 .xlsx 格式的 Excel 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-dialog>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
class="upload-demo"
|
||||
action="/professional/file/makeImportTeacherInfoSimpleTask"
|
||||
:headers="headers"
|
||||
:accept="'.xls,.xlsx'"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleAvatarError"
|
||||
:limit="1"
|
||||
drag
|
||||
>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传 .xls 或 .xlsx 格式的 Excel 文件</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, nextTick } from 'vue'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { Download, UploadFilled } from '@element-plus/icons-vue'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import { ref, computed, nextTick } from 'vue';
|
||||
import { ElNotification } from 'element-plus';
|
||||
import { Download, UploadFilled } from '@element-plus/icons-vue';
|
||||
import { Session } from '/@/utils/storage';
|
||||
|
||||
// 响应式数据
|
||||
const visible = ref(false)
|
||||
// 响应式数据
|
||||
const visible = ref(false);
|
||||
|
||||
// 计算属性
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
// 计算属性
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
const uploadRef = ref<{ clearFiles?: () => void }>()
|
||||
const uploadRef = ref<{ clearFiles?: () => void }>();
|
||||
|
||||
// 方法
|
||||
const init = () => {
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
uploadRef.value?.clearFiles?.()
|
||||
})
|
||||
}
|
||||
// 方法
|
||||
const init = () => {
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
uploadRef.value?.clearFiles?.();
|
||||
});
|
||||
};
|
||||
|
||||
const handleUploadSuccess = () => {
|
||||
visible.value = false
|
||||
ElNotification({
|
||||
title: '成功',
|
||||
message: '导入成功',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
const handleUploadSuccess = () => {
|
||||
visible.value = false;
|
||||
ElNotification({
|
||||
title: '成功',
|
||||
message: '导入成功',
|
||||
type: 'success',
|
||||
});
|
||||
};
|
||||
|
||||
const handleAvatarError = (err: any) => {
|
||||
const result = JSON.parse(err.message)
|
||||
if (result.code == "1") {
|
||||
ElNotification.error({
|
||||
title: '错误',
|
||||
message: result.msg,
|
||||
duration: 30000
|
||||
})
|
||||
}
|
||||
}
|
||||
const handleAvatarError = (err: any) => {
|
||||
const result = JSON.parse(err.message);
|
||||
if (result.code == '1') {
|
||||
ElNotification.error({
|
||||
title: '错误',
|
||||
message: result.msg,
|
||||
duration: 30000,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.upload-demo {
|
||||
:deep(.el-upload-dragger) {
|
||||
width: 100%;
|
||||
}
|
||||
:deep(.el-upload-dragger) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,383 +1,359 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" width="600" :title="waitShenheForm.title" append-to-body>
|
||||
<!--人员调动-->
|
||||
<el-form v-if="waitShenheForm.isPersonnelTransfer" ref="stationChangeFormRef" :model="waitShenheForm.form" :rules="stationChangeRules" label-width="120px">
|
||||
<el-form-item label="工号 / 姓名">
|
||||
<el-tag>{{waitShenheForm.form.teacherNo}} - {{waitShenheForm.form.realName}}</el-tag>
|
||||
</el-form-item>
|
||||
<el-dialog v-model="dialogVisible" width="600" :title="waitShenheForm.title" append-to-body>
|
||||
<!--人员调动-->
|
||||
<el-form
|
||||
v-if="waitShenheForm.isPersonnelTransfer"
|
||||
ref="stationChangeFormRef"
|
||||
:model="waitShenheForm.form"
|
||||
:rules="stationChangeRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="工号 / 姓名">
|
||||
<el-tag>{{ waitShenheForm.form.teacherNo }} - {{ waitShenheForm.form.realName }}</el-tag>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="原部门名称">
|
||||
<el-input v-model="waitShenheForm.form.deptName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="现二级部门" prop="newDeptCode">
|
||||
<el-select v-model="newSecDeptCode" @change="getDeptListByParent" placeholder="请选择二级部门">
|
||||
<el-option v-for="item in secDeptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="原部门名称">
|
||||
<el-input v-model="waitShenheForm.form.deptName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="现二级部门" prop="newDeptCode">
|
||||
<el-select v-model="newSecDeptCode" @change="getDeptListByParent" placeholder="请选择二级部门">
|
||||
<el-option v-for="item in secDeptList" :key="item.deptCode" :label="item.deptName" :value="item.deptCode"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="现子级部门">
|
||||
<el-select v-model="newSecChildDeptCode" placeholder="请选择下级部门" clearable style="width: 100%">
|
||||
<el-option v-for="item in newSecChildDeptCodeList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="调令日期" prop="changeDate">
|
||||
<el-date-picker
|
||||
v-model="waitShenheForm.form.changeDate"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="岗位类型" prop="pos">
|
||||
<el-select v-model="waitShenheForm.form.pos" placeholder="请选择岗位类型" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in global.STATION_TYPE"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="waitShenheForm.form.remarks" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div style="text-align: right; width: 100%;">
|
||||
<el-button type="primary" @click="dialogSubmit(5)">提交</el-button>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!--党员调动-->
|
||||
<el-form v-if="waitShenheForm.isPartyTransfer" ref="partChangeFormRef" :model="waitShenheForm.form" :rules="partChangeRules" label-width="120px">
|
||||
<el-form-item label="工号 / 用户名">
|
||||
<el-tag>{{waitShenheForm.form.teacherNo}} - {{waitShenheForm.form.realName}}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="现子级部门">
|
||||
<el-select v-model="newSecChildDeptCode" placeholder="请选择下级部门" clearable style="width: 100%">
|
||||
<el-option v-for="item in newSecChildDeptCodeList" :key="item.deptCode" :label="item.deptName" :value="item.deptCode"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="原支部名">
|
||||
<el-select disabled v-model="waitShenheForm.form.oldBranchName" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in baseInfoAbout.partBranchList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="调令日期" prop="changeDate">
|
||||
<el-date-picker v-model="waitShenheForm.form.changeDate" type="date" placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="现支部名" prop="branchName">
|
||||
<el-select clearable v-model="waitShenheForm.form.branchName" placeholder="请选择现支部" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in baseInfoAbout.partBranchList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="党费" prop="partyFee">
|
||||
<el-input-number v-model="waitShenheForm.form.partyFee" :precision="2" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="变动时间" prop="changeTime">
|
||||
<el-date-picker
|
||||
v-model="waitShenheForm.form.changeTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="waitShenheForm.form.remarks" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div style="text-align: right; width: 100%;">
|
||||
<el-button type="primary" @click="dialogSubmit(6)">提交</el-button>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
<el-form-item label="岗位类型" prop="pos">
|
||||
<el-select v-model="waitShenheForm.form.pos" placeholder="请选择岗位类型" style="width: 100%">
|
||||
<el-option v-for="item in global.STATION_TYPE" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="waitShenheForm.form.remarks" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div style="text-align: right; width: 100%">
|
||||
<el-button type="primary" @click="dialogSubmit(5)">提交</el-button>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!--党员调动-->
|
||||
<el-form v-if="waitShenheForm.isPartyTransfer" ref="partChangeFormRef" :model="waitShenheForm.form" :rules="partChangeRules" label-width="120px">
|
||||
<el-form-item label="工号 / 用户名">
|
||||
<el-tag>{{ waitShenheForm.form.teacherNo }} - {{ waitShenheForm.form.realName }}</el-tag>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="原支部名">
|
||||
<el-select disabled v-model="waitShenheForm.form.oldBranchName" style="width: 100%">
|
||||
<el-option v-for="item in baseInfoAbout.partBranchList" :key="item.id" :label="item.name" :value="item.id"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="现支部名" prop="branchName">
|
||||
<el-select clearable v-model="waitShenheForm.form.branchName" placeholder="请选择现支部" style="width: 100%">
|
||||
<el-option v-for="item in baseInfoAbout.partBranchList" :key="item.id" :label="item.name" :value="item.id"> </el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="党费" prop="partyFee">
|
||||
<el-input-number v-model="waitShenheForm.form.partyFee" :precision="2" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="变动时间" prop="changeTime">
|
||||
<el-date-picker
|
||||
v-model="waitShenheForm.form.changeTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="waitShenheForm.form.remarks" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div style="text-align: right; width: 100%">
|
||||
<el-button type="primary" @click="dialogSubmit(6)">提交</el-button>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { getAllInfoAboutList } from '/@/api/professional/professionaluser/teacherbase'
|
||||
import { getDeptListByLevelTwo, getDeptListByParent as getDeptListByParentApi } from '/@/api/basic/basicdept'
|
||||
import { addObj as addStationChangeObj } from '/@/api/professional/professionaluser/professionalteacherstationchange'
|
||||
import { addObj as addPartyChangeObj } from '/@/api/professional/professionaluser/professionalpartychange'
|
||||
import global from '/@/components/tools/commondict.vue'
|
||||
import type { Pagination } from '/@/hooks/table'
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { getAllInfoAboutList } from '/@/api/professional/professionaluser/teacherbase';
|
||||
import { getDeptListByLevelTwo, getDeptListByParent as getDeptListByParentApi } from '/@/api/basic/basicdept';
|
||||
import { addObj as addStationChangeObj } from '/@/api/professional/professionaluser/professionalteacherstationchange';
|
||||
import { addObj as addPartyChangeObj } from '/@/api/professional/professionaluser/professionalpartychange';
|
||||
import global from '/@/components/tools/commondict.vue';
|
||||
import type { Pagination } from '/@/hooks/table';
|
||||
|
||||
// 表单类型常量
|
||||
const FORM_TYPE = {
|
||||
PERSONNEL_TRANSFER: 5, // 人员调动
|
||||
PARTY_TRANSFER: 6 // 党员调动
|
||||
} as const
|
||||
// 表单类型常量
|
||||
const FORM_TYPE = {
|
||||
PERSONNEL_TRANSFER: 5, // 人员调动
|
||||
PARTY_TRANSFER: 6, // 党员调动
|
||||
} as const;
|
||||
|
||||
// 类型定义
|
||||
interface FormData {
|
||||
newDeptCodeList?: any[]
|
||||
deptCodeList?: any[]
|
||||
teacherNo?: string
|
||||
realName?: string
|
||||
userName?: string
|
||||
deptName?: string
|
||||
id?: string
|
||||
oldBranchId?: string
|
||||
oldBranchName?: string
|
||||
newDeptCode?: string
|
||||
newSecDeptCode?: string
|
||||
changeDate?: string
|
||||
pos?: string
|
||||
remarks?: string
|
||||
branchName?: string
|
||||
partyFee?: number
|
||||
changeTime?: string
|
||||
[key: string]: any
|
||||
}
|
||||
// 类型定义
|
||||
interface FormData {
|
||||
newDeptCodeList?: any[];
|
||||
deptCodeList?: any[];
|
||||
teacherNo?: string;
|
||||
realName?: string;
|
||||
userName?: string;
|
||||
deptName?: string;
|
||||
id?: string;
|
||||
oldBranchId?: string;
|
||||
oldBranchName?: string;
|
||||
newDeptCode?: string;
|
||||
newSecDeptCode?: string;
|
||||
changeDate?: string;
|
||||
pos?: string;
|
||||
remarks?: string;
|
||||
branchName?: string;
|
||||
partyFee?: number;
|
||||
changeTime?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface WaitShenheForm {
|
||||
form: FormData
|
||||
title: string
|
||||
isPersonnelTransfer: boolean
|
||||
isPartyTransfer: boolean
|
||||
}
|
||||
interface WaitShenheForm {
|
||||
form: FormData;
|
||||
title: string;
|
||||
isPersonnelTransfer: boolean;
|
||||
isPartyTransfer: boolean;
|
||||
}
|
||||
|
||||
// 表单 ref
|
||||
const stationChangeFormRef = ref()
|
||||
const partChangeFormRef = ref()
|
||||
|
||||
// 人员调动验证规则
|
||||
const stationChangeRules = {
|
||||
newDeptCode: [{ required: true, message: '请选择要调入的二级部门', trigger: 'blur' }],
|
||||
changeDate: [{ required: true, message: '请选择调令日期', trigger: 'blur' }],
|
||||
pos: [{ required: true, message: '请选择岗位类型', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
// 党员调动验证规则
|
||||
const partChangeRules = {
|
||||
branchName: [{ required: true, message: '请选择现支部', trigger: 'blur' }],
|
||||
changeTime: [{ required: true, message: '请选择变动时间', trigger: 'blur' }]
|
||||
}
|
||||
// 表单 ref
|
||||
const stationChangeFormRef = ref();
|
||||
const partChangeFormRef = ref();
|
||||
|
||||
/**
|
||||
* 定义Props
|
||||
* @param page 分页信息
|
||||
* @param nowRow 当前行数据
|
||||
*/
|
||||
const props = defineProps<{
|
||||
page?: Pagination
|
||||
nowRow: Record<string, any>
|
||||
}>()
|
||||
// 人员调动验证规则
|
||||
const stationChangeRules = {
|
||||
newDeptCode: [{ required: true, message: '请选择要调入的二级部门', trigger: 'blur' }],
|
||||
changeDate: [{ required: true, message: '请选择调令日期', trigger: 'blur' }],
|
||||
pos: [{ required: true, message: '请选择岗位类型', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
/**
|
||||
* 定义Emits
|
||||
*/
|
||||
const emit = defineEmits<{
|
||||
(e: 'getList', page?: Pagination): void
|
||||
}>()
|
||||
// 党员调动验证规则
|
||||
const partChangeRules = {
|
||||
branchName: [{ required: true, message: '请选择现支部', trigger: 'blur' }],
|
||||
changeTime: [{ required: true, message: '请选择变动时间', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
/**
|
||||
* 定义Props
|
||||
* @param page 分页信息
|
||||
* @param nowRow 当前行数据
|
||||
*/
|
||||
const props = defineProps<{
|
||||
page?: Pagination;
|
||||
nowRow: Record<string, any>;
|
||||
}>();
|
||||
|
||||
// 响应式数据
|
||||
const dialogVisible = ref(false)
|
||||
|
||||
/**
|
||||
* 等待审核表单
|
||||
*/
|
||||
const waitShenheForm = reactive<WaitShenheForm>({
|
||||
form: {
|
||||
newDeptCodeList: [],
|
||||
deptCodeList: []
|
||||
},
|
||||
title: '',
|
||||
isPersonnelTransfer: false,
|
||||
isPartyTransfer: false
|
||||
})
|
||||
|
||||
const baseInfoAbout = reactive({
|
||||
partBranchList: [] as any[]
|
||||
})
|
||||
|
||||
const secDeptList = ref<any[]>([])
|
||||
const newSecChildDeptCodeList = ref<any[]>([])
|
||||
const newSecDeptCode = ref('')
|
||||
const newSecChildDeptCode = ref('')
|
||||
const teacherNo = ref('')
|
||||
/**
|
||||
* 定义Emits
|
||||
*/
|
||||
const emit = defineEmits<{
|
||||
(e: 'getList', page?: Pagination): void;
|
||||
}>();
|
||||
|
||||
// 方法定义
|
||||
/**
|
||||
* 初始化字典数据
|
||||
*/
|
||||
const initDicData = async () => {
|
||||
const response = await getAllInfoAboutList()
|
||||
const map = response.data
|
||||
baseInfoAbout.partBranchList = map['partBranchList'] || []
|
||||
}
|
||||
// 消息提示 hooks
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
/**
|
||||
* 初始化对话框
|
||||
* @param val 表单类型:5-人员调动,6-党员调动
|
||||
*/
|
||||
const init = async (val: number) => {
|
||||
if (val !== FORM_TYPE.PERSONNEL_TRANSFER && val !== FORM_TYPE.PARTY_TRANSFER) {
|
||||
return
|
||||
}
|
||||
|
||||
await initDicData()
|
||||
teacherNo.value = props.nowRow.teacherNo
|
||||
handleFormType(val)
|
||||
}
|
||||
// 响应式数据
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
/**
|
||||
* 处理表单类型显示
|
||||
* @param val 表单类型
|
||||
*/
|
||||
const handleFormType = (val: number) => {
|
||||
// 重置所有表单状态
|
||||
waitShenheForm.isPersonnelTransfer = false
|
||||
waitShenheForm.isPartyTransfer = false
|
||||
|
||||
if (val === FORM_TYPE.PERSONNEL_TRANSFER) {
|
||||
// 人员调动:加载部门数据
|
||||
waitShenheForm.title = "人员调动"
|
||||
waitShenheForm.isPersonnelTransfer = true
|
||||
waitShenheForm.form = { ...props.nowRow }
|
||||
waitShenheForm.form.id = ''
|
||||
waitShenheForm.form.newDeptCodeList = []
|
||||
waitShenheForm.form.deptCodeList = []
|
||||
newSecDeptCode.value = ''
|
||||
newSecChildDeptCode.value = ''
|
||||
|
||||
getDeptListByLevelTwo().then((res: any) => {
|
||||
secDeptList.value = res.data || []
|
||||
dialogVisible.value = true
|
||||
// 弹窗打开后,清除表单验证状态,避免立即显示验证提示
|
||||
nextTick(() => {
|
||||
stationChangeFormRef.value?.clearValidate()
|
||||
})
|
||||
})
|
||||
} else if (val === FORM_TYPE.PARTY_TRANSFER) {
|
||||
// 党员调动:设置原支部
|
||||
waitShenheForm.title = "党员调动"
|
||||
waitShenheForm.isPartyTransfer = true
|
||||
waitShenheForm.form = { ...props.nowRow }
|
||||
waitShenheForm.form.id = ''
|
||||
waitShenheForm.form.realName = waitShenheForm.form.userName || waitShenheForm.form.realName
|
||||
waitShenheForm.form.oldBranchName = waitShenheForm.form.oldBranchId
|
||||
dialogVisible.value = true
|
||||
// 弹窗打开后,清除表单验证状态,避免立即显示验证提示
|
||||
nextTick(() => {
|
||||
partChangeFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 提交表单
|
||||
* @param val 表单类型:5-人员调动,6-党员调动
|
||||
*/
|
||||
const dialogSubmit = async (val: number) => {
|
||||
if (val !== FORM_TYPE.PERSONNEL_TRANSFER && val !== FORM_TYPE.PARTY_TRANSFER) {
|
||||
return
|
||||
}
|
||||
/**
|
||||
* 等待审核表单
|
||||
*/
|
||||
const waitShenheForm = reactive<WaitShenheForm>({
|
||||
form: {
|
||||
newDeptCodeList: [],
|
||||
deptCodeList: [],
|
||||
},
|
||||
title: '',
|
||||
isPersonnelTransfer: false,
|
||||
isPartyTransfer: false,
|
||||
});
|
||||
|
||||
waitShenheForm.form.teacherNo = teacherNo.value
|
||||
const baseInfoAbout = reactive({
|
||||
partBranchList: [] as any[],
|
||||
});
|
||||
|
||||
// 表单验证配置
|
||||
const formRefMap: Record<number, any> = {
|
||||
[FORM_TYPE.PERSONNEL_TRANSFER]: stationChangeFormRef.value,
|
||||
[FORM_TYPE.PARTY_TRANSFER]: partChangeFormRef.value
|
||||
}
|
||||
|
||||
const formRef = formRefMap[val]
|
||||
|
||||
// 人员调动:在验证前同步数据
|
||||
if (val === FORM_TYPE.PERSONNEL_TRANSFER) {
|
||||
waitShenheForm.form.newDeptCode = newSecDeptCode.value
|
||||
waitShenheForm.form.newSecDeptCode = newSecChildDeptCode.value || newSecDeptCode.value
|
||||
}
|
||||
const secDeptList = ref<any[]>([]);
|
||||
const newSecChildDeptCodeList = ref<any[]>([]);
|
||||
const newSecDeptCode = ref('');
|
||||
const newSecChildDeptCode = ref('');
|
||||
const teacherNo = ref('');
|
||||
|
||||
// 验证表单
|
||||
if (formRef) {
|
||||
try {
|
||||
await formRef.validate()
|
||||
} catch (err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
// 方法定义
|
||||
/**
|
||||
* 初始化字典数据
|
||||
*/
|
||||
const initDicData = async () => {
|
||||
const response = await getAllInfoAboutList();
|
||||
const map = response.data;
|
||||
baseInfoAbout.partBranchList = map['partBranchList'] || [];
|
||||
};
|
||||
|
||||
// 先确认,用户取消时不执行后续操作
|
||||
try {
|
||||
await messageBox.confirm('确认提交?')
|
||||
} catch (err: any) {
|
||||
// 用户取消操作,直接返回,不显示错误提示
|
||||
return
|
||||
}
|
||||
|
||||
// 用户确认后,执行提交操作
|
||||
try {
|
||||
let res: any
|
||||
|
||||
if (val === FORM_TYPE.PERSONNEL_TRANSFER) {
|
||||
// 人员调动:使用人员调动接口
|
||||
res = await addStationChangeObj(waitShenheForm.form)
|
||||
} else if (val === FORM_TYPE.PARTY_TRANSFER) {
|
||||
// 党员调动:使用党员调动接口
|
||||
res = await addPartyChangeObj(waitShenheForm.form)
|
||||
}
|
||||
|
||||
if (res && res.data === '-1') {
|
||||
message.warning("当前不允许提交")
|
||||
} else if (res) {
|
||||
message.success("提交成功")
|
||||
emit("getList", props.page)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
} catch (err: any) {
|
||||
// 处理业务错误
|
||||
message.error(err.msg)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 初始化对话框
|
||||
* @param val 表单类型:5-人员调动,6-党员调动
|
||||
*/
|
||||
const init = async (val: number) => {
|
||||
if (val !== FORM_TYPE.PERSONNEL_TRANSFER && val !== FORM_TYPE.PARTY_TRANSFER) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子部门列表
|
||||
*/
|
||||
const getDeptListByParent = async () => {
|
||||
newSecChildDeptCode.value = ''
|
||||
newSecChildDeptCodeList.value = []
|
||||
|
||||
if (!newSecDeptCode.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const res = await getDeptListByParentApi(newSecDeptCode.value)
|
||||
newSecChildDeptCodeList.value = res.data || []
|
||||
}
|
||||
await initDicData();
|
||||
teacherNo.value = props.nowRow.teacherNo;
|
||||
handleFormType(val);
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
/**
|
||||
* 处理表单类型显示
|
||||
* @param val 表单类型
|
||||
*/
|
||||
const handleFormType = (val: number) => {
|
||||
// 重置所有表单状态
|
||||
waitShenheForm.isPersonnelTransfer = false;
|
||||
waitShenheForm.isPartyTransfer = false;
|
||||
|
||||
if (val === FORM_TYPE.PERSONNEL_TRANSFER) {
|
||||
// 人员调动:加载部门数据
|
||||
waitShenheForm.title = '人员调动';
|
||||
waitShenheForm.isPersonnelTransfer = true;
|
||||
waitShenheForm.form = { ...props.nowRow };
|
||||
waitShenheForm.form.id = '';
|
||||
waitShenheForm.form.newDeptCodeList = [];
|
||||
waitShenheForm.form.deptCodeList = [];
|
||||
newSecDeptCode.value = '';
|
||||
newSecChildDeptCode.value = '';
|
||||
|
||||
getDeptListByLevelTwo().then((res: any) => {
|
||||
secDeptList.value = res.data || [];
|
||||
dialogVisible.value = true;
|
||||
// 弹窗打开后,清除表单验证状态,避免立即显示验证提示
|
||||
nextTick(() => {
|
||||
stationChangeFormRef.value?.clearValidate();
|
||||
});
|
||||
});
|
||||
} else if (val === FORM_TYPE.PARTY_TRANSFER) {
|
||||
// 党员调动:设置原支部
|
||||
waitShenheForm.title = '党员调动';
|
||||
waitShenheForm.isPartyTransfer = true;
|
||||
waitShenheForm.form = { ...props.nowRow };
|
||||
waitShenheForm.form.id = '';
|
||||
waitShenheForm.form.realName = waitShenheForm.form.userName || waitShenheForm.form.realName;
|
||||
waitShenheForm.form.oldBranchName = waitShenheForm.form.oldBranchId;
|
||||
dialogVisible.value = true;
|
||||
// 弹窗打开后,清除表单验证状态,避免立即显示验证提示
|
||||
nextTick(() => {
|
||||
partChangeFormRef.value?.clearValidate();
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 提交表单
|
||||
* @param val 表单类型:5-人员调动,6-党员调动
|
||||
*/
|
||||
const dialogSubmit = async (val: number) => {
|
||||
if (val !== FORM_TYPE.PERSONNEL_TRANSFER && val !== FORM_TYPE.PARTY_TRANSFER) {
|
||||
return;
|
||||
}
|
||||
|
||||
waitShenheForm.form.teacherNo = teacherNo.value;
|
||||
|
||||
// 表单验证配置
|
||||
const formRefMap: Record<number, any> = {
|
||||
[FORM_TYPE.PERSONNEL_TRANSFER]: stationChangeFormRef.value,
|
||||
[FORM_TYPE.PARTY_TRANSFER]: partChangeFormRef.value,
|
||||
};
|
||||
|
||||
const formRef = formRefMap[val];
|
||||
|
||||
// 人员调动:在验证前同步数据
|
||||
if (val === FORM_TYPE.PERSONNEL_TRANSFER) {
|
||||
waitShenheForm.form.newDeptCode = newSecDeptCode.value;
|
||||
waitShenheForm.form.newSecDeptCode = newSecChildDeptCode.value || newSecDeptCode.value;
|
||||
}
|
||||
|
||||
// 验证表单
|
||||
if (formRef) {
|
||||
try {
|
||||
await formRef.validate();
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 先确认,用户取消时不执行后续操作
|
||||
try {
|
||||
await messageBox.confirm('确认提交?');
|
||||
} catch (err: any) {
|
||||
// 用户取消操作,直接返回,不显示错误提示
|
||||
return;
|
||||
}
|
||||
|
||||
// 用户确认后,执行提交操作
|
||||
try {
|
||||
let res: any;
|
||||
|
||||
if (val === FORM_TYPE.PERSONNEL_TRANSFER) {
|
||||
// 人员调动:使用人员调动接口
|
||||
res = await addStationChangeObj(waitShenheForm.form);
|
||||
} else if (val === FORM_TYPE.PARTY_TRANSFER) {
|
||||
// 党员调动:使用党员调动接口
|
||||
res = await addPartyChangeObj(waitShenheForm.form);
|
||||
}
|
||||
|
||||
if (res && res.data === '-1') {
|
||||
message.warning('当前不允许提交');
|
||||
} else if (res) {
|
||||
message.success('提交成功');
|
||||
emit('getList', props.page);
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
} catch (err: any) {
|
||||
// 处理业务错误
|
||||
message.error(err.msg);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取子部门列表
|
||||
*/
|
||||
const getDeptListByParent = async () => {
|
||||
newSecChildDeptCode.value = '';
|
||||
newSecChildDeptCodeList.value = [];
|
||||
|
||||
if (!newSecDeptCode.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await getDeptListByParentApi(newSecDeptCode.value);
|
||||
newSecChildDeptCodeList.value = res.data || [];
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,92 +1,88 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="政治面貌" width="600px" @close="handleClose">
|
||||
<el-form :model="form" label-width="120px" ref="formRef">
|
||||
<el-form-item label="政治面貌" required>
|
||||
<el-select v-model="form.politicsStatusId" placeholder="请选择政治面貌" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in politicsStatusList"
|
||||
:key="item.id"
|
||||
:label="item.politicsStatus"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="加入时间" required>
|
||||
<el-date-picker
|
||||
v-model="form.joinTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="转正时间" required>
|
||||
<el-date-picker
|
||||
v-model="form.correctionTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="政治面貌" width="600px" @close="handleClose">
|
||||
<el-form :model="form" label-width="120px" ref="formRef">
|
||||
<el-form-item label="政治面貌" required>
|
||||
<el-select v-model="form.politicsStatusId" placeholder="请选择政治面貌" style="width: 100%">
|
||||
<el-option v-for="item in politicsStatusList" :key="item.id" :label="item.politicsStatus" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="加入时间" required>
|
||||
<el-date-picker
|
||||
v-model="form.joinTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="转正时间" required>
|
||||
<el-date-picker
|
||||
v-model="form.correctionTime"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
formData?: any
|
||||
politicsStatusList?: any[]
|
||||
modelValue: boolean;
|
||||
formData?: any;
|
||||
politicsStatusList?: any[];
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'submit', data: any): void
|
||||
(e: 'update:modelValue', value: boolean): void;
|
||||
(e: 'submit', data: any): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
formData: () => ({}),
|
||||
politicsStatusList: () => []
|
||||
})
|
||||
formData: () => ({}),
|
||||
politicsStatusList: () => [],
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const visible = ref(false)
|
||||
const formRef = ref()
|
||||
const form = ref<any>({})
|
||||
const visible = ref(false);
|
||||
const formRef = ref();
|
||||
const form = ref<any>({});
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
if (val && props.formData) {
|
||||
form.value = { ...props.formData }
|
||||
} else {
|
||||
form.value = {}
|
||||
}
|
||||
})
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val;
|
||||
if (val && props.formData) {
|
||||
form.value = { ...props.formData };
|
||||
} else {
|
||||
form.value = {};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
emit('update:modelValue', val);
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
form.value = {}
|
||||
}
|
||||
visible.value = false;
|
||||
form.value = {};
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
emit('submit', { ...form.value })
|
||||
}
|
||||
emit('submit', { ...form.value });
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,136 +1,112 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="社会关系" width="600px" @close="handleClose">
|
||||
<el-form :model="form" :rules="rules" label-width="130px" ref="formRef">
|
||||
<el-form-item label="称谓" prop="title" required>
|
||||
<el-select v-model="form.title" placeholder="请选择称谓" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in titleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName" required>
|
||||
<el-input v-model="form.realName" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出生年月" prop="birthday" required>
|
||||
<el-date-picker
|
||||
v-model="form.birthday"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="政治面貌" prop="politicsStatusId" required>
|
||||
<el-select v-model="form.politicsStatusId" placeholder="请选择政治面貌" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in politicsStatusList"
|
||||
:key="item.id"
|
||||
:label="item.politicsStatus"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作单位及职务" prop="workStation" required>
|
||||
<el-input
|
||||
v-model="form.workStation"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入工作单位及职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="社会关系" width="600px" @close="handleClose">
|
||||
<el-form :model="form" :rules="rules" label-width="130px" ref="formRef">
|
||||
<el-form-item label="称谓" prop="title" required>
|
||||
<el-select v-model="form.title" placeholder="请选择称谓" style="width: 100%">
|
||||
<el-option v-for="item in titleOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName" required>
|
||||
<el-input v-model="form.realName" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出生年月" prop="birthday" required>
|
||||
<el-date-picker
|
||||
v-model="form.birthday"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="政治面貌" prop="politicsStatusId" required>
|
||||
<el-select v-model="form.politicsStatusId" placeholder="请选择政治面貌" style="width: 100%">
|
||||
<el-option v-for="item in politicsStatusList" :key="item.id" :label="item.politicsStatus" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作单位及职务" prop="workStation" required>
|
||||
<el-input v-model="form.workStation" type="textarea" :rows="2" placeholder="请输入工作单位及职务" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
formData?: any
|
||||
politicsStatusList?: any[]
|
||||
modelValue: boolean;
|
||||
formData?: any;
|
||||
politicsStatusList?: any[];
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'submit', data: any): void
|
||||
(e: 'update:modelValue', value: boolean): void;
|
||||
(e: 'submit', data: any): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
formData: () => ({}),
|
||||
politicsStatusList: () => []
|
||||
})
|
||||
formData: () => ({}),
|
||||
politicsStatusList: () => [],
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const visible = ref(false)
|
||||
const formRef = ref()
|
||||
const form = ref<any>({})
|
||||
const visible = ref(false);
|
||||
const formRef = ref();
|
||||
const form = ref<any>({});
|
||||
|
||||
// 称谓选项
|
||||
const titleOptions = [
|
||||
{ label: '父亲', value: '父亲' },
|
||||
{ label: '母亲', value: '母亲' },
|
||||
{ label: '配偶', value: '配偶' },
|
||||
{ label: '子女', value: '子女' },
|
||||
{ label: '兄弟姐妹', value: '兄弟姐妹' },
|
||||
{ label: '其他', value: '其他' }
|
||||
]
|
||||
{ label: '父亲', value: '父亲' },
|
||||
{ label: '母亲', value: '母亲' },
|
||||
{ label: '配偶', value: '配偶' },
|
||||
{ label: '子女', value: '子女' },
|
||||
{ label: '兄弟姐妹', value: '兄弟姐妹' },
|
||||
{ label: '其他', value: '其他' },
|
||||
];
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
if (val && props.formData) {
|
||||
form.value = { ...props.formData }
|
||||
} else {
|
||||
form.value = {}
|
||||
}
|
||||
})
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val;
|
||||
if (val && props.formData) {
|
||||
form.value = { ...props.formData };
|
||||
} else {
|
||||
form.value = {};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
emit('update:modelValue', val);
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
form.value = {}
|
||||
}
|
||||
visible.value = false;
|
||||
form.value = {};
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
formRef.value?.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
emit('submit', { ...form.value })
|
||||
}
|
||||
})
|
||||
}
|
||||
formRef.value?.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
emit('submit', { ...form.value });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
title: [
|
||||
{ required: true, message: '请选择称谓', trigger: 'change' }
|
||||
],
|
||||
realName: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' }
|
||||
],
|
||||
birthday: [
|
||||
{ required: true, message: '请选择出生年月', trigger: 'change' }
|
||||
],
|
||||
politicsStatusId: [
|
||||
{ required: true, message: '请选择政治面貌', trigger: 'change' }
|
||||
],
|
||||
workStation: [
|
||||
{ required: true, message: '请输入工作单位及职务', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
title: [{ required: true, message: '请选择称谓', trigger: 'change' }],
|
||||
realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
birthday: [{ required: true, message: '请选择出生年月', trigger: 'change' }],
|
||||
politicsStatusId: [{ required: true, message: '请选择政治面貌', trigger: 'change' }],
|
||||
workStation: [{ required: true, message: '请输入工作单位及职务', trigger: 'blur' }],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,214 +1,207 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="锁定状态管理"
|
||||
width="600px"
|
||||
class="status-lock-dialog"
|
||||
@close="handleClose">
|
||||
<div class="status-lock-content">
|
||||
<div class="status-lock-description">
|
||||
<el-icon class="status-lock-icon"><Lock /></el-icon>
|
||||
<span>请选择需要锁定的模块,锁定后将无法进行编辑操作</span>
|
||||
</div>
|
||||
|
||||
<el-form :model="form" label-width="120px" class="status-lock-form">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职称管理">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.title"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-dialog v-model="visible" title="锁定状态管理" width="600px" class="status-lock-dialog" @close="handleClose">
|
||||
<div class="status-lock-content">
|
||||
<div class="status-lock-description">
|
||||
<el-icon class="status-lock-icon"><Lock /></el-icon>
|
||||
<span>请选择需要锁定的模块,锁定后将无法进行编辑操作</span>
|
||||
</div>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职业资格">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.job"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form :model="form" label-width="120px" class="status-lock-form">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职称管理">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.title"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="教师资格证">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.teacherTitle"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职业资格">
|
||||
<el-switch inline-prompt v-model="form.job" active-text="已锁定" inactive-text="未锁定" active-color="#f56c6c" inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学历学位">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.acade"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="教师资格证">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.teacherTitle"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="综合表彰">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.remix"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学历学位">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.acade"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位晋升">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.work"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="status-lock-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="canEdit"
|
||||
@click="handleSubmit">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="综合表彰">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.remix"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位晋升">
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="form.work"
|
||||
active-text="已锁定"
|
||||
inactive-text="未锁定"
|
||||
active-color="#f56c6c"
|
||||
inactive-color="#67c23a"
|
||||
>
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="status-lock-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" v-if="canEdit" @click="handleSubmit">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { Lock } from '@element-plus/icons-vue'
|
||||
import { ref, watch } from 'vue';
|
||||
import { Lock } from '@element-plus/icons-vue';
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
formData?: any
|
||||
canEdit?: boolean
|
||||
modelValue: boolean;
|
||||
formData?: any;
|
||||
canEdit?: boolean;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'submit', data: any): void
|
||||
(e: 'update:modelValue', value: boolean): void;
|
||||
(e: 'submit', data: any): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
formData: () => ({
|
||||
title: false,
|
||||
job: true,
|
||||
teacherTitle: true,
|
||||
acade: true,
|
||||
remix: true,
|
||||
work: true
|
||||
}),
|
||||
canEdit: false
|
||||
})
|
||||
formData: () => ({
|
||||
title: false,
|
||||
job: true,
|
||||
teacherTitle: true,
|
||||
acade: true,
|
||||
remix: true,
|
||||
work: true,
|
||||
}),
|
||||
canEdit: false,
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
const form = ref<any>({
|
||||
title: false,
|
||||
job: true,
|
||||
teacherTitle: true,
|
||||
acade: true,
|
||||
remix: true,
|
||||
work: true
|
||||
})
|
||||
title: false,
|
||||
job: true,
|
||||
teacherTitle: true,
|
||||
acade: true,
|
||||
remix: true,
|
||||
work: true,
|
||||
});
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
if (val && props.formData) {
|
||||
form.value = { ...props.formData }
|
||||
} else {
|
||||
form.value = {
|
||||
title: false,
|
||||
job: true,
|
||||
teacherTitle: true,
|
||||
acade: true,
|
||||
remix: true,
|
||||
work: true
|
||||
}
|
||||
}
|
||||
})
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val;
|
||||
if (val && props.formData) {
|
||||
form.value = { ...props.formData };
|
||||
} else {
|
||||
form.value = {
|
||||
title: false,
|
||||
job: true,
|
||||
teacherTitle: true,
|
||||
acade: true,
|
||||
remix: true,
|
||||
work: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
emit('update:modelValue', val);
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
}
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
emit('submit', { ...form.value })
|
||||
}
|
||||
emit('submit', { ...form.value });
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.status-lock-dialog {
|
||||
.status-lock-content {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.status-lock-description {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
background: #fef0f0;
|
||||
border: 1px solid #fbc4c4;
|
||||
border-radius: 6px;
|
||||
color: #f56c6c;
|
||||
font-size: 14px;
|
||||
|
||||
.status-lock-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 18px;
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
.status-lock-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-lock-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
.status-lock-content {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.status-lock-description {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
margin-bottom: 24px;
|
||||
background: #fef0f0;
|
||||
border: 1px solid #fbc4c4;
|
||||
border-radius: 6px;
|
||||
color: #f56c6c;
|
||||
font-size: 14px;
|
||||
|
||||
.status-lock-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 18px;
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
.status-lock-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-lock-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,121 +1,113 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="薪资导出" width="650px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="劳务日期锁定">
|
||||
<el-radio-group v-model="lockedLw">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0px">
|
||||
<el-tag type="warning">选择是,则本月其他造单批次无法指定到当前月份。如需解锁,请前往「薪资导出记录」删除记录即可。</el-tag>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span v-if="showBtn" class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="exportSalaryData" :loading="btnLoading">导 出</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="薪资导出" width="650px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker v-model="chooseDate" type="month" format="YYYY-M" value-format="YYYY-M" placeholder="请选择日期" @change="handleChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="劳务日期锁定">
|
||||
<el-radio-group v-model="lockedLw">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0px">
|
||||
<el-tag type="warning">选择是,则本月其他造单批次无法指定到当前月份。如需解锁,请前往「薪资导出记录」删除记录即可。</el-tag>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span v-if="showBtn" class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="exportSalaryData" :loading="btnLoading">导 出</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { ref } from 'vue';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const showBtn = ref(false)
|
||||
const btnLoading = ref(false)
|
||||
const lockedLw = ref(1)
|
||||
const chooseDate = ref('');
|
||||
const showBtn = ref(false);
|
||||
const btnLoading = ref(false);
|
||||
const lockedLw = ref(1);
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
chooseDate.value = ''
|
||||
showBtn.value = false
|
||||
btnLoading.value = false
|
||||
lockedLw.value = 1
|
||||
visible.value = true
|
||||
}
|
||||
chooseDate.value = '';
|
||||
showBtn.value = false;
|
||||
btnLoading.value = false;
|
||||
lockedLw.value = 1;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 日期改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showBtn.value = true
|
||||
} else {
|
||||
showBtn.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showBtn.value = true;
|
||||
} else {
|
||||
showBtn.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 下载文件
|
||||
const downLoadFile = async (url: string) => {
|
||||
return request({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
}
|
||||
return request({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 导出薪资数据
|
||||
const exportSalaryData = async () => {
|
||||
if (!chooseDate.value) {
|
||||
message.warning('请选择日期')
|
||||
return
|
||||
}
|
||||
|
||||
btnLoading.value = true
|
||||
try {
|
||||
const res = await downLoadFile(`/professional/file/exportSalary?chooseDate=${chooseDate.value}&state=${lockedLw.value}`)
|
||||
|
||||
// 处理返回的文件流
|
||||
const blob = new Blob([res.data])
|
||||
const elink = document.createElement('a')
|
||||
elink.download = "薪资表.xls"
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href) // 释放URL 对象
|
||||
document.body.removeChild(elink)
|
||||
|
||||
message.success('导出成功')
|
||||
visible.value = false
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导出失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
if (!chooseDate.value) {
|
||||
message.warning('请选择日期');
|
||||
return;
|
||||
}
|
||||
|
||||
btnLoading.value = true;
|
||||
try {
|
||||
const res = await downLoadFile(`/professional/file/exportSalary?chooseDate=${chooseDate.value}&state=${lockedLw.value}`);
|
||||
|
||||
// 处理返回的文件流
|
||||
const blob = new Blob([res.data]);
|
||||
const elink = document.createElement('a');
|
||||
elink.download = '薪资表.xls';
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href); // 释放URL 对象
|
||||
document.body.removeChild(elink);
|
||||
|
||||
message.success('导出成功');
|
||||
visible.value = false;
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导出失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,170 +1,165 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="薪资导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_import')"
|
||||
size="small"
|
||||
type="primary">选择文件
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="薪资导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button v-if="hasAuth('professional_salary_import')" size="small" type="primary">选择文件 </el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { ref, computed } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const url = ref('')
|
||||
const showUpload = ref(false)
|
||||
const fileList = ref<any[]>([])
|
||||
const btnLoading = ref(false)
|
||||
const fileName = ref('')
|
||||
const files = ref<File | null>(null)
|
||||
const chooseDate = ref('');
|
||||
const url = ref('');
|
||||
const showUpload = ref(false);
|
||||
const fileList = ref<any[]>([]);
|
||||
const btnLoading = ref(false);
|
||||
const fileName = ref('');
|
||||
const files = ref<File | null>(null);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 日期改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true
|
||||
url.value = `/professional/file/importTeacherPayslpi?chooseDate=${chooseDate.value}`
|
||||
} else {
|
||||
showUpload.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true;
|
||||
url.value = `/professional/file/importTeacherPayslpi?chooseDate=${chooseDate.value}`;
|
||||
} else {
|
||||
showUpload.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
fileList.value = []
|
||||
files.value = null
|
||||
fileName.value = ''
|
||||
chooseDate.value = ''
|
||||
showUpload.value = false
|
||||
visible.value = true
|
||||
}
|
||||
fileList.value = [];
|
||||
files.value = null;
|
||||
fileName.value = '';
|
||||
chooseDate.value = '';
|
||||
showUpload.value = false;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 上传前验证
|
||||
const beforeUpload = (file: File) => {
|
||||
files.value = file
|
||||
const fileLast = file.name.split('.')
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
||||
const isLt2M = file.size / 1024 / 1024 < 20
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
return false // 返回false不会自动上传
|
||||
}
|
||||
files.value = file;
|
||||
const fileLast = file.name.split('.');
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||
const isLt2M = file.size / 1024 / 1024 < 20;
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
return false; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
// 导入提交
|
||||
const submitUpload = async () => {
|
||||
btnLoading.value = true
|
||||
if (fileName.value === "") {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const fileFormData = new FormData()
|
||||
fileFormData.append('file', files.value, fileName.value)
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`)
|
||||
} else {
|
||||
message.success("导入成功")
|
||||
visible.value = false
|
||||
emit('refreshData')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
btnLoading.value = true;
|
||||
if (fileName.value === '') {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileFormData = new FormData();
|
||||
fileFormData.append('file', files.value, fileName.value);
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`);
|
||||
} else {
|
||||
message.success('导入成功');
|
||||
visible.value = false;
|
||||
emit('refreshData');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,172 +1,167 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="税金导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_import')"
|
||||
size="small"
|
||||
type="primary">选择文件
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="税金导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button v-if="hasAuth('professional_salary_import')" size="small" type="primary">选择文件 </el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { ref, computed } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const url = ref('')
|
||||
const showUpload = ref(false)
|
||||
const fileList = ref<any[]>([])
|
||||
const btnLoading = ref(false)
|
||||
const fileName = ref('')
|
||||
const files = ref<File | null>(null)
|
||||
const chooseDate = ref('');
|
||||
const url = ref('');
|
||||
const showUpload = ref(false);
|
||||
const fileList = ref<any[]>([]);
|
||||
const btnLoading = ref(false);
|
||||
const fileName = ref('');
|
||||
const files = ref<File | null>(null);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 日期改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true
|
||||
url.value = `/professional/file/importTaxSalary?chooseDate=${chooseDate.value}`
|
||||
} else {
|
||||
showUpload.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true;
|
||||
url.value = `/professional/file/importTaxSalary?chooseDate=${chooseDate.value}`;
|
||||
} else {
|
||||
showUpload.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
fileList.value = []
|
||||
files.value = null
|
||||
fileName.value = ''
|
||||
chooseDate.value = ''
|
||||
showUpload.value = false
|
||||
visible.value = true
|
||||
}
|
||||
fileList.value = [];
|
||||
files.value = null;
|
||||
fileName.value = '';
|
||||
chooseDate.value = '';
|
||||
showUpload.value = false;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 上传前验证
|
||||
const beforeUpload = (file: File) => {
|
||||
files.value = file
|
||||
const fileLast = file.name.split('.')
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
||||
const isLt2M = file.size / 1024 / 1024 < 20
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
return false // 返回false不会自动上传
|
||||
}
|
||||
files.value = file;
|
||||
const fileLast = file.name.split('.');
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||
const isLt2M = file.size / 1024 / 1024 < 20;
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
return false; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
// 导入提交
|
||||
const submitUpload = async () => {
|
||||
btnLoading.value = true
|
||||
if (fileName.value === "") {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const fileFormData = new FormData()
|
||||
fileFormData.append('file', files.value, fileName.value)
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`)
|
||||
} else {
|
||||
message.success("导入成功")
|
||||
visible.value = false
|
||||
emit('refreshData')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
btnLoading.value = true;
|
||||
if (fileName.value === '') {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileFormData = new FormData();
|
||||
fileFormData.append('file', files.value, fileName.value);
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`);
|
||||
} else {
|
||||
message.success('导入成功');
|
||||
visible.value = false;
|
||||
emit('refreshData');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,364 +1,295 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
placeholder="请输入工号"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" placeholder="请输入工号" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input
|
||||
v-model="search.idCard"
|
||||
placeholder="请输入身份证号"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input v-model="search.idCard" placeholder="请输入身份证号" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="nf">
|
||||
<el-date-picker
|
||||
v-model="search.nf"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年份"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="年份" prop="nf">
|
||||
<el-date-picker v-model="search.nf" type="year" format="YYYY" value-format="YYYY" placeholder="请选择年份" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="月份" prop="yf">
|
||||
<el-date-picker
|
||||
v-model="search.yf"
|
||||
type="month"
|
||||
format="M"
|
||||
value-format="M"
|
||||
placeholder="请选择月份"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份" prop="yf">
|
||||
<el-date-picker v-model="search.yf" type="month" format="M" value-format="M" placeholder="请选择月份" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="岗位级别" prop="stationTypeId">
|
||||
<el-select
|
||||
v-model="search.stationTypeId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择岗位级别"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in stationLevelList"
|
||||
:key="item.id"
|
||||
:label="item.levelName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="岗位级别" prop="stationTypeId">
|
||||
<el-select v-model="search.stationTypeId" filterable clearable placeholder="请选择岗位级别">
|
||||
<el-option v-for="item in stationLevelList" :key="item.id" :label="item.levelName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_import')"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
@click="handleImportBaseSalary">工资条导入
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_seach_auth')"
|
||||
icon="View"
|
||||
class="ml10"
|
||||
@click="canSearch(1)">设置可查询
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_seach_auth')"
|
||||
icon="Hide"
|
||||
class="ml10"
|
||||
@click="canSearch(0)">设置不可查询
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalsalaries_del')"
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
class="ml10"
|
||||
@click="delbatch">批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button v-if="hasAuth('professional_salary_import')" type="primary" plain icon="UploadFilled" @click="handleImportBaseSalary"
|
||||
>工资条导入
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_seach_auth')" icon="View" class="ml10" @click="canSearch(1)">设置可查询 </el-button>
|
||||
<el-button v-if="hasAuth('professional_seach_auth')" icon="Hide" class="ml10" @click="canSearch(0)">设置不可查询 </el-button>
|
||||
<el-button v-if="hasAuth('professional_professionalsalaries_del')" type="danger" plain icon="Delete" class="ml10" @click="delbatch"
|
||||
>批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
@selection-change="selectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
@selection-change="selectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="nf" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="yf" label="月份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="idCard" label="身份证号" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="shouldPay" label="应发工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realWage" label="实发工资" width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="normalView" label="职工查看" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.normalView === '1' ? 'success' : 'info'">
|
||||
{{ scope.row.normalView === '1' ? '可查询' : '不可查询' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="document"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 子组件 -->
|
||||
<salary-info ref="salaryInfoRef" />
|
||||
<import-base-salary ref="importBaseSalaryRef" @refreshData="handleFilter" />
|
||||
<export-base-salary ref="exportBaseSalaryRef" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="nf" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="yf" label="月份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="idCard" label="身份证号" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="shouldPay" label="应发工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realWage" label="实发工资" width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="normalView" label="职工查看" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.normalView === '1' ? 'success' : 'info'">
|
||||
{{ scope.row.normalView === '1' ? '可查询' : '不可查询' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button icon="document" link type="primary" @click="handleEdit(scope.row)">查看 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<salary-info ref="salaryInfoRef" />
|
||||
<import-base-salary ref="importBaseSalaryRef" @refreshData="handleFilter" />
|
||||
<export-base-salary ref="exportBaseSalaryRef" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, delBatch, setCanSearch } from '/@/api/professional/salaries/teacherpayslip'
|
||||
import { checkAuth } from '/@/api/professional/salaries/teachersalary'
|
||||
import { getStationLevelList } from '/@/api/professional/professionalstationlevelconfig'
|
||||
const SalaryInfo = defineAsyncComponent(() => import('./salaryInfo.vue'))
|
||||
const ImportBaseSalary = defineAsyncComponent(() => import('./importBaseSalary.vue'))
|
||||
const ExportBaseSalary = defineAsyncComponent(() => import('./exportBaseSalary.vue'))
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, delBatch, setCanSearch } from '/@/api/professional/salaries/teacherpayslip';
|
||||
import { checkAuth } from '/@/api/professional/salaries/teachersalary';
|
||||
import { getStationLevelList } from '/@/api/professional/professionalstationlevelconfig';
|
||||
const SalaryInfo = defineAsyncComponent(() => import('./salaryInfo.vue'));
|
||||
const ImportBaseSalary = defineAsyncComponent(() => import('./importBaseSalary.vue'));
|
||||
const ExportBaseSalary = defineAsyncComponent(() => import('./exportBaseSalary.vue'));
|
||||
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const salaryInfoRef = ref()
|
||||
const importBaseSalaryRef = ref()
|
||||
const exportBaseSalaryRef = ref()
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const salaryInfoRef = ref();
|
||||
const importBaseSalaryRef = ref();
|
||||
const exportBaseSalaryRef = ref();
|
||||
|
||||
// 搜索表单显示状态
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 岗位类别列表
|
||||
const stationLevelList = ref<any[]>([])
|
||||
const stationLevelList = ref<any[]>([]);
|
||||
|
||||
// 选中的行
|
||||
const selectList = ref<any[]>([])
|
||||
const selectList = ref<any[]>([]);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: '',
|
||||
canSearch: 0,
|
||||
selectList:[]
|
||||
})
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: '',
|
||||
canSearch: 0,
|
||||
selectList: [],
|
||||
});
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
init();
|
||||
});
|
||||
|
||||
// 初始化数据
|
||||
const init = async () => {
|
||||
try {
|
||||
const [stationRes, authRes] = await Promise.all([
|
||||
getStationLevelList(),
|
||||
checkAuth()
|
||||
])
|
||||
|
||||
stationLevelList.value = stationRes.data || []
|
||||
|
||||
// 根据权限设置表格选项(如果需要)
|
||||
// if (authRes.data.data === false) {
|
||||
// // 设置普通表格选项
|
||||
// }
|
||||
} catch (error) {
|
||||
// 初始化失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const [stationRes, authRes] = await Promise.all([getStationLevelList(), checkAuth()]);
|
||||
|
||||
stationLevelList.value = stationRes.data || [];
|
||||
|
||||
// 根据权限设置表格选项(如果需要)
|
||||
// if (authRes.data.data === false) {
|
||||
// // 设置普通表格选项
|
||||
// }
|
||||
} catch (error) {
|
||||
// 初始化失败
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList() // 查询后跳转到第一页
|
||||
}
|
||||
getDataList(); // 查询后跳转到第一页
|
||||
};
|
||||
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: ''
|
||||
})
|
||||
handleFilter()
|
||||
}
|
||||
searchFormRef.value?.formRef?.resetFields();
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: '',
|
||||
});
|
||||
handleFilter();
|
||||
};
|
||||
|
||||
// 选择变化
|
||||
const selectionChange = (selection: any[]) => {
|
||||
selectList.value = selection
|
||||
}
|
||||
selectList.value = selection;
|
||||
};
|
||||
|
||||
// 查看
|
||||
const handleEdit = (row: any) => {
|
||||
salaryInfoRef.value?.init(row)
|
||||
}
|
||||
salaryInfoRef.value?.init(row);
|
||||
};
|
||||
|
||||
// 导入工资条
|
||||
const handleImportBaseSalary = () => {
|
||||
importBaseSalaryRef.value?.init()
|
||||
}
|
||||
importBaseSalaryRef.value?.init();
|
||||
};
|
||||
|
||||
// 批量删除
|
||||
const delbatch = () => {
|
||||
if (selectList.value.length === 0) {
|
||||
message.warning("请至少选择一名人员")
|
||||
return
|
||||
}
|
||||
|
||||
messageBox.confirm(`确认删除当前${selectList.value.length}条记录`).then(async () => {
|
||||
try {
|
||||
const data = { selectList: selectList.value }
|
||||
const response = await delBatch(data)
|
||||
|
||||
if (response.data.code == -1) {
|
||||
message.error(response.data.data)
|
||||
} else {
|
||||
message.success("删除成功")
|
||||
getDataList(false) // 删除后保持当前页
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
if (selectList.value.length === 0) {
|
||||
message.warning('请至少选择一名人员');
|
||||
return;
|
||||
}
|
||||
|
||||
messageBox
|
||||
.confirm(`确认删除当前${selectList.value.length}条记录`)
|
||||
.then(async () => {
|
||||
try {
|
||||
const data = { selectList: selectList.value };
|
||||
const response = await delBatch(data);
|
||||
|
||||
if (response.data.code == -1) {
|
||||
message.error(response.data.data);
|
||||
} else {
|
||||
message.success('删除成功');
|
||||
getDataList(false); // 删除后保持当前页
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
});
|
||||
};
|
||||
|
||||
// 设置可查询/不可查询
|
||||
const canSearch = (val: number) => {
|
||||
search.canSearch = val;
|
||||
search.selectList = selectList.value;
|
||||
|
||||
|
||||
search.canSearch=val
|
||||
search.selectList=selectList.value
|
||||
|
||||
messageBox.confirm('确认设置?').then(async () => {
|
||||
try {
|
||||
await setCanSearch(search)
|
||||
message.success("设置成功")
|
||||
getDataList(false) // 设置后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
messageBox
|
||||
.confirm('确认设置?')
|
||||
.then(async () => {
|
||||
try {
|
||||
await setCanSearch(search);
|
||||
message.success('设置成功');
|
||||
getDataList(false); // 设置后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.data-table {
|
||||
width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,571 +1,528 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
width="95%"
|
||||
v-loading="baseLoading"
|
||||
top="2vh"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
class="salary-info-dialog"
|
||||
>
|
||||
<div class="salary-info-container">
|
||||
<!--基本信息-->
|
||||
<div class="base-info-section">
|
||||
<div class="base-info-content">
|
||||
<div class="info-group">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.realName">{{ salaryData.baseInfo[0].realName }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">身份证号:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.idCard">{{ salaryData.baseInfo[0].idCard }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-form :model="nowUser" :inline="true" class="search-form">
|
||||
<el-form-item label="年份">
|
||||
<el-date-picker
|
||||
v-model="nowUser.nf"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="选择年"
|
||||
style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份">
|
||||
<el-date-picker
|
||||
v-model="nowUser.yff"
|
||||
type="month"
|
||||
format="M"
|
||||
value-format="M"
|
||||
placeholder="选择月"
|
||||
style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="searchUserInfo" type="primary" icon="Search">
|
||||
查询
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
width="95%"
|
||||
v-loading="baseLoading"
|
||||
top="2vh"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
class="salary-info-dialog"
|
||||
>
|
||||
<div class="salary-info-container">
|
||||
<!--基本信息-->
|
||||
<div class="base-info-section">
|
||||
<div class="base-info-content">
|
||||
<div class="info-group">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.realName">{{ salaryData.baseInfo[0].realName }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">身份证号:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.idCard">{{ salaryData.baseInfo[0].idCard }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-form :model="nowUser" :inline="true" class="search-form">
|
||||
<el-form-item label="年份">
|
||||
<el-date-picker v-model="nowUser.nf" type="year" format="YYYY" value-format="YYYY" placeholder="选择年" style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份">
|
||||
<el-date-picker v-model="nowUser.yff" type="month" format="M" value-format="M" placeholder="选择月" style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="searchUserInfo" type="primary" icon="Search"> 查询 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card shadow="hover" class="info-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon><Money /></el-icon>
|
||||
<span>工资明细</span>
|
||||
</div>
|
||||
</template>
|
||||
<!--应发部分-->
|
||||
<div class="section-title">
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
<span>应发部分</span>
|
||||
</div>
|
||||
<el-table
|
||||
:data="salaryData.baseInfo"
|
||||
size="small"
|
||||
border
|
||||
class="salary-table"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="应发部分">
|
||||
<el-table-column prop="baseSalary" label="基础专项绩效" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="payWage" label="薪级工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="见习期工资" prop="studentPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="liveAllowance" label="生活补贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="postAllowance" label="岗位津贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="住房(租金)补贴" prop="houseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="新职工住房补贴" prop="newHouseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="回民补贴" prop="huiSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="养老保险补贴" prop="oldSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="教龄津贴" prop="ageAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特教补贴" prop="specialSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特级教师津贴" prop="teacherAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(一)" prop="sPostAllowance1" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(二)" prop="sPostAllowance2" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="其他" prop="other" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="奖励性绩效工资" prop="meritPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="乡镇工作补贴" prop="villageSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="临时性补贴" prop="temporarySubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="上下班交通补贴" prop="trafficSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="保留津贴" prop="keepAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="补发工资" prop="retroactivePay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应休未休假补贴" prop="vacationMoney" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应发工资" prop="shouldPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础专项绩效" prop="baseSalary" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础工资应税收入" prop="shouldTaxMoney" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag type="danger" size="small">基础工资应税收入= 岗位工资 +薪级工资+见习期工资+生活补贴+岗位津贴+教龄津贴+特教补贴+特级教师津贴+特岗津贴(1)+特岗津贴(2)+奖励绩效性工资+乡镇工作补贴+临时补贴+保留津贴+应休未休假-个人补缴-其他扣款-医疗救助金</el-tag>
|
||||
</div>
|
||||
|
||||
<!--应扣部分-->
|
||||
<div class="section-title">
|
||||
<el-icon><Remove /></el-icon>
|
||||
<span>应扣部分</span>
|
||||
</div>
|
||||
<el-table
|
||||
size="small"
|
||||
border
|
||||
:data="salaryData.baseInfo"
|
||||
class="salary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column label="应扣部分">
|
||||
<el-table-column label="住房公积金" min-width="90" prop="houseFund"></el-table-column>
|
||||
<el-table-column label="医疗保险金" min-width="90" prop="medicalInsurance"></el-table-column>
|
||||
<el-table-column label="失业保险金" min-width="90" prop="unemployInsurance"></el-table-column>
|
||||
<el-table-column label="养老保险金" min-width="90" prop="endowInsurance"></el-table-column>
|
||||
<el-table-column label="工会费" min-width="60" prop="unionFee"></el-table-column>
|
||||
<el-table-column label="儿童统筹" min-width="90" prop="childrenWhole"></el-table-column>
|
||||
<el-table-column label="个人所得税" width="90" prop="personalTax"></el-table-column>
|
||||
<el-table-column label="其他扣款" min-width="90" prop="otherDeduction"></el-table-column>
|
||||
<el-table-column label="病事假扣款" min-width="90" prop="sickDeduction"></el-table-column>
|
||||
<el-table-column label="医疗救助基金" min-width="90" prop="medicalFund"></el-table-column>
|
||||
<el-table-column label="工伤保险" min-width="90" prop="inductrialInjury"></el-table-column>
|
||||
<el-table-column label="个人补缴" min-width="90" prop="personalPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" min-width="90" prop="withhold"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag size="small">个人所得税 = 个税计算数据中的《 累计应补(退)税额 》</el-tag>
|
||||
</div>
|
||||
<el-card shadow="hover" class="info-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon><Money /></el-icon>
|
||||
<span>工资明细</span>
|
||||
</div>
|
||||
</template>
|
||||
<!--应发部分-->
|
||||
<div class="section-title">
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
<span>应发部分</span>
|
||||
</div>
|
||||
<el-table :data="salaryData.baseInfo" size="small" border class="salary-table" style="width: 100%">
|
||||
<el-table-column label="应发部分">
|
||||
<el-table-column prop="baseSalary" label="基础专项绩效" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="payWage" label="薪级工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="见习期工资" prop="studentPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="liveAllowance" label="生活补贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="postAllowance" label="岗位津贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="住房(租金)补贴" prop="houseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="新职工住房补贴" prop="newHouseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="回民补贴" prop="huiSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="养老保险补贴" prop="oldSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="教龄津贴" prop="ageAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特教补贴" prop="specialSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特级教师津贴" prop="teacherAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(一)" prop="sPostAllowance1" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(二)" prop="sPostAllowance2" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="其他" prop="other" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="奖励性绩效工资" prop="meritPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="乡镇工作补贴" prop="villageSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="临时性补贴" prop="temporarySubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="上下班交通补贴" prop="trafficSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="保留津贴" prop="keepAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="补发工资" prop="retroactivePay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应休未休假补贴" prop="vacationMoney" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应发工资" prop="shouldPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础专项绩效" prop="baseSalary" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础工资应税收入" prop="shouldTaxMoney" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag type="danger" size="small"
|
||||
>基础工资应税收入= 岗位工资
|
||||
+薪级工资+见习期工资+生活补贴+岗位津贴+教龄津贴+特教补贴+特级教师津贴+特岗津贴(1)+特岗津贴(2)+奖励绩效性工资+乡镇工作补贴+临时补贴+保留津贴+应休未休假-个人补缴-其他扣款-医疗救助金</el-tag
|
||||
>
|
||||
</div>
|
||||
|
||||
<!--劳务费-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>造单收入清单</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="showAllContent"
|
||||
size="small"
|
||||
border
|
||||
:data="allProjectData"
|
||||
class="salary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column label="造单收入清单">
|
||||
<el-table-column label="造单部门" prop="deptName"></el-table-column>
|
||||
<el-table-column label="造单人" prop="createName"></el-table-column>
|
||||
<el-table-column label="项目编号" prop="projectNo"></el-table-column>
|
||||
<el-table-column label="项目名" prop="title"></el-table-column>
|
||||
<el-table-column label="金额" prop="realMoney"></el-table-column>
|
||||
<el-table-column label="付讫时间" prop="payTime"></el-table-column>
|
||||
<el-table-column label="免税或暂不交税" prop="freeTax">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.freeTax=='1'">√</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--应扣部分-->
|
||||
<div class="section-title">
|
||||
<el-icon><Remove /></el-icon>
|
||||
<span>应扣部分</span>
|
||||
</div>
|
||||
<el-table size="small" border :data="salaryData.baseInfo" class="salary-table" style="width: 100%">
|
||||
<el-table-column label="应扣部分">
|
||||
<el-table-column label="住房公积金" min-width="90" prop="houseFund"></el-table-column>
|
||||
<el-table-column label="医疗保险金" min-width="90" prop="medicalInsurance"></el-table-column>
|
||||
<el-table-column label="失业保险金" min-width="90" prop="unemployInsurance"></el-table-column>
|
||||
<el-table-column label="养老保险金" min-width="90" prop="endowInsurance"></el-table-column>
|
||||
<el-table-column label="工会费" min-width="60" prop="unionFee"></el-table-column>
|
||||
<el-table-column label="儿童统筹" min-width="90" prop="childrenWhole"></el-table-column>
|
||||
<el-table-column label="个人所得税" width="90" prop="personalTax"></el-table-column>
|
||||
<el-table-column label="其他扣款" min-width="90" prop="otherDeduction"></el-table-column>
|
||||
<el-table-column label="病事假扣款" min-width="90" prop="sickDeduction"></el-table-column>
|
||||
<el-table-column label="医疗救助基金" min-width="90" prop="medicalFund"></el-table-column>
|
||||
<el-table-column label="工伤保险" min-width="90" prop="inductrialInjury"></el-table-column>
|
||||
<el-table-column label="个人补缴" min-width="90" prop="personalPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" min-width="90" prop="withhold"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag size="small">个人所得税 = 个税计算数据中的《 累计应补(退)税额 》</el-tag>
|
||||
</div>
|
||||
|
||||
<!--专项扣除-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><DataAnalysis /></el-icon>
|
||||
<span>个税计算数据</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="showAllContent"
|
||||
size="small"
|
||||
border
|
||||
:data="salaryExtendData"
|
||||
class="salary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column label="个税计算数据">
|
||||
<el-table-column prop="currentIncome" label="应税收入" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalIncome" label="累计收入额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalDeduction" label="累计减除费用" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSpecialDecution" label="累计专项扣除" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="累计专项扣除附加" align="center">
|
||||
<el-table-column prop="totalChildEdu" label="累计子女教育" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalConEdu" label="累计继续教育" min-width="60" align="center"> </el-table-column>
|
||||
<el-table-column prop="totalHouseInterest" label="累计住房贷款利息" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalHouse" label="累计住房租金" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSupportOld" label="累计赡养老人" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalBabyMoney" label="累计婴幼儿照护费用" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalTaxMoney" label="累计应纳税所得额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="taxRate" label="税率" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="quickDecution" label="速算扣除数" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRealTaxPay" label="累计应扣缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalPrePayTax" label="累计已预缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRetrieveTax" label="累计应补(退)税额" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag type="warning" size="small">应税收入= 基础工资应税收入+造单收入</el-tag>
|
||||
<el-tag type="success" size="small" class="ml10">累计专项扣除=当年累计个人承担的住房公积金+医疗保险金+失业保险金+养老保险金</el-tag>
|
||||
</div>
|
||||
<!--劳务费-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>造单收入清单</span>
|
||||
</div>
|
||||
<el-table v-if="showAllContent" size="small" border :data="allProjectData" class="salary-table" style="width: 100%">
|
||||
<el-table-column label="造单收入清单">
|
||||
<el-table-column label="造单部门" prop="deptName"></el-table-column>
|
||||
<el-table-column label="造单人" prop="createName"></el-table-column>
|
||||
<el-table-column label="项目编号" prop="projectNo"></el-table-column>
|
||||
<el-table-column label="项目名" prop="title"></el-table-column>
|
||||
<el-table-column label="金额" prop="realMoney"></el-table-column>
|
||||
<el-table-column label="付讫时间" prop="payTime"></el-table-column>
|
||||
<el-table-column label="免税或暂不交税" prop="freeTax">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.freeTax == '1'">√</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!--实发合计-->
|
||||
<div class="section-title">
|
||||
<el-icon><Wallet /></el-icon>
|
||||
<span>实发合计</span>
|
||||
</div>
|
||||
<el-table
|
||||
size="small"
|
||||
border
|
||||
:data="[staticsData]"
|
||||
class="salary-table summary-table"
|
||||
empty-text=" "
|
||||
style="width: 100%">
|
||||
<el-table-column label="小计">
|
||||
<el-table-column label="应发工资" prop="shouldPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" prop="shouldDedu"></el-table-column>
|
||||
<el-table-column label="实发工资" prop="realWage"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag type="primary" size="small">实发工资= 应发工资-应扣合计</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--专项扣除-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><DataAnalysis /></el-icon>
|
||||
<span>个税计算数据</span>
|
||||
</div>
|
||||
<el-table v-if="showAllContent" size="small" border :data="salaryExtendData" class="salary-table" style="width: 100%">
|
||||
<el-table-column label="个税计算数据">
|
||||
<el-table-column prop="currentIncome" label="应税收入" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalIncome" label="累计收入额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalDeduction" label="累计减除费用" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSpecialDecution" label="累计专项扣除" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="累计专项扣除附加" align="center">
|
||||
<el-table-column prop="totalChildEdu" label="累计子女教育" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalConEdu" label="累计继续教育" min-width="60" align="center"> </el-table-column>
|
||||
<el-table-column prop="totalHouseInterest" label="累计住房贷款利息" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalHouse" label="累计住房租金" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSupportOld" label="累计赡养老人" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalBabyMoney" label="累计婴幼儿照护费用" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalTaxMoney" label="累计应纳税所得额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="taxRate" label="税率" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="quickDecution" label="速算扣除数" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRealTaxPay" label="累计应扣缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalPrePayTax" label="累计已预缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRetrieveTax" label="累计应补(退)税额" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag type="warning" size="small">应税收入= 基础工资应税收入+造单收入</el-tag>
|
||||
<el-tag type="success" size="small" class="ml10">累计专项扣除=当年累计个人承担的住房公积金+医疗保险金+失业保险金+养老保险金</el-tag>
|
||||
</div>
|
||||
|
||||
<!--实发合计-->
|
||||
<div class="section-title">
|
||||
<el-icon><Wallet /></el-icon>
|
||||
<span>实发合计</span>
|
||||
</div>
|
||||
<el-table size="small" border :data="[staticsData]" class="salary-table summary-table" empty-text=" " style="width: 100%">
|
||||
<el-table-column label="小计">
|
||||
<el-table-column label="应发工资" prop="shouldPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" prop="shouldDedu"></el-table-column>
|
||||
<el-table-column label="实发工资" prop="realWage"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag type="primary" size="small">实发工资= 应发工资-应扣合计</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { Money, TrendCharts, Remove, Document, DataAnalysis, Wallet, Search } from '@element-plus/icons-vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { queryUserInfo, queryExtendSalaryInfo } from '/@/api/professional/salaries/teacherpayslip'
|
||||
import { checkAuth } from '/@/api/professional/salaries/teachersalary'
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { Money, TrendCharts, Remove, Document, DataAnalysis, Wallet, Search } from '@element-plus/icons-vue';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { queryUserInfo, queryExtendSalaryInfo } from '/@/api/professional/salaries/teacherpayslip';
|
||||
import { checkAuth } from '/@/api/professional/salaries/teachersalary';
|
||||
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 数据
|
||||
const salaryData = reactive({
|
||||
baseInfo: [] as any[]
|
||||
})
|
||||
baseInfo: [] as any[],
|
||||
});
|
||||
|
||||
const nowUser = ref<any>({})
|
||||
const baseLoading = ref(false)
|
||||
const salaryExtendData = ref<any[]>([])
|
||||
const allProjectData = ref<any[]>([])
|
||||
const nowUser = ref<any>({});
|
||||
const baseLoading = ref(false);
|
||||
const salaryExtendData = ref<any[]>([]);
|
||||
const allProjectData = ref<any[]>([]);
|
||||
const staticsData = reactive({
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0
|
||||
})
|
||||
const showAllContent = ref(false)
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0,
|
||||
});
|
||||
const showAllContent = ref(false);
|
||||
|
||||
// 检查权限
|
||||
const checkAuthMethod = async () => {
|
||||
try {
|
||||
const res = await checkAuth()
|
||||
showAllContent.value = res.data
|
||||
} catch (error) {
|
||||
// 检查权限失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const res = await checkAuth();
|
||||
showAllContent.value = res.data;
|
||||
} catch (error) {
|
||||
// 检查权限失败
|
||||
}
|
||||
};
|
||||
|
||||
// 构建用户信息
|
||||
const makeUserInfo = (data: any) => {
|
||||
const row = JSON.parse(JSON.stringify(data))
|
||||
salaryData.baseInfo = []
|
||||
row.realName = (row.realName == "" || row.realName == null ? row.userName : row.realName)
|
||||
salaryData.baseInfo.push(row)
|
||||
const row = JSON.parse(JSON.stringify(data));
|
||||
salaryData.baseInfo = [];
|
||||
row.realName = row.realName == '' || row.realName == null ? row.userName : row.realName;
|
||||
salaryData.baseInfo.push(row);
|
||||
|
||||
staticsData.shouldPay = row.shouldPay || 0
|
||||
staticsData.shouldDedu = row.withhold || 0
|
||||
staticsData.realWage = row.realWage || 0
|
||||
staticsData.personTax = (row.personalTax as number) || 0
|
||||
}
|
||||
staticsData.shouldPay = row.shouldPay || 0;
|
||||
staticsData.shouldDedu = row.withhold || 0;
|
||||
staticsData.realWage = row.realWage || 0;
|
||||
staticsData.personTax = (row.personalTax as number) || 0;
|
||||
};
|
||||
|
||||
// 查询扩展薪资信息
|
||||
const queryExtendSalaryInfoMethod = async (row: any) => {
|
||||
salaryExtendData.value = []
|
||||
const params = { nf: row.nf, yf: row.yf, teacherNo: row.teacherNo }
|
||||
try {
|
||||
const res = await queryExtendSalaryInfo(params)
|
||||
salaryExtendData.value.push(res.data.salaryTax)
|
||||
allProjectData.value = res.data.allProject
|
||||
staticsData.orderMoney = res.data.totalMoney
|
||||
} catch (error) {
|
||||
// 查询失败
|
||||
}
|
||||
}
|
||||
salaryExtendData.value = [];
|
||||
const params = { nf: row.nf, yf: row.yf, teacherNo: row.teacherNo };
|
||||
try {
|
||||
const res = await queryExtendSalaryInfo(params);
|
||||
salaryExtendData.value.push(res.data.salaryTax);
|
||||
allProjectData.value = res.data.allProject;
|
||||
staticsData.orderMoney = res.data.totalMoney;
|
||||
} catch (error) {
|
||||
// 查询失败
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索用户信息
|
||||
const searchUserInfo = async () => {
|
||||
if (!nowUser.value.idCard) {
|
||||
message.warning('请输入身份证号')
|
||||
return
|
||||
}
|
||||
if (!nowUser.value.nf) {
|
||||
message.warning('请选择年份')
|
||||
return
|
||||
}
|
||||
if (!nowUser.value.yff) {
|
||||
message.warning('请选择月份')
|
||||
return
|
||||
}
|
||||
if (!nowUser.value.idCard) {
|
||||
message.warning('请输入身份证号');
|
||||
return;
|
||||
}
|
||||
if (!nowUser.value.nf) {
|
||||
message.warning('请选择年份');
|
||||
return;
|
||||
}
|
||||
if (!nowUser.value.yff) {
|
||||
message.warning('请选择月份');
|
||||
return;
|
||||
}
|
||||
|
||||
baseLoading.value = true
|
||||
const data = { idCard: nowUser.value.idCard, nf: nowUser.value.nf, yf: nowUser.value.yff }
|
||||
try {
|
||||
const response = await queryUserInfo(data)
|
||||
if (response.data.data == null) {
|
||||
message.info('未查询到该时间段的数据')
|
||||
salaryData.baseInfo = []
|
||||
const obj: any = {}
|
||||
obj.realName = nowUser.value.realName
|
||||
obj.idCard = nowUser.value.idCard
|
||||
salaryData.baseInfo.push(obj)
|
||||
baseLoading.value = true;
|
||||
const data = { idCard: nowUser.value.idCard, nf: nowUser.value.nf, yf: nowUser.value.yff };
|
||||
try {
|
||||
const response = await queryUserInfo(data);
|
||||
if (response.data.data == null) {
|
||||
message.info('未查询到该时间段的数据');
|
||||
salaryData.baseInfo = [];
|
||||
const obj: any = {};
|
||||
obj.realName = nowUser.value.realName;
|
||||
obj.idCard = nowUser.value.idCard;
|
||||
salaryData.baseInfo.push(obj);
|
||||
|
||||
salaryExtendData.value = []
|
||||
Object.assign(staticsData, {
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0
|
||||
})
|
||||
} else {
|
||||
const resData = response.data.data
|
||||
resData.realName = nowUser.value.realName
|
||||
resData.nf = nowUser.value.nf
|
||||
resData.yf = nowUser.value.yff
|
||||
resData.teacherNo = nowUser.value.teacherNo
|
||||
makeUserInfo(resData)
|
||||
await queryExtendSalaryInfoMethod(resData)
|
||||
message.success('查询成功')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '查询失败')
|
||||
} finally {
|
||||
baseLoading.value = false
|
||||
}
|
||||
}
|
||||
salaryExtendData.value = [];
|
||||
Object.assign(staticsData, {
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0,
|
||||
});
|
||||
} else {
|
||||
const resData = response.data.data;
|
||||
resData.realName = nowUser.value.realName;
|
||||
resData.nf = nowUser.value.nf;
|
||||
resData.yf = nowUser.value.yff;
|
||||
resData.teacherNo = nowUser.value.teacherNo;
|
||||
makeUserInfo(resData);
|
||||
await queryExtendSalaryInfoMethod(resData);
|
||||
message.success('查询成功');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '查询失败');
|
||||
} finally {
|
||||
baseLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = (row: any) => {
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
checkAuthMethod()
|
||||
nowUser.value = JSON.parse(JSON.stringify(row))
|
||||
nowUser.value.yff = row.yf
|
||||
makeUserInfo(row)
|
||||
queryExtendSalaryInfoMethod(row)
|
||||
})
|
||||
}
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
checkAuthMethod();
|
||||
nowUser.value = JSON.parse(JSON.stringify(row));
|
||||
nowUser.value.yff = row.yf;
|
||||
makeUserInfo(row);
|
||||
queryExtendSalaryInfoMethod(row);
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 10px !important;
|
||||
max-height: calc(100vh - 120px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 10px !important;
|
||||
max-height: calc(100vh - 120px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.salary-info-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.section-header-inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-right: 16px;
|
||||
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.info-card {
|
||||
:deep(.el-card__header) {
|
||||
padding: 16px 20px;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
:deep(.el-card__header) {
|
||||
padding: 16px 20px;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 20px;
|
||||
}
|
||||
:deep(.el-card__body) {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.base-info-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.info-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
// align-items: center;
|
||||
gap: 6px;
|
||||
display: flex;
|
||||
// align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
.info-label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
.info-label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.info-value {
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-left: auto;
|
||||
margin-bottom: 0;
|
||||
|
||||
|
||||
|
||||
margin-left: auto;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 24px 0 12px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 24px 0 12px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.salary-table {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
:deep(.el-table__header) {
|
||||
th {
|
||||
background: #f5f7fa;
|
||||
color: #606266;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
:deep(.el-table__header) {
|
||||
th {
|
||||
background: #f5f7fa;
|
||||
color: #606266;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__cell) {
|
||||
padding: 8px 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
:deep(.el-table__cell) {
|
||||
padding: 8px 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.summary-table {
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.formula-tag {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
|
||||
.el-tag {
|
||||
margin-right: 8px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
.el-tag {
|
||||
margin-right: 8px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式优化
|
||||
@media (max-width: 1400px) {
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog) {
|
||||
width: 98% !important;
|
||||
}
|
||||
}
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog) {
|
||||
width: 98% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条优化
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,121 +1,113 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="薪资导出" width="650px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="劳务日期锁定">
|
||||
<el-radio-group v-model="lockedLw">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0px">
|
||||
<el-tag type="warning">选择是,则本月其他造单批次无法指定到当前月份。如需解锁,请前往「薪资导出记录」删除记录即可。</el-tag>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span v-if="showBtn" class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="exportSalaryData" :loading="btnLoading">导 出</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="薪资导出" width="650px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker v-model="chooseDate" type="month" format="YYYY-M" value-format="YYYY-M" placeholder="请选择日期" @change="handleChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="劳务日期锁定">
|
||||
<el-radio-group v-model="lockedLw">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0px">
|
||||
<el-tag type="warning">选择是,则本月其他造单批次无法指定到当前月份。如需解锁,请前往「薪资导出记录」删除记录即可。</el-tag>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span v-if="showBtn" class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="exportSalaryData" :loading="btnLoading">导 出</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { ref } from 'vue';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const showBtn = ref(false)
|
||||
const btnLoading = ref(false)
|
||||
const lockedLw = ref(1)
|
||||
const chooseDate = ref('');
|
||||
const showBtn = ref(false);
|
||||
const btnLoading = ref(false);
|
||||
const lockedLw = ref(1);
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
chooseDate.value = ''
|
||||
showBtn.value = false
|
||||
btnLoading.value = false
|
||||
lockedLw.value = 1
|
||||
visible.value = true
|
||||
}
|
||||
chooseDate.value = '';
|
||||
showBtn.value = false;
|
||||
btnLoading.value = false;
|
||||
lockedLw.value = 1;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 日期改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showBtn.value = true
|
||||
} else {
|
||||
showBtn.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showBtn.value = true;
|
||||
} else {
|
||||
showBtn.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 下载文件
|
||||
const downLoadFile = async (url: string) => {
|
||||
return request({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
}
|
||||
return request({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 导出薪资数据
|
||||
const exportSalaryData = async () => {
|
||||
if (!chooseDate.value) {
|
||||
message.warning('请选择日期')
|
||||
return
|
||||
}
|
||||
|
||||
btnLoading.value = true
|
||||
try {
|
||||
const res = await downLoadFile(`/professional/file/exportSalary?chooseDate=${chooseDate.value}&state=${lockedLw.value}`)
|
||||
|
||||
// 处理返回的文件流
|
||||
const blob = new Blob([res.data])
|
||||
const elink = document.createElement('a')
|
||||
elink.download = "薪资表.xls"
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href) // 释放URL 对象
|
||||
document.body.removeChild(elink)
|
||||
|
||||
message.success('导出成功')
|
||||
visible.value = false
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导出失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
if (!chooseDate.value) {
|
||||
message.warning('请选择日期');
|
||||
return;
|
||||
}
|
||||
|
||||
btnLoading.value = true;
|
||||
try {
|
||||
const res = await downLoadFile(`/professional/file/exportSalary?chooseDate=${chooseDate.value}&state=${lockedLw.value}`);
|
||||
|
||||
// 处理返回的文件流
|
||||
const blob = new Blob([res.data]);
|
||||
const elink = document.createElement('a');
|
||||
elink.download = '薪资表.xls';
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href); // 释放URL 对象
|
||||
document.body.removeChild(elink);
|
||||
|
||||
message.success('导出成功');
|
||||
visible.value = false;
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导出失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,170 +1,165 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="薪资导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_import')"
|
||||
size="small"
|
||||
type="primary">选择文件
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="薪资导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button v-if="hasAuth('professional_salary_import')" size="small" type="primary">选择文件 </el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { ref, computed } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const url = ref('')
|
||||
const showUpload = ref(false)
|
||||
const fileList = ref<any[]>([])
|
||||
const btnLoading = ref(false)
|
||||
const fileName = ref('')
|
||||
const files = ref<File | null>(null)
|
||||
const chooseDate = ref('');
|
||||
const url = ref('');
|
||||
const showUpload = ref(false);
|
||||
const fileList = ref<any[]>([]);
|
||||
const btnLoading = ref(false);
|
||||
const fileName = ref('');
|
||||
const files = ref<File | null>(null);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 日期改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true
|
||||
url.value = `/professional/file/importSalary?chooseDate=${chooseDate.value}`
|
||||
} else {
|
||||
showUpload.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true;
|
||||
url.value = `/professional/file/importSalary?chooseDate=${chooseDate.value}`;
|
||||
} else {
|
||||
showUpload.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
fileList.value = []
|
||||
files.value = null
|
||||
fileName.value = ''
|
||||
chooseDate.value = ''
|
||||
showUpload.value = false
|
||||
visible.value = true
|
||||
}
|
||||
fileList.value = [];
|
||||
files.value = null;
|
||||
fileName.value = '';
|
||||
chooseDate.value = '';
|
||||
showUpload.value = false;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 上传前验证
|
||||
const beforeUpload = (file: File) => {
|
||||
files.value = file
|
||||
const fileLast = file.name.split('.')
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
||||
const isLt2M = file.size / 1024 / 1024 < 20
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
return false // 返回false不会自动上传
|
||||
}
|
||||
files.value = file;
|
||||
const fileLast = file.name.split('.');
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||
const isLt2M = file.size / 1024 / 1024 < 20;
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
return false; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
// 导入提交
|
||||
const submitUpload = async () => {
|
||||
btnLoading.value = true
|
||||
if (fileName.value === "") {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const fileFormData = new FormData()
|
||||
fileFormData.append('file', files.value, fileName.value)
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`)
|
||||
} else {
|
||||
message.success("导入成功")
|
||||
visible.value = false
|
||||
emit('refreshData')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
btnLoading.value = true;
|
||||
if (fileName.value === '') {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileFormData = new FormData();
|
||||
fileFormData.append('file', files.value, fileName.value);
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`);
|
||||
} else {
|
||||
message.success('导入成功');
|
||||
visible.value = false;
|
||||
emit('refreshData');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,170 +1,165 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="税金导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_import')"
|
||||
size="small"
|
||||
type="primary">选择文件
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="visible" title="税金导入" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="日期">
|
||||
<el-date-picker
|
||||
v-model="chooseDate"
|
||||
type="month"
|
||||
format="YYYY-M"
|
||||
value-format="YYYY-M"
|
||||
placeholder="请选择日期"
|
||||
@change="handleChange"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
v-if="showUpload"
|
||||
:headers="headers"
|
||||
class="upload-demo"
|
||||
:action="url"
|
||||
:limit="1"
|
||||
:with-credentials="true"
|
||||
:before-upload="beforeUpload"
|
||||
>
|
||||
<template #tip>
|
||||
<div class="el-upload-list__item-name">{{ fileName }}</div>
|
||||
</template>
|
||||
<el-button v-if="hasAuth('professional_salary_import')" size="small" type="primary">选择文件 </el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="submitUpload" :loading="btnLoading">导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { Session } from '/@/utils/storage'
|
||||
import request from '/@/utils/request'
|
||||
import { ref, computed } from 'vue';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshData'): void
|
||||
}>()
|
||||
(e: 'refreshData'): void;
|
||||
}>();
|
||||
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
// 消息提示
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const chooseDate = ref('')
|
||||
const url = ref('')
|
||||
const showUpload = ref(false)
|
||||
const fileList = ref<any[]>([])
|
||||
const btnLoading = ref(false)
|
||||
const fileName = ref('')
|
||||
const files = ref<File | null>(null)
|
||||
const chooseDate = ref('');
|
||||
const url = ref('');
|
||||
const showUpload = ref(false);
|
||||
const fileList = ref<any[]>([]);
|
||||
const btnLoading = ref(false);
|
||||
const fileName = ref('');
|
||||
const files = ref<File | null>(null);
|
||||
|
||||
// 请求头
|
||||
const headers = computed(() => {
|
||||
return {
|
||||
"Authorization": 'Bearer ' + Session.getToken()
|
||||
}
|
||||
})
|
||||
return {
|
||||
Authorization: 'Bearer ' + Session.getToken(),
|
||||
};
|
||||
});
|
||||
|
||||
// 日期改变
|
||||
const handleChange = () => {
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true
|
||||
url.value = `/professional/file/importTaxSalary?chooseDate=${chooseDate.value}`
|
||||
} else {
|
||||
showUpload.value = false
|
||||
}
|
||||
}
|
||||
if (chooseDate.value) {
|
||||
showUpload.value = true;
|
||||
url.value = `/professional/file/importTaxSalary?chooseDate=${chooseDate.value}`;
|
||||
} else {
|
||||
showUpload.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
fileList.value = []
|
||||
files.value = null
|
||||
fileName.value = ''
|
||||
chooseDate.value = ''
|
||||
showUpload.value = false
|
||||
visible.value = true
|
||||
}
|
||||
fileList.value = [];
|
||||
files.value = null;
|
||||
fileName.value = '';
|
||||
chooseDate.value = '';
|
||||
showUpload.value = false;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 上传前验证
|
||||
const beforeUpload = (file: File) => {
|
||||
files.value = file
|
||||
const fileLast = file.name.split('.')
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
||||
const isLt2M = file.size / 1024 / 1024 < 20
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
||||
return false
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!')
|
||||
return false
|
||||
}
|
||||
fileName.value = file.name
|
||||
return false // 返回false不会自动上传
|
||||
}
|
||||
files.value = file;
|
||||
const fileLast = file.name.split('.');
|
||||
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||
const isLt2M = file.size / 1024 / 1024 < 20;
|
||||
|
||||
if (!extension && !extension2) {
|
||||
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||
return false;
|
||||
}
|
||||
if (!isLt2M) {
|
||||
message.warning('上传模板大小不能超过 20MB!');
|
||||
return false;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
return false; // 返回false不会自动上传
|
||||
};
|
||||
|
||||
// 导入提交
|
||||
const submitUpload = async () => {
|
||||
btnLoading.value = true
|
||||
if (fileName.value === "") {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!')
|
||||
btnLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const fileFormData = new FormData()
|
||||
fileFormData.append('file', files.value, fileName.value)
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`)
|
||||
} else {
|
||||
message.success("导入成功")
|
||||
visible.value = false
|
||||
emit('refreshData')
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败')
|
||||
} finally {
|
||||
btnLoading.value = false
|
||||
}
|
||||
}
|
||||
btnLoading.value = true;
|
||||
if (fileName.value === '') {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!files.value) {
|
||||
message.warning('请选择要上传的文件!');
|
||||
btnLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileFormData = new FormData();
|
||||
fileFormData.append('file', files.value, fileName.value);
|
||||
|
||||
try {
|
||||
const res = await request({
|
||||
url: url.value,
|
||||
method: 'post',
|
||||
data: fileFormData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.data && res.data.data.code == 1) {
|
||||
message.error(`导入失败,${res.data.data.title}: ${res.data.data.msg}`);
|
||||
} else {
|
||||
message.success('导入成功');
|
||||
visible.value = false;
|
||||
emit('refreshData');
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '导入失败');
|
||||
} finally {
|
||||
btnLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,401 +1,337 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter"
|
||||
>
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input
|
||||
v-model="search.teacherNo"
|
||||
placeholder="请输入工号"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter">
|
||||
<template #default="{ visible }">
|
||||
<template v-if="visible">
|
||||
<el-form-item label="工号" prop="teacherNo">
|
||||
<el-input v-model="search.teacherNo" placeholder="请输入工号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="search.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="search.realName" placeholder="请输入姓名" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input
|
||||
v-model="search.idCard"
|
||||
placeholder="请输入身份证号"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input v-model="search.idCard" placeholder="请输入身份证号" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="年份" prop="nf">
|
||||
<el-date-picker
|
||||
v-model="search.nf"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年份"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="年份" prop="nf">
|
||||
<el-date-picker
|
||||
v-model="search.nf"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="请选择年份"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="月份" prop="yf">
|
||||
<el-date-picker
|
||||
v-model="search.yf"
|
||||
type="month"
|
||||
format="M"
|
||||
value-format="M"
|
||||
placeholder="请选择月份"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份" prop="yf">
|
||||
<el-date-picker v-model="search.yf" type="month" format="M" value-format="M" placeholder="请选择月份" clearable style="width: 200px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="岗位级别" prop="stationTypeId">
|
||||
<el-select
|
||||
v-model="search.stationTypeId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择岗位级别"
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in stationLevelList"
|
||||
:key="item.id"
|
||||
:label="item.levelName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item label="岗位级别" prop="stationTypeId">
|
||||
<el-select v-model="search.stationTypeId" filterable clearable placeholder="请选择岗位级别" style="width: 200px">
|
||||
<el-option v-for="item in stationLevelList" :key="item.id" :label="item.levelName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
<!-- 查询和重置按钮 -->
|
||||
<template #actions>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFilter" icon="Search">查询</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">重置</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</search-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_import')"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
@click="handleImportBaseSalary">人事薪资导入
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_finance_import')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
class="ml10"
|
||||
@click="handleExportSalart">薪资导出
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_finance_import')"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
class="ml10"
|
||||
@click="handleImportTaxSalary">税金导入
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_seach_auth')"
|
||||
icon="View"
|
||||
class="ml10"
|
||||
@click="canSearch(1)">设置可查询
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_seach_auth')"
|
||||
icon="Hide"
|
||||
class="ml10"
|
||||
@click="canSearch(0)">设置不可查询
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_professionalsalaries_del')"
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
class="ml10"
|
||||
@click="delbatch">批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15">
|
||||
<el-button v-if="hasAuth('professional_salary_import')" type="primary" plain icon="UploadFilled" @click="handleImportBaseSalary"
|
||||
>人事薪资导入
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_finance_import')"
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
class="ml10"
|
||||
@click="handleExportSalart"
|
||||
>薪资导出
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_salary_finance_import')"
|
||||
type="primary"
|
||||
plain
|
||||
icon="UploadFilled"
|
||||
class="ml10"
|
||||
@click="handleImportTaxSalary"
|
||||
>税金导入
|
||||
</el-button>
|
||||
<el-button v-if="hasAuth('professional_seach_auth')" icon="View" class="ml10" @click="canSearch(1)">设置可查询 </el-button>
|
||||
<el-button v-if="hasAuth('professional_seach_auth')" icon="Hide" class="ml10" @click="canSearch(0)">设置不可查询 </el-button>
|
||||
<el-button v-if="hasAuth('professional_professionalsalaries_del')" type="danger" plain icon="Delete" class="ml10" @click="delbatch"
|
||||
>批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
@selection-change="selectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="nf" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="yf" label="月份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="idCard" label="身份证号" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="shouldPay" label="应发工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realWage" label="实发工资" width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="normalView" label="职工查看" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.normalView === '1' ? 'success' : 'info'">
|
||||
{{ scope.row.normalView === '1' ? '可查询' : '不可查询' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="80" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="document"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="data-table"
|
||||
@selection-change="selectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<salary-info ref="salaryInfoRef" />
|
||||
<import-base-salary ref="importBaseSalaryRef" @refreshData="handleFilter" />
|
||||
<export-base-salary ref="exportBaseSalaryRef" />
|
||||
<import-tax-salary ref="importTaxSalaryRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column label="姓名/工号" min-width="150" align="center">
|
||||
<template #default="scope">
|
||||
<TeacherNameNo :name="scope.row.realName" :no="scope.row.teacherNo" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="nf" label="年份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="yf" label="月份" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="idCard" label="身份证号" min-width="180" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="shouldPay" label="应发工资" min-width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="realWage" label="实发工资" width="120" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="normalView" label="职工查看" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.normalView === '1' ? 'success' : 'info'">
|
||||
{{ scope.row.normalView === '1' ? '可查询' : '不可查询' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" min-width="80" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button icon="document" link type="primary" @click="handleEdit(scope.row)">查看 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 子组件 -->
|
||||
<salary-info ref="salaryInfoRef" />
|
||||
<import-base-salary ref="importBaseSalaryRef" @refreshData="handleFilter" />
|
||||
<export-base-salary ref="exportBaseSalaryRef" />
|
||||
<import-tax-salary ref="importTaxSalaryRef" @refreshData="handleFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, delBatch, setCanSearch, checkAuth } from '/@/api/professional/salaries/teachersalary'
|
||||
import { getStationLevelList } from '/@/api/professional/professionalstationlevelconfig'
|
||||
const SalaryInfo = defineAsyncComponent(() => import('./salaryInfo.vue'))
|
||||
const ImportBaseSalary = defineAsyncComponent(() => import('./importBaseSalary.vue'))
|
||||
const ExportBaseSalary = defineAsyncComponent(() => import('./exportBaseSalary.vue'))
|
||||
const ImportTaxSalary = defineAsyncComponent(() => import('./importTaxSalary.vue'))
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, delBatch, setCanSearch, checkAuth } from '/@/api/professional/salaries/teachersalary';
|
||||
import { getStationLevelList } from '/@/api/professional/professionalstationlevelconfig';
|
||||
const SalaryInfo = defineAsyncComponent(() => import('./salaryInfo.vue'));
|
||||
const ImportBaseSalary = defineAsyncComponent(() => import('./importBaseSalary.vue'));
|
||||
const ExportBaseSalary = defineAsyncComponent(() => import('./exportBaseSalary.vue'));
|
||||
const ImportTaxSalary = defineAsyncComponent(() => import('./importTaxSalary.vue'));
|
||||
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'))
|
||||
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue'));
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const salaryInfoRef = ref()
|
||||
const importBaseSalaryRef = ref()
|
||||
const exportBaseSalaryRef = ref()
|
||||
const importTaxSalaryRef = ref()
|
||||
const tableRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const salaryInfoRef = ref();
|
||||
const importBaseSalaryRef = ref();
|
||||
const exportBaseSalaryRef = ref();
|
||||
const importTaxSalaryRef = ref();
|
||||
|
||||
// 搜索表单显示状态
|
||||
const showSearch = ref(true)
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 岗位类别列表
|
||||
const stationLevelList = ref<any[]>([])
|
||||
const stationLevelList = ref<any[]>([]);
|
||||
|
||||
// 选中的行
|
||||
const selectList = ref<any[]>([])
|
||||
const selectList = ref<any[]>([]);
|
||||
|
||||
// 搜索表单数据
|
||||
const search = reactive({
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: '',
|
||||
canSearch: 0,
|
||||
selectList:[]
|
||||
})
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: '',
|
||||
canSearch: 0,
|
||||
selectList: [],
|
||||
});
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: search
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: search,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
init();
|
||||
});
|
||||
|
||||
// 初始化数据
|
||||
const init = async () => {
|
||||
try {
|
||||
const [stationRes, authRes] = await Promise.all([
|
||||
getStationLevelList(),
|
||||
checkAuth()
|
||||
])
|
||||
|
||||
stationLevelList.value = stationRes.data || []
|
||||
|
||||
// 根据权限设置表格选项(如果需要)
|
||||
// if (authRes.data.data === false) {
|
||||
// // 设置普通表格选项
|
||||
// }
|
||||
} catch (error) {
|
||||
// 初始化失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const [stationRes, authRes] = await Promise.all([getStationLevelList(), checkAuth()]);
|
||||
|
||||
stationLevelList.value = stationRes.data || [];
|
||||
|
||||
// 根据权限设置表格选项(如果需要)
|
||||
// if (authRes.data.data === false) {
|
||||
// // 设置普通表格选项
|
||||
// }
|
||||
} catch (error) {
|
||||
// 初始化失败
|
||||
}
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = () => {
|
||||
getDataList() // 查询后跳转到第一页
|
||||
}
|
||||
getDataList(); // 查询后跳转到第一页
|
||||
};
|
||||
|
||||
// 重置
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: ''
|
||||
})
|
||||
handleFilter()
|
||||
}
|
||||
searchFormRef.value?.formRef?.resetFields();
|
||||
Object.assign(search, {
|
||||
teacherNo: '',
|
||||
realName: '',
|
||||
idCard: '',
|
||||
nf: '',
|
||||
yf: '',
|
||||
stationTypeId: '',
|
||||
});
|
||||
handleFilter();
|
||||
};
|
||||
|
||||
// 选择变化
|
||||
const selectionChange = (selection: any[]) => {
|
||||
selectList.value = selection
|
||||
}
|
||||
selectList.value = selection;
|
||||
};
|
||||
|
||||
// 查看
|
||||
const handleEdit = (row: any) => {
|
||||
salaryInfoRef.value?.init(row)
|
||||
}
|
||||
salaryInfoRef.value?.init(row);
|
||||
};
|
||||
|
||||
// 导入人事薪资
|
||||
const handleImportBaseSalary = () => {
|
||||
importBaseSalaryRef.value?.init()
|
||||
}
|
||||
importBaseSalaryRef.value?.init();
|
||||
};
|
||||
|
||||
// 导入税金
|
||||
const handleImportTaxSalary = () => {
|
||||
importTaxSalaryRef.value?.init()
|
||||
}
|
||||
importTaxSalaryRef.value?.init();
|
||||
};
|
||||
|
||||
// 导出薪资
|
||||
const handleExportSalart = () => {
|
||||
exportBaseSalaryRef.value?.init()
|
||||
}
|
||||
exportBaseSalaryRef.value?.init();
|
||||
};
|
||||
|
||||
// 批量删除
|
||||
const delbatch = () => {
|
||||
if (selectList.value.length === 0) {
|
||||
message.warning("请至少选择一名人员")
|
||||
return
|
||||
}
|
||||
|
||||
messageBox.confirm(`确认删除当前${selectList.value.length}条记录`).then(async () => {
|
||||
try {
|
||||
const data = { selectList: selectList.value }
|
||||
const response = await delBatch(data)
|
||||
|
||||
if (response.data.code == -1) {
|
||||
message.error(response.data.data)
|
||||
} else {
|
||||
message.success("删除成功")
|
||||
getDataList(false) // 删除后保持当前页
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '删除失败')
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
if (selectList.value.length === 0) {
|
||||
message.warning('请至少选择一名人员');
|
||||
return;
|
||||
}
|
||||
|
||||
messageBox
|
||||
.confirm(`确认删除当前${selectList.value.length}条记录`)
|
||||
.then(async () => {
|
||||
try {
|
||||
const data = { selectList: selectList.value };
|
||||
const response = await delBatch(data);
|
||||
|
||||
if (response.data.code == -1) {
|
||||
message.error(response.data.data);
|
||||
} else {
|
||||
message.success('删除成功');
|
||||
getDataList(false); // 删除后保持当前页
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || '删除失败');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
});
|
||||
};
|
||||
|
||||
// 设置可查询/不可查询
|
||||
const canSearch = (val: number) => {
|
||||
// if (selectList.value.length === 0) {
|
||||
// message.warning("请至少选择一名人员")
|
||||
// return
|
||||
// }
|
||||
search.canSearch=val
|
||||
search.selectList=selectList.value
|
||||
// if (selectList.value.length === 0) {
|
||||
// message.warning("请至少选择一名人员")
|
||||
// return
|
||||
// }
|
||||
search.canSearch = val;
|
||||
search.selectList = selectList.value;
|
||||
|
||||
|
||||
|
||||
messageBox.confirm('确认设置?').then(async () => {
|
||||
try {
|
||||
await setCanSearch(search)
|
||||
message.success("设置成功")
|
||||
getDataList(false) // 设置后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
messageBox
|
||||
.confirm('确认设置?')
|
||||
.then(async () => {
|
||||
try {
|
||||
await setCanSearch(search);
|
||||
message.success('设置成功');
|
||||
getDataList(false); // 设置后保持当前页
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.data-table {
|
||||
width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,556 +1,523 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
width="95%"
|
||||
v-loading="baseLoading"
|
||||
top="2vh"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
class="salary-info-dialog"
|
||||
>
|
||||
<div class="salary-info-container">
|
||||
<!--基本信息-->
|
||||
<div class="base-info-section">
|
||||
<div class="base-info-content">
|
||||
<div class="info-group">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.realName">{{ salaryData.baseInfo[0].realName }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">身份证号:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.idCard">{{ salaryData.baseInfo[0].idCard }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-form :model="nowUser" :inline="true" class="search-form">
|
||||
<el-form-item label="年份">
|
||||
<el-date-picker
|
||||
v-model="nowUser.nf"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
value-format="YYYY"
|
||||
placeholder="选择年"
|
||||
style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份">
|
||||
<el-date-picker
|
||||
v-model="nowUser.yff"
|
||||
type="month"
|
||||
format="M"
|
||||
value-format="M"
|
||||
placeholder="选择月"
|
||||
style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="searchUserInfo" type="primary" icon="Search">
|
||||
查询
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
width="95%"
|
||||
v-loading="baseLoading"
|
||||
top="2vh"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
class="salary-info-dialog"
|
||||
>
|
||||
<div class="salary-info-container">
|
||||
<!--基本信息-->
|
||||
<div class="base-info-section">
|
||||
<div class="base-info-content">
|
||||
<div class="info-group">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.realName">{{ salaryData.baseInfo[0].realName }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">身份证号:</span>
|
||||
<el-tag v-if="salaryData.baseInfo[0]?.idCard">{{ salaryData.baseInfo[0].idCard }}</el-tag>
|
||||
<span v-else class="info-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-form :model="nowUser" :inline="true" class="search-form">
|
||||
<el-form-item label="年份">
|
||||
<el-date-picker v-model="nowUser.nf" type="year" format="YYYY" value-format="YYYY" placeholder="选择年" style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份">
|
||||
<el-date-picker v-model="nowUser.yff" type="month" format="M" value-format="M" placeholder="选择月" style="width: 150px">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="searchUserInfo" type="primary" icon="Search"> 查询 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card shadow="hover" class="info-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon><Money /></el-icon>
|
||||
<span>工资明细</span>
|
||||
</div>
|
||||
</template>
|
||||
<!--应发部分-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
<span>应发部分</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="showAllContent"
|
||||
:data="salaryData.baseInfo"
|
||||
size="small"
|
||||
border
|
||||
class="salary-table"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="应发部分">
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="payWage" label="薪级工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="见习期工资" prop="studentPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="liveAllowance" label="生活补贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="postAllowance" label="岗位津贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="住房(租金)补贴" prop="houseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="新职工住房补贴" prop="newHouseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="回民补贴" prop="huiSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="养老保险补贴" prop="oldSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="教龄津贴" prop="ageAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特教补贴" prop="specialSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特级教师津贴" prop="teacherAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(一)" prop="sPostAllowance1" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(二)" prop="sPostAllowance2" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="其他" prop="other" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="奖励性绩效工资" prop="meritPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="乡镇工作补贴" prop="villageSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="临时性补贴" prop="temporarySubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="上下班交通补贴" prop="trafficSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="保留津贴" prop="keepAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="补发工资" prop="retroactivePay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应休未休假补贴" prop="vacationMoney" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应发工资" prop="shouldPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础专项绩效" prop="baseSalary" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础工资应税收入" prop="shouldTaxMoney" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag type="danger" size="small">基础工资应税收入= 岗位工资 +薪级工资+见习期工资+生活补贴+岗位津贴+教龄津贴+特教补贴+特级教师津贴+特岗津贴(1)+特岗津贴(2)+奖励绩效性工资+乡镇工作补贴+临时补贴+保留津贴+应休未休假-个人补缴-其他扣款-医疗救助金</el-tag>
|
||||
</div>
|
||||
|
||||
<!--应扣部分-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><Remove /></el-icon>
|
||||
<span>应扣部分</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="showAllContent"
|
||||
size="small"
|
||||
border
|
||||
:data="salaryData.baseInfo"
|
||||
class="salary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column label="应扣部分">
|
||||
<el-table-column label="住房公积金" min-width="90" prop="houseFund"></el-table-column>
|
||||
<el-table-column label="医疗保险金" min-width="90" prop="medicalInsurance"></el-table-column>
|
||||
<el-table-column label="失业保险金" min-width="90" prop="unemployInsurance"></el-table-column>
|
||||
<el-table-column label="养老保险金" min-width="90" prop="endowInsurance"></el-table-column>
|
||||
<el-table-column label="工会费" min-width="60" prop="unionFee"></el-table-column>
|
||||
<el-table-column label="儿童统筹" min-width="90" prop="childrenWhole"></el-table-column>
|
||||
<el-table-column label="个人所得税" width="90" prop="personalTax"></el-table-column>
|
||||
<el-table-column label="其他扣款" min-width="90" prop="otherDeduction"></el-table-column>
|
||||
<el-table-column label="病事假扣款" min-width="90" prop="sickDeduction"></el-table-column>
|
||||
<el-table-column label="医疗救助基金" min-width="90" prop="medicalFund"></el-table-column>
|
||||
<el-table-column label="工伤保险" min-width="90" prop="inductrialInjury"></el-table-column>
|
||||
<el-table-column label="个人补缴" min-width="90" prop="personalPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" min-width="90" prop="withhold"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag size="small">个人所得税 = 个税计算数据中的《 累计应补(退)税额 》</el-tag>
|
||||
</div>
|
||||
<el-card shadow="hover" class="info-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon><Money /></el-icon>
|
||||
<span>工资明细</span>
|
||||
</div>
|
||||
</template>
|
||||
<!--应发部分-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
<span>应发部分</span>
|
||||
</div>
|
||||
<el-table v-if="showAllContent" :data="salaryData.baseInfo" size="small" border class="salary-table" style="width: 100%">
|
||||
<el-table-column label="应发部分">
|
||||
<el-table-column prop="postSalary" label="岗位工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="payWage" label="薪级工资" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="见习期工资" prop="studentPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="liveAllowance" label="生活补贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="postAllowance" label="岗位津贴" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="住房(租金)补贴" prop="houseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="新职工住房补贴" prop="newHouseSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="回民补贴" prop="huiSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="养老保险补贴" prop="oldSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="教龄津贴" prop="ageAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特教补贴" prop="specialSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特级教师津贴" prop="teacherAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(一)" prop="sPostAllowance1" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="特岗津贴(二)" prop="sPostAllowance2" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="其他" prop="other" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="奖励性绩效工资" prop="meritPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="乡镇工作补贴" prop="villageSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="临时性补贴" prop="temporarySubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="上下班交通补贴" prop="trafficSubsidies" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="保留津贴" prop="keepAllowance" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="补发工资" prop="retroactivePay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应休未休假补贴" prop="vacationMoney" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="应发工资" prop="shouldPay" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础专项绩效" prop="baseSalary" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="基础工资应税收入" prop="shouldTaxMoney" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag type="danger" size="small"
|
||||
>基础工资应税收入= 岗位工资
|
||||
+薪级工资+见习期工资+生活补贴+岗位津贴+教龄津贴+特教补贴+特级教师津贴+特岗津贴(1)+特岗津贴(2)+奖励绩效性工资+乡镇工作补贴+临时补贴+保留津贴+应休未休假-个人补缴-其他扣款-医疗救助金</el-tag
|
||||
>
|
||||
</div>
|
||||
|
||||
<!--劳务费-->
|
||||
<div class="section-title">
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>造单收入清单</span>
|
||||
</div>
|
||||
<el-table
|
||||
size="small"
|
||||
border
|
||||
:data="allProjectData"
|
||||
class="salary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column label="造单收入清单">
|
||||
<el-table-column label="造单部门" prop="deptName"></el-table-column>
|
||||
<el-table-column label="造单人" prop="createName"></el-table-column>
|
||||
<el-table-column label="项目编号" prop="projectNo"></el-table-column>
|
||||
<el-table-column label="项目名" prop="title"></el-table-column>
|
||||
<el-table-column label="金额" prop="realMoney"></el-table-column>
|
||||
<el-table-column label="付讫时间" prop="payTime"></el-table-column>
|
||||
<el-table-column label="免税或暂不交税" prop="freeTax">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.freeTax=='1'">√</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--应扣部分-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><Remove /></el-icon>
|
||||
<span>应扣部分</span>
|
||||
</div>
|
||||
<el-table v-if="showAllContent" size="small" border :data="salaryData.baseInfo" class="salary-table" style="width: 100%">
|
||||
<el-table-column label="应扣部分">
|
||||
<el-table-column label="住房公积金" min-width="90" prop="houseFund"></el-table-column>
|
||||
<el-table-column label="医疗保险金" min-width="90" prop="medicalInsurance"></el-table-column>
|
||||
<el-table-column label="失业保险金" min-width="90" prop="unemployInsurance"></el-table-column>
|
||||
<el-table-column label="养老保险金" min-width="90" prop="endowInsurance"></el-table-column>
|
||||
<el-table-column label="工会费" min-width="60" prop="unionFee"></el-table-column>
|
||||
<el-table-column label="儿童统筹" min-width="90" prop="childrenWhole"></el-table-column>
|
||||
<el-table-column label="个人所得税" width="90" prop="personalTax"></el-table-column>
|
||||
<el-table-column label="其他扣款" min-width="90" prop="otherDeduction"></el-table-column>
|
||||
<el-table-column label="病事假扣款" min-width="90" prop="sickDeduction"></el-table-column>
|
||||
<el-table-column label="医疗救助基金" min-width="90" prop="medicalFund"></el-table-column>
|
||||
<el-table-column label="工伤保险" min-width="90" prop="inductrialInjury"></el-table-column>
|
||||
<el-table-column label="个人补缴" min-width="90" prop="personalPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" min-width="90" prop="withhold"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag size="small">个人所得税 = 个税计算数据中的《 累计应补(退)税额 》</el-tag>
|
||||
</div>
|
||||
|
||||
<!--专项扣除-->
|
||||
<div class="section-title">
|
||||
<el-icon><DataAnalysis /></el-icon>
|
||||
<span>个税计算数据</span>
|
||||
</div>
|
||||
<el-table
|
||||
size="small"
|
||||
border
|
||||
:data="salaryExtendData"
|
||||
class="salary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column label="个税计算数据">
|
||||
<el-table-column prop="currentIncome" label="应税收入" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalIncome" label="累计收入额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalDeduction" label="累计减除费用" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSpecialDecution" label="累计专项扣除" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="累计专项扣除附加" align="center">
|
||||
<el-table-column prop="totalChildEdu" label="累计子女教育" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalConEdu" label="累计继续教育" min-width="60" align="center"> </el-table-column>
|
||||
<el-table-column prop="totalHouseInterest" label="累计住房贷款利息" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalHouse" label="累计住房租金" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSupportOld" label="累计赡养老人" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalBabyMoney" label="累计婴幼儿照护费用" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalTaxMoney" label="累计应纳税所得额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="taxRate" label="税率" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="quickDecution" label="速算扣除数" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRealTaxPay" label="累计应扣缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalPrePayTax" label="累计已预缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRetrieveTax" label="累计应补(退)税额" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag type="warning" size="small">应税收入= 基础工资应税收入+造单收入</el-tag>
|
||||
<el-tag type="success" size="small" class="ml10">累计专项扣除=当年累计个人承担的住房公积金+医疗保险金+失业保险金+养老保险金</el-tag>
|
||||
</div>
|
||||
<!--劳务费-->
|
||||
<div class="section-title">
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>造单收入清单</span>
|
||||
</div>
|
||||
<el-table size="small" border :data="allProjectData" class="salary-table" style="width: 100%">
|
||||
<el-table-column label="造单收入清单">
|
||||
<el-table-column label="造单部门" prop="deptName"></el-table-column>
|
||||
<el-table-column label="造单人" prop="createName"></el-table-column>
|
||||
<el-table-column label="项目编号" prop="projectNo"></el-table-column>
|
||||
<el-table-column label="项目名" prop="title"></el-table-column>
|
||||
<el-table-column label="金额" prop="realMoney"></el-table-column>
|
||||
<el-table-column label="付讫时间" prop="payTime"></el-table-column>
|
||||
<el-table-column label="免税或暂不交税" prop="freeTax">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.freeTax == '1'">√</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!--实发合计-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><Wallet /></el-icon>
|
||||
<span>实发合计</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="showAllContent"
|
||||
size="small"
|
||||
border
|
||||
:data="[staticsData]"
|
||||
class="salary-table summary-table"
|
||||
empty-text=" "
|
||||
style="width: 100%">
|
||||
<el-table-column label="小计">
|
||||
<el-table-column label="应发工资" prop="shouldPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" prop="shouldDedu"></el-table-column>
|
||||
<el-table-column label="实发工资" prop="realWage"></el-table-column>
|
||||
<el-table-column label="造单收入" prop="orderMoney"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag type="primary" size="small">实发工资= 应发工资-应扣合计</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--专项扣除-->
|
||||
<div class="section-title">
|
||||
<el-icon><DataAnalysis /></el-icon>
|
||||
<span>个税计算数据</span>
|
||||
</div>
|
||||
<el-table size="small" border :data="salaryExtendData" class="salary-table" style="width: 100%">
|
||||
<el-table-column label="个税计算数据">
|
||||
<el-table-column prop="currentIncome" label="应税收入" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalIncome" label="累计收入额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalDeduction" label="累计减除费用" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSpecialDecution" label="累计专项扣除" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column label="累计专项扣除附加" align="center">
|
||||
<el-table-column prop="totalChildEdu" label="累计子女教育" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalConEdu" label="累计继续教育" min-width="60" align="center"> </el-table-column>
|
||||
<el-table-column prop="totalHouseInterest" label="累计住房贷款利息" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalHouse" label="累计住房租金" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalSupportOld" label="累计赡养老人" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalBabyMoney" label="累计婴幼儿照护费用" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalTaxMoney" label="累计应纳税所得额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="taxRate" label="税率" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="quickDecution" label="速算扣除数" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRealTaxPay" label="累计应扣缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalPrePayTax" label="累计已预缴税额" min-width="60" align="center"></el-table-column>
|
||||
<el-table-column prop="totalRetrieveTax" label="累计应补(退)税额" min-width="60" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="formula-tag">
|
||||
<el-tag type="warning" size="small">应税收入= 基础工资应税收入+造单收入</el-tag>
|
||||
<el-tag type="success" size="small" class="ml10">累计专项扣除=当年累计个人承担的住房公积金+医疗保险金+失业保险金+养老保险金</el-tag>
|
||||
</div>
|
||||
|
||||
<!--实发合计-->
|
||||
<div v-if="showAllContent" class="section-title">
|
||||
<el-icon><Wallet /></el-icon>
|
||||
<span>实发合计</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-if="showAllContent"
|
||||
size="small"
|
||||
border
|
||||
:data="[staticsData]"
|
||||
class="salary-table summary-table"
|
||||
empty-text=" "
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="小计">
|
||||
<el-table-column label="应发工资" prop="shouldPay"></el-table-column>
|
||||
<el-table-column label="应扣合计" prop="shouldDedu"></el-table-column>
|
||||
<el-table-column label="实发工资" prop="realWage"></el-table-column>
|
||||
<el-table-column label="造单收入" prop="orderMoney"></el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="showAllContent" class="formula-tag">
|
||||
<el-tag type="primary" size="small">实发工资= 应发工资-应扣合计</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { Money, TrendCharts, Remove, Document, DataAnalysis, Wallet } from '@element-plus/icons-vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { queryUserInfo, queryExtendSalaryInfo, checkAuth } from '/@/api/professional/salaries/teachersalary'
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { Money, TrendCharts, Remove, Document, DataAnalysis, Wallet } from '@element-plus/icons-vue';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { queryUserInfo, queryExtendSalaryInfo, checkAuth } from '/@/api/professional/salaries/teachersalary';
|
||||
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
// 对话框显示状态
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 数据
|
||||
const salaryData = reactive({
|
||||
baseInfo: [] as any[]
|
||||
})
|
||||
baseInfo: [] as any[],
|
||||
});
|
||||
|
||||
const nowUser = ref<any>({})
|
||||
const baseLoading = ref(false)
|
||||
const salaryExtendData = ref<any[]>([])
|
||||
const allProjectData = ref<any[]>([])
|
||||
const nowUser = ref<any>({});
|
||||
const baseLoading = ref(false);
|
||||
const salaryExtendData = ref<any[]>([]);
|
||||
const allProjectData = ref<any[]>([]);
|
||||
const staticsData = reactive({
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0
|
||||
})
|
||||
const showAllContent = ref(false)
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0,
|
||||
});
|
||||
const showAllContent = ref(false);
|
||||
|
||||
// 检查权限
|
||||
const checkAuthMethod = async () => {
|
||||
try {
|
||||
const res = await checkAuth()
|
||||
showAllContent.value = res.data
|
||||
} catch (error) {
|
||||
// 检查权限失败
|
||||
}
|
||||
}
|
||||
try {
|
||||
const res = await checkAuth();
|
||||
showAllContent.value = res.data;
|
||||
} catch (error) {
|
||||
// 检查权限失败
|
||||
}
|
||||
};
|
||||
|
||||
// 构建用户信息
|
||||
const makeUserInfo = (data: any) => {
|
||||
const row = JSON.parse(JSON.stringify(data))
|
||||
salaryData.baseInfo = []
|
||||
row.realName = (row.realName == "" || row.realName == null ? row.userName : row.realName)
|
||||
salaryData.baseInfo.push(row)
|
||||
const row = JSON.parse(JSON.stringify(data));
|
||||
salaryData.baseInfo = [];
|
||||
row.realName = row.realName == '' || row.realName == null ? row.userName : row.realName;
|
||||
salaryData.baseInfo.push(row);
|
||||
|
||||
staticsData.shouldPay = row.shouldPay || 0
|
||||
staticsData.shouldDedu = row.withhold || 0
|
||||
staticsData.realWage = row.realWage || 0
|
||||
staticsData.personTax = (row.personalTax as number) || 0
|
||||
}
|
||||
staticsData.shouldPay = row.shouldPay || 0;
|
||||
staticsData.shouldDedu = row.withhold || 0;
|
||||
staticsData.realWage = row.realWage || 0;
|
||||
staticsData.personTax = (row.personalTax as number) || 0;
|
||||
};
|
||||
|
||||
// 查询扩展薪资信息
|
||||
const queryExtendSalaryInfoMethod = async (row: any) => {
|
||||
salaryExtendData.value = []
|
||||
const params = { nf: row.nf, yf: row.yf, teacherNo: row.teacherNo }
|
||||
try {
|
||||
const res = await queryExtendSalaryInfo(params)
|
||||
salaryExtendData.value.push(res.data.salaryTax)
|
||||
allProjectData.value = res.data.allProject
|
||||
staticsData.orderMoney = res.data.totalMoney
|
||||
} catch (error) {
|
||||
// 查询失败
|
||||
}
|
||||
}
|
||||
salaryExtendData.value = [];
|
||||
const params = { nf: row.nf, yf: row.yf, teacherNo: row.teacherNo };
|
||||
try {
|
||||
const res = await queryExtendSalaryInfo(params);
|
||||
salaryExtendData.value.push(res.data.salaryTax);
|
||||
allProjectData.value = res.data.allProject;
|
||||
staticsData.orderMoney = res.data.totalMoney;
|
||||
} catch (error) {
|
||||
// 查询失败
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索用户信息
|
||||
const searchUserInfo = async () => {
|
||||
if (!nowUser.value.idCard) {
|
||||
message.warning('请输入身份证号')
|
||||
return
|
||||
}
|
||||
if (!nowUser.value.nf) {
|
||||
message.warning('请选择年份')
|
||||
return
|
||||
}
|
||||
if (!nowUser.value.yff) {
|
||||
message.warning('请选择月份')
|
||||
return
|
||||
}
|
||||
if (!nowUser.value.idCard) {
|
||||
message.warning('请输入身份证号');
|
||||
return;
|
||||
}
|
||||
if (!nowUser.value.nf) {
|
||||
message.warning('请选择年份');
|
||||
return;
|
||||
}
|
||||
if (!nowUser.value.yff) {
|
||||
message.warning('请选择月份');
|
||||
return;
|
||||
}
|
||||
|
||||
baseLoading.value = true
|
||||
const data = { idCard: nowUser.value.idCard, nf: nowUser.value.nf, yf: nowUser.value.yff }
|
||||
try {
|
||||
const response = await queryUserInfo(data)
|
||||
if (response.data.data == null) {
|
||||
message.info('未查询到该时间段的数据')
|
||||
salaryData.baseInfo = []
|
||||
const obj: any = {}
|
||||
obj.realName = nowUser.value.realName
|
||||
obj.idCard = nowUser.value.idCard
|
||||
salaryData.baseInfo.push(obj)
|
||||
baseLoading.value = true;
|
||||
const data = { idCard: nowUser.value.idCard, nf: nowUser.value.nf, yf: nowUser.value.yff };
|
||||
try {
|
||||
const response = await queryUserInfo(data);
|
||||
if (response.data.data == null) {
|
||||
message.info('未查询到该时间段的数据');
|
||||
salaryData.baseInfo = [];
|
||||
const obj: any = {};
|
||||
obj.realName = nowUser.value.realName;
|
||||
obj.idCard = nowUser.value.idCard;
|
||||
salaryData.baseInfo.push(obj);
|
||||
|
||||
salaryExtendData.value = []
|
||||
Object.assign(staticsData, {
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0
|
||||
})
|
||||
} else {
|
||||
const resData = response.data.data
|
||||
resData.realName = nowUser.value.realName
|
||||
resData.nf = nowUser.value.nf
|
||||
resData.yf = nowUser.value.yff
|
||||
resData.teacherNo = nowUser.value.teacherNo
|
||||
makeUserInfo(resData)
|
||||
await queryExtendSalaryInfoMethod(resData)
|
||||
message.success('查询成功')
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
baseLoading.value = false
|
||||
}
|
||||
}
|
||||
salaryExtendData.value = [];
|
||||
Object.assign(staticsData, {
|
||||
shouldPay: 0,
|
||||
shouldDedu: 0,
|
||||
realWage: 0,
|
||||
orderMoney: 0,
|
||||
personTax: 0,
|
||||
});
|
||||
} else {
|
||||
const resData = response.data.data;
|
||||
resData.realName = nowUser.value.realName;
|
||||
resData.nf = nowUser.value.nf;
|
||||
resData.yf = nowUser.value.yff;
|
||||
resData.teacherNo = nowUser.value.teacherNo;
|
||||
makeUserInfo(resData);
|
||||
await queryExtendSalaryInfoMethod(resData);
|
||||
message.success('查询成功');
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
baseLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = (row: any) => {
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
checkAuthMethod()
|
||||
nowUser.value = JSON.parse(JSON.stringify(row))
|
||||
nowUser.value.yff = row.yf
|
||||
makeUserInfo(row)
|
||||
queryExtendSalaryInfoMethod(row)
|
||||
})
|
||||
}
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
checkAuthMethod();
|
||||
nowUser.value = JSON.parse(JSON.stringify(row));
|
||||
nowUser.value.yff = row.yf;
|
||||
makeUserInfo(row);
|
||||
queryExtendSalaryInfoMethod(row);
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
init,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 10px !important;
|
||||
max-height: calc(100vh - 120px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 10px !important;
|
||||
max-height: calc(100vh - 120px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.salary-info-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.base-info-section {
|
||||
padding: 12px 16px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ebeef5;
|
||||
padding: 12px 16px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.base-info-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.info-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
|
||||
.info-label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
.info-label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.info-value {
|
||||
color: #303133;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-left: auto;
|
||||
margin-bottom: 0;
|
||||
margin-left: auto;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
:deep(.el-card__header) {
|
||||
padding: 16px 20px;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
:deep(.el-card__header) {
|
||||
padding: 16px 20px;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 20px;
|
||||
}
|
||||
:deep(.el-card__body) {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 24px 0 12px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 24px 0 12px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
.el-icon {
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.salary-table {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
:deep(.el-table__header) {
|
||||
th {
|
||||
background: #f5f7fa;
|
||||
color: #606266;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
:deep(.el-table__header) {
|
||||
th {
|
||||
background: #f5f7fa;
|
||||
color: #606266;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__cell) {
|
||||
padding: 8px 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
:deep(.el-table__cell) {
|
||||
padding: 8px 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.summary-table {
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
:deep(.el-table__body) {
|
||||
td {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.formula-tag {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
|
||||
.el-tag {
|
||||
margin-right: 8px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
.el-tag {
|
||||
margin-right: 8px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式优化
|
||||
@media (max-width: 1400px) {
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog) {
|
||||
width: 98% !important;
|
||||
}
|
||||
}
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog) {
|
||||
width: 98% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条优化
|
||||
.salary-info-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,239 +1,198 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%;">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_typeofworkconfig_add')"
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="handleAdd">新 增
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb15" style="width: 100%">
|
||||
<el-button v-if="hasAuth('professional_typeofworkconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<el-table-column prop="workTitle" label="工种名字" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="hasAuth('professional_typeofworkconfig_edit')"
|
||||
icon="edit-pen"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_typeofworkconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
row-key="id"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-bind="state.pagination"
|
||||
@current-change="currentChangeHandle"
|
||||
@size-change="sizeChangeHandle"
|
||||
/>
|
||||
<el-table-column prop="workTitle" label="工种名字" min-width="150" align="center" show-overflow-tooltip />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.id ? '修改' : '新增'"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="工种名字" prop="workTitle">
|
||||
<el-input
|
||||
v-model="form.workTitle"
|
||||
placeholder="请输入工种名字"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" align="center" />
|
||||
|
||||
<el-table-column prop="sort" label="排序" width="100" align="center" />
|
||||
|
||||
<el-table-column prop="remarks" label="备注" min-width="200" align="center" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button v-if="hasAuth('professional_typeofworkconfig_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('professional_typeofworkconfig_del')"
|
||||
icon="delete"
|
||||
link
|
||||
type="danger"
|
||||
style="margin-left: 12px"
|
||||
@click="handleDel(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||
<el-form-item label="工种名字" prop="workTitle">
|
||||
<el-input v-model="form.workTitle" placeholder="请输入工种名字" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { useAuth } from '/@/hooks/auth'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { useMessageBox } from '/@/hooks/message'
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/typeofworkconfig'
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { useMessageBox } from '/@/hooks/message';
|
||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/typeofworkconfig';
|
||||
|
||||
// 无权限即无节点
|
||||
const { hasAuth } = useAuth()
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
// 消息提示 hooks
|
||||
const message = useMessage()
|
||||
const messageBox = useMessageBox()
|
||||
const message = useMessage();
|
||||
const messageBox = useMessageBox();
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref()
|
||||
const formRef = ref()
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
|
||||
// 弹窗状态
|
||||
const dialogVisible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const dialogVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
workTitle: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
id: '',
|
||||
workTitle: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
workTitle: [
|
||||
{ required: true, message: '请输入工种名字', trigger: 'blur' }
|
||||
],
|
||||
sort: [
|
||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
workTitle: [{ required: true, message: '请输入工种名字', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params)
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0
|
||||
}
|
||||
}
|
||||
},
|
||||
queryForm: {}
|
||||
})
|
||||
pageList: async (params: any) => {
|
||||
const response = await fetchList(params);
|
||||
return {
|
||||
data: {
|
||||
records: response.data.records || [],
|
||||
total: response.data.total || 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
queryForm: {},
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
// 打开新增窗口
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
workTitle: '',
|
||||
sort: 0,
|
||||
remarks: ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
workTitle: '',
|
||||
sort: 0,
|
||||
remarks: '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 打开编辑窗口
|
||||
const handleEdit = async (row: any) => {
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
workTitle: row.workTitle || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || ''
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
workTitle: row.workTitle || '',
|
||||
sort: row.sort || 0,
|
||||
remarks: row.remarks || '',
|
||||
});
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDel = (row: any) => {
|
||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
||||
await delObj(row.id)
|
||||
message.success('删除成功')
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1
|
||||
}
|
||||
getDataList()
|
||||
}).catch(() => {})
|
||||
}
|
||||
messageBox
|
||||
.confirm('是否确认删除该条记录')
|
||||
.then(async () => {
|
||||
await delObj(row.id);
|
||||
message.success('删除成功');
|
||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||
state.pagination.current = state.pagination.current - 1;
|
||||
}
|
||||
getDataList();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form)
|
||||
message.success('修改成功')
|
||||
} else {
|
||||
await addObj(form)
|
||||
message.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
if (form.id) {
|
||||
await putObj(form);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await addObj(form);
|
||||
message.success('添加成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
getDataList();
|
||||
} catch (error: any) {
|
||||
// 处理业务错误
|
||||
// 错误处理已在数据请求层统一处理,此处不需要提示
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user