From fb39a7bb69cc55d2e1ce61d47e0677aa40540f95 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Fri, 30 Jan 2026 16:20:33 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue | 671 +++----------------------------------------------------
1 files changed, 42 insertions(+), 629 deletions(-)
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue
index cc492ca..302d14e 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog copy.vue
@@ -12,54 +12,6 @@
:layer-mode="4"
:boundary="false"
/>
- <div
- v-if="showTypePanel && !readonly"
- class="shape-type-panel"
- >
- <div class="panel-header">
- <span>{{ drawTypeLabelMap[currentShapeType] || '区域' }}</span>
- <el-icon class="panel-close" @click.stop="handleTypePanelClose"><Close /></el-icon>
- </div>
- <div class="panel-body">
- <span class="panel-label">区域类型</span>
- <el-select
- class="command-select"
- popper-class="command-select-popper"
- v-model="formData.areaType"
- placeholder="请选择"
- @change="handleAreaTypeChange"
- >
- <el-option
- v-for="item in dictObj.areaType"
- :key="item.dictKey"
- :label="item.dictValue"
- :value="item.dictKey"
- />
- </el-select>
- </div>
- </div>
- <div class="map-toolbar">
- <button class="tool-btn" type="button" @click="handleDraw('polygon')">
- <span class="tool-icon polygon"></span>
- <span class="tool-text">多边形</span>
- </button>
- <button class="tool-btn" type="button" @click="handleDraw('rectangle')">
- <span class="tool-icon rect"></span>
- <span class="tool-text">矩形</span>
- </button>
- <button class="tool-btn" type="button" @click="handleDraw('ellipse')">
- <span class="tool-icon ellipse"></span>
- <span class="tool-text">椭圆</span>
- </button>
- <button class="tool-btn" type="button" @click="handleDraw('buffer')">
- <span class="tool-icon buffer"></span>
- <span class="tool-text">缓冲圆</span>
- </button>
- <button class="tool-btn danger" type="button" @click="handleClearShape">
- <span class="tool-icon trash"></span>
- <span class="tool-text">删除</span>
- </button>
- </div>
</div>
<div class="right-container">
@@ -180,28 +132,6 @@
</el-select>
</el-form-item>
- <div class="shape-table-container">
- <div class="shape-table-title">绘制区域列表</div>
- <el-table class="command-table" :data="shapeList" row-key="id" height="360">
- <el-table-column prop="areaType" label="类型" width="120">
- <template v-slot="{ row }">
- {{ getDictLabel(row.areaType, dictObj.areaType) }}
- </template>
- </el-table-column>
- <el-table-column prop="drawType" label="绘制类型" width="120">
- <template v-slot="{ row }">
- {{ drawTypeLabelMap[row.drawType] || '-' }}
- </template>
- </el-table-column>
- <el-table-column label="操作" class-name="operation-btns">
- <template v-slot="{ row }">
- <el-link @click="handleShapeEdit(row)">编辑</el-link>
- <el-link @click="handleShapeDelete(row)">删除</el-link>
- </template>
- </el-table-column>
- </el-table>
- </div>
-
<div class="search-table-container">
<div class="search-box">
<div class="label">
@@ -243,17 +173,15 @@
<script setup>
import { Close } from '@element-plus/icons-vue'
-import { computed, inject, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
+import { computed, inject, nextTick, onMounted, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { fwAreaDivideDetailApi, fwAreaDivideSubmitApi } from './partitionApi'
import { saveOperationLog } from '@ztzf/apis'
import { useRoute } from 'vue-router'
import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils'
import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
-import { DrawManager } from './shapeTools/DrawManager'
-import { EditManager } from './shapeTools/EditManager'
+import { DrawPolygon } from '@/utils/cesium/DrawPolygon'
import { cartesian3Convert } from '@/utils/cesium/mapUtil'
-import { buildEllipsePositions } from './shapeTools/shapeUtils'
import * as turf from '@turf/turf'
import * as Cesium from 'cesium'
import { fwPoliceStationListApi } from '@/views/areaManage/precinctInfo/precinctInfoApi'
@@ -291,39 +219,9 @@
const deviceOptions = ref([]) // 关联设备
const dictObj = inject('dictObj')
const mapRef = ref(null)
-const currentShapeType = ref('polygon')
-const shapeList = ref([])
-const activeShapeId = ref(null)
-const drawTypeLabelMap = {
- polygon: '多边形',
- rectangle: '矩形',
- ellipse: '椭圆',
- buffer: '缓冲圆',
-}
-const showTypePanel = ref(false)
-const suppressTypePanelOnce = ref(false)
-const areaTypeStyleMap = {
- '1': {
- fill: Cesium.Color.fromBytes(25, 178, 230, 128),
- outline: Cesium.Color.fromBytes(0, 251, 255, 255),
- },
- '2': {
- fill: Cesium.Color.fromBytes(255, 235, 59, 128),
- outline: Cesium.Color.fromBytes(255, 235, 59, 255),
- },
- '3': {
- fill: Cesium.Color.fromBytes(247, 20, 20, 128),
- outline: Cesium.Color.fromBytes(255, 0, 0, 255),
- },
-}
let viewer
-let drawManager
-let editManager
-let activeTool
+let drawPolygonExample
let pointList = []
-let viewEntity
-let shapeDisplaySource
-const activeToolMode = ref('')
const rules = {
areaName: fieldRules(true, 50),
@@ -408,24 +306,6 @@
formData.value.flyDateEnd = flyDateRange.value[1] || ''
}
)
-watch(
- () => visible.value,
- val => {
- if (!val) {
- viewEntity && viewer?.entities?.remove(viewEntity)
- viewEntity = null
- clearActiveTool()
- hideTypePanel()
- clearShapeDisplay()
- }
- }
-)
-watch(
- () => formData.value.areaType,
- val => {
- updateActiveShapeAreaType(val)
- }
-)
// 加载详情
async function loadDetail () {
@@ -454,191 +334,14 @@
viewer = map?.viewer || null
}
-function ensureShapeDisplaySource () {
- if (!viewer) return null
- if (!shapeDisplaySource) {
- shapeDisplaySource = new Cesium.CustomDataSource('partition-shape-display')
- viewer.dataSources.add(shapeDisplaySource)
- }
- return shapeDisplaySource
-}
-
-function clearShapeDisplay () {
- if (!shapeDisplaySource) return
- shapeDisplaySource.entities.removeAll()
-}
-
-function normalizeShapePoint (point) {
- const lng = point?.lng ?? point?.longitude
- const lat = point?.lat ?? point?.latitude
- if (!Number.isFinite(Number(lng)) || !Number.isFinite(Number(lat))) return null
- return {
- lng: Number(lng),
- lat: Number(lat),
- height: Number.isFinite(Number(point?.height)) ? Number(point.height) : 0,
- }
-}
-
-function buildShapePositions (points = []) {
- const normalized = points.map(normalizeShapePoint).filter(Boolean)
- return normalized.map(point =>
- Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.height)
- )
-}
-
-function getAreaTypeStyle (areaType) {
- return areaTypeStyleMap?.[String(areaType)] || {
- fill: Cesium.Color.fromBytes(45, 140, 240, 99),
- outline: Cesium.Color.fromBytes(45, 140, 240, 255),
- }
-}
-
-function renderShapeList () {
- if (!viewer || !visible.value || readonly.value) {
- clearShapeDisplay()
- return
- }
- const dataSource = ensureShapeDisplaySource()
- if (!dataSource) return
- dataSource.entities.removeAll()
- shapeList.value.forEach(shape => {
- if (!shape?.points?.length) return
- if (activeToolMode.value === 'edit' && shape.id === activeShapeId.value) return
- if (shape.drawType === 'buffer' && shape.meta?.bufferRadii?.length && shape.meta?.center) {
- const center = shape.meta.center
- const centerCartesian = Cesium.Cartesian3.fromDegrees(center.lng, center.lat, center.height || 0)
- const [radius1, radius2, radius3] = shape.meta.bufferRadii
- const radii = [radius1, radius2, radius3].filter(item => Number.isFinite(item) && item > 0)
- if (radii.length) {
- const styles = [
- {
- fill: Cesium.Color.fromBytes(247, 20, 20, 128),
- outline: Cesium.Color.fromBytes(255, 0, 0, 255),
- },
- {
- fill: Cesium.Color.fromBytes(255, 235, 59, 128),
- outline: Cesium.Color.fromBytes(255, 235, 59, 255),
- },
- {
- fill: Cesium.Color.fromBytes(25, 178, 230, 128),
- outline: Cesium.Color.fromBytes(0, 251, 255, 255),
- },
- ]
- radii.forEach((radius, index) => {
- const style = styles[index] || styles[styles.length - 1]
- dataSource.entities.add({
- name: 'shape-display',
- customData: { shapeId: shape.id, drawType: shape.drawType, level: index + 1 },
- position: centerCartesian,
- ellipse: {
- semiMajorAxis: radius,
- semiMinorAxis: radius,
- material: style.fill,
- outline: false,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- },
- })
- const positions = buildEllipsePositions(centerCartesian, radius, radius)
- dataSource.entities.add({
- name: 'shape-display',
- customData: { shapeId: shape.id, drawType: shape.drawType, level: index + 1, outline: true },
- polyline: {
- positions: positions.length ? [...positions, positions[0]] : positions,
- clampToGround: true,
- width: 2,
- material: style.outline,
- },
- })
- })
- }
- return
- }
-
- const positions = buildShapePositions(shape.points)
- if (positions.length < 3) return
- const style = getAreaTypeStyle(shape.areaType)
- dataSource.entities.add({
- name: 'shape-display',
- customData: { shapeId: shape.id, drawType: shape.drawType },
- polygon: {
- hierarchy: new Cesium.PolygonHierarchy(positions),
- material: style.fill,
- outline: false,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- },
- polyline: {
- positions: positions.length ? [...positions, positions[0]] : positions,
- clampToGround: true,
- width: 2,
- material: style.outline,
- },
- })
- })
-}
-
// 绘制完成回调
const drawFinished = async data => {
- const positions = Array.isArray(data?.positions) ? data.positions : data
- if (!Array.isArray(positions) || positions.length < 3) {
- pointList = []
- formData.value.areaSize = null
- formData.value.longitude = null
- formData.value.latitude = null
- hideTypePanel()
- return
- }
- const meta = data?.meta
- const bufferRadii = Array.isArray(meta?.bufferRadii) ? meta.bufferRadii : null
- const centerCartesian = meta?.center
- const centerLngLat = centerCartesian ? cartesian3Convert(centerCartesian, viewer) : null
- pointList = _.cloneDeep(positions).map(item => {
+ pointList = _.cloneDeep(data).map(item => {
const val = cartesian3Convert(item, viewer)
return { ...val, lng: val.longitude, lat: val.latitude }
})
- applyPolygonMetrics(pointList)
- if (!formData.value.areaType) {
- const detectAreaType = getDetectAreaTypeKey()
- if (detectAreaType) {
- formData.value.areaType = detectAreaType
- }
- }
- if (!suppressTypePanelOnce.value) {
- showTypePanelAtCurrent()
- }
- suppressTypePanelOnce.value = false
-
- if (!activeShapeId.value) {
- activeShapeId.value = `shape_${Date.now()}_${Math.random().toString(16).slice(2, 6)}`
- }
- const targetIndex = shapeList.value.findIndex(item => item.id === activeShapeId.value)
- const shapePayload = {
- id: activeShapeId.value,
- areaType: formData.value.areaType,
- drawType: currentShapeType.value,
- points: _.cloneDeep(pointList),
- meta: bufferRadii && centerLngLat
- ? {
- bufferRadii,
- center: {
- lng: centerLngLat.longitude,
- lat: centerLngLat.latitude,
- height: centerLngLat.height ?? 0,
- },
- }
- : null,
- }
- if (targetIndex === -1) {
- shapeList.value.push(shapePayload)
- } else {
- shapeList.value.splice(targetIndex, 1, shapePayload)
- }
- renderShapeList()
-}
-
-function applyPolygonMetrics(points) {
- if (!points?.length) return
const polygon = turf.polygon([
- [...points.map(item => [item.longitude, item.latitude]), [points[0].longitude, points[0].latitude]],
+ [...pointList.map(item => [item.longitude, item.latitude]), [pointList[0].longitude, pointList[0].latitude]],
])
const center = turf.centerOfMass(polygon)
const areaSqm = turf.area(polygon) // 平方米
@@ -647,152 +350,41 @@
formData.value.latitude = center.geometry.coordinates[1]
}
-function getDetectAreaTypeKey () {
- const areaTypeOptions = Array.isArray(dictObj?.value?.areaType)
- ? dictObj.value.areaType
- : dictObj?.areaType
- if (!Array.isArray(areaTypeOptions)) return ''
- const target = areaTypeOptions.find(item => item?.dictKey === '1')
- return target?.dictKey ?? ''
+// 新增模式绘制
+function addPolygon () {
+ drawPolygonExample = new DrawPolygon(viewer)
+ drawPolygonExample.initHandler(viewer)
+ drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
}
-function showTypePanelAtCurrent () {
- if (readonly.value) return
- showTypePanel.value = true
-}
-
-function hideTypePanel () {
- showTypePanel.value = false
-}
-
-function handleTypePanelClose () {
- hideTypePanel()
- if (readonly.value) return
- if (activeToolMode.value !== 'edit') return
- const positions = activeTool?.getPositions?.()
- if (Array.isArray(positions) && positions.length >= 3) {
- suppressTypePanelOnce.value = true
- drawFinished(positions)
- }
- clearActiveTool()
-}
-
-function handleAreaTypeChange (value) {
- updateActiveShapeAreaType(value)
-}
-
-function updateActiveShapeAreaType (value) {
- if (currentShapeType.value !== 'buffer') {
- activeTool?.setStyle?.(getAreaTypeStyle(value))
- }
- if (!activeShapeId.value) return
- const targetIndex = shapeList.value.findIndex(item => item.id === activeShapeId.value)
- if (targetIndex === -1) return
- const target = shapeList.value[targetIndex]
- shapeList.value.splice(targetIndex, 1, {
- ...target,
- areaType: value,
- })
- renderShapeList()
-}
-
-// Tool lifecycle
-function clearActiveTool () {
- activeTool?.destroy?.()
- activeTool = null
- drawManager?.destroy()
- editManager?.destroy()
- activeToolMode.value = ''
- renderShapeList()
-}
-
-function startDraw (type) {
- currentShapeType.value = type
- activeToolMode.value = 'draw'
- drawManager ||= new DrawManager(viewer)
- activeTool = drawManager.start(type, { style: getAreaTypeStyle(formData.value.areaType) })
- activeTool?.subscribe('getPolygonPositions', drawFinished)
-}
-
-function startEdit (type, points) {
- currentShapeType.value = type
- activeToolMode.value = 'edit'
- editManager ||= new EditManager(viewer)
- activeTool = editManager.start(type, points, { style: getAreaTypeStyle(formData.value.areaType) })
- activeTool?.subscribe('getPolygonPositions', drawFinished)
-}
-
-function handleDraw (type) {
- if (readonly.value) return
- if (!viewer) return
- clearActiveTool()
- viewEntity && viewer?.entities?.remove(viewEntity)
- viewEntity = null
- hideTypePanel()
- renderShapeList()
- if (dialogMode.value === 'edit' && pointList.length >= 3) {
- const editPoints = _.cloneDeep(pointList)
- if (editPoints.length > 1) {
- const first = editPoints[0]
- const last = editPoints[editPoints.length - 1]
- if (first.longitude === last.longitude && first.latitude === last.latitude) {
- editPoints.pop()
- }
+// 编辑面
+function editPolygon () {
+ if (!formData.value?.geom) return
+ pointList = geomAnalysis(formData.value.geom)
+ drawPolygonExample?.destroy()
+ drawPolygonExample = new DrawPolygon(viewer)
+ let pointList1 = _.cloneDeep(pointList)
+ pointList1.pop()
+ drawPolygonExample.initPolygon(
+ viewer,
+ pointList.map(item => ({ lng: item.longitude, lat: item.latitude }))
+ )
+ drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
+ if (pointList1.length) {
+ const result = pointList1.map(item => [item.longitude, item.latitude]).flat()
+ const tempEntity = viewer.entities?.add({
+ position: Cesium.Cartesian3.fromDegrees(result[0], result[1]),
+ polyline: {
+ positions: Cesium.Cartesian3.fromDegreesArray(result),
+ clampToGround: true,
+ width: 1,
+ material: Cesium.Color.TRANSPARENT,
+ },
+ })
+ if (tempEntity) {
+ viewer.flyTo(tempEntity, { duration: 0 })
+ viewer.entities.remove(tempEntity)
}
- activeShapeId.value = activeShapeId.value || (shapeList.value[0]?.id ?? null)
- startEdit(type, editPoints)
- return
- }
- const defaultAreaType = getDetectAreaTypeKey()
- if (defaultAreaType) {
- formData.value.areaType = defaultAreaType
- }
- activeShapeId.value = null
- startDraw(type)
-}
-
-function handleClearShape () {
- if (readonly.value) return
- clearActiveTool()
- viewEntity && viewer?.entities?.remove(viewEntity)
- viewEntity = null
- pointList = []
- shapeList.value = []
- activeShapeId.value = null
- formData.value.areaSize = null
- formData.value.longitude = null
- formData.value.latitude = null
- hideTypePanel()
- clearShapeDisplay()
-}
-
-function handleShapeEdit (row) {
- if (!row?.points?.length) return
- if (activeToolMode.value === 'edit' && activeShapeId.value === row.id) return
- activeShapeId.value = row.id
- currentShapeType.value = row.drawType
- formData.value.areaType = row.areaType
- pointList = _.cloneDeep(row.points)
- clearActiveTool()
- const editPayload = row.drawType === 'buffer' ? { points: row.points, meta: row.meta } : row.points
- startEdit(row.drawType, editPayload)
- applyPolygonMetrics(pointList)
- showTypePanelAtCurrent()
- renderShapeList()
-}
-
-function handleShapeDelete (row) {
- if (!row) return
- shapeList.value = shapeList.value.filter(item => item.id !== row.id)
- renderShapeList()
- if (activeShapeId.value === row.id) {
- activeShapeId.value = null
- clearActiveTool()
- pointList = []
- formData.value.areaSize = null
- formData.value.longitude = null
- formData.value.latitude = null
- hideTypePanel()
}
}
@@ -801,7 +393,7 @@
if (!formData.value?.geom) return
pointList = geomAnalysis(formData.value.geom)
const result = pointList.map(item => [item.longitude, item.latitude]).flat()
- viewEntity = viewer.entities?.add({
+ const mian = viewer.entities?.add({
customType: 'control_group',
position: Cesium.Cartesian3.fromDegrees(result[0], result[1]),
polyline: {
@@ -811,7 +403,7 @@
material: Cesium.Color.RED,
},
})
- viewer.flyTo(viewEntity, { duration: 0 })
+ viewer.flyTo(mian, { duration: 0 })
}
// 获取派出所列表
@@ -857,32 +449,14 @@
dialogMode.value = mode || 'add'
formData.value = dialogMode.value === 'add' ? initForm() : row
selectedDeviceRows.value = []
- shapeList.value = []
- activeShapeId.value = null
await nextTick()
initMap()
- clearShapeDisplay()
- viewEntity && viewer?.entities?.remove(viewEntity)
- viewEntity = null
- clearActiveTool()
await getDeviceList()
if (dialogMode.value === 'add') {
- // default no draw mode
+ addPolygon()
} else if (dialogMode.value === 'edit') {
await loadDetail()
- pointList = geomAnalysis(formData.value.geom) || []
- if (pointList.length) {
- activeShapeId.value = `shape_${Date.now()}_${Math.random().toString(16).slice(2, 6)}`
- shapeList.value = [
- {
- id: activeShapeId.value,
- areaType: formData.value.areaType,
- drawType: currentShapeType.value,
- points: _.cloneDeep(pointList),
- },
- ]
- }
- viewPolygon()
+ editPolygon()
} else {
await loadDetail()
viewPolygon()
@@ -896,170 +470,9 @@
getDeviceList()
})
-onBeforeUnmount(() => {
- hideTypePanel()
-})
-
defineExpose({
open,
})
</script>
-<style scoped lang="scss">
-.left-container {
- position: relative;
-}
-
-.shape-type-panel {
- position: absolute;
- right: 16px;
- bottom: 16px;
- z-index: 6;
- min-width: 260px;
- background: rgba(22, 33, 44, 0.9);
- border: 1px solid rgba(255, 255, 255, 0.15);
- border-radius: 8px;
- box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
- backdrop-filter: blur(6px);
- color: #e5e7f0;
-}
-
-.panel-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 8px 12px;
- border-bottom: 1px solid rgba(255, 255, 255, 0.12);
- font-size: 13px;
- font-weight: 600;
-}
-
-.panel-close {
- cursor: pointer;
- color: rgba(255, 255, 255, 0.7);
-}
-
-.panel-body {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 10px 12px 12px;
-}
-
-.panel-label {
- font-size: 12px;
- color: rgba(255, 255, 255, 0.75);
- white-space: nowrap;
-}
-
-.map-toolbar {
- position: absolute;
- top: 64px;
- right: 16px;
- display: flex;
- flex-direction: column;
- gap: 10px;
- padding: 10px 8px;
- background: rgba(19, 28, 36, 0.75);
- backdrop-filter: blur(4px);
- border-radius: 8px;
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
-}
-
-.tool-btn {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 6px;
- width: 64px;
- padding: 8px 6px;
- background: rgba(255, 255, 255, 0.08);
- border: 1px solid rgba(255, 255, 255, 0.18);
- border-radius: 6px;
- color: #ffffff;
- font-size: 12px;
- line-height: 1;
- cursor: pointer;
- transition: all 0.2s ease;
-}
-
-.tool-btn:hover {
- background: rgba(255, 255, 255, 0.16);
- border-color: rgba(255, 255, 255, 0.35);
- transform: translateY(-1px);
-}
-
-.tool-btn:active {
- transform: translateY(0);
-}
-
-.tool-btn.danger {
- border-color: rgba(255, 112, 112, 0.6);
- color: #ffb3b3;
-}
-
-.tool-icon {
- position: relative;
- width: 20px;
- height: 20px;
- border: 2px solid #ffffff;
- border-radius: 3px;
-}
-
-.tool-icon.polygon {
- border-radius: 4px;
- transform: rotate(15deg);
-}
-
-.tool-icon.rect {
- border-radius: 2px;
-}
-
-.tool-icon.ellipse {
- border-radius: 50%;
-}
-
-.tool-icon.buffer {
- border-radius: 50%;
- box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
-}
-
-.tool-icon.trash {
- border: none;
- box-shadow: none;
-}
-
-.tool-icon.trash::before,
-.tool-icon.trash::after {
- content: "";
- position: absolute;
- left: 4px;
- right: 4px;
- background: #ffffff;
-}
-
-.tool-icon.trash::before {
- top: 4px;
- height: 10px;
- border-radius: 2px;
-}
-
-.tool-icon.trash::after {
- top: 1px;
- height: 3px;
- border-radius: 2px;
-}
-
-.shape-table-container {
- margin-top: 8px;
- padding: 8px;
- border-radius: 8px;
- background: rgba(27, 34, 56, 0.6);
-}
-
-.shape-table-title {
- margin-bottom: 8px;
- color: #e5e7f0;
- font-size: 13px;
-}
-</style>
+<style scoped lang="scss"></style>
--
Gitblit v1.9.3