first
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?
|
5
babel.config.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
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"
|
||||
]
|
||||
}
|
||||
}
|
13087
package-lock.json
generated
Normal file
39
package.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "xhysalesweb",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@infectoone/vue-ganttastic": "^2.3.2",
|
||||
"@pureadmin/utils": "^2.5.0",
|
||||
"axios": "^1.7.7",
|
||||
"core-js": "^3.8.3",
|
||||
"echarts": "^5.5.1",
|
||||
"element-plus": "^2.8.3",
|
||||
"sass": "^1.79.2",
|
||||
"sass-loader": "^16.0.1",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3",
|
||||
"vue3-count-to": "^1.1.2",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-icons/ep": "^1.2.12",
|
||||
"@iconify/icons-ri": "^1.2.10",
|
||||
"@iconify/vue": "^4.2.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead",
|
||||
"not ie 11"
|
||||
]
|
||||
}
|
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 4.2 KiB |
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>
|
9
src/App.vue
Normal file
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
html,body,#app{
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
BIN
src/assets/logo.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
182
src/assets/styles/border.css
Normal file
|
@ -0,0 +1,182 @@
|
|||
@charset "utf-8";
|
||||
.border,
|
||||
.border-top,
|
||||
.border-right,
|
||||
.border-bottom,
|
||||
.border-left,
|
||||
.border-topbottom,
|
||||
.border-rightleft,
|
||||
.border-topleft,
|
||||
.border-rightbottom,
|
||||
.border-topright,
|
||||
.border-bottomleft {
|
||||
position: relative;
|
||||
}
|
||||
.border::before,
|
||||
.border-top::before,
|
||||
.border-right::before,
|
||||
.border-bottom::before,
|
||||
.border-left::before,
|
||||
.border-topbottom::before,
|
||||
.border-topbottom::after,
|
||||
.border-rightleft::before,
|
||||
.border-rightleft::after,
|
||||
.border-topleft::before,
|
||||
.border-topleft::after,
|
||||
.border-rightbottom::before,
|
||||
.border-rightbottom::after,
|
||||
.border-topright::before,
|
||||
.border-topright::after,
|
||||
.border-bottomleft::before,
|
||||
.border-bottomleft::after {
|
||||
content: "\0020";
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
/* border
|
||||
* 因,边框是由伪元素区域遮盖在父级
|
||||
* 故,子级若有交互,需要对子级设置
|
||||
* 定位 及 z轴
|
||||
*/
|
||||
.border::before {
|
||||
box-sizing: border-box;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 1px solid #eaeaea;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.border-top::before,
|
||||
.border-bottom::before,
|
||||
.border-topbottom::before,
|
||||
.border-topbottom::after,
|
||||
.border-topleft::before,
|
||||
.border-rightbottom::after,
|
||||
.border-topright::before,
|
||||
.border-bottomleft::before {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
.border-right::before,
|
||||
.border-left::before,
|
||||
.border-rightleft::before,
|
||||
.border-rightleft::after,
|
||||
.border-topleft::after,
|
||||
.border-rightbottom::before,
|
||||
.border-topright::after,
|
||||
.border-bottomleft::after {
|
||||
top: 0;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
.border-top::before,
|
||||
.border-topbottom::before,
|
||||
.border-topleft::before,
|
||||
.border-topright::before {
|
||||
border-top: 1px solid #eaeaea;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.border-right::before,
|
||||
.border-rightbottom::before,
|
||||
.border-rightleft::before,
|
||||
.border-topright::after {
|
||||
border-right: 1px solid #eaeaea;
|
||||
transform-origin: 100% 0;
|
||||
}
|
||||
.border-bottom::before,
|
||||
.border-topbottom::after,
|
||||
.border-rightbottom::after,
|
||||
.border-bottomleft::before {
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
transform-origin: 0 100%;
|
||||
}
|
||||
.border-left::before,
|
||||
.border-topleft::after,
|
||||
.border-rightleft::after,
|
||||
.border-bottomleft::after {
|
||||
border-left: 1px solid #eaeaea;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.border-top::before,
|
||||
.border-topbottom::before,
|
||||
.border-topleft::before,
|
||||
.border-topright::before {
|
||||
top: 0;
|
||||
}
|
||||
.border-right::before,
|
||||
.border-rightleft::after,
|
||||
.border-rightbottom::before,
|
||||
.border-topright::after {
|
||||
right: 0;
|
||||
}
|
||||
.border-bottom::before,
|
||||
.border-topbottom::after,
|
||||
.border-rightbottom::after,
|
||||
.border-bottomleft::after {
|
||||
bottom: 0;
|
||||
}
|
||||
.border-left::before,
|
||||
.border-rightleft::before,
|
||||
.border-topleft::after,
|
||||
.border-bottomleft::before {
|
||||
left: 0;
|
||||
}
|
||||
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
|
||||
/* 默认值,无需重置 */
|
||||
}
|
||||
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
|
||||
.border::before {
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
transform: scale(.5);
|
||||
}
|
||||
.border-top::before,
|
||||
.border-bottom::before,
|
||||
.border-topbottom::before,
|
||||
.border-topbottom::after,
|
||||
.border-topleft::before,
|
||||
.border-rightbottom::after,
|
||||
.border-topright::before,
|
||||
.border-bottomleft::before {
|
||||
transform: scaleY(.5);
|
||||
}
|
||||
.border-right::before,
|
||||
.border-left::before,
|
||||
.border-rightleft::before,
|
||||
.border-rightleft::after,
|
||||
.border-topleft::after,
|
||||
.border-rightbottom::before,
|
||||
.border-topright::after,
|
||||
.border-bottomleft::after {
|
||||
transform: scaleX(.5);
|
||||
}
|
||||
}
|
||||
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
|
||||
.border::before {
|
||||
width: 300%;
|
||||
height: 300%;
|
||||
transform: scale(.33333);
|
||||
}
|
||||
.border-top::before,
|
||||
.border-bottom::before,
|
||||
.border-topbottom::before,
|
||||
.border-topbottom::after,
|
||||
.border-topleft::before,
|
||||
.border-rightbottom::after,
|
||||
.border-topright::before,
|
||||
.border-bottomleft::before {
|
||||
transform: scaleY(.33333);
|
||||
}
|
||||
.border-right::before,
|
||||
.border-left::before,
|
||||
.border-rightleft::before,
|
||||
.border-rightleft::after,
|
||||
.border-topleft::after,
|
||||
.border-rightbottom::before,
|
||||
.border-topright::after,
|
||||
.border-bottomleft::after {
|
||||
transform: scaleX(.33333);
|
||||
}
|
||||
}
|
26
src/assets/styles/reset.css
Normal file
|
@ -0,0 +1,26 @@
|
|||
@charset "utf-8";
|
||||
html{background-color:#fff;color:#000;font-size:12px}
|
||||
body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding:0}
|
||||
body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
|
||||
h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{font-size:100%}
|
||||
h1,h2,h3,h4,h5,h6{font-family:tahoma,arial,"Hiragino Sans GB","微软雅黑",simsun,sans-serif}
|
||||
h1,h2,h3,h4,h5,h6,b,strong{font-weight:normal}
|
||||
address,cite,dfn,em,i,optgroup,var{font-style:normal}
|
||||
table{border-collapse:collapse;border-spacing:0;text-align:left}
|
||||
caption,th{text-align:inherit}
|
||||
ul,ol,menu{list-style:none}
|
||||
fieldset,img{border:0}
|
||||
img,object,input,textarea,button,select{vertical-align:middle}
|
||||
article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{display:block}
|
||||
audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
|
||||
blockquote:before,blockquote:after,q:before,q:after{content:"\0020"}
|
||||
textarea{overflow:auto;resize:vertical}
|
||||
input,textarea,button,select,a{outline:0 none;border: none;}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
|
||||
mark{background-color:transparent}
|
||||
a,ins,s,u,del{text-decoration:none}
|
||||
sup,sub{vertical-align:baseline}
|
||||
html {overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
|
||||
body {font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
|
||||
hr {height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
|
||||
a {color: #25a4bb;text-decoration: none;}
|
27
src/components/SvgIcon/index.vue
Normal file
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<svg class="svg-icon" aria-hidden="true">
|
||||
<use :xlink:href="iconName"></use>
|
||||
</svg>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineProps, computed} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const iconName = computed(() => {
|
||||
return `#icon-${props.icon}`
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
8
src/icons/index.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import SvgIcon from '@/components/SvgIcon'
|
||||
|
||||
const svgRequired = require.context('./svg', false, /\.svg$/)
|
||||
svgRequired.keys().forEach((item) => svgRequired(item))
|
||||
|
||||
export default (app) => {
|
||||
app.component('svg-icon', SvgIcon)
|
||||
}
|
1
src/icons/svg/exit-fullscreen.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
1
src/icons/svg/eye-open.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/icons/svg/eye.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>
|
After Width: | Height: | Size: 944 B |
1
src/icons/svg/fullscreen.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg>
|
After Width: | Height: | Size: 421 B |
1
src/icons/svg/guide.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.482 70.131l36.204 16.18 69.932-65.485-61.38 70.594 46.435 18.735c1.119.425 2.397-.17 2.797-1.363v-.085L127.998.047 1.322 65.874c-1.12.597-1.519 1.959-1.04 3.151.32.511.72.937 1.2 1.107zm44.676 57.821L64.22 107.26l-18.062-7.834v28.527z"/></svg>
|
After Width: | Height: | Size: 320 B |
1
src/icons/svg/hamburger-closed.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg t="1631523205707" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1504" width="128" height="128"><path d="M393.67111111 432.35555555h546.13333334a9.10222222 9.10222222 0 0 0 9.10222222-9.10222222v-63.71555555a9.10222222 9.10222222 0 0 0-9.10222222-9.10222223H393.67111111a9.10222222 9.10222222 0 0 0-9.10222222 9.10222223v63.71555555a9.10222222 9.10222222 0 0 0 9.10222222 9.10222222z m-9.10222222 232.10666667a9.10222222 9.10222222 0 0 0 9.10222222 9.10222223h546.13333334a9.10222222 9.10222222 0 0 0 9.10222222-9.10222223v-63.71555555a9.10222222 9.10222222 0 0 0-9.10222222-9.10222222H393.67111111a9.10222222 9.10222222 0 0 0-9.10222222 9.10222222v63.71555555z m573.44-552.96H65.99111111a9.10222222 9.10222222 0 0 0-9.10222222 9.10222223v63.71555555a9.10222222 9.10222222 0 0 0 9.10222222 9.10222222h892.01777778a9.10222222 9.10222222 0 0 0 9.10222222-9.10222222v-63.71555555a9.10222222 9.10222222 0 0 0-9.10222222-9.10222223z m0 719.07555556H65.99111111a9.10222222 9.10222222 0 0 0-9.10222222 9.10222222v63.71555555a9.10222222 9.10222222 0 0 0 9.10222222 9.10222223h892.01777778a9.10222222 9.10222222 0 0 0 9.10222222-9.10222223v-63.71555555a9.10222222 9.10222222 0 0 0-9.10222222-9.10222222zM91.47733333 660.02488889L269.312 519.96444445a10.01244445 10.01244445 0 0 0 0-15.81511112L91.47733333 363.97511111a10.12622222 10.12622222 0 0 0-16.384 7.85066667v280.23466667a10.12622222 10.12622222 0 0 0 16.384 7.96444444z" p-id="1505"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
1
src/icons/svg/hamburger-opened.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg t="1631523178203" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1362" width="128" height="128"><path d="M630.32888889 591.64444445l-546.13333334 0a9.10222222 9.10222222 0 0 0-9.10222222 9.10222222l0 63.71555555a9.10222222 9.10222222 0 0 0 9.10222222 9.10222223L630.32888889 673.56444444a9.10222222 9.10222222 0 0 0 9.10222222-9.10222222l0-63.71555555a9.10222222 9.10222222 0 0 0-9.10222222-9.10222222z m9.10222222-232.10666667a9.10222222 9.10222222 0 0 0-9.10222222-9.10222222l-546.13333334-1e-8a9.10222222 9.10222222 0 0 0-9.10222222 9.10222223l0 63.71555555a9.10222222 9.10222222 0 0 0 9.10222222 9.10222222L630.32888889 432.35555555a9.10222222 9.10222222 0 0 0 9.10222222-9.10222222l0-63.71555555z m-573.44 552.96L958.00888889 912.49777778a9.10222222 9.10222222 0 0 0 9.10222221-9.10222223l1e-8-63.71555555a9.10222222 9.10222222 0 0 0-9.10222222-9.10222222l-892.01777778 0a9.10222222 9.10222222 0 0 0-9.10222222 9.10222222l1e-8 63.71555555a9.10222222 9.10222222 0 0 0 9.10222221 9.10222223z m0-719.07555556L958.00888889 193.42222222a9.10222222 9.10222222 0 0 0 9.10222222-9.10222222l-1e-8-63.71555555a9.10222222 9.10222222 0 0 0-9.10222221-9.10222223l-892.01777778 0a9.10222222 9.10222222 0 0 0-9.10222221 9.10222223l-1e-8 63.71555555a9.10222222 9.10222222 0 0 0 9.10222222 9.10222222zM932.52266667 363.97511111L754.688 504.03555555a10.01244445 10.01244445 0 0 0 0 15.81511112L932.52266667 660.02488889a10.12622222 10.12622222 0 0 0 16.384-7.85066667l0-280.23466667a10.12622222 10.12622222 0 0 0-16.384-7.96444444z" p-id="1363"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
src/icons/svg/language.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.742 36.8c2.398 7.2 5.595 12.8 11.19 18.4 4.795-4.8 7.992-11.2 10.39-18.4h-21.58zm-52.748 40h20.78l-10.39-28-10.39 28z"/><path d="M111.916 0H16.009C7.218 0 .025 7.2.025 16v96c0 8.8 7.193 16 15.984 16h95.907c8.791 0 15.984-7.2 15.984-16V16c0-8.8-6.394-16-15.984-16zM72.754 103.2c-1.598 1.6-3.197 1.6-4.795 1.6-.8 0-2.398 0-3.197-.8-.8-.8-1.599 0-1.599-.8s-.799-1.6-1.598-3.2c-.8-1.6-.8-2.4-1.599-4l-3.196-8.8H28.797L25.6 96c-1.598 3.2-2.398 5.6-3.197 7.2-.8 1.6-2.398 1.6-4.795 1.6-1.599 0-3.197-.8-4.796-1.6-1.598-1.6-2.397-2.4-2.397-4 0-.8 0-1.6.799-3.2.8-1.6.8-2.4 1.598-4l17.583-44.8c.8-1.6.8-3.2 1.599-4.8.799-1.6 1.598-3.2 2.397-4 .8-.8 1.599-2.4 3.197-3.2 1.599-.8 3.197-.8 4.796-.8 1.598 0 3.196 0 4.795.8 1.598.8 2.398 1.6 3.197 3.2.799.8 1.598 2.4 2.397 4 .8 1.6 1.599 3.2 2.398 5.6l17.583 44c1.598 3.2 2.398 5.6 2.398 7.2-.8.8-1.599 2.4-2.398 4zM116.711 72c-8.791-3.2-15.185-7.2-20.78-12-5.594 5.6-12.787 9.6-21.579 12l-2.397-4c8.791-2.4 15.984-5.6 21.579-11.2C87.939 51.2 83.144 44 81.545 36h-7.992v-3.2h21.58c-1.6-2.4-3.198-5.6-4.796-8l2.397-.8c1.599 2.4 3.997 5.6 5.595 8.8h19.98v4h-7.992c-2.397 8-6.393 15.2-11.189 20 5.595 4.8 11.988 8.8 20.78 11.2l-3.197 4z"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
src/icons/svg/password.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>
|
After Width: | Height: | Size: 623 B |
1
src/icons/svg/user.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>
|
After Width: | Height: | Size: 440 B |
17
src/main.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import '././assets/styles/border.css'
|
||||
import '././assets/styles/reset.css'
|
||||
import SvgIcon from './icons'
|
||||
import '@/router/permission.js'
|
||||
import axios from "axios";
|
||||
|
||||
axios.defaults.withCredentials=true
|
||||
|
||||
// 意思是携带cookie信息,保持session的一致性
|
||||
|
||||
createApp(App).use(store).use(router).use(ElementPlus).use(SvgIcon).mount('#app');
|
103
src/router/index.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import HomeView from '../views/login/index.vue'
|
||||
|
||||
const routes = [
|
||||
|
||||
// {
|
||||
// path: '/home',
|
||||
// name: '首页',
|
||||
// // route level code-splitting
|
||||
// // this generates a separate chunk (about.[hash].js) for this route
|
||||
// // which is lazy-loaded when the route is visited.
|
||||
// component: () => import('../views/home/index')
|
||||
// },
|
||||
{
|
||||
path: '/',
|
||||
name: '首页',
|
||||
component: () => import('../views/layout/index'),
|
||||
redirect: '/home',
|
||||
children:[
|
||||
{
|
||||
path: '/home',
|
||||
name: '首页',
|
||||
component: () => import('../views/home/index')
|
||||
},
|
||||
{
|
||||
path: '/welcome',
|
||||
name: 'welcome',
|
||||
component: () => import('../views/welcome/index')
|
||||
},
|
||||
{
|
||||
path: '/busines',
|
||||
name: '商家',
|
||||
component: () => import('../views/bigType/index'),
|
||||
|
||||
},
|
||||
{
|
||||
path: '/product',
|
||||
name: '商品管理',
|
||||
component: () => import('../views/product/index')
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: '用户',
|
||||
component: () => import('../views/user/index')
|
||||
},
|
||||
{
|
||||
path: '/employee',
|
||||
name: '美甲师',
|
||||
component: () => import('../views/employee/index')
|
||||
},
|
||||
{
|
||||
path: '/modifyPassword',
|
||||
name: '修改密码',
|
||||
component: () => import('../views/modifyPassword/index')
|
||||
},
|
||||
{
|
||||
path: '/order',
|
||||
name: '订单',
|
||||
component: () => import('../views/order/index')
|
||||
},
|
||||
{
|
||||
path: '/personal',
|
||||
name: '个人中心',
|
||||
component: () => import('../views/personalCenter/index')
|
||||
},
|
||||
{
|
||||
path: '/business',
|
||||
name: '商家',
|
||||
component: () => import('../views/business/index')
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
name: '详情',
|
||||
component: () => import('../views/profile/index')
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import( '../views/login/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/test',
|
||||
name: 'test',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import( '../views/test/index.vue')
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
21
src/router/permission.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import router from '@/router/index'
|
||||
const whiteList=['/login']
|
||||
router.beforeEach((to,from,next)=>{
|
||||
let token=window.sessionStorage.getItem("token");
|
||||
// console.log("token="+token);
|
||||
// console.log("to.path="+to.path)
|
||||
// 暂时放行
|
||||
if(token){
|
||||
if(to.path=='/login'){ // 如果是登录请求
|
||||
next('/home') // 跳转后台管理页面
|
||||
}else{
|
||||
next(); // 放行
|
||||
}
|
||||
}else{
|
||||
if(whiteList.includes(to.path)){
|
||||
next() // 放行
|
||||
}else{
|
||||
next("/login") // 跳转登录页面
|
||||
}
|
||||
}
|
||||
})
|
35
src/store/index.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
// import { createStore } from 'vuex'
|
||||
//
|
||||
// export default createStore({
|
||||
// state: {
|
||||
// },
|
||||
// getters: {
|
||||
// },
|
||||
// mutations: {
|
||||
// },
|
||||
// actions: {
|
||||
// },
|
||||
// modules: {
|
||||
// }
|
||||
// })
|
||||
|
||||
import { createStore } from 'vuex'
|
||||
import router from '@/router'
|
||||
export default createStore({
|
||||
state: {
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
// 安全退出
|
||||
logout(){
|
||||
window.sessionStorage.clear();
|
||||
window.localStorage.clear();
|
||||
router.replace('/login')
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
}
|
||||
})
|
108
src/util/axios.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
// 引入axios
|
||||
import axios from 'axios';
|
||||
import {request} from "axios";
|
||||
|
||||
|
||||
|
||||
//let baseUrl='http://localhost:8081/api/';
|
||||
let baseUrl='http://154.8.193.216:1107/api/';
|
||||
// 创建axios实例
|
||||
const httpService = axios.create({
|
||||
// url前缀-'http:xxx.xxx'
|
||||
// baseURL: process.env.BASE_API, // 需自定义
|
||||
baseURL: baseUrl,
|
||||
withCredentials: true,
|
||||
// 请求超时时间
|
||||
timeout: 120000 // 需自定义
|
||||
|
||||
});
|
||||
//添加请求和响应拦截器
|
||||
// 添加请求拦截器
|
||||
httpService.interceptors.request.use(function (config) {
|
||||
// 在发送请求之前做些什么
|
||||
config.headers.token=window.sessionStorage.getItem('token');
|
||||
return config;
|
||||
}, function (error) {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error);
|
||||
});
|
||||
// 添加响应拦截器
|
||||
httpService.interceptors.response.use(function (response) {
|
||||
// 对响应数据做点什么
|
||||
return response;
|
||||
}, function (error) {
|
||||
// 对响应错误做点什么
|
||||
return Promise.reject(error);
|
||||
});
|
||||
/*网络请求部分*/
|
||||
/*
|
||||
* get请求
|
||||
* url:请求地址
|
||||
* params:参数
|
||||
* */
|
||||
export function get(url, params = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpService({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params: params
|
||||
}).then(response => {
|
||||
resolve(response);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
/*
|
||||
* post请求
|
||||
* url:请求地址
|
||||
* params:参数
|
||||
* */
|
||||
export function post(url, params = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpService({
|
||||
url: url,
|
||||
method: 'post',
|
||||
data: params
|
||||
}).then(response => {
|
||||
// console.log(response)
|
||||
resolve(response);
|
||||
}).catch(error => {
|
||||
console.log(error)
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* 文件上传
|
||||
* url:请求地址
|
||||
* params:参数
|
||||
* */
|
||||
export function fileUpload(url, params = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpService({
|
||||
url: url,
|
||||
method: 'post',
|
||||
data: params,
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
}).then(response => {
|
||||
resolve(response);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function getServerUrl(){
|
||||
return baseUrl;
|
||||
}
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
fileUpload,
|
||||
getServerUrl
|
||||
}
|
||||
|
116
src/views/bigType/dialog/index.vue
Normal file
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="大类名称:" prop="name">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="大类描述:" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="4"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
const props=defineProps({
|
||||
id:{
|
||||
type:Number,
|
||||
default:-1,
|
||||
required:true
|
||||
},
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
id:-1,
|
||||
name:"",
|
||||
remark:""
|
||||
})
|
||||
const rules=ref({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入商品大类名称!'
|
||||
}
|
||||
],
|
||||
remark: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入商品大类描述!'
|
||||
}
|
||||
]
|
||||
})
|
||||
const formRef=ref(null);
|
||||
const initFormData=async(id)=>{
|
||||
|
||||
const res=await axios.get("admin/bigType/"+id)
|
||||
form.value=res.data.bigType;
|
||||
console.log(form.value)
|
||||
}
|
||||
watch(
|
||||
()=>props.id,
|
||||
()=>{
|
||||
//console.log("id="+props.id);
|
||||
let id=props.id;
|
||||
if(id!=-1){
|
||||
initFormData(id)
|
||||
}else{
|
||||
formRef.value.resetFields();
|
||||
form.value={
|
||||
id:-1,
|
||||
name:"",
|
||||
remark:""
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initBigTypeList'])
|
||||
const handleClose=()=>{
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
const handleConfirm=()=>{
|
||||
formRef.value.validate(async(valid)=>{
|
||||
if(valid){
|
||||
let result=await axios.post("admin/bigType/save",form.value)
|
||||
let data=result.data;
|
||||
if(data.code==0){
|
||||
ElMessage.success("执行成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initBigTypeList");
|
||||
handleClose();
|
||||
}else{
|
||||
ElMessage.error(data.msg);
|
||||
}
|
||||
}else{
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
121
src/views/bigType/imageDialog/index.vue
Normal file
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="imageDialogVisible"
|
||||
title="商品大类图片更换"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
center
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-upload
|
||||
:headers="headers"
|
||||
class="avatar-uploader"
|
||||
:action="getServerUrl()+'/admin/bigType/uploadImage'"
|
||||
:show-file-list="false"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
>
|
||||
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button type="primary" @click="handleConfirm">确认更换</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios,{getServerUrl} from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
const props=defineProps({
|
||||
imageDialogValue:{
|
||||
type:Object,
|
||||
default:()=>{},
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
id:-1,
|
||||
image:''
|
||||
})
|
||||
const headers=ref({
|
||||
token:window.sessionStorage.getItem('token')
|
||||
})
|
||||
const formRef=ref(null);
|
||||
const imageUrl=ref("")
|
||||
watch(
|
||||
()=>props.imageDialogValue,
|
||||
()=>{
|
||||
form.value=props.imageDialogValue;
|
||||
imageUrl.value=getServerUrl()+'/image/bigType/'+form.value.image
|
||||
},
|
||||
{deep:true,immediate:true}
|
||||
)
|
||||
const beforeAvatarUpload = (file) => {
|
||||
const isJPG = file.type === 'image/jpeg'
|
||||
const isLt2M = file.size / 1024 / 1024 < 2
|
||||
if (!isJPG) {
|
||||
ElMessage.error('图片必须是jpg格式')
|
||||
}
|
||||
if (!isLt2M) {
|
||||
ElMessage.error('图片大小不能超过2M!')
|
||||
}
|
||||
return isJPG && isLt2M
|
||||
}
|
||||
const handleAvatarSuccess=(res)=>{
|
||||
imageUrl.value=getServerUrl()+res.data.src;
|
||||
form.value.image=res.data.title;
|
||||
}
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initBigTypeList'])
|
||||
const handleClose=()=>{
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
const handleConfirm=async()=>{
|
||||
let result=await axios.post("admin/bigType/save",form.value)
|
||||
let data=result.data;
|
||||
if(data.code==0){
|
||||
ElMessage.success("执行成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initBigTypeList");
|
||||
handleClose();
|
||||
}else{
|
||||
ElMessage.error(data.msg);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style >
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
.el-icon.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
.avatar {
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
144
src/views/bigType/index.vue
Normal file
|
@ -0,0 +1,144 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header">
|
||||
<el-col :span="7">
|
||||
<el-input placeholder="请输入商品大类名称..." clearable v-model="queryForm.query"></el-input>
|
||||
</el-col>
|
||||
<el-button type="primary" :icon="Search" @click="initBigTypeList">搜索</el-button>
|
||||
<el-button type="primary" :icon="DocumentAdd" @click="handleDialogValue()" >添加 商品大类</el-button>
|
||||
</el-row>
|
||||
<el-table :data="tableData" stripe style="width: 100%">
|
||||
<el-table-column prop="id" label="#ID" width="80" />
|
||||
<el-table-column prop="name" label="商品大类名称" width="200" />
|
||||
<el-table-column prop="image" label="商品大类图片" width="200">
|
||||
<template v-slot="scope">
|
||||
<img :src="getServerUrl()+'/image/bigType/'+scope.row.image" width="80" height="80"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="商品大类描述"/>
|
||||
<el-table-column prop="action" label="操作" width="300" >
|
||||
<template v-slot="scope">
|
||||
<el-button type="success" @click="handleChangeImage(scope.row)">更换图片</el-button>
|
||||
<el-button type="primary" :icon="Edit"
|
||||
@click="handleDialogValue(scope.row.id)"></el-button>
|
||||
<el-button type="danger" :icon="Delete"
|
||||
@click="handleDelete(scope.row.id)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="queryForm.pageNum"
|
||||
v-model:page-size="queryForm.pageSize"
|
||||
:page-sizes="[5, 10, 15, 20,25]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
|
||||
<Dialog v-model="dialogVisible" :id="id" :dialogTitle="dialogTitle"
|
||||
@initBigTypeList="initBigTypeList"></Dialog>
|
||||
|
||||
|
||||
<ImageDialog v-model="imageDialogVisible" :imageDialogValue="imageDialogValue"
|
||||
@initBigTypeList="initBigTypeList"/>
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search ,Delete,Edit,DocumentAdd} from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
import axios, {getServerUrl} from "@/util/axios";
|
||||
import Dialog from "@/views/bigType/dialog/index.vue";
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import ImageDialog from '@/views/bigType/imageDialog/index.vue'
|
||||
|
||||
|
||||
const handleChangeImage=(row)=>{
|
||||
imageDialogVisible.value=true
|
||||
imageDialogValue.value=JSON.parse(JSON.stringify(row))
|
||||
}
|
||||
|
||||
|
||||
const imageDialogVisible=ref(false)
|
||||
const imageDialogValue=ref({})
|
||||
|
||||
const id=ref(-1)
|
||||
const dialogTitle=ref('');
|
||||
const dialogVisible=ref(false)
|
||||
const handleDialogValue=(bigTypeId)=>{
|
||||
// console.log("bigTypeId="+bigTypeId)
|
||||
if(bigTypeId){
|
||||
id.value=bigTypeId;
|
||||
dialogTitle.value="商品大类修改"
|
||||
// console.log(dialogTitle.value)
|
||||
}else{
|
||||
id.value=-1;
|
||||
dialogTitle.value="商品大类添加"
|
||||
// console.log(dialogTitle.value)
|
||||
}
|
||||
dialogVisible.value=true
|
||||
}
|
||||
const queryForm=ref({
|
||||
query:'',
|
||||
pageNum:1,
|
||||
pageSize:10
|
||||
})
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
const initBigTypeList=async()=>{
|
||||
const res=await axios.post("admin/bigType/list",queryForm.value);
|
||||
tableData.value=res.data.bigTypeList;
|
||||
total.value=res.data.total;
|
||||
}
|
||||
initBigTypeList();
|
||||
const handleSizeChange = (pageSize) => {
|
||||
queryForm.value.pageNum=1;
|
||||
queryForm.value.pageSize=pageSize;
|
||||
initBigTypeList();
|
||||
}
|
||||
const handleCurrentChange = (pageNum) => {
|
||||
queryForm.value.pageNum=pageNum;
|
||||
initBigTypeList();
|
||||
}
|
||||
|
||||
|
||||
const handleDelete=(id)=>{
|
||||
ElMessageBox.confirm(
|
||||
'您确定要删除这条记录吗?',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async() => {
|
||||
let res=await axios.get('admin/bigType/delete/'+id)
|
||||
if(res.data.code==0){
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
initBigTypeList();
|
||||
}else{
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: res.data.msg,
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
166
src/views/business/addDialog/index.vue
Normal file
|
@ -0,0 +1,166 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="BdialogaddVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="门店头像" prop="businessAvatar">
|
||||
<el-input v-model="form.businessAvatar" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户账号" prop="userAccount">
|
||||
<el-input v-model="form.userAccount" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户密码" prop="userPassword">
|
||||
<el-input v-model="form.userPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店名" prop="businessName">
|
||||
<el-input v-model="form.businessName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店手机号" prop="businessPhone">
|
||||
<el-input v-model="form.businessPhone" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺详细地址" prop="address">
|
||||
<el-input v-model="form.address" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店简介" prop="businessProfile">
|
||||
<el-input v-model="form.businessProfile" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="商家相册" prop="businessImages">-->
|
||||
<!-- <el-input v-model="form.businessImages" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="分类ID" prop="categoryId">-->
|
||||
<!-- <el-input v-model="form.categoryId" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="店主名" prop="shopkeeper">
|
||||
<el-input v-model="form.shopkeeper" />
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照" prop="license">
|
||||
<el-input v-model="form.license" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="身份证正反面" prop="frontIdCard">-->
|
||||
<!-- <el-input v-model="form.frontIdCard" />-->
|
||||
<!-- -->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="身份证反面" prop="backIdCard">-->
|
||||
<!-- <el-input v-model="form.backIdCard" /> -->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="银行卡号" prop="bankCard">
|
||||
<el-input v-model="form.bankCard" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始营业时间" prop="startBusiness">
|
||||
<el-time-select
|
||||
v-model="value1"
|
||||
style="width: 100%"
|
||||
start="00:00"
|
||||
step="00:15"
|
||||
end="23:45"
|
||||
placeholder="选择开始营业时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束营业时间" prop="endBusiness">
|
||||
<el-time-select
|
||||
v-model="value2"
|
||||
style="width: 100%"
|
||||
start="00:00"
|
||||
step="00:15"
|
||||
end="23:45"
|
||||
placeholder="选择结束营业时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const value1 = ref('')
|
||||
const value2 = ref('')
|
||||
const props=defineProps({
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
userAccount:"",
|
||||
userPassword:"",
|
||||
address: "",
|
||||
backIdCard: "",
|
||||
bankCard: "",
|
||||
businessAvatar: "",
|
||||
businessImages: "",
|
||||
businessName: "",
|
||||
businessPhone: "",
|
||||
businessProfile: "",
|
||||
categoryId: null,
|
||||
endBusiness: "",
|
||||
frontIdCard: "",
|
||||
license: "",
|
||||
shopkeeper: "",
|
||||
startBusiness: ""
|
||||
|
||||
})
|
||||
// const rules=ref({
|
||||
// name: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请输入商品大类名称!'
|
||||
// }
|
||||
// ],
|
||||
// remark: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请输入商品大类描述!'
|
||||
// }
|
||||
// ]
|
||||
// })
|
||||
const formRef=ref(null);
|
||||
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initBusinessList'])
|
||||
const handleClose=()=>{
|
||||
console.log("用户添加关闭xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
const handleConfirm=()=>{
|
||||
formRef.value.validate(async(valid)=>{
|
||||
if(valid){
|
||||
form.value.startBusiness=value1.value;
|
||||
form.value.endBusiness=value2.value;
|
||||
let result=await axios.post("business/add",form.value)
|
||||
console.log(result.data)
|
||||
let data=result.data;
|
||||
if(data.code==0){
|
||||
ElMessage.success("执行添加成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initBusinessList");
|
||||
handleClose();
|
||||
}else{
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
}else{
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
159
src/views/business/dialog/index.vue
Normal file
|
@ -0,0 +1,159 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="BdialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="门店头像" prop="businessAvatar">
|
||||
<img :src="form.businessAvatar" width="50" height="50"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店名" prop="businessName">
|
||||
{{form.businessName}}
|
||||
</el-form-item>
|
||||
<el-form-item label="门店手机号" prop="businessPhone">
|
||||
{{form.businessPhone}}
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺详细地址" prop="address">
|
||||
{{form.address}}
|
||||
</el-form-item>
|
||||
<el-form-item label="门店简介" prop="businessProfile">
|
||||
{{form.businessProfile}}
|
||||
</el-form-item>
|
||||
<el-form-item label="商家相册" prop="businessImages">
|
||||
{{form.businessImages}}
|
||||
</el-form-item>
|
||||
<el-form-item label="分类ID" prop="categoryId">
|
||||
{{form.categoryId}}
|
||||
</el-form-item>
|
||||
<el-form-item label="店主名" prop="shopkeeper">
|
||||
{{form.shopkeeper}}
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照" prop="license">
|
||||
{{form.license}}
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证正面" prop="frontIdCard">
|
||||
{{form.frontIdCard}}
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证反面" prop="backIdCard">
|
||||
{{form.backIdCard}}
|
||||
</el-form-item>
|
||||
<el-form-item label="银行卡号" prop="bankCard">
|
||||
{{form.bankCard}}
|
||||
</el-form-item>
|
||||
<el-form-item label="开始营业时间" prop="startBusiness">
|
||||
{{form.startBusiness}}
|
||||
</el-form-item>
|
||||
<el-form-item label="结束营业时间" prop="endBusiness">
|
||||
{{form.endBusiness}}
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
{{form.createTime}}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer v-if="title">
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">审核成功</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
const props=defineProps({
|
||||
bussinessId:{
|
||||
type: String,
|
||||
default:-1,
|
||||
required:true
|
||||
},
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
id:null,
|
||||
address: "",
|
||||
backIdCard: "",
|
||||
bankCard: "",
|
||||
businessAvatar: "",
|
||||
businessImages: "",
|
||||
businessName: "",
|
||||
businessPhone: "",
|
||||
businessProfile: "",
|
||||
categoryId: null,
|
||||
endBusiness: "",
|
||||
frontIdCard: "",
|
||||
license: "",
|
||||
state:null,
|
||||
shopkeeper: "",
|
||||
startBusiness: "",
|
||||
createTime:""
|
||||
})
|
||||
|
||||
const formRef=ref(null);
|
||||
const title=ref(false);
|
||||
const initFormData=async(id)=>{
|
||||
// console.log(id)
|
||||
// const res=await axios.get("business/getById",{id: id})
|
||||
|
||||
// // form.value=res.data.data;
|
||||
// form.value=res.data.data;
|
||||
const res=await axios.post("business/list/page",{id: id})
|
||||
console.log(res.data.data)
|
||||
form.value=res.data.data.records[0];
|
||||
}
|
||||
watch(
|
||||
()=>props.bussinessId,
|
||||
()=>{
|
||||
console.log("id="+props.dialogTitle);
|
||||
console.log(props.bussinessId)
|
||||
if (props.dialogTitle=='审核商家'){
|
||||
title.value=true;
|
||||
}
|
||||
let id=props.bussinessId;
|
||||
initFormData(id)
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initBusinessList'])
|
||||
const handleClose=()=>{
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
form.value.state=1
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
let result = await axios.post("business/update", form.value)
|
||||
console.log(result.data.data)
|
||||
let data = result.data;
|
||||
if (data.code == 0) {
|
||||
ElMessage.success("执行成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initBusinessList");
|
||||
handleClose();
|
||||
} else {
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
} else {
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
258
src/views/business/index.vue
Normal file
|
@ -0,0 +1,258 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header">
|
||||
<el-col :span="7">
|
||||
<el-input placeholder="请输入用户昵称..." clearable v-model="formPage.businessName"></el-input>
|
||||
</el-col>
|
||||
<el-button type="button" :icon="Search" @click="initBusinessList">搜索</el-button>
|
||||
<el-button type="primary" :icon="DocumentAdd" @click="handleAddDialogValue()" >添加商家</el-button>
|
||||
|
||||
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px;margin-left: 20px">
|
||||
<el-radio-button :value="true" @click="handleCollapse(true)">审核</el-radio-button>
|
||||
<el-radio-button :value="false" @click="handleCollapse(false)">未审核</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
<el-table :data="tableData" stripe style="width: 100%;" showOverflowTooltip>
|
||||
<el-table-column prop="id" label="#ID" width="80" fixed="fixed" />
|
||||
<el-table-column prop="businessName" label="商家昵称" width="200" />
|
||||
<el-table-column prop="businessAvatar" label="头像" width="150" >
|
||||
<template v-slot="scope">
|
||||
<el-popover
|
||||
placement="right-start"
|
||||
:width="200"
|
||||
trigger="hover"
|
||||
:content="scope.row.businessAvatar"
|
||||
>
|
||||
<template #reference>
|
||||
<img :src="scope.row.businessAvatar" width="50" height="50"/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="businessPhone" label="电话号码" width="120" />
|
||||
<el-table-column prop="state" label="状态" width="80">
|
||||
<template v-slot="scope">
|
||||
<div v-if="scope.row.state===0" style="color: red">
|
||||
禁用
|
||||
</div>
|
||||
<div style="color: lawngreen" v-else>
|
||||
启用
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeStatus" label="店铺状态" width="80">
|
||||
<template v-slot="scope">
|
||||
<div v-if="scope.row.storeStatus===0" style="color: red">
|
||||
休业
|
||||
</div>
|
||||
<div style="color: lawngreen" v-else>
|
||||
营业
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="注册日期" width="200"/>
|
||||
<el-table-column prop="updateTime" label="最后登录日期" width="200"/>
|
||||
<el-table-column prop="action" fixed="right" label="操作" min-width="270" v-if="isCollapse||isCollapse===undefined">
|
||||
<template v-slot="scope" >
|
||||
<el-button type="success" size="small" @click="handleRouter(scope.row)" >
|
||||
商品管理
|
||||
</el-button>
|
||||
<el-button type="success" size="small" @click="handleDialogValue(scope.row.id)">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" :icon="Edit" @click="handleUpdateDialogValue(scope.row.id)"></el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column prop="action" fixed="right" label="操作" min-width="120" v-else>
|
||||
<template v-slot="scope" >
|
||||
<el-button type="primary" size="small" @click="handleClick(scope.row.id)">审核</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="formPage.current"
|
||||
v-model:page-size="formPage.pageSize"
|
||||
:page-sizes="[10, 20, 30, 40,50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
|
||||
<Dialog v-model="BdialogVisible" :bussinessId="bussinessId" :dialogTitle="dialogTitle"
|
||||
@initBusinessList="initBusinessList"></Dialog>
|
||||
<AddDialog v-model="BdialogaddVisible" :dialogTitle="dialogTitle"
|
||||
@initBusinessList="initBusinessList"></AddDialog>
|
||||
<UpdateDialog v-model="BdialogUpdateVisible" :bussinessId="bussinessId" :dialogTitle="dialogTitle"
|
||||
@initBusinessList="initBusinessList"></UpdateDialog>
|
||||
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search,DocumentAdd,Edit} from '@element-plus/icons-vue'
|
||||
import {ref, watch} from 'vue'
|
||||
import axios from "@/util/axios";
|
||||
import { ElNotification } from 'element-plus'
|
||||
import Dialog from '@/views/business/dialog/index.vue'
|
||||
import AddDialog from '@/views/business/addDialog/index.vue'
|
||||
import UpdateDialog from '@/views/business/updateDialog/index.vue'
|
||||
|
||||
import axiosUtil from "@/util/axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
import {useRouter} from "vue-router"
|
||||
import {request} from "axios";
|
||||
|
||||
const isCollapse=ref();
|
||||
const RCollapse=ref([]);
|
||||
const LCollapse=ref([]);
|
||||
const router=useRouter();
|
||||
const bussinessId=ref('')
|
||||
const dialogTitle=ref('');
|
||||
const BdialogaddVisible=ref(false)
|
||||
const BdialogVisible=ref(false)
|
||||
const BdialogUpdateVisible=ref(false)
|
||||
|
||||
|
||||
|
||||
const handleClick=(id)=>{
|
||||
bussinessId.value=id;
|
||||
// console.log(bussinessId.value)
|
||||
dialogTitle.value="审核商家"
|
||||
BdialogVisible.value=true
|
||||
}
|
||||
const handleRouter=(temp)=>{
|
||||
console.log(temp.id)
|
||||
router.push({path:'/product',query:{product: JSON.stringify(temp)}})
|
||||
}
|
||||
const handleDialogValue=(id)=>{
|
||||
//console.log("bigTypeId="+bussinessId)
|
||||
// if(bussinessId){
|
||||
bussinessId.value=id;
|
||||
dialogTitle.value="商家详情"
|
||||
BdialogVisible.value=true
|
||||
}
|
||||
|
||||
const handleUpdateDialogValue=(id)=>{
|
||||
// console.log(bussinessId)
|
||||
bussinessId.value=id;
|
||||
// console.log(bussinessId.value)
|
||||
dialogTitle.value="商家修改"
|
||||
BdialogUpdateVisible.value=true
|
||||
}
|
||||
|
||||
const handleAddDialogValue=()=>{
|
||||
dialogTitle.value="商家添加"
|
||||
BdialogaddVisible.value=true
|
||||
}
|
||||
|
||||
|
||||
|
||||
const formPage=ref({
|
||||
businessName:'',
|
||||
current:1,
|
||||
pageSize:10
|
||||
})
|
||||
|
||||
|
||||
// watch(formPage.value.businessName,()=>{
|
||||
// // console.log(id.value)
|
||||
// initBusinessList();
|
||||
// })
|
||||
|
||||
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
|
||||
|
||||
const handleCollapse=async (temp)=>{
|
||||
console.log(temp)
|
||||
const res=await axios.post("business/list");
|
||||
RCollapse.value.splice(0,RCollapse.value.length);
|
||||
LCollapse.value.splice(0,LCollapse.value.length);
|
||||
// console.log(res.data.data.records)
|
||||
tableData.value=res.data.data;
|
||||
tableData.value.forEach(item => {
|
||||
if(item.state){
|
||||
RCollapse.value.push(item)
|
||||
}
|
||||
else{
|
||||
LCollapse.value.push(item)
|
||||
}
|
||||
|
||||
//console.log(item.state);
|
||||
});
|
||||
console.log("RCollapse"+RCollapse.value);
|
||||
console.log("LCollapse"+LCollapse.value);
|
||||
if (temp){
|
||||
tableData.value=RCollapse.value
|
||||
total.value=Number(RCollapse.value.length);
|
||||
}else {
|
||||
tableData.value=LCollapse.value
|
||||
total.value=Number(LCollapse.value.length);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
const initBusinessList=async()=>{
|
||||
// console.log(formPage.value)
|
||||
const res=await axios.post("business/list/page",formPage.value);
|
||||
// console.log(res.data.data.records)
|
||||
isCollapse.value=undefined;
|
||||
tableData.value=res.data.data.records;
|
||||
total.value=Number(res.data.data.total);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// const initBusinessList=async()=>{
|
||||
//
|
||||
// if(!id.value)
|
||||
// {
|
||||
// const res=await axios.post("business/list/page",formPage.value);
|
||||
// // console.log(res.data.data.records)
|
||||
// tableData.value=res.data.data.records;
|
||||
// // console.log(res.data.data.total)
|
||||
// total.value=res.data.data.records.length;
|
||||
// }
|
||||
// else{
|
||||
// const res=await axios.post("business/list/page", {businessName:id.value});
|
||||
// // console.log(res.data.data)
|
||||
// //const temp=[];
|
||||
// // temp.push(res.data.data)
|
||||
// tableData.value=res.data.data.records;
|
||||
// total.value=res.data.data.records.length;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
initBusinessList();
|
||||
const handleSizeChange = (pageSize) => {
|
||||
formPage.value.current=1;
|
||||
formPage.value.pageSize=pageSize;
|
||||
initBusinessList();
|
||||
}
|
||||
const handleCurrentChange = (pageNum) => {
|
||||
formPage.value.current=pageNum;
|
||||
initBusinessList();
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
138
src/views/business/updateDialog/index.vue
Normal file
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="BdialogUpdateVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="门店头像" prop="businessAvatar">
|
||||
<el-input v-model="form.businessAvatar" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店名" prop="businessName">
|
||||
<el-input v-model="form.businessName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店手机号" prop="businessPhone">
|
||||
<el-input v-model="form.businessPhone" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺详细地址" prop="address">
|
||||
<el-input v-model="form.address" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店简介" prop="businessProfile">
|
||||
<el-input v-model="form.businessProfile" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商家相册" prop="businessImages">
|
||||
<el-input v-model="form.businessImages" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类ID" prop="categoryId">
|
||||
<el-input v-model="form.categoryId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺关联用户ID" prop="userId">
|
||||
<el-input v-model="form.userId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="state">
|
||||
<el-input v-model="form.state" />
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺状态" prop="storeStatus">
|
||||
<el-input v-model="form.state" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始营业时间" prop="startBusiness">
|
||||
<el-input v-model="form.startBusiness" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束营业时间" prop="endBusiness">
|
||||
<el-input v-model="form.endBusiness" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
bussinessId: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
dialogTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const form = ref({
|
||||
id:"",
|
||||
address: "",
|
||||
userId: null,
|
||||
businessAvatar: "",
|
||||
businessImages: "",
|
||||
businessName: "",
|
||||
businessPhone: "",
|
||||
businessProfile: "",
|
||||
categoryId: null,
|
||||
endBusiness: "",
|
||||
state:null,
|
||||
storeStatus: null,
|
||||
startBusiness: ""
|
||||
})
|
||||
|
||||
const formRef = ref(null);
|
||||
const initFormData = async (id) => {
|
||||
//console.log(id)
|
||||
const res=await axios.post("business/list/page",{id: id})
|
||||
form.value=res.data.data.records[0];
|
||||
//console.log(res.data.data)
|
||||
// console.log("bussinessId"+props.bussinessId)
|
||||
}
|
||||
watch(
|
||||
() => props.bussinessId,
|
||||
() => {
|
||||
// console.log("id=" + props.businessId);
|
||||
let id = props.bussinessId;
|
||||
initFormData(id)
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits = defineEmits(['update:modelValue', 'initBusinessList'])
|
||||
const handleClose = () => {
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
|
||||
emits('update:modelValue', false)
|
||||
}
|
||||
const handleConfirm = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
let result = await axios.post("business/update", form.value)
|
||||
console.log(result.data.data)
|
||||
let data = result.data;
|
||||
if (data.code == 0) {
|
||||
ElMessage.success("执行成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initBusinessList");
|
||||
handleClose();
|
||||
} else {
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
} else {
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
118
src/views/employee/addDialog/index.vue
Normal file
|
@ -0,0 +1,118 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="edialogaddVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="用户账号" prop="userAccount">
|
||||
<el-input v-model="form.userAccount" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户密码" prop="userPassword">
|
||||
<el-input v-model="form.userPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="manicuristName">
|
||||
<el-input v-model="form.manicuristName"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-input v-model="form.gender"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="form.phone"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作名称" prop="specialties">
|
||||
<el-input v-model="form.specialties"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="评分" prop="rating">
|
||||
<el-input v-model="form.rating"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="余额" prop="salary">
|
||||
<el-input v-model="form.salary"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="认证号" prop="certification_number">
|
||||
<el-input v-model="form.certification_number"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="认证路径" prop="certificate_path">
|
||||
<el-input v-model="form.certificate_path"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="组织认证" prop="issuing_authority">
|
||||
<el-input v-model="form.issuing_authority"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
const props=defineProps({
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
userAccount:"",
|
||||
userPassword:"",
|
||||
certificate_path: "",
|
||||
certification_number: "",
|
||||
email: "",
|
||||
gender: null,
|
||||
issuing_authority: "",
|
||||
manicuristName: "",
|
||||
phone: "",
|
||||
rating: null,
|
||||
salary: null,
|
||||
specialties: ""
|
||||
|
||||
})
|
||||
|
||||
const formRef=ref(null);
|
||||
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initEmployeeList'])
|
||||
const handleClose=()=>{
|
||||
console.log("用户添加关闭xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
const handleConfirm=()=>{
|
||||
formRef.value.validate(async(valid)=>{
|
||||
if(valid){
|
||||
let result=await axios.post("manicurist/adminAdd",form.value)
|
||||
console.log(result.data)
|
||||
let data=result.data;
|
||||
if(data.code==0){
|
||||
ElMessage.success("执行添加成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initEmployeeList");
|
||||
handleClose();
|
||||
}else{
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
}else{
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
109
src/views/employee/dialog/index.vue
Normal file
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="edialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="头像" prop="manicuristAvatar">
|
||||
|
||||
<img :src="form.manicuristAvatar" width="80px" height="80px"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="manicuristName">
|
||||
{{form.manicuristName}}
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<template v-if="form.gender==0">女</template>
|
||||
<template v-else>男</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
{{form.phone}}
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
{{form.email}}
|
||||
</el-form-item>
|
||||
<el-form-item label="工作名称" prop="specialties">
|
||||
{{form.specialties}}
|
||||
</el-form-item>
|
||||
<el-form-item label="工作时长" prop="employment_date">
|
||||
{{form.employment_date}}
|
||||
</el-form-item>
|
||||
<el-form-item label="评分" prop="rating">
|
||||
{{form.rating}}
|
||||
</el-form-item>
|
||||
<el-form-item label="余额" prop="salary">
|
||||
{{form.salary}}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
const props=defineProps({
|
||||
id:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
},
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
id:null,
|
||||
email: "",
|
||||
gender: null,
|
||||
phone: "",
|
||||
userId:"",
|
||||
businessId: "",
|
||||
manicuristName: "",
|
||||
employment_date: "",
|
||||
specialties: "",
|
||||
rating: null,
|
||||
salary: null,
|
||||
isDelete: null,
|
||||
createTime: "",
|
||||
updateTime: "",
|
||||
manicuristAvatar: "",
|
||||
manStatus: null
|
||||
})
|
||||
|
||||
const formRef=ref(null);
|
||||
const initFormData=async(id)=>{
|
||||
|
||||
const res = await axios.get("manicurist/queryById", {manicuristId: id})
|
||||
form.value=res.data.data;
|
||||
//console.log(res.data.data)
|
||||
}
|
||||
watch(
|
||||
()=>props.id,
|
||||
()=>{
|
||||
//console.log("id="+props.id);
|
||||
let id=props.id;
|
||||
initFormData(id)
|
||||
|
||||
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initEmployeeList'])
|
||||
const handleClose=()=>{
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
382
src/views/employee/index.vue
Normal file
|
@ -0,0 +1,382 @@
|
|||
<template>
|
||||
<!-- <g-gantt-chart-->
|
||||
<!-- chart-start="00:00"-->
|
||||
<!-- chart-end="23:59"-->
|
||||
<!-- precision="hour"-->
|
||||
<!-- date-format="HH:mm"-->
|
||||
<!-- bar-start="beginDate"-->
|
||||
<!-- bar-end="endDate"-->
|
||||
<!-- grid-->
|
||||
<!-- >-->
|
||||
<!-- <template #upper-timeunit>-->
|
||||
<!-- <h1>-->
|
||||
<!-- {{-->
|
||||
<!-- `${weekRangeInChina.currentWeekStart} / ${weekRangeInChina.currentWeekEnd}`-->
|
||||
<!-- }}-->
|
||||
<!-- </h1>-->
|
||||
<!-- </template>-->
|
||||
<!-- <g-gantt-row-->
|
||||
<!-- v-for="(item, index) in context"-->
|
||||
<!-- :key="index"-->
|
||||
<!-- :bars="item"-->
|
||||
<!-- :label="item[0].week"-->
|
||||
<!-- highlight-on-hover-->
|
||||
<!-- />-->
|
||||
<!-- </g-gantt-chart>-->
|
||||
<!--=================================================================-->
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header">
|
||||
<el-col :span="7">
|
||||
<el-input placeholder="请输入用户昵称..." clearable v-model="query" ></el-input>
|
||||
</el-col>
|
||||
<el-button type="button" :icon="Search" @click="initEmployeeList">搜索</el-button>
|
||||
<el-button type="primary" :icon="DocumentAdd" @click="handleAddDialogValue()" >添加用户</el-button>
|
||||
</el-row>
|
||||
<el-table :data="tableData" stripe style="width: 100%;" showOverflowTooltip>
|
||||
<el-table-column prop="id" label="#ID" width="80" />
|
||||
<el-table-column prop="manicuristName" label="用户昵称" width="200" />
|
||||
<el-table-column prop="manicuristAvatar" label="头像" width="200">
|
||||
<template v-slot="scope">
|
||||
<img :src="scope.row.manicuristAvatar" width="50" height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="rating" label="评分" width="200px">
|
||||
<template v-slot="scope" style="height: 100px">
|
||||
<div class="demo-rate-block">
|
||||
<el-rate v-model="scope.row.rating" :colors="colors"/>
|
||||
{{scope.row.rating}}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="salary" label="余额" />
|
||||
<el-table-column prop="createTime" label="注册日期" width="200"/>
|
||||
<el-table-column prop="updateTime" label="最后登录日期" width="200"/>
|
||||
<el-table-column prop="action" fixed="right" label="操作" min-width="220">
|
||||
<template v-slot="scope" >
|
||||
<!-- <el-button @click="handleRouter(scope.row.id)" type="primary" :icon="DocumentAdd" >审核美甲师</el-button>-->
|
||||
<el-button type="success" size="small" @click="handleDialogValue(scope.row.id)">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" :icon="Edit" @click="handleUpdateDialogValue(scope.row.id)"></el-button>
|
||||
<el-button type="danger" size="small" :icon="Delete" @click="handleDelete(scope.row.id)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="queryForm.current"
|
||||
v-model:page-size="queryForm.pageSize"
|
||||
:page-sizes="[10, 20, 30, 40,50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
|
||||
|
||||
|
||||
<Dialog v-model="edialogVisible" :id="id" :dialogTitle="dialogTitle"
|
||||
@initEmployeeList="initEmployeeList"></Dialog>
|
||||
<AddDialog v-model="edialogaddVisible" :dialogTitle="dialogTitle"
|
||||
@initEmployeeList="initEmployeeList"></AddDialog>
|
||||
<UpdateDialog v-model="edialogUpdateVisible" :id="id" :dialogTitle="dialogTitle"
|
||||
@initEmployeeList="initEmployeeList"></UpdateDialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search,DocumentAdd,Delete,Edit} from '@element-plus/icons-vue'
|
||||
import {ref, watch} from 'vue'
|
||||
import axios from "@/util/axios";
|
||||
import Dialog from '@/views/employee/dialog/index.vue'
|
||||
import AddDialog from '@/views/employee/addDialog/index.vue'
|
||||
import UpdateDialog from '@/views/employee/updateDialog/index.vue'
|
||||
import { ElMessage,ElMessageBox } from "element-plus";
|
||||
import { GGanttChart, GGanttRow } from "@infectoone/vue-ganttastic";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const queryForm=ref({
|
||||
current:1,
|
||||
pageSize:10
|
||||
})
|
||||
const query=ref();
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
|
||||
|
||||
const id=ref('')
|
||||
const dialogTitle=ref('');
|
||||
const edialogaddVisible=ref(false)
|
||||
const edialogVisible=ref(false)
|
||||
const edialogUpdateVisible=ref(false)
|
||||
|
||||
|
||||
const handleRouter=(id)=>{
|
||||
bussinessId.value=id;
|
||||
router.push({path:'/profile',query:{id: bussinessId.value}})
|
||||
|
||||
}
|
||||
|
||||
const handleDialogValue=(ids)=>{
|
||||
id.value=ids;
|
||||
dialogTitle.value="美甲师详情"
|
||||
edialogVisible.value=true
|
||||
}
|
||||
|
||||
const handleUpdateDialogValue=(ids)=>{
|
||||
// console.log(id)
|
||||
id.value=ids;
|
||||
// console.log(id.value)
|
||||
dialogTitle.value="美甲师修改"
|
||||
edialogUpdateVisible.value=true
|
||||
}
|
||||
|
||||
const handleAddDialogValue=()=>{
|
||||
dialogTitle.value="美甲师添加"
|
||||
edialogaddVisible.value=true
|
||||
}
|
||||
|
||||
|
||||
const handleDelete=(ids)=>{
|
||||
// console.log(ids)
|
||||
ElMessageBox.confirm(
|
||||
'您确定要删除这条记录吗?',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async() => {
|
||||
let res=await axios.post('manicurist/deleteMan?id='+Number(ids))
|
||||
if(res.data.code==0){
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
initSmallTypeList();
|
||||
}else{
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: res.data.description,
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
// initUserList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
watch(query,()=>{
|
||||
// console.log(query.value)
|
||||
initEmployeeList();
|
||||
},10000)
|
||||
const initEmployeeList=async()=>{
|
||||
if (!query.value){
|
||||
const res=await axios.post("manicurist/queryAll");
|
||||
// console.log(res.data)
|
||||
tableData.value=res.data.data;
|
||||
total.value=res.data.data.length;
|
||||
}else{
|
||||
const res = await axios.get("manicurist/queryById", {manicuristId: query.value});
|
||||
// console.log(res.data)
|
||||
const temp = []
|
||||
temp.push(res.data.data)
|
||||
tableData.value = temp;
|
||||
total.value = 1;
|
||||
}
|
||||
}
|
||||
initEmployeeList();
|
||||
const handleSizeChange = (pageSize) => {
|
||||
queryForm.value.current=1;
|
||||
queryForm.value.pageSize=pageSize;
|
||||
initEmployeeList();
|
||||
}
|
||||
const handleCurrentChange = (current) => {
|
||||
queryForm.value.current=current;
|
||||
initEmployeeList();
|
||||
}
|
||||
|
||||
|
||||
// =============================================
|
||||
const colors = ref(['#99A9BF', '#F7BA2A', '#FF9900'])
|
||||
|
||||
// =========================================================================================================
|
||||
|
||||
|
||||
const context = ref([
|
||||
[
|
||||
{
|
||||
week: "星期一",
|
||||
beginDate: "06:00",
|
||||
endDate: "22:00",
|
||||
ganttBarConfig: {
|
||||
id: "0",
|
||||
hasHandles: true,
|
||||
label: "需求收集和分析 负责人:小张",
|
||||
style: {
|
||||
background: "#e96560"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
week: "星期二",
|
||||
beginDate: "09:00",
|
||||
endDate: "18:00",
|
||||
ganttBarConfig: {
|
||||
id: "1",
|
||||
hasHandles: true,
|
||||
label: "系统设计 负责人:小强",
|
||||
style: {
|
||||
background: "#5ccfa3"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
week: "星期三",
|
||||
beginDate: "07:00",
|
||||
endDate: "20:00",
|
||||
ganttBarConfig: {
|
||||
id: "2",
|
||||
hasHandles: true,
|
||||
label: "编码实现 负责人:老李",
|
||||
style: {
|
||||
background: "#77d6fa"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
week: "星期四",
|
||||
beginDate: "06:00",
|
||||
endDate: "21:00",
|
||||
ganttBarConfig: {
|
||||
id: "3",
|
||||
hasHandles: true,
|
||||
label: "编码实现 负责人:小明",
|
||||
style: {
|
||||
color: "#fff",
|
||||
background: "#1b2a47"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
week: "星期五",
|
||||
beginDate: "05:00",
|
||||
endDate: "19:00",
|
||||
ganttBarConfig: {
|
||||
id: "4",
|
||||
hasHandles: true,
|
||||
label: "内部测试 负责人:小雪",
|
||||
style: {
|
||||
background: "#5ccfa3"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
week: "星期六",
|
||||
beginDate: "10:00",
|
||||
endDate: "22:00",
|
||||
ganttBarConfig: {
|
||||
id: "5",
|
||||
hasHandles: true,
|
||||
label: "系统优化和文档整理 负责人:小欣",
|
||||
style: {
|
||||
background: "#f8bc45"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
week: "星期天",
|
||||
beginDate: "04:00",
|
||||
endDate: "23:59",
|
||||
ganttBarConfig: {
|
||||
id: "6",
|
||||
immobile: false,
|
||||
hasHandles: false,
|
||||
label: "部署和上线 负责人:老王",
|
||||
style: {
|
||||
background: "#f3953d"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
const getWeekRange=()=> {
|
||||
const today = new Date();
|
||||
const dayOfWeek = today.getDay();
|
||||
const startDate = new Date(today);
|
||||
startDate.setDate(today.getDate() - dayOfWeek + 1);
|
||||
const endDate = new Date(startDate);
|
||||
endDate.setDate(startDate.getDate() + 6);
|
||||
const formatDate = date => {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
const currentWeekStart = formatDate(startDate);
|
||||
const currentWeekEnd = formatDate(endDate);
|
||||
return {
|
||||
currentWeekStart,
|
||||
currentWeekEnd
|
||||
};
|
||||
}
|
||||
const weekRangeInChina = getWeekRange();
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.demo-rate-block {
|
||||
padding: 15px 0;
|
||||
text-align: center;
|
||||
border-right: solid 1px var(--el-border-color);
|
||||
display: inline-block;
|
||||
width: 49%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.demo-rate-block:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.demo-rate-block .demonstration {
|
||||
display: block;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
127
src/views/employee/updateDialog/index.vue
Normal file
|
@ -0,0 +1,127 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="edialogUpdateVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="头像" prop="manicuristAvatar">
|
||||
<el-input v-model="form.manicuristAvatar"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="manicuristName">
|
||||
<el-input v-model="form.manicuristName"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-input v-model="form.gender"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="form.phone"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作名称" prop="specialties">
|
||||
<el-input v-model="form.specialties"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联商家ID" prop="businessId">
|
||||
<el-input v-model="form.businessId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作时长" prop="employment_date">
|
||||
<el-input v-model="form.employment_date"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="评分" prop="rating">
|
||||
<el-input v-model="form.rating"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="余额" prop="salary">
|
||||
<el-input v-model="form.salary"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
dialogTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const form = ref({
|
||||
id:null,
|
||||
email: "",
|
||||
gender: null,
|
||||
phone: "",
|
||||
businessId: "",
|
||||
manicuristName: "",
|
||||
employment_date: "",
|
||||
specialties: "",
|
||||
rating: null,
|
||||
salary: null,
|
||||
manicuristAvatar: ""
|
||||
})
|
||||
|
||||
const formRef = ref(null);
|
||||
const initFormData = async (id) => {
|
||||
const res = await axios.get("manicurist/queryById", {manicuristId: id})
|
||||
form.value = res.data.data;
|
||||
// console.log(res.data.data)
|
||||
}
|
||||
watch(
|
||||
() => props.id,
|
||||
() => {
|
||||
// console.log("id=" + props.id);
|
||||
let id = props.id;
|
||||
initFormData(id)
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits = defineEmits(['update:modelValue', 'initEmployeeList'])
|
||||
const handleClose = () => {
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
|
||||
emits('update:modelValue', false)
|
||||
}
|
||||
const handleConfirm = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
let result = await axios.post("manicurist/update", form.value)
|
||||
console.log(result.data.data)
|
||||
let data = result.data;
|
||||
if (data.code == 0) {
|
||||
ElMessage.success("执行成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initEmployeeList");
|
||||
handleClose();
|
||||
} else {
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
} else {
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
208
src/views/home/index.vue
Normal file
|
@ -0,0 +1,208 @@
|
|||
<template>
|
||||
<div class="home">
|
||||
甲情甲意流水,展示
|
||||
数据展示
|
||||
</div>
|
||||
<div style="display: flex" v-for="(item,index) in tableData" :key="index">
|
||||
<div style="flex: 1">
|
||||
|
||||
<div id="t" style="height: 300px;width: 400px;border: 1px solid #ebebeb;border-radius: 2px;">
|
||||
<el-form
|
||||
:model="item"
|
||||
label-width="100px"
|
||||
style="height: auto"
|
||||
>
|
||||
<el-form-item label="门店头像" prop="businessAvatar">
|
||||
<img :src="item.businessAvatar" width="50" height="50"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店名" prop="businessName">
|
||||
{{item.businessName}}
|
||||
</el-form-item>
|
||||
<el-form-item label="店主名" prop="shopkeeper">
|
||||
{{item.shopkeeper}}
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺详细地址" prop="address">
|
||||
{{item.address}}
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="银行卡号" prop="bankCard">
|
||||
{{item.bankCard}}
|
||||
</el-form-item>
|
||||
<el-form-item label="营业时间段" prop="startBusiness">
|
||||
{{item.startBusiness}}~~{{item.endBusiness}}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex: 1" >
|
||||
<div id="main" style="height: 300px;width: 400px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
<div style="flex: 1" >
|
||||
<div id="main1" style="height: 300px;width: 400px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <el-pagination-->
|
||||
<!-- v-model:currentPage="formPage.current"-->
|
||||
<!-- v-model:page-size="formPage.pageSize"-->
|
||||
<!-- :page-sizes="[10, 20, 30, 40,50]"-->
|
||||
<!-- layout="total, sizes, prev, pager, next, jumper"-->
|
||||
<!-- :total="total"-->
|
||||
<!-- @size-change="handleSizeChange"-->
|
||||
<!-- @current-change="handleCurrentChange"-->
|
||||
<!-- />-->
|
||||
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
import axios from "@/util/axios";
|
||||
import * as echarts from "echarts";
|
||||
import {onMounted, ref} from 'vue'
|
||||
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
const formPage=ref({
|
||||
current:1,
|
||||
pageSize:1
|
||||
})
|
||||
|
||||
const initBusinessList=async()=>{
|
||||
console.log(formPage.value)
|
||||
const res=await axios.post("business/list/page",formPage.value);
|
||||
console.log(res.data.data.records)
|
||||
tableData.value=res.data.data.records;
|
||||
total.value=res.data.data.records.length;
|
||||
setTimeout(() => {hei();shi();}, 500)
|
||||
|
||||
}
|
||||
|
||||
initBusinessList();
|
||||
|
||||
const handleSizeChange = (pageSize) => {
|
||||
formPage.value.current=1;
|
||||
formPage.value.pageSize=pageSize;
|
||||
initBusinessList();
|
||||
}
|
||||
const handleCurrentChange = (pageNum) => {
|
||||
formPage.value.current=pageNum;
|
||||
initBusinessList();
|
||||
}
|
||||
|
||||
//
|
||||
// onMounted(async () => {
|
||||
// setTimeout(() => {hei();shi();}, 500)
|
||||
// })
|
||||
|
||||
// onMounted(async () => {
|
||||
// setTimeout(() => {hei();shi();}, 500)
|
||||
// })
|
||||
|
||||
const hei=()=>{
|
||||
|
||||
var chartDom = document.getElementById('main1');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option;
|
||||
|
||||
option = {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 1048, name: 'Search Engine' },
|
||||
{ value: 735, name: 'Direct' },
|
||||
{ value: 580, name: 'Email' },
|
||||
{ value: 484, name: 'Union Ads' },
|
||||
{ value: 300, name: 'Video Ads' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
|
||||
}
|
||||
const shi=()=>{
|
||||
var chartDom = document.getElementById('main');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option;
|
||||
|
||||
option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Direct',
|
||||
type: 'bar',
|
||||
barWidth: '60%',
|
||||
data: [10, 52, 200, 334, 390, 330, 220]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.home {
|
||||
padding: 40px;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
18
src/views/layout/footer/index.vue
Normal file
|
@ -0,0 +1,18 @@
|
|||
<template>
|
||||
<div class="footer">
|
||||
Copyright © 2024-* 甲情甲意 版权所有一切归你所有
|
||||
<!-- <a href="http://www.java1234.vip" target="_blank">www.java1234.vip</a>-->
|
||||
<!-- https://www.baidu.com/-->
|
||||
<a href="https://www.baidu.com" target="_blank">www.baidu.com</a>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.footer{
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
37
src/views/layout/header/avatar.vue
Normal file
56
src/views/layout/header/breadcrumb.vue
Normal file
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item v-for="(item,index) in breadcrumbList" :key="index">
|
||||
<span class="redirect" v-if="item.name=='详情'||item.name=='商品管理'" @click="handleRedirectBack(item.name)">返回上一级</span>
|
||||
<span class="no-redirect" v-else-if="index==breadcrumbList.length-1" >{{ item.name }}</span>
|
||||
<span class="redirect" v-else @click="handleRedirect(item.path)">{{ item.name }}</span>
|
||||
<!-- <span class="redirect" v-else @click="handleRedirectBack">返回上一级</span>-->
|
||||
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref, watch} from 'vue'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
// console.log(route.matched)
|
||||
const breadcrumbList = ref([]);
|
||||
|
||||
const handleRedirectBack=(name)=>{
|
||||
if (name=='详情')
|
||||
{
|
||||
router.push('/employee')
|
||||
}else{
|
||||
router.push('/business')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
const handleRedirect = (path) => {
|
||||
router.push('/home')
|
||||
}
|
||||
|
||||
const initBreadcrumbList = () => {
|
||||
breadcrumbList.value = route.matched;
|
||||
}
|
||||
watch(route, () => {
|
||||
initBreadcrumbList();
|
||||
}, {deep: true, immediate: true})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.no-redirect {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.redirect {
|
||||
color: #666;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #304156
|
||||
}
|
||||
}
|
||||
</style>
|
102
src/views/layout/index.vue
Normal file
|
@ -0,0 +1,102 @@
|
|||
<!--<template>-->
|
||||
<!-- <div class="app-wrapper">-->
|
||||
<!-- <el-container>-->
|
||||
<!-- <el-aside width="200px" class="sidebar-container"><Menu/></el-aside>-->
|
||||
<!-- <el-container>-->
|
||||
<!-- <el-header>Header</el-header>-->
|
||||
<!-- <el-main>Main</el-main>-->
|
||||
<!-- </el-container>-->
|
||||
<!-- </el-container>-->
|
||||
<!-- </div>-->
|
||||
<!--</template>-->
|
||||
<!--<script setup>-->
|
||||
<!--import Menu from "@/views/layout/menu/index.vue";-->
|
||||
<!--import Breadcrumb from "@/views/layout/header/breadcrumb.vue";-->
|
||||
<!--</script>-->
|
||||
|
||||
<!--<style scoped lang="scss">-->
|
||||
<!--.app-wrapper {-->
|
||||
<!-- position: relative;-->
|
||||
<!-- width: 100%;-->
|
||||
<!-- height: 100%;-->
|
||||
<!--}-->
|
||||
<!--.sidebar-container {-->
|
||||
<!-- background-color: #2d3a4b;-->
|
||||
<!-- height: 100%;-->
|
||||
<!--}-->
|
||||
<!--::v-deep .el-container{-->
|
||||
<!-- height: 100%;-->
|
||||
<!--}-->
|
||||
<!--</style>-->
|
||||
|
||||
|
||||
<template>
|
||||
<div class="app-wrapper">
|
||||
<el-container>
|
||||
<el-aside width="200px" class="sidebar-container"><Menu/></el-aside>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<div class="navbar">
|
||||
<Breadcrumb/>
|
||||
<div class="navbar-right">
|
||||
<Avatar/>
|
||||
</div>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<router-view/>
|
||||
</el-main>
|
||||
<el-footer><Footer/></el-footer>
|
||||
</el-container>
|
||||
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import Menu from '@/views/layout/menu'
|
||||
import Breadcrumb from '@/views/layout/header/breadcrumb'
|
||||
import Avatar from '@/views/layout/header/avatar'
|
||||
import Footer from "@/views/layout/footer/index"
|
||||
import modifyPassword from '@/views/modifyPassword/index'
|
||||
import order from '@/views/order/index'
|
||||
import smallType from '@/views/smallType/index.vue'
|
||||
import bigType from '@/views/bigType/index.vue'
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.app-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
.navbar-right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
:deep(.el-header){
|
||||
padding: 0px;
|
||||
}
|
||||
.sidebar-container {
|
||||
background-color: #2d3a4b;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
:deep(.el-container){
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
86
src/views/layout/menu/index.vue
Normal file
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<el-menu
|
||||
active-text-color="#ffd04b"
|
||||
background-color="#2d3a4b"
|
||||
class="el-menu-vertical-demo"
|
||||
default-active="home"
|
||||
text-color="#fff"
|
||||
router
|
||||
>
|
||||
<el-menu-item index="welcome">
|
||||
<el-icon><home-filled /></el-icon>
|
||||
<span>Welcome</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="home">
|
||||
<el-icon><home-filled /></el-icon>
|
||||
<span>首页</span>
|
||||
</el-menu-item>
|
||||
<!-- <el-menu-item index="display">-->
|
||||
<!-- <el-icon><tickets /></el-icon>-->
|
||||
<!-- <span>数据展示</span>-->
|
||||
<!-- </el-menu-item>-->
|
||||
<el-menu-item index="user">
|
||||
<el-icon><user /></el-icon>
|
||||
<span>用户管理</span>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="3">
|
||||
<template #title >
|
||||
<el-icon><management /></el-icon>
|
||||
<span>商家管理</span>
|
||||
</template>
|
||||
<el-menu-item index="business">
|
||||
<el-icon><management /></el-icon>
|
||||
<span>商家</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="product">
|
||||
<el-icon><management /></el-icon>
|
||||
<span>商品管理</span>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-menu-item index="employee">
|
||||
<el-icon><tickets /></el-icon>
|
||||
<span>美甲师管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="order">
|
||||
<el-icon><tickets /></el-icon>
|
||||
<span>订单管理</span>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="11">
|
||||
<template #title >
|
||||
<el-icon><management /></el-icon>
|
||||
<span>系统管理</span>
|
||||
</template>
|
||||
<el-menu-item index="personal">
|
||||
<el-icon><House /></el-icon>
|
||||
<span>个人中心</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="modifyPassword">
|
||||
<el-icon><edit /></el-icon>
|
||||
<span>修改密码</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item >
|
||||
<el-icon @click="logout"><switch-button /></el-icon>
|
||||
<span @click="logout">安全退出</span>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
</template>
|
||||
<script setup>
|
||||
import
|
||||
{HomeFilled,User,Tickets,Goods,DocumentAdd,Management,Setting,Edit,SwitchButton,House}
|
||||
from '@element-plus/icons-vue'
|
||||
import { useStore } from 'vuex'
|
||||
import axios from "@/util/axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
const store=useStore();
|
||||
const logout=async ()=>{
|
||||
store.dispatch('logout')
|
||||
let res= await axios.post("/user/logout")
|
||||
ElMessage.warning("退出成功");
|
||||
//console.log(res)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
276
src/views/login/index.vue
Normal file
|
@ -0,0 +1,276 @@
|
|||
<template>
|
||||
<div class="login-container">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
class="login-form">
|
||||
<div class="title-container">
|
||||
<h3 class="title">甲情甲意管理平台</h3>
|
||||
</div>
|
||||
<el-form-item prop="userAccount">
|
||||
<!-- <el-icon :size="20" class="svg-container">-->
|
||||
<!-- <User/>-->
|
||||
<!-- </el-icon>-->
|
||||
<svg-icon icon="user" class="svg-container"></svg-icon>
|
||||
<el-input v-model="form.userAccount" placeholder="请输入用户名..."></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="userPassword">
|
||||
<!-- <el-icon :size="20" class="svg-container">-->
|
||||
<!-- <lock/>-->
|
||||
<!-- </el-icon>-->
|
||||
<svg-icon icon="password" class="svg-container"></svg-icon>
|
||||
<el-input v-model="form.userPassword" placeholder="请输入密码..."
|
||||
type="password" />
|
||||
</el-form-item>
|
||||
<el-button type="primary" class="login-button" @click="handleLogin">登录</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import {Lock, User} from '@element-plus/icons-vue'
|
||||
import axios, {request} from "axios";
|
||||
import axiosUtil from '@/util/axios'
|
||||
import {ElMessage} from "element-plus";
|
||||
import router from "@/router";
|
||||
|
||||
const form = ref({
|
||||
userAccount: 'root',
|
||||
userPassword: '12345678'
|
||||
});
|
||||
|
||||
const rules = ref({
|
||||
userAccount: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
userPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入密码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
const formRef = ref(null);
|
||||
|
||||
const handleLogin = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
let result = await axiosUtil.post("user/login", form.value);
|
||||
let data = result.data;
|
||||
console.log(result)
|
||||
// const value = response.data;
|
||||
// // 在Vue中使用获取到的值
|
||||
// this.sessionValue = value;
|
||||
// console.log("宿舍楼靠近对方"+data.value)
|
||||
// console.log("爱上了对方骄傲"+JSON.stringify(data))
|
||||
if (data.code == 0) {
|
||||
// console.log(form.value)
|
||||
ElMessage.success("登录成功");
|
||||
window.sessionStorage.setItem("token",JSON.stringify(form.value));
|
||||
window.sessionStorage.setItem("USER_LOGIN_STATE", JSON.stringify(data.data));
|
||||
router.push('/home');
|
||||
} else {
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("error:" + err);
|
||||
ElMessage.error("系统运行出错,请联系管理员");
|
||||
}
|
||||
}else {
|
||||
console.log("验证失败");
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
$bg: #2d3a4b;
|
||||
$dark_gray: #889aa4;
|
||||
$light_gray: #eee;
|
||||
$cursor: #fff;
|
||||
.login-container {
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
background-color: #ece0e3;
|
||||
overflow: hidden;
|
||||
|
||||
.login-form {
|
||||
box-shadow: 10px 10px 5px #888888;
|
||||
position: relative;
|
||||
background-color: #f8f3f4;
|
||||
width: 520px;
|
||||
border-radius: 20px;
|
||||
// border: 1px solid red;
|
||||
max-width: 100%;
|
||||
padding: 40px 35px 40px;
|
||||
margin: 140px auto;
|
||||
overflow: hidden;
|
||||
|
||||
::v-deep .el-form-item {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 5px;
|
||||
color: #454545;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item__content {
|
||||
color: #454545;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
::v-deep .el-input__wrapper {
|
||||
display: block;
|
||||
color: #9a9a9a;
|
||||
background: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
::v-deep .el-input {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
height: 47px;
|
||||
width: 85%;
|
||||
|
||||
input {
|
||||
background-color: #ffffff;
|
||||
border: 0px;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0px;
|
||||
padding: 12px 5px 12px 15px;
|
||||
color: #c8c4c5;
|
||||
height: 47px;
|
||||
caret-color: $cursor;
|
||||
}
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border-radius: 10px;
|
||||
border: 0px;
|
||||
background-color: #de868f;
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 16px;
|
||||
line-height: 28px;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
&:first-of-type {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svg-container {
|
||||
padding: 6px 5px 6px 15px;
|
||||
color: $dark_gray;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
|
||||
}
|
||||
|
||||
.title-container {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 26px;
|
||||
color: black;
|
||||
margin: 0px auto 40px auto;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
::v-deep .lang-select {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
font-size: 22px;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.show-pwd {
|
||||
// position: absolute;
|
||||
// right: 10px;
|
||||
// top: 7px;
|
||||
font-size: 16px;
|
||||
color: $dark_gray;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--<template>-->
|
||||
|
||||
<!--</template>-->
|
||||
<!--<style>-->
|
||||
|
||||
<!--</style>-->
|
||||
<!--<script>-->
|
||||
<!--const t=[]-->
|
||||
<!--axios.post(url, {-->
|
||||
<!-- 参数名1: 参数值1,-->
|
||||
<!-- 参数名2: 参数值2-->
|
||||
<!--}).then(res => {-->
|
||||
<!-- // res.data就是我们的结果-->
|
||||
<!-- // 注意可以进行链式调用-->
|
||||
<!-- // 继续在括号后面.then或者.catch-->
|
||||
<!--})-->
|
||||
<!--</script>-->
|
||||
|
||||
|
||||
<!--<template>-->
|
||||
<!-- <table cellspacing="0px" cellpadding="10px">-->
|
||||
<!-- <tr>-->
|
||||
<!-- <td>openID</td>-->
|
||||
<!-- <td>shopID</td>-->
|
||||
<!-- <td>totalAmout</td>-->
|
||||
<!-- <td>orderID</td>-->
|
||||
<!-- <td>note</td>-->
|
||||
<!-- </tr>-->
|
||||
<!-- <tr v-for="book in books" :key="book.orderID">-->
|
||||
<!-- <td>{{ book.openID }}</td>-->
|
||||
<!-- <td>{{ book.shopID }}</td>-->
|
||||
<!-- <td>{{ book.totalAmout }}</td>-->
|
||||
<!-- <td>{{ book.orderID }}</td>-->
|
||||
<!-- <td>{{ book.note }}</td>-->
|
||||
<!-- </tr>-->
|
||||
<!-- </table>-->
|
||||
<!-- <a href="http://localhost:5657/alipay/pay?subject=我是⭐&traceNo=124&totalAmount=8888&alipayTraceNo=1000">xixi</a>-->
|
||||
<!--</template>-->
|
||||
|
||||
<!--<script setup>-->
|
||||
<!--import axios from 'axios'-->
|
||||
<!--import {ref} from "vue";-->
|
||||
<!--let books =ref([]);-->
|
||||
|
||||
<!--// axios.get(-->
|
||||
<!--// 'http://localhost:5657/alipay/pay?subject=我是⭐&traceNo=124&totalAmount=8888&alipayTraceNo=1000')-->
|
||||
<!--//-->
|
||||
<!--// .then(response => {-->
|
||||
<!--//-->
|
||||
<!--//-->
|
||||
<!--// console.log(response.data)-->
|
||||
<!--//-->
|
||||
<!--// })-->
|
||||
<!--//-->
|
||||
<!--// .catch(error => {-->
|
||||
<!--//-->
|
||||
<!--// console.log(error)-->
|
||||
<!--//-->
|
||||
<!--// })-->
|
||||
<!--</script>-->
|
111
src/views/modifyPassword/index.vue
Normal file
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="150px"
|
||||
>
|
||||
<el-form-item label="用户名:" prop="username">
|
||||
<el-input v-model="username" disabled/>
|
||||
</el-form-item>
|
||||
<el-form-item label="原密码:" prop="userPassword">
|
||||
<el-input v-model="form.userPassword" type="password" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码:" prop="newPassword">
|
||||
<el-input v-model="form.newPassword" type="password" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码:" prop="checkNewPassword">
|
||||
<el-input v-model="form.checkNewPassword" type="password" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">确认修改
|
||||
</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import axios from "@/util/axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
|
||||
import { useStore } from 'vuex'
|
||||
const store=useStore();
|
||||
const username=ref()
|
||||
const password=ref()
|
||||
|
||||
const form = ref({
|
||||
userPassword: "",
|
||||
newPassword: "",
|
||||
checkNewPassword: ""
|
||||
})
|
||||
const rules = ref({
|
||||
newPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入新密码'
|
||||
}
|
||||
],
|
||||
newPassword2: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入确认新密码'
|
||||
}
|
||||
],
|
||||
})
|
||||
const formRef = ref(null);
|
||||
const initFormData = () => {
|
||||
let userInfoJson = window.sessionStorage.getItem("USER_LOGIN_STATE");
|
||||
//console.log(JSON.parse(userInfoJson).username)
|
||||
username.value = JSON.parse(userInfoJson).username;
|
||||
let pwd = window.sessionStorage.getItem("token");
|
||||
password.value=JSON.parse(pwd).userPassword;
|
||||
//console.log(JSON.parse(pwd).userPassword)
|
||||
// form.value.userPassword = JSON.parse(pwd).userPassword;
|
||||
// console.log(form.value.userPassword)
|
||||
}
|
||||
initFormData();
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
//console.log("success")
|
||||
if (form.value.userPassword !== password.value) {
|
||||
ElMessage.error("原密码错误!");
|
||||
} else if (form.value.newPassword !== form.value.checkNewPassword) {
|
||||
|
||||
ElMessage.error("确认新密码错误!");
|
||||
} else {
|
||||
try {
|
||||
let result = await axios.post("user/password/update", form.value)
|
||||
let data = result.data;
|
||||
console.log(result.request)
|
||||
if (data.code == 0) {
|
||||
ElMessage.success("密码修改成功,重新登录后生效!");
|
||||
formRef.value.resetFields();
|
||||
} else {
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
ElMessage.error("系统运行出错,请联系管理员!");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
store.dispatch('logout')
|
||||
let res= await axios.post("/user/logout")
|
||||
console.log(res)
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-input {
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
55
src/views/order/dialog/index.vue
Normal file
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="dialogVisible"
|
||||
title="订单详情"
|
||||
width="40%"
|
||||
@close="handleClose">
|
||||
<el-table
|
||||
:data="tableData"stripe style="width:100%">
|
||||
<el-table-column prop="goodspic" label="商品图片" width="200">
|
||||
<template v-slot="scope">
|
||||
<img width="80" height="80" :src="getServerUrl()+'/image/product/'+scope.row.goodspic"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="goodsname" label="商品名称" ></el-table-column>
|
||||
<el-table-column prop="goodsprice" label="商品价格" width="100"></el-table-column>
|
||||
<el-table-column prop="goodsnumber" label="商品数量" width="100"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios,{getServerUrl} from "@/util/axios";
|
||||
|
||||
const props=defineProps({
|
||||
id:{
|
||||
type:Number,
|
||||
default:-1,
|
||||
required:true
|
||||
}
|
||||
})
|
||||
watch(
|
||||
()=>props.id,
|
||||
()=>{
|
||||
let id=props.id;
|
||||
if (id != -1){
|
||||
initOrderDetailData(id)
|
||||
}
|
||||
}
|
||||
)
|
||||
const tableData=ref(null);
|
||||
const initOrderDetailData=async (id)=>{
|
||||
const res=await axios.get("admin/orderDetial/list/"+id);
|
||||
tableData.value=res.data.list;
|
||||
console.log(res.data.list)
|
||||
}
|
||||
const emits=defineEmits(['update:modelValue'])
|
||||
const handleClose=()=>{
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
177
src/views/order/index.vue
Normal file
|
@ -0,0 +1,177 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header">
|
||||
<el-col :span="7">
|
||||
<el-input placeholder="请输入订单号..." clearable v-model="queryForm.orderNumber"></el-input>
|
||||
</el-col>
|
||||
<el-button type="button" :icon="Search" @click="initOrderList">搜索</el-button>
|
||||
</el-row>
|
||||
<el-table :data="tableData" stripe style="width: 100%" showOverflowTooltip>
|
||||
<el-table-column prop="orderNumber" label="订单号" width="220" fixed/>
|
||||
<el-table-column prop="userName" label="用户昵称" width="200"/>
|
||||
<el-table-column prop="totalPrice" label="订单总价" width="100"/>
|
||||
<el-table-column prop="paymentStatus" label="订单状态" width="100"/>
|
||||
<el-table-column prop="createTime" label="订单创建日期" width="200"/>
|
||||
<el-table-column prop="updateTime" label="订单支付日期" width="200"/>
|
||||
<el-table-column prop="userName" label="收货人" width="80"/>
|
||||
<el-table-column prop="phone" label="联系电话" width="150"/>
|
||||
<el-table-column prop="notes" label="描述" width="400"/>
|
||||
<!-- <el-table-column label="操作" width="300" fixed="right">-->
|
||||
<!-- <template v-slot="scope">-->
|
||||
<!-- <el-button type="success" @click="handleDialogValue(scope.row.id)">详情</el-button>-->
|
||||
<!-- <el-button type="primary" @click="handleOrderStatus(scope.row.id,2)">发货</el-button>-->
|
||||
<!-- <el-button type="primary" @click="handleOrderStatus(scope.row.id,3)">退货</el-button>-->
|
||||
<!-- <el-button type="danger" :icon="Delete" @click="handleDelete(scope.row.id)"></el-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="queryForm.current"
|
||||
v-model:page-size="queryForm.pageSize"
|
||||
:page-sizes="[10, 20, 30, 40,50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<Dialog v-model:="dialogVisible" :id="id"></Dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search,Delete} from '@element-plus/icons-vue'
|
||||
import { ref} from 'vue'
|
||||
import axios from "@/util/axios";
|
||||
import Dialog from "@/views/order/dialog/index.vue";
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
|
||||
const handleDelete=(id)=>{
|
||||
ElMessageBox.confirm(
|
||||
'您确认要删除这个订单记录吗吗?',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
let res=await axios.get("admin/delete/"+id)
|
||||
if (res.data.code==0){
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
initOrderList();
|
||||
}else{
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: res.data.msg,
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
const handleOrderStatus=(id,status)=>{
|
||||
ElMessageBox.confirm(
|
||||
'您确认要更新这个订单状态吗?',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
let res=await axios.post("admin/updateStatus",{id:id,status:status})
|
||||
if (res.data.code==0){
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '执行成功',
|
||||
})
|
||||
initOrderList();
|
||||
}else{
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: res.data.msg,
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const dialogVisible=ref(false)
|
||||
|
||||
|
||||
const handleDialogValue=(orderId)=>{
|
||||
id.value=orderId;
|
||||
dialogVisible.value=true;
|
||||
}
|
||||
|
||||
const id=ref(-1);
|
||||
|
||||
|
||||
const queryForm=ref({
|
||||
orderNumber:'',
|
||||
current:1,
|
||||
pageSize:10
|
||||
})
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
const initOrderList=async()=>{
|
||||
const res=await axios.post("orders/list/page",queryForm.value);
|
||||
//console.log(res.data.data)
|
||||
// const temp=[];
|
||||
// temp.push(res.data.data)
|
||||
// console.log(res.data.data)
|
||||
if(res.data.data){
|
||||
tableData.value=res.data.data.records;
|
||||
total.value=Number(res.data.data.total);
|
||||
}
|
||||
else{
|
||||
ElMessage.error(res.data.description);
|
||||
}
|
||||
}
|
||||
initOrderList();
|
||||
const handleSizeChange = (pageSize) => {
|
||||
queryForm.value.current=1;
|
||||
queryForm.value.pageSize=pageSize;
|
||||
initOrderList();
|
||||
}
|
||||
const handleCurrentChange = (current) => {
|
||||
queryForm.value.current=current;
|
||||
initOrderList();
|
||||
}
|
||||
|
||||
const statusFormatter=(row)=>{
|
||||
switch (row.status){
|
||||
case 1:
|
||||
return "待支付";
|
||||
case 2:
|
||||
return "待发货";
|
||||
case 3:
|
||||
return "退款/退货";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
76
src/views/personalCenter/index.vue
Normal file
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="用户头像" prop="avatarUrl">
|
||||
<img :src="form.avatarUrl" alt="空" width="50" height="50"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="username">
|
||||
{{form.username}}
|
||||
</el-form-item>
|
||||
<el-form-item label="用户账号" prop="userAccount">
|
||||
{{form.userAccount}}
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<template v-if="form.gender==0">女</template>
|
||||
<template v-else>男</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
{{form.phone}}
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
{{form.email}}
|
||||
</el-form-item>
|
||||
<el-form-item label="用户状态" prop="userStatus">
|
||||
<template v-if="form.userStatus==0">禁用</template>
|
||||
<template v-else>启用</template>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="用户角色" prop="userRole">
|
||||
<template v-if="form.userRole===0">普通用户</template>
|
||||
<template v-else-if="form.userRole===1">管理员</template>
|
||||
<template v-else-if="form.userRole===2">商家</template>
|
||||
<template v-else>美甲师</template>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
|
||||
const form=ref({
|
||||
avatarUrl: "",
|
||||
createTime:"",
|
||||
email:"",
|
||||
gender:null,
|
||||
isDelete:null,
|
||||
openId:null,
|
||||
phone:null,
|
||||
unionId:null,
|
||||
updateTime:"",
|
||||
userAccount:"",
|
||||
userPassword:"",
|
||||
userRole:null,
|
||||
userStatus:null,
|
||||
username:""
|
||||
})
|
||||
const initFormData=()=>{
|
||||
// console.log(ids)
|
||||
let token=window.sessionStorage.getItem('USER_LOGIN_STATE');
|
||||
|
||||
// const temp=[]
|
||||
// temp.push(token)
|
||||
console.log(token)
|
||||
form.value=JSON.parse(token);
|
||||
|
||||
}
|
||||
initFormData();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
163
src/views/product/index.vue
Normal file
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header" style="display: flex;align-items: center;
|
||||
justify-content: center;" v-if="params.product!==undefined">
|
||||
商家名称:{{JSON.parse(params.product).businessName}}
|
||||
商家头像:<img :src="JSON.parse(params.product).businessAvatar" width="50" height="50"/>
|
||||
商家电话:{{JSON.parse(params.product).businessPhone}}
|
||||
|
||||
</el-row>
|
||||
<el-row :gutter="20" class="header" >
|
||||
<el-col :span="7" >
|
||||
<el-input placeholder="请输入商品ID..." clearable v-model="queryForm.id"></el-input>
|
||||
</el-col>
|
||||
<el-button type="primary" :icon="Search" @click="initProductList" >搜索</el-button>
|
||||
<!-- <el-button type="primary" :icon="DocumentAdd"-->
|
||||
<!-- @click="handleDialogValue()">添加商品</el-button>-->
|
||||
</el-row>
|
||||
|
||||
<el-table :data="tableData" stripe style="width: 100%;">
|
||||
<el-table-column prop="id" label="#ID" />
|
||||
<el-table-column prop="commoditiesName" label="商品名称" />
|
||||
<el-table-column prop="commoditiesImagecommoditiesImage" label="商品图片" >
|
||||
<template v-slot="scope">
|
||||
<img :src="scope.row.commoditiesImagecommoditiesImage"
|
||||
width="50" height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="commoditiesPrice" label="商品名称" />
|
||||
<el-table-column prop="inventoryStatus" label="商品库存" />
|
||||
<el-table-column prop="status" label="商品状态" />
|
||||
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="queryForm.current"
|
||||
v-model:page-size="queryForm.pageSize"
|
||||
:page-sizes="[10, 20, 30, 40,50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- <Dialog v-model="dialogVisible" :dialogVisible="dialogVisible"-->
|
||||
<!-- :dialogTitle="dialogTitle" :id="id" @initProductList="initProductList"></Dialog>-->
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search,Delete,Edit,DocumentAdd} from '@element-plus/icons-vue'
|
||||
import {ref, watch} from 'vue'
|
||||
import axios,{getServerUrl} from "@/util/axios";
|
||||
import { ElMessageBox,ElMessage } from 'element-plus'
|
||||
import {useRoute} from "vue-router";
|
||||
// import Dialog from './components/dialog'
|
||||
|
||||
let params=useRoute().query
|
||||
const query=ref()
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
const id=ref(-1)
|
||||
const dialogTitle=ref('');
|
||||
const dialogVisible=ref(false)
|
||||
|
||||
|
||||
const queryForm=ref({
|
||||
businessId: '',
|
||||
id:'',
|
||||
current:1,
|
||||
pageSize:10
|
||||
})
|
||||
// const handleDialogValue=(productId)=>{
|
||||
// if(productId){
|
||||
// id.value=productId;
|
||||
// dialogTitle.value="商品修改"
|
||||
// }else{
|
||||
// id.value=-1;
|
||||
// dialogTitle.value="商品添加"
|
||||
// }
|
||||
// dialogVisible.value=true
|
||||
// }
|
||||
const initProductList=async()=>{
|
||||
//console.log(JSON.parse(params.product).id)
|
||||
if(params.product!=undefined){
|
||||
|
||||
queryForm.value.businessId=JSON.parse(params.product).id
|
||||
}
|
||||
const res=await axios.post("commodities/list/page/commodities",queryForm.value);
|
||||
// console.log(res.data.data)
|
||||
tableData.value=res.data.data.records;
|
||||
total.value=Number(res.data.data.total);
|
||||
|
||||
}
|
||||
initProductList();
|
||||
watch(query,()=>{
|
||||
// console.log(id.value)
|
||||
initProductList();
|
||||
},10000)
|
||||
|
||||
const handleSizeChange = (pageSize) => {
|
||||
queryForm.value.current=1;
|
||||
queryForm.value.pageSize=pageSize;
|
||||
initProductList();
|
||||
}
|
||||
const handleCurrentChange = (current) => {
|
||||
queryForm.value.current=current;
|
||||
initProductList();
|
||||
}
|
||||
// const typeNameFormatter=(row)=>{
|
||||
// // console.log(row)
|
||||
// // let name=await axios.get('admin/smallType/'+row.typeid).then((res) => {
|
||||
// // return res.data.smallType.name
|
||||
// // });
|
||||
// // row.smalltype=name;
|
||||
// let name= axios.get('admin/smallType/'+row.typeid).then((res) => {
|
||||
// return res.data.smallType.name
|
||||
// });
|
||||
// let t=name
|
||||
// console.log(t.then())
|
||||
// return t.then()
|
||||
// }
|
||||
// const typeNameFormatter=(row)=>{
|
||||
// // console.log(row)
|
||||
// let name= typeNameFormatter2(row)
|
||||
// console.log(name)
|
||||
// return name
|
||||
// }
|
||||
// const handleDelete=(id)=>{
|
||||
// ElMessageBox.confirm(
|
||||
// '您确定要删除这条记录吗?',
|
||||
// '系统提示',
|
||||
// {
|
||||
// confirmButtonText: '确定',
|
||||
// cancelButtonText: '取消',
|
||||
// type: 'warning',
|
||||
// }
|
||||
// )
|
||||
// .then(async() => {
|
||||
// let res=await axios.get('admin/product/delete/'+id)
|
||||
// if(res.data.code==0){
|
||||
// ElMessage({
|
||||
// type: 'success',
|
||||
// message: '删除成功',
|
||||
// })
|
||||
// initProductList();
|
||||
// }else{
|
||||
// ElMessage({
|
||||
// type: 'error',
|
||||
// message: res.data.msg,
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// .catch(() => {
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
145
src/views/profile/index.vue
Normal file
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
style="display: flex; "
|
||||
>
|
||||
<!-- <el-form-item label="门店头像" prop="businessAvatar">-->
|
||||
<!-- {{form.businessAvatar}}-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
<div style="flex: 1">
|
||||
<el-form-item label="门店名" prop="businessName">
|
||||
<el-input v-model="form.businessName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照" prop="license">
|
||||
<img :src="form.license" width="80" height="80"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="店主名" prop="shopkeeper">
|
||||
<el-input v-model="form.shopkeeper" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店手机号" prop="businessPhone">
|
||||
<el-input v-model="form.businessPhone" />
|
||||
</el-form-item>
|
||||
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<el-form-item label="身份证" prop="frontIdCard" style="display: flex">
|
||||
<div style="flex: 1">
|
||||
<div>
|
||||
<img :src="form.frontIdCard" width="80" height="80"/>
|
||||
</div>
|
||||
<div>
|
||||
正面
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<div>
|
||||
<img :src="form.backIdCard" width="80" height="80"/>
|
||||
</div>
|
||||
<div>
|
||||
反面
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="身份证反面" prop="backIdCard">-->
|
||||
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="店铺地址" prop="address">
|
||||
<el-input v-model="form.address" />
|
||||
</el-form-item>
|
||||
<el-form-item label="银行卡号" prop="bankCard">
|
||||
<el-input v-model="form.bankCard" show-password/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div style="margin-top: 100px">
|
||||
<div style="margin: 10px"> 是否审核通过</div>
|
||||
<div style="display: flex;">
|
||||
<div style="margin-left: 50px;" > <el-button type="danger" > 审核通过</el-button></div>
|
||||
<div style="margin-left: 20px"><el-button type="danger" plain>审核不通过</el-button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <el-form-item label="门店简介" prop="businessProfile">-->
|
||||
<!-- {{form.businessProfile}}-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="商家相册" prop="businessImages">-->
|
||||
<!-- {{form.businessImages}}-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="分类ID" prop="categoryId">-->
|
||||
<!-- {{form.categoryId}}-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
|
||||
<!-- <el-form-item label="开始营业时间" prop="startBusiness">-->
|
||||
<!-- {{form.startBusiness}}-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="结束营业时间" prop="endBusiness">-->
|
||||
<!-- {{form.endBusiness}}-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="创建时间" prop="createTime">-->
|
||||
<!-- {{form.createTime}}-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
<!-- <template #footer>-->
|
||||
<!--<span class="dialog-footer">-->
|
||||
<!--<el-button @click="handleClose">取消</el-button>-->
|
||||
<!--<el-button type="primary" @click="handleConfirm">确认</el-button>-->
|
||||
<!--</span>-->
|
||||
<!-- </template>-->
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import {useRoute} from "vue-router"
|
||||
|
||||
|
||||
let params=useRoute().query
|
||||
const form=ref({
|
||||
id:null,
|
||||
address: "",
|
||||
backIdCard: "",
|
||||
bankCard: "",
|
||||
businessAvatar: "",
|
||||
businessImages: "",
|
||||
businessName: "",
|
||||
businessPhone: "",
|
||||
businessProfile: "",
|
||||
categoryId: null,
|
||||
endBusiness: "",
|
||||
frontIdCard: "",
|
||||
license: "",
|
||||
shopkeeper: "",
|
||||
startBusiness: "",
|
||||
createTime:""
|
||||
})
|
||||
|
||||
const formRef=ref(null);
|
||||
const initFormData=async()=>{
|
||||
|
||||
// console.log(params.id)
|
||||
const res=await axios.post("business/list/page",{id: params.id})
|
||||
console.log(res.data.data)
|
||||
form.value=res.data.data.records[0];
|
||||
//form.value=res.data.data;
|
||||
}
|
||||
initFormData();
|
||||
// watch(
|
||||
//
|
||||
// ()=>{
|
||||
// // console.log("id="+props.bussinessId);
|
||||
//
|
||||
// // console.log(id.value)
|
||||
// initFormData(id)
|
||||
// }
|
||||
// )
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
138
src/views/smallType/dialog/index.vue
Normal file
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="小类名称" prop="name">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属大类">
|
||||
<el-select v-model="form.bigtype.id" placeholder="请选择...">
|
||||
<el-option
|
||||
v-for="item in bigTypeSelectOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="小类描述" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="4"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from 'element-plus'
|
||||
const tableData=ref([])
|
||||
const bigTypeSelectOptions=ref([])
|
||||
const initBigTypeSelectList=async()=>{
|
||||
const res=await axios.get("admin/bigType/listAll");
|
||||
bigTypeSelectOptions.value=res.data.bigTypeList;
|
||||
}
|
||||
initBigTypeSelectList();
|
||||
const props=defineProps(
|
||||
{
|
||||
id:{
|
||||
type:Number,
|
||||
default:-1,
|
||||
required:true
|
||||
},
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
},
|
||||
dialogVisible:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:true
|
||||
}
|
||||
}
|
||||
)
|
||||
const form=ref({
|
||||
id:-1,
|
||||
name:"",
|
||||
remark:"",
|
||||
bigtype:{
|
||||
id:""
|
||||
}
|
||||
})
|
||||
const rules=ref({
|
||||
name:[
|
||||
{ required: true, message: '请输入商品小类名称'}
|
||||
],
|
||||
remark:[
|
||||
{ required: true, message: '请输入商品小类描述'}
|
||||
]
|
||||
})
|
||||
const formRef=ref(null)
|
||||
const initFormData=async(id)=>{
|
||||
const res=await axios.get("admin/smallType/"+id);
|
||||
form.value=res.data.smallType;
|
||||
}
|
||||
watch(
|
||||
()=>props.dialogVisible,
|
||||
()=>{
|
||||
let id=props.id;
|
||||
console.log("id="+id)
|
||||
if(id!=-1){
|
||||
initFormData(id)
|
||||
}else{
|
||||
form.value={
|
||||
id:-1,
|
||||
name:"",
|
||||
remark:"",
|
||||
bigtype:{
|
||||
id:""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
const emits=defineEmits(['update:modelValue','initSmallTypeList'])
|
||||
const handleClose=()=>{
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
const handleConfirm=()=>{
|
||||
formRef.value.validate(async(valid)=>{
|
||||
if(valid){
|
||||
if(form.value.bigtype.id==""){
|
||||
ElMessage.error("请选择商品大类");
|
||||
return;
|
||||
}
|
||||
let result=await axios.post("admin/smallType/save",form.value);
|
||||
let data=result.data;
|
||||
if(data.code==0){
|
||||
ElMessage.success("执行成功!")
|
||||
formRef.value.resetFields();
|
||||
emits("initSmallTypeList")
|
||||
handleClose();
|
||||
}else{
|
||||
ElMessage.error(data.msg);
|
||||
}
|
||||
}else{
|
||||
console.log("fail")
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
128
src/views/smallType/index.vue
Normal file
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header">
|
||||
<el-col :span="7">
|
||||
<el-input placeholder="请输入商品小类名称..." clearable v-model="queryForm.query"></el-input>
|
||||
</el-col>
|
||||
<el-button type="button" :icon="Search" @click="initSmallTypeList">搜索
|
||||
</el-button>
|
||||
</el-row>
|
||||
<el-table :data="tableData" stripe style="width: 100%">
|
||||
<el-table-column prop="id" label="#ID" width="80" />
|
||||
<el-table-column prop="name" label="商品小类名称" width="200" />
|
||||
<el-table-column prop="bigType" label="所属大类" width="200"
|
||||
:formatter="bigTypeNameFormatter"/>
|
||||
<el-table-column prop="remark" label="商品小类描述"/>
|
||||
<el-table-column prop="action" label="操作" width="300" >
|
||||
<template v-slot="scope">
|
||||
<el-button type="primary" :icon="Edit"
|
||||
@click="handleDialogValue(scope.row.id)"></el-button>
|
||||
<el-button type="danger" :icon="Delete"
|
||||
@click="handleDelete(scope.row.id)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="queryForm.pageNum"
|
||||
v-model:page-size="queryForm.pageSize"
|
||||
:page-sizes="[10, 20, 30, 40,50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- <Dialog v-model="dialogVisible" :id="id"></Dialog>-->
|
||||
|
||||
<Dialog v-model="dialogVisible" :dialogVisible="dialogVisible"
|
||||
:dialogTitle="dialogTitle" :id="id" @initSmallTypeList="initSmallTypeList">
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search,Delete,Edit} from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessageBox,ElMessage } from 'element-plus'
|
||||
import Dialog from '@/views/smallType/dialog/index.vue'
|
||||
const queryForm=ref({
|
||||
query:'',
|
||||
pageNum:1,
|
||||
pageSize:10
|
||||
})
|
||||
|
||||
const dialogTitle=ref(null)
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
const id=ref(-1)
|
||||
const dialogVisible=ref(false)
|
||||
// const handleDialogValue=(smallTypeId)=>{
|
||||
// dialogVisible.value=true
|
||||
// id.value=smallTypeId;
|
||||
// }
|
||||
const handleDialogValue=(smallTypeId)=>{
|
||||
if(smallTypeId){
|
||||
id.value=smallTypeId;
|
||||
dialogTitle.value="商品小类修改"
|
||||
}else{
|
||||
id.value=-1;
|
||||
dialogTitle.value="商品小类添加"
|
||||
}
|
||||
dialogVisible.value=true
|
||||
}
|
||||
const initSmallTypeList=async()=>{
|
||||
const res=await axios.post("admin/smallType/list",queryForm.value);
|
||||
tableData.value=res.data.smallTypeList;
|
||||
total.value=res.data.total;
|
||||
}
|
||||
initSmallTypeList();
|
||||
const handleSizeChange = (pageSize) => {
|
||||
queryForm.value.pageNum=1;
|
||||
queryForm.value.pageSize=pageSize;
|
||||
initSmallTypeList();
|
||||
}
|
||||
const handleCurrentChange = (pageNum) => {
|
||||
queryForm.value.pageNum=pageNum;
|
||||
initSmallTypeList();
|
||||
}
|
||||
const bigTypeNameFormatter=(row)=>{
|
||||
return row.bigtype.name
|
||||
}
|
||||
const handleDelete=(id)=>{
|
||||
ElMessageBox.confirm(
|
||||
'您确定要删除这条记录吗?',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async() => {
|
||||
let res=await axios.get('admin/smallType/delete/'+id)
|
||||
if(res.data.code==0){
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
initSmallTypeList();
|
||||
}else{
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: res.data.msg,
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
278
src/views/test/index.vue
Normal file
|
@ -0,0 +1,278 @@
|
|||
<template>
|
||||
<div style="display: flex">
|
||||
<div style="flex: 1">
|
||||
<div id="echarRef" style="height: 300px;width: 400px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<div id="main" style="height: 300px;width: 400px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<div style="flex: 1">
|
||||
<div id="temp" style="height: 600px;width: 800px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<div id="tanbai" style="height: 600px;width: 600px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script setup>
|
||||
import * as echarts from "echarts";
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
onMounted(async () => {
|
||||
setTimeout(() => {hei()}, 1000)
|
||||
setTimeout(() => {shi();}, 1000)
|
||||
setTimeout(() => {temp();tanbai();}, 1000)
|
||||
})
|
||||
|
||||
const hei = () => {
|
||||
let myChart = echarts.init(document.getElementById("echarRef"));
|
||||
myChart.setOption({
|
||||
title: { text: "CPU使用率" },
|
||||
tooltip: {},
|
||||
xAxis: {
|
||||
data: ["12-3", "12-4", "12-5", "12-6", "12-7", "12-8"],
|
||||
},
|
||||
yAxis: {},
|
||||
series: [
|
||||
{
|
||||
name: "用户量",
|
||||
type: "line",
|
||||
data: [5, 20, 36, 10, 10, 20],
|
||||
},
|
||||
],
|
||||
});
|
||||
window.onresize = function () {//自适应大小
|
||||
myChart.resize();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const shi=()=>{
|
||||
var chartDom = document.getElementById('main');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option;
|
||||
|
||||
option = {
|
||||
|
||||
title: { text: "订单柱状图" },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [120, 200, 150, 80, 70, 110, 130],
|
||||
type: 'bar'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
}
|
||||
|
||||
const tanbai=()=>{
|
||||
|
||||
var chartDom = document.getElementById('tanbai');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option;
|
||||
|
||||
option = {
|
||||
legend: {
|
||||
top: 'bottom'
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: { show: true, readOnly: false },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Nightingale Chart',
|
||||
type: 'pie',
|
||||
radius: [50, 250],
|
||||
center: ['50%', '50%'],
|
||||
roseType: 'area',
|
||||
itemStyle: {
|
||||
borderRadius: 8
|
||||
},
|
||||
data: [
|
||||
{ value: 40, name: 'rose 1' },
|
||||
{ value: 38, name: 'rose 2' },
|
||||
{ value: 32, name: 'rose 3' },
|
||||
{ value: 30, name: 'rose 4' },
|
||||
{ value: 28, name: 'rose 5' },
|
||||
{ value: 26, name: 'rose 6' },
|
||||
{ value: 22, name: 'rose 7' },
|
||||
{ value: 18, name: 'rose 8' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
|
||||
}
|
||||
|
||||
const temp=()=>{
|
||||
var app = {};
|
||||
|
||||
var chartDom = document.getElementById('temp');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option;
|
||||
|
||||
let xData = [];
|
||||
let yData = [];
|
||||
let data = [];
|
||||
for (let y = 0; y < 10; y++) {
|
||||
yData.push(y);
|
||||
for (let x = 0; x < 10; x++) {
|
||||
data.push([x, y, 10]);
|
||||
}
|
||||
}
|
||||
for (let x = 0; x < 10; x++) {
|
||||
xData.push(x);
|
||||
}
|
||||
const options = [
|
||||
{
|
||||
grid: {
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0
|
||||
},
|
||||
xAxis: {
|
||||
show: false,
|
||||
type: 'category',
|
||||
data: xData
|
||||
},
|
||||
yAxis: {
|
||||
show: false,
|
||||
type: 'category',
|
||||
data: yData
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'scatter',
|
||||
data: data,
|
||||
symbol: 'roundRect',
|
||||
symbolKeepAspect: true,
|
||||
universalTransition: true,
|
||||
symbolSize: 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
series: [
|
||||
{
|
||||
type: 'scatter',
|
||||
symbol: 'circle'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// heart
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M23.6 2c-3.363 0-6.258 2.736-7.599 5.594-1.342-2.858-4.237-5.594-7.601-5.594-4.637 0-8.4 3.764-8.4 8.401 0 9.433 9.516 11.906 16.001 21.232 6.13-9.268 15.999-12.1 15.999-21.232 0-4.637-3.763-8.401-8.4-8.401z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// happy
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM22 8c1.105 0 2 1.343 2 3s-0.895 3-2 3-2-1.343-2-3 0.895-3 2-3zM10 8c1.105 0 2 1.343 2 3s-0.895 3-2 3-2-1.343-2-3 0.895-3 2-3zM16 28c-5.215 0-9.544-4.371-10-9.947 2.93 1.691 6.377 2.658 10 2.658s7.070-0.963 10-2.654c-0.455 5.576-4.785 9.942-10 9.942z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// evil
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M32 2c0-1.422-0.298-2.775-0.833-4-1.049 2.401-3.014 4.31-5.453 5.287-2.694-2.061-6.061-3.287-9.714-3.287s-7.021 1.226-9.714 3.287c-2.439-0.976-4.404-2.886-5.453-5.287-0.535 1.225-0.833 2.578-0.833 4 0 2.299 0.777 4.417 2.081 6.106-1.324 2.329-2.081 5.023-2.081 7.894 0 8.837 7.163 16 16 16s16-7.163 16-16c0-2.871-0.757-5.565-2.081-7.894 1.304-1.689 2.081-3.806 2.081-6.106zM18.003 11.891c0.064-1.483 1.413-2.467 2.55-3.036 1.086-0.543 2.16-0.814 2.205-0.826 0.536-0.134 1.079 0.192 1.213 0.728s-0.192 1.079-0.728 1.213c-0.551 0.139-1.204 0.379-1.779 0.667 0.333 0.357 0.537 0.836 0.537 1.363 0 1.105-0.895 2-2 2s-2-0.895-2-2c0-0.037 0.001-0.073 0.003-0.109zM8.030 8.758c0.134-0.536 0.677-0.862 1.213-0.728 0.045 0.011 1.119 0.283 2.205 0.826 1.137 0.569 2.486 1.553 2.55 3.036 0.002 0.036 0.003 0.072 0.003 0.109 0 1.105-0.895 2-2 2s-2-0.895-2-2c0-0.527 0.204-1.005 0.537-1.363-0.575-0.288-1.228-0.528-1.779-0.667-0.536-0.134-0.861-0.677-0.728-1.213zM16 26c-3.641 0-6.827-1.946-8.576-4.855l2.573-1.544c1.224 2.036 3.454 3.398 6.003 3.398s4.779-1.362 6.003-3.398l2.573 1.544c-1.749 2.908-4.935 4.855-8.576 4.855z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// hipster
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM22 8c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2zM10 8c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2zM16.994 21.23c-0.039-0.035-0.078-0.072-0.115-0.109-0.586-0.586-0.878-1.353-0.879-2.121-0 0.768-0.293 1.535-0.879 2.121-0.038 0.038-0.076 0.074-0.115 0.109-2.704 2.453-9.006-0.058-9.006-3.23 1.938 1.25 3.452 0.306 4.879-1.121 1.172-1.172 3.071-1.172 4.243 0 0.586 0.586 0.879 1.353 0.879 2.121 0-0.768 0.293-1.535 0.879-2.121 1.172-1.172 3.071-1.172 4.243 0 1.427 1.427 2.941 2.371 4.879 1.121 0 3.173-6.302 5.684-9.006 3.23z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// shocked
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM10 14c-1.105 0-2-1.343-2-3s0.895-3 2-3 2 1.343 2 3-0.895 3-2 3zM16 26c-2.209 0-4-1.791-4-4s1.791-4 4-4c2.209 0 4 1.791 4 4s-1.791 4-4 4zM22 14c-1.105 0-2-1.343-2-3s0.895-3 2-3 2 1.343 2 3-0.895 3-2 3z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// pie chart
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M14 18v-14c-7.732 0-14 6.268-14 14s6.268 14 14 14 14-6.268 14-14c0-2.251-0.532-4.378-1.476-6.262l-12.524 6.262zM28.524 7.738c-2.299-4.588-7.043-7.738-12.524-7.738v14l12.524-6.262z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// users
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M10.225 24.854c1.728-1.13 3.877-1.989 6.243-2.513-0.47-0.556-0.897-1.176-1.265-1.844-0.95-1.726-1.453-3.627-1.453-5.497 0-2.689 0-5.228 0.956-7.305 0.928-2.016 2.598-3.265 4.976-3.734-0.529-2.39-1.936-3.961-5.682-3.961-6 0-6 4.029-6 9 0 3.096 1.797 6.191 4 7.432v1.649c-6.784 0.555-12 3.888-12 7.918h8.719c0.454-0.403 0.956-0.787 1.506-1.146zM24 24.082v-1.649c2.203-1.241 4-4.337 4-7.432 0-4.971 0-9-6-9s-6 4.029-6 9c0 3.096 1.797 6.191 4 7.432v1.649c-6.784 0.555-12 3.888-12 7.918h28c0-4.030-5.216-7.364-12-7.918z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// mug
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M30 10h-6v-3c0-2.761-5.373-5-12-5s-12 2.239-12 5v20c0 2.761 5.373 5 12 5s12-2.239 12-5v-3h6c1.105 0 2-0.895 2-2v-10c0-1.105-0.895-2-2-2zM5.502 8.075c-1.156-0.381-1.857-0.789-2.232-1.075 0.375-0.286 1.075-0.694 2.232-1.075 1.811-0.597 4.118-0.925 6.498-0.925s4.688 0.329 6.498 0.925c1.156 0.381 1.857 0.789 2.232 1.075-0.375 0.286-1.076 0.694-2.232 1.075-1.811 0.597-4.118 0.925-6.498 0.925s-4.688-0.329-6.498-0.925zM28 20h-4v-6h4v6z'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// plane
|
||||
series: [
|
||||
{
|
||||
symbol:
|
||||
'path://M24 19.999l-5.713-5.713 13.713-10.286-4-4-17.141 6.858-5.397-5.397c-1.556-1.556-3.728-1.928-4.828-0.828s-0.727 3.273 0.828 4.828l5.396 5.396-6.858 17.143 4 4 10.287-13.715 5.713 5.713v7.999h4l2-6 6-2v-4l-7.999 0z'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
let optionIndex = 0;
|
||||
option = options[optionIndex];
|
||||
setInterval(function () {
|
||||
optionIndex = (optionIndex + 1) % options.length;
|
||||
myChart.setOption(options[optionIndex]);
|
||||
}, 700);
|
||||
|
||||
option && myChart.setOption(option);
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
110
src/views/user/addDialog/index.vue
Normal file
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="dialogaddVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="门店头像" prop="avatarUrl">
|
||||
|
||||
<el-upload list-type="picture-card" limit="1" :auto-upload="false" drag action="#">
|
||||
<el-icon><Plus /></el-icon>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
(最多传一张)
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="username">
|
||||
<el-input v-model="form.username" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户账号" prop="userAccount">
|
||||
<el-input v-model="form.userAccount" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户密码" prop="userPassword">
|
||||
<el-input v-model="form.userPassword" show-password />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue'
|
||||
|
||||
|
||||
const props=defineProps({
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
avatarUrl:'',
|
||||
userAccount:'',
|
||||
userPassword:'',
|
||||
username:null
|
||||
|
||||
})
|
||||
// const rules=ref({
|
||||
// name: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请输入商品大类名称!'
|
||||
// }
|
||||
// ],
|
||||
// remark: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请输入商品大类描述!'
|
||||
// }
|
||||
// ]
|
||||
// })
|
||||
const formRef=ref(null);
|
||||
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initUserList'])
|
||||
const handleClose=()=>{
|
||||
console.log("用户添加关闭xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
const handleConfirm=()=>{
|
||||
formRef.value.validate(async(valid)=>{
|
||||
if(valid){
|
||||
let result=await axios.post("user/add",form.value)
|
||||
console.log(result.data)
|
||||
let data=result.data;
|
||||
if(data.code==0){
|
||||
ElMessage.success("执行添加成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initUserList");
|
||||
handleClose();
|
||||
}else{
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
}else{
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
152
src/views/user/dialog/index.vue
Normal file
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="用户头像" prop="avatarUrl">
|
||||
<img :src="form.avatarUrl" alt="空" width="50" height="50"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="username">
|
||||
{{form.username}}
|
||||
</el-form-item>
|
||||
<el-form-item label="用户账号" prop="userAccount">
|
||||
{{form.userAccount}}
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<template v-if="form.gender==0">女</template>
|
||||
<template v-else>男</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
{{form.phone}}
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
{{form.email}}
|
||||
</el-form-item>
|
||||
<el-form-item label="用户状态" prop="userStatus">
|
||||
<template v-if="form.userStatus==0">禁用</template>
|
||||
<template v-else>启用</template>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="用户角色" prop="userRole">
|
||||
<template v-if="form.userRole===0">普通用户</template>
|
||||
<template v-else-if="form.userRole===1">管理员</template>
|
||||
<template v-else-if="form.userRole===2">商家</template>
|
||||
<template v-else>美甲师</template>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- <template #footer>-->
|
||||
<!--<span class="dialog-footer">-->
|
||||
<!--<el-button @click="handleClose">取消</el-button>-->
|
||||
<!--<el-button type="primary" @click="handleConfirm">确认</el-button>-->
|
||||
<!--</span>-->
|
||||
<!-- </template>-->
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import { ElMessage } from "element-plus";
|
||||
const props=defineProps({
|
||||
id:{
|
||||
type:String,
|
||||
default:-1,
|
||||
required:true
|
||||
},
|
||||
dialogTitle:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:true
|
||||
}
|
||||
})
|
||||
const form=ref({
|
||||
avatarUrl: "",
|
||||
createTime:"",
|
||||
email:"",
|
||||
gender:null,
|
||||
isDelete:null,
|
||||
openId:null,
|
||||
phone:null,
|
||||
unionId:null,
|
||||
updateTime:"",
|
||||
userAccount:"",
|
||||
userPassword:"",
|
||||
userRole:null,
|
||||
userStatus:null,
|
||||
username:""
|
||||
})
|
||||
// const rules=ref({
|
||||
// name: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请输入商品大类名称!'
|
||||
// }
|
||||
// ],
|
||||
// remark: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请输入商品大类描述!'
|
||||
// }
|
||||
// ]
|
||||
// })
|
||||
const formRef=ref(null);
|
||||
const initFormData=async(ids)=>{
|
||||
// console.log(ids)
|
||||
const res=await axios.get("user/getById",{id: ids})
|
||||
// console.log(res.data.data)
|
||||
form.value=res.data.data;
|
||||
|
||||
}
|
||||
watch(
|
||||
()=>props.id,
|
||||
()=>{
|
||||
//console.log("id="+props.id);
|
||||
let ids=props.id;
|
||||
initFormData(ids)
|
||||
|
||||
// }else{
|
||||
// formRef.value.resetFields();
|
||||
// form.value={
|
||||
// id:-1,
|
||||
// name:"",
|
||||
// remark:""
|
||||
// }
|
||||
// }
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits=defineEmits(['update:modelValue','initUserList'])
|
||||
const handleClose=()=>{
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue',false)
|
||||
}
|
||||
// const handleConfirm=()=>{
|
||||
// formRef.value.validate(async(valid)=>{
|
||||
// if(valid){
|
||||
// let result=await axios.post("admin/bigType/save",form.value)
|
||||
// let data=result.data;
|
||||
// if(data.code==0){
|
||||
// ElMessage.success("执行成功!");
|
||||
// formRef.value.resetFields();
|
||||
// emits("initUserList");
|
||||
// handleClose();
|
||||
// }else{
|
||||
// ElMessage.error(data.msg);
|
||||
// }
|
||||
// }else{
|
||||
// console.log("fail")
|
||||
// return false
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
232
src/views/user/index.vue
Normal file
|
@ -0,0 +1,232 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-row :gutter="20" class="header">
|
||||
<el-col :span="7">
|
||||
<el-input placeholder="请输入用户昵称..." clearable v-model="queryForm.username"></el-input>
|
||||
</el-col>
|
||||
<el-button type="button" :icon="Search" @click="initUserList" >搜索</el-button>
|
||||
<el-button type="primary" :icon="DocumentAdd" @click="handleAddDialogValue()" >添加用户</el-button>
|
||||
</el-row>
|
||||
<el-table :data="tableData" stripe style="width: 100%;" showOverflowTooltip>
|
||||
<el-table-column fixed prop="id" label="#ID" width="80" />
|
||||
<el-table-column prop="username" label="用户昵称" width="150" />
|
||||
<el-table-column prop="avatarUrl" label="头像" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-popover
|
||||
placement="right-start"
|
||||
:width="200"
|
||||
trigger="hover"
|
||||
:content="scope.row.avatarUrl"
|
||||
>
|
||||
<template #reference>
|
||||
<img :src="scope.row.avatarUrl" width="50" height="50"/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="openId" label="openId" />
|
||||
<el-table-column prop="phone" label="电话" width="120"/>
|
||||
<el-table-column prop="email" label="email" width="200"/>
|
||||
<el-table-column prop="userStatus" label="用户状态" width="200">
|
||||
<template v-slot="scope">
|
||||
<div v-if="scope.row.userStatus===0" style="color: red">
|
||||
禁用
|
||||
</div>
|
||||
<div style="color: lawngreen" v-else>
|
||||
启用
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userRole" label="用户角色" width="200">
|
||||
<template v-slot="scope">
|
||||
<div v-if="scope.row.userRole===0">普通用户</div>
|
||||
<div v-else-if="scope.row.userRole===1">管理员</div>
|
||||
<div v-else-if="scope.row.userRole===2">商家</div>
|
||||
<div v-else>美甲师</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="注册日期" width="200">
|
||||
<!-- <template v-slot="scope">-->
|
||||
<!-- {{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}-->
|
||||
<!-- </template>-->
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="最后登录日期" width="200"/>
|
||||
<el-table-column prop="action" fixed="right" label="操作" min-width="170">
|
||||
<template v-slot="scope" >
|
||||
<el-button type="success" size="small" @click="handleDialogValue(scope.row.id)">
|
||||
详情
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" :icon="Edit" @click="handleUpdateDialogValue(scope.row.id)"></el-button>
|
||||
<el-button type="danger" size="small" :icon="Delete" @click="handleDelete(scope.row.id)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:currentPage="queryForm.current"
|
||||
v-model:page-size="queryForm.pageSize"
|
||||
:page-sizes="[10, 20, 30, 40,50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
<!-- {{total}}-->
|
||||
</el-card>
|
||||
|
||||
|
||||
<Dialog v-model="UdialogVisible" :id="id" :dialogTitle="dialogTitle"
|
||||
@initUserList="initUserList"></Dialog>
|
||||
<AddDialog v-model="UdialogaddVisible" :dialogTitle="dialogTitle"
|
||||
@initUserList="initUserList"></AddDialog>
|
||||
<UpdateDialog v-model="UdialogUpdateVisible" :id="id" :dialogTitle="dialogTitle"
|
||||
@initUserList="initUserList"></UpdateDialog>
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
import {Search,Delete,Edit,DocumentAdd,Close,Check} from '@element-plus/icons-vue'
|
||||
import {ref, watch} from 'vue'
|
||||
import axios from "@/util/axios";
|
||||
import Dialog from '@/views/user/dialog/index.vue'
|
||||
import AddDialog from '@/views/user/addDialog/index.vue'
|
||||
import UpdateDialog from '@/views/user/updateDialog/index.vue'
|
||||
import { ElMessage,ElMessageBox } from "element-plus";
|
||||
import {parseTime} from "element-plus/es/components/time-select/src/utils";
|
||||
|
||||
|
||||
const queryForm=ref({
|
||||
username: '',
|
||||
current:1,
|
||||
pageSize:10
|
||||
})
|
||||
|
||||
const id=ref('')
|
||||
const dialogTitle=ref('');
|
||||
const UdialogaddVisible=ref(false)
|
||||
const UdialogVisible=ref(false)
|
||||
const UdialogUpdateVisible=ref(false)
|
||||
|
||||
|
||||
// watch(queryForm.value.username,()=>{
|
||||
// // console.log(query.value)
|
||||
// initUserList();
|
||||
// },10000)
|
||||
|
||||
|
||||
const handleDialogValue=(ids)=>{
|
||||
//console.log("bigTypeId="+userAccount)
|
||||
// if(userAccount){
|
||||
id.value=ids;
|
||||
dialogTitle.value="用户详情"
|
||||
// console.log("asdfasdfasd"+useraccount.value)
|
||||
// }else{
|
||||
// useraccount.value=-1;
|
||||
// dialogTitle.value="添加用户"
|
||||
// // console.log(dialogTitle.value)
|
||||
// }
|
||||
UdialogVisible.value=true
|
||||
}
|
||||
|
||||
const handleUpdateDialogValue=(ids)=>{
|
||||
// console.log(userAccount)
|
||||
id.value=ids;
|
||||
// console.log(userAccount.value)
|
||||
dialogTitle.value="用户修改"
|
||||
UdialogUpdateVisible.value=true
|
||||
}
|
||||
|
||||
const handleAddDialogValue=()=>{
|
||||
dialogTitle.value="用户添加"
|
||||
UdialogaddVisible.value=true
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//删除
|
||||
|
||||
const handleDelete=(id)=>{
|
||||
// console.log(id)
|
||||
ElMessageBox.confirm(
|
||||
'您确定要删除这条记录吗?',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(async() => {
|
||||
let res=await axios.post('user/delete',{id:id})
|
||||
if(res.data.code==0){
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功',
|
||||
})
|
||||
initSmallTypeList();
|
||||
}else{
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: res.data.description,
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
// initUserList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
const total=ref(0)
|
||||
const tableData =ref([])
|
||||
|
||||
const initUserList=async()=>{
|
||||
// // console.log(query)
|
||||
// if (!query.value) {
|
||||
// const res = await axios.post("user/list/page", queryForm.value);
|
||||
// // console.log(res)
|
||||
// tableData.value = res.data.data.records;
|
||||
// //console.log(res.data.data)
|
||||
// total.value = Number(res.data.data.total);
|
||||
// }
|
||||
// else{
|
||||
// const res=await axios.get("user/getById", {id:query.value});
|
||||
// // console.log(res.data.data)
|
||||
// const temp=[];
|
||||
// temp.push(res.data.data)
|
||||
// tableData.value=temp;
|
||||
// total.value=1;
|
||||
// }
|
||||
const res = await axios.post("user/list/page", queryForm.value);
|
||||
// console.log(res.data.data.records)
|
||||
if (res.data.data) {
|
||||
tableData.value = res.data.data.records;
|
||||
//console.log(res.data.data)
|
||||
total.value = Number(res.data.data.total);
|
||||
}
|
||||
else{
|
||||
ElMessage.error(res.data.description);
|
||||
}
|
||||
}
|
||||
initUserList();
|
||||
const handleSizeChange = (pageSize) => {
|
||||
queryForm.value.current=1;
|
||||
queryForm.value.pageSize=pageSize;
|
||||
initUserList();
|
||||
}
|
||||
const handleCurrentChange = (current1) => {
|
||||
queryForm.value.current=current1;
|
||||
initUserList();
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
padding-bottom: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
.el-pagination{
|
||||
padding-top: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
171
src/views/user/updateDialog/index.vue
Normal file
|
@ -0,0 +1,171 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
model-value="dialogUpdateVisible"
|
||||
:title="dialogTitle"
|
||||
width="30%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="用户头像" prop="avatarUrl">
|
||||
<!-- {{ form.avatarUrl }}-->
|
||||
<el-input v-model="form.avatarUrl"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="username">
|
||||
<el-input v-model="form.username"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户ID" prop="id">
|
||||
<el-input v-model="form.id"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<template v-if="form.gender==0">女</template>
|
||||
<template v-else>男</template>
|
||||
|
||||
|
||||
<el-radio-group v-model="form.gender">
|
||||
<el-radio :value="0" size="default">女</el-radio>
|
||||
<el-radio :value="1" size="default">男</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="form.phone"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户状态" prop="userStatus">
|
||||
<el-input v-model="form.userStatus"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户角色" prop="userRole">
|
||||
<!-- {{form.userRole}}-->
|
||||
<!-- {{labelt}}-->
|
||||
<!-- 展示由于v-model绑定出现v-model的form.userRole的值-->
|
||||
<el-select
|
||||
v-model="form.userRole"
|
||||
size="default"
|
||||
placeholder="用户角色"
|
||||
style="width: 100%"
|
||||
>
|
||||
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import {defineEmits, defineProps, ref, watch} from "vue";
|
||||
import axios from "@/util/axios";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: -1,
|
||||
required: true
|
||||
},
|
||||
dialogTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const labelt=ref('')
|
||||
|
||||
const form = ref({
|
||||
id:null,
|
||||
avatarUrl: "",
|
||||
email: "",
|
||||
gender: null,
|
||||
phone: null,
|
||||
userRole: null,
|
||||
userStatus: null,
|
||||
username: ""
|
||||
})
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: '',
|
||||
label: '用户身份',
|
||||
},
|
||||
{
|
||||
value: '0',
|
||||
label: '普通用户',
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: '管理员',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '商家',
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '美甲师',
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
|
||||
const formRef = ref(null);
|
||||
const initFormData = async (ids) => {
|
||||
const res = await axios.get("user/getById", {id: ids})
|
||||
form.value = res.data.data;
|
||||
labelt.value=options[form.value.userRole].label
|
||||
// console.log(options[form.value.userRole].label)
|
||||
}
|
||||
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
() => {
|
||||
// console.log("id=" + props.useraccount);
|
||||
let ids = props.id;
|
||||
initFormData(ids)
|
||||
}
|
||||
)
|
||||
// 定义父组件事件
|
||||
const emits = defineEmits(['update:modelValue', 'initUserList'])
|
||||
const handleClose = () => {
|
||||
console.log("xxx")
|
||||
// 调用执行
|
||||
emits('update:modelValue', false)
|
||||
}
|
||||
const handleConfirm = () => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
let result = await axios.post("user/update", form.value)
|
||||
let data = result.data;
|
||||
if (data.code == 0) {
|
||||
ElMessage.success("执行成功!");
|
||||
formRef.value.resetFields();
|
||||
emits("initUserList");
|
||||
handleClose();
|
||||
} else {
|
||||
ElMessage.error(data.description);
|
||||
}
|
||||
} else {
|
||||
console.log("fail")
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
|
474
src/views/welcome/index.vue
Normal file
|
@ -0,0 +1,474 @@
|
|||
<template>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="6">
|
||||
<div class="statistic-card">
|
||||
<el-statistic :value="98500">
|
||||
<template #title>
|
||||
<div style="display: inline-flex; justify-self: right;align-items: center;width: 100%">
|
||||
用户人数
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="Number of users who logged into the product in one day"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon style="margin-left: 4px" :size="12">
|
||||
<Warning />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<el-icon style="float: right" size="24"><Odometer /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-statistic>
|
||||
<div class="statistic-footer">
|
||||
<div class="footer-item">
|
||||
<span class="green">
|
||||
+24%
|
||||
<el-icon>
|
||||
<CaretTop />
|
||||
</el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="statistic-card">
|
||||
<el-statistic :value="693700">
|
||||
<template #title>
|
||||
<div style="display: inline-flex; align-items: center">
|
||||
商家人数
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="Number of users who logged into the product in one month"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon style="margin-left: 4px" :size="12">
|
||||
<Warning />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-statistic>
|
||||
<div class="statistic-footer">
|
||||
<div class="footer-item">
|
||||
|
||||
<span class="red">
|
||||
+12%
|
||||
<el-icon>
|
||||
<CaretBottom />
|
||||
</el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="statistic-card">
|
||||
<el-statistic :value="72000" title="New transactions today">
|
||||
<template #title>
|
||||
<div style="display: inline-flex; align-items: center">
|
||||
订单数量
|
||||
</div>
|
||||
</template>
|
||||
</el-statistic>
|
||||
<div class="statistic-footer">
|
||||
<div class="footer-item">
|
||||
|
||||
<span class="green">
|
||||
+16%
|
||||
<el-icon>
|
||||
<CaretTop />
|
||||
</el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="statistic-card">
|
||||
<el-statistic :value="72000" title="New transactions today">
|
||||
<template #title>
|
||||
<div style="display: inline-flex; align-items: center">
|
||||
用户满意度
|
||||
</div>
|
||||
</template>
|
||||
</el-statistic>
|
||||
<div class="statistic-footer">
|
||||
<div class="footer-item">
|
||||
<span class="green">
|
||||
+16%
|
||||
<el-icon>
|
||||
<CaretTop />
|
||||
</el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- ============================================================================ -->
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="18">
|
||||
<div class="statistic-card">
|
||||
<div style="display: inline-flex; justify-self: right;align-items: center;width: 100%">
|
||||
分析概览
|
||||
</div>
|
||||
<div class="statistic-footer">
|
||||
<div class="footer-item">
|
||||
<div id="main1" style="height: 320px;width: 780px;border: 1px solid #ebebeb;border-radius: 2px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="statistic-card">
|
||||
<div style="display: inline-flex; justify-self: right;align-items: center;width: 100%">
|
||||
每周展示
|
||||
</div>
|
||||
<div class="statistic-footer">
|
||||
<div class="footer-item">
|
||||
<div style="height: 320px;width: 220px;border: 1px solid #ebebeb;border-radius: 2px;">
|
||||
<div class="common" >
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周日</div>
|
||||
</div>
|
||||
<!-- ---------->
|
||||
<div class="common">
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周六</div>
|
||||
</div>
|
||||
|
||||
<div class="common">
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周五</div>
|
||||
</div>
|
||||
|
||||
<div class="common">
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周四</div>
|
||||
</div>
|
||||
<div class="common">
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周三</div>
|
||||
</div>
|
||||
<div class="common">
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周二</div>
|
||||
</div>
|
||||
<div class="common">
|
||||
<div style="flex: 8"><el-progress
|
||||
:text-inside="true"
|
||||
:stroke-width="15"
|
||||
:percentage="100"
|
||||
duration="30"
|
||||
color="#26ce83"
|
||||
striped
|
||||
striped-flow
|
||||
/></div>
|
||||
<div style="flex: 1">周一</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ArrowRight,
|
||||
Odometer,
|
||||
CaretBottom,
|
||||
CaretTop,
|
||||
Warning,
|
||||
} from '@element-plus/icons-vue'
|
||||
import {onMounted} from "vue";
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
onMounted(async () => {
|
||||
setTimeout(() => {hei();}, 500)
|
||||
})
|
||||
const hei=()=>{
|
||||
|
||||
var app = {};
|
||||
|
||||
var chartDom = document.getElementById('main1');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option;
|
||||
|
||||
const posList = [
|
||||
'left',
|
||||
'right',
|
||||
'top',
|
||||
'bottom',
|
||||
'inside',
|
||||
'insideTop',
|
||||
'insideLeft',
|
||||
'insideRight',
|
||||
'insideBottom',
|
||||
'insideTopLeft',
|
||||
'insideTopRight',
|
||||
'insideBottomLeft',
|
||||
'insideBottomRight'
|
||||
];
|
||||
app.configParameters = {
|
||||
rotate: {
|
||||
min: -90,
|
||||
max: 90
|
||||
},
|
||||
align: {
|
||||
options: {
|
||||
left: 'left',
|
||||
center: 'center',
|
||||
right: 'right'
|
||||
}
|
||||
},
|
||||
verticalAlign: {
|
||||
options: {
|
||||
top: 'top',
|
||||
middle: 'middle',
|
||||
bottom: 'bottom'
|
||||
}
|
||||
},
|
||||
position: {
|
||||
options: posList.reduce(function (map, pos) {
|
||||
map[pos] = pos;
|
||||
return map;
|
||||
}, {})
|
||||
},
|
||||
distance: {
|
||||
min: 0,
|
||||
max: 100
|
||||
}
|
||||
};
|
||||
app.config = {
|
||||
rotate: 90,
|
||||
align: 'left',
|
||||
verticalAlign: 'middle',
|
||||
position: 'insideBottom',
|
||||
distance: 15,
|
||||
onChange: function () {
|
||||
const labelOption = {
|
||||
rotate: app.config.rotate,
|
||||
align: app.config.align,
|
||||
verticalAlign: app.config.verticalAlign,
|
||||
position: app.config.position,
|
||||
distance: app.config.distance
|
||||
};
|
||||
myChart.setOption({
|
||||
series: [
|
||||
{
|
||||
label: labelOption
|
||||
},
|
||||
{
|
||||
label: labelOption
|
||||
},
|
||||
{
|
||||
label: labelOption
|
||||
},
|
||||
{
|
||||
label: labelOption
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
||||
const labelOption = {
|
||||
show: true,
|
||||
position: app.config.position,
|
||||
distance: app.config.distance,
|
||||
align: app.config.align,
|
||||
verticalAlign: app.config.verticalAlign,
|
||||
rotate: app.config.rotate,
|
||||
formatter: '{c} {name|{a}}',
|
||||
fontSize: 16,
|
||||
rich: {
|
||||
name: {}
|
||||
}
|
||||
};
|
||||
option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['Forest', 'Steppe', 'Desert', 'Wetland']
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
top: 'center',
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: { show: true, readOnly: false },
|
||||
magicType: { show: true, type: ['line', 'bar', 'stack'] },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
data: ['2012', '2013', '2014', '2015', '2016']
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Forest',
|
||||
type: 'bar',
|
||||
barGap: 0,
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [320, 332, 301, 334, 390]
|
||||
},
|
||||
{
|
||||
name: 'Steppe',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [220, 182, 191, 234, 290]
|
||||
},
|
||||
{
|
||||
name: 'Desert',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [150, 232, 201, 154, 190]
|
||||
},
|
||||
{
|
||||
name: 'Wetland',
|
||||
type: 'bar',
|
||||
label: labelOption,
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [98, 77, 101, 99, 40]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:global(h2#card-usage ~ .example .example-showcase) {
|
||||
background-color: var(--el-fill-color) !important;
|
||||
}
|
||||
|
||||
|
||||
.common{
|
||||
display: flex;
|
||||
padding: 15px 0 15px;
|
||||
}
|
||||
.common_left{
|
||||
flex: 8;
|
||||
}
|
||||
.common_right{
|
||||
flex: 1;
|
||||
}
|
||||
.statistic-card {
|
||||
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
.statistic-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
font-size: 12px;
|
||||
color: var(--el-text-color-regular);
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.statistic-footer .footer-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.statistic-footer .footer-item span:last-child {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
.red {
|
||||
color: var(--el-color-error);
|
||||
}
|
||||
</style>
|
76
vue.config.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
const { defineConfig } = require('@vue/cli-service')
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true
|
||||
})
|
||||
|
||||
const webpack = require('webpack');
|
||||
const path = require('path')
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
module.exports = {
|
||||
transpileDependencies: true,
|
||||
lintOnSave: false,
|
||||
configureWebpack:{
|
||||
resolve:{
|
||||
alias:{
|
||||
'@':resolve('src')
|
||||
}
|
||||
}
|
||||
},
|
||||
chainWebpack(config) {
|
||||
// 设置 svg-sprite-loader
|
||||
// config 为 webpack 配置对象
|
||||
// config.module 表示创建一个具名规则,以后用来修改规则
|
||||
config.module
|
||||
// 规则
|
||||
.rule('svg')
|
||||
// 忽略
|
||||
.exclude.add(resolve('src/icons'))
|
||||
// 结束
|
||||
.end()
|
||||
// config.module 表示创建一个具名规则,以后用来修改规则
|
||||
config.module
|
||||
// 规则
|
||||
.rule('icons')
|
||||
// 正则,解析 .svg 格式文件
|
||||
.test(/\.svg$/)
|
||||
// 解析的文件
|
||||
.include.add(resolve('src/icons'))
|
||||
// 结束
|
||||
.end()
|
||||
// 新增了一个解析的loader
|
||||
.use('svg-sprite-loader')
|
||||
// 具体的loader
|
||||
.loader('svg-sprite-loader')
|
||||
// loader 的配置
|
||||
.options({
|
||||
symbolId: 'icon-[name]'
|
||||
})
|
||||
// 结束
|
||||
.end()
|
||||
config
|
||||
.plugin('ignore')
|
||||
.use(
|
||||
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
|
||||
)
|
||||
config.module
|
||||
.rule('icons')
|
||||
.test(/\.svg$/)
|
||||
.include.add(resolve('src/icons'))
|
||||
.end()
|
||||
.use('svg-sprite-loader')
|
||||
.loader('svg-sprite-loader')
|
||||
.options({
|
||||
symbolId: 'icon-[name]'
|
||||
})
|
||||
.end()
|
||||
}
|
||||
}
|
||||
//打包配置文件
|
||||
module.exports = {
|
||||
assetsDir: 'static',
|
||||
parallel: false,
|
||||
publicPath: './',
|
||||
};
|
||||
|