index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <template>
  2. <div class="card-search">
  3. <a-form ref="formRef" name="advanced_search" class="ant-advanced-search-form" :model="searchParams">
  4. <a-row :gutter="24">
  5. <a-col :span="6">
  6. <a-form-item label="岗位名称" :label-col="{span:6}" name="professionName">
  7. <a-input v-model:value="searchParams.professionName" placeholder="" :allow-clear="true"/>
  8. </a-form-item>
  9. </a-col>
  10. <a-col :span="6">
  11. <a-form-item label="招聘企业" :label-col="{span:6}" name="companyName">
  12. <a-select ref="select" @change="loadData"
  13. show-search optionFilterProp="label"
  14. v-model:value="searchParams.companyName"
  15. :allow-clear="true">
  16. <a-select-option v-for="item in companyList" :label="item.companyName" :value="item.companyName"
  17. :key="item.companyID">
  18. <span>{{ item.companyName }}</span>
  19. </a-select-option>
  20. </a-select>
  21. </a-form-item>
  22. </a-col>
  23. <a-col :span="6">
  24. <a-form-item label="招聘人数" :label-col="{span:6}" name="recruitCount">
  25. <a-input type="number" v-model:value="searchParams.minCount" style="width:110px;" placeholder="" />
  26. <label style="margin:10px;">-</label>
  27. <a-input type="number" v-model:value="searchParams.maxCount" style="width:110px;" placeholder="" />
  28. </a-form-item>
  29. </a-col>
  30. <a-col :span="6" style="text-align: left">
  31. <a-button type="primary" html-type="submit" @click="onSearch">查询</a-button>
  32. <a-button
  33. style="margin: 0 8px"
  34. @click="
  35. () => {
  36. searchParams.minCount = null;
  37. searchParams.maxCount = null;
  38. formRef.resetFields();
  39. loadData();
  40. }
  41. ">重置
  42. </a-button>
  43. <a style="font-size: 12px" @click="expand = !expand">
  44. <template v-if="expand">
  45. <UpOutlined/>
  46. </template>
  47. <template v-else>
  48. <DownOutlined/>
  49. </template>
  50. {{ expand ? '收缩' : '展开' }}
  51. </a>
  52. </a-col>
  53. </a-row>
  54. <a-row :gutter="24" v-show="expand">
  55. <a-col :span="6">
  56. <a-form-item label="岗位状态" :label-col="{span:6}" name="recordStatus">
  57. <a-select
  58. ref="select"
  59. v-model:value="searchParams.recordStatus"
  60. :options="postStatusList"
  61. :field-names="{ label: 'name', value: 'value' }"
  62. :allow-clear="true"
  63. @change="loadData"
  64. >
  65. </a-select>
  66. </a-form-item>
  67. </a-col>
  68. </a-row>
  69. <a-row class="edit-operation">
  70. <a-col :span="24" style="text-align: right">
  71. <a-button type="primary" html-type="submit" functioncode="T01020202" @click='onAdd'>新增</a-button>
  72. <BImportExcel
  73. functioncode="T01020205"
  74. :options="importOptions"
  75. @success="loadData"
  76. ></BImportExcel>
  77. <BExportExcel :title="'导出'" :filename="'岗位信息'"
  78. :url="'companyService/post/export'"
  79. :params="{...searchParams, isExport: true, rows:10000,postIDList:formState.selectedRowKeys.join(',')}"></BExportExcel>
  80. </a-col>
  81. </a-row>
  82. </a-form>
  83. <div class="search-result-list">
  84. <a-table :columns="columns" :data-source="dataList" :scroll="{ x:2000, y: 500 }" :pagination="pagination"
  85. :loading="formState.loading"
  86. @change="handleTableChange"
  87. :row-selection="{ selectedRowKeys: formState.selectedRowKeys, onChange: onSelectChange}"
  88. :row-key="record=>record.postID"
  89. bordered>
  90. <template #bodyCell="{ column, text, record }">
  91. <template v-if="column.key === 'recommendNum'">
  92. <div>
  93. <a-button type="link" size="small" @click='onRecommendInfo(record)'>{{record.recommendNum}}</a-button>
  94. </div>
  95. </template>
  96. <template v-if="column.key === 'operation'">
  97. <div class="table-operation">
  98. <a-button type="link" size="small" @click='onEdit(record)' functioncode="T01020203">编辑</a-button>
  99. <a-button type="link" size="small" @click="onDel(record)" functioncode="T01020204">删除</a-button>
  100. <a-button type="link" size="small" @click="onRecommendJob(record)" functioncode="T01030207">推荐求职人员</a-button>
  101. </div>
  102. </template>
  103. </template>
  104. </a-table>
  105. </div>
  106. <Recommend ref="recommendRef"></Recommend>
  107. </div>
  108. </template>
  109. <script lang="ts">
  110. import {reactive, ref, computed, defineComponent, createVNode} from 'vue';
  111. import {DownOutlined, UpOutlined} from '@ant-design/icons-vue';
  112. import type {FormInstance} from 'ant-design-vue';
  113. import {Modal, SelectProps} from 'ant-design-vue';
  114. import type {TableColumnsType, TableProps} from 'ant-design-vue';
  115. import {getList, del} from '@/api/companyService/post';
  116. import BExportExcel from "@/components/basic/excel/exportExcel/exportExcel.vue";
  117. import BImportExcel from '@/components/basic/excel/importExcel/importExcel.vue';
  118. import {getPaginationTotalTitle} from "@/utils/common";
  119. import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
  120. import dayjs from 'dayjs';
  121. import {useRoute} from 'vue-router';
  122. import {useTabsViewStore} from "@/store/modules/tabsView";
  123. import type {ImportProps} from "@/components/basic/excel/importExcel/ImportProps";
  124. import {get} from "@/api/common";
  125. import Recommend from "@/views/companyService/post/recommend.vue";
  126. export default defineComponent({
  127. components: {DownOutlined, UpOutlined, BExportExcel, BImportExcel, Recommend},
  128. setup: function () {
  129. const formRef = ref<FormInstance>();
  130. const searchParams = reactive({
  131. pageIndex: 1,
  132. pageSize: 20,
  133. minCount: null,
  134. maxCount: null,
  135. professionName: null,
  136. recordStatus: null
  137. });
  138. const expand = ref(false);
  139. const companyList = ref<SelectProps['options']>();
  140. const postStatusList = [{name: '启用', value: 1}, {name: '禁用', value: 0}];
  141. const recommendRef = ref();
  142. const importOptions = ref<ImportProps>({
  143. title: '导入',
  144. url: 'companyService/post/importPost',
  145. columns: [
  146. {cnName: '企业名称', enName: 'companyName', width: 100},
  147. {cnName: '岗位名称', enName: 'professionName', width: 100},
  148. {cnName: '招聘人数', enName: 'recruitCount', width: 100},
  149. {cnName: '开始日期', enName: 'startTime', width: 100},
  150. {cnName: '结束日期', enName: 'endTime', width: 100},
  151. {cnName: '招聘地点', enName: 'jobPlace', width: 100},
  152. {cnName: '工作年限', enName: 'workYear', width: 100},
  153. {cnName: '学历要求', enName: 'cultureLevelName', width: 100},
  154. {cnName: '岗位最高月薪', enName: 'maxSalary', width: 100},
  155. {cnName: '岗位最低月薪', enName: 'minSalary', width: 100},
  156. {cnName: '是否有试用期', enName: 'isTrailName', width: 100},
  157. {cnName: '试用期时长(月)', enName: 'trailtime', width: 100},
  158. {cnName: '试用期最高薪酬', enName: 'trailMaxSalary', width: 100},
  159. {cnName: '试用期最低薪酬', enName: 'trailMinSalary', width: 100},
  160. {cnName: '福利待遇', enName: 'welfare', width: 100},
  161. {cnName: '其它要求', enName: 'postDesc', width: 100}
  162. ],
  163. template: {
  164. tempFileName: '岗位信息导入模板.xlsx',
  165. url: '',
  166. params: null,
  167. },
  168. });
  169. const formState = reactive({
  170. total: 0,
  171. selectedRowKeys: [],
  172. loading: false
  173. });
  174. const columns: TableColumnsType = [
  175. {
  176. title: '序号',
  177. align: "center",
  178. key: 'institutionID',
  179. width: 90,
  180. customRender: item => `${searchParams.pageSize * (searchParams.pageIndex - 1) + item.index + 1}`
  181. },
  182. {title: '岗位名称', dataIndex: 'professionName', key: 'professionName', align: "center"},
  183. {title: '招聘人数', dataIndex: 'recruitCount', key: 'recruitCount', width: 120, align: "center"},
  184. {
  185. title: '开始日期', dataIndex: 'startTime', key: 'startTime', align: "center", customRender: (item) => {
  186. return item.record.startTime == null ? "" : (dayjs(item.record.startTime).format('YYYY-MM-DD'))
  187. }
  188. },
  189. {title: '结束日期', dataIndex: 'endTime', key: 'endTime', align: "center",customRender: (item) => {
  190. return item.record.endTime == null ? "" : (dayjs(item.record.endTime).format('YYYY-MM-DD'))
  191. }
  192. },
  193. {title: '招聘企业', dataIndex: 'companyName', key: 'companyName', align: "center"},
  194. {
  195. title: '岗位状态', dataIndex: 'recordStatus', key: 'recordStatus', align: "center", customRender: (item) => {
  196. return item.record.recordStatus == 1 ? "启用" : "停用";
  197. }
  198. },
  199. // {title: '工种名称', dataIndex: 'workName', key: 'workName', align: "center"},
  200. {title: '文化程度', dataIndex: 'cultureLevelName', key: 'cultureLevelName', width: 150, align: "center"},
  201. {
  202. title: '薪酬', dataIndex: 'postSalary', key: 'postSalary', align: "center", customRender: (item) => {
  203. const salary = showSalary(item.record.minSalary,item.record.maxSalary);/*`${item.record.minSalary ?? ""}-${item.record.maxSalary ?? ""}`*/
  204. return salary;
  205. }
  206. },
  207. {title: '联系人', dataIndex: 'userName', key: 'userName', align: "center"},
  208. {title: '联系电话', dataIndex: 'userMobile', key: 'userMobile', width: 200, align: "center"},
  209. {title: '推荐数量', dataIndex: 'recommendNum',key: 'recommendNum',width: 100, align: "center"},
  210. {title: '操作', key: 'operation', fixed: 'right', width: 200, align: "center"},
  211. ];
  212. const pagination = computed(() => ({
  213. total: formState.total,
  214. current: searchParams.pageIndex,
  215. pageSize: searchParams.pageSize,
  216. showSizeChanger: true,
  217. showTotal: total => getPaginationTotalTitle(total)
  218. }));
  219. const tabsViewStore = useTabsViewStore();
  220. const dataList = ref([]);
  221. const loadData = async function () {
  222. formState.loading = true;
  223. const result: any = await getList(searchParams);
  224. dataList.value = result.list;
  225. console.log("所有岗位信息",dataList.value);
  226. formState.total = result.total;
  227. formState.loading = false;
  228. }
  229. const onAdd = () => {
  230. tabsViewStore.addTabByPath('/companyService/post/add', {});
  231. };
  232. const onEdit = (item: any) => {
  233. tabsViewStore.addTabByPath('/companyService/post/edit', {id: item.postID});
  234. };
  235. const onRecommendJob = (item) =>{
  236. recommendRef.value.show(item.professionID,item.professionName,item.postID,item.companyName,0,'推荐求职人员');
  237. }
  238. const onRecommendInfo = (item) =>{
  239. recommendRef.value.show(item.professionID,item.professionName,item.postID,item.companyName,1,'求职人员信息');
  240. }
  241. const handleTableChange: TableProps['onChange'] = (pag: { pageSize: number; current: number },) => {
  242. searchParams.pageIndex = pag.current;
  243. searchParams.pageSize = pag.pageSize;
  244. loadData();
  245. };
  246. const getCompanyList = () => {
  247. console.log('getCompanyList');
  248. get('companyService/company/getList', {pageIndex: 1, pageSize: 999}).then(result => {
  249. companyList.value = result.list;
  250. console.log(companyList.value);
  251. })
  252. }
  253. const onSelectChange = (selectedRowKeys: any) => {
  254. formState.selectedRowKeys = selectedRowKeys;
  255. };
  256. const onSearch = () => {
  257. loadData();
  258. }
  259. const showSalary =(minSalary:any,maxSalary:any)=>{
  260. if(minSalary!=null){
  261. if(maxSalary!=null){
  262. return minSalary.toString()+"-"+maxSalary.toString();
  263. }else{
  264. return "≥"+minSalary.toString();
  265. }
  266. }else{
  267. if(maxSalary!=null){
  268. return "≤"+maxSalary.toString();
  269. }else{
  270. return "";
  271. }
  272. }
  273. }
  274. const onDel = (item: any) => {
  275. console.log(item.postID);
  276. Modal.confirm({
  277. title: '确认删除该岗位?',
  278. icon: createVNode(ExclamationCircleOutlined),
  279. content: '',
  280. okText: '确认删除',
  281. okType: 'danger',
  282. okButtonProps: {},
  283. cancelText: '取消',
  284. onOk() {
  285. del([item.postID]).then(() => {
  286. loadData();
  287. });
  288. },
  289. onCancel() {
  290. },
  291. })
  292. };
  293. return {
  294. formRef,
  295. searchParams,
  296. formState,
  297. columns,
  298. pagination,
  299. dataList,
  300. importOptions,
  301. recommendRef,
  302. showSalary,
  303. getCompanyList,
  304. handleTableChange,
  305. onSelectChange,
  306. onSearch,
  307. onDel,
  308. loadData,
  309. onAdd,
  310. onEdit,
  311. onRecommendJob,
  312. onRecommendInfo,
  313. expand,
  314. postStatusList,
  315. companyList
  316. };
  317. },
  318. created() {
  319. this.loadData();
  320. this.getCompanyList();
  321. },
  322. activated() {
  323. const route = useRoute();
  324. if (route.params.reload) this.loadData();
  325. }
  326. });
  327. </script>
  328. <style lang="less" scoped></style>