<template>
  <div class="h5-container">
    <van-nav-bar title="隐患举报" @click-left="onClickLeft">
    </van-nav-bar>
    <van-form @submit="baocun" ref="formRef">
      <div style="color: #4C93E6;font-size: 14px;margin-left: 0px;
      background-color: #f4f4f4;padding: 8px 12px;margin: 0 -10px 10px -10px;">隐患信息
      </div>
      <van-field border v-model="form.hdId" name="隐患编号" label="隐患编号" :colon="true" placeholder=""
                 :readonly="true" />
      <van-field is-link :colon="true" readonly v-model="form.hdType" required label="隐患类型"
                 placeholder="选择隐患类型"
                 @click="showPicker = true" :rules="[{ required: true, message: '请选择内容' }]" />
      <van-popup v-model:show="showPicker" round position="bottom">
        <van-picker :columns="yhlxs" @cancel="showPicker = false" @confirm="onConfirmYhlx" />
      </van-popup>

      <van-field
        v-model="form.discoveryTime"
        is-link
        readonly
        name="datetime"
        label="发现时间"
        :colon="true"
        placeholder="点击选择日期和时间"
        @click="showDatetimePicker = true"
        required
        :rules="[{ required:true, message: '请选择内容' }]"
      />
      <!-- 日期时间选择器部分 -->
      <van-popup
        v-model:show="showDatetimePicker"
        position="bottom"
        round
        style="max-height: 50vh;"
      >
        <van-date-picker
          v-if="!dateOrTime"
          v-model="currentDate"
          title="选择日期"
          :min-date="minDate"
          :max-date="maxDate"
          @confirm="onDateConfirm"
          @cancel="cancelDatePicker"
        >
          <template #confirm>
            <van-button type="primary" @click="onDateConfirm">下一步</van-button>
          </template>
          <template #cancel>
            <van-button type="danger" @click="cancelDatePicker">取消</van-button>
          </template>
        </van-date-picker>

        <van-time-picker
          v-if="dateOrTime"
          v-model="currentTime"
          title="选择时间"
          :columns-type="['hour', 'minute', 'second']"
          @confirm="onConfirmDatetime"
          @cancel="cancelTimePicker"
        >
          <template #confirm>
            <van-button type="primary" @click="onConfirmDatetime">确定</van-button>
          </template>
          <template #cancel>
            <van-button type="danger" @click="cancelTimePicker">取消</van-button>
          </template>
        </van-time-picker>
      </van-popup>
      <van-field
        v-model="form.hdLocation"
        label="隐患区域"
        placeholder="请选择隐患区域"
        readonly
        right-icon="arrow-down"
        @click="showPickerHandle"
        required
        :rules="[{ required: true, message: '请选择' }]"
      />
      <!--        部门弹出框-->
      <van-popup v-model:show="showBottom" position="bottom">
        <OrganizationalWithLeaf @update:selected-node="handleTableDataUserDeptUpdate" />
      </van-popup>
      <van-field
        readonly
        v-model="form.discovererDesc"
        :colon="true"
        label="发现人"
        name="发现人"
        placeholder="请选择发现人"
        required
        :rules="[{ required: true, message: '请选择' }]"
        @click="handleDepartmentLeaderName"
      />
      <OrganizationalWithLeafUserOne ref="PopupDepartmentLeaderNameRef" @receive-from-child="getDepartmentLeaderName"
                                     :main-key="leaderKey" />
      <van-field
        border
        v-model="form.hdDescription"
        name="隐患描述"
        label="隐患描述"
        :colon="true"
        placeholder="请输入内容"
        required
        :rules="[{ required: true, message: '请输入内容' }]"
        type="textarea"
        rows="1"
        autosize
      >
        <template #right-icon>
          <van-icon 
            name="volume-o" 
            size="20" 
            :color="isRecording ? '#ee0a24' : '#1989fa'"
            @click="toggleVoiceInput"
            style="margin-right: 8px; cursor: pointer;"
          />
        </template>
      </van-field>

      <!-- AI研判按钮 -->
      <div style="margin: 10px 0; padding: 0 16px;">
        <van-button 
          type="primary" 
          size="small" 
          block
          :loading="aiJudging"
          @click="handleAIJudge"
          :disabled="!form.hdDescription || form.hdDescription.trim() === ''"
        >
          <van-icon name="chat-o" style="margin-right: 5px;" />
          {{ aiJudging ? 'AI判断中...' : 'AI研判' }}
        </van-button>
      </div>

      <!-- AI判断结果显示 -->
      <van-field
        v-if="aiJudgeResult"
        border
        readonly
        label="AI判断结果"
        :colon="true"
      >
        <template #input>
          <div class="ai-judge-result" v-html="renderedJudgeResult"></div>
        </template>
      </van-field>

      <van-field
        is-link
        :colon="true"
        readonly
        v-model="form.hdLevel"
        required
        label="隐患等级"
        placeholder="选择等级"
        @click="showPicker2 = true"
        :rules="[{ required:true, message: '请选择内容' }]"
      />
      <van-popup v-model:show="showPicker2" round position="bottom">
        <van-picker
          :columns="yhdjs"
          @cancel="showPicker2 = false"
          @confirm="onConfirmYhdj"
        />
      </van-popup>

      <van-field
        v-model="form.picBefore"
        :colon="true"
        readonly
        label="整改前图片"
      ></van-field>
      <!--      <van-uploader v-model="fileList" :after-read="afterRead" @delete="handleDelete" acc-->
      <!--                    ept=".jpg,.gif,.png,.jpeg" upload-icon="plus" multiple />-->

      <AttachmentS3Image :f-id="form.hdPicId" />

      <van-field
        :colon="true"
        readonly
        label="附件上传"
      />
      <AttachmentS3 :f-id="form.hdPicId+'fjwj'" />

      <span v-if="!isStandardFlow" style="color: #4C93E6;font-size: 12px;">隐患分析确认</span>
      <van-field
        v-if="form.hdSelect==='即查即改'"
        readonly
        v-model="form.repairLeaderDesc"
        :colon="true"
        label="整改人"
        name="整改人"
        placeholder="请选择整改人"
        required
        :rules="[{ required: true, message: '请选择' }]"
        @click="handleDepartmentLeaderNamezgr"
      />
      <OrganizationalWithLeafUserOne ref="PopupDepartmentLeaderNameRefzgr"
                                     @receive-from-child="getDepartmentLeaderNamezgr" :main-key="leaderKeyzgr" />
      <van-field
        v-if="form.hdSelect==='即查即改'"
        readonly
        border
        v-model="form.repairOtherDesc"
        name="其他整改人"
        label="其他整改人"
        :colon="true"
        placeholder="请选择其他整改人"
        @click="handleDepartmentLeaderName2qtzgr"
        required
        :rules="[{ required: true, message: '请选择' }]"
      />
      <OrganizationalWithLeafUser ref="PopupDepartmentLeaderNameRef2qtzgr"
                                  @receive-from-child="getDepartmentLeaderName2qtzgr" :main-key="leaderKey2qtzgr" />

      <!--        部门选择-->
      
      <van-field
        label-width="300px"
        v-if="form.hdSelect==='即查即改'"
        :colon="true"
        readonly
        label="临时管控现场图片"
      />
      <AttachmentS3Image style="background-color: white;" v-if="form.hdSelect==='即查即改'"
                         :f-id="form.hdPicId+'lsgkxctp'" />
      <van-field
        v-if="form.hdSelect==='即查即改'"
        v-model="form.picAfter"
        :colon="true"
        readonly
        label="整改后图片"

      />
      <AttachmentS3Image style="background-color: white;" v-if="form.hdSelect==='即查即改'"
                         :f-id="form.hdPicId+'zgh'" />

      <van-field
        v-if="form.hdSelect==='即查即改'"
        border
        v-model="form.repairDescription"
        name="整改后情况描述"
        label="整改后情况描述"
        :colon="true"
        placeholder="请输入整改后情况描述"
        required
        :rules="[{ required: true, message: '请输入内容' }]"
        type="textarea"
        rows="1"
        autosize
      />
      <van-button v-if="!(form.workId)" block round type="primary" native-type="submit" style="margin-bottom: 5px;">
        保存
      </van-button>
      <van-button block round plain type="default" @click="qvxiao">
        取消
      </van-button>
      <div style="height: 10px;"></div>
    </van-form>
  </div>


  <van-dialog v-model:show="showDialogVisible" title="删除文件" show-cancel-button
              confirm-button-color="#ee0124" message="确定删除该文件吗?" @confirm="onDelete" />

  <!-- 语音识别弹窗 -->
  <van-dialog
    v-model:show="showVoiceDialog"
    title="语音输入"
    :show-cancel-button="false"
    :show-confirm-button="false"
    :close-on-click-overlay="true"
    width="90%"
  >
    <div style="padding: 20px; text-align: center;">
      <van-icon 
        name="volume-o" 
        size="60" 
        :color="isRecording ? '#ee0a24' : '#1989fa'"
        :class="{ 'pulsing': isRecording }"
      />
      <div style="margin-top: 20px; font-size: 16px; color: #323233;">
        {{ isRecording ? '正在录音，请说话...' : voiceErrorMessage || '点击开始录音' }}
      </div>
      <!-- 错误信息显示 -->
      <div v-if="voiceErrorMessage && !isRecording" style="margin-top: 15px; padding: 10px; background: #fff7e6; border-radius: 4px; border-left: 3px solid #ff9800;">
        <div style="font-size: 14px; color: #ff9800; text-align: left;">
          {{ voiceErrorMessage }}
        </div>
      </div>
      <!-- 识别结果显示 -->
      <div v-if="recognizedText" style="margin-top: 15px; padding: 10px; background: #f7f8fa; border-radius: 4px; text-align: left; max-height: 150px; overflow-y: auto;">
        <div style="font-size: 14px; color: #666; margin-bottom: 5px;">识别结果：</div>
        <div style="font-size: 14px; color: #323233; word-break: break-all;">{{ recognizedText }}</div>
      </div>
      <div style="margin-top: 20px; display: flex; justify-content: center; gap: 10px;">
        <van-button 
          v-if="!isRecording" 
          type="primary" 
          size="small" 
          @click="startRecognition"
        >
          开始录音
        </van-button>
        <van-button 
          v-else 
          type="danger" 
          size="small" 
          @click="stopRecognition"
        >
          停止录音
        </van-button>
        <van-button 
          v-if="recognizedText" 
          type="primary" 
          size="small" 
          @click="confirmVoiceText"
        >
          确认使用
        </van-button>
      </div>
    </div>
  </van-dialog>
</template>

<script setup>
import { ref, reactive, onMounted, getCurrentInstance, nextTick, onUnmounted, computed } from 'vue';
import { closeToast, Dialog, showFailToast, showLoadingToast, showSuccessToast, showToast } from 'vant';
import AttachmentS3Image from '@/components/AttachmentS3Image.vue';
import AttachmentS3 from '@/components/AttachmentS3.vue';
import OrganizationalWithLeafUserOne from '@/components/OrganizationalWithLeafUserOne.vue';
import OrganizationalWithLeafUser from '@/components/OrganizationalWithLeafUser.vue';
import OrganizationalWithLeaf from '@/components/JuBaoOrganizationalWithLeaf.vue';

const { proxy } = getCurrentInstance();

const onClickLeft = () => {
  history.back();
};

/* 风险隐患排查发现隐患，进行登记代码 */
const checklistForm = ref({
  evaluationId: '',
  checklistType: '',
  hiddenDangerId: ''
});
const saveCheckInfo = async () => {
  let url = '/sgsafe/ActivityRecords/save';
  if (checklistForm.value.checklistType === 'equipment') {
    url = '/sgsafe/EquipmentRecords/save';
  }
  const param = {
    json: JSON.stringify(checklistForm.value)
  };
  const res = await proxy.$axios.post(url, param);
  if (res.data.code === 0) {
    showSuccessToast('新增排查记录成功！');
    sessionStorage.setItem('inspectionResult', '已排查');
  } else {
    showFailToast('操作失败！' + res.data.msg);
  }
};

onMounted(async () => {
  /**初始化时间**/
    // 更智能的日期范围设置
  const now = new Date();
  const currentYear = now.getFullYear();
  const currentMonth = now.getMonth();

  // 设置更合理的动态范围
  minDate.value = new Date(currentYear - 20, 0, 1); // 20年前
  maxDate.value = new Date(currentYear + 2, currentMonth, 28); // 2年后，日期固定为28号避免2月问题

  fileList.value = [];
  form.value.id = '';
  if (proxy.$route.query) {
    form.value = proxy.$route.query;
  }

  const hiddenDangerId = sessionStorage.getItem('hiddenDangerId');
  if (hiddenDangerId) {
    form.value.id = hiddenDangerId;
    sessionStorage.removeItem('hiddenDangerId');
  }

  const checklistInfoStr = sessionStorage.getItem('checklistInfo');
  if (checklistInfoStr) {
    checklistForm.value = JSON.parse(checklistInfoStr);
    sessionStorage.removeItem('checklistInfo');
  }

  form.value.hdSelect = '隐患举报';
  form.value.workId = '';
  form.value.discoveryTime = getTimeFormatter(new Date());
  if (form.value.id) {
    var url = '/sgsafe/JuBaoHiddendanger/queryById';
    var param = {
      id: form.value.id
    };
    await proxy.$axios.get(url, param).then(response => {
      if (response.data.code === 0) {
        form.value = response.data.data;
        // 如果有 AI 判断结果，同步到显示变量
        if (form.value.aiJudge) {
          aiJudgeResult.value = form.value.aiJudge;
        } else {
          aiJudgeResult.value = '';
        }
      } else {
        showToast({
          message: '操作失败！' + response.data.msg
        });
      }
    });
  }
  getTableData();
  console.log('路由传值', proxy.$route.query);
  console.log('form值', form.value);

  // 添加日期时间选择器初始化
  resetDatetime();
});

const getTimeFormatter = (date) => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始，需加 1
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

/**表单*/
const form = ref({
  discovererOtherDesc: '',
  hdPicId: '',
  hdId: '',
  hdType: '',
  discoveryTime: '',
  hdSubtype: '',
  discoverer: '',
  discovererOther: '',
  hdDescription: '',
  aiJudge: '', // AI判断结果字段
  hdLevel: '',
  bz: '',
  hdLocation: '',
  picBefore: '',
  workId: '',

  equipmentId: '',
  hdmanageLevel: '',
  handlingProcesses: '',
  companyId: '',
  repairLeader: '',
  repairOther: '',
  repairSuggest: '',
  repairDdl: '',
  repairDept: '',
  acceptLeader: '',
  acceptOther: '',
  picAfter: '',
  picTemp: '',
  repairDescription: '',
  discovererDept: '',
  discovererDeptCode: '',
  hdLocationCode: '',
  hdLocationName: '',

  status: '',


  hdSelect: '隐患举报',
  id: ''
});

const showPicker = ref(false);

const onConfirmYhlx = ({ selectedOptions }) => {
  showPicker.value = false;
  form.value.hdType = selectedOptions[0].value;
  console.log('选择的内容', form.value);
};

const yhlxs = ref([{ text: '物的不安全状态', value: '物的不安全状态' },
  { text: '人的不安全行为', value: '人的不安全行为' },
  { text: '管理缺陷', value: '管理缺陷' },
  { text: '环境因素', value: '环境因素' }]
);

const showDatetimePicker = ref(false);
const currentDate = ref();
const currentTime = ref();
const minDate = ref();
const maxDate = ref();

const dateOrTime = ref(false);
const onDateConfirm = () => {
  // 日期选择确认后的处理
  dateOrTime.value = true;
};

const onTimeConfirm = () => {
  // 时间选择确认后的处理
};

const resetDatetime = () => {
  dateOrTime.value = false;

  // 初始化日期和时间
  if (form.value.discoveryTime) {
    const dt = new Date(form.value.discoveryTime);
    currentDate.value = [dt.getFullYear(), dt.getMonth() + 1, dt.getDate()];
    currentTime.value = [
      String(dt.getHours()).padStart(2, '0'),
      String(dt.getMinutes()).padStart(2, '0'),
      String(dt.getSeconds()).padStart(2, '0')
    ];
  } else {
    const now = new Date();
    currentDate.value = [now.getFullYear(), now.getMonth() + 1, now.getDate()];
    currentTime.value = [
      String(now.getHours()).padStart(2, '0'),
      String(now.getMinutes()).padStart(2, '0'),
      String(now.getSeconds()).padStart(2, '0')
    ];
  }
};

const onConfirmDatetime = () => {
  const year = currentDate.value[0];
  const month = currentDate.value[1].toString().padStart(2, '0');
  const day = currentDate.value[2].toString().padStart(2, '0');
  const hours = currentTime.value[0].toString().padStart(2, '0');
  const minutes = currentTime.value[1].toString().padStart(2, '0');
  const seconds = currentTime.value[2].toString().padStart(2, '0');

  form.value.discoveryTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  showDatetimePicker.value = false;
  dateOrTime.value = false;
};

const showPicker2 = ref(false);

const onConfirmYhdj = ({ selectedOptions }) => {
  showPicker2.value = false;
  form.value.hdLevel = selectedOptions[0].value;
  console.log('选择的内容', form.value);
};

const yhdjs = ref([{ text: '一般隐患', value: '一般隐患' },
  { text: '重大隐患', value: '重大隐患' }]
);

const formRef = ref(null);
const qvxiao = () => {
  showToast({
    type: 'fail',
    message: '操作取消！'
  });
  onClickLeft();
};
const baocun = async () => {
  if (form.value.hdSelect === '隐患举报') {
    form.value.status = '0';
  } 

  // 强制同步 AI 判断结果到 form（确保数据不丢失）
  if (aiJudgeResult.value) {
    form.value.aiJudge = aiJudgeResult.value;
  }

  console.log('保存的参数', form.value);

  // 原有保存逻辑保持不变
  var url = 'sgsafe/JuBaoHiddendanger/save';
  var param = {
    json: JSON.stringify(form.value)
  };
  const response = await proxy.$axios.post(url, param);
  if (response.data.code === 0) {
    checklistForm.value.hiddenDangerId = response.data.data.id;
    if (checklistForm.value.hiddenDangerId) {
      await saveCheckInfo();
    }
    showToast({
      type: 'success',
      message: '保存成功！'
    });
    onClickLeft();
  } else {
    showToast({
      type: 'fail',
      message: '操作失败！'
    });
  }
};

const handleChangeHdSelect = (value) => {
  form.value.hdSelect = value;
  if (value === '隐患举报') {
    isStandardFlow.value = true;
  } else if (value === '即查即改') {
    isStandardFlow.value = false;
  }
  getYHID();
};

const guid = () => {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }

  return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
};
/* 发现人 */
const leaderKey = guid();
const PopupDepartmentLeaderNameRef = ref();
const handleDepartmentLeaderName = () => {
  PopupDepartmentLeaderNameRef.value.open();
};

const codeAndDesc = ref([]);
const getDepartmentLeaderName = (item) => {
  form.value.discoverer = item.user.userCode;
  form.value.discovererDesc = item.user.userDesc;
  form.value.discovererDeptCode = item.dept.deptCode;
  form.value.discovererDept = item.dept.deptName;
};

/* 其他发现人 */
const leaderKey2 = guid();
const PopupDepartmentLeaderNameRef2 = ref();
const handleDepartmentLeaderName2 = () => {
  PopupDepartmentLeaderNameRef2.value.open();
};

const codeAndDesc2 = ref([]);
const getDepartmentLeaderName2 = (items) => {
  console.log('人员数据', items);
  let codeList = [];
  let descList = [];
  for (let item of items) {
    codeAndDesc2.value.push(item.userCode + '-' + item.userDesc);
    codeList.push(item.userCode);
    descList.push(item.userDesc);
  }
  form.value.discovererOther = codeList.join(',');
  form.value.discovererOtherDesc = descList.join(',');
};

//定义一个变量切换即查即改还是标准流程
const isStandardFlow = ref(true);

//当是即查即改时得到隐患编号并赋值
const getYHID = () => {
  //直接请求后端返回一个隐患编号
  console.log('getYHID');
  if (form.value.hdSelect === '即查即改') {
    var url = 'sgsafe/JuBaoHiddendanger/getYhbhTemp';
    var param = {};
    proxy.$axios.get(url, param).then(response => {
      if (response.data.code == '0') {
        form.value.hdId = response.data.data;
      } else {
        ElMessage.error('操作失败！' + response.data.msg);
      }
    });
  } else {
    form.value.hdId = '';
  }
};

/* 整改人 */
const leaderKeyzgr = guid();
const PopupDepartmentLeaderNameRefzgr = ref();
const handleDepartmentLeaderNamezgr = () => {
  PopupDepartmentLeaderNameRefzgr.value.open();
};

const codeAndDesczgr = ref([]);
const getDepartmentLeaderNamezgr = (item) => {
  form.value.repairLeader = item.user.userCode;
  form.value.repairLeaderDesc = item.user.userDesc;
  form.value.repairDept = item.dept.deptName;
};

/* 其他整改人 */
const leaderKey2qtzgr = guid();
const PopupDepartmentLeaderNameRef2qtzgr = ref();
const handleDepartmentLeaderName2qtzgr = () => {
  PopupDepartmentLeaderNameRef2qtzgr.value.open();
};

const codeAndDesc2qtzgr = ref([]);
const getDepartmentLeaderName2qtzgr = (items) => {
  console.log('人员数据', items);
  let codeList = [];
  let descList = [];
  for (let item of items) {
    codeAndDesc2qtzgr.value.push(item.userCode + '-' + item.userDesc);
    codeList.push(item.userCode);
    descList.push(item.userDesc);
  }
  form.value.repairOther = codeList.join(',');
  form.value.repairOtherDesc = descList.join(',');
};

/* 组织树选择 */
const showBottom = ref(false);
const handleTableDataUserDeptUpdate = async (nodeData) => {
  let temp = nodeData.split('-');
  if(temp[0].length<9){
    showFailToast('请选择四级及以下部门')
    return
  }
  form.value.hdLocation = temp[1];
  form.value.hdLocationCode = temp[0];
  form.value.hdConfirm = temp[2]
  // form.value.repairDept = nodeData.deptCode + '-' + nodeData.deptName
  showBottom.value = false;
};
const showPickerHandle = () => {
  showBottom.value = true;
};

/**表单*/

/***********************新图******************************/
//公共区
import { atob } from 'js-base64';

const bucket = ref(import.meta.env.VITE_BUCKET);

function base64ToBlob(base64) {
  const contentType = base64.substring(base64.indexOf(':') + 1, base64.indexOf(';'));
  const byteCharacters = atob(base64);
  const byteArrays = [];

  for (let i = 0; i < byteCharacters.length; i++) {
    byteArrays.push(byteCharacters.charCodeAt(i));
  }

  const byteArray = new Uint8Array(byteArrays);
  return new Blob([byteArray], { type: contentType });
}

const headers = ref({
  token: localStorage.getItem('token'),
  userId: localStorage.getItem('userId')
});

//整改前
const fileList = ref([]);
const afterRead = (file) => {
  const content = base64ToBlob(file.content);
  const formData = new FormData();
  formData.append('fId', form.value.hdPicId);
  formData.append('bucket', bucket.value);
  formData.append('value1', null);
  formData.append('value2', null);
  formData.append('value3', null);
  formData.append('value4', null);
  formData.append('value5', null);
  formData.append('file', content, file.file.name);
  let url = import.meta.env.VITE_BASE_API + '/framework/Common/uploadFileS3';
  proxy.$axios.post(url, formData, { headers: headers.value }).then(res => {
    if (res.data.code === 0) {
      showSuccessToast('上传成功');
      getTableData();
    } else {
      showFailToast('上传失败' + res.data.msg);
    }
  }).catch(error => {
    console.log(error);
  });
};
const getTableData = () => {
  //携带自定义参数
  var url = 'framework/Common/queryFileWithValues';
  var param = {
    fId: form.value.hdPicId, //必填
    value1: null, //非必填
    value2: null, //非必填
    value3: null, //非必填
    value4: null, //非必填
    value5: null //非必填
  };
  proxy.$axios.get(url, param).then(response => {
    if (response.data.code === 0) {
      for (var item of response.data.data) {
        fileList.value.push({
          id: item.id,
          uploadFile: item.fileName,
          url: import.meta.env.VITE_BASE_API +
            '/framework/Common/downloadFileS3?bucket=' + bucket.value +
            '&id=' + item.id
        });
        form.value.picBefore = fileList.value[0].url;
      }
    } else {
      showFailToast('失败！' + response.data.msg);
    }
  });
};
/* 在线删除 */
const showDialogVisible = ref(false);
const deleteInfo = ref();
const handleDelete = (row) => {
  showDialogVisible.value = true;
  deleteInfo.value = row;
};
const onDelete = () => {
  let url = 'framework/Common/removeFile';
  let param = {
    id: deleteInfo.value.id
  };
  proxy.$axios.post(url, param).then(response => {
    if (response.data.code === 0) {
      showSuccessToast('删除成功!');
      getTableData();
    } else {
      showFailToast('删除失败;' + response.data.msg);
    }
  });
};

//隐患选择
const selectOption = (option) => {
  if (form.value.workId.length > 0) {
    return;
  }
  form.value.hdSelect = option;
  if (option === '隐患举报') {
    isStandardFlow.value = true;
  } else if (option === '即查即改') {
    isStandardFlow.value = false;
  }
  getYHID();
};

/**修改发现时间**/
// 日期选择器取消
const cancelDatePicker = () => {
  showDatetimePicker.value = false;
  resetDatetime();
};

// 时间选择器取消
const cancelTimePicker = () => {
  resetDatetime();
  // 重置为当前时间或从表单获取时间
  if (form.value.discoveryTime) {
    const dt = new Date(form.value.discoveryTime);
    currentTime.value = [
      String(dt.getHours()).padStart(2, '0'),
      String(dt.getMinutes()).padStart(2, '0'),
      String(dt.getSeconds()).padStart(2, '0')
    ];
  } else {
    const now = new Date();
    currentTime.value = [
      String(now.getHours()).padStart(2, '0'),
      String(now.getMinutes()).padStart(2, '0'),
      String(now.getSeconds()).padStart(2, '0')
    ];
  }
};
/**修改发现时间**/

  /***********************语音识别功能******************************/
  // 语音识别相关状态
  const isRecording = ref(false);
  const showVoiceDialog = ref(false);
  const recognizedText = ref('');
  const voiceErrorMessage = ref('');
  let recognition = null;
  // 累积的最终识别文本（用于保存已确认的识别结果）
  let accumulatedFinalText = '';

  // 检查浏览器是否支持语音识别
  function checkSpeechRecognitionSupport() {
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SpeechRecognition) {
      showToast({
        type: 'fail',
        message: '您的浏览器不支持语音识别功能'
      });
      return false;
    }
    return true;
  }

  // 初始化语音识别
  function initSpeechRecognition() {
    if (!checkSpeechRecognitionSupport()) {
      return;
    }

    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    recognition = new SpeechRecognition();
    
    // 设置语言为中文
    recognition.lang = 'zh-CN';
    // 连续识别
    recognition.continuous = true;
    // 返回临时结果
    recognition.interimResults = true;

    // 识别开始
    recognition.onstart = () => {
      isRecording.value = true;
      recognizedText.value = '';
      voiceErrorMessage.value = '';
      accumulatedFinalText = ''; // 重置累积的最终文本
    };

    // 移除所有句号的辅助函数（移除所有句号，保留其他标点符号）
    function removePeriods(text) {
      if (!text) return text;
      // 移除所有的中文句号和英文句号（包括中间和末尾的）
      return text.replace(/[。.]/g, '');
    }

    // 识别结果
    recognition.onresult = (event) => {
      let interimTranscript = '';
      let newFinalTranscript = '';

      // 只处理新产生的结果（从resultIndex开始）
      for (let i = event.resultIndex; i < event.results.length; i++) {
        let transcript = event.results[i][0].transcript;
        if (event.results[i].isFinal) {
          // 最终结果：移除所有句号后追加到累积文本中（保留其他标点符号）
          newFinalTranscript += removePeriods(transcript);
        } else {
          // 临时结果：移除所有句号后显示当前正在识别的部分（保留其他标点符号）
          interimTranscript += removePeriods(transcript);
        }
      }

      // 如果有新的最终结果，追加到累积文本（已移除标点符号）
      if (newFinalTranscript) {
        // 如果累积文本不为空，在追加前添加空格（避免文本粘连）
        if (accumulatedFinalText) {
          accumulatedFinalText += ' ';
        }
        accumulatedFinalText += newFinalTranscript;
      }

      // 显示：累积的最终文本 + 当前的临时文本（识别过程中不包含标点符号）
      // 如果累积文本不为空且临时文本不为空，在它们之间添加空格
      if (accumulatedFinalText && interimTranscript) {
        recognizedText.value = accumulatedFinalText + ' ' + interimTranscript;
      } else {
        recognizedText.value = accumulatedFinalText + interimTranscript;
      }
    };

    // 识别错误
    recognition.onerror = (event) => {
      console.error('语音识别错误:', event.error);
      isRecording.value = false;
      
      let errorMessage = '语音识别出错';
      switch (event.error) {
        case 'no-speech':
          errorMessage = '未检测到语音，请重试';
          break;
        case 'audio-capture':
          errorMessage = '无法访问麦克风，请检查权限';
          break;
        case 'not-allowed':
          errorMessage = '麦克风权限被拒绝，请在浏览器设置中允许';
          break;
        case 'network':
          errorMessage = '网络错误，请检查网络连接';
          break;
        case 'aborted':
          errorMessage = '语音识别已中断';
          break;
        case 'service-not-allowed':
          errorMessage = '语音识别服务不可用';
          break;
        default:
          errorMessage = `语音识别出错: ${event.error}`;
      }
      
      voiceErrorMessage.value = errorMessage;
      
      showToast({
        type: 'fail',
        message: errorMessage
      });
    };

    // 识别结束
    recognition.onend = () => {
      isRecording.value = false;
    };
  }

  // 切换语音输入
  function toggleVoiceInput() {
    if (!checkSpeechRecognitionSupport()) {
      return;
    }

    if (!recognition) {
      initSpeechRecognition();
    }

    showVoiceDialog.value = true;
    recognizedText.value = '';
    voiceErrorMessage.value = '';
    accumulatedFinalText = ''; // 重置累积文本
  }

  // 开始识别
  function startRecognition() {
    if (!recognition) {
      initSpeechRecognition();
    }

    // 清除之前的错误信息和文本
    voiceErrorMessage.value = '';
    recognizedText.value = '';
    accumulatedFinalText = ''; // 重置累积文本

    try {
      recognition.start();
    } catch (error) {
      console.error('启动语音识别失败:', error);
      voiceErrorMessage.value = '启动语音识别失败，请重试';
      showToast({
        type: 'fail',
        message: '启动语音识别失败，请重试'
      });
    }
  }

  // 停止识别
  function stopRecognition() {
    if (recognition && isRecording.value) {
      recognition.stop();
    }
  }

  // 确认使用识别的文本
  function confirmVoiceText() {
    if (recognizedText.value) {
      let textToAdd = recognizedText.value.trim();
      
      // 只在确认使用时，检查并添加句号
      // 如果文本末尾没有标点符号（句号、问号、感叹号、逗号等），则添加句号
      const punctuationRegex = /[。！？，；：、]$/;
      if (textToAdd && !punctuationRegex.test(textToAdd)) {
        textToAdd += '。';
      }
      
      // 如果已有内容，追加；否则直接设置
      if (form.value.hdDescription) {
        form.value.hdDescription += textToAdd;
      } else {
        form.value.hdDescription = textToAdd;
      }
      recognizedText.value = '';
      accumulatedFinalText = ''; // 重置累积文本
      voiceErrorMessage.value = '';
      showVoiceDialog.value = false;
      showToast({
        type: 'success',
        message: '已添加语音识别内容'
      });
    }
  }

  // 组件卸载时清理
  onUnmounted(() => {
    if (recognition && isRecording.value) {
      recognition.stop();
    }
  });

  /***********************AI判断法律法规功能******************************/
  // AI判断相关状态
  const aiJudging = ref(false);
  const aiJudgeResult = ref('');
  
  // Markdown 渲染库
  let marked = null;
  let DOMPurify = null;
  
  // 初始化 Markdown 库
  async function initMarkdownLibs() {
    try {
      // 动态导入 marked
      const markedModule = await import('marked');
      marked = markedModule.marked || markedModule.default || markedModule;
      
      // 配置 marked 选项
      if (marked.setOptions) {
        marked.setOptions({
          breaks: true, // 支持换行
          gfm: true, // 支持 GitHub Flavored Markdown
        });
      }
      
      // 动态导入 DOMPurify
      const dompurifyModule = await import('dompurify');
      DOMPurify = dompurifyModule.default || dompurifyModule;
    } catch (error) {
      console.warn('Markdown libraries not available, using plain text', error);
      marked = {
        parse: (text) => text
      };
      DOMPurify = {
        sanitize: (html) => html
      };
    }
  }
  
  // 初始化 Markdown 库
  initMarkdownLibs();
  
  // 渲染后的判断结果
  const renderedJudgeResult = computed(() => {
    if (!aiJudgeResult.value) return '';
    
    try {
      if (!marked || !DOMPurify) {
        // 如果库还没加载，先返回纯文本，但格式化一下
        return formatPlainText(aiJudgeResult.value);
      }
      
      // 使用 marked 解析 markdown
      const html = marked.parse ? marked.parse(aiJudgeResult.value) : marked(aiJudgeResult.value);
      // 使用 DOMPurify 清理 HTML
      return DOMPurify.sanitize ? DOMPurify.sanitize(html) : html;
    } catch (error) {
      console.error('Markdown解析错误:', error);
      return formatPlainText(aiJudgeResult.value);
    }
  });
  
  // 格式化纯文本（当 Markdown 库不可用时）
  function formatPlainText(text) {
    if (!text) return '';
    
    // 处理隐患点格式：以冒号结尾的行（隐患点描述）+ 下一行是违反说明
    let formatted = text
      // 先处理标题
      .replace(/^####\s+(.+)$/gm, '<h4>$1</h4>')
      .replace(/^###\s+(.+)$/gm, '<h3>$1</h3>')
      .replace(/^##\s+(.+)$/gm, '<h2>$1</h2>')
      .replace(/^#\s+(.+)$/gm, '<h1>$1</h1>')
      // 处理隐患点格式：以冒号结尾的行，后面跟着违反说明
      .replace(/^([^：:：\n]+[：:])\s*\n\s*(违反了[^\n]+)/gm, '<p class="hazard-point">$1</p><p class="violation-desc">$2</p>')
      // 粗体
      .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
      // 斜体
      .replace(/\*(.+?)\*/g, '<em>$1</em>')
      // 多个连续换行转换为段落分隔
      .replace(/\n\n+/g, '</p><p>')
      // 单个换行转换为换行符
      .replace(/\n/g, '<br/>');
    
    // 确保每个段落都有正确的标签（但保留已有的段落标签）
    const parts = formatted.split(/(<[^>]+>)/);
    formatted = parts.map(part => {
      if (part.startsWith('<') || !part.trim()) {
        return part;
      }
      // 如果已经是段落标签，直接返回
      if (part.includes('<p') || part.includes('</p>')) {
        return part;
      }
      // 否则包装成段落
      return '<p>' + part + '</p>';
    }).join('');
    
    return formatted;
  }

  // 处理AI判断
  async function handleAIJudge() {
    if (!form.value.hdDescription || form.value.hdDescription.trim() === '') {
      showToast({
        type: 'fail',
        message: '请先输入隐患描述'
      });
      return;
    }

    aiJudging.value = true;
    aiJudgeResult.value = '';

    try {
      const prompt = buildJudgePrompt(form.value.hdDescription);
      const messages = [{ role: 'user', content: prompt }];

      await callAIStream(messages, (content, isEnd) => {
        aiJudgeResult.value = content;
        // 实时同步到 form.aiJudge
        form.value.aiJudge = content;
        
        if (isEnd) {
          aiJudging.value = false;
          // 确保最终结果保存到 form
          form.value.aiJudge = content;
          showToast({
            type: 'success',
            message: 'AI判断完成'
          });
        }
      });
    } catch (error) {
      console.error('AI判断失败:', error);
      aiJudging.value = false;
      showToast({
        type: 'fail',
        message: 'AI判断失败，请重试'
      });
    }
  }

  // 构造判断提示词
  function buildJudgePrompt(hdDescription) {
    const prompt = `请根据以下隐患描述内容，分析违反法律法规的原因：

隐患描述内容：
${hdDescription}

请按照以下Markdown格式，只返回"违反法律法规的原因"部分：

## 违反法律法规的原因

**[从隐患描述中提取的第一个具体隐患点，要详细描述隐患的具体情况]**：

违反了《[法律法规名称]》第[条款号]，[详细说明为什么违反，包括具体原因和可能导致的后果]。

**[从隐患描述中提取的第二个具体隐患点，要详细描述隐患的具体情况]**：

违反了《[法律法规名称]》第[条款号]，[详细说明为什么违反，包括具体原因和可能导致的后果]。

**[从隐患描述中提取的第三个具体隐患点，要详细描述隐患的具体情况]**：

违反了《[法律法规名称]》第[条款号]，[详细说明为什么违反，包括具体原因和可能导致的后果]。

重要格式要求：
1. 使用Markdown格式，标题使用 ##
2. 每个隐患点描述使用 **粗体** 格式，后面加冒号
3. 每个隐患点描述和违反说明之间必须换行
4. 每个隐患点之间必须空一行
5. 必须从隐患描述中提取具体的隐患点，每个隐患点要有详细、具体的描述，不能使用占位符
6. 每个隐患点要明确指出违反了哪部法律法规的哪个条款
7. 详细说明违反的原因，包括具体原因和可能导致的后果
8. 使用清晰、专业的语言，确保法律法规名称和条款号准确无误
9. 不要返回其他内容（如法律法规的具体条款内容、处罚依据、整改建议等）

请严格按照Markdown格式输出。`;
    
    return prompt;
  }

  // 调用AI流式接口
  async function callAIStream(messageHistory, callback) {
    try {
      const url = `${import.meta.env.VITE_BASE_API}/sgsafe/deepseek/chat-stream`;
      
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'token': localStorage.getItem('token') || '',
          'userId': localStorage.getItem('userId') || ''
        },
        body: JSON.stringify({ messages: messageHistory })
      });
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      
      if (!response.body) {
        throw new Error('ReadableStream not supported');
      }
      
      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let buffer = '';
      let fullResponse = '';
      
      while (true) {
        const { done, value } = await reader.read();
        if (done) {
          callback(fullResponse, true);
          break;
        }
        
        const chunk = decoder.decode(value, { stream: true });
        buffer += chunk;
        
        const lines = buffer.split('\n');
        buffer = lines.pop();
        
        for (const line of lines) {
          if (line.trim() === '' || !line.startsWith('data:')) continue;
          
          const data = line.slice(5).trim();
          if (data === '[DONE]') {
            callback(fullResponse, true);
            return;
          }
          
          try {
            const jsonData = JSON.parse(data);
            if (jsonData.choices?.[0]?.delta) {
              let content = '';
              if (jsonData.choices[0].delta.reasoning_content) {
                content += jsonData.choices[0].delta.reasoning_content;
              }
              if (jsonData.choices[0].delta.content) {
                content += jsonData.choices[0].delta.content;
              }
              if (content) {
                fullResponse += content;
                callback(fullResponse, false);
              }
            }
          } catch (e) {
            console.error('JSON解析错误:', e);
          }
        }
      }
    } catch (error) {
      console.error('AI调用失败:', error);
      throw error;
    }
  }

</script>

<style scoped>
.h5-container {
  width: 100%;
  box-sizing: border-box;
  height: 100vh;
  background-color: white;
  padding: 10px;
  padding-bottom: 20px;
}

.radio-group {
  display: flex;
  background-color: white;
  padding: 10px;
  border-radius: 5px;
  margin: 10px 0;
  gap: 10px;
}

.radio-item {
  padding: 8px 12px;
  border: 1px solid #222;
  border-radius: 4px;
  background-color: white;
  cursor: pointer;
  transition: background-color 0.3s ease;
  /* 添加过渡效果 */
}

.radio-item.active {
  background-color: #4285f4;
  /* 选中时的蓝色 */
  color: white;
  border-color: #4285f4;
}

.pulsing {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.2);
    opacity: 0.7;
  }
}

/* AI判断结果样式 */
.ai-judge-result {
  padding: 15px 0;
  color: #323233;
  line-height: 1.8;
  font-size: 14px;
  word-break: break-word;
}

.ai-judge-result :deep(h1) {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  margin: 15px 0 10px 0;
  padding-bottom: 8px;
  border-bottom: 2px solid #e4e7ed;
}

.ai-judge-result :deep(h2) {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin: 15px 0 10px 0;
  padding-bottom: 6px;
  border-bottom: 1px solid #e4e7ed;
}

.ai-judge-result :deep(h3) {
  font-size: 15px;
  font-weight: 600;
  color: #409eff;
  margin: 12px 0 8px 0;
}

.ai-judge-result :deep(p) {
  margin: 12px 0;
  line-height: 1.8;
  color: #606266;
}

/* 优化隐患点格式 - 包含冒号的段落（隐患点描述） */
.ai-judge-result :deep(p:first-line) {
  font-weight: 500;
}

/* 隐患点描述（以冒号结尾的段落） */
.ai-judge-result :deep(p:first-child) {
  margin-top: 0;
}

/* 确保段落之间的间距一致 */
.ai-judge-result :deep(p + p) {
  margin-top: 12px;
}

/* 优化段落内换行 */
.ai-judge-result :deep(br) {
  line-height: 1.8;
}

.ai-judge-result :deep(p.list-item) {
  margin: 6px 0;
  padding-left: 8px;
  position: relative;
}

.ai-judge-result :deep(p.article-num) {
  margin: 8px 0;
  padding: 8px 12px;
  background: #f0f9ff;
  border-left: 3px solid #409eff;
  border-radius: 4px;
}

.ai-judge-result :deep(p.article-content) {
  margin: 8px 0;
  padding: 10px 12px;
  background: #fafafa;
  border-radius: 4px;
  line-height: 1.8;
}

.ai-judge-result :deep(strong) {
  font-weight: 600;
  color: #303133;
}

.ai-judge-result :deep(ul),
.ai-judge-result :deep(ol) {
  margin: 10px 0;
  padding-left: 25px;
}

.ai-judge-result :deep(li) {
  margin: 6px 0;
  line-height: 1.8;
  color: #606266;
}

.ai-judge-result :deep(blockquote) {
  margin: 10px 0;
  padding: 10px 15px;
  background: #f5f7fa;
  border-left: 4px solid #409eff;
  border-radius: 4px;
}

.ai-judge-result :deep(code) {
  background: #f5f7fa;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
  font-size: 13px;
  color: #e6a23c;
}

.ai-judge-result :deep(pre) {
  background: #f5f7fa;
  padding: 12px;
  border-radius: 4px;
  overflow-x: auto;
  margin: 10px 0;
}

.ai-judge-result :deep(pre code) {
  background: transparent;
  padding: 0;
  color: #303133;
}

.ai-judge-result :deep(hr) {
  border: none;
  border-top: 1px solid #e4e7ed;
  margin: 15px 0;
}
</style>
