Procházet zdrojové kódy

✨ 人员管理、电脑管理编辑页面添加

xinyan před 7 měsíci
rodič
revize
b53f6a96d8

+ 4 - 1
src/views/computer-information/api.ts

@@ -72,7 +72,10 @@ export function updateComputerDetail(query: any) {
     url: apiPrefix + `${query.id}/`,
     method: 'POST',
     params: { partial: query.partial },
-    data: query.formData,
+    data: query.dataToUpload,
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    }
   });
 }
 

+ 0 - 2
src/views/computer-information/components/CreateComputer.vue

@@ -53,8 +53,6 @@ const rules = reactive<FormRules<RuleForm>>({
 	ipaddress: [{ required: true, message: '请输入IP地址', trigger: 'blur' }],
 });
 
-
-
 // 超过图片限制时触发的回调
 const handleExceed: UploadProps['onExceed'] = (files) => {
 	upload.value!.clearFiles();

+ 70 - 13
src/views/computer-information/components/EditComputerInfo.vue

@@ -5,10 +5,11 @@
  * @Author: xinyan
  */
 import { ref } from 'vue';
-import { FormInstance, FormRules, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
+import { ElMessage, FormInstance, FormRules, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
 import { genFileId } from 'element-plus';
-import router from '/@/router';
-import { cloneDeep } from 'lodash';
+import { useResponse } from '/@/utils/useResponse';
+import * as api from '../api';
+import { EditPen, Picture as IconPicture, Plus, Search } from '@element-plus/icons-vue';
 
 const visible = defineModel({ default: false });
 const { computerInfo, computerNumber , userOptions, shopOptions } = defineProps<{
@@ -18,6 +19,8 @@ const { computerInfo, computerNumber , userOptions, shopOptions } = defineProps<
   shopOptions: any;
 }>();
 
+const emit = defineEmits(['refresh']);
+
 // 图片处理
 const upload = ref<UploadInstance>();
 // 表单数据
@@ -55,25 +58,79 @@ const handleExceed: UploadProps['onExceed'] = (files) => {
 };
 
 // 保存操作
-const handleSave = () => {
-	console.log(formData);
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const dataToUpload = new FormData();
+
+      // for (const key in formData) {
+      //   if (key !== 'images' && formData.hasOwnProperty(key)) {
+      //     dataToUpload.append(key, formData[key]);
+      //   }
+      // }
+
+      const fieldsToAppend = ['computerNumber', 'computerType', 'station', 'user', 'macaddress', 'ipaddress'];
+
+      fieldsToAppend.forEach((field) => {
+        dataToUpload.append(field, formData[field as keyof RuleForm]);
+      });
+
+      const shopValue = Array.isArray(formData.shop) ? formData.shop.join(',') : formData.shop;
+      dataToUpload.append('shops', shopValue);
+
+      if (Array.isArray(formData.images)) {
+        formData.images.forEach((image: any) => {
+          if (image.raw) {
+            dataToUpload.append('images', image.raw);
+          }
+        });
+      }
+      try {
+        const resp = await useResponse({ id: computerInfo.id, partial: 1, dataToUpload, }, api.updateComputerDetail);
+        // 检查上传结果并提示用户
+        if (resp.code === 2000) {
+          ElMessage.success('修改成功');
+          visible.value = false;
+          emit('refresh');
+        }
+      } catch (error) {
+        console.error('上传失败:', error);
+        ElMessage.error('上传失败,请重试');
+      }
+    } else {
+      console.log('error submit!', fields);
+    }
+  });
 };
 
-// 取消操作
-const handleCancel = () => {
-	router.push({
-		path: '/computer',
-	});
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
 };
 
 function replaceCol() {
   const result = Object.keys(formData).reduce((acc, key) => {
     if (key in computerInfo) {
-      acc[key] = computerInfo[key];
+      if (key === 'images' && Array.isArray(computerInfo[key])) {
+        acc[key] = computerInfo[key].map((img: { image: string }) => ({
+          name: '已上传图片',
+          url: img.image_url,
+        }));
+      } else {
+        acc[key] = computerInfo[key];
+      }
     }
     return acc;
   }, {} as { [key: string]: any });
   Object.assign(formData, result);
+  console.log(formData.images[0].url);
+}
+
+function handleImageError(file) {
+  // 当图片加载失败时,设置 file 对象的 error 状态为 true
+  file.error = true;
 }
 </script>
 
@@ -125,8 +182,8 @@ function replaceCol() {
 
 				<!-- 按钮组 -->
 				<el-form-item class="button-group">
-					<el-button type="primary" @click="handleSave">保存</el-button>
-					<el-button @click="handleCancel">取消</el-button>
+          <el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+          <el-button @click="resetForm(ruleFormRef)">取消</el-button>
 				</el-form-item>
 			</el-form>
 	</el-drawer>

+ 45 - 46
src/views/computer-information/components/InfoCard.vue

@@ -97,7 +97,7 @@ onMounted(() => {
 
 <template>
   <!-- 标题区域 -->
-  <el-card class="my-2.5" shadow="never" style="border: none;">
+  <el-card class="mb-5"  style="border: none;">
     <div class="flex justify-between items-baseline">
       <div>
         <span class="font-bold text-xl">电脑信息概览</span>
@@ -109,58 +109,57 @@ onMounted(() => {
     </div>
   </el-card>
 	<!-- 卡片展示区域 -->
-	<el-card v-loading="loading" shadow="never" style="border: none; min-height: 820px; position: relative">
-		<div class="card-container">
-			<el-row :gutter="20">
-				<el-col v-for="(item, index) in tableOptions.data" :key="index" :lg="6" :md="8" :sm="8" :xl="4" :xs="12" class="my-2.5">
-					<el-card class="item-card" shadow="hover">
-						<el-image :src="getImageUrl(item.images)" alt="电脑图片" class="card-image">
-							<template #error>
-								<el-icon class="card-image" style="font-size: 4rem">
-									<icon-picture />
-								</el-icon>
-							</template>
-						</el-image>
-						<div class="card-content">
-							<div>
-								<span style="color: #808d97; font-weight: 500">电脑编号: </span>
-								<span style="font-weight: 500">{{ item.computerNumber }}</span>
-							</div>
-							<div>
-								<span style="color: #808d97; font-weight: 500">所属店铺: </span>
-								<span style="font-weight: 500">{{ item.shopName }}</span>
-							</div>
-						</div>
-						<div class="card-footer">
-							<el-button :icon="Search" bg circle text type="primary" @click="checkItem(item)" />
-							<el-button :icon="EditPen" bg circle text type="warning" @click="editItem(item)" />
-							<!--<el-button :icon="Delete" circle text bg type="danger" @click="deleteItem(item)" />-->
-						</div>
-					</el-card>
-				</el-col>
-			</el-row>
-		</div>
-		<div class="pagination-container" style="position: absolute; right: 32px; bottom: 32px">
-			<el-pagination
-				v-model:current-page="tableOptions.page"
-				v-model:page-size="tableOptions.limit"
-				:page-sizes="[6, 12, 24, 36, 48, 60]"
-				:total="tableOptions.total"
-				background
-				layout="sizes, prev, pager, next, total"
-				@change="handlePageChange"
-			/>
-		</div>
-	</el-card>
+  <el-card class="mb-5" style="border: none;min-height: 83vh;">
+    <el-card class="card-container" v-loading="loading" shadow="never" style="border: none;">
+        <el-row :gutter="20">
+          <el-col v-for="(item, index) in tableOptions.data" :key="index" :lg="6" :md="8" :sm="8" :xl="4" :xs="12" class="my-2.5">
+            <el-card class="item-card" shadow="hover">
+              <el-image :src="getImageUrl(item.images)" alt="电脑图片" class="card-image">
+                <template #error>
+                  <el-icon class="card-image" style="font-size: 4rem">
+                    <icon-picture />
+                  </el-icon>
+                </template>
+              </el-image>
+              <div class="card-content">
+                <div>
+                  <span style="color: #808d97; font-weight: 500">电脑编号: </span>
+                  <span style="font-weight: 500">{{ item.computerNumber }}</span>
+                </div>
+                <div>
+                  <span style="color: #808d97; font-weight: 500">所属店铺: </span>
+                  <span style="font-weight: 500">{{ item.shopName }}</span>
+                </div>
+              </div>
+              <div class="card-footer">
+                <el-button :icon="Search" bg circle text type="primary" @click="checkItem(item)" />
+                <el-button :icon="EditPen" bg circle text type="warning" @click="editItem(item)" />
+              </div>
+            </el-card>
+          </el-col>
+        </el-row>
+    </el-card>
+    <div class="pagination-container" style="position: absolute; right: 40px; bottom: 50px">
+      <el-pagination
+          v-model:current-page="tableOptions.page"
+          v-model:page-size="tableOptions.limit"
+          :page-sizes="[6, 12, 24, 36, 48, 60]"
+          :total="tableOptions.total"
+          background
+          layout="sizes, prev, pager, next, total"
+          @change="handlePageChange"
+      />
+    </div>
+  </el-card>
   <!-- 新增 Dialog -->
   <CreateComputer v-model="showDialog" :shopOptions :userOptions @refresh="fetchCardData"></CreateComputer>
   <!-- 编辑 Drawer -->
-  <EditComputerInfo v-if="isDrawerVisible" v-model="isDrawerVisible" :shopOptions="shopOptions" :userOptions="userOptions" :computerInfo :computerNumber="computerInfo.computerNumber" />
+  <EditComputerInfo v-if="isDrawerVisible" @refresh="fetchCardData" v-model="isDrawerVisible" :shopOptions="shopOptions" :userOptions="userOptions" :computerInfo :computerNumber="computerInfo.computerNumber" />
 </template>
 
 <style lang="scss" scoped>
 .card-container {
-	margin-bottom: 20px;
+	margin-bottom: 30px;
 }
 
 .item-card {

+ 1 - 1
src/views/computer-information/index.vue

@@ -13,7 +13,7 @@ import { ref } from 'vue';
 </script>
 
 <template>
-	<div class="px-2.5">
+	<div class="flex flex-col p-5">
 		<InfoCard />
 	</div>
 </template>

+ 7 - 1
src/views/employee-information/api.ts

@@ -41,6 +41,9 @@ export function createEmployee(body: any) {
 		url: apiPrefix + 'create/',
 		method: 'POST',
 		data: body,
+		headers: {
+			'Content-Type': 'multipart/form-data',
+		}
 	});
 }
 
@@ -50,6 +53,9 @@ export function updateEmployeeDetail(query: any) {
 		url: apiPrefix + `${query.id}/`,
 		method: 'POST',
 		params: { partial: query.partial },
-		data: query.formData,
+		data: query.dataToUpload,
+		headers: {
+			'Content-Type': 'multipart/form-data',
+		}
 	});
 }

+ 13 - 7
src/views/employee-information/components/CreateEmployee.vue

@@ -9,6 +9,7 @@ import { useResponse } from '/@/utils/useResponse';
 import * as api from '../api';
 
 const showDialog = defineModel({ default: false });
+const emit = defineEmits([ 'refresh' ]);
 
 // 图片处理
 const upload = ref<UploadInstance>();
@@ -35,10 +36,13 @@ const formData = reactive<RuleForm>({
 const rules = reactive<FormRules<RuleForm>>({
   name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
   department: [{ required: true, message: '请输入部门', trigger: 'blur' }],
-  phone: [{ required: true, message: '请输入电话号码', trigger: 'blur' }],
-  email: [{ required: true, message: '请输入所属商铺', trigger: 'blur' }],
+  phone: [{ required: true, message: '请输入电话号码', trigger: 'blur' },
+    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
+  email: [{ required: true, message: '请输入邮箱', trigger: 'blur' },
+  { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }],
 });
 
+
 // 超过图片限制时触发的回调
 const handleExceed: UploadProps['onExceed'] = (files) => {
   upload.value!.clearFiles();
@@ -52,7 +56,8 @@ const submitForm = async (formEl: FormInstance | undefined) => {
   await formEl.validate((valid, fields) => {
     if (valid) {
       handleSave();
-      ElMessage.success('添加成功');
+      showDialog.value = false;
+      emit('refresh');
     } else {
       ElMessage.error('添加失败');
     }
@@ -66,12 +71,13 @@ async function handleSave() {
     bodyData.append(field, formData[field as keyof RuleForm]);
   });
 
-  // 处理图片文件,将每个图片文件对象添加到 FormData 中
-  const imageFile = formData.images[0]?.raw; // 获取 raw 属性中的 File 对象
-  if (imageFile instanceof File) {
-    bodyData.append('images', imageFile); // 使用 'images' 作为字段名,将 File 对象添加到 FormData 中
+  if (formData.images.length > 0 && formData.images[0].raw) {
+    bodyData.append('images', formData.images[0].raw); // 使用 'images' 作为字段名,将 File 对象添加到 FormData 中
   }
   await useResponse(bodyData, api.createEmployee);
+  if (resp.code === 2000) {
+    ElMessage.success('添加成功');
+  }
 }
 
 // 取消操作

+ 129 - 88
src/views/employee-information/components/EditEmployeeInfo.vue

@@ -5,138 +5,179 @@
  * @Author: xinyan
  */
 import { ref } from 'vue';
-import { FormInstance, FormRules, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
-import { genFileId } from 'element-plus';
-import router from '/@/router';
+import { ElIcon, ElMessage, FormInstance, FormRules, genFileId, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
+import { Plus } from '@element-plus/icons-vue';
+import { useResponse } from '/@/utils/useResponse';
+import * as api from '../api';
 
 const visible = defineModel({ default: false });
 const { employeeInfo, name } = defineProps<{
-  employeeInfo: any;
-  name: any;
+	employeeInfo: any;
+	name: any;
 }>();
 
+const emit = defineEmits(['refresh']);
+
 // 图片处理
 const upload = ref<UploadInstance>();
+
 // 表单数据
 interface RuleForm {
-  name: string;
-  department: string;
-  phone: string;
-  email: string;
-  user: string;
-  macaddress: string;
-  ipaddress: string;
-  images: UploadFile[];
+	name: string;
+	department: string;
+	phone: string;
+	email: string;
+	user: string;
+	macaddress: string;
+	ipaddress: string;
+	images: UploadFile[];
 }
 
 const ruleFormRef = ref<FormInstance>();
 const formData = reactive<RuleForm>({
-  name: '',
-  department: '',
-  phone: '',
-  email: '',
-  images: [],
+	name: '',
+	department: '',
+	phone: '',
+	email: '',
+	images: [],
 });
 
 const rules = reactive<FormRules<RuleForm>>({
-  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
-  department: [{ required: true, message: '请输入部门', trigger: 'blur' }],
-  phone: [{ required: true, message: '请输入电话号码', trigger: 'blur' }],
-  email: [{ required: true, message: '请输入所属商铺', trigger: 'blur' }],
+	name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
+	department: [{ required: true, message: '请输入部门', trigger: 'blur' }],
+	phone: [{ required: true, message: '请输入电话号码', trigger: 'blur' }],
+	email: [{ required: true, message: '请输入所属商铺', trigger: 'blur' }],
 });
 
 onBeforeMount(() => {
-  replaceCol();
+	replaceCol();
 });
 
 // 超过图片限制时触发的回调
 const handleExceed: UploadProps['onExceed'] = (files) => {
-  upload.value!.clearFiles();
-  const file = files[0] as UploadRawFile;
-  file.uid = genFileId();
-  upload.value!.handleStart(file);
+	upload.value!.clearFiles();
+	const file = files[0] as UploadRawFile;
+	file.uid = genFileId();
+	upload.value!.handleStart(file);
 };
 
-// 保存操作
-const handleSave = () => {
-  console.log(formData);
+const submitForm = async (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+
+	await formEl.validate(async (valid, fields) => {
+		if (valid) {
+			const dataToUpload = new FormData();
+
+			for (const key in formData) {
+				if (key !== 'images' && formData.hasOwnProperty(key)) {
+					dataToUpload.append(key, formData[key]);
+				}
+			}
+
+			if (Array.isArray(formData.images)) {
+				formData.images.forEach((image: any) => {
+					if (image.raw) {
+						dataToUpload.append('images', image.raw);
+					}
+				});
+			}
+			try {
+				const resp = await useResponse({ id: employeeInfo.id, partial: 1, dataToUpload, }, api.updateEmployeeDetail);
+				// 检查上传结果并提示用户
+				if (resp.code === 2000) {
+					ElMessage.success('修改成功');
+					visible.value = false;
+					emit('refresh');
+				}
+			} catch (error) {
+				console.error('上传失败:', error);
+				ElMessage.error('上传失败,请重试');
+			}
+		} else {
+			console.log('error submit!', fields);
+		}
+	});
 };
 
-// 取消操作
-const handleCancel = () => {
-  router.push({
-    path: '/employee',
-  });
+const resetForm = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
 };
 
 function replaceCol() {
-  const result = Object.keys(formData).reduce((acc, key) => {
-    if (key in employeeInfo) {
-      acc[key] = employeeInfo[key];
-    }
-    return acc;
-  }, {} as { [key: string]: any });
-  Object.assign(formData, result);
+	const result = Object.keys(formData).reduce((acc, key) => {
+		if (key in employeeInfo) {
+			// 如果字段是 images,则转换图片格式
+			if (key === 'images' && Array.isArray(employeeInfo[key])) {
+				acc[key] = employeeInfo[key].map((img: { image: string }) => ({
+					name: '已上传图片',
+					url: img.image_url,
+				}));
+			} else {
+				acc[key] = employeeInfo[key];
+			}
+		}
+		return acc;
+	}, {} as { [key: string]: any });
+	Object.assign(formData, result);
 }
 
-onMounted(() => {
-  console.log('visible',visible);
-})
+onMounted(() => {});
 </script>
 
 <template>
-  <el-drawer :title="`人员编辑 - ${name}`" v-model="visible" size="30%">
-    <el-form  ref="ruleFormRef" :model="formData" :rules="rules" class="employee-info-form" label-width="auto">
-      <el-form-item label="姓名:" prop="name">
-        <el-input v-model="formData.name" placeholder="请输入姓名" />
-      </el-form-item>
-      <el-form-item label="部门:" prop="department">
-        <el-input v-model="formData.department" placeholder="请输入部门" />
-      </el-form-item>
-      <el-form-item label="电话号码:" prop="phone">
-        <el-input v-model="formData.phone" placeholder="请输入电话号码" />
-      </el-form-item>
-      <el-form-item label="邮箱:" prop="email">
-        <el-input v-model="formData.email" placeholder="请输入邮箱" />
-      </el-form-item>
-      <!-- 电脑图片上传 -->
-      <el-form-item :key="images" label="电脑图片:">
-        <el-upload
-            ref="upload"
-            v-model:file-list="formData.images"
-            :auto-upload="false"
-            :limit="1"
-            :on-exceed="handleExceed"
-            action="#"
-            list-type="picture-card"
-        >
-          <el-icon>
-            <Plus />
-          </el-icon>
-        </el-upload>
-      </el-form-item>
-
-      <!-- 按钮组 -->
-      <el-form-item class="button-group">
-        <el-button type="primary" @click="handleSave">保存</el-button>
-        <el-button @click="handleCancel">取消</el-button>
-      </el-form-item>
-    </el-form>
-  </el-drawer>
+	<el-drawer v-model="visible" :title="`人员编辑 - ${name}`" size="30%">
+		<el-form ref="ruleFormRef" :model="formData" :rules="rules" class="employee-info-form" label-width="auto">
+			<el-form-item label="姓名:" prop="name">
+				<el-input v-model="formData.name" placeholder="请输入姓名" />
+			</el-form-item>
+			<el-form-item label="部门:" prop="department">
+				<el-input v-model="formData.department" placeholder="请输入部门" />
+			</el-form-item>
+			<el-form-item label="电话号码:" prop="phone">
+				<el-input v-model="formData.phone" placeholder="请输入电话号码" />
+			</el-form-item>
+			<el-form-item label="邮箱:" prop="email">
+				<el-input v-model="formData.email" placeholder="请输入邮箱" />
+			</el-form-item>
+			<!-- 电脑图片上传 -->
+			<el-form-item :key="images" label="电脑图片:">
+				<el-upload
+					ref="upload"
+					v-model:file-list="formData.images"
+					:auto-upload="false"
+					:limit="1"
+					:on-exceed="handleExceed"
+					action="#"
+					list-type="picture-card"
+				>
+					<el-icon>
+						<Plus />
+					</el-icon>
+				</el-upload>
+			</el-form-item>
+
+			<!-- 按钮组 -->
+			<el-form-item class="button-group">
+				<el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
+				<el-button @click="resetForm(ruleFormRef)">取消</el-button>
+			</el-form-item>
+		</el-form>
+	</el-drawer>
 </template>
 
 <style scoped>
 .employee-info-form {
-  padding: 20px;
+	padding: 20px;
 }
 
 .button-group {
-  margin-top: 20px;
-  text-align: center;
+	margin-top: 20px;
+	text-align: center;
 }
 
 .employee-info-form :deep(.el-form-item__label) {
-  font-size: 14px;
-  font-weight: 500;
+	font-size: 14px;
+	font-weight: 500;
 }
 </style>

+ 22 - 22
src/views/employee-information/components/EmployeeDetail.vue

@@ -37,11 +37,11 @@ const gridOptions: any = reactive({
   columnConfig: {
     resizable: true,
   },
-  pagerConfig: {
-    total: tableOptions.value.total,
-    page: tableOptions.value.page,
-    limit: tableOptions.value.limit,
-  },
+  // pagerConfig: {
+  //   total: tableOptions.value.total,
+  //   page: tableOptions.value.page,
+  //   limit: tableOptions.value.limit,
+  // },
   loading: false,
   loadingConfig: {
     icon: 'vxe-icon-indicator roll',
@@ -51,17 +51,17 @@ const gridOptions: any = reactive({
   data: [],
 });
 
-function pageChange({ pageSize, shopPage }: any) {
-  gridOptions.pagerConfig.limit = pageSize;
-  gridOptions.pagerConfig.page = shopPage;
-  fetchEmployeeData();
-}
+// function pageChange({ pageSize, shopPage }: any) {
+//   gridOptions.pagerConfig.limit = pageSize;
+//   gridOptions.pagerConfig.page = shopPage;
+//   fetchEmployeeData();
+// }
 
 // 当前信息、历史记录
 async function fetchEmployeeData(view) { // 默认为当前视图
   const query = {
-    page: gridOptions.pagerConfig.page,
-    limit: gridOptions.pagerConfig.limit,
+    // page: gridOptions.pagerConfig.page,
+    // limit: gridOptions.pagerConfig.limit,
   };
 
   switch (view) {
@@ -161,16 +161,16 @@ onMounted(() => {
           <el-button :type="currentView === 'shop' ? 'primary' : 'default'" @click="switchView('shop')"> 店铺信息 </el-button>
           <el-button :type="currentView === 'computer' ? 'primary' : 'default'" @click="switchView('computer')"> 电脑信息 </el-button>
         </template>
-        <template #pager>
-          <vxe-pager
-              v-model:currentPage="gridOptions.pagerConfig.page"
-              v-model:pageSize="gridOptions.pagerConfig.limit"
-              :total="gridOptions.pagerConfig.total"
-              size="small"
-              @page-change="handlePageChange"
-          >
-          </vxe-pager>
-        </template>
+        <!--<template #pager>-->
+        <!--  <vxe-pager-->
+        <!--      v-model:currentPage="gridOptions.pagerConfig.page"-->
+        <!--      v-model:pageSize="gridOptions.pagerConfig.limit"-->
+        <!--      :total="gridOptions.pagerConfig.total"-->
+        <!--      size="small"-->
+        <!--      @page-change="handlePageChange"-->
+        <!--  >-->
+        <!--  </vxe-pager>-->
+        <!--</template>-->
       </vxe-grid>
     </el-card>
   </div>

+ 100 - 78
src/views/employee-information/components/InfoCard.vue

@@ -1,4 +1,5 @@
-<script setup lang="ts">/**
+<script lang="ts" setup>
+/**
  * @Name: InfoCard.vue
  * @Description:
  * @Author: xinyan
@@ -7,135 +8,156 @@ import { useRouter } from 'vue-router';
 import { ref } from 'vue';
 import { usePagination } from '/@/utils/usePagination';
 import { useTableData } from '/@/utils/useTableData';
-import { Delete, EditPen, Picture as IconPicture, Search } from '@element-plus/icons-vue';
+import { Delete, EditPen, Picture as IconPicture, Plus, Search } from '@element-plus/icons-vue';
 import * as api from '/@/views/employee-information/api';
 import { useResponse } from '/@/utils/useResponse';
 import EditEmployeeInfo from '/@/views/employee-information/components/EditEmployeeInfo.vue';
+import CreateEmployee from '/@/views/employee-information/components/CreateEmployee.vue';
+import { ElCol } from 'element-plus';
 
 const router = useRouter();
 const loading = ref();
+// 创建弹窗
+const showDialog = ref(false);
 const isDrawerVisible = ref(false);
+
 const employeeInfo = ref([]);
 const { tableOptions, handlePageChange } = usePagination(fetchCardData);
 tableOptions.value.limit = 12;
 
 async function fetchCardData() {
-  const query = {
-    page: tableOptions.value.page,
-    limit: tableOptions.value.limit,
-  };
-  await useTableData(api.getCardData, query, tableOptions);
+	const query = {
+		page: tableOptions.value.page,
+		limit: tableOptions.value.limit,
+	};
+	await useTableData(api.getCardData, query, tableOptions);
+}
+
+async function addEmployee() {
+	showDialog.value = true;
 }
 
 const checkItem = (item) => {
-  router.push({
-    path: '/employee/detail',
-    query: {
-      id: item.id,
-    },
-  });
+	router.push({
+		path: '/employee/detail',
+		query: {
+			id: item.id,
+		},
+	});
 };
 
-async function editItem (item) {
-  const res = await useResponse(item.id, api.getEmployeeDetailOverview);
-  employeeInfo.value = res.data;
-  if (employeeInfo.value){
-    isDrawerVisible.value = true;  // 显示 Drawer
-    console.log("=>(InfoCard.vue:44) isDrawerVisible.value", isDrawerVisible.value);
-  }
+async function editItem(item) {
+	const res = await useResponse(item.id, api.getEmployeeDetailOverview);
+	employeeInfo.value = res.data;
+	if (employeeInfo.value) {
+		isDrawerVisible.value = true; // 显示 Drawer
+	}
 }
 
 const getImageUrl = (images) => {
-  // 如果有图片,返回第一个图片的 image_url,否则返回占位图
-  return images.length > 0 ? images[0].image_url : '';
+	// 如果有图片,返回第一个图片的 image_url,否则返回占位图
+	return images.length > 0 ? images[0].image_url : '';
 };
 
 onMounted(() => {
-  fetchCardData();
+	fetchCardData();
 });
-
 </script>
 
 <template>
-  <el-card shadow="never" style="border: none; min-height: 820px; position: relative;">
-    <div class="card-container">
-      <el-row :gutter="20">
-        <el-col v-for="(item, index) in tableOptions.data" :key="index" :span="4" class="my-2.5">
-          <el-card class="item-card" shadow="hover">
-            <el-image :src="getImageUrl(item.images)" alt="电脑图片" class="card-image">
-              <template #error>
-                <el-icon class="card-image" style="font-size: 4rem">
-                  <icon-picture />
-                </el-icon>
-              </template>
-            </el-image>
-            <div class="card-content">
-              <div>
-                <span style="color: #808d97;font-weight: 500">姓名: </span>
-                <span style="font-weight: 500">{{ item.name }}</span>
-              </div>
-              <div>
-                <span style="color: #808d97;font-weight: 500">部门: </span>
-                <span style="font-weight: 500">{{ item.department }}</span>
-              </div>
-            </div>
-            <div class="card-footer">
-              <el-button :icon="Search" circle text bg type="primary" @click="checkItem(item)" />
-              <el-button :icon="EditPen" circle text bg type="warning" @click="editItem(item)" />
-              <el-button :icon="Delete" circle text bg type="danger" @click="deleteItem(item)" />
-            </div>
-          </el-card>
-        </el-col>
-      </el-row>
-    </div>
-    <div class="pagination-container" style="position: absolute; right: 32px; bottom: 32px;">
+	<!-- 标题区域 -->
+	<el-card class="mb-5" style="border: none">
+		<div class="flex justify-between items-baseline">
+			<div>
+				<span class="font-bold text-xl">人员信息概览</span>
+				<el-divider class="text-3xl" direction="vertical" />
+			</div>
+			<span>
+				<el-button :icon="Plus" bg text type="primary" @click="addEmployee">添 加</el-button>
+			</span>
+		</div>
+	</el-card>
+	<!-- 卡片展示区域 -->
+	<el-card class="mb-5" style="border: none; min-height: 83vh">
+		<el-card v-loading="loading" class="card-container" shadow="never" style="border: none">
+			<el-row :gutter="20">
+				<el-col v-for="(item, index) in tableOptions.data" :key="index" :lg="6" :md="8" :sm="8" :xl="4" :xs="12" class="my-2.5">
+					<el-card class="item-card" shadow="hover">
+						<el-image :src="getImageUrl(item.images)" alt="电脑图片" class="card-image">
+							<template #error>
+								<el-icon class="card-image" style="font-size: 4rem">
+									<icon-picture />
+								</el-icon>
+							</template>
+						</el-image>
+						<div class="card-content">
+							<div>
+								<span style="color: #808d97; font-weight: 500">姓名: </span>
+								<span style="font-weight: 500">{{ item.name }}</span>
+							</div>
+							<div>
+								<span style="color: #808d97; font-weight: 500">部门: </span>
+								<span style="font-weight: 500">{{ item.department }}</span>
+							</div>
+						</div>
+						<div class="card-footer">
+							<el-button :icon="Search" bg circle text type="primary" @click="checkItem(item)" />
+							<el-button :icon="EditPen" bg circle text type="warning" @click="editItem(item)" />
+							<!--<el-button :icon="Delete" bg circle text type="danger" @click="deleteItem(item)" />-->
+						</div>
+					</el-card>
+				</el-col>
+			</el-row>
+		</el-card>
+    <div class="pagination-container" style="position: absolute; right: 40px; bottom: 50px">
       <el-pagination
           v-model:current-page="tableOptions.page"
           v-model:page-size="tableOptions.limit"
-          :page-sizes="[6, 12, 24,36,48,60]"
+          :page-sizes="[6, 12, 24, 36, 48, 60]"
           :total="tableOptions.total"
           background
           layout="sizes, prev, pager, next, total"
           @change="handlePageChange"
       />
     </div>
-    <!-- 编辑 Drawer -->
-    <EditEmployeeInfo v-if="isDrawerVisible" v-model="isDrawerVisible" :name="employeeInfo.name" :employeeInfo/>
-  </el-card>
-
+	</el-card>
+	<!-- 新增 Dialog -->
+	<CreateEmployee v-model="showDialog" @refresh="fetchCardData" />
+	<!-- 编辑 Drawer -->
+	<EditEmployeeInfo v-if="isDrawerVisible" @refresh="fetchCardData" v-model="isDrawerVisible" :employeeInfo :name="employeeInfo.name" />
 </template>
 
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .card-container {
-  margin-bottom: 20px;
+	margin-bottom: 30px;
 }
 
 .item-card {
-  border-radius: 10px;
-  overflow: hidden;
-  position: relative;
+	border-radius: 10px;
+	overflow: hidden;
+	position: relative;
 }
 
 .card-image {
-  width: 100%;
-  height: 150px;
-  object-fit: cover;
+	width: 100%;
+	height: 150px;
+	object-fit: cover;
 }
 
 .card-content {
-  padding: 10px;
-  font-size: 14px;
+	padding: 10px;
+	font-size: 14px;
 }
 
 .card-footer {
-  display: flex;
-  justify-content: flex-end;
-  // padding: 10px;
+	display: flex;
+	justify-content: flex-end;
+	// padding: 10px;
 }
 
 .pagination-container {
-  display: flex;
-  justify-content: flex-end;
-  // margin-bottom: 20px;
+	display: flex;
+	justify-content: flex-end;
+	// margin-bottom: 20px;
 }
-</style>
+</style>

+ 1 - 18
src/views/employee-information/index.vue

@@ -9,29 +9,12 @@ import InfoCard from '/@/views/employee-information/components/InfoCard.vue';
 import { Plus } from '@element-plus/icons-vue';
 import CreateEmployee from '/@/views/employee-information/components/CreateEmployee.vue';
 
-// 创建弹窗
-const showDialog = ref(false);
 
-async function addEmployee() {
-  showDialog.value = true;
-}
 </script>
 
 <template>
-	<div class="px-2.5">
-    <el-card class="my-2.5" shadow="never" style="border: none;">
-      <div class="flex justify-between items-baseline">
-        <div>
-          <span class="font-bold text-xl">人员信息概览</span>
-          <el-divider class=" text-3xl" direction="vertical"/>
-        </div>
-        <span>
-           <el-button :icon="Plus" text bg type="primary" @click="addEmployee">添 加</el-button>
-        </span>
-      </div>
-    </el-card>
+  <div class="flex flex-col p-5">
 		<InfoCard />
-    <CreateEmployee v-model="showDialog"/>
 	</div>
 </template>