|
@@ -1,6 +1,6 @@
|
|
|
<template>
|
|
|
+ <!-- 搜索工作栏 -->
|
|
|
<ContentWrap>
|
|
|
- <!-- 搜索工作栏 -->
|
|
|
<el-form
|
|
|
class="-mb-15px"
|
|
|
:model="queryParams"
|
|
@@ -8,8 +8,25 @@
|
|
|
:inline="true"
|
|
|
label-width="68px"
|
|
|
>
|
|
|
- <el-form-item label="名称" prop="name">
|
|
|
- <el-input v-model="queryParams.name" placeholder="请输入名称" clearable @keyup.enter="handleQuery" class="!w-180px" />
|
|
|
+ <el-form-item label="任务类型" prop="task_type">
|
|
|
+ <el-select
|
|
|
+ v-model="queryParams.task_type"
|
|
|
+ placeholder="请选择类型"
|
|
|
+ clearable
|
|
|
+ class="!w-200px"
|
|
|
+ >
|
|
|
+ <el-option v-for="(val, index) in taskType" :label="val.label" :value="val.value" :key="index" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="任务状态" prop="task_status">
|
|
|
+ <el-select
|
|
|
+ v-model="queryParams.task_status"
|
|
|
+ placeholder="请选择状态"
|
|
|
+ clearable
|
|
|
+ class="!w-200px"
|
|
|
+ >
|
|
|
+ <el-option v-for="(val, index) in taskStatus" :label="val" :value="val" :key="index" />
|
|
|
+ </el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
<el-button @click="handleQuery('search')"><Icon icon="ep:search" /> 搜索</el-button>
|
|
@@ -24,240 +41,127 @@
|
|
|
<!-- 列表 -->
|
|
|
<ContentWrap>
|
|
|
<el-table v-loading="loading" :data="list" :stripe="true">
|
|
|
- <el-table-column label="中文名称" align="center" prop="name_zh" fixed="left" />
|
|
|
- <el-table-column label="英文名称" align="center" prop="name_en" />
|
|
|
- <el-table-column label="职位" align="center" prop="title_zh" />
|
|
|
- <el-table-column label="酒店/公司" align="center" prop="hotel_zh" />
|
|
|
- <el-table-column label="手机号码" align="center" prop="mobile" />
|
|
|
- <el-table-column label="固定电话" align="center" prop="phone" />
|
|
|
- <el-table-column label="状态" align="center" prop="status" width="80">
|
|
|
- <template #default="scope">
|
|
|
- <el-tag type="success" v-if="scope.row.status === 'active'">已启用</el-tag>
|
|
|
- <el-tag type="danger" v-else>已禁用</el-tag>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="创建日期" align="center" prop="created_at" :formatter="dateFormatter" />
|
|
|
+ <el-table-column label="任务名称" align="center" prop="task_name" />
|
|
|
+ <el-table-column label="任务类型" align="center" prop="task_type" />
|
|
|
+ <el-table-column label="任务状态" align="center" prop="task_status" />
|
|
|
+ <el-table-column label="创建时间" align="center" prop="created_at" :formatter="dateFormatter" />
|
|
|
+ <el-table-column label="更新时间" align="center" prop="updated_at" :formatter="dateFormatter" />
|
|
|
<el-table-column label="操作" align="center" fixed="right" min-width="110">
|
|
|
<template #default="scope">
|
|
|
- <!-- <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button> -->
|
|
|
- <el-button link type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
|
|
|
- <el-button link :type="scope.row.status === 'active' ? 'warning': 'success'" @click="handleDisable(scope.row)">
|
|
|
- {{ scope.row.status === 'active' ? '禁用' : '启用'}}
|
|
|
- </el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.task_status === '待解析'"
|
|
|
+ link
|
|
|
+ type="success"
|
|
|
+ >解析</el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.parse_result"
|
|
|
+ link
|
|
|
+ type="primary"
|
|
|
+ @click="handleStore(scope.row)"
|
|
|
+ >入库</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
+ <!-- 分页 -->
|
|
|
+ <Pagination
|
|
|
+ :total="total"
|
|
|
+ v-model:page="queryParams.page"
|
|
|
+ v-model:limit="queryParams.per_page"
|
|
|
+ @pagination="getList"
|
|
|
+ />
|
|
|
+ </ContentWrap>
|
|
|
|
|
|
- <!-- 选择来源 -->
|
|
|
- <Dialog title="新增" v-model="openSelect" width="550" @close="openSelect = false">
|
|
|
- <el-radio-group v-model="radioValue" size="large" class="radioBox">
|
|
|
- <el-radio
|
|
|
- v-for="item in radioList"
|
|
|
- :key="item.value"
|
|
|
- :value="item.value"
|
|
|
- >
|
|
|
- {{ item.label }}
|
|
|
- </el-radio>
|
|
|
- </el-radio-group>
|
|
|
- <template #footer>
|
|
|
- <el-button type="primary" @click="handleSelect">确 认</el-button>
|
|
|
- <el-button @click="openSelect = false">取 消</el-button>
|
|
|
- </template>
|
|
|
- </Dialog>
|
|
|
-
|
|
|
- <!-- 人员搜索 -->
|
|
|
- <Dialog :title="radioObject.menduner" v-model="openSearch" :modalClose="false" width="1200" @close="openSearch = false">
|
|
|
- <Search ref="SearchRef" />
|
|
|
- <template #footer>
|
|
|
- <el-button type="primary" @click="handleSubmit">确 认</el-button>
|
|
|
- <el-button @click="openSearch = false">取 消</el-button>
|
|
|
- </template>
|
|
|
- </Dialog>
|
|
|
+ <!-- 选择来源 -->
|
|
|
+ <Dialog title="新增" v-model="openSelect" width="550" @close="openSelect = false">
|
|
|
+ <el-radio-group v-model="radioValue" size="large" class="radioBox">
|
|
|
+ <el-radio
|
|
|
+ v-for="item in radioList"
|
|
|
+ :key="item.value"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ {{ item.label }}
|
|
|
+ </el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ <template #footer>
|
|
|
+ <el-button type="primary" @click="handleSelect">确 认</el-button>
|
|
|
+ <el-button @click="openSelect = false">取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+
|
|
|
+ <!-- 人员搜索 -->
|
|
|
+ <Dialog :title="radioObject.menduner" v-model="openSearch" :modalClose="false" width="1200" @close="openSearch = false">
|
|
|
+ <Search @detail="handleDetail" />
|
|
|
+ </Dialog>
|
|
|
|
|
|
<!-- 解析文件上传 -->
|
|
|
- <Dialog :title="radioObject[radioValue]" v-model="dialog_upload" :modalClose="false" :width="DialogWidth" @close="handleCancel">
|
|
|
- <div>
|
|
|
- <!-- 简历解析 -->
|
|
|
- <template v-if="radioValue === 'file'">
|
|
|
- <el-upload
|
|
|
- ref="uploadRef"
|
|
|
- v-model:file-list="fileList"
|
|
|
- :action="uploadUrl"
|
|
|
- :auto-upload="false"
|
|
|
- :data="fileData"
|
|
|
- :limit="1"
|
|
|
- :on-change="handleChange"
|
|
|
- :on-error="submitFormError"
|
|
|
- :on-exceed="handleExceed"
|
|
|
- :on-success="submitFormSuccess"
|
|
|
- :http-request="httpRequest"
|
|
|
- accept=".pdf, doc, .docx"
|
|
|
- drag
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <i class="el-icon-upload"></i>
|
|
|
- <div class="el-upload__text">上传附件, 将文件拖到此处,或 <em>点击上传</em></div>
|
|
|
- <template #tip>
|
|
|
- <div class="el-upload__tip color-red">
|
|
|
- 提示:仅允许导入 pdf、doc、docx 格式文件!
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-upload>
|
|
|
- </template>
|
|
|
- <!-- 名片解析 -->
|
|
|
- <template v-if="radioValue === 'card'">
|
|
|
- <UploadImg
|
|
|
- v-model="cardImgUrl"
|
|
|
- :limit="1"
|
|
|
- :uploadSuccessTip="false"
|
|
|
- @handle-change="cardUploadChange"
|
|
|
- height="150px" width="150px" style="margin: 20px auto; width: 150px;"
|
|
|
- >
|
|
|
- <template #tip>{{ cardImgUrl ? '' : '请上传名片' }}</template>
|
|
|
- </UploadImg>
|
|
|
- </template>
|
|
|
- <template v-if="radioValue === 'picture'">
|
|
|
+ <Dialog :title="radioObject[radioValue]" v-model="dialog_upload" :modalClose="false" :width="DialogWidth" @close="handleCancel">
|
|
|
+ <div>
|
|
|
+ <!-- 简历解析 -->
|
|
|
+ <template v-if="radioValue === 'file'">
|
|
|
+ <el-upload
|
|
|
+ ref="uploadRef"
|
|
|
+ v-model:file-list="fileList"
|
|
|
+ :action="uploadUrl"
|
|
|
+ :auto-upload="false"
|
|
|
+ :data="fileData"
|
|
|
+ :on-change="handleChange"
|
|
|
+ :on-error="submitFormError"
|
|
|
+ :on-exceed="handleExceed"
|
|
|
+ :http-request="httpRequest"
|
|
|
+ accept=".pdf"
|
|
|
+ drag
|
|
|
+ multiple
|
|
|
+ class="flex-1"
|
|
|
+ >
|
|
|
+ <i class="el-icon-upload"></i>
|
|
|
+ <div class="el-upload__text">上传附件, 将文件拖到此处,或 <em>点击上传</em></div>
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip color-red">
|
|
|
+ 提示:仅允许导入 PDF格式文件!
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </template>
|
|
|
+ <!-- 名片解析 -->
|
|
|
+ <template v-if="radioValue === 'card'">
|
|
|
+ <UploadImgs
|
|
|
+ v-model="cardImgUrl"
|
|
|
+ :uploadSuccessTip="false"
|
|
|
+ :limit="30"
|
|
|
+ @handle-change="cardUploadChange"
|
|
|
+ height="150px" width="150px" style="margin: 20px auto; text-align: center;"
|
|
|
+ >
|
|
|
+ <template #tip>{{ cardImgUrl ? '' : '请上传名片' }}</template>
|
|
|
+ </UploadImgs>
|
|
|
+ </template>
|
|
|
+ <!-- 杂项 -->
|
|
|
+ <template v-if="radioValue === 'picture'">
|
|
|
+ <div class="flex align-center">
|
|
|
<UploadImg
|
|
|
v-model="cardImgUrl"
|
|
|
- :limit="1"
|
|
|
:uploadSuccessTip="false"
|
|
|
- @handle-change="cardUploadChange"
|
|
|
- height="150px" width="150px" style="margin: 20px auto; width: 150px;"
|
|
|
+ @handle-change="val => cardUploadChange(val, '杂项')"
|
|
|
+ height="150px" width="150px" style="margin: 20px auto; text-align: center;"
|
|
|
>
|
|
|
<template #tip>{{ cardImgUrl ? '' : '请上传图片' }}</template>
|
|
|
</UploadImg>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- <template #footer>
|
|
|
- <el-button @click="handleAnalysis" type="success" :disabled="analysisLoading" :loading="analysisLoading">解 析</el-button>
|
|
|
- <el-button @click="handleCancel">取 消</el-button>
|
|
|
- </template>
|
|
|
- </Dialog>
|
|
|
-
|
|
|
- <!-- 解析回显 -->
|
|
|
- <Dialog :title="radioObject[radioValue]" v-model="dialog_analysisInfo" :modalClose="false" width="90%" @close="dialog_analysisInfo = false">
|
|
|
- <div class="analysisInfoBox">
|
|
|
- <div class="analysisFile" :style="{'width': showFormPage || tagList?.length > 0 ? '50%' :'100%'}">
|
|
|
- <!-- 门墩儿人才库 -->
|
|
|
- <template v-if="radioValue === 'menduner'">
|
|
|
- <el-tabs v-model="activeName" type="border-card">
|
|
|
- <el-tab-pane label="基本信息" name="info">
|
|
|
- <el-card shadow="never">
|
|
|
- <Info :id="id" :user-id="userId" />
|
|
|
- <expExtend :user-id="userId" defaultShowAll class="m-t-20px" />
|
|
|
- </el-card>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane label="附件简历" name="Attachment">
|
|
|
- <Attachment showPreview :user-id="userId" />
|
|
|
- </el-tab-pane>
|
|
|
- </el-tabs>
|
|
|
- </template>
|
|
|
- <!-- 简历解析 -->
|
|
|
- <template v-if="radioValue === 'file'">
|
|
|
- <div v-if="fileUrl" style="position: relative;">
|
|
|
- <div class="text-right m-b-10px">
|
|
|
- <el-button v-if="!isEdit" @click="handleText">查看文本信息</el-button>
|
|
|
- <el-button type="primary" @click="handleResetUpload">重新上传简历</el-button>
|
|
|
- </div>
|
|
|
- <IFrame :src="fileUrl" />
|
|
|
- <el-drawer
|
|
|
- v-model="drawer"
|
|
|
- modal-class="drawer"
|
|
|
- size="75%"
|
|
|
- direction="ltr"
|
|
|
- title="简历解析(可复制文本使用)"
|
|
|
- >
|
|
|
- <p v-for="(text, index) in resumeTxt" :key="text + index">{{ text }}</p>
|
|
|
- </el-drawer>
|
|
|
- </div>
|
|
|
- <el-upload
|
|
|
- v-else
|
|
|
- ref="uploadRef"
|
|
|
- v-model:file-list="fileList"
|
|
|
- :action="uploadUrl"
|
|
|
- :auto-upload="false"
|
|
|
- :data="data"
|
|
|
- :limit="1"
|
|
|
- :on-change="handleChange"
|
|
|
- :on-error="submitFormError"
|
|
|
- :on-exceed="handleExceed"
|
|
|
- :on-success="submitFormSuccess"
|
|
|
- :http-request="httpRequest"
|
|
|
- accept=".pdf, doc, .docx"
|
|
|
- drag
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <i class="el-icon-upload"></i>
|
|
|
- <div class="el-upload__text">上传附件, 将文件拖到此处,或 <em>点击上传</em></div>
|
|
|
- <template #tip>
|
|
|
- <div class="el-upload__tip color-red">
|
|
|
- 提示:仅允许导入 pdf、doc、docx 格式文件!
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-upload>
|
|
|
- </template>
|
|
|
- <!-- 名片解析 -->
|
|
|
- <template v-if="radioValue === 'card'">
|
|
|
- <div class="image">
|
|
|
- <el-image v-if="cardImgUrl" class="!w-100%" :src="cardImgUrl" />
|
|
|
- <div v-else>
|
|
|
- <UploadImg
|
|
|
- v-model="cardImgUrl"
|
|
|
- :limit="1"
|
|
|
- :uploadSuccessTip="false"
|
|
|
- drag
|
|
|
- buttonUpload
|
|
|
- @handle-change="cardUploadChange"
|
|
|
- height="32px" width="104px"
|
|
|
- style="margin: 0 auto; width: 104px;margin-top: 40%;"
|
|
|
- >
|
|
|
- <template #tip>{{ cardImgUrl ? '' : '请上传名片' }}</template>
|
|
|
- </UploadImg>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <!-- 网页解析 -->
|
|
|
- <template v-if="radioValue === 'web'">
|
|
|
- <webAnalysis
|
|
|
- v-if="showWebAnalysis"
|
|
|
- @analysis="handleWebAnalysis"
|
|
|
- @reset="handleWebClear(), showFormPage = false, formData = {}"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- <div class="flex-1">
|
|
|
- <div class="tagBox mb-10px" v-if="tagList?.length">
|
|
|
- <el-tag
|
|
|
- type="primary"
|
|
|
- round
|
|
|
- size="large"
|
|
|
- v-for="(val, index) in tagList"
|
|
|
- :key="index + val"
|
|
|
- class="mr-10px cursor-pointer mb-10px"
|
|
|
- @click="handleTagClick(index)"
|
|
|
- >
|
|
|
- {{ val }}
|
|
|
- <Icon v-if="index === tagCurrentIndex" icon="ep:check" class="ml-5px" />
|
|
|
- </el-tag>
|
|
|
- </div>
|
|
|
- <FormPage
|
|
|
- v-if="showFormPage"
|
|
|
- ref="FormPageRef"
|
|
|
- :formType="analysisType"
|
|
|
- :itemData="formData"
|
|
|
- />
|
|
|
- <div v-if="tagList?.length && !tagCurrentIndex" class="!h-100% flex items-center justify-center">请点击上方人才姓名进行查看编辑</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <template #footer>
|
|
|
- <el-button @click="handleSave" type="success">保 存</el-button>
|
|
|
- <el-button @click="dialog_analysisInfo = false, handleWebClear">取 消</el-button>
|
|
|
</template>
|
|
|
- </Dialog>
|
|
|
- </ContentWrap>
|
|
|
-
|
|
|
- <MergeForm ref="mergeFormRef" @refresh="getList" />
|
|
|
+ <!-- 网页解析 -->
|
|
|
+ <template v-if="radioValue === 'web'">
|
|
|
+ <webAnalysis
|
|
|
+ @analysis="handleWebAnalysis"
|
|
|
+ @reset="webOriginList = []"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="handleSubmit" type="success" :disabled="analysisLoading" :loading="analysisLoading">提 交</el-button>
|
|
|
+ <el-button @click="handleCancel">取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+
|
|
|
+ <StorePage ref="StorePageRef" @refresh="getList" />
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
@@ -265,10 +169,7 @@ defineOptions({ name: 'TalentMapStoreIndex' })
|
|
|
import { dateFormatter } from '@/utils/formatTime'
|
|
|
import { talentLabelingApi } from '@/api/menduner/system/talentMap/labeling'
|
|
|
import { TalentMap } from '@/api/menduner/system/talentMap'
|
|
|
-import { Delete, Plus } from '@element-plus/icons-vue'
|
|
|
-import MergeForm from '@/views/menduner/system/talentMap/components/merge.vue'
|
|
|
-import FormPage from '@/views/menduner/system/talentMap/components/FormPage.vue'
|
|
|
-// import uploadDialog from './components/uploadDialog.vue'
|
|
|
+import { Plus } from '@element-plus/icons-vue'
|
|
|
import { timesTampChange, timestampToAge } from '@/utils/transform/date'
|
|
|
import Search from './components/search.vue'
|
|
|
import webAnalysis from './components/webAnalysis.vue'
|
|
@@ -280,8 +181,9 @@ import expExtend from '@/views/menduner/system/person/details/components/expExte
|
|
|
import Attachment from '@/views/menduner/system/person/details/components/attachment.vue'
|
|
|
import { talentWebParsingApi } from '@/api/menduner/system/talentMap/webParsing'
|
|
|
import { ElLoading } from 'element-plus'
|
|
|
+import StorePage from '@/views/menduner/system/talentMap/maintenance/gather/components/store.vue'
|
|
|
+import { talentGatherApi } from '@/api/menduner/system/talentMap/gather'
|
|
|
|
|
|
-const baseUrl = import.meta.env.VITE_PREVIEW_URL
|
|
|
const { uploadUrl, httpRequest } = useUpload()
|
|
|
const message = useMessage() // 消息弹窗
|
|
|
const { t } = useI18n() // 国际化
|
|
@@ -290,32 +192,31 @@ const loading = ref(false) // 列表的加载中
|
|
|
const list = ref([]) // 列表的数据
|
|
|
const total = ref(0) // 列表的总页数
|
|
|
const queryParams = reactive({
|
|
|
- name: undefined
|
|
|
+ page: 1,
|
|
|
+ per_page: 10,
|
|
|
+ task_type: undefined, // 任务类型
|
|
|
+ task_status: undefined // 任务状态
|
|
|
})
|
|
|
const queryFormRef = ref() // 搜索的表单
|
|
|
const dialog_upload = ref(false)
|
|
|
-
|
|
|
-const loadingMark = ref(null)
|
|
|
-const loadingMarkSetting = (text) => {
|
|
|
- if (text) {
|
|
|
- loadingMark.value = ElLoading.service({
|
|
|
- lock: true,
|
|
|
- text,
|
|
|
- background: 'rgba(0, 0, 0, 0.7)',
|
|
|
- })
|
|
|
- } else {
|
|
|
- if (loadingMark.value) loadingMark.value.close()
|
|
|
- loadingMark.value = null
|
|
|
- }
|
|
|
-}
|
|
|
+const taskType = [
|
|
|
+ { label: '名片', value: '名片' },
|
|
|
+ { label: '简历', value: '简历' },
|
|
|
+ { label: '门墩儿新任命', value: '新任命' },
|
|
|
+ { label: '门墩儿招聘', value: '招聘' },
|
|
|
+ { label: '杂项', value: '杂项' }
|
|
|
+]
|
|
|
+const taskStatus = ['待解析', '解析中', '解析完成']
|
|
|
+const itemData = ref({})
|
|
|
|
|
|
/** 查询列表 */
|
|
|
const getList = async () => {
|
|
|
loading.value = true
|
|
|
try {
|
|
|
list.value = []
|
|
|
- const data = await talentLabelingApi.getCardList()
|
|
|
- list.value = data ?? []
|
|
|
+ const data = await talentGatherApi.getTaskList(queryParams)
|
|
|
+ list.value = data.tasks ?? []
|
|
|
+ total.value = data.pagination.total ?? 0
|
|
|
} finally {
|
|
|
loading.value = false
|
|
|
}
|
|
@@ -323,10 +224,7 @@ const getList = async () => {
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
const handleQuery = (type) => {
|
|
|
- if (type !== 'reset') {
|
|
|
- message.warning('搜索正在建设中...')
|
|
|
- return
|
|
|
- }
|
|
|
+ queryParams.page = 1
|
|
|
getList()
|
|
|
}
|
|
|
|
|
@@ -336,270 +234,79 @@ const resetQuery = () => {
|
|
|
handleQuery('reset')
|
|
|
}
|
|
|
|
|
|
-/** 删除按钮操作 */
|
|
|
-const handleDelete = async (id) => {
|
|
|
- try {
|
|
|
- // 删除的二次确认
|
|
|
- await message.delConfirm()
|
|
|
- // 发起删除
|
|
|
- await talentLabelingApi.deleteBusinessCard(id)
|
|
|
- message.success(t('common.delSuccess'))
|
|
|
- // 刷新列表
|
|
|
- setTimeout(async () => {
|
|
|
- await getList()
|
|
|
- }, 0)
|
|
|
- } catch {}
|
|
|
-}
|
|
|
-
|
|
|
-// 网页解析-人才标签点击
|
|
|
-const handleTagClick = (index) => {
|
|
|
- if (!webOriginList.value?.[index]) return
|
|
|
- tagCurrentIndex.value = index
|
|
|
- const obj = webOriginList.value[index]
|
|
|
- formData.value = obj ?? {}
|
|
|
- if (!showFormPage.value) showFormPage.value = true
|
|
|
-}
|
|
|
-
|
|
|
// 网页解析-信息提取
|
|
|
-const tagCurrentIndex = ref(null)
|
|
|
-const tagList = ref([])
|
|
|
-const originMarkdown = ref(null)
|
|
|
const webOriginList = ref([])
|
|
|
-const handleWebAnalysis = (list, md) => {
|
|
|
- webOriginList.value = list
|
|
|
- tagList.value = list.map(e => e.name_zh)
|
|
|
- originMarkdown.value = md
|
|
|
- // 只有单个人才时默认选中
|
|
|
- if (list?.length === 1) {
|
|
|
- handleTagClick(0)
|
|
|
- }
|
|
|
+const handleWebAnalysis = (list) => {
|
|
|
+ webOriginList.value = list ?? []
|
|
|
}
|
|
|
|
|
|
-const handleWebClear = () => {
|
|
|
- tagCurrentIndex.value = null
|
|
|
- originMarkdown.value = null
|
|
|
- tagList.value = []
|
|
|
- webOriginList.value = []
|
|
|
+// 入库
|
|
|
+const StorePageRef = ref(null)
|
|
|
+const handleStore = (row) => {
|
|
|
+ StorePageRef.value.open(row)
|
|
|
}
|
|
|
|
|
|
-/** 编辑 */
|
|
|
-const { push } = useRouter()
|
|
|
-const handleEdit = async (item) => {
|
|
|
- analysisType.value = 'edit'
|
|
|
- formData.value = item
|
|
|
- radioValue.value = item.type || 'card' // menduner
|
|
|
- try {
|
|
|
- if (radioValue.value === 'card') {
|
|
|
- if (!item?.image_path) {
|
|
|
- cardUploadRow.value = null
|
|
|
- cardImgUrl.value = null
|
|
|
- dialog_analysisInfo.value = true
|
|
|
- return
|
|
|
- }
|
|
|
- const data = await talentLabelingApi.getBusinessCardImage(item.image_path)
|
|
|
- cardUploadRow.value = data?.type ? new File([data], item.image_path, { type: data.type }) : null
|
|
|
- cardImgUrl.value = data?.type ? URL.createObjectURL(data) : null
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.log('打印->getBusinessCardImage', error)
|
|
|
- } finally {
|
|
|
- dialog_analysisInfo.value = true
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/** 禁用按钮操作 */
|
|
|
-const handleDisable = async (item) => {
|
|
|
- if (!item?.id) return message.warning('操作失败,请稍后再试')
|
|
|
- try {
|
|
|
- // 禁用的二次确认
|
|
|
- const status = item.status === 'active' ? 'inactive' : 'active'
|
|
|
- const text = status === 'inactive' ? '禁用' : '启用'
|
|
|
-
|
|
|
- await message.delConfirm(`是否${text}该名片?`)
|
|
|
- // 发起禁用
|
|
|
- await talentLabelingApi.updateBusinessCardStatus({
|
|
|
- status,
|
|
|
- }, item.id)
|
|
|
- message.success(`${text}成功`)
|
|
|
- // 刷新列表
|
|
|
- await getList()
|
|
|
- } catch {}
|
|
|
+// 关闭上传弹窗
|
|
|
+const handleCancel = () => {
|
|
|
+ dialog_upload.value = false
|
|
|
+ analysisLoading.value = false
|
|
|
+ cardUploadRow.value = []
|
|
|
+ fileList.value = []
|
|
|
}
|
|
|
|
|
|
-// 更新
|
|
|
-const activeName = ref('info')
|
|
|
-const dialog_analysisInfo = ref(false)
|
|
|
-const analysisType = ref('')
|
|
|
-const showFormPage = ref(true)
|
|
|
-const FormPageRef = ref(null)
|
|
|
-const mergeFormRef = ref() // 合并表单 Ref
|
|
|
-
|
|
|
-const handleSaveWebData = async () => {
|
|
|
- if (!webOriginList.value || !webOriginList.value?.length) {
|
|
|
- message.warning('请输入微信公众号链接解析并提取信息核对后再提交保存')
|
|
|
- return
|
|
|
- }
|
|
|
- if (!FormPageRef.value) return message.warning('请点击右侧顶部的人才标签查看核对信息后保存')
|
|
|
-
|
|
|
- // 验证webOriginList数组中每个人才的name_zh字段,并处理mobile字段
|
|
|
- if (webOriginList.value && Array.isArray(webOriginList.value) && webOriginList.value.length > 0) {
|
|
|
- for (let i = 0; i < webOriginList.value.length; i++) {
|
|
|
- const talent = webOriginList.value[i]
|
|
|
- if (!talent.name_zh || talent.name_zh.trim() === '') {
|
|
|
- return message.warning(`第${i + 1}个人才中的中文姓名未填写,请完善后再进行保存`)
|
|
|
- }
|
|
|
-
|
|
|
- // 处理mobile字段,如果是数组则转换为字符串
|
|
|
- if (Array.isArray(talent.mobile)) {
|
|
|
- talent.mobile = talent.mobile.filter(i => Boolean(i)).map(j => String(j).replace(/,|,/g, '')).join(',');
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- console.log(webOriginList.value, '网页解析-新增')
|
|
|
-
|
|
|
- const loading = ElLoading.service({
|
|
|
- lock: true,
|
|
|
- text: '正在保存中...',
|
|
|
- background: 'rgba(0, 0, 0, 0.7)',
|
|
|
- })
|
|
|
+// 创建任务
|
|
|
+const handleCreateTask = async (query) => {
|
|
|
try {
|
|
|
- const result = await talentWebParsingApi.webParsingTalentCreate({
|
|
|
- talent_list: webOriginList.value,
|
|
|
- web_md: originMarkdown.value
|
|
|
- })
|
|
|
- console.log(result, 'create-result')
|
|
|
- message.success('新增成功')
|
|
|
- dialog_analysisInfo.value = false
|
|
|
- // 刷新列表
|
|
|
+ await talentGatherApi.createTask(query)
|
|
|
+ message.success('任务创建成功')
|
|
|
getList()
|
|
|
- if (result.code === 202 || result.message.includes('疑似重复')) {
|
|
|
- if (!result.data?.main_card?.id) return
|
|
|
-
|
|
|
- await message.confirm('发现与当前名片的疑似重复数据,去处理')
|
|
|
- mergeFormRef.value.open(result.data?.main_card?.id)
|
|
|
- }
|
|
|
} finally {
|
|
|
- loading.close()
|
|
|
- handleWebClear()
|
|
|
+ analysisLoading.value = false
|
|
|
+ webOriginList.value = []
|
|
|
+ handleCancel()
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-const handleSave = async () => {
|
|
|
- // 网页解析新增调用单独的接口保存
|
|
|
- if (analysisType.value === 'create' && radioValue.value === 'web') return handleSaveWebData()
|
|
|
+// 新任命
|
|
|
+const handleCreateWebTask = async () => {
|
|
|
+ if (!webOriginList.value || !webOriginList.value?.length) return message.warning('请输入新任命链接查看后再进行提交')
|
|
|
|
|
|
- if (!FormPageRef.value) return message.warning('请将表单信息完善后再提交')
|
|
|
-
|
|
|
- const params = { ...FormPageRef.value.formQuery, type: radioValue.value }
|
|
|
- if (!params.name_zh) return message.warning('请填写姓名!')
|
|
|
-
|
|
|
- // 数组转为字符串保存
|
|
|
- if (Array.isArray(params?.mobile)) {
|
|
|
- params.mobile = params.mobile.filter(i => Boolean(i)).map(j => String(j).replace(/,|,/g, '')).join(',');
|
|
|
- }
|
|
|
+ analysisLoading.value = true
|
|
|
|
|
|
- const loading = ElLoading.service({
|
|
|
- lock: true,
|
|
|
- text: '正在保存中...',
|
|
|
- background: 'rgba(0, 0, 0, 0.7)',
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('task_type', '新任命')
|
|
|
+ webOriginList.value.forEach(e => {
|
|
|
+ formData.append('files', e.file)
|
|
|
})
|
|
|
- try {
|
|
|
- let result = {}
|
|
|
|
|
|
- if (analysisType.value === 'create') {
|
|
|
- if (cardFileQuery.value) {
|
|
|
- cardFileQuery.value.append('card_data', JSON.stringify(params)) // 名片
|
|
|
- result = await talentLabelingApi.createBusinessCard(cardFileQuery.value)
|
|
|
- } else {
|
|
|
- // 结构化数据源 不传递文件
|
|
|
- result = await talentLabelingApi.createBusinessCardPost(params)
|
|
|
- }
|
|
|
- message.success('新增成功')
|
|
|
- dialog_analysisInfo.value = false
|
|
|
- // 刷新列表
|
|
|
- getList()
|
|
|
-
|
|
|
- if (result.code === 202 || result.message.includes('疑似重复')) {
|
|
|
- if (!result.data?.main_card?.id) return
|
|
|
-
|
|
|
- await message.confirm('发现与当前名片的疑似重复数据,去处理')
|
|
|
- mergeFormRef.value.open(result.data?.main_card?.id)
|
|
|
- }
|
|
|
- } else {
|
|
|
- await talentLabelingApi.updateBusinessCard(params, formData.value.id)
|
|
|
- message.success('更新成功')
|
|
|
- dialog_analysisInfo.value = false
|
|
|
- // 刷新列表
|
|
|
- getList()
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.log('更新失败', error)
|
|
|
- } finally {
|
|
|
- cardFileQuery.value = null
|
|
|
- loading.close()
|
|
|
- openSearch.value = false
|
|
|
- handleWebClear()
|
|
|
- }
|
|
|
+ handleCreateTask(formData)
|
|
|
}
|
|
|
|
|
|
-// 解析中
|
|
|
+// 名片、简历、杂项
|
|
|
const analysisLoading = ref(false)
|
|
|
-const formData = ref({})
|
|
|
-const handleAnalysis = async () => {
|
|
|
- // 开始解析
|
|
|
- analysisLoading.value = true
|
|
|
- loadingMarkSetting('解析中...')
|
|
|
- cardFileQuery.value = null
|
|
|
- formData.value = null
|
|
|
- const type = radioValue.value
|
|
|
- try {
|
|
|
- // if (type === 'menduner') { // 门墩儿人才库
|
|
|
- // } else
|
|
|
- if (type === 'file') { // 简历解析
|
|
|
- if (!fileUrl.value) return message.warning('获取文件失败,请重新上传!')
|
|
|
- const data = await commonApi.resumeParser({ fileUrl: fileUrl.value })
|
|
|
- resumeAnalysisToForm(data) // 简历解析
|
|
|
- } else if (type === 'card') { // 名片解析
|
|
|
- if (!cardImgUrl.value) {
|
|
|
- message.warning('请先上传名片!')
|
|
|
- return
|
|
|
- }
|
|
|
- cardFileQuery.value = new FormData()
|
|
|
- cardFileQuery.value.append('image', cardUploadRow.value)
|
|
|
- message.warning('正在解析...')
|
|
|
-
|
|
|
- const index = createAnalysisNum.value
|
|
|
- const res = await talentLabelingApi.businessCardParse(cardFileQuery.value)
|
|
|
- if (index !== createAnalysisNum.value || !dialog_upload.value) return // 不是最新的名片解析数据(用户在解析完成前已重新上传)或用户已取消解析
|
|
|
- formData.value = res?.data || res
|
|
|
- message.success('名片解析成功')
|
|
|
+const handleSubmit = async () => {
|
|
|
+ const type = radioValue.value
|
|
|
+ // 新任命任务创建
|
|
|
+ if (type === 'web') return handleCreateWebTask()
|
|
|
+
|
|
|
+ if (['card', 'file', 'picture'].includes(type)) {
|
|
|
+ const currentList = type === 'file' ? fileList.value : cardUploadRow.value
|
|
|
+ if (!currentList || !currentList?.length) {
|
|
|
+ message.warning(`请上传${type === 'file' ? '简历' : type === 'card' ? '名片' : '杂项'}`)
|
|
|
+ return
|
|
|
}
|
|
|
- // else if (type === 'web') {}
|
|
|
+ analysisLoading.value = true
|
|
|
|
|
|
- dialog_upload.value = false
|
|
|
- dialog_analysisInfo.value = true
|
|
|
- } catch (error) {
|
|
|
- console.log('解析失败', error)
|
|
|
- cardFileQuery.value = null
|
|
|
- } finally {
|
|
|
- analysisLoading.value = false
|
|
|
- loadingMarkSetting()
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('task_type', type === 'file' ? '简历' : type === 'card' ? '名片' : '杂项')
|
|
|
+ currentList.forEach(e => {
|
|
|
+ formData.append('files', e.raw)
|
|
|
+ })
|
|
|
+ handleCreateTask(formData)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 监听表单变化,同步更新tagList中对应的数据
|
|
|
-watch(() => FormPageRef.value?.formQuery, (newVal) => {
|
|
|
- if (tagCurrentIndex.value !== null && webOriginList.value && webOriginList.value.length > tagCurrentIndex.value) {
|
|
|
- // 保留原始pic_url
|
|
|
- const { pic_url } = webOriginList.value[tagCurrentIndex.value]
|
|
|
- webOriginList.value[tagCurrentIndex.value] = { ...newVal, pic_url }
|
|
|
- }
|
|
|
-}, { deep: true })
|
|
|
-
|
|
|
// 简历解析
|
|
|
-const fileUrl = ref('') // https://minio.menduner.com/dev/person/229988673960153088/attachment/ee3eb21f45e13ede3557a03d18585ed80c5b4212ac5634e3436e309afaa8fe6a.pdf
|
|
|
const uploadRef = ref()
|
|
|
const fileList = ref([])
|
|
|
const fileData = ref({ path: '' })
|
|
@@ -607,17 +314,6 @@ const fileData = ref({ path: '' })
|
|
|
const handleChange = async (file) => {
|
|
|
fileData.value.path = file.name
|
|
|
unref(uploadRef)?.submit()
|
|
|
- if (!fileList.value.length) return
|
|
|
-
|
|
|
- const url = fileList.value[0].response.data
|
|
|
- fileUrl.value = !url.includes('.pdf') ? `${baseUrl}/onlinePreview?url=${encodeURIComponent(Base64.encode(url))}` : url
|
|
|
- if (dialog_analysisInfo.value) {
|
|
|
- if (FormPageRef.value?.changeLoading) FormPageRef.value.changeLoading(true)
|
|
|
- message.warning('正在解析...')
|
|
|
- const data = await commonApi.resumeParser({ fileUrl: fileUrl.value })
|
|
|
- resumeAnalysisToForm(data) // 简历解析
|
|
|
- if (FormPageRef.value?.changeLoading) FormPageRef.value.changeLoading(false)
|
|
|
- }
|
|
|
}
|
|
|
const submitFormError = () => {
|
|
|
message.error('上传失败,请您重新上传!')
|
|
@@ -625,34 +321,10 @@ const submitFormError = () => {
|
|
|
const handleExceed = () => {
|
|
|
message.error('最多只能上传一个文件!')
|
|
|
}
|
|
|
-const submitFormSuccess = (e) => {
|
|
|
- // 清理
|
|
|
- // unref(uploadRef)?.clearFiles()
|
|
|
-}
|
|
|
-
|
|
|
-const drawer = ref(false)
|
|
|
-const resumeTxt = ref([])
|
|
|
-// 查看文本信息
|
|
|
-const handleText = () => {
|
|
|
- drawer.value = true
|
|
|
-}
|
|
|
-// 重新上传简历
|
|
|
-const handleResetUpload = async () => {
|
|
|
- await message.confirm('是否确定重新上传简历?确定后将清空当前信息')
|
|
|
- fileUrl.value = ''
|
|
|
- fileData.value.path = ''
|
|
|
- fileList.value = []
|
|
|
- resumeAnalysisToForm('reset') // 简历解析
|
|
|
-}
|
|
|
|
|
|
// 简历解析数据解构赋值
|
|
|
const resumeAnalysisToForm = (data) => {
|
|
|
- if (data === 'reset') {
|
|
|
- // 重置表单
|
|
|
- resumeTxt.value = ''
|
|
|
- if (FormPageRef.value?.resetFormData) FormPageRef.value.resetFormData()
|
|
|
- }
|
|
|
- formData.value = {
|
|
|
+ itemData.value = {
|
|
|
name_zh: data?.person?.name || '',
|
|
|
email: data?.person?.email || '',
|
|
|
mobile: data?.person?.phone || '',
|
|
@@ -668,71 +340,47 @@ const resumeAnalysisToForm = (data) => {
|
|
|
created_at: data?.person?.createTime ? timesTampChange(data.person.createTime, 'Y-M-D') : null,
|
|
|
updated_at: data?.person?.updateTime ? timesTampChange(data.person.updateTime, 'Y-M-D') : null,
|
|
|
}
|
|
|
- resumeTxt.value = data?.resume?.rawText?.split('\n') || ''
|
|
|
- if (FormPageRef.value?.setFormData) FormPageRef.value.setFormData(formData.value)
|
|
|
}
|
|
|
|
|
|
// 名片解析
|
|
|
-const createAnalysisNum = ref(0)
|
|
|
-const cardFileQuery = ref(null)
|
|
|
const cardUploadRow = ref(null)
|
|
|
const cardImgUrl = ref(null)
|
|
|
-const cardUploadChange = (raw) => {
|
|
|
- cardUploadRow.value = raw
|
|
|
+const cardUploadChange = (file, type) => {
|
|
|
+ cardUploadRow.value = type ? [{ raw: file }] : file
|
|
|
}
|
|
|
|
|
|
// 人员搜索
|
|
|
const openSearch = ref(false)
|
|
|
const id = ref(null)
|
|
|
const userId = ref(null)
|
|
|
-// const handleDetail = async ({id: use_id, userId: use_userId}) => {
|
|
|
-// if (!use_userId || !use_userId) return message.warning('请先选择人才!')
|
|
|
-// id.value = use_id; userId.value = use_userId
|
|
|
-// try {
|
|
|
-// const data = await TalentMap.getTalentMapDetail(use_userId)
|
|
|
-// resumeAnalysisToForm(data) // 简历解析
|
|
|
-// dialog_analysisInfo.value = true
|
|
|
-// } catch {}
|
|
|
-// }
|
|
|
-
|
|
|
-const SearchRef = ref(null)
|
|
|
-const handleSubmit = async () => {
|
|
|
- console.log('打印->addList', SearchRef.value.addList)
|
|
|
- message.success('创建任务成功!')
|
|
|
- openSearch.value = false
|
|
|
+const handleDetail = async ({id: use_id, userId: use_userId}) => {
|
|
|
+ if (!use_userId || !use_userId) return message.warning('请先选择人才!')
|
|
|
+ id.value = use_id; userId.value = use_userId
|
|
|
+ try {
|
|
|
+ const data = await TalentMap.getTalentMapDetail(use_userId)
|
|
|
+ // 去除id
|
|
|
+ resumeAnalysisToForm(data) // 简历解析
|
|
|
+ } catch {}
|
|
|
}
|
|
|
|
|
|
-const DialogWidth = ref('500')
|
|
|
-const showWebAnalysis = ref(false)
|
|
|
// 选择解析方式
|
|
|
+const DialogWidth = ref('500')
|
|
|
const handleSelect = () => {
|
|
|
openSelect.value = false
|
|
|
- formData.value = null
|
|
|
- showWebAnalysis.value = false
|
|
|
- showFormPage.value = true // 默认展示表单
|
|
|
+ itemData.value = {}
|
|
|
+ DialogWidth.value = '500'
|
|
|
+
|
|
|
const type = radioValue.value
|
|
|
- if (type === 'card') {
|
|
|
- createAnalysisNum.value++
|
|
|
+ if (['card', 'web'].includes(type)) {
|
|
|
+ DialogWidth.value = '800'
|
|
|
}
|
|
|
if (type === 'menduner') {
|
|
|
openSearch.value = true
|
|
|
return
|
|
|
}
|
|
|
- if (type === 'web') {
|
|
|
- showFormPage.value = false // 新任命没有表单
|
|
|
- showWebAnalysis.value = true
|
|
|
- dialog_analysisInfo.value = true
|
|
|
- return
|
|
|
- }
|
|
|
dialog_upload.value = true
|
|
|
}
|
|
|
|
|
|
-// 关闭上传弹窗
|
|
|
-const handleCancel = () => {
|
|
|
- dialog_upload.value = false
|
|
|
- analysisLoading.value = false
|
|
|
-}
|
|
|
-
|
|
|
const openSelect = ref(false)
|
|
|
const radioObject = { card: '名片', file: '简历', web: '门墩儿新任命', menduner: '门墩儿招聘', picture: '杂项' }
|
|
|
const radioList = ref(Object.keys(radioObject).map(key => ({ value: key, label: radioObject[key]}) ))
|
|
@@ -740,16 +388,11 @@ const defaultValue = radioList.value[0].value // 默认选中
|
|
|
const radioValue = ref(defaultValue)
|
|
|
// 新增解析
|
|
|
const handleAdd = () => {
|
|
|
- handleWebClear()
|
|
|
+ webOriginList.value = []
|
|
|
cardUploadRow.value = null
|
|
|
cardImgUrl.value = null
|
|
|
- fileUrl.value = ''
|
|
|
- fileData.value.path = ''
|
|
|
- fileList.value = []
|
|
|
analysisLoading.value = false
|
|
|
- analysisType.value = 'create'
|
|
|
radioValue.value = defaultValue // 重置解析类型
|
|
|
- //
|
|
|
openSelect.value = true
|
|
|
}
|
|
|
|
|
@@ -761,30 +404,9 @@ onMounted(() => {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.analysisInfoBox {
|
|
|
- display: flex;
|
|
|
- .analysisFile {
|
|
|
- // width: 50%;
|
|
|
- // max-height: 70vh;
|
|
|
- padding-right: 12px;
|
|
|
- overflow: auto;
|
|
|
- }
|
|
|
-}
|
|
|
.radioBox {
|
|
|
margin: 40px 0;
|
|
|
}
|
|
|
-
|
|
|
-:deep(.drawer) {
|
|
|
- position: absolute;
|
|
|
- .el-drawer {
|
|
|
- background-color: aliceblue;
|
|
|
- }
|
|
|
-}
|
|
|
-.tagBox {
|
|
|
- padding: 12px;
|
|
|
- border: 1px dashed #409EFF;
|
|
|
- border-radius: 4px;
|
|
|
-}
|
|
|
:deep {
|
|
|
.el-tag__content {
|
|
|
display: flex;
|