yangg 1 mesiac pred
rodič
commit
3ed96c6f05

+ 1 - 0
src/theme/element.scss

@@ -81,6 +81,7 @@
 	height: 56px !important;
 	line-height: 56px !important;
 	margin: 0 5px;
+	font-size: 12px;
 }
 .el-menu-item,
 .el-sub-menu__title {

+ 8 - 3
src/views/JobApplication/list/api.ts

@@ -2,7 +2,7 @@ import { request } from '/@/utils/service';
 import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
 
 export const apiPrefix = '/api/system/job_applications/';
-export function GetList(query: UserPageQuery) {
+export function GetList(query: any) {
 	return request({
 		url: apiPrefix,
 		method: 'get',
@@ -59,9 +59,14 @@ export function BulkUpdateStatus(data: {
 	});
 }
 
-export function updateBatchStatus(data: any) {
+export function updateBatchStatus(data: {
+	application_ids: number[];
+	new_status: number;
+	note?: string;
+	tenant_id: string;
+}) {
 	return request({
-		url: '/api/system/job_applications/bulk_update_status/',
+		url: '/api/system/job/batch_update_application_status/',
 		method: 'post',
 		data
 	});

+ 115 - 0
src/views/JobApplication/list/components/BatchStatusDialog.vue

@@ -0,0 +1,115 @@
+<template>
+  <el-dialog
+    v-model="dialogVisible"
+    title="批量修改申请状态"
+    width="500px"
+    :close-on-click-modal="false"
+    @closed="handleClosed"
+  >
+    <el-form :model="form" label-width="100px" ref="formRef" :rules="rules">
+      <el-form-item label="新状态" prop="new_status">
+        <el-select v-model="form.new_status" placeholder="请选择新状态" style="width: 100%">
+          <el-option :value="1" label="待面试" />
+          <el-option :value="2" label="已面试" />
+          <el-option :value="3" label="已录用" />
+          <el-option :value="4" label="已拒绝" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="备注" prop="note">
+        <el-input
+          v-model="form.note"
+          type="textarea"
+          placeholder="请输入备注信息"
+          :rows="3"
+        />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="dialogVisible = false">取消</el-button>
+      <el-button type="primary" @click="handleSubmit" :loading="loading">确认</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive } from 'vue';
+import { ElMessage, FormInstance } from 'element-plus';
+import { updateBatchStatus } from '../api';
+
+const dialogVisible = ref(false);
+const loading = ref(false);
+const formRef = ref<FormInstance>();
+
+const form = reactive({
+  new_status: undefined as number | undefined,
+  note: '',
+  application_ids: [] as number[]
+});
+
+const rules = {
+  new_status: [{ required: true, message: '请选择新状态', trigger: 'change' }]
+};
+
+const emit = defineEmits(['success']);
+const props = defineProps({
+  crudExpose: {
+    type: Object,
+    required: true
+  }
+});
+
+// 打开对话框
+const open = (selection: any[]) => {
+  dialogVisible.value = true;
+  form.application_ids = selection.map(item => item.id);
+  form.new_status = undefined;
+  form.note = '';
+};
+
+// 提交表单
+const handleSubmit = async () => {
+  if (!formRef.value) return;
+  
+  await formRef.value.validate(async (valid) => {
+    if (!valid) return;
+    
+    loading.value = true;
+    try {
+      const data = {
+        application_ids: form.application_ids,
+        new_status: form.new_status,
+        note: form.note,
+        tenant_id: '1'
+      };
+      
+      const res = await updateBatchStatus(data);
+      
+      if (res.code === 2000) {
+        ElMessage.success('批量修改状态成功');
+        dialogVisible.value = false;
+        emit('success');
+        props.crudExpose.doRefresh();
+      } else {
+        ElMessage.error(res.msg || '操作失败');
+      }
+    } catch (error) {
+      console.error('批量修改状态失败:', error);
+      ElMessage.error('操作失败,请重试');
+    } finally {
+      loading.value = false;
+    }
+  });
+};
+
+// 关闭对话框时重置表单
+const handleClosed = () => {
+  if (formRef.value) {
+    formRef.value.resetFields();
+  }
+};
+
+// 暴露方法给父组件
+defineExpose({
+  open
+});
+</script> 

+ 18 - 1
src/views/JobApplication/list/crud.tsx

@@ -12,7 +12,7 @@ import axios from 'axios';
 export const createCrudOptions = function ({ crudExpose, context}: CreateCrudOptionsProps): CreateCrudOptionsRet {
 	const router = useRouter();
 	
-	const pageRequest = async (query: UserPageQuery) => {
+	const pageRequest = async (query: any) => {
 		return await api.GetList(query);
 	};
 	const editRequest = async ({ form, row }: EditReq) => {
@@ -223,6 +223,23 @@ export const createCrudOptions = function ({ crudExpose, context}: CreateCrudOpt
 							context.openBatchTagsDialog(selection);
 						},
 					},
+					// 添加批量修改状态按钮
+					batchUpdateStatus: {
+						text: '批量修改状态',
+						type: 'primary',
+						show: true,
+						order: 1,
+						click: () => {
+							const selection = context.selectedRows || [];
+							
+							if (!selection || selection.length === 0) {
+								warningMessage('请先选择要操作的申请');
+								return;
+							}
+							// 打开批量修改状态对话框
+							context.openBatchStatusDialog(selection);
+						},
+					},
 				},
 			},
 			rowHandle: {

+ 16 - 2
src/views/JobApplication/list/index.vue

@@ -90,6 +90,7 @@
 			</div>
 		</div>
 		<BatchTagsDialog ref="batchTagsDialogRef" :crudExpose="crudExpose" />
+		<BatchStatusDialog ref="batchStatusDialogRef" :crudExpose="crudExpose" @success="handleBatchStatusSuccess" />
 	</fs-page>
 </template>
 
@@ -101,16 +102,23 @@ import { GetPermission } from './api';
 import { handleColumnPermission } from '/@/utils/columnPermission';
 import { Grid, Clock, ArrowRight, Check, RefreshRight, Briefcase } from '@element-plus/icons-vue';
 import BatchTagsDialog from './components/index.vue';
+import BatchStatusDialog from './components/BatchStatusDialog.vue';
+
 const { crudBinding, crudRef, crudExpose, crudOptions, resetCrudOptions } = useFs({ 
 	createCrudOptions,
 	context: {
 		openBatchTagsDialog: (selection: any) => {
 			batchTagsDialogRef.value.open(selection);
-		}
+		},
+		openBatchStatusDialog: (selection: any) => {
+			batchStatusDialogRef.value.open(selection);
+		},
+		selectedRows: [] // 存储选中的行
 	}
 });
 
 const batchTagsDialogRef = ref();
+const batchStatusDialogRef = ref();
 
 // 状态计数
 const totalCount = ref(0);
@@ -216,6 +224,12 @@ const updateCounts = (data: any) => {
 	});
 };
 
+// 处理批量状态修改成功
+const handleBatchStatusSuccess = () => {
+	// 刷新数据
+	crudExpose.doRefresh();
+};
+
 // 页面打开后获取列表数据
 onMounted(async () => {
 	// 获取职位列表
@@ -251,7 +265,7 @@ onMounted(async () => {
 .sidebar {
 	margin-top: 10px;
 	width: 200px;
-	margin-right: 16px;
+	margin-right: 5px;
 	flex-shrink: 0;
 	background-color: #fff;
 	border-right: 1px solid #ebeef5;

+ 1 - 1
src/views/questionBank/positionList/crud.tsx

@@ -83,7 +83,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				}
 			},
 			rowHandle: {
-				width: 300, // 增加宽度以容纳新按钮
+				width: 350, // 增加宽度以容纳新按钮
 				buttons: {
 					view: {
 						size: 'small',

+ 2 - 2
src/views/questionBank/positionList/index.vue

@@ -1,7 +1,7 @@
 <template>
   <fs-page>
     <el-row class="document-el-row">
-      <el-col :span="4">
+      <el-col :span="3">
         <div class="document-box document-left-box">
           <DocumentTreeCom
             ref="documentTreeRef"
@@ -13,7 +13,7 @@
         </div>
       </el-col>
 
-      <el-col :span="20">
+      <el-col :span="21">
         <div class="document-box document-right-box">
           <fs-crud ref="crudRef" v-bind="crudBinding">
             <template #form_file="scope">

+ 38 - 9
src/views/system/home/index.vue

@@ -12,7 +12,7 @@
 				:key="k"
 				:class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }"
 			>
-				<div class="home-card-item flex">
+				<div class="home-card-item flex" @click="handleCardClick(k)" style="cursor: pointer;">
 					<div class="flex-margin flex w100" :class="` home-one-animation${k}`">
 						<div class="flex-auto">
 							<span class="font30">{{ v.num1 }}</span>
@@ -73,6 +73,20 @@ import { storeToRefs } from 'pinia';
 import { useThemeConfig } from '/@/stores/themeConfig';
 import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
 import { GetList } from './api';
+import { useRouter } from 'vue-router';
+
+// 定义API数据接口
+interface ApiData {
+	total_applications: number;
+	total_positions: number;
+	total_questions: number;
+	total_reports: number;
+	application_trend: Array<{
+		date: string;
+		count: number;
+	}>;
+}
+
 let global: any = {
 	homeChartOne: null,
 	homeChartTwo: null,
@@ -191,8 +205,9 @@ export default defineComponent({
 				bgColor: '',
 				color: '#303133',
 			},
-			apiData: null,
+			apiData: null as ApiData | null,
 		});
+		const router = useRouter();
 		// 折线图
 		const initLineChart = () => {
 			if (!global.dispose.some((b: any) => b === global.homeChartOne)) global.homeChartOne.dispose();
@@ -208,7 +223,7 @@ export default defineComponent({
 				tooltip: { trigger: 'axis' },
 				legend: { data: ['申请数量'], right: 0 },
 				xAxis: {
-					data: state.apiData?.application_trend?.map(item => item.date.substring(5)) || 
+					data: state.apiData?.application_trend?.map((item: {date: string; count: number}) => item.date.substring(5)) || 
 						['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
 				},
 				yAxis: [
@@ -225,7 +240,7 @@ export default defineComponent({
 						symbolSize: 6,
 						symbol: 'circle',
 						smooth: true,
-						data: state.apiData?.application_trend?.map(item => item.count) || 
+						data: state.apiData?.application_trend?.map((item: {date: string; count: number}) => item.count) || 
 							[0, 41.1, 30.4, 65.1, 53.3, 53.3, 53.3, 41.1, 30.4, 65.1, 53.3, 10],
 						lineStyle: { color: '#fe9a8b' },
 						itemStyle: { color: '#fe9a8b', borderColor: '#fe9a8b' },
@@ -526,7 +541,7 @@ export default defineComponent({
 		// 获取API数据
 		const fetchApiData = async () => {
 			try {
-				const res = await GetList();
+				const res = await GetList({});
 				if (res.code === 2000) {
 					state.apiData = res.data;
 					updateHomeData(res.data);
@@ -536,7 +551,7 @@ export default defineComponent({
 			}
 		};
 		// 更新首页数据
-		const updateHomeData = (data) => {
+		const updateHomeData = (data: ApiData) => {
 			// 更新顶部卡片数据
 			state.homeOne[0].num1 = data.total_applications.toString();
 			state.homeOne[1].num1 = data.total_positions.toString();
@@ -547,27 +562,41 @@ export default defineComponent({
 			updateLineChart(data.application_trend);
 		};
 		// 更新折线图数据
-		const updateLineChart = (trendData) => {
+		const updateLineChart = (trendData: Array<{date: string; count: number}>) => {
 			if (!global.homeChartOne) return;
 			
 			const option = {
 				xAxis: {
-					data: trendData.map(item => item.date.substring(5)), // 只显示月-日
+					data: trendData.map((item: {date: string; count: number}) => item.date.substring(5)), // 只显示月-日
 				},
 				series: [
 					{
 						name: '申请数量',
-						data: trendData.map(item => item.count),
+						data: trendData.map((item: {date: string; count: number}) => item.count),
 					}
 				]
 			};
 			
 			(<any>global.homeChartOne).setOption(option);
 		};
+		// 添加卡片点击跳转功能
+		const handleCardClick = (index: number) => {
+			const routes = [
+				'/JobApplication/list/index', // 申请总数
+				'/position/list',    // 职位总数
+				'/questionBank/list',    // 问题总数
+				'/JobApplication/list/index'       // 报告总数
+			];
+			
+			if (index >= 0 && index < routes.length) {
+				router.push(routes[index]);
+			}
+		};
 		return {
 			homeLineRef,
 			homePieRef,
 			homeBarRef,
+			handleCardClick,
 			...toRefs(state),
 		};
 	},