2026-03-14 15:06:18 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="aps-quick-sheet-preview excel-theme">
|
|
|
|
|
|
<div class="sheet-toolbar">
|
|
|
|
|
|
<div class="sheet-actions">
|
|
|
|
|
|
<el-date-picker
|
|
|
|
|
|
v-model="filter.range"
|
|
|
|
|
|
type="daterange"
|
|
|
|
|
|
range-separator="至"
|
|
|
|
|
|
start-placeholder="开始日期"
|
|
|
|
|
|
end-placeholder="结束日期"
|
|
|
|
|
|
value-format="yyyy-MM-dd"
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
style="width: 240px"
|
|
|
|
|
|
@change="onFilterChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<el-select v-model="filter.lineId" clearable filterable size="small" placeholder="产线" style="width: 160px" @change="onFilterChange">
|
|
|
|
|
|
<el-option v-for="line in lineOptions" :key="line.lineId" :label="line.lineName || line.lineCode || ('产线' + line.lineId)" :value="line.lineId" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
<el-input v-model="filter.customer" size="small" clearable placeholder="客户" style="width: 160px" @input="onFilterChange" />
|
|
|
|
|
|
<el-button size="small" icon="el-icon-refresh" @click="loadRows">刷新</el-button>
|
2026-03-23 15:33:12 +08:00
|
|
|
|
<el-button size="small" icon="el-icon-setting" @click="columnSettingVisible = true">列设置</el-button>
|
2026-03-14 15:06:18 +08:00
|
|
|
|
<el-button size="small" icon="el-icon-download" @click="exportExcel">导出</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="sheet-body">
|
|
|
|
|
|
<el-table
|
2026-03-23 15:33:12 +08:00
|
|
|
|
ref="quickSheetPreviewTable"
|
2026-03-14 15:06:18 +08:00
|
|
|
|
v-loading="loading"
|
|
|
|
|
|
:data="displayRows"
|
|
|
|
|
|
border
|
|
|
|
|
|
size="mini"
|
|
|
|
|
|
class="excel-table"
|
|
|
|
|
|
>
|
2026-03-23 15:33:12 +08:00
|
|
|
|
<el-table-column label="序号" width="60" align="center" fixed="left">
|
2026-03-14 15:06:18 +08:00
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
|
{{ ((pager.pageNum - 1) * pager.pageSize) + scope.$index + 1 }}
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column
|
2026-03-23 15:33:12 +08:00
|
|
|
|
v-for="col in displayColumns"
|
2026-03-14 15:06:18 +08:00
|
|
|
|
:key="col.prop || col.label"
|
|
|
|
|
|
:label="col.label"
|
|
|
|
|
|
:prop="col.prop"
|
|
|
|
|
|
:width="col.width"
|
|
|
|
|
|
:min-width="col.minWidth"
|
|
|
|
|
|
:align="col.align || 'center'"
|
2026-03-23 15:33:12 +08:00
|
|
|
|
:fixed="fixedProps.includes(col.prop) ? 'left' : false"
|
2026-03-14 15:06:18 +08:00
|
|
|
|
:show-overflow-tooltip="col.showOverflowTooltip !== false"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<div class="pager-wrap">
|
|
|
|
|
|
<el-pagination
|
|
|
|
|
|
small
|
|
|
|
|
|
background
|
|
|
|
|
|
layout="prev, pager, next, total"
|
|
|
|
|
|
:current-page.sync="pager.pageNum"
|
|
|
|
|
|
:page-size="pager.pageSize"
|
|
|
|
|
|
:total="totalRows"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-03-23 15:33:12 +08:00
|
|
|
|
|
|
|
|
|
|
<el-drawer
|
|
|
|
|
|
title="列设置"
|
|
|
|
|
|
:visible.sync="columnSettingVisible"
|
|
|
|
|
|
direction="rtl"
|
|
|
|
|
|
size="55%"
|
2026-03-23 15:39:02 +08:00
|
|
|
|
append-to-body
|
|
|
|
|
|
@open="resetColumnDraft">
|
2026-03-23 15:33:12 +08:00
|
|
|
|
<div class="col-setting-body">
|
|
|
|
|
|
<div class="col-setting-toolbar">
|
|
|
|
|
|
<el-button size="mini" @click="restoreDefaultColumns">恢复默认</el-button>
|
2026-03-23 15:39:02 +08:00
|
|
|
|
<el-button size="mini" @click="resetColumnDraft">重置</el-button>
|
|
|
|
|
|
<el-button size="mini" type="primary" @click="saveColumnSettings">保存</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-section">
|
|
|
|
|
|
<div class="col-section-title">固定列(最多5列)</div>
|
|
|
|
|
|
<draggable v-model="fixedColumnList" handle=".drag-handle" animation="200" class="col-setting-grid">
|
|
|
|
|
|
<div v-for="item in fixedColumnList" :key="`fixed-${item.prop}`" class="col-setting-item">
|
|
|
|
|
|
<i class="el-icon-rank drag-handle" />
|
|
|
|
|
|
<span class="col-label">{{ item.label }}</span>
|
|
|
|
|
|
<el-button type="text" size="mini" @click="removeFromFixed(item.prop)">移除</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</draggable>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-section">
|
|
|
|
|
|
<div class="col-section-title">其他列</div>
|
|
|
|
|
|
<draggable v-model="normalColumnList" handle=".drag-handle" animation="200" class="col-setting-grid">
|
|
|
|
|
|
<div v-for="item in normalColumnList" :key="`normal-${item.prop}`" class="col-setting-item">
|
|
|
|
|
|
<i class="el-icon-rank drag-handle" />
|
|
|
|
|
|
<span class="col-label">{{ item.label }}</span>
|
|
|
|
|
|
<el-button type="text" size="mini" @click="addToFixed(item.prop)">加入固定</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</draggable>
|
2026-03-23 15:33:12 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-drawer>
|
2026-03-14 15:06:18 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { fetchQuickSheetList, exportQuickSheet } from '@/api/aps/quickSheet'
|
|
|
|
|
|
import { listProductionLine } from '@/api/wms/productionLine'
|
|
|
|
|
|
import { getTemplateByKey } from './sheets/templates'
|
|
|
|
|
|
import { saveAs } from 'file-saver'
|
2026-03-23 15:33:12 +08:00
|
|
|
|
import draggable from 'vuedraggable'
|
2026-03-14 15:06:18 +08:00
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: 'ApsQuickSheetPreview',
|
2026-03-23 15:33:12 +08:00
|
|
|
|
components: { draggable },
|
2026-03-14 15:06:18 +08:00
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
loading: false,
|
|
|
|
|
|
rows: [],
|
|
|
|
|
|
lineOptions: [],
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
range: [],
|
|
|
|
|
|
lineId: null,
|
|
|
|
|
|
customer: ''
|
|
|
|
|
|
},
|
|
|
|
|
|
pager: {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 25
|
2026-03-23 15:33:12 +08:00
|
|
|
|
},
|
|
|
|
|
|
columnSettingVisible: false,
|
2026-03-23 15:39:02 +08:00
|
|
|
|
columnSettingList: [],
|
|
|
|
|
|
fixedColumnList: [],
|
|
|
|
|
|
normalColumnList: []
|
2026-03-14 15:06:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
currentTemplate() {
|
|
|
|
|
|
return getTemplateByKey('unified')
|
|
|
|
|
|
},
|
|
|
|
|
|
flatColumns() {
|
|
|
|
|
|
const res = []
|
|
|
|
|
|
const loop = (cols) => {
|
|
|
|
|
|
;(cols || []).forEach(c => {
|
|
|
|
|
|
if (c.children && c.children.length) loop(c.children)
|
|
|
|
|
|
else res.push(c)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
loop(this.currentTemplate.columns || [])
|
2026-03-23 15:33:12 +08:00
|
|
|
|
return res.filter(c => c && c.prop)
|
|
|
|
|
|
},
|
|
|
|
|
|
displayColumns() {
|
|
|
|
|
|
const setting = this.columnSettingList || []
|
|
|
|
|
|
const hasSetting = setting.length > 0
|
|
|
|
|
|
const base = this.flatColumns
|
|
|
|
|
|
|
|
|
|
|
|
const selected = hasSetting
|
|
|
|
|
|
? setting.filter(i => i.visible).map(i => base.find(c => c.prop === i.prop)).filter(Boolean)
|
|
|
|
|
|
: base
|
|
|
|
|
|
|
|
|
|
|
|
const selectedSet = new Set(selected.map(c => c.prop))
|
|
|
|
|
|
const rest = base.filter(c => !selectedSet.has(c.prop))
|
|
|
|
|
|
return [...selected, ...rest]
|
2026-03-14 15:06:18 +08:00
|
|
|
|
},
|
2026-03-23 15:39:02 +08:00
|
|
|
|
fixedProps() {
|
|
|
|
|
|
return (this.columnSettingList || []).filter(i => i.visible && i.fixed).map(i => i.prop).slice(0, 5)
|
|
|
|
|
|
},
|
2026-03-14 15:06:18 +08:00
|
|
|
|
filteredRows() {
|
|
|
|
|
|
const [startAfter, endBefore] = this.filter.range || []
|
|
|
|
|
|
const lineName = (this.filter.lineName || '').trim()
|
|
|
|
|
|
const customer = (this.filter.customer || '').trim().toLowerCase()
|
|
|
|
|
|
return this.rows.filter(r => {
|
|
|
|
|
|
if (startAfter || endBefore) {
|
|
|
|
|
|
const d = r.startTime ? String(r.startTime).slice(0, 10) : ''
|
|
|
|
|
|
if (startAfter && d && d < startAfter) return false
|
|
|
|
|
|
if (endBefore && d && d > endBefore) return false
|
|
|
|
|
|
}
|
|
|
|
|
|
if (lineName && r.lineName !== lineName) return false
|
|
|
|
|
|
if (customer) {
|
|
|
|
|
|
const txt = String(r.customerName || '').toLowerCase()
|
|
|
|
|
|
if (!txt.includes(customer)) return false
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
displayRows() {
|
|
|
|
|
|
const start = (this.pager.pageNum - 1) * this.pager.pageSize
|
|
|
|
|
|
return this.filteredRows.slice(start, start + this.pager.pageSize)
|
|
|
|
|
|
},
|
|
|
|
|
|
totalRows() {
|
|
|
|
|
|
return this.filteredRows.length
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
created() {
|
|
|
|
|
|
const today = new Date()
|
|
|
|
|
|
const start = `${today.getFullYear()}-${`${today.getMonth() + 1}`.padStart(2, '0')}-${`${today.getDate()}`.padStart(2, '0')}`
|
|
|
|
|
|
this.filter.range = [start, '']
|
2026-03-23 15:33:12 +08:00
|
|
|
|
this.initColumnSettings()
|
2026-03-14 15:06:18 +08:00
|
|
|
|
this.loadRows()
|
|
|
|
|
|
this.loadLines()
|
|
|
|
|
|
},
|
2026-03-23 15:33:12 +08:00
|
|
|
|
beforeDestroy() {
|
|
|
|
|
|
this.persistColumnSettings()
|
|
|
|
|
|
},
|
2026-03-14 15:06:18 +08:00
|
|
|
|
methods: {
|
2026-03-23 15:33:12 +08:00
|
|
|
|
initColumnSettings() {
|
|
|
|
|
|
const key = this.getColumnSettingKey()
|
|
|
|
|
|
const stored = localStorage.getItem(key)
|
2026-03-23 15:39:02 +08:00
|
|
|
|
const base = this.flatColumns.map((col, idx) => ({ prop: col.prop, label: col.label, visible: true, fixed: idx < 5 }))
|
2026-03-23 15:33:12 +08:00
|
|
|
|
if (!stored) {
|
|
|
|
|
|
this.columnSettingList = base
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
const parsed = JSON.parse(stored)
|
|
|
|
|
|
if (!Array.isArray(parsed)) {
|
|
|
|
|
|
this.columnSettingList = base
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const map = new Map(parsed.map(item => [item.prop, item]))
|
|
|
|
|
|
const merged = base.map(item => {
|
|
|
|
|
|
const saved = map.get(item.prop)
|
|
|
|
|
|
return saved ? { ...item, visible: saved.visible !== false } : item
|
|
|
|
|
|
})
|
|
|
|
|
|
const savedProps = parsed.map(i => i.prop)
|
|
|
|
|
|
const extras = base.filter(i => !savedProps.includes(i.prop))
|
|
|
|
|
|
this.columnSettingList = [...parsed.filter(i => base.some(b => b.prop === i.prop)).map(i => {
|
|
|
|
|
|
const match = base.find(b => b.prop === i.prop)
|
2026-03-23 15:39:02 +08:00
|
|
|
|
return { ...match, visible: i.visible !== false, fixed: i.fixed === true }
|
2026-03-23 15:33:12 +08:00
|
|
|
|
}), ...extras]
|
2026-03-23 15:39:02 +08:00
|
|
|
|
this.resetColumnDraft()
|
2026-03-23 15:33:12 +08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
|
this.columnSettingList = base
|
2026-03-23 15:39:02 +08:00
|
|
|
|
this.resetColumnDraft()
|
2026-03-23 15:33:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-03-23 15:39:02 +08:00
|
|
|
|
resetColumnDraft() {
|
|
|
|
|
|
const fixed = (this.columnSettingList || []).filter(i => i.visible && i.fixed).slice(0, 5)
|
|
|
|
|
|
const normal = (this.columnSettingList || []).filter(i => !i.fixed || !i.visible)
|
|
|
|
|
|
this.fixedColumnList = fixed.map(i => ({ ...i, visible: true, fixed: true }))
|
|
|
|
|
|
this.normalColumnList = normal.map(i => ({ ...i, visible: true, fixed: false }))
|
|
|
|
|
|
},
|
|
|
|
|
|
saveColumnSettings() {
|
|
|
|
|
|
const fixed = (this.fixedColumnList || []).map(i => ({ ...i, visible: true, fixed: true }))
|
|
|
|
|
|
const normal = (this.normalColumnList || []).map(i => ({ ...i, fixed: false }))
|
|
|
|
|
|
this.columnSettingList = [...fixed, ...normal]
|
|
|
|
|
|
this.persistColumnSettings()
|
|
|
|
|
|
this.columnSettingVisible = false
|
|
|
|
|
|
this.pager.pageNum = 1
|
|
|
|
|
|
this.loadRows().finally(() => {
|
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
|
this.$refs.quickSheetPreviewTable && this.$refs.quickSheetPreviewTable.doLayout && this.$refs.quickSheetPreviewTable.doLayout()
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
addToFixed(prop) {
|
|
|
|
|
|
if ((this.fixedColumnList || []).length >= 5) {
|
|
|
|
|
|
this.$message.warning('固定列最多5列')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
const idx = (this.normalColumnList || []).findIndex(i => i.prop === prop)
|
|
|
|
|
|
if (idx < 0) return
|
|
|
|
|
|
const item = this.normalColumnList.splice(idx, 1)[0]
|
|
|
|
|
|
this.fixedColumnList.push({ ...item, fixed: true, visible: true })
|
|
|
|
|
|
},
|
|
|
|
|
|
removeFromFixed(prop) {
|
|
|
|
|
|
const idx = (this.fixedColumnList || []).findIndex(i => i.prop === prop)
|
|
|
|
|
|
if (idx < 0) return
|
|
|
|
|
|
const item = this.fixedColumnList.splice(idx, 1)[0]
|
|
|
|
|
|
this.normalColumnList.push({ ...item, fixed: false, visible: true })
|
|
|
|
|
|
},
|
2026-03-23 15:33:12 +08:00
|
|
|
|
persistColumnSettings() {
|
|
|
|
|
|
const key = this.getColumnSettingKey()
|
|
|
|
|
|
const payload = (this.columnSettingList || []).map(item => ({
|
|
|
|
|
|
prop: item.prop,
|
|
|
|
|
|
label: item.label,
|
2026-03-23 15:39:02 +08:00
|
|
|
|
visible: item.visible !== false,
|
|
|
|
|
|
fixed: item.fixed === true
|
2026-03-23 15:33:12 +08:00
|
|
|
|
}))
|
|
|
|
|
|
localStorage.setItem(key, JSON.stringify(payload))
|
|
|
|
|
|
},
|
|
|
|
|
|
restoreDefaultColumns() {
|
2026-03-23 15:39:02 +08:00
|
|
|
|
const base = this.flatColumns.map((col, idx) => ({ prop: col.prop, label: col.label, visible: true, fixed: idx < 5 }))
|
2026-03-23 15:33:12 +08:00
|
|
|
|
this.columnSettingList = base
|
2026-03-23 15:39:02 +08:00
|
|
|
|
this.resetColumnDraft()
|
2026-03-23 15:33:12 +08:00
|
|
|
|
this.persistColumnSettings()
|
|
|
|
|
|
},
|
|
|
|
|
|
getColumnSettingKey() {
|
|
|
|
|
|
return 'apsQuickSheetPreviewColumns_unified'
|
|
|
|
|
|
},
|
2026-03-14 15:06:18 +08:00
|
|
|
|
async loadLines() {
|
|
|
|
|
|
const res = await listProductionLine({ pageNum: 1, pageSize: 1000 })
|
|
|
|
|
|
this.lineOptions = res.rows || []
|
|
|
|
|
|
},
|
|
|
|
|
|
async loadRows() {
|
|
|
|
|
|
this.loading = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const params = this.buildQueryParams()
|
|
|
|
|
|
const res = await fetchQuickSheetList(params)
|
|
|
|
|
|
this.rows = (res.data || []).map(r => ({ ...r }))
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
this.loading = false
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onFilterChange() {
|
|
|
|
|
|
this.pager.pageNum = 1
|
|
|
|
|
|
this.loadRows()
|
|
|
|
|
|
},
|
|
|
|
|
|
exportExcel() {
|
|
|
|
|
|
const params = this.buildQueryParams()
|
|
|
|
|
|
exportQuickSheet(params)
|
|
|
|
|
|
.then(blob => {
|
|
|
|
|
|
const filename = `quick_sheet_preview_${new Date().getTime()}.xlsx`
|
|
|
|
|
|
saveAs(new Blob([blob], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), filename)
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
buildQueryParams() {
|
|
|
|
|
|
const [startDate, endDate] = this.filter.range || []
|
|
|
|
|
|
return {
|
|
|
|
|
|
startDate: startDate || undefined,
|
|
|
|
|
|
endDate: endDate || undefined,
|
|
|
|
|
|
lineId: this.filter.lineId || undefined,
|
|
|
|
|
|
customerName: this.filter.customer || undefined
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.aps-quick-sheet-preview {
|
|
|
|
|
|
padding: 8px;
|
|
|
|
|
|
background: #f7f9fc;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sheet-toolbar {
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
padding: 8px;
|
|
|
|
|
|
border: 1px solid #eef2f7;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sheet-actions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sheet-body {
|
|
|
|
|
|
border: 1px solid #eef2f7;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
padding: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
::v-deep .excel-table {
|
|
|
|
|
|
border: 1px solid #edf1f7;
|
|
|
|
|
|
}
|
|
|
|
|
|
::v-deep .excel-table th.el-table__cell {
|
|
|
|
|
|
background: #fafbfe;
|
|
|
|
|
|
color: #5d6b82;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
border-right: 1px solid #edf1f7;
|
|
|
|
|
|
border-bottom: 1px solid #edf1f7;
|
|
|
|
|
|
padding: 4px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
::v-deep .excel-table td.el-table__cell {
|
|
|
|
|
|
border-right: 1px solid #f0f2f6;
|
|
|
|
|
|
border-bottom: 1px solid #f0f2f6;
|
|
|
|
|
|
padding: 1px 2px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.pager-wrap {
|
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
}
|
2026-03-23 15:33:12 +08:00
|
|
|
|
|
|
|
|
|
|
.col-setting-body {
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
height: calc(100% - 12px);
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.col-setting-toolbar {
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-23 15:39:02 +08:00
|
|
|
|
.col-section {
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.col-section-title {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #303133;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-23 15:33:12 +08:00
|
|
|
|
.col-setting-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.col-setting-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
padding: 8px 10px;
|
|
|
|
|
|
border: 1px solid #ebeef5;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
min-height: 38px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.col-setting-item:hover {
|
|
|
|
|
|
border-color: #d9ecff;
|
|
|
|
|
|
background: #f5faff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.drag-handle {
|
|
|
|
|
|
cursor: move;
|
|
|
|
|
|
color: #909399;
|
|
|
|
|
|
}
|
2026-03-14 15:06:18 +08:00
|
|
|
|
</style>
|