512 lines
12 KiB
Vue
512 lines
12 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="page">
|
|||
|
|
<app-top-push-notice />
|
|||
|
|
<view class="tabback">
|
|||
|
|
<view class="rtjt" @click="back">←</view>
|
|||
|
|
<view class="name">{{ navTitle }}</view>
|
|||
|
|
<view class="tabback-placeholder"></view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="main-area">
|
|||
|
|
<scroll-view v-show="currentTab === 0" scroll-y class="panel" :show-scrollbar="false">
|
|||
|
|
<view v-if="tab0Loading" class="state state--muted">{{ $i18n.t('loading') }}</view>
|
|||
|
|
<template v-else>
|
|||
|
|
<view class="company-card">
|
|||
|
|
<view class="company-card-media">
|
|||
|
|
<image
|
|||
|
|
v-if="companyLogoUrl"
|
|||
|
|
class="company-card-logo"
|
|||
|
|
:src="companyLogoUrl"
|
|||
|
|
mode="aspectFill"
|
|||
|
|
/>
|
|||
|
|
<view v-else class="company-card-logo company-card-logo--ph"></view>
|
|||
|
|
</view>
|
|||
|
|
<text class="company-card-name">{{ companyName }}</text>
|
|||
|
|
<text v-if="companyEmail" class="company-card-line">{{ companyEmail }}</text>
|
|||
|
|
<text v-if="companyPhone" class="company-card-line">{{ companyPhone }}</text>
|
|||
|
|
<text v-if="companyDesc" class="company-card-desc">{{ companyDesc }}</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="section-title">{{ $i18n.t('companyHomeSpaces') }}</view>
|
|||
|
|
<view v-if="spacesLoading" class="state state--muted sm">{{ $i18n.t('loading') }}</view>
|
|||
|
|
<view v-else-if="spaceList.length === 0" class="state state--muted sm">{{ $i18n.t('companyEmptySpaces') }}</view>
|
|||
|
|
<view
|
|||
|
|
v-else
|
|||
|
|
v-for="(item, index) in spaceList"
|
|||
|
|
:key="spaceKey(item, index)"
|
|||
|
|
class="cell"
|
|||
|
|
@click="openSpace(item)"
|
|||
|
|
>
|
|||
|
|
<text class="cell-title">{{ spaceTitle(item) }}</text>
|
|||
|
|
<text v-if="spaceSub(item)" class="cell-sub">{{ spaceSub(item) }}</text>
|
|||
|
|
<text class="cell-arrow">›</text>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
</scroll-view>
|
|||
|
|
|
|||
|
|
<scroll-view v-show="currentTab === 1" scroll-y class="panel" :show-scrollbar="false">
|
|||
|
|
<view v-if="panicLoading" class="state state--muted">{{ $i18n.t('loading') }}</view>
|
|||
|
|
<view v-else-if="panicList.length === 0" class="state state--muted">{{ $i18n.t('companyEmptyPanic') }}</view>
|
|||
|
|
<view
|
|||
|
|
v-else
|
|||
|
|
v-for="(item, index) in panicList"
|
|||
|
|
:key="panicKey(item, index)"
|
|||
|
|
class="cell cell--panic"
|
|||
|
|
@click="openPanic(item)"
|
|||
|
|
>
|
|||
|
|
<view class="panic-row-top">
|
|||
|
|
<text class="cell-title">{{ panicTitle(item) }}</text>
|
|||
|
|
<text v-if="panicStatus(item)" class="panic-badge">{{ panicStatus(item) }}</text>
|
|||
|
|
</view>
|
|||
|
|
<text v-if="panicTime(item)" class="cell-sub">{{ panicTime(item) }}</text>
|
|||
|
|
<text class="cell-link">{{ $i18n.t('companyPanicDetailTitle') }} ›</text>
|
|||
|
|
</view>
|
|||
|
|
</scroll-view>
|
|||
|
|
|
|||
|
|
<scroll-view v-show="currentTab === 2" scroll-y class="panel" :show-scrollbar="false">
|
|||
|
|
<view class="state state--muted manage-placeholder">{{ $i18n.t('companyManageNoApi') }}</view>
|
|||
|
|
</scroll-view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="bottom-tabs">
|
|||
|
|
<view
|
|||
|
|
v-for="(tab, idx) in tabs"
|
|||
|
|
:key="idx"
|
|||
|
|
class="bottom-tab"
|
|||
|
|
:class="{ 'bottom-tab--active': currentTab === idx }"
|
|||
|
|
@click="switchTab(idx)"
|
|||
|
|
>
|
|||
|
|
<text class="bottom-tab-text">{{ tab.label }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
companyId: '',
|
|||
|
|
currentTab: 0,
|
|||
|
|
companyDetail: {},
|
|||
|
|
tab0Loading: true,
|
|||
|
|
spacesLoading: false,
|
|||
|
|
spaceList: [],
|
|||
|
|
panicLoading: false,
|
|||
|
|
panicLoaded: false,
|
|||
|
|
panicList: []
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
computed: {
|
|||
|
|
tabs() {
|
|||
|
|
return [
|
|||
|
|
{ label: this.$i18n.t('companyTabHome') },
|
|||
|
|
{ label: this.$i18n.t('companyTabPanic') },
|
|||
|
|
{ label: this.$i18n.t('companyTabManage') }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
navTitle() {
|
|||
|
|
if (this.currentTab === 1) return this.$i18n.t('companyPanicListTitle')
|
|||
|
|
if (this.currentTab === 2) return this.$i18n.t('companyTabManage')
|
|||
|
|
return this.companyName || this.$i18n.t('companyTabHome')
|
|||
|
|
},
|
|||
|
|
companyName() {
|
|||
|
|
const d = this.companyDetail
|
|||
|
|
return d.name || d.companyName || d.title || d.shortName || '--'
|
|||
|
|
},
|
|||
|
|
companyLogoUrl() {
|
|||
|
|
const d = this.companyDetail
|
|||
|
|
const u = d.logo || d.companyLogo || ''
|
|||
|
|
return u ? String(u).trim() : ''
|
|||
|
|
},
|
|||
|
|
companyEmail() {
|
|||
|
|
const d = this.companyDetail
|
|||
|
|
const e = d.email || d.companyEmail || ''
|
|||
|
|
return e ? String(e).trim() : ''
|
|||
|
|
},
|
|||
|
|
companyPhone() {
|
|||
|
|
const d = this.companyDetail
|
|||
|
|
const parts = [d.phoneCode, d.phone, d.contact].filter(Boolean)
|
|||
|
|
return parts.length ? parts.join(' ') : ''
|
|||
|
|
},
|
|||
|
|
companyDesc() {
|
|||
|
|
const d = this.companyDetail
|
|||
|
|
const t = d.description || d.remark || ''
|
|||
|
|
return t ? String(t).trim() : ''
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onLoad(options) {
|
|||
|
|
this.companyId = (options && (options.id || options.companyId)) ? String(options.id || options.companyId) : ''
|
|||
|
|
if (!this.companyId) {
|
|||
|
|
uni.showToast({ title: this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
this.loadHomeData()
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
back() {
|
|||
|
|
uni.navigateBack({ delta: 1 })
|
|||
|
|
},
|
|||
|
|
switchTab(idx) {
|
|||
|
|
if (this.currentTab === idx) return
|
|||
|
|
this.currentTab = idx
|
|||
|
|
if (idx === 1 && !this.panicLoaded) {
|
|||
|
|
this.loadPanicList()
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
normalizeRows(res) {
|
|||
|
|
if (!res) return []
|
|||
|
|
if (Array.isArray(res.rows)) return res.rows
|
|||
|
|
if (Array.isArray(res.data)) return res.data
|
|||
|
|
if (Array.isArray(res.records)) return res.records
|
|||
|
|
if (Array.isArray(res.list)) return res.list
|
|||
|
|
return []
|
|||
|
|
},
|
|||
|
|
loadHomeData() {
|
|||
|
|
this.tab0Loading = true
|
|||
|
|
this.spacesLoading = true
|
|||
|
|
this.spaceList = []
|
|||
|
|
this.$http
|
|||
|
|
.get(`/bst/company/${this.companyId}`)
|
|||
|
|
.then((res) => {
|
|||
|
|
if (res.code == 200) {
|
|||
|
|
this.companyDetail = res.data || {}
|
|||
|
|
} else {
|
|||
|
|
uni.showToast({ title: res.msg || this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
this.companyDetail = {}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(() => {
|
|||
|
|
uni.showToast({ title: this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
this.companyDetail = {}
|
|||
|
|
})
|
|||
|
|
.finally(() => {
|
|||
|
|
this.tab0Loading = false
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
this.$http
|
|||
|
|
.get(`/bst/companySpace/list?companyId=${this.companyId}&pageNum=1&pageSize=100`)
|
|||
|
|
.then((res) => {
|
|||
|
|
if (res.code == 200) {
|
|||
|
|
this.spaceList = this.normalizeRows(res)
|
|||
|
|
} else {
|
|||
|
|
this.spaceList = []
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(() => {
|
|||
|
|
this.spaceList = []
|
|||
|
|
})
|
|||
|
|
.finally(() => {
|
|||
|
|
this.spacesLoading = false
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
loadPanicList() {
|
|||
|
|
this.panicLoading = true
|
|||
|
|
this.$http
|
|||
|
|
.get(`/bst/panic/list?companyId=${this.companyId}&pageNum=1&pageSize=100`)
|
|||
|
|
.then((res) => {
|
|||
|
|
if (res.code == 200) {
|
|||
|
|
this.panicList = this.normalizeRows(res)
|
|||
|
|
this.panicLoaded = true
|
|||
|
|
} else {
|
|||
|
|
this.panicList = []
|
|||
|
|
uni.showToast({ title: res.msg || this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(() => {
|
|||
|
|
this.panicList = []
|
|||
|
|
uni.showToast({ title: this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
})
|
|||
|
|
.finally(() => {
|
|||
|
|
this.panicLoading = false
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
spaceKey(item, index) {
|
|||
|
|
const id = item && (item.spaceId || item.id)
|
|||
|
|
return id != null && id !== '' ? String(id) : 's-' + index
|
|||
|
|
},
|
|||
|
|
spaceTitle(item) {
|
|||
|
|
if (!item) return '--'
|
|||
|
|
if (item.space && item.space.name) return item.space.name
|
|||
|
|
return item.spaceName || item.name || item.title || '--'
|
|||
|
|
},
|
|||
|
|
spaceSub(item) {
|
|||
|
|
if (!item) return ''
|
|||
|
|
const parts = [item.address, item.remark, item.code].filter(
|
|||
|
|
(v) => v !== undefined && v !== null && String(v).trim() !== ''
|
|||
|
|
)
|
|||
|
|
return parts.length ? parts.join(' · ') : ''
|
|||
|
|
},
|
|||
|
|
openSpace(item) {
|
|||
|
|
const sid = item && (item.spaceId || item.id || (item.space && item.space.id))
|
|||
|
|
if (!sid) {
|
|||
|
|
uni.showToast({ title: this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
uni.navigateTo({ url: `/pages/company/space-detail?id=${sid}` })
|
|||
|
|
},
|
|||
|
|
panicKey(item, index) {
|
|||
|
|
const id = item && item.id
|
|||
|
|
return id != null && id !== '' ? String(id) : 'p-' + index
|
|||
|
|
},
|
|||
|
|
panicTitle(item) {
|
|||
|
|
if (!item) return '--'
|
|||
|
|
return item.title || item.typeName || item.content || item.msg || `Alarm #${item.id || ''}`
|
|||
|
|
},
|
|||
|
|
panicTime(item) {
|
|||
|
|
if (!item) return ''
|
|||
|
|
return item.createTime || item.createdAt || item.time || item.alarmTime || ''
|
|||
|
|
},
|
|||
|
|
panicStatus(item) {
|
|||
|
|
if (!item) return ''
|
|||
|
|
const s = item.status ?? item.state ?? item.handleStatus
|
|||
|
|
if (s === undefined || s === null || s === '') return ''
|
|||
|
|
return String(s)
|
|||
|
|
},
|
|||
|
|
openPanic(item) {
|
|||
|
|
const id = item && item.id
|
|||
|
|
if (!id) {
|
|||
|
|
uni.showToast({ title: this.$i18n.t('requestFailed'), icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
uni.navigateTo({ url: `/pages/company/panic-detail?id=${id}` })
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped lang="scss">
|
|||
|
|
.page {
|
|||
|
|
min-height: 100vh;
|
|||
|
|
background-color: #f3f5f6;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tabback {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 160rpx;
|
|||
|
|
padding: 0 20rpx;
|
|||
|
|
padding-top: 80rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
position: fixed;
|
|||
|
|
top: 0;
|
|||
|
|
left: 0;
|
|||
|
|
z-index: 999;
|
|||
|
|
background-color: #fff;
|
|||
|
|
|
|||
|
|
.rtjt {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
color: #333;
|
|||
|
|
min-width: 48rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.name {
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: #333;
|
|||
|
|
max-width: 420rpx;
|
|||
|
|
overflow: hidden;
|
|||
|
|
text-overflow: ellipsis;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tabback-placeholder {
|
|||
|
|
width: 48rpx;
|
|||
|
|
height: 1rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.main-area {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 160rpx;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: calc(112rpx + env(safe-area-inset-bottom));
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.panel {
|
|||
|
|
height: 100%;
|
|||
|
|
padding: 16rpx 24rpx 24rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.state {
|
|||
|
|
text-align: center;
|
|||
|
|
padding: 48rpx 24rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.state--muted {
|
|||
|
|
color: #8b9199;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.state.sm {
|
|||
|
|
padding: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card {
|
|||
|
|
background: #fff;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
padding: 28rpx;
|
|||
|
|
margin-bottom: 24rpx;
|
|||
|
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card-media {
|
|||
|
|
margin-bottom: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card-logo {
|
|||
|
|
width: 120rpx;
|
|||
|
|
height: 120rpx;
|
|||
|
|
border-radius: 12rpx;
|
|||
|
|
display: block;
|
|||
|
|
background: #e8eaed;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card-logo--ph {
|
|||
|
|
border: 1rpx dashed #cfd4dc;
|
|||
|
|
background: #f0f2f5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card-name {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 34rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: #1a1a1a;
|
|||
|
|
line-height: 1.35;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card-line {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 12rpx;
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
color: #4b5563;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.company-card-desc {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 16rpx;
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
color: #6b7280;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-title {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: #374151;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
padding-left: 4rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cell {
|
|||
|
|
position: relative;
|
|||
|
|
background: #fff;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
padding: 24rpx 56rpx 24rpx 28rpx;
|
|||
|
|
margin-bottom: 16rpx;
|
|||
|
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cell--panic {
|
|||
|
|
padding-bottom: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cell-title {
|
|||
|
|
display: block;
|
|||
|
|
font-size: 30rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: #1a1a1a;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
padding-right: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cell-sub {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 10rpx;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #6b7280;
|
|||
|
|
line-height: 1.45;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cell-arrow {
|
|||
|
|
position: absolute;
|
|||
|
|
right: 24rpx;
|
|||
|
|
top: 50%;
|
|||
|
|
transform: translateY(-50%);
|
|||
|
|
font-size: 40rpx;
|
|||
|
|
color: #c4c8ce;
|
|||
|
|
line-height: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.panic-row-top {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.panic-badge {
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
color: #b45309;
|
|||
|
|
background: #fef3c7;
|
|||
|
|
padding: 6rpx 14rpx;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.cell-link {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 12rpx;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #2563eb;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.manage-placeholder {
|
|||
|
|
padding-top: 120rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.bottom-tabs {
|
|||
|
|
position: fixed;
|
|||
|
|
left: 0;
|
|||
|
|
right: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
z-index: 998;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: stretch;
|
|||
|
|
min-height: 100rpx;
|
|||
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|||
|
|
background: #fff;
|
|||
|
|
border-top: 1rpx solid #e8eaed;
|
|||
|
|
box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.04);
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.bottom-tab {
|
|||
|
|
flex: 1;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
padding: 20rpx 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.bottom-tab-text {
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
color: #8b9199;
|
|||
|
|
text-align: center;
|
|||
|
|
line-height: 1.3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.bottom-tab--active .bottom-tab-text {
|
|||
|
|
color: #0f0f0f;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
</style>
|