@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
*.log
|
||||
|
||||
tests/**/coverage/
|
||||
tests/e2e/reports
|
||||
selenium-debug.log
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.local
|
||||
|
||||
package-lock.json
|
||||
yarn.lock
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/hear.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>快递系统</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "practical_project",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.7",
|
||||
"element-china-area-data": "^6.1.0",
|
||||
"element-plus": "^2.8.7",
|
||||
"mitt": "^3.0.1",
|
||||
"pinia": "^2.2.5",
|
||||
"vue": "^3.5.10",
|
||||
"vue-router": "4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.1.4",
|
||||
"vite": "^5.4.8"
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url("./assets/css/base.css");
|
||||
</style>
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 419 B |
@ -0,0 +1,44 @@
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* 水平布局 居中*/
|
||||
.horizontalView {
|
||||
position: relative;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 垂直布局居中 */
|
||||
.verticalView {
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 居中 */
|
||||
.center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
font-size: 28px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.w100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.h100 {
|
||||
height: 100%;
|
||||
}
|
||||
.icon-svg {
|
||||
width: 1.4rem;
|
||||
height: 1.4rem;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
After Width: | Height: | Size: 295 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 490 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 184 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<el-carousel :interval="4000" type="card" height="400px">
|
||||
<el-carousel-item v-for="item in carouseData" :key="item.url">
|
||||
<img :src="item.url" alt="" @error="handleImageError($event, item.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const carouseData = ref([]);
|
||||
|
||||
const initializeCarouselData = () => {
|
||||
const urls = [
|
||||
"../assets/sf1.jpg",
|
||||
"../assets/sf2.jpg",
|
||||
"../assets/sf3.png",
|
||||
"../assets/sf4.jpg",
|
||||
"../assets/sf5.jpg",
|
||||
"../assets/sf6.jpg",
|
||||
"../assets/sf7.jpg",
|
||||
"../assets/sf8.jpg",
|
||||
];
|
||||
|
||||
carouseData.value = urls.map(url => ({
|
||||
url: new URL(url, import.meta.url).href
|
||||
}));
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initializeCarouselData();
|
||||
});
|
||||
|
||||
const handleImageError = (event, url) => {
|
||||
console.error(`Failed to load image: ${url}`);
|
||||
event.target.src = '/path/to/default/image.jpg';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-carousel__item h3 {
|
||||
color: #475669;
|
||||
opacity: 0.75;
|
||||
line-height: 285px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
img {
|
||||
width: 100%; /* 设置图片宽度为容器的100% */
|
||||
height: 100%; /* 设置图片高度为容器的100% */
|
||||
object-fit: cover; /* 保持图片的宽高比 */
|
||||
}
|
||||
|
||||
.el-carousel__item {
|
||||
text-align: center; /* 确保图片在容器中居中 */
|
||||
overflow: hidden; /* 如果图片超出容器大小,隐藏超出部分 */
|
||||
height: 400px; /* 设置容器高度与轮播图高度一致 */
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-color: #99a9bf;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-color: #d3dce6;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="not-found">
|
||||
<h1>404 - 页面未找到</h1>
|
||||
<p>您访问的页面不存在。</p>
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
const goBack = () => {
|
||||
router.go(-1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.not-found {
|
||||
text-align: center;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,9 @@
|
||||
// src/hooks/useEmitter.js
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
export default function useEmitter() {
|
||||
const internalInstance = getCurrentInstance()
|
||||
const emitter = internalInstance.appContext.config.globalProperties.emitter
|
||||
|
||||
return emitter
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import { createApp } from 'vue'
|
||||
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import * as Icons from '@element-plus/icons-vue'
|
||||
import mitt from 'mitt';
|
||||
|
||||
import Header from './components/Header.vue';
|
||||
import Footer from './components/Footer.vue';
|
||||
import backIndex from './components/backIndex.vue';
|
||||
|
||||
import router from './router'
|
||||
import App from './App.vue'
|
||||
|
||||
const app = createApp(App)
|
||||
const emitter = mitt()
|
||||
|
||||
Object.keys(Icons).forEach((key) => {
|
||||
app.component(key, Icons[key]);
|
||||
});
|
||||
|
||||
app.use(ElementPlus)
|
||||
app.use(router)
|
||||
app.config.globalProperties.emitter = emitter;
|
||||
|
||||
app.component('Header', Header);
|
||||
app.component('Footer', Footer);
|
||||
app.component('backIndex', backIndex);
|
||||
|
||||
app.mount('#app')
|
@ -0,0 +1,8 @@
|
||||
import axios from "axios";
|
||||
import { ElEmpty } from "element-plus";
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: 'http://localhost:8081'
|
||||
})
|
||||
|
||||
export default request
|
@ -0,0 +1,130 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router"
|
||||
|
||||
const routes= [
|
||||
// 登录相关
|
||||
{
|
||||
path: "/",
|
||||
name: 'login',
|
||||
component: () => import("../components/Login.vue")
|
||||
},
|
||||
{
|
||||
path: "/backLogin",
|
||||
name: 'backLogin',
|
||||
component: () => import("../views/back/backLogin.vue")
|
||||
},
|
||||
{
|
||||
path: '/rescue',
|
||||
name: 'rescue',
|
||||
component: () => import("../components/Rescue.vue")
|
||||
},
|
||||
{
|
||||
path: '/backIndex',
|
||||
name: 'backIndex',
|
||||
component: () => import('../components/backIndex.vue')
|
||||
},
|
||||
|
||||
// 页面组件
|
||||
{
|
||||
path: "/header",
|
||||
name: 'header',
|
||||
component: () => import("../components/Header.vue")
|
||||
},
|
||||
{
|
||||
path: '/carousel',
|
||||
name: 'carousel',
|
||||
component: () => import("../components/Carousel.vue")
|
||||
},
|
||||
{
|
||||
path: "/footer",
|
||||
name: 'footer',
|
||||
component: () => import("../components/Footer.vue")
|
||||
},
|
||||
|
||||
// 前台用户相关页面
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: () => import("../views/home.vue")
|
||||
},
|
||||
{
|
||||
path: '/delivery',
|
||||
name: 'delivery',
|
||||
component: () => import('../views/fore/delivery.vue')
|
||||
},
|
||||
{
|
||||
path: '/check',
|
||||
name: 'check',
|
||||
component: () => import('../views/fore/check.vue')
|
||||
},
|
||||
{
|
||||
path: '/service',
|
||||
name: 'service',
|
||||
component: () => import('../views/fore/service.vue')
|
||||
},
|
||||
{
|
||||
path: '/address',
|
||||
name: 'address',
|
||||
component: () => import('../views/fore/address.vue')
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
name: 'profile',
|
||||
component: () => import('../views/fore/profile.vue')
|
||||
},
|
||||
{
|
||||
path: '/complaint',
|
||||
name: 'complaint',
|
||||
component: () => import('../views/fore/complaint.vue')
|
||||
},
|
||||
{
|
||||
path: '/feedback',
|
||||
name: 'feedback',
|
||||
component: () => import('../views/fore/feedback.vue')
|
||||
},
|
||||
|
||||
// 后台管理页面
|
||||
|
||||
{
|
||||
path: '/shopp',
|
||||
name: 'shopp',
|
||||
component: () => import('../views/back/shopp.vue')
|
||||
},
|
||||
{
|
||||
path: '/addkuaidi',
|
||||
name: 'addkuaidi',
|
||||
component: () => import('../views/back/addkuaidi.vue')
|
||||
},
|
||||
{
|
||||
path: '/personal',
|
||||
name: 'personal',
|
||||
component: () => import('../views/back/personal.vue')
|
||||
},
|
||||
{
|
||||
path: '/problem',
|
||||
name: 'problem',
|
||||
component: () => import('../views/back/problem.vue')
|
||||
},
|
||||
{
|
||||
path: '/notice',
|
||||
name: 'notice',
|
||||
component: () => import('../views/back/notice.vue')
|
||||
},
|
||||
|
||||
// 快递员页面
|
||||
{
|
||||
path: '/indexDeliveryman',
|
||||
name: 'indexDeliveryman',
|
||||
component: () => import('../views/courier/index.vue')
|
||||
},
|
||||
|
||||
// 404 页面
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: () => import('../components/NotFound.vue')
|
||||
}
|
||||
]
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(), routes
|
||||
})
|
||||
|
||||
export default router
|
@ -0,0 +1,18 @@
|
||||
import {
|
||||
defineStore
|
||||
}
|
||||
from "pinia";
|
||||
|
||||
export const userStore = defineStore('storeId', {
|
||||
state: () => {
|
||||
return {
|
||||
loginState: false // 登录状态, 已经登录true没有登录false
|
||||
}
|
||||
},
|
||||
getters: {},
|
||||
actions: {
|
||||
setLoginState(state) {
|
||||
this.loginState = state
|
||||
}
|
||||
}
|
||||
})
|
@ -0,0 +1,79 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header />
|
||||
</el-header>
|
||||
<el-main>
|
||||
<Carousel />
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Header from '../components/Header.vue';
|
||||
import Carousel from '../components/Carousel.vue';
|
||||
import Footer from '../components/Footer.vue';
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-aside {
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.el-main {
|
||||
margin-top: 80px;
|
||||
height: 400px;
|
||||
}
|
||||
.el-footer {
|
||||
margin-top: 100px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<!-- 顶部导航 -->
|
||||
<el-header>
|
||||
<backIndex />
|
||||
</el-header>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<el-container>
|
||||
<el-main>
|
||||
<div style="
|
||||
padding: 20px;
|
||||
max-width: 600px;
|
||||
margin: 30px auto;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
">
|
||||
<h2>录入快件</h2>
|
||||
<!-- 表单部分 -->
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
|
||||
<el-form-item label="单号" prop="trackingNumber">
|
||||
<el-input v-model="form.trackingNumber" placeholder="请输入快递单号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="快递公司" prop="company">
|
||||
<el-select v-model="form.company" placeholder="请选择快递公司">
|
||||
<el-option label="顺丰速运" value="顺丰速运" />
|
||||
<el-option label="中通快递" value="中通快递" />
|
||||
<el-option label="圆通速递" value="圆通速递" />
|
||||
<el-option label="韵达快递" value="韵达快递" />
|
||||
<el-option label="京东物流" value="京东物流" />
|
||||
<el-option label="菜鸟裹裹" value="菜鸟裹裹" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="收件人姓名" prop="recipientName">
|
||||
<el-input v-model="form.recipientName" placeholder="请输入收件人姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="phoneNumber">
|
||||
<el-input v-model="form.phoneNumber" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="管理员姓名" prop="adminName">
|
||||
<el-input v-model="form.adminName" placeholder="请输入管理员姓名" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 提交按钮 -->
|
||||
<div style="text-align: center; margin-top: 20px;">
|
||||
<el-button type="primary" :disabled="!form.trackingNumber ||
|
||||
!form.company ||
|
||||
!form.recipientName ||
|
||||
!form.phoneNumber ||
|
||||
!form.adminName
|
||||
" @click="submitForm">
|
||||
立即提交
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<!-- 底部信息 -->
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
trackingNumber: '',
|
||||
company: '',
|
||||
recipientName: '',
|
||||
phoneNumber: '',
|
||||
adminName: '',
|
||||
});
|
||||
|
||||
// 表单校验规则
|
||||
const rules = {
|
||||
trackingNumber: [{ required: true, message: '请输入快递单号', trigger: 'blur' }],
|
||||
company: [{ required: true, message: '请选择快递公司', trigger: 'change' }],
|
||||
recipientName: [{ required: true, message: '请输入收件人姓名', trigger: 'blur' }],
|
||||
phoneNumber: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
|
||||
adminName: [{ required: true, message: '请输入管理员姓名', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref(null);
|
||||
|
||||
// 提交表单函数
|
||||
const submitForm = () => {
|
||||
if (formRef) {
|
||||
console.log('表单提交成功', form);
|
||||
alert('快递信息提交成功!');
|
||||
} else {
|
||||
alert('请填写完整信息!');
|
||||
}
|
||||
// });
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
div[style*='max-width: 600px;'] {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
div[style*='max-width: 600px;'] {
|
||||
max-width: 90%;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,527 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<backIndex />
|
||||
</el-header>
|
||||
|
||||
<el-container>
|
||||
<el-main class="emain">
|
||||
<div class="management-container">
|
||||
<!-- 用户管理 -->
|
||||
<div class="section">
|
||||
<h3>用户管理</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- 搜索框和添加用户按钮的容器 -->
|
||||
<div class="toolbar">
|
||||
<!-- 用户搜索框 -->
|
||||
<el-input v-model="userSearch" placeholder="输入员工id或用户id" class="user-search" prefix-icon="el-icon-search">
|
||||
</el-input>
|
||||
|
||||
<!-- 添加用户按钮 -->
|
||||
<el-button @click="handleAddUser" type="primary" class="add-user-button">
|
||||
添加用户
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 用户表格 -->
|
||||
<el-table :data="paginatedUsers" stripe style="width: 90%; margin: 20px auto;" border>
|
||||
<el-table-column prop="id" label="用户ID" align="center"></el-table-column>
|
||||
<el-table-column prop="email" label="邮箱" align="center"></el-table-column>
|
||||
<el-table-column prop="password" label="密码" align="center"></el-table-column>
|
||||
<el-table-column prop="phone" label="电话号" align="center"></el-table-column>
|
||||
<el-table-column prop="lastLogin" label="最后登录时间" align="center"></el-table-column>
|
||||
<el-table-column prop="registerTime" label="注册时间" align="center"></el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center">
|
||||
<template v-slot="scope">
|
||||
<div class="button-group">
|
||||
<el-button @click="handleEditUser(scope.row)" size="mini" type="primary" plain>编辑</el-button>
|
||||
<el-button @click="handleDeleteUser(scope.row)" size="mini" type="danger" plain>删除</el-button>
|
||||
<el-button @click="handleViewUser(scope.row)" size="mini" type="info" plain>查看详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页控件 -->
|
||||
<el-pagination :current-page="userCurrentPage" :page-size="userPageSize" :total="userData.length"
|
||||
@current-change="handleUserPageChange" layout="prev, pager, next, jumper" class="pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 快递员管理 -->
|
||||
<div class="section">
|
||||
<h3>快递员管理</h3>
|
||||
|
||||
<!-- 添加快递员按钮 -->
|
||||
<div class="action-buttons">
|
||||
<el-button @click="handleAddCourier" type="primary">添加快递员</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="paginatedCouriers" stripe style="width: 90%; margin: 0 auto;" border>
|
||||
<el-table-column prop="id" label="员工号" align="center"></el-table-column>
|
||||
<el-table-column prop="name" label="姓名" align="center"></el-table-column>
|
||||
<el-table-column prop="status" label="在职状态" align="center"></el-table-column>
|
||||
<el-table-column prop="phone" label="电话" align="center"></el-table-column>
|
||||
<el-table-column prop="entryTime" label="入职时间" align="center"></el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center">
|
||||
<template v-slot="scope">
|
||||
<div class="button-group">
|
||||
<el-button @click="handleEditCourier(scope.row)" size="mini" type="primary" plain>编辑</el-button>
|
||||
<el-button @click="handleDeleteCourier(scope.row)" size="mini" type="danger" plain>删除</el-button>
|
||||
<el-button @click="handleViewCourier(scope.row)" size="mini" type="info" plain>查看详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页控件 -->
|
||||
<el-pagination :current-page="courierCurrentPage" :page-size="courierPageSize" :total="courierData.length"
|
||||
@current-change="handleCourierPageChange" layout="prev, pager, next, jumper" class="pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
|
||||
<!-- 编辑用户对话框 -->
|
||||
<el-dialog title="编辑用户" v-model="editUserDialogVisible">
|
||||
<el-form :model="currentUser">
|
||||
<el-form-item label="用户ID">
|
||||
<el-input v-model="currentUser.id" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="currentUser.email" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="currentUser.password" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话号">
|
||||
<el-input v-model="currentUser.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="editUserDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSaveUserEdit">保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 添加用户对话框 -->
|
||||
<el-dialog title="添加用户" v-model="addUserDialogVisible">
|
||||
<el-form :model="newUser" label-width="100px">
|
||||
<el-form-item label="用户ID">
|
||||
<el-input v-model="newUser.id" placeholder="请输入用户ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="newUser.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="newUser.password" placeholder="请输入密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话号">
|
||||
<el-input v-model="newUser.phone" placeholder="请输入电话号码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="注册时间">
|
||||
<el-date-picker v-model="newUser.registerTime" type="date" placeholder="选择注册时间" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="addUserDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSaveNewUser">保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 编辑快递员对话框 -->
|
||||
<el-dialog title="编辑快递员" v-model="editCourierDialogVisible">
|
||||
<el-form :model="currentCourier">
|
||||
<el-form-item label="员工号">
|
||||
<el-input v-model="currentCourier.id" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="currentCourier.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="在职状态">
|
||||
<el-input v-model="currentCourier.status" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="currentCourier.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="editCourierDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSaveCourierEdit">保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 添加快递员对话框 -->
|
||||
<el-dialog title="添加快递员" v-model="addCourierDialogVisible">
|
||||
<el-form :model="newCourier" label-width="100px">
|
||||
<el-form-item label="员工号">
|
||||
<el-input v-model="newCourier.id" placeholder="请输入员工号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="newCourier.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="在职状态">
|
||||
<el-input v-model="newCourier.status" placeholder="请输入在职状态(如:在职、离职)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="newCourier.phone" placeholder="请输入电话号码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入职时间">
|
||||
<el-date-picker v-model="newCourier.entryTime" type="date" placeholder="选择入职时间" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="addCourierDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSaveNewCourier">保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 查看快递员详情对话框 -->
|
||||
<el-dialog title="快递员详情" v-model="viewCourierDialogVisible">
|
||||
<el-form :model="currentCourier" label-width="100px">
|
||||
<el-form-item label="员工号">
|
||||
<el-input v-model="currentCourier.id" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="currentCourier.name" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="在职状态">
|
||||
<el-input v-model="currentCourier.status" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="currentCourier.phone" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="入职时间">
|
||||
<el-input v-model="currentCourier.entryTime" readonly />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="viewCourierDialogVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 查看详情对话框 -->
|
||||
<!-- 查看用户详情对话框 -->
|
||||
<el-dialog title="查看用户详情" v-model="viewUserDialogVisible">
|
||||
<el-form :model="currentUser" label-width="100px" readonly>
|
||||
<el-form-item label="用户ID">
|
||||
<el-input v-model="currentUser.id" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="currentUser.email" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="currentUser.password" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话号">
|
||||
<el-input v-model="currentUser.phone" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="最后登录时间">
|
||||
<el-input v-model="currentUser.lastLogin" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="注册时间">
|
||||
<el-input v-model="currentUser.registerTime" readonly />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="viewUserDialogVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
// 查看用户详情
|
||||
const viewUserDialogVisible = ref(false)
|
||||
|
||||
|
||||
const handleViewUser = (user) => {
|
||||
currentUser.value = { ...user } // 将选中的用户数据赋值给当前用户对象
|
||||
viewUserDialogVisible.value = true // 显示查看详情对话框
|
||||
}
|
||||
// 查看快递员
|
||||
const viewCourierDialogVisible = ref(false) // 控制查看对话框的显示
|
||||
const handleViewCourier = (courier: any) => {
|
||||
currentCourier.value = { ...courier } // 将当前选择的快递员数据赋值
|
||||
viewCourierDialogVisible.value = true // 打开查看对话框
|
||||
}
|
||||
|
||||
// 添加用户
|
||||
const addUserDialogVisible = ref(false) // 控制添加用户对话框的显示
|
||||
const newUser = ref({
|
||||
id: '', // 用户ID
|
||||
email: '', // 用户邮箱
|
||||
password: '', // 用户密码
|
||||
phone: '', // 用户电话
|
||||
registerTime: '' // 注册时间
|
||||
})
|
||||
|
||||
const handleAddUser = () => {
|
||||
newUser.value = { id: '', email: '', password: '', phone: '', registerTime: '' } // 初始化表单
|
||||
addUserDialogVisible.value = true // 打开添加对话框
|
||||
}
|
||||
|
||||
const handleSaveNewUser = () => {
|
||||
if (!newUser.value.id || !newUser.value.email || !newUser.value.phone) {
|
||||
ElMessage.warning('请完整填写信息')
|
||||
return
|
||||
}
|
||||
// 添加到用户数据
|
||||
|
||||
ElMessage.success('用户添加成功')
|
||||
addUserDialogVisible.value = false // 关闭对话框
|
||||
}
|
||||
|
||||
// 用户和快递员数据
|
||||
const userData = ref([
|
||||
{ id: '001', email: 'user1@example.com', password: 'password123', phone: '13800000001', lastLogin: '2024-11-01 10:30:00', registerTime: '2023-01-15 14:20:00' },
|
||||
{ id: '002', email: 'user2@example.com', password: 'password123', phone: '13800000002', lastLogin: '2024-11-02 12:00:00', registerTime: '2023-02-10 09:15:00' },
|
||||
|
||||
|
||||
// ... 其他用户数据
|
||||
]);
|
||||
const courierData = ref([
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
// ... 其他快递员数据
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
{ id: '001', name: '小刘', status: '在职', phone: '13800000001', entryTime: '2022-03-01' },
|
||||
{ id: '002', name: '小王', status: '离职', phone: '13800000002', entryTime: '2021-06-15' },
|
||||
|
||||
]);
|
||||
|
||||
// 当前用户/快递员
|
||||
const currentUser = ref<any>({})
|
||||
const currentCourier = ref<any>({})
|
||||
|
||||
// 对话框可见性
|
||||
const editUserDialogVisible = ref(false)
|
||||
const editCourierDialogVisible = ref(false)
|
||||
|
||||
// 当前页和分页大小
|
||||
const userPageSize = 5
|
||||
const courierPageSize = 5
|
||||
const userCurrentPage = ref(1)
|
||||
const courierCurrentPage = ref(1)
|
||||
const userSearch = ref('')
|
||||
// 添加快递员
|
||||
const addCourierDialogVisible = ref(false) // 控制添加快递员对话框的显示
|
||||
const newCourier = ref({
|
||||
id: '', // 员工号
|
||||
name: '', // 姓名
|
||||
status: '', // 在职状态
|
||||
phone: '', // 电话
|
||||
entryTime: '' // 入职时间
|
||||
})
|
||||
|
||||
const handleAddCourier = () => {
|
||||
newCourier.value = { id: '', name: '', status: '', phone: '', entryTime: '' } // 初始化表单
|
||||
addCourierDialogVisible.value = true // 打开添加对话框
|
||||
}
|
||||
|
||||
const handleSaveNewCourier = () => {
|
||||
if (!newCourier.value.id || !newCourier.value.name || !newCourier.value.phone) {
|
||||
ElMessage.warning('请完整填写信息')
|
||||
return
|
||||
}
|
||||
// 添加到快递员数据
|
||||
courierData.value.push({ ...newCourier.value })
|
||||
ElMessage.success('快递员添加成功')
|
||||
addCourierDialogVisible.value = false // 关闭对话框
|
||||
}
|
||||
|
||||
// 分页后的用户和快递员数据
|
||||
const paginatedUsers = computed(() => {
|
||||
const start = (userCurrentPage.value - 1) * userPageSize
|
||||
return userData.value.slice(start, start + userPageSize)
|
||||
})
|
||||
const paginatedCouriers = computed(() => {
|
||||
const start = (courierCurrentPage.value - 1) * courierPageSize
|
||||
return courierData.value.slice(start, start + courierPageSize)
|
||||
})
|
||||
|
||||
// 编辑用户
|
||||
const handleEditUser = (user: any) => {
|
||||
currentUser.value = { ...user }
|
||||
editUserDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 编辑快递员
|
||||
const handleEditCourier = (courier: any) => {
|
||||
currentCourier.value = { ...courier }
|
||||
editCourierDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
const handleDeleteUser = (user: any) => {
|
||||
ElMessageBox.confirm(
|
||||
'确定删除该用户吗?',
|
||||
'删除确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
// 删除操作
|
||||
const index = userData.value.findIndex(u => u.id === user.id)
|
||||
if (index !== -1) userData.value.splice(index, 1)
|
||||
ElMessage.success('删除成功')
|
||||
}).catch(() => {
|
||||
ElMessage.info('删除已取消')
|
||||
})
|
||||
}
|
||||
|
||||
// 删除快递员
|
||||
const handleDeleteCourier = (courier: any) => {
|
||||
ElMessageBox.confirm(
|
||||
'确定删除该快递员吗?',
|
||||
'删除确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
// 删除操作
|
||||
const index = courierData.value.findIndex(c => c.id === courier.id)
|
||||
if (index !== -1) courierData.value.splice(index, 1)
|
||||
ElMessage.success('删除成功')
|
||||
}).catch(() => {
|
||||
ElMessage.info('删除已取消')
|
||||
})
|
||||
}
|
||||
|
||||
// 保存用户编辑
|
||||
const handleSaveUserEdit = () => {
|
||||
const index = userData.value.findIndex(u => u.id === currentUser.value.id)
|
||||
if (index !== -1) {
|
||||
userData.value[index] = { ...currentUser.value }
|
||||
ElMessage.success('用户信息已更新')
|
||||
}
|
||||
editUserDialogVisible.value = false
|
||||
}
|
||||
|
||||
// 保存快递员编辑
|
||||
const handleSaveCourierEdit = () => {
|
||||
const index = courierData.value.findIndex(c => c.id === currentCourier.value.id)
|
||||
if (index !== -1) {
|
||||
courierData.value[index] = { ...currentCourier.value }
|
||||
ElMessage.success('快递员信息已更新')
|
||||
}
|
||||
editCourierDialogVisible.value = false
|
||||
}
|
||||
|
||||
// 分页变化
|
||||
const handleUserPageChange = (page: number) => userCurrentPage.value = page
|
||||
const handleCourierPageChange = (page: number) => courierCurrentPage.value = page
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
/* 将内容对齐到右边 */
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.user-search {
|
||||
flex: 0 0 200px;
|
||||
/* 搜索框的固定宽度 */
|
||||
margin-right: 10px;
|
||||
/* 可以根据需要调整这个值 */
|
||||
}
|
||||
|
||||
/* 添加用户按钮 */
|
||||
.add-user-button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.emain {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.management-container {
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.management-container h2 {
|
||||
font-size: 24px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
font-size: 20px;
|
||||
color: #666;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
min-width: 60px;
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.el-table-column {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-table__header-wrapper th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.action-buttons {
|
||||
text-align: right;
|
||||
margin-top: 20px;
|
||||
margin-right: 100px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<backIndex />
|
||||
</el-header>
|
||||
<el-container>
|
||||
<el-main class="emain">
|
||||
<div class="problem-container">
|
||||
|
||||
<!-- 用户问题表格 -->
|
||||
<div class="section">
|
||||
<h3>用户问题</h3>
|
||||
<el-table :data="paginatedUserProblems" stripe style="width: 90%; margin: 0 auto;" border>
|
||||
<el-table-column prop="id" label="ID" align="center"></el-table-column>
|
||||
<el-table-column prop="username" label="用户名" align="center"></el-table-column>
|
||||
<el-table-column prop="title" label="问题标题" align="center" header-align="center"></el-table-column>
|
||||
|
||||
<el-table-column prop="status" label="问题状态" align="center">
|
||||
<template v-slot="scope">
|
||||
<el-tag :type="scope.row.status === '已解决' ? 'success' : 'warning'" disable-transitions>
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="merchantStatus" label="商家回复" width="120" align="center">
|
||||
<template v-slot="scope">
|
||||
<el-tag :type="scope.row.merchantStatus === '已回复' ? 'success' : 'danger'" disable-transitions>
|
||||
{{ scope.row.merchantStatus }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center">
|
||||
<template v-slot="scope">
|
||||
<div class="button-group">
|
||||
<el-button @click="handleResolve(scope.row)" size="mini" type="success" plain>解决</el-button>
|
||||
<el-button @click="handleDelete(scope.row)" size="mini" type="danger" plain>删除</el-button>
|
||||
<el-button @click="handleContact(scope.row)" size="mini" type="primary" plain>联系客户</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页控件 -->
|
||||
<el-pagination :current-page="userCurrentPage" :page-size="userPageSize" :total="userProblemData.length"
|
||||
@current-change="handleUserPageChange" layout="prev, pager, next, jumper" class="pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 快递员问题表格 -->
|
||||
<div class="section">
|
||||
<h3>快递员问题</h3>
|
||||
<el-table :data="paginatedCourierProblems" stripe style="width: 90%; margin: 0 auto;" border>
|
||||
<el-table-column prop="id" label="ID" align="center"></el-table-column>
|
||||
<el-table-column prop="courierName" label="快递员姓名" align="center"></el-table-column>
|
||||
<el-table-column prop="title" label="问题标题" align="center" header-align="center"></el-table-column>
|
||||
|
||||
<el-table-column prop="status" label="问题状态" align="center">
|
||||
<template v-slot="scope">
|
||||
<el-tag :type="scope.row.status === '已解决' ? 'success' : 'warning'" disable-transitions>
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="companyReply" label="公司回复" width="120" align="center">
|
||||
<template v-slot="scope">
|
||||
<el-tag :type="scope.row.companyReply === '已回复' ? 'success' : 'danger'" disable-transitions>
|
||||
{{ scope.row.companyReply }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center">
|
||||
<template v-slot="scope">
|
||||
<div class="button-group">
|
||||
<el-button @click="handleResolve(scope.row)" size="mini" type="success" plain>解决</el-button>
|
||||
<el-button @click="handleDelete(scope.row)" size="mini" type="danger" plain>删除</el-button>
|
||||
<el-button @click="handleContactCourier(scope.row)" size="mini" type="primary"
|
||||
plain>联系快递员</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页控件 -->
|
||||
<el-pagination :current-page="courierCurrentPage" :page-size="courierPageSize"
|
||||
:total="courierProblemData.length" @current-change="handleCourierPageChange"
|
||||
layout="prev, pager, next, jumper" class="pagination" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
const userProblemData = ref([
|
||||
{ id: 1, username: '张三', title: '快递丢失', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 2, username: '李四', title: '配送延迟', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 3, username: '王五', title: '包裹损坏', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 4, username: '赵六', title: '地址错误', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 5, username: '孙七', title: '包装破损', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 6, username: '周八', title: '收件人地址错误', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 7, username: '吴九', title: '物品破损', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 8, username: '郑十', title: '配送信息不符', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 9, username: '钱十一', title: '签收问题', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 10, username: '孙十二', title: '快递丢失', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 11, username: '李十三', title: '包裹迟迟未到', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 12, username: '王十四', title: '派送时效不符合', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 13, username: '赵十五', title: '包装破损', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 14, username: '孙十六', title: '快递迟到', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 15, username: '周十七', title: '配送路线问题', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 16, username: '吴十八', title: '物品丢失', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 17, username: '郑十九', title: '快递员态度差', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 18, username: '钱二十', title: '快递员迟到', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 19, username: '孙二十一', title: '商品损坏', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 20, username: '李二十二', title: '配送不及时', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 21, username: '王二十三', title: '包裹未送达', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 22, username: '赵二十四', title: '地址不清晰', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 23, username: '孙二十五', title: '收件地址错误', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 24, username: '周二十六', title: '派送延误', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 25, username: '吴二十七', title: '包裹破损', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 26, username: '郑二十八', title: '配送信息错误', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 27, username: '钱二十九', title: '包裹无法签收', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 28, username: '孙三十', title: '派送时效问题', status: '已解决', merchantStatus: '已回复' },
|
||||
{ id: 29, username: '李三十一', title: '快递包裹丢失', status: '未解决', merchantStatus: '未回复' },
|
||||
{ id: 30, username: '王三十二', title: '物流追踪问题', status: '已解决', merchantStatus: '已回复' }
|
||||
])
|
||||
|
||||
const courierProblemData = ref([
|
||||
{ id: 1, courierName: '小刘', title: '车辆故障', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 2, courierName: '小王', title: '路线不清', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 3, courierName: '小李', title: '客户未取件', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 4, courierName: '小张', title: '包裹丢失', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 5, courierName: '小赵', title: '快递迟到', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 3, courierName: '小李', title: '客户未取件', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 4, courierName: '小张', title: '包裹丢失', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 5, courierName: '小赵', title: '快递迟到', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 6, courierName: '小陈', title: '包裹损坏', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 7, courierName: '小黄', title: '快递错发', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 8, courierName: '小李', title: '包裹丢失', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 9, courierName: '小刘', title: '客户未取件', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 10, courierName: '小王', title: '快递迟到', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 11, courierName: '小张', title: '车辆故障', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 12, courierName: '小赵', title: '路线不清', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 13, courierName: '小陈', title: '包裹丢失', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 14, courierName: '小黄', title: '客户未取件', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 15, courierName: '小李', title: '快递错发', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 16, courierName: '小刘', title: '车辆故障', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 17, courierName: '小王', title: '快递迟到', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 18, courierName: '小张', title: '客户未取件', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 19, courierName: '小赵', title: '包裹丢失', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 20, courierName: '小陈', title: '快递错发', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 21, courierName: '小黄', title: '包裹损坏', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 22, courierName: '小李', title: '路线不清', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 23, courierName: '小刘', title: '快递迟到', status: '已解决', companyReply: '已回复' },
|
||||
{ id: 24, courierName: '小王', title: '车辆故障', status: '未解决', companyReply: '未回复' },
|
||||
{ id: 25, courierName: '小张', title: '快递错发', status: '已解决', companyReply: '已回复' },
|
||||
// 可以继续增加数据
|
||||
])
|
||||
|
||||
const userPageSize = 10 // 每页显示的数量
|
||||
const courierPageSize = 10 // 每页显示的数量
|
||||
|
||||
const userCurrentPage = ref(1) // 当前页数
|
||||
const courierCurrentPage = ref(1) // 当前页数
|
||||
|
||||
// 分页后的用户问题数据
|
||||
const paginatedUserProblems = computed(() => {
|
||||
const start = (userCurrentPage.value - 1) * userPageSize
|
||||
return userProblemData.value.slice(start, start + userPageSize)
|
||||
})
|
||||
|
||||
// 分页后的快递员问题数据
|
||||
const paginatedCourierProblems = computed(() => {
|
||||
const start = (courierCurrentPage.value - 1) * courierPageSize
|
||||
return courierProblemData.value.slice(start, start + courierPageSize)
|
||||
})
|
||||
|
||||
// 用户问题页数变化时
|
||||
const handleUserPageChange = (page: number) => {
|
||||
userCurrentPage.value = page
|
||||
}
|
||||
|
||||
// 快递员问题页数变化时
|
||||
const handleCourierPageChange = (page: number) => {
|
||||
courierCurrentPage.value = page
|
||||
}
|
||||
|
||||
const handleResolve = (row: any) => {
|
||||
console.log('解决问题', row)
|
||||
row.status = '已解决'
|
||||
}
|
||||
|
||||
const handleDelete = (row: any) => {
|
||||
console.log('删除问题', row)
|
||||
}
|
||||
|
||||
const handleContact = (row: any) => {
|
||||
console.log('联系客户', row)
|
||||
}
|
||||
|
||||
const handleContactCourier = (row: any) => {
|
||||
console.log('联系快递员', row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.emain {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.problem-container {
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.problem-container h2 {
|
||||
font-size: 24px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
font-size: 20px;
|
||||
color: #666;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
|
||||
}
|
||||
|
||||
.el-button {
|
||||
min-width: 60px;
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
/* 居中分页 */
|
||||
}
|
||||
|
||||
.el-table-column {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-table__header-wrapper th {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<el-container style="height: 100vh;">
|
||||
<!-- 顶部标题 -->
|
||||
<el-header style="background-color: #A8B9C9; color: #F2F8FE; text-align: center; font-size: 24px; padding: 20px;">
|
||||
快递员中心
|
||||
</el-header>
|
||||
|
||||
<el-container>
|
||||
<!-- 左侧菜单栏 -->
|
||||
<el-aside width="250px" style="background-color: #f4f6f9;">
|
||||
<el-menu :default-active="currentTab" class="el-menu-vertical-demo" @select="handleTabChange">
|
||||
<el-menu-item index="toDeliver">待配送订单</el-menu-item>
|
||||
<el-menu-item index="history">历史订单</el-menu-item>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<el-main style="padding: 20px;">
|
||||
<!-- 待配送订单 -->
|
||||
<el-row v-if="currentTab === 'toDeliver'" class="order-card">
|
||||
<h3>待配送订单</h3>
|
||||
<div class="button-container">
|
||||
<el-button type="primary" @click="openAddOrderDialog" class="btn">新增订单</el-button>
|
||||
</div>
|
||||
<el-table :data="toDeliverOrders" border stripe>
|
||||
<el-table-column prop="id" label="订单编号" width="180" />
|
||||
<el-table-column prop="receiver" label="收件人" width="180" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
<el-table-column prop="status" label="状态" width="120" />
|
||||
<el-table-column label="操作" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.status === '待取件'" type="primary" size="small"
|
||||
@click="updateStatus(row, '配送中')">开始配送</el-button>
|
||||
<el-button v-if="row.status === '配送中'" type="success" size="small"
|
||||
@click="updateStatus(row, '已完成')">完成配送</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
|
||||
<!-- 历史订单 -->
|
||||
<el-row v-if="currentTab === 'history'" class="order-card">
|
||||
<h3>历史订单</h3>
|
||||
<el-table :data="historyOrders" border stripe>
|
||||
<el-table-column prop="id" label="订单编号" width="180" />
|
||||
<el-table-column prop="receiver" label="收件人" width="180" />
|
||||
<el-table-column prop="address" label="地址" />
|
||||
<el-table-column prop="status" label="状态" width="120" />
|
||||
<el-table-column prop="deliveryTime" label="配送时间" width="180" />
|
||||
<el-table-column label="操作" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-button type="danger" size="small" @click="deleteHistoryOrder(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
|
||||
</el-main>
|
||||
|
||||
<!-- 新增订单对话框 -->
|
||||
<el-dialog title="新增订单" v-model="addOrderDialogVisible" width="400px" align-center>
|
||||
<el-form :model="newOrder" ref="newOrderForm" label-width="100px">
|
||||
<el-form-item label="订单编号">
|
||||
<el-input v-model="newOrder.id" placeholder="请输入订单编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收件人">
|
||||
<el-input v-model="newOrder.receiver" placeholder="请输入收件人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="newOrder.address" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="newOrder.status" placeholder="请选择状态">
|
||||
<el-option label="待取件" value="待取件" />
|
||||
<el-option label="配送中" value="配送中" />
|
||||
<el-option label="已完成" value="已完成" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row slot="footer" class="dialog-footer">
|
||||
<el-button @click="addOrderDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="addOrder">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
|
||||
// State
|
||||
const currentTab = ref('toDeliver');
|
||||
const addOrderDialogVisible = ref(false); // 控制新增订单对话框的显示
|
||||
const newOrder = ref({
|
||||
id: '',
|
||||
receiver: '',
|
||||
address: '',
|
||||
status: '待取件'
|
||||
});
|
||||
|
||||
const toDeliverOrders = ref([{
|
||||
id: '001',
|
||||
receiver: '李四',
|
||||
address: '北京市朝阳区',
|
||||
status: '待取件'
|
||||
},
|
||||
{
|
||||
id: '002',
|
||||
receiver: '王五',
|
||||
address: '北京市海淀区',
|
||||
status: '待取件'
|
||||
},
|
||||
{
|
||||
id: '003',
|
||||
receiver: '赵六',
|
||||
address: '北京市昌平区',
|
||||
status: '配送中'
|
||||
}
|
||||
]);
|
||||
|
||||
const historyOrders = ref([{
|
||||
id: '004',
|
||||
receiver: '孙七',
|
||||
address: '北京市东城区',
|
||||
status: '已完成',
|
||||
deliveryTime: '2024-10-10 14:00'
|
||||
},
|
||||
{
|
||||
id: '005',
|
||||
receiver: '周八',
|
||||
address: '北京市西城区',
|
||||
status: '已完成',
|
||||
deliveryTime: '2024-10-12 15:30'
|
||||
}
|
||||
]);
|
||||
|
||||
// Methods
|
||||
const updateStatus = (order, newStatus) => {
|
||||
const orderIndex = toDeliverOrders.value.findIndex(o => o.id === order.id);
|
||||
if (orderIndex !== -1) {
|
||||
toDeliverOrders.value[orderIndex].status = newStatus;
|
||||
if (newStatus === '已完成') {
|
||||
historyOrders.value.push({
|
||||
...toDeliverOrders.value[orderIndex],
|
||||
deliveryTime: new Date().toLocaleString()
|
||||
});
|
||||
toDeliverOrders.value.splice(orderIndex, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deleteHistoryOrder = (order) => {
|
||||
const index = historyOrders.value.findIndex(o => o.id === order.id);
|
||||
if (index !== -1) {
|
||||
historyOrders.value.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTabChange = (index) => {
|
||||
currentTab.value = index;
|
||||
};
|
||||
|
||||
const openAddOrderDialog = () => {
|
||||
addOrderDialogVisible.value = true;
|
||||
};
|
||||
|
||||
const addOrder = () => {
|
||||
if (newOrder.value.id && newOrder.value.receiver && newOrder.value.address) {
|
||||
toDeliverOrders.value.push({
|
||||
...newOrder.value
|
||||
});
|
||||
newOrder.value = {
|
||||
id: '',
|
||||
receiver: '',
|
||||
address: '',
|
||||
status: '待取件'
|
||||
}; // 清空表单
|
||||
addOrderDialogVisible.value = false; // 关闭对话框
|
||||
} else {
|
||||
alert('请填写完整订单信息');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.btn {
|
||||
margin-left: 1200px;
|
||||
}
|
||||
|
||||
.order-card {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background-color: #f2f3f5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-table td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-menu-vertical-demo {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-menu-item {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
text-align: right;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header />
|
||||
</el-header>
|
||||
|
||||
<el-container>
|
||||
<el-main>
|
||||
<!-- 地址列表 -->
|
||||
<el-row class="address-container">
|
||||
<el-button type="primary" @click="showAddDialog">新增地址</el-button>
|
||||
<el-table :data="addressList" style="width: 100%; margin-top: 20px;">
|
||||
<el-table-column prop="name" label="联系人" width="180"></el-table-column>
|
||||
<el-table-column prop="phone" label="电话" width="180"></el-table-column>
|
||||
<el-table-column prop="fullAddress" label="地址"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="mini" @click="editAddress(scope.row)">编辑</el-button>
|
||||
<el-button size="mini" type="danger" @click="deleteAddress(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
|
||||
<!-- 新增地址弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" align-center>
|
||||
<el-form :model="newAddress" :rules="rules" ref="addressForm" label-width="120px">
|
||||
<el-form-item label="联系人" prop="name">
|
||||
<el-input v-model="newAddress.name" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="newAddress.phone" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="省市" prop="provinceCity">
|
||||
<el-cascader v-model="newAddress.provinceCity" autocomplete="off" :options="provinceCityOptions" placeholder="选择省市"
|
||||
:props="{ expandTrigger: 'hover' }" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model="newAddress.address" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row class="dialog-footer">
|
||||
<el-button @click="cancelDialog">取消</el-button>
|
||||
<el-button type="primary" @click="saveAddress">保存</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, computed, watch } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import addressListJson from '../../assets/addressList.js';
|
||||
|
||||
// 初始化地址列表
|
||||
const addressList = ref([
|
||||
{ name: '陈子润', phone: '19502407201', fullAddress: '福建省福州市杨桥西路50号福州大学至诚学院' }
|
||||
]);
|
||||
|
||||
|
||||
// 弹窗显示状态
|
||||
const dialogVisible = ref(false);
|
||||
// 弹窗标题
|
||||
const dialogTitle = ref('新增地址');
|
||||
// 编辑索引
|
||||
const editingIndex = ref(-1);
|
||||
// 新地址对象
|
||||
const newAddress = reactive({
|
||||
name: '',
|
||||
phone: '',
|
||||
provinceCity: [],
|
||||
address: ''
|
||||
});
|
||||
|
||||
// 省市区数据格式化
|
||||
const formatCityData = (arr) => {
|
||||
return arr.map(item => ({
|
||||
value: item.name,
|
||||
label: item.name,
|
||||
children: item.sub && item.sub.length > 0 ? formatCityData(item.sub) : []
|
||||
}));
|
||||
};
|
||||
|
||||
// 省市区数据
|
||||
const provinceCityOptions = computed(() => formatCityData(addressListJson));
|
||||
|
||||
// 校验规则
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
||||
phone: [
|
||||
{ required: true, message: '请输入电话号码', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号', trigger: 'blur' }
|
||||
],
|
||||
address: [{ required: true, message: '请输入地址', trigger: 'blur' }]
|
||||
};
|
||||
|
||||
// 表单实例
|
||||
const addressForm = ref();
|
||||
|
||||
// 新增地址弹窗
|
||||
const showAddDialog = () => {
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 保存地址
|
||||
const saveAddress = () => {
|
||||
addressForm.value.validate((valid) => {
|
||||
if (valid) {
|
||||
const fullAddress = `${newAddress.provinceCity.join('')}${newAddress.address}`;
|
||||
if (editingIndex.value === -1) {
|
||||
// 新增地址
|
||||
addressList.value.push({ ...newAddress, fullAddress });
|
||||
ElMessage.success('地址新增成功');
|
||||
} else {
|
||||
// 编辑地址
|
||||
addressList.value[editingIndex.value] = { ...newAddress, fullAddress };
|
||||
ElMessage.success('地址修改成功');
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
addressForm.value.resetFields();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑地址
|
||||
const editAddress = (address) => {
|
||||
dialogTitle.value = '编辑地址';
|
||||
editingIndex.value = addressList.value.findIndex((item) => item === address);
|
||||
newAddress.name = address.name;
|
||||
newAddress.phone = address.phone;
|
||||
newAddress.address = address.address;
|
||||
newAddress.provinceCity = address.provinceCity || [];
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除地址
|
||||
const deleteAddress = (address) => {
|
||||
ElMessageBox.confirm('确认删除该地址吗?', '提示', {
|
||||
type: 'warning',
|
||||
showCancelButton: true
|
||||
}).then(() => {
|
||||
addressList.value = addressList.value.filter((item) => item !== address);
|
||||
ElMessage.success('地址删除成功');
|
||||
});
|
||||
};
|
||||
|
||||
// 取消弹窗
|
||||
const cancelDialog = () => {
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
// 监听弹窗显示状态
|
||||
watch(dialogVisible, (newValue) => {
|
||||
if (!newValue) {
|
||||
addressForm.value?.resetFields();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.address-container {
|
||||
margin-top: 50px;
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,406 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<!-- 导航栏 -->
|
||||
<el-header>
|
||||
<Header />
|
||||
</el-header>
|
||||
|
||||
<el-main>
|
||||
<div class="container">
|
||||
<!-- 标题、输入框和按钮 -->
|
||||
<div class="top-section">
|
||||
<h1 class="title">运单查询</h1>
|
||||
<div class="input-group">
|
||||
<el-input
|
||||
v-model="form.trackingNumber"
|
||||
placeholder="请输入快递单号"
|
||||
clearable
|
||||
style="width: 300px; margin-right: 20px;"
|
||||
@input="validateTrackingNumber"
|
||||
@keyup.enter="searchPackage"
|
||||
></el-input>
|
||||
<el-button @click="searchPackage" type="primary" :loading="loading">查询</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选项卡 -->
|
||||
<el-tabs v-model="activeTab" type="card" style="margin-top: 20px;" @tab-click="handleTabClick">
|
||||
<el-tab-pane label="我寄的" name="sent">
|
||||
<el-table v-if="sentPackages.length" :data="sentPackages" style="margin-top: 20px;">
|
||||
<el-table-column label="快递单号" prop="trackingNumber"></el-table-column>
|
||||
<el-table-column label="包裹名称" prop="packageName"></el-table-column>
|
||||
<el-table-column label="寄件人" prop="sender"></el-table-column>
|
||||
<el-table-column label="寄件人地址" prop="senderaddress"></el-table-column>
|
||||
<el-table-column label="收件人" prop="receiver"></el-table-column>
|
||||
<el-table-column label="收件人地址" prop="receiveraddress"></el-table-column>
|
||||
<el-table-column label="状态" prop="status">
|
||||
<template #default="scope">
|
||||
<span :class="getStatusClass(scope.row.status)">{{ scope.row.status }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="最新位置" prop="latestLocation"></el-table-column>
|
||||
</el-table>
|
||||
<p v-else>暂无数据</p>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="我收的" name="received">
|
||||
<el-table v-if="receivedPackages.length" :data="receivedPackages" style="margin-top: 20px;">
|
||||
<el-table-column label="快递单号" prop="trackingNumber"></el-table-column>
|
||||
<el-table-column label="包裹名称" prop="packageName"></el-table-column>
|
||||
<el-table-column label="寄件人地址" prop="senderaddress"></el-table-column>
|
||||
<el-table-column label="寄件人" prop="sender"></el-table-column>
|
||||
<el-table-column label="收件人地址" prop="receiveraddress"></el-table-column>
|
||||
<el-table-column label="收件人" prop="receiver"></el-table-column>
|
||||
<el-table-column label="状态" prop="status">
|
||||
<template #default="scope">
|
||||
<span :class="getStatusClass(scope.row.status)">{{ scope.row.status }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="最新位置" prop="latestLocation"></el-table-column>
|
||||
</el-table>
|
||||
<p v-else>暂无数据</p>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-main>
|
||||
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox, ElInput, ElButton, ElTable, ElTableColumn } from 'element-plus'
|
||||
|
||||
// 定义包裹数据的类型
|
||||
interface Package {
|
||||
trackingNumber: string;
|
||||
packageName: string;
|
||||
sender: string;
|
||||
senderaddress: string;
|
||||
receiver: string;
|
||||
receiveraddress: string;
|
||||
status: string;
|
||||
latestLocation: string;
|
||||
}
|
||||
|
||||
// 模拟数据
|
||||
const mockData: Package[] = [
|
||||
{
|
||||
trackingNumber: '123',
|
||||
packageName: '书籍',
|
||||
sender: '张帅齐',
|
||||
senderaddress: '北京市海淀区',
|
||||
receiver: '李四',
|
||||
receiveraddress: '上海市浦东新区',
|
||||
status: '未签收',
|
||||
latestLocation: '北京市海淀区',
|
||||
},
|
||||
{
|
||||
trackingNumber: '456',
|
||||
packageName: '衣物',
|
||||
sender: '林涛',
|
||||
senderaddress: '上海市浦东新区',
|
||||
receiver: '李四',
|
||||
receiveraddress: '北京市海淀区',
|
||||
status: '正在运输',
|
||||
latestLocation: '上海市浦东新区',
|
||||
},
|
||||
{
|
||||
trackingNumber: '789',
|
||||
packageName: '电子产品',
|
||||
sender: '陈子润',
|
||||
senderaddress: '北京市海淀区',
|
||||
receiver: '李四',
|
||||
receiveraddress: '北京市海淀区',
|
||||
status: '已签收',
|
||||
latestLocation: '北京市海淀区',
|
||||
},
|
||||
{
|
||||
trackingNumber: '011',
|
||||
packageName: '书籍',
|
||||
sender: '张帅齐',
|
||||
senderaddress: '北京市海淀区',
|
||||
receiver: '李四',
|
||||
receiveraddress: '北京市海淀区',
|
||||
status: '已签收',
|
||||
latestLocation: '北京市海淀区',
|
||||
},
|
||||
{
|
||||
trackingNumber: '012',
|
||||
packageName: '书籍',
|
||||
sender: '孙贺贺',
|
||||
senderaddress: '北京市海淀区',
|
||||
receiver: '李四',
|
||||
receiveraddress: '北京市海淀区',
|
||||
status: '已签收',
|
||||
latestLocation: '北京市海淀区',
|
||||
},
|
||||
{
|
||||
trackingNumber: '013',
|
||||
packageName: '书籍',
|
||||
sender: '梁佳琪',
|
||||
senderaddress: '北京市海淀区',
|
||||
receiver: '李四',
|
||||
receiveraddress: '北京市海淀区',
|
||||
status: '未签收',
|
||||
latestLocation: '北京市海淀区',
|
||||
}
|
||||
]
|
||||
|
||||
const form = ref({
|
||||
trackingNumber: ''
|
||||
})
|
||||
|
||||
const activeTab = ref('sent')
|
||||
|
||||
const sentPackages = ref<Package[]>([]) // 初始为空数组
|
||||
const receivedPackages = ref<Package[]>([]) // 初始为空数组
|
||||
|
||||
const error = ref('')
|
||||
const loading = ref(false)
|
||||
|
||||
// 验证快递单号
|
||||
const validateTrackingNumber = () => {
|
||||
if (form.value.trackingNumber && !/^\d+$/.test(form.value.trackingNumber)) {
|
||||
error.value = '快递单号只能包含数字'
|
||||
} else {
|
||||
error.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 处理选项卡点击事件
|
||||
const handleTabClick = (tab: any) => {
|
||||
// 清空当前的包裹数据
|
||||
sentPackages.value = [];
|
||||
receivedPackages.value = [];
|
||||
|
||||
if (tab.paneName === 'sent') {
|
||||
sentPackages.value = mockData.filter(item => ['123', '456', '789'].includes(item.trackingNumber));
|
||||
activeTab.value = 'sent'; // 确保 activeTab 更新
|
||||
} else if (tab.paneName === 'received') {
|
||||
receivedPackages.value = mockData.filter(item => ['011', '012', '013'].includes(item.trackingNumber));
|
||||
activeTab.value = 'received'; // 确保 activeTab 更新
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化加载“我寄的”运单数据
|
||||
const initSentPackages = () => {
|
||||
sentPackages.value = mockData.filter(item => ['123', '456', '789'].includes(item.trackingNumber));
|
||||
}
|
||||
|
||||
// 在组件初始化时调用
|
||||
onMounted(() => {
|
||||
initSentPackages();
|
||||
})
|
||||
|
||||
// 查询包裹的函数
|
||||
const searchPackage = async () => {
|
||||
if (!form.value.trackingNumber) {
|
||||
ElMessage.error('请输入快递单号')
|
||||
return
|
||||
}
|
||||
|
||||
if (error.value) {
|
||||
ElMessageBox.alert(error.value, '错误', {
|
||||
confirmButtonText: '确定',
|
||||
type: 'error',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const result = mockData.find(item => item.trackingNumber === form.value.trackingNumber)
|
||||
if (result) {
|
||||
ElMessage.success('查询成功')
|
||||
// 自动跳转到对应的选项卡
|
||||
if (['123', '456', '789'].includes(result.trackingNumber)) {
|
||||
activeTab.value = 'sent'
|
||||
sentPackages.value = [result] // 只显示查询到的包裹
|
||||
receivedPackages.value = [] // 清空收到的包裹
|
||||
} else if (['011', '012', '013'].includes(result.trackingNumber)) {
|
||||
activeTab.value = 'received'
|
||||
receivedPackages.value = [result] // 只显示查询到的包裹
|
||||
sentPackages.value = [] // 清空寄出的包裹
|
||||
}
|
||||
} else {
|
||||
ElMessageBox.alert('未找到该快递单号的信息,请确认单号是否正确。', '错误', {
|
||||
confirmButtonText: '确定',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态的颜色类
|
||||
const getStatusClass = (status: string) => {
|
||||
switch (status) {
|
||||
case '已签收':
|
||||
return 'status-success';
|
||||
case '正在运输':
|
||||
return 'status-warning';
|
||||
default:
|
||||
return 'status-fail';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 将容器设置为 flex 布局,居中对齐 */
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start; /* 从顶部开始排列 */
|
||||
padding: 20px;
|
||||
/* background: #f5f5f5; */
|
||||
}
|
||||
|
||||
/* 标题样式 */
|
||||
.title {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
margin-top: 0px; /* 为标题留出导航栏的空间 */
|
||||
}
|
||||
|
||||
/* 顶部区域样式 */
|
||||
.top-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
/* 输入框和按钮容器 */
|
||||
.input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.input-group .el-input {
|
||||
margin-right: 20px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 表格样式 */
|
||||
.el-table {
|
||||
width: 100%;
|
||||
max-width: 1000px; /* 增加表格的最大宽度 */
|
||||
margin-top: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-table th,
|
||||
.el-table td {
|
||||
text-align: center;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background: #f0f0f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-table tr:nth-child(even) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.el-table tr:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
/* 状态颜色样式 */
|
||||
.status-success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.status-fail {
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.status-warning {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
/* 选项卡样式 */
|
||||
.el-tabs {
|
||||
width: 100%;
|
||||
max-width: 1000px; /* 增加选项卡的最大宽度 */
|
||||
margin-top: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-tabs__header {
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
background: #f0f0f0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.el-tabs__nav-wrap::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
padding: 0 20px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
transition: background 0.3s, color 0.3s, border-bottom 0.3s;
|
||||
border-bottom: 2px solid transparent; /* 默认情况下没有下划线 */
|
||||
}
|
||||
|
||||
.el-tabs__item.is-active {
|
||||
background: #fff;
|
||||
color: #409eff;
|
||||
border-bottom: 2px solid red !important; /* 激活状态下有红色下划线 */
|
||||
}
|
||||
|
||||
.el-tabs__item:hover {
|
||||
background: #e0e0e0;
|
||||
color: #409eff;
|
||||
border-bottom: 2px solid #f60d0d !important; /* 悬停时有下划线 */
|
||||
}
|
||||
|
||||
/* Element UI 容器样式 */
|
||||
.el-header {
|
||||
padding: 0;
|
||||
height: 100;
|
||||
}
|
||||
|
||||
.el-main {
|
||||
margin-top: 80px;
|
||||
padding: 20px 0;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - 200px); /* 调整高度以适应屏幕 */
|
||||
}
|
||||
|
||||
.el-footer {
|
||||
margin-top: 0px;
|
||||
padding: 20px 0;
|
||||
/* background: #333; */
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header />
|
||||
</el-header>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<div class="complaint-container">
|
||||
<h2>快递投诉</h2>
|
||||
<el-form
|
||||
:model="complaintForm"
|
||||
:rules="rules"
|
||||
ref="complaintFormRef"
|
||||
label-width="100px"
|
||||
class="complaint-form"
|
||||
>
|
||||
<el-form-item label="订单号" prop="orderNumber">
|
||||
<el-input v-model="complaintForm.orderNumber" placeholder="请输入订单号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="投诉原因" prop="reason">
|
||||
<el-select v-model="complaintForm.reason" placeholder="请选择投诉原因">
|
||||
<el-option label="快递未按时送达" value="未按时送达" />
|
||||
<el-option label="快递损坏或丢失" value="损坏或丢失" />
|
||||
<el-option label="服务态度差" value="服务态度差" />
|
||||
<el-option label="其他问题" value="其他" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细描述" prop="description">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="complaintForm.description"
|
||||
placeholder="请详细描述您的问题"
|
||||
rows="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="联系方式" prop="contact">
|
||||
<el-input v-model="complaintForm.contact" placeholder="请输入您的联系方式" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitComplaint">提交投诉</el-button>
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const complaintForm = ref({
|
||||
orderNumber: '',
|
||||
reason: '',
|
||||
description: '',
|
||||
contact: '',
|
||||
});
|
||||
|
||||
const rules = {
|
||||
orderNumber: [
|
||||
{ required: true, message: '订单号不能为空', trigger: 'blur' },
|
||||
],
|
||||
reason: [
|
||||
{ required: true, message: '请选择投诉原因', trigger: 'change' },
|
||||
],
|
||||
description: [
|
||||
{ required: true, message: '请详细描述问题', trigger: 'blur' },
|
||||
{ min: 10, message: '描述至少需要10个字', trigger: 'blur' },
|
||||
],
|
||||
contact: [
|
||||
{ required: true, message: '联系方式不能为空', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
message: '请输入有效的手机号码',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const complaintFormRef = ref();
|
||||
|
||||
const submitComplaint = () => {
|
||||
complaintFormRef.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
ElMessage.success('投诉已提交,我们将尽快处理您的问题!');
|
||||
resetForm();
|
||||
} else {
|
||||
ElMessage.error('请检查表单内容是否填写完整!');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
complaintFormRef.value?.resetFields();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.complaint-container {
|
||||
max-width: 600px;
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.complaint-form {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header />
|
||||
</el-header>
|
||||
<el-main>
|
||||
<div class="service-list-container">
|
||||
<ul class="service-list">
|
||||
<li>
|
||||
<el-image src="src/assets/time.png"></el-image>
|
||||
<div>
|
||||
<p>运费时效</p>
|
||||
<p>查预估费用和预计送达时间</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-image src="src/assets/serviceSpot.png"></el-image>
|
||||
<div>
|
||||
<p>服务网点</p>
|
||||
<p>查各地网点、丰巢柜、合作点</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-image src="src/assets/require.png"></el-image>
|
||||
<div>
|
||||
<p>收寄标准</p>
|
||||
<p>查物品能不能寄</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-image src="src/assets/serviceRange.png"></el-image>
|
||||
<div>
|
||||
<p>服务范围</p>
|
||||
<p>查地址能不能收派</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="service-list">
|
||||
<li>
|
||||
<el-icon><DataLine /></el-icon>
|
||||
<div>
|
||||
<p>汇率查询</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-icon><Document /></el-icon>
|
||||
<div>
|
||||
<p>常用表格</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-icon><SetUp /></el-icon>
|
||||
<div>
|
||||
<p>清关服务</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-icon><DataBoard /></el-icon>
|
||||
<div>
|
||||
<p>无着件公示</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-icon><HomeFilled /></el-icon>
|
||||
<div>
|
||||
<p>特殊入仓地址查询</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<el-icon><Download /></el-icon>
|
||||
<div>
|
||||
<p>电子回单下载</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<Footer />
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.service-list-container {
|
||||
padding: 20px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.service-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.service-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.service-list li {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
border: 1px solid #eaeaea;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.service-list img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.service-list div {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.service-list p {
|
||||
margin: 5px 0;
|
||||
}
|
||||
.el-icon{
|
||||
font-size: 30px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,12 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import path from 'path'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
}
|
||||
}
|
||||
})
|