hejianhao
2026-01-23 6376b597278882cd500be4ddbc3ac71489dd2a7a
Merge branch 'main' of http://120.76.84.145:10101/gitblit/r/H5/smartBuilding
1个文件已添加
2个文件已修改
678 ■■■■■ 已修改文件
screen/src/view/hiddenDanger/README.md 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/hiddenDanger/index.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/hiddenDanger/service.js 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/hiddenDanger/README.md
New file
@@ -0,0 +1,326 @@
# 隐患管理模块 - 项目端与委托方端兼容方案
## 📋 概述
本模块实现了项目端和委托方端的统一管理,通过数据适配器模式,在不改变原有项目端逻辑的前提下,完美兼容委托方端的接口调用。
**判断逻辑:通过路由参数 `projectId` 区分**
- ✅ **有 `projectId`** = 项目端
- ✅ **无 `projectId`** = 委托方端
## 🔄 接口差异
### 1. 列表查询接口
| 端 | 重大隐患 | 安全隐患 | 设备隐患 |
|---|---------|---------|---------|
| **项目端** | `/project/getHiddenDangerList` | 同左(通过type参数区分) | 同左(通过type参数区分) |
| **委托方** | `/projectEntrust/errorList` | `/projectEntrust/safetyErrorList` | `/projectEntrust/deviceErrorList` |
### 2. 字段差异
| 字段含义 | 项目端 | 委托方 | 处理方式 |
|---------|--------|--------|---------|
| 问题描述 | `description` | `problemName` | 适配器映射 |
| 检查时间 | `createTime` | `checkTime` | 适配器映射 |
| 图片列表 | `userFiles` | `pictures` | 适配器映射 |
| 图片数量 | `fileNum` | `pictures.length` | 适配器计算 |
| 隐患等级 | 0-3 | 1-4 | 适配器转换(-1) |
| 整改状态 | 0/1 (number) | true/false (boolean) | 适配器转换 |
### 3. 详情和编辑接口
| 功能 | 项目端 | 委托方 |
|-----|--------|--------|
| 获取详情 | `/project/getHiddenDangerDetail/{id}` | `/projectEntrust/getHiddenDangerDetail/{id}` |
| 编辑责任人 | `/project/editHiddenDangerResponsiblePerson` | `/projectEntrust/editHiddenDangerResponsiblePerson` |
### 4. 项目列表接口
| 功能 | 接口 | 参数 |
|-----|------|------|
| 获取项目列表 | `/project/getLoginNameVoList` | `userId`(从 localStorage 获取) |
## 🛠️ 实现方案
### 1. service.js 架构
```
service.js
├── 项目端接口(原有)
│   ├── getLoginNameVoList (需要 userId 参数)
│   ├── getHiddenDangerList
│   ├── getHiddenDangerDetail
│   └── editHiddenDangerResponsiblePerson
│
├── 委托方接口(新增)
│   ├── getClientMajorErrorList
│   ├── getClientSafetyErrorList
│   ├── getClientDeviceErrorList
│   ├── getClientHiddenDangerDetail
│   └── editClientHiddenDangerResponsiblePerson
│
├── 数据适配器(核心)
│   ├── adaptClientDataToProject - 委托方数据 → 项目端格式
│   └── adaptProjectDataToClient - 项目端数据 → 委托方格式
│
└── 统一调用方法(对外暴露)
    ├── getHiddenDangerListByType
    ├── getHiddenDangerDetailByType
    └── editResponsiblePersonByType
```
### 2. 数据适配器逻辑
#### adaptClientDataToProject(委托方 → 项目端)
```javascript
{
  description: item.problemName,           // 字段映射
  createTime: item.checkTime,              // 字段映射
  userFiles: item.pictures,                // 字段映射
  fileNum: item.pictures.length,           // 计算字段
  level: item.level - 1,                   // 等级转换:1-4 → 0-3
  reformed: item.reformed ? 1 : 0,         // 布尔转数字
}
```
#### adaptProjectDataToClient(项目端 → 委托方)
```javascript
{
  reformed: data.reformed === 1 || data.reformed === true  // 数字转布尔
}
```
### 3. index.vue 修改点
#### 新增数据字段和计算属性
```javascript
data() {
  return {
    isClient: false, // 是否委托方端(新增)
    // ... 其他字段保持不变
  }
},
computed: {
  isProjectMode() {
    return !!this.projectId;  // 有projectId = 项目端
  },
  isClientMode() {
    return !this.projectId;   // 无projectId = 委托方端
  }
}
```
#### 判断用户类型(created钩子)
```javascript
created() {
  // 从路由获取参数
  if (this.$route.query.projectId) {
    this.projectId = this.$route.query.projectId;
  }
  // 通过 projectId 判断:有 = 项目端,无 = 委托方端
  this.isClient = !this.projectId;
}
```
#### 加载项目列表(从 localStorage 获取 userId)
```javascript
async loadProjectList() {
  try {
    // 从 localStorage 获取 userInfo
    const userInfoStr = localStorage.getItem('userInfo');
    if (!userInfoStr) {
      console.error("未找到用户信息");
      return;
    }
    const userInfo = JSON.parse(userInfoStr);
    const userId = userInfo.userId;
    if (!userId) {
      console.error("用户信息中未找到 userId");
      return;
    }
    // 调用接口,传入 userId
    const res = await getLoginNameVoList({ userId });
    if (res && res) {
      this.projectList = res.map((item) => ({
        label: item.name,
        value: item.id,
      }));
    }
  } catch (error) {
    console.error("加载项目列表失败:", error);
  }
}
```
#### 修改的方法(仅3处)
1. **loadTableData()** - 加载列表数据
   ```javascript
   const res = await getHiddenDangerListByType(
     params,
     this.activeTab,
     this.isClient  // 传入用户类型
   );
   ```
2. **handleViewDetail()** - 查看详情
   ```javascript
   const res = await getHiddenDangerDetailByType(
     row.problemId,
     this.isClient  // 传入用户类型
   );
   ```
3. **saveUpdatePeople()** - 保存责任人
   ```javascript
   await editResponsiblePersonByType(
     { id: this.currentEditRow.id, responsiblePerson: this.peopleName },
     this.isClient  // 传入用户类型
   );
   ```
## 🎯 使用方式
### **项目端访问(原有方式)**
```javascript
// 带 projectId 参数 = 项目端
this.$router.push({
  path: '/hiddenDanger',
  query: {
    projectId: '123',      // 👈 有这个参数就是项目端
    projectName: '某某项目',
    activeTab: 1
  }
})
```
### **委托方端访问(新增方式)**
```javascript
// 不带 projectId 参数 = 委托方端
this.$router.push({
  path: '/hiddenDanger',
  query: {
    // 👈 没有 projectId 参数就是委托方端
    activeTab: 1
  }
})
// 委托方也可以选择项目后传入 projectId(用于筛选)
// 但页面会显示项目选择下拉框,用户可以切换项目
```
## 🔍 工作原理
```
用户访问页面
    ↓
读取路由参数 projectId
    ↓
┌─────────────┬─────────────┐
│  有projectId │  无projectId │
│  项目端      │  委托方端    │
└─────────────┴─────────────┘
    ↓              ↓
调用项目端接口  调用委托方接口
    ↓              ↓
    │         数据适配器转换
    │              ↓
    └──────┬───────┘
           ↓
    统一的数据格式
           ↓
    正常渲染页面
```
## ✨ 方案优势
| 优势 | 说明 |
|-----|------|
| 🎯 **零侵入** | 项目端代码逻辑完全不受影响 |
| 🔄 **高复用** | UI和业务逻辑100%复用 |
| 🛠️ **易维护** | 只需维护一个页面 |
| 🚀 **易扩展** | 未来增加新角色只需添加适配器 |
| ✅ **低风险** | 通过适配器隔离差异,不会数据混乱 |
| 🎨 **简单判断** | 只需通过 projectId 即可区分端 |
## 🔍 测试要点
### 1. 项目端测试(回归测试)
- [ ] 带 projectId 参数访问
- [ ] 列表查询正常
- [ ] 三个Tab切换正常
- [ ] 筛选条件正常
- [ ] 详情查看正常
- [ ] 编辑责任人正常
- [ ] 图片预览正常
### 2. 委托方端测试(新功能测试)
- [ ] 不带 projectId 参数访问
- [ ] 显示项目选择下拉框
- [ ] 项目列表加载正常(需要 localStorage 中有 userInfo.userId)
- [ ] 重大隐患列表正常(调用 `/projectEntrust/errorList`)
- [ ] 安全隐患列表正常(调用 `/projectEntrust/safetyErrorList`)
- [ ] 设备隐患列表正常(调用 `/projectEntrust/deviceErrorList`)
- [ ] 字段映射正确(problemName → description)
- [ ] 时间字段正确(checkTime → createTime)
- [ ] 图片显示正常(pictures → userFiles)
- [ ] 隐患等级正确(1-4 → 一级~四级)
- [ ] 整改状态正确(true/false → 已整改/未整改)
- [ ] 详情查看正常
- [ ] 编辑责任人正常
### 3. 边界测试
- [ ] 空数据处理
- [ ] 图片为空时的处理
- [ ] 等级为null时的处理
- [ ] 整改状态为null时的处理
- [ ] localStorage 中没有 userInfo 的处理
- [ ] userInfo 中没有 userId 的处理
## 📝 注意事项
1. **判断逻辑**:
   - 当前通过 `projectId` 是否存在来判断
   - 项目端:从上游页面跳转时带 `projectId`,页面不显示项目选择框
   - 委托方端:不带 `projectId`,页面显示项目选择下拉框
2. **localStorage 依赖**:
   - 委托方端需要从 `localStorage.getItem('userInfo')` 获取用户信息
   - 确保登录时已将 `userInfo` 存储到 localStorage
   - `userInfo` 对象中必须包含 `userId` 字段
3. **接口路径确认**:如果委托方的详情和编辑接口路径不同,需要在 service.js 中修改
4. **权限控制**:如果需要权限控制,建议在路由守卫中处理
5. **错误处理**:适配器中已做了兼容处理,但建议在实际使用中增加更多的边界判断
## 🚀 后续优化建议
1. 可以将 `isClient` 存储到 Vuex 中,避免每次从路由参数读取
2. 可以将适配器逻辑抽离为独立的工具类,便于其他模块复用
3. 可以增加日志记录,方便排查问题
4. 可以增加单元测试,确保适配器逻辑正确
5. 建议在应用初始化时检查 localStorage 中是否有 userInfo,避免运行时错误
## 📞 联系方式
如有问题,请联系开发团队。
screen/src/view/hiddenDanger/index.vue
@@ -39,7 +39,7 @@
            v-model="searchForm.projectId"
            placeholder="请选择项目"
            class="flex1"
            clearable
            @change="handleSelectChange"
          >
            <el-option
              v-for="item in projectList"
@@ -49,10 +49,17 @@
            >
            </el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearSelect('projectId')"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="searchForm.projectId"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
          </div>
        </div>
        <!-- 整改状态 -->
@@ -63,7 +70,7 @@
            v-model="searchForm.reformed"
            placeholder="请选择整改状态"
            class="flex1"
            clearable
            @change="handleSelectChange"
          >
            <el-option
              v-for="item in reformedOptions"
@@ -73,10 +80,17 @@
            >
            </el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearSelect('reformed')"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="searchForm.reformed !== null"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
          </div>
        </div>
        <!-- 隐患类型(仅重大隐患显示) -->
@@ -88,15 +102,22 @@
            v-model="searchForm.type"
            placeholder="请选择隐患类型"
            class="flex1"
            clearable
            @change="handleSelectChange"
          >
            <el-option label="安全隐患" :value="1"></el-option>
            <el-option label="设备隐患" :value="2"></el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearSelect('type')"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="searchForm.type !== null"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
          </div>
        </div>
        <!-- 隐患等级(安全和设备隐患显示) -->
@@ -108,7 +129,7 @@
            v-model="searchForm.level"
            placeholder="请选择隐患等级"
            class="flex1"
            clearable
            @change="handleSelectChange"
          >
            <el-option
              v-for="item in levelOptions"
@@ -118,10 +139,17 @@
            >
            </el-option>
          </el-select>
          <img
            src="../../assets/img/down-circle@2x.png"
            class="w--15 h--16 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearSelect('level')"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="searchForm.level !== null"
            />
            <img
              src="../../assets/img/down-circle@2x.png"
              class="w--15 h--16 shrink0"
            />
          </div>
        </div>
        <!-- 开始时间 -->
@@ -149,10 +177,17 @@
          >
            开始时间
          </div>
          <img
            src="../../assets/img/home/Shape@2x (6).png"
            class="w--13 h--13 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearDateTime('start')"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="startDateTxt"
            />
            <img
              src="../../assets/img/home/Shape@2x (6).png"
              class="w--13 h--13 shrink0"
            />
          </div>
        </div>
        <!-- 结束时间 -->
@@ -180,10 +215,17 @@
          >
            结束时间
          </div>
          <img
            src="../../assets/img/home/Shape@2x (6).png"
            class="w--13 h--13 shrink0"
          />
          <div class="flex a-center gap--5">
            <i
              @click.stop="clearDateTime('end')"
              class="el-icon-circle-close c-fff cursor-pointer"
              v-show="endDateTxt"
            />
            <img
              src="../../assets/img/home/Shape@2x (6).png"
              class="w--13 h--13 shrink0"
            />
          </div>
        </div>
        <!-- 搜索内容 -->
@@ -203,6 +245,7 @@
      </div>
      <!-- 表格 -->
      <CustomTable
        :key="activeTab"
        :data="tableData"
        height="800"
        style="border: 2px solid #3d7fff"
@@ -539,9 +582,9 @@
import moment from "moment";
import {
  getLoginNameVoList,
  getHiddenDangerList,
  getHiddenDangerDetail,
  editHiddenDangerResponsiblePerson,
  getHiddenDangerListByType,
  getHiddenDangerDetailByType,
  editResponsiblePersonByType,
} from "./service";
import {
  errorLevelMap,
@@ -559,6 +602,7 @@
      // 路由参数
      projectId: null, // 项目ID,如果有则是项目端使用
      projectName: "", // 项目名称
      isClient: false, // 是否委托方端
      // 搜索条件
      searchForm: {
@@ -607,6 +651,11 @@
      return !!this.projectId;
    },
    // 是否是委托方端(没有projectId参数)
    isClientMode() {
      return !this.projectId;
    },
    // 当前隐患类型(根据activeTab判断)
    currentType() {
      // 1=重大隐患(暂无对应type) 2=安全隐患(type=1) 3=设备隐患(type=2)
@@ -642,6 +691,8 @@
        if (newVal) {
          this.startDateTxt = moment(newVal).format("YYYY年MM月DD日 HH:mm:ss");
          this.searchForm.startTime = moment(newVal).format("YYYY-MM-DD HH:mm:ss");
          // 选择时间后自动请求
          this.handleSelectChange();
        } else {
          this.startDateTxt = "";
          this.searchForm.startTime = null;
@@ -655,6 +706,8 @@
        if (newVal) {
          this.endDateTxt = moment(newVal).format("YYYY年MM月DD日 HH:mm:ss");
          this.searchForm.endTime = moment(newVal).format("YYYY-MM-DD HH:mm:ss");
          // 选择时间后自动请求
          this.handleSelectChange();
        } else {
          this.endDateTxt = "";
          this.searchForm.endTime = null;
@@ -674,6 +727,10 @@
    if (this.$route.query.projectName) {
      this.projectName = this.$route.query.projectName;
    }
    // 判断是否委托方端:通过 projectId 判断
    // 有 projectId = 项目端,无 projectId = 委托方端
    this.isClient = !this.projectId;
    // 初始化下拉选项
    this.initOptions();
@@ -723,7 +780,22 @@
    // 加载项目列表
    async loadProjectList() {
      try {
        const res = await getLoginNameVoList({});
        // 从 localStorage 获取 userInfo
        const userInfoStr = localStorage.getItem('userInfo');
        if (!userInfoStr) {
          console.error("未找到用户信息");
          return;
        }
        const userInfo = JSON.parse(userInfoStr);
        const userId = userInfo.userId;
        if (!userId) {
          console.error("用户信息中未找到 userId");
          return;
        }
        const res = await getLoginNameVoList({ userId });
        if (res && res) {
          this.projectList = res.map((item) => ({
            label: item.name,
@@ -743,8 +815,21 @@
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          ...this.searchForm,
          type: this.currentType,
        };
        // 项目端:使用 currentType(根据 Tab 自动判断)
        // 委托方:
        //   - 重大隐患 Tab:使用 searchForm.type(用户选择的隐患类型筛选)
        //   - 安全/设备 Tab:不需要传 type(已经通过不同接口区分)
        if (!this.isClient) {
          // 项目端:传递 type
          params.type = this.currentType;
        } else {
          // 委托方:只在重大隐患 Tab 且用户选择了类型时传递 type
          if (this.activeTab === 1 && this.searchForm.type) {
            params.type = this.searchForm.type;
          }
        }
        // 过滤掉空值
        Object.keys(params).forEach((key) => {
@@ -753,8 +838,14 @@
          }
        });
        const res = await getHiddenDangerList(params);
        if (res ) {
        // 使用统一方法,自动根据用户类型和Tab调用对应接口
        const res = await getHiddenDangerListByType(
          params,
          this.activeTab,
          this.isClient
        );
        if (res) {
          this.tableData = res.records || [];
          this.total = res.total || 0;
        }
@@ -770,6 +861,32 @@
    handleSearch() {
      this.pageNum = 1;
      this.loadTableData();
    },
    // 选择器改变时自动请求
    handleSelectChange() {
      this.pageNum = 1;
      this.loadTableData();
    },
    // 清除选择器
    clearSelect(field) {
      this.searchForm[field] = null;
      this.handleSelectChange();
    },
    // 清除日期时间
    clearDateTime(type) {
      if (type === 'start') {
        this.startDateTime = null;
        this.startDateTxt = "";
        this.searchForm.startTime = null;
      } else {
        this.endDateTime = null;
        this.endDateTxt = "";
        this.searchForm.endTime = null;
      }
      this.handleSelectChange();
    },
    // 点击日期选择器
@@ -827,10 +944,14 @@
      }
      try {
        await editHiddenDangerResponsiblePerson({
          id: this.currentEditRow.id,
          responsiblePerson: this.peopleName,
        });
        // 使用统一方法
        await editResponsiblePersonByType(
          {
            id: this.currentEditRow.id,
            responsiblePerson: this.peopleName,
          },
          this.isClient
        );
        this.$message({
          message: "保存成功",
@@ -852,7 +973,12 @@
        // 保存当前行数据
        this.currentRow = row;
        const res = await getHiddenDangerDetail(row.problemId);
        // 使用统一方法
        const res = await getHiddenDangerDetailByType(
          row.problemId,
          this.isClient
        );
        if (res && res) {
          this.detailData = res;
          this.detailVisible = true;
screen/src/view/hiddenDanger/service.js
@@ -1,25 +1,165 @@
import request from '@/utils/request'
// ==================== 项目端接口 ====================
// 获取项目-委托方列表
export const getLoginNameVoList = async (params) => {
  return request(`/project/getLoginNameVoList`, {
    method: 'get', params
  })
}
// 获取隐患列表
// 获取隐患列表(项目端)
export const getHiddenDangerList = async (data) => {
  return request(`/project/getHiddenDangerList`, {
    method: 'post', data
  })
}
// 获取隐患详情
// 获取隐患详情(项目端)
export const getHiddenDangerDetail = async (problemId) => {
  return request(`/project/getHiddenDangerDetail/${problemId}`, {
    method: 'get'
  })
}
// 编辑隐患责任人
// 编辑隐患责任人(项目端)
export const editHiddenDangerResponsiblePerson = async (data) => {
  return request(`/project/editHiddenDangerResponsiblePerson`, {
    method: 'post', data
  })
}
// ==================== 委托方接口 ====================
// 获取重大隐患列表(委托方)
export const getClientMajorErrorList = async (data) => {
  return request(`/projectEntrust/errorList`, {
    method: 'post', data
  })
}
// 获取安全隐患列表(委托方)
export const getClientSafetyErrorList = async (data) => {
  return request(`/projectEntrust/safetyErrorList`, {
    method: 'post', data
  })
}
// 获取设备隐患列表(委托方)
export const getClientDeviceErrorList = async (data) => {
  return request(`/projectEntrust/deviceErrorList`, {
    method: 'post', data
  })
}
// 获取隐患详情(委托方)
export const getClientHiddenDangerDetail = async (problemId) => {
  return request(`/projectEntrust/getHiddenDangerDetail/${problemId}`, {
    method: 'get'
  })
}
// 编辑隐患责任人(委托方)
export const editClientHiddenDangerResponsiblePerson = async (data) => {
  return request(`/projectEntrust/editHiddenDangerResponsiblePerson`, {
    method: 'post', data
  })
}
// ==================== 数据适配器 ====================
/**
 * 将委托方接口数据适配为项目端格式
 */
const adaptClientDataToProject = (item) => {
  return {
    ...item,
    // 字段映射
    description: item.problemName || item.description, // 问题描述
    createTime: item.checkTime || item.createTime, // 检查时间
    userFiles: item.pictures || item.userFiles || [], // 图片列表
    fileNum: item.pictures ? item.pictures.length : (item.fileNum || 0), // 图片数量
    // 隐患等级转换:委托方 1-4 -> 项目端 0-3
    level: item.level !== undefined && item.level !== null ? item.level - 1 : item.level,
    // 整改状态兼容:委托方 boolean -> 项目端 number
    reformed: typeof item.reformed === 'boolean' ? (item.reformed ? 1 : 0) : item.reformed,
  }
}
/**
 * 将项目端数据适配为委托方格式(用于编辑等操作)
 */
const adaptProjectDataToClient = (data) => {
  const adapted = { ...data }
  // 整改状态转换:项目端 number -> 委托方 boolean
  if (adapted.reformed !== undefined && adapted.reformed !== null) {
    adapted.reformed = adapted.reformed === 1 || adapted.reformed === true
  }
  return adapted
}
// ==================== 统一调用方法 ====================
/**
 * 根据用户类型获取隐患列表
 * @param {Object} data - 查询参数
 * @param {Number} activeTab - 当前Tab (1=重大 2=安全 3=设备)
 * @param {Boolean} isClient - 是否委托方
 */
export const getHiddenDangerListByType = async (data, activeTab, isClient) => {
  let result
  if (isClient) {
    // 委托方:根据不同Tab调用不同接口
    const clientData = adaptProjectDataToClient(data)
    switch (activeTab) {
      case 1: // 重大隐患
        result = await getClientMajorErrorList(clientData)
        break
      case 2: // 安全隐患
        result = await getClientSafetyErrorList(clientData)
        break
      case 3: // 设备隐患
        result = await getClientDeviceErrorList(clientData)
        break
      default:
        result = await getClientMajorErrorList(clientData)
    }
    // 数据适配
    if (result && result.records) {
      result.records = result.records.map(item => adaptClientDataToProject(item))
    }
  } else {
    // 项目端:统一接口
    result = await getHiddenDangerList(data)
  }
  return result
}
/**
 * 根据用户类型获取隐患详情
 * @param {String} problemId - 问题ID
 * @param {Boolean} isClient - 是否委托方
 */
export const getHiddenDangerDetailByType = async (problemId, isClient) => {
  let result
  if (isClient) {
    result = await getClientHiddenDangerDetail(problemId)
    // 数据适配
    if (result) {
      result = adaptClientDataToProject(result)
    }
  } else {
    result = await getHiddenDangerDetail(problemId)
  }
  return result
}
/**
 * 根据用户类型编辑责任人
 * @param {Object} data - 编辑数据
 * @param {Boolean} isClient - 是否委托方
 */
export const editResponsiblePersonByType = async (data, isClient) => {
  if (isClient) {
    const clientData = adaptProjectDataToClient(data)
    return editClientHiddenDangerResponsiblePerson(clientData)
  } else {
    return editHiddenDangerResponsiblePerson(data)
  }
}