chore: initialize mini program frontend
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
const api = require('../../utils/api')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
locks: [],
|
||||
unreadRows: [],
|
||||
readRows: [],
|
||||
unreadPage: 1,
|
||||
readPage: 1,
|
||||
unreadPageInput: '1',
|
||||
readPageInput: '1',
|
||||
unreadTotal: 0,
|
||||
readTotal: 0,
|
||||
unreadTotalPages: 1,
|
||||
readTotalPages: 1,
|
||||
loading: false,
|
||||
refreshing: false,
|
||||
detailVisible: false,
|
||||
detailType: '',
|
||||
selectedLock: null,
|
||||
selectedFeedback: null,
|
||||
},
|
||||
onShow() {
|
||||
this.load().catch(error => {
|
||||
wx.showToast({ title: error.message || '加载失败', icon: 'none' })
|
||||
})
|
||||
},
|
||||
async onPullDownRefresh() {
|
||||
this.setData({ refreshing: true })
|
||||
try {
|
||||
await this.load()
|
||||
} finally {
|
||||
this.setData({ refreshing: false })
|
||||
if (wx.stopPullDownRefresh) {
|
||||
wx.stopPullDownRefresh()
|
||||
}
|
||||
}
|
||||
},
|
||||
async load() {
|
||||
this.setData({ loading: true })
|
||||
try {
|
||||
await Promise.all([
|
||||
this.loadLocks(),
|
||||
this.loadFeedbacks('unread', this.data.unreadPage),
|
||||
this.loadFeedbacks('read', this.data.readPage),
|
||||
])
|
||||
} finally {
|
||||
this.setData({ loading: false })
|
||||
}
|
||||
},
|
||||
async loadLocks() {
|
||||
const locks = await api.listMonitorLocks()
|
||||
this.setData({ locks })
|
||||
},
|
||||
async loadFeedbacks(box, page = 1) {
|
||||
const result = await api.listMoldLockFeedbacks({ box, page, pageSize: 10 })
|
||||
if (box === 'read') {
|
||||
this.setData({
|
||||
readRows: result.rows || [],
|
||||
readPage: result.page || 1,
|
||||
readPageInput: String(result.page || 1),
|
||||
readTotal: result.total || 0,
|
||||
readTotalPages: result.totalPages || 1,
|
||||
})
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
unreadRows: result.rows || [],
|
||||
unreadPage: result.page || 1,
|
||||
unreadPageInput: String(result.page || 1),
|
||||
unreadTotal: result.total || 0,
|
||||
unreadTotalPages: result.totalPages || 1,
|
||||
})
|
||||
},
|
||||
async changeFeedbackPage(e) {
|
||||
const box = e.currentTarget.dataset.box
|
||||
const direction = Number(e.currentTarget.dataset.direction || 0)
|
||||
const pageKey = box === 'read' ? 'readPage' : 'unreadPage'
|
||||
const totalPagesKey = box === 'read' ? 'readTotalPages' : 'unreadTotalPages'
|
||||
const nextPage = Math.max(1, Math.min(this.data[totalPagesKey], this.data[pageKey] + direction))
|
||||
await this.loadFeedbacks(box, nextPage)
|
||||
},
|
||||
onFeedbackPageInput(e) {
|
||||
const box = e.currentTarget.dataset.box
|
||||
const inputKey = box === 'read' ? 'readPageInput' : 'unreadPageInput'
|
||||
this.setData({ [inputKey]: e.detail.value })
|
||||
},
|
||||
async jumpFeedbackPage(e) {
|
||||
wx.hideKeyboard()
|
||||
const box = e.currentTarget.dataset.box
|
||||
const pageKey = box === 'read' ? 'readPage' : 'unreadPage'
|
||||
const inputKey = box === 'read' ? 'readPageInput' : 'unreadPageInput'
|
||||
const totalPagesKey = box === 'read' ? 'readTotalPages' : 'unreadTotalPages'
|
||||
const inputValue = e && e.detail && e.detail.value !== undefined ? e.detail.value : this.data[inputKey]
|
||||
const target = Math.max(1, Math.min(Number(inputValue) || this.data[pageKey], this.data[totalPagesKey]))
|
||||
if (target === this.data[pageKey]) {
|
||||
this.setData({ [inputKey]: String(this.data[pageKey] || 1) })
|
||||
return
|
||||
}
|
||||
await this.loadFeedbacks(box, target)
|
||||
},
|
||||
openLock(e) {
|
||||
const index = Number(e.currentTarget.dataset.index)
|
||||
const selectedLock = this.data.locks[index]
|
||||
if (!selectedLock) {
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
detailVisible: true,
|
||||
detailType: 'lock',
|
||||
selectedLock,
|
||||
selectedFeedback: null,
|
||||
})
|
||||
},
|
||||
async openFeedback(e) {
|
||||
const box = e.currentTarget.dataset.box
|
||||
const index = Number(e.currentTarget.dataset.index)
|
||||
const rows = box === 'read' ? this.data.readRows : this.data.unreadRows
|
||||
const feedback = rows[index]
|
||||
if (!feedback) {
|
||||
return
|
||||
}
|
||||
wx.showLoading({ title: '加载中' })
|
||||
try {
|
||||
const selectedFeedback = box === 'unread'
|
||||
? await api.readMoldLockFeedback(feedback.id)
|
||||
: feedback
|
||||
this.setData({
|
||||
detailVisible: true,
|
||||
detailType: 'feedback',
|
||||
selectedLock: null,
|
||||
selectedFeedback,
|
||||
})
|
||||
if (box === 'unread') {
|
||||
await Promise.all([
|
||||
this.loadFeedbacks('unread', this.data.unreadPage),
|
||||
this.loadFeedbacks('read', 1),
|
||||
])
|
||||
}
|
||||
} catch (error) {
|
||||
wx.showToast({ title: error.message || '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
wx.hideLoading()
|
||||
}
|
||||
},
|
||||
closeDetail() {
|
||||
this.setData({
|
||||
detailVisible: false,
|
||||
detailType: '',
|
||||
selectedLock: null,
|
||||
selectedFeedback: null,
|
||||
})
|
||||
},
|
||||
noop() {},
|
||||
async releaseFromLock() {
|
||||
const lock = this.data.selectedLock
|
||||
if (!lock) {
|
||||
return
|
||||
}
|
||||
wx.showLoading({ title: '解除中' })
|
||||
try {
|
||||
await api.releaseMoldLock(lock.id)
|
||||
wx.showToast({ title: '已解除占用', icon: 'success' })
|
||||
this.closeDetail()
|
||||
await this.load()
|
||||
} catch (error) {
|
||||
wx.showToast({ title: error.message || '解除失败', icon: 'none' })
|
||||
} finally {
|
||||
wx.hideLoading()
|
||||
}
|
||||
},
|
||||
async releaseFromFeedback() {
|
||||
const feedback = this.data.selectedFeedback
|
||||
if (!feedback || !feedback.canRelease) {
|
||||
return
|
||||
}
|
||||
wx.showLoading({ title: '解除中' })
|
||||
try {
|
||||
const selectedFeedback = await api.releaseMoldLockByFeedback(feedback.id)
|
||||
wx.showToast({ title: '已解除占用', icon: 'success' })
|
||||
this.setData({ selectedFeedback })
|
||||
await Promise.all([
|
||||
this.loadLocks(),
|
||||
this.loadFeedbacks('unread', this.data.unreadPage),
|
||||
this.loadFeedbacks('read', this.data.readPage),
|
||||
])
|
||||
} catch (error) {
|
||||
wx.showToast({ title: error.message || '解除失败', icon: 'none' })
|
||||
} finally {
|
||||
wx.hideLoading()
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "智能监控",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<scroll-view
|
||||
class="page safe-bottom"
|
||||
scroll-y
|
||||
type="list"
|
||||
refresher-enabled
|
||||
refresher-triggered="{{refreshing}}"
|
||||
bindrefresherrefresh="onPullDownRefresh"
|
||||
>
|
||||
<view class="header">
|
||||
<text class="title">智能监控</text>
|
||||
<text class="subtitle">查看当前模具占用和员工反馈</text>
|
||||
</view>
|
||||
|
||||
<view class="section-title">反馈信箱</view>
|
||||
<view class="mail-grid">
|
||||
<view class="mail-card">
|
||||
<view class="mail-head">
|
||||
<view class="mail-title">
|
||||
<text class="mail-icon unread">未</text>
|
||||
<text class="value">未读信箱</text>
|
||||
</view>
|
||||
<text class="mail-badge">{{unreadTotal}}</text>
|
||||
</view>
|
||||
<view wx:if="{{!unreadRows.length}}" class="mail-empty">暂无未读反馈</view>
|
||||
<view
|
||||
wx:for="{{unreadRows}}"
|
||||
wx:key="id"
|
||||
wx:for-index="index"
|
||||
class="feedback-row unread-row"
|
||||
data-box="unread"
|
||||
data-index="{{index}}"
|
||||
bindtap="openFeedback"
|
||||
>
|
||||
<text class="feedback-title">{{item.moldDisplayName}}</text>
|
||||
<text class="feedback-sub">{{item.reporterName || item.reporterPhone}} 反馈 {{item.occupiedName || item.occupiedPhone}}</text>
|
||||
<text class="feedback-time">{{item.feedbackAtText}}</text>
|
||||
</view>
|
||||
<view class="pager">
|
||||
<button class="btn mini secondary" data-box="unread" data-direction="-1" bindtap="changeFeedbackPage" disabled="{{unreadPage <= 1}}">上一页</button>
|
||||
<view class="page-jump-control mini">
|
||||
<input class="page-jump-input" type="number" confirm-type="done" value="{{unreadPageInput}}" data-box="unread" bindinput="onFeedbackPageInput" bindconfirm="jumpFeedbackPage" />
|
||||
<text class="page-total-label">/ {{unreadTotalPages}}</text>
|
||||
<text class="page-jump-action" data-box="unread" bindtap="jumpFeedbackPage">跳</text>
|
||||
</view>
|
||||
<button class="btn mini secondary" data-box="unread" data-direction="1" bindtap="changeFeedbackPage" disabled="{{unreadPage >= unreadTotalPages}}">下一页</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mail-card">
|
||||
<view class="mail-head">
|
||||
<view class="mail-title">
|
||||
<text class="mail-icon read">读</text>
|
||||
<text class="value">已读信箱</text>
|
||||
</view>
|
||||
<text class="mail-badge muted-badge">{{readTotal}}</text>
|
||||
</view>
|
||||
<view wx:if="{{!readRows.length}}" class="mail-empty">暂无已读反馈</view>
|
||||
<view
|
||||
wx:for="{{readRows}}"
|
||||
wx:key="id"
|
||||
wx:for-index="index"
|
||||
class="feedback-row"
|
||||
data-box="read"
|
||||
data-index="{{index}}"
|
||||
bindtap="openFeedback"
|
||||
>
|
||||
<view class="feedback-title-line">
|
||||
<text class="feedback-title">{{item.moldDisplayName}}</text>
|
||||
<text class="status-text {{item.isHandled ? 'handled' : 'pending'}}">{{item.statusName}}</text>
|
||||
</view>
|
||||
<text class="feedback-sub">{{item.reporterName || item.reporterPhone}} 反馈 {{item.occupiedName || item.occupiedPhone}}</text>
|
||||
<text class="feedback-time">{{item.readAtText || item.feedbackAtText}}</text>
|
||||
</view>
|
||||
<view class="pager">
|
||||
<button class="btn mini secondary" data-box="read" data-direction="-1" bindtap="changeFeedbackPage" disabled="{{readPage <= 1}}">上一页</button>
|
||||
<view class="page-jump-control mini">
|
||||
<input class="page-jump-input" type="number" confirm-type="done" value="{{readPageInput}}" data-box="read" bindinput="onFeedbackPageInput" bindconfirm="jumpFeedbackPage" />
|
||||
<text class="page-total-label">/ {{readTotalPages}}</text>
|
||||
<text class="page-jump-action" data-box="read" bindtap="jumpFeedbackPage">跳</text>
|
||||
</view>
|
||||
<button class="btn mini secondary" data-box="read" data-direction="1" bindtap="changeFeedbackPage" disabled="{{readPage >= readTotalPages}}">下一页</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="section-title">生产监控</view>
|
||||
<view class="card monitor-card">
|
||||
<view class="monitor-head">
|
||||
<view>
|
||||
<text class="value">当前占用模具</text>
|
||||
<text class="subtitle">只显示已经被员工打卡上班占用的模具</text>
|
||||
</view>
|
||||
<text class="monitor-mark">监控</text>
|
||||
</view>
|
||||
<view wx:if="{{!locks.length}}" class="list-empty inline-empty">暂无占用中的模具</view>
|
||||
<view wx:else class="mold-grid">
|
||||
<view
|
||||
wx:for="{{locks}}"
|
||||
wx:key="id"
|
||||
wx:for-index="index"
|
||||
class="mold-tile"
|
||||
data-index="{{index}}"
|
||||
bindtap="openLock"
|
||||
>
|
||||
<view class="mold-icon">模</view>
|
||||
<text class="mold-name">{{item.moldDisplayName}}</text>
|
||||
<text class="mold-worker">{{item.occupiedName || item.occupiedPhone}}</text>
|
||||
<text class="mold-duration">{{item.occupiedDurationText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view wx:if="{{detailVisible}}" class="modal-mask" catchtap="closeDetail">
|
||||
<view class="modal-panel" catchtap="noop">
|
||||
<view class="modal-head">
|
||||
<text class="modal-title">{{detailType === 'lock' ? '占用详情' : '反馈详情'}}</text>
|
||||
<button class="btn mini secondary modal-close" bindtap="closeDetail">关闭</button>
|
||||
</view>
|
||||
|
||||
<block wx:if="{{detailType === 'lock' && selectedLock}}">
|
||||
<view class="detail-row">
|
||||
<text class="label">模具名</text>
|
||||
<text class="value">{{selectedLock.moldDisplayName}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">占用人员</text>
|
||||
<text class="value">{{selectedLock.occupiedName || selectedLock.occupiedPhone}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">本次占用开始时间</text>
|
||||
<text class="value">{{selectedLock.occupiedStartAtText}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">已占用时长</text>
|
||||
<text class="value">{{selectedLock.occupiedDurationText}}</text>
|
||||
</view>
|
||||
<button class="btn danger full detail-action" bindtap="releaseFromLock">强制解除占用</button>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{detailType === 'feedback' && selectedFeedback}}">
|
||||
<view class="detail-row">
|
||||
<text class="label">反馈人员姓名</text>
|
||||
<text class="value">{{selectedFeedback.reporterName || selectedFeedback.reporterPhone}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">占用人员姓名</text>
|
||||
<text class="value">{{selectedFeedback.occupiedName || selectedFeedback.occupiedPhone}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">模具名</text>
|
||||
<text class="value">{{selectedFeedback.moldDisplayName}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">反馈时间</text>
|
||||
<text class="value">{{selectedFeedback.feedbackAtText}}</text>
|
||||
</view>
|
||||
<view class="detail-row">
|
||||
<text class="label">处理状态</text>
|
||||
<text class="status-text detail-status {{selectedFeedback.isHandled ? 'handled' : 'pending'}}">{{selectedFeedback.statusName}}</text>
|
||||
</view>
|
||||
<button wx:if="{{selectedFeedback.canRelease}}" class="btn danger full detail-action" bindtap="releaseFromFeedback">一键解除占用</button>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,310 @@
|
||||
.mail-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.mail-card {
|
||||
min-width: 0;
|
||||
padding: 22rpx;
|
||||
border: 3rpx solid #aebbd0;
|
||||
border-radius: 16rpx;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
|
||||
box-shadow:
|
||||
0 0 0 2rpx rgba(255, 255, 255, 0.9),
|
||||
0 11rpx 0 rgba(147, 163, 185, 0.68),
|
||||
0 20rpx 32rpx rgba(22, 34, 50, 0.15),
|
||||
inset 0 2rpx 0 rgba(255, 255, 255, 0.96);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mail-head,
|
||||
.mail-title,
|
||||
.feedback-title-line,
|
||||
.monitor-head,
|
||||
.pager {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mail-head,
|
||||
.monitor-head {
|
||||
justify-content: space-between;
|
||||
gap: 14rpx;
|
||||
}
|
||||
|
||||
.mail-title {
|
||||
min-width: 0;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.mail-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 46rpx;
|
||||
height: 46rpx;
|
||||
flex: 0 0 46rpx;
|
||||
border-radius: 12rpx;
|
||||
color: #ffffff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
box-shadow:
|
||||
0 6rpx 0 rgba(15, 23, 42, 0.16),
|
||||
inset 0 2rpx 0 rgba(255, 255, 255, 0.28);
|
||||
}
|
||||
|
||||
.mail-icon.unread {
|
||||
background: linear-gradient(180deg, #ef4444 0%, #b91c1c 100%);
|
||||
}
|
||||
|
||||
.mail-icon.read {
|
||||
background: linear-gradient(180deg, #64748b 0%, #334155 100%);
|
||||
}
|
||||
|
||||
.mail-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 42rpx;
|
||||
height: 42rpx;
|
||||
padding: 0 12rpx;
|
||||
border-radius: 999rpx;
|
||||
background: #ef4444;
|
||||
color: #ffffff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.muted-badge {
|
||||
background: #64748b;
|
||||
}
|
||||
|
||||
.mail-empty {
|
||||
margin-top: 22rpx;
|
||||
padding: 22rpx 12rpx;
|
||||
border: 2rpx dashed #b8c4d4;
|
||||
border-radius: 14rpx;
|
||||
color: #667085;
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feedback-row {
|
||||
margin-top: 18rpx;
|
||||
padding: 18rpx;
|
||||
border: 2rpx solid #c7d2e3;
|
||||
border-left: 7rpx solid #64748b;
|
||||
border-radius: 14rpx;
|
||||
background: #f8fbff;
|
||||
box-shadow: 0 7rpx 0 rgba(148, 163, 184, 0.24);
|
||||
}
|
||||
|
||||
.unread-row {
|
||||
border-left-color: #ef4444;
|
||||
}
|
||||
|
||||
.feedback-title {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
color: #162232;
|
||||
font-size: 26rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.35;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.feedback-title-line {
|
||||
justify-content: space-between;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.feedback-sub,
|
||||
.feedback-time,
|
||||
.mold-worker,
|
||||
.mold-duration {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
color: #667085;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
flex: 0 0 auto;
|
||||
font-size: 22rpx;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.status-text.pending {
|
||||
color: #d92d20;
|
||||
}
|
||||
|
||||
.status-text.handled {
|
||||
color: #087443;
|
||||
}
|
||||
|
||||
.pager {
|
||||
justify-content: space-between;
|
||||
gap: 10rpx;
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
.pager .btn {
|
||||
min-width: 82rpx;
|
||||
padding: 0 8rpx;
|
||||
margin: 0;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.pager .page-jump-control.mini {
|
||||
flex-basis: 152rpx;
|
||||
gap: 4rpx;
|
||||
padding: 0 6rpx;
|
||||
}
|
||||
|
||||
.pager .page-jump-control.mini .page-jump-input {
|
||||
flex-basis: 42rpx;
|
||||
}
|
||||
|
||||
.pager .page-jump-control.mini .page-total-label {
|
||||
min-width: 50rpx;
|
||||
font-size: 18rpx;
|
||||
}
|
||||
|
||||
.pager .page-jump-control.mini .page-jump-action {
|
||||
width: 28rpx;
|
||||
font-size: 18rpx;
|
||||
}
|
||||
|
||||
.monitor-card {
|
||||
margin-bottom: 34rpx;
|
||||
}
|
||||
|
||||
.monitor-mark {
|
||||
flex: 0 0 auto;
|
||||
padding: 10rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #e9f1ff;
|
||||
color: #1456c2;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.inline-empty {
|
||||
margin-top: 22rpx;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mold-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150rpx, 1fr));
|
||||
gap: 18rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.mold-tile {
|
||||
min-height: 210rpx;
|
||||
padding: 18rpx 14rpx;
|
||||
border: 2rpx solid #bcc8d9;
|
||||
border-radius: 16rpx;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #eef5ff 100%);
|
||||
text-align: center;
|
||||
box-shadow:
|
||||
0 8rpx 0 rgba(148, 163, 184, 0.54),
|
||||
0 16rpx 26rpx rgba(22, 34, 50, 0.12),
|
||||
inset 0 2rpx 0 rgba(255, 255, 255, 0.96);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mold-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
margin: 0 auto 14rpx;
|
||||
border-radius: 18rpx;
|
||||
background: linear-gradient(180deg, #1d4ed8 0%, #153e9f 100%);
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 900;
|
||||
box-shadow:
|
||||
0 7rpx 0 rgba(21, 62, 159, 0.42),
|
||||
inset 0 2rpx 0 rgba(255, 255, 255, 0.28);
|
||||
}
|
||||
|
||||
.mold-name {
|
||||
display: block;
|
||||
color: #162232;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.35;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 80;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 32rpx;
|
||||
background: rgba(15, 23, 42, 0.48);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.modal-panel {
|
||||
width: 100%;
|
||||
max-height: 82vh;
|
||||
overflow-y: auto;
|
||||
padding: 30rpx;
|
||||
border: 1rpx solid #e4e9f1;
|
||||
border-radius: 18rpx;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
|
||||
box-shadow:
|
||||
0 16rpx 0 rgba(170, 184, 204, 0.62),
|
||||
0 30rpx 64rpx rgba(15, 23, 42, 0.24),
|
||||
inset 0 2rpx 0 rgba(255, 255, 255, 0.96);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.modal-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 18rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
color: #162232;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
margin-top: 22rpx;
|
||||
padding-bottom: 18rpx;
|
||||
border-bottom: 1rpx solid #e4e9f1;
|
||||
}
|
||||
|
||||
.detail-status {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.detail-action {
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user