872 lines
25 KiB
Vue
Executable File
872 lines
25 KiB
Vue
Executable File
<template>
|
||
<div class="layout-padding">
|
||
<div class="layout-padding-auto layout-padding-view">
|
||
<!-- 搜索表单 -->
|
||
<el-row shadow="hover" v-show="showSearch" class="ml10">
|
||
<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="请选择班级"
|
||
style="width: 200px"
|
||
>
|
||
<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
|
||
style="width: 200px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="姓名" prop="realName">
|
||
<el-input
|
||
v-model="state.queryForm.realName"
|
||
placeholder="请输入姓名"
|
||
clearable
|
||
style="width: 200px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="身份证" prop="idCard">
|
||
<el-input
|
||
v-model="state.queryForm.idCard"
|
||
placeholder="请输入身份证"
|
||
clearable
|
||
style="width: 200px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="手机" prop="mobile">
|
||
<el-input
|
||
v-model="state.queryForm.mobile"
|
||
placeholder="请输入手机"
|
||
clearable
|
||
style="width: 200px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="允许进出" prop="inoutFlag">
|
||
<el-select
|
||
v-model="state.queryForm.inoutFlag"
|
||
clearable
|
||
placeholder="请选择"
|
||
style="width: 200px"
|
||
>
|
||
<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 icon="search" type="primary" @click="handleFilter">查询</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
|
||
type="primary"
|
||
icon="FolderAdd"
|
||
@click="handleAdd"
|
||
v-if="permissions.professional_outercompanyemployee_add">新 增
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
@click="handleExportIn"
|
||
v-if="permission.scope == '1'"
|
||
>导 入
|
||
</el-button>
|
||
<el-button
|
||
type="warning"
|
||
@click="handleExportScore"
|
||
:loading="exportLoading"
|
||
icon="Download">导出
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
@click="batchDelect">批量删除
|
||
</el-button>
|
||
<right-toolbar
|
||
v-model:showSearch="showSearch"
|
||
class="ml10"
|
||
style="float: right; margin-right: 20px"
|
||
@queryTable="getDataList"
|
||
></right-toolbar>
|
||
</div>
|
||
</el-row>
|
||
|
||
<!-- 表格 -->
|
||
<el-table
|
||
ref="tableRef"
|
||
:data="state.dataList"
|
||
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">{{ 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">
|
||
<img
|
||
width="50px"
|
||
height="50px"
|
||
@click="handlePictureCardPreview(scope.row.employeeNo)"
|
||
:src="getImageView(scope.row.employeeNo)"
|
||
@error="handleImageError"
|
||
style="cursor: pointer; object-fit: cover; border-radius: 4px;"
|
||
/>
|
||
</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="permissions.professional_outercompanyemployee_edit"
|
||
icon="edit-pen"
|
||
link
|
||
type="primary"
|
||
@click="handleEdit(scope.row)">修改
|
||
</el-button>
|
||
<el-button
|
||
v-if="permissions.professional_outercompanyemployee_reset_pw"
|
||
icon="RefreshLeft"
|
||
link
|
||
type="primary"
|
||
style="margin-left: 12px"
|
||
@click="resetPassword(scope.row)">重置密码
|
||
</el-button>
|
||
<el-button
|
||
v-if="permissions.professional_outercompanyemployee_del"
|
||
icon="delete"
|
||
link
|
||
type="primary"
|
||
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-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="班级名称" prop="companyId">
|
||
<el-select
|
||
v-model="form.companyId"
|
||
filterable
|
||
clearable
|
||
placeholder="请选择班级"
|
||
style="width: 100%"
|
||
>
|
||
<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="form.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="form.realName"
|
||
placeholder="请输入姓名"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="身份证" prop="idCard">
|
||
<el-input
|
||
v-model="form.idCard"
|
||
placeholder="请输入身份证号"
|
||
clearable
|
||
/>
|
||
</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="form.mobile"
|
||
placeholder="请输入手机号"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="允许进出" prop="inoutFlag">
|
||
<el-select
|
||
v-model="form.inoutFlag"
|
||
clearable
|
||
placeholder="请选择"
|
||
style="width: 100%"
|
||
>
|
||
<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="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>
|
||
|
||
<!-- 头像预览对话框 -->
|
||
<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="dialogAvatarVisible" title="上传头像" width="50%" append-to-body>
|
||
<el-upload
|
||
action="/basic/basicstudent/uploadAvatarBase64"
|
||
list-type="picture-card"
|
||
name="file"
|
||
:headers="headers"
|
||
:limit="1"
|
||
:data="uploadData"
|
||
:file-list="fileList"
|
||
:before-upload="beforeUpload"
|
||
:on-remove="removeHandler"
|
||
:http-request="httpRequest"
|
||
:on-success="uploadSuccess"
|
||
>
|
||
<el-icon><Plus /></el-icon>
|
||
<template #tip>
|
||
<div class="el-upload__tip">上传头像,人脸识别用</div>
|
||
</template>
|
||
</el-upload>
|
||
</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>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, reactive, computed, onMounted } from 'vue'
|
||
import { storeToRefs } from 'pinia'
|
||
import { useUserInfo } from '/@/stores/userInfo'
|
||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||
import { useMessage } from '/@/hooks/message'
|
||
import { useMessageBox } from '/@/hooks/message'
|
||
import { useDict } from '/@/hooks/dict'
|
||
import { Session } from '/@/utils/storage'
|
||
import { validateNull } from '/@/utils/validate'
|
||
import axios from 'axios'
|
||
import request from '/@/utils/request'
|
||
import { Plus } from '@element-plus/icons-vue'
|
||
import { ElMessageBox } from 'element-plus'
|
||
import {
|
||
fetchList,
|
||
getObj,
|
||
saveSecond,
|
||
putObj,
|
||
delObj,
|
||
batchDel,
|
||
resetPassWord
|
||
} from '/@/api/professional/stayschool/outercompanyemployee'
|
||
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany'
|
||
|
||
// 使用 Pinia store
|
||
const userInfoStore = useUserInfo()
|
||
const { userInfos } = storeToRefs(userInfoStore)
|
||
|
||
// 创建权限对象
|
||
const permissions = computed(() => {
|
||
const perms: Record<string, boolean> = {}
|
||
userInfos.value.authBtnList.forEach((perm: string) => {
|
||
perms[perm] = true
|
||
})
|
||
return perms
|
||
})
|
||
|
||
// 消息提示 hooks
|
||
const message = useMessage()
|
||
const messageBox = useMessageBox()
|
||
|
||
// 字典数据
|
||
const { yes_no: yesNoDict } = useDict('yes_no')
|
||
|
||
// 获取字典标签的辅助函数
|
||
const getDictLabel = (value: string | number) => {
|
||
const item = yesNoDict.value.find((i: any) => i.value === value)
|
||
return item ? item.label : ''
|
||
}
|
||
|
||
// 表格引用
|
||
const tableRef = ref()
|
||
const formRef = ref()
|
||
const queryRef = ref()
|
||
const uploadFormRef = ref()
|
||
|
||
// 搜索显示
|
||
const showSearch = ref(true)
|
||
|
||
// 弹窗状态
|
||
const dialogVisible = ref(false)
|
||
const dialogUploadVisible = ref(false)
|
||
const dialogAvatarVisible = ref(false)
|
||
const dialogViewVisible = ref(false)
|
||
const submitLoading = ref(false)
|
||
const exportLoading = ref(false)
|
||
|
||
// 选中的行数据
|
||
const selectList = ref<any[]>([])
|
||
const permission = reactive({
|
||
hasPermission: "0",
|
||
scope: "0"
|
||
})
|
||
|
||
// 单位列表
|
||
const companyList = ref<any[]>([])
|
||
|
||
// 表单数据
|
||
const form = reactive({
|
||
id: '',
|
||
companyId: '',
|
||
companyName: '',
|
||
employeeNo: '',
|
||
realName: '',
|
||
idCard: '',
|
||
mobile: '',
|
||
inoutFlag: '',
|
||
remarks: ''
|
||
})
|
||
|
||
// 表单验证规则 - 培训单位没有必填验证
|
||
const formRules = {
|
||
companyId: [
|
||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||
]
|
||
}
|
||
|
||
// 头像相关
|
||
const dialogImageUrl = ref('')
|
||
const fileList = ref<any[]>([])
|
||
const rowData = ref<any>({})
|
||
const fileReader = ref<FileReader | null>(null)
|
||
|
||
// 上传相关
|
||
const uploadData = reactive({
|
||
bucketName: "base",
|
||
module: "basic",
|
||
username: ""
|
||
})
|
||
|
||
// 导入相关
|
||
const fileName = ref('')
|
||
const filesList = ref<any[]>([])
|
||
let files: File | null = null
|
||
|
||
// 请求头
|
||
const headers = computed(() => {
|
||
return {
|
||
"Authorization": 'Bearer ' + Session.getToken()
|
||
}
|
||
})
|
||
|
||
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||
pageList: async (params: any) => {
|
||
const response = await fetchList({
|
||
...params,
|
||
companyType: '1' // 培训单位
|
||
})
|
||
// 特殊处理: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 loadCompanyList = async () => {
|
||
try {
|
||
const response = await getCompanyList({ companyType: '1' })
|
||
companyList.value = response.data || []
|
||
} catch (error) {
|
||
// 获取单位列表失败
|
||
}
|
||
}
|
||
|
||
// 重置查询
|
||
const resetQuery = () => {
|
||
queryRef.value?.resetFields()
|
||
getDataList()
|
||
}
|
||
|
||
// 处理搜索
|
||
const handleFilter = () => {
|
||
getDataList()
|
||
}
|
||
|
||
// 多选变化
|
||
const handleSelectionChange = (selection: any[]) => {
|
||
selectList.value = selection
|
||
}
|
||
|
||
// 打开新增窗口
|
||
const handleAdd = () => {
|
||
Object.assign(form, {
|
||
id: '',
|
||
companyId: '',
|
||
companyName: '',
|
||
employeeNo: '',
|
||
realName: '',
|
||
idCard: '',
|
||
mobile: '',
|
||
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 || '',
|
||
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(() => {})
|
||
}
|
||
|
||
// 批量删除
|
||
const batchDelect = () => {
|
||
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?.data
|
||
if (!validateNull(pw)) {
|
||
ElMessageBox.alert('重置后密码为: ' + pw, '重置密码')
|
||
} else {
|
||
ElMessageBox.alert('系统繁忙,请重试', '重置密码')
|
||
}
|
||
} catch (error) {
|
||
// 重置密码失败
|
||
}
|
||
}).catch(() => {})
|
||
}
|
||
|
||
// 提交表单
|
||
const handleSubmit = async () => {
|
||
if (!formRef.value) return
|
||
|
||
await formRef.value.validate(async (valid: boolean) => {
|
||
if (valid) {
|
||
submitLoading.value = true
|
||
try {
|
||
// 设置单位名称
|
||
const selectedCompany = companyList.value.find(item => item.id === form.companyId)
|
||
if (selectedCompany) {
|
||
form.companyName = selectedCompany.companyName
|
||
}
|
||
|
||
if (form.id) {
|
||
await putObj(form)
|
||
message.success('修改成功')
|
||
} else {
|
||
await saveSecond(form) // 使用 saveSecond API
|
||
message.success('添加成功')
|
||
}
|
||
dialogVisible.value = false
|
||
getDataList()
|
||
} catch (error: any) {
|
||
message.error(error?.msg || '操作失败')
|
||
} finally {
|
||
submitLoading.value = false
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 获取图片 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 handleImageError = (event: Event) => {
|
||
const img = event.target as HTMLImageElement
|
||
img.src = '/img/default/no_pic.png'
|
||
}
|
||
|
||
// 预览头像
|
||
const handlePictureCardPreview = (employeeNo: string) => {
|
||
dialogImageUrl.value = getImageView(employeeNo)
|
||
dialogUploadVisible.value = true
|
||
}
|
||
|
||
// 上传前验证
|
||
const beforeUpload = (file: File) => {
|
||
const isLt5M = file.size < 1 * 1024 * 1024
|
||
if (fileList.value.length >= 1) {
|
||
message.warning('只能上传一张头像')
|
||
return false
|
||
}
|
||
if (!isLt5M) {
|
||
message.warning('文件大小不能超过1M')
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
// 自定义上传
|
||
const httpRequest = (options: any) => {
|
||
const file = options.file
|
||
if (!fileReader.value) {
|
||
fileReader.value = new FileReader()
|
||
}
|
||
|
||
if (file) {
|
||
fileReader.value.readAsDataURL(file)
|
||
}
|
||
|
||
fileReader.value.onload = () => {
|
||
const base64Str = fileReader.value?.result as string
|
||
|
||
const config = {
|
||
url: '/basic/basicstudent/uploadAvatarBase64',
|
||
method: 'post',
|
||
data: {
|
||
base64Str: base64Str.split(',')[1],
|
||
username: rowData.value.employeeNo
|
||
},
|
||
timeout: 10000,
|
||
onUploadProgress: (progressEvent: any) => {
|
||
progressEvent.percent = progressEvent.loaded / progressEvent.total * 100
|
||
options.onProgress(progressEvent, file)
|
||
}
|
||
}
|
||
|
||
axios(config)
|
||
.then(res => {
|
||
options.onSuccess(res, file)
|
||
getDataList()
|
||
})
|
||
.catch(err => {
|
||
options.onError(err)
|
||
})
|
||
}
|
||
}
|
||
|
||
// 移除文件
|
||
const removeHandler = (file: any) => {
|
||
const index = fileList.value.findIndex(f => f.uid === file.uid)
|
||
if (index !== -1) {
|
||
fileList.value.splice(index, 1)
|
||
}
|
||
}
|
||
|
||
// 上传成功
|
||
const uploadSuccess = (res: any, file: any) => {
|
||
if (res.data) {
|
||
const data = res.data
|
||
file.key = data.key
|
||
fileList.value.push(file)
|
||
message.success('上传成功')
|
||
dialogAvatarVisible.value = false
|
||
getDataList()
|
||
}
|
||
}
|
||
|
||
// 导入
|
||
const handleExportIn = () => {
|
||
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 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=1`,
|
||
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: "1"
|
||
}
|
||
|
||
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(() => {
|
||
if (!window.FileReader) {
|
||
// eslint-disable-next-line no-console
|
||
console.error('Your browser does not support FileReader API!')
|
||
} else {
|
||
fileReader.value = new FileReader()
|
||
}
|
||
loadCompanyList()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.upload-container {
|
||
:deep(.el-upload) {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|