Merge branch 'developer' of ssh://code.cyweb.top:30033/scj/zhxy/v3/cloud-ui into developer

This commit is contained in:
吴红兵
2026-02-05 23:12:07 +08:00
7 changed files with 224 additions and 1 deletions

View File

@@ -0,0 +1,116 @@
<template>
<el-dialog v-model="visible" :title="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">
<el-button type="success" :icon="Download" @click="handleDownloadTemplate">下载模板</el-button>
</div>
<el-upload
class="upload-demo"
:action="uploadUrl"
: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 } from 'vue';
import { ElNotification } from 'element-plus';
import { Download, UploadFilled } from '@element-plus/icons-vue';
import { Session } from '/@/utils/storage';
import { downBlobFile } from '/@/utils/other';
const title = ref('');
// 响应式数据
const visible = ref(false);
// 计算属性
const headers = computed(() => {
return {
Authorization: 'Bearer ' + Session.getToken(),
TENANT_ID: Session.getTenant()
};
});
const uploadUrl = ref('')
const currentType = ref('')
const titleMap: Record<string, string> = {
titleRelation: '职称信息导入',
quaRelation: '职业资格信息导入',
cerRelation: '教师资格证信息导入',
eduDegree: '学历学位信息导入',
partyChange: '党组织变动信息导入',
honor: '综合表彰信息导入'
}
// 方法
const init = (type: any) => {
currentType.value = type
uploadUrl.value = '/professional/file/importTeacherOtherInfo?type=' + type
title.value = titleMap[type] || '信息导入'
visible.value = true
}
// Emits
const emit = defineEmits<{
(e: 'refreshData'): void
}>()
const handleUploadSuccess = () => {
visible.value = false;
ElNotification({
title: '成功',
message: '导入成功',
type: 'success',
});
emit('refreshData')
};
const handleAvatarError = (err: any) => {
const result = JSON.parse(err.message);
if (result.code == '1') {
ElNotification.error({
title: '错误',
message: result.msg,
duration: 30000,
});
}
};
const handleDownloadTemplate = () => {
downBlobFile('/professional/file/exportTeacherInfoTemplate', { type: currentType.value || 'titleRelation' }, '职工信息导入模板.xlsx')
}
// 暴露方法给父组件
defineExpose({
init,
});
</script>
<style scoped lang="scss">
.upload-demo {
:deep(.el-upload-dragger) {
width: 100%;
}
}
</style>

View File

@@ -37,6 +37,20 @@
</template> </template>
</search-form> </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-table <el-table
ref="tableRef" ref="tableRef"
@@ -77,6 +91,9 @@
@current-change="currentChangeHandle" @current-change="currentChangeHandle"
@size-change="sizeChangeHandle" @size-change="sizeChangeHandle"
/> />
<!-- 子组件 -->
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
</div> </div>
</div> </div>
</template> </template>
@@ -88,6 +105,7 @@ import { BasicTableProps, useTable } from '/@/hooks/table'
import { fetchList } from '/@/api/professional/professionaluser/professionalpartychange' import { fetchList } from '/@/api/professional/professionaluser/professionalpartychange'
const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.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 tableRef = ref()
@@ -100,6 +118,10 @@ const search = reactive({
realName: '' realName: ''
}) })
// 导入加载状态
const exportLoading = ref(false)
const importTeacherOtherInfoRef = ref()
// 配置 useTable // 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({ const state: BasicTableProps = reactive<BasicTableProps>({
pageList: async (params: any) => { pageList: async (params: any) => {
@@ -130,6 +152,11 @@ const resetQuery = () => {
getDataList() getDataList()
} }
// 打开导入弹窗
const handleImportDialog = () => {
importTeacherOtherInfoRef.value?.init('partyChange')
}
// 表格数据由 useTablecreatedIsNeed 默认 true在挂载时自动请求 // 表格数据由 useTablecreatedIsNeed 默认 true在挂载时自动请求
</script> </script>

View File

@@ -73,6 +73,14 @@
@click="handleDownLoadWord" @click="handleDownLoadWord"
:loading="exportLoading" :loading="exportLoading"
>导出信息</el-button> >导出信息</el-button>
<el-button
v-auth="'professional_teacherinfo_import'"
type="primary"
plain
icon="UploadFilled"
:loading="exportLoading"
@click="handleImportDialog"
>导入信息</el-button>
</div> </div>
<div class="header-right"> <div class="header-right">
<RightToolbar <RightToolbar
@@ -207,6 +215,7 @@
<!-- 子组件 --> <!-- 子组件 -->
<DataForm ref="dataFormRef" @refreshData="handleFilter" /> <DataForm ref="dataFormRef" @refreshData="handleFilter" />
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" /> <ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
</div> </div>
</template> </template>
@@ -234,6 +243,7 @@ const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/i
const DataForm = defineAsyncComponent(() => import('./form.vue')) const DataForm = defineAsyncComponent(() => import('./form.vue'))
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.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
@@ -265,8 +275,9 @@ const search = reactive({
// 材料预览 // 材料预览
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 importTeacherOtherInfoRef = ref()
// 资格等级和工种列表 // 资格等级和工种列表
const qualificationLevelList = ref<any[]>([]) const qualificationLevelList = ref<any[]>([])
@@ -414,6 +425,11 @@ const getWorkTypeName = (id: string | number) => {
return item ? item.workName : '-' return item ? item.workName : '-'
} }
// 打开导入弹窗
const handleImportDialog = () => {
importTeacherOtherInfoRef.value?.init('quaRelation')
}
// 加载字典数据 // 加载字典数据
const loadDictData = async () => { const loadDictData = async () => {
try { try {

View File

@@ -69,6 +69,14 @@
@click="handleDownLoadWord" @click="handleDownLoadWord"
:loading="exportLoading">导出信息 :loading="exportLoading">导出信息
</el-button> </el-button>
<el-button
v-auth="'professional_teacherinfo_import'"
type="primary"
plain
icon="UploadFilled"
:loading="exportLoading"
@click="handleImportDialog">导入信息
</el-button>
</div> </div>
</el-row> </el-row>
@@ -218,6 +226,7 @@
<!-- 子组件 --> <!-- 子组件 -->
<DataForm ref="dataFormRef" @refreshData="handleFilter" /> <DataForm ref="dataFormRef" @refreshData="handleFilter" />
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" /> <ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
</div> </div>
</div> </div>
</template> </template>
@@ -245,6 +254,7 @@ const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/i
const DataForm = defineAsyncComponent(() => import('./form.vue')) const DataForm = defineAsyncComponent(() => import('./form.vue'))
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.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
@@ -279,6 +289,7 @@ const imgUrl = ref<Array<{ title: string; url: string }>>([])
// 导出加载状态 // 导出加载状态
const exportLoading = ref(false) const exportLoading = ref(false)
const importTeacherOtherInfoRef = ref()
// 学位、学历和教育类型列表 // 学位、学历和教育类型列表
const degreeList = ref<any[]>([]) const degreeList = ref<any[]>([])
@@ -442,6 +453,11 @@ const getEducationTypeName = (id: string | number | undefined) => {
return item ? item.name : '-' return item ? item.name : '-'
} }
// 打开导入弹窗
const handleImportDialog = () => {
importTeacherOtherInfoRef.value?.init('eduDegree')
}
// 加载字典数据 // 加载字典数据
const loadDictData = async () => { const loadDictData = async () => {
try { try {

View File

@@ -69,6 +69,14 @@
@click="handleDownLoadWord" @click="handleDownLoadWord"
:loading="exportLoading">导出信息 :loading="exportLoading">导出信息
</el-button> </el-button>
<el-button
v-auth="'professional_teacherinfo_import'"
type="primary"
plain
icon="UploadFilled"
:loading="exportLoading"
@click="handleImportDialog">导入信息
</el-button>
</div> </div>
</el-row> </el-row>
@@ -188,6 +196,7 @@
<!-- 子组件 --> <!-- 子组件 -->
<DataForm ref="dataFormRef" @refreshData="handleFilter" /> <DataForm ref="dataFormRef" @refreshData="handleFilter" />
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" /> <ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
</div> </div>
</div> </div>
</template> </template>
@@ -213,6 +222,7 @@ const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/i
const DataForm = defineAsyncComponent(() => import('./form.vue')) const DataForm = defineAsyncComponent(() => import('./form.vue'))
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.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' import type { StateOption } from '/@/components/AuditState/index.vue'
@@ -247,6 +257,7 @@ const imgUrl = ref<Array<{ title: string; url: string }>>([])
// 导出加载状态 // 导出加载状态
const exportLoading = ref(false) const exportLoading = ref(false)
const importTeacherOtherInfoRef = ref()
// 证书列表 // 证书列表
const certificateList = ref<any[]>([]) const certificateList = ref<any[]>([])
@@ -385,6 +396,11 @@ const getCertificateName = (id: string | number) => {
return item ? item.cretificateName : '-' return item ? item.cretificateName : '-'
} }
// 打开导入弹窗
const handleImportDialog = () => {
importTeacherOtherInfoRef.value?.init('cerRelation')
}
// 加载字典数据 // 加载字典数据
const loadDictData = async () => { const loadDictData = async () => {
try { try {

View File

@@ -68,6 +68,14 @@
@click="handleDownLoadWord" @click="handleDownLoadWord"
:loading="exportLoading">导出信息 :loading="exportLoading">导出信息
</el-button> </el-button>
<el-button
v-auth="'professional_teacherinfo_import'"
type="primary"
plain
icon="UploadFilled"
:loading="exportLoading"
@click="handleImportDialog">导入信息
</el-button>
</div> </div>
</el-row> </el-row>
@@ -216,6 +224,7 @@
<!-- 子组件 --> <!-- 子组件 -->
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" /> <ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
<DataForm ref="dataFormRef" @refreshData="handleFilter" /> <DataForm ref="dataFormRef" @refreshData="handleFilter" />
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter" />
</div> </div>
</div> </div>
</template> </template>
@@ -241,6 +250,7 @@ const DetailPopover = defineAsyncComponent(() => import('/@/components/DetailPop
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
const DataForm = defineAsyncComponent(() => import('./form.vue')) const DataForm = defineAsyncComponent(() => import('./form.vue'))
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue')) const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
// 消息提示 hooks // 消息提示 hooks
const message = useMessage() const message = useMessage()
@@ -281,6 +291,7 @@ const imgUrl = ref<Array<{ title: string; url: string }>>([])
// 导出加载状态 // 导出加载状态
const exportLoading = ref(false) const exportLoading = ref(false)
const importTeacherOtherInfoRef = ref()
// 配置 useTable // 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({ const state: BasicTableProps = reactive<BasicTableProps>({
@@ -407,6 +418,11 @@ const handleDownLoadWord = async () => {
} }
} }
// 打开导入弹窗
const handleImportDialog = () => {
importTeacherOtherInfoRef.value?.init('honor')
}
// 表格数据由 useTablecreatedIsNeed 默认 true在挂载时自动请求 // 表格数据由 useTablecreatedIsNeed 默认 true在挂载时自动请求
</script> </script>

View File

@@ -104,6 +104,14 @@
@click="handleDownLoadWord" @click="handleDownLoadWord"
:loading="exportLoading" :loading="exportLoading"
>导出信息</el-button> >导出信息</el-button>
<el-button
v-auth="'professional_teacherinfo_import'"
type="primary"
plain
icon="UploadFilled"
:loading="exportLoading"
@click="handleImportDialog">导入信息
</el-button>
</div> </div>
<div class="header-right"> <div class="header-right">
<RightToolbar <RightToolbar
@@ -238,6 +246,8 @@
<MultiDialog ref="multiDialogRef" @getList="getDataList" :page="state.pagination" :nowRow="null" /> <MultiDialog ref="multiDialogRef" @getList="getDataList" :page="state.pagination" :nowRow="null" />
<DataForm ref="dataFormRef" @refreshData="handleFilter" /> <DataForm ref="dataFormRef" @refreshData="handleFilter" />
<ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" /> <ProfessionalBackResaon ref="backReasonRef" @refreshData="handleFilter" />
<import-teacher-other-info ref="importTeacherOtherInfoRef" @refreshData="handleFilter"></import-teacher-other-info>
</div> </div>
</template> </template>
@@ -265,6 +275,7 @@ const MultiDialog = defineAsyncComponent(() => import('/@/views/professional/tea
const DataForm = defineAsyncComponent(() => import('./form.vue')) const DataForm = defineAsyncComponent(() => import('./form.vue'))
const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue'))
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue')) const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'))
const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue'))
// 无权限即无节点:使用 useAuth + v-if // 无权限即无节点:使用 useAuth + v-if
const { hasAuth } = useAuth() const { hasAuth } = useAuth()
@@ -462,6 +473,11 @@ const loadDictData = async () => {
} }
} }
const importTeacherOtherInfoRef=ref()
const handleImportDialog = () => {
importTeacherOtherInfoRef.value?.init('titleRelation')
}
// 初始化:仅加载下拉字典,表格数据由 useTable 在 createdIsNeed: true 时自动请求 // 初始化:仅加载下拉字典,表格数据由 useTable 在 createdIsNeed: true 时自动请求
onMounted(async () => { onMounted(async () => {
await loadDictData() await loadDictData()