jy-safe-app/pages/apply/subPages/SK/enterprise/enterpriseLibarary.vue
2026-04-17 11:35:59 +08:00

514 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="enterprise-library-page">
<!-- 筛选区域 -->
<view class="filter-section">
<view class="filter-header" @click="showFilter = !showFilter">
<text class="filter-title">筛选条件</text>
<u-icon :name="showFilter ? 'arrow-up' : 'arrow-down'" size="14" color="#666"></u-icon>
</view>
<view class="filter-content" v-if="showFilter">
<view class="filter-row">
<view class="filter-item" @click="handleChangeStep('Area')">
<text class="filter-label">辨识区域</text>
<u--input @click="handleChangeStep('Area')" v-model="filters.areaName" disabled disabledColor="#ffffff" suffixIcon="arrow-down" suffixIconStyle="font-size: 12px" fontSize="13px" placeholder="请选择辨识区域" size="small"></u--input>
</view>
</view>
<view class="filter-row">
<view class="filter-item" @click="handleChangeStep('typeName')">
<text class="filter-label">风险类别:</text>
<u--input @click="handleChangeStep('typeName')" v-model="filters.typeName" disabled disabledColor="#ffffff" suffixIcon="arrow-down" suffixIconStyle="font-size: 12px" fontSize="13px" placeholder="请选择风险类别" size="small"></u--input>
</view>
</view>
<view class="filter-row">
<view class="filter-item">
<text class="filter-label">生产单元:</text>
<u--input v-model="filters.productionUnitName" fontSize="13px" placeholder="请输入生产单元" clearable size="small"></u--input>
</view>
</view>
<view class="filter-row">
<view class="filter-item filter-reset">
<u-button type="primary" size="small" :plain="true" @click="resetFilters" class="reset-btn">重置</u-button>
</view>
<view class="filter-item filter-reset">
<u-button type="primary" size="small" @click="searchWithFilters" class="reset-btn">搜索</u-button>
</view>
</view>
</view>
</view>
<!-- 列表区域 -->
<view class="list-container">
<view v-for="(item, idx) in enterpriseLibraryList" :key="item.ID" class="enterprise-item">
<u-checkbox-group><u-checkbox :checked="selectedIndices.includes(idx)" shape="circle" @change="(e) => toggleSelection(idx, e)"></u-checkbox></u-checkbox-group>
<text class="info-index">{{idx+1}}</text>
<view class="enterprise-info">
<view class="info-row">
<text class="info-label">生产单元:</text>
<text class="info-value">{{ item.Nav_ProductionUnit.NAME || '' }}</text>
</view>
<view class="info-row">
<text class="info-label">辨识区域:</text>
<text class="info-value">{{ item.Nav_Area.NAME || '' }}</text>
</view>
<view class="info-row">
<text class="info-label">风险名称:</text>
<text class="info-value">{{ item.RISK_NAME || '' }}</text>
</view>
<view class="info-row">
<text class="info-label">风险描述:</text>
<text class="info-value">{{ item.RISK_DESCRIPTION || '' }}</text>
</view>
<view class="info-row">
<text class="info-label">风险类别:</text>
<text class="info-value">{{ item.Nav_Type.NAME || '' }}</text>
</view>
<view class="info-row">
<text class="info-label">管控措施:</text>
<text class="info-value">{{ item.MEASURE || '' }}</text>
</view>
<view class="info-row">
<text class="info-label">应急处置:</text>
<text class="info-value">{{ item.EMERGENCY || '' }}</text>
</view>
</view>
</view>
<view v-if="enterpriseLibraryList.length === 0 && !loading" class="empty-tip">暂无企业库数据</view>
<view class="load-more-footer" v-if="enterpriseLibraryList.length > 0">
<u-button v-if="hasMore" type="primary" :plain="true" :loading="loading" @click="loadMore" class="load-more-btn" size="small">
{{ loading ? '加载中...' : '加载更多' }}
</u-button>
<view v-else class="no-more-tip">—— 没有更多数据了 ——</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="bottom-buttons">
<u-button type="primary" :plain="true" @click="handleCancel">取消</u-button>
<u-button type="primary" @click="handleConfirm" :disabled="selectedIndices.length === 0">确定导入({{ selectedIndices.length }})</u-button>
</view>
<query-selector :show="showPopupStep" :total="curTotalStep" :lists="stepLists" :defaultValue="currentOperateStep.NAME" @close="handleClosePopupStep" @search="handleSearchStep" @select="handleSelectedStep" />
</view>
</template>
<script>
import {
initFilter,
extendFilterGroup,
extendGroupRule,
extendInclude,
extendRule,
initFilterGroup
} from '@/utils/common'
import {
getRequest
} from '@/services/apply/FOServices/FOServices'
import {
GetNewRiskAreaInfo,
GetRiskTypeInfo
} from '../../../../../services/apply/subPages/SK/SKServices.js'
export default {
data() {
return {
ORG_ID: uni.getStorageSync('orgId'),
enterpriseLibraryList: [],
selectedIndices: [],
loading: false,
hasMore: true,
pageIndex: 1,
pageSize: 2,
showFilter: false,
searchKeyword: '',
filters: {
areaName: '',
productionUnitName: '',
typeName: ''
},
filterTimer: null,
currentOperateStep: {},
showPopupStep: false,
stepLists: [],
curTotalStep: 0,
nowName:''
}
},
onLoad(options) {
// 可以接收外部传入的已存在数据用于去重提示
if (options.existingData) {
try {
this.existingData = JSON.parse(decodeURIComponent(options.existingData))
} catch (e) {}
}
this.loadData()
},
methods: {
loadData(isLoadMore = false) {
if (this.loading) return
if (!isLoadMore) {
this.pageIndex = 1
this.hasMore = true
this.enterpriseLibraryList = []
this.selectedIndices = []
}
if (!this.hasMore && isLoadMore) {
uni.showToast({
title: '没有更多数据了',
icon: 'none'
})
return
}
this.loading = true
const json = initFilter(this.ORG_ID)
extendInclude(json, 'Nav_ProductionUnit')
extendInclude(json, 'Nav_Area')
extendInclude(json, 'Nav_Type')
// 添加筛选条件
const conditions = []
if (this.filters.areaName) {
const tempGroup = initFilterGroup(false);
extendGroupRule(tempGroup, 'AREA_ID', 1, this.filters.AREA_ID)
extendFilterGroup(json, tempGroup);
}
if (this.filters.productionUnitName) {
const tempGroup = initFilterGroup(false);
extendGroupRule(tempGroup, 'Nav_ProductionUnit.NAME', 9, this.filters.productionUnitName)
extendFilterGroup(json, tempGroup);
}
if (this.filters.typeName) {
const tempGroup = initFilterGroup(false);
extendGroupRule(tempGroup, 'TYPE_ID', 1, this.filters.TYPE_ID)
extendFilterGroup(json, tempGroup);
}
json.SelectField = [
"CODE",
"Nav_ProductionUnit.NAME",
"Nav_Area.NAME",
"RISK_NAME",
"RISK_DESCRIPTION",
"Nav_Type.NAME",
"CHECKLEVEL",
"CHECKDEPT",
"CHECKPOST",
"EVALUATE_LEVEL",
"MEASURE",
"EMERGENCY",
"ID",
"ORG_ID",
"PRODUCTION_UNIT_ID",
"AREA_ID",
"TYPE_ID",
"RISK_NAME_ID"
]
json.Limit = this.pageSize
json.PageIndex = this.pageIndex
json.Start = (this.pageIndex - 1) * this.pageSize
getRequest(json, "/SK/SKEnterpriseLibrary/SKOrderPaged").then(res => {
this.loading = false
if (res && res.length > 0) {
if (isLoadMore) {
this.enterpriseLibraryList = [...this.enterpriseLibraryList, ...res]
} else {
this.enterpriseLibraryList = res
}
this.hasMore = res.length >= this.pageSize
this.pageIndex++
} else {
this.hasMore = false
if (!isLoadMore && this.enterpriseLibraryList.length === 0) {
uni.showToast({
title: '暂无数据',
icon: 'none'
})
}
}
}).catch(err => {
this.loading = false
uni.showToast({
title: '加载失败',
icon: 'none'
})
})
},
loadMore() {
if (this.hasMore && !this.loading) {
this.loadData(true)
}
},
toggleSelection(index) {
const idx = this.selectedIndices.indexOf(index)
if (idx === -1) {
this.selectedIndices.push(index)
} else {
this.selectedIndices.splice(idx, 1)
}
},
handleSearch() {
this.loadData()
},
handleClear() {
this.searchKeyword = ''
this.loadData()
},
handleFilterChange() {
if (this.filterTimer) clearTimeout(this.filterTimer)
this.filterTimer = setTimeout(() => {
this.loadData()
}, 500)
},
searchWithFilters() {
this.loadData()
},
resetFilters() {
this.filters = {
areaName: '',
productionUnitName: '',
typeName: '',
AREA_ID:'',
TYPE_ID:''
}
this.loadData()
},
handleConfirm() {
const selectedItems = this.selectedIndices.map(idx => this.enterpriseLibraryList[idx])
// 使用 uni.$emit 或 getOpenerEventChannel 返回数据
const eventChannel = this.getOpenerEventChannel()
if (eventChannel) {
eventChannel.emit('confirm', {
selectedItems
})
}
uni.navigateBack()
},
handleCancel() {
uni.navigateBack()
},
handleChangeStep(name) {
this.currentOperateStep = {}
this.showPopupStep = true
this.nowName = name
this.handleSearchStep('init')
},
handleClosePopupStep() {
this.showPopupStep = false
// this.showPopupCertificate = false
},
handleSearchStep(val, pageIndex) {
let requestInfo = this.nowName == 'Area' ? GetNewRiskAreaInfo :GetRiskTypeInfo
const orgId = uni.getStorageSync('orgId')
const json = initFilter(orgId, "", "", 0, pageIndex ?? 1)
json.Limit = 20
if (pageIndex) {
json.Start = (pageIndex - 1) * json.Limit;
}
if (val !== 'init') {
const tempGroup = initFilterGroup(false);
extendGroupRule(tempGroup, 'NAME', 9, val)
extendFilterGroup(json, tempGroup);
}
requestInfo(json).then(res => {
// if (res.IsSuccessful) {
this.stepLists = (res.Data || res).map(i => {
return {
...i,
id: i.ID,
name: i.NAME,
}
})
this.curTotalStep = res.TotalCount
// }
})
},
handleSelectedStep(val) {
if (this.nowName == 'Area') {
this.filters.areaName = val.NAME
this.filters.AREA_ID = val.ID
} else {
this.filters.typeName = val.NAME
this.filters.TYPE_ID = val.ID
}
this.showPopupStep = false
},
}
}
</script>
<style scoped>
.enterprise-library-page {
min-height: 100vh;
background-color: #f5f5f5;
display: flex;
flex-direction: column;
}
.search-header {
padding: 12px 16px;
background-color: #fff;
border-bottom: 1px solid #eee;
}
.filter-section {
background-color: #fff;
padding: 0 16px;
border-bottom: 1px solid #eee;
}
.filter-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
cursor: pointer;
}
.filter-title {
font-size: 14px;
font-weight: 500;
color: #333;
}
.filter-content {
padding-bottom: 12px;
}
.filter-row {
display: flex;
gap: 12px;
margin-bottom: 10px;
}
.filter-item {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
}
.filter-label {
font-size: 13px;
color: #666;
white-space: nowrap;
width: 70px;
}
.filter-reset {
flex: 0.5;
}
.reset-btn {
width: 100%;
}
.list-container {
flex: 1;
padding: 12px 16px;
padding-bottom: 80px;
}
.enterprise-item {
display: flex;
align-items: flex-start;
padding: 12px;
background-color: #fff;
border-radius: 8px;
margin-bottom: 12px;
gap: 12px;
}
.enterprise-info {
flex: 1;
}
.info-row {
display: flex;
margin-bottom: 6px;
flex-wrap: wrap;
}
.info-label {
font-size: 13px;
color: #999;
width: 70px;
flex-shrink: 0;
}
.info-index {
font-size: 13px;
color: #999;
}
.info-value {
font-size: 13px;
color: #333;
flex: 1;
}
.empty-tip {
text-align: center;
padding: 40px 0;
color: #999;
font-size: 14px;
}
.load-more-footer {
padding: 15px 0;
display: flex;
justify-content: center;
}
.load-more-btn {
width: 80%;
}
.no-more-tip {
text-align: center;
padding: 10px 0;
color: #999;
font-size: 12px;
}
.bottom-buttons {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
gap: 12px;
padding: 12px 16px;
background-color: #fff;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
z-index: 100;
}
.bottom-buttons button {
flex: 1;
}
</style>