1
This commit is contained in:
1774
package-lock.json
generated
Normal file
1774
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
package.json
Normal file
24
package.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "jarvis_vue",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.2",
|
||||||
|
"element-plus": "^2.4.10",
|
||||||
|
"vue": "^3.4.28",
|
||||||
|
"vue-router": "^4.2.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
|
"vite": "^5.1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
101
src/App.vue
Normal file
101
src/App.vue
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<el-container v-if="isLoggedIn">
|
||||||
|
<!-- 顶部导航 -->
|
||||||
|
<el-header>
|
||||||
|
<div class="header-container">
|
||||||
|
<div class="logo">订单管理系统</div>
|
||||||
|
<div class="user-info">
|
||||||
|
<el-dropdown trigger="click">
|
||||||
|
<span class="el-dropdown-link">
|
||||||
|
{{ username }} <i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-header>
|
||||||
|
|
||||||
|
<!-- 主内容区 -->
|
||||||
|
<el-main>
|
||||||
|
<router-view />
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
|
||||||
|
<!-- 未登录时显示登录页 -->
|
||||||
|
<router-view v-else />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
username: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isLoggedIn() {
|
||||||
|
return localStorage.getItem('token') !== null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const userInfo = localStorage.getItem('userInfo')
|
||||||
|
if (userInfo) {
|
||||||
|
try {
|
||||||
|
const user = JSON.parse(userInfo)
|
||||||
|
this.username = user.username || '用户'
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析用户信息失败', error)
|
||||||
|
this.username = '用户'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
logout() {
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
localStorage.removeItem('userInfo')
|
||||||
|
this.$axios.defaults.headers.common['Authorization'] = null
|
||||||
|
this.$router.push('/login')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-header {
|
||||||
|
background-color: #409EFF;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
13
src/components/HomeView.vue
Normal file
13
src/components/HomeView.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>首页</h1>
|
||||||
|
<p>欢迎来到首页!</p>
|
||||||
|
<router-link to="/login">去登录页</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HomeView'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
0
src/components/Login.vue
Normal file
0
src/components/Login.vue
Normal file
212
src/components/OrderList.vue
Normal file
212
src/components/OrderList.vue
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
<template>
|
||||||
|
<div class="order-container">
|
||||||
|
<el-card class="box-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="clearfix">
|
||||||
|
<span>订单列表</span>
|
||||||
|
<el-button style="float: right; padding: 3px 0" type="text" @click="fetchOrders">刷新</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 搜索表单 -->
|
||||||
|
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
|
||||||
|
<el-form-item label="订单编号">
|
||||||
|
<el-input v-model="searchForm.orderNo" placeholder="请输入订单编号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="客户名称">
|
||||||
|
<el-input v-model="searchForm.customerName" placeholder="请输入客户名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="订单状态">
|
||||||
|
<el-select v-model="searchForm.status" placeholder="请选择订单状态">
|
||||||
|
<el-option label="待支付" value="PENDING"></el-option>
|
||||||
|
<el-option label="已支付" value="PAID"></el-option>
|
||||||
|
<el-option label="已发货" value="SHIPPED"></el-option>
|
||||||
|
<el-option label="已完成" value="COMPLETED"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="fetchOrders">查询</el-button>
|
||||||
|
<el-button @click="resetForm">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 订单表格 -->
|
||||||
|
<el-table
|
||||||
|
:data="orders"
|
||||||
|
stripe
|
||||||
|
style="width: 100%">
|
||||||
|
<el-table-column prop="orderNo" label="订单编号"></el-table-column>
|
||||||
|
<el-table-column prop="customerName" label="客户名称"></el-table-column>
|
||||||
|
<el-table-column prop="orderAmount" label="订单金额"></el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="创建时间"></el-table-column>
|
||||||
|
<el-table-column prop="status" label="订单状态">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag
|
||||||
|
:type="statusMap[scope.row.status].type">
|
||||||
|
{{ statusMap[scope.row.status].label }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" type="text" @click="viewDetail(scope.row)">查看详情</el-button>
|
||||||
|
<el-button size="small" type="text" @click="editOrder(scope.row)">编辑</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页控件 -->
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 订单详情对话框 -->
|
||||||
|
<el-dialog :visible.sync="detailDialogVisible" title="订单详情">
|
||||||
|
<template #content>
|
||||||
|
<el-form :model="currentOrder">
|
||||||
|
<el-form-item label="订单编号" :label-width="formLabelWidth">
|
||||||
|
<span>{{ currentOrder.orderNo }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="客户名称" :label-width="formLabelWidth">
|
||||||
|
<span>{{ currentOrder.customerName }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="订单金额" :label-width="formLabelWidth">
|
||||||
|
<span>{{ currentOrder.orderAmount }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="订单状态" :label-width="formLabelWidth">
|
||||||
|
<el-tag :type="statusMap[currentOrder.status].type">
|
||||||
|
{{ statusMap[currentOrder.status].label }}
|
||||||
|
</el-tag>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" :label-width="formLabelWidth">
|
||||||
|
<span>{{ currentOrder.createTime }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="订单详情" :label-width="formLabelWidth">
|
||||||
|
<el-table :data="currentOrder.items" stripe style="width: 100%">
|
||||||
|
<el-table-column prop="productName" label="商品名称"></el-table-column>
|
||||||
|
<el-table-column prop="quantity" label="数量"></el-table-column>
|
||||||
|
<el-table-column prop="price" label="单价"></el-table-column>
|
||||||
|
<el-table-column prop="subtotal" label="小计"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'OrderList',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 状态映射
|
||||||
|
statusMap: {
|
||||||
|
PENDING: { label: '待支付', type: 'warning' },
|
||||||
|
PAID: { label: '已支付', type: 'success' },
|
||||||
|
SHIPPED: { label: '已发货', type: 'info' },
|
||||||
|
COMPLETED: { label: '已完成', type: 'primary' }
|
||||||
|
},
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
searchForm: {
|
||||||
|
orderNo: '',
|
||||||
|
customerName: '',
|
||||||
|
status: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
// 分页信息
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
orders: [],
|
||||||
|
|
||||||
|
// 详情对话框
|
||||||
|
detailDialogVisible: false,
|
||||||
|
currentOrder: {},
|
||||||
|
formLabelWidth: '120px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchOrders()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取订单列表
|
||||||
|
fetchOrders() {
|
||||||
|
this.$axios.get('/orders', {
|
||||||
|
params: {
|
||||||
|
...this.searchForm,
|
||||||
|
page: this.currentPage,
|
||||||
|
size: this.pageSize
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
this.orders = response.data.content
|
||||||
|
this.total = response.data.totalElements
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$message.error('获取订单列表失败,请稍后重试')
|
||||||
|
console.error(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
resetForm() {
|
||||||
|
this.searchForm.orderNo = ''
|
||||||
|
this.searchForm.customerName = ''
|
||||||
|
this.searchForm.status = ''
|
||||||
|
this.fetchOrders()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 分页相关方法
|
||||||
|
handleSizeChange(newSize) {
|
||||||
|
this.pageSize = newSize
|
||||||
|
this.fetchOrders()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCurrentChange(newPage) {
|
||||||
|
this.currentPage = newPage
|
||||||
|
this.fetchOrders()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查看订单详情
|
||||||
|
viewDetail(order) {
|
||||||
|
this.$axios.get(`/orders/${order.id}`)
|
||||||
|
.then(response => {
|
||||||
|
this.currentOrder = response.data
|
||||||
|
this.detailDialogVisible = true
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$message.error('获取订单详情失败,请稍后重试')
|
||||||
|
console.error(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 编辑订单
|
||||||
|
editOrder(order) {
|
||||||
|
this.$message.info(`编辑订单: ${order.orderNo}`)
|
||||||
|
// 实现编辑逻辑
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.order-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-card {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
57
src/main.js
Normal file
57
src/main.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
|
||||||
|
// 配置axios基础URL http://134.175.126.60:36666
|
||||||
|
axios.defaults.baseURL = 'http://134.175.126.60:36666/api'
|
||||||
|
|
||||||
|
// 请求拦截器 - 携带token
|
||||||
|
// axios.interceptors.request.use(
|
||||||
|
// config => {
|
||||||
|
// const token = localStorage.getItem('token')
|
||||||
|
// if (token) {
|
||||||
|
// config.headers['Authorization'] = `Bearer ${token}`
|
||||||
|
// }
|
||||||
|
// return config
|
||||||
|
// },
|
||||||
|
// error => {
|
||||||
|
// return Promise.reject(error)
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
|
// 响应拦截器 - 处理401未授权
|
||||||
|
// axios.interceptors.response.use(
|
||||||
|
// response => {
|
||||||
|
// return response
|
||||||
|
// },
|
||||||
|
// error => {
|
||||||
|
// if (error.response && error.response.status === 401) {
|
||||||
|
// localStorage.removeItem('token')
|
||||||
|
// localStorage.removeItem('userInfo')
|
||||||
|
// app.config.globalProperties.$message.error('登录已过期,请重新登录')
|
||||||
|
// router.push('/login')
|
||||||
|
// }
|
||||||
|
// return Promise.reject(error)
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// 仅在开发环境启用调试模式
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
app.config.performance = true // 启用性能追踪
|
||||||
|
app.config.devtools = true // 启用 DevTools 调试
|
||||||
|
}
|
||||||
|
// main.js
|
||||||
|
app.config.errorHandler = (err, instance, info) => {
|
||||||
|
console.error('全局错误捕获:', err, info)
|
||||||
|
// 可以添加错误上报逻辑
|
||||||
|
}
|
||||||
|
// 将axios挂载到全局
|
||||||
|
app.config.globalProperties.$axios = axios
|
||||||
|
|
||||||
|
app.use(ElementPlus)
|
||||||
|
app.use(router)
|
||||||
|
app.mount('#app')
|
||||||
14
src/public/index.html
Normal file
14
src/public/index.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>订单管理系统</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
41
src/router/index.js
Normal file
41
src/router/index.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
import OrderList from '../components/OrderList.vue'
|
||||||
|
import Login from '../components/Login.vue'
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
// src/router/index.js
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
redirect: '/login'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'OrderList',
|
||||||
|
component: OrderList,
|
||||||
|
meta: { requiresAuth: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'Login',
|
||||||
|
component: Login
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHashHistory(),
|
||||||
|
routes
|
||||||
|
})
|
||||||
|
|
||||||
|
// 全局前置守卫 - 验证登录状态
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
|
||||||
|
const isLoggedIn = localStorage.getItem('token') !== null
|
||||||
|
|
||||||
|
if (requiresAuth && !isLoggedIn) {
|
||||||
|
next('/login')
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
||||||
23
vite.config.js
Normal file
23
vite.config.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': '/src'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
host:'0.0.0.0',
|
||||||
|
port:9999,
|
||||||
|
// 解决开发环境跨域
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://134.175.126.206:6666',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/api/, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user