Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加天气组件,增加商品管理页面、增加财务管理页面 #400

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,6 @@ declare module '@vue/runtime-core' {
TableEdit: typeof import('./src/components/table-edit.vue')['default']
TableSearch: typeof import('./src/components/table-search.vue')['default']
Tabs: typeof import('./src/components/tabs.vue')['default']
WeatherWidget: typeof import('./src/components/WeatherWidget.vue')['default']
}
}
79 changes: 79 additions & 0 deletions src/components/WeatherWidget.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!-- src/components/WeatherWidget.vue -->
<template>
<el-card shadow="hover" class="weather-widget">
<div class="weather-header">
<el-icon class="weather-icon">
<Sunny />
</el-icon>
<div class="weather-info">
<div class="weather-temp">{{ weather.temp }}°C</div>
<div class="weather-desc">{{ weather.description }}</div>
<div class="weather-city">{{weather.city}}</div>
</div>
</div>
</el-card>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Sunny } from '@element-plus/icons-vue';

const weather = ref({
temp: 0,
description: 'Loading...',
});

const fetchWeather = async () => {
try {
const response = await fetch('https://restapi.amap.com/v3/weather/weatherInfo?key= &city=230103&extensions=base');
const data = await response.json();
if (data.status === '1' && data.lives && data.lives.length > 0) {
weather.value.temp = data.lives[0].temperature;
weather.value.description = data.lives[0].weather;
weather.value.city = data.lives[0].city;

} else {
throw new Error('Invalid weather data');
}
} catch (error) {
ElMessage.error('Failed to fetch weather data');
}
};

onMounted(() => {
fetchWeather();
});
</script>

<style scoped>
.weather-widget {
display: flex;
align-items: center;
padding: 20px;
}

.weather-header {
display: flex;
align-items: center;
}

.weather-icon {
font-size: 50px;
margin-right: 20px;
}

.weather-info {
text-align: left;
}

.weather-temp {
font-size: 30px;
font-weight: bold;
}

.weather-desc {
font-size: 14px;
color: #999;
}
</style>
12 changes: 12 additions & 0 deletions src/components/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ export const menuData: Menus[] = [
index: '/system-menu',
title: '菜单管理',
},
{
id: '14',
pid: '1',
index: '/product-management',
title: '商品管理',
},
{
id: '15',
pid: '1',
index: '/finance-management',
title: '财务管理',
},
],
},
{
Expand Down
18 changes: 18 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ const routes: RouteRecordRaw[] = [
},
component: () => import(/* webpackChunkName: "system-menu" */ '../views/system/menu.vue'),
},
{
path: '/product-management',
name: 'product-management',
meta: {
title: '商品管理',
permiss: '14',
},
component: () => import(/* webpackChunkName: "product-management" */ '../views/product-management.vue'),
},
{
path: '/finance-management',
name: 'finance-management',
meta: {
title: '财务管理',
permiss: '15',
},
component: () => import(/* webpackChunkName: "finance-management" */ '../views/finance-management.vue'),
},
{
path: '/table',
name: 'basetable',
Expand Down
4 changes: 3 additions & 1 deletion src/store/permiss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const usePermissStore = defineStore('permiss', {
'11',
'12',
'13',
'14',
'15',
'2',
'21',
'22',
Expand Down Expand Up @@ -43,7 +45,7 @@ export const usePermissStore = defineStore('permiss', {
'65',
'66',
],
user: ['0', '1', '11', '12', '13'],
user: ['0', '1', '11', '12', '13', '14', '15'],
};
const username = localStorage.getItem('vuems_name');
console.log(username);
Expand Down
6 changes: 6 additions & 0 deletions src/views/dashboard.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<template>
<div>
<el-row :gutter="20" class="mgb20">
<el-col :span="6">
<WeatherWidget />
</el-col>
</el-row>
<el-row :gutter="20" class="mgb20">
<el-col :span="6">
<el-card shadow="hover" body-class="card-body">
Expand Down Expand Up @@ -127,6 +132,7 @@
</template>

<script setup lang="ts" name="dashboard">
import WeatherWidget from '@/components/WeatherWidget.vue';
import countup from '@/components/countup.vue';
import { use, registerMap } from 'echarts/core';
import { BarChart, LineChart, PieChart, MapChart } from 'echarts/charts';
Expand Down
113 changes: 113 additions & 0 deletions src/views/finance-management.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<template>
<div>
<h1>财务管理</h1>
<el-button type="primary" @click="openDialog">新增记录</el-button>
<el-table :data="records" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="amount" label="金额" width="180"></el-table-column>
<el-table-column prop="description" label="描述" width="180"></el-table-column>
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button @click="editRecord(scope.row)" type="primary" size="small">编辑</el-button>
<el-button @click="deleteRecord(scope.row)" type="danger" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>

<el-dialog :title="isEdit ? '编辑记录' : '新增记录'" v-model="dialogVisible">
<el-form :model="form">
<el-form-item label="日期">
<el-date-picker v-model="form.date" type="date" placeholder="选择日期"></el-date-picker>
</el-form-item>
<el-form-item label="金额">
<el-input v-model="form.amount"></el-input>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="form.description"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveRecord">保存</el-button>
</div>
</el-dialog>
</div>
</template>

<script setup lang="ts" name="finance-management">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';

const records = ref([]);
const dialogVisible = ref(false);
const isEdit = ref(false);
const form = ref({
date: '',
amount: '',
description: '',
});

const fetchRecords = async () => {
try {
const response = await fetch('/api/finance-records');
const data = await response.json();
records.value = data;
} catch (error) {
ElMessage.error('Failed to fetch financial records');
}
};

const openDialog = () => {
isEdit.value = false;
form.value = { date: '', amount: '', description: '' };
dialogVisible.value = true;
};

const editRecord = (record) => {
isEdit.value = true;
form.value = { ...record };
dialogVisible.value = true;
};

const saveRecord = async () => {
try {
if (isEdit.value) {
// Update record
await fetch(`/api/finance-records/${form.value.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form.value),
});
} else {
// Add new record
await fetch('/api/finance-records', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form.value),
});
}
fetchRecords();
dialogVisible.value = false;
ElMessage.success('Record saved successfully');
} catch (error) {
ElMessage.error('Failed to save record');
}
};

const deleteRecord = async (record) => {
try {
await fetch(`/api/finance-records/${record.id}`, { method: 'DELETE' });
fetchRecords();
ElMessage.success('Record deleted successfully');
} catch (error) {
ElMessage.error('Failed to delete record');
}
};

onMounted(() => {
fetchRecords();
});
</script>

<style scoped>
</style>
113 changes: 113 additions & 0 deletions src/views/product-management.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<template>
<div>
<h1>商品管理</h1>
<el-button type="primary" @click="openDialog">新增商品</el-button>
<el-table :data="products" style="width: 100%">
<el-table-column prop="name" label="商品名称" width="180"></el-table-column>
<el-table-column prop="price" label="价格" width="180"></el-table-column>
<el-table-column prop="category" label="分类" width="180"></el-table-column>
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button @click="editProduct(scope.row)" type="primary" size="small">编辑</el-button>
<el-button @click="deleteProduct(scope.row)" type="danger" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>

<el-dialog :title="isEdit ? '编辑商品' : '新增商品'" v-model="dialogVisible">
<el-form :model="form">
<el-form-item label="商品名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="价格">
<el-input v-model="form.price"></el-input>
</el-form-item>
<el-form-item label="分类">
<el-input v-model="form.category"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveProduct">保存</el-button>
</div>
</el-dialog>
</div>
</template>

<script setup lang="ts" name="product-management">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';

const products = ref([]);
const dialogVisible = ref(false);
const isEdit = ref(false);
const form = ref({
name: '',
price: '',
category: '',
});

const fetchProducts = async () => {
try {
const response = await fetch('/api/products');
const data = await response.json();
products.value = data;
} catch (error) {
ElMessage.error('Failed to fetch product data');
}
};

const openDialog = () => {
isEdit.value = false;
form.value = { name: '', price: '', category: '' };
dialogVisible.value = true;
};

const editProduct = (product) => {
isEdit.value = true;
form.value = { ...product };
dialogVisible.value = true;
};

const saveProduct = async () => {
try {
if (isEdit.value) {
// Update product
await fetch(`/api/products/${form.value.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form.value),
});
} else {
// Add new product
await fetch('/api/products', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form.value),
});
}
fetchProducts();
dialogVisible.value = false;
ElMessage.success('Product saved successfully');
} catch (error) {
ElMessage.error('Failed to save product');
}
};

const deleteProduct = async (product) => {
try {
await fetch(`/api/products/${product.id}`, { method: 'DELETE' });
fetchProducts();
ElMessage.success('Product deleted successfully');
} catch (error) {
ElMessage.error('Failed to delete product');
}
};

onMounted(() => {
fetchProducts();
});
</script>

<style scoped>
</style>