index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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="{...exportSearchParams, 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='onDetail(record)' functioncode="T01020201">查看</a-button>
  99. <a-button type="link" size="small" @click='onEdit(record)' functioncode="T01020203">编辑</a-button>
  100. <a-button type="link" size="small" @click="onDel(record)" functioncode="T01020204">删除</a-button>
  101. <a-button type="link" size="small" @click="onRecommendJob(record)" functioncode="T01030207">推荐求职人员</a-button>
  102. </div>
  103. </template>
  104. </template>
  105. </a-table>
  106. </div>
  107. <Recommend ref="recommendRef"></Recommend>
  108. </div>
  109. </template>
  110. <script lang="ts">
  111. import {computed, createVNode, defineComponent, reactive, ref} from 'vue';
  112. import {DownOutlined, ExclamationCircleOutlined, UpOutlined} from '@ant-design/icons-vue';
  113. import type {FormInstance, TableColumnsType, TableProps} from 'ant-design-vue';
  114. import {Modal, SelectProps} from 'ant-design-vue';
  115. import {del, getList} 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 dayjs from 'dayjs';
  120. import {useRoute} from 'vue-router';
  121. import {useTabsViewStore} from "@/store/modules/tabsView";
  122. import type {ImportProps} from "@/components/basic/excel/importExcel/ImportProps";
  123. import {get} from "@/api/common";
  124. import Recommend from "@/views/companyService/post/recommend.vue";
  125. export default defineComponent({
  126. components: {DownOutlined, UpOutlined, BExportExcel, BImportExcel, Recommend},
  127. setup: function () {
  128. const formRef = ref<FormInstance>();
  129. const searchParams = reactive({
  130. pageIndex: 1,
  131. pageSize: 20,
  132. minCount: null,
  133. maxCount: null,
  134. professionName: null,
  135. recordStatus: null
  136. });
  137. // 导出Excel查询参数
  138. const exportSearchParams = computed(() => {
  139. let data = JSON.parse(JSON.stringify(searchParams));
  140. data.pageSize = formState.total;
  141. return data;
  142. })
  143. const expand = ref(false);
  144. const companyList = ref<SelectProps['options']>();
  145. const postStatusList = [{name: '启用', value: 1}, {name: '禁用', value: 0}];
  146. const recommendRef = ref();
  147. const importOptions = ref<ImportProps>({
  148. title: '导入',
  149. url: 'companyService/post/importPost',
  150. columns: [
  151. {cnName: '企业名称', enName: 'companyName', width: 100},
  152. {cnName: '岗位名称', enName: 'professionName', width: 100},
  153. {cnName: '招聘人数', enName: 'recruitCount', width: 100},
  154. {cnName: '开始日期', enName: 'startTime', width: 100},
  155. {cnName: '结束日期', enName: 'endTime', width: 100},
  156. {cnName: '招聘地点', enName: 'jobPlace', width: 100},
  157. {cnName: '工作年限', enName: 'workYear', width: 100},
  158. {cnName: '学历要求', enName: 'cultureLevelName', width: 100},
  159. {cnName: '岗位最高月薪', enName: 'maxSalary', width: 100},
  160. {cnName: '岗位最低月薪', enName: 'minSalary', width: 100},
  161. {cnName: '是否有试用期', enName: 'isTrailName', width: 100},
  162. {cnName: '试用期时长(月)', enName: 'trailtime', width: 100},
  163. {cnName: '试用期最高薪酬', enName: 'trailMaxSalary', width: 100},
  164. {cnName: '试用期最低薪酬', enName: 'trailMinSalary', width: 100},
  165. {cnName: '福利待遇', enName: 'welfare', width: 100},
  166. {cnName: '其它要求', enName: 'postDesc', width: 100}
  167. ],
  168. template: {
  169. tempFileName: '岗位信息导入模板.xlsx',
  170. url: '',
  171. params: null,
  172. },
  173. });
  174. const formState = reactive({
  175. total: 0,
  176. selectedRowKeys: [],
  177. loading: false
  178. });
  179. const columns: TableColumnsType = [
  180. {
  181. title: '序号',
  182. align: "center",
  183. key: 'postID',
  184. width: 90,
  185. customRender: item => `${searchParams.pageSize * (searchParams.pageIndex - 1) + item.index + 1}`
  186. },
  187. {title: '岗位名称', dataIndex: 'professionName', key: 'professionName', align: "center"},
  188. {title: '招聘人数', dataIndex: 'recruitCount', key: 'recruitCount', width: 120, align: "center"},
  189. {
  190. title: '开始日期', dataIndex: 'startTime', key: 'startTime', align: "center", customRender: (item) => {
  191. return item.record.startTime == null ? "" : (dayjs(item.record.startTime).format('YYYY-MM-DD'))
  192. }
  193. },
  194. {title: '结束日期', dataIndex: 'endTime', key: 'endTime', align: "center",customRender: (item) => {
  195. return item.record.endTime == null ? "" : (dayjs(item.record.endTime).format('YYYY-MM-DD'))
  196. }
  197. },
  198. {title: '招聘企业', dataIndex: 'companyName', key: 'companyName', width: 200, align: "center"},
  199. {title: '所属驿站', dataIndex: 'siteName', key: 'siteName', width: 200, align: "center"},
  200. {
  201. title: '岗位状态', dataIndex: 'recordStatus', key: 'recordStatus', align: "center", customRender: (item) => {
  202. return item.record.recordStatus == 1 ? "启用" : "停用";
  203. }
  204. },
  205. // {title: '工种名称', dataIndex: 'workName', key: 'workName', align: "center"},
  206. {title: '学历要求', dataIndex: 'cultureLevelName', key: 'cultureLevelName', width: 150, align: "center"},
  207. {
  208. title: '薪酬', dataIndex: 'postSalary', key: 'postSalary', align: "center", customRender: (item) => {
  209. const salary = showSalary(item.record.minSalary,item.record.maxSalary);/*`${item.record.minSalary ?? ""}-${item.record.maxSalary ?? ""}`*/
  210. return salary;
  211. }
  212. },
  213. {title: '联系人', dataIndex: 'contactName', key: 'contactName', align: "center"},
  214. {title: '联系电话', dataIndex: 'contactMobile', key: 'contactMobile', width: 200, align: "center"},
  215. {title: '推荐数量', dataIndex: 'recommendNum',key: 'recommendNum',width: 100, align: "center"},
  216. {title: '操作', key: 'operation', fixed: 'right', width: 240, align: "center"},
  217. ];
  218. const pagination = computed(() => ({
  219. total: formState.total,
  220. current: searchParams.pageIndex,
  221. pageSize: searchParams.pageSize,
  222. showSizeChanger: true,
  223. showTotal: total => getPaginationTotalTitle(total)
  224. }));
  225. const tabsViewStore = useTabsViewStore();
  226. const dataList = ref([]);
  227. const loadData = async function () {
  228. formState.loading = true;
  229. const result: any = await getList(searchParams);
  230. dataList.value = result.list;
  231. console.log("所有岗位信息",dataList.value);
  232. formState.total = result.total;
  233. formState.loading = false;
  234. }
  235. const onAdd = () => {
  236. tabsViewStore.addTabByPath('/companyService/post/add', {});
  237. };
  238. const onEdit = (item: any) => {
  239. tabsViewStore.addTabByPath('/companyService/post/edit', {id: item.postID});
  240. };
  241. const onDetail = (item: any) => {
  242. tabsViewStore.addTabByPath('/companyService/post/detail', {id: item.postID});
  243. };
  244. const onRecommendJob = (item) =>{
  245. recommendRef.value.show(item.professionID,item.parentProfessionID,item.professionName,item.postID,item.companyName,0,'推荐求职人员');
  246. }
  247. const onRecommendInfo = (item) =>{
  248. recommendRef.value.show('','',item.professionName,item.postID,item.companyName,1,'求职人员信息');
  249. }
  250. const handleTableChange: TableProps['onChange'] = (pag: { pageSize: number; current: number },) => {
  251. searchParams.pageIndex = pag.current;
  252. searchParams.pageSize = pag.pageSize;
  253. loadData();
  254. };
  255. const getCompanyList = () => {
  256. console.log('getCompanyList');
  257. get('companyService/company/getList', {pageIndex: 1, pageSize: 999}).then(result => {
  258. companyList.value = result.list;
  259. console.log(companyList.value);
  260. })
  261. }
  262. const onSelectChange = (selectedRowKeys: any) => {
  263. formState.selectedRowKeys = selectedRowKeys;
  264. };
  265. const onSearch = () => {
  266. loadData();
  267. }
  268. const showSalary =(minSalary:any,maxSalary:any)=>{
  269. if(minSalary!=null){
  270. if(maxSalary!=null){
  271. return minSalary.toString()+"-"+maxSalary.toString();
  272. }else{
  273. return "≥"+minSalary.toString();
  274. }
  275. }else{
  276. if(maxSalary!=null){
  277. return "≤"+maxSalary.toString();
  278. }else{
  279. return "";
  280. }
  281. }
  282. }
  283. const onDel = (item: any) => {
  284. console.log(item.postID);
  285. Modal.confirm({
  286. title: '确认删除该岗位?',
  287. icon: createVNode(ExclamationCircleOutlined),
  288. content: '',
  289. okText: '确认删除',
  290. okType: 'danger',
  291. okButtonProps: {},
  292. cancelText: '取消',
  293. onOk() {
  294. del([item.postID]).then(() => {
  295. loadData();
  296. });
  297. },
  298. onCancel() {
  299. },
  300. })
  301. };
  302. return {
  303. formRef,
  304. searchParams,
  305. formState,
  306. columns,
  307. pagination,
  308. dataList,
  309. importOptions,
  310. recommendRef,
  311. showSalary,
  312. getCompanyList,
  313. handleTableChange,
  314. onSelectChange,
  315. onSearch,
  316. onDel,
  317. loadData,
  318. onAdd,
  319. onEdit,
  320. onRecommendJob,
  321. onRecommendInfo,
  322. expand,
  323. postStatusList,
  324. companyList,
  325. onDetail,
  326. exportSearchParams
  327. };
  328. },
  329. created() {
  330. this.loadData();
  331. this.getCompanyList();
  332. },
  333. activated() {
  334. const route = useRoute();
  335. if (route.params.reload) this.loadData();
  336. }
  337. });
  338. </script>
  339. <style lang="less" scoped></style>