Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
|
57fe2c7256 | |
|
10a9d8f354 | |
|
da34a60c9b | |
|
0d510cee1b | |
|
6c34d8e94d | |
|
2b90eba0ab | |
|
4d7b6c15a9 | |
|
dec27219c9 |
|
@ -36,3 +36,7 @@ components.d.ts
|
|||
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
public
|
||||
*.zip
|
||||
*.rar
|
117
index.html
117
index.html
|
@ -1,71 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>粤好生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>思缘生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
0% {
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=2SABZ-S4TWH-AMCDO-W742B-SKEOE-UWBKJ"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
@keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=2SABZ-S4TWH-AMCDO-W742B-SKEOE-UWBKJ"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,130 +1,125 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>粤好生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
-webkit-animation: loading-rotate 2s linear infinite;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
-webkit-animation: loading-dash 1.5s ease-in-out infinite;
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@-webkit-keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>思缘生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes loading-dash {
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
-webkit-animation: loading-rotate 2s linear infinite;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
0% {
|
||||
.circular .path {
|
||||
-webkit-animation: loading-dash 1.5s ease-in-out infinite;
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
@-webkit-keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=2SABZ-S4TWH-AMCDO-W742B-SKEOE-UWBKJ"></script>
|
||||
<script type="module" crossorigin src="/assets/index.1f6a65da.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vue.ad3a2c51.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vueuse.c2fd8b33.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@element-plus.4b8482d8.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash-es.61686ec6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/axios.136fb7b6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dayjs.c8b8967e.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/async-validator.fb49d0f5.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@ctrl.82a509e0.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@popperjs.36402333.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/escape-html.e5dfadb9.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/normalize-wheel-es.8aeb3683.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/memoize-one.4ee5c96d.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/element-plus.02c000b8.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash.8effadcb.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-router.93f65f3b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-demi.ebc8116b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pinia.f0255b9b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/clone.4b381e37.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-name.e7a4e1d3.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-convert.755d189f.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-string.e356f5de.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color.0adfd97a.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/css-color-function.3cb93b94.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/nprogress.09754c1e.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/clipboard.42524a75.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-clipboard3.c5f2d3ed.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tslib.60310f1a.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/zrender.8ee1a698.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/echarts.234b3572.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/highlight.js.4ebdf9a4.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@highlightjs.0d5173e3.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/mitt.d8e3ba72.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue3-eventbus.c7305b83.js">
|
||||
<link rel="stylesheet" href="/assets/element-plus.149e8a96.css">
|
||||
<link rel="stylesheet" href="/assets/nprogress.a2a0c377.css">
|
||||
<link rel="stylesheet" href="/assets/highlight.5f5db245.css">
|
||||
<link rel="stylesheet" href="/assets/index.8c422639.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
@-webkit-keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=2SABZ-S4TWH-AMCDO-W742B-SKEOE-UWBKJ"></script>
|
||||
<script type="module" crossorigin src="/assets/index.073f879d.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vue.ad3a2c51.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vueuse.c2fd8b33.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/@element-plus.4b8482d8.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash-es.61686ec6.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/axios.136fb7b6.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/dayjs.c8b8967e.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/async-validator.fb49d0f5.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/@ctrl.82a509e0.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/@popperjs.36402333.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/escape-html.e5dfadb9.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/normalize-wheel-es.8aeb3683.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/memoize-one.4ee5c96d.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/element-plus.02c000b8.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash.8effadcb.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-router.93f65f3b.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-demi.ebc8116b.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/pinia.f0255b9b.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/clone.4b381e37.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-name.e7a4e1d3.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-convert.755d189f.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-string.e356f5de.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/color.0adfd97a.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/css-color-function.3cb93b94.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/nprogress.09754c1e.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/clipboard.42524a75.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-clipboard3.c5f2d3ed.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/tslib.60310f1a.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/zrender.8ee1a698.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/echarts.234b3572.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/highlight.js.4ebdf9a4.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/@highlightjs.0d5173e3.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/mitt.d8e3ba72.js" />
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue3-eventbus.c7305b83.js" />
|
||||
<link rel="stylesheet" href="/assets/element-plus.149e8a96.css" />
|
||||
<link rel="stylesheet" href="/assets/nprogress.a2a0c377.css" />
|
||||
<link rel="stylesheet" href="/assets/highlight.5f5db245.css" />
|
||||
<link rel="stylesheet" href="/assets/index.8c422639.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,130 +1,126 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>粤好生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
-webkit-animation: loading-rotate 2s linear infinite;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
-webkit-animation: loading-dash 1.5s ease-in-out infinite;
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@-webkit-keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>思缘生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes loading-dash {
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
-webkit-animation: loading-rotate 2s linear infinite;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
0% {
|
||||
.circular .path {
|
||||
-webkit-animation: loading-dash 1.5s ease-in-out infinite;
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
@-webkit-keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=2SABZ-S4TWH-AMCDO-W742B-SKEOE-UWBKJ"></script>
|
||||
<script type="module" crossorigin src="/assets/index.7e71cca7.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vue.ad3a2c51.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vueuse.c2fd8b33.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@element-plus.4b8482d8.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash-es.61686ec6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/axios.136fb7b6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dayjs.c8b8967e.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/async-validator.fb49d0f5.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@ctrl.82a509e0.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@popperjs.36402333.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/escape-html.e5dfadb9.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/normalize-wheel-es.8aeb3683.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/memoize-one.4ee5c96d.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/element-plus.02c000b8.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash.8effadcb.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-router.93f65f3b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-demi.ebc8116b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pinia.f0255b9b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/clone.4b381e37.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-name.e7a4e1d3.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-convert.755d189f.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-string.e356f5de.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color.0adfd97a.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/css-color-function.3cb93b94.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/nprogress.09754c1e.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/clipboard.42524a75.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-clipboard3.c5f2d3ed.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tslib.60310f1a.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/zrender.8ee1a698.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/echarts.234b3572.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/highlight.js.4ebdf9a4.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@highlightjs.0d5173e3.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/mitt.d8e3ba72.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue3-eventbus.c7305b83.js">
|
||||
<link rel="stylesheet" href="/assets/element-plus.149e8a96.css">
|
||||
<link rel="stylesheet" href="/assets/nprogress.a2a0c377.css">
|
||||
<link rel="stylesheet" href="/assets/highlight.5f5db245.css">
|
||||
<link rel="stylesheet" href="/assets/index.8c422639.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
@-webkit-keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=2SABZ-S4TWH-AMCDO-W742B-SKEOE-UWBKJ"></script>
|
||||
<script type="module" crossorigin src="/assets/index.2c7b212c.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vue.ad3a2c51.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@vueuse.c2fd8b33.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@element-plus.4b8482d8.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash-es.61686ec6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/axios.136fb7b6.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dayjs.c8b8967e.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/async-validator.fb49d0f5.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@ctrl.82a509e0.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@popperjs.36402333.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/escape-html.e5dfadb9.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/normalize-wheel-es.8aeb3683.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/memoize-one.4ee5c96d.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/element-plus.02c000b8.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/lodash.8effadcb.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-router.93f65f3b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-demi.ebc8116b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pinia.f0255b9b.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/clone.4b381e37.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-name.e7a4e1d3.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-convert.755d189f.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color-string.e356f5de.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/color.0adfd97a.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/css-color-function.3cb93b94.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/nprogress.09754c1e.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/clipboard.42524a75.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue-clipboard3.c5f2d3ed.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/tslib.60310f1a.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/zrender.8ee1a698.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/echarts.234b3572.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/highlight.js.4ebdf9a4.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/@highlightjs.0d5173e3.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/mitt.d8e3ba72.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vue3-eventbus.c7305b83.js">
|
||||
<link rel="stylesheet" href="/assets/element-plus.149e8a96.css">
|
||||
<link rel="stylesheet" href="/assets/nprogress.a2a0c377.css">
|
||||
<link rel="stylesheet" href="/assets/highlight.5f5db245.css">
|
||||
<link rel="stylesheet" href="/assets/index.8c422639.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function addOperation(params: any) {
|
||||
return request.post({ url: '/customerService/add', params })
|
||||
}
|
||||
export function editOperation(params: any) {
|
||||
return request.post({ url: '/customerService/edit', params })
|
||||
}
|
||||
export function operationDetail(params: any) {
|
||||
return request.get({ url: '/customerService/detail', params })
|
||||
}
|
||||
export function getOperationList() {
|
||||
return request.get({ url: '/customerService/list' })
|
||||
}
|
||||
export function delOperation(params: any) {
|
||||
return request.post({ url: '/customerService/del', params })
|
||||
}
|
||||
export function OperationStatus(params: any) {
|
||||
return request.post({ url: '/customerService/enable', params })
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
const config = {
|
||||
terminal: 1, //终端
|
||||
title: '粤好生活-后台管理系统', //网站默认标题
|
||||
title: '思缘生活-后台管理系统', //网站默认标题
|
||||
version: '1.3.3', //版本号
|
||||
baseUrl: `${import.meta.env.VITE_APP_BASE_URL || ''}/`, //请求接口域名
|
||||
urlPrefix: 'api', //请求默认前缀
|
||||
|
|
|
@ -181,4 +181,8 @@ export const StaffRefundEnumMap: Record<number, string> = {
|
|||
export enum RefundEnum {
|
||||
SETTING = 1,
|
||||
UN_SETTING = 0
|
||||
}
|
||||
}
|
||||
export enum PriceEnum {
|
||||
CUSTOMER_PRICE = 0, //固定价格
|
||||
TEACHER_PRICE = 1 // 价格区间
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<footer class="layout-footer bg-[#f5f5f5] bg-opacity-90 text-center">
|
||||
<div class="p-2 text-xs text-tx-secondary max-w-[900px] mx-auto">
|
||||
<a href="http://beian.miit.gov.cn" class="my-[10px]">Copyright © 2023 粤ICP备2025364700号 - 广东粤好生活服务有限公司版权所有</a>
|
||||
<a href="http://beian.miit.gov.cn" class="my-[10px]">Copyright © 2023 粤ICP备2025364700号 - 广东思缘生活服务有限公司版权所有</a>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
|
|
@ -421,6 +421,20 @@ export const constantRoutes: Array<RouteRecordRaw> = [
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/setting/notice',
|
||||
component: LAYOUT,
|
||||
children: [
|
||||
{
|
||||
path: 'edit',
|
||||
component: () => import('@/views/message/notice/edit.vue'),
|
||||
meta: {
|
||||
title: '设置',
|
||||
activeMenu: '/setting/message/notice'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -261,9 +261,9 @@ export function formatFileSize(bytes: number) {
|
|||
*/
|
||||
export function retain(value: any, n: any): string {
|
||||
if (n === 'null' || n === 'undefined' || n === 0) return value
|
||||
let tran = Math.round(value * Math.pow(10, n)) / Math.pow(10, n)
|
||||
const tran = Math.round(value * Math.pow(10, n)) / Math.pow(10, n)
|
||||
let tranV = tran.toString()
|
||||
let newVal = tranV.indexOf('.')
|
||||
const newVal = tranV.indexOf('.')
|
||||
if (newVal < 0) {
|
||||
tranV += '.'
|
||||
}
|
||||
|
@ -272,3 +272,40 @@ export function retain(value: any, n: any): string {
|
|||
}
|
||||
return tranV
|
||||
}
|
||||
export function formatString(input) {
|
||||
const processNumber = numStr => {
|
||||
if (!numStr.includes('.')) return numStr
|
||||
|
||||
// 分割整数和小数部分(处理 .00 和 20. 等情况)
|
||||
const parts = numStr.split('.', 2)
|
||||
let [intPart, decPart] = parts
|
||||
|
||||
// 处理类似 ".00" 的情况
|
||||
intPart = intPart || '0'
|
||||
|
||||
// 处理小数部分全零或无小数部分的情况
|
||||
if (!decPart || decPart.trimEnd().replace(/^0+$/, '') === '') {
|
||||
return intPart
|
||||
}
|
||||
|
||||
// 去除末尾零并处理格式问题
|
||||
const strippedDec = decPart.trimEnd().replace(/^0+$/, '')
|
||||
const result = `${intPart}.${strippedDec}`
|
||||
|
||||
// 处理特殊情况
|
||||
if (strippedDec === '') return intPart // 123.000 → 123
|
||||
if (result.endsWith('.')) return intPart // 123. → 123
|
||||
if (result.startsWith('.') && strippedDec) return `0${result}` // .55 → 0.55
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if (!input) return
|
||||
const parts = input.split('-', 2)
|
||||
if (parts.length !== 2) return input
|
||||
|
||||
const left = processNumber(parts[0])
|
||||
const right = processNumber(parts[1])
|
||||
|
||||
return `${left}-${right}`
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { DispatchCountEnum, DispatchEnum, UseConditionEnum, UseGoodsEnum } from '@/enums/modeEnum'
|
||||
import { DispatchCountEnum, DispatchEnum, PriceEnum, UseConditionEnum, UseGoodsEnum } from '@/enums/modeEnum'
|
||||
import type { UploadFile } from 'element-plus'
|
||||
|
||||
/*
|
||||
|
@ -357,3 +357,31 @@ export function validateValue(rule: any, value: any, callback: any) {
|
|||
}
|
||||
}
|
||||
}
|
||||
export function validatePirce(args, payload: any) {
|
||||
const [, value, callback] = args
|
||||
const { priceType, minPrice, maxPrice } = payload
|
||||
if (priceType == PriceEnum.CUSTOMER_PRICE) {
|
||||
if (value == '') {
|
||||
callback(new Error('请填写价格'))
|
||||
} else if (!isNumberWithDot(value)) {
|
||||
callback(new Error('价格必须大于或等于零'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
} else {
|
||||
if (minPrice == '' || maxPrice == '') {
|
||||
const errMsg = minPrice == '' ? '下限' : maxPrice == '' ? '上限' : ''
|
||||
callback(new Error('请输入价格' + errMsg))
|
||||
} else {
|
||||
if (!isNumberWithDot(minPrice as string) || !isNumberWithDot(maxPrice as string)) {
|
||||
callback(new Error('价格必须大于或等于零'))
|
||||
} else if (Number(minPrice) > Number(maxPrice)) {
|
||||
callback(new Error('价格下限不能高于上限'))
|
||||
} else if (minPrice == maxPrice) {
|
||||
callback(new Error('请输入有效区间,价格下限不能等于上限'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,19 @@
|
|||
<el-card shadow="never" style="margin-top: 15px" class="!border-none">
|
||||
<!-- 用户绑定 -->
|
||||
<el-form-item label="绑定用户:" prop="userId">
|
||||
<user-select btn-text="选择用户" type="primary" v-model="formData.userId" :userVo="formData.userVo" :id="id"
|
||||
v-model:userMobile="formData.mobile" :api="apiUserNotStaff" />
|
||||
<user-select
|
||||
btn-text="选择用户"
|
||||
type="primary"
|
||||
v-model="formData.userId"
|
||||
:userVo="formData.userVo"
|
||||
:id="id"
|
||||
v-model:userMobile="formData.mobile"
|
||||
:api="apiUserNotStaff"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="师傅编号:" prop="sn">
|
||||
<!-- <el-form-item label="师傅编号:" prop="sn">
|
||||
<el-input class="w-56 ls-input" :disabled="true" v-model="formData.sn" placeholder="请输入师傅编号" />
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="师傅名称:" prop="name">
|
||||
<el-input class="w-56 ls-input" v-model="formData.name" placeholder="请输入师傅的真实姓名" />
|
||||
</el-form-item>
|
||||
|
@ -22,8 +29,7 @@
|
|||
<!-- 服务项目 -->
|
||||
<el-form-item label="服务项目" prop="goodsIds">
|
||||
<el-select v-model="formData.goodsIds" placeholder="请选择" class="ls-input" clearable multiple>
|
||||
<el-option v-for="category in categoryLists" :key="category.id" :label="category.name"
|
||||
:value="category.id"></el-option>
|
||||
<el-option v-for="category in categoryLists" :key="category.id" :label="category.name" :value="category.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <div class="serviceItem">
|
||||
|
@ -51,27 +57,37 @@
|
|||
</el-form-item>
|
||||
<!-- 所在地区 -->
|
||||
<el-form-item label="所在地区:" prop="districtId">
|
||||
<area-select class="w-56 ls-input" v-model:province="formData.provinceId" v-model:city="formData.cityId"
|
||||
v-model:district="formData.districtId" />
|
||||
<area-select
|
||||
class="w-56 ls-input"
|
||||
v-model:province="formData.provinceId"
|
||||
v-model:city="formData.cityId"
|
||||
v-model:district="formData.districtId"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="详细地址:">
|
||||
<el-input class="ls-input" type="textarea" v-model="formData.address" placeholder="选填,请输入详细地址"
|
||||
:rows="6"></el-input>
|
||||
<el-input class="ls-input" type="textarea" v-model="formData.address" placeholder="选填,请输入详细地址" :rows="6"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="接单状态:" prop="isReceiveOrder">
|
||||
<el-switch v-model="formData.isReceiveOrder" :active-text="!formData.isReceiveOrder ? '启用' : '停用'"
|
||||
:active-value="0" :inactive-value="1" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运营师傅:">
|
||||
<el-switch v-model="formData.isOperational" :active-value="1" :inactive-value="0"
|
||||
:active-text="formData.isOperational ? '是' : '否'" />
|
||||
<!-- <el-form-item label="接单状态:" prop="isReceiveOrder">
|
||||
<el-switch
|
||||
v-model="formData.isReceiveOrder"
|
||||
:active-text="!formData.isReceiveOrder ? '启用' : '停用'"
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item label="运营师傅:">
|
||||
<el-switch
|
||||
v-model="formData.isOperational"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
:active-text="formData.isOperational ? '是' : '否'"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作时间" prop="workStartTime" v-if="formData.isOperational === 1">
|
||||
<el-time-picker v-model="formData.workStartTime" placeholder="开始时间" value-format="HH:mm" format="HH:mm"
|
||||
class="h-[45px]" />
|
||||
<el-time-picker v-model="formData.workEndTime" placeholder="结束时间" value-format="HH:mm" format="HH:mm"
|
||||
class="h-[45px]" />
|
||||
</el-form-item>
|
||||
<el-time-picker v-model="formData.workStartTime" placeholder="开始时间" value-format="HH:mm" format="HH:mm" class="h-[45px]" />
|
||||
<el-time-picker v-model="formData.workEndTime" placeholder="结束时间" value-format="HH:mm" format="HH:mm" class="h-[45px]" />
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item label="首页推荐:">
|
||||
<el-radio v-model="formData.isRecommend" name="1" :label="1">推荐</el-radio>
|
||||
<el-radio v-model="formData.isRecommend" name="0" :label="0">不推荐</el-radio>
|
||||
|
@ -84,18 +100,15 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { apiMasterWorkerAdd, apiMasterWorkerEdit, apiMasterWorkerDetail, apiMasterWorkerAreaAdd, apiMasterWorkerArea } from '@/api/master_worker'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { apiMasterWorkerAdd, apiMasterWorkerArea, apiMasterWorkerDetail, apiMasterWorkerEdit, apiUserNotStaff } from '@/api/master_worker'
|
||||
import AreaSelect from '@/components/area-select/index.vue'
|
||||
import FooterBtns from '@/components/footer-btns/index.vue'
|
||||
import UserSelect from '@/components/user-select/index.vue'
|
||||
import AreaSelect from '@/components/area-select/index.vue'
|
||||
import ServiceSelect from '@/components/service-select/index.vue'
|
||||
import ServiceArea from '@/components/service-area/index.vue'
|
||||
import type { ElForm } from 'element-plus'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { apiUserNotStaff } from '@/api/master_worker'
|
||||
import { validateWorkTime } from '@/utils/validate'
|
||||
import { useCommon } from '@/hooks/useCommon'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { validateWorkTime } from '@/utils/validate'
|
||||
import type { ElForm } from 'element-plus'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
/** Interface Start **/
|
||||
interface formDataObj {
|
||||
|
@ -155,7 +168,7 @@ const formData = ref<formDataObj>({
|
|||
isRecommend: 0, //是否推荐
|
||||
serviceArea: [],
|
||||
serviceAreaIds: [],
|
||||
isReceiveOrder: '',
|
||||
isReceiveOrder: 0,
|
||||
workStartTime: '',
|
||||
workEndTime: '',
|
||||
isOperational: 0
|
||||
|
@ -181,7 +194,7 @@ const rules = reactive<object>({
|
|||
|
||||
// 获取详情
|
||||
const getMasterWorkerDetail = async (id: number): Promise<void> => {
|
||||
; (formData.value as {}) = await apiMasterWorkerDetail({ id })
|
||||
;(formData.value as {}) = await apiMasterWorkerDetail({ id })
|
||||
if (!formData.value.goodsCategoryList.length) return
|
||||
formData.value.goodsIds = formData.value.goodsCategoryList.map(category => category.id)
|
||||
}
|
||||
|
@ -221,6 +234,7 @@ const onSubmit = (formEl: FormInstance | undefined): void => {
|
|||
// return true
|
||||
// }
|
||||
// 请求详情 => 如果是编辑的话
|
||||
fetchCategoryList()
|
||||
onMounted(async () => {
|
||||
if (id) {
|
||||
fetchCategoryList()
|
||||
|
|
|
@ -4,26 +4,26 @@
|
|||
<el-form-item label="师傅信息">
|
||||
<el-input class="ls-input" v-model="formData.staffInfo" placeholder="师傅编号/姓名/手机号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户信息">
|
||||
<!-- <el-form-item label="用户信息">
|
||||
<el-input class="ls-input" v-model="formData.userInfo" placeholder="请输入用户昵称/用户编号/手机号" />
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="所在地区">
|
||||
<el-cascader class="w-56 ls-input" :options="options" :props="props2" @change="handleSelect" ref="cascader" />
|
||||
</el-form-item>
|
||||
<el-form-item label="首页推荐">
|
||||
<!-- <el-form-item label="首页推荐">
|
||||
<el-select v-model="formData.isRecommend" placeholder="请选择" class="ls-input">
|
||||
<el-option label="全部" value></el-option>
|
||||
<el-option label="推荐" value="1"></el-option>
|
||||
<el-option label="不推荐" value="0"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="师傅状态">
|
||||
</el-form-item> -->
|
||||
<!-- <el-form-item label="师傅状态">
|
||||
<el-select v-model="formData.status" placeholder="请选择" class="ls-input">
|
||||
<el-option label="全部" value></el-option>
|
||||
<el-option label="启用" value="1"></el-option>
|
||||
<el-option label="停用" value="0"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<div class="flex">
|
||||
<el-button type="primary" @click="getLists">查询</el-button>
|
||||
|
@ -34,7 +34,7 @@
|
|||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt-4 !border-none">
|
||||
<!-- <el-button type="primary" @click="$router.push('edit')">添加师傅</el-button> -->
|
||||
<el-button type="primary" @click="$router.push('edit')">添加师傅</el-button>
|
||||
<div class="mt-3">
|
||||
<el-table :data="pager.lists" style="width: 100%" v-loading="pager.loading">
|
||||
<el-table-column property="sn" label="师傅编号" min-width="110">
|
||||
|
@ -45,8 +45,8 @@
|
|||
<div class="flex items-center">
|
||||
<el-image
|
||||
class="avatar"
|
||||
:src="row.headPortrait"
|
||||
:preview-src-list="[row.headPortrait]"
|
||||
:src="row.avatarUrl"
|
||||
:preview-src-list="[row.avatarUrl]"
|
||||
:hide-on-click-modal="true"
|
||||
:preview-teleported="true"
|
||||
fit="cover"
|
||||
|
@ -63,7 +63,7 @@
|
|||
<div>{{ scope.row.province }}{{ scope.row.city }}{{ scope.row.district }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idCard" label="身份证号码" min-width="200"></el-table-column>
|
||||
<!-- <el-table-column prop="idCard" label="身份证号码" min-width="200"></el-table-column>
|
||||
<el-table-column prop="idCardImg" label="身份证正反面" min-width="200" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-image
|
||||
|
@ -75,7 +75,6 @@
|
|||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="physicalExamination" min-width="200" label="体检报告(图片和pdf)">
|
||||
<template #default="{ row }">
|
||||
<div class="method" v-if="row.physicalExamination">
|
||||
|
@ -104,24 +103,32 @@
|
|||
<template #default="scope">
|
||||
<el-popover placement="top-start" title="提示:" trigger="hover" content="点击可跳转服务评价页面">
|
||||
<template #reference>
|
||||
<router-link :to="{ path: '/service/evaluate', query: { staffInfo: scope.row.sn } }">
|
||||
<div class="w-[50px] text-center text-[#4A5DFF]">{{ scope.row.score }}</div>
|
||||
<router-link
|
||||
:to="{
|
||||
path: '/service/evaluate',
|
||||
query: { staffInfo: scope.row.sn }
|
||||
}"
|
||||
>
|
||||
<div class="w-[50px] text-center text-[#4A5DFF]">
|
||||
{{ scope.row.score }}
|
||||
</div>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="接单状态" min-width="80">
|
||||
</el-table-column> -->
|
||||
<!-- <el-table-column label="接单状态" min-width="80">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.isReceiveOrder"
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
:before-change="() => handleStatusChange(scope.row)"
|
||||
disabled
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="运营师傅" min-width="80">
|
||||
</el-table-column> -->
|
||||
<!-- <el-table-column label="运营师傅" min-width="80">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.isOperational"
|
||||
|
@ -130,18 +137,18 @@
|
|||
:before-change="() => handleIsOperationalChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column> -->
|
||||
<!-- <el-table-column property="recommend_desc" label="首页推荐" min-width="160">
|
||||
<template #default="scope">
|
||||
<el-tag type="info" v-if="scope.row.isRecommend == 0">不推荐</el-tag>
|
||||
<el-tag v-if="scope.row.isRecommend == 1">推荐</el-tag>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column prop="getType" label="金额详情" min-width="110">
|
||||
<!-- <el-table-column prop="getType" label="金额详情" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<MoneyDetailDialog btn-text="金额详情" :rowData="row" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column> -->
|
||||
<el-table-column property="createTime" label="添加时间" min-width="180" />
|
||||
<el-table-column label="操作" width="148" fixed="right">
|
||||
<template #default="scope">
|
||||
|
@ -170,17 +177,13 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup name="masterList">
|
||||
import { apiMasterWorkerLists, apiMasterWorkerDel, apiMasterWorkerStatusEdit, apiStaffIsOperationalUpdate } from '@/api/master_worker'
|
||||
import { ref } from 'vue'
|
||||
import { apiMasterWorkerDel, apiMasterWorkerLists, apiMasterWorkerStatusEdit, apiStaffIsOperationalUpdate } from '@/api/master_worker'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import MoneyDetailDialog from '@/components/money-detail/moneyDetailDialog.vue'
|
||||
import { ReceiveOrderEnum } from '@/enums/modeEnum'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import area from '@/utils/area'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { ReceiveOrderEnum } from '@/enums/modeEnum'
|
||||
import PdfImg from '@/assets/icons/pdf.svg'
|
||||
import reportImg from '@/assets/images/report.png'
|
||||
import IdCardImg from '@/assets/images/idCard.png'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
|
@ -216,7 +219,7 @@ const isVisiblePdf = computed(() => {
|
|||
})
|
||||
const previewIdCardList = computed(() => {
|
||||
return (row: any) => {
|
||||
return row.idCardImg.split(',')
|
||||
return row.idCardImg?.split(',')
|
||||
}
|
||||
})
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
|
@ -268,7 +271,10 @@ const handleIsOperationalChange = (row: any) => {
|
|||
const handlePreviewPdf = (row: any) => {
|
||||
const { physicalExamination } = row
|
||||
if (!physicalExamination) return
|
||||
const url = router.resolve({ path: '/report/pdf', query: { path: physicalExamination?.split(',').filter(item => item.includes('pdf')) } })
|
||||
const url = router.resolve({
|
||||
path: '/report/pdf',
|
||||
query: { path: physicalExamination?.split(',').filter(item => item.includes('pdf')) }
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
getLists()
|
||||
|
|
|
@ -3,18 +3,12 @@
|
|||
<el-card class="!border-none" shadow="never">
|
||||
<el-page-header :content="$route.meta.title" @back="$router.back()" />
|
||||
</el-card>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
label-width="120px"
|
||||
:rules="rules"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="120px" :rules="rules" v-loading="loading">
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div class="font-medium mb-7">通知名称</div>
|
||||
<el-form-item label="通知名称" prop="name"> {{ formData.name }} </el-form-item>
|
||||
<el-form-item label="通知类型" prop="name"> {{ formData.type }} </el-form-item>
|
||||
<el-form-item label="通知业务" prop="name"> {{ formData.remarks }} </el-form-item>
|
||||
<el-form-item label="通知名称" prop="name">{{ formData.name }}</el-form-item>
|
||||
<el-form-item label="通知类型" prop="name">{{ formData.type }}</el-form-item>
|
||||
<el-form-item label="通知业务" prop="name">{{ formData.remarks }}</el-form-item>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div class="font-medium mb-7">短信通知</div>
|
||||
|
@ -26,20 +20,13 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="模板ID" prop="smsNotice.templateId">
|
||||
<div class="w-80">
|
||||
<el-input
|
||||
v-model="formData.smsNotice.templateId"
|
||||
placeholder="请输入模板ID"
|
||||
/>
|
||||
<el-input v-model="formData.smsNotice.templateId" placeholder="请输入模板ID" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="短信内容" prop="smsNotice.content">
|
||||
<div class="flex-1">
|
||||
<div class="w-full max-w-[320px]">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 6, maxRows: 6 }"
|
||||
v-model="formData.smsNotice.content"
|
||||
/>
|
||||
<el-input type="textarea" :autosize="{ minRows: 6, maxRows: 6 }" v-model="formData.smsNotice.content" />
|
||||
</div>
|
||||
<div class="form-tips">
|
||||
<!-- <div v-for="(item, index) in formData.smsNotice.tips" :key="index"> -->
|
||||
|
@ -103,7 +90,7 @@ const getDetails = async () => {
|
|||
const data = await noticeDetail({
|
||||
id: route.query.id
|
||||
})
|
||||
Object.keys(data).forEach((key) => {
|
||||
Object.keys(data).forEach(key => {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
})
|
||||
|
@ -114,7 +101,7 @@ const handleSave = async () => {
|
|||
await formRef.value?.validate()
|
||||
await setNoticeConfig(formData)
|
||||
feedback.msgSuccess('操作成功')
|
||||
removeTab()
|
||||
// removeTab()
|
||||
router.back()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-alert
|
||||
type="warning"
|
||||
title="温馨提示:平台配置在各个场景下的通知发送方式和内容模板"
|
||||
:closable="false"
|
||||
show-icon
|
||||
></el-alert>
|
||||
<el-alert type="warning" title="温馨提示:平台配置在各个场景下的通知发送方式和内容模板" :closable="false" show-icon></el-alert>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<el-tabs v-model="tabsActive" @tab-change="getLists">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in tabsMap"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.type"
|
||||
lazy
|
||||
></el-tab-pane>
|
||||
<el-tab-pane v-for="(item, index) in tabsMap" :key="index" :label="item.name" :name="item.type" lazy></el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-table size="large" :data="state.lists" v-loading="state.loading">
|
||||
<el-table-column label="通知场景" prop="name" min-width="120" />
|
||||
|
@ -29,18 +18,7 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="80" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-perms="['setting:notice:detail']" type="primary" link>
|
||||
<router-link
|
||||
:to="{
|
||||
path: getRoutePath('setting:notice:detail'),
|
||||
query: {
|
||||
id: row.id
|
||||
}
|
||||
}"
|
||||
>
|
||||
设置
|
||||
</router-link>
|
||||
</el-button>
|
||||
<el-button v-perms="['setting:notice:detail']" type="primary" link @click="handleSetting(row.id)">设置</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -49,7 +27,6 @@
|
|||
</template>
|
||||
<script lang="ts" setup name="notice">
|
||||
import { noticeLists } from '@/api/message'
|
||||
import { getRoutePath } from '@/router'
|
||||
|
||||
enum NoticeEnums {
|
||||
USER = 1,
|
||||
|
@ -91,7 +68,10 @@ const getLists = async () => {
|
|||
state.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
const handleSetting = (id: number) => {
|
||||
router.push({ path: '/setting/notice/edit', query: { id } })
|
||||
}
|
||||
onActivated(() => {
|
||||
getLists()
|
||||
})
|
||||
|
|
|
@ -14,32 +14,32 @@
|
|||
</div>
|
||||
</template>
|
||||
<!-- 订单信息 -->
|
||||
<el-form :inline="true" :model="formData" label-width="auto">
|
||||
<el-form :inline="true" :model="formData" label-width="auto" class="order-form">
|
||||
<el-form-item label="订单状态: ">
|
||||
<div class="content text-warning">{{ formData.orderStatusName || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付状态: ">
|
||||
<!-- <el-form-item label="支付状态: ">
|
||||
<div class="content">{{ formData.payStatusName || '-' }}</div>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="订单编号: ">
|
||||
<div class="content">{{ formData.sn || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式: ">
|
||||
<!-- <el-form-item label="支付方式: ">
|
||||
<div class="content">{{ formData.payWayName || '-' }}</div>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="下单时间: ">
|
||||
<div class="content">{{ formData.createTime || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付时间: ">
|
||||
<!-- <el-form-item label="支付时间: ">
|
||||
<div class="content">{{ formData.payTime || '-' }}</div>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="用户昵称: ">
|
||||
<div class="content">{{ formData.nickname || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户备注: ">
|
||||
<div class="content">{{ formData.userRemark || '-' }}</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="核销码: ">
|
||||
<el-form-item label="核销码: ">
|
||||
<div class="content">{{ formData.verificationCode || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="核销状态: ">
|
||||
|
@ -49,13 +49,18 @@
|
|||
</span>
|
||||
<span v-else>-</span>
|
||||
</div>
|
||||
</el-form-item> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="完成时间: ">
|
||||
<div class="content break-words">{{ formData.finishTime || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="商家备注: ">
|
||||
<div class="w-[300px] break-words">{{ formData.orderRemarks! || '-' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="退款原因: " v-if="formData.orderStatus == 4">
|
||||
<div class="content">
|
||||
{{ formData?.orderRefundDetailVo?.refundReason || '-' }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- Button Group Start -->
|
||||
<div class="button-group">
|
||||
|
@ -112,7 +117,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 服务师傅 Start -->
|
||||
<!-- <el-card class="!border-none mt-4" shadow="never" style="padding: 0 20px" v-if="formData.orderStatus !== 0">
|
||||
<el-card class="!border-none mt-4" shadow="never" style="padding: 0 20px" v-if="formData.orderStatus !== 0">
|
||||
<template #header>
|
||||
<span class="font-medium nr">服务师傅</span>
|
||||
</template>
|
||||
|
@ -160,11 +165,11 @@
|
|||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card> -->
|
||||
</el-card>
|
||||
<!-- 服务师傅 End -->
|
||||
|
||||
<!-- 历史服务师傅 -->
|
||||
<!-- <el-card
|
||||
<el-card
|
||||
class="!border-none mt-4"
|
||||
shadow="never"
|
||||
style="padding: 0 20px"
|
||||
|
@ -179,14 +184,18 @@
|
|||
<div class="ml-2">
|
||||
{{ `${staff.staffName}(${staff.staffSn})` }}
|
||||
</div>
|
||||
<div>
|
||||
<!-- <div>
|
||||
上门服务时间{{ staff.timeBefore < 0 ? '后' : '前' }}{{ staff.timeBefore.toString().replace(/\-/g, ' ') }}分钟退单,扣
|
||||
<span style="color: #f56c6c">{{ staff.deductScore }}</span>
|
||||
分(改派时间:{{ staff.createTime }})
|
||||
</div> -->
|
||||
<div>
|
||||
上门服务时间{{ staff.timeBefore < 0 ? '后' : '前'
|
||||
}}{{ staff.timeBefore.toString().replace(/\-/g, ' ') }}分钟退单,改派时间:{{ staff.createTime }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card> -->
|
||||
</el-card>
|
||||
|
||||
<!-- 预约信息 Start -->
|
||||
<el-card class="!border-none mt-4" shadow="never" style="padding: 0 20px">
|
||||
|
@ -230,7 +239,9 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="goodsPrice" label="价格" width="120" />
|
||||
<el-table-column property="goodsPrice" label="价格" width="120">
|
||||
<template #default="scope">¥{{ parsePrice(scope.row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="unitName" label="单位" width="120" />
|
||||
<el-table-column property="goodsNum" label="数量" width="120" />
|
||||
<el-table-column property="totalAmount" label="总价格" width="120" />
|
||||
|
@ -238,7 +249,7 @@
|
|||
<template #default="{ row }">{{ isUseCoupon(row) }}</template>
|
||||
</el-table-column> -->
|
||||
<!-- <el-table-column property="deductionMoney" label="抵扣金额" width="120" fixed="right" /> -->
|
||||
<el-table-column property="orderAmount" label="实付金额" width="120" fixed="right" />
|
||||
<!-- <el-table-column property="orderAmount" label="实付金额" width="120" fixed="right" /> -->
|
||||
</el-table>
|
||||
</el-card>
|
||||
<!-- 服务信息 End -->
|
||||
|
@ -283,17 +294,16 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { apiOrderDetail, apiMasterLists, apiDispatchStaff, apiDispatchStaffScore } from '@/api/order/lists'
|
||||
import { ref } from 'vue'
|
||||
import Operation from './components/operation.vue'
|
||||
import dispatchDialog from './components/dispatchDialog.vue'
|
||||
import { apiDispatchStaff, apiDispatchStaffScore, apiMasterLists, apiOrderDetail } from '@/api/order/lists'
|
||||
import { PriceEnum, ReceiveOrderEnum, getTypeMap, useGoodsTypeMap } from '@/enums/modeEnum'
|
||||
import { useCreateModal } from '@/hooks/useCreateModal'
|
||||
import area from '@/utils/area'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { useGoodsTypeMap, getTypeMap, ReceiveOrderEnum } from '@/enums/modeEnum'
|
||||
import { parseEmpty, timeFormat } from '@/utils/util'
|
||||
import { parseCouponTime } from '@/utils/util'
|
||||
import { useCreateModal } from '@/hooks/useCreateModal'
|
||||
import { formatString, parseCouponTime, parseEmpty } from '@/utils/util'
|
||||
import { ref } from 'vue'
|
||||
import cancelOrderDialog from './components/cancelOrderDialog.vue'
|
||||
import dispatchDialog from './components/dispatchDialog.vue'
|
||||
import Operation from './components/operation.vue'
|
||||
import { useCancelOrderAction } from './hook'
|
||||
|
||||
const route = useRoute()
|
||||
|
@ -321,7 +331,9 @@ const goodsData = ref<any>([
|
|||
deductionMoney: '',
|
||||
totalAmount: '',
|
||||
orderAmount: '',
|
||||
couponDetailVo: {}
|
||||
couponDetailVo: {},
|
||||
priceType: PriceEnum.CUSTOMER_PRICE,
|
||||
priceRange: ''
|
||||
}
|
||||
])
|
||||
const couponInfo = ref([
|
||||
|
@ -387,6 +399,10 @@ const orderRefundDetailVo = computed(() => (unref(isShowOrderRefundDetailVo) ? u
|
|||
|
||||
/**是否派发给师傅 */
|
||||
const isDispatch = computed(() => (status: number) => status === ReceiveOrderEnum.PAUSE)
|
||||
const parsePrice = computed(() => row => {
|
||||
const { priceType, priceRange, goodsPrice } = row
|
||||
return priceType == PriceEnum.CUSTOMER_PRICE ? goodsPrice : formatString(priceRange)
|
||||
})
|
||||
|
||||
function generateCouponFields(res: any) {
|
||||
const fields = {
|
||||
|
@ -423,7 +439,8 @@ const handleChange = (val: any) => {
|
|||
return val
|
||||
}
|
||||
|
||||
const areaValue = ref([440000, 440100, 440118])
|
||||
// const areaValue = ref([440000, 440100, 440118])
|
||||
const areaValue = ref([])
|
||||
// 选中不同地区的师傅列表
|
||||
const handleSelect = async (val: number[]) => {
|
||||
// 记录所选地区
|
||||
|
@ -435,13 +452,24 @@ const handleSelect = async (val: number[]) => {
|
|||
isReceiveOrder: ReceiveOrderEnum.ENABLEDING,
|
||||
isOrder: ReceiveOrderEnum.ENABLEDING,
|
||||
appointTimeStart: unref(formData).appointTimeStart,
|
||||
appointTimeEnd: unref(formData).appointTimeEnd
|
||||
appointTimeEnd: unref(formData).appointTimeEnd,
|
||||
goodsId: goodsData.value[0].goodsId,
|
||||
staffId: formData.value.staffId
|
||||
}
|
||||
const { lists } = await apiMasterLists({ ...params })
|
||||
staffData.value = lists
|
||||
areaValue.value = val
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formData.value.staffId,
|
||||
newVal => {
|
||||
if (newVal) {
|
||||
const { provinceId, cityId, districtId } = formData.value
|
||||
areaValue.value = [provinceId, cityId, districtId]
|
||||
handleSelect(areaValue.value)
|
||||
}
|
||||
}
|
||||
)
|
||||
// 指派师傅
|
||||
const handleDispatch = async () => {
|
||||
getOrderDetail()
|
||||
|
@ -517,7 +545,7 @@ const handleReDispatch = () => {
|
|||
|
||||
// 取消指派
|
||||
const handleCancel = () => {
|
||||
btnStatus.value = 2
|
||||
btnStatus.value = formData.value.staffId ? 2 : 0
|
||||
selStaff.value = ''
|
||||
getOrderDetail()
|
||||
}
|
||||
|
@ -542,4 +570,8 @@ onMounted(async () => {
|
|||
.button-group {
|
||||
border-top: 1px solid #f2f2f2;
|
||||
}
|
||||
.order-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,19 +10,19 @@
|
|||
<el-form-item label="服务名称">
|
||||
<el-input class="ls-input" v-model="formData.goodsName" placeholder="请输入服务名称" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="师傅信息">
|
||||
<el-form-item label="师傅信息">
|
||||
<el-input class="ls-input" v-model="formData.staffInfo" placeholder="请输入师傅信息" clearable />
|
||||
</el-form-item> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="支付状态">
|
||||
<el-select v-model="formData.payStatus" placeholder="请选择" class="ls-input">
|
||||
<el-option v-for="option in optionMap.payStatusOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="派单状态">
|
||||
<el-form-item label="派单状态">
|
||||
<el-select v-model="formData.isDispatch" placeholder="请选择" class="ls-input">
|
||||
<el-option v-for="option in optionMap.dispatchOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="下单时间">
|
||||
<data-picker
|
||||
class="ls-input"
|
||||
|
@ -42,9 +42,8 @@
|
|||
<el-tabs class="-mt-2" v-model="formData.orderStatus" @tab-change="resetPage">
|
||||
<el-tab-pane :label="`全部(${countData?.totalCount || '0'})`" name="" />
|
||||
<el-tab-pane :label="`待支付(${countData?.waitPayCount || '0'})`" :name="0" />
|
||||
<!-- <el-tab-pane :label="`预约中(${countData?.reserveCount || '0'})`" :name="1" />
|
||||
<el-tab-pane :label="`服务中(${countData?.servicingCount || '0'})`" :name="2" /> -->
|
||||
<el-tab-pane :label="`已预约(${countData?.servicingCount || '0'})`" :name="2" />
|
||||
<el-tab-pane :label="`预约中(${countData?.reserveCount || '0'})`" :name="1" />
|
||||
<el-tab-pane :label="`服务中(${countData?.servicingCount || '0'})`" :name="2" />
|
||||
<el-tab-pane :label="`已完成(${countData?.finishedCount || '0'})`" :name="3" />
|
||||
<el-tab-pane :label="`退款单(${countData?.closeCount || '0'})`" :name="4" />
|
||||
</el-tabs>
|
||||
|
@ -91,23 +90,26 @@
|
|||
</div>
|
||||
<router-link :to="`/service/lists/edit?id=${row.goodsId}`" class="ml-2 xs">
|
||||
<div class="goods-name truncate w-44">{{ row.goodsName }}</div>
|
||||
<div class="form-tips">{{ row.goodsPrice }} {{ row.unitName }}</div>
|
||||
<div class="form-tips">{{ parsePrice(row) }} {{ row.unitName }}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实付金额" min-width="100">
|
||||
<template #default="scope">¥{{ scope.row.orderAmount }}</template>
|
||||
<el-table-column label="服务金额" min-width="100">
|
||||
<template #default="scope">¥{{ parsePrice(scope.row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预约日期" min-width="160">
|
||||
<!-- <el-table-column label="实付金额" min-width="100">
|
||||
<template #default="scope">¥{{ scope.row.orderAmount }}</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="预约日期" min-width="180">
|
||||
<template #default="scope">
|
||||
{{ scope.row.appointTime }} {{ scope.row.weekDay }} {{ scope.row.appointTimeStartStr }}-{{ scope.row.appointTimeEndStr }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="contact" label="联系人" min-width="100" />
|
||||
<!-- <el-table-column property="staffName" label="服务师傅" min-width="100">
|
||||
<el-table-column property="staffName" label="服务师傅" min-width="100">
|
||||
<template #default="{ row }">{{ parseEmpty(row, 'staffName') }}</template>
|
||||
</el-table-column> -->
|
||||
</el-table-column>
|
||||
<el-table-column label="订单状态" min-width="100">
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
|
@ -119,12 +121,12 @@
|
|||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="派单状态" width="100" prop="isDispatchName">
|
||||
<el-table-column label="派单状态" width="100" prop="isDispatchName">
|
||||
<template v-slot="{ row }">
|
||||
<el-tag type="success" v-if="row.isDispatch === 1">已派单</el-tag>
|
||||
<el-tag type="danger" v-if="row.isDispatch === 0">未派单</el-tag>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="140" fixed="right">
|
||||
<template #default="scope">
|
||||
<router-link
|
||||
|
@ -163,13 +165,13 @@
|
|||
import { apiOrderLists, apiOrderStatis } from '@/api/order/lists'
|
||||
import { reactive, onMounted, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { OrderMode } from '@/enums/modeEnum'
|
||||
import { OrderMode, PriceEnum } from '@/enums/modeEnum'
|
||||
import Operation from './components/operation.vue'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import DataPicker from '@/components/daterange-picker/index.vue'
|
||||
import cancelOrderDialog from './components/cancelOrderDialog.vue'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { parseEmpty } from '@/utils/util'
|
||||
import { formatString, parseEmpty } from '@/utils/util'
|
||||
import { optionMap } from '@/config/status'
|
||||
import { useCancelOrderAction } from './hook'
|
||||
|
||||
|
@ -183,6 +185,8 @@ interface formDataObj {
|
|||
orderStatus: string | number //否 int 订单状态;0-待支付;1-预约中;2-服务中;3-已完成;4-已取消
|
||||
staffInfo: string // 否 师傅信息
|
||||
isDispatch: string | number // 否 int 派单状态;0-委派单;1-已派单
|
||||
priceType: PriceEnum
|
||||
priceRange: string
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
|
@ -196,7 +200,9 @@ const formData = reactive<formDataObj>({
|
|||
orderTimeEnd: '',
|
||||
orderStatus: '',
|
||||
staffInfo: route.query.staffInfo ?? '',
|
||||
isDispatch: ''
|
||||
isDispatch: '',
|
||||
priceType: PriceEnum.CUSTOMER_PRICE,
|
||||
priceRange: ''
|
||||
})
|
||||
const getOrderAmount = async () => {
|
||||
countData.value = await apiOrderStatis(formData)
|
||||
|
@ -206,6 +212,10 @@ const setStatusColor = computed(() => {
|
|||
return val === '待支付' || val === '已退款' || val === '退款中'
|
||||
}
|
||||
})
|
||||
const parsePrice = computed(() => row => {
|
||||
const { priceType, priceRange, goodsPrice } = row
|
||||
return priceType == PriceEnum.CUSTOMER_PRICE ? goodsPrice : formatString(priceRange)
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
fetchFun: apiOrderLists,
|
||||
|
|
|
@ -26,13 +26,24 @@
|
|||
<div class="form-tips">建议尺寸:750*750,可拖拽改变图片顺序,最多上传10张</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="前台价格:" prop="price">
|
||||
<el-input class="w-56 ls-input" v-model="modelValue.price" placeholder="请输入价格" />
|
||||
<el-form-item label="前台价格:" prop="price" class="price">
|
||||
<el-radio-group v-model="modelValue.priceType">
|
||||
<el-radio v-for="item in priceOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
<template v-if="modelValue.priceType == PriceEnum.CUSTOMER_PRICE">
|
||||
<el-input class="w-56 ls-input" v-model="modelValue.price" placeholder="请输入价格" />
|
||||
</template>
|
||||
<template v-else-if="modelValue.priceType == PriceEnum.TEACHER_PRICE">
|
||||
<div>
|
||||
<el-input class="w-56 ls-input" v-model="modelValue.minPrice" placeholder="请输入价格" />
|
||||
<span class="mx-[6px]">至</span>
|
||||
<el-input class="w-56 ls-input" v-model="modelValue.maxPrice" placeholder="请输入价格" />
|
||||
</div>
|
||||
</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="折前价格:" prop="scribingPrice">
|
||||
<!-- <el-form-item label="折前价格:" prop="scribingPrice">
|
||||
<el-input class="w-56 ls-input" v-model="modelValue.scribingPrice" placeholder="请输入折前价格" />
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="单位:" prop="unitId">
|
||||
<!-- 选择单位 -->
|
||||
<el-select v-model="modelValue.unitId" class="w-56 select" placeholder="请选择">
|
||||
|
@ -80,6 +91,7 @@ import { apiGetGoodsTimeAllList } from '@/api/service/subscribe'
|
|||
import { reactive, ref } from 'vue'
|
||||
import MaterialPicker from '@/components/material/picker.vue'
|
||||
import unitForm from '../../unit/components/unit-form.vue'
|
||||
import { PriceEnum } from '@/enums/modeEnum'
|
||||
|
||||
interface Lists {
|
||||
name: string
|
||||
|
@ -95,6 +107,10 @@ withDefaults(
|
|||
}
|
||||
)
|
||||
|
||||
const priceOptions = shallowRef([
|
||||
{ label: '固定价格', value: PriceEnum.CUSTOMER_PRICE },
|
||||
{ label: '价格区间', value: PriceEnum.TEACHER_PRICE }
|
||||
])
|
||||
const categoryData = ref<Array<Lists> | null>([])
|
||||
const unitData = ref<Array<Lists> | null>([])
|
||||
const goodsTimeData = ref<Array<Lists> | null>([])
|
||||
|
@ -133,6 +149,11 @@ const toAddCategory = () => {
|
|||
getCategoryLists()
|
||||
getUnitCommonLists()
|
||||
getGoodsTimeLists()
|
||||
|
||||
const formItemRef = ref()
|
||||
defineExpose({
|
||||
formItemRef
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -144,4 +165,12 @@ getGoodsTimeLists()
|
|||
width: 340px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.price {
|
||||
:deep(> .el-form-item__content) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: normal;
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -38,7 +38,8 @@ import editorVue from '@/components/editor/index.vue'
|
|||
import FooterBtns from '@/components/footer-btns/index.vue'
|
||||
import type { ElForm, FormRules } from 'element-plus'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { isNumber, isNumberWithDot, validateServiceCommissionRate } from '@/utils/validate'
|
||||
import { isNumber, isNumberWithDot, validatePirce, validateServiceCommissionRate } from '@/utils/validate'
|
||||
import { PriceEnum } from '@/enums/modeEnum'
|
||||
|
||||
interface formDataObj {
|
||||
name?: string
|
||||
|
@ -56,6 +57,10 @@ interface formDataObj {
|
|||
distributorCommissionRate: number
|
||||
staffCommissionRate: number
|
||||
goodsTimeId?: string
|
||||
priceType: number
|
||||
priceRange: Array<{ minPrice: number | string; maxPrice: number | string }>
|
||||
maxPrice: number | string
|
||||
minPrice: number | string
|
||||
}
|
||||
type FormInstance = InstanceType<typeof ElForm>
|
||||
const formRef = ref<FormInstance>()
|
||||
|
@ -72,7 +77,11 @@ const formData = ref<formDataObj>({
|
|||
remarks: '',
|
||||
categoryId: '',
|
||||
image: '',
|
||||
price: '',
|
||||
priceType: PriceEnum.CUSTOMER_PRICE,
|
||||
price: '', //固定价格
|
||||
priceRange: [], //价格区间
|
||||
minPrice: '', //价格区间-下限
|
||||
maxPrice: '', //价格区间-上限
|
||||
scribingPrice: '',
|
||||
unitId: '',
|
||||
status: 0,
|
||||
|
@ -90,7 +99,7 @@ const rules = ref<FormRules>({
|
|||
name: [{ required: true, message: '请输入服务名称', trigger: 'blur' }],
|
||||
categoryId: [{ required: true, message: '请选择分类', trigger: 'change' }],
|
||||
// image: [{ required: true, message: '请上传轮播图', trigger: 'change' }],
|
||||
price: [{ required: true, message: '请输入价格', trigger: 'blur' }],
|
||||
price: [{ validator: (...args) => validatePirce(args, formData.value), trigger: 'blur' }],
|
||||
unitId: [{ required: true, message: '请选择单位', trigger: 'change' }],
|
||||
status: [{ required: true, message: '请选择商品状态', trigger: 'change' }],
|
||||
isNewRecommend: [{ required: true, message: '请选择新品推荐', trigger: 'change' }],
|
||||
|
@ -120,12 +129,13 @@ const getServiceDetail = async (): Promise<void> => {
|
|||
// 添加
|
||||
const handleServiceAdd = async (): Promise<void> => {
|
||||
// const str = formData.value.image.join(',')
|
||||
if (!isNumberWithDot(formData.value.price as string)) return feedback.msgError('价格必须大于或等于零')
|
||||
if (formData.value.scribingPrice && !isNumberWithDot(formData.value.scribingPrice as string)) return feedback.msgError('折前价格必须为纯数字')
|
||||
if (formData.value.scribingPrice && Number(formData.value.price) > Number(formData.value.scribingPrice))
|
||||
return feedback.msgError('前台价格高于折前价格,不合理定价!')
|
||||
// if (!isNumberWithDot(formData.value.price as string)) return feedback.msgError('价格必须大于或等于零')
|
||||
// if (formData.value.scribingPrice && !isNumberWithDot(formData.value.scribingPrice as string)) return feedback.msgError('折前价格必须为纯数字')
|
||||
// if (formData.value.scribingPrice && Number(formData.value.price) > Number(formData.value.scribingPrice))
|
||||
// return feedback.msgError('前台价格高于折前价格,不合理定价!')
|
||||
// 不设置为0,接口返回的还是编辑前的值
|
||||
// !formData.value.scribingPrice && (formData.value.scribingPrice = '0')
|
||||
console.log(formData.value)
|
||||
await apiServiceAdd({ ...formData.value })
|
||||
router.back()
|
||||
feedback.msgSuccess('操作成功')
|
||||
|
@ -135,11 +145,10 @@ const handleServiceAdd = async (): Promise<void> => {
|
|||
const handleServiceEdit = async (): Promise<void> => {
|
||||
// const str = formData.value.image.join(',')
|
||||
if (!isNumber(formData.value.sort as string)) return feedback.msgError('排序必须为纯数字')
|
||||
if (!isNumberWithDot(formData.value.price as string)) return feedback.msgError('价格必须大于或等于零')
|
||||
if (formData.value.scribingPrice && !isNumberWithDot(formData.value.scribingPrice as string)) return feedback.msgError('折前价格必须为纯数字')
|
||||
if (formData.value.scribingPrice && Number(formData.value.price) > Number(formData.value.scribingPrice))
|
||||
return feedback.msgError('前台价格高于折前价格,不合理定价!')
|
||||
console.log('formData.value', formData.value)
|
||||
// if (!isNumberWithDot(formData.value.price as string)) return feedback.msgError('价格必须大于或等于零')
|
||||
// if (formData.value.scribingPrice && !isNumberWithDot(formData.value.scribingPrice as string)) return feedback.msgError('折前价格必须为纯数字')
|
||||
// if (formData.value.scribingPrice && Number(formData.value.price) > Number(formData.value.scribingPrice))
|
||||
// return feedback.msgError('前台价格高于折前价格,不合理定价!')
|
||||
// 不设置为0,接口返回的还是编辑前的值
|
||||
// !formData.value.scribingPrice && (formData.value.scribingPrice = '0')
|
||||
|
||||
|
@ -162,6 +171,21 @@ const onSubmit = (formEl: FormInstance | undefined): void => {
|
|||
}
|
||||
|
||||
if (id) getServiceDetail()
|
||||
|
||||
watch(
|
||||
() => formData.value.priceType,
|
||||
(newVal, oldVal) => {
|
||||
if (newVal !== oldVal) {
|
||||
if (newVal == PriceEnum.TEACHER_PRICE) {
|
||||
formData.value.price = ''
|
||||
formRef.value?.clearValidate(['price'])
|
||||
} else {
|
||||
formData.value.minPrice = ''
|
||||
formData.value.maxPrice = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -74,16 +74,17 @@
|
|||
<el-table-column property="category" label="服务分类" min-width="145" />
|
||||
<el-table-column property="price" label="前台价格" min-width="80">
|
||||
<template #default="scope">
|
||||
<el-input v-if="isEdit" v-model="scope.row.price" placeholder="请输入价格"></el-input>
|
||||
<div v-if="!isEdit">¥{{ scope.row.price }}</div>
|
||||
{{ parsePrice(scope.row) }}
|
||||
<!-- <el-input v-if="isEdit" v-model="scope.row.price" placeholder="请输入价格"></el-input>
|
||||
<div v-if="!isEdit">¥{{ scope.row.price }}</div> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="scribingPrice" label="折前价格" min-width="80">
|
||||
<!-- <el-table-column property="scribingPrice" label="折前价格" min-width="80">
|
||||
<template #default="scope">
|
||||
<el-input v-if="isEdit" v-model="scope.row.scribingPrice" placeholder="请输入价格"></el-input>
|
||||
<div v-if="!isEdit">{{ scope.row.scribingPrice ? '¥' + scope.row.scribingPrice : '' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column> -->
|
||||
<el-table-column property="unit" label="单位" min-width="80" />
|
||||
<el-table-column property="orderNum" label="预约人数" min-width="80" />
|
||||
<el-table-column property="statusDesc" label="销售状态" min-width="80">
|
||||
|
@ -159,6 +160,7 @@ import { ref } from 'vue'
|
|||
import Pagination from '@/components/pagination/index.vue'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { PriceEnum } from '@/enums/modeEnum'
|
||||
|
||||
interface formDataObj {
|
||||
name: string //服务名称
|
||||
|
@ -174,6 +176,10 @@ const formData = ref<formDataObj>({
|
|||
status: '',
|
||||
categoryId: ''
|
||||
})
|
||||
const parsePrice = computed(() => row => {
|
||||
const { priceType, price, minPrice, maxPrice } = row
|
||||
return priceType == PriceEnum.CUSTOMER_PRICE ? price + '元' : minPrice + '-' + maxPrice + '元'
|
||||
})
|
||||
|
||||
const getOrderAmount = async () => {
|
||||
countData.value = await apiServiceStatis({ ...formData.value, status: '' })
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||
<el-form-item label="客服姓名" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入客服姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="客服电话" prop="phone">
|
||||
<el-input v-model="formData.phone" placeholder="请输入客服电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="短信通知" prop="enable" required>
|
||||
<el-radio-group v-model="formData.enable">
|
||||
<el-radio :label="1">开启</el-radio>
|
||||
<el-radio :label="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { addOperation, editOperation, operationDetail } from '@/api/setting/operation_manager'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { validateContact } from '@/utils/validate'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑客服' : '新增客服'
|
||||
})
|
||||
|
||||
const formData = reactive({
|
||||
enable: 1,
|
||||
name: '',
|
||||
phone: ''
|
||||
})
|
||||
|
||||
const formRules = reactive({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入客服姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入客服电话',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
{
|
||||
validator: validateContact,
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
mode.value == 'edit' ? await editOperation(formData) : await addOperation(formData)
|
||||
popupRef.value?.close()
|
||||
feedback.msgSuccess('操作成功')
|
||||
emit('success')
|
||||
}
|
||||
|
||||
const open = (type = 'add') => {
|
||||
mode.value = type
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const setFormData = async (row: any) => {
|
||||
const data = await operationDetail({
|
||||
id: row.id
|
||||
})
|
||||
for (const key in formData) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
formData.id = data.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,97 @@
|
|||
<template>
|
||||
<div class="admin">
|
||||
<el-card v-loading="pager.loading" class="mt-4 !border-none" shadow="never">
|
||||
<el-button v-perms="['setting:operation_manager:add']" type="primary" @click="handleAdd">
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
新增客服
|
||||
</el-button>
|
||||
<div class="mt-4">
|
||||
<el-table :data="pager.lists" size="large">
|
||||
<el-table-column label="客服姓名" prop="name" min-width="100" />
|
||||
<el-table-column label="客服电话" prop="phone" min-width="100" />
|
||||
<el-table-column label="短信通知" min-width="80">
|
||||
<template #default="{ row }">
|
||||
<el-switch :model-value="row.enable" :active-value="1" :inactive-value="0" @change="changeStatus(row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-perms="['setting:operation_manager:edit']" type="primary" link @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button v-perms="['setting:operation_manager:delete']" type="danger" link @click="handleDelete(row.id)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="flex mt-4 justify-end">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="admin">
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
import EditPopup from './edit.vue'
|
||||
import { OperationStatus, delOperation, getOperationList } from '@/api/setting/operation_manager'
|
||||
|
||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
phone: '',
|
||||
enable: 0
|
||||
})
|
||||
const showEdit = ref(false)
|
||||
const { pager, getLists } = usePaging({
|
||||
fetchFun: getOperationList,
|
||||
params: formData
|
||||
})
|
||||
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('add')
|
||||
}
|
||||
|
||||
const handleEdit = async (data: any) => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('edit')
|
||||
editRef.value?.setFormData(data)
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
await feedback.confirm('确定要删除?')
|
||||
await delOperation({ id })
|
||||
feedback.msgSuccess('删除成功')
|
||||
getLists()
|
||||
} catch (error) {}
|
||||
}
|
||||
const changeStatus = (row: any) => {
|
||||
const { id, enable } = row
|
||||
const msg = enable == 1 ? '停用' : '开启'
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
await feedback.confirm(`确定${msg}短信通知?`)
|
||||
await OperationStatus({ id })
|
||||
feedback.msgSuccess('修改成功')
|
||||
getLists()
|
||||
resolve(true)
|
||||
} catch (error) {
|
||||
getLists()
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getLists()
|
||||
})
|
||||
</script>
|
|
@ -1,66 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>粤好生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>思缘生活-后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.preload {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.circular {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
animation: loading-rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.circular .path {
|
||||
animation: loading-dash 1.5s ease-in-out infinite;
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-width: 2;
|
||||
stroke: #4073fa;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
@keyframes loading-rotate {
|
||||
100% {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading-dash {
|
||||
0% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 90, 150;
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue