index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <div class="card-search">
  3. <a-form
  4. ref="formRef"
  5. name="advanced_search"
  6. class="ant-advanced-search-form"
  7. :model="searchParamsState"
  8. >
  9. <a-row :gutter="24">
  10. <a-col :span="6">
  11. <a-form-item label="姓名" :label-col="{ span: 8 }" name="jobUserName">
  12. <a-input v-model:value="searchParamsState.jobUserName" placeholder=""/>
  13. </a-form-item>
  14. </a-col>
  15. <a-col :span="6">
  16. <a-form-item label="求职岗位" :label-col="{ span: 8 }" name="professionName">
  17. <a-input v-model:value="searchParamsState.professionName" placeholder=""/>
  18. </a-form-item>
  19. </a-col>
  20. <a-col :span="8">
  21. <a-form-item label="工作年限" :label-col="{ span: 6 }" name="workYear">
  22. <a-input-group compact>
  23. <a-input-number :min="0" :controls="false" v-model:value="searchParamsState.minWorkYear"
  24. style="width:110px;" placeholder=""/>
  25. <a-input placeholder="——" disabled style="width: 30px; border-left: 0;border-right: 0;
  26. pointer-events: none;background: #fff;margin-left: 1px; "/>
  27. <a-input-number :min="searchParamsState.minWorkYear" :controls="false" v-model:value="searchParamsState.maxWorkYear"
  28. style="width:110px;" placeholder=""/>
  29. </a-input-group>
  30. </a-form-item>
  31. </a-col>
  32. <a-col :span="4" style="text-align: left">
  33. <a-button type="primary" html-type="submit" @click="onSearch">查询</a-button>
  34. <a-button
  35. style="margin: 0 8px"
  36. @click="
  37. () => {
  38. searchParamsState.minWorkYear = null;
  39. searchParamsState.maxWorkYear = null;
  40. searchParamsState.minSalary = null;
  41. searchParamsState.maxSalary = null;
  42. formRef.resetFields();
  43. loadData();
  44. }
  45. ">重置
  46. </a-button>
  47. <a style="font-size: 12px" @click="expand = !expand">
  48. <template v-if="expand">
  49. <UpOutlined/>
  50. </template>
  51. <template v-else>
  52. <DownOutlined/>
  53. </template>
  54. {{ expand ? '收缩' : '展开' }}
  55. </a>
  56. </a-col>
  57. </a-row>
  58. <a-row :gutter="24" v-show="expand">
  59. <a-col :span="6">
  60. <a-form-item label="求职类型" :label-col="{ span: 8 }" name="jobHuntTypeID">
  61. <a-select ref="select"
  62. v-model:value="searchParamsState.jobHuntTypeID"
  63. :options="jobHuntTypeList"
  64. :field-names="{ label: 'name', value: 'value' }"
  65. :allow-clear="true"
  66. @change="loadData"
  67. >
  68. </a-select>
  69. </a-form-item>
  70. </a-col>
  71. <a-col :span="6">
  72. <a-form-item label="人才类型" :label-col="{ span: 8 }" name="jobUserTypeID">
  73. <a-select ref="select"
  74. v-model:value="searchParamsState.jobUserTypeID"
  75. :options="jobUserTypeList"
  76. :field-names="{ label: 'name', value: 'value' }"
  77. :allow-clear="true"
  78. @change="loadData">
  79. </a-select>
  80. </a-form-item>
  81. </a-col>
  82. <a-col :span="8">
  83. <a-form-item label="月薪要求" :label-col="{ span: 6 }" name="salary">
  84. <a-input-group compact>
  85. <a-input-number :min="0" :controls="false" v-model:value="searchParamsState.minSalary"
  86. style="width:110px;" placeholder=""/>
  87. <a-input placeholder="——" disabled style="width: 30px; border-left: 0;border-right: 0;
  88. pointer-events: none;background: #fff;margin-left: 1px; "/>
  89. <a-input-number :min="searchParamsState.minSalary" :controls="false" v-model:value="searchParamsState.maxSalary"
  90. style="width:110px;" placeholder=""/>
  91. </a-input-group>
  92. </a-form-item>
  93. </a-col>
  94. <a-col :span="4" style="text-align: left"></a-col>
  95. </a-row>
  96. <a-row :gutter="24" v-show="expand">
  97. <a-col :span="6">
  98. <a-form-item label="是否完成求职" :label-col="{ span: 8 }" name="isAccomplish">
  99. <a-select ref="select"
  100. v-model:value="searchParamsState.isAccomplish"
  101. :options="isAccomplishList"
  102. :field-names="{ label: 'name', value: 'value' }"
  103. :allow-clear="true"
  104. @change="loadData"
  105. >
  106. </a-select>
  107. </a-form-item>
  108. </a-col>
  109. <a-col :span="6">
  110. <a-form-item label="所属驿站" :label-col="{ span: 8 }" name="siteID">
  111. <a-select
  112. ref="select"
  113. v-model:value="searchParamsState.siteID"
  114. :options="siteList"
  115. :field-names="{ label: 'siteName', value: 'siteID' }"
  116. :allow-clear="true"
  117. @change="loadData"
  118. >
  119. </a-select>
  120. </a-form-item>
  121. </a-col>
  122. <a-col :span="6">
  123. <a-form-item label="所属县区" :label-col="{span:8}" name="regionCode">
  124. <a-select
  125. ref="select"
  126. v-model:value="searchParamsState.regionCode"
  127. :options="regionList"
  128. :field-names="{ label: 'name', value: 'code' }"
  129. :allow-clear="true"
  130. @change="loadData"
  131. >
  132. </a-select>
  133. </a-form-item>
  134. </a-col>
  135. </a-row>
  136. <a-row :gutter="24" v-show="expand">
  137. <a-col :span="6">
  138. <a-form-item label="登记时间" :label-col="{ span: 8 }" name="isAccomplish">
  139. <a-range-picker v-model:value="createDate" :placeholder="['开始日期', '结束日期']" format="YYYY-MM-DD"
  140. @change="onCreateTimeChange"/>
  141. </a-form-item>
  142. </a-col>
  143. </a-row>
  144. <a-row class="edit-operation">
  145. <a-col :span="24" class="flex-space-between">
  146. <div>
  147. <!-- 表格字段筛选按钮 -->
  148. <ColumnsSetting :table-columns="originalColumns" :checked-table-columns="columns"
  149. @on-check="columnsCheckSub"></ColumnsSetting>
  150. </div>
  151. <div>
  152. <a-button type="primary" html-type="submit" functioncode="T01030202" @click='onAdd'>新增</a-button>
  153. <BImportExcel functioncode="T01030205"
  154. :options="importOptions"
  155. @success="loadData"
  156. ></BImportExcel>
  157. <BExportExcel :title="'导出'" :filename="'求职意向信息'" :url="'jobUserService/jobHunt/export'"
  158. :params="{...exportSearchParams, rows:100000,jobHuntIDList:formState.selectedRowKeys.join(',')}"></BExportExcel>
  159. </div>
  160. </a-col>
  161. </a-row>
  162. </a-form>
  163. <div class="search-result-list">
  164. <a-table :columns="columns" :data-source="dataList" :scroll="{ x: '100%', y: 500 }" :pagination="pagination"
  165. :loading="formState.loading"
  166. :row-selection="{ selectedRowKeys: formState.selectedRowKeys, onChange: onSelectChange }"
  167. :row-key="(record) => record.jobHuntID" bordered @change="handleTableChange">
  168. <template #bodyCell="{ column, text, record }">
  169. <template v-if="column.key === 'recommendNum'">
  170. <div>
  171. <a-button type="link" size="small" @click='onRecommendInfo(record)'>{{ record.recommendNum }}</a-button>
  172. </div>
  173. </template>
  174. <template v-if="column.key === 'operation'">
  175. <div class="table-operation">
  176. <a-button type="link" size="small" functioncode="T01030201" @click="onDetail(record.jobHuntID)">查看
  177. </a-button>
  178. <a-button type="link" size="small" functioncode="T01030203" @click='onEdit(record.jobHuntID)'>编辑
  179. </a-button>
  180. <a-button type="link" size="small" functioncode="T01030204" @click="onDel(record)">删除</a-button>
  181. <a-button type="link" size="small" functioncode="T01030207" @click="onRecommendCompanyPost(record)">推荐岗位
  182. </a-button>
  183. </div>
  184. </template>
  185. </template>
  186. </a-table>
  187. </div>
  188. <Recommend ref="recommendRef"></Recommend>
  189. </div>
  190. </template>
  191. <script lang="ts">
  192. import {computed, createVNode, defineComponent, reactive, ref} from 'vue';
  193. import type {FormInstance, SelectProps, TableProps} from 'ant-design-vue';
  194. import {message, Modal} from "ant-design-vue";
  195. import {delJobHunt, getJobHuntList} from '@/api/jobUserManager/jobhunt';
  196. import {getSysDictionaryList} from '@/api/system/dictionary';
  197. import {getPaginationTotalTitle} from '@/utils/common';
  198. import dayjs from 'dayjs';
  199. import BImportExcel from "@/components/basic/excel/importExcel/importExcel.vue";
  200. import BExportExcel from "@/components/basic/excel/exportExcel/exportExcel.vue";
  201. import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
  202. import type {ImportProps} from "@/components/basic/excel/importExcel/ImportProps";
  203. import {useTabsViewStore} from "@/store/modules/tabsView";
  204. import Recommend from "@/views/jobUserManager/jobhunt/recommend.vue";
  205. import {getSiteList} from "@/api/baseSettings/siteInfo";
  206. import {get} from "@/api/common";
  207. import ColumnsSetting from "@/components/common/ColumnsSetting.vue";
  208. export default defineComponent({
  209. name: 'JobHuntList',
  210. components: {ColumnsSetting, BImportExcel, BExportExcel, Recommend},
  211. setup() {
  212. const formRef = ref<FormInstance>();
  213. const tabsViewStore = useTabsViewStore();
  214. const expand = ref(false);
  215. const recommendRef = ref();
  216. const searchParamsState = reactive({
  217. pageIndex: 1,
  218. pageSize: 20,
  219. jobUserName: null,
  220. professionName: null,
  221. minWorkYear: null,
  222. maxWorkYear: null,
  223. jobHuntTypeID: null,
  224. jobUserTypeID: null,
  225. minSalary: null,
  226. maxSalary: null,
  227. isAccomplish: null,
  228. siteID: null,
  229. regionCode: null,
  230. startDate: null,
  231. endDate: null
  232. });
  233. // 导出Excel查询参数
  234. const exportSearchParams = computed(() => {
  235. let data = JSON.parse(JSON.stringify(searchParamsState));
  236. data.pageSize = formState.total;
  237. return data;
  238. })
  239. const formState = reactive({
  240. total: 0,
  241. selectedRowKeys: [],
  242. loading: false,
  243. });
  244. // 原始表格定义数据
  245. const originalColumns = [
  246. {
  247. title: '序号',
  248. align: 'center',
  249. width: 80,
  250. key: 'jobHuntID',
  251. customRender: (item) =>
  252. `${searchParamsState.pageSize * (searchParamsState.pageIndex - 1) + item.index + 1}`,
  253. isDisabled: true
  254. },
  255. {title: '姓名', dataIndex: 'jobUserName', key: 'jobUserName', width: 120, align: "center",},
  256. {title: '希望工作地区', dataIndex: 'areaWork', key: 'areaWork', width: 180, align: "center",},
  257. {title: '工作年限', dataIndex: 'workYear', key: 'workYear', width: 140, align: "center",},
  258. {title: '求职类型', dataIndex: 'jobHuntTypeStr', key: 'jobHuntTypeStr', align: "center",},
  259. {title: '求职岗位', dataIndex: 'professionName', key: 'professionName', align: "center",},
  260. {title: '推荐数量', dataIndex: 'recommendNum', key: 'recommendNum', align: "center"},
  261. {
  262. title: '可到职日期', dataIndex: 'inDate', key: 'inDate', width: 120, align: "center",
  263. customRender: ({record}) => record.inDate == null ? "" : dayjs(record.inDate).format('YYYY-MM-DD'),
  264. isDefaultClose: true
  265. },
  266. {title: '人才类型', dataIndex: 'jobUserTypeStr', key: 'jobUserTypeStr', align: "center", isDefaultClose: true},
  267. {
  268. title: '月薪要求', dataIndex: 'salary', key: 'salary', align: "center",
  269. customRender: (item) => {
  270. const salary = showSalary(item.record.minSalary, item.record.maxSalary);
  271. return salary;
  272. }, isDefaultClose: true
  273. },
  274. {title: '操作', key: 'operation', fixed: 'right', width: 220, align: "center", isDisabled: true},
  275. ];
  276. // 响应式表格定义
  277. const columns = ref<Array<any>>(originalColumns.filter(item => !item.isDefaultClose));
  278. const pagination = computed(() => ({
  279. total: formState.total,
  280. current: searchParamsState.pageIndex,
  281. pageSize: searchParamsState.pageSize,
  282. showSizeChanger: true,
  283. showTotal: (total) => getPaginationTotalTitle(total),
  284. }));
  285. const importOptions = ref<ImportProps>({
  286. title: '导入',
  287. url: '/jobUserService/jobHunt/importJobHunt',
  288. columns: [
  289. {cnName: '姓名', enName: 'jobUserName', width: 100},
  290. // {cnName: '工种名称', enName: 'workName', width: 100},
  291. {cnName: '求职类型', enName: 'jobHuntTypeStr', width: 100},
  292. {cnName: '人才类型', enName: 'jobUserTypeStr', width: 100},
  293. {cnName: '最低月薪(元)', enName: 'minSalary', width: 100},
  294. {cnName: '最高月薪(元)', enName: 'maxSalary', width: 100},
  295. {cnName: '求职岗位', enName: 'professionName', width: 100},
  296. {cnName: '希望工作地区', enName: 'areaWork', width: 100},
  297. {cnName: '可到职日期', enName: 'inDate', width: 100},
  298. {cnName: '工作年限', enName: 'workYear', width: 100},
  299. {cnName: '其他要求', enName: 'otherDemand', width: 100},
  300. ],
  301. template: {
  302. tempFileName: '求职意向导入模板.xlsx',
  303. url: '',
  304. params: null,
  305. },
  306. });
  307. const dataList = ref([]);
  308. const jobHuntTypeList = ref<SelectProps['options']>();
  309. const jobUserTypeList = ref<SelectProps['options']>();
  310. const isAccomplishList = ref<SelectProps['options']>();
  311. const createDate = ref([]);
  312. const siteList = ref<Array<any>>([]);
  313. const regionList = ref<SelectProps['options']>();
  314. const showSalary = (minSalary: any, maxSalary: any) => {
  315. if (minSalary != null) {
  316. if (maxSalary != null) {
  317. return minSalary.toString() + "-" + maxSalary.toString();
  318. } else {
  319. return "≥" + minSalary.toString();
  320. }
  321. } else {
  322. if (maxSalary != null) {
  323. return "≤" + maxSalary.toString();
  324. } else {
  325. return "";
  326. }
  327. }
  328. }
  329. const onSelectChange = (selectedRowKeys: any) => {
  330. formState.selectedRowKeys = selectedRowKeys;
  331. };
  332. const handleTableChange: TableProps['onChange'] = (pag: {
  333. pageSize: number;
  334. current: number;
  335. }) => {
  336. searchParamsState.pageIndex = pag.current;
  337. searchParamsState.pageSize = pag.pageSize;
  338. loadData();
  339. };
  340. const onSearch = () => {
  341. loadData();
  342. }
  343. const onDel = (item: any) => {
  344. formState.selectedRowKeys = [];
  345. if (item) {
  346. formState.selectedRowKeys.push(item.jobHuntID as never)
  347. }
  348. if (formState.selectedRowKeys.length <= 0) {
  349. message.warning('请选择需要删除的数据!');
  350. return false;
  351. }
  352. Modal.confirm({
  353. title: '确认删除选中的求职意向?',
  354. icon: createVNode(ExclamationCircleOutlined),
  355. content: '',
  356. okText: '确认删除',
  357. okType: 'danger',
  358. okButtonProps: {},
  359. cancelText: '取消',
  360. onOk() {
  361. delJobHunt(formState.selectedRowKeys).then(() => {
  362. loadData();
  363. });
  364. },
  365. onCancel() {
  366. formState.selectedRowKeys = [];
  367. },
  368. });
  369. };
  370. function getAllSites() {
  371. getSiteList({pageIndex: 1, pageSize: 9999}).then((result: any) => {
  372. siteList.value = result.list;
  373. })
  374. }
  375. function getAllRegion() {
  376. get('system/area/getCityList', {}).then(data => {
  377. regionList.value = data;
  378. });
  379. }
  380. const loadData = async function () {
  381. formState.loading = true;
  382. getJobHuntTypeList();
  383. getJobUserTypeList();
  384. getIsAccomplishList();
  385. const result: any = await getJobHuntList(searchParamsState);
  386. dataList.value = result.list;
  387. formState.total = result.total;
  388. formState.loading = false;
  389. };
  390. const onAdd = () => {
  391. tabsViewStore.addTabByPath('/jobusermgr/jobhunt/add', {id: null});
  392. };
  393. const onEdit = (id: string) => {
  394. tabsViewStore.addTabByPath('/jobusermgr/jobhunt/edit', {id: id});
  395. };
  396. const onDetail = (id: string) => {
  397. tabsViewStore.addTabByPath('/jobusermgr/jobhunt/detail', {id: id});
  398. };
  399. const onRecommendCompanyPost = (item) => {
  400. recommendRef.value.show(item.professionID, item.professionName, item.jobHuntID, item.jobUserName, 0,
  401. item.parentProfessionID, item.cultureRank, item.workYear, item.minSalary, item.maxSalary, "推荐企业岗位");
  402. }
  403. const onRecommendInfo = (item) => {
  404. if(item.recommendNum == 0){
  405. return;
  406. }
  407. recommendRef.value.show('', item.professionName, item.jobHuntID, item.jobUserName, 1,
  408. '', null, null, null, null, '已推荐企业岗位信息');
  409. }
  410. const getJobHuntTypeList = () => {
  411. getSysDictionaryList('JobHuntType').then((data) => {
  412. jobHuntTypeList.value = data;
  413. });
  414. };
  415. const getJobUserTypeList = () => {
  416. getSysDictionaryList('JobUserType').then((data) => {
  417. jobUserTypeList.value = data;
  418. });
  419. };
  420. const getIsAccomplishList = () => {
  421. getSysDictionaryList('ContractRecord').then((data) => {
  422. isAccomplishList.value = data;
  423. });
  424. };
  425. // 登记时间组件调整
  426. const onCreateTimeChange = (dateString) => {
  427. createDate.value = dateString;
  428. searchParamsState.startDate = dateString ? dateString[0].format("YYYY-MM-DD") : '';
  429. searchParamsState.endDate = dateString ? dateString[1].format("YYYY-MM-DD") : '';
  430. loadData();
  431. }
  432. // 字段展示列选择完毕
  433. function columnsCheckSub(columnsKeys: Array<string>) {
  434. // 从原始表格定义数据中过滤出已选择的字段
  435. columns.value = originalColumns.filter((item: any) => columnsKeys.includes(item.key));
  436. }
  437. return {
  438. formRef,
  439. expand,
  440. searchParamsState,
  441. formState,
  442. columns,
  443. originalColumns,
  444. columnsCheckSub,
  445. pagination,
  446. dataList,
  447. importOptions,
  448. jobHuntTypeList,
  449. jobUserTypeList,
  450. isAccomplishList,
  451. recommendRef,
  452. exportSearchParams,
  453. showSalary,
  454. loadData,
  455. onSearch,
  456. onAdd,
  457. onEdit,
  458. onDel,
  459. onRecommendCompanyPost,
  460. onRecommendInfo,
  461. onSelectChange,
  462. handleTableChange,
  463. getJobHuntTypeList,
  464. getJobUserTypeList,
  465. getIsAccomplishList,
  466. onDetail,
  467. getAllSites,
  468. getAllRegion,
  469. siteList,
  470. regionList,
  471. createDate,
  472. onCreateTimeChange
  473. };
  474. },
  475. created() {
  476. this.getAllSites();
  477. this.getAllRegion();
  478. this.loadData();
  479. },
  480. activated() {
  481. if (history.state.params?.reload) this.loadData();
  482. },
  483. });
  484. </script>
  485. <style lang="less" scoped></style>