1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003 |
- <template>
- <div class="h-full flex flex-col teamstyle overflow-hidden temaClass">
- <!-- 头部 -->
- <div class="bg-white flex justify-between team-header">
- <div class="flex items-center">
- <el-link type="primary" class="text-nowrap mr-20" :icon="CirclePlusFilled"
- @click="dialogFromCli('addDeptDialogVisible')">创建部门</el-link>
- <el-link class="text-nowrap textFont textFont mr-10" type="primary" :icon="Edit"
- @click="updateDepartment('addDeptDialogVisible')">
- <template v-if="!deptListItem.labe">全部人员</template>
- <template v-if="deptListItem.labe">
- <TextTranslation translationTypes="departmentName" :translationValue="deptListItem.labe"></TextTranslation>
- </template>
- </el-link>
- <span class="textSpan textFont">共 0 人</span>
- </div>
- <div class="teamForm flex items-center">
- <el-input v-model="teamForm.keyword" style="max-width: 650px" size="default" placeholder="请输入姓名搜索" class="mr-6"
- clearable @clear="getTableData()" @keyup.enter.native="getTableData()">
- <template #prepend>
- <el-select v-model="teamForm.matchingType" style="width: 80px">
- <el-option label="姓名" :value="0" />
- <el-option label="电话" :value="1" />
- <el-option label="工号" :value="2" />
- </el-select>
- </template>
- <template #append>
- <el-button :icon="Search" @click="getTableData()" />
- </template>
- </el-input>
- <div class="formItem mr-6 flex items-center">
- <div class="text-nowrap">状态:</div>
- <el-select v-model="teamForm.status" placeholder="请选择" size="default" style="width: 100px"
- @change="getTableData()">
- <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- <div class="formItem mr-6 flex items-center">
- <div class="text-nowrap">角色:</div>
- <el-select v-model="teamForm.roleId" placeholder="请选择" size="default" style="width: 150px" clearable
- @change="getTableData()">
- <el-option v-for="item in roleList" :key="item.id" :label="item.rolename" :value="item.id" />
- </el-select>
- </div>
- <!-- <el-button type="primary" v-if="userInfo.userNameNeedTranslate == 1"
- @click="transitionOperation('exportUser', '')" v-permission="['teamExport']">导出人员</el-button>
- <el-button type="primary" v-if="userInfo.userNameNeedTranslate == 1"
- @click="dialogFrom.newSyncWithCorpWxDayloadVisable = true">同步企微通讯录</el-button>
- <el-button type="primary" v-if="userInfo.userNameNeedTranslate == 1" @click="officialAccountSetting()">{{
- officialAccountInformation.id ? '修改公众号配置' : '配置公众号' }}</el-button>
- <el-dropdown v-if="userInfo.userNameNeedTranslate != 1">
- <el-button type="primary">
- 更多操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item @click="addPersone(false)" v-permission="['teamAdd']">添加人员</el-dropdown-item>
- <el-dropdown-item @click="transitionOperation('exportUser', '')"
- v-permission="['teamExport']">导出人员</el-dropdown-item>
- <el-dropdown-item @click="transitionOperation('importUser', '')"
- v-permission="['teamImport']">批量导入</el-dropdown-item>
- <el-dropdown-item @click="officialAccountSetting()">
- {{ officialAccountInformation.id ? '修改公众号配置' : '配置公众号' }}
- </el-dropdown-item>
- <el-dropdown-item @click="oneClickGenerationOfQrCode()" v-if="officialAccountInformation.id">
- 一键生成员工二维码
- </el-dropdown-item>
- <el-dropdown-item @click="exportQrCode()" v-if="officialAccountInformation.id">
- 导出员工二维码
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown> -->
- <el-dropdown>
- <el-button type="primary">
- 更多操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <template v-if="userInfo.userNameNeedTranslate != 1">
- <el-dropdown-item @click="addPersone(false)" v-permission="['teamAdd']">添加人员</el-dropdown-item>
- <el-dropdown-item @click="transitionOperation('exportUser', '')" v-permission="['teamExport']">导出人员</el-dropdown-item>
- <el-dropdown-item @click="transitionOperation('importUser', '')" v-permission="['teamImport']">批量导入</el-dropdown-item>
- </template>
- <template v-if="userInfo.userNameNeedTranslate == 1">
- <el-dropdown-item @click="transitionOperation('exportUser', '')" v-permission="['teamExport']">导出人员</el-dropdown-item>
- <el-dropdown-item @click="dialogFrom.newSyncWithCorpWxDayloadVisable = true" v-permission="['teamAdd']">同步企微通讯录</el-dropdown-item>
- </template>
- <el-dropdown-item @click="officialAccountSetting()">
- {{ officialAccountInformation.id ? '修改公众号配置' : '配置公众号' }}
- </el-dropdown-item>
- <el-dropdown-item @click="oneClickGenerationOfQrCode()" v-if="officialAccountInformation.id">
- 一键生成员工二维码
- </el-dropdown-item>
- <el-dropdown-item @click="exportQrCode()" v-if="officialAccountInformation.id">
- 导出员工二维码
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- </div>
- <!-- 内容 -->
- <div class="flex-1 flex">
- <div class="p-4 w-80 pr-0">
- <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
- <div class="flex-1 overflow-y-auto const-left">
- <el-tree style="max-width: 600px" :data="deptList" :props="treeProps" @node-click="treeNode">
- <template #default="{ node, data }">
- <div class="flex justify-between treeContent">
- <div class="custom-tree-node" @mouseleave="mouseleave(data, $event)"
- @mouseover="mouseover(data, $event)">
- <div class="treeLabel">
- <TextTranslation translationTypes="departmentName" :translationValue="node.label">
- </TextTranslation>
- </div>
- <div class="treeIcon nodeEle" id="treeIcon" v-if="data.id > 0">
- <el-link type="primary" :icon="CirclePlus" :underline="false"
- @click.stop="dialogFromCli('addDeptDialogVisible', data, true)"></el-link>
- <el-link type="primary" :icon="Delete" :underline="false" style="margin-left: 6px;"
- @click.stop="deteleDept(data)"></el-link>
- </div>
- </div>
- </div>
- </template>
- </el-tree>
- </div>
- </div>
- </div>
- <div class="flex-1 p-4 overflow-auto">
- <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col overflow-hidden pt-2 pl-2 pr-2">
- <div class="flex-1">
- <el-table ref="multipleTableRef" :data="tableData" v-loading="loadingFrom.tableLoading"
- @selection-change="changeBatch" style="width: 100%;height: calc(100vh - 204px);">
- <el-table-column type="selection" width="55" />
- <el-table-column label="姓名" property="name" width="150">
- <template #default="scope">
- <div class="flex items-center">
- <TextTranslation translationTypes="userName" :translationValue="scope.row.name"></TextTranslation>
- <template v-if="officialAccountInformation.id && scope.row.wxImgUrlWithTicket">
- <el-tooltip class="box-item" effect="dark" content="点击查看销售二维码" placement="top">
- <div class="ml-2 cursor-pointer" @click="viewQrCode(scope.row)">
- <el-icon color="#075985">
- <PictureFilled />
- </el-icon>
- </div>
- </el-tooltip>
- </template>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="手机" property="phone"></el-table-column>
- <el-table-column label="工号" property="jobNumber"></el-table-column>
- <el-table-column label="部门" property="departmentName">
- <template #default="scope">
- <TextTranslation translationTypes="departmentName" :translationValue="scope.row.departmentName">
- </TextTranslation>
- </template>
- </el-table-column>
- <el-table-column label="角色" property="roleName"></el-table-column>
- <el-table-column label="创建时间" property="createTime"></el-table-column>
- <el-table-column label="操作" width="200" fixed="right">
- <template #default="scope">
- <el-button :size="'small'" @click="resetPwd(scope.row)">重置</el-button>
- <el-button type="primary" :size="'small'" @click="addPersone(scope.row)">编辑</el-button>
- <el-button :size="'small'" @click="transitionOperation('disable', scope.row)"
- v-if="scope.row.isActive == 1">停用</el-button>
- <el-button type="success" :size="'small'" @click="enableUser(scope.row)"
- v-if="scope.row.isActive == 0">启用</el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div class="flex justify-between pb-2 pt-2 pl-3 pr-3">
- <div class="flex">
- <el-button size="default" @click="changeBatch(false)"
- :disabled="batchTableData.length == 0">取消</el-button>
- <el-dropdown class="ml-3">
- <el-button type="primary">
- 更多操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item @click="batchItem('批量修改部门', 'dept', deptList)"
- :disabled="batchTableData.length == 0">批量修改部门</el-dropdown-item>
- <el-dropdown-item @click="batchItem('批量修改角色', 'role', roleList)"
- :disabled="batchTableData.length == 0">批量修改角色</el-dropdown-item>
- <el-dropdown-item @click="batchEnableItem"
- :disabled="batchTableData.length == 0">批量启用员工</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- <div class="pr-4">
- <el-pagination layout="total, prev, pager, next, sizes" :total="totalTable" :page-size="teamForm.pageSize"
- @size-change="handleSizeChange" @current-change="handleCurrentChange" />
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 新增部门 -->
- <el-dialog v-model="dialogFrom.addDeptDialogVisible" width="600" :show-close="false" :before-close="handleClose">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">{{ deptListItem.label || '创建部门' }}</h4>
- <div class="flex">
- <el-button @click="dialogFrom.addDeptDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="createDepartment(deptRuleFormRef)"
- v-bind:loading="loadingFrom.deptDialogVisibleLoading">
- 确定
- </el-button>
- </div>
- </div>
- </template>
- <div class="pt-5">
- <el-form ref="deptRuleFormRef" style="max-width: 500px" :model="deptForm" :rules="deptRules" label-width="140px"
- size="large" status-icon>
- <el-form-item label="部门名称" prop="name">
- <el-input v-model="deptForm.name" placeholder="请输入部门名称" clearable
- :disabled="userInfo.userNameNeedTranslate == 1" />
- </el-form-item>
- <el-form-item label="主要负责人">
- <!-- <el-select v-model="deptForm.managerId" placeholder="请选择" style="width: 100%" clearable>
- <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" />
- </el-select> -->
- <personnel-search v-model="deptForm.managerId" :size="''" placeholder="请选择"></personnel-search>
- </el-form-item>
- <el-form-item label="其他负责人">
- <!-- <el-select v-model="deptForm.otherManagerIds" placeholder="请选择" style="width: 100%" multiple clearable>
- <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" />
- </el-select> -->
- <personnel-search v-model="deptForm.otherManagerIds" :size="''" multiple
- placeholder="请选择"></personnel-search>
- </el-form-item>
- </el-form>
- </div>
- </el-dialog>
- <!-- 停用 -->
- <el-dialog v-model="dialogFrom.resignationVisible" width="600" :show-close="false" :before-close="handleClose">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">离职停用员工</h4>
- <div class="flex">
- <el-button @click="dialogFrom.resignationVisible = false">取消</el-button>
- <el-button type="primary" @click="resignation" v-bind:loading="loadingFrom.resignationLoading">
- 确定
- </el-button>
- </div>
- </div>
- </template>
- <div class="pt-4 pb-2">
- <div class="flex items-center justify-center">
- <div class="pr-2">员工离职日期:</div>
- <el-date-picker v-model="resignationDate" type="date" placeholder="请选择日期" value-format="YYYY-MM-DD"
- :clearable="false" />
- </div>
- </div>
- </el-dialog>
- <!-- 导出人员列表 -->
- <el-dialog v-model="dialogFrom.exportUserVisible" width="600" :show-close="false" :before-close="handleClose">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">导出人员列表</h4>
- <div class="flex">
- <el-button @click="dialogFrom.exportUserVisible = false">取消</el-button>
- <el-button type="primary" @click="exportUser" v-bind:loading="loadingFrom.exportUserLoading">
- 导出
- </el-button>
- </div>
- </div>
- </template>
- <div class="pt-4 pb-2">
- <div class="flex items-center justify-center">
- <div class="pr-2">导出:</div>
- <el-radio-group v-model="exportRadio" class="ml-4">
- <el-radio value="1" size="large">全部人员</el-radio>
- <el-radio value="0" size="large">仅在职人员</el-radio>
- </el-radio-group>
- </div>
- </div>
- </el-dialog>
- <!-- 人员导入 -->
- <el-dialog v-model="dialogFrom.importVisible" width="680" :show-close="false" top="10vh">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">人员批量导入</h4>
- <div class="flex">
- <el-button class="mr-3" @click="dialogFrom.importVisible = false">取消</el-button>
- <el-upload ref="importUserRef" class="upload-demo" :limit="1" :show-file-list="false" accept=".xlsx"
- :http-request="importUser">
- <el-button type="primary" :loading="loadingFrom.importLoading">导入</el-button>
- </el-upload>
- </div>
- </div>
- </template>
- <div class="p-8">
- <div class="ml-4 mr-4">
- <div class="flex items-center">1、点击下载 <el-link type="primary"
- @click="downloadFile('/upload/人员导入模板.xlsx', '人员导入模板.xlsx')">人员导入模板.xlsx</el-link></div>
- <div class="mt-4">2、填写excel模板,并上传</div>
- </div>
- </div>
- </el-dialog>
- <!-- 同步企业微信通讯录 -->
- <el-dialog v-model="dialogFrom.newSyncWithCorpWxDayloadVisable" width="600" :show-close="false"
- :before-close="handleClose">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">同步企微通讯录</h4>
- <div class="flex">
- <el-button @click="dialogFrom.newSyncWithCorpWxDayloadVisable = false">取消</el-button>
- <el-button type="primary" :loading="loadingFrom.newSyncWithCorpWxDayloadLoading"
- @click="newSyncWithCorpWx()">
- 开始同步
- </el-button>
- </div>
- </div>
- </template>
- <div class="pt-4 px-12 py-2">
- 同步前请联系企业微信管理员检查应用授权的可见范围路径:管理企业-应用管理-工时管家-可见范围
- </div>
- </el-dialog>
- <!-- 公众号配置 -->
- <el-dialog v-model="dialogFrom.officialAccountSettingVisable" width="600" :show-close="false"
- :before-close="handleClose" :close="closeOfficialAccountInformation(officialAccountInformationRef)">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">公众号配置</h4>
- <div class="flex">
- <el-button @click="dialogFrom.officialAccountSettingVisable = false">取消</el-button>
- <el-button type="primary" :loading="loadingFrom.officialAccountSettingLoading"
- @click="configureOfficialAccountInformation(officialAccountInformationRef)">
- 配置
- </el-button>
- </div>
- </div>
- </template>
- <div class="pt-4 px-12 py-2">
- <!-- <el-form ref="officialAccountInformationRef" :model="officialAccountInformationFrom"
- :rules="officialAccountInformationFromRules" label-width="auto" class="demo-ruleForm">
- <el-form-item label="名称:" prop="companyName">
- <el-input v-model="officialAccountInformationFrom.companyName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="appId:" prop="appId">
- <el-input v-model="officialAccountInformationFrom.appId" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="appSecret:" prop="appSecret">
- <el-input v-model="officialAccountInformationFrom.appSecret" placeholder="请输入" />
- </el-form-item>
- </el-form> -->
- <div class="flex items-center mb-4">
- <div class="w-[80px] text-right mr-3">名称</div>
- <el-input v-model="officialAccountInformationFrom.companyName" placeholder="请输入" />
- </div>
- <div class="flex items-center mb-4">
- <div class="w-[80px] text-right mr-3">appId</div>
- <el-input v-model="officialAccountInformationFrom.appId" placeholder="请输入" />
- </div>
- <div class="flex items-center mb-4">
- <div class="w-[80px] text-right mr-3">appSecret</div>
- <el-input v-model="officialAccountInformationFrom.appSecret" placeholder="请输入" />
- </div>
- <el-text class="mx-1" type="warning">请联系客服, 获取ip白名单参数, 配置后方可生效</el-text>
- </div>
- </el-dialog>
- <!-- 新增人员 -->
- <AddPersonnelModal :data="{
- addPersonnelDialogVisible: dialogFrom.addPersonnelDialogVisible,
- deptList: deptListUntreated,
- roleList: roleList,
- personnelFromData: personnelFromData
- }" @closeModal="closeModal" @personnelModalConfirm="personnelModalConfirm" />
- <!-- 批量操作 -->
- <BatchOperation :batchData="visibleData" :batchNode="batchTableData" :visibleText="allText.batchText"
- :popup="visibleType" :batchOperationVisible="dialogFrom.batchOperationVisible" @close="closeModal" />
- <!-- 图片预览 -->
- <el-image-viewer v-if="showPreview" :url-list="previewSrcList" show-progress :initial-index="0"
- @close="showPreview = false" />
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, reactive, onMounted, onBeforeMount, inject } from 'vue';
- import { UploadRequestOptions, dayjs, ElLoading, ElNotification } from 'element-plus'
- import { Search, CirclePlusFilled, Edit, CirclePlus, Delete, PictureFilled } from '@element-plus/icons-vue'
- import { FormInstance, FormRules, ElMessageBox } from 'element-plus'
- import { useStore } from '@/store/index'
- import { GET_DATA_LIST, DETELE_DEPT, MOD, GET_USERINFO, GET_ROUTELIST, DEACTIVEUSER, SETACTIVE, GET_DEPTLIST, BACTHSERROLE, GET_USERLIST, GET_ADDDEPT, ADD_USER, SETRESETPWD, EXPOERTUSER, EDIT_ADDDEPT, GET_COMPANY_WEI_XIN, SAVE_OR_UPDATE, ONE_CLICK_GENERATION, EXPORT_QR_CODE } from './api'
- import { post, uploadFile, downloadFileRequest } from "@/utils/request";
- import { getFromValue, updateDepTreeData, resetFromValue, confirmAction, downloadFile } from '@/utils/tools'
- import { storeToRefs } from 'pinia';
- import personnelSearch from '@/components/translationComponent/personnelSearch/personnelSearch.vue';
- // 导入页面
- import AddPersonnelModal from './module/AddPersonnelModal.vue'
- import BatchOperation from './module/BatchOperation.vue'
- import { formatDate } from '@/utils/times';
- import { URL_IMPORTTHREAD } from '../thread/constant';
- const { getFunctionList, getUserInfoVal } = useStore()
- const { userInfo } = storeToRefs(useStore());
- const globalPopup = inject<GlobalPopup>('globalPopup')
- // 定义类型
- interface deptRuleForm { // 部门表单类型
- name: string,
- id: string | number,
- parentId: string | number,
- managerId: string | number,
- otherManagerIds: string[] | number[],
- }
- interface officialAccountInformationInterface { // 公众号类型
- id?: string | number,
- companyName: string,
- appId: string,
- appSecret: string,
- }
- // 固定数据
- const stateOptions = [{ value: '3', label: '全部' }, { value: '1', label: '在职' }, { value: '0', label: '停用' }]
- // ref
- const importUserRef = ref<any>()
- // 定义变量
- const transitiondata = ref<any>() // 过度数据(针对二次弹窗)
- const pagePermission: any = ref([]) // 功能权限
- const loadingFrom = reactive({ // 所有加载状态
- tableLoading: false,
- deptDialogVisibleLoading: false,
- resignationLoading: false,
- exportUserLoading: false,
- importLoading: false,
- newSyncWithCorpWxDayloadLoading: false,
- officialAccountSettingLoading: false,
- })
- const dialogFrom: any = reactive({ // 所有弹窗状态
- addDeptDialogVisible: false,
- addPersonnelDialogVisible: false,
- batchOperationVisible: false,
- resignationVisible: false,
- exportUserVisible: false,
- importVisible: false,
- newSyncWithCorpWxDayloadVisable: false,
- officialAccountSettingVisable: false,
- });
- const allText = reactive({
- batchText: '批量操作'
- })
- const visibleType = ref<batchOperationType>('dept') // 弹窗类型
- const visibleData = ref<any>([]) // 批量弹窗数据源
- const totalTable = ref(0) // 表格总数
- const tableData: any = ref([]) // 表格数据
- const roleList: any = ref([]) // 角色列表
- const userList: any = ref([]) // 用户列表
- const deptList: any = ref([]) // 部门数据
- const batchTableData: any = ref([]) // 批量数据
- const multipleTableRef: any = ref()
- const deptListUntreated: any = ref([]) // 部门数据(未处理)
- const deptListItem: any = ref({}) // 选中的部门数据
- const personnelFromData = ref({}) // 人员表单数据
- const resignationDate = ref(formatDate(new Date())) // 员工离职日期
- const exportRadio = ref('1') // 导出人员列表
- const teamForm = reactive({ // 筛选条件表单
- matchingType: 0,
- keyword: '',
- status: '3',
- pageIndex: 1,
- pageSize: 20,
- roleId: '',
- onlyDirect: '',
- departmentId: '-1',
- });
- const deptRuleFormRef = ref<FormInstance>() // 表单实例
- const deptForm = reactive<deptRuleForm>({ // 部门表单
- name: '',
- id: '',
- parentId: '',
- managerId: '',
- otherManagerIds: [],
- })
- const treeProps = { // 部门树配置
- children: 'children',
- label: 'label',
- }
- const officialAccountInformation = ref<officialAccountInformationInterface>({
- id: '',
- companyName: '',
- appId: '',
- appSecret: '',
- })
- const officialAccountInformationFrom = reactive<officialAccountInformationInterface>({
- id: '',
- companyName: '',
- appId: '',
- appSecret: '',
- })
- const officialAccountInformationRef = ref<FormInstance>()
- const showPreview = ref(false)
- const previewSrcList = ref<string[]>([])
- // 定义校验规则
- const deptRules = reactive<FormRules<typeof deptForm>>({ // 部门表单校验规则
- name: [{ required: true, trigger: 'blur', message: '请输入部门名称' }]
- })
- const officialAccountInformationFromRules = reactive<FormRules<typeof officialAccountInformation>>({
- companyName: [{ required: true, trigger: 'blur', message: '请输入' }],
- appId: [{ required: true, trigger: 'blur', message: '请输入' }],
- appSecret: [{ required: true, trigger: 'blur', message: '请输入' }]
- })
- function viewQrCode(row: any) {
- const { wxImgUrlWithTicket = '' } = row
- previewSrcList.value = [wxImgUrlWithTicket]
- showPreview.value = true
- }
- function exportQrCode() {
- ElNotification({
- title: '提示',
- message: '二维码导出中...',
- type: 'info',
- showClose: false,
- duration: 0
- })
- downloadFileRequest(EXPORT_QR_CODE, {}).then((blob) => {
- const url = window.URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = url;
- link.setAttribute('download', '员工销售二维码.zip'); // 根据需要设定文件名
- document.body.appendChild(link);
- link.click();
- link.remove();
- window.URL.revokeObjectURL(url);
- globalPopup?.showSuccess('下载中 请稍后')
- })
- }
- // 同步企业微信通讯录
- function newSyncWithCorpWx() {
- const loading = ElLoading.service({
- lock: true,
- text: 'Loading',
- background: 'rgba(0, 0, 0, 0.7)',
- })
- post(`/wxcorp/getCorpMembsFromPlatform`, { companyId: userInfo.value.companyId }).then(() => {
- globalPopup?.showSuccess('同步成功')
- dialogFrom.newSyncWithCorpWxDayloadVisable = false
- getRoleList()
- getUserList()
- getTableData()
- getDeptList()
- }).finally(() => {
- loading.close();
- })
- }
- // 定义方法
- async function importUser(param: UploadRequestOptions) {
- loadingFrom.importLoading = true
- const formData = new FormData();
- formData.append('file', param.file)
- const res = await uploadFile(URL_IMPORTTHREAD, formData).finally(() => {
- importUserRef.value.clearFiles()
- loadingFrom.importLoading = false
- })
- loadingFrom.importLoading = false
- if (res.code == 'ok') {
- globalPopup?.showSuccess('导入成功')
- closeModal('importVisible')
- getTableData()
- return
- }
- globalPopup?.showError(res.msg || '')
- }
- // 获取公众号配置信息
- function getCompanyWeiXin() {
- post(GET_COMPANY_WEI_XIN, {}).then((res) => {
- const { companyName = '', id = '', appId = '', appSecret = '' } = res.data
- officialAccountInformation.value = {
- id, companyName, appId, appSecret
- }
- })
- }
- function oneClickGenerationOfQrCode() {
- ElNotification({
- title: '提示',
- message: '生成二维码中...',
- type: 'info',
- showClose: false,
- duration: 0
- })
- post(ONE_CLICK_GENERATION, {}).then(() => {
- globalPopup?.showSuccess('生成成功')
- getTableData()
- })
- }
- async function configureOfficialAccountInformation(_formEl: FormInstance | undefined) {
- // if (!formEl) return
- // await formEl.validate((valid) => {
- // if (valid) {
- const { companyName, appId, appSecret } = officialAccountInformationFrom
- if(!companyName || !appId || !appSecret) {
- globalPopup?.showError('请填写完整')
- return
- }
- confirmAction('确定保存当前公众号的配置吗?', '公众号配置', 'warning').then(() => {
- loadingFrom.officialAccountSettingLoading = true
- post(SAVE_OR_UPDATE, getFromValue(officialAccountInformationFrom)).then(() => {
- globalPopup?.showSuccess('配置成功')
- closeModal('officialAccountSettingVisable')
- getCompanyWeiXin()
- }).finally(() => {
- loadingFrom.officialAccountSettingLoading = false
- })
- })
- // }
- // })
- }
- function closeOfficialAccountInformation(formEl: FormInstance | undefined) {
- if (!formEl) return
- formEl.resetFields()
- }
- function officialAccountSetting() {
- Object.assign(officialAccountInformationFrom, officialAccountInformation.value || {
- id: '',
- companyName: '',
- appId: '',
- appSecret: ''
- })
- dialogFrom.officialAccountSettingVisable = true
- }
- function exportUser() {
- loadingFrom.exportUserLoading = true
- post(EXPOERTUSER, { containInvalid: exportRadio.value }).then((res) => {
- downloadFile(`${res.data}`, '人员列表.xlsx')
- globalPopup?.showSuccess('导出成功')
- closeModal('exportUserVisible')
- }).finally(() => {
- loadingFrom.exportUserLoading = false
- })
- }
- function enableUser(row: any) {
- const id = row.id
- post(SETACTIVE, { id, isActive: 1 }).then(() => {
- globalPopup?.showSuccess('启用成功')
- getTableData()
- })
- }
- function resignation() {
- const id = transitiondata.value.id || ''
- loadingFrom.resignationLoading = true
- post(DEACTIVEUSER, { id, inactiveDate: resignationDate.value }).then(() => {
- globalPopup?.showSuccess('停用成功')
- getTableData()
- closeModal('resignationVisible')
- }).finally(() => {
- loadingFrom.resignationLoading = false
- })
- }
- function resetPwd(row: any) {
- const userId = row.id
- confirmAction(`确定要为${row.name}重置密码吗?`, '重置密码').then(() => {
- post(SETRESETPWD, { userId }).then(() => {
- globalPopup?.showSuccess('密码已重置为000000,请通知员工及时修改')
- }).catch((err) => {
- globalPopup?.showError(err.msg)
- })
- })
- }
- function batchEnableItem() {
- const userIds = batchTableData.value.map((item: any) => item.id)
- post(BACTHSERROLE, { ids: JSON.stringify(userIds), isActive: 1 }).then(() => {
- globalPopup?.showSuccess('操作成功')
- changeBatch(false)
- getTableData()
- }).catch((err) => {
- globalPopup?.showError(err.msg)
- })
- }
- function changeBatch(flag: boolean = true) {
- if (flag) {
- batchTableData.value = multipleTableRef.value && multipleTableRef.value.getSelectionRows()
- } else {
- batchTableData.value = []
- multipleTableRef.value && multipleTableRef.value.clearSelection()
- }
- }
- function addPersone(item: any) {
- if (!item) {
- personnelFromData.value = {}
- dialogFrom.addPersonnelDialogVisible = true
- return
- }
- post(GET_USERINFO, { userId: item.id }).then(res => {
- const { id, name, phone, jobNumber, roleId, departmentCascade, departmentId, inductionDate } = res.data
- let newData = {
- id, name, phone, jobNumber, roleId,
- // departmentId: departmentCascade && departmentCascade.split(',').map(Number).reverse(),
- departmentId: departmentId,
- inductionDate
- }
- personnelFromData.value = newData
- dialogFrom.addPersonnelDialogVisible = true
- })
- }
- async function personnelModalConfirm(data: any, modelType: string) {
- post(ADD_USER, { ...data }).then(res => {
- if (res.code != 'ok') {
- dialogFrom[modelType] = false
- globalPopup?.showError(res.msg)
- return
- }
- dialogFrom[modelType] = false
- globalPopup?.showSuccess('添加成功')
- getTableData()
- }).catch(_err => {
- dialogFrom[modelType] = false
- })
- }
- function createDepartment(formEl: FormInstance | undefined) {
- if (!formEl) return
- let data = getFromValue(deptForm)
- loadingFrom.deptDialogVisibleLoading = true
- EDIT_ADDDEPT
- post(data.id ? EDIT_ADDDEPT : GET_ADDDEPT, { ...deptForm, otherManagerIds: data.otherManagerIds && data.otherManagerIds.join(',') }).then(res => {
- if (res.code != 'ok') {
- loadingFrom.deptDialogVisibleLoading = false
- globalPopup?.showError(res.msg)
- return
- }
- loadingFrom.deptDialogVisibleLoading = false
- globalPopup?.showSuccess(data.id ? '修改成功' : '创建成功')
- getDeptList()
- dialogFrom.addDeptDialogVisible = false
- }).catch(_err => {
- loadingFrom.deptDialogVisibleLoading = false
- })
- }
- function updateDepartment(type: string) {
- if (!deptListItem.value.id || deptListItem.value.id <= 0) return
- const { id, label, parentId, managerId, otherManagerIds } = deptListItem.value
- console.log(deptListItem.value)
- let data = { id, name: label, parentId, managerId, otherManagerIds }
- Object.assign(deptForm, data)
- dialogFrom[type] = true
- }
- function treeNode(item: any) {
- deptListItem.value = item
- teamForm.departmentId = item.id
- getTableData()
- }
- function deteleDept(data: any) {
- console.log(data)
- ElMessageBox.confirm(
- `确定删除【${data.label}】部门吗?`, '',
- {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }
- )
- .then(() => {
- post(DETELE_DEPT, { id: data.id }).then(res => {
- if (res.code != 'ok') {
- globalPopup?.showError(res.msg)
- return
- }
- globalPopup?.showSuccess('删除成功')
- getDeptList()
- })
- })
- }
- function getTableData() {
- loadingFrom.tableLoading = true
- post(GET_DATA_LIST, { ...teamForm }).then(res => {
- if (res.code != 'ok') {
- loadingFrom.tableLoading = false
- globalPopup?.showError(res.msg)
- return
- }
- loadingFrom.tableLoading = false
- totalTable.value = res.data.total
- tableData.value = res.data.records
- }).catch(_err => {
- loadingFrom.tableLoading = false
- })
- }
- function getRoleList() {
- const companyId = getUserInfoVal('companyId') || ''
- post(GET_ROUTELIST, { companyId }).then(res => {
- if (res.code != 'ok') {
- globalPopup?.showError(res.msg)
- return
- }
- roleList.value = res.data
- })
- }
- function getDeptList() {
- post(GET_DEPTLIST, {}).then(res => {
- if (res.code != 'ok') {
- globalPopup?.showError(res.msg)
- return
- }
- deptListUntreated.value = updateDepTreeData(res.data, false)
- deptList.value = updateDepTreeData(res.data, true)
- })
- }
- function getUserList() {
- post(GET_USERLIST, {}).then(res => {
- if (res.code != 'ok') {
- globalPopup?.showError(res.msg)
- return
- }
- userList.value = res.data
- })
- }
- function mouseleave(data: any, $event: Event) {
- if (data.id <= 0) return;
- const target = $event.currentTarget as HTMLElement;
- const iconElement = target.querySelector('#treeIcon');
- if (iconElement) {
- iconElement.setAttribute("class", "treeIcon nodeEle");
- }
- }
- function mouseover(data: any, $event: MouseEvent) {
- if (data.id <= 0) return;
- const target = $event.currentTarget as HTMLElement;
- const iconElement = target.querySelector('#treeIcon');
- if (iconElement) {
- iconElement.setAttribute("class", "treeIcon");
- }
- }
- function dialogFromCli(type: string, data: any = {}, flag: boolean = false) {
- resetDialog()
- if (flag) {
- const { id } = data
- deptForm.parentId = id
- }
- dialogFrom[type] = true
- }
- function handleSizeChange(val: number) {
- teamForm.pageIndex = 1
- teamForm.pageSize = val
- getTableData()
- }
- function handleCurrentChange(val: number) {
- teamForm.pageIndex = val
- getTableData()
- }
- function resetDialog() {
- let newDeptForm = resetFromValue(deptForm)
- Object.assign(deptForm, newDeptForm)
- }
- function batchItem(text: string, type: batchOperationType, data: any) {
- allText.batchText = text,
- visibleType.value = type
- visibleData.value = data
- dialogFrom.batchOperationVisible = true
- }
- function handleClose(done: any) {
- done()
- }
- function transitionOperation(type: string, data: any) {
- if (type == 'disable') { // 停用
- resignationDate.value = formatDate(new Date())
- console.log(resignationDate.value, '<==== 离职')
- dialogFrom.resignationVisible = true
- } else if (type == 'exportUser') { // 导出
- exportRadio.value = '1'
- dialogFrom.exportUserVisible = true
- } else if (type == 'importUser') { // 导入
- dialogFrom.importVisible = true
- }
- transitiondata.value = data
- }
- function closeModal(modelType: string, flag: boolean = false) {
- dialogFrom[modelType] = false
- if (flag) {
- changeBatch(false)
- getTableData()
- }
- }
- onBeforeMount(() => {
- pagePermission.value = getFunctionList(MOD)
- })
- onMounted(() => {
- getRoleList()
- getUserList()
- getTableData()
- getDeptList()
- getCompanyWeiXin()
- });
- </script>
- <style lang="scss" scoped>
- .teamstyle {
- .team-header {
- padding: 0.75rem 1.25rem;
- box-sizing: border-box
- }
- .textFont {
- font-size: 16px;
- }
- .textSpan {
- color: $fontGray;
- }
- }
- .const-left {
- padding: 0.75rem 0;
- .treeContent {
- width: 87%;
- .custom-tree-node {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- }
- .treeLabel {
- width: 80%;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .treeIcon {
- display: flex;
- align-items: center;
- justify-self: flex-end;
- }
- .nodeEle {
- display: none;
- }
- }
- }
- .operation {
- cursor: pointer;
- }
- </style>
- <style>
- .temaClass .el-tree-node {
- padding: 4px 0;
- }
- </style>
|