合并
85
src/api/contract/index.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import { AxiosPromise } from 'axios';
|
||||||
|
|
||||||
|
//获取版本
|
||||||
|
export const obtainAllVersionNumbers = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/billofquantitiesLimitList/obtainAllVersionNumbers',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//获取sheet
|
||||||
|
export const sheetList = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/billofquantitiesLimitList/sheetList',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//获取一览表
|
||||||
|
export const listBillofquantitiesLimitList = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/billofquantitiesLimitList/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//获取一览数据树
|
||||||
|
export const treeList = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/billofquantitiesLimitList/getTree',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//修改单价
|
||||||
|
export const updatePrice = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/billofquantitiesLimitList',
|
||||||
|
method: 'put',
|
||||||
|
data: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//查询分标策划
|
||||||
|
export const getPlanningList = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/segmentedIndicatorPlanning/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//新增分标策划
|
||||||
|
export const segmentedIndicatorPlanning = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/segmentedIndicatorPlanning',
|
||||||
|
method: 'post',
|
||||||
|
data: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//编辑分标策划
|
||||||
|
export const updatePlanning = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/segmentedIndicatorPlanning',
|
||||||
|
method: 'put',
|
||||||
|
data: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//编辑分标策划
|
||||||
|
export const delPlanning = (query: any): AxiosPromise<any> => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/segmentedIndicatorPlanning/' + query.ids,
|
||||||
|
method: 'delete'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const importExcelFile = (params: any, data: any): AxiosPromise => {
|
||||||
|
return request({
|
||||||
|
url: '/tender/billofquantitiesLimitList/importExcelFile',
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
};
|
27252
src/assets/china.json
Normal file
7522
src/assets/cq.json
Normal file
BIN
src/assets/fonts/alimamashuheiti.ttf
Normal file
BIN
src/assets/fonts/庞门正道标题体2.0增强版.ttf
Normal file
BIN
src/assets/large/Inversion.png
Normal file
After Width: | Height: | Size: 361 B |
BIN
src/assets/large/bg.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
src/assets/large/center1.png
Normal file
After Width: | Height: | Size: 399 B |
BIN
src/assets/large/center2.png
Normal file
After Width: | Height: | Size: 597 B |
BIN
src/assets/large/center3.png
Normal file
After Width: | Height: | Size: 541 B |
BIN
src/assets/large/center4.png
Normal file
After Width: | Height: | Size: 457 B |
BIN
src/assets/large/center5.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/large/income.png
Normal file
After Width: | Height: | Size: 568 B |
BIN
src/assets/large/monitor.png
Normal file
After Width: | Height: | Size: 793 B |
BIN
src/assets/large/power.png
Normal file
After Width: | Height: | Size: 671 B |
BIN
src/assets/large/right1.png
Normal file
After Width: | Height: | Size: 464 B |
BIN
src/assets/large/right2.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
src/assets/large/right3.png
Normal file
After Width: | Height: | Size: 492 B |
BIN
src/assets/large/right4.png
Normal file
After Width: | Height: | Size: 368 B |
BIN
src/assets/large/right5.png
Normal file
After Width: | Height: | Size: 487 B |
BIN
src/assets/large/right6.png
Normal file
After Width: | Height: | Size: 758 B |
BIN
src/assets/large/right7.png
Normal file
After Width: | Height: | Size: 478 B |
BIN
src/assets/large/right8.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
src/assets/large/right9.png
Normal file
After Width: | Height: | Size: 534 B |
BIN
src/assets/large/secure.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
src/assets/large/setting.png
Normal file
After Width: | Height: | Size: 760 B |
BIN
src/assets/large/weather.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
@ -8,6 +8,15 @@
|
|||||||
@import 'animate.css';
|
@import 'animate.css';
|
||||||
@import 'element-plus/dist/index.css';
|
@import 'element-plus/dist/index.css';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'AlimamaShuHeiTi';
|
||||||
|
src: url('@/assets/fonts/庞门正道标题体2.0增强版.ttf') format('truetype');
|
||||||
|
// font-weight: normal;
|
||||||
|
// font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -212,4 +221,4 @@ aside {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -99,6 +99,11 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||||||
component: () => import('@/views/gisHome/index.vue'),
|
component: () => import('@/views/gisHome/index.vue'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/largeScreen',
|
||||||
|
component: () => import('@/views/largeScreen/index.vue'),
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/indexEquipment',
|
path: '/indexEquipment',
|
||||||
component: () => import('@/views/materials/orderEquipment/indexEquipment.vue'),
|
component: () => import('@/views/materials/orderEquipment/indexEquipment.vue'),
|
||||||
|
441
src/views/contract/division/index.vue
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-2">
|
||||||
|
<el-tabs type="border-card" @tab-change="handleTabChange" v-model="activeTab">
|
||||||
|
<el-tab-pane v-for="(item, index) in tabList" :key="item.index" :label="item.label" :name="item.value">
|
||||||
|
<el-card shadow="always">
|
||||||
|
<el-form :model="queryForm" :inline="true" ref="queryFormRef">
|
||||||
|
<el-form-item label="名称" prop="versions">
|
||||||
|
<el-input v-model="queryForm.name" placeholder="请输入名称" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="内容" prop="sheet">
|
||||||
|
<el-input v-model="queryForm.content" placeholder="请输入内容" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
<el-button type="primary" plain :icon="Plus" @click="openDialog" v-hasPermi="['tender:segmentedIndicatorPlanning:add']">新增</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-table :data="tableData" row-key="id" border v-loading="loading">
|
||||||
|
<el-table-column prop="id" label="编号" />
|
||||||
|
<el-table-column prop="name" label="名称" />
|
||||||
|
<el-table-column prop="content" label="内容" />
|
||||||
|
<el-table-column prop="plannedBiddingTime" label="计划招标时间" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-date-picker v-model="scope.row.plannedBiddingTime" type="date" value-format="YYYY-MM-DD" placeholder="选择时间" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="price" label="操作" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" size="small" @click="handleSave(scope.row)" v-hasPermi="['tender:segmentedIndicatorPlanning:edit']"
|
||||||
|
>修改</el-button
|
||||||
|
>
|
||||||
|
<el-button type="danger" size="small" @click="delHandle(scope.row)" v-hasPermi="['tender:segmentedIndicatorPlanning:remove']"
|
||||||
|
>删除</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<el-dialog title="新增" v-model="dialogVisible" width="75%" draggable>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="11">
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
|
||||||
|
<el-form-item label="名称" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="内容" prop="content">
|
||||||
|
<el-input v-model="form.content" placeholder="请输入内容" type="textarea" clearable :rows="4" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row style="margin-top: 20px">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<el-form :model="treeForm" :inline="true">
|
||||||
|
<el-form-item label="表名" prop="sheet">
|
||||||
|
<el-select v-model="treeForm.sheet" placeholder="选择表名" @change="changeSheet">
|
||||||
|
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-table
|
||||||
|
:data="treeData"
|
||||||
|
ref="treeTableRef"
|
||||||
|
v-loading="treeLoading"
|
||||||
|
row-key="id"
|
||||||
|
border
|
||||||
|
lazy
|
||||||
|
default-expand-all
|
||||||
|
@selection-change="handleSelection"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column prop="num" label="编号" />
|
||||||
|
<el-table-column prop="name" label="工程或费用名称" />
|
||||||
|
<el-table-column prop="unit" label="单位" />
|
||||||
|
<el-table-column prop="quantity" label="数量" />
|
||||||
|
<el-table-column prop="selectNum" label="选择数量" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input-number
|
||||||
|
:model-value="scope.row.selectNum"
|
||||||
|
@change="
|
||||||
|
(val) => {
|
||||||
|
scope.row.selectNum = val;
|
||||||
|
handleNumberChange(scope.row);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:precision="2"
|
||||||
|
:step="1"
|
||||||
|
:controls="false"
|
||||||
|
:max="Math.floor(scope.row.quantity)"
|
||||||
|
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="unitPrice" label="单价" align="center" />
|
||||||
|
<el-table-column prop="price" label="总价" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.price }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm(formRef)">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
|
import { getDicts } from '@/api/system/dict/data';
|
||||||
|
import { Plus } from '@element-plus/icons-vue';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { treeList, sheetList, segmentedIndicatorPlanning, getPlanningList, updatePlanning, delPlanning } from '@/api/contract/index';
|
||||||
|
|
||||||
|
const userStore = useUserStoreHook();
|
||||||
|
const currentProject = computed(() => userStore.selectedProject);
|
||||||
|
const tabList = ref<any[]>([]);
|
||||||
|
const tableData = ref<any[]>([]);
|
||||||
|
const queryFormRef = ref();
|
||||||
|
const formRef = ref();
|
||||||
|
const activeTab = ref();
|
||||||
|
const queryParams = ref({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
});
|
||||||
|
const total = ref(0);
|
||||||
|
const queryForm = ref({
|
||||||
|
name: '',
|
||||||
|
content: ''
|
||||||
|
});
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const form = ref({
|
||||||
|
name: '',
|
||||||
|
content: ''
|
||||||
|
});
|
||||||
|
const rules = ref({
|
||||||
|
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
||||||
|
content: [{ required: true, message: '请输入内容', trigger: 'blur' }]
|
||||||
|
});
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
//字典获取数据
|
||||||
|
const getTabsList = async () => {
|
||||||
|
const res = await getDicts('subcontracting_type');
|
||||||
|
if (res.code == 200) {
|
||||||
|
activeTab.value = res.data[0].dictValue;
|
||||||
|
tabList.value = res.data.map((item: any) => {
|
||||||
|
return {
|
||||||
|
label: item.dictLabel,
|
||||||
|
value: item.dictValue
|
||||||
|
};
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//获取表格数据
|
||||||
|
const getList = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id,
|
||||||
|
...queryParams.value,
|
||||||
|
...queryForm.value,
|
||||||
|
dictName: activeTab.value
|
||||||
|
};
|
||||||
|
const res = await getPlanningList(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
tableData.value = res.rows;
|
||||||
|
total.value = res.total;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '获取数据失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleTabChange = (tabs: any) => {
|
||||||
|
activeTab.value = tabs;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.value.pageNum = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryForm.value.content = '';
|
||||||
|
queryForm.value.name = '';
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
const openDialog = () => {
|
||||||
|
dialogVisible.value = true;
|
||||||
|
getSheetName();
|
||||||
|
};
|
||||||
|
const closeDialog = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
form.value = {
|
||||||
|
name: '',
|
||||||
|
content: ''
|
||||||
|
};
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
};
|
||||||
|
const treeData = ref<any[]>([]);
|
||||||
|
const treeForm = ref({
|
||||||
|
sheet: ''
|
||||||
|
});
|
||||||
|
const sheets = ref<any[]>([]);
|
||||||
|
const treeTableRef = ref();
|
||||||
|
const isExpandAll = ref(false);
|
||||||
|
const treeLoading = ref(false);
|
||||||
|
const selectionData = ref<any>([]);
|
||||||
|
//获取表名
|
||||||
|
const getSheetName = async () => {
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id
|
||||||
|
// versions: queryForm.value.versions
|
||||||
|
};
|
||||||
|
const res = await sheetList(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
sheets.value = res.data;
|
||||||
|
if (res.data.length > 0) {
|
||||||
|
treeForm.value.sheet = res.data[0];
|
||||||
|
} else {
|
||||||
|
treeForm.value.sheet = '';
|
||||||
|
ElMessage({
|
||||||
|
message: '获取表名失败',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getTreeList();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '获取表名失败',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleSelection = (selection: any) => {
|
||||||
|
selectionData.value = selection;
|
||||||
|
};
|
||||||
|
const handleNumberChange = (row: any) => {
|
||||||
|
const selectedIds = selectionData.value.map((item) => item.id);
|
||||||
|
restoreSelections(treeData.value, selectedIds);
|
||||||
|
};
|
||||||
|
const restoreSelections = (data, selectedIds) => {
|
||||||
|
const traverse = (nodes) => {
|
||||||
|
nodes.forEach((node) => {
|
||||||
|
if (selectedIds.includes(node.id)) {
|
||||||
|
nextTick(() => {
|
||||||
|
treeTableRef.value.toggleRowSelection(node, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
traverse(node.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
traverse(data);
|
||||||
|
};
|
||||||
|
watch(
|
||||||
|
() => selectionData.value,
|
||||||
|
(newVal, oldVal) => {
|
||||||
|
console.log(newVal, 55555555555555555);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//选择表名
|
||||||
|
const changeSheet = () => {
|
||||||
|
getTreeList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleExpandAll = (isExpand: boolean) => {
|
||||||
|
treeData.value.forEach((row) => {
|
||||||
|
treeTableRef.value.toggleRowExpansion(row, isExpand);
|
||||||
|
});
|
||||||
|
isExpandAll.value = isExpand;
|
||||||
|
};
|
||||||
|
//打开获取表数据
|
||||||
|
const getTreeList = async () => {
|
||||||
|
try {
|
||||||
|
treeLoading.value = true;
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id,
|
||||||
|
sheet: treeForm.value.sheet
|
||||||
|
};
|
||||||
|
const res = await treeList(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
res.data.forEach((item: any) => {
|
||||||
|
item.selectNum = '';
|
||||||
|
});
|
||||||
|
treeData.value = res.data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '获取表格失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
treeLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
await formEl.validate(async (valid, fields) => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
if (selectionData.value.length == 0) {
|
||||||
|
ElMessage({
|
||||||
|
message: '请选择项目材料',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectionData.value.some((item) => item.selectNum == '' || item.selectNum == null)) {
|
||||||
|
ElMessage.error('存在未填写数量的工程或费用名称,请检查');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const limitListBos = selectionData.value.map((item: any) => {
|
||||||
|
return {
|
||||||
|
limitListId: item.id,
|
||||||
|
num: item.selectNum
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id,
|
||||||
|
...form.value,
|
||||||
|
dictName: activeTab.value,
|
||||||
|
limitListBos
|
||||||
|
};
|
||||||
|
const res = await segmentedIndicatorPlanning(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '新增成功',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
closeDialog();
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '新增失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('error submit!', fields);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//确定修改
|
||||||
|
const handleSave = (row: any) => {
|
||||||
|
try {
|
||||||
|
if (!row.plannedBiddingTime) {
|
||||||
|
ElMessage({
|
||||||
|
message: '请输入计划招标时间',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updatePlanning(row).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '修改成功',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '修改失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//删除
|
||||||
|
const delHandle = (row: any) => {
|
||||||
|
try {
|
||||||
|
const params = { ids: row.id };
|
||||||
|
delPlanning(params).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '删除成功',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '删除失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTabsList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.Region {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
276
src/views/contract/limitPrice/index.vue
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-2">
|
||||||
|
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||||
|
<el-card shadow="always">
|
||||||
|
<el-form :model="queryForm" :inline="true">
|
||||||
|
<!-- <el-form-item label="版本号" prop="versions">
|
||||||
|
<el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions">
|
||||||
|
<el-option v-for="item in options" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="表名" prop="sheet">
|
||||||
|
<el-select v-model="queryForm.sheet" placeholder="选择表名" @change="changeSheet">
|
||||||
|
<el-option v-for="item in sheets" :key="item" :label="item" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
class="upload-demo"
|
||||||
|
:http-request="importExcel"
|
||||||
|
:show-file-list="false"
|
||||||
|
v-hasPermi="['tender:billofquantitiesLimitList:importExcelFile']"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<el-button type="primary">导入excel</el-button>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleExport()" v-hasPermi="['tender:billofquantitiesLimitList:export']">导出excel</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</transition>
|
||||||
|
<el-card shadow="never" class="mb8">
|
||||||
|
<el-table ref="tableRef" v-loading="loading" :data="tableData" row-key="id" border lazy default-expand-all>
|
||||||
|
<el-table-column prop="num" label="编号" />
|
||||||
|
<el-table-column prop="name" label="工程或费用名称" />
|
||||||
|
<el-table-column prop="unit" label="单位" />
|
||||||
|
<el-table-column prop="quantity" label="数量" />
|
||||||
|
<el-table-column prop="remark" label="单价" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input-number
|
||||||
|
:model-value="scope.row.unitPrice"
|
||||||
|
@change="(val) => (scope.row.unitPrice = val)"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.1"
|
||||||
|
:controls="false"
|
||||||
|
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="price" label="总价" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.price }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="price" label="操作" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
@click="handleSave(scope.row)"
|
||||||
|
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||||
|
v-hasPermi="['tender:billofquantitiesLimitList:edit']"
|
||||||
|
>修改</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
|
import { listBillofquantitiesLimitList, obtainAllVersionNumbers, sheetList, updatePrice, importExcelFile } from '@/api/contract/index';
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
const userStore = useUserStoreHook();
|
||||||
|
const currentProject = computed(() => userStore.selectedProject);
|
||||||
|
const queryForm = ref({
|
||||||
|
versions: '',
|
||||||
|
sheet: ''
|
||||||
|
});
|
||||||
|
const loading = ref(false);
|
||||||
|
const options = ref<any[]>([]);
|
||||||
|
const sheets = ref<any[]>([]);
|
||||||
|
const tableData = ref<any[]>([]);
|
||||||
|
const isExpandAll = ref(false);
|
||||||
|
|
||||||
|
//获取版本号
|
||||||
|
const getVersionNums = async () => {
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id,
|
||||||
|
pageSize: 1000,
|
||||||
|
pageNum: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await obtainAllVersionNumbers(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
options.value = res.data;
|
||||||
|
if (res.data.length > 0) {
|
||||||
|
queryForm.value.versions = res.data[0];
|
||||||
|
getSheetName();
|
||||||
|
} else {
|
||||||
|
queryForm.value.versions = '';
|
||||||
|
ElMessage({
|
||||||
|
message: '获取版本号失败',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '获取版本号失败',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//选择版本号
|
||||||
|
const changeVersions = () => {
|
||||||
|
getSheetName();
|
||||||
|
};
|
||||||
|
|
||||||
|
//选择表名
|
||||||
|
const changeSheet = () => {
|
||||||
|
getTableData();
|
||||||
|
};
|
||||||
|
|
||||||
|
//获取表名
|
||||||
|
const getSheetName = async () => {
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id
|
||||||
|
// versions: queryForm.value.versions
|
||||||
|
};
|
||||||
|
const res = await sheetList(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
sheets.value = res.data;
|
||||||
|
if (res.data.length > 0) {
|
||||||
|
queryForm.value.sheet = res.data[0];
|
||||||
|
} else {
|
||||||
|
queryForm.value.sheet = '';
|
||||||
|
ElMessage({
|
||||||
|
message: '获取表名失败',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getTableData();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '获取表名失败',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//获取表格
|
||||||
|
const getTableData = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const params = {
|
||||||
|
projectId: currentProject.value?.id,
|
||||||
|
versions: queryForm.value.versions,
|
||||||
|
sheet: queryForm.value.sheet
|
||||||
|
};
|
||||||
|
const res = await listBillofquantitiesLimitList(params);
|
||||||
|
if (res.code == 200) {
|
||||||
|
tableData.value = [res.data[0]];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage({
|
||||||
|
message: '获取表格失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
tableData.value = [];
|
||||||
|
loading.value = false;
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//修改单价
|
||||||
|
const handleSave = (row: any) => {
|
||||||
|
try {
|
||||||
|
if (!row.unitPrice) {
|
||||||
|
ElMessage({
|
||||||
|
message: '请输入单价',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
updatePrice(row).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '修改成功',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
getTableData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage({
|
||||||
|
message: '修改失败',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const tableRef = ref<any>();
|
||||||
|
|
||||||
|
const toggleExpandAll = (isExpand: boolean) => {
|
||||||
|
tableData.value.forEach((row) => {
|
||||||
|
tableRef.value.toggleRowExpansion(row, isExpand);
|
||||||
|
});
|
||||||
|
isExpandAll.value = isExpand;
|
||||||
|
};
|
||||||
|
//导入
|
||||||
|
const importExcel = (options: any): any => {
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('file', options.file);
|
||||||
|
loading.value = true;
|
||||||
|
importExcelFile({ projectId: currentProject.value?.id }, formData)
|
||||||
|
.then((res) => {
|
||||||
|
const { code } = res;
|
||||||
|
if (code == 200) {
|
||||||
|
proxy.$modal.msgSuccess(res.msg || '导入成功');
|
||||||
|
getTableData();
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgError(res.msg || '导入失败');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
proxy.$modal.msgError(err.msg || '导入失败');
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//监听项目id刷新数据
|
||||||
|
const listeningProject = watch(
|
||||||
|
() => currentProject.value?.id,
|
||||||
|
(nid, oid) => {
|
||||||
|
getVersionNums();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const handleExport = () => {
|
||||||
|
proxy?.download(
|
||||||
|
'/tender/billofquantitiesLimitList/export',
|
||||||
|
{
|
||||||
|
projectId: currentProject.value?.id,
|
||||||
|
sheet: queryForm.value.sheet
|
||||||
|
},
|
||||||
|
`限价一览表${queryForm.value.sheet}.xlsx`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
onUnmounted(() => {
|
||||||
|
listeningProject();
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// getVersionNums();
|
||||||
|
getSheetName();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
176
src/views/largeScreen/components/centerPage.vue
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
<template>
|
||||||
|
<div class="centerPage">
|
||||||
|
<div class="centerPage_map">
|
||||||
|
<div ref="mapRef" class="map-container" style="width: 100%; height: 100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// import { getPowerStationOverview } from '@/api/large';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import china from '@/assets/china.json';
|
||||||
|
const data = ref<any>({});
|
||||||
|
|
||||||
|
// 地图容器引用
|
||||||
|
const mapRef = ref<HTMLDivElement | null>(null);
|
||||||
|
// ECharts实例
|
||||||
|
let myChart: any = null;
|
||||||
|
|
||||||
|
// 响应窗口大小变化
|
||||||
|
const handleResize = () => {
|
||||||
|
if (myChart) {
|
||||||
|
myChart.resize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化地图
|
||||||
|
const initEcharts = () => {
|
||||||
|
if (!mapRef.value) {
|
||||||
|
console.error('未找到地图容器元素');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册地图
|
||||||
|
echarts.registerMap('china', china as any);
|
||||||
|
|
||||||
|
// 地图数据
|
||||||
|
const mapData: any = [{ name: '田东县', value: 1, itemStyle: { color: '#fff' } }];
|
||||||
|
|
||||||
|
// 散点数据
|
||||||
|
// 散点数据 - 使用图片标记并调整名称位置
|
||||||
|
const scatterData: any[] = [
|
||||||
|
{
|
||||||
|
name: '田东光伏智慧生态工地开发项目',
|
||||||
|
value: [107.15, 23.63],
|
||||||
|
// 使用图片作为标记(注意:需替换为你的图片实际路径)
|
||||||
|
symbol: 'diamond',
|
||||||
|
// 标记颜色
|
||||||
|
itemStyle: {
|
||||||
|
color: '#0166d6'
|
||||||
|
},
|
||||||
|
// 图片标记大小(宽, 高)
|
||||||
|
symbolSize: [20, 20],
|
||||||
|
// 名称样式设置
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
formatter: '{b}', // 显示名称
|
||||||
|
position: 'top', // 名称在图片上方
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 12,
|
||||||
|
// 可选:添加文字背景以增强可读性
|
||||||
|
backgroundColor: 'rgba(3, 26, 52, 0.7)',
|
||||||
|
padding: [3, 6],
|
||||||
|
borderRadius: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
// 初始化新实例,强制清除缓存
|
||||||
|
myChart = echarts.init(mapRef.value, null, {
|
||||||
|
renderer: 'canvas', // 明确指定渲染器
|
||||||
|
useDirtyRect: false // 禁用脏矩形渲染,避免样式缓存
|
||||||
|
});
|
||||||
|
// 配置项
|
||||||
|
const option: any = {
|
||||||
|
roam: true, // 关键配置:允许鼠标滚轮缩放和拖拽平移
|
||||||
|
geo: {
|
||||||
|
type: 'map',
|
||||||
|
map: 'china',
|
||||||
|
zoom: 5,
|
||||||
|
center: [107.15, 23.63],
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: '#031a34', // 地图区域底色
|
||||||
|
borderColor: '#1e3a6e', // 区域边框颜色
|
||||||
|
borderWidth: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return params.name + (params.value ? `:${params.value}` : '');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'map',
|
||||||
|
map: 'china',
|
||||||
|
geoIndex: 0,
|
||||||
|
// 关键:在series级别定义emphasis,优先级最高
|
||||||
|
emphasis: {
|
||||||
|
areaColor: '#fff', // 强制设置hover颜色
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: '#02417e' // 重复设置确保生效
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 确保没有使用默认样式
|
||||||
|
select: {
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: '#02417e'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: mapData
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'scatter',
|
||||||
|
coordinateSystem: 'geo',
|
||||||
|
data: scatterData
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置配置项
|
||||||
|
myChart.setOption(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时初始化
|
||||||
|
onMounted(() => {
|
||||||
|
// 确保DOM渲染完成
|
||||||
|
nextTick(() => {
|
||||||
|
initEcharts();
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组件卸载时清理
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
if (myChart) {
|
||||||
|
myChart.dispose();
|
||||||
|
myChart = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// const getDataList = () => {
|
||||||
|
// getPowerStationOverview().then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// if (res.code == 200) {
|
||||||
|
// data.value = res.data;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
// getDataList();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.centerPage {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 10px 10px 10px;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
.centerPage_map {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
180
src/views/largeScreen/components/header.vue
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
<template>
|
||||||
|
<div class="header">
|
||||||
|
<div class="header_left">
|
||||||
|
<div class="header_left_img">
|
||||||
|
<img src="@/assets/large/secure.png" style="width: 100%; height: 100%" />
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px; padding-left: 10px">安全生产天数:</div>
|
||||||
|
<div class="header_left_text">
|
||||||
|
1,235
|
||||||
|
<span style="font-size: 12px">天</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="title">
|
||||||
|
<div class="title_text">资金管理看板</div>
|
||||||
|
<div>Fund Management Dashboard</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<div class="top-bar">
|
||||||
|
<!-- 左侧:天气图标 + 日期文字 -->
|
||||||
|
<div class="left-section">
|
||||||
|
<img src="@/assets/large/weather.png" alt="天气图标" />
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<span>多云 9°/18°</span>
|
||||||
|
<span style="padding-left: 20px"> {{ week[date.week] }} ({{ date.ymd }})</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!-- 分割线 -->
|
||||||
|
<div class="divider">
|
||||||
|
<div class="top-block"></div>
|
||||||
|
<div class="bottom-block"></div>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧:管理系统图标 + 文字 -->
|
||||||
|
<div class="right-section">
|
||||||
|
<img src="@/assets/large/setting.png" alt="设置图标" />
|
||||||
|
<span>管理系统</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
||||||
|
const date = ref({
|
||||||
|
ymd: '',
|
||||||
|
hms: '',
|
||||||
|
week: 0
|
||||||
|
});
|
||||||
|
const setTime = () => {
|
||||||
|
let date1 = new Date();
|
||||||
|
let year: any = date1.getFullYear();
|
||||||
|
let month: any = date1.getMonth() + 1;
|
||||||
|
let day: any = date1.getDate();
|
||||||
|
let hours: any = date1.getHours();
|
||||||
|
if (hours < 10) {
|
||||||
|
hours = '0' + hours;
|
||||||
|
}
|
||||||
|
let minutes: any = date1.getMinutes();
|
||||||
|
if (minutes < 10) {
|
||||||
|
minutes = '0' + minutes;
|
||||||
|
}
|
||||||
|
let seconds: any = date1.getSeconds();
|
||||||
|
if (seconds < 10) {
|
||||||
|
seconds = '0' + seconds;
|
||||||
|
}
|
||||||
|
date.value.ymd = year + '-' + month + '-' + day;
|
||||||
|
date.value.hms = hours + ':' + minutes + ':' + seconds;
|
||||||
|
date.value.week = date1.getDay();
|
||||||
|
};
|
||||||
|
// 添加定时器,每秒更新一次时间
|
||||||
|
const timer = setInterval(setTime, 1000);
|
||||||
|
// 组件卸载时清除定时器
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(timer);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.header {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.header_left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.header_left_img {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
// padding-right: 10px;
|
||||||
|
}
|
||||||
|
.header_left_text {
|
||||||
|
font-weight: 500;
|
||||||
|
text-shadow: 0px 1.24px 6.21px rgba(25, 179, 250, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.title > div:first-child {
|
||||||
|
/* 第一个子元素的样式 */
|
||||||
|
font-size: 38px;
|
||||||
|
// font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title > div:last-child {
|
||||||
|
/* 最后一个子元素的样式 */
|
||||||
|
font-size: 14px;
|
||||||
|
letter-spacing: 0.3em; /* 调整这个值来控制间距大小 */
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
/* 顶部栏容器:Flex 水平布局 + 垂直居中 */
|
||||||
|
.top-bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
// background-color: #1e2128;
|
||||||
|
color: #fff;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
/* 左侧区域(天气 + 日期):自身也用 Flex 水平排列,确保元素在一行 */
|
||||||
|
.left-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// margin-right: auto; /* 让右侧元素(管理系统)居右 */
|
||||||
|
}
|
||||||
|
.left-section img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 8px; /* 图标与文字间距 */
|
||||||
|
}
|
||||||
|
/* 分割线(视觉分隔,可根据需求调整样式) */
|
||||||
|
.divider {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 1fr 1fr;
|
||||||
|
height: 100%; /* 根据需要调整高度 */
|
||||||
|
padding: 14px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider .top-block {
|
||||||
|
width: 2px;
|
||||||
|
height: 7px;
|
||||||
|
background: #19b5fb;
|
||||||
|
align-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider .bottom-block {
|
||||||
|
width: 2px;
|
||||||
|
height: 7px;
|
||||||
|
background: #19b5fb;
|
||||||
|
align-self: end;
|
||||||
|
}
|
||||||
|
/* 右侧区域(管理系统):图标 + 文字水平排列 */
|
||||||
|
.right-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.right-section img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 6px; /* 图标与文字间距 */
|
||||||
|
}
|
||||||
|
</style>
|
13
src/views/largeScreen/components/leftPage.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div class="leftPage">左边</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.leftPage {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #0c1e35;
|
||||||
|
}
|
||||||
|
</style>
|
735
src/views/largeScreen/components/optionList.ts
Normal file
@ -0,0 +1,735 @@
|
|||||||
|
import * as echarts from 'echarts/core';
|
||||||
|
// import { PictorialBarChart } from 'echarts/charts'
|
||||||
|
// 客流量图
|
||||||
|
export const getOption = (xData: any, yData: any) => {
|
||||||
|
const data = {
|
||||||
|
xData,
|
||||||
|
yData
|
||||||
|
};
|
||||||
|
const maxData = Math.ceil(Math.max(...data.yData));
|
||||||
|
const barData = data.yData.map((item) => {
|
||||||
|
return maxData;
|
||||||
|
});
|
||||||
|
const option = {
|
||||||
|
grid: {
|
||||||
|
top: '10%',
|
||||||
|
left: '8%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '20%'
|
||||||
|
// containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: data.xData,
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
show: true,
|
||||||
|
type: 'value',
|
||||||
|
max: maxData,
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
type: 'solid',
|
||||||
|
color: 'rgba(73, 169, 191, 0.2)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: '',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
// show: true,
|
||||||
|
start: 0,
|
||||||
|
end: 30,
|
||||||
|
bottom: 2, // 下滑块距离x轴底部的距离
|
||||||
|
height: 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'inside'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '柱图',
|
||||||
|
type: 'bar',
|
||||||
|
// barWidth: '10%',
|
||||||
|
data: barData,
|
||||||
|
tooltip: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
barGap: '-50%',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgba(73, 169, 191, 0.2)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '客单价',
|
||||||
|
type: 'line',
|
||||||
|
showAllSymbol: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 8,
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgba(217, 231, 255, 0.3)',
|
||||||
|
shadowColor: 'rgba(0, 0, 0, .3)',
|
||||||
|
shadowBlur: 0
|
||||||
|
// shadowOffsetY: 5,
|
||||||
|
// shadowOffsetX: 5,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgba(224, 194, 22, 1)',
|
||||||
|
borderWidth: 0,
|
||||||
|
shadowBlur: 0
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: false, // 显示数据标签
|
||||||
|
color: 'rgba(255, 208, 59, 1)'
|
||||||
|
},
|
||||||
|
data: data.yData
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 上菜分析图
|
||||||
|
export const getOption2 = (data: any) => {
|
||||||
|
const maxData = Math.max(...data.yData);
|
||||||
|
const option = {
|
||||||
|
// backgroundColor: "#38445E",
|
||||||
|
grid: {
|
||||||
|
left: '10%',
|
||||||
|
top: '13%',
|
||||||
|
bottom: '16%',
|
||||||
|
right: '10%'
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
data: data.xData,
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(255, 129, 109, 0.1)',
|
||||||
|
width: 1 //这里是为了突出显示加上的
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#999',
|
||||||
|
fontSize: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
splitNumber: 2,
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(255, 129, 109, 0.1)',
|
||||||
|
width: 1 //这里是为了突出显示加上的
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#999'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
areaStyle: {
|
||||||
|
color: 'rgba(255,255,255,.5)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(255,255,255,.5)',
|
||||||
|
width: 0.5,
|
||||||
|
type: 'dashed'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
// show: true,
|
||||||
|
|
||||||
|
start: 0,
|
||||||
|
end: 30,
|
||||||
|
bottom: 2, // 下滑块距离x轴底部的距离
|
||||||
|
height: 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'inside'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis', // 设置为 'item',表示鼠标悬浮在图形上时显示 tooltip
|
||||||
|
// formatter: function (params) {
|
||||||
|
// return `订单数: ${params.data}` // 显示鼠标悬浮项的数量
|
||||||
|
// },
|
||||||
|
backgroundColor: '', // 设置提示框的背景颜色
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff' // 设置文字颜色
|
||||||
|
// fontSize: 14 // 设置文字大小
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '订单数',
|
||||||
|
type: 'pictorialBar',
|
||||||
|
barCategoryGap: '0%',
|
||||||
|
symbol: 'path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z',
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
position: 'top',
|
||||||
|
distance: 15,
|
||||||
|
color: 'rgba(255, 235, 59, 1)',
|
||||||
|
// fontWeight: "bolder",
|
||||||
|
fontSize: 16
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
// color: {
|
||||||
|
// type: "linear",
|
||||||
|
// x: 0,
|
||||||
|
// y: 0,
|
||||||
|
// x2: 0,
|
||||||
|
// y2: 1,
|
||||||
|
// colorStops: [
|
||||||
|
// {
|
||||||
|
// offset: 0,
|
||||||
|
// color: "rgba(232, 94, 106, .8)", // 0% 处的颜色
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// offset: 1,
|
||||||
|
// color: "rgba(232, 94, 106, .1)", // 100% 处的颜色
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// global: false, // 缺省为 false
|
||||||
|
// },
|
||||||
|
color: function (params: any) {
|
||||||
|
if (params.data === maxData) {
|
||||||
|
return 'rgba(255, 219, 103, 0.6)';
|
||||||
|
} else {
|
||||||
|
return 'rgba(239, 244, 255, 0.45)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: data.yData,
|
||||||
|
z: 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
//食堂周报图
|
||||||
|
export const getLineOption = (lineData: any) => {
|
||||||
|
const maxData = Math.ceil(Math.max(...lineData.line1));
|
||||||
|
const option = {
|
||||||
|
backgroundColor: '',
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
color: '#7ec7ff',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
borderColor: '#7ec7ff'
|
||||||
|
},
|
||||||
|
// legend: {
|
||||||
|
// align: 'left',
|
||||||
|
// right: '5%',
|
||||||
|
// top: '1%',
|
||||||
|
// type: 'plain',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#fff',
|
||||||
|
// fontSize: 12
|
||||||
|
// },
|
||||||
|
// // icon:'rect',
|
||||||
|
// itemGap: 15,
|
||||||
|
// itemWidth: 18,
|
||||||
|
// data: [
|
||||||
|
// {
|
||||||
|
// name: '上周销售量'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: '本周销售量'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
grid: {
|
||||||
|
top: '12%',
|
||||||
|
left: '1%',
|
||||||
|
right: '3%',
|
||||||
|
bottom: '12%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: lineData.xLabel,
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
show: true,
|
||||||
|
type: 'value',
|
||||||
|
max: maxData,
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
type: 'solid',
|
||||||
|
color: 'rgba(73, 169, 191, 0.2)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
// show: true,
|
||||||
|
start: 0,
|
||||||
|
end: 30,
|
||||||
|
bottom: 2, // 下滑块距离x轴底部的距离
|
||||||
|
height: 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'inside'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '逆变器功率',
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆
|
||||||
|
showAllSymbol: false,
|
||||||
|
symbolSize: 0,
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 1,
|
||||||
|
color: 'rgba(80, 164, 225, 1)', // 线条颜色
|
||||||
|
borderColor: 'rgba(0,0,0,.4)'
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgba(80, 164, 225, 1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
//线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(80, 164, 225, 0.4)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(80, 164, 225, 0)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
false
|
||||||
|
),
|
||||||
|
shadowColor: 'rgba(25,163,223, 0.5)', //阴影颜色
|
||||||
|
shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
|
||||||
|
},
|
||||||
|
data: lineData.line1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
// 菜品销售图
|
||||||
|
export const getDishesOption = (data?: any) => {
|
||||||
|
const res = data;
|
||||||
|
const dataIndex = 1;
|
||||||
|
const option = {
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
margin: 10 // 增大标签与轴线间距
|
||||||
|
},
|
||||||
|
width: 60, // 增大Y轴宽度
|
||||||
|
data: res.name,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#93C9C3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '5%', // 设置网格区域与容器之间的边距
|
||||||
|
bottom: '5%', // 同理
|
||||||
|
left: '5%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: res.ratio,
|
||||||
|
barMaxWidth: 25,
|
||||||
|
itemStyle: {
|
||||||
|
barBorderRadius: 3,
|
||||||
|
color: 'rgba(12, 242, 216, 0.2)'
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: res.data,
|
||||||
|
barGap: '-100%',
|
||||||
|
barMaxWidth: 25,
|
||||||
|
itemStyle: {
|
||||||
|
barBorderRadius: 3,
|
||||||
|
color: function (params: any) {
|
||||||
|
if (params.data <= 300) {
|
||||||
|
return new echarts.graphic.LinearGradient(1, 0, 0, 0, [
|
||||||
|
{ color: 'rgba(252, 105, 0, 1)', offset: 0 },
|
||||||
|
{ color: 'rgba(250, 42, 42, 1)', offset: 1 }
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return new echarts.graphic.LinearGradient(1, 0, 0, 0, [
|
||||||
|
{ color: 'rgba(73, 169, 191, 1)', offset: 0 },
|
||||||
|
{ color: 'rgba(108, 248, 236, 1)', offset: 1 }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: [200, -15],
|
||||||
|
formatter: function (params: any) {
|
||||||
|
if (params.data <= 300) {
|
||||||
|
return `{a| ${params.value}g/${res.ratio[params.dataIndex]}g}`;
|
||||||
|
} else {
|
||||||
|
return `{b| ${params.value}g/${res.ratio[params.dataIndex]}g}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rich: {
|
||||||
|
a: {
|
||||||
|
color: 'rgba(255, 78, 51, 1)'
|
||||||
|
},
|
||||||
|
b: {
|
||||||
|
color: 'rgba(255, 235, 59, 1)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
// 菜品库存图
|
||||||
|
export const getInventoryOption = () => {
|
||||||
|
const res = {
|
||||||
|
data: [2800, 300, 3900, 3000, 2450, 2670, 3320],
|
||||||
|
name: ['麻辣牛肉', '水煮肉片', '酸菜鱼', '辣子鸡丁', '烧白', '冬瓜排骨汤', '清炒油麦菜'],
|
||||||
|
ratio: [4000, 4000, 4000, 4000, 4000, 4000, 4000]
|
||||||
|
},
|
||||||
|
dataIndex = 1;
|
||||||
|
const option = {
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
show: false,
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
margin: 10 // 增大标签与轴线间距
|
||||||
|
},
|
||||||
|
width: 20, // 增大Y轴宽度
|
||||||
|
data: res.name,
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#93C9C3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '5%', // 设置网格区域与容器之间的边距
|
||||||
|
bottom: '5%', // 同理
|
||||||
|
left: '5%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: res.ratio,
|
||||||
|
barMaxWidth: 6,
|
||||||
|
itemStyle: {
|
||||||
|
barBorderRadius: 3,
|
||||||
|
color: 'rgba(12, 242, 216, 0.2)'
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: [0, -15],
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#fff',
|
||||||
|
formatter: function (params: any) {
|
||||||
|
return params.name;
|
||||||
|
}
|
||||||
|
// rich: {
|
||||||
|
// a: {
|
||||||
|
// color: "rgba(255, 78, 51, 1)",
|
||||||
|
// },
|
||||||
|
// b: {
|
||||||
|
// color: "rgba(255, 235, 59, 1)",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: res.data,
|
||||||
|
barGap: '-100%',
|
||||||
|
barMaxWidth: 6,
|
||||||
|
itemStyle: {
|
||||||
|
barBorderRadius: 0,
|
||||||
|
color: function (params: any) {
|
||||||
|
if (params.dataIndex === dataIndex) {
|
||||||
|
return new echarts.graphic.LinearGradient(1, 0, 0, 0, [
|
||||||
|
{ color: 'rgba(255, 78, 51, 1)', offset: 0 },
|
||||||
|
{ color: 'rgba(252, 105, 0, 0)', offset: 1 }
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return new echarts.graphic.LinearGradient(1, 0, 0, 0, [
|
||||||
|
{ color: 'rgba(242, 224, 27, 1)', offset: 0 },
|
||||||
|
{ color: 'rgba(236, 227, 127, 0.55)', offset: 0.5 },
|
||||||
|
{ color: 'rgba(230, 229, 227, 0.1)', offset: 1 }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: [200, -15],
|
||||||
|
formatter: function (params: any) {
|
||||||
|
if (params.dataIndex === dataIndex) {
|
||||||
|
return `{a| ${params.value}g}`;
|
||||||
|
} else {
|
||||||
|
return `{b| ${params.value}g}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rich: {
|
||||||
|
a: {
|
||||||
|
color: 'rgba(255, 78, 51, 1)'
|
||||||
|
},
|
||||||
|
b: {
|
||||||
|
color: 'rgba(255, 235, 59, 1)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
export const getBarOptions = (data: any) => {
|
||||||
|
const option = {
|
||||||
|
backgroundColor: '',
|
||||||
|
grid: {
|
||||||
|
left: '7%',
|
||||||
|
top: '4%',
|
||||||
|
bottom: '25%',
|
||||||
|
right: '2%'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: true,
|
||||||
|
backgroundColor: '',
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: '{b0}:{c0}元',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
// borderColor: 'rgba(252, 217, 18, 1)'
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
data: data.name,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(108, 128, 151, 0.3)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#999',
|
||||||
|
fontSize: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
// show: true,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(108, 128, 151, 0.3)',
|
||||||
|
type: 'dashed'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
axisLabel: {
|
||||||
|
formatter: function (value) {
|
||||||
|
if (value >= 1000) {
|
||||||
|
value = (value / 1000).toFixed(1) + 'k'; // 大于等于1000的数字显示为1k、2.5k等
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
color: 'rgba(255, 255, 255, 0.8)'
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(108, 128, 151, 0.3)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgba(108, 128, 151, 0.3)',
|
||||||
|
type: 'dashed'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
// show: true,
|
||||||
|
start: 0,
|
||||||
|
end: 30,
|
||||||
|
bottom: 2, // 下滑块距离x轴底部的距离
|
||||||
|
height: 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'inside'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: data.value,
|
||||||
|
stack: '合并',
|
||||||
|
barWidth: '15',
|
||||||
|
itemStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(0, 111, 255, 0)' // 0% 处的颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.7,
|
||||||
|
color: 'rgba(0, 111, 255, 0.5)' // 0% 处的颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(0, 111, 255, 1)' // 100% 处的颜色
|
||||||
|
}
|
||||||
|
],
|
||||||
|
false
|
||||||
|
)
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
formatter: '{c}',
|
||||||
|
position: 'top',
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 10
|
||||||
|
// padding: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// {
|
||||||
|
// type: 'bar',
|
||||||
|
// stack: '合并',
|
||||||
|
// data: topData,
|
||||||
|
// barWidth: '15',
|
||||||
|
// itemStyle: {
|
||||||
|
// color: 'rgba(252, 217, 18, 1)'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
13
src/views/largeScreen/components/rightPage.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div class="rightPage">右边</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.rightPage {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #0c1e35;
|
||||||
|
}
|
||||||
|
</style>
|
43
src/views/largeScreen/index.vue
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class="large-screen">
|
||||||
|
<Header />
|
||||||
|
<div class="nav">
|
||||||
|
<div class="nav_left">
|
||||||
|
<leftPage />
|
||||||
|
</div>
|
||||||
|
<div class="nav_center">
|
||||||
|
<centerPage />
|
||||||
|
</div>
|
||||||
|
<div class="nav_right">
|
||||||
|
<rightPage />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Header from './components/header.vue';
|
||||||
|
import leftPage from './components/leftPage.vue';
|
||||||
|
import centerPage from './components/centerPage.vue';
|
||||||
|
import rightPage from './components/rightPage.vue';
|
||||||
|
// import '@/assets/styles/element.scss';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.large-screen {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: url('@/assets/large/bg.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-color: rgba(4, 7, 17, 1);
|
||||||
|
}
|
||||||
|
.nav {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100vh - 80px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
// padding: 10px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 2fr 1fr;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|