地图图标

main
userName 2025-02-24 17:11:18 +08:00
commit f97e72660e
83 changed files with 3219 additions and 1583 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

View File

@ -3,19 +3,26 @@ enum Api {
imageUpload = '/api/goview/project/image/upload',
imageList = '/api/goview/project/image/list',
imageDelete = '/api/goview/project/image/delete',
imageGroupList = '/api/goview/project/imageGroup/list',
}
export const imageList = (params?) =>
defHttp.get({ url: Api.imageList });
export const imageList = (params:{GroupName:string,page:number,limit:number,key?:string}) =>
defHttp.get({
url: Api.imageList,
params
});
export const getImageGroupList = () =>
defHttp.get({ url: Api.imageGroupList });
export const imageDelete = (id:string) =>
defHttp.post({
url: `${Api.imageDelete}?ids=${id}`
});
export const imageUpload = (params) =>
export const imageUpload = (params,groupName) =>
defHttp.post({
url: Api.imageUpload,
url: `${Api.imageUpload}?groupName=${groupName}`,
params,
headers: {
'Content-type': 'multipart/form-data',

View File

@ -19,6 +19,9 @@ enum Api {
projectFile = '/api/goview/project/uploadFile',
SetMainPage = '/api/goview/project/mainPage/set',
GetMainPage = '/api/goview/project/mainPage/get',
CustomComponentSave = '/api/goview/project/customComponent/save',
CustomComponentSaveList = '/api/goview/project/customComponent/list',
CustomComponentSaveDelete = '/api/goview/project/customComponent/delete',
}
// * 项目列表
export const projectListApi = (params?: ProjectItem) =>
@ -80,7 +83,6 @@ export function projectUploadFile(
params,
onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
) {
console.log(params);
return defHttp.uploadFile<UploadApiResult>(
{
url: uploadFileUrl,
@ -106,7 +108,6 @@ export function projectUploadFile(
// 设置系统主页面
export function setMainPage(params) {
console.log(params);
return defHttp.post({
url: Api.SetMainPage,
params,
@ -114,3 +115,22 @@ export function setMainPage(params) {
}
// 获取系统主页面
export const getMainPage = () => defHttp.get({ url: Api.GetMainPage });
// 保存组件
export function customComponentSave(params) {
return defHttp.post({
url: Api.CustomComponentSave,
params,
});
}
// 获取组件列表
export const customComponentList = (params: any) =>
defHttp.get({ url: Api.CustomComponentSaveList, params });
// 删除组件
export function customComponentSaveDelete(params) {
return defHttp.post({
url: Api.CustomComponentSaveDelete + '?ids=' + params.ids,
params,
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

View File

@ -60,6 +60,8 @@ export enum MenuEnum {
HIDE = 'hide',
// 显示
SHOW = 'show',
// 保存至分组
SAVETOGROUP = 'saveToGroup',
}
// Win 键盘枚举

View File

@ -1,17 +1,218 @@
import * as mars3d from "mars3d";
// 地图函数列表
export function mapFun() {
// 根据坐标点跳转位置
const handlerFlyToPoint = (params) => {
window.globalMap.flyToPoint([118.000666, 35.11987], {
alt: 4269.7,
heading: 359.2,
pitch: -51.9,
});
const ceshiClick = () => {
console.log('ceshi');
alert('ceshi');
};
const handlerAddEntity = (data) => {
// 根据坐标点跳转位置
const handlerFlyToPoint = (params) => {
window.globalMap.flyToPoint([118.000666,35.11987],
{"alt":4269.7,"heading":359.2,"pitch":-51.9});
}
const handlerMeasureSurfaceLength = async () => {
const graphic = await window.measureTool.distanceSurface({
showAddText: true,
exact: false
})
}
const handlerMeasureLenth = async () => {
}
const handlerMeasureLength = async () => {
const graphic = await window.measureTool.distance({
showAddText: true,
label: {
type: "div",
updateText: function (text, graphic) {
graphic.html = `<div class="marsGreenGradientPnl" >${text}</div>`
},
html: `<div class="marsGreenGradientPnl" ></div>`,
}
})
}
const handlerMeasureSurfaceArea = async () => {
const graphic = await window.measureTool.areaSurface({
style: {
color: "#ffff00"
},
splitNum: 10, // step插值分割的个数
exact: false // 是否进行精确计算, 传false时是否快速概略计算方式该方式计算精度较低但计算速度快仅能计算在当前视域内坐标的高度
})
}
const handlerMeasureArea = async () => {
const graphic = await window.measureTool.area({
style: {
color: '#00fff2',
opacity: 0.4,
outline: true,
outlineColor: '#fafa5a',
outlineWidth: 1,
clampToGround: false //贴地
}
})
}
const handlerMeasurePoint = async () => {
const graphic = await window.measureTool.point({
popupOptions: {
pointerEvents: false
},
popup: function (point, event) {
return `<div class="mars3d-template-title">位置信息</div>
<div class="mars3d-template-content">
<div><label></label>${point.lng}</div>
<div><label></label>${point.lat}</div>
<div><label></label>${point.alt}</div>
</div>`
}
})
}
const handlerMeasureHeight = async () => {
const graphic = await window.measureTool.height();
}
const handlerClearMeasure = () => {
window.measureTool.clear();
}
const handlerDrawPolygon = async () => {
const graphic = await window.drawGraphicLayer.startDraw({
type: "polygon",
style: {
color: "#3388ff",
opacity: 0.5,
outline: true,
outlineColor: "#ffffff",
outlineWidth: 2.0,
clampToGround:true
}
})
}
const handlerClearDraw = async ()=>{
window.drawGraphicLayer.clear();
}
const handlerDrawRectangle = async () => {
const graphic = await window.drawGraphicLayer.startDraw({
type: isEntityPrimitive ? "rectangle" : "rectangleP",
style: {
color: clampToGround ? "#ffff00" : "#3388ff",
opacity: 0.6,
outline: true,
outlineColor: "#ffffff",
outlineWidth: 2.0,
clampToGround
}
})
}
const handlerDrawBrushLine =async ()=> {
const graphic = await window.drawGraphicLayer.startDraw({
type: "brushLine",
style: {
color: "#ffff00",
width: 3,
clampToGround:true
}
})
}
const handlerDrawLine =async () => {
const graphic = await window.drawGraphicLayer.startDraw({
type: "polylineP",
style: {
color: "#ffff00",
width: 3,
clampToGround:true
}
})
console.log("标绘完成", graphic.toJSON())
}
const handlerDrawPoint= async () => {
const graphic = await window.drawGraphicLayer.startDraw({
type: "pointP",
style: {
pixelSize: 12,
color: "#3388ff",
label: {
// 不需要文字时去掉label配置即可
text: "可以同时支持文字",
font_size: 20,
color: "#ffffff",
outline: true,
outlineColor: "#000000",
pixelOffsetY: -20
}
}
})
console.log("标绘完成", graphic.toJSON())
}
// 矢量坐标点控制
const handlerGetPoint = async () => {
const graphic = await window.drawGraphicLayer.startDraw({
type: "point",
})
let position = graphic.toJSON().position;
let res = {
lng:position[0],
lat:position[1],
alt:position[0]
}
graphicLayer.removeGraphic(graphic);
return res;
}
// 添加Entity
const handlerAddEntity = () => {
let data = {
id:10000001,
position:{
lat:35.451451,
lng:118.0804257,
},
image:{
generalIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
activeIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
},
attribute:{
label:"测试火点",
address:"遍历"
}
}
let graphicOptions = {
id: data.id,
id:data.id,
position: [parseFloat(data.position.lng), parseFloat(data.position.lat)],
style: {
image: data.image.generalIcon,
@ -20,7 +221,7 @@ export function mapFun() {
label: {
text: data.attribute.label,
font_size: 14,
color: '#ffffff',
color: "#ffffff",
pixelOffsetY: 10,
distanceDisplayCondition: true,
distanceDisplayCondition_far: 500000,
@ -63,105 +264,252 @@ export function mapFun() {
</div>`,
popupOptions: {
offsetY: -30,
template: '{content}',
horizontalOrigin: 'Cesium.HorizontalOrigin.LEFT',
verticalOrigin: 'Cesium.VerticalOrigin.CENTER',
template: "{content}",
horizontalOrigin: "Cesium.HorizontalOrigin.LEFT",
verticalOrigin: "Cesium.VerticalOrigin.CENTER",
},
};
let graphic = window.graphicLayer.getGraphicById(data.id);
if (graphic) {
graphic.setStyleOptions(graphicOptions);
} else {
graphic = new mars3d.graphic.BillboardEntity(graphicOptions);
window.graphicLayer.addGraphic(graphic);
}
};
let graphic = window.graphicLayer.getGraphicById(data.id);
if(graphic){
graphic.setStyleOptions(graphicOptions);
}else{
graphic = new mars3d.graphic.BillboardEntity(graphicOptions);
window.graphicLayer.addGraphic(graphic);
}
}
const handlerShowEntity = () => {
let data = {
id:10000001,
position:{
lat:35.451451,
lng:118.0804257,
},
image:{
generalIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
activeIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
},
attribute:{
label:"测试火点",
address:"遍历"
}
}
const handlerMeasureSurfaceLength = async () => {
const graphic = await window.measureTool.distanceSurface({
showAddText: true,
exact: false,
});
};
let graphic = window.graphicLayer.getGraphicById(data.id);
if(graphic){
graphic.show = true;
}
}
const handlerMeasureLength = async () => {
const graphic = await window.measureTool.distance({
showAddText: true,
label: {
type: 'div',
updateText: function (text, graphic) {
graphic.html = `<div class="marsGreenGradientPnl" >${text}</div>`;
const handlerHiddenEntity = () => {
let data = {
id:10000001,
position:{
lat:35.451451,
lng:118.0804257,
},
image:{
generalIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
activeIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
},
attribute:{
label:"测试火点",
address:"遍历"
}
}
let graphic = window.graphicLayer.getGraphicById(data.id);
if(graphic){
graphic.show = false;
}
}
const handlerRemoveEntity = () => {
let data = {
id:10000001,
position:{
lat:35.451451,
lng:118.0804257,
},
image:{
generalIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
activeIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
},
attribute:{
label:"测试火点",
address:"遍历"
}
}
let graphic = window.graphicLayer.getGraphicById(data.id);
if(graphic){
graphicLayer.removeGraphic(graphic);
}
}
const handlerFlyToEntity = () => {
let data = {
id:10000001,
position:{
lat:35.451451,
lng:118.0804257,
},
image:{
generalIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
activeIcon:"http://221.2.83.254:9012/styleImages/image/1777249374668402688.png",
},
attribute:{
label:"测试火点",
address:"遍历"
}
}
let graphic = window.graphicLayer.getGraphicById(data.id);
if(graphic){
// if(data.image.activeIcon){
// grasphic.setStyle({
// image:data.image.activeIcon
// })
// }
window.globalMap.flyToGraphic(graphic);
}
}
// 清空所有适量图标
const handlerClearEntityLayer = () => {
window.graphicLayer.clear();
}
// 隐藏所有矢量图标
const handlerHiddenEntityLayer = ()=> {
window.graphicLayer.show = false;
}
const handlerShowEntityLayer = () => {
window.graphicLayer.show = true;
}
// 图层控制类
const handlerAddLayer = ()=>{
let layer = new mars3d.layer.WmsLayer({
"id": 4460,
"name": "建筑物面",
"type": "wms",
"url": "http://221.2.83.254:9007/geoserver/ksp/wms",
"layers": "ksp:beibushanqudaolufenlei0923",
"crs": "EPSG:4326",
"parameters": {
"transparent": "true",
"format": "image/png"
},
html: `<div class="marsGreenGradientPnl" ></div>`,
},
});
};
"highlight": {
"showTime": 5000,
"fill": true,
"color": "#2deaf7",
"opacity": 0.6,
"outline": true,
"outlineWidth": 3,
"outlineColor": "#e000d9",
"outlineOpacity": 1,
"clampToGround": true
},
"center": {"lat":35.376403,"lng":117.97628,"alt":3615.8,"heading":3.1,"pitch":-26.8},
"popup": "all",
"show": true,
"flyTo": true
})
const handlerMeasureSurfaceArea = async () => {
const graphic = await window.measureTool.areaSurface({
window.globalMap.addLayer(layer);
}
const handlerHiddenLayer = ()=>{
let layer = window.globalMap.getLayerById(4460);
if(layer){
layer.show = false;
}
}
const handlerShowLayer = ()=>{
let layer = window.globalMap.getLayerById(4460);
console.log("layer",layer);
if(layer){
layer.show = true;
}
}
const handlerRemoveLayer = ()=>{
let layer = window.globalMap.getLayerById(4460);
if(layer){
window.globalMap.removeLayer(layer);
}
}
const handlerFlyToLayer = ()=>{
let layer = window.globalMap.getLayerById(4460);
if(layer){
layer.flyTo();
}
}
// 三维模型
const handlerAddModel = ()=>{
// {"lat":35.4422,"lng":117.985466,"alt":2070.2,"heading":1.1,"pitch":-87.1}
const graphic = new mars3d.graphic.ModelEntity({
name:"消防车",
position: [117.985466, 35.4422, 11.34],
style: {
color: '#ffff00',
url: "http://221.2.83.254:9010/cartoon_fire_truck/xiaofangche.gltf",
scale: 20,
minimumPixelSize: 50,
heading: 90,
distanceDisplayCondition: true,
distanceDisplayCondition_near: 0,
distanceDisplayCondition_far: 10000,
distanceDisplayPoint: {
// 当视角距离超过一定距离(distanceDisplayCondition_far定义的) 后显示为点对象的样式
color: "#00ff00",
pixelSize: 8
},
label: {
text: "显示信息",
font_size: 18,
color: "#ffffff",
pixelOffsetY: -50,
distanceDisplayCondition: true,
distanceDisplayCondition_far: 10000,
distanceDisplayCondition_near: 0
}
},
splitNum: 10, // step插值分割的个数
exact: false, // 是否进行精确计算, 传false时是否快速概略计算方式该方式计算精度较低但计算速度快仅能计算在当前视域内坐标的高度
});
};
attr: { remark: "示例1" }
})
window.graphicLayer.addGraphic(graphic)
}
const handlerMeasureArea = async () => {
const graphic = await window.measureTool.area({
style: {
color: '#00fff2',
opacity: 0.4,
outline: true,
outlineColor: '#fafa5a',
outlineWidth: 1,
clampToGround: false, //贴地
},
});
};
const handlerMeasurePoint = async () => {
const graphic = await window.measureTool.point({
popupOptions: {
pointerEvents: false,
},
popup: function (point, event) {
return `<div class="mars3d-template-title">位置信息</div>
<div class="mars3d-template-content">
<div><label></label>${point.lng}</div>
<div><label></label>${point.lat}</div>
<div><label></label>${point.alt}</div>
</div>`;
},
});
};
const handlerMeasureHeight = async () => {
const graphic = await window.measureTool.height();
};
const handlerClearMeasure = () => {
window.measureTool.clear();
};
const handlerDrawPolygon = async () => {
const graphic = await graphicLayer.startDraw({
type: 'polygon',
style: {
color: '#3388ff',
opacity: 0.5,
outline: true,
outlineColor: '#ffffff',
outlineWidth: 2.0,
clampToGround: true,
},
});
};
return {
ceshiClick,
handlerFlyToPoint,
handlerAddEntity,
handlerMeasureSurfaceLength,
@ -172,109 +520,159 @@ export function mapFun() {
handlerMeasureHeight,
handlerClearMeasure,
handlerDrawPolygon,
handlerDrawBrushLine,
handlerDrawLine,
handlerDrawPoint,
handlerDrawRectangle,
handlerClearDraw,
// 矢量操作
handlerHiddenEntity,
handlerShowEntity,
handlerRemoveEntity,
handlerFlyToEntity,
// 图层操作
handlerClearEntityLayer,
handlerHiddenEntityLayer,
handlerShowEntityLayer,
// 图层控制类
handlerAddLayer,
handlerHiddenLayer,
handlerShowLayer,
handlerRemoveLayer,
handlerFlyToLayer,
// 三维模型
handlerAddModel
};
}
// 地图函数列表options
export const funSelectOptions = [
{
label: '根据坐标定位地图视角',
value: 'handlerFlyToPoint',
// 事件名称(用于选择显示)
label: 'ceshi点击',
// 事件名(用于触发)
value: 'ceshiClick',
},
{
label: '添加任意类型图层',
value: 'handlerAddLayer',
label:"根据坐标定位地图视角",
value: 'handlerFlyToPoint'
},
{
label: '隐藏任意类型图层',
value: 'handlerHiddenLayer',
label:"添加任意类型图层",
value: 'handlerAddLayer'
},
{
label: '删除任意类型图层',
value: 'handlerRemoveLayer',
label:"隐藏指定图层",
value: 'handlerHiddenLayer'
},{
label:"显示指定图层",
value: 'handlerShowLayer'
},
{
label: '添加单个矢量数据',
value: 'handlerAddEntity',
label:"删除指定图层",
value: 'handlerRemoveLayer'
},
{
label: '隐藏单个矢量数据',
value: 'handlerHiddenEntity',
label:"跳转到指定图层",
value: 'handlerFlyToLayer'
},
{
label: '移除单个矢量数据',
value: 'handlerRemoveEntity',
label:"添加单个矢量数据",
value: 'handlerAddEntity'
},
{
label: '定位和高亮矢量数据',
value: 'handlerFlyToEntity',
label:"隐藏单个矢量数据",
value:"handlerHiddenEntity"
},
{
label: '清除全部矢量数据',
value: 'handlerClearEntityLayer',
label:"显示单个矢量数据",
value:"handlerShowEntity"
},
{
label: '隐藏全部矢量数据',
value: 'handlerHiddenEntityLayer',
label:"移除单个矢量数据",
value:"handlerRemoveEntity"
},
{
label: '点击地图拾取坐标',
value: 'handlerDrawPoint',
label:"定位和高亮矢量数据",
value:"handlerFlyToEntity"
},
{
label: '绘制贴地线',
value: 'handlerDrawLine',
label:"清除全部矢量数据",
value:"handlerClearEntityLayer"
},
{
label: '绘制图标点',
value: 'handlerDrawIconPoint',
label:"隐藏全部矢量数据",
value:"handlerHiddenEntityLayer"
},
{
label: '绘制贴地线',
value: 'handlerDrawLine',
label:"显示全部矢量数据",
value:"handlerShowEntityLayer"
},
{
label: '绘制贴地自由线',
value: 'handlerDrawBrushLine',
label:"点击地图拾取坐标",
value:"handlerGetPoint"
},
{
label: '绘制贴地面',
value: 'handlerDrawLine',
label:"绘制贴地线",
value:"handlerDrawLine"
},
{
label: '绘制贴地矩形',
value: 'handlerDrawRectangle',
label:"绘制图标点",
value:"handlerDrawPoint"
},
{
label: '绘制贴地面',
value: 'handlerDrawPolygon',
label:"绘制贴地自由线",
value:"handlerDrawBrushLine"
},
{
label: '贴地距离测量',
value: 'handlerMeasureSurfaceLength',
label:"军事标绘",
value:"handlerDrawJun"
},
{
label: '空间距离测量',
value: 'handlerMeasureLength',
label:"绘制贴地矩形",
value:"handlerDrawRectangle"
},
{
label: '贴地面积测量',
value: 'handlerMeasureSurfaceArea',
label:"绘制贴地面",
value:"handlerDrawPolygon"
},
{
label: '水平面积测量',
value: 'handlerMeasureArea',
label:"清除图层绘制",
value:"handlerClearDraw"
},
{
label: '坐标点位测量',
value: 'handlerMeasurePoint',
label:"贴地距离测量",
value:"handlerMeasureSurfaceLength"
},
{
label: '高度差测量',
value: 'handlerMeasureHeight',
label:"绘制自由线",
value:"drawBrushLine",
},
{
label: '清空测量数据',
value: 'handlerClearMeasure',
label:"空间距离测量",
value:"handlerMeasureLength"
},
{
label:"贴地面积测量",
value:"handlerMeasureSurfaceArea"
},
{
label:"水平面积测量",
value:"handlerMeasureArea"
},
{
label:"坐标点位测量",
value:"handlerMeasurePoint"
},
{
label:"高度差测量",
value:"handlerMeasureHeight"
},
{
label:"清空测量数据",
value:"handlerClearMeasure"
},{
label:"添加三维模型",
value:"handlerAddModel"
}
];

View File

@ -1,6 +1,7 @@
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { mapFun } from '@/hooks/ceshiFun.hook';
import { router } from '@/router';
import { previewUrl } from '@/utils';
const chartEditStore = useChartEditStore();
const ceshiFunction = mapFun();
@ -20,6 +21,12 @@ export const eventHandlerHook = (comonentList: any, elementList: any, params: an
});
window.open(routeUrl.href, '_blank');
return;
} else if (elementList[j].skipType == 'publishLink') {
const routeUrl = router.resolve({
path: previewUrl(elementList[j].url),
});
window.open(routeUrl.href, '_blank');
return;
} else {
window.open(elementList[j].url, '_blank');
return;
@ -28,6 +35,12 @@ export const eventHandlerHook = (comonentList: any, elementList: any, params: an
if (elementList[j].skipType == 'routeLink') {
router.replace(elementList[j].url);
return;
} else if (elementList[j].skipType == 'publishLink') {
const routeUrl = router.resolve({
path: previewUrl(elementList[j].url),
});
window.open(routeUrl.href, '_self');
return;
} else {
window.open(elementList[j].url, '_self');
return;

View File

@ -20,5 +20,6 @@
"r_unpublish": "Unpublish",
"r_download": "Download",
"r_delete": "Delete",
"r_more": "More"
"r_more": "More",
"r_copy_url": "Copy Release Address"
}

View File

@ -17,5 +17,6 @@
"r_unpublish": "取消发布",
"r_download": "下载",
"r_delete": "删除",
"r_more": "更多"
"r_more": "更多",
"r_copy_url": "复制发布地址"
}

View File

@ -73,7 +73,10 @@ const initMap = (newData: any) => {
//
handlerInitMeasureTool();
//
handlerInitDrawLayer();
return null;
//
AMapLoader.load({
@ -172,7 +175,7 @@ const stopWatch = watch(
await nextTick();
options = {
options = {
"scene": {
"center": {
"lat": 30.526361,
@ -2153,6 +2156,7 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
//
let graphicLayer = null;
let drawGraphicLayer = null;
let measureTool = null;
//
const handlerInitEntityLayer = () => {
@ -2185,6 +2189,17 @@ const handlerInitEntityLayer = () => {
}
}
const handlerInitDrawLayer = () => {
if(drawGraphicLayer == null){
drawGraphicLayer = new mars3d.layer.GraphicLayer({ id: 888 });
window.drawGraphicLayer = drawGraphicLayer;
window.globalMap.addLayer(drawGraphicLayer);
}
}
const handlerInitMeasureTool = () => {
measureTool = new mars3d.thing.Measure({
label: {
@ -2203,6 +2218,8 @@ const handlerInitMeasureTool = () => {
window.globalMap.addThing(measureTool)
}
// 使
const handlerDrawPoint = async () => {

View File

@ -1,36 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { DiyTestConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const option = {
// 数据
dataset: dataJson,
// 表行数
rowNum: 5,
// 轮播时间
waitTime: 2,
// 数值单位
unit: '',
// 自动排序
sort: true,
color: '#1370fb',
textColor: '#CDD2F8FF',
borderColor: '#1370fb80',
carousel: 'single',
//序号字体大小
indexFontSize: 12,
//左侧数据字体大小
leftFontSize: 12,
//右侧数据字体大小
rightFontSize: 12,
// 格式化
valueFormatter(item: { value: any}) { return item.value}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = DiyTestConfig.key
public chartConfig = cloneDeep(DiyTestConfig)
public option = cloneDeep(option)
}

View File

@ -1,95 +0,0 @@
<template>
<CollapseItem name="列表" :expanded="true">
<SettingItemBox name="基础">
<SettingItem name="表行数">
<n-input-number
v-model:value="optionData.rowNum"
:min="1"
size="small"
placeholder="请输入自动计算"
></n-input-number>
</SettingItem>
<SettingItem name="轮播时间(s)">
<n-input-number
v-model:value="optionData.waitTime"
:min="1"
size="small"
placeholder="请输入轮播时间"
></n-input-number>
</SettingItem>
<SettingItem name="数值单位">
<n-input
v-model:value="optionData.unit"
size="small"
placeholder="数值单位"
></n-input>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="样式">
<SettingItem name="主体颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.color"
></n-color-picker>
</SettingItem>
<SettingItem name="数据颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.textColor"
></n-color-picker>
</SettingItem>
<SettingItem name="底部线条">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.borderColor"
></n-color-picker>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="字体样式">
<SettingItem name="序号字体">
<n-input-number
size="small"
v-model:value="optionData.indexFontSize"
:min="12"
/>
</SettingItem>
<SettingItem name="左侧数据字体">
<n-input-number
size="small"
v-model:value="optionData.leftFontSize"
:min="12"
/>
</SettingItem>
<SettingItem name="右侧数据字体">
<n-input-number
size="small"
v-model:value="optionData.rightFontSize"
:min="12"
/>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
</script>

View File

@ -1,14 +0,0 @@
[
{ "name": "荣成", "value": 26700 },
{ "name": "河南", "value": 20700 },
{ "name": "河北", "value": 18700 },
{ "name": "徐州", "value": 17800 },
{ "name": "漯河", "value": 16756 },
{ "name": "三门峡", "value": 12343 },
{ "name": "郑州", "value": 9822 },
{ "name": "周口", "value": 8912 },
{ "name": "濮阳", "value": 6834 },
{ "name": "信阳", "value": 5875 },
{ "name": "新乡", "value": 3832 },
{ "name": "大同", "value": 1811 }
]

View File

@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const DiyTestConfig: ConfigType = {
key: 'DiyTest',
chartKey: 'VDiyTest',
conKey: 'VCDiyTest',
title: '自定义测试组件',
category: ChatCategoryEnum.DIY,
categoryName: ChatCategoryEnumName.DIY,
package: PackagesCategoryEnum.DIY,
chartFrame: ChartFrameEnum.COMMON,
image: 'tables_list.png'
}

View File

@ -1,57 +0,0 @@
<template>
<component :is="remote" v-if="remote" @childClick="childClick" :optionParam="optionParam" />
</template>
<script setup lang="ts">
import { loadModule } from 'vue3-sfc-loader/dist/vue3-sfc-loader'
import { ref, onMounted, getCurrentInstance, defineAsyncComponent } from 'vue'
import * as Vue from 'vue'
import { PropType } from 'vue'
import { option } from './config'
import { CreateComponentType } from '@/packages/index.d'
let remote = ref()
let url = 'http://localhost:3000/getVue3Str'
onMounted(() => {
load(url)
})
const load = async url => {
let res = await fetch(url).then(res => res.json())
const options = {
moduleCache: {
vue: Vue
},
async getFile() {
return res.fileStr
},
addStyle(textContent) {
const style = Object.assign(document.createElement('style'), { textContent })
const ref = document.head.getElementsByTagName('style')[0] || null
document.head.insertBefore(style, ref)
}
}
//
remote.value = defineAsyncComponent(() => loadModule(res.fileName || 'loader.vue', options))
}
const childClick = newVal => {
console.log('子组件点击事件', newVal)
}
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
},
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
console.log('props', props)
const optionParam = ref(props.chartConfig.option ? props.chartConfig.option : option)
</script>
<style lang="scss" scoped></style>

View File

@ -1,22 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { RemoteConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const option = {
backgroundColor: '#000000FF',
// 数据
dataset: dataJson,
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = RemoteConfig.key
public chartConfig = cloneDeep(RemoteConfig)
public option = cloneDeep(option)
constructor() {
super();
this.attr.w = 600;
this.attr.h = 600;
}
}

View File

@ -1,33 +0,0 @@
<template>
<CollapseItem name="配置" :expanded="true">
<SettingItemBox name="背景颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.backgroundColor"
></n-color-picker>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
console.log('自定义组件配置props',props)
</script>

View File

@ -1,14 +0,0 @@
[
{ "name": "荣成", "value": 26700 },
{ "name": "河南", "value": 20700 },
{ "name": "河北", "value": 18700 },
{ "name": "徐州", "value": 17800 },
{ "name": "漯河", "value": 16756 },
{ "name": "三门峡", "value": 12343 },
{ "name": "郑州", "value": 9822 },
{ "name": "周口", "value": 8912 },
{ "name": "濮阳", "value": 6834 },
{ "name": "信阳", "value": 5875 },
{ "name": "新乡", "value": 3832 },
{ "name": "大同", "value": 1811 }
]

View File

@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const RemoteConfig: ConfigType = {
key: 'Remote',
chartKey: 'Remote',
conKey: 'RemoteConfig',
title: '测试远程组件',
category: ChatCategoryEnum.DIY,
categoryName: ChatCategoryEnumName.DIY,
package: PackagesCategoryEnum.DIY,
chartFrame: ChartFrameEnum.COMMON,
image: 'tables_list.png'
}

View File

@ -1,62 +0,0 @@
<template>
<component :is="remote" v-if="remote" :config="chartConfig" :data="data" />
</template>
<script setup lang="ts">
import { loadModule } from 'vue3-sfc-loader/dist/vue3-sfc-loader'
import { ref, onMounted, getCurrentInstance, defineAsyncComponent } from 'vue'
import * as Vue from 'vue'
import { PropType } from 'vue'
import { option } from './config'
import { CreateComponentType } from '@/packages/index.d'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
},
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
let remote = ref()
let url = 'http://192.168.10.124:3000/getVue3Str2'
const data = ref(props.chartConfig.option.dataset)
onMounted(() => {
load(url)
})
const load = async url => {
let res = await fetch(url).then(res => res.json())
const options = {
moduleCache: {
vue: Vue
},
async getFile() {
return res.fileStr
},
addStyle(textContent) {
const style = Object.assign(document.createElement('style'), { textContent })
const ref = document.head.getElementsByTagName('style')[0] || null
document.head.insertBefore(style, ref)
}
}
//
remote.value = defineAsyncComponent(() => loadModule(res.fileName || 'loader.vue', options))
}
console.log('props', props)
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
console.log('接口获取数据',newData)
data.value = newData
})
</script>
<style lang="scss" scoped></style>

View File

@ -1,3 +0,0 @@
import { DiyTestConfig } from './DiyTest'
import { RemoteConfig } from './Remote'
export default [ DiyTestConfig, RemoteConfig ]

View File

@ -1,9 +0,0 @@
export enum ChatCategoryEnum {
TABLE = 'Tables',
DIY = 'Diy'
}
export enum ChatCategoryEnumName {
TABLE = '表格',
DIY = '自定义'
}

View File

@ -1,3 +0,0 @@
import Diy from './Diy'
export const DiyList = [...Diy]

View File

@ -39,7 +39,7 @@
width="106.1%"
height="124.9%"
filterUnits="objectBoundingBox"
id="filter-6"
id="filter-GeneralHead-6"
>
<feGaussianBlur stdDeviation="4.31844888" in="SourceGraphic"></feGaussianBlur>
</filter>
@ -76,7 +76,7 @@
points="10.3064025 0 166.362718 0 176.570151 13.6763066 255.888803 13.6763066 399.202062 13.6763066 399.201597 38.3517324 205.452516 38.3517324 0 38.3517324 0 11.1814815"
></polygon>
<g id="椭圆形">
<mask id="mask-4" fill="white">
<mask id="mask-GeneralHead-4" fill="white">
<use xlink:href="#path-GeneralHead-3"></use>
</mask>
<use
@ -86,8 +86,8 @@
></use>
<ellipse
fill="url(#radialGradient-5)"
filter="url(#filter-6)"
mask="url(#mask-4)"
filter="url(#filter-GeneralHead-6)"
mask="url(#mask-GeneralHead-4)"
cx="180.697047"
cy="25.5190419"
rx="214"

View File

@ -1,5 +1,5 @@
<template>
<div class="MoreButton">
<div class="MoreButton" @click="clickBtn">
<n-button text :color="option.buttonStyle.color" size="large">
<span :style="{ fontSize: option.buttonStyle.fontSize + 'px' }">{{ option.buttonName }}</span>
<Title v-if="option.buttonStyle.iconFlag" class="title" :buttonStyle="option.buttonStyle" />
@ -13,8 +13,10 @@
import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
import Title from './svg/title.vue';
const chartEditStore = useChartEditStore();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
@ -28,6 +30,22 @@
buttonName: props.chartConfig.option.buttonName,
buttonStyle: props.chartConfig.option.buttonStyle,
});
//
const clickElementItem = ref([]);
const list = props.chartConfig.events.interactConfigEvents;
for (let i = 0; i < list.length; i++) {
if (list[i].type == 'click') {
for (let j = 0; j < list[i].movementList.length; j++) {
clickElementItem.value.push(list[i].movementList[j]);
}
}
}
const clickBtn = () => {
eventHandlerHook(chartEditStore.getComponentList, clickElementItem.value);
};
</script>
<style lang="scss" scoped>

View File

@ -1,5 +1,5 @@
<template>
<div class="ModalButton">
<div class="ModalButton" @click="clickBtn">
<n-button text>
<Button :w="w" :h="h" :buttonName="option.buttonName" :buttonStyle="option.buttonStyle" />
</n-button>
@ -12,8 +12,10 @@
import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
import Button from './svg/button.vue';
const chartEditStore = useChartEditStore();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
@ -27,6 +29,22 @@
buttonName: props.chartConfig.option.buttonName,
buttonStyle: props.chartConfig.option.buttonStyle,
});
//
const clickElementItem = ref([]);
const list = props.chartConfig.events.interactConfigEvents;
for (let i = 0; i < list.length; i++) {
if (list[i].type == 'click') {
for (let j = 0; j < list[i].movementList.length; j++) {
clickElementItem.value.push(list[i].movementList[j]);
}
}
}
const clickBtn = () => {
eventHandlerHook(chartEditStore.getComponentList, clickElementItem.value);
};
</script>
<style lang="scss" scoped>

View File

@ -11,14 +11,21 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<rect id="path-ModalButton-1" x="0" y="0" width="120.597701" height="43" rx="3"></rect>
<rect
id="path-ModalButton-yellow-1"
x="0"
y="0"
width="120.597701"
height="43"
rx="3"
></rect>
<filter
x="-3.3%"
y="-9.3%"
width="106.6%"
height="118.6%"
filterUnits="objectBoundingBox"
id="filter-2"
id="filter-yellow-2"
>
<feMorphology
radius="2"
@ -46,11 +53,23 @@
in="shadowInnerInner1"
></feColorMatrix>
</filter>
<linearGradient x1="50%" y1="0%" x2="50%" y2="99.5930705%" id="linearGradient-3">
<linearGradient
x1="50%"
y1="0%"
x2="50%"
y2="99.5930705%"
id="linearGradient-ModalButton-yellow-3"
>
<stop stop-color="#FF8D00" offset="0%"></stop>
<stop stop-color="#7D3700" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="99.7555179%" y1="50%" x2="0.659186059%" y2="50%" id="linearGradient-4">
<linearGradient
x1="99.7555179%"
y1="50%"
x2="0.659186059%"
y2="50%"
id="linearGradient-ModalButton-yellow-4"
>
<stop stop-color="#FF8900" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#FFB200" offset="52.4037608%"></stop>
<stop stop-color="#FF8900" stop-opacity="0" offset="100%"></stop>
@ -61,12 +80,16 @@
<g id="弹窗----" transform="translate(175.2674, 165.0542)">
<g id="编组-56" transform="translate(997, 604)">
<g id="矩形">
<use fill="#582900" fill-rule="evenodd" xlink:href="#path-ModalButton-1"></use>
<use
fill="#582900"
fill-rule="evenodd"
xlink:href="#path-ModalButton-yellow-1"
></use>
<use
fill="black"
fill-opacity="1"
filter="url(#filter-2)"
xlink:href="#path-ModalButton-1"
filter="url(#filter-yellow-2)"
xlink:href="#path-ModalButton-yellow-1"
></use>
<rect
stroke="#FF8900"
@ -82,12 +105,12 @@
<path
d="M2.68679754,0 L117.920714,2.22044605e-15 C118.472999,9.96743133e-15 118.920714,0.44771525 118.920714,1 C118.920714,1.28969745 118.795083,1.56515805 118.576335,1.75508987 L92.5517241,24.3514589 L92.5517241,24.3514589 L28.045977,24.2338973 L2.03298651,1.75665787 C1.6150959,1.39556801 1.56904981,0.764079571 1.93013967,0.346188968 C2.12009371,0.126354469 2.39626399,-1.9450313e-15 2.68679754,-1.99840144e-15 Z"
id="矩形"
fill="url(#linearGradient-3)"
fill="url(#linearGradient-ModalButton-yellow-3)"
opacity="0.480172294"
></path>
<rect
id="矩形"
fill="url(#linearGradient-4)"
fill="url(#linearGradient-ModalButton-yellow-4)"
x="25.5110522"
y="41.7453581"
width="64.9372237"
@ -129,14 +152,21 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<rect id="path-ModalButton-1" x="0" y="0" width="120.597701" height="43" rx="3"></rect>
<rect
id="path-ModalButton-green-1"
x="0"
y="0"
width="120.597701"
height="43"
rx="3"
></rect>
<filter
x="-3.3%"
y="-9.3%"
width="106.6%"
height="118.6%"
filterUnits="objectBoundingBox"
id="filter-2"
id="filter-ModalButton-green-2"
>
<feMorphology
radius="2"
@ -164,11 +194,17 @@
in="shadowInnerInner1"
></feColorMatrix>
</filter>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-ModalButton-green-3">
<stop stop-color="#00F535" offset="0%"></stop>
<stop stop-color="#003310" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="99.7555179%" y1="50%" x2="0%" y2="50%" id="linearGradient-4">
<linearGradient
x1="99.7555179%"
y1="50%"
x2="0%"
y2="50%"
id="linearGradient-ModalButton-green-4"
>
<stop stop-color="#00FF2F" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#00F535" offset="50.8795251%"></stop>
<stop stop-color="#00FF4B" stop-opacity="0" offset="100%"></stop>
@ -179,12 +215,16 @@
<g id="弹窗----" transform="translate(175.2674, 165.0542)">
<g id="编组-61" transform="translate(1281, 604)">
<g id="矩形">
<use fill="#003310" fill-rule="evenodd" xlink:href="#path-ModalButton-1"></use>
<use
fill="#003310"
fill-rule="evenodd"
xlink:href="#path-ModalButton-green-1"
></use>
<use
fill="black"
fill-opacity="1"
filter="url(#filter-2)"
xlink:href="#path-ModalButton-1"
filter="url(#filter-ModalButton-green-2)"
xlink:href="#path-ModalButton-green-1"
></use>
<rect
stroke="#00FC3A"
@ -247,14 +287,14 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<rect id="path-ModalButton-1" x="0" y="0" width="120.597701" height="43" rx="3"></rect>
<rect id="path-ModalButton-red-1" x="0" y="0" width="120.597701" height="43" rx="3"></rect>
<filter
x="-3.3%"
y="-9.3%"
width="106.6%"
height="118.6%"
filterUnits="objectBoundingBox"
id="filter-2"
id="filter-ModalButton-red-2"
>
<feMorphology
radius="2"
@ -282,11 +322,17 @@
in="shadowInnerInner1"
></feColorMatrix>
</filter>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-ModalButton-red-3">
<stop stop-color="#F02626" offset="0%"></stop>
<stop stop-color="#F02626" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="99.7555179%" y1="50%" x2="0%" y2="50%" id="linearGradient-4">
<linearGradient
x1="99.7555179%"
y1="50%"
x2="0%"
y2="50%"
id="linearGradient-ModalButton-red-4"
>
<stop stop-color="#FB6C69" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#F02626" offset="50.8795251%"></stop>
<stop stop-color="#F9413E" stop-opacity="0" offset="100%"></stop>
@ -297,12 +343,12 @@
<g id="弹窗----" transform="translate(175.2674, 165.0542)">
<g id="编组-61" transform="translate(1281, 604)">
<g id="矩形">
<use fill="#270304" fill-rule="evenodd" xlink:href="#path-ModalButton-1"></use>
<use fill="#270304" fill-rule="evenodd" xlink:href="#path-ModalButton-red-1"></use>
<use
fill="black"
fill-opacity="1"
filter="url(#filter-2)"
xlink:href="#path-ModalButton-1"
xlink:href="#path-ModalButton-red-1"
></use>
<rect
stroke="#F02626"
@ -318,12 +364,12 @@
<path
d="M2.68679754,0 L117.920714,2.22044605e-15 C118.472999,9.96743133e-15 118.920714,0.44771525 118.920714,1 C118.920714,1.28969745 118.795083,1.56515805 118.576335,1.75508987 L92.5517241,24.3514589 L92.5517241,24.3514589 L28.045977,24.2338973 L2.03298651,1.75665787 C1.6150959,1.39556801 1.56904981,0.764079571 1.93013967,0.346188968 C2.12009371,0.126354469 2.39626399,-1.9450313e-15 2.68679754,-1.99840144e-15 Z"
id="矩形"
fill="url(#linearGradient-3)"
fill="url(#linearGradient-ModalButton-red-3)"
opacity="0.480172294"
></path>
<rect
id="矩形"
fill="url(#linearGradient-4)"
fill="url(#linearGradient-ModalButton-red-4)"
x="40.5857648"
y="41.7453581"
width="64.9372237"

View File

@ -12,15 +12,15 @@ export const option = {
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg',
],
buttonStyle:{
dotBottom: 10,
dotLeft: 120,
dotBottom: 5,
dotLeft: 37,
dotColor1: '#00611a',
dotColor2: '#00cc13',
buttonWidth: 20,
buttonHeight: 60,
buttonBottom: 80,
buttonBottom: 37,
buttonLeftAndRight: 0,
buttonColor: '#A4A4A4FF',

View File

@ -70,7 +70,7 @@
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.dataStyle.showDots" size="small" />
<n-text>显示</n-text>
<n-text>控制点</n-text>
</n-space>
</SettingItem>
<SettingItem>
@ -87,19 +87,16 @@
</SettingItem>
</SettingItem-box>
<SettingItem-box name="控制点样式">
<SettingItem-box name="控制点样式" v-if="optionData.dataStyle.showDots">
<SettingItem name="控制点位置(下)">
<n-input-number
v-model:value="optionData.buttonStyle.dotBottom"
size="small"
></n-input-number>
<n-input-number v-model:value="optionData.buttonStyle.dotBottom" size="small">
<template #suffix> % </template>
</n-input-number>
</SettingItem>
<SettingItem name="控制点位置(左)">
<n-input-number
v-model:value="optionData.buttonStyle.dotLeft"
size="small"
:min="0"
></n-input-number>
<n-input-number v-model:value="optionData.buttonStyle.dotLeft" size="small" :min="0">
<template #suffix> % </template>
</n-input-number>
</SettingItem>
<SettingItem name="控制点颜色1">
<n-color-picker
@ -132,34 +129,34 @@
</n-button>
</SettingItem>
</SettingItem-box>
<SettingItem-box name="箭头样式">
<SettingItem name="箭头按钮度">
<SettingItem-box name="箭头样式" v-if="optionData.dataStyle.showArrow">
<SettingItem name="箭头按钮度">
<n-input-number
v-model:value="optionData.buttonStyle.buttonBottom"
v-model:value="optionData.buttonStyle.buttonWidth"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<SettingItem name="箭头按钮度">
<SettingItem name="箭头按钮度">
<n-input-number
v-model:value="optionData.buttonStyle.buttonHeight"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<SettingItem name="箭头位置(上下)">
<n-input-number
v-model:value="optionData.buttonStyle.buttonBottom"
size="small"
:min="0"
></n-input-number>
<SettingItem name="箭头位置(下)">
<n-input-number v-model:value="optionData.buttonStyle.buttonBottom" size="small" :min="0">
<template #suffix> % </template>
</n-input-number>
</SettingItem>
<SettingItem name="箭头位置(左右">
<SettingItem name="箭头位置(边界)">
<n-input-number
v-model:value="optionData.buttonStyle.buttonWidth"
v-model:value="optionData.buttonStyle.buttonLeftAndRight"
size="small"
:min="0"
></n-input-number>
>
<template #suffix> % </template>
</n-input-number>
</SettingItem>
<SettingItem name="箭头按钮颜色">
<n-color-picker

View File

@ -127,14 +127,14 @@
.arrow-left {
display: flex;
position: absolute;
bottom: v-bind('`${option.buttonStyle.buttonBottom}px`');
left: v-bind('`${option.buttonStyle.buttonLeftAndRight}px`');
bottom: v-bind('`${option.buttonStyle.buttonBottom}%`');
left: v-bind('`${option.buttonStyle.buttonLeftAndRight}%`');
}
.arrow-right {
display: flex;
position: absolute;
bottom: v-bind('`${option.buttonStyle.buttonBottom}px`');
right: v-bind('`${option.buttonStyle.buttonLeftAndRight}px`');
bottom: v-bind('`${option.buttonStyle.buttonBottom}%`');
right: v-bind('`${option.buttonStyle.buttonLeftAndRight}%`');
}
.dots {
@ -142,8 +142,8 @@
margin: 0;
padding: 0;
position: absolute;
bottom: v-bind('`${option.buttonStyle.dotBottom}px`');
left: v-bind('`${option.buttonStyle.dotLeft}px`');
bottom: v-bind('`${option.buttonStyle.dotBottom}%`');
left: v-bind('`${option.buttonStyle.dotLeft}%`');
}
.dots li {

View File

@ -6,6 +6,13 @@ import { ModalFrameConfig } from './index'
export const option = {
dataStyle:{
mask: false,
maskClickClose: false,
maskColor:'#FFFFFF00',
maskFrameX: 0,
maskFrameY: 0,
maskFrameW: 0,
maskFrameH: 0,
// 背景颜色
backgroud: '#161A1A',
// 左上、右下角装饰颜色
@ -24,6 +31,7 @@ export const option = {
bottomUseColor: '#FFE4AC',
},
dataStyleClone:{
maskColor:'#000000FF',
// 背景颜色
backgroud: '#161A1A',
// 左上、右下角装饰颜色
@ -45,7 +53,7 @@ export const option = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = ModalFrameConfig.key
public attr = { ...chartInitConfig, w: 1490, h: 712, zIndex: 5 }
public attr = { ...chartInitConfig, w: 1490, h: 712, zIndex: -1 }
public chartConfig = cloneDeep(ModalFrameConfig)
public option = cloneDeep(option)
}

View File

@ -1,5 +1,59 @@
<template>
<CollapseItem name="弹窗设置" :expanded="true">
<SettingItemBox name="样式设置">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.dataStyle.mask" size="small" />
<n-text>展示遮罩</n-text>
</n-space>
</SettingItem>
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.dataStyle.maskClickClose" size="small" />
<n-text>点击非弹窗部分是否关闭弹窗</n-text>
</n-space>
</SettingItem>
<SettingItem name="遮罩颜色" v-if="optionData.dataStyle.mask">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.maskColor"
></n-color-picker>
</SettingItem>
<SettingItem name="弹窗宽度" v-if="optionData.dataStyle.mask">
<n-input-number
v-model:value="optionData.dataStyle.maskFrameW"
:min="0"
size="small"
placeholder="弹窗宽度"
/>
</SettingItem>
<SettingItem name="弹窗X轴位置" v-if="optionData.dataStyle.mask">
<n-input-number
v-model:value="optionData.dataStyle.maskFrameX"
:min="0"
size="small"
placeholder="弹窗X轴位置"
/>
</SettingItem>
<SettingItem name="弹窗Y轴位置" v-if="optionData.dataStyle.mask">
<n-input-number
v-model:value="optionData.dataStyle.maskFrameY"
:min="0"
size="small"
placeholder="弹窗Y轴位置"
/>
</SettingItem>
<!-- <SettingItem name="弹窗高度" v-if="optionData.dataStyle.mask">
<n-input-number
v-model:value="optionData.dataStyle.maskFrameH"
:min="0"
size="small"
placeholder="弹窗高度"
/>
</SettingItem> -->
</SettingItemBox>
<SettingItemBox name="颜色设置">
<SettingItem name="背景颜色">
<n-color-picker

View File

@ -1,17 +1,30 @@
<template>
<div class="ModalFrame">
<Frame :w="w" :h="h" :dataStyle="option.dataStyle" />
<div class="ModalFrame" @click="clickFrame">
<div class="frame">
<Frame :w="oframeWidth" :h="frameHeight" :dataStyle="option.dataStyle" />
</div>
</div>
</template>
<script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue';
import {
computed,
PropType,
toRefs,
watch,
reactive,
ref,
onMounted,
onBeforeUnmount,
} from 'vue';
import { CreateComponentType } from '@/packages/index.d';
import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks';
import Frame from './svg/frame.vue';
import cloneDeep from 'lodash/cloneDeep';
const chartEditStore = useChartEditStore();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
@ -19,11 +32,160 @@
},
});
const { w, h } = toRefs(props.chartConfig.attr);
const { w, h, x, y } = toRefs(props.chartConfig.attr);
const option = reactive({
dataStyle: props.chartConfig.option.dataStyle,
});
//
const frameWidth = computed(() => {
if (option.dataStyle.mask) {
return option.dataStyle.maskFrameW;
} else {
return w.value;
}
});
const frameHeight = computed(() => {
if (option.dataStyle.mask) {
return option.dataStyle.maskFrameH;
} else {
return h.value;
}
});
const frameTop = computed(() => {
if (option.dataStyle.mask) {
return option.dataStyle.maskFrameY;
} else {
return 0;
}
});
const frameLeft = computed(() => {
if (option.dataStyle.mask) {
return option.dataStyle.maskFrameX;
} else {
return 0;
}
});
//
watch(
() => option.dataStyle.mask,
() => {
if (option.dataStyle.mask) {
option.dataStyle.maskFrameX = cloneDeep(x.value);
option.dataStyle.maskFrameY = cloneDeep(y.value);
option.dataStyle.maskFrameW = cloneDeep(w.value);
option.dataStyle.maskFrameH = cloneDeep(h.value);
x.value = 0;
y.value = 0;
w.value = chartEditStore.getEditCanvasConfig.width;
h.value = chartEditStore.getEditCanvasConfig.height;
} else {
x.value = option.dataStyle.maskFrameX;
y.value = option.dataStyle.maskFrameY;
w.value = option.dataStyle.maskFrameW;
h.value = option.dataStyle.maskFrameH;
}
},
);
watch(
() => option.dataStyle.maskFrameW,
() => {
option.dataStyle.maskFrameH = (option.dataStyle.maskFrameW * 712) / 1490;
},
);
//
function clickFrame(event) {
if (!window.location.href.includes('/chart/home/')) {
if (option.dataStyle.mask && option.dataStyle.maskClickClose) {
chartEditStore.getComponentList.forEach((element) => {
if (
element.key == props.chartConfig.key ||
(element.isGroup && element?.groupList.some((li) => li.key == props.chartConfig.key))
) {
if (
!(
element.option.maskFrameX <= event.x &&
event.x <= element.option.maskFrameX + element.option.maskFrameW &&
element.option.maskFrameY <= event.y &&
event.y <= element.option.maskFrameY + element.option.maskFrameH
)
) {
if (!element.status.hide) {
element.status.hide = true;
}
}
}
});
}
}
}
const num = ref(0);
function getModalFrameIsNum() {
chartEditStore.getComponentList.forEach((element, index) => {
if (
element.key == props.chartConfig.key ||
(element.isGroup && element?.groupList.some((li) => li.key == props.chartConfig.key))
) {
num.value = index;
}
});
}
let isClickUpdate = false;
watch(
() => chartEditStore.getComponentList[num.value]?.status?.hide,
() => {
// if (!chartEditStore.getComponentList[num.value]?.status?.hide) {
isClickUpdate = true;
// }
},
{
deep: true,
},
);
//
const handleKeydown = (event: MouseEvent) => {
if (!window.location.href.includes('/chart/home/')) {
if (!option.dataStyle.mask && option.dataStyle.maskClickClose) {
chartEditStore.getComponentList.forEach((element) => {
//
if (
element.key == props.chartConfig.key ||
(element.isGroup && element?.groupList.some((li) => li.key == props.chartConfig.key))
) {
if (
!(
element.attr.x <= event.x &&
event.x <= element.attr.x + element.attr.w &&
element.attr.y <= event.y &&
event.y <= element.attr.y + element.attr.h
)
) {
if (!element.status.hide && !isClickUpdate) {
element.status.hide = true;
} else {
isClickUpdate = false;
}
}
}
});
}
}
};
//
onMounted(() => {
getModalFrameIsNum();
window.addEventListener('click', handleKeydown);
});
//
onBeforeUnmount(() => {
window.removeEventListener('click', handleKeydown);
});
</script>
<style lang="scss" scoped>
@ -33,5 +195,11 @@
text-align: center;
width: v-bind('`${w}px`');
height: v-bind('`${h}px`');
background: v-bind('`${option.dataStyle.maskColor}`');
}
.frame {
position: absolute;
top: v-bind('`${frameTop}px`');
left: v-bind('`${frameLeft}px`');
}
</style>

View File

@ -16,6 +16,7 @@ export const option = {
borderWidth: 2,
borderColor: '#008000',
borderColorClone: '#008000',
padding: 4,
}
}

View File

@ -34,6 +34,14 @@
v-model:value="optionData.dataStyle.borderColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.borderColor = optionData.dataStyle.borderColorClone"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="边框宽度">
<n-input-number
v-model:value="optionData.dataStyle.borderWidth"

View File

@ -8,8 +8,8 @@
:object-fit="option.dataset.fit"
:loop="option.dataStyle.videoLoop"
:muted="option.dataStyle.videoMuted"
:width="`${w - option.dataStyle.padding - option.dataStyle.borderWidth}`"
:height="`${h - option.dataStyle.padding - option.dataStyle.borderWidth}`"
:width="`${w - option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:height="`${h - option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
:src="option.dataset"
/>
</div>

View File

@ -15,10 +15,8 @@ export const option = {
marginleft: 20,
gap: 16,
topMarginTop: 5,
iconSize: 45,
iconX: 12,
iconY: 12,
iconColor1: '#B8FDB4',
iconColor2: '#60EC8D',
topWidth: 80,
topHeight: 80,
rectStrokeColor: '#00611A',
@ -29,17 +27,35 @@ export const option = {
bottomFontSize1: 20,
bottomFontColor2: '#FFFFFF',
bottomFontSize2: 12,
lineColor: '#A4F9AB',
lineFontSize: 12,
bottomFontColor3: '#FFFFFF',
bottomFontSize3: 12,
lineColor: '#A4F9AB',
bottomMarginTop: 16,
bottomWidth: 80,
bottomHeight: 80 * 97 / 71,
bottomLineColor1: '#337D4E',
bottomLineColor2: '#2D593B',
bottomComponentColor1: '#6FEF94',
bottomComponentColor2: '#A8F8C6',
},
dataStyleClone: {
iconColor1: '#B8FDB4',
iconColor2: '#60EC8D',
rectStrokeColor: '#00611A',
rectFillColor: '#0A251E',
gFillColor: '#4FE985',
bottomFontColor1: '#A4F9AB',
bottomFontColor2: '#FFFFFF',
lineColor: '#A4F9AB',
bottomFontColor3: '#FFFFFF',
bottomComponentColor1: '#337D4E',
bottomComponentColor2: '#2D593B',
bottomLineColor1: '#6FEF94',
bottomLineColor2: '#A8F8C6',
}
}

View File

@ -35,57 +35,47 @@
<SettingItem name="组件间隔">
<n-input-number v-model:value="optionData.dataStyle.gap" min="0" type="text" size="small" />
</SettingItem>
<SettingItem name="上方组件与下方组件之间的间隔距离">
<n-input-number
v-model:value="optionData.dataStyle.bottomMarginTop"
min="0"
type="text"
size="small"
/>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="上方组件设置">
<SettingItem name="上方距离">
<n-input-number
v-model:value="optionData.dataStyle.topMarginTop"
min="0"
type="text"
<SettingItem name="图标渐变颜色(始)">
<n-color-picker
size="small"
/>
:modes="['rgb']"
v-model:value="optionData.dataStyle.iconColor1"
></n-color-picker>
</SettingItem>
<SettingItem name="图标大小">
<n-input-number
v-model:value="optionData.dataStyle.iconSize"
min="0"
type="text"
<SettingItem>
<n-button
size="small"
/>
@click="optionData.dataStyle.iconColor1 = optionData.dataStyleClone.iconColor1"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="图标横坐标位置">
<n-input-number
v-model:value="optionData.dataStyle.iconX"
min="0"
type="text"
<SettingItem name="图标渐变颜色(终)">
<n-color-picker
size="small"
/>
:modes="['rgb']"
v-model:value="optionData.dataStyle.iconColor2"
></n-color-picker>
</SettingItem>
<SettingItem name="图标纵坐标位置">
<n-input-number
v-model:value="optionData.dataStyle.iconY"
min="0"
type="text"
<SettingItem>
<n-button
size="small"
/>
@click="optionData.dataStyle.iconColor2 = optionData.dataStyleClone.iconColor2"
>
恢复默认
</n-button>
</SettingItem>
<!-- <SettingItem name="组件宽度">
<n-input-number
v-model:value="optionData.dataStyle.topWidth"
min="0"
type="text"
size="small"
/>
</SettingItem>
<SettingItem name="组件高度">
<n-input-number
v-model:value="optionData.dataStyle.topHeight"
min="0"
type="text"
size="small"
/>
</SettingItem> -->
<SettingItem name="组件边框颜色">
<n-color-picker
size="small"
@ -141,12 +131,15 @@
v-model:value="optionData.dataStyle.bottomFontColor1"
></n-color-picker>
</SettingItem>
<SettingItem name="数量字体大小">
<n-input-number
v-model:value="optionData.dataStyle.bottomFontSize1"
:min="0"
<SettingItem>
<n-button
size="small"
/>
@click="
optionData.dataStyle.bottomFontColor1 = optionData.dataStyleClone.bottomFontColor1
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="单位字体颜色">
<n-color-picker
@ -155,26 +148,15 @@
v-model:value="optionData.dataStyle.bottomFontColor2"
></n-color-picker>
</SettingItem>
<SettingItem name="单位字体大小">
<n-input-number
v-model:value="optionData.dataStyle.bottomFontSize2"
:min="0"
<SettingItem>
<n-button
size="small"
/>
</SettingItem>
<SettingItem name="标题字体颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.bottomFontColor3"
></n-color-picker>
</SettingItem>
<SettingItem name="标题字体大小">
<n-input-number
v-model:value="optionData.dataStyle.bottomFontSize3"
:min="0"
size="small"
/>
@click="
optionData.dataStyle.bottomFontColor2 = optionData.dataStyleClone.bottomFontColor2
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="横线颜色">
<n-color-picker
@ -183,14 +165,127 @@
v-model:value="optionData.dataStyle.lineColor"
></n-color-picker>
</SettingItem>
<SettingItem name="距离上方组件距离">
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.lineColor = optionData.dataStyleClone.lineColor"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题字体颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.bottomFontColor3"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomFontColor3 = optionData.dataStyleClone.bottomFontColor3
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="数量字体大小">
<n-input-number
v-model:value="optionData.dataStyle.bottomMarginTop"
min="0"
type="text"
v-model:value="optionData.dataStyle.bottomFontSize1"
:min="0"
size="small"
/>
</SettingItem>
<SettingItem name="单位字体大小">
<n-input-number
v-model:value="optionData.dataStyle.bottomFontSize2"
:min="0"
size="small"
/>
</SettingItem>
<SettingItem name="横线字体大小">
<n-input-number v-model:value="optionData.dataStyle.lineFontSize" :min="0" size="small" />
</SettingItem>
<SettingItem name="标题字体大小">
<n-input-number
v-model:value="optionData.dataStyle.bottomFontSize3"
:min="0"
size="small"
/>
</SettingItem>
<SettingItem name="边界渐变颜色(始)">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.bottomLineColor1"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomLineColor1 = optionData.dataStyleClone.bottomLineColor1
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="边界渐变颜色(终)">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.bottomLineColor2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomLineColor2 = optionData.dataStyleClone.bottomLineColor2
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="组件渐变颜色(始)">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.bottomComponentColor1"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomComponentColor1 =
optionData.dataStyleClone.bottomComponentColor1
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="组件渐变颜色(终)">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.bottomComponentColor2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.bottomComponentColor2 =
optionData.dataStyleClone.bottomComponentColor2
"
>
恢复默认
</n-button>
</SettingItem>
<!-- <SettingItem name="组件宽度">
<n-input-number

View File

@ -34,19 +34,6 @@
dataStyle: props.chartConfig.option.dataStyle,
});
// watch(
// () => option.dataStyle.topWidth,
// () => {
// option.dataStyle.topHeight = option.dataStyle.topWidth;
// option.dataStyle.bottomWidth = option.dataStyle.topWidth;
// option.dataStyle.bottomHeight = 97 * (option.dataStyle.bottomWidth / 71);
// },
// {
// immediate: true,
// deep: true,
// },
// );
watch(
() => w.value,
() => {

View File

@ -16,8 +16,12 @@
y2="68.6506732%"
id="linearGradient-WuRenJiFeiXingShuJu-1"
>
<stop stop-color="#337D4E" offset="0%"></stop>
<stop stop-color="#2D593B" stop-opacity="0" offset="100%"></stop>
<stop :stop-color="props.dataStyle.bottomComponentColor1" offset="0%"></stop>
<stop
:stop-color="props.dataStyle.bottomComponentColor2"
stop-opacity="0"
offset="100%"
></stop>
</linearGradient>
<linearGradient
x1="100%"
@ -26,8 +30,8 @@
y2="50%"
id="linearGradient-WuRenJiFeiXingShuJu-2"
>
<stop stop-color="#6FEF94" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#A8F8C6" offset="100%"></stop>
<stop :stop-color="props.dataStyle.bottomLineColor1" stop-opacity="0" offset="0%"></stop>
<stop :stop-color="props.dataStyle.bottomLineColor2" offset="100%"></stop>
</linearGradient>
</defs>
<g
@ -65,7 +69,7 @@
</g>
</g>
<text
x="45%"
x="50%"
y="30"
text-anchor="middle"
:fill="props.dataStyle.bottomFontColor1"
@ -74,7 +78,7 @@
{{ Number(props.item.num).toLocaleString() }}
</text>
<text
x="45%"
x="50%"
y="50"
text-anchor="middle"
:fill="props.dataStyle.bottomFontColor2"
@ -82,11 +86,17 @@
>
{{ props.item.unit }}
</text>
<text x="45%" y="60" text-anchor="middle" :fill="props.dataStyle.lineColor" font-size="16">
<text
x="50%"
y="60"
text-anchor="middle"
:fill="props.dataStyle.lineColor"
:font-size="props.dataStyle.lineFontSize"
>
</text>
<text
x="45%"
x="50%"
y="75"
text-anchor="middle"
:fill="props.dataStyle.bottomFontColor3"

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@ import { WuRenJiImageConfig } from './index'
export const option = {
dataset: {
url: 'src/assets/images/chart/zhigan/component/example1.png'
url: 'src/assets/images/chart/zhigan/component/example1.gif'
},
}

View File

@ -32,7 +32,7 @@
});
const options = [
{ label: '卫星例图', value: 'src/assets/images/chart/zhigan/component/example1.png' },
{ label: '无人机例图', value: 'src/assets/images/chart/zhigan/component/example2.png' },
{ label: '卫星例图', value: 'src/assets/images/chart/zhigan/component/example1.gif' },
{ label: '无人机例图', value: 'src/assets/images/chart/zhigan/component/example2.gif' },
];
</script>

View File

@ -26,6 +26,30 @@ export const option = {
videowidth: 181,
videoheight: 115,
videoMarginTop: 10,
borderWidth: 2,
borderColor: '#008000',
padding: 4,
titleColorStop1: '#1F6B55',
titleColorStop2: '#0A392A',
titleRightrColor: '#00611A',
iconColorStop1: '#73F095',
iconColorStop2: '#BBFDB5',
iconStrokeColor: '#00611A',
iconFillColor: '#0A251E',
iconBottomColor: '#0E4030',
},
dataStyleClone:{
borderColor: '#008000',
titleColorStop1: '#1F6B55',
titleColorStop2: '#0A392A',
titleRightrColor: '#00611A',
iconColorStop1: '#73F095',
iconColorStop2: '#BBFDB5',
iconStrokeColor: '#00611A',
iconFillColor: '#0A251E',
iconBottomColor: '#0E4030',
}
}

View File

@ -58,7 +58,162 @@
</SettingItem>
</SettingItemBox>
<SettingItemBox name="边框设置">
<SettingItem name="边框颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.borderColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.borderColor = optionData.dataStyleClone.borderColor"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="边框宽度">
<n-input-number
v-model:value="optionData.dataStyle.borderWidth"
size="small"
:min="0"
></n-input-number>
</SettingItem>
<SettingItem name="边框距离">
<n-input-number
v-model:value="optionData.dataStyle.padding"
size="small"
:min="0"
></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="标题设置">
<SettingItem name="标题底色(始)">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.titleColorStop1"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.titleColorStop1 = optionData.dataStyleClone.titleColorStop1"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题底色(终)">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.titleColorStop2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.titleColorStop2 = optionData.dataStyleClone.titleColorStop2"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题右边颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.titleRightrColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.titleRightrColor = optionData.dataStyleClone.titleRightrColor
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="无人机标记颜色(始)">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.iconColorStop1"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconColorStop1 = optionData.dataStyleClone.iconColorStop1"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="无人机标记颜色(终)">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.iconColorStop2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconColorStop2 = optionData.dataStyleClone.iconColorStop2"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="无人机边框颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.iconStrokeColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconStrokeColor = optionData.dataStyleClone.iconStrokeColor"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="无人机填充颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.iconFillColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconFillColor = optionData.dataStyleClone.iconFillColor"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标记下方矩形颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.dataStyle.iconBottomColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.iconBottomColor = optionData.dataStyleClone.iconBottomColor"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题字体颜色">
<n-color-picker
size="small"

View File

@ -4,7 +4,10 @@
<div v-for="item in option.dataset" :key="item.key">
<div class="item">
<video
style="border: 2px solid green; padding: 5px"
:style="{
border: `${option.dataStyle.borderWidth}px solid ${option.dataStyle.borderColor}`,
padding: `${option.dataStyle.padding}px`,
}"
preload="auto"
crossOrigin="anonymous"
playsinline

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -10,27 +10,57 @@ const { typeOptions, source } = dataJson;
export const option = {
type: typeOptions[0].value,
typeOptions: typeOptions,
typeStyle: {
dataset: source,
dataStyle: {
backgroud: '#FFFFFF00',
typeColor1: '#FFC600',
typeTitle1: '已处置',
typeColor2: '#08B47A',
typeTitle2: '总数',
typeFontColor: '#FFFFFF',
typeFontSize: 16,
},
dataset: source,
dataStyle: {
typeFontSize: 13,
listTitlePathStrokeColor: '#049D73',
listTitlePathFillColor: '#05A074',
listTitlePathStrokeColor2: '#049D72',
listTitleRectFillColor: '#05A074',
listTypePathStrokeColor: '#06A475',
listTypePathFillColor: '#FFFFFF00',
listTypeRactFillColor: '#06A475',
fontSize1: 13,
fontSize2: 10,
fontSize3: 13,
fontColor1: '#FFFFFF',
fontColor2: '#FFFFFF',
fontColor3: '#FFFFFF',
sortOrder: "0",
typeTop: 5,
listTop: 5,
listLeft: 15,
listTitleWidth: 106,
listTitleHeight: 30,
listProgressHeight: 15,
listTypeWidth: 66,
listTypeHeight: 30,
},
dataStyleClone:{
typeColor1: '#FFC600',
typeColor2: '#08B47A',
listTitlePathStrokeColor: '#049D73',
listTitlePathFillColor: '#05A074',
listTitlePathStrokeColor2: '#049D72',
listTitleRectFillColor: '#05A074',
listTypePathStrokeColor: '#06A475',
listTypePathFillColor: '#FFFFFF00',
listTypeRactFillColor: '#06A475',
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = XianSuoShangBaoConfig.key
public attr = { ...chartInitConfig, w: 400, h: 235, zIndex: -1 }
public attr = { ...chartInitConfig, w: 400, h: 225, zIndex: -1 }
public chartConfig = cloneDeep(XianSuoShangBaoConfig)
public option = cloneDeep(option)
}

View File

@ -1,46 +1,46 @@
<template>
<CollapseItem name="标记设置" :expanded="true">
<SettingItemBox name="标记样式">
<SettingItem name="宽度">
<n-input-number
v-model:value="optionData.typeStyle.width"
:min="0"
size="small"
placeholder="宽度"
></n-input-number>
</SettingItem>
<SettingItem name="高度">
<n-input-number
v-model:value="optionData.typeStyle.height"
:min="0"
size="small"
placeholder="高度"
></n-input-number>
</SettingItem>
<SettingItem name="标识颜色1">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.typeStyle.typeColor1"
v-model:value="optionData.dataStyle.typeColor1"
></n-color-picker>
</SettingItem>
<SettingItem name="标识标题1">
<n-input
v-model:value="optionData.typeStyle.typeTitle1"
<SettingItem>
<n-button
size="small"
placeholder="标识标题1"
></n-input>
@click="optionData.dataStyle.typeColor1 = optionData.dataStyleClone.typeColor1"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标识颜色2">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.typeStyle.typeColor2"
v-model:value="optionData.dataStyle.typeColor2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="optionData.dataStyle.typeColor2 = optionData.dataStyleClone.typeColor2"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标识标题1">
<n-input
v-model:value="optionData.dataStyle.typeTitle1"
size="small"
placeholder="标识标题1"
></n-input>
</SettingItem>
<SettingItem name="标识标题2">
<n-input
v-model:value="optionData.typeStyle.typeTitle2"
v-model:value="optionData.dataStyle.typeTitle2"
size="small"
placeholder="标识标题2"
></n-input>
@ -49,20 +49,35 @@
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.typeStyle.typeFontColor"
v-model:value="optionData.dataStyle.typeFontColor"
></n-color-picker>
</SettingItem>
<SettingItem name="标识字体大小">
<n-input-number
v-model:value="optionData.typeStyle.typeFontSize"
v-model:value="optionData.dataStyle.typeFontSize"
:min="0"
size="small"
placeholder="标识字体大小"
></n-input-number>
</SettingItem>
<SettingItem name="背景颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.backgroud"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-radio-group v-model:value="optionData.dataStyle.sortOrder" name="radiogroup">
<n-space>
<n-radio value="0"> {{ optionData.dataStyle.typeTitle2 }}排序 </n-radio>
<n-radio value="1"> {{ optionData.dataStyle.typeTitle1 }}排序 </n-radio>
<n-radio value="2"> 比例排序 </n-radio>
<n-text>排序方式</n-text>
</n-space>
</n-radio-group>
</SettingItem>
</SettingItemBox>
</CollapseItem>
<CollapseItem name="数据设置" :expanded="true">
<SettingItemBox name="数据样式">
<SettingItem name="字体颜色1">
<n-color-picker
@ -71,13 +86,6 @@
v-model:value="optionData.dataStyle.fontColor1"
></n-color-picker>
</SettingItem>
<SettingItem name="字体颜色2">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.fontColor2"
></n-color-picker>
</SettingItem>
<SettingItem name="字体大小1">
<n-input-number
v-model:value="optionData.dataStyle.fontSize1"
@ -86,6 +94,13 @@
placeholder="字体大小1"
></n-input-number>
</SettingItem>
<SettingItem name="字体颜色2">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.fontColor2"
></n-color-picker>
</SettingItem>
<SettingItem name="字体大小2">
<n-input-number
v-model:value="optionData.dataStyle.fontSize2"
@ -94,6 +109,13 @@
placeholder="字体大小2"
></n-input-number>
</SettingItem>
<SettingItem name="字体颜色3">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.fontColor3"
></n-color-picker>
</SettingItem>
<SettingItem name="字体大小3">
<n-input-number
v-model:value="optionData.dataStyle.fontSize3"
@ -103,6 +125,136 @@
></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="颜色样式">
<SettingItem name="标题矩形边框颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTitlePathStrokeColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTitlePathStrokeColor =
optionData.dataStyleClone.listTitlePathStrokeColor
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题矩形填充颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTitlePathFillColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTitlePathFillColor =
optionData.dataStyleClone.listTitlePathFillColor
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题左侧矩形颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTitlePathStrokeColor2"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTitlePathStrokeColor2 =
optionData.dataStyleClone.listTitlePathStrokeColor2
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="标题右侧矩形边框颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTitleRectFillColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTitleRectFillColor =
optionData.dataStyleClone.listTitleRectFillColor
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="比例矩形边框颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTypePathStrokeColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTypePathStrokeColor =
optionData.dataStyleClone.listTypePathStrokeColor
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="比例矩形填充颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTypePathFillColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTypePathFillColor =
optionData.dataStyleClone.listTypePathFillColor
"
>
恢复默认
</n-button>
</SettingItem>
<SettingItem name="比例矩形装饰点颜色">
<n-color-picker
size="small"
:modes="['rgb']"
v-model:value="optionData.dataStyle.listTypeRactFillColor"
></n-color-picker>
</SettingItem>
<SettingItem>
<n-button
size="small"
@click="
optionData.dataStyle.listTypeRactFillColor =
optionData.dataStyleClone.listTypeRactFillColor
"
>
恢复默认
</n-button>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>

View File

@ -11,47 +11,40 @@
],
"source": [
{
"key": "01",
"title":"临沂市",
"total": "10",
"handled": "6"
},
{
"key": "02",
"title":"临沂市",
"total": "20",
"handled": "6"
},
{
"key": "03",
"title":"临沂市",
"total": "4",
"handled": "3"
},
{
"key": "04",
"title":"临沂市",
"total": "5",
"handled": "1"
},
{
"key": "05",
"title":"临沂市",
"total": "5",
"handled": "2"
},
{
"key": "06",
"title":"临沂市",
"total": "6",
"handled": "1"
},
{
"key": "07",
"title":"临沂市",
"total": "7",
"handled": "3"
"handled": "7"
}
]
}

View File

@ -2,10 +2,10 @@
<div class="XianSuoShangBao">
<div class="type">
<div class="type-left">
<Progress :color="option.typeStyle.typeColor1" :numberOfDivs="1" />
<span>{{ option.typeStyle.typeTitle1 }}</span>
<Progress :color="option.typeStyle.typeColor2" :numberOfDivs="1" />
<span>{{ option.typeStyle.typeTitle2 }}</span>
<Progress :color="option.dataStyle.typeColor1" :numberOfDivs="1" />
<span>{{ option.dataStyle.typeTitle1 }}</span>
<Progress :color="option.dataStyle.typeColor2" :numberOfDivs="1" />
<span>{{ option.dataStyle.typeTitle2 }}</span>
</div>
<div class="type-right">
<n-select v-model:value="option.type" size="small" :options="option.typeOptions" />
@ -16,14 +16,19 @@
<ListTitle :item="item" :dataStyle="option.dataStyle" />
<div class="progressDiv">
<div class="list-jindu">
<Progress :color="option.typeStyle.typeColor1" :numberOfDivs="Number(item.handled)" />
<Progress
:color="option.typeStyle.typeColor2"
:color="option.dataStyle.typeColor1"
:numberOfDivs="Number(item.handled)"
:height="option.dataStyle.listProgressHeight"
/>
<Progress
:color="option.dataStyle.typeColor2"
:numberOfDivs="Number(item.total - item.handled)"
:height="Number(option.dataStyle.listProgressHeight)"
/>
</div>
</div>
<ListType style="margin-top: 3px" :item="item" :dataStyle="option.dataStyle" />
<ListType class="listType" :item="item" :dataStyle="option.dataStyle" />
</div>
</div>
</div>
@ -35,6 +40,7 @@
import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks';
import dayjs from 'dayjs';
import ListTitle from './svg/listTitle.vue';
import ListType from './svg/listType.vue';
import Progress from './svg/progress.vue';
@ -51,14 +57,60 @@
const option = reactive({
type: props.chartConfig.option.type,
typeOptions: props.chartConfig.option.typeOptions,
typeStyle: props.chartConfig.option.typeStyle,
dataset: props.chartConfig.option.dataset,
dataStyle: props.chartConfig.option.dataStyle,
});
watch(
() => option.dataStyle.sortOrder,
() => {
if (option.dataStyle.sortOrder == '0') {
//
option.dataset = option.dataset.sort((a, b) => parseInt(b.total) - parseInt(a.total));
} else if (option.dataStyle.sortOrder == '1') {
//
option.dataset = option.dataset.sort((a, b) => parseInt(b.handled) - parseInt(a.handled));
} else if (option.dataStyle.sortOrder == '2') {
//
option.dataset = option.dataset.sort(
(a, b) =>
parseInt(b.handled) / parseInt(b.total) - parseInt(a.handled) / parseInt(a.total),
);
}
option.dataset = option.dataset.map((item, index) => {
const order = String(index + 1);
const newKey = Number(order) >= 10 ? `${order}` : `0${order}`;
return {
...item,
key: newKey,
};
});
},
{
immediate: true,
deep: true,
},
);
watch(
() => w.value,
() => {
option.dataStyle.listTitleWidth = (w.value * 106.5) / 400;
option.dataStyle.listTitleHeight = (option.dataStyle.listTitleWidth * 20) / 71;
option.dataStyle.listTypeWidth = (w.value * 66) / 400;
option.dataStyle.listTypeHeight = (option.dataStyle.listTypeWidth * 30) / 66;
option.dataStyle.listProgressHeight = (w.value * 15) / 400;
},
{
immediate: true,
deep: true,
},
);
</script>
<style lang="scss" scoped>
.XianSuoShangBao {
background: v-bind('`${option.dataStyle.backgroud}`');
width: v-bind('`${w}px`');
height: v-bind('`${h}px`');
}
@ -67,9 +119,8 @@
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 5px;
margin-left: 30px;
margin-right: 10px;
margin-top: v-bind('`${option.dataStyle.typeTop}px`');
margin-left: v-bind('`${option.dataStyle.listLeft + 10}px`');
.type-left {
display: flex;
@ -82,8 +133,8 @@
}
span {
color: v-bind('`${option.typeStyle.typeFontColor}`');
font-size: v-bind('`${option.typeStyle.typeFontSize}px`');
color: v-bind('`${option.dataStyle.typeFontColor}`');
font-size: v-bind('`${option.dataStyle.typeFontSize}px`');
margin-left: 20px;
margin-right: 30px;
}
@ -92,9 +143,8 @@
.list {
width: v-bind('`${w}px`');
height: v-bind('`${h - 45}px`');
margin-top: 5px;
margin-left: 20px;
margin-right: 10px;
margin-top: v-bind('`${option.dataStyle.listTop}px`');
margin-left: v-bind('`${option.dataStyle.listLeft}px`');
overflow-y: auto;
display: flex;
flex-direction: column;
@ -102,21 +152,33 @@
.inline-container {
display: flex;
.listTitle {
}
.progressDiv {
margin-top: 3px;
// margin-top: 3px;
margin-left: 5px;
margin-right: 5px;
width: v-bind('`${w - 180}px`');
height: 23px;
background: #000000;
width: v-bind(
'`${w - option.dataStyle.listTypeWidth - option.dataStyle.listTitleWidth - option.dataStyle.listLeft * 2}px`'
);
height: v-bind('`${option.dataStyle.listTypeHeight}px`');
background: #ffffff00;
border: 1px solid#000000;
}
.list-jindu {
margin-left: 5px;
margin-right: 5px;
width: v-bind('`${w - 200}px`');
width: v-bind(
'`${w - option.dataStyle.listTypeWidth - option.dataStyle.listTitleWidth - option.dataStyle.listLeft * 2 - 10}px`'
);
display: flex;
}
.listType {
// margin-top: 3px;
}
}
}

View File

@ -1,64 +0,0 @@
<template>
<div>
<svg
width="60px"
height="30px"
viewBox="0 0 88 26"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient
x1="100%"
y1="50%"
x2="-21.8928848%"
y2="50%"
id="linearGradient-XianSuoShangBao-listMark-1"
>
<stop stop-color="#02221B" offset="0%"></stop>
<stop stop-color="#06463A" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="监测平台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="林业防火-智感-火情线索-切图版" transform="translate(-1782, -584)">
<g id="可视化" transform="translate(-8, -1)">
<g id="模块" transform="translate(53, 92)">
<g id="标题模块--右侧1" transform="translate(1449.5, 444)">
<g id="按钮" transform="translate(288, 49)">
<rect
id="矩形"
stroke="#06A475"
fill-opacity="0.4"
x="0.5"
y="0.5"
width="86"
height="25"
></rect>
<polygon
id="路径-11"
fill="#06A475"
points="0.5 0 0.5 7.33194884 8.38666648 0"
></polygon>
<polygon
id="路径-11"
fill="#06A475"
transform="translate(82.4433, 21.666) scale(-1, -1) translate(-82.4433, -21.666)"
points="78.5 18 78.5 25.3319488 86.3866665 18"
></polygon>
</g>
</g>
</g>
</g>
</g>
</g>
<text x="40%" y="13" text-anchor="middle" font-size="15" fill="#000000">
{{ props.item.handled }} / {{ props.item.total }}
</text>
</svg>
</div>
</template>
<script setup lang="ts">
const props = defineProps(['item']);
</script>

View File

@ -1,8 +1,8 @@
<template>
<div>
<svg
width="90px"
height="30px"
:width="props.dataStyle.listTitleWidth"
:height="props.dataStyle.listTitleHeight"
viewBox="0 0 71 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
@ -17,28 +17,35 @@
<path
d="M38.0468141,0.5 L24.9195699,19.5 L5.5,19.5 L5.5,0.5 L38.0468141,0.5 Z"
id="矩形"
stroke="#049D73"
fill="#05A074"
:stroke="props.dataStyle.listTitlePathStrokeColor"
:fill="props.dataStyle.listTitlePathFillColor"
></path>
<path
d="M70.0581002,0.5 L57.2050021,19.5 L23.5,19.5 L23.5,0.5 L70.0581002,0.5 Z"
id="矩形"
stroke="#049D72"
:stroke="props.dataStyle.listTitlePathStrokeColor2"
fill-opacity="0.46"
opacity="0.79897926"
transform="translate(47, 10) scale(-1, -1) translate(-47, -10)"
></path>
<rect id="矩形" fill="#05A074" x="0" y="0" width="2" height="30"></rect>
<rect
id="矩形"
:fill="props.dataStyle.listTitleRectFillColor"
x="0"
y="0"
width="2"
height="30"
></rect>
</g>
</g>
</g>
</g>
</g>
</g>
<text x="12" y="13" :font-size="dataStyle.fontSize1" :fill="dataStyle.fontColor1">
<text x="10" y="15" :font-size="props.dataStyle.fontSize1" :fill="props.dataStyle.fontColor1">
{{ props.item.key }}
</text>
<text x="36" y="13" :font-size="dataStyle.fontSize2" :fill="dataStyle.fontColor1">
<text x="36" y="13" :font-size="props.dataStyle.fontSize2" :fill="props.dataStyle.fontColor2">
{{ props.item.title }}
</text>
</svg>

View File

@ -1,58 +1,52 @@
<template>
<div>
<svg
width="50px"
height="30px"
viewBox="0 0 50 30"
:width="props.dataStyle.listTypeWidth"
:height="props.dataStyle.listTypeHeight"
viewBox="0 0 44 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient
x1="100%"
y1="50%"
x2="-21.8928848%"
y2="50%"
id="linearGradient-XianSuoShangBao-listType-1"
>
<stop stop-color="#02221B" offset="0%"></stop>
<stop stop-color="#06463A" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="监测平台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="林业防火-智感-火情线索-切图版" transform="translate(-1782, -584)">
<g id="林业防火-智感-火情线索-切图版" transform="translate(-1829, -621)">
<g id="可视化" transform="translate(-8, -1)">
<g id="模块" transform="translate(53, 92)">
<g id="标题模块--右侧1" transform="translate(1449.5, 444)">
<g id="按钮" transform="translate(288, 49)">
<rect
id="矩形"
stroke="#06A475"
fill-opacity="0.4"
x="1"
y="1"
width="40"
height="20"
></rect>
<polygon
id="路径-11"
fill="#06A475"
points="0.5 0 0.5 7.33194884 8.38666648 0"
></polygon>
<polygon
id="路径-11"
fill="#06A475"
transform="translate(82.4433, 21.666) scale(-1, -1) translate(-82.4433, -21.666)"
points="78.5 18 78.5 25.3319488 86.3866665 18"
></polygon>
<g id="list" transform="translate(17.5, 86)">
<g id="编组-56" transform="translate(317, 0)">
<path
d="M43.5,0.5 L43.5,19.5 L0.5,19.5 L0.5,0.5 L43.5,0.5 Z"
id="矩形"
:stroke="props.dataStyle.listTypePathStrokeColor"
fill-opacity="0.4"
:fill="props.dataStyle.listTypePathFillColor"
transform="translate(22, 10) scale(-1, 1) translate(-22, -10)"
></path>
<rect
id="矩形"
:fill="props.dataStyle.listTypeRactFillColor"
x="0"
y="0"
width="4"
height="4"
></rect>
<rect
id="矩形备份-17"
:fill="props.dataStyle.listTypeRactFillColor"
x="40"
y="16"
width="4"
height="4"
></rect>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
<text x="5" y="15" :font-size="dataStyle.fontSize3" :fill="dataStyle.fontColor2">
<text x="6" y="15" :font-size="props.dataStyle.fontSize3" :fill="props.dataStyle.fontColor3">
{{ props.item.handled }} / {{ props.item.total }}
</text>
</svg>

View File

@ -1,84 +0,0 @@
<template>
<div class="container">
<svg
width="120px"
height="40px"
viewBox="0 0 88 26"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient
x1="100%"
y1="50%"
x2="-21.8928848%"
y2="50%"
id="linearGradient-XianSuoShangBao-mark-1"
>
<stop stop-color="#02221B" offset="0%"></stop>
<stop stop-color="#06463A" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="监测平台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="林业防火-智感-火情线索-切图版" transform="translate(-1782, -584)">
<g id="可视化" transform="translate(-8, -1)">
<g id="模块" transform="translate(53, 92)">
<g id="标题模块--右侧1" transform="translate(1449.5, 444)">
<g id="按钮" transform="translate(288, 49)">
<rect
id="矩形"
stroke="#06A475"
fill-opacity="0.4"
x="0.5"
y="0.5"
width="86"
height="25"
></rect>
<polygon
id="路径-11"
fill="#06A475"
points="0.5 0 0.5 7.33194884 8.38666648 0"
></polygon>
<polygon
id="路径-11"
fill="#06A475"
transform="translate(82.4433, 21.666) scale(-1, -1) translate(-82.4433, -21.666)"
points="78.5 18 78.5 25.3319488 86.3866665 18"
></polygon>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
<n-select
class="overlay-select"
v-model:value="props.type"
size="small"
:options="props.typeOptions"
/>
</div>
</template>
<script setup lang="ts">
const props = defineProps(['typeOptions', 'type']);
</script>
<style lang="scss" scoped>
.container {
position: absolute;
left: 245px;
display: inline-block;
.overlay-select {
position: absolute;
width: 115px;
top: 45%;
left: 15%;
transform: translate(-50%, -50%);
z-index: 10;
}
}
</style>

View File

@ -3,13 +3,17 @@
</template>
<script setup lang="ts">
const props = defineProps(['color', 'numberOfDivs']);
const props = defineProps({
color: { type: String },
numberOfDivs: { type: Number },
height: { type: Number, default: 15 },
});
</script>
<style lang="scss" scoped>
.parallelogram {
width: 21px;
height: 10px;
width: 20px;
height: v-bind('`${props.height}px`');
margin-top: 6px;
margin-right: 1px;
background-color: v-bind('`${props.color}`');

View File

@ -1,198 +0,0 @@
<template>
<div>
<svg
width="400px"
height="40px"
viewBox="0 0 401 40"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient
x1="97.3499803%"
y1="112.35863%"
x2="0%"
y2="112.35863%"
id="linearGradient-XianSuoShangBao-1"
>
<stop stop-color="#08251E" stop-opacity="0.1742622" offset="0%"></stop>
<stop stop-color="#00A374" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="0%" y1="50%" x2="100%" y2="50%" id="linearGradient-XianSuoShangBao-2">
<stop stop-color="#11B472" offset="0%"></stop>
<stop stop-color="#00A374" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<polygon
id="path-3"
points="10.9822114 0 112.704666 0 119.46341 11.2799213 173.1989 11.2799213 270.2884 11.2799213 270.2884 38.3517324 139.186577 38.3517324 0 38.3517324 0 11.1814815"
></polygon>
<radialGradient
cx="50%"
cy="0%"
fx="50%"
fy="0%"
r="100%"
gradientTransform="translate(0.5, 0), scale(0.243, 1), rotate(90), scale(1, 2.7755), translate(-0.5, -0)"
id="radialGradient-5"
>
<stop stop-color="#00FF8C" offset="0%"></stop>
<stop stop-color="#00F4B6" stop-opacity="0" offset="100%"></stop>
</radialGradient>
<filter
x="-3.0%"
y="-12.5%"
width="106.1%"
height="124.9%"
filterUnits="objectBoundingBox"
id="filter-6"
>
<feGaussianBlur stdDeviation="4.31844888" in="SourceGraphic"></feGaussianBlur>
</filter>
<linearGradient
x1="27.2222213%"
y1="49.528366%"
x2="102.926609%"
y2="50.2892453%"
id="linearGradient-XianSuoShangBao-7"
>
<stop stop-color="#00FF77" offset="0%"></stop>
<stop stop-color="#00BF6B" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="linearGradient-XianSuoShangBao-8">
<stop stop-color="#00673F" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#00683F" offset="100%"></stop>
</linearGradient>
<linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="linearGradient-XianSuoShangBao-9">
<stop stop-color="#72A18A" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#1CC370" offset="100%"></stop>
</linearGradient>
</defs>
<g id="监测平台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="林业防火-智感-火情线索-切图版" transform="translate(-1495, -535)">
<g id="可视化" transform="translate(-8, -1)">
<g id="模块" transform="translate(53, 92)">
<g id="标题模块--右侧1" transform="translate(1449.5, 444)">
<g id="底部背景" transform="translate(0, -0)">
<g id="小标题" transform="translate(0.5, 0)">
<g transform="translate(1, 1)">
<polygon
id="矩形"
fill="url(#linearGradient-XianSuoShangBao-1)"
points="10.3064025 0 166.362718 0 176.570151 13.6763066 255.888803 13.6763066 399.202062 13.6763066 399.201597 38.3517324 205.452516 38.3517324 0 38.3517324 0 11.1814815"
></polygon>
<g id="椭圆形">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<use
id="蒙版"
fill="url(#linearGradient-XianSuoShangBao-2)"
xlink:href="#path-3"
></use>
<ellipse
fill="url(#radialGradient-5)"
filter="url(#filter-6)"
mask="url(#mask-4)"
cx="180.697047"
cy="25.5190419"
rx="214"
ry="52"
></ellipse>
</g>
<polyline
id="路径"
stroke="url(#linearGradient-XianSuoShangBao-7)"
stroke-width="0.616921269"
points="0 25.7188334 0 11.1814815 11.0190925 0 177.866737 0 188.53316 13.2759293 264.809581 13.2759293"
></polyline>
<polygon
id="矩形"
fill="url(#linearGradient-XianSuoShangBao-8)"
points="118.561275 2.99401198 393.561275 2.99401198 393.561275 9.76196476 122.229351 9.76196476"
></polygon>
<polygon
id="路径-11"
fill="#EBBE10"
points="0 0 0 7.33194884 7.88666648 0"
></polygon>
<g
id="编组-2"
opacity="0.691816057"
transform="translate(370.7821, 6.5393) scale(-1, -1) translate(-370.7821, -6.5393)translate(345.3094, 3.992)"
fill="#00C157"
>
<polygon
id="矩形"
opacity="0.558652605"
points="46.5583547 0 50.945502 0 46.48422 5.0945502 42.0970727 5.0945502"
></polygon>
<polygon
id="矩形备份"
opacity="0.385865711"
points="38.2461939 0 42.6333411 0 38.1720591 5.0945502 33.7849118 5.0945502"
></polygon>
<polygon
id="矩形备份-2"
opacity="0.321045648"
points="29.6658988 0 34.0530461 0 29.5917641 5.0945502 25.2046168 5.0945502"
></polygon>
<polygon
id="矩形备份-3"
opacity="0.191528"
points="21.3537379 0 25.7408852 0 21.2796032 5.0945502 16.8924559 5.0945502"
></polygon>
<polygon
id="矩形备份-4"
opacity="0.123233"
points="12.5053086 0 16.8924559 0 12.4311739 5.0945502 8.04402663 5.0945502"
></polygon>
<polygon
id="矩形备份-5"
opacity="0.097781"
points="4.46128201 0 8.84842929 0 4.38714728 5.0945502 0 5.0945502"
></polygon>
</g>
</g>
<g id="装饰线" transform="translate(8.3051, 37.5255)">
<polygon
id="矩形"
fill="#EBBE10"
points="1.58053304 0 11.6250344 0 10.0445013 1.82627297 0 1.82627297"
></polygon>
<polygon
id="矩形备份-13"
fill="#4FE985"
points="14.4276265 0 24.4721279 0 22.8284122 1.82627297 12.7839108 1.82627297"
></polygon>
<polygon
id="矩形备份-14"
fill="url(#linearGradient-XianSuoShangBao-9)"
points="27.2666802 0 390.822416 0 390.822416 1.82627297 25.5678216 1.82627297"
></polygon>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
<text x="20%" y="30" text-anchor="middle" font-size="20" fill="#FFFFFF">
{{ props.title }}
</text>
<a xlink:href="https://www.example.com">
<text x="360" y="30" text-anchor="middle" font-size="20" fill="#FFFFFF">更多>></text>
</a>
</svg>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
required: true,
},
});
</script>

View File

@ -200,7 +200,6 @@ export enum PackagesCategoryEnum {
ICONS = 'Icons',
DECORATES = 'Decorates',
CUSTOM = 'Custom',
DIY = 'Diy',
UNITS = 'Units',
ZHIGAN = 'Zhigan',
MAPICONS = 'MapIcons'
@ -216,7 +215,6 @@ export enum PackagesCategoryName {
ICONS = '图标',
DECORATES = '小组件',
CUSTOM = '预警信息',
DIY = 'DIY',
UNITS = '组件',
ZHIGAN = '智感',
MAPICONS = '地图图标'
@ -238,7 +236,6 @@ export type PackagesType = {
[PackagesCategoryEnum.ICONS]: ConfigType[];
[PackagesCategoryEnum.DECORATES]: ConfigType[];
[PackagesCategoryEnum.CUSTOM]: ConfigType[];
[PackagesCategoryEnum.DIY]: ConfigType[];
[PackagesCategoryEnum.UNITS]: ConfigType[];
[PackagesCategoryEnum.ZHIGAN]: ConfigType[];
[PackagesCategoryEnum.MAPICONS]: ConfigType[];

View File

@ -43,7 +43,6 @@ export let packagesList: PackagesType = {
[PackagesCategoryEnum.DECORATES]: DecorateList,
[PackagesCategoryEnum.PHOTOS]: PhotoList,
[PackagesCategoryEnum.ICONS]: IconList,
[PackagesCategoryEnum.DIY]: DiyList,
[PackagesCategoryEnum.UNITS]: UnitsList,
[PackagesCategoryEnum.ZHIGAN]: ZhiganList,
[PackagesCategoryEnum.MAPICONS]: MapIconsList,

View File

@ -7,9 +7,8 @@ import { mainOutRoutes } from './mainOut';
import { PageEnum } from '@/enums/pageEnum';
import { t } from '@/hooks/web/useI18n';
import { projectRoutes, chartRoutes, previewRoutes, editRoutes } from '@/router/disposition/index';
import { router } from '@/router';
import { usePermissionStore } from '@/store/modules/permission';
import { getMainPage } from '@/api/path/project.api';
import { previewPath } from '@/utils';
// import.meta.glob() 直接引入所有的模块 Vite 独有的功能
const modules = import.meta.glob('./modules/**/*.ts', { eager: true });
@ -37,34 +36,23 @@ export const asyncRoutes = [
export const RootRoute: AppRouteRecordRaw = {
path: '/',
name: 'Root',
redirect: PageEnum.BASE_HOME,
// redirect: PageEnum.BASE_HOME,
meta: {
title: 'Root',
},
// beforeEnter: async (to, from, next) => {
// const mainPage = await getMainPage();
// console.log('to', to);
// console.log('from', from);
// if (to.fullPath == '/') {
// console.log('进入重定向');
// if (mainPage) {
// console.log('设置了主页');
// console.log('mainPage', mainPage);
// // window.open(
// // 'http://192.168.10.120:5173/#/chart/preview/f0adeb4b-8f11-4cbb-84e3-7e03de472a7b',
// // '_self',
// // );
// window.location.replace(
// 'http://192.168.10.120:5173/#/chart/preview/f0adeb4b-8f11-4cbb-84e3-7e03de472a7b',
// );
// // window.location.href = mainPage;
// } else {
// next();
// }
// } else {
// next();
// }
// },
beforeEnter: async (to, from, next) => {
const mainPage = await getMainPage();
const path = previewPath(mainPage);
if (to.fullPath == '/') {
if (mainPage) {
next(path.split('#')[1]);
} else {
next();
}
} else {
next();
}
},
};
export const LoginRoute: AppRouteRecordRaw = {

View File

@ -30,6 +30,7 @@ import {
EditCanvasConfigType,
} from './chartEditStore.d';
import useClipboard from 'vue-clipboard3';
import { customComponentSave } from '@/api/path/project.api';
const { toClipboard } = useClipboard();
@ -1040,5 +1041,35 @@ export const useChartEditStore = defineStore({
this.getEditCanvas.scale = scale;
}
},
// 保存至分组
saveToGroup() {
if (this.getTargetChart.selectId.length > 1) {
window['$message'].warning('多个组件,请先创建分组后保存');
return;
}
let obj = {};
this.getComponentList.forEach((item) => {
if (item.id == this.getTargetChart.selectId[0]) {
obj = {
title: item.chartConfig.title,
image: 'upload.png',
key: 'GroupItem',
json: {
charts: item,
type: 'copy',
},
};
}
});
customComponentSave({
content: JSON.stringify(obj),
}).then((res) => {
if (res) {
window['$message'].success('保存成功');
} else {
window['$message'].error('保存失败');
}
});
},
},
});

View File

@ -1,5 +1,5 @@
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
import { EditCanvasType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d';
import { EditCanvasType } from '@/store/modules/chartEditStore/chartEditStore.d';
// 操作类型枚举
@ -37,19 +37,19 @@ export enum HistoryActionTypeEnum {
// 隐藏
HIDE = 'hide',
// 显示
SHOW = 'show'
SHOW = 'show',
}
// 对象类型
export enum HistoryTargetTypeEnum {
CANVAS = 'canvas',
CHART = 'chart'
CHART = 'chart',
}
// 历史栈
export enum HistoryStackEnum {
BACK_STACK = 'backStack',
FORWARD_STACK = 'forwardStack'
FORWARD_STACK = 'forwardStack',
}
// 历史记录项
@ -57,22 +57,25 @@ export enum HistoryStackItemEnum {
ID = 'id',
TARGET_TYPE = 'targetType',
ACTION_TYPE = 'actionType',
HISTORY_DATA = 'historyData'
HISTORY_DATA = 'historyData',
}
// 历史记录项类型
export interface HistoryItemType {
// 会有同时操作多个组件场景
[HistoryStackItemEnum.ID]: string
[HistoryStackItemEnum.TARGET_TYPE]: HistoryTargetTypeEnum
[HistoryStackItemEnum.ACTION_TYPE]: HistoryActionTypeEnum
[HistoryStackItemEnum.HISTORY_DATA]: CreateComponentType[] | CreateComponentGroupType[] | EditCanvasType[]
[HistoryStackItemEnum.ID]: string;
[HistoryStackItemEnum.TARGET_TYPE]: HistoryTargetTypeEnum;
[HistoryStackItemEnum.ACTION_TYPE]: HistoryActionTypeEnum;
[HistoryStackItemEnum.HISTORY_DATA]:
| CreateComponentType[]
| CreateComponentGroupType[]
| EditCanvasType[];
}
// 历史 Store 类型
export interface ChartHistoryStoreType {
// 后退栈
[HistoryStackEnum.BACK_STACK]: Array<HistoryItemType>
[HistoryStackEnum.BACK_STACK]: Array<HistoryItemType>;
// 前进栈
[HistoryStackEnum.FORWARD_STACK]: Array<HistoryItemType>
[HistoryStackEnum.FORWARD_STACK]: Array<HistoryItemType>;
}

View File

@ -28,6 +28,7 @@ import { router } from '@/router';
import { LAYOUT } from '@/router/constant';
import dayjs from 'dayjs';
import { getMainPage } from '@/api/path/project.api';
import { previewPath } from '@/utils';
interface PermissionState {
// Permission code list
@ -371,7 +372,6 @@ export const usePermissionStore = defineStore({
* @description pathroutesaffix
* */
const patchHomeAffix = async (routes: AppRouteRecordRaw[]) => {
console.log('patchHomeAffix')
if (!routes || routes.length === 0) return;
let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME;
@ -394,9 +394,9 @@ export const usePermissionStore = defineStore({
try {
const homePage = await getMainPage();
console.log(homePage);
const path = previewPath(homePage);
if (hoemPage) {
window.open(hoemPage, '_self');
window.open(path, '_self');
} else {
patcher(routes);
}

View File

@ -26,6 +26,7 @@ import { h } from 'vue';
import md5 from 'js-md5';
import { useMultipleTabStore } from '@/store/modules/multipleTab';
import { getMainPage } from '@/api/path/project.api';
import { previewPath } from '@/utils';
interface UserState {
userInfo: Nullable<UserInfo>;
@ -166,9 +167,11 @@ export const useUserStore = defineStore({
permissionStore.setDynamicAddedRoute(true);
}
const homePage = await getMainPage();
const path = previewPath(homePage);
// 配置主页面后,进入主页面
if (homePage) {
window.open(homePage, '_self');
router.replace(path.split('#')[1]);
} else {
goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME));
// goHome && (await router.replace(userInfo?.homePath || PageEnum.SUBJECT_HOME));

View File

@ -200,3 +200,9 @@ export const previewPath = (id?: string | number) => {
const previewPath = `${origin}${pathname}${path}/${id || fetchRouteParamsLocation()}`;
return previewPath;
};
// 跳转地址
export const previewUrl = (id?: string | number) => {
const path = fetchPathByName(PreviewEnum.CHART_PREVIEW_NAME, 'href');
const previewPath = `${path.split('#')[1]}/${id || fetchRouteParamsLocation()}`;
return previewPath;
};

View File

@ -24,6 +24,9 @@
></mac-os-control-btn>
<n-text class="list-header-text" depth="3">
<n-ellipsis>{{ item.title }}</n-ellipsis>
<span class="span-icon" @click="deleteComponent(item, index)">
<TrashIcon v-if="item.key == 'GroupItem'" />
</span>
</n-text>
</div>
<div class="list-center go-flex-center go-transition" draggable="true">
@ -80,16 +83,25 @@
loadingError,
JSONStringify,
goDialog,
getUUID,
} from '@/utils';
import { DragKeyEnum } from '@/enums/editPageEnum';
import { createComponent } from '@/packages';
import { ConfigType, CreateComponentType, PackagesCategoryEnum } from '@/packages/index.d';
import {
ConfigType,
CreateComponentType,
PackagesCategoryEnum,
CreateComponentGroupType,
} from '@/packages/index.d';
import { ChatCategoryEnum } from '@/packages/components/Photos/index.d';
import { fetchConfigComponent, fetchChartComponent } from '@/packages/index';
import { GoIconify } from '@/components/GoIconify';
import { icon } from '@/plugins';
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d';
import omit from 'lodash/omit';
import cloneDeep from 'lodash/cloneDeep';
import { customComponentSaveDelete } from '@/api/path/project.api';
const chartEditStore = useChartEditStore();
const { TrashIcon } = icon.ionicons5;
@ -140,27 +152,88 @@
const dblclickHandle = async (item: ConfigType) => {
console.log('双击添加', item);
if (item.disabled) return;
try {
loadingStart();
//
componentInstall(item.chartKey, fetchChartComponent(item));
componentInstall(item.conKey, fetchConfigComponent(item));
//
let newComponent: CreateComponentType = await createComponent(item);
if (item.redirectComponent) {
item.dataset && (newComponent.option.dataset = item.dataset);
newComponent.chartConfig.title = item.title;
newComponent.chartConfig.chartFrame = item.chartFrame;
// 使
if (item.key == 'GroupItem') {
console.log('分组');
try {
loadingStart();
const recordCharts = item.json;
if (recordCharts === undefined) {
loadingFinish();
return;
}
const parseHandle = (e: CreateComponentType | CreateComponentGroupType) => {
e = cloneDeep(e);
e.attr.x = chartEditStore.getMousePosition.startX;
e.attr.y = chartEditStore.getMousePosition.startY;
// id
e.id = getUUID();
// id
if (e.isGroup) {
(e as CreateComponentGroupType).groupList.forEach(async (item: CreateComponentType) => {
item.id = getUUID();
});
}
return e;
};
const createComponentInstall = (e) => {
if (e.isGroup) {
//
e.groupList.forEach(async (item) => {
// //
componentInstall(item.chartConfig.chartKey, fetchChartComponent(item.chartConfig));
componentInstall(item.chartConfig.conKey, fetchConfigComponent(item.chartConfig));
});
} else {
componentInstall(e.chartConfig.chartKey, fetchChartComponent(e.chartConfig));
componentInstall(e.chartConfig.conKey, fetchConfigComponent(e.chartConfig));
}
};
const isCut = recordCharts.type === HistoryActionTypeEnum.CUT;
const targetList = Array.isArray(recordCharts.charts)
? recordCharts.charts
: [recordCharts.charts];
//
targetList.forEach((e: CreateComponentType | CreateComponentGroupType) => {
createComponentInstall(e);
chartEditStore.addComponentList(parseHandle(e), undefined, true);
//
if (isCut) {
chartEditStore.setTargetSelectChart(e.id);
chartEditStore.removeComponentList(undefined, true);
}
});
if (isCut) chartEditStore.setRecordChart(undefined);
loadingFinish();
} catch (value) {
window['$message'].warning(`图表正在研发中, 敬请期待...`);
loadingError();
}
} else {
try {
loadingStart();
//
componentInstall(item.chartKey, fetchChartComponent(item));
componentInstall(item.conKey, fetchConfigComponent(item));
//
let newComponent: CreateComponentType = await createComponent(item);
if (item.redirectComponent) {
item.dataset && (newComponent.option.dataset = item.dataset);
newComponent.chartConfig.title = item.title;
newComponent.chartConfig.chartFrame = item.chartFrame;
}
//
chartEditStore.addComponentList(newComponent, false, true);
//
chartEditStore.setTargetSelectChart(newComponent.id);
loadingFinish();
} catch (error) {
loadingError();
console.log('chartItemBox-index');
window['$message'].warning(`图表正在研发中, 敬请期待...`);
}
//
chartEditStore.addComponentList(newComponent, false, true);
//
chartEditStore.setTargetSelectChart(newComponent.id);
loadingFinish();
} catch (error) {
loadingError();
console.log('chartItemBox-index');
window['$message'].warning(`图表正在研发中, 敬请期待...`);
}
};
@ -191,6 +264,18 @@
}
},
);
const deleteComponent = (item: ConfigType, index: number) => {
props.menuOptions.splice(index, 1);
customComponentSaveDelete({
ids: item.id,
}).then((res) => {
if (res) {
window['$message'].success(`删除成功`);
} else {
window['$message'].success(`删除失败`);
}
});
};
</script>
<style lang="scss" scoped>
@ -338,4 +423,11 @@
animation: miniAnimation 0.5s;
}
}
.span-icon {
font-size: 16px;
display: inline-block;
width: 20px;
height: 20px;
margin-left: 5px;
}
</style>

View File

@ -1,19 +1,115 @@
<template>
<div class="modal-content">
<div class="modal-title">
图片管理
<div class="close-button" @click="closeModal">
<Icon icon="material-symbols:cancel-outline-rounded" :size="30"/>
<div class="title-span">图片管理</div>
<div class="close-button-div">
<div class="close-button" @click="closeModal"></div>
</div>
</div>
<div class="content-div">
<div class="photo-item" v-for="(item, index) in photoList" :key="index" @click="changeSelect(selectPhotoList.some(obj => obj.id === item.id)? 1: 2,item)">
<Image
:src="`${apiUrl}/${item.filePath}`"
/>
<div class="select-div">
<Icon v-if="selectPhotoList.some(obj => obj.id === item.id)" icon="material-symbols-light:check-circle" :size="25" style="color: #18a058;"/>
<Icon v-else icon="material-symbols-light:check-circle-outline" :size="25" style="color: #cacdcd;"/>
<div class="menu-div">
<div class="menu-title">
<div class="menu-title-icon"></div>
<div class="menu-title-span">图片资源</div>
<div style="font-size: 20px;cursor: pointer;" @click="openAddMenu"><PlusSquareOutlined /></div>
</div>
<div class="menu-list">
<div :class="`menu-item ${selectPhotoGroup == item? 'select-menu': ''}`" v-for="(item, index) in photoGroupList" :key="index" @click="changeMenu">
<div class="menu-item-icon"></div>
<div class="menu-item-span">{{ item }}</div>
</div>
<!-- <div v-if="!addMenuOpen" class="add-menu-div" @click="openAddMenu"><PlusSquareOutlined /></div> -->
<div v-if="addMenuOpen" class="add-menu-div" style="padding: 0px 10px;">
<a-input v-model:value="addMenuName" style="margin-right: 7px;" />
<a-button type="primary" style="background-color: #52c41a;margin-right: 5px;" shape="circle" :icon="h(CheckOutlined)" @click="submitMenu"></a-button>
<a-button type="primary" style="background-color: #ff7875;" shape="circle" :icon="h(CloseOutlined)" @click="closeAddMenu"></a-button>
</div>
</div>
</div>
<div class="show-list-div">
<div class="show-control">
<div class="control-left">
<a-radio-group class="show-type" v-model:value="showType">
<a-radio-button class="custom-radio-btn" value="item">
<AppstoreOutlined style="font-size: 20px;"/>
</a-radio-button>
<a-radio-button class="custom-radio-btn" value="list">
<BarsOutlined style="font-size: 20px;"/>
</a-radio-button>
</a-radio-group>
<a-select
class="select-sort"
v-model:value="sort"
style="width: 166px;"
:options="selectSortOptions"/>
</div>
<div class="control-right">
<a-input-search
class="search-input"
v-model:value="search"
placeholder="查询图片名称"
>
<template #enterButton>
<a-button
type="primary"
:icon="h(SearchOutlined)"
style="height: 36px;"
@click="searchPhoto"
>搜索</a-button>
</template>
</a-input-search>
</div>
</div>
<div class="show-list" v-if="showType == `item`">
<div class="show-item" v-for="(item,index) in paginatedData" :key="index">
<div class="item-image-div">
<a-image
class="item-image"
:src="`${apiUrl}/${item.filePath}`"
/>
<div class="image-size">{{ `` }}</div>
<a-checkbox class="select-image"
:checked="selectPhotoList.some(obj => obj.id === item.id)"
@change="changeSelect(selectPhotoList.some(obj => obj.id === item.id)? 1: 2,item)">
</a-checkbox>
</div>
<div class="item-span">{{ item.fileName }}</div>
</div>
</div>
<div class="show-list" v-else style="margin-right: 74px;border: 1px solid #D9D9D9;border-radius: 4px;">
<div class="list-title">
<div style="margin-left: 69px;margin-right: 339px;">素材名称</div>
<div style="margin-right: 103px;">尺寸</div>
<div style="margin-right: 161px;">大小</div>
<div>更新时间</div>
</div>
<div class="list-content">
<div class="list-item" v-for="(item, index) in paginatedData" :key="index">
<a-checkbox class="list-select-image"
:checked="selectPhotoList.some(obj => obj.id === item.id)"
@change="changeSelect(selectPhotoList.some(obj => obj.id === item.id)? 1: 2,item)"/>
<a-image
class="list-item-image"
:src="`${apiUrl}/${item.filePath}`"
/>
<div class="list-item-span">{{ item.fileName }}</div>
<div class="list-item-size"></div>
<div class="list-item-size">{{ `${(item.fileSize / 1024).toFixed(1)}kb`}}</div>
<div class="list-item-time">{{item.createTime}}</div>
</div>
</div>
</div>
<div class="pagination-div">
<a-pagination
v-model:current="current"
v-model:page-size="pageSize"
show-quick-jumper
show-size-changer
:total="photoList.length"
:show-total="total => `共 ${total} 条`"
@showSizeChange="handlePageSizeChange"
/>
</div>
</div>
</div>
@ -33,12 +129,12 @@
</template>
<script setup lang="ts">
import { ref, onMounted, h } from "vue"
import { imageList, imageUpload, imageDelete } from '@/api/demo/photo'
import { ref, onMounted, h, computed } from "vue"
import { imageList, imageUpload, imageDelete, getImageGroupList } from '@/api/demo/photo'
import { useGlobSetting } from '@/hooks/setting';
import { Image, Button, Upload, Modal } from 'ant-design-vue';
import Icon from '@/components/Icon/Icon.vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import { UploadOutlined,AppstoreOutlined, BarsOutlined, SearchOutlined, PlusSquareOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue';
import { photoModalStore } from '@/store/modules/photoModal'
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore'
import { StorageEnum } from '@/enums/storageEnum'
@ -46,24 +142,60 @@ import { ImageConfig } from '@/packages/components/Informations/Mores/Image/inde
import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Photos/index.d'
import { ChartFrameEnum, ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { selectSortOptions } from './util'
const photoModalStateStore = photoModalStore()
const packagesStore = usePackagesStore()
const { apiUrl } = useGlobSetting();
onMounted(() => {
getList()
// getList()
getPhotoGroup()
})
const StoreKey = StorageEnum.GO_USER_MEDIA_PHOTOS
const photoList = ref([])
const selectPhotoList = ref([])
const photoGroupList = ref([])
const selectPhotoGroup = ref()
const showType = ref('item')
const sort = ref()
const search = ref()
const checked = ref()
const current = ref(1)
const pageSize = ref(10)
const addMenuName = ref('')
const addMenuOpen = ref(false)
const paginatedData = computed(() => {
const start = (current.value - 1) * pageSize.value;
const end = start + pageSize.value;
return photoList.value.slice(start, end);
});
const getList = () => {
imageList().then(res => {
let params = {
GroupName: selectPhotoGroup.value,
page: current.value,
limit: pageSize.value,
}
if(search.value){
params['key'] = search.value
}
imageList(params).then(res => {
photoList.value = res
})
}
const getPhotoGroup = () => {
getImageGroupList().then(res => {
console.log('res',res)
photoGroupList.value = res
if(res.length > 0){
selectPhotoGroup.value = res[0]
getList()
}
})
}
const closeModal = () => {
photoModalStateStore.changeOpenState(false)
}
@ -80,7 +212,7 @@ const changeSelect = (type,item) => {
const customRequest = (file) => {
const formData = new FormData()
formData.append('files', file.file)
imageUpload(formData).then(res => {
imageUpload(formData,selectPhotoGroup.value).then(res => {
console.log(res)
getList()
})
@ -134,63 +266,355 @@ const addPhotoToList = () =>{
selectPhotoList.value = []
closeModal()
}
const handlePageSizeChange = (page, size) => {
pageSize.value = size;
current.value = 1;
};
const searchPhoto = () => {
current.value = 1
getList()
}
const openAddMenu = () => {
addMenuName.value = ''
addMenuOpen.value = true
}
const closeAddMenu = () => {
addMenuOpen.value = false
addMenuName.value = ''
}
const submitMenu = () => {
if(addMenuName.value.trim()){
photoGroupList.value.push(addMenuName.value.trim())
addMenuOpen.value = false
addMenuName.value = ''
}else{
window.$message.warning('分组名称不能为空')
}
}
const changeMenu = (item) => {
selectPhotoGroup.value = item.target.textContent
current.value = 1
getList()
}
</script>
<style lang="scss" scoped>
.modal-content{
width: 1152px;
height: 700px;
height: 790px;
.modal-title{
height: 91px;
font-size: 23px;
font-weight: 500;
margin-bottom: 10px;
// margin-bottom: 10px;
display:flex;
justify-content: space-between;
.close-button{
width: 30px;
height: 30px;
border-bottom: 1px solid #E9E9E9;
.title-span{
display: flex;
align-items: center;
justify-content: center;
transform: rotate(0deg);
transition: 0.5s;
cursor: pointer;
padding-left: 42px;
font-family: 'PingFangSC-Medium';
font-weight: 500;
font-size: 30px;
color: #1A1A1A;
line-height: 42px;
}
.close-button-div{
display: flex;
align-items: center;
padding-right: 39px;
.close-button{
width: 30px;
height: 30px;
transform: rotate(0deg);
transition: 0.5s;
cursor: pointer;
background-image: url('/public/photomodal/photo_close_button.png');
background-size: 100% 100%;
}
}
.close-button:hover{
transform: rotate(180deg);
}
}
.content-div{
// background-color: aqua;
height: 600px;
height: 630px;
display: flex;
flex-wrap: wrap;
overflow: auto;
align-content: flex-start;
scrollbar-width: none;
margin-bottom: 10px;
::-webkit-scrollbar {
width: 0;
height: 0;
}
.photo-item{
position: relative;
width: 150px;
height: 150px;
background-color: rgb(24,24,28);
margin-bottom: 10px;
margin-right: 10px;
cursor: pointer;
.select-div{
position: absolute;
bottom: 0px;
height: 20px;
width: 100%;
height: 30px;
background-color: #00000075;
.menu-div{
width: 260px;
border-right: 1px solid #E9E9E9;
border-bottom: 1px solid #E9E9E9;
.menu-title{
height: 63px;
display: flex;
align-items: center;
justify-content: center;
padding-left: 45px;
.menu-title-icon{
width: 18px;
height: 16px;
background-image: url('/public/photomodal/menu_title_icon.png');
background-size: 100% 100%;
margin-right: 8px;
}
.menu-title-span{
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 18px;
color: #333333;
line-height: 25px;
margin-right: 40px;
}
}
.menu-list{
height: 567px;
overflow: auto;
scrollbar-width: none;
::-webkit-scrollbar {
width: 0;
height: 0;
}
.menu-item{
height: 40px;
display: flex;
align-items: center;
padding-left: 91px;
cursor: pointer;
.menu-item-icon{
width: 18px;
height: 14px;
background-image: url('/public/photomodal/menu_item_icon.png');
background-size: 100% 100%;
margin-right: 11px;
}
.menu-item-span{
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 14px;
color: #333333;
line-height: 20px;
}
}
.menu-item:hover{
background-color: #F4F8FF;
}
.select-menu{
background-color: #F4F8FF;
}
.add-menu-div{
height: 40px;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
}
}
}
.show-list-div{
flex: 1;
padding-top: 34px;
padding-left: 31px;
position: relative;
border-bottom: 1px solid #E9E9E9;
.show-control{
display: flex;
justify-content: space-between;
margin-bottom: 34px;
.control-left{
display: flex;
.show-type{
display: flex;
margin-right: 14px;
.custom-radio-btn {
display: flex;
align-items: center;
justify-content: center;
height: 36px;
padding: 0 12px;
.anticon {
font-size: 20px;
}
span{
display: flex;
}
}
}
.select-sort{
:deep(.ant-select-selector){
height: 36px;
.ant-select-selection-item{
display: flex;
align-items: center;
}
}
}
}
.control-right{
padding-right: 74px;
.search-input{
:deep(.ant-input){
height: 36px;
}
}
}
}
.show-list{
height: 440px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
overflow: auto;
scrollbar-width: none;
::-webkit-scrollbar {
width: 0;
height: 0;
}
.show-item{
width: 150px;
margin-right: 28px;
margin-bottom: 13px;
.item-image-div{
position: relative;
border-radius: 11px;
margin-bottom: 15px;
background-color: rgb(24,24,28);
:deep(.item-image){
width: 150px;
height: 150px;
object-fit: contain;
border-radius: 11px;
}
.image-size{
position: absolute;
bottom: 0px;
left: 0px;
width: 150px;
height: 30px;
background-color: rgba(22, 22, 22, 0.56);
border-bottom-right-radius: 11px;
border-bottom-left-radius: 11px;
display: flex;
align-items: center;
justify-content: center;
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 14px;
color: #FFFFFF;
line-height: 20px;
user-select: none;
}
.select-image{
position: absolute;
top: 12px;
right: 14px;
:deep(.ant-checkbox-inner){
width: 23px;
height: 23px;
}
}
}
.item-span{
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 16px;
color: #040404;
line-height: 22px;
text-align: center;
font-style: normal;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.list-title{
width: 974px;
height: 50px;
display: flex;
align-items: center;
background: #F3F3F3;
font-family: 'PingFangSC-Medium';
font-weight: 500;
font-size: 18px;
color: #504E4E;
line-height: 25px;
font-style: normal;
text-transform: none;
}
.list-item{
width: 974px;
height: 110px;
display: flex;
align-items: center;
padding-left: 29px;
border-bottom: 1px solid #EFEFEF;
.list-select-image{
margin-right: 20px;
:deep(.ant-checkbox-inner){
width: 20px;
height: 20px;
}
}
:deep(.list-item-image){
width: 70px;
height: 70px;
object-fit: contain;
border-radius: 5px;
background-color: rgb(24,24,28);
}
.list-item-span{
width: 220px;
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 16px;
color: #040404;
line-height: 22px;
font-style: normal;
margin-left: 20px;
margin-right: 51px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.list-item-size{
width: 138px;
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 16px;
color: #171717;
line-height: 22px;
text-align: center;
font-style: normal;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.list-item-time{
font-family: 'PingFangSC-Regular';
font-weight: 400;
font-size: 16px;
color: #171717;
line-height: 22px;
text-align: center;
font-style: normal;
margin-left: 60px;
}
}
.list-content{
height: 388px;
overflow: auto;
scrollbar-width: none;
::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
.pagination-div{
height: 80px;
display: flex;
align-items: center;
justify-content: end;
padding-right: 73px;
}
}
}
@ -199,6 +623,7 @@ const addPhotoToList = () =>{
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 73px;
}
}
</style>

View File

@ -0,0 +1,8 @@
export const selectSortOptions = [
{ label: '最近上传在前', value: '1' },
{ label: '最近上传在后', value: '2' },
{ label: '最近更新在前', value: '3' },
{ label: '最近更新在后', value: '4' },
{ label: '按照文件名升序', value: '5' },
{ label: '按照文件名降序', value: '6' },
]

View File

@ -1,62 +1,60 @@
import { ref, watch, computed } from 'vue'
import { icon } from '@/plugins'
import { renderLang, renderIcon } from '@/utils'
import { themeColor, setItem, getCharts } from './useLayout.hook'
import { PackagesCategoryEnum, PackagesCategoryName, ConfigType } from '@/packages/index.d'
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { ref, watch, computed } from 'vue';
import { icon } from '@/plugins';
import { renderLang, renderIcon } from '@/utils';
import { themeColor, setItem, getCharts } from './useLayout.hook';
import { PackagesCategoryEnum, PackagesCategoryName, ConfigType } from '@/packages/index.d';
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore';
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d';
// 图标
const { AirPlaneOutlineIcon, ImageIcon, BarChartIcon } = icon.ionicons5
const { TableSplitIcon, RoadmapIcon, ChartPieIcon, SpellCheckIcon, GraphicalDataFlowIcon } = icon.carbon
const { AirPlaneOutlineIcon, ImageIcon, BarChartIcon, GridIcon } = icon.ionicons5;
const { TableSplitIcon, RoadmapIcon, ChartPieIcon, SpellCheckIcon, GraphicalDataFlowIcon } =
icon.carbon;
// 图表
export type MenuOptionsType = {
key: string
icon: ReturnType<typeof renderIcon>
label: ReturnType<typeof renderLang>
list: ConfigType[]
}
key: string;
icon: ReturnType<typeof renderIcon>;
label: ReturnType<typeof renderLang>;
list: ConfigType[];
};
const packagesListObj = {
[PackagesCategoryEnum.CHARTS]: {
icon: renderIcon(RoadmapIcon),
label: PackagesCategoryName.CHARTS
label: PackagesCategoryName.CHARTS,
},
[PackagesCategoryEnum.VCHART]: {
icon: renderIcon(ChartPieIcon),
label: PackagesCategoryName.VCHART
label: PackagesCategoryName.VCHART,
},
[PackagesCategoryEnum.INFORMATIONS]: {
icon: renderIcon(SpellCheckIcon),
label: PackagesCategoryName.INFORMATIONS
label: PackagesCategoryName.INFORMATIONS,
},
[PackagesCategoryEnum.TABLES]: {
icon: renderIcon(TableSplitIcon),
label: PackagesCategoryName.TABLES
label: PackagesCategoryName.TABLES,
},
[PackagesCategoryEnum.DECORATES]: {
icon: renderIcon(GraphicalDataFlowIcon),
label: PackagesCategoryName.DECORATES
label: PackagesCategoryName.DECORATES,
},
[PackagesCategoryEnum.PHOTOS]: {
icon: renderIcon(ImageIcon),
label: PackagesCategoryName.PHOTOS
label: PackagesCategoryName.PHOTOS,
},
[PackagesCategoryEnum.ICONS]: {
icon: renderIcon(AirPlaneOutlineIcon),
label: PackagesCategoryName.ICONS
label: PackagesCategoryName.ICONS,
},
[PackagesCategoryEnum.CUSTOM]: {
icon: renderIcon(AirPlaneOutlineIcon),
label: PackagesCategoryName.CUSTOM
},
[PackagesCategoryEnum.DIY]: {
icon: renderIcon(AirPlaneOutlineIcon),
label: PackagesCategoryName.DIY
label: PackagesCategoryName.CUSTOM,
},
[PackagesCategoryEnum.UNITS]: {
icon: renderIcon(AirPlaneOutlineIcon),
label: PackagesCategoryName.UNITS
label: PackagesCategoryName.UNITS,
},
[PackagesCategoryEnum.ZHIGAN]: {
icon: renderIcon(AirPlaneOutlineIcon),
@ -66,14 +64,14 @@ const packagesListObj = {
icon: renderIcon(AirPlaneOutlineIcon),
label: PackagesCategoryName.MAPICONS
}
}
};
export const useAsideHook = () => {
const packagesStore = usePackagesStore()
const menuOptions: MenuOptionsType[] = []
const packagesStore = usePackagesStore();
const menuOptions: MenuOptionsType[] = [];
// 处理列表
const handlePackagesList = () => {
const handlePackagesList = async () => {
for (const val in packagesStore.getPackagesList) {
menuOptions.push({
key: val,
@ -82,30 +80,29 @@ export const useAsideHook = () => {
// @ts-ignore
label: packagesListObj[val].label,
// @ts-ignore
list: packagesStore.getPackagesList[val]
})
list: packagesStore.getPackagesList[val],
});
}
}
handlePackagesList()
};
handlePackagesList();
// 记录选中值
let beforeSelect: string = menuOptions[0]['key']
const selectValue = ref<string>(menuOptions[0]['key'])
let beforeSelect: string = menuOptions[0]['key'];
const selectValue = ref<string>(menuOptions[0]['key']);
// 选中的对象值
const selectOptions = ref(menuOptions[0])
const selectOptions = ref(menuOptions[0]);
// 点击 item
const clickItemHandle = (key: string, item: any) => {
selectOptions.value = item
selectOptions.value = item;
// 处理折叠
if (beforeSelect === key) {
setItem(ChartLayoutStoreEnum.CHARTS, !getCharts.value, false)
setItem(ChartLayoutStoreEnum.CHARTS, !getCharts.value, false);
} else {
setItem(ChartLayoutStoreEnum.CHARTS, true, false)
setItem(ChartLayoutStoreEnum.CHARTS, true, false);
}
beforeSelect = key
}
beforeSelect = key;
};
return {
getCharts,
@ -114,6 +111,6 @@ export const useAsideHook = () => {
selectOptions,
selectValue,
clickItemHandle,
menuOptions
}
}
menuOptions,
};
};

View File

@ -1,6 +1,12 @@
<template>
<!-- 左侧所有组件的展示列表 -->
<content-box class="go-content-charts" :class="{ scoped: !getCharts }" title="组件" :depth="1" :backIcon="false">
<content-box
class="go-content-charts"
:class="{ scoped: !getCharts }"
title="组件"
:depth="1"
:backIcon="false"
>
<template #icon>
<n-icon size="14" :depth="2">
<bar-chart-icon></bar-chart-icon>
@ -8,7 +14,7 @@
</template>
<template #top-right>
<charts-search v-show="getCharts" :menuOptions="menuOptions"></charts-search>
<charts-search v-show="getCharts" :menuOptions="menuOptionsList"></charts-search>
</template>
<!-- 图表 -->
<aside>
@ -16,13 +22,19 @@
<n-menu
class="menu-width"
v-model:value="selectValue"
:options="menuOptions"
:options="menuOptionsList"
:icon-size="16"
:indent="18"
@update:value="clickItemHandle"
></n-menu>
<div class="menu-component-box">
<go-skeleton :load="!selectOptions" round text :repeat="2" style="width: 90%"></go-skeleton>
<go-skeleton
:load="!selectOptions"
round
text
:repeat="2"
style="width: 90%"
></go-skeleton>
<charts-option-content
v-if="selectOptions"
:selectOptions="selectOptions"
@ -32,11 +44,12 @@
</div>
</aside>
</content-box>
<a-modal
<a-modal
class="photo-control-modal"
v-model:open="photoModalStateStore.getOpen"
width="1200px"
:okButtonProps="{ style: { display: 'none' } }"
:cancelButtonProps="{ style: { display: 'none' } }"
width="1340px"
style="top: 90px"
:footer="null"
:closable="false"
>
<PhotoModal />
@ -44,74 +57,120 @@
</template>
<script setup lang="ts">
import { ContentBox } from '../ContentBox/index'
import { ChartsOptionContent } from './components/ChartsOptionContent'
import { ChartsSearch } from './components/ChartsSearch'
import { useAsideHook } from './hooks/useAside.hook'
import PhotoModal from './components/PhotoModal/index.vue'
import { photoModalStore } from '@/store/modules/photoModal'
import { ContentBox } from '../ContentBox/index';
import { ChartsOptionContent } from './components/ChartsOptionContent';
import { ChartsSearch } from './components/ChartsSearch';
import { useAsideHook } from './hooks/useAside.hook';
import PhotoModal from './components/PhotoModal/index.vue';
import { photoModalStore } from '@/store/modules/photoModal';
import { onMounted, ref } from 'vue';
import { customComponentList } from '@/api/path/project.api';
import { icon } from '@/plugins';
import { renderIcon } from '@/utils';
const { getCharts, BarChartIcon, themeColor, selectOptions, selectValue, clickItemHandle, menuOptions } = useAsideHook()
const photoModalStateStore = photoModalStore()
const { GridIcon } = icon.ionicons5;
const {
getCharts,
BarChartIcon,
themeColor,
selectOptions,
selectValue,
clickItemHandle,
menuOptions,
} = useAsideHook();
const photoModalStateStore = photoModalStore();
const menuOptionsList = ref(menuOptions);
const getCustomComponentList = async () => {
const data = await customComponentList({
page: 1,
limit: 999,
});
let list = [];
data.items.forEach((item) => {
let obj = JSON.parse(item.content);
list.push({
...obj,
id: item.id,
});
});
return list;
};
onMounted(async () => {
getCustomComponentList().then((res) => {
menuOptionsList.value.push({
key: 'Group',
label: '分组',
icon: renderIcon(GridIcon),
list: res,
});
});
});
</script>
<style lang="scss" scoped>
/* 整体宽度 */
$width: 330px;
/* 列表的宽度 */
$widthScoped: 65px;
/* 此高度与 ContentBox 组件关联 */
$topHeight: 40px;
/* 整体宽度 */
$width: 330px;
/* 列表的宽度 */
$widthScoped: 65px;
/* 此高度与 ContentBox 组件关联 */
$topHeight: 40px;
@include go(content-charts) {
width: $width;
@extend .go-transition;
&.scoped,
.menu-width {
width: $widthScoped;
}
.menu-width-box {
display: flex;
height: calc(100vh - #{$--header-height} - #{$topHeight});
@include go(content-charts) {
width: $width;
@extend .go-transition;
&.scoped,
.menu-width {
flex-shrink: 0;
@include fetch-bg-color('background-color2');
width: $widthScoped;
}
.menu-component-box {
flex-shrink: 0;
width: $width - $widthScoped;
overflow: hidden;
.menu-width-box {
display: flex;
height: calc(100vh - #{$--header-height} - #{$topHeight});
.menu-width {
flex-shrink: 0;
@include fetch-bg-color('background-color2');
}
.menu-component-box {
flex-shrink: 0;
width: $width - $widthScoped;
overflow: hidden;
}
}
}
@include deep() {
.menu-width {
.n-menu-item {
height: auto !important;
&.n-menu-item--selected {
&::after {
content: '';
position: absolute;
left: 2px;
top: 0;
height: 100%;
width: 3px;
background-color: v-bind('themeColor');
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
@include deep() {
.menu-width {
.n-menu-item {
height: auto !important;
&.n-menu-item--selected {
&::after {
content: '';
position: absolute;
left: 2px;
top: 0;
height: 100%;
width: 3px;
background-color: v-bind('themeColor');
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
}
.n-menu-item-content {
display: flex;
flex-direction: column;
padding: 6px 12px !important;
font-size: 14px !important;
}
.n-menu-item-content__icon {
font-size: 18px !important;
margin-right: 0 !important;
}
}
.n-menu-item-content {
display: flex;
flex-direction: column;
padding: 6px 12px !important;
font-size: 14px !important;
}
.n-menu-item-content__icon {
font-size: 18px !important;
margin-right: 0 !important;
}
}
}
}
}
</style>
<style lang="scss">
.photo-control-modal {
.ant-modal-content {
padding: 0px;
}
}
</style>

View File

@ -128,6 +128,7 @@
import { funSelectOptions } from '@/hooks/ceshiFun.hook';
const { chartEditStore } = useTargetData();
const routeOptions = ref([]);
const skipTypeOptions = ref([
{
@ -144,6 +145,7 @@
},
]);
const publishOptions = ref([]);
const props = defineProps({
eventData: {
type: Object,
@ -240,12 +242,18 @@
publishOptions.value = data.items.map((item) => {
return {
label: item.projectName,
value: previewPath(item.id),
// value: previewPath(item.id),
value: item.id,
};
});
};
onMounted(() => {
routeOptions.value = [];
routeOptions.value = [
{
label: '首页',
value: '/dashboard/analysis',
},
];
getRouteList();
getPublishedPageList();
});

View File

@ -1,11 +1,11 @@
import { ref, nextTick, toRaw } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
import { renderIcon, loadingError } from '@/utils'
import { icon } from '@/plugins'
import { MenuOptionsItemType } from './useContextMenu.hook.d'
import { MenuEnum } from '@/enums/editPageEnum'
import cloneDeep from 'lodash/cloneDeep'
import { ref, nextTick, toRaw } from 'vue';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d';
import { renderIcon, loadingError } from '@/utils';
import { icon } from '@/plugins';
import { MenuOptionsItemType } from './useContextMenu.hook.d';
import { MenuEnum } from '@/enums/editPageEnum';
import cloneDeep from 'lodash/cloneDeep';
const {
CopyIcon,
@ -17,11 +17,13 @@ const {
LockOpenOutlineIcon,
LockClosedOutlineIcon,
EyeOutlineIcon,
EyeOffOutlineIcon
} = icon.ionicons5
const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon, Carbon3DSoftwareIcon, Carbon3DCursorIcon } = icon.carbon
EyeOffOutlineIcon,
GridIcon,
} = icon.ionicons5;
const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon, Carbon3DSoftwareIcon, Carbon3DCursorIcon } =
icon.carbon;
const chartEditStore = useChartEditStore()
const chartEditStore = useChartEditStore();
/**
* 线
@ -31,9 +33,9 @@ const chartEditStore = useChartEditStore()
export const divider = (n: number = 3) => {
return {
type: 'divider',
key: `d${n}`
}
}
key: `d${n}`,
};
};
// * 默认单组件选项
export const defaultOptions: MenuOptionsItemType[] = [
@ -41,93 +43,99 @@ export const defaultOptions: MenuOptionsItemType[] = [
label: '锁定',
key: MenuEnum.LOCK,
icon: renderIcon(LockClosedOutlineIcon),
fnHandle: chartEditStore.setLock
fnHandle: chartEditStore.setLock,
},
{
label: '解锁',
key: MenuEnum.UNLOCK,
icon: renderIcon(LockOpenOutlineIcon),
fnHandle: chartEditStore.setUnLock
fnHandle: chartEditStore.setUnLock,
},
{
label: '隐藏',
key: MenuEnum.HIDE,
icon: renderIcon(EyeOffOutlineIcon),
fnHandle: chartEditStore.setHide
fnHandle: chartEditStore.setHide,
},
{
label: '显示',
key: MenuEnum.SHOW,
icon: renderIcon(EyeOutlineIcon),
fnHandle: chartEditStore.setShow
fnHandle: chartEditStore.setShow,
},
{
type: 'divider',
key: 'd0'
key: 'd0',
},
{
label: '复制',
key: MenuEnum.COPY,
icon: renderIcon(CopyIcon),
fnHandle: chartEditStore.setCopy
fnHandle: chartEditStore.setCopy,
},
{
label: '剪切',
key: MenuEnum.CUT,
icon: renderIcon(CutIcon),
fnHandle: chartEditStore.setCut
fnHandle: chartEditStore.setCut,
},
{
label: '粘贴',
key: MenuEnum.PARSE,
icon: renderIcon(ClipboardOutlineIcon),
fnHandle: chartEditStore.setParse
fnHandle: chartEditStore.setParse,
},
{
type: 'divider',
key: 'd1'
key: 'd1',
},
{
label: '置顶',
key: MenuEnum.TOP,
icon: renderIcon(UpToTopIcon),
fnHandle: chartEditStore.setTop
fnHandle: chartEditStore.setTop,
},
{
label: '置底',
key: MenuEnum.BOTTOM,
icon: renderIcon(DownToBottomIcon),
fnHandle: chartEditStore.setBottom
fnHandle: chartEditStore.setBottom,
},
{
label: '上移',
key: MenuEnum.UP,
icon: renderIcon(ChevronUpIcon),
fnHandle: chartEditStore.setUp
fnHandle: chartEditStore.setUp,
},
{
label: '下移',
key: MenuEnum.DOWN,
icon: renderIcon(ChevronDownIcon),
fnHandle: chartEditStore.setDown
fnHandle: chartEditStore.setDown,
},
{
type: 'divider',
key: 'd2'
key: 'd2',
},
{
label: '清空剪贴板',
key: MenuEnum.CLEAR,
icon: renderIcon(PaintBrushIcon),
fnHandle: chartEditStore.setRecordChart
fnHandle: chartEditStore.setRecordChart,
},
{
label: '删除',
key: MenuEnum.DELETE,
icon: renderIcon(TrashIcon),
fnHandle: chartEditStore.removeComponentList
}
]
fnHandle: chartEditStore.removeComponentList,
},
{
label: '保存至分组',
key: MenuEnum.SAVETOGROUP,
icon: renderIcon(GridIcon),
fnHandle: chartEditStore.saveToGroup,
},
];
// * 默认多选组件选项
export const defaultMultiSelectOptions: MenuOptionsItemType[] = [
@ -135,18 +143,18 @@ export const defaultMultiSelectOptions: MenuOptionsItemType[] = [
label: '创建分组',
key: MenuEnum.GROUP,
icon: renderIcon(Carbon3DSoftwareIcon),
fnHandle: chartEditStore.setGroup
fnHandle: chartEditStore.setGroup,
},
{
label: '解除分组',
key: MenuEnum.UN_GROUP,
icon: renderIcon(Carbon3DCursorIcon),
fnHandle: chartEditStore.setUnGroup
}
]
fnHandle: chartEditStore.setUnGroup,
},
];
// * 无数据传递拥有的选项
const defaultNoItemKeys = [MenuEnum.PARSE, MenuEnum.CLEAR]
const defaultNoItemKeys = [MenuEnum.PARSE, MenuEnum.CLEAR];
/**
* *
@ -155,13 +163,13 @@ const defaultNoItemKeys = [MenuEnum.PARSE, MenuEnum.CLEAR]
* @returns
*/
const pickOption = (options: MenuOptionsItemType[], pickList?: MenuEnum[]) => {
if (!pickList) return options
const list: MenuOptionsItemType[] = []
pickList.forEach(e => {
list.push(...options.filter(op => op.key === e))
})
return list
}
if (!pickList) return options;
const list: MenuOptionsItemType[] = [];
pickList.forEach((e) => {
list.push(...options.filter((op) => op.key === e));
});
return list;
};
/**
* *
@ -170,14 +178,14 @@ const pickOption = (options: MenuOptionsItemType[], pickList?: MenuEnum[]) => {
* @returns
*/
const hideOption = (options: MenuOptionsItemType[], hideList?: MenuEnum[]) => {
if (!hideList) return options
if (!hideList) return options;
return options.filter((op: MenuOptionsItemType) => {
return hideList.findIndex((e: MenuEnum) => e !== op.key) !== -1
})
}
return hideList.findIndex((e: MenuEnum) => e !== op.key) !== -1;
});
};
// * 右键内容
const menuOptions = ref<MenuOptionsItemType[]>([])
const menuOptions = ref<MenuOptionsItemType[]>([]);
// * 右键处理
const handleContextMenu = (
@ -189,51 +197,57 @@ const handleContextMenu = (
// 隐藏选项列表
hideOptionsList?: MenuEnum[],
// 挑选选项列表
pickOptionsList?: MenuEnum[]
pickOptionsList?: MenuEnum[],
) => {
e.stopPropagation()
e.preventDefault()
e.stopPropagation();
e.preventDefault();
let target = e.target
let target = e.target;
while (target instanceof SVGElement) {
target = target.parentNode
target = target.parentNode;
}
chartEditStore.setTargetSelectChart(targetInstance && targetInstance.id)
chartEditStore.setTargetSelectChart(targetInstance && targetInstance.id);
// 隐藏旧列表
chartEditStore.setRightMenuShow(false)
chartEditStore.setRightMenuShow(false);
// * 多选默认选项
if (chartEditStore.getTargetChart.selectId.length > 1) {
menuOptions.value = defaultMultiSelectOptions
menuOptions.value = defaultMultiSelectOptions;
} else {
// * 单选默认选项
menuOptions.value = defaultOptions
menuOptions.value = defaultOptions;
}
if (!targetInstance) {
menuOptions.value = pickOption(toRaw(menuOptions.value), defaultNoItemKeys)
menuOptions.value = pickOption(toRaw(menuOptions.value), defaultNoItemKeys);
}
if (hideOptionsList) {
menuOptions.value = hideOption([...defaultMultiSelectOptions, divider(), ...defaultOptions], hideOptionsList)
menuOptions.value = hideOption(
[...defaultMultiSelectOptions, divider(), ...defaultOptions],
hideOptionsList,
);
}
if (pickOptionsList) {
menuOptions.value = pickOption([...defaultMultiSelectOptions, divider(), ...defaultOptions], pickOptionsList)
menuOptions.value = pickOption(
[...defaultMultiSelectOptions, divider(), ...defaultOptions],
pickOptionsList,
);
}
if (optionsHandle) {
// 自定义函数能够拿到当前选项和所有选项
menuOptions.value = optionsHandle(
cloneDeep(toRaw(menuOptions.value)),
[...defaultMultiSelectOptions, ...defaultOptions],
targetInstance
)
targetInstance,
);
}
nextTick().then(() => {
chartEditStore.setMousePosition(e.clientX, e.clientY)
chartEditStore.setRightMenuShow(true)
})
}
chartEditStore.setMousePosition(e.clientX, e.clientY);
chartEditStore.setRightMenuShow(true);
});
};
/**
* * hook
@ -242,28 +256,30 @@ const handleContextMenu = (
*/
export const useContextMenu = () => {
// 设置默认项
menuOptions.value = defaultOptions
menuOptions.value = defaultOptions;
// * 失焦
const onClickOutSide = () => {
chartEditStore.setRightMenuShow(false)
}
chartEditStore.setRightMenuShow(false);
};
// * 事件处理
const handleMenuSelect = (key: string) => {
chartEditStore.setRightMenuShow(false)
const targetItem: MenuOptionsItemType[] = menuOptions.value.filter((e: MenuOptionsItemType) => e.key === key)
chartEditStore.setRightMenuShow(false);
const targetItem: MenuOptionsItemType[] = menuOptions.value.filter(
(e: MenuOptionsItemType) => e.key === key,
);
menuOptions.value.forEach((e: MenuOptionsItemType) => {
if (e.key === key) {
if (e.fnHandle) {
e.fnHandle()
return
e.fnHandle();
return;
}
if (!targetItem) loadingError()
if (!targetItem) loadingError();
}
})
}
});
};
return {
menuOptions,
@ -272,6 +288,6 @@ export const useContextMenu = () => {
handleContextMenu,
onClickOutSide,
handleMenuSelect,
mousePosition: chartEditStore.getMousePosition
}
}
mousePosition: chartEditStore.getMousePosition,
};
};

View File

@ -63,7 +63,7 @@
publishOptions.value = data.items.map((item) => {
return {
label: item.projectName,
value: previewPath(item.id),
value: item.id,
};
});
};

View File

@ -30,7 +30,7 @@
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { computed, watch } from 'vue';
import { PreviewRenderList } from './components/PreviewRenderList';
import { getFilterStyle, setTitle } from '@/utils';
import {
@ -45,8 +45,10 @@
import { PreviewScaleEnum } from '@/enums/styleEnum';
import type { ChartEditStorageType } from './index.d';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useRoute } from 'vue-router';
// const localStorageInfo: ChartEditStorageType = getSessionStorageInfo() as ChartEditStorageType
const route = useRoute();
await getSessionStorageInfo();
const chartEditStore = useChartEditStore() as unknown as ChartEditStorageType;
@ -72,6 +74,12 @@
//
keyRecordHandle();
watch(
() => route.fullPath,
(newValue) => {
location.reload();
},
);
</script>
<style lang="scss" scoped>

View File

@ -62,7 +62,7 @@
</n-dropdown>
</template>
<n-tooltip v-else placement="bottom" trigger="hover">
<n-tooltip v-else placement="bottom" trigger="hover" v-if="!(item.key === 'copyUrl') || (item.key === 'copyUrl' && cardData.release)">
<template #trigger>
<n-button size="small" @click="handleSelect(item.key)">
<template #icon>
@ -84,7 +84,7 @@
<script setup lang="ts">
import { reactive, ref, PropType } from 'vue';
import { renderIcon, renderLang, requireErrorImg } from '@/utils';
import { renderIcon, renderLang, requireErrorImg, previewPath } from '@/utils';
import { icon } from '@/plugins';
import { MacOsControlBtn } from '@/components/Tips/MacOsControlBtn';
import { Chartype } from '../../index.d';
@ -115,6 +115,11 @@
key: 'edit',
icon: renderIcon(HammerIcon),
},
{
label: renderLang('global.r_copy_url'),
key: 'copyUrl',
icon: renderIcon(CopyIcon),
},
{
lable: renderLang('global.r_more'),
key: 'select',
@ -156,6 +161,9 @@
case 'edit':
editHandle();
break;
case 'copyUrl':
copyUrl()
break
}
};
@ -187,6 +195,21 @@
const requireUrl = (name: string) => {
return new URL(`../../../../../assets/images/${name}`, import.meta.url).href;
};
//
const copyUrl = () => {
try{
let url = previewPath(props.cardData.id)
const textarea = document.createElement("textarea");
textarea.value = url;
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
window['$message'].success('地址复制成功')
}catch(error){
window['$message'].error('地址复制失败')
}
}
</script>
<style lang="scss" scoped>

View File

@ -18,6 +18,7 @@ export const useDataListInit = () => {
count: 10,
});
const state = ref('0')
const list = ref<ChartList>([]);
// const list = ref<ChartList>([
// {
@ -58,6 +59,7 @@ export const useDataListInit = () => {
const res = await projectListApi({
page: paginat.page,
limit: paginat.limit,
state: state.value == '0'? '': state.value,
});
if (res && res.items) {
const { total } = res as any; // 这里的count与data平级不在Response结构中
@ -87,6 +89,13 @@ export const useDataListInit = () => {
fetchList();
};
// 修改筛选条件
const changeState = (value) => {
console.log(111,value)
state.value = value
fetchList();
}
// 修改大小
const changeSize = (_size: number) => {
paginat.limit = _size;
@ -147,10 +156,12 @@ export const useDataListInit = () => {
loading,
paginat,
list,
state,
fetchList,
releaseHandle,
changeSize,
changePage,
deleteHandle,
changeState,
};
};

View File

@ -1,12 +1,23 @@
<template>
<div class="go-items-list">
<div class="filter">
<a-select
v-model:value="state"
style="width: 200px"
@change="changeState"
>
<a-select-option value="0">全部</a-select-option>
<a-select-option value="1">已发布</a-select-option>
<a-select-option value="-1">未发布</a-select-option>
</a-select>
</div>
<!-- 加载 -->
<div v-show="loading">
<go-loading></go-loading>
</div>
<!-- 列表 -->
<div v-show="!loading">
<n-grid :x-gap="20" :y-gap="20" cols="2 s:2 m:3 l:4 xl:4 xxl:4" responsive="screen">
<div v-show="!loading" style="height: calc(100vh - 230px); overflow: auto;">
<n-grid :x-gap="20" :y-gap="18" cols="2 s:2 m:3 l:4 xl:4 xxl:4" responsive="screen">
<n-grid-item v-for="(item, index) in list" :key="item.id">
<project-items-card
:cardData="item"
@ -54,7 +65,7 @@
const { CopyIcon, EllipsisHorizontalCircleSharpIcon } = icon.ionicons5;
const { modalData, modalShow, closeModal, previewHandle, resizeHandle, editHandle } =
useModalDataInit();
const { loading, paginat, list, changeSize, changePage, releaseHandle, deleteHandle } =
const { loading, paginat, list, state, changeSize, changePage, releaseHandle, deleteHandle, changeState } =
useDataListInit();
</script>
@ -64,7 +75,7 @@
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: calc(100vh - #{$--header-height} - 40px - 2px);
min-height: calc(100vh - #{$--header-height} - 40px - 40px);
.list-content {
position: relative;
height: $contentHeight;
@ -74,5 +85,10 @@
justify-content: flex-end;
margin-top: 20px;
}
.filter{
display: flex;
justify-content: end;
margin-bottom: 10px;
}
}
</style>