初始化
This commit is contained in:
commit
8a19c93d22
5
.editorconfig
Normal file
5
.editorconfig
Normal file
@ -0,0 +1,5 @@
|
||||
[*.{js,jsx,ts,tsx,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
24
README.md
Normal file
24
README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# ecs_vue
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
5
babel.config.js
Normal file
5
babel.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
19
jsconfig.json
Normal file
19
jsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
22322
package-lock.json
generated
Normal file
22322
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
51
package.json
Normal file
51
package.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "ecs_vue",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"@vue/eslint-config-standard": "^6.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/vue3-essential",
|
||||
"@vue/standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "@babel/eslint-parser"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead",
|
||||
"not ie 11"
|
||||
]
|
||||
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
17
public/index.html
Normal file
17
public/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
26
src/App.vue
Normal file
26
src/App.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
6
src/main.js
Normal file
6
src/main.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
|
||||
createApp(App).use(store).use(router).mount('#app')
|
56
src/router/index.js
Normal file
56
src/router/index.js
Normal file
@ -0,0 +1,56 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Login from '../views/auth/Login.vue'
|
||||
import Register from '../views/auth/Register.vue'
|
||||
import AdminDashboard from '../views/admin/AdminDashboard.vue'
|
||||
import StaffDashboard from '../views/staff/StaffDashboard.vue'
|
||||
import CustomerDashboard from '../views/customer/CustomerDashboard.vue'
|
||||
import CustomerHome from '../views/customer/CustomerHome.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/login'
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: Login
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
name: 'Register',
|
||||
component: Register
|
||||
},
|
||||
{
|
||||
path: '/admin',
|
||||
name: 'AdminDashboard',
|
||||
component: AdminDashboard,
|
||||
meta: { requiresAuth: true, role: 'admin' }
|
||||
},
|
||||
{
|
||||
path: '/staff',
|
||||
name: 'StaffDashboard',
|
||||
component: StaffDashboard,
|
||||
meta: { requiresAuth: true, role: 'staff' }
|
||||
},
|
||||
{
|
||||
path: '/customer',
|
||||
name: 'CustomerDashboard',
|
||||
component: CustomerDashboard,
|
||||
meta: { requiresAuth: true, role: 'customer' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'CustomerHome',
|
||||
component: CustomerHome
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(process.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
14
src/store/index.js
Normal file
14
src/store/index.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { createStore } from 'vuex'
|
||||
|
||||
export default createStore({
|
||||
state: {
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
}
|
||||
})
|
143
src/views/admin/AdminDashboard.vue
Normal file
143
src/views/admin/AdminDashboard.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<div class="admin-dashboard">
|
||||
<header class="dashboard-header">
|
||||
<h1>管理员控制台</h1>
|
||||
<button @click="logout">退出登录</button>
|
||||
</header>
|
||||
|
||||
<div class="dashboard-content">
|
||||
<nav class="sidebar">
|
||||
<ul>
|
||||
<li @click="currentView = 'staff'">员工管理</li>
|
||||
<li @click="currentView = 'customers'">顾客管理</li>
|
||||
<li @click="currentView = 'services'">服务管理</li>
|
||||
<li @click="currentView = 'reports'">统计报表</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main class="main-content">
|
||||
<!-- 员工管理 -->
|
||||
<div v-if="currentView === 'staff'" class="staff-management">
|
||||
<h2>员工管理</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>员工ID</th>
|
||||
<th>姓名</th>
|
||||
<th>职位</th>
|
||||
<th>联系方式</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="staff in staffList" :key="staff.id">
|
||||
<td>{{ staff.id }}</td>
|
||||
<td>{{ staff.name }}</td>
|
||||
<td>{{ staff.position }}</td>
|
||||
<td>{{ staff.contact }}</td>
|
||||
<td>
|
||||
<button @click="editStaff(staff)">编辑</button>
|
||||
<button @click="deleteStaff(staff.id)">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 其他视图可以根据需要添加 -->
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AdminDashboard',
|
||||
data () {
|
||||
return {
|
||||
currentView: 'staff',
|
||||
staffList: [
|
||||
{ id: 1, name: '张三', position: '护工', contact: '13800138000' },
|
||||
{ id: 2, name: '李四', position: '护士', contact: '13800138001' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout () {
|
||||
// 实现退出登录逻辑
|
||||
this.$router.push('/login')
|
||||
},
|
||||
editStaff (staff) {
|
||||
// 实现编辑员工逻辑
|
||||
console.log('编辑员工:', staff)
|
||||
},
|
||||
deleteStaff (staffId) {
|
||||
// 实现删除员工逻辑
|
||||
console.log('删除员工:', staffId)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.admin-dashboard {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboard-header {
|
||||
background: #2c3e50;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 200px;
|
||||
background: #34495e;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sidebar li:hover {
|
||||
background: #2c3e50;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
</style>
|
102
src/views/auth/Login.vue
Normal file
102
src/views/auth/Login.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<div class="login-box">
|
||||
<h2>登录系统</h2>
|
||||
<form @submit.prevent="handleLogin">
|
||||
<div class="form-group">
|
||||
<label>用户名</label>
|
||||
<input type="text" v-model="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码</label>
|
||||
<input type="password" v-model="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>用户类型</label>
|
||||
<select v-model="userType">
|
||||
<option value="admin">管理员</option>
|
||||
<option value="staff">员工</option>
|
||||
<option value="customer">顾客</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit">登录</button>
|
||||
</form>
|
||||
<!-- 添加注册链接 -->
|
||||
<div class="form-footer">
|
||||
<p>还没有账号?<router-link to="/register">立即注册</router-link></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
name: 'Login',
|
||||
data () {
|
||||
return {
|
||||
username: '',
|
||||
password: '',
|
||||
userType: 'customer'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleLogin () {
|
||||
// 实现登录逻辑
|
||||
console.log('登录信息:', this.username, this.password, this.userType)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
width: 400px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
input, select {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.form-footer {
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-footer a {
|
||||
color: #4CAF50;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.form-footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
110
src/views/auth/Register.vue
Normal file
110
src/views/auth/Register.vue
Normal file
@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div class="register-container">
|
||||
<div class="register-box">
|
||||
<h2>注册账号</h2>
|
||||
<form @submit.prevent="handleRegister">
|
||||
<div class="form-group">
|
||||
<label>用户名</label>
|
||||
<input type="text" v-model="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码</label>
|
||||
<input type="password" v-model="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>确认密码</label>
|
||||
<input type="password" v-model="confirmPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>用户类型</label>
|
||||
<select v-model="userType">
|
||||
<option value="customer">顾客</option>
|
||||
<option value="staff">员工</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit">注册</button>
|
||||
</form>
|
||||
<!-- 添加登录链接 -->
|
||||
<div class="form-footer">
|
||||
<p>已有账号?<router-link to="/login">立即登录</router-link></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
name: 'Register',
|
||||
data () {
|
||||
return {
|
||||
username: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
userType: 'customer'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleRegister () {
|
||||
if (this.password !== this.confirmPassword) {
|
||||
alert('两次输入的密码不一致!')
|
||||
return
|
||||
}
|
||||
// 实现注册逻辑
|
||||
console.log('注册信息:', this.username, this.password, this.userType)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.register-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.register-box {
|
||||
width: 400px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
input, select {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.form-footer {
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-footer a {
|
||||
color: #4CAF50;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.form-footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
80
src/views/customer/CustomerDashboard.vue
Normal file
80
src/views/customer/CustomerDashboard.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="customer-dashboard">
|
||||
<header class="dashboard-header">
|
||||
<h1>顾客服务中心</h1>
|
||||
<nav class="main-nav">
|
||||
<router-link to="/customer" class="nav-link">首页</router-link>
|
||||
<router-link to="/customer/services" class="nav-link">服务预约</router-link>
|
||||
<router-link to="/customer/schedule" class="nav-link">我的日程</router-link>
|
||||
<router-link to="/customer/profile" class="nav-link">个人信息</router-link>
|
||||
</nav>
|
||||
<button @click="logout">退出登录</button>
|
||||
</header>
|
||||
|
||||
<div class="dashboard-content">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomerDashboard',
|
||||
methods: {
|
||||
logout () {
|
||||
this.$router.push('/login')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.customer-dashboard {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboard-header {
|
||||
background: #2c3e50;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.nav-link:hover,
|
||||
.nav-link.router-link-active {
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
</style>
|
237
src/views/customer/CustomerHome.vue
Normal file
237
src/views/customer/CustomerHome.vue
Normal file
@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<div class="customer-home">
|
||||
<!-- 轮播图部分 -->
|
||||
<div class="carousel">
|
||||
<div class="carousel-container" :style="{ transform: `translateX(-${currentIndex * 100}%)` }">
|
||||
<div v-for="(slide, index) in slides" :key="index" class="carousel-slide">
|
||||
<img :src="slide.image" :alt="slide.title">
|
||||
<div class="slide-content">
|
||||
<h2>{{ slide.title }}</h2>
|
||||
<p>{{ slide.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel-dots">
|
||||
<span
|
||||
v-for="(slide, index) in slides"
|
||||
:key="index"
|
||||
:class="{ active: currentIndex === index }"
|
||||
@click="setSlide(index)"
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统介绍部分 -->
|
||||
<div class="system-intro">
|
||||
<h1>养老服务系统</h1>
|
||||
<div class="intro-cards">
|
||||
<div class="intro-card">
|
||||
<i class="fas fa-heart"></i>
|
||||
<h3>专业照护</h3>
|
||||
<p>提供24小时专业护理服务,确保老年人得到细致周到的照顾</p>
|
||||
</div>
|
||||
<div class="intro-card">
|
||||
<i class="fas fa-user-md"></i>
|
||||
<h3>医疗保障</h3>
|
||||
<p>配备专业医疗团队,定期体检,及时响应健康需求</p>
|
||||
</div>
|
||||
<div class="intro-card">
|
||||
<i class="fas fa-hands-helping"></i>
|
||||
<h3>生活照料</h3>
|
||||
<p>提供饮食起居、清洁卫生等全方位生活服务</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 服务特色部分 -->
|
||||
<div class="service-features">
|
||||
<h2>我们的服务特色</h2>
|
||||
<div class="features-grid">
|
||||
<div class="feature">
|
||||
<h3>个性化服务</h3>
|
||||
<p>根据每位老人的具体需求,制定个性化的护理方案</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>智能监护</h3>
|
||||
<p>采用现代化设备,实时监测老人的身体状况</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>营养配餐</h3>
|
||||
<p>专业营养师搭配,确保营养均衡</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<h3>文娱活动</h3>
|
||||
<p>丰富多样的文化娱乐活动,丰富晚年生活</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomerHome',
|
||||
data () {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
slides: [
|
||||
{
|
||||
image: '/images/slide1.jpg', // 需要添加实际的图片路径
|
||||
title: '温馨舒适的生活环境',
|
||||
description: '为老年人提供宾至如归的居住体验'
|
||||
},
|
||||
{
|
||||
image: '/images/slide2.jpg',
|
||||
title: '专业的医疗护理团队',
|
||||
description: '24小时专业护理,保障老年人健康'
|
||||
},
|
||||
{
|
||||
image: '/images/slide3.jpg',
|
||||
title: '丰富多彩的文娱活动',
|
||||
description: '让晚年生活充满欢乐与活力'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setSlide (index) {
|
||||
this.currentIndex = index
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 自动轮播
|
||||
setInterval(() => {
|
||||
this.currentIndex = (this.currentIndex + 1) % this.slides.length
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.customer-home {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 轮播图样式 */
|
||||
.carousel {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.carousel-container {
|
||||
display: flex;
|
||||
transition: transform 0.5s ease-in-out;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.carousel-slide {
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.carousel-slide img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.slide-content {
|
||||
position: absolute;
|
||||
bottom: 50px;
|
||||
left: 50px;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.carousel-dots {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.carousel-dots span {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255,255,255,0.5);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.carousel-dots span.active {
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* 系统介绍样式 */
|
||||
.system-intro {
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intro-cards {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 30px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.intro-card {
|
||||
flex: 1;
|
||||
max-width: 300px;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.intro-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.intro-card i {
|
||||
font-size: 40px;
|
||||
color: #4CAF50;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 服务特色样式 */
|
||||
.service-features {
|
||||
background: #f5f5f5;
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 30px;
|
||||
margin-top: 40px;
|
||||
padding: 0 50px;
|
||||
}
|
||||
|
||||
.feature {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #34495e;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
144
src/views/staff/StaffDashboard.vue
Normal file
144
src/views/staff/StaffDashboard.vue
Normal file
@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div class="staff-dashboard">
|
||||
<header class="dashboard-header">
|
||||
<h1>员工工作台</h1>
|
||||
<button @click="logout">退出登录</button>
|
||||
</header>
|
||||
|
||||
<div class="dashboard-content">
|
||||
<nav class="sidebar">
|
||||
<ul>
|
||||
<li @click="currentView = 'tasks'">工作任务</li>
|
||||
<li @click="currentView = 'schedule'">排班表</li>
|
||||
<li @click="currentView = 'customers'">顾客信息</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main class="main-content">
|
||||
<!-- 工作任务视图 -->
|
||||
<div v-if="currentView === 'tasks'" class="tasks-view">
|
||||
<h2>今日工作任务</h2>
|
||||
<div class="task-list">
|
||||
<div v-for="task in tasks" :key="task.id" class="task-card">
|
||||
<h3>{{ task.title }}</h3>
|
||||
<p>顾客:{{ task.customer }}</p>
|
||||
<p>时间:{{ task.time }}</p>
|
||||
<p>状态:{{ task.status }}</p>
|
||||
<button @click="completeTask(task.id)">完成任务</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'StaffDashboard',
|
||||
data () {
|
||||
return {
|
||||
currentView: 'tasks',
|
||||
tasks: [
|
||||
{
|
||||
id: 1,
|
||||
title: '晨间护理',
|
||||
customer: '王老先生',
|
||||
time: '08:00-09:00',
|
||||
status: '待完成'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '用药提醒',
|
||||
customer: '李奶奶',
|
||||
time: '09:30-10:00',
|
||||
status: '待完成'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout () {
|
||||
this.$router.push('/login')
|
||||
},
|
||||
completeTask (taskId) {
|
||||
// 实现完成任务逻辑
|
||||
console.log('完成任务:', taskId)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.staff-dashboard {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboard-header {
|
||||
background: #2c3e50;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 200px;
|
||||
background: #34495e;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sidebar li:hover {
|
||||
background: #2c3e50;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.task-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.task-card {
|
||||
background: white;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
button {
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
</style>
|
4
vue.config.js
Normal file
4
vue.config.js
Normal file
@ -0,0 +1,4 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true
|
||||
})
|
Loading…
Reference in New Issue
Block a user