Browse Source

feat(shipOwnerManage): 实现船员证书类型三级联动选择功能

- 新增专业类别、证书类别和职务类别选择器
- 实现三级联动逻辑,根据选择动态更新选项
- 添加证书类型数据获取接口和相关处理函数
- 修改表单验证规则和数据结构,以支持新的选择器
wzg 8 months ago
parent
commit
bdd4bc8b0d
2 changed files with 187 additions and 15 deletions
  1. 5 0
      src/apis/fetch.js
  2. 182 15
      src/views/shipOwnerManage/shipOwnerDetail.vue

+ 5 - 0
src/apis/fetch.js

@@ -429,4 +429,9 @@ export default {
   deletePallet(data) {
     return $http("/pallet/delete", data);
   },
+
+  // 船员证件类型下拉
+  getShipOwnerCertTypeSelect() {
+    return $http("/shipOwner/cert/post/select");
+  },
 };

+ 182 - 15
src/views/shipOwnerManage/shipOwnerDetail.vue

@@ -147,27 +147,64 @@
       </el-row>
       <el-row :gutter="20">
         <el-col :span="8">
-          <el-form-item label="证书类型">
-            <el-input
-              v-model="shipOwnerForm.certificate.certType"
-              placeholder="请输入"
+          <el-form-item label="专业类别" prop="majorId">
+            <el-select
+              v-model="shipOwnerForm.certificate.majorId"
+              placeholder="请选择专业类别"
               class="w200"
               :disabled="!!shipOwnerForm.shipOwnerId && !isEditingCertificate"
-            ></el-input>
+              @change="handleMajorChange"
+            >
+              <el-option
+                v-for="item in certTypeOptions"
+                :key="item.key"
+                :label="item.value"
+                :value="item.key"
+              ></el-option>
+            </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="职务资格" prop="postRole">
+          <el-form-item label="证书类别" prop="categoryId">
             <el-select
-              v-model="shipOwnerForm.certificate.postRole"
-              placeholder="请选择"
+              v-model="shipOwnerForm.certificate.categoryId"
+              placeholder="请选择证书类别"
               class="w200"
-              :disabled="!!shipOwnerForm.shipOwnerId && !isEditingCertificate"
+              :disabled="
+                (!!shipOwnerForm.shipOwnerId && !isEditingCertificate) ||
+                !shipOwnerForm.certificate.majorId
+              "
+              @change="handleCategoryChange"
             >
-              <el-option label="大副" value="大副"></el-option>
-              <el-option label="二副" value="二副"></el-option>
-              <el-option label="三副" value="三副"></el-option>
-              <el-option label="船长" value="船长"></el-option>
+              <el-option
+                v-for="item in categoryOptions"
+                :key="item.key"
+                :label="item.value"
+                :value="item.key"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="职务类别" prop="postId">
+            <el-select
+              v-model="shipOwnerForm.certificate.postId"
+              placeholder="请选择职务类别"
+              class="w200"
+              :disabled="
+                (!!shipOwnerForm.shipOwnerId && !isEditingCertificate) ||
+                !shipOwnerForm.certificate.categoryId
+              "
+              @change="handlePostChange"
+            >
+              <el-option
+                v-for="item in postOptions"
+                :key="item.key"
+                :label="item.value"
+                :value="item.key"
+              ></el-option>
             </el-select>
           </el-form-item>
         </el-col>
@@ -597,7 +634,11 @@ const validateIssuerDate = (rule, value, callback) => {
 const certificateRules = {
   gender: [{ required: true, message: "请选择船员性别", trigger: "change" }],
   certNo: [{ required: true, message: "请输入证书编号", trigger: "blur" }],
-  postRole: [{ required: true, message: "请选择职务资格", trigger: "change" }],
+  majorId: [{ required: true, message: "请选择专业类别", trigger: "change" }],
+  categoryId: [
+    { required: true, message: "请选择证书类别", trigger: "change" },
+  ],
+  postId: [{ required: true, message: "请选择职务类别", trigger: "change" }],
   issuerAt: [
     { required: true, message: "请选择发证日期", trigger: "change" },
     { validator: validateIssuerDate, trigger: "change" },
@@ -628,6 +669,9 @@ const shipOwnerForm = ref({
     certNo: "", // 证书编号(必填)
     certType: "", // 证书类型(非必填)
     postRole: "", // 职务资格(必填)
+    majorId: "", // 专业类别ID(必填)
+    categoryId: "", // 证书类别ID(必填)
+    postId: "", // 职务类别ID(必填)
     issuerAt: "", // 发证日期(必填)
     expiryAt: "", // 截止日期(必填)
     issuerAuthority: "", // 签发机构(必填)
@@ -723,6 +767,85 @@ const serviceFileList = computed(() => {
   );
 });
 
+// 三级联动选择器数据
+const certTypeOptions = ref([]); // 专业类别选项
+const categoryOptions = ref([]); // 证书类别选项
+const postOptions = ref([]); // 职务类别选项
+const certTypeData = ref([]); // 存储完整的证书类型数据
+
+// 获取证书类型数据
+async function getCertTypeData() {
+  try {
+    const { data } = await api.getShipOwnerCertTypeSelect();
+    if (data.status === 0 && data.result) {
+      certTypeData.value = data.result;
+      certTypeOptions.value = data.result.map((item) => ({
+        key: item.key,
+        value: item.value,
+      }));
+    } else {
+      ElMessage.error(data.msg || "获取证书类型数据失败");
+    }
+  } catch (error) {
+    console.error("获取证书类型数据出错:", error);
+    ElMessage.error("获取证书类型数据出错");
+  }
+}
+
+// 处理专业类别变化
+function handleMajorChange(value) {
+  // 清空后续选择
+  shipOwnerForm.value.certificate.categoryId = "";
+  shipOwnerForm.value.certificate.postId = "";
+  categoryOptions.value = [];
+  postOptions.value = [];
+
+  // 根据选择的专业类别,更新证书类别选项
+  const selectedMajor = certTypeData.value.find((item) => item.key === value);
+  if (selectedMajor && selectedMajor.children) {
+    categoryOptions.value = selectedMajor.children.map((item) => ({
+      key: item.key,
+      value: item.value,
+    }));
+  }
+
+  // 更新证书类型显示值
+  const majorText =
+    certTypeOptions.value.find((item) => item.key === value)?.value || "";
+  shipOwnerForm.value.certificate.certType = majorText;
+}
+
+// 处理证书类别变化
+function handleCategoryChange(value) {
+  // 清空后续选择
+  shipOwnerForm.value.certificate.postId = "";
+  postOptions.value = [];
+
+  // 根据选择的专业类别和证书类别,更新职务类别选项
+  const selectedMajor = certTypeData.value.find(
+    (item) => item.key === shipOwnerForm.value.certificate.majorId
+  );
+  if (selectedMajor && selectedMajor.children) {
+    const selectedCategory = selectedMajor.children.find(
+      (item) => item.key === value
+    );
+    if (selectedCategory && selectedCategory.children) {
+      postOptions.value = selectedCategory.children.map((item) => ({
+        key: item.key,
+        value: item.value,
+      }));
+    }
+  }
+}
+
+// 处理职务类别变化
+function handlePostChange(value) {
+  // 更新职务资格显示值
+  const postText =
+    postOptions.value.find((item) => item.key === value)?.value || "";
+  shipOwnerForm.value.certificate.postRole = postText;
+}
+
 async function getShipOwnerDetail(shipOwnerId) {
   let { data } = await api.getShipOwnerDetail({
     shipOwnerId,
@@ -747,6 +870,9 @@ async function getShipOwnerDetail(shipOwnerId) {
         certNo: data.result.certificate?.certNo || "", // 证书编号
         certType: data.result.certificate?.certType || "", // 证书类型
         postRole: data.result.certificate?.postRole || "", // 职务资格
+        majorId: data.result.certificate?.majorId || "", // 专业类别ID
+        categoryId: data.result.certificate?.categoryId || "", // 证书类别ID
+        postId: data.result.certificate?.postId || "", // 职务类别ID
         issuerAt: data.result.certificate?.issuerAt || "", // 发证日期
         expiryAt: data.result.certificate?.expiryAt || "", // 截止日期
         issuerAuthority: data.result.certificate?.issuerAuthority || "", // 签发机构
@@ -760,6 +886,33 @@ async function getShipOwnerDetail(shipOwnerId) {
     if (shipOwnerForm.value.shipInfo.id) {
       shipInfoDisabled.value = true;
     }
+
+    // 如果有专业类别ID,需要初始化对应的选项
+    if (data.result.certificate?.majorId) {
+      // 根据选择的专业类别,更新证书类别选项
+      const selectedMajor = certTypeData.value.find(
+        (item) => item.key === data.result.certificate.majorId
+      );
+      if (selectedMajor && selectedMajor.children) {
+        categoryOptions.value = selectedMajor.children.map((item) => ({
+          key: item.key,
+          value: item.value,
+        }));
+
+        // 如果有证书类别ID,需要初始化对应的选项
+        if (data.result.certificate?.categoryId) {
+          const selectedCategory = selectedMajor.children.find(
+            (item) => item.key === data.result.certificate.categoryId
+          );
+          if (selectedCategory && selectedCategory.children) {
+            postOptions.value = selectedCategory.children.map((item) => ({
+              key: item.key,
+              value: item.value,
+            }));
+          }
+        }
+      }
+    }
   } else {
     ElMessage.error(data.msg || "获取船员详情失败");
   }
@@ -1073,6 +1226,10 @@ const updateShipOwnerCert = () => {
     const saveData = {
       shipOwnerId: shipOwnerForm.value.shipOwnerId,
       ...shipOwnerForm.value.certificate,
+      // 确保三级联动字段被包含
+      majorId: shipOwnerForm.value.certificate.majorId,
+      categoryId: shipOwnerForm.value.certificate.categoryId,
+      postId: shipOwnerForm.value.certificate.postId,
     };
 
     api
@@ -1141,6 +1298,13 @@ const saveShipOwner = async () => {
 
       // 构建保存数据
       const saveData = { ...shipOwnerForm.value };
+      // 确保三级联动字段被包含在证书信息中
+      if (saveData.certificate) {
+        saveData.certificate.majorId = shipOwnerForm.value.certificate.majorId;
+        saveData.certificate.categoryId =
+          shipOwnerForm.value.certificate.categoryId;
+        saveData.certificate.postId = shipOwnerForm.value.certificate.postId;
+      }
       if (route.query.shipOwnerId) {
         saveData.id = route.query.shipOwnerId;
       }
@@ -1332,7 +1496,10 @@ async function shipDetail(shipCode) {
 }
 
 // 初始化数据
-onMounted(() => {
+onMounted(async () => {
+  // 获取证书类型数据
+  await getCertTypeData();
+
   // 如果有ID参数,获取船员详情
   if (route.query.shipOwnerId) {
     shipOwnerForm.value.shipOwnerId = Number(route.query.shipOwnerId);