Просмотр исходного кода

feat(abrylr): 重构安保人员管理页面

- 重命名文件:将 index.vue 改为 ablr.vue
- 优化页面布局和样式
- 添加新增、编辑和删除功能
- 实现分页和搜索功能
-增加表单验证
- 重构数据结构和接口调用
nahida 1 год назад
Родитель
Сommit
1658c250e1

+ 2 - 2
components.d.ts

@@ -28,6 +28,8 @@ declare module 'vue' {
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
     ElProgress: typeof import('element-plus/es')['ElProgress']
+    ElRadio: typeof import('element-plus/es')['ElRadio']
+    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
@@ -38,8 +40,6 @@ declare module 'vue' {
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTag: typeof import('element-plus/es')['ElTag']
-    ElText: typeof import('element-plus/es')['ElText']
-    ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
     IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']

+ 2 - 2
src/router/route.ts

@@ -493,10 +493,10 @@ export const routeList:RouterType[] = [
     icon: 'Location',
   },
   {
-    path: 'abrylr/index',
+    path: 'abrylr/ablr',
     name: '安保录入',
     icon: 'Location',
-    addr: 'abrylr/index'
+    addr: 'abrylr/ablr'
   },
 ]
 export const useDynamicRoutes: () => RouterType[] = () => {

+ 11 - 1
src/utils/getQueryMethod.ts

@@ -1,8 +1,18 @@
 interface QueryType {
   column:string,
-  value:string | number |boolean,
+  value?:string | number |boolean,
   type:'eq'|'like'
 }
+
+interface QueryTypeWithAny {
+  column:string,
+  value?:string | number |boolean,
+  type:string
+}
 export const getQueryEqMethod = (queryList:QueryType[]) => {
   return encodeURIComponent(JSON.stringify(queryList));
 }
+
+export const getQueryMethod = (queryList:QueryTypeWithAny[]) => {
+  return encodeURIComponent(JSON.stringify(queryList));
+}

+ 651 - 0
src/views/abrylr/ablr.vue

@@ -0,0 +1,651 @@
+<template>
+  <div class="security-personnel-container p-4">
+    <h2 class="text-xl font-bold mb-4">安保人员列表</h2>
+
+    <!-- 搜索和操作区域 -->
+    <div class="search-area mb-4 flex flex-wrap gap-3 items-center">
+      <div class="search-box flex">
+        <el-input
+          v-model="searchName"
+          placeholder="请输入姓名搜索"
+          class="w-64"
+          clearable
+          @clear="handleSearch"
+        >
+          <template #append>
+            <el-button @click="handleSearch">
+              <el-icon><Search /></el-icon>
+            </el-button>
+          </template>
+        </el-input>
+      </div>
+      <div class="action-box flex gap-2 ml-2">
+        <el-button type="primary" @click="openDialog()">
+          <el-icon><Plus /></el-icon>
+          <span class="ml-1">添加安保人员</span>
+        </el-button>
+        <el-button
+          type="danger"
+          :disabled="selectedRows.length === 0"
+          @click="handleBatchDelete"
+        >
+          <el-icon><Delete /></el-icon>
+          <span class="ml-1">批量删除</span>
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 表格区域 -->
+    <el-table
+      v-loading="loading"
+      :data="tableData"
+      border
+      stripe
+      class="w-full"
+      height="calc(100vh - 280px)"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column prop="name" label="姓名" min-width="100" />
+      <el-table-column prop="gender" label="性别" width="80" />
+      <el-table-column prop="birthDate" label="出生日期" min-width="120" />
+      <el-table-column prop="contactPhone" label="联系电话" min-width="120" />
+      <el-table-column prop="idNumber" label="身份证号码" min-width="180" />
+      <el-table-column prop="email" label="电子邮箱" min-width="150" />
+      <el-table-column prop="ethnicity" label="民族" width="100" />
+      <el-table-column prop="maritalStatus" label="婚姻状况" width="100" />
+      <el-table-column prop="nativePlace" label="籍贯" min-width="120" />
+      <el-table-column prop="currentAddress" label="现居住地址" min-width="200" />
+      <el-table-column prop="createTime" label="创建时间" min-width="180" />
+      <el-table-column label="操作" fixed="right" width="180">
+        <template #default="{ row }">
+          <div class="flex items-center space-x-1">
+            <el-button type="primary" link @click="viewDetails(row)">
+              <el-icon><View /></el-icon>
+            </el-button>
+            <el-button type="primary" link @click="openDialog(row)">
+              <el-icon><Edit /></el-icon>
+            </el-button>
+            <el-button type="danger" link @click="handleDelete(row.id)">
+              <el-icon><Delete /></el-icon>
+            </el-button>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页区域 -->
+    <div class="pagination-container flex justify-end mt-4">
+      <el-pagination
+        v-model:current-page="pagination.current"
+        v-model:page-size="pagination.size"
+        :page-sizes="[10, 20, 50, 100]"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="pagination.total"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+
+    <!-- 添加/编辑对话框 -->
+    <el-dialog
+      v-model="dialogVisible"
+      :title="formData.id ? '编辑安保人员' : '添加安保人员'"
+      width="650px"
+      destroy-on-close
+    >
+      <el-form
+        ref="formRef"
+        :model="formData"
+        :rules="formRules"
+        label-width="100px"
+        class="mt-4"
+      >
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="姓名" prop="name">
+              <el-input v-model="formData.name" placeholder="请输入姓名" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="性别" prop="gender">
+              <el-radio-group v-model="formData.gender">
+                <el-radio label="男">男</el-radio>
+                <el-radio label="女">女</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="出生日期" prop="birthDate">
+              <el-date-picker
+                v-model="formData.birthDate"
+                type="date"
+                placeholder="选择出生日期"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="联系电话" prop="contactPhone">
+              <el-input v-model="formData.contactPhone" placeholder="请输入联系电话" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="身份证号" prop="idNumber">
+              <el-input v-model="formData.idNumber" placeholder="请输入身份证号码" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="电子邮箱" prop="email">
+              <el-input v-model="formData.email" placeholder="请输入电子邮箱" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="民族" prop="ethnicity">
+              <el-input v-model="formData.ethnicity" placeholder="请输入民族" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="婚姻状况" prop="maritalStatus">
+              <el-select v-model="formData.maritalStatus" placeholder="请选择婚姻状况" style="width: 100%">
+                <el-option label="未婚" value="未婚" />
+                <el-option label="已婚" value="已婚" />
+                <el-option label="离异" value="离异" />
+                <el-option label="丧偶" value="丧偶" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="籍贯" prop="nativePlace">
+              <el-input v-model="formData.nativePlace" placeholder="请输入籍贯" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="现居住地址" prop="currentAddress">
+          <el-input
+            v-model="formData.currentAddress"
+            type="textarea"
+            :rows="2"
+            placeholder="请输入现居住地址"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="submitForm">确定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 查看详情对话框 -->
+    <el-dialog
+      v-model="detailsVisible"
+      title="安保人员详情"
+      width="700px"
+    >
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="姓名">{{ detailsData.name }}</el-descriptions-item>
+        <el-descriptions-item label="性别">{{ detailsData.gender }}</el-descriptions-item>
+        <el-descriptions-item label="出生日期">{{ detailsData.birthDate }}</el-descriptions-item>
+        <el-descriptions-item label="联系电话">{{ detailsData.contactPhone }}</el-descriptions-item>
+        <el-descriptions-item label="身份证号码">{{ detailsData.idNumber }}</el-descriptions-item>
+        <el-descriptions-item label="电子邮箱">{{ detailsData.email }}</el-descriptions-item>
+        <el-descriptions-item label="民族">{{ detailsData.ethnicity }}</el-descriptions-item>
+        <el-descriptions-item label="婚姻状况">{{ detailsData.maritalStatus }}</el-descriptions-item>
+        <el-descriptions-item label="籍贯">{{ detailsData.nativePlace }}</el-descriptions-item>
+        <el-descriptions-item label="现居住地址" :span="2">{{ detailsData.currentAddress }}</el-descriptions-item>
+        <el-descriptions-item label="创建时间" :span="2">{{ detailsData.createTime }}</el-descriptions-item>
+      </el-descriptions>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="detailsVisible = false">关闭</el-button>
+          <el-button type="primary" @click="openDialog(detailsData)">编辑</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, onMounted } from 'vue'
+import { clientGet, clientPost } from '@/utils/request.ts'
+import { getQueryMethod } from '@/utils/getQueryMethod.ts'
+import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
+import type { BaseResponse } from '@/utils/type.ts'
+import { Search, Plus, Delete, View, Edit } from '@element-plus/icons-vue'
+
+interface SecurityPersonnel {
+  /**
+   * 出生日期
+   */
+  birthDate: string;
+
+  /**
+   * 联系电话
+   */
+  contactPhone: string;
+
+  /**
+   * 创建者
+   */
+  createBy?: string | null;
+
+  /**
+   * 创建时间
+   */
+  createTime?: string;
+
+  /**
+   * 现居住地址
+   */
+  currentAddress: string;
+
+  /**
+   * 电子邮箱
+   */
+  email: string;
+
+  /**
+   * 民族
+   */
+  ethnicity: string;
+
+  /**
+   * 性别
+   */
+  gender: string;
+
+  /**
+   * 主键
+   */
+  id?: number;
+
+  /**
+   * 身份证号码
+   */
+  idNumber: string;
+
+  /**
+   * 婚姻状况
+   */
+  maritalStatus: string;
+
+  /**
+   * 安保人员姓名
+   */
+  name: string;
+
+  /**
+   * 籍贯
+   */
+  nativePlace: string;
+
+  /**
+   * 更新者
+   */
+  updateBy?: string | null;
+
+  /**
+   * 更新时间
+   */
+  updateTime?: string;
+}
+
+interface SecurityResponsePage {
+  records: SecurityPersonnel[];
+  total: number;
+  current: number;
+  size: number;
+}
+
+interface SecurityResponse extends BaseResponse{
+  data: SecurityPersonnel;
+}
+
+// 表格数据
+const tableData = ref<SecurityPersonnel[]>([]);
+const loading = ref(true);
+const searchName = ref('');
+const selectedRows = ref<SecurityPersonnel[]>([]);
+
+// 分页数据
+const pagination = reactive({
+  current: 1,
+  size: 10,
+  total: 0
+});
+
+// 表单相关
+const dialogVisible = ref(false);
+const formRef = ref<FormInstance>();
+const formData = reactive<SecurityPersonnel>({
+  birthDate: '',
+  contactPhone: '',
+  currentAddress: '',
+  email: '',
+  ethnicity: '',
+  gender: '男',
+  idNumber: '',
+  maritalStatus: '',
+  name: '',
+  nativePlace: '',
+});
+
+// 详情相关
+const detailsVisible = ref(false);
+const detailsData = ref<SecurityPersonnel>({
+  birthDate: '',
+  contactPhone: '',
+  currentAddress: '',
+  email: '',
+  ethnicity: '',
+  gender: '',
+  idNumber: '',
+  maritalStatus: '',
+  name: '',
+  nativePlace: '',
+});
+
+// 表单验证规则
+const validateIdCard = (rule: any, value: string, callback: any) => {
+  const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
+  if (!value) {
+    callback(new Error('请输入身份证号码'));
+  } else if (!reg.test(value)) {
+    callback(new Error('身份证号码格式不正确'));
+  } else {
+    callback();
+  }
+};
+
+const validatePhone = (rule: any, value: string, callback: any) => {
+  const reg = /^1[3-9]\d{9}$/;
+  if (!value) {
+    callback(new Error('请输入手机号码'));
+  } else if (!reg.test(value)) {
+    callback(new Error('手机号码格式不正确'));
+  } else {
+    callback();
+  }
+};
+
+const formRules = reactive<FormRules>({
+  name: [
+    { required: true, message: '请输入姓名', trigger: 'blur' },
+    { max: 20, message: '姓名长度不能超过20个字符', trigger: 'blur' }
+  ],
+  gender: [
+    { required: true, message: '请选择性别', trigger: 'change' }
+  ],
+  birthDate: [
+    { required: true, message: '请选择出生日期', trigger: 'change' }
+  ],
+  contactPhone: [
+    { required: true, message: '请输入联系电话', trigger: 'blur' },
+    { validator: validatePhone, trigger: 'blur' }
+  ],
+  idNumber: [
+    { required: true, message: '请输入身份证号码', trigger: 'blur' },
+    { validator: validateIdCard, trigger: 'blur' }
+  ],
+  email: [
+    { required: true, message: '请输入电子邮箱', trigger: 'blur' },
+    { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
+  ],
+  ethnicity: [
+    { required: true, message: '请输入民族', trigger: 'blur' },
+    { max: 15, message: '民族长度不能超过15个字符', trigger: 'blur' }
+  ],
+  maritalStatus: [
+    { required: true, message: '请选择婚姻状况', trigger: 'change' }
+  ],
+  nativePlace: [
+    { required: true, message: '请输入籍贯', trigger: 'blur' }
+  ],
+  currentAddress: [
+    { required: true, message: '请输入现居住地址', trigger: 'blur' }
+  ]
+});
+
+// 获取列表数据
+const getList = async () => {
+  loading.value = true;
+  try {
+    const res = await clientGet<{
+      pageNum: number;
+      pageSize: number;
+      conditionJson: string;
+    }, SecurityResponsePage>('/park/securityPersonnel/findByPage', {
+      params: {
+        pageNum: pagination.current,
+        pageSize: pagination.size,
+        conditionJson: getQueryMethod([
+          { column: 'create_time', type: 'orderByDesc' },
+          { column: 'name', type: 'like', value: searchName.value }
+        ])
+      }
+    });
+
+    tableData.value = res.records;
+    pagination.total = res.total;
+    pagination.current = res.current;
+    pagination.size = res.size;
+  } catch (e) {
+    console.error(e);
+    ElMessage.error('获取数据失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 搜索
+const handleSearch = () => {
+  pagination.current = 1;
+  getList();
+};
+
+// 分页处理
+const handleSizeChange = (size: number) => {
+  pagination.size = size;
+  getList();
+};
+
+const handleCurrentChange = (current: number) => {
+  pagination.current = current;
+  getList();
+};
+
+// 表格选择行变化
+const handleSelectionChange = (rows: SecurityPersonnel[]) => {
+  selectedRows.value = rows;
+};
+
+// 打开表单对话框
+const openDialog = (row?: SecurityPersonnel) => {
+  dialogVisible.value = true;
+
+  // 重置表单
+  if (formRef.value) {
+    formRef.value.resetFields();
+  }
+
+  // 编辑模式
+  if (row && row.id) {
+    Object.assign(formData, row);
+  } else {
+    // 新增模式
+    Object.keys(formData).forEach(key => {
+      if (key !== 'gender') {
+        (formData as any)[key] = '';
+      } else {
+        formData.gender = '男';
+      }
+    });
+    delete formData.id;
+  }
+};
+
+// 提交表单
+const submitForm = async () => {
+  if (!formRef.value) return;
+
+  await formRef.value.validate(async (valid) => {
+    if (valid) {
+      try {
+        loading.value = true;
+
+        if (formData.id) {
+          // 编辑
+          const res = await clientPost<SecurityPersonnel, BaseResponse>(
+            '/park/securityPersonnel/updateById',
+            formData
+          );
+
+          if (res.code === 200) {
+            ElMessage.success('修改成功');
+            dialogVisible.value = false;
+            getList();
+          } else {
+            ElMessage.error(res.msg || '修改失败');
+          }
+        } else {
+          // 新增
+          const res = await clientPost<SecurityPersonnel, BaseResponse>(
+            '/park/securityPersonnel/save',
+            formData
+          );
+
+          if (res.code === 200) {
+            ElMessage.success('添加成功');
+            dialogVisible.value = false;
+            getList();
+          } else {
+            ElMessage.error(res.msg || '添加失败');
+          }
+        }
+      } catch (error) {
+        console.error(error);
+        ElMessage.error('操作失败');
+      } finally {
+        loading.value = false;
+      }
+    }
+  });
+};
+
+// 查看详情
+const viewDetails = async (row: SecurityPersonnel) => {
+  try {
+    loading.value = true;
+    const res = await clientGet<null, SecurityResponse>('/park/securityPersonnel/getById/' + row.id);
+
+    if (res.code === 200) {
+      detailsData.value = res.data;
+      detailsVisible.value = true;
+    } else {
+      ElMessage.error(res.msg || '获取详情失败');
+    }
+  } catch (error) {
+    console.error(error);
+    ElMessage.error('获取详情失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 删除单个
+const handleDelete = async (id: number) => {
+  ElMessageBox.confirm('确定要删除该安保人员吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      loading.value = true;
+      const res = await clientPost<string, BaseResponse>(
+        '/park/securityPersonnel/delete',
+        JSON.stringify([id])
+      );
+
+      if (res.code === 200) {
+        ElMessage.success('删除成功');
+        getList();
+      } else {
+        ElMessage.error(res.msg || '删除失败');
+      }
+    } catch (error) {
+      console.error(error);
+      ElMessage.error('删除失败');
+    } finally {
+      loading.value = false;
+    }
+  }).catch(() => {
+    // 取消删除
+  });
+};
+
+// 批量删除
+const handleBatchDelete = async () => {
+  if (selectedRows.value.length === 0) {
+    ElMessage.warning('请选择要删除的安保人员');
+    return;
+  }
+
+  ElMessageBox.confirm(`确定要删除选中的 ${selectedRows.value.length} 名安保人员吗?`, '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      loading.value = true;
+      const ids = selectedRows.value.map(item => item.id);
+      const res = await clientPost<string, BaseResponse>(
+        '/park/securityPersonnel/delete',
+        JSON.stringify(ids)
+      );
+
+      if (res.code === 200) {
+        ElMessage.success('批量删除成功');
+        getList();
+      } else {
+        ElMessage.error(res.msg || '批量删除失败');
+      }
+    } catch (error) {
+      console.error(error);
+      ElMessage.error('批量删除失败');
+    } finally {
+      loading.value = false;
+    }
+  }).catch(() => {
+    // 取消删除
+  });
+};
+
+onMounted(() => {
+  getList();
+});
+</script>
+
+<style scoped>
+.security-personnel-container {
+  background-color: #fff;
+  border-radius: 4px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+</style>

+ 0 - 368
src/views/abrylr/index.vue

@@ -1,368 +0,0 @@
-<template>
-  <div class="min-h-screen bg-gray-50 p-8">
-    <div class="mx-auto">
-      <!-- 头部区域 -->
-      <div class="mb-6 flex items-center justify-between">
-        <h1 class="text-2xl font-bold text-gray-900">安保人员管理</h1>
-        <el-button type="primary" class="!rounded-button" @click="handleAdd">
-          <el-icon class="mr-1">
-            <Plus />
-          </el-icon>新增安保人员
-        </el-button>
-      </div>
-
-      <!-- 搜索区域 -->
-      <div class="mb-6 flex gap-4 rounded-lg bg-white p-4 shadow-sm">
-        <el-input v-model="searchForm.name" placeholder="请输入姓名搜索" class="max-w-xs" clearable>
-          <template #prefix>
-            <el-icon>
-              <Search />
-            </el-icon>
-          </template>
-        </el-input>
-        <el-input v-model="searchForm.phone" placeholder="请输入手机号搜索" class="max-w-xs" clearable>
-          <template #prefix>
-            <el-icon>
-              <Phone />
-            </el-icon>
-          </template>
-        </el-input>
-        <el-button type="primary" class="!rounded-button" @click="handleSearch">
-          搜索
-        </el-button>
-        <el-button class="!rounded-button" @click="handleReset">重置</el-button>
-      </div>
-
-      <!-- 表格区域 -->
-      <div class="rounded-lg bg-white p-6 shadow-sm">
-        <el-table :data="tableData" stripe style="width: 100%">
-          <el-table-column type="index" label="序号" />
-          <el-table-column label="头像">
-            <template #default="{ row }">
-              <el-avatar :size="50" :src="row.avatar" />
-            </template>
-          </el-table-column>
-          <el-table-column prop="name" label="姓名" />
-          <el-table-column prop="gender" label="性别" />
-          <el-table-column prop="IDNO" label="证件号码" />
-          <el-table-column prop="phone" label="手机号" width="130" />
-          <el-table-column prop="DEPARTMENT" label="所属部门" />
-          <el-table-column prop="PositionLevel" label="职位级别" />
-          <el-table-column prop="entryTime" label="入职时间" />
-          <el-table-column prop="contractPeriod" label="合同期限" />
-          <el-table-column prop="PPS" label="试用期状态" />
-          <el-table-column prop="DirectSupervisor" label="直属领导" />
-          <el-table-column prop="WorkLocation" label="工作地点" />
-          <el-table-column prop="certName" label="证书名称" />
-          <el-table-column prop="certStatus" label="证书状态">
-            <template #default="{ row }">
-              <el-tag :type="getCertStatusType(row.certStatus)" class="whitespace-nowrap">
-                {{ row.certStatus }}
-              </el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="操作" fixed="right" width="150">
-            <template #default="{ row }">
-              <el-button type="primary" link class="!rounded-button" @click="handleEdit(row)">
-                编辑
-              </el-button>
-              <el-button type="danger" link class="!rounded-button" @click="handleDelete(row)">
-                删除
-              </el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-
-        <div class="mt-4 flex    justify-end">
-          <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :total="total"
-            :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next" @size-change="handleSizeChange"
-            @current-change="handleCurrentChange" />
-        </div>
-      </div>
-    </div>
-
-    <!-- 新增/编辑弹窗 -->
-    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '新增安保人员' : '编辑安保人员'" width="600px">
-      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px" class="mt-4">
-        <el-form-item label="姓名" prop="name">
-          <el-input v-model="form.name" placeholder="请输入姓名" />
-        </el-form-item>
-        <el-form-item label="手机号" prop="phone">
-          <el-input v-model="form.phone" placeholder="请输入手机号" />
-        </el-form-item>
-        <el-form-item label="出生日期" prop="certDate">
-          <el-date-picker v-model="form.certDate" type="date" placeholder="出生日期"
-            :default-value="new Date(2010, 9, 1)" />
-        </el-form-item>
-      </el-form>
-
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button class="!rounded-button" @click="dialogVisible = false">取消</el-button>
-          <el-button type="primary" class="!rounded-button" @click="handleSubmit">确认</el-button>
-        </span>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { ref, reactive } from 'vue';
-import {
-  Plus,
-  Search,
-  Phone,
-  Upload,
-} from '@element-plus/icons-vue';
-import type { FormInstance, FormRules } from 'element-plus';
-import { clientDel, clientGet, clientPost, clientPut } from '@/utils/request.ts'
-import type { BaseResponse } from '@/utils/type.ts'
-
-
-interface IntroductItem {
-  id: string;
-  parkName: string;
-  remarks: string;
-  totalArea: string;
-  enteredCompany: string;
-  numberBuildings: string;
-  parkPersonnel: string;
-  standardFactory: string;
-  parkingLot: string;
-  productionLand: string;
-  officeLand: string;
-  greenVegetation: string;
-  infrastructure: string;
-  developmentArea: string;
-  createTime: string;
-  businessType: string;
-  updateTime: string;
-  isEnable: number;
-  filePath?: string;
-  file?: File;
-}
-
-interface IntroductResponse extends BaseResponse {
-  data: IntroductItem[]
-}
-const searchForm = reactive({
-  name: '',
-  phone: '',
-});
-
-const tableData = ref([
-  {
-    avatar: 'https://ai-public.mastergo.com/ai/img_res/ab6b2a2731dd9309532c1d31e77e37d8.jpg',
-    name: '邵建国',
-    gender: '男',
-    IDNO: '430524199808084151',
-    DEPARTMENT: '保安一部',
-    PositionLevel: '二级',
-    entryTime: '2025-01-02',
-    contractPeriod: '一年',
-    PPS: '实习',
-    DirectSupervisor: '张三',
-    WorkLocation: '综合楼',
-    phone: '13812345678',
-    certName: '安保人员资格证',
-    certStatus: '有效',
-  },
-  {
-    avatar: 'https://ai-public.mastergo.com/ai/img_res/adb4757a51078fd93278243eabcbf90a.jpg',
-    name: '李志强',
-    gender: '男',
-    IDNO: '430524199808084151',
-    DEPARTMENT: '保安一部',
-    PositionLevel: '二级',
-    entryTime: '2025-01-02',
-    contractPeriod: '一年',
-    PPS: '实习',
-    DirectSupervisor: '张三',
-    WorkLocation: '综合楼',
-    phone: '13812345678',
-    certName: '安保人员资格证',
-    certStatus: '有效',
-  },
-  {
-    avatar: 'https://ai-public.mastergo.com/ai/img_res/4e3ef5f71c53f38ea1cf35689071b390.jpg',
-    name: '王秀英',
-    gender: '男',
-    IDNO: '430524199808084151',
-    DEPARTMENT: '保安一部',
-    PositionLevel: '二级',
-    entryTime: '2025-01-02',
-    contractPeriod: '一年',
-    PPS: '实习',
-    DirectSupervisor: '张三',
-    WorkLocation: '综合楼',
-    phone: '13812345678',
-    certName: '安保人员资格证',
-    certStatus: '有效',
-  },
-]);
-
-const currentPage = ref(1);
-const pageSize = ref(10);
-const total = ref(100);
-
-const dialogVisible = ref(false);
-const dialogType = ref<'add' | 'edit'>('add');
-const formRef = ref<FormInstance>();
-
-const form = reactive({
-  avatar: '',
-  name: '',
-  phone: '',
-  cert: '',
-  certDate: [],
-});
-
-
-const getData = async () => {
-  const res = await clientGet<null, IntroductResponse>('/park/securityPersonnel/getList')
-  if (res.code === 200) {
-    console.log("获取到数据:", res.data)
-  }
-}
-
-getData();
-
-const rules: FormRules = {
-  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
-  phone: [
-    { required: true, message: '请输入手机号', trigger: 'blur' },
-    {
-      pattern: /^1[3-9]\d{9}$/,
-      message: '请输入正确的手机号',
-      trigger: 'blur',
-    },
-  ],
-  cert: [{ required: true, message: '请上传证书', trigger: 'change' }],
-  certDate: [{ required: true, message: '请选择证书有效期', trigger: 'change' }],
-};
-
-const handleSearch = () => {
-  // 实现搜索逻辑
-};
-
-const handleReset = () => {
-  searchForm.name = '';
-  searchForm.phone = '';
-};
-
-const handleAdd = () => {
-  dialogType.value = 'add';
-  dialogVisible.value = true;
-  Object.assign(form, {
-    avatar: '',
-    name: '',
-    phone: '',
-    cert: '',
-    certDate: [],
-  });
-
-
-  // try {
-  //   const formData = new FormData();
-  //   Object.entries(addForm.value).forEach(([key, value]) => {
-  //     if (key === 'file' && value instanceof File) {
-  //       formData.append('file', value);
-  //     } else {
-  //       formData.append(key, String(value));
-  //     }
-  //   });
-
-  //   const res = await clientPost<FormData, BaseResponse>('/park/parkInfo/save', formData, {
-  //     headers: {
-  //       'Content-Type': 'multipart/form-data',
-  //     },
-  //   });
-
-  //   if (res.code === 200) {
-  //     getData();
-  //     dialogVisible.value = false;
-  //     ElMessage.success('新增成功');
-  //     addForm.value = initData;
-  //   }
-  // } catch (error) {
-  //   console.error('新增失败', error);
-  //   ElMessage.error('新增失败');
-  // }
-};
-
-const handleEdit = (row: any) => {
-  dialogType.value = 'edit';
-  dialogVisible.value = true;
-  Object.assign(form, row);
-};
-
-const handleDelete = (row: any) => {
-  ElMessageBox.confirm('确认删除该安保人员?', '提示', {
-    confirmButtonText: '确定',
-    cancelButtonText: '取消',
-    type: 'warning',
-  }).then(() => {
-    ElMessage({
-      type: 'success',
-      message: '删除成功',
-    });
-  });
-};
-
-const handleSizeChange = (val: number) => {
-  pageSize.value = val;
-};
-
-const handleCurrentChange = (val: number) => {
-  currentPage.value = val;
-};
-
-const handleAvatarSuccess = (response: any) => {
-  form.avatar = response.url;
-};
-
-const handleCertSuccess = (response: any) => {
-  form.cert = response.url;
-};
-
-const handleSubmit = async () => {
-  if (!formRef.value) return;
-  await formRef.value.validate((valid) => {
-    if (valid) {
-      ElMessage({
-        type: 'success',
-        message: dialogType.value === 'add' ? '添加成功' : '修改成功',
-      });
-      dialogVisible.value = false;
-    }
-  });
-};
-
-const getCertStatusType = (status: string) => {
-  const statusMap: Record<string, string> = {
-    有效: 'success',
-    即将过期: 'warning',
-    已过期: 'danger',
-  };
-  return statusMap[status] || 'info';
-};
-</script>
-
-
-<style scoped>
-.avatar-uploader {
-  width: 100px;
-  height: 100px;
-}
-
-.avatar-uploader-icon {
-  font-size: 28px;
-  width: 100px;
-  height: 100px;
-}
-
-.avatar-image {
-  width: 100%;
-}
-</style>
-

+ 2 - 2
src/views/zhdpgl/zhdg/yjhj.vue

@@ -4,13 +4,13 @@ import { onMounted } from 'vue'
 //3秒后自动跳转一个网页(打开一个新窗口栏)
 onMounted(() => {
   setTimeout(() => {
-    window.open('http://172.16.102.52:8088')
+    window.open('https://172.16.102.52:8088')
   }, 3000)
 })
 </script>
 
 <template>
-  <div class="w-70% mx-a mt-30vh text-30px">即将打开一个新窗口如果不自动跳转请点击<a href="http://172.16.102.52:8088">这里</a></div>
+  <div class="w-70% mx-a mt-30vh text-30px">即将打开一个新窗口如果不自动跳转请点击<a href="https://172.16.102.52:8088">这里</a></div>
 </template>
 
 <style scoped>

+ 1 - 1
vite.config.ts

@@ -33,7 +33,7 @@ export default defineConfig({
       '/api': {
         // target: 'http://172.16.102.52:8080',
         //  target: 'http://localhost:8080',
-         target: 'http://172.16.102.52:8080',
+         target: 'http://192.168.110.235:8080',
         changeOrigin: true,
         rewrite: (path) => path.replace(/^\/api/, '')
       }