candidateList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. <!--
  2. * @Description: create
  3. * @Version: 1.0
  4. * @Autor: XuTongZhang
  5. * @Date: 2020-07-28 15:25:06
  6. * @LastEditors: XuTongZhang
  7. * @LastEditTime: 2020-08-07 09:55:05
  8. -->
  9. <template>
  10. <div class="indexPage">
  11. <v-input
  12. :btn="isCollapse?isCollapse===1?btn1:btn2:btn0"
  13. :list="list"
  14. :key="isCollapse+3"
  15. @del="delAll"
  16. @search="search"
  17. @through="throughAll"
  18. @notice="noticeAll"
  19. @eliminate="eliminateAll"
  20. ></v-input>
  21. <el-radio-group v-model="isCollapse" size="medium" style="margin-bottom: 20px;">
  22. <el-radio-button :label="0">候选人列表</el-radio-button>
  23. <el-radio-button :label="1">已通过候选人</el-radio-button>
  24. <el-radio-button :label="2">已淘汰候选人</el-radio-button>
  25. </el-radio-group>
  26. <v-table
  27. :key="isCollapse"
  28. :table="isCollapse===2?table2:table"
  29. :tableList="tableList"
  30. :sortType="true"
  31. :form="searchForm"
  32. :queryData="queryData"
  33. @details="details"
  34. @eliminate="eliminate"
  35. @through="through"
  36. @notice="notice"
  37. @del="del"
  38. @selection-change="selection"
  39. id="id"
  40. ></v-table>
  41. <v-pager @page="callPage" :total="totalrecords"></v-pager>
  42. <el-dialog
  43. :visible.sync="dialogFormVisible"
  44. width="600px"
  45. :before-close="close"
  46. :show-close="false"
  47. >
  48. <el-form :model="form" ref="form" label-width="140px" :rules="rules" label-position="left">
  49. <el-form-item label-width="0">
  50. <div class="title">通知群发列表</div>
  51. <div class="content">
  52. <el-tag
  53. v-for="(item, index) in copyPickList"
  54. :key="item"
  55. closable
  56. @close="copyPickList.splice(index, 1)"
  57. type="success"
  58. >{{tableList.some(i => i.id === item) ? tableList.find(i => i.id === item).delivererName : ''}}</el-tag>
  59. </div>
  60. </el-form-item>
  61. <el-form-item label="选择群发模板" prop="templateId">
  62. <el-select v-model="form.templateId" placeholder="请选择群发模板">
  63. <el-option
  64. v-for="item in downList"
  65. :key="item.id"
  66. :label="item.templateName"
  67. :value="item.id"
  68. ></el-option>
  69. </el-select>
  70. <!-- <div v-else>{{this.downList1.some(i => i.id === form.processId) ? this.downList1.find(i => i.id === form.processId).processName : ''}}</div> -->
  71. </el-form-item>
  72. <el-form-item label="群发邮箱">139820930@qq.com</el-form-item>
  73. <el-form-item>
  74. <el-button type="primary" @click="launch">立即发出</el-button>
  75. </el-form-item>
  76. </el-form>
  77. </el-dialog>
  78. <resume :dialogFormVisible="dialogVisible" :close="closeDia" :info="info" :searchForm="searchForm" :queryData="queryData"></resume>
  79. </div>
  80. </template>
  81. <script>
  82. import resume from './resume'
  83. export default {
  84. data () {
  85. return {
  86. dialogFormVisible: false,
  87. dialogVisible: false,
  88. tableList: [],
  89. page: 1,
  90. isCollapse: 0,
  91. totalrecords: 0,
  92. pickList: [],
  93. copyPickList: [],
  94. downList: [],
  95. searchForm: {},
  96. form: {},
  97. info: {},
  98. rules: {
  99. templateId: [
  100. { required: true, message: '请选择群发模板', trigger: 'blur' }
  101. ]
  102. },
  103. list: [
  104. {
  105. placeholder: '请输入关键字查询',
  106. props: 'condition'
  107. },
  108. {
  109. type: 'select',
  110. placeholder: '性别',
  111. props: 'delivererSex',
  112. options: [
  113. { label: '男', value: 1 },
  114. { label: '女', value: 0 }
  115. ]
  116. },
  117. {
  118. type: 'select',
  119. placeholder: '来源',
  120. props: 'resumeFrom',
  121. options: [
  122. { label: '51job', value: 0 },
  123. { label: '智联', value: 1 },
  124. { label: '58同城', value: 2 }
  125. ]
  126. },
  127. {
  128. placeholder: '请输入投递职位',
  129. props: 'positionApplied'
  130. },
  131. {
  132. type: 'select',
  133. placeholder: '应聘职位',
  134. props: 'desiredPositionId',
  135. options: []
  136. },
  137. {
  138. type: 'date'
  139. }
  140. ],
  141. btn0: [
  142. {
  143. name: '确定',
  144. type: 'primary',
  145. method: 'search'
  146. },
  147. {
  148. name: '标记通过',
  149. type: 'success',
  150. method: 'through'
  151. },
  152. {
  153. name: '标记淘汰',
  154. type: 'danger',
  155. method: 'eliminate'
  156. }
  157. ],
  158. btn1: [
  159. {
  160. name: '确定',
  161. type: 'primary',
  162. method: 'search'
  163. },
  164. {
  165. name: '通知成功',
  166. type: 'success',
  167. method: 'notice'
  168. }
  169. ],
  170. btn2: [
  171. {
  172. name: '确定',
  173. type: 'primary',
  174. method: 'search'
  175. },
  176. {
  177. name: '标记通过',
  178. type: 'success',
  179. method: 'through'
  180. },
  181. {
  182. name: '删除',
  183. type: 'danger',
  184. method: 'del'
  185. }
  186. ],
  187. table: {
  188. selection: true,
  189. column: [
  190. {
  191. label: '编号',
  192. props: 'id'
  193. },
  194. {
  195. label: '姓名',
  196. props: 'delivererName'
  197. },
  198. {
  199. label: '性别',
  200. props: 'delivererSex',
  201. options: ['女', '男']
  202. },
  203. {
  204. label: '简历来源',
  205. props: 'resumeFrom',
  206. options: ['51job', '智联招聘', '58同城']
  207. },
  208. {
  209. label: '招聘类型',
  210. props: 'recruitType',
  211. options: ['社招', '校招', '直接校招']
  212. },
  213. {
  214. label: '简历投递职位',
  215. props: 'positionApplied'
  216. },
  217. {
  218. label: '面试应聘职位',
  219. props: 'desiredPositionId'
  220. },
  221. {
  222. label: '工作年限',
  223. props: 'delivererWorkExp'
  224. },
  225. {
  226. label: '学历',
  227. props: 'delivererEducation'
  228. },
  229. {
  230. label: '联系电话',
  231. props: 'delivererPhone'
  232. },
  233. {
  234. label: '通知面试时间',
  235. props: 'sendMailTime'
  236. },
  237. {
  238. label: '完成面试时间',
  239. props: 'confirmInterviewTime'
  240. }
  241. ],
  242. width: 310,
  243. handle: [
  244. {
  245. title: '查看简历',
  246. method: 'details',
  247. type: 'info'
  248. },
  249. {
  250. title: '标记通过',
  251. method: 'through',
  252. type: 'success'
  253. },
  254. {
  255. title: '标记淘汰',
  256. method: 'eliminate',
  257. type: 'danger'
  258. }
  259. ]
  260. },
  261. table2: {
  262. selection: true,
  263. column: [
  264. {
  265. label: '编号',
  266. props: 'id'
  267. },
  268. {
  269. label: '姓名',
  270. props: 'delivererName'
  271. },
  272. {
  273. label: '性别',
  274. props: 'delivererSex',
  275. options: ['女', '男']
  276. },
  277. {
  278. label: '简历来源',
  279. props: 'resumeFrom',
  280. options: ['51job', '智联招聘', '58同城']
  281. },
  282. {
  283. label: '简历投递职位',
  284. props: 'positionApplied'
  285. },
  286. {
  287. label: '面试应聘职位',
  288. props: 'desiredPositionId'
  289. },
  290. {
  291. label: '工作年限',
  292. props: 'delivererWorkExp'
  293. },
  294. {
  295. label: '学历',
  296. props: 'delivererEducation'
  297. },
  298. {
  299. label: '联系电话',
  300. props: 'delivererPhone'
  301. },
  302. {
  303. label: '被标记未通过时间',
  304. props: 'rejectTime'
  305. },
  306. {
  307. label: '理由',
  308. props: 'rejectReason'
  309. }
  310. ],
  311. width: 300,
  312. handle: [
  313. {
  314. title: '查看简历',
  315. method: 'details',
  316. type: 'info'
  317. },
  318. {
  319. title: '标记通过',
  320. method: 'through',
  321. type: 'success'
  322. },
  323. {
  324. title: '删除',
  325. method: 'del',
  326. type: 'danger'
  327. }
  328. ]
  329. }
  330. }
  331. },
  332. mounted () {
  333. this.queryData()
  334. this.queryDownList()
  335. },
  336. components: {
  337. resume
  338. },
  339. methods: {
  340. queryData (form = {}) {
  341. let page = this.page
  342. this.searchForm = form
  343. let reqdata = form
  344. reqdata.interviewResult = this.isCollapse
  345. this.$api
  346. .post('/resumeInfo/queryCandidateList', {
  347. reqdata,
  348. page
  349. })
  350. .then((res) => {
  351. this.totalrecords = res.totalrecords
  352. this.tableList = res.list
  353. })
  354. },
  355. queryDownList () {
  356. this.$api
  357. .post('/position/queryPositionList', {
  358. reqdata: {}
  359. })
  360. .then((res) => {
  361. this.list[4].options = res.list.map((item) => ({
  362. value: item.id,
  363. label: item.positionName
  364. }))
  365. })
  366. this.$api
  367. .post('/template/queryTemplateList', {
  368. reqdata: {}
  369. })
  370. .then((res) => {
  371. this.downList = res.list
  372. })
  373. },
  374. search (form) {
  375. this.queryData(form)
  376. },
  377. details (row) {
  378. this.openDia()
  379. this.info = row
  380. },
  381. launch () {
  382. let a
  383. this.$refs['form'].validate((valid) => {
  384. a = valid
  385. })
  386. if (!a) return
  387. this.copyPickList.length
  388. ? this.$api
  389. .post('/resumeInfo/sendInviteMail', {
  390. reqdata: {
  391. ids: this.copyPickList,
  392. templateId: this.form.templateId
  393. }
  394. })
  395. .then((res) => {
  396. this.$message({
  397. message: '通知成功',
  398. type: 'success'
  399. })
  400. this.close()
  401. this.queryData(this.searchForm)
  402. })
  403. : this.$message({ type: 'info', message: '请添加需要通知的对象' })
  404. },
  405. notice (row) {
  406. this.open()
  407. this.copyPickList = [row.id]
  408. },
  409. noticeAll () {
  410. this.pickList.length
  411. ? this.open()
  412. : this.$message({ type: 'info', message: '请选择需要通知的对象' })
  413. },
  414. through (row, type = false) {
  415. let ids = type ? row : [row.id]
  416. let resumeInfoStatusList = ids.map(item => ({ id: item, interviewResult: 1 }))
  417. this.$api
  418. .post('/resumeInfo/changeInterviewResult', {
  419. reqdata: {
  420. resumeInfoStatusList
  421. }
  422. })
  423. .then((res) => {
  424. this.queryData(this.searchForm)
  425. })
  426. },
  427. throughAll () {
  428. this.pickList.length
  429. ? this.through(this.pickList, true)
  430. : this.$message({ type: 'info', message: '请选择通过的应聘者' })
  431. },
  432. eliminate (row, type = false) {
  433. let ids = type ? row : [row.id]
  434. let resumeInfoStatusList = ids.map(item => ({ id: item, interviewResult: 2 }))
  435. this.$api
  436. .post('/resumeInfo/changeInterviewResult', {
  437. reqdata: {
  438. resumeInfoStatusList
  439. }
  440. })
  441. .then((res) => {
  442. this.queryData(this.searchForm)
  443. })
  444. },
  445. eliminateAll () {
  446. this.pickList.length
  447. ? this.eliminate(this.pickList, true)
  448. : this.$message({ type: 'info', message: '请选择被淘汰的应聘者' })
  449. },
  450. del (row, type = false) {
  451. let ids = type ? row : [row.id]
  452. let deleteResumeInfoList = ids.map(item => ({ id: item, status: 1 }))
  453. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  454. confirmButtonText: '确定',
  455. cancelButtonText: '取消',
  456. type: 'warning'
  457. })
  458. .then(() => {
  459. this.$api
  460. .post('/resumeInfo/deleteResumeInfo', {
  461. reqdata: {
  462. deleteResumeInfoList
  463. }
  464. })
  465. .then((res) => {
  466. this.queryData(this.searchForm)
  467. this.$message({
  468. type: 'success',
  469. message: '删除成功!'
  470. })
  471. })
  472. })
  473. .catch(() => {
  474. this.$message({
  475. type: 'info',
  476. message: '已取消删除'
  477. })
  478. })
  479. },
  480. delAll () {
  481. this.pickList.length
  482. ? this.del(this.pickList, true)
  483. : this.$message({ type: 'info', message: '请选择需要删除的内容' })
  484. },
  485. selection (val) {
  486. this.$set(this.$data, 'pickList', val)
  487. },
  488. open () {
  489. this.dialogFormVisible = true
  490. },
  491. close () {
  492. this.dialogFormVisible = false
  493. this.form = {}
  494. this.copyPickList = Array.from(this.pickList)
  495. },
  496. closeDia () {
  497. this.dialogVisible = false
  498. },
  499. openDia () {
  500. this.dialogVisible = true
  501. },
  502. callPage (val) {
  503. this.page = val
  504. this.queryData(this.searchForm)
  505. }
  506. },
  507. watch: {
  508. isCollapse () {
  509. this.queryData(this.searchForm)
  510. this.isCollapse === 1
  511. ? this.$set(this.table, 'handle', [
  512. {
  513. title: '查看简历',
  514. method: 'details',
  515. type: 'info'
  516. },
  517. {
  518. title: '通知成功',
  519. method: 'notice',
  520. type: 'success'
  521. }
  522. ])
  523. : this.isCollapse === 0 && this.$set(this.table, 'handle',
  524. [
  525. {
  526. title: '查看简历',
  527. method: 'details',
  528. type: 'info'
  529. },
  530. {
  531. title: '标记通过',
  532. method: 'through',
  533. type: 'success'
  534. },
  535. {
  536. title: '标记淘汰',
  537. method: 'eliminate',
  538. type: 'danger'
  539. }
  540. ]
  541. )
  542. },
  543. pickList () {
  544. this.copyPickList = Array.from(this.pickList)
  545. }
  546. }
  547. }
  548. </script>