代码提交_对接风险光控卡接口

This commit is contained in:
lixiaobang 2026-01-16 17:54:09 +08:00
parent 13bde0497e
commit b191114bcc
4 changed files with 628 additions and 53 deletions

View File

@ -0,0 +1,77 @@
import request from '@/utils/request'
// 查询风险卡模版列表
export function listRiskCardTemplate(query) {
return request({
url: '/manage/logistics/riskCard/template/list',
method: 'get',
params: query
})
}
//查询风险卡模版详情信息
export function getRiskCardTemplateDetail(templateId) {
return request({
url: '/manage/logistics/riskCard/template/' + templateId,
method: 'get'
})
}
// 新增风险卡模版保存并发布
export function saveAndPublishRiskCardTemplate(data) {
return request({
url: '/manage/logistics/riskCard/template/saveAndPublish',
method: 'post',
data: data
})
}
// 新增风险卡模版保存不发布
export function saveNotPublishRiskCardTemplate(data) {
return request({
url: '/manage/logistics/riskCard/template/save',
method: 'post',
data: data
})
}
//
// 发布风险卡模版
export function publishRiskCardTemplate(id) {
return request({
url: '/manage/logistics/riskCard/template/publish/' + id,
method: 'put'
})
}
// 作废风险卡模版
export function obsoleteRiskCardTemplate(id) {
return request({
url: '/manage/logistics/riskCard/template/obsolete/' + id,
method: 'put'
})
}
// 编辑风险卡模版
export function editRiskCardTemplate(data) {
return request({
url: '/manage/logistics/riskCard/template',
method: 'put',
data
})
}
//查询检查项列表
export function listRiskCardItem(id) {
return request({
url: '/manage/logistics/riskCard/template/items/' + id,
method: 'get',
})
}
//导出模版列表
export function exportRiskCardTemplateList(data) {
return request({
url: '/manage/logistics/riskCard/template/export',
method: 'post',
data: data,
responseType: 'blob'
})
}

View File

@ -1,20 +1,51 @@
<!-- 后勤模块-风险管控卡详情 -->
<template>
<div class="MainBox">
<!-- 页面标题 -->
<div class="page-title">
<h2>{{ pageTitle }}</h2>
</div>
<!-- 模板基础信息 -->
<el-card class="info-card" shadow="hover">
<template #header>
<span>模板基础信息</span>
</template>
<el-descriptions :column="3" border>
<!-- 新增/编辑模式使用表单 -->
<el-form v-if="isEditMode" :model="templateForm" label-width="100px">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="模板名称">
<el-input v-model="templateForm.templateName" placeholder="请输入模板名称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="风险类型">
<el-select v-model="templateForm.riskType" placeholder="请选择风险类型">
<el-option label="高空作业" value="高空作业"></el-option>
<el-option label="电气安全" value="电气安全"></el-option>
<el-option label="机械设备" value="机械设备"></el-option>
<el-option label="特殊环境作业" value="特殊环境作业"></el-option>
<el-option label="特种设备" value="特种设备"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注">
<el-input v-model="templateForm.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- 详情模式使用描述列表 -->
<el-descriptions v-else :column="3" border>
<el-descriptions-item label="模板名称">
高处危险作业风险管控卡
{{ templateForm.templateName || '高处危险作业风险管控卡' }}
</el-descriptions-item>
<el-descriptions-item label="风险类型">
高空作业
{{ templateForm.riskType || '高空作业' }}
</el-descriptions-item>
<el-descriptions-item label="备注">
适用于建筑施工中高度超过2米的作业场景
{{ templateForm.remark || '适用于建筑施工中高度超过2米的作业场景' }}
</el-descriptions-item>
</el-descriptions>
</el-card>
@ -28,6 +59,10 @@
<el-tab-pane label="必选项" name="required">
<div class="tab-content">
<p class="tab-description">以下检查项为红头文件规定必选项不可删除仅可编辑描述:</p>
<div class="add-section">
<el-input v-model="newRequiredItemContent" placeholder="请输入新的检查项描述..." class="add-input" />
<el-button type="primary" icon="Plus" @click="addRequiredItem">+添加检查项</el-button>
</div>
<el-list>
<el-list-item v-for="(item, index) in requiredItems" :key="index" class="list-item">
<div class="item-content">
@ -72,15 +107,51 @@
<!-- 底部操作按钮 -->
<div class="bottom-actions">
<el-button type="default" icon="ArrowLeft" @click="router.back()">返回</el-button>
<el-button type="primary" plain style="margin-left: 10px;">保存配置</el-button>
<el-button type="primary" style="margin-left: 10px;">保存并发布</el-button>
<el-button v-if="!isDetailMode" type="primary" plain style="margin-left: 10px;" @click="handleSave(0)">保存配置</el-button>
<el-button v-if="!isDetailMode" type="primary" style="margin-left: 10px;" @click="handleSave(1)">保存并发布</el-button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { ref, computed, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { saveAndPublishRiskCardTemplate, saveNotPublishRiskCardTemplate, getRiskCardTemplateDetail, editRiskCardTemplate, listRiskCardItem } from '@/api/Logistics/riskManagement.js'
import { ElMessage } from 'element-plus'
const router = useRouter()
const route = useRoute()
//
const pageTitle = computed(() => {
const operate = route.query.operate
if (operate === 'add') {
return '新增模版'
} else if (operate === 'edit') {
return '编辑模版'
} else if (operate === 'detail') {
return '查看详情'
}
return '模版详情'
})
//
const isEditMode = computed(() => {
const operate = route.query.operate
return operate === 'add' || operate === 'edit'
})
//
const isDetailMode = computed(() => {
const operate = route.query.operate
return operate === 'detail'
})
//
const templateForm = ref({
templateName: '',
riskType: '',
remark: ''
})
const activeTab = ref('required')
@ -99,6 +170,15 @@ const optionalItems = ref([
])
const newItemContent = ref('')
const newRequiredItemContent = ref('')
//
const addRequiredItem = () => {
if (newRequiredItemContent.value.trim()) {
requiredItems.value.push({ content: newRequiredItemContent.value })
newRequiredItemContent.value = ''
}
}
//
const addOptionalItem = () => {
@ -146,6 +226,256 @@ const moveItemDown = (index) => {
requiredItems.value[index + 1] = temp
}
}
//
const getTemplateDetail = async () => {
const templateId = route.query.templateId || route.query.id
if (!templateId) {
return
}
try {
//
const response = await getRiskCardTemplateDetail(templateId)
if (response.code === 200) {
const data = response.data || response
//
templateForm.value = {
templateName: data.templateName || '',
riskType: data.riskType || '',
remark: data.remark || ''
}
} else {
ElMessage.error(response.msg || '获取详情失败')
return
}
// ID
try {
const itemsResponse = await listRiskCardItem(templateId)
if (itemsResponse.code === 200) {
const itemsData = itemsResponse.data || itemsResponse.rows || itemsResponse
const itemsList = Array.isArray(itemsData) ? itemsData : (itemsData.items || [])
//
if (itemsList && itemsList.length > 0) {
//
const fetchedRequiredCount = itemsList.filter(item =>
item.isRequired === '1' || item.isRequired === 1 || item.isRequired === true || item.isRequired === 'true'
).length
const fetchedOptionalCount = itemsList.length - fetchedRequiredCount
//
requiredItems.value = []
optionalItems.value = []
//
itemsList.forEach(item => {
const itemData = {
id: item.id || item.itemId || item.checkItemId || null, // IDID
content: item.itemDescription || item.content || item.description || ''
}
// '1' 1
if (item.isRequired === '1' || item.isRequired === 1 || item.isRequired === true || item.isRequired === 'true') {
requiredItems.value.push(itemData)
} else {
optionalItems.value.push(itemData)
}
})
//
console.log('获取到的必选项数量:', fetchedRequiredCount, '数据:', requiredItems.value)
console.log('获取到的可选项数量:', fetchedOptionalCount, '数据:', optionalItems.value)
//
if (fetchedOptionalCount === 0 && optionalItems.value.length === 0) {
console.warn('获取到的数据中没有可选项,如果之前有可选项数据,可能已被清空')
}
} else {
//
console.warn('获取到的检查项列表为空,保留现有数据')
// optionalItems requiredItems
}
} else {
console.warn('获取检查项接口返回非200状态:', itemsResponse)
// 200
}
} catch (itemsError) {
console.error('获取检查项失败:', itemsError)
//
const data = response.data || response
if (data.items && Array.isArray(data.items) && data.items.length > 0) {
requiredItems.value = []
optionalItems.value = []
data.items.forEach(item => {
const itemData = {
id: item.id || item.itemId || item.checkItemId || null,
content: item.itemDescription || item.content || item.description || ''
}
if (item.isRequired === '1' || item.isRequired === 1 || item.isRequired === true || item.isRequired === 'true') {
requiredItems.value.push(itemData)
} else {
optionalItems.value.push(itemData)
}
})
} else {
//
console.warn('从详情接口也无法获取检查项数据,保留现有数据')
// optionalItems requiredItems
}
}
} catch (error) {
console.error('获取详情失败:', error)
ElMessage.error('获取详情失败,请稍后重试')
}
}
//
const handleSave = async (status) => {
try {
//
const templateId = route.query.templateId || route.query.id
if (templateId && optionalItems.value.length === 0 && requiredItems.value.length === 0) {
ElMessage.warning('检查项数据为空,请先加载数据或添加检查项')
return
}
//
const backupRequiredItems = JSON.parse(JSON.stringify(requiredItems.value))
const backupOptionalItems = JSON.parse(JSON.stringify(optionalItems.value))
//
const items = []
//
requiredItems.value.forEach((item, index) => {
if (!item.content || !item.content.trim()) {
//
return
}
const itemData = {
itemDescription: item.content || '',
checkMethod: 'O', // O
isRequired: '1', //
sortOrder: index + 1
}
// ID
// ID
if (item.id) {
itemData.id = item.id
itemData.itemId = item.id
itemData.checkItemId = item.id
}
items.push(itemData)
})
optionalItems.value.forEach((item, index) => {
if (!item.content || !item.content.trim()) {
//
return
}
const itemData = {
itemDescription: item.content || '',
checkMethod: 'O', // O
isRequired: '0', //
sortOrder: requiredItems.value.length + index + 1
}
// ID
// ID
if (item.id) {
itemData.id = item.id
itemData.itemId = item.id
itemData.checkItemId = item.id
}
items.push(itemData)
})
//
if (templateId && items.length === 0) {
ElMessage.warning('没有有效的检查项数据,无法保存')
return
}
//
const requestData = {
templateName: templateForm.value.templateName,
riskType: templateForm.value.riskType,
remark: templateForm.value.remark,
status: 0, // 0-1-
items: items
}
// ID
if (templateId) {
requestData.id = templateId
requestData.templateId = templateId
}
// IDstatus
let response
if (templateId) {
// 使
if (status === 0) {
//
requestData.status = 0
} else {
//
requestData.status = 1
}
response = await editRiskCardTemplate(requestData)
} else {
// 使
if (status === 0) {
//
response = await saveNotPublishRiskCardTemplate(requestData)
} else {
//
response = await saveAndPublishRiskCardTemplate(requestData)
}
}
if (response.code === 200) {
//
if (optionalItems.value.length === 0 && backupOptionalItems.length > 0) {
optionalItems.value = backupOptionalItems
}
if (requiredItems.value.length === 0 && backupRequiredItems.length > 0) {
requiredItems.value = backupRequiredItems
}
ElMessage.success(status === 0 ? '保存成功' : '保存并发布成功')
//
router.back()
} else {
//
if (optionalItems.value.length === 0 && backupOptionalItems.length > 0) {
optionalItems.value = backupOptionalItems
}
if (requiredItems.value.length === 0 && backupRequiredItems.length > 0) {
requiredItems.value = backupRequiredItems
}
ElMessage.error(response.msg || '操作失败')
}
} catch (error) {
console.error('保存失败:', error)
//
const templateId = route.query.templateId || route.query.id
if (templateId) {
//
await getTemplateDetail()
}
ElMessage.error('保存失败,请稍后重试')
}
}
//
onMounted(() => {
const operate = route.query.operate
if (operate === 'edit' || operate === 'detail') {
getTemplateDetail()
}
})
</script>
<style scoped lang="scss">
@ -155,6 +485,16 @@ const moveItemDown = (index) => {
background: #F9FAFB;
}
.page-title {
margin-bottom: 20px;
h2 {
margin: 0;
font-size: 20px;
font-weight: 600;
color: #303133;
}
}
.info-card {
margin-bottom: 20px;
}

View File

@ -4,18 +4,19 @@
<div class="MainBox">
<div class="card-box" style="display: flex; justify-content: space-between; align-items: center; ">
<div class="FlexBox">
<el-button type="primary" size="default">新增模版</el-button>
<el-button type="primary" size="default" @click="handleAdd">新增模版</el-button>
<el-button type="primary" plain size="default">批量导入检查项</el-button>
<el-button type="primary" plain size="default">导出模版</el-button>
<el-button type="primary" plain size="default" @click="handleExport">导出模版</el-button>
<el-button type="primary" plain size="default">发布模版</el-button>
</div>
<div class="FlexBox">
<el-select v-model="queryForm.selectedRiskType" placeholder="请选择风险类型" style="width: 120px;">
<el-option label="全部风险" value="0"></el-option>
<el-option label="高空作业" value="1"></el-option>
<el-option label="电气安全" value="2"></el-option>
<el-option label="机械设备" value="3"></el-option>
<el-option label="特殊环境作业" value="4"></el-option>
<el-option label="高空作业" value="高空作业"></el-option>
<el-option label="电气安全" value="电气安全"></el-option>
<el-option label="机械设备" value="机械设备"></el-option>
<el-option label="特殊环境作业" value="特殊环境作业"></el-option>
<el-option label="特种设备" value="特种设备"></el-option>
</el-select>
<el-select v-model="queryForm.selectedRiskStatus" placeholder="请选择审核状态" style="width: 100px;">
<el-option label="全部状态" value="0"></el-option>
@ -23,29 +24,43 @@
<el-option label="已发布" value="2"></el-option>
<el-option label="已作废" value="3"></el-option>
</el-select>
<el-button type="primary" size="default" @click="handleQuery">查询</el-button>
<el-button size="default" @click="handleReset">重置</el-button>
</div>
</div>
<div class="card-box">
<el-table :data="tableData" class="mt-2">
<el-table-column prop="riskTemplateName" label="模版名称"></el-table-column>
<el-table-column prop="riskTypeName" label="风险类型"></el-table-column>
<el-table-column prop="checkItemNum" label="检查项数量"></el-table-column>
<el-table :data="tableData" v-loading="loading" class="mt-2">
<el-table-column prop="templateName" label="模版名称"></el-table-column>
<el-table-column prop="riskType" label="风险类型"></el-table-column>
<el-table-column prop="itemCount" label="检查项数量"></el-table-column>
<el-table-column prop="status" label="状态">
<template #default="scope">
<el-tag :type="scope.row.status === '已发布' ? 'success' : 'info'">
{{ scope.row.status }}
<el-tag :type="getStatusType(scope.row.status)">
{{ getStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间"></el-table-column>
<el-table-column label="操作" width="220">
<template #default="scope">
<el-button size="small" type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="primary" link @click="handleDetail(scope.row)">查看详情</el-button>
<el-button size="small" type="success" link @click="handlePublish(scope.row)">发布</el-button>
<el-button size="small" type="danger" link @click="handleInvalidate(scope.row)">作废</el-button>
<!-- 已发布状态显示编辑查看详情作废 -->
<template v-if="scope.row.status === '1'">
<el-button size="small" type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="primary" link @click="handleDetail(scope.row)">查看详情</el-button>
<el-button size="small" type="danger" link @click="handleInvalidate(scope.row)">作废</el-button>
</template>
<!-- 未发布状态显示编辑查看详情发布 -->
<template v-else-if="scope.row.status === '0'">
<el-button size="small" type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="primary" link @click="handleDetail(scope.row)">查看详情</el-button>
<el-button size="small" type="success" link @click="handlePublish(scope.row)">发布</el-button>
</template>
<!-- 已作废状态只显示查看详情 -->
<template v-else-if="scope.row.status === '2'">
<el-button size="small" type="primary" link @click="handleDetail(scope.row)">查看详情</el-button>
</template>
</template>
</el-table-column>
</el-table>
@ -55,15 +70,22 @@
total }}
</span>
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
:total="total" layout="prev, pager, next"></el-pagination>
:total="total" layout="prev, pager, next" @size-change="getList"
@current-change="getList"></el-pagination>
</div>
</div>
</div>
</template>
<script setup name="Index">
import { ref } from "vue";
import { ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import { listRiskCardTemplate, publishRiskCardTemplate, obsoleteRiskCardTemplate, exportRiskCardTemplateList } from "@/api/Logistics/riskManagement.js";
import { ElMessage, ElMessageBox, ElLoading } from "element-plus";
import { blobValidate } from "@/utils/ruoyi";
import { saveAs } from "file-saver";
import errorCode from "@/utils/errorCode";
const router = useRouter();
//
@ -73,30 +95,69 @@ const queryForm = ref({
});
//
const tableData = ref([
{
id: 1,
riskTemplateName: "高空作业风险模版",
riskTypeName: "高空作业",
checkItemNum: "10",
status: "已发布",
createTime: "2023-08-01 10:00:00"
},
{
id: 2,
riskTemplateName: "电气安全风险模版",
riskTypeName: "电气安全",
checkItemNum: "15",
status: "未发布",
createTime: "2023-08-02 10:00:00"
},
]);
const tableData = ref([]);
const loading = ref(false); //
const pageNum = ref(1); //
const pageSize = ref(5); //
const total = ref(20); //
const pageSize = ref(10); //
const total = ref(0); //
//
const getList = () => {
loading.value = true;
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value
};
//
if (queryForm.value.selectedRiskType && queryForm.value.selectedRiskType !== "0") {
params.riskType = queryForm.value.selectedRiskType;
}
//
if (queryForm.value.selectedRiskStatus && queryForm.value.selectedRiskStatus !== "0") {
params.status = queryForm.value.selectedRiskStatus;
}
listRiskCardTemplate(params).then(response => {
if (response.code === 200) {
tableData.value = response.rows || response.data || [];
total.value = response.total || 0;
}
loading.value = false;
}).catch(() => {
loading.value = false;
});
};
//
onMounted(() => {
getList();
});
//
const handleQuery = () => {
pageNum.value = 1;
getList();
};
//
const handleReset = () => {
queryForm.value.selectedRiskType = "0";
queryForm.value.selectedRiskStatus = "0";
pageNum.value = 1;
getList();
};
//
const handleAdd = () => {
router.push({
path: "/logistics/RiskManagement/Details",
query: {
operate: "add"
}
})
}
//
const handleEdit = (row) => {
@ -104,7 +165,7 @@ const handleEdit = (row) => {
router.push({
path: "/logistics/RiskManagement/Details",
query: {
id: row.id,
templateId: row.templateId || row.id,
operate: "edit"
}
})
@ -116,7 +177,7 @@ const handleDetail = (row) => {
router.push({
path: "/logistics/RiskManagement/Details",
query: {
id: row.id,
templateId: row.templateId || row.id,
operate: "detail"
}
})
@ -124,14 +185,111 @@ const handleDetail = (row) => {
//
const handlePublish = (row) => {
console.log('发布风险模版', row)
ElMessageBox.confirm('确定要发布该风险卡模版吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
publishRiskCardTemplate(row.templateId).then(response => {
if (response.code === 200) {
ElMessage.success('发布成功');
getList(); //
} else {
ElMessage.error(response.msg || '发布失败');
}
}).catch(error => {
ElMessage.error('发布失败,请稍后重试');
console.error('发布失败:', error);
});
}).catch(() => {
//
});
}
//
const handleInvalidate = (row) => {
console.log('作废风险模版', row)
ElMessageBox.confirm('确定要作废该风险卡模版吗?作废后将无法恢复。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
obsoleteRiskCardTemplate(row.templateId).then(response => {
if (response.code === 200) {
ElMessage.success('作废成功');
getList(); //
} else {
ElMessage.error(response.msg || '作废失败');
}
}).catch(error => {
ElMessage.error('作废失败,请稍后重试');
console.error('作废失败:', error);
});
}).catch(() => {
//
});
}
//
const getStatusText = (status) => {
const statusMap = {
'0': '未发布',
'1': '已发布',
'2': '已作废'
};
return statusMap[status] || status;
}
//
const getStatusType = (status) => {
const typeMap = {
'0': 'info', // -
'1': 'success', // - 绿
'2': 'danger' // -
};
return typeMap[status] || 'info';
}
//
const handleExport = () => {
const params = {};
//
if (queryForm.value.selectedRiskType && queryForm.value.selectedRiskType !== "0") {
params.riskType = queryForm.value.selectedRiskType;
}
//
if (queryForm.value.selectedRiskStatus && queryForm.value.selectedRiskStatus !== "0") {
params.status = queryForm.value.selectedRiskStatus;
}
//
const downloadLoadingInstance = ElLoading.service({
text: "正在下载数据,请稍候",
background: "rgba(0, 0, 0, 0.7)"
});
//
exportRiskCardTemplateList(params).then(async (response) => {
// blob
const isBlob = blobValidate(response.data);
if (isBlob) {
const blob = new Blob([response.data]);
saveAs(blob, `风险卡模版_${new Date().getTime()}.xlsx`);
} else {
// blob
const resText = await response.data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] || '导出失败';
ElMessage.error(errMsg);
}
downloadLoadingInstance.close();
}).catch((error) => {
console.error('导出失败:', error);
ElMessage.error('导出文件出现错误,请联系管理员!');
downloadLoadingInstance.close();
});
}
</script>
<style scoped lang="scss">

View File

@ -46,7 +46,7 @@ export default defineConfig(({ mode, command }) => {
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
target: 'http://172.16.1.148:8080',
target: 'http://172.16.1.146:8080',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
}