<template>
  <div class="p-2 personnel-page">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2 class="page-title">人员信息管理</h2>
      <p class="page-desc">管理企业所有工作人员基本信息和岗位证书</p>
    </div>

    <!-- 筛选区域 -->
    <el-card shadow="hover" class="filter-card">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="80">
        <el-form-item label="姓名" prop="personnelName">
          <el-input
            v-model="queryParams.personnelName"
            placeholder="请输入姓名搜索"
            style="width: 220px"
            clearable
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item label="人员类型" prop="jobType">
          <el-select v-model="queryParams.jobType" placeholder="全部类型" style="width: 200px" @change="handleQuery">
            <el-option label="全部类型" value="" />
            <el-option
              v-for="d in personTypeOptions"
              :key="d.value"
              :label="d.label"
              :value="d.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="工作门店" prop="storeId">
          <el-select
            v-model="queryParams.storeId"
            placeholder="请选择工作门店"
            clearable
            filterable
            style="width: 220px"
            @change="handleQuery"
          >
            <el-option
              v-for="d in storeOptions"
              :key="d.value"
              :label="d.label"
              :value="d.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">搜索</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 列表 -->
    <el-card shadow="hover" class="list-card">
      <div class="list-toolbar">
        <span class="list-total">共 {{ total }} 条记录</span>
        <el-button type="primary" :icon="Plus" @click="handleAdd">新增人员</el-button>
      </div>

      <el-table v-loading="loading" :data="personnelList" border stripe>
        <el-table-column type="index" label="序号" align="center" width="60" />
        <el-table-column label="类型" align="center" prop="jobType" width="100">
          <template #default="scope">
            <el-tag :type="getJobTypeTag(scope.row.jobType)">
              {{ getDictLabel(personTypeOptions, scope.row.jobType) || scope.row.jobType || '-' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="姓名" align="center" prop="personnelName" width="100" />
        <el-table-column label="年龄" align="center" prop="age" width="70" />
        <el-table-column label="身份证号" align="center" prop="idCard" width="200">
          <template #default="scope">
            <span>{{ maskIdCard(scope.row.idCard) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="岗位证书" align="center" min-width="200">
          <template #default="scope">
            <el-tag
              v-for="(cert, idx) in getPersonnelCerts(scope.row.id)"
              :key="idx"
              type="success"
              size="small"
              style="margin-right: 4px; margin-bottom: 4px"
            >
              {{ cert.certName || cert.certType }}
            </el-tag>
            <span v-if="getPersonnelCerts(scope.row.id).length === 0" class="text-placeholder">暂无证书</span>
          </template>
        </el-table-column>
        <el-table-column label="工作门店" align="center" prop="storeName" :show-overflow-tooltip="true" width="160" />
        <el-table-column label="保险状态" align="center" width="110">
          <template #default="scope">
            <el-tag :type="getInsuranceTag(scope.row)">{{ getInsuranceLabel(scope.row) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="220" fixed="right">
          <template #default="scope">
            <el-button link type="primary" @click="handleViewCert(scope.row)">查看证书</el-button>
            <el-button link type="primary" @click="handleUpdate(scope.row)">编辑</el-button>
            <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-show="total > 0"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        :total="total"
        @pagination="getList"
      />
    </el-card>

    <!-- 新增/编辑弹窗 -->
    <el-dialog
      v-model="dialog.visible"
      :title="dialog.title"
      width="820px"
      append-to-body
      :close-on-click-modal="false"
      @close="closeDialog"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="人员类型" prop="jobType">
              <el-select v-model="form.jobType" placeholder="请选择人员类型" style="width: 100%">
                <el-option
                  v-for="d in personTypeOptions"
                  :key="d.value"
                  :label="d.label"
                  :value="d.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="姓名" prop="personnelName">
              <el-input v-model="form.personnelName" placeholder="请输入姓名" maxlength="50" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="身份证号" prop="idCard">
              <el-input
                v-model="form.idCard"
                placeholder="请输入18位身份证号"
                maxlength="18"
                @blur="handleIdCardBlur"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="年龄" prop="age">
              <el-input-number
                v-model="form.age"
                :min="0"
                :max="150"
                placeholder="根据身份证自动计算"
                disabled
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="工作门店" prop="storeId">
              <el-select
                v-model="form.storeId"
                placeholder="请选择工作门店"
                filterable
                style="width: 100%"
                @change="handleStoreChange"
              >
                <el-option
                  v-for="d in storeOptions"
                  :key="d.value"
                  :label="d.label"
                  :value="d.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="保险状态" prop="insuranceStatus">
              <el-select
                v-model="form.insuranceStatus"
                placeholder="请选择保险状态"
                style="width: 100%"
                @change="handleInsuranceStatusChange"
              >
                <el-option
                  v-for="d in insuranceStatusOptions"
                  :key="d.value"
                  :label="d.label"
                  :value="d.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 保险有效期:仅已投保时必填 -->
        <el-row v-if="form.insuranceStatus === '已投保'" :gutter="20">
          <el-col :span="12">
            <el-form-item label="保险有效期开始" prop="insuranceStartDate">
              <el-date-picker
                v-model="form.insuranceStartDate"
                type="datetime"
                placeholder="请选择保险有效期开始"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="保险有效期结束" prop="insuranceExpireDate">
              <el-date-picker
                v-model="form.insuranceExpireDate"
                type="datetime"
                placeholder="请选择保险有效期结束"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 岗位证书:动态项 -->
        <el-form-item label="岗位证书">
          <div class="cert-container">
            <div
              v-for="(cert, index) in form.certList"
              :key="cert.uid || index"
              class="cert-item"
            >
              <el-select
                v-model="cert.certType"
                placeholder="请选择证书类型"
                style="width: 220px"
              >
                <el-option
                  v-for="d in certTypeOptions"
                  :key="d.value"
                  :label="d.label"
                  :value="d.value"
                />
              </el-select>
              <el-upload
                v-model:file-list="cert.fileList"
                :http-request="customCertUpload"
                :limit="1"
                :accept="'.pdf,.jpg,.png,.jpeg'"
                :before-upload="beforeCertUpload"
                :on-success="(response, file) => handleCertUploadSuccess(response, file, index)"
                :on-error="handleUploadError"
                :on-exceed="handleCertExceed"
                :on-remove="() => handleCertRemove(index)"
              >
                <template #trigger>
                  <div class="cert-upload-trigger">
                    <el-button type="primary" plain>选择文件</el-button>
                    <span class="cert-upload-text">{{ cert.fileList.length > 0 ? '已选择 1 个文件' : '未选择任何文件' }}</span>
                  </div>
                </template>
              </el-upload>
              <el-button link type="danger" @click="handleRemoveCert(index)">删除</el-button>
            </div>
            <el-button type="primary" plain :icon="Plus" @click="handleAddCert" style="margin-top: 4px">
              添加证书
            </el-button>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="submitForm">保存</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 查看证书弹窗 -->
    <el-dialog v-model="certDialog.visible" title="岗位证书" width="640px" append-to-body>
      <el-descriptions v-if="currentCerts.length > 0" :column="1" border>
        <el-descriptions-item
          v-for="(cert, idx) in currentCerts"
          :key="idx"
          :label="cert.certName || cert.certType"
        >
          <div v-if="cert.certFile" class="cert-view-box">
            <el-icon :size="22" class="cert-view-icon"><Document /></el-icon>
            <el-link :href="cert.certFile" target="_blank" type="primary" style="margin-left: 6px">
              查看证书文件
            </el-link>
          </div>
          <span v-else class="text-placeholder">未上传证书文件</span>
        </el-descriptions-item>
      </el-descriptions>
      <div v-else class="empty-tip">该人员暂无岗位证书</div>
      <template #footer>
        <el-button @click="certDialog.visible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Personnel" lang="ts">
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue';
import {
  listPersonnel,
  getPersonnel,
  savePersonnelWithCerts,
  delPersonnel
} from '@/api/risk/personnel';
import { listPersonnelCertByPersonnel } from '@/api/risk/personnelCert';
import { uploadFile } from '@/api/risk/file';
import { getDicts } from '@/api/system/dict/data';
import { listDept } from '@/api/system/dept';
import type { DictDataVO } from '@/api/system/dict/data/types';
import type { RiskPersonnelBo, RiskPersonnelVo, RiskPersonnelCertVo } from '@/api/risk/types';
import { Plus, Document } from '@element-plus/icons-vue';
import { ElMessage, FormInstance, UploadFile, UploadRawFile, UploadUserFile } from 'element-plus';
import type { ComponentInternalInstance } from 'vue';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

interface CertItem {
  uid: number;
  id?: string | number;
  certType: string;
  certName?: string;
  certFile?: string;
  fileList: UploadUserFile[];
}

const personnelList = ref<RiskPersonnelVo[]>([]);
const certMap = ref<Record<string | number, RiskPersonnelCertVo[]>>({});
const loading = ref(true);
const total = ref(0);
const currentCerts = ref<RiskPersonnelCertVo[]>([]);

// 字典
const personTypeOptions = ref<Array<{ label: string; value: string }>>([]);
const certTypeOptions = ref<Array<{ label: string; value: string }>>([]);
const insuranceStatusOptions = ref<Array<{ label: string; value: string }>>([]);

// 门店列表(从 sys_dept 拉 dept_category='门店' 的)
const storeOptions = ref<Array<{ label: string; value: number }>>([]);

const queryFormRef = ref<FormInstance>();
const formRef = ref<FormInstance>();

/** 加载字典 */
const loadDicts = async () => {
  try {
    const [personType, certType, insuranceStatus] = await Promise.all([
      getDicts('person_type'),
      getDicts('certificate_type'),
      getDicts('insurance_status')
    ]);
    personTypeOptions.value = mapDictData(personType);
    certTypeOptions.value = mapDictData(certType);
    insuranceStatusOptions.value = mapDictData(insuranceStatus);
  } catch (e) {
    console.error('加载字典失败', e);
  }
};

const mapDictData = (resOrList: any) => {
  // 字典接口被 axios 拦截器自动解包,返回值为数组;兼容部分场景被再包一层 .data 的情况
  const list: any[] = Array.isArray(resOrList)
    ? resOrList
    : Array.isArray(resOrList?.data)
      ? resOrList.data
      : [];
  return list
    .filter((d) => d.status === '0' || d.status === undefined)
    .sort((a, b) => (a.dictSort || 0) - (b.dictSort || 0))
    .map((d) => ({ label: d.dictLabel, value: d.dictValue }));
};

/** 加载门店列表(从 sys_dept 过滤 dept_category='门店') */
const loadStores = async () => {
  try {
    const res: any = await listDept({});
    const list: any[] = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
    storeOptions.value = list
      .filter((d: any) => d.deptCategory === '门店' && (d.status === '0' || d.status === undefined))
      .map((d: any) => ({ label: d.deptName, value: d.deptId }));
  } catch (e) {
    console.error('加载门店列表失败', e);
    storeOptions.value = [];
  }
};

const validateIdCard = (_rule: any, value: any, callback: any) => {
  if (!value) {
    callback(new Error('请输入身份证号'));
    return;
  }
  const reg = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
  if (!reg.test(value)) {
    callback(new Error('请输入正确的18位身份证号'));
    return;
  }
  const year = parseInt(value.substring(6, 10), 10);
  const month = parseInt(value.substring(10, 12), 10);
  const day = parseInt(value.substring(12, 14), 10);
  const birthDate = new Date(year, month - 1, day);
  if (
    birthDate.getFullYear() !== year ||
    birthDate.getMonth() !== month - 1 ||
    birthDate.getDate() !== day
  ) {
    callback(new Error('身份证号中的出生日期不合法'));
    return;
  }
  callback();
};

const data = reactive<any>({
  form: {
    id: undefined,
    personnelCode: '',
    personnelName: '',
    idCard: '',
    age: undefined,
    storeId: undefined,
    storeName: '',
    jobType: '',
    insuranceStatus: '未投保',
    insuranceStartDate: '',
    insuranceExpireDate: '',
    certList: [] as CertItem[]
  } as any,
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    personnelName: '',
    jobType: '',
    storeId: undefined
  },
  rules: {
    jobType: [{ required: true, message: '请选择人员类型', trigger: 'change' }],
    personnelName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
    idCard: [{ required: true, validator: validateIdCard, trigger: 'blur' }],
    storeId: [{ required: true, message: '请选择工作门店', trigger: 'change' }],
    insuranceStatus: [{ required: true, message: '请选择保险状态', trigger: 'change' }],
    insuranceStartDate: [
      {
        validator: (_rule: any, value: any, callback: any) => {
          if (data.form.insuranceStatus === '已投保' && !value) {
            callback(new Error('已投保时必须选择保险开始日期'));
          } else {
            callback();
          }
        },
        trigger: 'change'
      }
    ],
    insuranceExpireDate: [
      {
        validator: (_rule: any, value: any, callback: any) => {
          if (data.form.insuranceStatus === '已投保' && !value) {
            callback(new Error('已投保时必须选择保险结束日期'));
          } else {
            callback();
          }
        },
        trigger: 'change'
      }
    ]
  }
});

const { queryParams, form, rules } = toRefs(data);

const dialog = reactive({
  visible: false,
  title: '新增人员信息'
});

const certDialog = reactive({
  visible: false
});

/** 身份证号计算年龄 */
const calculateAge = (idCard: string): number => {
  if (!idCard || idCard.length !== 18) return 0;
  const birthYear = parseInt(idCard.substring(6, 10), 10);
  const birthMonth = parseInt(idCard.substring(10, 12), 10);
  const birthDay = parseInt(idCard.substring(14, 16), 10);
  const today = new Date();
  let age = today.getFullYear() - birthYear;
  if (
    today.getMonth() + 1 < birthMonth ||
    (today.getMonth() + 1 === birthMonth && today.getDate() < birthDay)
  ) {
    age--;
  }
  return age;
};

const maskIdCard = (idCard: string): string => {
  if (!idCard) return '';
  if (idCard.length < 8) return idCard;
  return idCard.substring(0, 6) + '********' + idCard.substring(14);
};

const handleIdCardBlur = () => {
  if (form.value.idCard && form.value.idCard.length === 18) {
    form.value.age = calculateAge(form.value.idCard);
  }
};

/** 保险状态切换:切换为未投保时清空有效期 */
const handleInsuranceStatusChange = (val: string) => {
  if (val !== '已投保') {
    form.value.insuranceStartDate = '';
    form.value.insuranceExpireDate = '';
  }
};

/** 工作门店选择变化:自动回填 storeName */
const handleStoreChange = (deptId: number | string) => {
  const found = storeOptions.value.find((s) => s.value === deptId);
  form.value.storeName = found?.label || '';
};

/** 列表中保险状态标签 */
const getInsuranceLabel = (row: any) => {
  if (row.insuranceStatus === '未投保') return '未投保';
  if (row.insuranceStatus === '已投保') {
    if (!row.insuranceExpireDate) return '已投保';
    const expire = new Date(row.insuranceExpireDate);
    const today = new Date();
    const diffDays = Math.floor((expire.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
    if (diffDays < 0) return '未投保';
    if (diffDays <= 30) return '即将到期';
    return '已投保';
  }
  return row.insuranceStatus || '未投保';
};

const getInsuranceTag = (row: any) => {
  const label = getInsuranceLabel(row);
  const map: Record<string, string> = {
    已投保: 'success',
    未投保: 'danger',
    即将到期: 'warning'
  };
  return map[label] || 'info';
};

// 人员类型 tag 颜色(按字典 value 映射,与设计稿一致)
const getJobTypeTag = (type: string) => {
  const map: Record<string, string> = {
    防损人员: 'primary',             // 蓝色
    施工人员: 'warning',             // 橙色
    特岗人员: 'danger',              // 红色
    食品相关岗位人员: 'success',     // 绿色
    检测员: 'info',                  // 灰色
    兼职品控人员: 'primary'          // 蓝色
  };
  return map[type] || 'info';
};

// 字典值 -> 中文 label(用于列表渲染)
const getDictLabel = (
  opts: Array<{ label: string; value: string }>,
  val: string
) => {
  if (!val) return ''
  return opts.find((o) => o.value === val)?.label || val
}

const getList = async () => {
  loading.value = true;
  const res = await listPersonnel(queryParams.value as RiskPersonnelBo);
  loading.value = false;
  personnelList.value = res.rows || [];
  total.value = res.total || 0;
  if (personnelList.value.length > 0) {
    loadPersonnelCerts(personnelList.value);
  }
};

const loadPersonnelCerts = async (list: RiskPersonnelVo[]) => {
  const map: Record<string | number, RiskPersonnelCertVo[]> = {};
  await Promise.all(
    list.map(async (p) => {
      try {
        const res = await listPersonnelCertByPersonnel(p.id);
        map[p.id] = res.data || [];
      } catch (e) {
        map[p.id] = [];
      }
    })
  );
  certMap.value = map;
};

const getPersonnelCerts = (id: string | number): RiskPersonnelCertVo[] => {
  return certMap.value[id] || [];
};

const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

const resetQuery = () => {
  queryFormRef.value?.resetFields();
  queryParams.value.pageNum = 1;
  queryParams.value.personnelName = '';
  queryParams.value.jobType = '';
  queryParams.value.storeId = undefined;
  handleQuery();
};

const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = '新增人员信息';
};

const handleUpdate = async (row: RiskPersonnelVo) => {
  reset();
  const res = await getPersonnel(row.id);
  Object.assign(form.value, res.data);
  if (form.value.idCard) {
    form.value.age = calculateAge(form.value.idCard);
  }
  try {
    const certRes = await listPersonnelCertByPersonnel(row.id);
    const certs = certRes.data || [];
    form.value.certList = certs.map((c) => ({
      uid: -Math.floor(Math.random() * 100000),
      id: c.id,
      certType: c.certType,
      certName: c.certName,
      certFile: c.certFile,
      fileList: c.certFile
        ? [
            {
              uid: -Math.floor(Math.random() * 100000),
              name: c.certName || c.certType || '证书',
              status: 'success',
              url: c.certFile
            }
          ]
        : []
    }));
  } catch (e) {
    form.value.certList = [];
  }
  dialog.visible = true;
  dialog.title = '编辑人员信息';
};

const handleViewCert = async (row: RiskPersonnelVo) => {
  try {
    const res = await listPersonnelCertByPersonnel(row.id);
    currentCerts.value = res.data || [];
  } catch (e) {
    currentCerts.value = [];
  }
  certDialog.visible = true;
};

const handleDelete = async (row: RiskPersonnelVo) => {
  try {
    await proxy?.$modal.confirm(`是否确认删除姓名为 "${row.personnelName}" 的人员信息?`);
    await delPersonnel(row.id);
    proxy?.$modal.msgSuccess('删除成功');
    await getList();
  } catch (e) {
    // 取消
  }
};

const handleAddCert = () => {
  if (!form.value.certList) {
    form.value.certList = [];
  }
  form.value.certList.push({
    uid: Date.now() + Math.floor(Math.random() * 1000),
    certType: '',
    certFile: '',
    fileList: []
  });
};

const handleRemoveCert = (index: number) => {
  form.value.certList?.splice(index, 1);
};

const handleCertUploadSuccess = (response: any, file: UploadFile, index: number) => {
  const url = response.data?.url || response.url;
  file.url = url;
  if (form.value.certList && form.value.certList[index]) {
    form.value.certList[index].certFile = url;
  }
  ElMessage.success('证书上传成功');
};

const handleCertRemove = (index: number) => {
  if (form.value.certList && form.value.certList[index]) {
    form.value.certList[index].certFile = '';
    form.value.certList[index].fileList = [];
  }
};

const handleUploadError = () => {
  ElMessage.error('上传失败,请重试');
};

const customCertUpload = async (options: any) => {
  try {
    const res: any = await uploadFile(options.file);
    if (res && res.code === 200 && res.data) {
      options.onSuccess(res, options.file);
    } else {
      options.onError(new Error(res?.msg || '上传失败'));
    }
  } catch (err: any) {
    options.onError(err);
  }
};

const beforeCertUpload = (file: UploadRawFile) => {
  const validTypes = ['image/jpeg', 'image/png', 'image/jpg', 'application/pdf'];
  if (!validTypes.includes(file.type)) {
    ElMessage.error('只能上传 PDF/JPG/PNG 格式的文件!');
    return false;
  }
  if (file.size / 1024 / 1024 >= 10) {
    ElMessage.error('文件大小不能超过 10MB!');
    return false;
  }
  return true;
};

const handleCertExceed = () => {
  ElMessage.warning('每个证书只能上传1个文件');
};

const submitForm = () => {
  formRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      const certBos = (form.value.certList || [])
        .filter((c: CertItem) => c.certType)
        .map((c: CertItem) => ({
          id: c.id,
          certType: c.certType,
          certName: c.certType,
          certFile: c.certFile || '',
          certStatus: '有效'
        }));

      const personnel = {
        id: form.value.id,
        personnelCode: form.value.personnelCode,
        personnelName: form.value.personnelName,
        idCard: form.value.idCard,
        age: form.value.age,
        storeId: form.value.storeId,
        storeName: form.value.storeName,
        jobType: form.value.jobType,
        insuranceStatus: form.value.insuranceStatus,
        insuranceStartDate: form.value.insuranceStatus === '已投保' ? form.value.insuranceStartDate : '',
        insuranceExpireDate: form.value.insuranceStatus === '已投保' ? form.value.insuranceExpireDate : ''
      };

      await savePersonnelWithCerts({ personnel, certList: certBos });
      proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
      dialog.visible = false;
      await getList();
    }
  });
};

const cancel = () => {
  dialog.visible = false;
  reset();
};

const reset = () => {
  form.value = {
    id: undefined,
    personnelCode: '',
    personnelName: '',
    idCard: '',
    age: undefined,
    storeId: undefined,
    storeName: '',
    jobType: '',
    insuranceStatus: '未投保',
    insuranceStartDate: '',
    insuranceExpireDate: '',
    certList: []
  } as any;
  formRef.value?.resetFields();
};

const closeDialog = () => {
  dialog.visible = false;
  reset();
};

onMounted(async () => {
  await loadDicts();
  await loadStores();
  await getList();
});
</script>

<style scoped>
.personnel-page {
  padding: 16px;
  height: 100%;
  overflow-y: auto;
  box-sizing: border-box;
}
.page-header {
  margin-bottom: 16px;
}
.page-title {
  font-size: 20px;
  font-weight: 600;
  margin: 0;
  color: #303133;
}
.page-desc {
  font-size: 13px;
  color: #909399;
  margin: 4px 0 0;
}
.filter-card {
  margin-bottom: 12px;
}
.list-card {
  margin-bottom: 12px;
}
.list-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.list-total {
  font-size: 13px;
  color: #606266;
}
.text-placeholder {
  color: #c0c4cc;
  font-size: 12px;
}
.empty-tip {
  text-align: center;
  color: #909399;
  padding: 40px 0;
  font-size: 14px;
}

.cert-container {
  width: 100%;
}
.cert-item {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.cert-upload-trigger {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.cert-upload-text {
  font-size: 13px;
  color: #606266;
}
:deep(.el-upload) {
  display: inline-block;
}

.cert-view-box {
  display: inline-flex;
  align-items: center;
}
.cert-view-icon {
  color: #e6a23c;
}
</style>