Merge branch 'master' of https://git.code.tencent.com/xian-ncc-da/xian-ncc-da-client
This commit is contained in:
commit
825cb1b7a8
@ -47,18 +47,6 @@ export function deleteDraft(id: number) {
|
||||
return api.delete(`${DraftUriBase}/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 草稿图发布
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function publishDraft(data: {
|
||||
layoutId: string;
|
||||
name: string;
|
||||
overwrite?: boolean;
|
||||
}) {
|
||||
return api.post(`${DraftUriBase}/publish`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取草稿数据
|
||||
* @param params
|
||||
|
80
src/api/LineInfoApi.ts
Normal file
80
src/api/LineInfoApi.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
const UriBase = '/api/lineInfo';
|
||||
|
||||
interface Item {
|
||||
id: number;
|
||||
name: string;
|
||||
lineId: number;
|
||||
config: string;
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function pageQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<Item>> {
|
||||
const response = await api.get(`${UriBase}/paging`, {
|
||||
params: params,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建线路
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function createLine(data: {
|
||||
name: string;
|
||||
lineId: number;
|
||||
config?: string;
|
||||
}) {
|
||||
return api.post(`${UriBase}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除线路
|
||||
* @param id 线路id
|
||||
*/
|
||||
export function deleteLine(id: number) {
|
||||
return api.delete(`${UriBase}/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存线路数据
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function saveLineData(id: number, data: Item) {
|
||||
return api.put(`${UriBase}/${id}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取线路数据详情
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getLineInfo(id: number): Promise<Item> {
|
||||
const response = await api.get(`${UriBase}/${id}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取线路信息列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getLineList(): Promise<Array<Item>> {
|
||||
const response = await api.get(`${UriBase}/list`);
|
||||
return response.data;
|
||||
}
|
61
src/api/PublishApi.ts
Normal file
61
src/api/PublishApi.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { api } from 'src/boot/axios';
|
||||
import { PageDto, PageQueryDto } from './ApiCommon';
|
||||
|
||||
const PublishUriBase = '/api/publishedGi';
|
||||
|
||||
interface Item {
|
||||
id: number;
|
||||
name: string;
|
||||
proto: string;
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
creatorId?: number;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 草稿图发布
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function publishDraft(data: {
|
||||
name: string;
|
||||
lineId: number;
|
||||
draftingId: number;
|
||||
}) {
|
||||
return api.post(`${PublishUriBase}/publish`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发布图形数据列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function getDraft(id: number): Promise<Item> {
|
||||
const response = await api.get(`${PublishUriBase}/list`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export async function pageQuery(
|
||||
params: PagingQueryParams
|
||||
): Promise<PageDto<Item>> {
|
||||
const response = await api.get(`${PublishUriBase}/paging`, {
|
||||
params: params,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除发布图
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function deletePublish(id: number) {
|
||||
return api.delete(`${PublishUriBase}/${id}`);
|
||||
}
|
@ -64,6 +64,16 @@ const list = reactive([
|
||||
label: '草稿管理',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
{
|
||||
path: '/dataManage/publish',
|
||||
label: '发布管理',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
{
|
||||
path: '/dataManage/lineInfo',
|
||||
label: '线路信息管理',
|
||||
icon: 'app_registration',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
@ -8,40 +8,6 @@
|
||||
v-model="stationModel.code"
|
||||
lazy-rules
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="hasCircle"
|
||||
:options="optionsCircle"
|
||||
label="是否有圆圈"
|
||||
/>
|
||||
<div v-if="stationModel.hasCircle">
|
||||
<q-item-label header>位置</q-item-label>
|
||||
<q-item>
|
||||
<q-item-section no-wrap class="q-gutter-sm column">
|
||||
<div class="row">
|
||||
<q-input
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
label="x"
|
||||
v-model.number="stationModel.circlePoint.x"
|
||||
type="number"
|
||||
step="any"
|
||||
class="col"
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
label="y"
|
||||
v-model.number="stationModel.circlePoint.y"
|
||||
type="number"
|
||||
step="any"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</div>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
@ -49,20 +15,10 @@
|
||||
import { StationData } from 'src/drawApp/graphics/StationInteraction';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const stationModel = reactive(new StationData());
|
||||
const hasCircle = ref('是');
|
||||
const optionsCircle = ['是', '否'];
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
}
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
@ -70,7 +26,6 @@ watch(
|
||||
(val) => {
|
||||
if (val && val.type == Station.Type) {
|
||||
stationModel.copyFrom(val.saveData() as StationData);
|
||||
hasCircle.value = (showSelectData as never)[stationModel.hasCircle + ''];
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -79,12 +34,10 @@ onMounted(() => {
|
||||
const station = drawStore.selectedGraphic as Station;
|
||||
if (station) {
|
||||
stationModel.copyFrom(station.saveData());
|
||||
hasCircle.value = (showSelectData as never)[stationModel.hasCircle + ''];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
stationModel.hasCircle = JSON.parse((showSelect as never)[hasCircle.value]);
|
||||
const station = drawStore.selectedGraphic as Station;
|
||||
if (station) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(station, stationModel);
|
||||
|
@ -1,5 +1,6 @@
|
||||
function getHost(): string {
|
||||
return '192.168.3.7:9081';
|
||||
// return '192.168.3.7:9081';
|
||||
return '192.168.3.233:9081';
|
||||
}
|
||||
|
||||
export function getHttpBase() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { IPointData } from 'pixi.js';
|
||||
import { IStationData } from 'src/graphics/station/Station';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
@ -26,18 +25,6 @@ export class StationData extends GraphicDataBase implements IStationData {
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get hasCircle(): boolean {
|
||||
return this.data.hasCircle;
|
||||
}
|
||||
set hasCircle(v: boolean) {
|
||||
this.data.hasCircle = v;
|
||||
}
|
||||
get circlePoint(): IPointData {
|
||||
return this.data.circlePoint;
|
||||
}
|
||||
set circlePoint(point: IPointData) {
|
||||
this.data.circlePoint = new graphicData.Point({ x: point.x, y: point.y });
|
||||
}
|
||||
clone(): StationData {
|
||||
return new StationData(this.data.cloneMessage());
|
||||
}
|
||||
|
@ -26,12 +26,6 @@ export class TurnoutData extends GraphicDataBase implements ITurnoutData {
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get forkPoint(): IPointData {
|
||||
return this.data.forkPoint;
|
||||
}
|
||||
set forkPoint(v: IPointData) {
|
||||
this.data.forkPoint = new graphicData.Point({ x: v.x, y: v.y });
|
||||
}
|
||||
get pointA(): IPointData {
|
||||
return this.data.pointA;
|
||||
}
|
||||
|
@ -1,80 +1,46 @@
|
||||
import { Color, Graphics, IPointData, Point } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'src/jl-graphic';
|
||||
import { StationDraw } from './StationDrawAssistant';
|
||||
|
||||
export interface IStationData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
set code(v: string);
|
||||
get hasCircle(): boolean; // 是否有圆圈--线网图
|
||||
set hasCircle(v: boolean);
|
||||
get circlePoint(): IPointData; // 位置坐标
|
||||
set circlePoint(point: IPointData);
|
||||
clone(): IStationData;
|
||||
copyFrom(data: IStationData): void;
|
||||
eq(other: IStationData): boolean;
|
||||
}
|
||||
|
||||
const stationConsts = {
|
||||
radius: 5,
|
||||
borderWidth: 1,
|
||||
borderColor: '0xff0000',
|
||||
fillColor: '0xff0000',
|
||||
codeColor: '0xF48815',
|
||||
codeFontSize: 22,
|
||||
lineWidth: 3,
|
||||
};
|
||||
|
||||
export class Station extends JlGraphic {
|
||||
static Type = 'station';
|
||||
codeGraph: VectorText = new VectorText(''); //车站名
|
||||
circleGraphic: Graphics = new Graphics();
|
||||
constructor() {
|
||||
super(Station.Type);
|
||||
this.addChild(this.codeGraph);
|
||||
this.addChild(this.circleGraphic);
|
||||
}
|
||||
|
||||
get datas(): IStationData {
|
||||
return this.getDatas<IStationData>();
|
||||
}
|
||||
static draw(station: Station | StationDraw, datas?: IStationData): void {
|
||||
station.circleGraphic.clear();
|
||||
const codeGraph = station.codeGraph;
|
||||
codeGraph.text = datas?.code || '车站Station';
|
||||
doRepaint(): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
codeGraph.text = this.datas?.code || '车站Station';
|
||||
codeGraph.style.fill = stationConsts.codeColor;
|
||||
codeGraph.setVectorFontSize(stationConsts.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
if (datas?.hasCircle) {
|
||||
const circleGraphic = station.circleGraphic;
|
||||
circleGraphic.lineStyle(
|
||||
stationConsts.borderWidth,
|
||||
new Color(stationConsts.borderColor)
|
||||
);
|
||||
circleGraphic.beginFill(stationConsts.fillColor, 1);
|
||||
circleGraphic.drawCircle(0, 0, stationConsts.radius);
|
||||
circleGraphic.endFill;
|
||||
circleGraphic.position.set(datas.circlePoint.x, datas.circlePoint.y);
|
||||
}
|
||||
}
|
||||
doRepaint(): void {
|
||||
Station.draw(this, this.datas);
|
||||
}
|
||||
}
|
||||
|
||||
export class StationTemplate extends JlGraphicTemplate<Station> {
|
||||
hasCircle: boolean;
|
||||
radius: number;
|
||||
circlePoint: IPointData;
|
||||
constructor() {
|
||||
super(Station.Type);
|
||||
this.hasCircle = false;
|
||||
this.radius = stationConsts.radius;
|
||||
this.circlePoint = new Point(0, -15);
|
||||
}
|
||||
new(): Station {
|
||||
return new Station();
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { FederatedPointerEvent, Point, Graphics } from 'pixi.js';
|
||||
import { FederatedPointerEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
VectorText,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
import { IStationData, Station, StationTemplate } from './Station';
|
||||
@ -17,9 +17,7 @@ export class StationDraw extends GraphicDrawAssistant<
|
||||
StationTemplate,
|
||||
IStationData
|
||||
> {
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
circleGraphic: Graphics = new Graphics();
|
||||
|
||||
codeGraph: Station;
|
||||
constructor(app: JlDrawApp, createData: () => IStationData) {
|
||||
super(
|
||||
app,
|
||||
@ -28,13 +26,16 @@ export class StationDraw extends GraphicDrawAssistant<
|
||||
'svguse:../drawIcon.svg#icon-station',
|
||||
'车站Station'
|
||||
);
|
||||
this.codeGraph = this.graphicTemplate.new();
|
||||
this.container.addChild(this.codeGraph);
|
||||
stationInteraction.init(app);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
Station.draw(this);
|
||||
const data = { graphicType: 'station' } as GraphicData;
|
||||
this.codeGraph.loadData(data);
|
||||
this.codeGraph.doRepaint();
|
||||
}
|
||||
unbind(): void {
|
||||
super.unbind();
|
||||
@ -52,10 +53,7 @@ export class StationDraw extends GraphicDrawAssistant<
|
||||
this.container.position.copyFrom(p);
|
||||
}
|
||||
prepareData(data: IStationData): boolean {
|
||||
const template = this.graphicTemplate;
|
||||
data.transform = this.container.saveTransform();
|
||||
data.hasCircle = template.hasCircle;
|
||||
data.circlePoint = template.circlePoint;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -35,26 +35,64 @@ export interface ITurnoutState extends GraphicState {
|
||||
position: TurnoutPosition;
|
||||
}
|
||||
|
||||
function getIntersectionPoint(r: number, p: IPointData): IPointData {
|
||||
if (r === 0) return { x: 0, y: 0 };
|
||||
const len = Math.sqrt((-p.x) ** 2 + (-p.y) ** 2);
|
||||
const scale = r / len;
|
||||
return { x: scale * p.x, y: scale * p.y };
|
||||
}
|
||||
|
||||
class TurnoutSection extends Graphics {
|
||||
paint(p: IPointData, gap: number) {
|
||||
const { x, y } = getIntersectionPoint(gap, p);
|
||||
this.clear()
|
||||
.lineStyle(TurnoutConsts.lineWidth, TurnoutConsts.lineColor)
|
||||
.moveTo(p.x, p.y)
|
||||
.lineTo(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
class ForkGraphic extends Graphics {
|
||||
paint(p: IPointData) {
|
||||
const target = getIntersectionPoint(20, p);
|
||||
this.clear()
|
||||
.lineStyle(TurnoutConsts.lineWidth, TurnoutConsts.lineColor)
|
||||
.moveTo(0, 0)
|
||||
.lineTo(target.x, target.y);
|
||||
}
|
||||
}
|
||||
|
||||
export class Turnout extends JlGraphic {
|
||||
static Type = 'Turnout';
|
||||
graphics: {
|
||||
fork: Graphics;
|
||||
sections: Graphics;
|
||||
fork: ForkGraphic;
|
||||
sections: {
|
||||
A: TurnoutSection;
|
||||
B: TurnoutSection;
|
||||
C: TurnoutSection;
|
||||
};
|
||||
label: VectorText;
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super(Turnout.Type);
|
||||
this.graphics = {
|
||||
fork: new Graphics(),
|
||||
sections: new Graphics(),
|
||||
fork: new ForkGraphic(),
|
||||
sections: {
|
||||
A: new TurnoutSection(),
|
||||
B: new TurnoutSection(),
|
||||
C: new TurnoutSection(),
|
||||
},
|
||||
label: new VectorText(),
|
||||
};
|
||||
this.addChild(this.graphics.fork);
|
||||
this.addChild(this.graphics.sections);
|
||||
this.addChild(this.graphics.sections.A);
|
||||
this.addChild(this.graphics.sections.B);
|
||||
this.addChild(this.graphics.sections.C);
|
||||
this.graphics.label.anchor.set(0.5);
|
||||
this.graphics.label.style.fill = '#0f0';
|
||||
this.graphics.label.setVectorFontSize(16);
|
||||
this.graphics.label.position.set(20, 20);
|
||||
this.addChild(this.graphics.label);
|
||||
}
|
||||
|
||||
@ -68,33 +106,14 @@ export class Turnout extends JlGraphic {
|
||||
|
||||
doRepaint(): void {
|
||||
const { pointA, pointB, pointC } = this.datas;
|
||||
const intersectB = Turnout.getIntersectionPoint(20, pointB);
|
||||
const intersectC = Turnout.getIntersectionPoint(20, pointC);
|
||||
|
||||
this.graphics.sections
|
||||
.clear()
|
||||
.lineStyle(TurnoutConsts.lineWidth, TurnoutConsts.lineColor)
|
||||
.moveTo(pointA.x, pointA.y)
|
||||
.lineTo(0, 0)
|
||||
.moveTo(pointB.x, pointB.y)
|
||||
.lineTo(intersectB.x, intersectB.y)
|
||||
.moveTo(pointC.x, pointC.y)
|
||||
.lineTo(intersectC.x, intersectC.y);
|
||||
this.graphics.sections.A.paint(pointA, 0);
|
||||
this.graphics.sections.B.paint(pointB, 20);
|
||||
this.graphics.sections.C.paint(pointC, 20);
|
||||
|
||||
this.graphics.fork
|
||||
.clear()
|
||||
.lineStyle(TurnoutConsts.lineWidth, TurnoutConsts.lineColor)
|
||||
.moveTo(0, 0)
|
||||
.lineTo(intersectB.x, intersectB.y);
|
||||
this.graphics.fork.paint(pointB);
|
||||
|
||||
this.graphics.label.text = this.datas.code;
|
||||
this.graphics.label.position.set(20, 20);
|
||||
}
|
||||
|
||||
static getIntersectionPoint(r: number, p: IPointData): IPointData {
|
||||
const len = Math.sqrt((-p.x) ** 2 + (-p.y) ** 2);
|
||||
const scale = r / len;
|
||||
return { x: scale * p.x, y: scale * p.y };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
import {
|
||||
DraggablePoint,
|
||||
GraphicApp,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
VectorText,
|
||||
linePoint,
|
||||
pointBox,
|
||||
} from 'src/jl-graphic';
|
||||
@ -13,7 +16,15 @@ import {
|
||||
TurnoutConsts,
|
||||
TurnoutTemplate,
|
||||
} from './Turnout';
|
||||
import { DisplayObject, FederatedMouseEvent, IHitArea, Point } from 'pixi.js';
|
||||
import {
|
||||
DisplayObject,
|
||||
FederatedMouseEvent,
|
||||
IHitArea,
|
||||
IPointData,
|
||||
Point,
|
||||
} from 'pixi.js';
|
||||
import { GraphicEditPlugin } from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
import Vector2 from 'src/jl-graphic/math/Vector2';
|
||||
|
||||
export class TurnoutDraw extends GraphicDrawAssistant<
|
||||
TurnoutTemplate,
|
||||
@ -32,7 +43,7 @@ export class TurnoutDraw extends GraphicDrawAssistant<
|
||||
this.turnout = this.graphicTemplate.new();
|
||||
this.container.addChild(this.turnout);
|
||||
|
||||
TurnoutPointsEditPlugin.init(app);
|
||||
TurnoutPointsInteractionPlugin.init(app);
|
||||
}
|
||||
|
||||
onLeftUp(e: FederatedMouseEvent): void {
|
||||
@ -70,45 +81,163 @@ export class TurnoutHitArea implements IHitArea {
|
||||
}
|
||||
contains(x: number, y: number): boolean {
|
||||
const { pointA, pointB, pointC } = this.turnout.datas;
|
||||
const labelRect = this.turnout.graphics.label.getBounds();
|
||||
const labelPosition = this.turnout.canvasToLocalPoint(labelRect);
|
||||
labelRect.x = labelPosition.x;
|
||||
labelRect.y = labelPosition.y;
|
||||
return (
|
||||
linePoint(pointA, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) ||
|
||||
linePoint(pointB, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) ||
|
||||
linePoint(pointC, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) /* ||
|
||||
pointBox({ x, y }, this.turnout.graphics.label.) */
|
||||
linePoint(pointC, { x: 0, y: 0 }, { x, y }, TurnoutConsts.lineWidth) ||
|
||||
pointBox({ x, y }, labelRect)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class TurnoutPointsEditPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
export class TurnoutPointsInteractionPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
static Name = 'TurnoutPointsDrag';
|
||||
static init(app: JlDrawApp) {
|
||||
return new TurnoutPointsEditPlugin(app);
|
||||
return new TurnoutPointsInteractionPlugin(app);
|
||||
}
|
||||
|
||||
constructor(app: GraphicApp) {
|
||||
super(TurnoutPointsEditPlugin.Name, app);
|
||||
super(TurnoutPointsInteractionPlugin.Name, app);
|
||||
}
|
||||
|
||||
bind(g: Turnout): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.hitArea = new TurnoutHitArea(g);
|
||||
console.log(g.hitArea);
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.graphics.label.eventMode = 'static';
|
||||
g.graphics.label.cursor = 'pointer';
|
||||
g.graphics.label.selectable = true;
|
||||
g.graphics.label.draggable = true;
|
||||
g.graphics.label.name = 'label';
|
||||
g.graphics.label.transformSave = true;
|
||||
g.transformSave = true;
|
||||
g.on('selected', this.onSelected, this);
|
||||
g.on('unselected', this.onUnSelected, this);
|
||||
}
|
||||
|
||||
unbind(g: Turnout): void {
|
||||
g.off('selected', this.onSelected, this);
|
||||
g.off('unselected', this.onUnSelected, this);
|
||||
}
|
||||
|
||||
onSelected(g: DisplayObject) {
|
||||
console.log(g);
|
||||
const turnout = g as Turnout;
|
||||
let tep = turnout.getAssistantAppend<TurnoutEditPlugin>(
|
||||
TurnoutEditPlugin.Name
|
||||
);
|
||||
if (!tep) {
|
||||
tep = new TurnoutEditPlugin(turnout);
|
||||
turnout.addAssistantAppend(tep);
|
||||
}
|
||||
tep.reset();
|
||||
tep.showAll();
|
||||
}
|
||||
|
||||
onUnSelected(g: DisplayObject) {
|
||||
const turnout = g as Turnout;
|
||||
const tep = turnout.getAssistantAppend<TurnoutEditPlugin>(
|
||||
TurnoutEditPlugin.Name
|
||||
);
|
||||
if (tep) {
|
||||
tep.hideAll();
|
||||
}
|
||||
}
|
||||
|
||||
filter(...grahpics: JlGraphic[]): Turnout[] | undefined {
|
||||
return grahpics.filter((g) => g.type == Turnout.Type) as Turnout[];
|
||||
}
|
||||
}
|
||||
|
||||
export class TurnoutEditPlugin extends GraphicEditPlugin<Turnout> {
|
||||
static Name = 'TurnoutEdit';
|
||||
editPoints: DraggablePoint[] = [];
|
||||
labels: VectorText[] = [];
|
||||
|
||||
constructor(graphic: Turnout) {
|
||||
super(graphic);
|
||||
this.name = TurnoutEditPlugin.Name;
|
||||
this.initEditPoints();
|
||||
}
|
||||
reset(): void {
|
||||
this.destoryEditPoints();
|
||||
this.removeChildren();
|
||||
this.initEditPoints();
|
||||
}
|
||||
|
||||
initEditPoints() {
|
||||
const cpA = this.graphic.localToCanvasPoint(this.graphic.datas.pointA);
|
||||
const cpB = this.graphic.localToCanvasPoint(this.graphic.datas.pointB);
|
||||
const cpC = this.graphic.localToCanvasPoint(this.graphic.datas.pointC);
|
||||
const cpMap: Map<Point, IPointData> = new Map([
|
||||
[cpA, this.graphic.datas.pointA],
|
||||
[cpB, this.graphic.datas.pointB],
|
||||
[cpC, this.graphic.datas.pointC],
|
||||
]);
|
||||
cpMap.forEach((v, k) => {
|
||||
const dp = new DraggablePoint(k);
|
||||
dp.on('transforming', (e: GraphicTransformEvent) => {
|
||||
if (k === cpA || k === cpB) {
|
||||
const vecA = new Vector2([
|
||||
this.graphic.datas.pointA.x,
|
||||
this.graphic.datas.pointA.y,
|
||||
]);
|
||||
const vecB = new Vector2([
|
||||
this.graphic.datas.pointB.x,
|
||||
this.graphic.datas.pointB.y,
|
||||
]);
|
||||
|
||||
if (k === cpA) {
|
||||
const len = vecB.length();
|
||||
const res = vecA.normalize().scale(-len);
|
||||
this.graphic.datas.pointB.x = res.x;
|
||||
this.graphic.datas.pointB.y = res.y;
|
||||
} else if (k === cpB) {
|
||||
const len = vecA.length();
|
||||
const res = vecB.normalize().scale(-len);
|
||||
this.graphic.datas.pointA.x = res.x;
|
||||
this.graphic.datas.pointA.y = res.y;
|
||||
}
|
||||
}
|
||||
const localPoint = this.graphic.canvasToLocalPoint(dp.position);
|
||||
v.x = localPoint.x;
|
||||
v.y = localPoint.y;
|
||||
|
||||
this.graphic.repaint();
|
||||
});
|
||||
this.editPoints.push(dp);
|
||||
});
|
||||
this.addChild(...this.editPoints);
|
||||
this.labels = ['A', 'B', 'C'].map((str) => {
|
||||
const vc = new VectorText(str);
|
||||
vc.setVectorFontSize(14);
|
||||
vc.anchor.set(0.5);
|
||||
return vc;
|
||||
});
|
||||
this.addChild(...this.labels);
|
||||
}
|
||||
|
||||
destoryEditPoints() {
|
||||
this.editPoints.forEach((dp) => {
|
||||
dp.off('transforming');
|
||||
dp.destroy();
|
||||
this.removeChild(dp);
|
||||
});
|
||||
this.editPoints.splice(0, this.editPoints.length);
|
||||
}
|
||||
|
||||
updateEditedPointsPosition() {
|
||||
const cps = this.graphic.localToCanvasPoints(
|
||||
this.graphic.datas.pointA,
|
||||
this.graphic.datas.pointB,
|
||||
this.graphic.datas.pointC
|
||||
);
|
||||
cps.forEach((cp, i) => {
|
||||
this.editPoints[i].position.copyFrom(cp);
|
||||
this.labels[i].position.copyFrom({ x: cp.x, y: cp.y + 12 });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<q-item clickable v-close-popup @click="saveAllDrawDatas">
|
||||
<q-item-section>保存并校验</q-item-section>
|
||||
</q-item>
|
||||
<!-- <q-item clickable v-close-popup>
|
||||
<!-- <q-item clickable v-close-popup @click="saveAsDialog = true">
|
||||
<q-item-section>另存为</q-item-section>
|
||||
</q-item> -->
|
||||
<q-item clickable v-close-popup>
|
||||
@ -129,6 +129,33 @@
|
||||
<q-page-container>
|
||||
<div id="draw-app-container"></div>
|
||||
</q-page-container>
|
||||
|
||||
<q-dialog
|
||||
v-model="saveAsDialog"
|
||||
persistent
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-card-section>
|
||||
<div class="text-h6">另存为</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<q-input
|
||||
outlined
|
||||
label="草稿名称"
|
||||
v-model.number="saveAsName"
|
||||
:rules="[(val) => val.trim() != '' || '草稿名称不能为空']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="提交" @click="saveAs(saveAsName)" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
@ -139,6 +166,8 @@ import { JlDrawApp } from 'src/jl-graphic';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
|
||||
import { saveAsDraft } from 'src/api/DraftApi';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
@ -250,6 +279,23 @@ function backConfirm() {
|
||||
router.go(-1);
|
||||
}
|
||||
|
||||
const saveAsDialog = ref(false);
|
||||
const saveAsName = ref('');
|
||||
|
||||
async function saveAs(name: string) {
|
||||
try {
|
||||
const record = await saveAsDraft(+route.params.id as number, { name });
|
||||
console.log('🚀 ~ file: DrawLayout.vue:288 ~ saveAs ~ record:', record);
|
||||
// if (record) {
|
||||
// router.replace(`/painting/${record.id}`);
|
||||
// }
|
||||
successNotify('另存为成功');
|
||||
saveAsDialog.value = false;
|
||||
} catch (e) {
|
||||
errorNotify('另存为异常', e);
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
drawStore.destroy();
|
||||
});
|
||||
|
@ -34,12 +34,12 @@
|
||||
label="编辑"
|
||||
:to="`/painting/${props.row.id}`"
|
||||
/>
|
||||
<!-- <q-btn
|
||||
<q-btn
|
||||
color="primary"
|
||||
:disable="operateDisabled"
|
||||
label="发布"
|
||||
@click="prePublish(props.row)"
|
||||
/> -->
|
||||
/>
|
||||
<q-btn
|
||||
color="red"
|
||||
:disable="operateDisabled"
|
||||
@ -58,9 +58,9 @@
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-form ref="myForm" @submit="onCreate" class="q-gutter-md">
|
||||
<q-card-section>
|
||||
<div class="text-h6">新建草稿图</div>
|
||||
<q-form @submit="onCreate" class="q-gutter-md">
|
||||
<q-input
|
||||
outlined
|
||||
label="名称"
|
||||
@ -72,15 +72,16 @@
|
||||
v-model="createType"
|
||||
:options="typeOptions"
|
||||
emit-value
|
||||
label="类型"
|
||||
map-options
|
||||
label="类型 * "
|
||||
/>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="创建" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
@ -95,6 +96,7 @@
|
||||
<div class="text-h6">草稿发布</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-form ref="pubForm" @submit="publishGraphics" class="q-gutter-md">
|
||||
<q-card-section>
|
||||
<q-input
|
||||
outlined
|
||||
@ -102,13 +104,29 @@
|
||||
label="草稿名称"
|
||||
v-model="publishForm.draftName"
|
||||
/>
|
||||
<q-input outlined label="发布名称" v-model="publishForm.pubName" />
|
||||
<q-input
|
||||
outlined
|
||||
label="发布名称 * "
|
||||
v-model="publishForm.pubName"
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入名称!']"
|
||||
/>
|
||||
<q-select
|
||||
v-model="publishForm.lineId"
|
||||
:options="lineOptions"
|
||||
emit-value
|
||||
map-options
|
||||
label="线路 * "
|
||||
lazy-rules
|
||||
:rules="[(val) => val || '请选择线路!']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="发布" @click="publishGraphics" />
|
||||
<q-btn color="primary" label="发布" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
@ -116,13 +134,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn } from 'quasar';
|
||||
import {
|
||||
pageQuery,
|
||||
publishDraft,
|
||||
createDraft,
|
||||
deleteDraft,
|
||||
} from '../api/DraftApi';
|
||||
import { useQuasar, type QTableColumn, QForm } from 'quasar';
|
||||
import { pageQuery, createDraft, deleteDraft } from '../api/DraftApi';
|
||||
import { publishDraft } from '../api/PublishApi';
|
||||
import { getLineList } from '../api/LineInfoApi';
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
@ -137,8 +152,41 @@ const tableHeight = computed(() => {
|
||||
return props.sizeHeight - 32;
|
||||
});
|
||||
|
||||
const typeOptions = [
|
||||
{ label: '线路', value: 'Line' },
|
||||
{ label: '线网', value: 'LineNetwork' },
|
||||
];
|
||||
const createType = ref('Line');
|
||||
|
||||
let lineOptions: Array<{ label: string; value: number }> = [];
|
||||
function getAllLineList() {
|
||||
lineOptions = [];
|
||||
getLineList()
|
||||
.then((res) => {
|
||||
res.forEach((item) => {
|
||||
const obj = {
|
||||
label: item.name,
|
||||
value: item.lineId,
|
||||
};
|
||||
lineOptions.push(obj);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err, '---err--');
|
||||
});
|
||||
}
|
||||
|
||||
const typeOptionsMap = computed(() => {
|
||||
const obj: { [k: string]: string } = {};
|
||||
typeOptions.forEach((item: { value: string; label: string }) => {
|
||||
obj[item.value] = item.label;
|
||||
});
|
||||
return obj;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
getAllLineList();
|
||||
});
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
@ -149,7 +197,15 @@ const columnDefs: QTableColumn[] = [
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{ name: 'creator', label: '创建人', field: 'creator', align: 'center' },
|
||||
// { name: 'creator', label: '创建人', field: 'creator', align: 'center' },
|
||||
{
|
||||
name: 'type',
|
||||
label: '类型',
|
||||
field: (row) => {
|
||||
return typeOptionsMap.value[row.type];
|
||||
},
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'createdAt',
|
||||
label: '创建时间',
|
||||
@ -210,7 +266,10 @@ async function onRequest(props: any) {
|
||||
|
||||
const createFormShow = ref(false);
|
||||
const draftName = ref('');
|
||||
async function onCreate() {
|
||||
const myForm = ref<QForm | null>(null);
|
||||
function onCreate() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
operateDisabled.value = true;
|
||||
try {
|
||||
await createDraft({
|
||||
@ -228,27 +287,32 @@ async function onCreate() {
|
||||
operateDisabled.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
const pubForm = ref<QForm | null>(null);
|
||||
const publishFormShow = ref(false);
|
||||
const publishForm = reactive({
|
||||
id: '',
|
||||
draftName: '',
|
||||
pubName: '',
|
||||
overwrite: true,
|
||||
lineId: '',
|
||||
});
|
||||
function prePublish(row: any) {
|
||||
publishFormShow.value = true;
|
||||
publishForm.id = row.id;
|
||||
publishForm.draftName = row.name;
|
||||
publishForm.pubName = row.name;
|
||||
publishForm.lineId = '';
|
||||
}
|
||||
|
||||
async function publishGraphics() {
|
||||
pubForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
try {
|
||||
await publishDraft({
|
||||
layoutId: publishForm.id,
|
||||
draftingId: +publishForm.id,
|
||||
name: publishForm.pubName,
|
||||
overwrite: publishForm.overwrite,
|
||||
lineId: +publishForm.lineId,
|
||||
});
|
||||
publishFormShow.value = false;
|
||||
$q.notify({
|
||||
@ -262,6 +326,8 @@ async function publishGraphics() {
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteData(row: any) {
|
||||
operateDisabled.value = true;
|
||||
@ -285,9 +351,4 @@ async function deleteData(row: any) {
|
||||
operateDisabled.value = false;
|
||||
});
|
||||
}
|
||||
const typeOptions = [
|
||||
{ label: '线路', value: 'Line' },
|
||||
{ label: '线网', value: 'LineNetwork' },
|
||||
];
|
||||
const createType = ref('Line');
|
||||
</script>
|
||||
|
217
src/pages/LineInfoManage.vue
Normal file
217
src/pages/LineInfoManage.vue
Normal file
@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
title="线路信息"
|
||||
:style="{ height: tableHeight + 'px' }"
|
||||
:rows="rows"
|
||||
:columns="columnDefs"
|
||||
row-key="id"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 20, 50, 100]"
|
||||
:loading="loading"
|
||||
:filter="filter"
|
||||
binary-state-sort
|
||||
@request="onRequest"
|
||||
>
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
dense
|
||||
debounce="1000"
|
||||
v-model="filter.name"
|
||||
label="名称"
|
||||
></q-input>
|
||||
<q-btn flat round color="primary" icon="search" />
|
||||
<q-btn color="primary" label="新建" @click="createFormShow = true" />
|
||||
</template>
|
||||
|
||||
<template v-slot:body-cell-operations="props">
|
||||
<q-td :props="props">
|
||||
<div class="q-gutter-sm row justify-center">
|
||||
<q-btn
|
||||
color="red"
|
||||
:disable="operateDisabled"
|
||||
label="删除"
|
||||
@click="deleteData(props.row)"
|
||||
/>
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<q-dialog
|
||||
v-model="createFormShow"
|
||||
persistent
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-form ref="myForm" @submit="onCreate" class="q-gutter-md">
|
||||
<q-card-section>
|
||||
<div class="text-h6">新建线路信息</div>
|
||||
<q-input
|
||||
outlined
|
||||
label="名称"
|
||||
v-model="LineName"
|
||||
lazy-rules
|
||||
:rules="[(val) => val.length > 0 || '请输入名称!']"
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="线路ID"
|
||||
v-model.number="LineId"
|
||||
type="number"
|
||||
lazy-rules
|
||||
:rules="[(val) => val || '请输入线路ID!']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="创建" type="submit" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn, QForm } from 'quasar';
|
||||
import { pageQuery, createLine, deleteLine } from '../api/LineInfoApi';
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
sizeHeight: number;
|
||||
}>(),
|
||||
{ sizeHeight: 500 }
|
||||
);
|
||||
|
||||
const tableHeight = computed(() => {
|
||||
return props.sizeHeight - 32;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
});
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
{
|
||||
name: 'name',
|
||||
label: '名称',
|
||||
field: 'name',
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{ name: 'lineId', label: '线路ID', field: 'lineId', align: 'center' },
|
||||
{
|
||||
name: 'createdAt',
|
||||
label: '创建时间',
|
||||
field: 'createdAt',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'updateAt',
|
||||
label: '更新时间',
|
||||
field: 'updateAt',
|
||||
align: 'center',
|
||||
},
|
||||
{ name: 'operations', label: '操作', field: 'operations', align: 'center' },
|
||||
];
|
||||
|
||||
const operateDisabled = ref(false);
|
||||
const tableRef = ref();
|
||||
const rows = reactive([]);
|
||||
const filter = reactive({
|
||||
name: '',
|
||||
});
|
||||
const loading = ref(false);
|
||||
const pagination = ref({
|
||||
sortBy: 'desc',
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 10,
|
||||
});
|
||||
|
||||
async function onRequest(props: any) {
|
||||
const { page, rowsPerPage, sortBy, descending } = props.pagination;
|
||||
const filter = props.filter;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
let response = await pageQuery({
|
||||
current: page,
|
||||
size: rowsPerPage,
|
||||
name: filter.name,
|
||||
});
|
||||
const pageData = response;
|
||||
pagination.value.rowsNumber = pageData.total;
|
||||
pagination.value.page = page;
|
||||
pagination.value.rowsPerPage = rowsPerPage;
|
||||
pagination.value.sortBy = sortBy;
|
||||
pagination.value.descending = descending;
|
||||
rows.splice(0, rows.length, ...(pageData.records as []));
|
||||
} catch (error: any) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.message,
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const createFormShow = ref(false);
|
||||
const LineName = ref('');
|
||||
const LineId = ref(1);
|
||||
const myForm = ref<QForm | null>(null);
|
||||
function onCreate() {
|
||||
myForm.value?.validate().then(async (res) => {
|
||||
if (res) {
|
||||
operateDisabled.value = true;
|
||||
try {
|
||||
await createLine({
|
||||
name: LineName.value,
|
||||
lineId: LineId.value,
|
||||
});
|
||||
createFormShow.value = false;
|
||||
tableRef.value.requestServerInteraction(); // 刷新列表
|
||||
} catch (error: any) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.message,
|
||||
});
|
||||
} finally {
|
||||
operateDisabled.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteData(row: any) {
|
||||
operateDisabled.value = true;
|
||||
$q.dialog({
|
||||
title: '确认',
|
||||
message: `确认删除线路 "${row.name}" 吗?`,
|
||||
cancel: true,
|
||||
})
|
||||
.onOk(async () => {
|
||||
try {
|
||||
await deleteLine(row.id);
|
||||
tableRef.value.requestServerInteraction(); // 刷新列表
|
||||
} catch (error: any) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.message,
|
||||
});
|
||||
}
|
||||
})
|
||||
.onDismiss(() => {
|
||||
operateDisabled.value = false;
|
||||
});
|
||||
}
|
||||
</script>
|
159
src/pages/PublishManage.vue
Normal file
159
src/pages/PublishManage.vue
Normal file
@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="q-pa-md">
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
title="发布图"
|
||||
:style="{ height: tableHeight + 'px' }"
|
||||
:rows="rows"
|
||||
:columns="columnDefs"
|
||||
row-key="id"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 20, 50, 100]"
|
||||
:loading="loading"
|
||||
:filter="filter"
|
||||
binary-state-sort
|
||||
@request="onRequest"
|
||||
>
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
dense
|
||||
debounce="1000"
|
||||
v-model="filter.name"
|
||||
label="名称"
|
||||
></q-input>
|
||||
<q-btn flat round color="primary" icon="search" />
|
||||
</template>
|
||||
|
||||
<template v-slot:body-cell-operations="props">
|
||||
<q-td :props="props">
|
||||
<div class="q-gutter-sm row justify-center">
|
||||
<q-btn
|
||||
color="red"
|
||||
:disable="operateDisabled"
|
||||
label="删除"
|
||||
@click="deleteData(props.row)"
|
||||
/>
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn, QForm } from 'quasar';
|
||||
import { pageQuery, deletePublish } from '../api/PublishApi';
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
sizeHeight: number;
|
||||
}>(),
|
||||
{ sizeHeight: 500 }
|
||||
);
|
||||
|
||||
const tableHeight = computed(() => {
|
||||
return props.sizeHeight - 32;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
});
|
||||
|
||||
const columnDefs: QTableColumn[] = [
|
||||
{
|
||||
name: 'name',
|
||||
label: '名称',
|
||||
field: 'name',
|
||||
required: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
label: '类型',
|
||||
field: 'type',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'lineId',
|
||||
label: '线路Id',
|
||||
field: 'lineId',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
name: 'publishAt',
|
||||
label: '发布时间',
|
||||
field: 'publishAt',
|
||||
align: 'center',
|
||||
},
|
||||
{ name: 'operations', label: '操作', field: 'operations', align: 'center' },
|
||||
];
|
||||
|
||||
const operateDisabled = ref(false);
|
||||
const tableRef = ref();
|
||||
const rows = reactive([]);
|
||||
const filter = reactive({
|
||||
name: '',
|
||||
});
|
||||
const loading = ref(false);
|
||||
const pagination = ref({
|
||||
sortBy: 'desc',
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 10,
|
||||
});
|
||||
|
||||
async function onRequest(props: any) {
|
||||
const { page, rowsPerPage, sortBy, descending } = props.pagination;
|
||||
const filter = props.filter;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
let response = await pageQuery({
|
||||
current: page,
|
||||
size: rowsPerPage,
|
||||
name: filter.name,
|
||||
});
|
||||
const pageData = response;
|
||||
pagination.value.rowsNumber = pageData.total;
|
||||
pagination.value.page = page;
|
||||
pagination.value.rowsPerPage = rowsPerPage;
|
||||
pagination.value.sortBy = sortBy;
|
||||
pagination.value.descending = descending;
|
||||
rows.splice(0, rows.length, ...(pageData.records as []));
|
||||
} catch (error: any) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.message,
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteData(row: any) {
|
||||
operateDisabled.value = true;
|
||||
$q.dialog({
|
||||
title: '确认',
|
||||
message: `确认删除草稿图 "${row.name}" 吗?`,
|
||||
cancel: true,
|
||||
})
|
||||
.onOk(async () => {
|
||||
try {
|
||||
await deletePublish(row.id);
|
||||
tableRef.value.requestServerInteraction(); // 刷新列表
|
||||
} catch (error: any) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: error.message,
|
||||
});
|
||||
}
|
||||
})
|
||||
.onDismiss(() => {
|
||||
operateDisabled.value = false;
|
||||
});
|
||||
}
|
||||
</script>
|
4239
src/protos/device_status.ts
Normal file
4239
src/protos/device_status.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -1451,8 +1451,6 @@ export namespace graphicData {
|
||||
constructor(data?: any[] | {
|
||||
common?: CommonInfo;
|
||||
code?: string;
|
||||
hasCircle?: boolean;
|
||||
circlePoint?: Point;
|
||||
}) {
|
||||
super();
|
||||
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
|
||||
@ -1463,12 +1461,6 @@ export namespace graphicData {
|
||||
if ("code" in data && data.code != undefined) {
|
||||
this.code = data.code;
|
||||
}
|
||||
if ("hasCircle" in data && data.hasCircle != undefined) {
|
||||
this.hasCircle = data.hasCircle;
|
||||
}
|
||||
if ("circlePoint" in data && data.circlePoint != undefined) {
|
||||
this.circlePoint = data.circlePoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
get common() {
|
||||
@ -1486,26 +1478,9 @@ export namespace graphicData {
|
||||
set code(value: string) {
|
||||
pb_1.Message.setField(this, 2, value);
|
||||
}
|
||||
get hasCircle() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 3, false) as boolean;
|
||||
}
|
||||
set hasCircle(value: boolean) {
|
||||
pb_1.Message.setField(this, 3, value);
|
||||
}
|
||||
get circlePoint() {
|
||||
return pb_1.Message.getWrapperField(this, Point, 4) as Point;
|
||||
}
|
||||
set circlePoint(value: Point) {
|
||||
pb_1.Message.setWrapperField(this, 4, value);
|
||||
}
|
||||
get has_circlePoint() {
|
||||
return pb_1.Message.getField(this, 4) != null;
|
||||
}
|
||||
static fromObject(data: {
|
||||
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
hasCircle?: boolean;
|
||||
circlePoint?: ReturnType<typeof Point.prototype.toObject>;
|
||||
}): Station {
|
||||
const message = new Station({});
|
||||
if (data.common != null) {
|
||||
@ -1514,20 +1489,12 @@ export namespace graphicData {
|
||||
if (data.code != null) {
|
||||
message.code = data.code;
|
||||
}
|
||||
if (data.hasCircle != null) {
|
||||
message.hasCircle = data.hasCircle;
|
||||
}
|
||||
if (data.circlePoint != null) {
|
||||
message.circlePoint = Point.fromObject(data.circlePoint);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
toObject() {
|
||||
const data: {
|
||||
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
hasCircle?: boolean;
|
||||
circlePoint?: ReturnType<typeof Point.prototype.toObject>;
|
||||
} = {};
|
||||
if (this.common != null) {
|
||||
data.common = this.common.toObject();
|
||||
@ -1535,12 +1502,6 @@ export namespace graphicData {
|
||||
if (this.code != null) {
|
||||
data.code = this.code;
|
||||
}
|
||||
if (this.hasCircle != null) {
|
||||
data.hasCircle = this.hasCircle;
|
||||
}
|
||||
if (this.circlePoint != null) {
|
||||
data.circlePoint = this.circlePoint.toObject();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
serialize(): Uint8Array;
|
||||
@ -1551,10 +1512,6 @@ export namespace graphicData {
|
||||
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
|
||||
if (this.code.length)
|
||||
writer.writeString(2, this.code);
|
||||
if (this.hasCircle != false)
|
||||
writer.writeBool(3, this.hasCircle);
|
||||
if (this.has_circlePoint)
|
||||
writer.writeMessage(4, this.circlePoint, () => this.circlePoint.serialize(writer));
|
||||
if (!w)
|
||||
return writer.getResultBuffer();
|
||||
}
|
||||
@ -1570,12 +1527,6 @@ export namespace graphicData {
|
||||
case 2:
|
||||
message.code = reader.readString();
|
||||
break;
|
||||
case 3:
|
||||
message.hasCircle = reader.readBool();
|
||||
break;
|
||||
case 4:
|
||||
reader.readMessage(message.circlePoint, () => message.circlePoint = Point.deserialize(reader));
|
||||
break;
|
||||
default: reader.skipField();
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,16 @@ const routes: RouteRecordRaw[] = [
|
||||
name: 'draft',
|
||||
component: () => import('pages/DraftManage.vue'),
|
||||
},
|
||||
{
|
||||
path: 'publish',
|
||||
name: 'publish',
|
||||
component: () => import('pages/PublishManage.vue'),
|
||||
},
|
||||
{
|
||||
path: 'lineInfo',
|
||||
name: 'lineInfo',
|
||||
component: () => import('pages/LineInfoManage.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 89c9f023cff957ecb414d09252b306ef20b9e908
|
||||
Subproject commit a33338038ddd00db9cdd28d0aad57d4b1b6428df
|
Loading…
Reference in New Issue
Block a user