recommend.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <template>
  2. <a-modal
  3. :width="1400"
  4. v-model:visible="visible"
  5. :title="title"
  6. :confirm-loading="confirmLoading"
  7. @ok="handleOk"
  8. ok-text="确认"
  9. cancel-text="取消"
  10. :keyboard="false"
  11. :mask-closable="false"
  12. >
  13. <div class="card-search">
  14. <a-form
  15. ref="formRef"
  16. name="advanced_search"
  17. class="ant-advanced-search-form"
  18. :model="searchParams"
  19. >
  20. <a-row :gutter="24">
  21. <a-col :span="6">
  22. <a-form-item label="求职人员姓名" :label-col="{ span: 8 }" name="name">
  23. <a-input v-model:value="searchParams.jobUserName" style="color: black;" disabled="true" placeholder=""/>
  24. </a-form-item>
  25. </a-col>
  26. <a-col :span="6">
  27. <a-form-item label="求职岗位" :label-col="{ span: 8 }" name="professionName">
  28. <a-input v-model:value="searchParams.professionName" style="color: black;" disabled="true"
  29. placeholder=""/>
  30. </a-form-item>
  31. </a-col>
  32. <a-col :span="6">
  33. <a-form-item label="招聘企业" :label-col="{ span: 8 }" name="companyName">
  34. <!-- <a-input v-model:value="searchParams.companyName" placeholder=""/>-->
  35. <a-select ref="select" show-search optionFilterProp="label" allow-clear="true"
  36. v-model:value="searchParams.companyName" >
  37. <a-select-option v-for="item in companyList" :label="item.companyName" :value="item.companyName"
  38. :key="item.companyID" @change="companyChange">
  39. <span>{{ item.companyName }}</span>
  40. </a-select-option>
  41. </a-select>
  42. </a-form-item>
  43. </a-col>
  44. <a-col :span="6" style="text-align: left;">
  45. <a-button type="primary" html-type="submit" @click="onSearch">查询</a-button>
  46. <a-button
  47. style="margin: 0 8px"
  48. @click="
  49. () => {
  50. searchParams.pageIndex = 1;
  51. searchParams.pageSize = 10;
  52. searchParams.companyName = null;
  53. searchParams.parentProfessionID= '';
  54. searchParams.cultureRank= null;
  55. searchParams.workYear= null;
  56. searchParams.minSalary= null;
  57. searchParams.maxSalary= null;
  58. loadData();
  59. }
  60. ">重置
  61. </a-button>
  62. <!-- <a style="font-size: 12px" @click="expand = !expand">-->
  63. <!-- <template v-if="expand">-->
  64. <!-- <UpOutlined />-->
  65. <!-- </template>-->
  66. <!-- <template v-else>-->
  67. <!-- <DownOutlined />-->
  68. <!-- </template>-->
  69. <!-- {{ expand ? '收缩' : '展开' }}-->
  70. <!-- </a>-->
  71. </a-col>
  72. </a-row>
  73. <a-row :gutter="24">
  74. <a-col :span="6">
  75. <a-form-item label="招聘岗位" :label-col="{ span: 8 }" name="inviteProfessionName">
  76. <a-auto-complete
  77. v-model:value="searchParams.inviteProfessionName"
  78. :options="inviteProfessionList"
  79. @search="selectInviteProfessionList"
  80. @change="inviteProfessionChange"
  81. :field-names="{
  82. value:'professionName',
  83. }"
  84. >
  85. <template #option="item">
  86. <span v-html="formatStr(item.professionName)"></span>({{ item.parentProfessionName }})
  87. </template>
  88. </a-auto-complete>
  89. </a-form-item>
  90. </a-col>
  91. <a-col :span="12" v-if="searchParams.type===0">
  92. <a-form-item label="推荐岗位筛选:" :label-col="{ span: 4 }" name="recommendPostWhere">
  93. <!-- <div :style="{ borderBottom: '1px solid #E9E9E9' }">-->
  94. <!-- <a-checkbox-->
  95. <!-- v-model:checked="checkAll"-->
  96. <!-- :indeterminate="indeterminate"-->
  97. <!-- @change="onCheckAllChange">-->
  98. <!-- 全选-->
  99. <!-- </a-checkbox>-->
  100. <!-- </div>-->
  101. <a-checkbox-group v-model:value="checkRecommendPostWhereList" :options="recommendPostWhereList"/>
  102. </a-form-item>
  103. </a-col>
  104. </a-row>
  105. <a-row :gutter="24" >
  106. </a-row>
  107. <a-row class="edit-operation">
  108. <a-col :span="24" style="text-align: right">
  109. <a-button type="primary" v-if="searchParams.type===0" html-type="submit" functioncode="T01030207"
  110. @click='onBatchRecommend()'>批量推荐
  111. </a-button>
  112. </a-col>
  113. </a-row>
  114. </a-form>
  115. <div class="search-result-list">
  116. <a-table :columns="columns" :data-source="dataList" :scroll="{ x: '100%', y: 500 }" :pagination="pagination"
  117. :loading="formState.loading"
  118. :row-selection="{ selectedRowKeys: formState.selectedRowKeys, onChange: onSelectChange }"
  119. :row-key="(record) => record.recommendMgtID" bordered @change="handleTableChange">
  120. <template #bodyCell="{ column, text, record }">
  121. <template v-if="searchParams.type===0 && column.key === 'operation'">
  122. <div class="table-operation">
  123. <a-button type="link" size="small" @click='onRecommend(record)'>推荐</a-button>
  124. </div>
  125. </template>
  126. </template>
  127. </a-table>
  128. </div>
  129. </div>
  130. </a-modal>
  131. </template>
  132. <script lang="ts">
  133. import {reactive, ref, computed, defineComponent, toRefs, watch} from 'vue';
  134. import type {FormInstance, TableColumnsType, TableProps} from 'ant-design-vue';
  135. import {getRecommendCompanyPostList, addRecommend,getProfessionLikeList, getCompanyProfessionLikeList} from '@/api/jobUserManager/recommendMgt';
  136. import {getPaginationTotalTitle} from '@/utils/common';
  137. import dayjs from 'dayjs';
  138. import {message, SelectProps} from "ant-design-vue";
  139. import {getSysDictionaryList} from '@/api/system/dictionary';
  140. import {get} from "@/api/common";
  141. import {debounce} from "lodash-es";
  142. export default defineComponent({
  143. name: 'RecommendCompanyPostList',
  144. setup() {
  145. const visible = ref<boolean>(false);
  146. const confirmLoading = ref<boolean>(false);
  147. const formRef = ref<FormInstance>();
  148. const expand = ref(false);
  149. const title = ref<string>();
  150. const dataList = ref([]);
  151. const companyList = ref<SelectProps['options']>();
  152. const addRecommendList = ref([] as any);
  153. const recommendPostWhereList = ref([] as any);
  154. get('companyService/company/getList', {pageIndex: 1, pageSize: 9999}).then(result => {
  155. companyList.value = result.list;
  156. });
  157. function companyChange(value: any) {
  158. getCompanyProfessionLikeList({
  159. pageIndex: 1,
  160. pageSize: 30,
  161. professionName:"",
  162. companyName:value
  163. }).then(data => {
  164. inviteProfessionList.value = data.list;
  165. })
  166. }
  167. const searchParams = reactive({
  168. pageIndex: 1,
  169. pageSize: 10,
  170. jobUserName: null,
  171. professionName: null,
  172. inviteProfessionName: null,
  173. type: 0,
  174. jobHuntID: '',
  175. companyName: null,
  176. professionID: '',
  177. inviteProfessionID: '',
  178. parentProfessionID: '',
  179. cultureRank: null,
  180. workYear: null,
  181. minSalary: null,
  182. maxSalary: null
  183. });
  184. const formState = reactive({
  185. total: 0,
  186. selectedRowKeys: [],
  187. loading: false,
  188. });
  189. const state = reactive({
  190. indeterminate: true,
  191. checkAll: false,
  192. checkRecommendPostWhereList: [1],
  193. professionID: '',
  194. parentProfessionID: '',
  195. cultureRank: null,
  196. workYear: null,
  197. minSalary: null,
  198. maxSalary: null
  199. });
  200. const columns: TableColumnsType = [
  201. {
  202. title: '序号',
  203. align: 'center',
  204. width: 80,
  205. key: 'recommendMgtID',
  206. customRender: (item) =>
  207. `${searchParams.pageSize * (searchParams.pageIndex - 1) + item.index + 1}`,
  208. },
  209. {title: '企业名称', dataIndex: 'companyName', key: 'companyName', align: "center",},
  210. {title: '招聘岗位', dataIndex: 'professionName', key: 'professionName', align: "center",},
  211. {title: '要求学历', dataIndex: 'cultureRankName', key: 'cultureRankName', align: "center",},
  212. {title: '工作年限', dataIndex: 'workYearName', key: 'workYearName', align: "center",},
  213. {title: '招聘人数', dataIndex: 'recruitCount', key: 'recruitCount', align: "center",},
  214. {
  215. title: '薪资要求', dataIndex: 'salary', key: 'salary', align: "center",
  216. customRender: (item) => {
  217. const salary = showSalary(item.record.minSalary, item.record.maxSalary);
  218. return salary;
  219. }
  220. },
  221. {title: '工作地点', dataIndex: 'companyAddress', key: 'companyAddress', align: "center",},
  222. {
  223. title: '工作开始时间', dataIndex: 'startTime', key: 'startTime', align: "center",
  224. customRender: ({record}) => record.startTime == null ? "" : dayjs(record.startTime).format('YYYY-MM-DD'),
  225. },
  226. {
  227. title: '工作结束时间', dataIndex: 'endTime', key: 'endTime',align: "center",
  228. customRender: ({record}) => record.endTime == null ? "" : dayjs(record.endTime).format('YYYY-MM-DD'),
  229. },
  230. {title: '操作', key: 'operation', width: 60, align: 'center'},
  231. ];
  232. const pagination = computed(() => ({
  233. total: formState.total,
  234. current: searchParams.pageIndex,
  235. pageSize: searchParams.pageSize,
  236. showSizeChanger: true,
  237. showTotal: (total) => getPaginationTotalTitle(total),
  238. }));
  239. const onSelectChange = (selectedRowKeys: any) => {
  240. formState.selectedRowKeys = selectedRowKeys;
  241. };
  242. const handleTableChange: TableProps['onChange'] = (pag: {
  243. pageSize: number;
  244. current: number;
  245. }) => {
  246. searchParams.pageIndex = pag.current;
  247. searchParams.pageSize = pag.pageSize;
  248. loadData();
  249. };
  250. // 名称搜索关键字高亮
  251. const formatStr = (str: any) => {
  252. if (!str) {
  253. return "";
  254. }
  255. return str.replace(searchParams.inviteProfessionName, '<span style="color: coral">' + searchParams.inviteProfessionName + '</span>');
  256. }
  257. const inviteProfessionList = ref<Array<any>>([]);
  258. // 查询岗位
  259. const selectInviteProfessionList = debounce((professionName: string) => {
  260. if (professionName) {
  261. if(searchParams.companyName){
  262. getCompanyProfessionLikeList({
  263. pageIndex: 1,
  264. pageSize: 30,
  265. professionName:professionName,
  266. companyName:searchParams.companyName
  267. }).then(data => {
  268. inviteProfessionList.value = data.list;
  269. })
  270. }else{
  271. getProfessionLikeList({
  272. pageIndex: 1,
  273. pageSize: 30,
  274. professionName
  275. }).then(data => {
  276. inviteProfessionList.value = data.list;
  277. })
  278. }
  279. }
  280. }, 200)
  281. // 岗位名称变更
  282. function inviteProfessionChange(value: any) {
  283. searchParams.inviteProfessionName = value;
  284. console.log("当前搜索的招聘岗位名称",value);
  285. const profession = inviteProfessionList.value.find(prof => prof.professionName === value);
  286. if (profession) {
  287. searchParams.inviteProfessionID = profession.professionID;
  288. onSearch();
  289. } else {
  290. searchParams.inviteProfessionID = "";
  291. }
  292. }
  293. const onSearch = () => {
  294. searchParams.professionID = state.checkRecommendPostWhereList.findIndex(x => x == 1) >= 0 ? state.professionID : "";
  295. searchParams.cultureRank = state.checkRecommendPostWhereList.findIndex(x => x == 2) >= 0 ? state.cultureRank : null;
  296. searchParams.workYear = state.checkRecommendPostWhereList.findIndex(x => x == 3) >= 0 ? state.workYear : null;
  297. if (state.checkRecommendPostWhereList.findIndex(x => x == 4) >= 0) {
  298. searchParams.minSalary = state.minSalary;
  299. searchParams.maxSalary = state.maxSalary;
  300. } else {
  301. searchParams.minSalary = null;
  302. searchParams.maxSalary = null;
  303. }
  304. searchParams.parentProfessionID = state.checkRecommendPostWhereList.findIndex(x => x == 5) >= 0 ? state.parentProfessionID : "";
  305. loadData();
  306. }
  307. const loadData = async function () {
  308. formState.loading = true;
  309. const result: any = await getRecommendCompanyPostList(searchParams);
  310. dataList.value = result.list;
  311. formState.total = result.total;
  312. formState.loading = false;
  313. };
  314. const onCheckAllChange = (e: any) => {
  315. Object.assign(state, {
  316. checkRecommendPostWhereList: e.target.checked ? recommendPostWhereList.value.map(x => x.value) : [],
  317. indeterminate: false,
  318. });
  319. };
  320. watch(
  321. () => state.checkRecommendPostWhereList,
  322. val => {
  323. state.indeterminate = !!val.length && val.length < recommendPostWhereList.value.length;
  324. state.checkAll = val.length === recommendPostWhereList.value.length;
  325. },
  326. );
  327. const showSalary = (minSalary: any, maxSalary: any) => {
  328. if (minSalary != null) {
  329. if (maxSalary != null) {
  330. return minSalary.toString() + "-" + maxSalary.toString();
  331. } else {
  332. return "≥" + minSalary.toString();
  333. }
  334. } else {
  335. if (maxSalary != null) {
  336. return "≤" + maxSalary.toString();
  337. } else {
  338. return "";
  339. }
  340. }
  341. }
  342. const show = (professionID: any, professionName: any, jobHuntID: any, jobUserName: any, type: any,
  343. parentProfessionID: any, cultureRank: any, workYear: any, minSalary: any, maxSalary: any,
  344. titleName: string) => {
  345. visible.value = true;
  346. searchParams.jobHuntID = jobHuntID;
  347. searchParams.jobUserName = jobUserName;
  348. searchParams.professionID = professionID;
  349. searchParams.professionName = professionName;
  350. searchParams.type = type;
  351. searchParams.parentProfessionID = '';
  352. searchParams.cultureRank = null;
  353. searchParams.workYear = null;
  354. searchParams.minSalary = null;
  355. searchParams.maxSalary = null;
  356. state.checkRecommendPostWhereList = [1];
  357. state.professionID = professionID;
  358. state.parentProfessionID = parentProfessionID;
  359. state.cultureRank = cultureRank;
  360. state.workYear = workYear;
  361. state.workYear = workYear;
  362. state.minSalary = minSalary;
  363. state.maxSalary = maxSalary;
  364. title.value = titleName;
  365. loadData();
  366. }
  367. const onRecommend = (item: any) => {
  368. formState.selectedRowKeys = [];
  369. if(item){
  370. formState.selectedRowKeys.push(item.recommendMgtID as never);
  371. }
  372. addRecommendList.value.push({
  373. recommendMgtID: item.recommendMgtID,
  374. postID: item.postID,
  375. jobHuntID: searchParams.jobHuntID,
  376. recommendType: 1
  377. });
  378. addRecommend(addRecommendList.value).then((data) => {
  379. if(data!=-1){
  380. message.info("提交成功!");
  381. loadData();
  382. addRecommendList.value = [];
  383. }else{
  384. message.error("该岗位招聘日期已结束,不能推荐!");
  385. }
  386. });
  387. };
  388. const onBatchRecommend = () => {
  389. if (formState.selectedRowKeys.length == 0) {
  390. message.warn("请选择需要推荐的企业!")
  391. return;
  392. }
  393. formState.selectedRowKeys.forEach(id => {
  394. const item: any = dataList.value.find((x: any) => x.recommendMgtID == id)
  395. if (item) {
  396. addRecommendList.value.push({
  397. recommendMgtID: item.recommendMgtID,
  398. postID: item.postID,
  399. jobHuntID: searchParams.jobHuntID,
  400. recommendType: 1
  401. });
  402. }
  403. })
  404. addRecommend(addRecommendList.value).then((data) => {
  405. if(data!=-1){
  406. message.info("提交成功!");
  407. loadData();
  408. addRecommendList.value = [];
  409. }else{
  410. message.error("存在已停用或招聘日期已结束的岗位,推荐失败!");
  411. }
  412. });
  413. };
  414. const getRecommendPostWhereList = () => {
  415. getSysDictionaryList('RecommendPostWhere').then((data) => {
  416. recommendPostWhereList.value = data.map((x: any) => ({label: x.name, value: x.value}));
  417. });
  418. };
  419. const handleOk = () => {
  420. visible.value = false;
  421. };
  422. const handleCancel = () => {
  423. visible.value = false;
  424. };
  425. return {
  426. title,
  427. visible,
  428. confirmLoading,
  429. formRef,
  430. expand,
  431. searchParams,
  432. ...toRefs(state),
  433. formState,
  434. columns,
  435. pagination,
  436. dataList,
  437. companyList,
  438. inviteProfessionList,
  439. recommendPostWhereList,
  440. show,
  441. onSearch,
  442. formatStr,
  443. companyChange,
  444. inviteProfessionChange,
  445. showSalary,
  446. onCheckAllChange,
  447. onRecommend,
  448. onBatchRecommend,
  449. onSelectChange,
  450. handleTableChange,
  451. loadData,
  452. getRecommendPostWhereList,
  453. selectInviteProfessionList,
  454. handleOk,
  455. handleCancel
  456. };
  457. },
  458. mounted() {
  459. this.getRecommendPostWhereList();
  460. }
  461. });
  462. </script>
  463. <style lang="less" scoped></style>