chore: 新增一批接口
This commit is contained in:
parent
a835e266b5
commit
2fa8ed74e5
21
apps/designer/src/io/api.ts
Normal file
21
apps/designer/src/io/api.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getApiList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/api');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createApi = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/api', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateApi = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/api/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteApi = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/api/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
21
apps/designer/src/io/application.ts
Normal file
21
apps/designer/src/io/application.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getApplicationList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/application');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createApplication = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/application', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateApplication = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/application/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteApplication = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/application/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
21
apps/designer/src/io/block.ts
Normal file
21
apps/designer/src/io/block.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getBlockList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/blocks');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createBlock = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/blocks', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateBlock = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/blocks/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteBlock = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/blocks/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
21
apps/designer/src/io/file.ts
Normal file
21
apps/designer/src/io/file.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getFileList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/file');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createFile = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/file', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateFile = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/file/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteFile = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/file/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
21
apps/designer/src/io/history.ts
Normal file
21
apps/designer/src/io/history.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getMaterialsList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/histories');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createMaterials = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/histories', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateMaterials = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/histories/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteMaterials = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/histories/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
6
apps/designer/src/io/index.ts
Normal file
6
apps/designer/src/io/index.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export * from './api';
|
||||||
|
export * from './block';
|
||||||
|
export * from './file';
|
||||||
|
export * from './materials';
|
||||||
|
export * from './project';
|
||||||
|
export * from './application';
|
30
apps/designer/src/io/instance.ts
Normal file
30
apps/designer/src/io/instance.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const baseApiUrl = 'https://custom-chart-pre-api.shiyue.com/';
|
||||||
|
|
||||||
|
// 创建独立实例
|
||||||
|
const instance = axios.create({
|
||||||
|
baseURL: baseApiUrl // 基础URL直接放在实例配置中
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求拦截器改为使用实例
|
||||||
|
instance.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// 可在此处添加统一请求头等配置
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
instance.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// 导出实例
|
||||||
|
export default instance;
|
23
apps/designer/src/io/materials.ts
Normal file
23
apps/designer/src/io/materials.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getMaterialsList = async (data?: Record<string, any>) => {
|
||||||
|
const response = await instance.get('/api/v1/materials', {
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createMaterials = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/materials', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateMaterials = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/materials/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteMaterials = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/materials/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
28
apps/designer/src/io/project.ts
Normal file
28
apps/designer/src/io/project.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getProjectList = async (data?: Record<string, any>) => {
|
||||||
|
const response = await instance.get('/api/v1/projects', {
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getProject = async (id: string) => {
|
||||||
|
const response = await instance.get(`/api/v1/projects/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createProject = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/projects', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateProject = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/projects/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteProject = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/projects/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
@ -12,8 +12,7 @@ import {
|
|||||||
} from '@vtj/core';
|
} from '@vtj/core';
|
||||||
import { Storage, mapToObject } from '@vtj/utils';
|
import { Storage, mapToObject } from '@vtj/utils';
|
||||||
import { BaseService } from '@vtj/renderer';
|
import { BaseService } from '@vtj/renderer';
|
||||||
import { debounce } from 'licia-es';
|
import { getProject } from '@/io';
|
||||||
|
|
||||||
const storage = new Storage({
|
const storage = new Storage({
|
||||||
type: 'local',
|
type: 'local',
|
||||||
expired: 0
|
expired: 0
|
||||||
@ -21,14 +20,20 @@ const storage = new Storage({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export class StorageService extends BaseService {
|
export class StorageService extends BaseService {
|
||||||
public init(project: ProjectSchema): Promise<ProjectSchema> {
|
public async init(project: ProjectSchema): Promise<ProjectSchema> {
|
||||||
console.log('init-project', project);
|
// console.log('init-project', project);
|
||||||
const model = new ProjectModel(project);
|
// const model = new ProjectModel(project);
|
||||||
// console.log('init-project-model', model);
|
// // console.log('init-project-model', model);
|
||||||
const match = storage.get(`project_${model.id}`);
|
// const match = storage.get(`project_${model.id}`);
|
||||||
console.log('init-project-match', match);
|
// console.log('init-project-match', match);
|
||||||
const dsl = Object.assign(model.toDsl(), match || {});
|
// const dsl = Object.assign(model.toDsl(), match || {});
|
||||||
console.log('init-project-dsl', dsl);
|
// console.log('init-project-dsl', dsl);
|
||||||
|
// storage.save(`project_${model.id}`, dsl);
|
||||||
|
|
||||||
|
const remoteProject = await getProject(3);
|
||||||
|
const model = new ProjectModel(remoteProject);
|
||||||
|
const dsl = model.toDsl();
|
||||||
|
console.log('dsl', dsl);
|
||||||
storage.save(`project_${model.id}`, dsl);
|
storage.save(`project_${model.id}`, dsl);
|
||||||
return Promise.resolve(dsl);
|
return Promise.resolve(dsl);
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,4 @@ ENV = 'development'
|
|||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
# base api url
|
# base api url
|
||||||
VITE_BASE_API_URL = 'http://8.134.216.72:8080/'
|
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
@ -1,8 +1,7 @@
|
|||||||
# 只在生产模式中被载入
|
# 只在生产模式中被载入
|
||||||
ENV = 'production'
|
ENV = 'production'
|
||||||
|
|
||||||
# base api url
|
|
||||||
VITE_BASE_API_URL = 'http://127.0.0.1:8080/'
|
|
||||||
|
|
||||||
# 公共基础路径, 详见: https://cn.vitejs.dev/guide/build.html#public-base-path
|
# 公共基础路径, 详见: https://cn.vitejs.dev/guide/build.html#public-base-path
|
||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
|
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
"@iconify/vue": "^4.3.0",
|
"@iconify/vue": "^4.3.0",
|
||||||
"@iframe-resizer/parent": "^5.3.3",
|
"@iframe-resizer/parent": "^5.3.3",
|
||||||
"@sy/low-code-renderer-adapter": "workspace:*",
|
"@sy/low-code-renderer-adapter": "workspace:*",
|
||||||
|
"@tanstack/query-core": "^5.66.4",
|
||||||
|
"@tanstack/vue-query": "^5.66.9",
|
||||||
"@vueuse/core": "~11.1.0",
|
"@vueuse/core": "~11.1.0",
|
||||||
"ant-design-vue": "~4.2.6",
|
"ant-design-vue": "~4.2.6",
|
||||||
"axios": "~1.7.9",
|
"axios": "~1.7.9",
|
||||||
|
@ -1,6 +1,22 @@
|
|||||||
import instance from './instance';
|
import instance from './instance';
|
||||||
|
|
||||||
export const getApplicationList = async () => {
|
export const getApplicationList = async () => {
|
||||||
const response = await instance.get('/application/list');
|
const response = await instance.get('/api/v1/applications');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createApplication = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/applications', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateApplication = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/applications/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteApplication = async (id: string) => {
|
||||||
|
console.log(id);
|
||||||
|
const response = await instance.delete(`/api/v1/applications/${id}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
@ -1 +1,3 @@
|
|||||||
export * from './application';
|
export * from './application';
|
||||||
|
export * from './project';
|
||||||
|
export * from './user';
|
||||||
|
21
apps/platform/src/io/project.ts
Normal file
21
apps/platform/src/io/project.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const getProjectList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/projects');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createProject = async (data: any) => {
|
||||||
|
const response = await instance.post('/api/v1/projects', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateProject = async (id: string, data: any) => {
|
||||||
|
const response = await instance.put(`/api/v1/projects/${id}`, data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteProject = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/projects/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
11
apps/platform/src/io/user.ts
Normal file
11
apps/platform/src/io/user.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const login = async (data: { username: string; password: string }) => {
|
||||||
|
const response = await instance.post('/login', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const logout = async () => {
|
||||||
|
const response = await instance.post('/logout');
|
||||||
|
return response.data;
|
||||||
|
};
|
@ -4,6 +4,8 @@ import dayjs from 'dayjs';
|
|||||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||||
import utc from 'dayjs/plugin/utc';
|
import utc from 'dayjs/plugin/utc';
|
||||||
import timezone from 'dayjs/plugin/timezone';
|
import timezone from 'dayjs/plugin/timezone';
|
||||||
|
import { VueQueryPlugin } from '@tanstack/vue-query';
|
||||||
|
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import { setupRouter } from './router';
|
import { setupRouter } from './router';
|
||||||
import { setupIcons } from './components/basic/icon';
|
import { setupIcons } from './components/basic/icon';
|
||||||
@ -17,6 +19,7 @@ dayjs.extend(timezone);
|
|||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
app.use(VueQueryPlugin);
|
||||||
function setupPlugins() {
|
function setupPlugins() {
|
||||||
// 安装图标
|
// 安装图标
|
||||||
setupIcons();
|
setupIcons();
|
||||||
|
@ -29,6 +29,16 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
component: () => import('@/components/renderer-adapter/index.vue'),
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'add',
|
||||||
|
name: `${moduleName}-add`,
|
||||||
|
meta: {
|
||||||
|
title: '添加应用',
|
||||||
|
keepAlive: true,
|
||||||
|
icon: 'ant-design:list',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/application/add.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -2,5 +2,6 @@ import dashboard from './dashboard';
|
|||||||
import user from './user';
|
import user from './user';
|
||||||
import micro from './micro';
|
import micro from './micro';
|
||||||
import application from './application';
|
import application from './application';
|
||||||
|
import project from './project';
|
||||||
|
|
||||||
export default [...dashboard, ...user, ...micro, ...application];
|
export default [...dashboard, ...user, ...micro, ...application, ...project];
|
||||||
|
29
apps/platform/src/router/routes/modules/project.ts
Normal file
29
apps/platform/src/router/routes/modules/project.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
|
// 微前端路由
|
||||||
|
const moduleName = 'project';
|
||||||
|
|
||||||
|
const routes: Array<RouteRecordRaw> = [
|
||||||
|
{
|
||||||
|
path: '/project',
|
||||||
|
name: moduleName,
|
||||||
|
meta: {
|
||||||
|
title: '项目管理',
|
||||||
|
icon: 'ant-design:appstore-outlined',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'add',
|
||||||
|
name: `${moduleName}-add`,
|
||||||
|
meta: {
|
||||||
|
title: '添加项目',
|
||||||
|
keepAlive: true,
|
||||||
|
icon: 'ant-design:list',
|
||||||
|
},
|
||||||
|
component: () => import('@/views/project/add.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
@ -3,7 +3,8 @@ import { defineStore } from 'pinia';
|
|||||||
import { useSSEStore } from './sse';
|
import { useSSEStore } from './sse';
|
||||||
import { store } from '@/store';
|
import { store } from '@/store';
|
||||||
import { resetRouter } from '@/router';
|
import { resetRouter } from '@/router';
|
||||||
import { userLogin, userLogout } from '@/io';
|
import { login, logout } from '@/io';
|
||||||
|
|
||||||
export const useUserStore = defineStore(
|
export const useUserStore = defineStore(
|
||||||
'user',
|
'user',
|
||||||
() => {
|
() => {
|
||||||
@ -28,7 +29,7 @@ export const useUserStore = defineStore(
|
|||||||
};
|
};
|
||||||
/** 登录 */
|
/** 登录 */
|
||||||
const login = async (params: any) => {
|
const login = async (params: any) => {
|
||||||
const data = await userLogin(params);
|
const data = await login(params);
|
||||||
console.log('data', data);
|
console.log('data', data);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
setToken(data.msg);
|
setToken(data.msg);
|
||||||
@ -36,7 +37,7 @@ export const useUserStore = defineStore(
|
|||||||
/** 登出 */
|
/** 登出 */
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
sseStore.closeEventSource();
|
sseStore.closeEventSource();
|
||||||
await userLogout();
|
await logout();
|
||||||
clearLoginStatus();
|
clearLoginStatus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
51
apps/platform/src/views/application/add.vue
Normal file
51
apps/platform/src/views/application/add.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useQuery, useMutation } from '@tanstack/vue-query';
|
||||||
|
import { getApplicationList, createApplication, deleteApplication } from '@/io';
|
||||||
|
|
||||||
|
const addData = {
|
||||||
|
name: 'test',
|
||||||
|
active: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: appList,
|
||||||
|
isError,
|
||||||
|
isLoading,
|
||||||
|
refetch,
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: ['applicationList'],
|
||||||
|
queryFn: getApplicationList,
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { mutate: createApp, isLoading: isCreating } = useMutation({
|
||||||
|
mutationFn: createApplication,
|
||||||
|
onSuccess: () => {
|
||||||
|
refetch();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
mutate: deleteApp,
|
||||||
|
isLoading: isDeleting,
|
||||||
|
error: deleteError,
|
||||||
|
} = useMutation({
|
||||||
|
mutationFn: deleteApplication,
|
||||||
|
onSuccess: () => {
|
||||||
|
refetch();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 10px">
|
||||||
|
<div v-if="isLoading">加载中...</div>
|
||||||
|
<div v-else-if="isError">加载失败</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ appList }}
|
||||||
|
</div>
|
||||||
|
<Button type="primary" :loading="isCreating" @click="createApp(addData)"> 添加应用 </Button>
|
||||||
|
<Button type="primary" @click="refetch">重新获取</Button>
|
||||||
|
<Button type="primary" :loading="isDeleting" @click="deleteApp('3')"> 删除应用 </Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
0
apps/platform/src/views/application/list.vue
Normal file
0
apps/platform/src/views/application/list.vue
Normal file
53
apps/platform/src/views/project/add.vue
Normal file
53
apps/platform/src/views/project/add.vue
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useQuery, useMutation } from '@tanstack/vue-query';
|
||||||
|
import { getProjectList, createProject, deleteProject } from '@/io';
|
||||||
|
|
||||||
|
const addData = {
|
||||||
|
application_id: 3,
|
||||||
|
description: 'test project',
|
||||||
|
name: 'test project',
|
||||||
|
platform: 'web',
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: projectList,
|
||||||
|
isError,
|
||||||
|
isLoading,
|
||||||
|
refetch,
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: ['getProjectList'],
|
||||||
|
queryFn: getProjectList,
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { mutate: createProjectMutation, isLoading: isCreating } = useMutation({
|
||||||
|
mutationFn: createProject,
|
||||||
|
onSuccess: () => {
|
||||||
|
refetch();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { mutate: deleteProjectMutation, isLoading: isDeleting } = useMutation({
|
||||||
|
mutationFn: deleteProject,
|
||||||
|
onSuccess: () => {
|
||||||
|
refetch();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 10px">
|
||||||
|
<div v-if="isLoading">加载中...</div>
|
||||||
|
<div v-else-if="isError">加载失败</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ projectList }}
|
||||||
|
</div>
|
||||||
|
<Button type="primary" :loading="isCreating" @click="createProjectMutation(addData)">
|
||||||
|
添加项目
|
||||||
|
</Button>
|
||||||
|
<Button type="primary" @click="refetch">重新获取</Button>
|
||||||
|
<Button type="primary" :loading="isDeleting" @click="deleteProjectMutation('3')">
|
||||||
|
删除项目
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -45,6 +45,13 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||||||
server: {
|
server: {
|
||||||
open: true,
|
open: true,
|
||||||
host: true,
|
host: true,
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'https://custom-chart-pre-api.shiyue.com',
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
|
68
pnpm-lock.yaml
generated
68
pnpm-lock.yaml
generated
@ -128,6 +128,9 @@ importers:
|
|||||||
'@vtj/web':
|
'@vtj/web':
|
||||||
specifier: ^0.10.5
|
specifier: ^0.10.5
|
||||||
version: 0.10.5(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
version: 0.10.5(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
||||||
|
axios:
|
||||||
|
specifier: ^1.8.1
|
||||||
|
version: 1.8.1
|
||||||
element-plus:
|
element-plus:
|
||||||
specifier: ^2.9.4
|
specifier: ^2.9.4
|
||||||
version: 2.9.5(vue@3.5.13(typescript@5.7.3))
|
version: 2.9.5(vue@3.5.13(typescript@5.7.3))
|
||||||
@ -168,6 +171,12 @@ importers:
|
|||||||
'@sy/low-code-renderer-adapter':
|
'@sy/low-code-renderer-adapter':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/render-adapter
|
version: link:../../packages/render-adapter
|
||||||
|
'@tanstack/query-core':
|
||||||
|
specifier: ^5.66.4
|
||||||
|
version: 5.66.4
|
||||||
|
'@tanstack/vue-query':
|
||||||
|
specifier: ^5.66.9
|
||||||
|
version: 5.66.9(vue@3.5.13(typescript@5.6.3))
|
||||||
'@vueuse/core':
|
'@vueuse/core':
|
||||||
specifier: ~11.1.0
|
specifier: ~11.1.0
|
||||||
version: 11.1.0(vue@3.5.13(typescript@5.6.3))
|
version: 11.1.0(vue@3.5.13(typescript@5.6.3))
|
||||||
@ -3126,6 +3135,22 @@ packages:
|
|||||||
'@sy/y-code-chart@1.2.7':
|
'@sy/y-code-chart@1.2.7':
|
||||||
resolution: {integrity: sha512-87/au4OoafTQSqwAAJhB8XpzwTlpu1u42VqYPG28JDarUOva/12eEyAU5i+e7e3t1pV+JSqP+Q/4HIhQw61q9w==}
|
resolution: {integrity: sha512-87/au4OoafTQSqwAAJhB8XpzwTlpu1u42VqYPG28JDarUOva/12eEyAU5i+e7e3t1pV+JSqP+Q/4HIhQw61q9w==}
|
||||||
|
|
||||||
|
'@tanstack/match-sorter-utils@8.19.4':
|
||||||
|
resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
'@tanstack/query-core@5.66.4':
|
||||||
|
resolution: {integrity: sha512-skM/gzNX4shPkqmdTCSoHtJAPMTtmIJNS0hE+xwTTUVYwezArCT34NMermABmBVUg5Ls5aiUXEDXfqwR1oVkcA==}
|
||||||
|
|
||||||
|
'@tanstack/vue-query@5.66.9':
|
||||||
|
resolution: {integrity: sha512-8FiyjOM/1PRn4tyGXacwmvi29sZZqoWjH/AdxqwYDDd2WL/mUkLwYDq4zK1ixY4Is71B8RbOqRweWiYOPOC3kg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue/composition-api': ^1.1.2
|
||||||
|
vue: ^2.6.0 || ^3.3.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@vue/composition-api':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@trysound/sax@0.2.0':
|
'@trysound/sax@0.2.0':
|
||||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
@ -4040,6 +4065,9 @@ packages:
|
|||||||
axios@1.7.9:
|
axios@1.7.9:
|
||||||
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
|
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
|
||||||
|
|
||||||
|
axios@1.8.1:
|
||||||
|
resolution: {integrity: sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==}
|
||||||
|
|
||||||
babel-plugin-polyfill-corejs2@0.4.12:
|
babel-plugin-polyfill-corejs2@0.4.12:
|
||||||
resolution: {integrity: sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==}
|
resolution: {integrity: sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -8379,6 +8407,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==}
|
resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
remove-accents@0.5.0:
|
||||||
|
resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==}
|
||||||
|
|
||||||
remove@0.1.5:
|
remove@0.1.5:
|
||||||
resolution: {integrity: sha512-AJMA9oWvJzdTjwIGwSQZsjGQiRx73YTmiOWmfCp1fpLa/D4n7jKcpoA+CZiVLJqKcEKUuh1Suq80c5wF+L/qVQ==}
|
resolution: {integrity: sha512-AJMA9oWvJzdTjwIGwSQZsjGQiRx73YTmiOWmfCp1fpLa/D4n7jKcpoA+CZiVLJqKcEKUuh1Suq80c5wF+L/qVQ==}
|
||||||
|
|
||||||
@ -13209,6 +13240,20 @@ snapshots:
|
|||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
|
'@tanstack/match-sorter-utils@8.19.4':
|
||||||
|
dependencies:
|
||||||
|
remove-accents: 0.5.0
|
||||||
|
|
||||||
|
'@tanstack/query-core@5.66.4': {}
|
||||||
|
|
||||||
|
'@tanstack/vue-query@5.66.9(vue@3.5.13(typescript@5.6.3))':
|
||||||
|
dependencies:
|
||||||
|
'@tanstack/match-sorter-utils': 8.19.4
|
||||||
|
'@tanstack/query-core': 5.66.4
|
||||||
|
'@vue/devtools-api': 6.6.4
|
||||||
|
vue: 3.5.13(typescript@5.6.3)
|
||||||
|
vue-demi: 0.14.10(vue@3.5.13(typescript@5.6.3))
|
||||||
|
|
||||||
'@trysound/sax@0.2.0': {}
|
'@trysound/sax@0.2.0': {}
|
||||||
|
|
||||||
'@tsconfig/node20@20.1.4': {}
|
'@tsconfig/node20@20.1.4': {}
|
||||||
@ -13762,11 +13807,6 @@ snapshots:
|
|||||||
vite: 6.1.1(@types/node@22.7.9)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
vite: 6.1.1(@types/node@22.7.9)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
||||||
vue: 3.5.13(typescript@5.6.3)
|
vue: 3.5.13(typescript@5.6.3)
|
||||||
|
|
||||||
'@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))':
|
|
||||||
dependencies:
|
|
||||||
vite: 6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
|
||||||
vue: 3.5.13(typescript@5.7.3)
|
|
||||||
|
|
||||||
'@vitejs/plugin-vue@5.2.1(vite@6.2.0(@types/node@20.17.19)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.3.3))':
|
'@vitejs/plugin-vue@5.2.1(vite@6.2.0(@types/node@20.17.19)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.3.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vite: 6.2.0(@types/node@20.17.19)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
vite: 6.2.0(@types/node@20.17.19)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
||||||
@ -13876,7 +13916,7 @@ snapshots:
|
|||||||
'@types/serve-static': 1.15.7
|
'@types/serve-static': 1.15.7
|
||||||
'@vitejs/plugin-basic-ssl': 1.2.0(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
'@vitejs/plugin-basic-ssl': 1.2.0(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
||||||
'@vitejs/plugin-legacy': 6.0.2(terser@5.37.0)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
'@vitejs/plugin-legacy': 6.0.2(terser@5.37.0)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
||||||
'@vitejs/plugin-vue': 5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
'@vitejs/plugin-vue': 5.2.1(vite@6.2.0(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
||||||
'@vitejs/plugin-vue-jsx': 4.1.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
'@vitejs/plugin-vue-jsx': 4.1.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
||||||
'@vitest/coverage-v8': 3.0.7(vitest@3.0.7(@types/node@22.12.0)(jiti@2.4.2)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.3(@types/node@22.12.0)(typescript@5.7.3))(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
'@vitest/coverage-v8': 3.0.7(vitest@3.0.7(@types/node@22.12.0)(jiti@2.4.2)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.3(@types/node@22.12.0)(typescript@5.7.3))(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
||||||
'@vtj/node': 0.10.1
|
'@vtj/node': 0.10.1
|
||||||
@ -13898,7 +13938,7 @@ snapshots:
|
|||||||
vite-plugin-dts: 4.5.0(@types/node@22.12.0)(rollup@3.29.5)(typescript@5.7.3)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
vite-plugin-dts: 4.5.0(@types/node@22.12.0)(rollup@3.29.5)(typescript@5.7.3)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
||||||
vite-plugin-node-polyfills: 0.23.0(rollup@3.29.5)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
vite-plugin-node-polyfills: 0.23.0(rollup@3.29.5)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))
|
||||||
vite-plugin-vue-devtools: 7.7.2(rollup@3.29.5)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
vite-plugin-vue-devtools: 7.7.2(rollup@3.29.5)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
||||||
vite-plugin-vue-style-bundler: 1.0.9(@types/less@3.0.8)(@vitejs/plugin-vue@5.2.1(vite@6.2.0(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3)))(less@4.2.2)(sass@1.83.4)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
vite-plugin-vue-style-bundler: 1.0.9(@types/less@3.0.8)(@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3)))(less@4.2.2)(sass@1.83.4)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
||||||
vitest: 3.0.7(@types/node@22.12.0)(jiti@2.4.2)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.3(@types/node@22.12.0)(typescript@5.7.3))(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
vitest: 3.0.7(@types/node@22.12.0)(jiti@2.4.2)(jsdom@26.0.0)(less@4.2.2)(msw@2.7.3(@types/node@22.12.0)(typescript@5.7.3))(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1)
|
||||||
vue-tsc: 2.2.4(typescript@5.7.3)
|
vue-tsc: 2.2.4(typescript@5.7.3)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -14630,6 +14670,14 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
|
|
||||||
|
axios@1.8.1:
|
||||||
|
dependencies:
|
||||||
|
follow-redirects: 1.15.9(debug@4.4.0)
|
||||||
|
form-data: 4.0.2
|
||||||
|
proxy-from-env: 1.1.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- debug
|
||||||
|
|
||||||
babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.26.9):
|
babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.26.9):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/compat-data': 7.26.8
|
'@babel/compat-data': 7.26.8
|
||||||
@ -19529,6 +19577,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
jsesc: 3.0.2
|
jsesc: 3.0.2
|
||||||
|
|
||||||
|
remove-accents@0.5.0: {}
|
||||||
|
|
||||||
remove@0.1.5:
|
remove@0.1.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
seq: 0.3.5
|
seq: 0.3.5
|
||||||
@ -21190,10 +21240,10 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
vite-plugin-vue-style-bundler@1.0.9(@types/less@3.0.8)(@vitejs/plugin-vue@5.2.1(vite@6.2.0(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3)))(less@4.2.2)(sass@1.83.4)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3)):
|
vite-plugin-vue-style-bundler@1.0.9(@types/less@3.0.8)(@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3)))(less@4.2.2)(sass@1.83.4)(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/less': 3.0.8
|
'@types/less': 3.0.8
|
||||||
'@vitejs/plugin-vue': 5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
'@vitejs/plugin-vue': 5.2.1(vite@6.2.0(@types/node@22.12.0)(jiti@2.4.2)(less@4.2.2)(sass@1.83.4)(terser@5.37.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.3))
|
||||||
less: 4.2.2
|
less: 4.2.2
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
remove: 0.1.5
|
remove: 0.1.5
|
||||||
|
Loading…
x
Reference in New Issue
Block a user