[tag] 实现基本功能demo
This commit is contained in:
parent
76e92b461d
commit
fd0d380ae9
|
|
@ -1,7 +1,7 @@
|
|||
# backend service base url, prod environment
|
||||
VITE_SERVICE_BASE_URL=http://localhost:8080
|
||||
VITE_SERVICE_BASE_URL=http://154.219.110.17:8080
|
||||
|
||||
# other backend service base url, prod environment
|
||||
VITE_OTHER_SERVICE_BASE_URL= `{
|
||||
"demo": "http://localhost:9529"
|
||||
}`
|
||||
# VITE_OTHER_SERVICE_BASE_URL= `{
|
||||
# "demo": "http://localhost:9529"
|
||||
# }`
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||
title: 'function',
|
||||
i18nKey: 'route.function',
|
||||
icon: 'icon-park-outline:all-application',
|
||||
order: 6
|
||||
order: 6,
|
||||
hideInMenu: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,46 +7,22 @@ export {}
|
|||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
|
||||
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
ACard: typeof import('ant-design-vue/es')['Card']
|
||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
ADescriptions: typeof import('ant-design-vue/es')['Descriptions']
|
||||
ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
||||
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
||||
AEmpty: typeof import('ant-design-vue/es')['Empty']
|
||||
AForm: typeof import('ant-design-vue/es')['Form']
|
||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||
AInput: typeof import('ant-design-vue/es')['Input']
|
||||
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
||||
AList: typeof import('ant-design-vue/es')['List']
|
||||
AListItem: typeof import('ant-design-vue/es')['ListItem']
|
||||
AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
|
||||
AMenu: typeof import('ant-design-vue/es')['Menu']
|
||||
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
|
||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||
APopover: typeof import('ant-design-vue/es')['Popover']
|
||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||
AppProvider: typeof import('./../components/common/app-provider.vue')['default']
|
||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASegmented: typeof import('ant-design-vue/es')['Segmented']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
AStatistic: typeof import('ant-design-vue/es')['Statistic']
|
||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||
ATable: typeof import('ant-design-vue/es')['Table']
|
||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
ATree: typeof import('ant-design-vue/es')['Tree']
|
||||
AWatermark: typeof import('ant-design-vue/es')['Watermark']
|
||||
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
|
||||
|
|
@ -55,21 +31,6 @@ declare module 'vue' {
|
|||
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
|
||||
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
|
||||
FullScreen: typeof import('./../components/common/full-screen.vue')['default']
|
||||
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
|
||||
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
|
||||
IconCarbonAdd: typeof import('~icons/carbon/add')['default']
|
||||
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
||||
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
|
||||
'IconIc:roundPlus': typeof import('~icons/ic/round-plus')['default']
|
||||
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
||||
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
||||
IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
|
||||
IconIcRoundRemove: typeof import('~icons/ic/round-remove')['default']
|
||||
IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
|
||||
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
||||
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
||||
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
||||
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
||||
MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
|
||||
|
|
|
|||
|
|
@ -3,17 +3,39 @@ import axios from 'axios';
|
|||
import { localStg } from '@/utils/storage';
|
||||
|
||||
// 封装网络请求的接口
|
||||
export const apiRequest = async (path: string, data: any) => {
|
||||
let url = "http://localhost:8080" + path;
|
||||
const token = localStg.get('token'); // 获取 token
|
||||
try {
|
||||
const response = await axios.post(url, data, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`, // 添加 Authorization 头
|
||||
},
|
||||
});
|
||||
return response.data; // 返回响应数据
|
||||
} catch (error) {
|
||||
throw new Error('请求失败'); // 抛出错误
|
||||
}
|
||||
};
|
||||
export const apiRequest = async (method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, data?: any) => {
|
||||
let url = "http://localhost:8080" + path;
|
||||
const token = localStg.get('token'); // 获取 token
|
||||
try {
|
||||
const response = await axios({
|
||||
method,
|
||||
url,
|
||||
data,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`, // 添加 Authorization 头
|
||||
},
|
||||
});
|
||||
return response.data; // 返回响应数据
|
||||
} catch (error) {
|
||||
throw new Error('请求失败'); // 抛出错误
|
||||
}
|
||||
};
|
||||
|
||||
export const apiRequestGet = async (path: string) => {
|
||||
let url = "http://localhost:8080" + path;
|
||||
const token = localStg.get('token'); // 获取 token
|
||||
try {
|
||||
return axios.get(
|
||||
url,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`, // 添加 Authorization 头
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error('请求失败'); // 抛出错误
|
||||
}
|
||||
};
|
||||
|
||||
export default apiRequest;
|
||||
|
|
@ -35,7 +35,7 @@ const services = ref([
|
|||
id: 1,
|
||||
name: '图像识别模型',
|
||||
status: 'Running',
|
||||
responseTime: 120,
|
||||
responseTime: Math.floor(Math.random() * 500),
|
||||
health: 'Healthy',
|
||||
lastUpdated: new Date().toLocaleTimeString(),
|
||||
},
|
||||
|
|
@ -43,7 +43,7 @@ const services = ref([
|
|||
id: 2,
|
||||
name: '大语言模型',
|
||||
status: 'Running',
|
||||
responseTime: 0,
|
||||
responseTime: Math.floor(Math.random() * 500),
|
||||
health: 'Healthy',
|
||||
lastUpdated: new Date().toLocaleTimeString(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@
|
|||
import { ref, onMounted } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import axios from 'axios';
|
||||
|
||||
import { apiRequestGet } from '@/utils/api'
|
||||
import { localStg } from '@/utils/storage';
|
||||
// 部门树数据
|
||||
const treeData = ref([]);
|
||||
// 弹窗相关
|
||||
|
|
@ -96,7 +97,8 @@ const selectedKeys = ref([]);
|
|||
// 获取部门数据
|
||||
const fetchDepartments = async () => {
|
||||
try {
|
||||
const response = await axios.get('http://localhost:8080/api/departments');
|
||||
const response = await apiRequestGet('/api/department/allDepartment');
|
||||
|
||||
if (response.data.success) {
|
||||
// 过滤重复数据并构建树结构
|
||||
const deptMap = new Map();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,151 @@
|
|||
<script setup lang="ts"></script>
|
||||
|
||||
<!-- fac.vue -->
|
||||
<template>
|
||||
<div>facility</div>
|
||||
<div class="facility-management">
|
||||
<a-card title="设施管理" :bordered="false">
|
||||
<!-- 搜索和操作区域 -->
|
||||
<div class="search-bar" style="margin-bottom: 16px;">
|
||||
<a-form
|
||||
:model="searchForm"
|
||||
layout="inline"
|
||||
class="search-form"
|
||||
>
|
||||
<a-form-item label="设施编号">
|
||||
<a-input v-model:value="searchForm.code" placeholder="请输入设施编号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="设施类型">
|
||||
<a-select
|
||||
v-model:value="searchForm.type"
|
||||
placeholder="请选择类型"
|
||||
style="width: 200px"
|
||||
>
|
||||
<a-select-option value="PIPELINE">管道</a-select-option>
|
||||
<!-- 可以根据需求添加更多类型 -->
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="fetchData">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="resetForm">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 表格展示 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="dataSource"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
row-key="id"
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="getStatusColor(record.status)">
|
||||
{{ statusText(record.status) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import axios from 'axios';
|
||||
import {apiRequestGet} from '@/utils/api'
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: '设施编号', dataIndex: 'code', key: 'code' },
|
||||
{ title: '设施类型', dataIndex: 'type', key: 'type' },
|
||||
{ title: '区域', dataIndex: 'area', key: 'area' },
|
||||
{ title: '状态', dataIndex: 'status', key: 'status', slots: { customRender: 'status' } },
|
||||
{ title: '安装日期', dataIndex: 'installDate', key: 'installDate' },
|
||||
{ title: '上次维护日期', dataIndex: 'lastMaintainDate', key: 'lastMaintainDate' },
|
||||
];
|
||||
|
||||
// 数据源和加载状态
|
||||
const dataSource = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
code: '',
|
||||
type: '',
|
||||
});
|
||||
|
||||
// 获取状态对应的颜色和文本
|
||||
const getStatusColor = (status) => {
|
||||
return status === 'NORMAL' ? 'green' : 'red';
|
||||
};
|
||||
|
||||
const statusText = (status) => {
|
||||
return status === 'NORMAL' ? '正常' : '异常';
|
||||
};
|
||||
|
||||
// 获取设施数据
|
||||
const fetchData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
page: pagination.current,
|
||||
size: pagination.pageSize,
|
||||
code: searchForm.code || undefined,
|
||||
type: searchForm.type || undefined,
|
||||
};
|
||||
const response = await apiRequestGet('/api/facilities/list', { params });
|
||||
if (response.data.success) {
|
||||
dataSource.value = response.data.data;
|
||||
pagination.total = response.data.total || response.data.data.length;
|
||||
} else {
|
||||
message.error(response.data.errorMsg || '数据获取失败');
|
||||
dataSource.value = [];
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('请求失败: ' + error.message);
|
||||
dataSource.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
searchForm.code = '';
|
||||
searchForm.type = '';
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 表格分页、排序、筛选变化时的回调
|
||||
const handleTableChange = (pag) => {
|
||||
pagination.current = pag.current;
|
||||
pagination.pageSize = pag.pageSize;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 页面加载时获取数据
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.facility-management {
|
||||
padding: 20px;
|
||||
}
|
||||
.search-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.search-form {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -22,9 +22,9 @@ import CreativityBanner from './modules/creativity-banner.vue';
|
|||
</ARow>
|
||||
-->
|
||||
<ARow :gutter="[16, 16]">
|
||||
<ACol :span="24" :lg="14">
|
||||
<!-- <ACol :span="24" :lg="14">
|
||||
<ProjectNews />
|
||||
</ACol>
|
||||
</ACol> -->
|
||||
<!--
|
||||
<ACol :span="24" :lg="10">
|
||||
<CreativityBanner />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,182 @@
|
|||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div>plan</div>
|
||||
<div class="plan-container">
|
||||
<h2>计划管理</h2>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="planData"
|
||||
:pagination="false"
|
||||
:loading="loading"
|
||||
:row-key="record => record.planId"
|
||||
>
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="getStatusColor(record.status)">
|
||||
{{ statusMap[record.status] || record.status }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #createdAt="{ record }">
|
||||
{{ formatDate(record.createdAt) }}
|
||||
</template>
|
||||
</a-table>
|
||||
<div class="pagination-wrapper">
|
||||
<a-pagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:pageSize="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:show-size-changer="true"
|
||||
:page-size-options="['10', '20', '50', '100']"
|
||||
@change="handlePageChange"
|
||||
@showSizeChange="handlePageSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<script>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import axios from 'axios';
|
||||
import dayjs from 'dayjs';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
import { apiRequestGet } from '@/utils/api';
|
||||
|
||||
export default {
|
||||
name: 'PlanManagement',
|
||||
setup() {
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{
|
||||
title: '计划ID',
|
||||
dataIndex: 'planId',
|
||||
key: 'planId',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '区域',
|
||||
dataIndex: 'area',
|
||||
key: 'area',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
slots: { customRender: 'status' },
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
key: 'createdAt',
|
||||
slots: { customRender: 'createdAt' },
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
|
||||
// 计划数据和加载状态
|
||||
const planData = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 状态映射和颜色
|
||||
const statusMap = {
|
||||
COMPLETED: '已完成',
|
||||
CANCELLED: '已取消',
|
||||
SCHEDULED: '已计划',
|
||||
};
|
||||
|
||||
const getStatusColor = (status) => {
|
||||
switch (status) {
|
||||
case 'COMPLETED':
|
||||
return 'green';
|
||||
case 'CANCELLED':
|
||||
return 'red';
|
||||
case 'SCHEDULED':
|
||||
return 'blue';
|
||||
default:
|
||||
return 'default';
|
||||
}
|
||||
};
|
||||
|
||||
// 日期格式化
|
||||
const formatDate = (date) => {
|
||||
return date ? dayjs(date).format('YYYY-MM-DD HH:mm:ss') : '-';
|
||||
};
|
||||
|
||||
// 获取计划数据
|
||||
const fetchPlanData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
// 模拟分页参数传递给后端
|
||||
const response = await apiRequestGet("/api/inspection-plans/employee/my-plan")
|
||||
|
||||
if (response.data.success) {
|
||||
planData.value = response.data.data;
|
||||
// 假设后端返回总记录数,这里模拟数据,实际应从响应中获取
|
||||
pagination.value.total = 50; // 实际项目中改为 response.data.total 或类似字段
|
||||
} else {
|
||||
console.error('获取计划数据失败:', response.data.errorMsg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 页码变化处理
|
||||
const handlePageChange = (page) => {
|
||||
pagination.value.current = page;
|
||||
fetchPlanData();
|
||||
};
|
||||
|
||||
// 每页数量变化处理
|
||||
const handlePageSizeChange = (current, size) => {
|
||||
pagination.value.pageSize = size;
|
||||
pagination.value.current = 1; // 改变每页数量时重置到第一页
|
||||
fetchPlanData();
|
||||
};
|
||||
|
||||
// 组件挂载时加载数据
|
||||
onMounted(() => {
|
||||
fetchPlanData();
|
||||
});
|
||||
|
||||
return {
|
||||
columns,
|
||||
planData,
|
||||
loading,
|
||||
pagination,
|
||||
statusMap,
|
||||
getStatusColor,
|
||||
formatDate,
|
||||
handlePageChange,
|
||||
handlePageSizeChange,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.plan-container {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 20px;
|
||||
font-size: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
margin-top: 16px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<LookForward />
|
||||
<!-- <LookForward /> -->
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue