v1.2.1版本,优化调整了很多,整改验收阶段新加字段

This commit is contained in:
王利强
2026-06-13 08:50:51 +08:00
parent 2af9f1fd59
commit 1fe87ec438
591 changed files with 5072 additions and 2706 deletions

View File

@@ -22,26 +22,26 @@
<view>区域颜色</view> <view>区域颜色</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<view class="flex align-center"> <view class="flex align-center margin-bottom-sm">
<input
class="color-input flex-sub"
v-model="formData.color"
placeholder="#FF5733"
/>
<view class="color-preview" :style="{ backgroundColor: formData.color }"></view> <view class="color-preview" :style="{ backgroundColor: formData.color }"></view>
<text class="margin-left-sm text-gray">{{ selectedColorLabel }}</text>
</view> </view>
<!-- 预设颜色 --> <view class="margin-bottom-sm text-gray">请选择颜色</view>
<view class="margin-top margin-bottom-sm text-gray">预设颜色</view>
<view class="color-grid"> <view class="color-grid">
<view <view
v-for="(color, index) in presetColors" v-for="item in presetColors"
:key="color + index" :key="item.value"
class="color-option"
@click="selectColor(item.value)"
>
<view
class="color-item" class="color-item"
:class="{ 'color-item-active': formData.color === color }" :class="{ 'color-item-active': formData.color === item.value }"
:style="{ backgroundColor: color }" :style="{ backgroundColor: item.value }"
@click="selectColor(color)"
></view> ></view>
<text class="color-label">{{ item.name }}</text>
</view>
</view> </view>
</view> </view>
<view class="popup-footer"> <view class="popup-footer">
@@ -53,7 +53,7 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, watch } from 'vue'; import { reactive, watch, computed } from 'vue';
const props = defineProps({ const props = defineProps({
visible: { visible: {
@@ -79,21 +79,36 @@ const emit = defineEmits(['update:visible', 'submit', 'close']);
// 表单数据 // 表单数据
const formData = reactive({ const formData = reactive({
name: '', name: '',
color: '#FF5733' color: '#D92121'
}); });
// 预设颜色 // 可选颜色(固定四种)
const presetColors = [ const presetColors = [
'#2563eb', '#ef4444', '#10b981', '#f59e0b', '#6366f1', '#ec4899', '#06b6d4', { name: '红色', value: '#D92121' },
'#84cc16', '#f97316', '#4f46e5', '#dc2626', '#f59e0b', '#d97706', '#8b5cf6', { name: '橙色', value: '#FF8822' },
'#db2777' { name: '黄色', value: '#FFCC00' },
{ name: '蓝色', value: '#165DFF' }
]; ];
const presetColorValues = presetColors.map((item) => item.value);
const selectedColorLabel = computed(() => {
const found = presetColors.find((item) => item.value === formData.color);
return found ? `${found.name} ${found.value}` : formData.color;
});
const normalizeColor = (color) => {
if (!color) return presetColors[0].value;
const upper = String(color).toUpperCase();
const matched = presetColorValues.find((v) => v.toUpperCase() === upper);
return matched || presetColors[0].value;
};
// 监听 editData 变化,填充表单 // 监听 editData 变化,填充表单
watch(() => props.editData, (newVal) => { watch(() => props.editData, (newVal) => {
if (newVal && Object.keys(newVal).length > 0) { if (newVal && Object.keys(newVal).length > 0) {
formData.name = newVal.name || ''; formData.name = newVal.name || '';
formData.color = newVal.color || '#FF5733'; formData.color = normalizeColor(newVal.color);
} }
}, { immediate: true, deep: true }); }, { immediate: true, deep: true });
@@ -112,7 +127,7 @@ const selectColor = (color) => {
// 重置表单 // 重置表单
const resetForm = () => { const resetForm = () => {
formData.name = ''; formData.name = '';
formData.color = '#FF5733'; formData.color = '#D92121';
}; };
// 关闭弹窗 // 关闭弹窗
@@ -128,8 +143,8 @@ const handleSubmit = () => {
uni.showToast({ title: '请输入区域名称', icon: 'none' }); uni.showToast({ title: '请输入区域名称', icon: 'none' });
return; return;
} }
if (!formData.color) { if (!presetColorValues.includes(formData.color)) {
uni.showToast({ title: '请选择区域颜色', icon: 'none' }); uni.showToast({ title: '请从预设颜色中选择', icon: 'none' });
return; return;
} }
@@ -222,42 +237,46 @@ const handleSubmit = () => {
box-sizing: border-box; box-sizing: border-box;
} }
// 颜色输入框
.color-input {
height: 70rpx;
padding: 0 20rpx;
border: 2rpx solid #dadbde;
border-radius: 8rpx;
font-size: 28rpx;
box-sizing: border-box;
}
// 颜色预览 // 颜色预览
.color-preview { .color-preview {
width: 70rpx; width: 70rpx;
height: 70rpx; height: 70rpx;
border-radius: 8rpx; border-radius: 8rpx;
margin-left: 20rpx;
flex-shrink: 0; flex-shrink: 0;
border: 2rpx solid #e5e5e5; border: 2rpx solid #e5e5e5;
} }
// 预设颜色网格 // 预设颜色
.color-grid { .color-grid {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 16rpx; justify-content: space-between;
gap: 24rpx 0;
}
.color-option {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
} }
.color-item { .color-item {
width: 70rpx; width: 80rpx;
height: 70rpx; height: 80rpx;
border-radius: 12rpx; border-radius: 12rpx;
border: 4rpx solid transparent; border: 4rpx solid transparent;
box-sizing: border-box; box-sizing: border-box;
} }
.color-label {
margin-top: 12rpx;
font-size: 24rpx;
color: #666;
}
.color-item-active { .color-item-active {
border-color: #333; border-color: #333;
box-shadow: 0 0 0 4rpx rgba(0, 0, 0, 0.08);
} }
</style> </style>

30
main.js
View File

@@ -36,24 +36,36 @@ uni.addInterceptor('chooseImage', {
} }
}); });
// 全局拦截文件上传校验文件后缀是否在后端白名单中,预防非法格式报错 // 全局拦截文件上传校验本地文件后缀;七牛直传按 upload 域名放行
uni.addInterceptor('uploadFile', { const UPLOAD_ALLOWED_EXTENSIONS = ['bmp', 'gif', 'jpg', 'jpeg', 'png', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'html', 'htm', 'txt', 'rar', 'zip', 'gz', 'bz2', 'mp4', 'avi', 'rmvb', 'pdf'];
invoke(args) { const QINIU_UPLOAD_HOST_MARKERS = ['qiniup.com', 'qbox.me'];
const filePath = args.filePath;
if (filePath) { function validateUploadLocalFileExt(filePath) {
if (!filePath) return true;
const cleanPath = filePath.split('?')[0]; const cleanPath = filePath.split('?')[0];
const ext = cleanPath.split('.').pop().toLowerCase(); const ext = cleanPath.split('.').pop().toLowerCase();
const allowedExtensions = ['bmp', 'gif', 'jpg', 'jpeg', 'png', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'html', 'htm', 'txt', 'rar', 'zip', 'gz', 'bz2', 'mp4', 'avi', 'rmvb', 'pdf']; if (!UPLOAD_ALLOWED_EXTENSIONS.includes(ext)) {
if (!allowedExtensions.includes(ext)) {
uni.showToast({ uni.showToast({
title: `不支持 .${ext} 格式,请上传合规的文件或图片`, title: `不支持 .${ext} 格式,请上传合规的文件或图片`,
icon: 'none', icon: 'none',
duration: 3000 duration: 3000
}); });
return false; // 拦截请求 return false;
} }
return true;
}
uni.addInterceptor('uploadFile', {
invoke(args) {
const uploadUrl = args.url || '';
const isQiniuUpload = QINIU_UPLOAD_HOST_MARKERS.some((m) => uploadUrl.includes(m));
if (isQiniuUpload) {
return validateUploadLocalFileExt(args.filePath) ? args : false;
} }
return args; if (uploadUrl.includes('/frontend/attachment/upload')) {
return validateUploadLocalFileExt(args.filePath) ? args : false;
}
return validateUploadLocalFileExt(args.filePath) ? args : false;
} }
}); });

View File

@@ -181,7 +181,8 @@ import {
updateLicense, updateLicense,
deleteLicense deleteLicense
} from '@/request/three_one_api/license.js'; } from '@/request/three_one_api/license.js';
import { baseUrl, getToken, toImageUrl } from '@/request/request.js'; import { toImageUrl } from '@/request/request.js';
import { uploadSingleWithLoading } from '@/utils/upload.js';
// 证照列表 // 证照列表
const licenseList = ref([]); const licenseList = ref([]);
@@ -435,41 +436,22 @@ const chooseImage = () => {
}); });
}; };
// 上传图片 // 上传图片(七牛直传,提交表单时使用完整 URL
const uploadImage = (filePath) => { const uploadImage = async (filePath) => {
uni.showLoading({ title: '上传中...' });
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (uploadRes) => {
uni.hideLoading();
try { try {
const data = JSON.parse(uploadRes.data); const { url } = await uploadSingleWithLoading(filePath);
if (data.code === 0 && data.data) { formData.photo = url;
formData.photo = data.data.url || data.data; formData.photoPreview = url;
uni.showToast({ title: '上传成功', icon: 'success' }); uni.showToast({ title: '上传成功', icon: 'success' });
} else {
uni.showToast({ title: data.msg || '上传失败', icon: 'none' });
formData.photoPreview = '';
}
} catch (e) { } catch (e) {
console.error('解析上传结果失败:', e); console.error('上传失败:', e);
uni.showToast({ title: '上传失败', icon: 'none' }); formData.photo = '';
formData.photoPreview = ''; formData.photoPreview = '';
} uni.showToast({
}, title: e?.msg || e?.message || '上传失败',
fail: (err) => { icon: 'none'
uni.hideLoading();
console.error('上传失败:', err);
uni.showToast({ title: '上传失败', icon: 'none' });
formData.photoPreview = '';
}
}); });
}
}; };
// 移除图片 // 移除图片

View File

@@ -58,7 +58,7 @@
</view> </view>
<view class="card-body"> <view class="card-body">
<view class="info-row"> <view class="info-row">
<text class="text-gray">隐患来源</text> <text class="text-gray">检查形式</text>
<text>{{ sourceOptions[hazardFormData.source]?.title || '-' }}</text> <text>{{ sourceOptions[hazardFormData.source]?.title || '-' }}</text>
</view> </view>
<view class="info-row"> <view class="info-row">
@@ -104,6 +104,19 @@
<text class="text-blue text-bold" style="cursor: pointer; padding: 0 10rpx; color: #2667E9; font-weight: bold;" @click="clearDraft(true)">清空草稿</text> <text class="text-blue text-bold" style="cursor: pointer; padding: 0 10rpx; color: #2667E9; font-weight: bold;" @click="clearDraft(true)">清空草稿</text>
</view> </view>
<view class="flex margin-bottom"> <view class="flex margin-bottom">
<view class="text-gray">检查形式</view>
<view class="text-red">*</view>
</view>
<view class="source-choose-scroll">
<up-choose
v-model="hazardFormData.source"
:options="sourceOptions"
:wrap="false"
item-width="152rpx"
item-height="64rpx"
></up-choose>
</view>
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患图片</view> <view class="text-gray">隐患图片</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
@@ -136,12 +149,6 @@
item-width="183rpx" item-width="183rpx"
item-height="72rpx" item-height="72rpx"
></up-choose> ></up-choose>
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患来源</view>
<view class="text-red">*</view>
</view>
<up-choose v-model="hazardFormData.source" :options="sourceOptions" :wrap="false" item-width="183rpx"
item-height="72rpx"></up-choose>
<view class="flex margin-bottom margin-top"> <view class="flex margin-bottom margin-top">
<view class="text-gray">隐患位置</view> <view class="text-gray">隐患位置</view>
<view class="text-red">*</view> <view class="text-red">*</view>
@@ -266,8 +273,8 @@
import { ref, reactive, computed, nextTick, watch, getCurrentInstance } from 'vue'; import { ref, reactive, computed, nextTick, watch, getCurrentInstance } from 'vue';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { enterCheckPlan, submitCheckResult, addHiddenDanger, getHiddenDangerLabelList, getRegulationList, analyzeHazardImage } from '@/request/api.js'; import { enterCheckPlan, submitCheckResult, addHiddenDanger, getHiddenDangerLabelList, getRegulationList, analyzeHazardImage } from '@/request/api.js';
import { baseUrl, getToken, toImageUrl, imageBaseUrl } from '@/request/request.js'; import { toImageUrl } from '@/request/request.js';
import { addTimestampWatermark } from '@/utils/watermark.js'; import { createUploadListHandlers, buildAttachmentItem } from '@/utils/upload.js';
import { getAreaList } from '@/request/three_one_api/area.js'; import { getAreaList } from '@/request/three_one_api/area.js';
// 页面参数 // 页面参数
@@ -476,12 +483,12 @@
{ id: 3, title: '重大隐患' } { id: 3, title: '重大隐患' }
]); ]);
// 隐患来源选项 // 检查形式选项
const sourceOptions = ref([ const sourceOptions = ref([
{ id: 1, title: '随手拍' }, { id: 1, title: '部门检查' },
{ id: 2, title: '企业自查' }, { id: 2, title: '都导检查' },
{ id: 3, title: '行业互查' }, { id: 3, title: '企业自查' },
{ id: 4, title: '专家诊查' } { id: 4, title: '行业互查' }
]); ]);
// 隐患标签选项 // 隐患标签选项
@@ -578,75 +585,15 @@
}, 300); }, 300);
}; };
// 删除图片 const inspectionUploadInstance = getCurrentInstance();
const deletePic = (event) => { const { afterRead, deletePic } = createUploadListHandlers(hazardFileList, {
hazardFileList.value.splice(event.index, 1); watermark: {
};
// 新增图片
const afterRead = async (event) => {
let lists = [].concat(event.file);
let fileListLen = hazardFileList.value.length;
lists.map((item) => {
hazardFileList.value.push({
...item,
status: 'uploading',
message: '上传中',
});
});
for (let i = 0; i < lists.length; i++) {
let watermarkedUrl = lists[i].url;
try {
const instance = getCurrentInstance();
watermarkedUrl = await addTimestampWatermark({
tempFilePath: lists[i].url,
canvasId: 'watermarkCanvas', canvasId: 'watermarkCanvas',
canvasWidthRef: canvasWidth, canvasWidthRef: canvasWidth,
canvasHeightRef: canvasHeight, canvasHeightRef: canvasHeight,
instance instance: inspectionUploadInstance
});
} catch (e) {
console.error('加水印失败,将使用原图上传:', e);
}
const result = await uploadFilePromise(watermarkedUrl);
let item = hazardFileList.value[fileListLen];
const serverPath = typeof result === 'string' ? result : (result?.url || result?.path || '');
hazardFileList.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
url: toImageUrl(serverPath),
serverPath: serverPath,
});
fileListLen++;
}
};
// 上传文件
const uploadFilePromise = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (res) => {
const data = JSON.parse(res.data);
if (data.code === 0) {
resolve(data.data);
} else {
reject(data.msg || '上传失败');
}
},
fail: (err) => {
console.error('上传失败:', err);
reject(err);
} }
}); });
});
};
// AI 识别隐患 // AI 识别隐患
const handleAiAnalyze = async () => { const handleAiAnalyze = async () => {
@@ -730,24 +677,9 @@
// 如果选择异常,先调用新增隐患接口 // 如果选择异常,先调用新增隐患接口
if (radiovalue1.value === '异常' && hasHazardData.value) { if (radiovalue1.value === '异常' && hasHazardData.value) {
// 构建附件列表 // 构建附件列表
const attachments = hazardFileList.value.map(file => { const attachments = hazardFileList.value
let url = ''; .filter((f) => f.status === 'success')
if (typeof file.url === 'string') { .map((file) => buildAttachmentItem(file));
url = file.url;
} else if (file.url && typeof file.url === 'object') {
url = file.url.url || file.url.path || '';
}
if (typeof url === 'string' && url.startsWith('http')) {
url = url.replace(imageBaseUrl, '');
}
const fileName = (typeof url === 'string' && url) ? url.split('/').pop() : (file.name || '');
return {
fileName: fileName || '',
filePath: url || '',
fileType: file.type || 'image/png',
fileSize: file.size || 0
};
});
// 获取隐患标签ID // 获取隐患标签ID
const selectedTag = tagOptions.value[hazardFormData.tagIndex]; const selectedTag = tagOptions.value[hazardFormData.tagIndex];
@@ -758,7 +690,7 @@
taskId: checkData.value?.taskId, taskId: checkData.value?.taskId,
checkPointId: checkData.value?.checkPointId, checkPointId: checkData.value?.checkPointId,
title: hazardFormData.title, title: hazardFormData.title,
level: hazardFormData.level + 1, level: levelOptions.value[hazardFormData.level]?.id || 2,
lng: hazardLng.value || 0, lng: hazardLng.value || 0,
lat: hazardLat.value || 0, lat: hazardLat.value || 0,
address: hazardAddress.value || '', address: hazardAddress.value || '',
@@ -1245,6 +1177,43 @@
padding: 30rpx; padding: 30rpx;
} }
// 检查形式横向滚动,露出第 4 项一角提示可滑动
.source-choose-scroll {
width: 100%;
overflow: hidden;
:deep(.up-choose) {
width: 100%;
white-space: nowrap;
}
:deep(.u-tag-wrapper) {
margin-right: 12rpx;
}
:deep(.u-tag) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
box-sizing: border-box;
padding: 0 8rpx !important;
line-height: normal !important;
}
:deep(.u-tag__content) {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
}
:deep(.u-tag__text) {
font-size: 24rpx !important;
line-height: 1.3 !important;
text-align: center;
}
}
// AI 识别按钮样式 // AI 识别按钮样式
.ai-btn-wrapper { .ai-btn-wrapper {
display: flex; display: flex;

View File

@@ -97,7 +97,7 @@ const openEditPopup = async (item) => {
currentEditId.value = item.id; currentEditId.value = item.id;
editData.value = { editData.value = {
name: res.data.name || '', name: res.data.name || '',
color: res.data.color || '#FF5733' color: res.data.color || '#D92121'
}; };
showPopup.value = true; showPopup.value = true;
} }

View File

@@ -1,9 +1,9 @@
<template> <template>
<view class="padding page"> <view class="padding page">
<view class="padding bg-white radius margin-bottom card-item" v-for="(item,index) in hazardList" :key="index"> <view class="padding bg-white radius margin-bottom card-item" v-for="item in hazardList" :key="item.hazardId || item.id">
<view class="flex justify-between margin-bottom"> <view class="flex justify-between margin-bottom">
<view class="text-bold text-black" style="flex: 1; margin-right: 16rpx;">{{item.hazardTitle}}</view> <view class="text-bold text-black" style="flex: 1; margin-right: 16rpx;">{{item.hazardTitle}}</view>
<view class="status-tag" :class="getStatusClass(item.verifyResultName)">{{item.verifyResultName || '未知'}}</view> <view class="status-tag" :class="getStatusClass(item)">{{item.verifyResultName || '未知'}}</view>
</view> </view>
<view class="flex margin-bottom"> <view class="flex margin-bottom">
<view class="text-gray">隐患日期</view> <view class="text-gray">隐患日期</view>
@@ -24,7 +24,7 @@
</view> </view>
<view class="flex justify-between"> <view class="flex justify-between">
<view></view> <view></view>
<view><button class="bg-blue round cu-btn lg" @click="editor()">查看详情</button></view> <view><button class="bg-blue round cu-btn lg" @click="editor(item)">查看详情</button></view>
</view> </view>
</view> </view>
<button class="cuIcon-add bg-blue round margin-top" @click="openAddPopup">新增</button> <button class="cuIcon-add bg-blue round margin-top" @click="openAddPopup">新增</button>
@@ -54,30 +54,17 @@
<view class="flex margin-bottom margin-top"> <view class="flex margin-bottom margin-top">
<view>整改时限</view> <view>整改时限</view>
</view> </view>
<view class="picker-input" @click="showDatePicker = true"> <view class="picker-input readonly">
<text :class="formData.rectifyDeadline ? '' : 'text-gray'">{{ formData.rectifyDeadline || '请选择整改时限' }}</text> <text :class="formData.rectifyDeadline ? '' : 'text-gray'">{{ formData.rectifyDeadline || '请选择隐患' }}</text>
</view> </view>
<up-datetime-picker
v-if="false" :show="showDatePicker"
v-model="dateValue"
mode="datetime"
@confirm="onDateConfirm"
@cancel="showDatePicker = false"
@close="showDatePicker = false"
></up-datetime-picker>
<view class="margin-bottom margin-top">隐患治理责任单位</view> <view class="margin-bottom margin-top">隐患治理责任单位</view>
<view class="picker-input" @click="showDeptPicker = true"> <view class="picker-input readonly">
<text :class="selectedDeptName ? '' : 'text-gray'">{{ selectedDeptName || '请选择隐患治理责任单位' }}</text> <text :class="selectedDeptName ? '' : 'text-gray'">{{ selectedDeptName || '请选择隐患' }}</text>
</view> </view>
<up-picker
v-if="false" :show="showDeptPicker"
:columns="deptColumns"
@confirm="onDeptConfirm"
@cancel="showDeptPicker = false"
@close="showDeptPicker = false"
></up-picker>
<view class="margin-bottom margin-top">主要负责人</view> <view class="margin-bottom margin-top">主要负责人</view>
<up-input v-model="formData.responsiblePerson" placeholder="请输入主要负责人"></up-input> <view class="picker-input readonly">
<text :class="formData.responsiblePerson ? '' : 'text-gray'">{{ formData.responsiblePerson || '请先选择隐患' }}</text>
</view>
<view class="ai-btn-wrapper margin-top margin-bottom"> <view class="ai-btn-wrapper margin-top margin-bottom">
<button class="ai-analyze-btn" :loading="aiGenerating" :disabled="aiGenerating" @click="handleAiGenerate"> <button class="ai-analyze-btn" :loading="aiGenerating" :disabled="aiGenerating" @click="handleAiGenerate">
<text v-if="!aiGenerating" class="cuIcon-magic ai-btn-icon"></text> <text v-if="!aiGenerating" class="cuIcon-magic ai-btn-icon"></text>
@@ -107,34 +94,16 @@
@close="showHazardPicker = false" @close="showHazardPicker = false"
></up-picker> ></up-picker>
<up-datetime-picker
:show="showDatePicker"
v-model="dateValue"
mode="datetime"
@confirm="onDateConfirm"
@cancel="showDatePicker = false"
@close="showDatePicker = false"
></up-datetime-picker>
<up-picker
:show="showDeptPicker"
:columns="deptColumns"
@confirm="onDeptConfirm"
@cancel="showDeptPicker = false"
@close="showDeptPicker = false"
></up-picker>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted } from 'vue'
import { getMyWriteOffList, applyDelete, getAcceptanceList, getDepartmentPersonUsers, getHiddenDangerDetail, getRectifyDetail, generateWriteoffContent } from '@/request/api.js'; import { getMyWriteOffList, applyDelete, getAcceptanceList, getHiddenDangerDetail, getRectifyDetail, generateWriteoffContent } from '@/request/api.js';
// 弹窗控制 // 弹窗控制
const showAddPopup = ref(false); const showAddPopup = ref(false);
const showHazardPicker = ref(false); const showHazardPicker = ref(false);
const showDatePicker = ref(false);
const showDeptPicker = ref(false);
// 隐患选择 // 隐患选择
const selectedHazard = ref(''); const selectedHazard = ref('');
@@ -143,14 +112,8 @@
const acceptanceHazardList = ref([]); // 存储可申请销号的隐患数据 const acceptanceHazardList = ref([]); // 存储可申请销号的隐患数据
const hazardList = ref([]); // 存储销号申请列表 const hazardList = ref([]); // 存储销号申请列表
// 部门选择 // 隐患关联的只读展示字段
const selectedDeptName = ref(''); const selectedDeptName = ref('');
const selectedDeptId = ref('');
const deptColumns = ref([['暂无数据']]);
const deptList = ref([]); // 存储部门列表
// 日期选择
const dateValue = ref(Date.now());
// AI生成状态 // AI生成状态
const aiGenerating = ref(false); const aiGenerating = ref(false);
@@ -198,94 +161,41 @@
} }
}; };
// 获取部门列表
const fetchDeptList = async () => {
try {
const res = await getDepartmentPersonUsers();
if (res.code === 0 && res.data) {
const users = [];
res.data.forEach(dept => {
if (dept.users && dept.users.length > 0) {
dept.users.forEach(user => {
users.push({
userId: user.userId,
deptId: dept.deptId,
name: `${user.nickName}${dept.deptName}`
});
});
}
});
deptList.value = users;
// 转换为 picker 需要的格式
if (users.length > 0) {
deptColumns.value = [users.map(item => item.name)];
} else {
deptColumns.value = [['暂无人员数据']];
}
console.log('部门人员列表:', users);
}
} catch (error) {
console.error('获取部门人员列表失败:', error);
}
};
// 部门选择确认
const onDeptConfirm = (e) => {
console.log('选择的人员:', e);
if (e.value && e.value.length > 0) {
selectedDeptName.value = e.value[0];
// 找到对应的用户ID和部门ID
const index = e.indexs[0];
if (deptList.value[index]) {
selectedDeptId.value = deptList.value[index].deptId;
formData.responsibleDeptId = deptList.value[index].deptId;
}
}
showDeptPicker.value = false;
};
// 打开新增弹窗 // 打开新增弹窗
const openAddPopup = () => { const openAddPopup = () => {
resetForm(); resetForm();
fetchAcceptanceList(); // 获取可申请销号的隐患列表 fetchAcceptanceList(); // 获取可申请销号的隐患列表
fetchDeptList(); // 获取部门列表
showAddPopup.value = true; showAddPopup.value = true;
}; };
// 根据选中的隐患回显只读字段
const fillHazardRelatedFields = (hazard) => {
formData.rectifyDeadline = hazard.deadline || '';
selectedDeptName.value = hazard.deptName || '';
formData.responsiblePerson = hazard.rectifierName || '';
formData.responsibleDeptId = hazard.deptId || '';
};
// 隐患选择确认 // 隐患选择确认
const onHazardConfirm = (e) => { const onHazardConfirm = (e) => {
console.log('选择的隐患:', e); console.log('选择的隐患:', e);
if (e.value && e.value.length > 0) { if (e.value && e.value.length > 0) {
selectedHazard.value = e.value[0]; selectedHazard.value = e.value[0];
// 找到对应的隐患ID
const index = e.indexs[0]; const index = e.indexs[0];
if (acceptanceHazardList.value[index]) { const hazard = acceptanceHazardList.value[index];
selectedHazardId.value = acceptanceHazardList.value[index].hazardId; if (hazard) {
selectedHazardId.value = hazard.hazardId;
fillHazardRelatedFields(hazard);
} }
} }
showHazardPicker.value = false; showHazardPicker.value = false;
}; };
// 日期时间选择确认
const onDateConfirm = (e) => {
console.log('选择的日期时间:', e);
const date = new Date(e.value);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
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');
formData.rectifyDeadline = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
showDatePicker.value = false;
};
// 重置表单 // 重置表单
const resetForm = () => { const resetForm = () => {
selectedHazard.value = ''; selectedHazard.value = '';
selectedHazardId.value = ''; selectedHazardId.value = '';
selectedDeptName.value = ''; selectedDeptName.value = '';
selectedDeptId.value = '';
formData.rectifyDeadline = ''; formData.rectifyDeadline = '';
formData.responsibleDeptId = ''; formData.responsibleDeptId = '';
formData.responsiblePerson = ''; formData.responsiblePerson = '';
@@ -386,20 +296,26 @@
} }
}; };
const editor = () => { const editor = (item) => {
if (!item?.id) {
uni.showToast({ title: '缺少申请ID', icon: 'none' });
return;
}
uni.navigateTo({ uni.navigateTo({
url: '/pages/closeout/editor' url: `/pages/closeout/editor?applyId=${item.id}`
}) });
}; };
// 根据审核状态返回对应样式类 // 根据审核状态返回对应样式类
const getStatusClass = (status) => { const getStatusClass = (item) => {
switch (status) { const statusName = item?.verifyResultName || '';
case '待审核': return 'status-pending'; if (statusName === '待审核') return 'status-pending';
case '通过': return 'status-passed'; if (statusName === '审核通过' || statusName === '已通过') return 'status-passed';
case '驳回': return 'status-rejected'; if (statusName === '审核驳回' || statusName === '已驳回') return 'status-rejected';
default: return 'status-pending'; if (statusName === '已重新申请') return 'status-reapply';
} if (item?.verifyResult === 1) return 'status-passed';
if (item?.verifyResult === 2) return 'status-rejected';
return 'status-default';
}; };
// 页面加载时获取销号申请列表 // 页面加载时获取销号申请列表
@@ -441,6 +357,16 @@
color: #F5222D; color: #F5222D;
} }
.status-reapply {
background: #E6F7FF;
color: #1890FF;
}
.status-default {
background: #F5F5F5;
color: #8C8C8C;
}
.popup-content { .popup-content {
width: 600rpx; width: 600rpx;
background: #fff; background: #fff;
@@ -534,12 +460,15 @@
border-radius: 8rpx; border-radius: 8rpx;
padding: 24rpx 20rpx; padding: 24rpx 20rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
// border: 1rpx solid #F6F6F6;
border: 1rpx solid #eee; border: 1rpx solid #eee;
text { text {
font-size: 28rpx; font-size: 28rpx;
// color: #333; }
&.readonly {
background: #f5f5f5;
color: #666;
} }
} }
</style> </style>

View File

@@ -1,132 +1,138 @@
<template> <template>
<view class="padding page"> <view class="padding page">
<view class="padding bg-white radius"> <view class="padding bg-white radius">
<view class="flex margin-bottom"> <view class="text-gray margin-bottom">隐患名称</view>
<view class="text-gray">隐患</view> <up-input v-model="formData.hazardName" placeholder="暂无" disabled></up-input>
</view>
<up-input v-model="formData.hazardTitle" placeholder="" disabled></up-input> <view class="text-gray margin-bottom margin-top">整改时限</view>
<view class="text-gray margin-bottom margin-top">隐患日期</view> <up-input v-model="formData.deadline" placeholder="暂无" disabled></up-input>
<up-input v-model="formData.hazardCreatedAt" placeholder="" disabled></up-input>
<view class="text-gray margin-bottom margin-top">隐患治理责任单位</view> <view class="text-gray margin-bottom margin-top">隐患治理责任单位</view>
<up-input v-model="formData.responsibleDeptName" placeholder="请输入" :disabled="!canEdit"></up-input> <up-input v-model="formData.responsibilityUnit" placeholder="暂无" disabled></up-input>
<view class="text-gray margin-bottom margin-top">主要负责人</view> <view class="text-gray margin-bottom margin-top">主要负责人</view>
<up-input v-model="formData.responsiblePerson" placeholder="请输入" :disabled="!canEdit"></up-input> <up-input v-model="formData.mainPerson" placeholder="暂无" disabled></up-input>
<view class="text-gray margin-bottom margin-top">创建时间</view>
<up-input v-model="formData.createdAt" placeholder="" disabled></up-input> <view class="text-gray margin-bottom margin-top">主要治理内容</view>
<up-textarea v-model="formData.mainGovernanceContent" placeholder="暂无" disabled autoHeight></up-textarea>
<view class="text-gray margin-bottom margin-top">隐患治理完成内容</view>
<up-textarea v-model="formData.governanceCompleteContent" placeholder="暂无" disabled autoHeight></up-textarea>
<view class="text-gray margin-bottom margin-top">状态</view> <view class="text-gray margin-bottom margin-top">状态</view>
<up-input v-model="formData.statusName" placeholder="" disabled></up-input> <up-input :modelValue="statusText" placeholder="暂无" disabled></up-input>
<view class="flex justify-center margin-top-xl" style="gap: 30rpx;">
<template v-if="hasRejectReason">
<view class="text-gray margin-bottom margin-top">驳回理由</view>
<up-textarea v-model="formData.rejectReason" placeholder="暂无" disabled autoHeight></up-textarea>
</template>
<template v-if="hasSignature">
<view class="text-gray margin-bottom margin-top">电子签名</view>
<view class="signature-box">
<image
:src="signatureUrl"
class="signature-img"
mode="aspectFit"
@click="previewSignature"
@error="onSignatureImageError"
></image>
</view>
</template>
<view class="flex justify-center margin-top-xl">
<button class="round cu-btn lg" @click="handleCancel">返回</button> <button class="round cu-btn lg" @click="handleCancel">返回</button>
<!-- <button v-if="canEdit" class="bg-blue round cu-btn lg" @click="handleSubmit">保存</button> -->
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import {getMyWriteOffList } from '@/request/api.js'; import { getWriteOffApplyDetail } from '@/request/api.js'
import { toSubmitFileUrl } from '@/utils/upload.js'
// 获取页面参数的方法 const applyId = ref('')
const getPageOptions = () => { const signatureUrl = ref('')
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
return currentPage?.options || {};
};
// 页面参数
const pageId = ref('');
const canEdit = ref(false); // 是否可编辑(待审核状态可编辑)
// 表单数据
const formData = reactive({ const formData = reactive({
id: '',
hazardId: '', hazardId: '',
hazardTitle: '', // 隐患标题 hazardName: '',
hazardCreatedAt: '', // 隐患日期 deadline: '',
responsibleDeptName: '', // 隐患治理责任单位 responsibilityUnit: '',
responsiblePerson: '', // 主要负责人 mainPerson: '',
createdAt: '', // 创建时间 mainGovernanceContent: '',
statusName: '' // 状态 governanceCompleteContent: '',
status: '',
rejectReason: ''
})
const statusText = computed(() => {
const val = Number(formData.status);
if (val === 1) return '通过';
if (val === 2) return '不通过';
return '';
}); });
// 获取详情 const hasRejectReason = computed(() => Boolean(String(formData.rejectReason || '').trim()));
const hasSignature = computed(() => Boolean(signatureUrl.value));
const applySignature = (signPath) => {
signatureUrl.value = signPath ? toSubmitFileUrl(signPath) : ''
}
const previewSignature = () => {
if (!signatureUrl.value) return
uni.previewImage({
urls: [signatureUrl.value],
current: signatureUrl.value
})
}
const onSignatureImageError = () => {
console.error('签名图片加载失败:', signatureUrl.value)
}
const fetchDetail = async (id) => { const fetchDetail = async (id) => {
console.log('=== fetchDetail 被调用 ===, id:', id); if (!id) {
uni.showToast({ title: '缺少申请ID', icon: 'none' })
return
}
try { try {
const res = await getMyWriteOffList(); uni.showLoading({ title: '加载中...' })
console.log('接口返回:', res); const res = await getWriteOffApplyDetail(id)
if (res.code === 0 && res.data && res.data.length > 0) { if (res.code === 0 && res.data) {
const list = res.data; const data = res.data
// 如果有 id 就按 id 找,否则取第一条 formData.hazardId = data.hazardId || ''
let data = null; formData.hazardName = data.hazardName || ''
if (id) { formData.deadline = data.deadline || ''
data = list.find(item => item.id == id); formData.responsibilityUnit = data.responsibilityUnit || ''
} formData.mainPerson = data.mainPerson || ''
// 如果没找到,取第一条 formData.mainGovernanceContent = data.mainGovernanceContent || ''
if (!data) { formData.governanceCompleteContent = data.governanceCompleteContent || ''
data = list[0]; formData.status = data.status ?? ''
} formData.rejectReason = data.rejectReason || ''
applySignature(data.signPath)
console.log('绑定数据:', data);
// 绑定数据
formData.id = data.id;
formData.hazardId = data.hazardId;
formData.hazardTitle = data.hazardTitle || '';
formData.hazardCreatedAt = data.hazardCreatedAt || '';
formData.responsibleDeptName = data.responsibleDeptName || '';
formData.responsiblePerson = data.responsiblePerson || '';
formData.createdAt = data.createdAt || '';
formData.statusName = data.statusName || '';
// 根据返回数据的状态判断是否可编辑(待审核 status=1 可编辑)
if (data.status == 1 || data.statusName === '待审核') {
canEdit.value = true;
console.log('状态为待审核,可以编辑');
} else { } else {
canEdit.value = false; uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' })
console.log('状态为已审核,不可编辑');
}
} }
} catch (error) { } catch (error) {
console.error('获取详情失败:', error); console.error('获取销号申请详情失败:', error)
uni.showToast({ title: '获取详情失败', icon: 'none' })
} finally {
uni.hideLoading()
}
} }
};
// 返回
const handleCancel = () => { const handleCancel = () => {
uni.navigateBack(); uni.navigateBack()
};
// 保存
const handleSubmit = async () => {
console.log('保存数据:', formData);
// TODO: 调用更新接口
uni.showToast({ title: '保存成功', icon: 'success' });
setTimeout(() => {
uni.navigateBack();
}, 1500);
};
// 页面加载
onLoad((options) => {
console.log('=== onLoad 触发 ===');
console.log('options:', options);
pageId.value = options?.id || '';
fetchDetail(pageId.value);
});
// 备用onMounted
onMounted(() => {
console.log('=== onMounted 触发 ===');
if (!pageId.value) {
const options = getPageOptions();
console.log('备用获取参数:', options);
pageId.value = options?.id || '';
fetchDetail(pageId.value);
} }
});
onLoad((options) => {
applyId.value = options?.applyId || ''
fetchDetail(applyId.value)
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -135,4 +141,17 @@
background: #EBF2FC; background: #EBF2FC;
} }
.signature-box {
width: 100%;
height: 240rpx;
background: #f8f8f8;
border: 1rpx dashed #dcdfe6;
border-radius: 8rpx;
overflow: hidden;
}
.signature-img {
width: 100%;
height: 240rpx;
}
</style> </style>

View File

@@ -299,7 +299,7 @@
import { ref, reactive, onMounted, computed } from 'vue' import { ref, reactive, onMounted, computed } from 'vue'
import { onShow } from '@dcloudio/uni-app' import { onShow } from '@dcloudio/uni-app'
import { getEnterpriseinfo, addEnterprise, updateEnterprise, getEnterprisetype, getindustry } from '@/request/api.js' import { getEnterpriseinfo, addEnterprise, updateEnterprise, getEnterprisetype, getindustry } from '@/request/api.js'
import { baseUrl, getToken } from '@/request/request.js' import { createUploadListHandlers, mapServerFileToUploadItem } from '@/utils/upload.js'
// 企业信息 // 企业信息
const enterpriseInfo = ref({}) const enterpriseInfo = ref({})
@@ -520,11 +520,7 @@ const openEditPopup = () => {
if (enterpriseInfo.value.certificates) { if (enterpriseInfo.value.certificates) {
try { try {
const certs = JSON.parse(enterpriseInfo.value.certificates) const certs = JSON.parse(enterpriseInfo.value.certificates)
certificateFiles.value = certs.map(cert => ({ certificateFiles.value = certs.map((cert) => mapServerFileToUploadItem(cert))
url: cert.filePath || cert.url,
name: cert.fileName || cert.name,
status: 'success'
}))
} catch (e) { } catch (e) {
certificateFiles.value = [] certificateFiles.value = []
} }
@@ -535,60 +531,7 @@ const openEditPopup = () => {
showPopup.value = true showPopup.value = true
} }
// 上传文件 const { afterRead, deletePic: deleteCertificate } = createUploadListHandlers(certificateFiles)
const afterRead = async (event) => {
let lists = [].concat(event.file)
let fileListLen = certificateFiles.value.length
lists.forEach((item) => {
certificateFiles.value.push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await uploadFilePromise(lists[i].url)
let item = certificateFiles.value[fileListLen]
certificateFiles.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
url: result
})
fileListLen++
}
}
// 删除文件
const deleteCertificate = (event) => {
certificateFiles.value.splice(event.index, 1)
}
// 上传文件Promise
const uploadFilePromise = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (res) => {
const data = JSON.parse(res.data)
if (data.code === 0) {
resolve(data.data)
} else {
reject(data.msg || '上传失败')
}
},
fail: (err) => {
console.error('上传失败:', err)
reject(err)
}
})
})
}
// 提交表单 // 提交表单
const handleSubmit = async () => { const handleSubmit = async () => {
@@ -606,10 +549,11 @@ const handleSubmit = async () => {
return return
} }
// 构建资质证书JSON const certificates = certificateFiles.value
const certificates = certificateFiles.value.map(file => ({ .filter((f) => f.status === 'success')
fileName: file.name || file.url.split('/').pop(), .map((file) => ({
filePath: file.url fileName: file.name || (file.serverPath || file.url || '').split('/').pop(),
filePath: file.serverPath || file.url
})) }))
const params = { const params = {

View File

@@ -200,19 +200,28 @@
</view> </view>
<!-- 从检查库添加的检查项卡片 --> <!-- 从检查库添加的检查项卡片 -->
<view class="check-card" v-for="(item, index) in checkItems" :key="'lib-' + index"> <view class="check-card library-card" v-for="(item, index) in libraryCheckItems" :key="'lib-' + item.pointId">
<view class="card-tag library-tag">检查库</view>
<view class="check-info"> <view class="check-info">
<view class="info-row"> <view class="info-row">
<text class="info-label">关联表名</text> <text class="info-label">来源检查库</text>
<text class="info-value">{{ item.tableName }}</text> <text class="info-value">{{ item.sourceLibraryName || '-' }}</text>
</view> </view>
<view class="info-row"> <view class="info-row">
<text class="info-label">检查项数量</text> <text class="info-label">检查项名称</text>
<text class="info-value">{{ item.count }}</text> <text class="info-value">{{ item.name }}</text>
</view>
<view class="info-row">
<text class="info-label">检查内容</text>
<text class="info-value">{{ item.point }}</text>
</view>
<view class="info-row">
<text class="info-label">参考法规</text>
<text class="info-value">{{ item.regulation || '-' }}</text>
</view> </view>
</view> </view>
<view class="check-action"> <view class="check-action">
<button class="btn-delete" @click="deleteCheckItem(index)">删除</button> <button class="btn-delete" @click="deleteLibraryCheckItem(index)">删除</button>
</view> </view>
</view> </view>
</view> </view>
@@ -647,15 +656,25 @@ const onEndDateConfirm = (e) => {
// 手动添加的检查项列表 // 手动添加的检查项列表
const manualCheckItems = ref([]); const manualCheckItems = ref([]);
// 从检查库添加的检查项 // 从检查库展开添加的检查项(每一条检查点一项)
const checkItems = ref([]); const libraryCheckItems = ref([]);
// 检查项数量(手动添加的数量 + 检查库的数量 // 检查项数量(手动添加 + 检查库展开项
const checkItemCount = computed(() => { const checkItemCount = computed(() => {
const libraryCount = checkItems.value.reduce((sum, item) => sum + item.count, 0); return manualCheckItems.value.length + libraryCheckItems.value.length;
return manualCheckItems.value.length + libraryCount;
}); });
const getExistingPointIds = () => {
const ids = new Set();
manualCheckItems.value.forEach((item) => {
if (item.id) ids.add(Number(item.id));
});
libraryCheckItems.value.forEach((item) => {
if (item.pointId) ids.add(Number(item.pointId));
});
return ids;
};
// 删除手动添加的检查项(调用接口删除) // 删除手动添加的检查项(调用接口删除)
const deleteManualCheckItem = (item, index) => { const deleteManualCheckItem = (item, index) => {
uni.showModal({ uni.showModal({
@@ -691,15 +710,15 @@ const deleteManualCheckItem = (item, index) => {
}); });
}; };
// 删除检查库的检查项(只从本地暂存删除,不调用接口) // 删除检查库展开的检查项(只从本地暂存删除,不调用接口)
const deleteCheckItem = (index) => { const deleteLibraryCheckItem = (index) => {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确定要删除该检查项吗?', content: '确定要删除该检查项吗?',
confirmColor: '#F56C6C', confirmColor: '#F56C6C',
success: (res) => { success: (res) => {
if (res.confirm) { if (res.confirm) {
checkItems.value.splice(index, 1); libraryCheckItems.value.splice(index, 1);
uni.showToast({ title: '删除成功', icon: 'success' }); uni.showToast({ title: '删除成功', icon: 'success' });
} }
} }
@@ -955,6 +974,66 @@ const toggleLibrarySelect = (item) => {
} }
}; };
// 拉取检查库详情全部分页数据
const fetchLibraryDetailAll = async (libraryId) => {
const pageSize = 50;
let pageNum = 1;
let allRecords = [];
let total = 0;
while (true) {
const res = await getCheckItemListDetail({
id: libraryId,
pageNum,
pageSize
});
if (res.code !== 0 || !res.data) break;
const records = res.data.records || [];
total = Number(res.data.total) || 0;
allRecords = [...allRecords, ...records];
if (records.length === 0 || allRecords.length >= total) break;
pageNum += 1;
}
return allRecords;
};
const getLibraryDisplayName = (libraryId, records) => {
const library = libraryList.value.find((item) => String(item.id) === String(libraryId));
if (library?.name) return library.name;
if (records.length > 0) return records[0].name || '';
return '';
};
const appendLibraryRecords = (libraryId, records, sourceLibraryName) => {
const existingPointIds = getExistingPointIds();
let addedCount = 0;
records.forEach((record) => {
if (!record.pointId) return;
const pointId = Number(record.pointId);
if (existingPointIds.has(pointId)) return;
existingPointIds.add(pointId);
libraryCheckItems.value.push({
pointId,
itemId: record.itemId,
sourceLibraryId: libraryId,
sourceLibraryName,
name: record.name || '',
point: record.point || '',
industry: record.industry || '',
leadDept: record.leadDept || '',
regulation: record.regulation || ''
});
addedCount += 1;
});
return addedCount;
};
// 添加选中的检查库 // 添加选中的检查库
const addSelectedLibrary = async () => { const addSelectedLibrary = async () => {
if (selectedLibraries.value.length === 0) { if (selectedLibraries.value.length === 0) {
@@ -965,27 +1044,22 @@ const addSelectedLibrary = async () => {
uni.showLoading({ title: '加载中...' }); uni.showLoading({ title: '加载中...' });
try { try {
// 遍历选中的检查库,获取详情 let totalAdded = 0;
for (const id of selectedLibraries.value) {
const res = await getCheckItemListDetail({ id: id });
if (res.code === 0 && res.data) {
const records = res.data.records || [];
const total = res.data.total || 0;
// 获取关联表名第一项的name
const tableName = records.length > 0 ? records[0].name : '';
// 添加到检查项列表 for (const id of selectedLibraries.value) {
checkItems.value.push({ const records = await fetchLibraryDetailAll(id);
itemId: id, const sourceLibraryName = getLibraryDisplayName(id, records);
tableName: tableName, totalAdded += appendLibraryRecords(id, records, sourceLibraryName);
count: total,
details: records // 保存详情数据,以便后续使用
});
}
} }
uni.hideLoading(); uni.hideLoading();
uni.showToast({ title: '添加成功', icon: 'success' });
if (totalAdded === 0) {
uni.showToast({ title: '没有可添加的新检查项', icon: 'none' });
return;
}
uni.showToast({ title: `已添加${totalAdded}`, icon: 'success' });
showLibraryPopup.value = false; showLibraryPopup.value = false;
selectedLibraries.value = []; selectedLibraries.value = [];
} catch (error) { } catch (error) {
@@ -1032,22 +1106,16 @@ const handleSave = async () => {
return; return;
} }
// 构建 items 数组(关联检查项id列表 // 构建 checkPointIds 数组(检查点 id 列表)
const items = []; const items = [];
// 添加手动添加的检查项id manualCheckItems.value.forEach((item) => {
manualCheckItems.value.forEach(item => {
if (item.id) { if (item.id) {
items.push(item.id ); items.push(Number(item.id));
}
});
// 添加从检查库选择的检查项详情中的所有项的 itemId
checkItems.value.forEach(lib => {
if (lib.details && lib.details.length > 0) {
lib.details.forEach(detail => {
if (detail.itemId) {
items.push(detail.itemId);
} }
}); });
libraryCheckItems.value.forEach((item) => {
if (item.pointId) {
items.push(Number(item.pointId));
} }
}); });
@@ -1070,13 +1138,13 @@ const handleSave = async () => {
'每季度一次': 4 '每季度一次': 4
}; };
// 构建 itemIds 数组从检查库选择的检查库id列表 // 构建 itemIds 数组(从检查库选择的检查库 id 列表,去重
const itemIds = []; const itemIds = [...new Set(
checkItems.value.forEach(lib => { libraryCheckItems.value
if (lib.itemId) { .map((item) => item.sourceLibraryId)
itemIds.push(lib.itemId); .filter(Boolean)
} .map((id) => Number(id))
}); )];
// 构建提交参数 // 构建提交参数
const params = { const params = {
@@ -1271,7 +1339,8 @@ onMounted(() => {
} }
// 手动添加的检查项卡片带第x项标签 // 手动添加的检查项卡片带第x项标签
.manual-card { .manual-card,
.library-card {
padding-top: 50rpx; padding-top: 50rpx;
.card-tag { .card-tag {
@@ -1286,6 +1355,10 @@ onMounted(() => {
} }
} }
.library-card .library-tag {
background: #67C23A;
}
// 添加按钮组 // 添加按钮组
.add-btns { .add-btns {
display: flex; display: flex;

View File

@@ -59,6 +59,7 @@
ref, ref,
reactive reactive
} from 'vue'; } from 'vue';
import { createUploadListHandlers } from '@/utils/upload.js';
// 基本案列数据 // 基本案列数据
const radiolist1 = reactive([{ const radiolist1 = reactive([{
@@ -90,14 +91,8 @@
console.log('radioChange', n); console.log('radioChange', n);
}; };
// 图片上传
const fileList1 = ref([]); const fileList1 = ref([]);
const afterRead = (event) => { const { afterRead, deletePic } = createUploadListHandlers(fileList1);
console.log(event);
};
const deletePic = (event) => {
console.log(event);
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -61,7 +61,7 @@
</view> </view>
<!-- 新增弹窗 --> <!-- 新增弹窗 -->
<u-popup :show="showAddPopup" mode="center" round="20" @close="showAddPopup = false"> <u-popup :show="showAddPopup" mode="center" round="20" :safe-area-inset-bottom="false" @close="showAddPopup = false">
<view class="popup-content"> <view class="popup-content">
<view class="popup-header"> <view class="popup-header">
<view class="popup-title text-bold">新增隐患排查</view> <view class="popup-title text-bold">新增隐患排查</view>
@@ -69,6 +69,20 @@
</view> </view>
<scroll-view class="popup-body" scroll-y> <scroll-view class="popup-body" scroll-y>
<view class="flex margin-bottom"> <view class="flex margin-bottom">
<view class="text-gray">检查形式</view>
<view class="text-red">*</view>
</view>
<view class="source-choose-scroll">
<up-choose
v-model="formData.source"
:options="sourceOptions"
:wrap="false"
item-width="152rpx"
item-height="64rpx"
></up-choose>
</view>
<!-- <view class="text-gray text-sm margin-top-xs">左右滑动可查看更多来源</view> -->
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患图片</view> <view class="text-gray">隐患图片</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
@@ -101,12 +115,6 @@
item-width="183rpx" item-width="183rpx"
item-height="72rpx" item-height="72rpx"
></up-choose> ></up-choose>
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患来源</view>
<view class="text-red">*</view>
</view>
<up-choose v-model="formData.source" :options="sourceOptions" :wrap="false" item-width="183rpx"
item-height="72rpx"></up-choose>
<view class="flex margin-bottom margin-top"> <view class="flex margin-bottom margin-top">
<view class="text-gray">隐患位置</view> <view class="text-gray">隐患位置</view>
<view class="text-red">*</view> <view class="text-red">*</view>
@@ -158,7 +166,7 @@
</u-popup> </u-popup>
<!-- 选择法规弹出框 --> <!-- 选择法规弹出框 -->
<u-popup :show="showLawPopup" mode="center" round="20" @close="showLawPopup = false"> <u-popup :show="showLawPopup" mode="center" round="20" :safe-area-inset-bottom="false" @close="showLawPopup = false">
<view class="law-popup"> <view class="law-popup">
<view class="popup-header"> <view class="popup-header">
<view class="popup-title">选择法律依据</view> <view class="popup-title">选择法律依据</view>
@@ -249,13 +257,8 @@
analyzeHazardImage analyzeHazardImage
} from '@/request/api.js' } from '@/request/api.js'
import { getAreaList } from '@/request/three_one_api/area.js' import { getAreaList } from '@/request/three_one_api/area.js'
import { addTimestampWatermark } from '@/utils/watermark.js' import { toImageUrl } from '@/request/request.js'
import { import { createUploadListHandlers, buildAttachmentItem } from '@/utils/upload.js'
baseUrl,
getToken,
toImageUrl,
imageBaseUrl
} from '@/request/request.js'
// 弹窗控制 // 弹窗控制
const showAddPopup = ref(false); const showAddPopup = ref(false);
@@ -533,16 +536,9 @@
return; return;
} }
const attachments = fileList1.value.map(file => { const attachments = fileList1.value
const path = file.serverPath || ''; .filter((f) => f.status === 'success')
const fileName = path ? path.split('/').pop() : (file.name || ''); .map((file) => buildAttachmentItem(file));
return {
fileName: fileName || '',
filePath: path,
fileType: file.type || 'image/png',
fileSize: file.size || 0
};
});
// 获取隐患标签ID // 获取隐患标签ID
const selectedTag = tagOptions.value[formData.tagIndex]; const selectedTag = tagOptions.value[formData.tagIndex];
@@ -640,9 +636,11 @@
}) })
} }
const Rectification = (item) => { const Rectification = (item) => {
uni.navigateTo({ let url = `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}`
url: `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}` if (item.deadline) {
}) url += `&deadline=${encodeURIComponent(item.deadline)}`
}
uni.navigateTo({ url })
} }
// 编辑整改信息(待验收状态) // 编辑整改信息(待验收状态)
@@ -664,77 +662,15 @@
}) })
} }
const fileList1 = ref([]); const fileList1 = ref([]);
const uploadInstance = getCurrentInstance();
// 删除图片 const { afterRead, deletePic } = createUploadListHandlers(fileList1, {
const deletePic = (event) => { watermark: {
fileList1.value.splice(event.index, 1);
};
// 新增图片
const afterRead = async (event) => {
// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileListLen = fileList1.value.length;
lists.map((item) => {
fileList1.value.push({
...item,
status: 'uploading',
message: '上传中',
});
});
for (let i = 0; i < lists.length; i++) {
let watermarkedUrl = lists[i].url;
try {
const instance = getCurrentInstance();
watermarkedUrl = await addTimestampWatermark({
tempFilePath: lists[i].url,
canvasId: 'watermarkCanvas', canvasId: 'watermarkCanvas',
canvasWidthRef: canvasWidth, canvasWidthRef: canvasWidth,
canvasHeightRef: canvasHeight, canvasHeightRef: canvasHeight,
instance instance: uploadInstance
});
} catch (e) {
console.error('加水印失败,将使用原图上传:', e);
}
const result = await uploadFilePromise(watermarkedUrl);
let item = fileList1.value[fileListLen];
const serverPath = typeof result === 'string' ? result : (result?.url || result?.path || '');
fileList1.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
// url: baseUrl + serverPath,
url: toImageUrl(serverPath),
serverPath: serverPath,
});
fileListLen++;
}
};
const uploadFilePromise = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (res) => {
const data = JSON.parse(res.data);
if (data.code === 0) {
resolve(data.data);
} else {
reject(data.msg || '上传失败');
}
},
fail: (err) => {
console.error('上传失败:', err);
reject(err);
} }
}); });
});
};
// AI 识别隐患 // AI 识别隐患
const aiAnalyzing = ref(false); const aiAnalyzing = ref(false);
@@ -833,19 +769,19 @@
//隐患来源 //隐患来源
const sourceOptions = ref([{ const sourceOptions = ref([{
id: 1, id: 1,
title: '随手拍' title: '部门检查'
}, },
{ {
id: 2, id: 2,
title: '企业自查' title: '都导检查'
}, },
{ {
id: 3, id: 3,
title: '行业互查' title: '企业自查'
}, },
{ {
id: 4, id: 4,
title: '专家诊查' title: '行业互查'
} }
]) ])
@@ -1013,6 +949,43 @@
overflow-y: auto; overflow-y: auto;
} }
// 检查形式横向滚动,露出第 4 项一角提示可滑动
.source-choose-scroll {
width: 100%;
overflow: hidden;
:deep(.up-choose) {
width: 100%;
white-space: nowrap;
}
:deep(.u-tag-wrapper) {
margin-right: 12rpx;
}
:deep(.u-tag) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
box-sizing: border-box;
padding: 0 8rpx !important;
line-height: normal !important;
}
:deep(.u-tag__content) {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
}
:deep(.u-tag__text) {
font-size: 24rpx !important;
line-height: 1.3 !important;
text-align: center;
}
}
.popup-footer { .popup-footer {
display: flex; display: flex;
border-top: 1rpx solid #eee; border-top: 1rpx solid #eee;

View File

@@ -8,9 +8,33 @@
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectifyPlan || '暂无' }}</view> <view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectifyPlan || '暂无' }}</view>
</view> </view>
<view class="margin-top"> <view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">完成情况</view> <view style="color: #999; margin-bottom: 10rpx;">整改措施</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectificationMeasures || '暂无' }}</view>
</view>
<view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">管控措施</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.controlMeasures || '暂无' }}</view>
</view>
<view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">整改完成情况</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectifyResult || '暂无' }}</view> <view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectifyResult || '暂无' }}</view>
</view> </view>
<view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">计划投资资金</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ formatMoney(rectifyData.planCost) }}</view>
</view>
<view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">实际投资资金</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ formatMoney(rectifyData.actualCost) }}</view>
</view>
<view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">整改责任人</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectifierName || '暂无' }}</view>
</view>
<view class="margin-top">
<view style="color: #999; margin-bottom: 10rpx;">完成情况</view>
<view style="word-break: break-all; line-height: 1.6; color: #333;">{{ rectifyData.rectifyStatusName || '暂无' }}</view>
</view>
<view class="margin-top-sm"> <view class="margin-top-sm">
<view>整改附件</view> <view>整改附件</view>
<view class="flex margin-top-xs" style="flex-wrap: wrap; gap: 10rpx;" v-if="rectifyAttachments.length > 0"> <view class="flex margin-top-xs" style="flex-wrap: wrap; gap: 10rpx;" v-if="rectifyAttachments.length > 0">
@@ -84,8 +108,12 @@
import { ref, reactive, watch, nextTick, getCurrentInstance } from 'vue'; import { ref, reactive, watch, nextTick, getCurrentInstance } from 'vue';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { acceptanceRectification, getHiddenDangerDetail } from '@/request/api.js'; import { acceptanceRectification, getHiddenDangerDetail } from '@/request/api.js';
import { baseUrl, getToken, toImageUrl, imageBaseUrl } from '@/request/request.js'; import { toImageUrl } from '@/request/request.js';
import { addTimestampWatermark } from '@/utils/watermark.js'; import {
createUploadListHandlers,
buildAttachmentItem,
uploadToCloud
} from '@/utils/upload.js';
// 页面参数 // 页面参数
const rectifyId = ref(''); const rectifyId = ref('');
@@ -95,9 +123,26 @@
// 整改记录数据 // 整改记录数据
const rectifyData = reactive({ const rectifyData = reactive({
rectifyPlan: '', rectifyPlan: '',
rectifyResult: '' rectificationMeasures: '',
controlMeasures: '',
rectifyResult: '',
planCost: null,
actualCost: null,
rectifierName: '',
rectifyStatusName: ''
}); });
const formatMoney = (value) => {
if (value === null || value === undefined || value === '') {
return '暂无';
}
const num = Number(value);
if (Number.isNaN(num)) {
return '暂无';
}
return `${num.toFixed(2)}`;
};
// 整改附件 // 整改附件
const rectifyAttachments = ref([]); const rectifyAttachments = ref([]);
@@ -148,26 +193,53 @@
}); });
}; };
// 从 assigns 中找到包含整改记录的那一项
const resolveAssignWithRectify = (assigns) => {
if (!assigns?.length) return null;
if (rectifyId.value) {
const byRectifyId = assigns.find(
(item) => item.rectify && String(item.rectify.rectifyId) === String(rectifyId.value)
);
if (byRectifyId) return byRectifyId;
}
if (assignId.value) {
const byAssignId = assigns.find(
(item) => String(item.assignId) === String(assignId.value) && item.rectify
);
if (byAssignId) return byAssignId;
}
return assigns.find((item) => item.rectify) || null;
};
const applyRectifyData = (rectify) => {
if (!rectify) return;
rectifyData.rectifyPlan = rectify.rectifyPlan || '';
rectifyData.rectificationMeasures = rectify.rectificationMeasures || '';
rectifyData.controlMeasures = rectify.controlMeasures || '';
rectifyData.rectifyResult = rectify.rectifyResult || '';
rectifyData.planCost = rectify.planCost ?? null;
rectifyData.actualCost = rectify.actualCost ?? null;
rectifyData.rectifierName = rectify.rectifierName || '';
rectifyData.rectifyStatusName = rectify.rectifyStatusName || '';
rectifyAttachments.value = rectify.attachments || [];
};
// 获取隐患详情 // 获取隐患详情
const fetchDetail = async () => { const fetchDetail = async () => {
if (!hazardId.value || !assignId.value) return; if (!hazardId.value) return;
try { try {
const res = await getHiddenDangerDetail({ hazardId: hazardId.value, assignId: assignId.value }); const res = await getHiddenDangerDetail({
hazardId: hazardId.value,
assignId: assignId.value
});
if (res.code === 0 && res.data) { if (res.code === 0 && res.data) {
// 提取整改信息assigns[0].rectify const assign = resolveAssignWithRectify(res.data.assigns);
if (res.data.assigns && res.data.assigns.length > 0) { if (assign?.rectify) {
const assign = res.data.assigns[0]; applyRectifyData(assign.rectify);
if (assign.rectify) {
rectifyData.rectifyPlan = assign.rectify.rectifyPlan || '';
rectifyData.rectifyResult = assign.rectify.rectifyResult || '';
if (assign.rectify.attachments) {
rectifyAttachments.value = assign.rectify.attachments;
}
console.log('整改记录:', rectifyData); console.log('整改记录:', rectifyData);
console.log('整改附件:', rectifyAttachments.value); console.log('整改附件:', rectifyAttachments.value);
} }
}
} else { } else {
uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' }); uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' });
} }
@@ -177,22 +249,6 @@
} }
}; };
onLoad((options) => {
if (options.rectifyId) {
rectifyId.value = options.rectifyId;
}
if (options.hazardId) {
hazardId.value = options.hazardId;
}
if (options.assignId) {
assignId.value = options.assignId;
}
console.log('验收页面参数:', { rectifyId: rectifyId.value, hazardId: hazardId.value, assignId: assignId.value });
// 获取隐患详情
fetchDetail();
});
// 取消 // 取消
const handleCancel = () => { const handleCancel = () => {
uni.navigateBack(); uni.navigateBack();
@@ -240,25 +296,9 @@
// 真正调取后台接口提交验收 // 真正调取后台接口提交验收
const executeSubmit = async () => { const executeSubmit = async () => {
// 构建附件列表 // 构建附件列表
const attachments = fileList1.value.map(file => { const attachments = fileList1.value
let url = ''; .filter((f) => f.status === 'success')
if (typeof file.url === 'string') { .map((file) => buildAttachmentItem(file));
url = file.url;
} else if (file.url && typeof file.url === 'object') {
url = file.url.url || file.url.path || '';
}
// 将预览绝对路径还原为服务端相对路径,避免后端保存带域名的绝对地址
if (typeof url === 'string' && url.startsWith('http')) {
url = url.replace(imageBaseUrl, '');
}
const fileName = (typeof url === 'string' && url) ? url.split('/').pop() : (file.name || '');
return {
fileName: fileName || '',
filePath: url || '',
fileType: file.type || 'image/png',
fileSize: file.size || 0
};
});
const params = { const params = {
rectifyId: Number(rectifyId.value), rectifyId: Number(rectifyId.value),
@@ -300,91 +340,15 @@
} }
}; };
// 删除图片 const acceptUploadInstance = getCurrentInstance();
const deletePic = (event) => { const { afterRead, deletePic } = createUploadListHandlers(fileList1, {
fileList1.value.splice(event.index, 1); watermark: {
};
// 新增图片
/**
* 在前端为图片进行实时渲染,添加当前系统时间戳水印(防作弊)
* @param {string} tempFilePath 原始选择的图片临时路径
* @returns {Promise<string>} 渲染后的带水印图片临时文件路径
*/
const addWatermark = (tempFilePath) => {
const instance = getCurrentInstance();
return addTimestampWatermark({
tempFilePath,
canvasId: 'watermarkCanvas', canvasId: 'watermarkCanvas',
canvasWidthRef: canvasWidth, canvasWidthRef: canvasWidth,
canvasHeightRef: canvasHeight, canvasHeightRef: canvasHeight,
instance instance: acceptUploadInstance
});
};
// 新增图片(自动加入实时前端水印渲染防作弊功能)
const afterRead = async (event) => {
let lists = [].concat(event.file);
let fileListLen = fileList1.value.length;
lists.map((item) => {
fileList1.value.push({
...item,
status: 'uploading',
message: '处理中...',
});
});
for (let i = 0; i < lists.length; i++) {
try {
// 1. 进行前端实时渲染绘制水印,得到新图片临时路径
const watermarkedUrl = await addWatermark(lists[i].url);
// 2. 将加完水印的新图片进行服务器上传
const result = await uploadFilePromise(watermarkedUrl);
let item = fileList1.value[fileListLen];
fileList1.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
url: toImageUrl(result.url || result.filePath || result),
});
} catch (e) {
console.error('加水印或上传失败:', e);
let item = fileList1.value[fileListLen];
fileList1.value.splice(fileListLen, 1, {
...item,
status: 'failed',
message: '处理失败',
});
}
fileListLen++;
}
};
const uploadFilePromise = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (res) => {
const data = JSON.parse(res.data);
if (data.code === 0) {
resolve(data.data);
} else {
reject(data.msg || '上传失败');
}
},
fail: (err) => {
console.error('上传失败:', err);
reject(err);
} }
}); });
});
};
// 电子签名画布手写线条变动回调 // 电子签名画布手写线条变动回调
const onSignatureChange = () => { const onSignatureChange = () => {
@@ -557,12 +521,11 @@
// 签名导出成功回调 // 签名导出成功回调
const onSignatureConfirm = async (tempFilePath) => { const onSignatureConfirm = async (tempFilePath) => {
try { try {
// 上传签名 const { url } = await uploadToCloud(tempFilePath);
const res = await uploadFilePromise(tempFilePath); signatureServerPath.value = url;
// 兼容后端返回对象或者单纯字符串路径 signatureUrl.value = url;
const path = (res && typeof res === 'object') ? (res.url || res.filePath || '') : (res || ''); showCanvas.value = false;
signatureServerPath.value = path; isSignatureEmpty.value = false;
signatureUrl.value = path.startsWith('http') ? path : (baseUrl.replace('/api', '') + path);
if (isSubmitting.value) { if (isSubmitting.value) {
await executeSubmit(); await executeSubmit();

View File

@@ -10,19 +10,61 @@
<text class="text-blue text-bold" style="cursor: pointer; padding: 0 10rpx; color: #2667E9; font-weight: bold;" @click="clearDraft(true)">清空草稿</text> <text class="text-blue text-bold" style="cursor: pointer; padding: 0 10rpx; color: #2667E9; font-weight: bold;" @click="clearDraft(true)">清空草稿</text>
</view> </view>
<view class="flex margin-bottom"> <view class="flex margin-bottom">
<view class="text-gray">整改人</view> <view class="text-gray">整改责任</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<view class="picker-input" @click="showUserPicker = true"> <view class="select-trigger" @click="openUserPopup">
<text :class="selectedUser ? '' : 'text-gray'">{{ selectedUser || '请选择整改人员' }}</text> <view class="select-content" :class="{ 'text-gray': !selectedUser }">
{{ selectedUser || '请选择整改责任人' }}
</view> </view>
<up-picker <text class="cuIcon-unfold"></text>
:show="showUserPicker" </view>
:columns="userColumns"
@confirm="onUserConfirm" <!-- 整改责任人部门-人员级联单选弹窗 -->
@cancel="showUserPicker = false" <u-popup :show="showUserPopup" mode="bottom" round="20" @close="cancelUserSelect">
@close="showUserPicker = false" <view class="user-popup cascader-user-popup">
></up-picker> <view class="popup-header">
<view class="popup-title text-bold">选择整改责任人</view>
<view class="popup-close" @click="cancelUserSelect">×</view>
</view>
<view v-if="userPickerSelectedId" class="selected-summary">
<text class="summary-label">已选</text>
<text class="summary-text">{{ userPickerSelectedText }}</text>
</view>
<view class="cascader-body">
<scroll-view class="cascader-col dept-col" scroll-y>
<view
v-for="(dept, index) in deptList"
:key="dept.deptId"
:class="['cascader-item', { active: activeDeptIndex === index }]"
@click="activeDeptIndex = index"
>
<text class="cascader-item-text">{{ dept.deptName }}</text>
<text v-if="deptHasSelectedUser(dept)" class="dept-dot"></text>
</view>
</scroll-view>
<scroll-view class="cascader-col user-col" scroll-y :key="'dept-users-' + activeDeptIndex">
<view v-if="currentDeptUsers.length === 0" class="empty-tip">该部门暂无人员</view>
<view v-else>
<view
class="user-item"
v-for="user in currentDeptUsers"
:key="'user-' + user.userId"
:class="{ active: String(userPickerSelectedId) === String(user.userId) }"
@click="onUserItemClick(user.userId)"
>
<text class="user-item-text">{{ formatUserDisplayName(user) }}</text>
<text v-if="String(userPickerSelectedId) === String(user.userId)" class="cuIcon-check text-blue"></text>
</view>
</view>
</scroll-view>
</view>
<view class="popup-footer">
<button class="btn-cancel" @click="cancelUserSelect">取消</button>
<button class="btn-confirm bg-blue" @click="confirmUserSelect">确定</button>
</view>
</view>
</u-popup>
<view class="flex margin-bottom margin-top"> <view class="flex margin-bottom margin-top">
<view class="text-gray">整改期限</view> <view class="text-gray">整改期限</view>
@@ -49,7 +91,7 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, watch, nextTick } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { getDepartmentPersonUsers,assignHiddenDanger } from '@/request/api.js'; import { getDepartmentPersonUsers,assignHiddenDanger } from '@/request/api.js';
@@ -58,11 +100,63 @@
const assignId = ref(''); const assignId = ref('');
// 整改人员选择 // 整改人员选择
const showUserPicker = ref(false); const showUserPopup = ref(false);
const selectedUser = ref(''); const selectedUser = ref('');
const selectedUserId = ref(''); const selectedUserId = ref('');
const userColumns = ref([['暂无数据']]); const deptList = ref([]);
const userList = ref([]); // 存储完整用户数据 const activeDeptIndex = ref(0);
const userPickerSelectedId = ref('');
const formatUserDisplayName = (user) => {
if (user.postName) {
return `${user.nickName}_${user.postName}`;
}
return user.nickName || '';
};
const currentDeptUsers = computed(() => {
const dept = deptList.value[activeDeptIndex.value];
return dept?.users || [];
});
const userPickerSelectedText = computed(() => {
if (!userPickerSelectedId.value) return '';
for (const dept of deptList.value) {
const user = (dept.users || []).find((u) => String(u.userId) === String(userPickerSelectedId.value));
if (user) return formatUserDisplayName(user);
}
return '';
});
const deptHasSelectedUser = (dept) => {
if (!userPickerSelectedId.value || !dept.users?.length) return false;
return dept.users.some((user) => String(user.userId) === String(userPickerSelectedId.value));
};
const onUserItemClick = (userId) => {
userPickerSelectedId.value = String(userId);
};
const openUserPopup = () => {
userPickerSelectedId.value = selectedUserId.value;
const firstDeptWithUsers = deptList.value.findIndex((dept) => dept.users?.length > 0);
activeDeptIndex.value = firstDeptWithUsers >= 0 ? firstDeptWithUsers : 0;
showUserPopup.value = true;
};
const cancelUserSelect = () => {
showUserPopup.value = false;
};
const confirmUserSelect = () => {
if (!userPickerSelectedId.value) {
uni.showToast({ title: '请选择整改责任人', icon: 'none' });
return;
}
selectedUserId.value = String(userPickerSelectedId.value);
selectedUser.value = userPickerSelectedText.value;
showUserPopup.value = false;
};
// 整改期限选择 // 整改期限选择
const showDatePicker = ref(false); const showDatePicker = ref(false);
@@ -74,41 +168,14 @@
try { try {
const res = await getDepartmentPersonUsers(); const res = await getDepartmentPersonUsers();
if (res.code === 0 && res.data) { if (res.code === 0 && res.data) {
const users = []; deptList.value = res.data;
res.data.forEach(dept => { console.log('部门人员树:', deptList.value);
if (dept.users && dept.users.length > 0) {
dept.users.forEach(user => {
users.push({
id: String(user.userId),
name: `${user.nickName}${dept.deptName}`
});
});
}
});
userList.value = users;
// 转换为 picker 需要的格式
userColumns.value = [users.map(u => u.name)];
console.log('整改人员列表:', users);
} }
} catch (error) { } catch (error) {
console.error('获取部门人员失败:', error); console.error('获取部门人员失败:', error);
} }
}; };
// 人员选择确认
const onUserConfirm = (e) => {
console.log('选择的人员:', e);
if (e.value && e.value.length > 0) {
selectedUser.value = e.value[0];
// 找到对应的用户ID
const user = userList.value.find(u => u.name === e.value[0]);
if (user) {
selectedUserId.value = user.id;
}
}
showUserPicker.value = false;
};
// 日期时间选择确认 // 日期时间选择确认
const onDateConfirm = (e) => { const onDateConfirm = (e) => {
console.log('选择的日期时间:', e); console.log('选择的日期时间:', e);
@@ -281,6 +348,194 @@
} }
} }
.select-trigger {
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 20rpx 24rpx;
margin-bottom: 20rpx;
.select-content {
flex: 1;
font-size: 28rpx;
color: #333;
}
}
.user-popup {
background: #fff;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
.popup-title {
font-size: 32rpx;
color: #333;
}
.popup-close {
font-size: 40rpx;
color: #999;
line-height: 1;
}
}
&.cascader-user-popup {
.selected-summary {
padding: 16rpx 30rpx;
background: #f5f7fa;
border-bottom: 1rpx solid #eee;
font-size: 24rpx;
line-height: 1.5;
.summary-label {
color: #909399;
}
.summary-text {
color: #333;
}
}
.cascader-body {
display: flex;
height: 600rpx;
}
.cascader-col {
height: 600rpx;
box-sizing: border-box;
}
.dept-col {
width: 38%;
background: #f7f8fa;
border-right: 1rpx solid #eee;
}
.user-col {
width: 62%;
padding: 10rpx 20rpx;
box-sizing: border-box;
}
.cascader-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 28rpx 24rpx;
font-size: 28rpx;
color: #333;
border-bottom: 1rpx solid #eef0f3;
&.active {
background: #fff;
color: #2667E9;
font-weight: 600;
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 6rpx;
background: #2667E9;
}
}
}
.cascader-item-text {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dept-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: #2667E9;
margin-left: 8rpx;
flex-shrink: 0;
}
.empty-tip {
padding: 80rpx 20rpx;
text-align: center;
color: #909399;
font-size: 26rpx;
}
}
.user-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
&.active {
.user-item-text {
color: #2667E9;
font-weight: 600;
}
}
.user-item-text {
flex: 1;
font-size: 28rpx;
color: #333;
}
}
.popup-footer {
display: flex;
gap: 24rpx;
padding: 24rpx 30rpx;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
background: #fff;
button {
flex: 1;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
font-size: 30rpx;
margin: 0;
padding: 0;
&::after {
border: none;
}
}
.btn-cancel {
background: #fff;
color: #2667E9;
border: 2rpx solid #2667E9;
}
.btn-confirm {
color: #fff;
border: none;
}
}
}
.btn-group { .btn-group {
display: flex; display: flex;
gap: 30rpx; gap: 30rpx;

File diff suppressed because it is too large Load Diff

View File

@@ -1,75 +1,100 @@
<template> <template>
<view class="padding page"> <view class="padding page">
<view class="padding bg-white radius"> <view class="padding bg-white radius">
<view class="flex"> <view class="flex margin-bottom">
<view class="text-gray">隐患图片/视频</view> <view class="text-gray">检查形式</view>
<view class="text-red">*</view>
</view>
<view class="read-only-box">{{ detailData.source || '暂无' }}</view>
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患图片</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<view class="margin-bottom"> <view class="margin-bottom">
<view v-if="detailData.attachments && detailData.attachments.length > 0" class="margin-top"> <view v-if="detailData.attachments && detailData.attachments.length > 0" class="margin-top-xs">
<view class="flex" style="flex-wrap: wrap; gap: 10rpx;"> <view class="flex" style="flex-wrap: wrap; gap: 10rpx;">
<image v-for="(img, idx) in detailData.attachments" :key="idx" :src="getFullPath(img.filePath)" style="width: 136rpx;height: 136rpx;border-radius: 16rpx;" mode="aspectFill" @click="previewHazardImage(idx)"></image> <image
v-for="(img, idx) in detailData.attachments"
:key="idx"
:src="getFullPath(img.filePath)"
style="width: 136rpx;height: 136rpx;border-radius: 16rpx;"
mode="aspectFill"
@click="previewHazardImage(idx)"
></image>
</view> </view>
</view> </view>
<view v-else class="text-gray text-sm">暂无图片</view> <view v-else class="text-gray text-sm">暂无图片</view>
<view class="text-gray text-sm margin-top-xs">必填请上传现场照片或者视频作为隐患证据</view> <view class="text-gray text-sm margin-top-xs">必填请上传现场照片作为隐患证据</view>
</view> </view>
<view class="flex margin-bottom">
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患标题</view> <view class="text-gray">隐患标题</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<up-input v-model="detailData.title" disabled="true" disabledColor="#F6F6F6" border="surround"/> <up-input v-model="detailData.title" disabled disabledColor="#F6F6F6" border="surround" placeholder="暂无" />
<view class="margin-bottom text-gray text-sm margin-top-xs" >请用简洁的语言概括隐患要点</view> <view class="text-sm text-gray margin-top-xs">请用简洁的语言概括隐患要点</view>
<view class="flex margin-bottom">
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患等级</view> <view class="text-gray">隐患等级</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<view class="flex col-3" style="gap: 10rpx;"> <view class="flex col-2" style="gap: 10rpx;">
<view :class="detailData.level === 1 ? 'bg-blue light' : 'bg-gray'" style="padding: 16rpx 40rpx;">轻微隐患</view> <view :class="detailData.level === 2 ? 'bg-blue light' : 'bg-gray'" class="level-item">一般隐患</view>
<view :class="detailData.level === 2 ? 'bg-blue light' : 'bg-gray'" style="padding: 16rpx 40rpx;">一般隐患</view> <view :class="detailData.level === 3 ? 'bg-blue light' : 'bg-gray'" class="level-item">重大隐患</view>
<view :class="detailData.level === 3 ? 'bg-blue light' : 'bg-gray'" style="padding: 16rpx 40rpx;">重大隐患</view>
</view> </view>
<view class="text-gray text-sm margin-top-xs margin-bottom">请用隐患可能造成的危害程度选择等级</view>
<view class="flex"> <view class="flex margin-bottom margin-top">
<view class="text-gray">隐患位置</view> <view class="text-gray">隐患位置</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<view class="address-box margin-top-sm margin-bottom-sm"> <up-input v-model="detailData.address" disabled disabledColor="#F6F6F6" border="surround" placeholder="暂无地址" />
<input <view class="text-gray text-sm margin-top-xs">办公楼3层东侧消防通道生产车间A区设备旁等或点击"选择地址"按钮在地图上选择</view>
class="address-input"
v-model="detailData.address"
placeholder="暂无地址"
disabled
/>
<button class="address-btn bg-blue">选择地址</button>
</view>
<view class="text-gray text-sm">办公楼3层东侧消防通道生产车间A区设备旁等或点击"选择地址"按钮在地图上选择</view>
<!-- 隐患区域 --> <view class="flex margin-bottom margin-top">
<view class="text-gray margin-top margin-bottom">隐患区域</view> <view class="text-gray">法律依据</view>
<view class="bg-gray padding radius">{{ detailData.areaName || '暂无' }}</view> </view>
<view class="read-only-select">
<view class="select-value" :class="{ placeholder: !legalBasisText }">
{{ legalBasisText || '暂无' }}
</view>
</view>
<view class="flex margin-bottom margin-top">
<view class="text-gray">隐患区域</view>
</view>
<view class="read-only-select">
<view class="flex align-center">
<view
v-if="detailData.areaColor"
class="area-color-dot"
:style="{ backgroundColor: detailData.areaColor }"
></view>
<view class="select-value" :class="{ placeholder: !detailData.areaName }">
{{ detailData.areaName || '暂无' }}
</view>
</view>
</view>
<view class="flex margin-bottom margin-top"> <view class="flex margin-bottom margin-top">
<view class="text-gray">隐患描述</view> <view class="text-gray">隐患描述</view>
<view class="text-red">*</view> <view class="text-red">*</view>
</view> </view>
<up-textarea v-model="detailData.description" placeholder="暂无描述" disabled></up-textarea> <up-textarea v-model="detailData.description" placeholder="暂无描述" disabled autoHeight></up-textarea>
<view class="text-gray text-sm margin-top-xs margin-bottom">请详细说明隐患现状潜在风险及影响范围</view> <view class="text-gray text-sm margin-top-xs">请详细说明隐患现状潜在风险及影响范围</view>
<view class="text-gray margin-bottom">隐患来源</view>
<view class="bg-gray padding radius">{{ detailData.source || '暂无' }}</view> <view class="text-gray margin-bottom margin-top">隐患标签</view>
<view class="text-gray margin-top margin-bottom">创建时间</view> <view class="read-only-box">{{ detailData.tagName || '暂无' }}</view>
<view class="bg-gray padding radius">{{ detailData.createdAt || '暂无' }}</view>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, reactive } from 'vue' import { ref, reactive, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { getHiddenDangerDetail } from '@/request/api.js' import { getHiddenDangerDetail } from '@/request/api.js'
import { toImageUrl } from '@/request/request.js' import { toImageUrl } from '@/request/request.js'
// 详情数据
const detailData = reactive({ const detailData = reactive({
hazardId: '', hazardId: '',
assignId: '', assignId: '',
@@ -79,69 +104,47 @@
source: '', source: '',
description: '', description: '',
address: '', address: '',
areaName: '', // 隐患区域名称 areaName: '',
createdAt: '', areaColor: '',
tagName: '',
legalBasis: '',
regulationName: '',
attachments: [] attachments: []
}); })
// 整改附件(单独存储) const legalBasisText = computed(() => detailData.legalBasis || detailData.regulationName || '')
const rectifyAttachments = ref([]);
// 获取完整图片路径 const getFullPath = (filePath) => toImageUrl(filePath)
const getFullPath = (filePath) => {
return toImageUrl(filePath);
};
// 图片预览 - 隐患图片
const previewHazardImage = (index) => { const previewHazardImage = (index) => {
if (!detailData.attachments || detailData.attachments.length === 0) return; if (!detailData.attachments || detailData.attachments.length === 0) return
const urls = detailData.attachments.map(item => getFullPath(item.filePath));
uni.previewImage({ uni.previewImage({
current: index, current: index,
urls: urls urls: detailData.attachments.map(item => getFullPath(item.filePath))
}); })
}; }
// 图片预览 - 整改图片
const previewRectifyImage = (index) => {
const urls = rectifyAttachments.value.map(item => getFullPath(item.filePath));
uni.previewImage({
current: index,
urls: urls
});
};
// 获取隐患详情
const fetchDetail = async (hazardId, assignId) => { const fetchDetail = async (hazardId, assignId) => {
try { try {
const res = await getHiddenDangerDetail({ hazardId, assignId }); const params = { hazardId }
if (assignId) params.assignId = assignId
const res = await getHiddenDangerDetail(params)
if (res.code === 0 && res.data) { if (res.code === 0 && res.data) {
Object.assign(detailData, res.data); Object.assign(detailData, res.data)
console.log('隐患详情数据:', res.data);
console.log('隐患附件:', res.data.attachments);
// 提取整改附件assigns[0].rectify.attachments
if (res.data.assigns && res.data.assigns.length > 0) {
const assign = res.data.assigns[0];
if (assign.rectify && assign.rectify.attachments) {
rectifyAttachments.value = assign.rectify.attachments;
console.log('整改附件:', rectifyAttachments.value);
}
}
} else { } else {
uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' }); uni.showToast({ title: res.msg || '获取详情失败', icon: 'none' })
} }
} catch (error) { } catch (error) {
console.error('获取隐患详情失败:', error); console.error('获取隐患详情失败:', error)
uni.showToast({ title: '请求失败', icon: 'none' }); uni.showToast({ title: '请求失败', icon: 'none' })
}
} }
};
onLoad((options) => { onLoad((options) => {
if (options.hazardId && options.assignId) { if (options.hazardId) {
fetchDetail(options.hazardId, options.assignId); fetchDetail(options.hazardId, options.assignId)
} }
}); })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -150,29 +153,44 @@
background: #EBF2FC; background: #EBF2FC;
} }
.address-box { .read-only-box {
display: flex; background: #f5f5f5;
align-items: center; border-radius: 8rpx;
gap: 20rpx; padding: 20rpx 24rpx;
}
.address-input {
flex: 1;
height: 80rpx;
background: #F6F6F6;
border-radius: 12rpx;
padding: 0 24rpx;
font-size: 28rpx; font-size: 28rpx;
color: #333; color: #333;
} }
.address-btn { .read-only-select {
flex-shrink: 0; background: #f5f5f5;
height: 80rpx; border: 1rpx solid #dcdfe6;
line-height: 80rpx; border-radius: 8rpx;
padding: 0 32rpx; padding: 20rpx 24rpx;
border-radius: 12rpx;
.select-value {
font-size: 28rpx; font-size: 28rpx;
color: #fff; color: #333;
line-height: 1.5;
word-break: break-all;
&.placeholder {
color: #999;
}
}
}
.level-item {
padding: 16rpx 40rpx;
border-radius: 8rpx;
text-align: center;
font-size: 28rpx;
}
.area-color-dot {
width: 24rpx;
height: 24rpx;
border-radius: 50%;
margin-right: 16rpx;
flex-shrink: 0;
} }
</style> </style>

View File

@@ -428,9 +428,11 @@
// 立即整改(待整改状态) // 立即整改(待整改状态)
const goRectification = (item) => { const goRectification = (item) => {
uni.navigateTo({ let url = `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}`
url: `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}` if (item.deadline) {
}) url += `&deadline=${encodeURIComponent(item.deadline)}`
}
uni.navigateTo({ url })
} }
// 编辑整改信息(待验收状态) // 编辑整改信息(待验收状态)

View File

@@ -67,7 +67,8 @@
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted } from 'vue';
import { baseUrl, getToken, toImageUrl } from '@/request/request.js'; import { toImageUrl } from '@/request/request.js';
import { uploadSingleWithLoading } from '@/utils/upload.js';
import { getProfileDetail, updateProfile } from '@/request/three_one_api/info.js'; import { getProfileDetail, updateProfile } from '@/request/three_one_api/info.js';
const saving = ref(false); const saving = ref(false);
@@ -75,7 +76,7 @@ const defaultAvatar = 'https://ossweb-img.qq.com/images/lol/web201310/skin/big81
const avatarPreview = ref(''); // 用于显示选择的图片临时预览 const avatarPreview = ref(''); // 用于显示选择的图片临时预览
const userInfo = reactive({ const userInfo = reactive({
avatar: '', // 保存相对路径,用于提交 avatar: '', // 七牛完整 URL,用于提交
nickName: '', nickName: '',
phonenumber: '', phonenumber: '',
email: '', email: '',
@@ -128,40 +129,20 @@ const chooseAvatar = () => {
}); });
}; };
// 上传头像获取链接 // 上传头像(七牛直传)
const uploadAvatar = (filePath) => { const uploadAvatar = async (filePath) => {
uni.showLoading({ title: '上传中...' });
uni.uploadFile({
url: baseUrl + '/frontend/attachment/upload',
filePath: filePath,
name: 'file',
header: {
'Authorization': getToken()
},
success: (uploadRes) => {
uni.hideLoading();
try { try {
const data = JSON.parse(uploadRes.data); const { url } = await uploadSingleWithLoading(filePath);
if (data.code === 0 && data.data) { userInfo.avatar = url;
// 上传成功,保存相对路径(用于提交) avatarPreview.value = url;
userInfo.avatar = data.data.url || data.data;
uni.showToast({ title: '上传成功', icon: 'success' }); uni.showToast({ title: '上传成功', icon: 'success' });
} else {
avatarPreview.value = ''; // 上传失败,清除预览
uni.showToast({ title: data.msg || '上传失败', icon: 'none' });
}
} catch (e) { } catch (e) {
avatarPreview.value = ''; avatarPreview.value = '';
uni.showToast({ title: '上传失败', icon: 'none' }); uni.showToast({
} title: e?.msg || e?.message || '上传失败',
}, icon: 'none'
fail: () => {
uni.hideLoading();
avatarPreview.value = '';
uni.showToast({ title: '上传失败', icon: 'none' });
}
}); });
}
}; };
// 保存 // 保存
@@ -179,7 +160,7 @@ const handleSave = async () => {
phonenumber: userInfo.phonenumber, phonenumber: userInfo.phonenumber,
email: userInfo.email, email: userInfo.email,
sex: userInfo.sex, sex: userInfo.sex,
avatar: userInfo.avatar // 提交相对路径 avatar: userInfo.avatar
}; };
const res = await updateProfile(params); const res = await updateProfile(params);

View File

@@ -45,7 +45,7 @@ export function assignHiddenDanger(params) {
data: params data: params
}); });
} }
//文件图片上传 //文件图片上传(本地上传,逐步迁移至七牛直传)
export function uploadFile(params) { export function uploadFile(params) {
return requestAPI({ return requestAPI({
url: '/frontend/attachment/upload', url: '/frontend/attachment/upload',
@@ -53,6 +53,16 @@ export function uploadFile(params) {
data: params data: params
}); });
} }
/** 获取七牛云客户端直传凭证 */
export function getQiniuUploadToken(params) {
return requestAPI({
url: '/frontend/attachment/qiniu/token',
method: 'GET',
data: params,
loadingText: false
});
}
//获取我的隐患排查列表 //获取我的隐患排查列表
export function getMyHiddenDangerList(params) { export function getMyHiddenDangerList(params) {
return requestAPI({ return requestAPI({
@@ -184,6 +194,13 @@ export function getMyWriteOffList(params) {
data: params data: params
}); });
} }
//获取销号申请详情
export function getWriteOffApplyDetail(applyId) {
return requestAPI({
url: `/admin/hazard/writeoff/getWriteOffApplyDetail/${applyId}`,
method: 'GET'
});
}
//验收整改 //验收整改
export function acceptanceRectification(params) { export function acceptanceRectification(params) {

View File

@@ -3,7 +3,8 @@ import Request from './luch-request/index.js';
// const baseUrl = 'https://yingji.hexieapi.com/prod-api'; // const baseUrl = 'https://yingji.hexieapi.com/prod-api';
const baseUrl = 'http://192.168.1.168:5004'; const baseUrl = 'http://192.168.1.168:5004'; //廖哥本地
// const baseUrl = 'http://192.168.1.140:5004'; //超哥本地
// 图片/文件资源域名:去掉 /prod-api便于 <image> / previewImage / downloadFile 直接访问 // 图片/文件资源域名:去掉 /prod-api便于 <image> / previewImage / downloadFile 直接访问
const imageBaseUrl = baseUrl.replace(/\/prod-api\/?$/, ''); const imageBaseUrl = baseUrl.replace(/\/prod-api\/?$/, '');

1
unpackage/dist/build/mp-weixin/app.js vendored Normal file
View File

@@ -0,0 +1 @@
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./common/vendor.js"),o=require("./uni_modules/uview-plus/index.js");Math;const t={onLaunch:function(){console.log("App Launch")},onShow:function(){console.log("App Show")},onHide:function(){console.log("App Hide")}};e.index.addInterceptor("chooseImage",{success(o){const t=["bmp","gif","jpg","jpeg","png"],n=[],p=[];let i=!1,s="";o.tempFiles.forEach(((e,c)=>{const u=(e.path||o.tempFilePaths[c]).split("?")[0].split(".").pop().toLowerCase();t.includes(u)?(p.push(e),n.push(o.tempFilePaths[c])):(i=!0,s=u)})),i&&e.index.showToast({title:`已过滤不支持的 .${s} 格式图片,请上传 png/jpg/jpeg/gif/bmp`,icon:"none",duration:3500}),o.tempFilePaths=n,o.tempFiles=p}});const n=["bmp","gif","jpg","jpeg","png","doc","docx","xls","xlsx","ppt","pptx","html","htm","txt","rar","zip","gz","bz2","mp4","avi","rmvb","pdf"],p=["qiniup.com","qbox.me"];function i(o){if(!o)return!0;const t=o.split("?")[0].split(".").pop().toLowerCase();return!!n.includes(t)||(e.index.showToast({title:`不支持 .${t} 格式,请上传合规的文件或图片`,icon:"none",duration:3e3}),!1)}function s(){const n=e.createSSRApp(t);return n.use(o.uviewPlus),{app:n}}e.index.addInterceptor("uploadFile",{invoke(e){const o=e.url||"";return p.some((e=>o.includes(e)))||o.includes("/frontend/attachment/upload"),!!i(e.filePath)&&e}}),s().app.mount("#app"),exports.createApp=s;

80
unpackage/dist/build/mp-weixin/app.json vendored Normal file
View File

@@ -0,0 +1,80 @@
{
"pages": [
"pages/index/index",
"pages/map/map",
"pages/plandetail/plandetail",
"pages/Inspectionresult/Inspectionresult",
"pages/membermanagemen/membermanagemen",
"pages/corporateInformation/corporateInformation",
"pages/editcompanInformation/editcompanInformation",
"pages/checklist/checklist",
"pages/editchecklist/editchecklist",
"pages/Inspectionlog/Inspectionlog",
"pages/Inspectionchecklist/Inspectionchecklist",
"pages/Idphotomanagement/Idphotomanagement",
"pages/hiddendanger/Inspection",
"pages/hiddendanger/view",
"pages/hiddendanger/rectification",
"pages/hiddendanger/acceptance",
"pages/hiddendanger/assignment",
"pages/closeout/application",
"pages/closeout/editor",
"pages/equipmentregistration/equipmentregistration",
"pages/area/management",
"pages/Inspectionwarning/Inspectionwarning",
"pages/personalcenter/my",
"pages/personalcenter/helpcenter",
"pages/personalcenter/notification",
"pages/personalcenter/settings",
"pages/personalcenter/account",
"pages/personalcenter/edit",
"pages/login/login",
"pages/login/reg",
"pages/login/enterprise",
"pages/login/success",
"pages/login/forget",
"pages/login/agreement"
],
"window": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007aff",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color": "#999999",
"selectedColor": "#007aff",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/tabbar_icon/home_icon.png",
"selectedIconPath": "static/tabbar_icon/home_selectedIcon.png"
},
{
"pagePath": "pages/Inspectionwarning/Inspectionwarning",
"text": "预警",
"iconPath": "static/tabbar_icon/yujing_icon.png",
"selectedIconPath": "static/tabbar_icon/yujing_selectedIcon.png"
},
{
"pagePath": "pages/personalcenter/my",
"text": "我的",
"iconPath": "static/tabbar_icon/mine_icon.png",
"selectedIconPath": "static/tabbar_icon/mine_selectedIcon.png"
}
]
},
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于选择隐患位置"
}
},
"requiredPrivateInfos": [
"chooseLocation",
"getLocation"
],
"usingComponents": {}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";exports._imports_0="/static/home_icon/jianbianbeijing.png",exports._imports_0$1="/static/yujin/yujin_sousuo.png",exports._imports_0$2="/static/my/edit.png",exports._imports_0$3="/static/my/Customer service.png",exports._imports_0$4="/static/index/index_bg.png",exports._imports_0$5="/static/index/phone.png",exports._imports_0$6="/static/index/蒙版组 260.png",exports._imports_1="/static/yujin/yujin_tongji.png",exports._imports_1$1="/static/my/Notification.png",exports._imports_1$2="/static/my/Phone.png",exports._imports_1$3="/static/index/lock.png",exports._imports_2="/static/my/Account.png";

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";const e=require("../common/vendor.js"),o={__name:"AreaFormPopup",props:{visible:{type:Boolean,default:!1},isEdit:{type:Boolean,default:!1},editData:{type:Object,default:()=>({})},loading:{type:Boolean,default:!1}},emits:["update:visible","submit","close"],setup(o,{emit:a}){const t=o,l=a,n=e.reactive({name:"",color:"#D92121"}),i=[{name:"红色",value:"#D92121"},{name:"橙色",value:"#FF8822"},{name:"黄色",value:"#FFCC00"},{name:"蓝色",value:"#165DFF"}],r=i.map((e=>e.value)),c=e.computed((()=>{const e=i.find((e=>e.value===n.color));return e?`${e.name} ${e.value}`:n.color}));e.watch((()=>t.editData),(e=>{e&&Object.keys(e).length>0&&(n.name=e.name||"",n.color=(e=>{if(!e)return i[0].value;const o=String(e).toUpperCase();return r.find((e=>e.toUpperCase()===o))||i[0].value})(e.color))}),{immediate:!0,deep:!0}),e.watch((()=>t.visible),(e=>{e||u()}));const u=()=>{n.name="",n.color="#D92121"},s=()=>{l("update:visible",!1),l("close")},m=()=>{n.name?r.includes(n.color)?l("submit",{name:n.name,color:n.color}):e.index.showToast({title:"请从预设颜色中选择",icon:"none"}):e.index.showToast({title:"请输入区域名称",icon:"none"})};return(a,t)=>e.e({a:o.visible},o.visible?{b:e.t(o.isEdit?"编辑区域":"新增区域"),c:e.o(s),d:n.name,e:e.o((e=>n.name=e.detail.value)),f:n.color,g:e.t(c.value),h:e.f(i,((o,a,t)=>({a:n.color===o.value?1:"",b:o.value,c:e.t(o.name),d:o.value,e:e.o((e=>{return a=o.value,void(n.color=a);var a}),o.value)}))),i:e.o(s),j:e.o(m),k:o.loading,l:e.o((()=>{})),m:e.o(s),n:e.gei(a,"")}:{})}},a=e._export_sfc(o,[["__scopeId","data-v-737ed489"]]);wx.createComponent(a);

View File

@@ -0,0 +1 @@
<view wx:if="{{a}}" bindtap="{{m}}" class="{{['popup-mask', 'data-v-737ed489', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{n}}"><view class="popup-content data-v-737ed489" catchtap="{{l}}"><view class="popup-header data-v-737ed489"><view class="popup-title text-bold data-v-737ed489">{{b}}</view><view class="popup-close data-v-737ed489" bindtap="{{c}}">×</view></view><view class="popup-body data-v-737ed489"><view class="flex margin-bottom-sm data-v-737ed489"><view class="data-v-737ed489">区域名称</view><view class="text-red data-v-737ed489">*</view></view><input class="form-input data-v-737ed489" placeholder="请输入区域名称" value="{{d}}" bindinput="{{e}}"/><view class="flex margin-bottom-sm margin-top data-v-737ed489"><view class="data-v-737ed489">区域颜色</view><view class="text-red data-v-737ed489">*</view></view><view class="flex align-center margin-bottom-sm data-v-737ed489"><view class="color-preview data-v-737ed489" style="{{'background-color:' + f}}"></view><text class="margin-left-sm text-gray data-v-737ed489">{{g}}</text></view><view class="margin-bottom-sm text-gray data-v-737ed489">请选择颜色</view><view class="color-grid data-v-737ed489"><view wx:for="{{h}}" wx:for-item="item" wx:key="d" class="color-option data-v-737ed489" bindtap="{{item.e}}"><view class="{{['color-item', 'data-v-737ed489', item.a && 'color-item-active']}}" style="{{'background-color:' + item.b}}"></view><text class="color-label data-v-737ed489">{{item.c}}</text></view></view></view><view class="popup-footer data-v-737ed489"><button class="btn-cancel data-v-737ed489" bindtap="{{i}}">取消</button><button class="btn-confirm bg-blue data-v-737ed489" bindtap="{{j}}" loading="{{k}}">确定</button></view></view></view>

View File

@@ -0,0 +1 @@
.popup-mask.data-v-737ed489{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:999}.popup-content.data-v-737ed489{width:600rpx;background:#fff;border-radius:20rpx;overflow:hidden}.popup-header.data-v-737ed489{display:flex;justify-content:space-between;align-items:center;padding:30rpx;border-bottom:1rpx solid #eee}.popup-title.data-v-737ed489{font-size:32rpx}.popup-close.data-v-737ed489{font-size:40rpx;color:#999}.popup-body.data-v-737ed489{padding:30rpx}.popup-footer.data-v-737ed489{display:flex;padding:20rpx 30rpx 30rpx}.popup-footer button.data-v-737ed489{flex:1;height:80rpx;line-height:80rpx;border-radius:40rpx;font-size:30rpx;margin:0 10rpx}.popup-footer button.data-v-737ed489:after{border:none}.popup-footer .btn-cancel.data-v-737ed489{background:#f5f5f5;color:#666}.popup-footer .btn-confirm.data-v-737ed489{color:#fff}.form-input.data-v-737ed489{width:100%;height:70rpx;padding:0 20rpx;border:2rpx solid #dadbde;border-radius:8rpx;font-size:28rpx;box-sizing:border-box}.color-preview.data-v-737ed489{width:70rpx;height:70rpx;border-radius:8rpx;flex-shrink:0;border:2rpx solid #e5e5e5}.color-grid.data-v-737ed489{display:flex;flex-wrap:wrap;justify-content:space-between;gap:24rpx 0}.color-option.data-v-737ed489{width:25%;display:flex;flex-direction:column;align-items:center}.color-item.data-v-737ed489{width:80rpx;height:80rpx;border-radius:12rpx;border:4rpx solid transparent;box-sizing:border-box}.color-label.data-v-737ed489{margin-top:12rpx;font-size:24rpx;color:#666}.color-item-active.data-v-737ed489{border-color:#333;box-shadow:0 0 0 4rpx rgba(0,0,0,.08)}

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../../../common/vendor.js");Math||o();const o=()=>"../wd-icon/wd-icon.js",n=e.defineComponent({name:"wd-button",options:{addGlobalClass:!0,virtualHost:!0,styleIsolation:"shared"},props:e.buttonProps,emits:["click","getuserinfo","contact","getphonenumber","getrealtimephonenumber","error","launchapp","opensetting","chooseavatar","agreeprivacyauthorization"],setup(o,{emit:n}){const a=o,t=n,i=e.ref(20),s=e.ref(70),r=e.ref(""),c=e.computed((()=>`background-image: url(${r.value});`)),l=e.computed((()=>a.disabled||a.loading?void 0:a.openType));function d(e){a.disabled||a.loading||t("click",e)}function u(e){"phoneNumber"===a.scope?g(e):"userInfo"===a.scope&&p(e)}function p(e){t("getuserinfo",e.detail)}function f(e){t("contact",e.detail)}function g(e){t("getphonenumber",e.detail)}function m(e){t("getrealtimephonenumber",e.detail)}function b(e){t("error",e.detail)}function h(e){t("launchapp",e.detail)}function v(e){t("opensetting",e.detail)}function w(e){t("chooseavatar",e.detail)}function k(e){t("agreeprivacyauthorization",e.detail)}return e.watch((()=>a.loading),(()=>{!function(){const{loadingColor:o,type:n,plain:t}=a;let i=o;if(!i)switch(n){case"primary":i="#4D80F0";break;case"success":i="#34d19d";break;case"info":case"default":i="#333";break;case"warning":i="#f0883a";break;case"error":i="#fa4350"}const s=((e="#4D80F0",o=!0)=>`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 42 42"><defs><linearGradient x1="100%" y1="0%" x2="0%" y2="0%" id="a"><stop stop-color="${o?e:"#fff"}" offset="0%" stop-opacity="0"/><stop stop-color="${o?e:"#fff"}" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M21 1c11.046 0 20 8.954 20 20s-8.954 20-20 20S1 32.046 1 21 9.954 1 21 1zm0 7C13.82 8 8 13.82 8 21s5.82 13 13 13 13-5.82 13-13S28.18 8 21 8z" fill="${o?"#fff":e}"/><path d="M4.599 21c0 9.044 7.332 16.376 16.376 16.376 9.045 0 16.376-7.332 16.376-16.376" stroke="url(#a)" stroke-width="3.5" stroke-linecap="round"/></g></svg>`)(i,!t);r.value=`"data:image/svg+xml;base64,${e.encode(s)}"`}()}),{deep:!0,immediate:!0}),(o,n)=>e.e({a:o.loading},o.loading?{b:e.s(c.value)}:o.icon?{d:e.p({"custom-class":"wd-button__icon",name:o.icon,classPrefix:o.classPrefix})}:{},{c:o.icon,e:e.gei(o,o.buttonId),f:""+(o.disabled||o.loading?"":"wd-button--active"),g:e.s(o.customStyle),h:e.n("is-"+o.type),i:e.n("is-"+o.size),j:e.n(o.round?"is-round":""),k:e.n(o.hairline?"is-hairline":""),l:e.n(o.plain?"is-plain":""),m:e.n(o.disabled?"is-disabled":""),n:e.n(o.block?"is-block":""),o:e.n(o.loading?"is-loading":""),p:e.n(o.customClass),q:i.value,r:s.value,s:l.value,t:o.sendMessageTitle,v:o.sendMessagePath,w:o.sendMessageImg,x:o.appParameter,y:o.showMessageCard,z:o.sessionFrom,A:o.lang,B:o.hoverStopPropagation,C:o.scope,D:e.o(d),E:e.o(u),F:e.o(p),G:e.o(f),H:e.o(g),I:e.o(m),J:e.o(b),K:e.o(h),L:e.o(v),M:e.o(w),N:e.o(k)})}}),a=e._export_sfc(n,[["__scopeId","data-v-161f130c"]]);wx.createComponent(a);

View File

@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"wd-icon": "../wd-icon/wd-icon"
}
}

View File

@@ -0,0 +1 @@
<button id="{{e}}" hover-class="{{f}}" style="{{g + ';' + virtualHostStyle}}" class="{{['data-v-161f130c', 'wd-button', h, i, j, k, l, m, n, o, p, virtualHostClass]}}" hover-start-time="{{q}}" hover-stay-time="{{r}}" open-type="{{s}}" send-message-title="{{t}}" send-message-path="{{v}}" send-message-img="{{w}}" app-parameter="{{x}}" show-message-card="{{y}}" session-from="{{z}}" lang="{{A}}" hover-stop-propagation="{{B}}" scope="{{C}}" bindtap="{{D}}" bindgetAuthorize="{{E}}" bindgetuserinfo="{{F}}" bindcontact="{{G}}" bindgetphonenumber="{{H}}" bindgetrealtimephonenumber="{{I}}" binderror="{{J}}" bindlaunchapp="{{K}}" bindopensetting="{{L}}" bindchooseavatar="{{M}}" bindagreeprivacyauthorization="{{N}}" hidden="{{virtualHostHidden || false}}"><view class="wd-button__content data-v-161f130c"><view wx:if="{{a}}" class="wd-button__loading data-v-161f130c"><view class="wd-button__loading-svg data-v-161f130c" style="{{b}}"></view></view><wd-icon wx:elif="{{c}}" class="data-v-161f130c" virtualHostClass="data-v-161f130c" u-i="161f130c-0" bind:__l="__l" u-p="{{d}}"></wd-icon><view class="wd-button__text data-v-161f130c"><slot/></view></view></button>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../../../common/vendor.js"),o=e.defineComponent({name:"wd-icon",options:{virtualHost:!0,addGlobalClass:!0,styleIsolation:"shared"},props:e.iconProps,emits:["click","touch"],setup(o,{emit:t}){const s=o,c=t,n=e.computed((()=>e.isDef(s.name)&&s.name.includes("/"))),a=e.computed((()=>{const e=s.classPrefix;return`${e} ${s.customClass} ${n.value?"wd-icon--image":e+"-"+s.name}`})),i=e.computed((()=>{const o={};return s.color&&(o.color=s.color),s.size&&(o["font-size"]=e.addUnit(s.size)),`${e.objToStyle(o)} ${s.customStyle}`}));function l(e){c("click",e)}return(o,t)=>e.e({a:n.value},n.value?{b:o.name}:{},{c:e.o(l),d:e.n(a.value),e:e.s(i.value),f:e.gei(o,"")})}}),t=e._export_sfc(o,[["__scopeId","data-v-bef80b7c"]]);wx.createComponent(t);

View File

@@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view bindtap="{{c}}" class="{{['data-v-bef80b7c', d, virtualHostClass]}}" style="{{e + ';' + virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{f}}"><image wx:if="{{a}}" class="wd-icon__image data-v-bef80b7c" src="{{b}}"></image></view>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"wd-button": "../wd-button/wd-button"
}
}

View File

@@ -0,0 +1 @@
<view class="{{['wd-signature', 'data-v-5e53ec40', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{y}}"><view class="wd-signature__content data-v-5e53ec40"><block wx:if="{{r0}}"><canvas class="wd-signature__content-canvas data-v-5e53ec40" style="{{a}}" width="{{b}}" height="{{c}}" canvas-id="{{d}}" id="{{e}}" disable-scroll="{{f}}" bindtouchstart="{{g}}" bindtouchend="{{h}}" bindtouchmove="{{i}}" type="2d"/></block></view><view class="wd-signature__footer data-v-5e53ec40"><block wx:if="{{$slots.footer}}"><slot name="footer"></slot></block><block wx:else><block wx:if="{{j}}"><wd-button wx:if="{{m}}" class="data-v-5e53ec40" virtualHostClass="data-v-5e53ec40" u-s="{{['d']}}" bindclick="{{l}}" u-i="5e53ec40-0" bind:__l="__l" u-p="{{m}}">{{k}}</wd-button><wd-button wx:if="{{p}}" class="data-v-5e53ec40" virtualHostClass="data-v-5e53ec40" u-s="{{['d']}}" bindclick="{{o}}" u-i="5e53ec40-1" bind:__l="__l" u-p="{{p}}">{{n}}</wd-button></block><wd-button wx:if="{{s}}" class="data-v-5e53ec40" virtualHostClass="data-v-5e53ec40" u-s="{{['d']}}" bindclick="{{r}}" u-i="5e53ec40-2" bind:__l="__l" u-p="{{s}}">{{q}}</wd-button><wd-button wx:if="{{w}}" class="data-v-5e53ec40" virtualHostClass="data-v-5e53ec40" u-s="{{['d']}}" bindclick="{{v}}" u-i="5e53ec40-3" bind:__l="__l" u-p="{{w}}">{{t}}</wd-button></block></view></view>

View File

@@ -0,0 +1 @@
.wd-signature__content.data-v-5e53ec40{justify-content:center;align-items:center;display:flex;overflow:hidden;background:var(--wot-signature-bg, var(--wot-color-white, white));border-radius:var(--wot-signature-radius, 4px);border:var(--wot-signature-border, 1px solid var(--wot-color-gray-5, #c8c9cc))}.wd-signature__content-canvas.data-v-5e53ec40{width:100%}.wd-signature__footer.data-v-5e53ec40{margin-top:var(--wot-signature-footer-margin-top, 8px);justify-content:flex-end;display:flex}.wd-signature__footer.data-v-5e53ec40 .wd-button{margin-left:var(--wot-signature-button-margin-left, 8px)}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
{
"navigationBarTitleText": "证件照管理",
"usingComponents": {
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup",
"u-datetime-picker": "../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker",
"u-modal": "../../uni_modules/uview-plus/components/u-modal/u-modal"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.page.data-v-5f64e04d{min-height:100vh;background:#ebf2fc;padding-bottom:120rpx}.license-list.data-v-5f64e04d{padding-bottom:20rpx}.license-item.data-v-5f64e04d{background:#fff;border-radius:16rpx;padding:24rpx;margin-bottom:20rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,.05)}.license-header.data-v-5f64e04d{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx;padding-bottom:16rpx;border-bottom:1rpx solid #f0f0f0}.license-type.data-v-5f64e04d{font-size:32rpx;font-weight:700;color:#333}.license-actions.data-v-5f64e04d{display:flex;gap:20rpx}.action-btn.data-v-5f64e04d{font-size:28rpx;padding:8rpx 16rpx}.license-detail.data-v-5f64e04d{margin-bottom:16rpx}.detail-row.data-v-5f64e04d{display:flex;margin-bottom:12rpx;font-size:28rpx}.detail-row .label.data-v-5f64e04d{color:#999;width:160rpx;flex-shrink:0}.detail-row .value.data-v-5f64e04d{color:#333;flex:1}.license-photo.data-v-5f64e04d{width:200rpx;height:150rpx;border-radius:8rpx;overflow:hidden}.license-photo image.data-v-5f64e04d{width:100%;height:100%}.empty-state.data-v-5f64e04d{padding:200rpx 0;text-align:center}.add-btn.data-v-5f64e04d{position:fixed;bottom:40rpx;left:30rpx;right:30rpx;height:88rpx;line-height:88rpx;border-radius:44rpx;font-size:32rpx}.popup-content.data-v-5f64e04d{width:600rpx;background:#fff;border-radius:20rpx;padding:30rpx}.popup-header.data-v-5f64e04d{display:flex;justify-content:space-between;align-items:center;margin-bottom:30rpx}.popup-title.data-v-5f64e04d{font-size:34rpx;color:#333}.popup-close.data-v-5f64e04d{font-size:48rpx;color:#999;line-height:1}.popup-body.data-v-5f64e04d{max-height:700rpx;overflow-y:auto}.form-item.data-v-5f64e04d{margin-bottom:24rpx}.form-label.data-v-5f64e04d{font-size:28rpx;color:#333;margin-bottom:12rpx}.form-input.data-v-5f64e04d{width:100%;height:80rpx;border:2rpx solid #E5E5E5;border-radius:12rpx;padding:0 24rpx;font-size:28rpx;box-sizing:border-box}.form-select.data-v-5f64e04d{display:flex;align-items:center;line-height:80rpx}.upload-box.data-v-5f64e04d{width:200rpx;height:200rpx;border:2rpx dashed #ccc;border-radius:12rpx;display:flex;align-items:center;justify-content:center;position:relative}.upload-add.data-v-5f64e04d{display:flex;flex-direction:column;align-items:center}.upload-icon.data-v-5f64e04d{font-size:60rpx;color:#999}.upload-text.data-v-5f64e04d{font-size:24rpx;color:#999;margin-top:8rpx}.upload-preview.data-v-5f64e04d{width:100%;height:100%;position:relative}.upload-img.data-v-5f64e04d{width:100%;height:100%;border-radius:12rpx}.upload-delete.data-v-5f64e04d{position:absolute;top:-16rpx;right:-16rpx;width:40rpx;height:40rpx;background:#ff4d4f;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:28rpx}.popup-footer.data-v-5f64e04d{display:flex;justify-content:center;gap:30rpx;margin-top:40rpx}.btn-cancel.data-v-5f64e04d{flex:1;height:80rpx;line-height:80rpx;border:2rpx solid #E5E5E5;border-radius:40rpx;background:#fff;color:#333;font-size:30rpx}.btn-confirm.data-v-5f64e04d{flex:1;height:80rpx;line-height:80rpx;border-radius:40rpx;color:#fff;font-size:30rpx}.dept-popup.data-v-5f64e04d{width:600rpx;background:#fff;border-radius:20rpx;padding:30rpx}.dept-list.data-v-5f64e04d{max-height:400rpx;overflow-y:auto;margin-bottom:30rpx}.dept-item.data-v-5f64e04d{display:flex;align-items:center;padding:24rpx;border:2rpx solid #E5E5E5;border-radius:12rpx;margin-bottom:16rpx}.dept-checkbox.data-v-5f64e04d{width:36rpx;height:36rpx;border:2rpx solid #ccc;border-radius:6rpx;margin-right:20rpx;display:flex;align-items:center;justify-content:center;flex-shrink:0}.dept-checkbox-active.data-v-5f64e04d{background:#2667e9;border-color:#2667e9;color:#fff}.dept-name.data-v-5f64e04d{font-size:28rpx;color:#333}.btn-dept-confirm.data-v-5f64e04d{width:100%;height:80rpx;line-height:80rpx;border-radius:40rpx;color:#fff;font-size:30rpx}

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),r={};const n=e._export_sfc(r,[["render",function(r,n){return{a:e.gei(r,"")}}]]);wx.createPage(n);

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "检查清单",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="{{['padding', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{a}}"><view class="text-bold text-black">检查清单预览</view><view class="flex margin-bottom"><view class="text-gray">计划名称:</view><view>和谐矿业每日巡检</view></view><view class="flex margin-bottom"><view class="text-gray">检查时间:</view><view>2025-11-19 10:18:40</view></view><view class="flex margin-bottom"><view class="text-gray">检查人员:</view><view>18174379303</view></view><image></image><view class="flex margin-bottom"><view>被检查单位:</view><view></view></view><view class="flex margin-bottom"><view>检查人员:</view><view></view></view><view class="flex margin-bottom"><view>上次检查情况:</view><view></view></view><view class="flex margin-bottom"><view>本次检查情况:</view><view></view></view><view class="flex margin-bottom"><view>检查日期:</view><view>2025-11-19 10:18:40</view></view><view class="flex justify-between"><view class="flex text-center align-center"><button class="bg-blue">缩小</button><view>50%</view><button class="bg-blue">放大</button></view><button class="lg cu-btn">重置</button></view></view>

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),c={__name:"Inspectionlog",setup:c=>(c,s)=>({a:e.o((c=>{e.index.navigateTo({url:"/pages/Inspectionchecklist/Inspectionchecklist"})})),b:e.gei(c,"")})},s=e._export_sfc(c,[["__scopeId","data-v-fa142cd8"]]);wx.createPage(s);

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "检查记录",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="{{['page', 'padding', 'data-v-fa142cd8', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{b}}"><view class="padding bg-white radius list data-v-fa142cd8"><view class="text-bold margin-bottom text-black data-v-fa142cd8">和谐矿业每日巡检</view><view class="flex margin-bottom data-v-fa142cd8"><view class="text-gray data-v-fa142cd8">检查时间:</view><view class="data-v-fa142cd8">2025-11-19 10:18:40</view></view><view class="flex margin-bottom data-v-fa142cd8"><view class="text-gray data-v-fa142cd8">检查人员:</view><view class="data-v-fa142cd8">18174379303</view></view><view class="flex margin-bottom data-v-fa142cd8"><view class="text-gray data-v-fa142cd8">隐患数量:</view><view class="data-v-fa142cd8">1</view></view><view class="flex margin-bottom data-v-fa142cd8"><view class="text-gray data-v-fa142cd8">备注:</view><view class="data-v-fa142cd8">可以</view></view><view class="flex justify-between data-v-fa142cd8"><view class="data-v-fa142cd8"></view><button class="bg-blue round cu-btn lg data-v-fa142cd8" bindtap="{{a}}">预览清单</button></view></view></view>

View File

@@ -0,0 +1 @@
.page.data-v-fa142cd8{min-height:100vh;background:#ebf2fc}.list.data-v-fa142cd8{background:#fff;box-shadow:0 2rpx 6rpx 2rpx rgba(0,0,0,.08);border-left:5px solid #2667E9;border-radius:20rpx;padding:20rpx}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
{
"navigationBarTitleText": "检查结果",
"usingComponents": {
"u-radio": "../../uni_modules/uview-plus/components/u-radio/u-radio",
"u-radio-group": "../../uni_modules/uview-plus/components/u-radio-group/u-radio-group",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea",
"up-choose": "../../uni_modules/uview-plus/components/u-choose/u-choose",
"up-upload": "../../uni_modules/uview-plus/components/u-upload/u-upload",
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),t=require("../../common/assets.js"),a=require("../../request/api.js");if(!Array){(e.resolveComponent("up-datetime-picker")+e.resolveComponent("up-input")+e.resolveComponent("u-loadmore"))()}Math||((()=>"../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker.js")+(()=>"../../uni_modules/uview-plus/components/u-input/u-input.js")+(()=>"../../uni_modules/uview-plus/components/u-loadmore/u-loadmore.js"))();const o={__name:"Inspectionwarning",setup(o){const l=e.reactive({startDate:"",endDate:"",deptName:""}),u=e.ref(!1),s=e.ref(!1),n=e.ref(Number(new Date)),r=e.ref(Number(new Date)),d=e.reactive({total:0,overdue:0,pending:0,completed:0,overdueCompleted:0,onTimeCompleted:0});e.reactive({total:0,overdue:0,completed:0,pending:0});const i=e.ref([]),v=e.ref(1),c=e.ref(20),m=e.ref("loadmore"),p=e.ref([{label:"全部状态",value:0,count:null},{label:"逾期未检",value:1,count:null},{label:"严重逾期",value:2,count:null},{label:"期限内待检",value:3,count:null},{label:"逾期已完成",value:4,count:null},{label:"按期已完成",value:5,count:null}]),g=e.ref(0),f=e=>{const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`},D=e=>{const t=f(e.value);l.startDate=t,u.value=!1},h=e=>{const t=f(e.value);l.endDate=t,s.value=!1},N=e=>{if(!e||"按期"===e)return"status-normal";const t=parseInt(e);return t>=7?"status-serious":t>=1?"status-overdue":"status-normal"},b=(e,t)=>{if(!e||"按期"===e)return"已完成"===t?"按期已完成":"期限内待检";const a=parseInt(e);return a>=7?"严重逾期":a>=1?"已完成"===t?"逾期已完成":"逾期未检":"期限内待检"},w=async()=>{try{const e={pageNum:v.value,pageSize:c.value};l.startDate&&(e.startDate=l.startDate),l.endDate&&(e.endDate=l.endDate),l.deptName&&l.deptName.trim()&&(e.deptName=l.deptName.trim());const t=p.value[g.value].value;0!==t&&(e.inspectionStatus=t);const o=await a.getInspectionWarningList(e);if(0===o.code)if(o.data.statistics&&(d.total=o.data.statistics.total||0,d.overdue=o.data.statistics.overdue||0,d.pending=o.data.statistics.pending||0,d.completed=o.data.statistics.completed||0,d.overdueCompleted=o.data.statistics.overdueCompleted||0,d.onTimeCompleted=o.data.statistics.onTimeCompleted||0,p.value[0].count=o.data.statistics.total||0,p.value[1].count=o.data.statistics.overdue||0,p.value[2].count=o.data.statistics.pending||0,p.value[3].count=o.data.statistics.completed||0,p.value[4].count=o.data.statistics.overdueCompleted||0,p.value[5].count=o.data.statistics.onTimeCompleted||0),o.data.page&&o.data.page.records){const e=o.data.page.records;1===v.value?i.value=e:i.value=[...i.value,...e];const t=o.data.page.total||0;i.value.length>=t?m.value="nomore":m.value="loadmore"}else m.value="nomore"}catch(e){console.error("获取预警列表失败:",e)}},C=()=>{v.value=1,i.value=[],w()};return e.onReachBottom((()=>{"loadmore"===m.value&&(v.value++,w())})),e.onShow((()=>{w()})),(a,o)=>e.e({a:t._imports_0$1,b:e.t(l.startDate||"请选择"),c:e.n(l.startDate?"date-value":"date-placeholder"),d:e.o((e=>u.value=!0)),e:e.o(D),f:e.o((e=>u.value=!1)),g:e.o((e=>u.value=!1)),h:e.o((e=>n.value=e)),i:e.p({show:u.value,mode:"date",modelValue:n.value}),j:e.t(l.endDate||"请选择"),k:e.n(l.endDate?"date-value":"date-placeholder"),l:e.o((e=>s.value=!0)),m:e.o(h),n:e.o((e=>s.value=!1)),o:e.o((e=>s.value=!1)),p:e.o((e=>r.value=e)),q:e.p({show:s.value,mode:"date",modelValue:r.value}),r:e.o((e=>l.deptName=e)),s:e.p({placeholder:"请输入公司名称",border:"surround",modelValue:l.deptName}),t:e.o(C),v:t._imports_1,w:e.t(d.total),x:e.t(d.overdue),y:e.t(d.onTimeCompleted),z:e.t(d.completed),A:e.f(p.value,((t,a,o)=>e.e({a:e.t(t.label),b:e.t(null!=t.count?t.count:""),c:g.value===a},(g.value,{}),{d:a,e:g.value===a?1:"",f:e.o((e=>(e=>{g.value=e,v.value=1,i.value=[],w()})(a)),a)}))),B:e.f(i.value,((t,a,o)=>({a:e.t(t.deptName||"-"),b:e.t(b(t.overdueDays,t.statusName)),c:e.n(N(t.overdueDays)),d:e.t(t.planName||"-"),e:e.t(t.cycleName||"-"),f:e.t(t.taskDate||"-"),g:e.t(t.finishTime||"未完成"),h:e.t(t.executorName||"-"),i:e.t(t.overdueDays||"-"),j:t.id}))),C:i.value.length>0},i.value.length>0?{D:e.p({status:m.value})}:{},{E:0===i.value.length},(i.value.length,{}),{F:e.gei(a,"")})}},l=e._export_sfc(o,[["__scopeId","data-v-b713017f"]]);wx.createPage(l);

View File

@@ -0,0 +1,8 @@
{
"navigationBarTitleText": "日常安全检查预警",
"usingComponents": {
"up-datetime-picker": "../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker",
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"u-loadmore": "../../uni_modules/uview-plus/components/u-loadmore/u-loadmore"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.page.data-v-b713017f{min-height:100vh;background:#ebf2fc;padding-bottom:40rpx}.section-header.data-v-b713017f{display:flex;align-items:center}.section-header .section-icon.data-v-b713017f{width:40rpx;height:40rpx;margin-right:12rpx}.search-card .date-row.data-v-b713017f{display:flex;gap:20rpx}.search-card .date-row .date-item.data-v-b713017f{flex:1}.search-card .date-label.data-v-b713017f{font-size:28rpx;color:#333;margin-bottom:12rpx}.search-card .date-picker.data-v-b713017f{display:flex;align-items:center;justify-content:space-between;height:72rpx;padding:0 20rpx;background:#f8f8f8;border-radius:8rpx;border:1rpx solid #eee}.search-card .date-picker .date-value.data-v-b713017f{color:#333;font-size:28rpx}.search-card .date-picker .date-placeholder.data-v-b713017f{color:#999;font-size:28rpx}.search-card .search-btn.data-v-b713017f{margin-top:30rpx;background:linear-gradient(135deg,#667eea,#2667e9);color:#fff;border-radius:40rpx;height:80rpx;line-height:80rpx;font-size:30rpx}.stat-grid.data-v-b713017f{display:flex;justify-content:space-between;gap:16rpx}.stat-grid .stat-item.data-v-b713017f{flex:1;height:124rpx;border-radius:12rpx;color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center}.stat-grid .stat-item .stat-num.data-v-b713017f{font-size:40rpx;font-weight:700}.stat-grid .stat-item .stat-label.data-v-b713017f{font-size:24rpx;margin-top:8rpx}.stat-grid .stat-total.data-v-b713017f{background:linear-gradient(135deg,#628efb,#4a7cf7)}.stat-grid .stat-overdue.data-v-b713017f{background:linear-gradient(135deg,#32dcc7,#20c5b0)}.stat-grid .stat-completed.data-v-b713017f{background:linear-gradient(135deg,#32d1e9,#20b8d0)}.stat-grid .stat-pending.data-v-b713017f{background:linear-gradient(135deg,#a190f5,#8b78e8)}.list-title-bar.data-v-b713017f{width:8rpx;height:32rpx;background:#2667e9;border-radius:4rpx;margin-right:12rpx}.list-card.data-v-b713017f{background:#fff;box-shadow:0 2rpx 10rpx rgba(0,0,0,.08);border-radius:16rpx;padding:0;margin-bottom:20rpx;overflow:hidden}.list-card .card-title-row.data-v-b713017f{display:flex;justify-content:space-between;align-items:center;background:linear-gradient(135deg,#4a7cf7,#2667e9);padding:24rpx 30rpx}.list-card .card-company-name.data-v-b713017f{font-size:32rpx;font-weight:700;color:#fff;flex:1;margin-right:16rpx}.list-card .card-status-tag.data-v-b713017f{padding:8rpx 24rpx;border-radius:8rpx;white-space:nowrap;flex-shrink:0;font-size:24rpx;color:#fff;font-weight:500}.list-card .card-body.data-v-b713017f{padding:30rpx}.list-card .card-row.data-v-b713017f{display:flex;margin-top:16rpx;font-size:28rpx;line-height:1.5}.list-card .card-row.data-v-b713017f:first-of-type{margin-top:0}.list-card .card-row .row-label.data-v-b713017f{color:#999;white-space:nowrap;flex-shrink:0}.list-card .card-row .row-value.data-v-b713017f{color:#333;word-break:break-all}.status-serious.data-v-b713017f{background:linear-gradient(135deg,#ff6b6b,#ee5a5a)}.status-overdue.data-v-b713017f{background:linear-gradient(135deg,#ffa726,#ff9800)}.status-normal.data-v-b713017f{background:linear-gradient(135deg,#66bb6a,#4caf50)}.status-completed.data-v-b713017f{background:linear-gradient(135deg,#42a5f5,#2196f3)}.empty-tip.data-v-b713017f{text-align:center;padding:100rpx 0;color:#999;font-size:28rpx}.status-tabs.data-v-b713017f{white-space:nowrap;background:#fff;border-radius:16rpx;margin-bottom:20rpx;padding:0 10rpx}.status-tabs-inner.data-v-b713017f{display:inline-flex;align-items:center;height:88rpx;white-space:nowrap}.status-tab-item.data-v-b713017f{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;padding:0 24rpx;height:88rpx;position:relative}.status-tab-text.data-v-b713017f{font-size:26rpx;color:#666}.status-tab-active .status-tab-text.data-v-b713017f{color:#2667e9;font-weight:700}.status-tab-bar.data-v-b713017f{position:absolute;bottom:8rpx;width:40rpx;height:6rpx;background:#2667e9;border-radius:3rpx}

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),a=require("../../request/three_one_api/area.js");Math||o();const o=()=>"../../components/AreaFormPopup.js",t={__name:"management",setup(o){const t=e.ref([]),l=e.ref(!1),n=e.ref(!1),c=e.ref(null),r=e.ref(!1),s=e.ref({});e.onMounted((()=>{i()}));const i=async()=>{try{const e=await a.getAreaList();0===e.code&&(t.value=e.data.records||[])}catch(e){console.error("获取区域列表失败:",e)}},u=()=>{n.value=!1,c.value=null,s.value={},l.value=!0},d=()=>{n.value=!1,c.value=null,s.value={}},v=async o=>{r.value=!0;try{const t={name:o.name,color:o.color};let s;n.value?(t.id=c.value,s=await a.updateArea(t)):s=await a.addArea(t),0===s.code&&(l.value=!1,e.index.showToast({title:n.value?"修改成功":"新增成功",icon:"success"}),i())}catch(t){console.error("提交失败:",t),e.index.showToast({title:"操作失败",icon:"none"})}finally{r.value=!1}};return(o,h)=>e.e({a:t.value.length>0},t.value.length>0?{b:e.f(t.value,((o,t,r)=>({a:e.t(o.name||"区域名称"),b:o.color,c:e.t(o.color),d:e.o((t=>(async o=>{try{const e=await a.getAreaDetail({id:o.id});0===e.code&&(n.value=!0,c.value=o.id,s.value={name:e.data.name||"",color:e.data.color||"#D92121"},l.value=!0)}catch(t){console.error("获取区域详情失败:",t),e.index.showToast({title:"获取详情失败",icon:"none"})}})(o)),o.id),e:e.o((t=>(o=>{e.index.showModal({title:"确认删除",content:"确定要删除该区域吗?",confirmColor:"#e54d42",success:async t=>{if(t.confirm)try{0===(await a.deleteArea({id:o.id})).code&&(e.index.showToast({title:"删除成功",icon:"success"}),i())}catch(l){console.error("删除失败:",l),e.index.showToast({title:"删除失败",icon:"none"})}}})})(o)),o.id),f:o.id})))}:{},{c:e.o(u),d:e.o(v),e:e.o(d),f:e.o((e=>l.value=e)),g:e.p({isEdit:n.value,editData:s.value,loading:r.value,visible:l.value}),h:e.gei(o,"")})}},l=e._export_sfc(t,[["__scopeId","data-v-6ce07390"]]);wx.createPage(l);

View File

@@ -0,0 +1,6 @@
{
"navigationBarTitleText": "区域管理",
"usingComponents": {
"area-form-popup": "../../components/AreaFormPopup"
}
}

View File

@@ -0,0 +1 @@
<view class="{{['padding', 'page', 'data-v-6ce07390', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{h}}"><view wx:if="{{a}}" class="area-list data-v-6ce07390"><view wx:for="{{b}}" wx:for-item="item" wx:key="f" class="padding bg-white radius margin-bottom data-v-6ce07390"><view class="flex justify-between data-v-6ce07390"><view class="data-v-6ce07390"><view class="text-bold text-black data-v-6ce07390">{{item.a}}</view><view class="margin-top flex align-center data-v-6ce07390"><text class="data-v-6ce07390">颜色:</text><view class="color-dot data-v-6ce07390" style="{{'background-color:' + item.b}}"></view><text class="margin-left-xs data-v-6ce07390">{{item.c}}</text></view></view><view class="data-v-6ce07390"><button class="bg-blue cu-btn data-v-6ce07390" bindtap="{{item.d}}">编辑</button><button class="bg-red cu-btn margin-left data-v-6ce07390" bindtap="{{item.e}}">删除</button></view></view></view></view><view wx:else class="empty-state data-v-6ce07390"><text class="text-gray data-v-6ce07390">暂无区域数据</text></view><button class="add-btn bg-blue round data-v-6ce07390" bindtap="{{c}}">新增公司区域</button><area-form-popup wx:if="{{g}}" class="data-v-6ce07390" virtualHostClass="data-v-6ce07390" bindsubmit="{{d}}" bindclose="{{e}}" u-i="6ce07390-0" bind:__l="__l" bindupdateVisible="{{f}}" u-p="{{g}}"/></view>

View File

@@ -0,0 +1 @@
.page.data-v-6ce07390{min-height:100vh;background:#ebf2fc;padding-bottom:120rpx}.area-list.data-v-6ce07390{padding-bottom:20rpx}.empty-state.data-v-6ce07390{padding:200rpx 0;text-align:center}.add-btn.data-v-6ce07390{position:fixed;bottom:40rpx;left:30rpx;right:30rpx;height:88rpx;line-height:88rpx;border-radius:44rpx;font-size:32rpx}.color-dot.data-v-6ce07390{width:30rpx;height:30rpx;border-radius:6rpx;flex-shrink:0;margin-left:10rpx}

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),a=require("../../request/api.js"),t={__name:"checklist",setup(t){const c=e.ref([]),r=()=>{e.index.navigateTo({url:"/pages/editchecklist/editchecklist"})};return e.onShow((()=>{(async()=>{try{const e=await a.getCheckTableList({pageNum:1,pageSize:100});0===e.code&&(c.value=e.data.records||[])}catch(e){console.error("获取检查表列表失败:",e)}})()})),(a,t)=>e.e({a:e.f(c.value,((a,t,c)=>({a:e.t(a.name),b:a.id}))),b:0===c.value.length},(c.value.length,{}),{c:e.o(r),d:e.gei(a,"")})}},c=e._export_sfc(t,[["__scopeId","data-v-e435212a"]]);wx.createPage(c);

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "检查表",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="{{['page', 'padding', 'data-v-e435212a', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{d}}"><view wx:for="{{a}}" wx:for-item="item" wx:key="b" class="checklist-card data-v-e435212a"><view class="card-name data-v-e435212a">{{item.a}}</view></view><view wx:if="{{b}}" class="empty-tip data-v-e435212a"><text class="data-v-e435212a">暂无检查表</text></view><button class="add-btn data-v-e435212a" bindtap="{{c}}"><text class="data-v-e435212a">新增检查表</text></button></view>

View File

@@ -0,0 +1 @@
.page.data-v-e435212a{min-height:100vh;background:#ebf2fc;padding-bottom:120rpx}.checklist-card.data-v-e435212a{background:#fff;border-radius:16rpx;padding:30rpx;margin-bottom:20rpx;box-shadow:0 2rpx 10rpx rgba(0,0,0,.05)}.checklist-card .card-name.data-v-e435212a{font-size:32rpx;color:#333;font-weight:500}.empty-tip.data-v-e435212a{text-align:center;padding:100rpx 0;color:#999;font-size:28rpx}.add-btn.data-v-e435212a{position:fixed;bottom:40rpx;left:30rpx;right:30rpx;height:90rpx;background:linear-gradient(135deg,#667eea,#2668ea);border-radius:45rpx;color:#fff;font-size:32rpx;display:flex;align-items:center;justify-content:center;box-shadow:0 8rpx 20rpx rgba(102,126,234,.4)}.add-btn .cuIcon-add.data-v-e435212a{margin-right:10rpx;font-size:36rpx}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
{
"navigationBarTitleText": "销号申请",
"usingComponents": {
"up-picker": "../../uni_modules/uview-plus/components/u-picker/u-picker",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea",
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup"
}
}

View File

@@ -0,0 +1 @@
<view class="{{['padding', 'page', 'data-v-310af818', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{K}}"><view wx:for="{{a}}" wx:for-item="item" wx:key="i" class="padding bg-white radius margin-bottom card-item data-v-310af818"><view class="flex justify-between margin-bottom data-v-310af818"><view class="text-bold text-black data-v-310af818" style="flex:1;margin-right:16rpx">{{item.a}}</view><view class="{{['status-tag', 'data-v-310af818', item.c]}}">{{item.b}}</view></view><view class="flex margin-bottom data-v-310af818"><view class="text-gray data-v-310af818">隐患日期:</view><view class="text-black data-v-310af818">{{item.d}}</view></view><view class="flex margin-bottom data-v-310af818"><view class="text-gray data-v-310af818">责任单位:</view><view class="text-black data-v-310af818">{{item.e}}</view></view><view class="flex margin-bottom data-v-310af818"><view class="text-gray data-v-310af818">判定人员:</view><view class="text-black data-v-310af818">{{item.f}}</view></view><view class="flex margin-bottom data-v-310af818"><view class="text-gray data-v-310af818">创建时间:</view><view class="text-black data-v-310af818">{{item.g}}</view></view><view class="flex justify-between data-v-310af818"><view class="data-v-310af818"></view><view class="data-v-310af818"><button class="bg-blue round cu-btn lg data-v-310af818" bindtap="{{item.h}}">查看详情</button></view></view></view><button class="cuIcon-add bg-blue round margin-top data-v-310af818" bindtap="{{b}}">新增</button><u-popup wx:if="{{F}}" class="data-v-310af818" virtualHostClass="data-v-310af818" u-s="{{['d']}}" bindclose="{{E}}" u-i="310af818-0" bind:__l="__l" u-p="{{F}}"><view class="popup-content data-v-310af818"><view class="popup-header data-v-310af818"><view class="popup-title text-bold data-v-310af818">新增销号申请</view><view class="popup-close data-v-310af818" bindtap="{{c}}">×</view></view><scroll-view class="popup-body data-v-310af818" scroll-y style="{{'height:' + '60vh'}}"><view class="flex margin-bottom data-v-310af818"><view class="data-v-310af818">隐患</view><view class="text-red data-v-310af818">*</view></view><view class="picker-input data-v-310af818" bindtap="{{f}}"><text class="{{['data-v-310af818', e]}}">{{d}}</text></view><up-picker wx:if="{{false}}" class="data-v-310af818" virtualHostClass="data-v-310af818" bindconfirm="{{g}}" bindcancel="{{h}}" bindclose="{{i}}" u-i="310af818-1,310af818-0" bind:__l="__l" u-p="{{j}}"></up-picker><view class="flex margin-bottom margin-top data-v-310af818"><view class="data-v-310af818">整改时限</view></view><view class="picker-input readonly data-v-310af818"><text class="{{['data-v-310af818', l]}}">{{k}}</text></view><view class="margin-bottom margin-top data-v-310af818">隐患治理责任单位</view><view class="picker-input readonly data-v-310af818"><text class="{{['data-v-310af818', n]}}">{{m}}</text></view><view class="margin-bottom margin-top data-v-310af818">主要负责人</view><view class="picker-input readonly data-v-310af818"><text class="{{['data-v-310af818', p]}}">{{o}}</text></view><view class="ai-btn-wrapper margin-top margin-bottom data-v-310af818"><button class="ai-analyze-btn data-v-310af818" loading="{{s}}" disabled="{{t}}" bindtap="{{v}}"><text wx:if="{{q}}" class="cuIcon-magic ai-btn-icon data-v-310af818"></text> {{r}}</button></view><view class="margin-bottom margin-top data-v-310af818">主要治理内容</view><up-textarea wx:if="{{x}}" class="data-v-310af818" virtualHostClass="data-v-310af818" u-i="310af818-2,310af818-0" bind:__l="__l" bindupdateModelValue="{{w}}" u-p="{{x}}"></up-textarea><view class="margin-bottom margin-top data-v-310af818">隐患治理完成内容</view><up-textarea wx:if="{{z}}" class="data-v-310af818" virtualHostClass="data-v-310af818" u-i="310af818-3,310af818-0" bind:__l="__l" bindupdateModelValue="{{y}}" u-p="{{z}}"></up-textarea><view class="margin-bottom margin-top data-v-310af818">隐患治理责任单位自行验收的情况</view><up-textarea wx:if="{{B}}" class="data-v-310af818" virtualHostClass="data-v-310af818" u-i="310af818-4,310af818-0" bind:__l="__l" bindupdateModelValue="{{A}}" u-p="{{B}}"></up-textarea></scroll-view><view class="popup-footer data-v-310af818"><button class="btn-cancel data-v-310af818" bindtap="{{C}}">取消</button><button class="btn-confirm bg-blue data-v-310af818" bindtap="{{D}}">确定</button></view></view></u-popup><up-picker wx:if="{{J}}" class="data-v-310af818" virtualHostClass="data-v-310af818" bindconfirm="{{G}}" bindcancel="{{H}}" bindclose="{{I}}" u-i="310af818-5" bind:__l="__l" u-p="{{J}}"></up-picker></view>

View File

@@ -0,0 +1 @@
.page.data-v-310af818{min-height:100vh;background:#ebf2fc}.status-tag.data-v-310af818{padding:4rpx 16rpx;border-radius:6rpx;font-size:22rpx;white-space:nowrap;flex-shrink:0;font-weight:500;height:40rpx;line-height:40rpx;align-self:flex-start}.status-pending.data-v-310af818{background:#fff7e6;color:#fa8c16}.status-passed.data-v-310af818{background:#f6ffed;color:#52c41a}.status-rejected.data-v-310af818{background:#fff1f0;color:#f5222d}.status-reapply.data-v-310af818{background:#e6f7ff;color:#1890ff}.status-default.data-v-310af818{background:#f5f5f5;color:#8c8c8c}.popup-content.data-v-310af818{width:600rpx;background:#fff;border-radius:20rpx;overflow:hidden}.popup-header.data-v-310af818{display:flex;justify-content:space-between;align-items:center;padding:30rpx;border-bottom:1rpx solid #eee}.popup-header .popup-title.data-v-310af818{font-size:32rpx;color:#333}.popup-header .popup-close.data-v-310af818{font-size:40rpx;color:#999;line-height:1}.popup-body.data-v-310af818{padding:30rpx}.popup-footer.data-v-310af818{display:flex;border-top:1rpx solid #eee}.popup-footer button.data-v-310af818{flex:1;height:90rpx;line-height:90rpx;border-radius:0;margin:0!important;padding:0!important;font-size:30rpx}.popup-footer button.data-v-310af818:after{border:none}.popup-footer .btn-cancel.data-v-310af818{background:#fff;color:#666}.popup-footer .btn-confirm.data-v-310af818{color:#fff}.ai-btn-wrapper.data-v-310af818{display:flex;justify-content:flex-end}.ai-analyze-btn.data-v-310af818{display:flex;align-items:center;justify-content:center;height:72rpx;padding:0 32rpx;font-size:28rpx;color:#fff;background:linear-gradient(135deg,#4facfe,#2668ea);border-radius:36rpx;border:none}.ai-analyze-btn.data-v-310af818:after{border:none}.ai-analyze-btn .ai-btn-icon.data-v-310af818{margin-right:8rpx;font-size:30rpx}.ai-analyze-btn[disabled].data-v-310af818{opacity:.7}.picker-input.data-v-310af818{background:#fff;border-radius:8rpx;padding:24rpx 20rpx;margin-bottom:20rpx;border:1rpx solid #eee}.picker-input text.data-v-310af818{font-size:28rpx}.picker-input.readonly.data-v-310af818{background:#f5f5f5;color:#666}

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),a=require("../../request/api.js"),n=require("../../utils/upload.js");if(!Array){(e.resolveComponent("up-input")+e.resolveComponent("up-textarea"))()}Math||((()=>"../../uni_modules/uview-plus/components/u-input/u-input.js")+(()=>"../../uni_modules/uview-plus/components/u-textarea/u-textarea.js"))();const o={__name:"editor",setup(o){const t=e.ref(""),l=e.ref(""),i=e.reactive({hazardId:"",hazardName:"",deadline:"",responsibilityUnit:"",mainPerson:"",mainGovernanceContent:"",governanceCompleteContent:"",status:"",rejectReason:""}),r=e.computed((()=>{const e=Number(i.status);return 1===e?"通过":2===e?"不通过":""})),d=e.computed((()=>Boolean(String(i.rejectReason||"").trim()))),s=e.computed((()=>Boolean(l.value))),u=()=>{l.value&&e.index.previewImage({urls:[l.value],current:l.value})},c=()=>{console.error("签名图片加载失败:",l.value)},p=async o=>{var t;if(o)try{e.index.showLoading({title:"加载中..."});const r=await a.getWriteOffApplyDetail(o);if(0===r.code&&r.data){const e=r.data;i.hazardId=e.hazardId||"",i.hazardName=e.hazardName||"",i.deadline=e.deadline||"",i.responsibilityUnit=e.responsibilityUnit||"",i.mainPerson=e.mainPerson||"",i.mainGovernanceContent=e.mainGovernanceContent||"",i.governanceCompleteContent=e.governanceCompleteContent||"",i.status=e.status??"",i.rejectReason=e.rejectReason||"",t=e.signPath,l.value=t?n.toSubmitFileUrl(t):""}else e.index.showToast({title:r.msg||"获取详情失败",icon:"none"})}catch(r){console.error("获取销号申请详情失败:",r),e.index.showToast({title:"获取详情失败",icon:"none"})}finally{e.index.hideLoading()}else e.index.showToast({title:"缺少申请ID",icon:"none"})},m=()=>{e.index.navigateBack()};return e.onLoad((e=>{t.value=(null==e?void 0:e.applyId)||"",p(t.value)})),(a,n)=>e.e({a:e.o((e=>i.hazardName=e)),b:e.p({placeholder:"暂无",disabled:!0,modelValue:i.hazardName}),c:e.o((e=>i.deadline=e)),d:e.p({placeholder:"暂无",disabled:!0,modelValue:i.deadline}),e:e.o((e=>i.responsibilityUnit=e)),f:e.p({placeholder:"暂无",disabled:!0,modelValue:i.responsibilityUnit}),g:e.o((e=>i.mainPerson=e)),h:e.p({placeholder:"暂无",disabled:!0,modelValue:i.mainPerson}),i:e.o((e=>i.mainGovernanceContent=e)),j:e.p({placeholder:"暂无",disabled:!0,autoHeight:!0,modelValue:i.mainGovernanceContent}),k:e.o((e=>i.governanceCompleteContent=e)),l:e.p({placeholder:"暂无",disabled:!0,autoHeight:!0,modelValue:i.governanceCompleteContent}),m:e.p({modelValue:r.value,placeholder:"暂无",disabled:!0}),n:d.value},d.value?{o:e.o((e=>i.rejectReason=e)),p:e.p({placeholder:"暂无",disabled:!0,autoHeight:!0,modelValue:i.rejectReason})}:{},{q:s.value},s.value?{r:l.value,s:e.o(u),t:e.o(c)}:{},{v:e.o(m),w:e.gei(a,"")})}},t=e._export_sfc(o,[["__scopeId","data-v-4709c0fa"]]);wx.createPage(t);

View File

@@ -0,0 +1,7 @@
{
"navigationBarTitleText": "销号详情",
"usingComponents": {
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea"
}
}

View File

@@ -0,0 +1 @@
<view class="{{['padding', 'page', 'data-v-4709c0fa', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{w}}"><view class="padding bg-white radius data-v-4709c0fa"><view class="text-gray margin-bottom data-v-4709c0fa">隐患名称</view><up-input wx:if="{{b}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-0" bind:__l="__l" bindupdateModelValue="{{a}}" u-p="{{b}}"></up-input><view class="text-gray margin-bottom margin-top data-v-4709c0fa">整改时限</view><up-input wx:if="{{d}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-1" bind:__l="__l" bindupdateModelValue="{{c}}" u-p="{{d}}"></up-input><view class="text-gray margin-bottom margin-top data-v-4709c0fa">隐患治理责任单位</view><up-input wx:if="{{f}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-2" bind:__l="__l" bindupdateModelValue="{{e}}" u-p="{{f}}"></up-input><view class="text-gray margin-bottom margin-top data-v-4709c0fa">主要负责人</view><up-input wx:if="{{h}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-3" bind:__l="__l" bindupdateModelValue="{{g}}" u-p="{{h}}"></up-input><view class="text-gray margin-bottom margin-top data-v-4709c0fa">主要治理内容</view><up-textarea wx:if="{{j}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-4" bind:__l="__l" bindupdateModelValue="{{i}}" u-p="{{j}}"></up-textarea><view class="text-gray margin-bottom margin-top data-v-4709c0fa">隐患治理完成内容</view><up-textarea wx:if="{{l}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-5" bind:__l="__l" bindupdateModelValue="{{k}}" u-p="{{l}}"></up-textarea><view class="text-gray margin-bottom margin-top data-v-4709c0fa">状态</view><up-input wx:if="{{m}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-6" bind:__l="__l" u-p="{{m}}"></up-input><block wx:if="{{n}}"><view class="text-gray margin-bottom margin-top data-v-4709c0fa">驳回理由</view><up-textarea wx:if="{{p}}" class="data-v-4709c0fa" virtualHostClass="data-v-4709c0fa" u-i="4709c0fa-7" bind:__l="__l" bindupdateModelValue="{{o}}" u-p="{{p}}"></up-textarea></block><block wx:if="{{q}}"><view class="text-gray margin-bottom margin-top data-v-4709c0fa">电子签名</view><view class="signature-box data-v-4709c0fa"><image src="{{r}}" class="signature-img data-v-4709c0fa" mode="aspectFit" bindtap="{{s}}" binderror="{{t}}"></image></view></block><view class="flex justify-center margin-top-xl data-v-4709c0fa"><button class="round cu-btn lg data-v-4709c0fa" bindtap="{{v}}">返回</button></view></view></view>

View File

@@ -0,0 +1 @@
.page.data-v-4709c0fa{min-height:100vh;background:#ebf2fc}.signature-box.data-v-4709c0fa{width:100%;height:240rpx;background:#f8f8f8;border:1rpx dashed #dcdfe6;border-radius:8rpx;overflow:hidden}.signature-img.data-v-4709c0fa{width:100%;height:240rpx}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
{
"navigationBarTitleText": "企业信息",
"usingComponents": {
"up-upload": "../../uni_modules/uview-plus/components/u-upload/u-upload",
"up-modal": "../../uni_modules/uview-plus/components/u-modal/u-modal",
"u-datetime-picker": "../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker",
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.page.data-v-b5d053e4{min-height:100vh;background:#ebf2fc}.list.data-v-b5d053e4{background:#fff;box-shadow:0 2rpx 6rpx 2rpx rgba(0,0,0,.08);border-left:5px solid #2667E9;border-radius:20rpx;padding:20rpx}.info-item.data-v-b5d053e4{display:flex;margin-top:16rpx;font-size:28rpx}.info-item .text-gray.data-v-b5d053e4{flex-shrink:0;color:#999}.empty-box.data-v-b5d053e4{padding:100rpx 40rpx;text-align:center}.modal-scroll-body.data-v-b5d053e4{height:60vh;padding:20rpx 0;box-sizing:border-box}.form-input.data-v-b5d053e4{width:100%;height:80rpx;padding:0 24rpx;border:1rpx solid #dcdfe6;border-radius:8rpx;font-size:28rpx;box-sizing:border-box;background:#fff}.form-textarea.data-v-b5d053e4{width:100%;min-height:160rpx;padding:20rpx 24rpx;border:1rpx solid #dcdfe6;border-radius:8rpx;font-size:28rpx;box-sizing:border-box;background:#fff}.form-label.data-v-b5d053e4{display:flex;align-items:center;margin-bottom:12rpx}.form-label .text-red.data-v-b5d053e4{margin-left:4rpx}.select-trigger.data-v-b5d053e4{display:flex;align-items:center;justify-content:space-between;background:#fff;border:1rpx solid #dcdfe6;border-radius:8rpx;padding:20rpx 24rpx}.select-trigger .select-value.data-v-b5d053e4{flex:1;font-size:28rpx;color:#333}.select-trigger .select-value.placeholder.data-v-b5d053e4{color:#c0c4cc}.picker-popup.data-v-b5d053e4{background:#fff}.picker-popup .picker-header.data-v-b5d053e4{display:flex;justify-content:space-between;align-items:center;padding:30rpx;border-bottom:1rpx solid #eee}.picker-popup .picker-header .picker-cancel.data-v-b5d053e4{font-size:28rpx;color:#999}.picker-popup .picker-header .picker-title.data-v-b5d053e4{font-size:32rpx;font-weight:700;color:#333}.picker-popup .picker-header .picker-confirm.data-v-b5d053e4{font-size:28rpx;color:#2667e9}.picker-popup .picker-body.data-v-b5d053e4{max-height:600rpx;padding:0 30rpx}.picker-popup .picker-item.data-v-b5d053e4{display:flex;justify-content:space-between;align-items:center;padding:30rpx 0;border-bottom:1rpx solid #f5f5f5;font-size:30rpx;color:#333}.picker-popup .picker-item.data-v-b5d053e4:last-child{border-bottom:none}.picker-popup .picker-item.active.data-v-b5d053e4{color:#2667e9}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{
"navigationBarTitleText": "添加检查表",
"usingComponents": {
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"up-picker": "../../uni_modules/uview-plus/components/u-picker/u-picker",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea",
"up-datetime-picker": "../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker",
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js"),o=require("../../utils/upload.js");if(!Array){(e.resolveComponent("up-input")+e.resolveComponent("up-radio")+e.resolveComponent("up-radio-group")+e.resolveComponent("up-upload")+e.resolveComponent("up-textarea"))()}Math||((()=>"../../uni_modules/uview-plus/components/u-input/u-input.js")+(()=>"../../uni_modules/uview-plus/components/u-radio/u-radio.js")+(()=>"../../uni_modules/uview-plus/components/u-radio-group/u-radio-group.js")+(()=>"../../uni_modules/uview-plus/components/u-upload/u-upload.js")+(()=>"../../uni_modules/uview-plus/components/u-textarea/u-textarea.js"))();const a={__name:"editcompanInformation",setup(a){const l=e.reactive([{name:"矿山开采",disabled:!1},{name:"化工生产",disabled:!1},{name:"冶金工业",disabled:!1},{name:"建筑施工",disabled:!1}]),u=e.ref("矿山开采"),r=e=>{console.log("groupChange",e)},d=e=>{console.log("radioChange",e)},n=e.ref([]),{afterRead:p,deletePic:s}=o.createUploadListHandlers(n);return(o,a)=>({a:e.o(o.change),b:e.o((e=>o.value=e)),c:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),d:e.o(o.change),e:e.o((e=>o.value=e)),f:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),g:e.o(o.change),h:e.o((e=>o.value=e)),i:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),j:e.o(o.change),k:e.o((e=>o.value=e)),l:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),m:e.o(o.change),n:e.o((e=>o.value=e)),o:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),p:e.o(o.change),q:e.o((e=>o.value=e)),r:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),s:e.f(l,((o,a,l)=>({a:a,b:e.o(d,a),c:"46b49516-7-"+l+",46b49516-6",d:e.p({customStyle:{marginBottom:"8px"},label:o.name,name:o.name})}))),t:e.o(r),v:e.o((e=>u.value=e)),w:e.p({placement:"row",shape:"square",modelValue:u.value}),x:e.o(o.change),y:e.o((e=>o.value=e)),z:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),A:e.o(o.change),B:e.o((e=>o.value=e)),C:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),D:e.o(o.change),E:e.o((e=>o.value=e)),F:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),G:e.o(o.change),H:e.o((e=>o.value=e)),I:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),J:e.o(o.change),K:e.o((e=>o.value=e)),L:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),M:e.o(o.change),N:e.o((e=>o.value=e)),O:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),P:e.o(o.change),Q:e.o((e=>o.value=e)),R:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),S:e.o(o.change),T:e.o((e=>o.value=e)),U:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),V:e.o(o.change),W:e.o((e=>o.value=e)),X:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),Y:e.o(o.change),Z:e.o((e=>o.value=e)),aa:e.p({placeholder:"请输入内容",border:"surround",modelValue:o.value}),ab:e.o(e.unref(p)),ac:e.o(e.unref(s)),ad:e.p({fileList:n.value,name:"1",multiple:!0,maxCount:10}),ae:e.o((e=>o.value1=e)),af:e.p({placeholder:"请输入内容",modelValue:o.value1}),ag:e.gei(o,"")})}},l=e._export_sfc(a,[["__scopeId","data-v-46b49516"]]);wx.createPage(l);

View File

@@ -0,0 +1,10 @@
{
"navigationBarTitleText": "编辑企业信息",
"usingComponents": {
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"up-radio": "../../uni_modules/uview-plus/components/u-radio/u-radio",
"up-radio-group": "../../uni_modules/uview-plus/components/u-radio-group/u-radio-group",
"up-upload": "../../uni_modules/uview-plus/components/u-upload/u-upload",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.page.data-v-46b49516{min-height:100vh;background:#ebf2fc}

View File

@@ -0,0 +1 @@
"use strict";const e=require("../../common/vendor.js");if(!Array){(e.resolveComponent("up-input")+e.resolveComponent("up-datetime-picker")+e.resolveComponent("up-textarea")+e.resolveComponent("u-popup"))()}Math||((()=>"../../uni_modules/uview-plus/components/u-input/u-input.js")+(()=>"../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker.js")+(()=>"../../uni_modules/uview-plus/components/u-textarea/u-textarea.js")+(()=>"../../uni_modules/uview-plus/components/u-popup/u-popup.js"))();const o={__name:"equipmentregistration",setup(o){const u=e.ref(!1),a=e.ref([]),l=()=>{u.value=!0},t=()=>{e.index.chooseMessageFile({count:10,type:"all",success:e=>{const o=e.tempFiles.map((e=>({name:e.name,path:e.path,size:e.size})));a.value=[...a.value,...o]},fail:()=>{e.index.chooseImage({count:9,success:e=>{const o=e.tempFilePaths.map(((e,o)=>({name:`文件${a.value.length+o+1}`,path:e,size:0})));a.value=[...a.value,...o]}})}})},p=()=>{u.value=!1,e.index.showToast({title:"新增成功",icon:"success"})},s=e.ref(!1),n=e.ref(Date.now());return(o,c)=>e.e({a:e.o(l),b:e.o((e=>u.value=!1)),c:e.p({placeholder:"请输入型号"}),d:e.p({placeholder:"请输入名称"}),e:e.p({placeholder:"请输入参数"}),f:e.p({placeholder:"请输入数量"}),g:e.o((e=>n.value=e)),h:e.p({hasInput:!0,show:s.value,mode:"date",modelValue:n.value}),i:e.o((e=>n.value=e)),j:e.p({hasInput:!0,show:s.value,mode:"date",modelValue:n.value}),k:e.p({placeholder:"请输入区域"}),l:e.o(t),m:a.value.length>0},a.value.length>0?{n:e.f(a.value,((o,u,l)=>({a:e.t(o.name),b:e.o((e=>(e=>{a.value.splice(e,1)})(u)),u),c:u})))}:{},{o:e.o((e=>n.value=e)),p:e.p({placeholder:"请输入备注",modelValue:n.value}),q:e.o((e=>u.value=!1)),r:e.o(p),s:e.o((e=>u.value=!1)),t:e.p({show:u.value,mode:"center",round:"20"}),v:e.gei(o,"")})}},u=e._export_sfc(o,[["__scopeId","data-v-66a12537"]]);wx.createPage(u);

View File

@@ -0,0 +1,9 @@
{
"navigationBarTitleText": "设备登记",
"usingComponents": {
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"up-datetime-picker": "../../uni_modules/uview-plus/components/u-datetime-picker/u-datetime-picker",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea",
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup"
}
}

View File

@@ -0,0 +1 @@
<view class="{{['padding', 'data-v-66a12537', virtualHostClass]}}" style="{{virtualHostStyle}}" hidden="{{virtualHostHidden || false}}" id="{{v}}"><view class="padding data-v-66a12537"><view class="text-gray text-center margin-top-xl margin-bottom-xl data-v-66a12537">暂无设备</view><button class="cuIcon-add round bg-blue data-v-66a12537" bindtap="{{a}}">新增</button></view><u-popup wx:if="{{t}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-s="{{['d']}}" bindclose="{{s}}" u-i="66a12537-0" bind:__l="__l" u-p="{{t}}"><view class="popup-content data-v-66a12537"><view class="popup-header data-v-66a12537"><view class="popup-title text-bold data-v-66a12537">新增设备</view><view class="popup-close data-v-66a12537" bindtap="{{b}}">×</view></view><scroll-view class="popup-body data-v-66a12537" scroll-y style="{{'height:' + '60vh'}}"><view class="flex data-v-66a12537"><view class="margin-bottom data-v-66a12537">型号</view><view class="text-red data-v-66a12537">*</view></view><up-input wx:if="{{c}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-1,66a12537-0" bind:__l="__l" u-p="{{c}}"></up-input><view class="flex margin-bottom margin-top data-v-66a12537"><view class="data-v-66a12537">名称</view><view class="text-red data-v-66a12537">*</view></view><up-input wx:if="{{d}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-2,66a12537-0" bind:__l="__l" u-p="{{d}}"></up-input><view class="margin-bottom margin-top data-v-66a12537">参数</view><up-input wx:if="{{e}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-3,66a12537-0" bind:__l="__l" u-p="{{e}}"></up-input><view class="flex margin-bottom margin-top data-v-66a12537"><view class="data-v-66a12537">数量(单位:台)</view><view class="text-red data-v-66a12537">*</view></view><up-input wx:if="{{f}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-4,66a12537-0" bind:__l="__l" u-p="{{f}}"></up-input><view class="flex margin-bottom margin-top data-v-66a12537"><view class="data-v-66a12537">购买时间</view><view class="text-red data-v-66a12537">*</view></view><up-datetime-picker wx:if="{{h}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-5,66a12537-0" bind:__l="__l" bindupdateModelValue="{{g}}" u-p="{{h}}"></up-datetime-picker><view class="flex margin-bottom margin-top data-v-66a12537"><view class="data-v-66a12537">设备预警时间</view><view class="text-red data-v-66a12537">*</view></view><up-datetime-picker wx:if="{{j}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-6,66a12537-0" bind:__l="__l" bindupdateModelValue="{{i}}" u-p="{{j}}"></up-datetime-picker><view class="flex margin-bottom margin-top data-v-66a12537"><view class="data-v-66a12537">区域</view><view class="text-red data-v-66a12537">*</view></view><up-input wx:if="{{k}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-7,66a12537-0" bind:__l="__l" u-p="{{k}}"></up-input><view class="margin-top-sm margin-bottom-sm margin-bottom margin-top data-v-66a12537">上传资料</view><view class="upload-area data-v-66a12537" bindtap="{{l}}"><view class="upload-icon data-v-66a12537"><text class="cuIcon-upload data-v-66a12537" style="font-size:60rpx;color:#999"></text></view><view class="upload-text data-v-66a12537">点击选择文件</view><view class="upload-tip data-v-66a12537">支持Word、Excel、PDF、图片等格式</view><button class="cu-but bg-blue data-v-66a12537">选择文件</button></view><view wx:if="{{m}}" class="file-list data-v-66a12537"><view wx:for="{{n}}" wx:for-item="file" wx:key="c" class="file-item data-v-66a12537"><text class="file-name data-v-66a12537">{{file.a}}</text><text class="file-delete text-red data-v-66a12537" catchtap="{{file.b}}">×</text></view></view><view class="margin-top-sm margin-bottom margin-top data-v-66a12537">备注</view><up-textarea wx:if="{{p}}" class="data-v-66a12537" virtualHostClass="data-v-66a12537" u-i="66a12537-8,66a12537-0" bind:__l="__l" bindupdateModelValue="{{o}}" u-p="{{p}}"></up-textarea></scroll-view><view class="popup-footer data-v-66a12537"><button class="btn-cancel data-v-66a12537" bindtap="{{q}}">取消</button><button class="btn-confirm bg-blue data-v-66a12537" bindtap="{{r}}">确定</button></view></view></u-popup></view>

View File

@@ -0,0 +1 @@
.popup-content.data-v-66a12537{width:600rpx;background:#fff;border-radius:20rpx;overflow:hidden}.popup-header.data-v-66a12537{display:flex;justify-content:space-between;align-items:center;padding:30rpx;border-bottom:1rpx solid #eee}.popup-title.data-v-66a12537{font-size:32rpx}.popup-close.data-v-66a12537{font-size:40rpx;color:#999;cursor:pointer}.popup-body.data-v-66a12537{padding:30rpx}.popup-footer.data-v-66a12537{display:flex;border-top:1rpx solid #eee}.popup-footer button.data-v-66a12537{flex:1;height:90rpx;line-height:90rpx;border-radius:0;font-size:30rpx}.popup-footer button.data-v-66a12537:after{border:none}.popup-footer .btn-cancel.data-v-66a12537{background:#f5f5f5;color:#666}.popup-footer .btn-confirm.data-v-66a12537{color:#fff}.upload-area.data-v-66a12537{background:#F8F8F;border:2rpx dashed #C5D4F5;border-radius:16rpx;padding:40rpx 30rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;margin-top:16rpx}.upload-icon.data-v-66a12537{width:80rpx;height:80rpx;display:flex;align-items:center;justify-content:center;margin-bottom:16rpx}.upload-text.data-v-66a12537{font-size:28rpx;color:#333;margin-bottom:8rpx}.upload-tip.data-v-66a12537{font-size:24rpx;color:#999;margin-bottom:24rpx}.upload-btn.data-v-66a12537{padding:16rpx 48rpx;font-size:28rpx;color:#fff;border-radius:40rpx}.file-list.data-v-66a12537{margin-top:20rpx}.file-item.data-v-66a12537{display:flex;justify-content:space-between;align-items:center;padding:16rpx 20rpx;background:#f5f5f5;border-radius:8rpx;margin-bottom:12rpx}.file-name.data-v-66a12537{font-size:26rpx;color:#333;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-delete.data-v-66a12537{font-size:36rpx;padding-left:20rpx}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{
"navigationBarTitleText": "隐患排查",
"usingComponents": {
"up-choose": "../../uni_modules/uview-plus/components/u-choose/u-choose",
"up-upload": "../../uni_modules/uview-plus/components/u-upload/u-upload",
"up-input": "../../uni_modules/uview-plus/components/u-input/u-input",
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea",
"u-popup": "../../uni_modules/uview-plus/components/u-popup/u-popup"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
{
"navigationBarTitleText": "隐患验收",
"usingComponents": {
"up-textarea": "../../uni_modules/uview-plus/components/u-textarea/u-textarea",
"up-upload": "../../uni_modules/uview-plus/components/u-upload/u-upload",
"wd-signature": "../../node-modules/wot-design-uni/components/wd-signature/wd-signature"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.page.data-v-df836b84{min-height:100vh;background:#ebf2fc}.result-btn.data-v-df836b84{flex:1;height:80rpx;line-height:80rpx;border-radius:8rpx;background:#f5f5f5;color:#666;font-size:28rpx}.result-btn.data-v-df836b84:after{border:none}.result-btn.active.data-v-df836b84{background:#2667e9;color:#fff}.signature-box.data-v-df836b84{width:100%;min-height:240rpx;background:#f8f8f8;border:1rpx dashed #dcdfe6;border-radius:8rpx;margin-top:16rpx}.signature-box .signature-img.data-v-df836b84{width:100%;height:100%}.signature-box .signature-placeholder.data-v-df836b84{color:#909399;font-size:28rpx}

Some files were not shown because too many files have changed in this diff Show More