(Update API paths, adjust configurations, and optimize user and order management functions)dd
This commit is contained in:
parent
1cc5088f81
commit
b2b8b13503
|
@ -18,6 +18,7 @@
|
||||||
"echarts": "^5.3.3",
|
"echarts": "^5.3.3",
|
||||||
"element-plus": "2.2.27",
|
"element-plus": "2.2.27",
|
||||||
"highlight.js": "^11.6.0",
|
"highlight.js": "^11.6.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.0.14",
|
"pinia": "^2.0.14",
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
|
@ -5362,6 +5363,14 @@
|
||||||
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
|
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"echarts": "^5.3.3",
|
"echarts": "^5.3.3",
|
||||||
"element-plus": "2.2.27",
|
"element-plus": "2.2.27",
|
||||||
"highlight.js": "^11.6.0",
|
"highlight.js": "^11.6.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.0.14",
|
"pinia": "^2.0.14",
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
export function apigetProvinceLists() {
|
export function apigetProvinceLists() {
|
||||||
return request.get({ url: '/geo/province' })
|
return request.get({ url: '/config/province' })
|
||||||
}
|
}
|
||||||
export function apicityLists(params: any) {
|
export function apicityLists(params: any) {
|
||||||
return request.get({ url: '/geo/city', params })
|
return request.get({ url: '/config/city', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiAreaLists(params: any) {
|
export function apiAreaLists(params: any) {
|
||||||
return request.get({ url: '/geo/area', params })
|
return request.get({ url: '/config/area', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiStreetLists(params: any) {
|
export function apiGetStore( ) {
|
||||||
return request.get({ url: '/geo/street', params })
|
return request.post({ url: '/config/store' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiVillageLists(params: any) {
|
export function apiSaveStore(params: any) {
|
||||||
return request.get({ url: '/geo/village', params })
|
return request.post({ url: '/config/saveStore', params })
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function apiDeliveryLists(params:any) {
|
||||||
|
return request.get({ url: '/delivery/lists',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiDeliveryAdd(params:any) {
|
||||||
|
return request.post({ url: '/delivery/add',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiDeliveryEdit(params:any) {
|
||||||
|
return request.post({ url: '/delivery/edit',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiDeliveryDetail(params:any) {
|
||||||
|
return request.get({ url: '/delivery/detail',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function apiDeliveryStatus(params:any) {
|
||||||
|
return request.post({ url: '/delivery/status',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiDeliveryDelete(params:any) {
|
||||||
|
return request.post({ url: '/delivery/delete',params })
|
||||||
|
}
|
|
@ -28,6 +28,24 @@ export function apiStatus(params: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 店员列表
|
// 店员列表
|
||||||
export function apiStaffLists() {
|
export function apiStaffLists(params:any) {
|
||||||
return request.get({ url: '/staff/lists' })
|
return request.get({ url: '/staff/lists',params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function apiStaffAdd(params:any) {
|
||||||
|
return request.post({ url: '/staff/add',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiStaffEdit(params:any) {
|
||||||
|
return request.post({ url: '/staff/edit',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function apiStaffDetail(params:any) {
|
||||||
|
return request.get({ url: '/staff/detail',params })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function apiStaffStatus(params:any) {
|
||||||
|
return request.post({ url: '/staff/status',params })
|
||||||
|
}
|
|
@ -0,0 +1,539 @@
|
||||||
|
/* Logo 字体 */
|
||||||
|
@font-face {
|
||||||
|
font-family: "iconfont logo";
|
||||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-family: "iconfont logo";
|
||||||
|
font-size: 160px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tabs */
|
||||||
|
.nav-tabs {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs .nav-more {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs li {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#tabs .active {
|
||||||
|
border-bottom-color: #f00;
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-container .content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面布局 */
|
||||||
|
.main {
|
||||||
|
padding: 30px 100px;
|
||||||
|
width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .logo {
|
||||||
|
color: #333;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
line-height: 1;
|
||||||
|
height: 110px;
|
||||||
|
margin-top: -50px;
|
||||||
|
overflow: hidden;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .logo a {
|
||||||
|
font-size: 160px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helps {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helps pre {
|
||||||
|
padding: 20px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border: solid 1px #e7e1cd;
|
||||||
|
background-color: #fffdef;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists {
|
||||||
|
width: 100% !important;
|
||||||
|
overflow: hidden;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists li {
|
||||||
|
width: 100px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 20px;
|
||||||
|
text-align: center;
|
||||||
|
list-style: none !important;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists li .code-name {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists .icon {
|
||||||
|
display: block;
|
||||||
|
height: 100px;
|
||||||
|
line-height: 100px;
|
||||||
|
font-size: 42px;
|
||||||
|
margin: 10px auto;
|
||||||
|
color: #333;
|
||||||
|
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||||
|
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||||
|
transition: font-size 0.25s linear, width 0.25s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists .icon:hover {
|
||||||
|
font-size: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists .svg-icon {
|
||||||
|
/* 通过设置 font-size 来改变图标大小 */
|
||||||
|
width: 1em;
|
||||||
|
/* 图标和文字相邻时,垂直对齐 */
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||||
|
fill: currentColor;
|
||||||
|
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||||
|
normalize.css 中也包含这行 */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists li .name,
|
||||||
|
.icon_lists li .code-name {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* markdown 样式 */
|
||||||
|
.markdown {
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown img {
|
||||||
|
vertical-align: middle;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1 {
|
||||||
|
color: #404040;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 40px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h2,
|
||||||
|
.markdown h3,
|
||||||
|
.markdown h4,
|
||||||
|
.markdown h5,
|
||||||
|
.markdown h6 {
|
||||||
|
color: #404040;
|
||||||
|
margin: 1.6em 0 0.6em 0;
|
||||||
|
font-weight: 500;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h5 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h6 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown hr {
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
background: #e9e9e9;
|
||||||
|
margin: 16px 0;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown p {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>p,
|
||||||
|
.markdown>blockquote,
|
||||||
|
.markdown>.highlight,
|
||||||
|
.markdown>ol,
|
||||||
|
.markdown>ul {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown ul>li {
|
||||||
|
list-style: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>ul li,
|
||||||
|
.markdown blockquote ul>li {
|
||||||
|
margin-left: 20px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>ul li p,
|
||||||
|
.markdown>ol li p {
|
||||||
|
margin: 0.6em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown ol>li {
|
||||||
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>ol li,
|
||||||
|
.markdown blockquote ol>li {
|
||||||
|
margin-left: 20px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown code {
|
||||||
|
margin: 0 3px;
|
||||||
|
padding: 0 5px;
|
||||||
|
background: #eee;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown strong,
|
||||||
|
.markdown b {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0px;
|
||||||
|
empty-cells: show;
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
width: 95%;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table th {
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table th,
|
||||||
|
.markdown>table td {
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
padding: 8px 16px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table th {
|
||||||
|
background: #F7F7F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown blockquote {
|
||||||
|
font-size: 90%;
|
||||||
|
color: #999;
|
||||||
|
border-left: 4px solid #e9e9e9;
|
||||||
|
padding-left: 0.8em;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown blockquote p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown .anchor {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown .waiting {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1:hover .anchor,
|
||||||
|
.markdown h2:hover .anchor,
|
||||||
|
.markdown h3:hover .anchor,
|
||||||
|
.markdown h4:hover .anchor,
|
||||||
|
.markdown h5:hover .anchor,
|
||||||
|
.markdown h6:hover .anchor {
|
||||||
|
opacity: 1;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>br,
|
||||||
|
.markdown>p>br {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
background: white;
|
||||||
|
padding: 0.5em;
|
||||||
|
color: #333333;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-meta {
|
||||||
|
color: #969896;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-strong,
|
||||||
|
.hljs-emphasis,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #df5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-type {
|
||||||
|
color: #a71d5d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-attribute {
|
||||||
|
color: #0086b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-name {
|
||||||
|
color: #63a35c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-tag {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-pseudo {
|
||||||
|
color: #795da3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
color: #55a532;
|
||||||
|
background-color: #eaffea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
color: #bd2c00;
|
||||||
|
background-color: #ffecec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码高亮 */
|
||||||
|
/* PrismJS 1.15.0
|
||||||
|
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||||
|
/**
|
||||||
|
* prism.js default theme for JavaScript, CSS and HTML
|
||||||
|
* Based on dabblet (http://dabblet.com)
|
||||||
|
* @author Lea Verou
|
||||||
|
*/
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
color: black;
|
||||||
|
background: none;
|
||||||
|
text-shadow: 0 1px white;
|
||||||
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre;
|
||||||
|
word-spacing: normal;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
-moz-tab-size: 4;
|
||||||
|
-o-tab-size: 4;
|
||||||
|
tab-size: 4;
|
||||||
|
|
||||||
|
-webkit-hyphens: none;
|
||||||
|
-moz-hyphens: none;
|
||||||
|
-ms-hyphens: none;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::-moz-selection,
|
||||||
|
pre[class*="language-"] ::-moz-selection,
|
||||||
|
code[class*="language-"]::-moz-selection,
|
||||||
|
code[class*="language-"] ::-moz-selection {
|
||||||
|
text-shadow: none;
|
||||||
|
background: #b3d4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::selection,
|
||||||
|
pre[class*="language-"] ::selection,
|
||||||
|
code[class*="language-"]::selection,
|
||||||
|
code[class*="language-"] ::selection {
|
||||||
|
text-shadow: none;
|
||||||
|
background: #b3d4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
pre[class*="language-"] {
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(pre)>code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
background: #f5f2f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline code */
|
||||||
|
:not(pre)>code[class*="language-"] {
|
||||||
|
padding: .1em;
|
||||||
|
border-radius: .3em;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.comment,
|
||||||
|
.token.prolog,
|
||||||
|
.token.doctype,
|
||||||
|
.token.cdata {
|
||||||
|
color: slategray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.punctuation {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.property,
|
||||||
|
.token.tag,
|
||||||
|
.token.boolean,
|
||||||
|
.token.number,
|
||||||
|
.token.constant,
|
||||||
|
.token.symbol,
|
||||||
|
.token.deleted {
|
||||||
|
color: #905;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.selector,
|
||||||
|
.token.attr-name,
|
||||||
|
.token.string,
|
||||||
|
.token.char,
|
||||||
|
.token.builtin,
|
||||||
|
.token.inserted {
|
||||||
|
color: #690;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.operator,
|
||||||
|
.token.entity,
|
||||||
|
.token.url,
|
||||||
|
.language-css .token.string,
|
||||||
|
.style .token.string {
|
||||||
|
color: #9a6e3a;
|
||||||
|
background: hsla(0, 0%, 100%, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.atrule,
|
||||||
|
.token.attr-value,
|
||||||
|
.token.keyword {
|
||||||
|
color: #07a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.function,
|
||||||
|
.token.class-name {
|
||||||
|
color: #DD4A68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.regex,
|
||||||
|
.token.important,
|
||||||
|
.token.variable {
|
||||||
|
color: #e90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.important,
|
||||||
|
.token.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.entity {
|
||||||
|
cursor: help;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,239 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "iconfont"; /* Project id 4573174 */
|
||||||
|
src: url('iconfont.woff2?t=1717554669936') format('woff2'),
|
||||||
|
url('iconfont.woff?t=1717554669936') format('woff'),
|
||||||
|
url('iconfont.ttf?t=1717554669936') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy49:before {
|
||||||
|
content: "\e6bd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy50:before {
|
||||||
|
content: "\e6be";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy51:before {
|
||||||
|
content: "\e6bf";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy53:before {
|
||||||
|
content: "\e6c1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy54:before {
|
||||||
|
content: "\e6c4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy59:before {
|
||||||
|
content: "\e6dd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy60:before {
|
||||||
|
content: "\e6de";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy37:before {
|
||||||
|
content: "\e6a6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy38:before {
|
||||||
|
content: "\e6a7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy39:before {
|
||||||
|
content: "\e6a8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy40:before {
|
||||||
|
content: "\e6a9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy41:before {
|
||||||
|
content: "\e6aa";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy42:before {
|
||||||
|
content: "\e6ab";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy43:before {
|
||||||
|
content: "\e6ac";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy44:before {
|
||||||
|
content: "\e6ad";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy45:before {
|
||||||
|
content: "\e6ae";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy46:before {
|
||||||
|
content: "\e6af";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy47:before {
|
||||||
|
content: "\e6bb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy:before {
|
||||||
|
content: "\e6a3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy1:before {
|
||||||
|
content: "\e6a2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy2:before {
|
||||||
|
content: "\e6a4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy3:before {
|
||||||
|
content: "\e6a1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy4:before {
|
||||||
|
content: "\e6a5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy5:before {
|
||||||
|
content: "\e6b0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy6:before {
|
||||||
|
content: "\e6b1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy7:before {
|
||||||
|
content: "\e6b2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy8:before {
|
||||||
|
content: "\e6b3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy9:before {
|
||||||
|
content: "\e6b4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy10:before {
|
||||||
|
content: "\e6b5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy11:before {
|
||||||
|
content: "\e6b6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy12:before {
|
||||||
|
content: "\e6b7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy13:before {
|
||||||
|
content: "\e6b8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy14:before {
|
||||||
|
content: "\e6b9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy15:before {
|
||||||
|
content: "\e6ba";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy16:before {
|
||||||
|
content: "\e6c2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy17:before {
|
||||||
|
content: "\e6c3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy18:before {
|
||||||
|
content: "\e6c6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy19:before {
|
||||||
|
content: "\e6c8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy20:before {
|
||||||
|
content: "\e6d1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy21:before {
|
||||||
|
content: "\e6d8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy22:before {
|
||||||
|
content: "\e6da";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy23:before {
|
||||||
|
content: "\e6e0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy24:before {
|
||||||
|
content: "\e6df";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy25:before {
|
||||||
|
content: "\e6e2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy26:before {
|
||||||
|
content: "\e6e3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy27:before {
|
||||||
|
content: "\e6e4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy28:before {
|
||||||
|
content: "\e6e5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy29:before {
|
||||||
|
content: "\e6e6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy30:before {
|
||||||
|
content: "\e6e7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy31:before {
|
||||||
|
content: "\e6e8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy32:before {
|
||||||
|
content: "\e6e9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy33:before {
|
||||||
|
content: "\e6ea";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy34:before {
|
||||||
|
content: "\e6eb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dingwei:before {
|
||||||
|
content: "\e6ec";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy35:before {
|
||||||
|
content: "\e6ed";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RectangleCopy36:before {
|
||||||
|
content: "\e6ee";
|
||||||
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,401 @@
|
||||||
|
{
|
||||||
|
"id": "4573174",
|
||||||
|
"name": "duo'men'dian",
|
||||||
|
"font_family": "iconfont",
|
||||||
|
"css_prefix_text": "icon-",
|
||||||
|
"description": "",
|
||||||
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "7549358",
|
||||||
|
"name": "流量",
|
||||||
|
"font_class": "RectangleCopy49",
|
||||||
|
"unicode": "e6bd",
|
||||||
|
"unicode_decimal": 59069
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551129",
|
||||||
|
"name": "供应商",
|
||||||
|
"font_class": "RectangleCopy50",
|
||||||
|
"unicode": "e6be",
|
||||||
|
"unicode_decimal": 59070
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551130",
|
||||||
|
"name": "分销商",
|
||||||
|
"font_class": "RectangleCopy51",
|
||||||
|
"unicode": "e6bf",
|
||||||
|
"unicode_decimal": 59071
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551132",
|
||||||
|
"name": "人群",
|
||||||
|
"font_class": "RectangleCopy53",
|
||||||
|
"unicode": "e6c1",
|
||||||
|
"unicode_decimal": 59073
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551133",
|
||||||
|
"name": "人群管理",
|
||||||
|
"font_class": "RectangleCopy54",
|
||||||
|
"unicode": "e6c4",
|
||||||
|
"unicode_decimal": 59076
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553624",
|
||||||
|
"name": "分销商结算",
|
||||||
|
"font_class": "RectangleCopy59",
|
||||||
|
"unicode": "e6dd",
|
||||||
|
"unicode_decimal": 59101
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553627",
|
||||||
|
"name": "商家数据",
|
||||||
|
"font_class": "RectangleCopy60",
|
||||||
|
"unicode": "e6de",
|
||||||
|
"unicode_decimal": 59102
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549348",
|
||||||
|
"name": "搜索",
|
||||||
|
"font_class": "RectangleCopy37",
|
||||||
|
"unicode": "e6a6",
|
||||||
|
"unicode_decimal": 59046
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549364",
|
||||||
|
"name": "协同",
|
||||||
|
"font_class": "RectangleCopy38",
|
||||||
|
"unicode": "e6a7",
|
||||||
|
"unicode_decimal": 59047
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549373",
|
||||||
|
"name": "招商",
|
||||||
|
"font_class": "RectangleCopy39",
|
||||||
|
"unicode": "e6a8",
|
||||||
|
"unicode_decimal": 59048
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549816",
|
||||||
|
"name": "商品",
|
||||||
|
"font_class": "RectangleCopy40",
|
||||||
|
"unicode": "e6a9",
|
||||||
|
"unicode_decimal": 59049
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549817",
|
||||||
|
"name": "单据",
|
||||||
|
"font_class": "RectangleCopy41",
|
||||||
|
"unicode": "e6aa",
|
||||||
|
"unicode_decimal": 59050
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549828",
|
||||||
|
"name": "工具箱",
|
||||||
|
"font_class": "RectangleCopy42",
|
||||||
|
"unicode": "e6ab",
|
||||||
|
"unicode_decimal": 59051
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549832",
|
||||||
|
"name": "券",
|
||||||
|
"font_class": "RectangleCopy43",
|
||||||
|
"unicode": "e6ac",
|
||||||
|
"unicode_decimal": 59052
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549842",
|
||||||
|
"name": "平台",
|
||||||
|
"font_class": "RectangleCopy44",
|
||||||
|
"unicode": "e6ad",
|
||||||
|
"unicode_decimal": 59053
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549845",
|
||||||
|
"name": "经销",
|
||||||
|
"font_class": "RectangleCopy45",
|
||||||
|
"unicode": "e6ae",
|
||||||
|
"unicode_decimal": 59054
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549851",
|
||||||
|
"name": "资源",
|
||||||
|
"font_class": "RectangleCopy46",
|
||||||
|
"unicode": "e6af",
|
||||||
|
"unicode_decimal": 59055
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7550034",
|
||||||
|
"name": "货",
|
||||||
|
"font_class": "RectangleCopy47",
|
||||||
|
"unicode": "e6bb",
|
||||||
|
"unicode_decimal": 59067
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549350",
|
||||||
|
"name": "用户",
|
||||||
|
"font_class": "RectangleCopy",
|
||||||
|
"unicode": "e6a3",
|
||||||
|
"unicode_decimal": 59043
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549351",
|
||||||
|
"name": "安全",
|
||||||
|
"font_class": "RectangleCopy1",
|
||||||
|
"unicode": "e6a2",
|
||||||
|
"unicode_decimal": 59042
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549352",
|
||||||
|
"name": "数据",
|
||||||
|
"font_class": "RectangleCopy2",
|
||||||
|
"unicode": "e6a4",
|
||||||
|
"unicode_decimal": 59044
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549353",
|
||||||
|
"name": "疑问",
|
||||||
|
"font_class": "RectangleCopy3",
|
||||||
|
"unicode": "e6a1",
|
||||||
|
"unicode_decimal": 59041
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7549355",
|
||||||
|
"name": "调拨",
|
||||||
|
"font_class": "RectangleCopy4",
|
||||||
|
"unicode": "e6a5",
|
||||||
|
"unicode_decimal": 59045
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551131",
|
||||||
|
"name": "用户管理",
|
||||||
|
"font_class": "RectangleCopy5",
|
||||||
|
"unicode": "e6b0",
|
||||||
|
"unicode_decimal": 59056
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551134",
|
||||||
|
"name": "商家管理",
|
||||||
|
"font_class": "RectangleCopy6",
|
||||||
|
"unicode": "e6b1",
|
||||||
|
"unicode_decimal": 59057
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551135",
|
||||||
|
"name": "分销商管理",
|
||||||
|
"font_class": "RectangleCopy7",
|
||||||
|
"unicode": "e6b2",
|
||||||
|
"unicode_decimal": 59058
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551136",
|
||||||
|
"name": "商家",
|
||||||
|
"font_class": "RectangleCopy8",
|
||||||
|
"unicode": "e6b3",
|
||||||
|
"unicode_decimal": 59059
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551137",
|
||||||
|
"name": "供应商管理",
|
||||||
|
"font_class": "RectangleCopy9",
|
||||||
|
"unicode": "e6b4",
|
||||||
|
"unicode_decimal": 59060
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551213",
|
||||||
|
"name": "商品管理",
|
||||||
|
"font_class": "RectangleCopy10",
|
||||||
|
"unicode": "e6b5",
|
||||||
|
"unicode_decimal": 59061
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551217",
|
||||||
|
"name": "商品复制",
|
||||||
|
"font_class": "RectangleCopy11",
|
||||||
|
"unicode": "e6b6",
|
||||||
|
"unicode_decimal": 59062
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551346",
|
||||||
|
"name": "采购单",
|
||||||
|
"font_class": "RectangleCopy12",
|
||||||
|
"unicode": "e6b7",
|
||||||
|
"unicode_decimal": 59063
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551349",
|
||||||
|
"name": "采购价管理",
|
||||||
|
"font_class": "RectangleCopy13",
|
||||||
|
"unicode": "e6b8",
|
||||||
|
"unicode_decimal": 59064
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551477",
|
||||||
|
"name": "定价",
|
||||||
|
"font_class": "RectangleCopy14",
|
||||||
|
"unicode": "e6b9",
|
||||||
|
"unicode_decimal": 59065
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7551486",
|
||||||
|
"name": "结算报表",
|
||||||
|
"font_class": "RectangleCopy15",
|
||||||
|
"unicode": "e6ba",
|
||||||
|
"unicode_decimal": 59066
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7552198",
|
||||||
|
"name": "入库",
|
||||||
|
"font_class": "RectangleCopy16",
|
||||||
|
"unicode": "e6c2",
|
||||||
|
"unicode_decimal": 59074
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7552199",
|
||||||
|
"name": "库存管理",
|
||||||
|
"font_class": "RectangleCopy17",
|
||||||
|
"unicode": "e6c3",
|
||||||
|
"unicode_decimal": 59075
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7552213",
|
||||||
|
"name": "出入库管理",
|
||||||
|
"font_class": "RectangleCopy18",
|
||||||
|
"unicode": "e6c6",
|
||||||
|
"unicode_decimal": 59078
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7552217",
|
||||||
|
"name": "退仓管理",
|
||||||
|
"font_class": "RectangleCopy19",
|
||||||
|
"unicode": "e6c8",
|
||||||
|
"unicode_decimal": 59080
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7552702",
|
||||||
|
"name": "合同",
|
||||||
|
"font_class": "RectangleCopy20",
|
||||||
|
"unicode": "e6d1",
|
||||||
|
"unicode_decimal": 59089
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553176",
|
||||||
|
"name": "商品计划",
|
||||||
|
"font_class": "RectangleCopy21",
|
||||||
|
"unicode": "e6d8",
|
||||||
|
"unicode_decimal": 59096
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553184",
|
||||||
|
"name": "销量计划",
|
||||||
|
"font_class": "RectangleCopy22",
|
||||||
|
"unicode": "e6da",
|
||||||
|
"unicode_decimal": 59098
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553638",
|
||||||
|
"name": "销量实时看板",
|
||||||
|
"font_class": "RectangleCopy23",
|
||||||
|
"unicode": "e6e0",
|
||||||
|
"unicode_decimal": 59104
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553639",
|
||||||
|
"name": "结算效率分析",
|
||||||
|
"font_class": "RectangleCopy24",
|
||||||
|
"unicode": "e6df",
|
||||||
|
"unicode_decimal": 59103
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553644",
|
||||||
|
"name": "营销流量配置",
|
||||||
|
"font_class": "RectangleCopy25",
|
||||||
|
"unicode": "e6e2",
|
||||||
|
"unicode_decimal": 59106
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553645",
|
||||||
|
"name": "运营工具",
|
||||||
|
"font_class": "RectangleCopy26",
|
||||||
|
"unicode": "e6e3",
|
||||||
|
"unicode_decimal": 59107
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553649",
|
||||||
|
"name": "目标管理",
|
||||||
|
"font_class": "RectangleCopy27",
|
||||||
|
"unicode": "e6e4",
|
||||||
|
"unicode_decimal": 59108
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553650",
|
||||||
|
"name": "目标制定",
|
||||||
|
"font_class": "RectangleCopy28",
|
||||||
|
"unicode": "e6e5",
|
||||||
|
"unicode_decimal": 59109
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553651",
|
||||||
|
"name": "活动协同",
|
||||||
|
"font_class": "RectangleCopy29",
|
||||||
|
"unicode": "e6e6",
|
||||||
|
"unicode_decimal": 59110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553656",
|
||||||
|
"name": "目标监控",
|
||||||
|
"font_class": "RectangleCopy30",
|
||||||
|
"unicode": "e6e7",
|
||||||
|
"unicode_decimal": 59111
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553662",
|
||||||
|
"name": "增值服务",
|
||||||
|
"font_class": "RectangleCopy31",
|
||||||
|
"unicode": "e6e8",
|
||||||
|
"unicode_decimal": 59112
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553667",
|
||||||
|
"name": "全链路可售",
|
||||||
|
"font_class": "RectangleCopy32",
|
||||||
|
"unicode": "e6e9",
|
||||||
|
"unicode_decimal": 59113
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553669",
|
||||||
|
"name": "超级服务",
|
||||||
|
"font_class": "RectangleCopy33",
|
||||||
|
"unicode": "e6ea",
|
||||||
|
"unicode_decimal": 59114
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7553918",
|
||||||
|
"name": "上门取货",
|
||||||
|
"font_class": "RectangleCopy34",
|
||||||
|
"unicode": "e6eb",
|
||||||
|
"unicode_decimal": 59115
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7562286",
|
||||||
|
"name": "定位",
|
||||||
|
"font_class": "dingwei",
|
||||||
|
"unicode": "e6ec",
|
||||||
|
"unicode_decimal": 59116
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7733536",
|
||||||
|
"name": "预约",
|
||||||
|
"font_class": "RectangleCopy35",
|
||||||
|
"unicode": "e6ed",
|
||||||
|
"unicode_decimal": 59117
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7733537",
|
||||||
|
"name": "物流",
|
||||||
|
"font_class": "RectangleCopy36",
|
||||||
|
"unicode": "e6ee",
|
||||||
|
"unicode_decimal": 59118
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg :class="svgClass" aria-hidden="true">
|
||||||
|
<use :xlink:href="iconClassName" :fill="white ? '#fff' : color" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
const props = defineProps({
|
||||||
|
iconName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#333'
|
||||||
|
},
|
||||||
|
white: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 图标在 iconfont 中的名字
|
||||||
|
const iconClassName = computed(()=>{
|
||||||
|
return `#icon-${props.iconName}`;
|
||||||
|
})
|
||||||
|
// 给图标添加上类名
|
||||||
|
const svgClass = computed(() => {
|
||||||
|
if (props.className) {
|
||||||
|
return `svg-icon ${props.className}`;
|
||||||
|
}
|
||||||
|
return 'svg-icon';
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.svg-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
position: relative;
|
||||||
|
fill: currentColor;
|
||||||
|
vertical-align: -2px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -4,22 +4,11 @@
|
||||||
<div class="flex-1 min-h-0">
|
<div class="flex-1 min-h-0">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<div class="material-left__content pt-4 p-b-4">
|
<div class="material-left__content pt-4 p-b-4">
|
||||||
<el-tree
|
<el-tree ref="treeRef" node-key="id" :data="cateLists" empty-text="''" :highlight-current="true"
|
||||||
ref="treeRef"
|
:expand-on-click-node="false" :current-node-key="cateId" @node-click="handleCatSelect">
|
||||||
node-key="id"
|
|
||||||
:data="cateLists"
|
|
||||||
empty-text="''"
|
|
||||||
:highlight-current="true"
|
|
||||||
:expand-on-click-node="false"
|
|
||||||
:current-node-key="cateId"
|
|
||||||
@node-click="handleCatSelect"
|
|
||||||
>
|
|
||||||
<template v-slot="{ data }">
|
<template v-slot="{ data }">
|
||||||
<div class="flex flex-1 items-center min-w-0 pr-4">
|
<div class="flex flex-1 items-center min-w-0 pr-4">
|
||||||
<img
|
<img class="w-[20px] h-[16px] mr-3" src="@/assets/images/icon_folder.png" />
|
||||||
class="w-[20px] h-[16px] mr-3"
|
|
||||||
src="@/assets/images/icon_folder.png"
|
|
||||||
/>
|
|
||||||
<span class="flex-1 truncate mr-2">
|
<span class="flex-1 truncate mr-2">
|
||||||
<overflow-tooltip :content="data.name" />
|
<overflow-tooltip :content="data.name" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -27,29 +16,16 @@
|
||||||
<span class="muted m-r-10">···</span>
|
<span class="muted m-r-10">···</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<popover-input
|
<popover-input @confirm="handleEditCate($event, data.id)" size="default"
|
||||||
@confirm="handleEditCate($event, data.id)"
|
:value="data.name" width="400px" :limit="20" show-limit teleported>
|
||||||
size="default"
|
|
||||||
:value="data.name"
|
|
||||||
width="400px"
|
|
||||||
:limit="20"
|
|
||||||
show-limit
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
命名分组
|
命名分组
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</div>
|
</div>
|
||||||
</popover-input>
|
</popover-input>
|
||||||
<popover-input
|
<popover-input @confirm="handleAddChildCate($event, data.id)" size="default"
|
||||||
@confirm="handleAddChildCate($event, data.id)"
|
width="400px" :limit="20" show-limit teleported>
|
||||||
size="default"
|
|
||||||
width="400px"
|
|
||||||
:limit="20"
|
|
||||||
show-limit
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
添加分组
|
添加分组
|
||||||
|
@ -70,14 +46,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-center p-2 border-t border-br">
|
<div class="flex justify-center p-2 border-t border-br">
|
||||||
<popover-input
|
<popover-input @confirm="handleAddCate" size="default" width="400px" :limit="20" show-limit teleported>
|
||||||
@confirm="handleAddCate"
|
|
||||||
size="default"
|
|
||||||
width="400px"
|
|
||||||
:limit="20"
|
|
||||||
show-limit
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<el-button> 添加分组 </el-button>
|
<el-button> 添加分组 </el-button>
|
||||||
</popover-input>
|
</popover-input>
|
||||||
</div>
|
</div>
|
||||||
|
@ -85,51 +54,24 @@
|
||||||
<div class="material__center flex flex-col">
|
<div class="material__center flex flex-col">
|
||||||
<div class="operate-btn flex">
|
<div class="operate-btn flex">
|
||||||
<div class="flex-1 flex">
|
<div class="flex-1 flex">
|
||||||
<upload
|
<upload v-if="type == 'image'" class="mr-3" :data="{ cid: cateId }" :type="type" :show-progress="true"
|
||||||
v-if="type == 'image'"
|
@change="refresh">
|
||||||
class="mr-3"
|
|
||||||
:data="{ cid: cateId }"
|
|
||||||
:type="type"
|
|
||||||
:show-progress="true"
|
|
||||||
@change="refresh"
|
|
||||||
>
|
|
||||||
<el-button type="primary">本地上传</el-button>
|
<el-button type="primary">本地上传</el-button>
|
||||||
</upload>
|
</upload>
|
||||||
<upload
|
<upload v-if="type == 'video'" class="mr-3" :data="{ cid: cateId }" :type="type" :show-progress="true"
|
||||||
v-if="type == 'video'"
|
@allSuccess="refresh">
|
||||||
class="mr-3"
|
|
||||||
:data="{ cid: cateId }"
|
|
||||||
:type="type"
|
|
||||||
:show-progress="true"
|
|
||||||
@allSuccess="refresh"
|
|
||||||
>
|
|
||||||
<el-button type="primary">本地上传</el-button>
|
<el-button type="primary">本地上传</el-button>
|
||||||
</upload>
|
</upload>
|
||||||
<upload
|
<upload v-if="type == 'file'" class="mr-3" :data="{ cid: cateId }" :type="type" :show-progress="true"
|
||||||
v-if="type == 'file'"
|
@allSuccess="refresh">
|
||||||
class="mr-3"
|
|
||||||
:data="{ cid: cateId }"
|
|
||||||
:type="type"
|
|
||||||
:show-progress="true"
|
|
||||||
@allSuccess="refresh"
|
|
||||||
>
|
|
||||||
<el-button type="primary">本地上传</el-button>
|
<el-button type="primary">本地上传</el-button>
|
||||||
</upload>
|
</upload>
|
||||||
<el-button
|
<el-button v-if="mode == 'page'" :disabled="!select.length" @click.stop="batchFileDelete()">
|
||||||
v-if="mode == 'page'"
|
|
||||||
:disabled="!select.length"
|
|
||||||
@click.stop="batchFileDelete()"
|
|
||||||
>
|
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<popup
|
<popup v-if="mode == 'page'" class="ml-3" @confirm="batchFileMove" :disabled="!select.length"
|
||||||
v-if="mode == 'page'"
|
title="移动文件">
|
||||||
class="ml-3"
|
|
||||||
@confirm="batchFileMove"
|
|
||||||
:disabled="!select.length"
|
|
||||||
title="移动文件"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<el-button :disabled="!select.length">移动</el-button>
|
<el-button :disabled="!select.length">移动</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -138,36 +80,17 @@
|
||||||
<span class="mr-5">移动文件至</span>
|
<span class="mr-5">移动文件至</span>
|
||||||
<el-select v-model="moveId" placeholder="请选择">
|
<el-select v-model="moveId" placeholder="请选择">
|
||||||
<template v-for="item in cateLists" :key="item.id">
|
<template v-for="item in cateLists" :key="item.id">
|
||||||
<el-option
|
<el-option v-if="item.id !== ''" :label="item.name" :value="item.id"></el-option>
|
||||||
v-if="item.id !== ''"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
></el-option>
|
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</popup>
|
</popup>
|
||||||
</div>
|
</div>
|
||||||
<el-select
|
<el-select v-model="fileParams.source" placeholder="请选择文件来源" clearable style="margin-right: 20px"
|
||||||
v-model="fileParams.source"
|
class="w-50">
|
||||||
placeholder="请选择文件来源"
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
clearable
|
|
||||||
style="margin-right: 20px"
|
|
||||||
class="w-50"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in options"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input
|
<el-input class="w-60" placeholder="请输入名称" v-model="fileParams.name" @keyup.enter="refresh">
|
||||||
class="w-60"
|
|
||||||
placeholder="请输入名称"
|
|
||||||
v-model="fileParams.name"
|
|
||||||
@keyup.enter="refresh"
|
|
||||||
>
|
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button @click="refresh">
|
<el-button @click="refresh">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
|
@ -179,55 +102,33 @@
|
||||||
|
|
||||||
<div class="flex items-center ml-2">
|
<div class="flex items-center ml-2">
|
||||||
<el-tooltip content="列表视图" placement="top">
|
<el-tooltip content="列表视图" placement="top">
|
||||||
<div
|
<div class="list-icon" :class="{
|
||||||
class="list-icon"
|
select: listShowType == 'table'
|
||||||
:class="{
|
}" @click="listShowType = 'table'">
|
||||||
select: listShowType == 'table'
|
|
||||||
}"
|
|
||||||
@click="listShowType = 'table'"
|
|
||||||
>
|
|
||||||
<icon name="local-icon-list-2" :size="18" />
|
<icon name="local-icon-list-2" :size="18" />
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip content="平铺视图" placement="top">
|
<el-tooltip content="平铺视图" placement="top">
|
||||||
<div
|
<div class="list-icon" :class="{
|
||||||
class="list-icon"
|
select: listShowType == 'normal'
|
||||||
:class="{
|
}" @click="listShowType = 'normal'">
|
||||||
select: listShowType == 'normal'
|
|
||||||
}"
|
|
||||||
@click="listShowType = 'normal'"
|
|
||||||
>
|
|
||||||
<icon name="el-icon-Menu" :size="18" />
|
<icon name="el-icon-Menu" :size="18" />
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3" v-if="mode == 'page'">
|
<div class="mt-3" v-if="mode == 'page'">
|
||||||
<el-checkbox
|
<el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
|
||||||
:disabled="!pager.lists.length"
|
:indeterminate="isIndeterminate">
|
||||||
v-model="isCheckAll"
|
|
||||||
@change="selectAll"
|
|
||||||
:indeterminate="isIndeterminate"
|
|
||||||
>
|
|
||||||
当页全选
|
当页全选
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="material-center__content flex flex-col flex-1 mb-1 min-h-0">
|
<div class="material-center__content flex flex-col flex-1 mb-1 min-h-0">
|
||||||
<el-scrollbar v-if="pager.lists.length" v-show="listShowType == 'normal'">
|
<el-scrollbar v-if="pager.lists.length" v-show="listShowType == 'normal'">
|
||||||
<ul class="file-list flex flex-wrap mt-4">
|
<ul class="file-list flex flex-wrap mt-4">
|
||||||
<li
|
<li class="file-item-wrap" v-for="item in pager.lists" :key="item.id" :style="{ width: fileSize }">
|
||||||
class="file-item-wrap"
|
|
||||||
v-for="item in pager.lists"
|
|
||||||
:key="item.id"
|
|
||||||
:style="{ width: fileSize }"
|
|
||||||
>
|
|
||||||
<del-wrap @close="batchFileDelete([item.id])">
|
<del-wrap @close="batchFileDelete([item.id])">
|
||||||
<file-item
|
<file-item :uri="item.url" :file-size="fileSize" :type="type" @click="selectFile(item)">
|
||||||
:uri="item.url"
|
|
||||||
:file-size="fileSize"
|
|
||||||
:type="type"
|
|
||||||
@click="selectFile(item)"
|
|
||||||
>
|
|
||||||
<div class="item-selected" v-if="isSelect(item.id)">
|
<div class="item-selected" v-if="isSelect(item.id)">
|
||||||
<icon :size="24" name="el-icon-Check" color="#fff" />
|
<icon :size="24" name="el-icon-Check" color="#fff" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -236,58 +137,27 @@
|
||||||
|
|
||||||
<overflow-tooltip class="mt-1" :content="item.name" />
|
<overflow-tooltip class="mt-1" :content="item.name" />
|
||||||
<div class="operation-btns flex items-center">
|
<div class="operation-btns flex items-center">
|
||||||
<popover-input
|
<popover-input @confirm="handleFileRename($event, item.id)" size="default"
|
||||||
@confirm="handleFileRename($event, item.id)"
|
:value="item.name" width="400px" :limit="50" show-limit teleported>
|
||||||
size="default"
|
|
||||||
:value="item.name"
|
|
||||||
width="400px"
|
|
||||||
:limit="50"
|
|
||||||
show-limit
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<el-button type="primary" link> 重命名 </el-button>
|
<el-button type="primary" link> 重命名 </el-button>
|
||||||
</popover-input>
|
</popover-input>
|
||||||
|
|
||||||
<el-button
|
<el-button v-if="item.type === 10 || item.type === 20" type="primary" link
|
||||||
v-if="item.type === 10 || item.type === 20"
|
@click="handlePreview(item.url)">
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
@click="handlePreview(item.url)"
|
|
||||||
>
|
|
||||||
查看
|
查看
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button
|
<el-button v-if="item.type === 10 || item.type === 20" type="primary" link
|
||||||
v-if="item.type === 10 || item.type === 20"
|
@click="textCopy(item.url)" style="margin-left: 1px">地址</el-button>
|
||||||
type="primary"
|
<el-link v-else type="primary" :underline="false" style="margin-left: 25px"
|
||||||
link
|
:href="item.url">下载</el-link>
|
||||||
@click="textCopy(item.url)"
|
|
||||||
style="margin-left: 1px"
|
|
||||||
>地址</el-button
|
|
||||||
>
|
|
||||||
<el-link
|
|
||||||
v-else
|
|
||||||
type="primary"
|
|
||||||
:underline="false"
|
|
||||||
style="margin-left: 25px"
|
|
||||||
:href="item.url"
|
|
||||||
>下载</el-link
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
|
||||||
<el-table
|
<el-table ref="tableRef" class="mt-4" v-show="listShowType == 'table'" :data="pager.lists" width="100%"
|
||||||
ref="tableRef"
|
height="100%" size="large" @row-click="selectFile">
|
||||||
class="mt-4"
|
|
||||||
v-show="listShowType == 'table'"
|
|
||||||
:data="pager.lists"
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
size="large"
|
|
||||||
@row-click="selectFile"
|
|
||||||
>
|
|
||||||
<el-table-column width="55">
|
<el-table-column width="55">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox :modelValue="isSelect(row.id)" @change="selectFile(row)" />
|
<el-checkbox :modelValue="isSelect(row.id)" @change="selectFile(row)" />
|
||||||
|
@ -309,29 +179,18 @@
|
||||||
<el-table-column label="操作" width="150" fixed="right">
|
<el-table-column label="操作" width="150" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="inline-block">
|
<div class="inline-block">
|
||||||
<popover-input
|
<popover-input @confirm="handleFileRename($event, row.id)" size="default" :value="row.name"
|
||||||
@confirm="handleFileRename($event, row.id)"
|
width="400px" :limit="50" show-limit teleported>
|
||||||
size="default"
|
|
||||||
:value="row.name"
|
|
||||||
width="400px"
|
|
||||||
:limit="50"
|
|
||||||
show-limit
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<el-button type="primary" link> 重命名 </el-button>
|
<el-button type="primary" link> 重命名 </el-button>
|
||||||
</popover-input>
|
</popover-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-block">
|
<div class="inline-block">
|
||||||
<el-button type="primary" link @click.stop="handlePreview(row.url)">
|
<el-button type="primary" link @click.stop="handlePreview(row.url)">
|
||||||
查看
|
查12看
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-block">
|
<div class="inline-block">
|
||||||
<el-button
|
<el-button type="primary" link @click.stop="batchFileDelete([row.id])">
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
@click.stop="batchFileDelete([row.id])"
|
|
||||||
>
|
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -339,10 +198,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div
|
<div class="flex flex-1 justify-center items-center" v-if="!pager.loading && !pager.lists.length">
|
||||||
class="flex flex-1 justify-center items-center"
|
|
||||||
v-if="!pager.loading && !pager.lists.length"
|
|
||||||
>
|
|
||||||
暂无数据~
|
暂无数据~
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -350,24 +206,15 @@
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<template v-if="mode == 'page'">
|
<template v-if="mode == 'page'">
|
||||||
<span class="mr-3">
|
<span class="mr-3">
|
||||||
<el-checkbox
|
<el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
|
||||||
:disabled="!pager.lists.length"
|
:indeterminate="isIndeterminate">
|
||||||
v-model="isCheckAll"
|
|
||||||
@change="selectAll"
|
|
||||||
:indeterminate="isIndeterminate"
|
|
||||||
>
|
|
||||||
当页全选
|
当页全选
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</span>
|
</span>
|
||||||
<el-button :disabled="!select.length" @click="batchFileDelete()">
|
<el-button :disabled="!select.length" @click="batchFileDelete()">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
<popup
|
<popup class="ml-3 inline" @confirm="batchFileMove" :disabled="!select.length" title="移动文件">
|
||||||
class="ml-3 inline"
|
|
||||||
@confirm="batchFileMove"
|
|
||||||
:disabled="!select.length"
|
|
||||||
title="移动文件"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<el-button :disabled="!select.length">移动</el-button>
|
<el-button :disabled="!select.length">移动</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -376,22 +223,14 @@
|
||||||
<span class="mr-5">移动文件至</span>
|
<span class="mr-5">移动文件至</span>
|
||||||
<el-select v-model="moveId" placeholder="请选择">
|
<el-select v-model="moveId" placeholder="请选择">
|
||||||
<template v-for="item in cateLists" :key="item.id">
|
<template v-for="item in cateLists" :key="item.id">
|
||||||
<el-option
|
<el-option v-if="item.id !== ''" :label="item.name" :value="item.id"></el-option>
|
||||||
v-if="item.id !== ''"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
></el-option>
|
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</popup>
|
</popup>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<pagination
|
<pagination v-model="pager" @change="getFileList" layout="total, prev, pager, next, jumper" />
|
||||||
v-model="pager"
|
|
||||||
@change="getFileList"
|
|
||||||
layout="total, prev, pager, next, jumper"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="material__right" v-if="mode == 'picker'">
|
<div class="material__right" v-if="mode == 'picker'">
|
||||||
|
@ -408,11 +247,7 @@
|
||||||
<li class="mb-4" v-for="item in select" :key="item.id">
|
<li class="mb-4" v-for="item in select" :key="item.id">
|
||||||
<div class="select-item">
|
<div class="select-item">
|
||||||
<del-wrap @close="cancelSelete(item.id)">
|
<del-wrap @close="cancelSelete(item.id)">
|
||||||
<file-item
|
<file-item :uri="item.url" file-size="100px" :type="type"></file-item>
|
||||||
:uri="item.url"
|
|
||||||
file-size="100px"
|
|
||||||
:type="type"
|
|
||||||
></file-item>
|
|
||||||
</del-wrap>
|
</del-wrap>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -586,10 +421,13 @@ const textCopy = (uri: string) => {
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.material {
|
.material {
|
||||||
@apply h-full min-h-0 flex flex-1;
|
@apply h-full min-h-0 flex flex-1;
|
||||||
|
|
||||||
&__left {
|
&__left {
|
||||||
@apply border-r border-br flex flex-col w-[200px];
|
@apply border-r border-br flex flex-col w-[200px];
|
||||||
|
|
||||||
:deep(.el-tree-node__content) {
|
:deep(.el-tree-node__content) {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
|
|
||||||
.el-tree-node__label {
|
.el-tree-node__label {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -597,25 +435,30 @@ const textCopy = (uri: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__center {
|
&__center {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
|
|
||||||
.list-icon {
|
.list-icon {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&.select {
|
&.select {
|
||||||
@apply text-primary bg-primary-light-8;
|
@apply text-primary bg-primary-light-8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-list {
|
.file-list {
|
||||||
.file-item-wrap {
|
.file-item-wrap {
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.item-selected {
|
.item-selected {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -629,19 +472,23 @@ const textCopy = (uri: string) => {
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.operation-btns {
|
.operation-btns {
|
||||||
height: 28px;
|
height: 28px;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover .operation-btns {
|
&:hover .operation-btns {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__right {
|
&__right {
|
||||||
@apply border-l border-br flex flex-col;
|
@apply border-l border-br flex flex-col;
|
||||||
width: 130px;
|
width: 130px;
|
||||||
|
|
||||||
.select-lists {
|
.select-lists {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import install from './install'
|
||||||
import './permission'
|
import './permission'
|
||||||
import './styles/index.scss'
|
import './styles/index.scss'
|
||||||
import 'virtual:svg-icons-register'
|
import 'virtual:svg-icons-register'
|
||||||
|
import "./assets/iconfont/iconfont.js";
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(install)
|
app.use(install)
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
<template>
|
||||||
|
<el-table :data="pager.lists">
|
||||||
|
<el-table-column label="订单号" prop="order_id" show-overflow-tooltip />
|
||||||
|
<el-table-column label="用户信息" prop="build_area_text" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<el-image style="width: 50px; height: 50px" :src="row.avatar" class="mr-2" />
|
||||||
|
{{ row.nickname }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品信息" prop="project_level_text" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-for="(item, index) in row.product" :key="index" class="flex items-center">
|
||||||
|
<!-- <el-image style="width: 50px; height: 50px" :src="item.cart_info.image" class="mr-2" /> -->
|
||||||
|
<div>
|
||||||
|
<p>{{ item.cart_info.name }}</p>
|
||||||
|
<p>¥{{ item.cart_info.price }} x {{ item.cart_info.cart_num }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="实际支付" prop="pay_price" show-overflow-tooltip />
|
||||||
|
<el-table-column label="支付方式" prop="pay_type_name" show-overflow-tooltip />
|
||||||
|
<el-table-column label="收银店员" prop="staff" show-overflow-tooltip />
|
||||||
|
<el-table-column label="下单时间" prop="pay_time" show-overflow-tooltip />
|
||||||
|
<el-table-column label="订单状态" prop="status_name" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
<div class="flex mt-4 justify-end">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="manageProjectLists">
|
||||||
|
import { ref, reactive, defineProps } from "vue"
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import { apiStoreOrderLists, } from '@/api/store_order'
|
||||||
|
|
||||||
|
let props = defineProps({
|
||||||
|
staff_id: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
shipping_type: {
|
||||||
|
type: Number,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: apiStoreOrderLists,
|
||||||
|
params: {
|
||||||
|
staff_id: props.staff_id,
|
||||||
|
shipping_type: props.shipping_type
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
getLists()
|
||||||
|
</script>
|
|
@ -0,0 +1,55 @@
|
||||||
|
<template>
|
||||||
|
<popup ref="popupRef" title="店员详情" :async="true" width="50vw" @close="close" :show-footer="false">
|
||||||
|
<div class="flex">
|
||||||
|
<el-avatar shape="circle" :size="70" :src="formData.avatar" />
|
||||||
|
<el-row class="w-[100%] ml-4">
|
||||||
|
<el-col :span="24">{{ formData.staff_name }}</el-col>
|
||||||
|
<el-col :span="7">收银订单:¥{{ formData.cashier_order }}</el-col>
|
||||||
|
<el-col :span="7">核销订单:¥{{ formData.verify_order }}</el-col>
|
||||||
|
<el-col :span="7">配送订单:¥{{ formData.delivery_order }}</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<el-tabs tab-position="left" v-model="activeName" style="height: 200px" class="demo-tabs mt-8">
|
||||||
|
<el-tab-pane label="收银订单" name="3">
|
||||||
|
<myTable v-if="activeName == '3'" :shipping_type="3" :staff_id="formData.id"></myTable>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="配送订单" name="1">
|
||||||
|
<myTable v-if="activeName == '1'" :shipping_type="1" :staff_id="formData.id"></myTable>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="核销订单" name="2">
|
||||||
|
<myTable v-if="activeName == '2'" :shipping_type="2" :staff_id="formData.id"></myTable>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</popup>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import myTable from './components/myTable.vue';
|
||||||
|
|
||||||
|
|
||||||
|
const popupRef = ref(null)
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
|
||||||
|
const open = () => {
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
const close = () => {
|
||||||
|
emit('close')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = ref({})
|
||||||
|
const activeName = ref('3')
|
||||||
|
|
||||||
|
|
||||||
|
const setForm = (data) => {
|
||||||
|
formData.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setForm
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -1,260 +1,129 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="edit-popup">
|
<div class="edit-popup">
|
||||||
<popup
|
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
|
||||||
ref="popupRef"
|
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
||||||
:title="popupTitle"
|
<el-form-item label="店员名称" prop="staff_name">
|
||||||
:async="true"
|
<el-input v-model="formData.staff_name" clearable placeholder="请输入店员名称" />
|
||||||
width="550px"
|
|
||||||
@confirm="handleSubmit"
|
|
||||||
@close="handleClose"
|
|
||||||
>
|
|
||||||
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
|
||||||
<!-- 账号输入框 -->
|
|
||||||
<el-form-item label="账号" prop="account">
|
|
||||||
<el-input
|
|
||||||
v-model="formData.account"
|
|
||||||
:disabled="formData.root == 1"
|
|
||||||
placeholder="请输入账号"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 管理员头像 -->
|
|
||||||
<el-form-item label="头像">
|
<el-form-item label="头像">
|
||||||
<div>
|
<material-picker v-model="formData.avatar" :limit="1" />
|
||||||
<div>
|
|
||||||
<material-picker v-model="formData.avatar" :limit="1" />
|
|
||||||
</div>
|
|
||||||
<div class="form-tips">建议尺寸:100*100px,支持jpg,jpeg,png格式</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="店员账号" prop="account">
|
||||||
<!-- 名称输入框 -->
|
<el-input v-model="formData.account" clearable placeholder="请输入店员账号" />
|
||||||
<el-form-item label="名称" prop="name">
|
|
||||||
<el-input v-model="formData.name" placeholder="请输入名称" clearable />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="归属部门" prop="dept_id">
|
<el-form-item label="店员密码" prop="pwd">
|
||||||
<el-tree-select
|
<el-input v-model="formData.pwd" clearable placeholder="请输入店员账号" type="password" />
|
||||||
class="flex-1"
|
|
||||||
v-model="formData.dept_id"
|
|
||||||
:data="optionsData.dept"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
node-key="id"
|
|
||||||
:props="{
|
|
||||||
value: 'id',
|
|
||||||
label: 'name',
|
|
||||||
disabled(data: any) {
|
|
||||||
return data.status !== 1
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
check-strictly
|
|
||||||
:default-expand-all="true"
|
|
||||||
placeholder="请选择上级部门"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="岗位" prop="jobs_id">
|
<el-form-item label="确认密码" prop="rePwd">
|
||||||
<el-select
|
<el-input v-model="formData.rePwd" clearable placeholder="请确认账号密码" type="password" />
|
||||||
class="flex-1"
|
|
||||||
v-model="formData.jobs_id"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
placeholder="请选择岗位"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item, index) in optionsData.jobs"
|
|
||||||
:key="index"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="核销开关" prop="rePwd">
|
||||||
<!-- 角色选择框 -->
|
<el-switch v-model="formData.verify_status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
<el-form-item label="角色" prop="role_id">
|
|
||||||
<el-select
|
|
||||||
v-model="formData.role_id"
|
|
||||||
:disabled="formData.root == 1"
|
|
||||||
class="flex-1"
|
|
||||||
multiple
|
|
||||||
placeholder="请选择角色"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item, index) in optionsData.role"
|
|
||||||
:key="index"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="订单状态" prop="rePwd">
|
||||||
<!-- 密码输入框 -->
|
<el-switch v-model="formData.order_status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
<el-form-item label="密码" prop="password">
|
|
||||||
<el-input
|
|
||||||
v-model="formData.password"
|
|
||||||
show-password
|
|
||||||
clearable
|
|
||||||
placeholder="请输入密码"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="是否是店长" prop="rePwd">
|
||||||
<!-- 确认密码输入框 -->
|
<el-switch v-model="formData.is_manager" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
<el-form-item label="确认密码" prop="password_confirm">
|
|
||||||
<el-input
|
|
||||||
v-model="formData.password_confirm"
|
|
||||||
show-password
|
|
||||||
clearable
|
|
||||||
placeholder="请输入确认密码"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号码" prop="phone">
|
||||||
<!-- 管理员状态 -->
|
<el-input v-model="formData.phone" clearable placeholder="请输入手机号码" />
|
||||||
<el-form-item label="管理员状态" v-if="formData.root != 1">
|
|
||||||
<el-switch v-model="formData.disable" :active-value="0" :inactive-value="1" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<!-- 多处登录 -->
|
|
||||||
<el-form-item label="多处登录">
|
|
||||||
<div>
|
|
||||||
<el-switch
|
|
||||||
v-model="formData.multipoint_login"
|
|
||||||
:active-value="1"
|
|
||||||
:inactive-value="0"
|
|
||||||
/>
|
|
||||||
<div class="form-tips">允许多人同时在线登录</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</popup>
|
</popup>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
|
||||||
|
<script lang="ts" setup name="oaPlanEdit">
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import Popup from '@/components/popup/index.vue'
|
import Popup from '@/components/popup/index.vue'
|
||||||
import { useDictOptions } from '@/hooks/useDictOptions'
|
import type { PropType } from 'vue'
|
||||||
import { adminAdd, adminDetail, adminEdit } from '@/api/perms/admin'
|
import { apiStaffAdd, apiStaffEdit } from '@/api/goodsList.ts'
|
||||||
import { roleAll } from '@/api/perms/role'
|
|
||||||
import { jobsAll } from '@/api/org/post'
|
defineProps({
|
||||||
import { deptAll } from '@/api/org/department'
|
dictData: {
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
const emit = defineEmits(['success', 'close'])
|
const emit = defineEmits(['success', 'close'])
|
||||||
const formRef = shallowRef<FormInstance>()
|
const formRef = shallowRef<FormInstance>()
|
||||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
const mode = ref('add')
|
const mode = ref('add')
|
||||||
|
|
||||||
|
|
||||||
|
// 弹窗标题
|
||||||
const popupTitle = computed(() => {
|
const popupTitle = computed(() => {
|
||||||
return mode.value == 'edit' ? '编辑管理员' : '新增管理员'
|
return mode.value == 'edit' ? '编辑日程安排' : '新增日程安排'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
id: '',
|
id: '',
|
||||||
|
staff_name: '',
|
||||||
|
avatar: 'https://lihaiim.oss-cn-chengdu.aliyuncs.com/public/uploads/images/20240606/20240606162227e3e005096.jpg',
|
||||||
account: '',
|
account: '',
|
||||||
name: '',
|
pwd: '',
|
||||||
dept_id: [],
|
rePwd: '',
|
||||||
jobs_id: [],
|
verify_status: 0,
|
||||||
role_id: [],
|
order_status: 0,
|
||||||
avatar: '',
|
is_manager: 0,
|
||||||
password: '',
|
phone: '',
|
||||||
password_confirm: '',
|
|
||||||
disable: 0,
|
|
||||||
multipoint_login: 1,
|
|
||||||
root: 0
|
|
||||||
})
|
})
|
||||||
const passwordConfirmValidator = (rule: object, value: string, callback: any) => {
|
|
||||||
if (formData.password) {
|
|
||||||
if (!value) callback(new Error('请再次输入密码'))
|
|
||||||
if (value !== formData.password) callback(new Error('两次输入密码不一致!'))
|
|
||||||
}
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleIdValidator = (rule: object, value: string, callback: any) => {
|
const chekcDate = (rule: any, value: any, callback: any) => {
|
||||||
if (formData.root) {
|
if ((formData.rePwd) != (formData.pwd)) {
|
||||||
callback()
|
callback(new Error('两次密码不一致'))
|
||||||
} else {
|
} else {
|
||||||
if (formData.role_id.length) {
|
callback()
|
||||||
callback()
|
|
||||||
} else {
|
|
||||||
callback(new Error('请选择角色'))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const formRules = reactive({
|
|
||||||
account: [
|
// 表单验证
|
||||||
{
|
const formRules = reactive<any>({
|
||||||
required: true,
|
staff_name: [{
|
||||||
message: '请输入账号',
|
required: true,
|
||||||
trigger: ['blur']
|
message: '不能为空',
|
||||||
}
|
trigger: ['blur']
|
||||||
],
|
}],
|
||||||
name: [
|
avatar: [{
|
||||||
{
|
required: true,
|
||||||
required: true,
|
message: '不能为空',
|
||||||
message: '请输入名称',
|
trigger: ['blur']
|
||||||
trigger: ['blur']
|
}],
|
||||||
}
|
account: [{
|
||||||
],
|
required: true,
|
||||||
role_id: [
|
message: '不能为空',
|
||||||
{
|
trigger: ['blur']
|
||||||
required: true,
|
}],
|
||||||
validator: roleIdValidator
|
pwd: [{
|
||||||
}
|
required: true,
|
||||||
],
|
message: '不能为空',
|
||||||
password: [
|
trigger: ['blur']
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入密码',
|
|
||||||
trigger: ['blur']
|
|
||||||
}
|
|
||||||
] as any[],
|
|
||||||
password_confirm: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入确认密码',
|
|
||||||
trigger: ['blur']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
validator: passwordConfirmValidator,
|
|
||||||
trigger: 'blur'
|
|
||||||
}
|
|
||||||
] as any[]
|
|
||||||
})
|
|
||||||
const { optionsData } = useDictOptions<{
|
|
||||||
role: any[]
|
|
||||||
jobs: any[]
|
|
||||||
dept: any[]
|
|
||||||
}>({
|
|
||||||
role: {
|
|
||||||
api: roleAll
|
|
||||||
},
|
|
||||||
jobs: {
|
|
||||||
api: jobsAll
|
|
||||||
},
|
|
||||||
dept: {
|
|
||||||
api: deptAll
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
rePwd: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: chekcDate,
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
phone: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
await formRef.value?.validate()
|
|
||||||
mode.value == 'edit' ? await adminEdit(formData) : await adminAdd(formData)
|
|
||||||
popupRef.value?.close()
|
|
||||||
emit('success')
|
|
||||||
}
|
|
||||||
|
|
||||||
const open = (type = 'add') => {
|
// 获取详情
|
||||||
mode.value = type
|
const setFormData = async (data: Record<any, any>) => {
|
||||||
popupRef.value?.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
const setFormData = async (row: any) => {
|
|
||||||
formRules.password = []
|
|
||||||
formRules.password_confirm = [
|
|
||||||
{
|
|
||||||
validator: passwordConfirmValidator,
|
|
||||||
trigger: 'blur'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
const data = await adminDetail({
|
|
||||||
id: row.id
|
|
||||||
})
|
|
||||||
for (const key in formData) {
|
for (const key in formData) {
|
||||||
if (data[key] != null && data[key] != undefined) {
|
if (data[key] != null && data[key] != undefined) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
|
@ -263,12 +132,34 @@ const setFormData = async (row: any) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
const data = { ...formData, }
|
||||||
|
mode.value == 'edit'
|
||||||
|
? await apiStaffEdit(data)
|
||||||
|
: await apiStaffAdd(data)
|
||||||
|
popupRef.value?.close()
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
//打开弹窗
|
||||||
|
const open = (type = 'add', start_time = '') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭回调
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open,
|
open,
|
||||||
setFormData
|
setFormData,
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,107 +1,60 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="admin">
|
<div>
|
||||||
<el-card class="!border-none" shadow="never">
|
<el-card class="!border-none mb-4" shadow="never">
|
||||||
<el-form class="mb-[-16px]" :model="formData" inline>
|
<el-form class="mb-[-16px]" :model="queryParams" label-width="80px">
|
||||||
<el-form-item label="管理员账号">
|
<el-row>
|
||||||
<el-input
|
<el-col :span="6">
|
||||||
v-model="formData.account"
|
<el-form-item label="店员搜索" prop="keyword">
|
||||||
class="w-[280px]"
|
<el-input v-model="queryParams.keyword" clearable placeholder="请输入店员名称/手机号" />
|
||||||
clearable
|
</el-form-item>
|
||||||
@keyup.enter="resetPage"
|
</el-col>
|
||||||
/>
|
<el-col :span="6">
|
||||||
</el-form-item>
|
<el-form-item>
|
||||||
<el-form-item label="管理员名称">
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
<el-input
|
<el-button @click="resetParams">重置</el-button>
|
||||||
v-model="formData.name"
|
</el-form-item>
|
||||||
class="w-[280px]"
|
</el-col>
|
||||||
clearable
|
</el-row>
|
||||||
@keyup.enter="resetPage"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="管理员角色">
|
|
||||||
<el-select class="w-[280px]" v-model="formData.role_id">
|
|
||||||
<el-option label="全部" value="" />
|
|
||||||
<el-option
|
|
||||||
v-for="(item, index) in optionsData.role"
|
|
||||||
:key="index"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
|
||||||
<el-button @click="resetParams">重置</el-button>
|
|
||||||
<export-data
|
|
||||||
class="ml-2.5"
|
|
||||||
:fetch-fun="adminLists"
|
|
||||||
:params="formData"
|
|
||||||
:page-size="pager.size"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card v-loading="pager.loading" class="mt-4 !border-none" shadow="never">
|
|
||||||
<el-button v-perms="['auth.admin/add']" type="primary" @click="handleAdd">
|
|
||||||
|
|
||||||
|
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
||||||
|
<el-button v-perms="['dept.dept/add']" type="primary" @click="handleAdd()">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon name="el-icon-Plus" />
|
<icon name="el-icon-Plus" />
|
||||||
</template>
|
</template>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<el-table :data="pager.lists" size="large">
|
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||||
<el-table-column label="ID" prop="id" min-width="60" />>
|
<el-table-column label="id" prop="id" show-overflow-tooltip />
|
||||||
<el-table-column label="头像" min-width="100">
|
<el-table-column label="头像" prop="avatar" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-avatar :size="50" :src="row.avatar"></el-avatar>
|
<el-image style="width: 50px; height: 50px" :src="row.avatar" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="账号" prop="account" min-width="100" />
|
<el-table-column label="昵称" prop="staff_name" show-overflow-tooltip />
|
||||||
<el-table-column label="名称" prop="name" min-width="100" />
|
<el-table-column label="店员身份" prop="project_level_text" show-overflow-tooltip>
|
||||||
<el-table-column
|
|
||||||
label="角色"
|
|
||||||
prop="role_name"
|
|
||||||
min-width="100"
|
|
||||||
show-tooltip-when-overflow
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
label="部门"
|
|
||||||
prop="dept_name"
|
|
||||||
min-width="100"
|
|
||||||
show-tooltip-when-overflow
|
|
||||||
/>
|
|
||||||
<el-table-column label="创建时间" prop="create_time" min-width="180" />
|
|
||||||
<el-table-column label="最近登录时间" prop="login_time" min-width="180" />
|
|
||||||
<el-table-column label="最近登录IP" prop="login_ip" min-width="120" />
|
|
||||||
<el-table-column label="状态" min-width="100" v-perms="['auth.admin/edit']">
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-switch
|
{{ row.is_manager == 1 ? '店长' : '员工' }}
|
||||||
v-if="row.root != 1"
|
|
||||||
v-model="row.disable"
|
|
||||||
:active-value="0"
|
|
||||||
:inactive-value="1"
|
|
||||||
@change="changeStatus(row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="120" fixed="right">
|
<el-table-column label="手机号" prop="phone" show-overflow-tooltip />
|
||||||
|
<el-table-column label="状态" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button
|
<el-switch v-model="row.status" :active-value="1" :inactive-value="0"
|
||||||
v-perms="['auth.admin/edit']"
|
@change="changeStatus(row)"></el-switch>
|
||||||
type="primary"
|
</template>
|
||||||
link
|
</el-table-column>
|
||||||
@click="handleEdit(row)"
|
<el-table-column label="操作" width="170" fixed="right">
|
||||||
>
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="handleEdit(row)">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="primary" link @click="handleDetail(row)">
|
||||||
v-if="row.root != 1"
|
详情
|
||||||
v-perms="['auth.admin/delete']"
|
|
||||||
type="danger"
|
|
||||||
link
|
|
||||||
@click="handleDelete(row.id)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@ -112,72 +65,78 @@
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||||
|
<DetailPopup v-if="showDetail" ref="detailRef" @close="showEdit = false" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="admin">
|
<script lang="ts" setup name="manageProjectLists">
|
||||||
import { adminEdit, adminLists, adminDelete } from '@/api/perms/admin'
|
import { ref, reactive } from "vue"
|
||||||
import { roleAll } from '@/api/perms/role'
|
|
||||||
import { useDictOptions } from '@/hooks/useDictOptions'
|
|
||||||
import { usePaging } from '@/hooks/usePaging'
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
import feedback from '@/utils/feedback'
|
|
||||||
import EditPopup from './edit.vue'
|
import EditPopup from './edit.vue'
|
||||||
|
import DetailPopup from './detail.vue'
|
||||||
|
import { apiStaffLists, apiStaffDetail, apiStaffStatus } from '@/api/goodsList.ts'
|
||||||
|
|
||||||
|
const detailRef = ref(null)
|
||||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||||
// 表单数据
|
// 是否显示编辑框
|
||||||
const formData = reactive({
|
|
||||||
account: '',
|
|
||||||
name: '',
|
|
||||||
role_id: ''
|
|
||||||
})
|
|
||||||
const showEdit = ref(false)
|
const showEdit = ref(false)
|
||||||
const { pager, getLists, resetParams, resetPage } = usePaging({
|
const showDetail = ref(false)
|
||||||
fetchFun: adminLists,
|
|
||||||
params: formData
|
|
||||||
|
// 查询条件
|
||||||
|
const queryParams = reactive({
|
||||||
|
keyword: ""
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 选中数据
|
||||||
|
const selectData = ref<any[]>([])
|
||||||
|
|
||||||
|
// 表格选择后回调事件
|
||||||
|
const handleSelectionChange = (val: any[]) => {
|
||||||
|
selectData.value = val.map(({ id }) => id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上架&下架
|
||||||
const changeStatus = (data: any) => {
|
const changeStatus = (data: any) => {
|
||||||
adminEdit({
|
|
||||||
id: data.id,
|
apiStaffStatus({
|
||||||
avatar: data.avatar,
|
id: data.id
|
||||||
account: data.account,
|
|
||||||
name: data.name,
|
|
||||||
role_id: data.role_id,
|
|
||||||
job_id: data.job_id,
|
|
||||||
dept_id: data.dept_id,
|
|
||||||
disable: data.disable,
|
|
||||||
multipoint_login: data.multipoint_login
|
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
getLists()
|
getLists()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: apiStaffLists,
|
||||||
|
params: queryParams
|
||||||
|
})
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const handleEdit = async (data: any) => {
|
||||||
|
let res = await apiStaffDetail({ id: data.id })
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('edit')
|
||||||
|
editRef.value?.setFormData(res)
|
||||||
|
}
|
||||||
|
// 新增
|
||||||
const handleAdd = async () => {
|
const handleAdd = async () => {
|
||||||
showEdit.value = true
|
showEdit.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
editRef.value?.open('add')
|
editRef.value?.open('add')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEdit = async (data: any) => {
|
const handleDetail = async (data: any) => {
|
||||||
showEdit.value = true
|
let res = await apiStaffDetail({ id: data.id })
|
||||||
await nextTick()
|
showDetail.value = true
|
||||||
editRef.value?.open('edit')
|
nextTick(() => {
|
||||||
editRef.value?.setFormData(data)
|
detailRef.value?.open()
|
||||||
|
detailRef.value?.setForm(res)
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDelete = async (id: number) => {
|
getLists()
|
||||||
await feedback.confirm('确定要删除?')
|
</script>
|
||||||
await adminDelete({ id })
|
|
||||||
getLists()
|
|
||||||
}
|
|
||||||
|
|
||||||
const { optionsData } = useDictOptions<{
|
|
||||||
role: any[]
|
|
||||||
}>({
|
|
||||||
role: {
|
|
||||||
api: roleAll
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getLists()
|
|
||||||
})
|
|
||||||
</script>
|
|
|
@ -0,0 +1,274 @@
|
||||||
|
<template>
|
||||||
|
<div class="edit-popup">
|
||||||
|
<popup
|
||||||
|
ref="popupRef"
|
||||||
|
:title="popupTitle"
|
||||||
|
:async="true"
|
||||||
|
width="550px"
|
||||||
|
@confirm="handleSubmit"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||||
|
<!-- 账号输入框 -->
|
||||||
|
<el-form-item label="账号" prop="account">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.account"
|
||||||
|
:disabled="formData.root == 1"
|
||||||
|
placeholder="请输入账号"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 管理员头像 -->
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<material-picker v-model="formData.avatar" :limit="1" />
|
||||||
|
</div>
|
||||||
|
<div class="form-tips">建议尺寸:100*100px,支持jpg,jpeg,png格式</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 名称输入框 -->
|
||||||
|
<el-form-item label="名称" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名称" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="归属部门" prop="dept_id">
|
||||||
|
<el-tree-select
|
||||||
|
class="flex-1"
|
||||||
|
v-model="formData.dept_id"
|
||||||
|
:data="optionsData.dept"
|
||||||
|
clearable
|
||||||
|
multiple
|
||||||
|
node-key="id"
|
||||||
|
:props="{
|
||||||
|
value: 'id',
|
||||||
|
label: 'name',
|
||||||
|
disabled(data: any) {
|
||||||
|
return data.status !== 1
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
check-strictly
|
||||||
|
:default-expand-all="true"
|
||||||
|
placeholder="请选择上级部门"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="岗位" prop="jobs_id">
|
||||||
|
<el-select
|
||||||
|
class="flex-1"
|
||||||
|
v-model="formData.jobs_id"
|
||||||
|
clearable
|
||||||
|
multiple
|
||||||
|
placeholder="请选择岗位"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in optionsData.jobs"
|
||||||
|
:key="index"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 角色选择框 -->
|
||||||
|
<el-form-item label="角色" prop="role_id">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.role_id"
|
||||||
|
:disabled="formData.root == 1"
|
||||||
|
class="flex-1"
|
||||||
|
multiple
|
||||||
|
placeholder="请选择角色"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in optionsData.role"
|
||||||
|
:key="index"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 密码输入框 -->
|
||||||
|
<el-form-item label="密码" prop="password">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.password"
|
||||||
|
show-password
|
||||||
|
clearable
|
||||||
|
placeholder="请输入密码"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 确认密码输入框 -->
|
||||||
|
<el-form-item label="确认密码" prop="password_confirm">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.password_confirm"
|
||||||
|
show-password
|
||||||
|
clearable
|
||||||
|
placeholder="请输入确认密码"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 管理员状态 -->
|
||||||
|
<el-form-item label="管理员状态" v-if="formData.root != 1">
|
||||||
|
<el-switch v-model="formData.disable" :active-value="0" :inactive-value="1" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 多处登录 -->
|
||||||
|
<el-form-item label="多处登录">
|
||||||
|
<div>
|
||||||
|
<el-switch
|
||||||
|
v-model="formData.multipoint_login"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
/>
|
||||||
|
<div class="form-tips">允许多人同时在线登录</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import Popup from '@/components/popup/index.vue'
|
||||||
|
import { useDictOptions } from '@/hooks/useDictOptions'
|
||||||
|
import { adminAdd, adminDetail, adminEdit } from '@/api/perms/admin'
|
||||||
|
import { roleAll } from '@/api/perms/role'
|
||||||
|
import { jobsAll } from '@/api/org/post'
|
||||||
|
import { deptAll } from '@/api/org/department'
|
||||||
|
const emit = defineEmits(['success', 'close'])
|
||||||
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
|
const mode = ref('add')
|
||||||
|
const popupTitle = computed(() => {
|
||||||
|
return mode.value == 'edit' ? '编辑管理员' : '新增管理员'
|
||||||
|
})
|
||||||
|
const formData = reactive({
|
||||||
|
id: '',
|
||||||
|
account: '',
|
||||||
|
name: '',
|
||||||
|
dept_id: [],
|
||||||
|
jobs_id: [],
|
||||||
|
role_id: [],
|
||||||
|
avatar: '',
|
||||||
|
password: '',
|
||||||
|
password_confirm: '',
|
||||||
|
disable: 0,
|
||||||
|
multipoint_login: 1,
|
||||||
|
root: 0
|
||||||
|
})
|
||||||
|
const passwordConfirmValidator = (rule: object, value: string, callback: any) => {
|
||||||
|
if (formData.password) {
|
||||||
|
if (!value) callback(new Error('请再次输入密码'))
|
||||||
|
if (value !== formData.password) callback(new Error('两次输入密码不一致!'))
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleIdValidator = (rule: object, value: string, callback: any) => {
|
||||||
|
if (formData.root) {
|
||||||
|
callback()
|
||||||
|
} else {
|
||||||
|
if (formData.role_id.length) {
|
||||||
|
callback()
|
||||||
|
} else {
|
||||||
|
callback(new Error('请选择角色'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const formRules = reactive({
|
||||||
|
account: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入账号',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入名称',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
role_id: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: roleIdValidator
|
||||||
|
}
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
] as any[],
|
||||||
|
password_confirm: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入确认密码',
|
||||||
|
trigger: ['blur']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: passwordConfirmValidator,
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
] as any[]
|
||||||
|
})
|
||||||
|
const { optionsData } = useDictOptions<{
|
||||||
|
role: any[]
|
||||||
|
jobs: any[]
|
||||||
|
dept: any[]
|
||||||
|
}>({
|
||||||
|
role: {
|
||||||
|
api: roleAll
|
||||||
|
},
|
||||||
|
jobs: {
|
||||||
|
api: jobsAll
|
||||||
|
},
|
||||||
|
dept: {
|
||||||
|
api: deptAll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
mode.value == 'edit' ? await adminEdit(formData) : await adminAdd(formData)
|
||||||
|
popupRef.value?.close()
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = (type = 'add') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
const setFormData = async (row: any) => {
|
||||||
|
formRules.password = []
|
||||||
|
formRules.password_confirm = [
|
||||||
|
{
|
||||||
|
validator: passwordConfirmValidator,
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const data = await adminDetail({
|
||||||
|
id: row.id
|
||||||
|
})
|
||||||
|
for (const key in formData) {
|
||||||
|
if (data[key] != null && data[key] != undefined) {
|
||||||
|
//@ts-ignore
|
||||||
|
formData[key] = data[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setFormData
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,139 @@
|
||||||
|
<template>
|
||||||
|
<div class="admin">
|
||||||
|
<el-card class="!border-none" shadow="never">
|
||||||
|
<el-form class="mb-[-16px]" :model="formData" inline>
|
||||||
|
<el-form-item label="管理员账号">
|
||||||
|
<el-input v-model="formData.account" class="w-[280px]" clearable @keyup.enter="resetPage" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="管理员名称">
|
||||||
|
<el-input v-model="formData.name" class="w-[280px]" clearable @keyup.enter="resetPage" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="管理员角色">
|
||||||
|
<el-select class="w-[280px]" v-model="formData.role_id">
|
||||||
|
<el-option label="全部" value="" />
|
||||||
|
<el-option v-for="(item, index) in optionsData.role" :key="index" :label="item.name"
|
||||||
|
:value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
|
<el-button @click="resetParams">重置</el-button>
|
||||||
|
<export-data class="ml-2.5" :fetch-fun="adminLists" :params="formData" :page-size="pager.size" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-card v-loading="pager.loading" class="mt-4 !border-none" shadow="never">
|
||||||
|
<el-button v-perms="['auth.admin/add']" type="primary" @click="handleAdd">
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Plus" />
|
||||||
|
</template>
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<div class="mt-4">
|
||||||
|
<el-table :data="pager.lists" size="large">
|
||||||
|
<el-table-column label="ID" prop="id" min-width="60" />>
|
||||||
|
<el-table-column label="头像" min-width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-avatar :size="50" :src="row.avatar"></el-avatar>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="账号" prop="account" min-width="100" />
|
||||||
|
<el-table-column label="名称" prop="name" min-width="100" />
|
||||||
|
<el-table-column label="角色" prop="role_name" min-width="100" show-tooltip-when-overflow />
|
||||||
|
<el-table-column label="部门" prop="dept_name" min-width="100" show-tooltip-when-overflow />
|
||||||
|
<el-table-column label="创建时间" prop="create_time" min-width="180" />
|
||||||
|
<el-table-column label="最近登录时间" prop="login_time" min-width="180" />
|
||||||
|
<el-table-column label="最近登录IP" prop="login_ip" min-width="120" />
|
||||||
|
<el-table-column label="状态" min-width="100" v-perms="['auth.admin/edit']">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-switch v-if="row.root != 1" v-model="row.disable" :active-value="0" :inactive-value="1"
|
||||||
|
@change="changeStatus(row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="120" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-perms="['auth.admin/edit']" type="primary" link @click="handleEdit(row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="row.root != 1" v-perms="['auth.admin/delete']" type="danger" link
|
||||||
|
@click="handleDelete(row.id)">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="flex mt-4 justify-end">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="admin">
|
||||||
|
import { adminEdit, adminLists, adminDelete } from '@/api/perms/admin'
|
||||||
|
import { roleAll } from '@/api/perms/role'
|
||||||
|
import { useDictOptions } from '@/hooks/useDictOptions'
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import feedback from '@/utils/feedback'
|
||||||
|
import EditPopup from './edit.vue'
|
||||||
|
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive({
|
||||||
|
account: '',
|
||||||
|
name: '',
|
||||||
|
role_id: ''
|
||||||
|
})
|
||||||
|
const showEdit = ref(false)
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: adminLists,
|
||||||
|
params: formData
|
||||||
|
})
|
||||||
|
|
||||||
|
const changeStatus = (data: any) => {
|
||||||
|
adminEdit({
|
||||||
|
id: data.id,
|
||||||
|
avatar: data.avatar,
|
||||||
|
account: data.account,
|
||||||
|
name: data.name,
|
||||||
|
role_id: data.role_id,
|
||||||
|
job_id: data.job_id,
|
||||||
|
dept_id: data.dept_id,
|
||||||
|
disable: data.disable,
|
||||||
|
multipoint_login: data.multipoint_login
|
||||||
|
}).finally(() => {
|
||||||
|
getLists()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleAdd = async () => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('add')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEdit = async (data: any) => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('edit')
|
||||||
|
editRef.value?.setFormData(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
await feedback.confirm('确定要删除?')
|
||||||
|
await adminDelete({ id })
|
||||||
|
getLists()
|
||||||
|
}
|
||||||
|
|
||||||
|
const { optionsData } = useDictOptions<{
|
||||||
|
role: any[]
|
||||||
|
}>({
|
||||||
|
role: {
|
||||||
|
api: roleAll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getLists()
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<template>
|
||||||
|
<el-table :data="pager.lists">
|
||||||
|
<el-table-column label="订单号" prop="order_id" show-overflow-tooltip />
|
||||||
|
<el-table-column label="用户信息" prop="build_area_text" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<el-image style="width: 50px; height: 50px" :src="row.avatar" class="mr-2" />
|
||||||
|
{{ row.nickname }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品信息" prop="project_level_text" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-for="(item, index) in row.product" :key="index" class="flex items-center">
|
||||||
|
<!-- <el-image style="width: 50px; height: 50px" :src="item.cart_info.image" class="mr-2" /> -->
|
||||||
|
<div>
|
||||||
|
<p>{{ item.cart_info.name }}</p>
|
||||||
|
<p>¥{{ item.cart_info.price }} x {{ item.cart_info.cart_num }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="实际支付" prop="pay_price" show-overflow-tooltip />
|
||||||
|
<el-table-column label="支付方式" prop="pay_type_name" show-overflow-tooltip />
|
||||||
|
<el-table-column label="收银店员" prop="staff" show-overflow-tooltip />
|
||||||
|
<el-table-column label="下单时间" prop="pay_time" show-overflow-tooltip />
|
||||||
|
<el-table-column label="订单状态" prop="status_name" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
<div class="flex mt-4 justify-end">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="manageProjectLists">
|
||||||
|
import { ref, reactive, defineProps } from "vue"
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import { apiStoreOrderLists, } from '@/api/store_order'
|
||||||
|
|
||||||
|
let props = defineProps({
|
||||||
|
delivery_phone: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: apiStoreOrderLists,
|
||||||
|
params: {
|
||||||
|
delivery_phone: props.phone,
|
||||||
|
status: '1,2'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
getLists()
|
||||||
|
</script>
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<popup ref="popupRef" title="店员详情" :async="true" width="50vw" @close="close" :show-footer="false">
|
||||||
|
<div class="flex">
|
||||||
|
<el-avatar shape="circle" :size="70" :src="formData.avatar" />
|
||||||
|
<el-row class="w-[100%] ml-4">
|
||||||
|
<el-col :span="24">{{ formData.nickname }}</el-col>
|
||||||
|
<el-col :span="7">待配送订单{{ formData.wait }}</el-col>
|
||||||
|
<el-col :span="7">已配送订单:{{ formData.finish }}</el-col>
|
||||||
|
<el-col :span="7">待配送订单金额:¥{{ formData.wait_amount }}</el-col>
|
||||||
|
<el-col :span="7">已配送订单金额:¥{{ formData.finish_amount }}</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<myTable :delivery_phone="formData.phone"></myTable>
|
||||||
|
|
||||||
|
</popup>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import myTable from './components/myTable.vue';
|
||||||
|
|
||||||
|
|
||||||
|
const popupRef = ref(null)
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
|
||||||
|
const open = () => {
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
const close = () => {
|
||||||
|
emit('close')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = ref({})
|
||||||
|
|
||||||
|
|
||||||
|
const setForm = (data) => {
|
||||||
|
formData.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setForm
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,145 @@
|
||||||
|
<template>
|
||||||
|
<div class="edit-popup">
|
||||||
|
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
|
||||||
|
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
||||||
|
<el-form-item label="店员名称" prop="nickname">
|
||||||
|
<el-input v-model="formData.nickname" clearable placeholder="请输入店员名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<material-picker v-model="formData.avatar" :limit="1" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号码" prop="phone">
|
||||||
|
<el-input v-model="formData.phone" clearable placeholder="请输入手机号码" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="oaPlanEdit">
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import Popup from '@/components/popup/index.vue'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
import { apiDeliveryAdd, apiDeliveryEdit } from '@/api/delivery.ts'
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
dictData: {
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['success', 'close'])
|
||||||
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
|
const mode = ref('add')
|
||||||
|
|
||||||
|
|
||||||
|
// 弹窗标题
|
||||||
|
const popupTitle = computed(() => {
|
||||||
|
return mode.value == 'edit' ? '编辑日程安排' : '新增日程安排'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive({
|
||||||
|
id: '',
|
||||||
|
nickname: '',
|
||||||
|
avatar: 'https://lihaiim.oss-cn-chengdu.aliyuncs.com/public/uploads/images/20240606/20240606162227e3e005096.jpg',
|
||||||
|
phone: '',
|
||||||
|
status: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const chekcDate = (rule: any, value: any, callback: any) => {
|
||||||
|
if ((formData.rePwd) != (formData.pwd)) {
|
||||||
|
callback(new Error('两次密码不一致'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单验证
|
||||||
|
const formRules = reactive<any>({
|
||||||
|
nickname: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
}],
|
||||||
|
avatar: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
}],
|
||||||
|
account: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
}],
|
||||||
|
pwd: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
rePwd: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: chekcDate,
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
phone: [{
|
||||||
|
required: true,
|
||||||
|
message: '不能为空',
|
||||||
|
trigger: ['blur']
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 获取详情
|
||||||
|
const setFormData = async (data: Record<any, any>) => {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (data[key] != null && data[key] != undefined) {
|
||||||
|
//@ts-ignore
|
||||||
|
formData[key] = data[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 提交按钮
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
const data = { ...formData, }
|
||||||
|
mode.value == 'edit'
|
||||||
|
? await apiDeliveryEdit(data)
|
||||||
|
: await apiDeliveryAdd(data)
|
||||||
|
popupRef.value?.close()
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
|
||||||
|
//打开弹窗
|
||||||
|
const open = (type = 'add', start_time = '') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭回调
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setFormData,
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,133 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-card class="!border-none mb-4" shadow="never">
|
||||||
|
<el-form class="mb-[-16px]" :model="queryParams" label-width="100px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="配送员搜索" prop="keyword">
|
||||||
|
<el-input v-model="queryParams.keyword" clearable placeholder="请输入配送员名称/手机号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
|
<el-button @click="resetParams">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
||||||
|
<el-button v-perms="['dept.dept/add']" type="primary" @click="handleAdd()">
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Plus" />
|
||||||
|
</template>
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<div class="mt-4">
|
||||||
|
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column label="id" prop="id" show-overflow-tooltip />
|
||||||
|
<el-table-column label="头像" prop="avatar" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image style="width: 50px; height: 50px" :src="row.avatar" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="昵称" prop="nickname" show-overflow-tooltip />
|
||||||
|
<el-table-column label="手机号" prop="phone" show-overflow-tooltip />
|
||||||
|
<el-table-column label="状态" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-switch v-model="row.status" :active-value="1" :inactive-value="0"
|
||||||
|
@change="changeStatus(row)"></el-switch>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="170" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="handleEdit(row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" link @click="handleDetail(row)">
|
||||||
|
详情
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="flex mt-4 justify-end">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||||
|
<DetailPopup v-if="showDetail" ref="detailRef" @close="showEdit = false" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="manageProjectLists">
|
||||||
|
import { ref, reactive } from "vue"
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import EditPopup from './edit.vue'
|
||||||
|
import DetailPopup from './detail.vue'
|
||||||
|
import { apiDeliveryLists, apiDeliveryDetail, apiDeliveryStatus } from '@/api/delivery.ts'
|
||||||
|
|
||||||
|
const detailRef = ref(null)
|
||||||
|
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||||
|
// 是否显示编辑框
|
||||||
|
const showEdit = ref(false)
|
||||||
|
const showDetail = ref(false)
|
||||||
|
|
||||||
|
|
||||||
|
// 查询条件
|
||||||
|
const queryParams = reactive({
|
||||||
|
keyword: ""
|
||||||
|
})
|
||||||
|
|
||||||
|
// 选中数据
|
||||||
|
const selectData = ref<any[]>([])
|
||||||
|
|
||||||
|
// 表格选择后回调事件
|
||||||
|
const handleSelectionChange = (val: any[]) => {
|
||||||
|
selectData.value = val.map(({ id }) => id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上架&下架
|
||||||
|
const changeStatus = (data: any) => {
|
||||||
|
apiDeliveryStatus({
|
||||||
|
id: data.id
|
||||||
|
}).finally(() => {
|
||||||
|
getLists()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: apiDeliveryLists,
|
||||||
|
params: queryParams
|
||||||
|
})
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const handleEdit = async (data: any) => {
|
||||||
|
let res = await apiDeliveryDetail({ id: data.id })
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('edit')
|
||||||
|
editRef.value?.setFormData(res)
|
||||||
|
}
|
||||||
|
// 新增
|
||||||
|
const handleAdd = async () => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('add')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDetail = async (data: any) => {
|
||||||
|
let res = await apiDeliveryDetail({ id: data.id })
|
||||||
|
showDetail.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
detailRef.value?.open()
|
||||||
|
detailRef.value?.setForm(res)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getLists()
|
||||||
|
</script>
|
|
@ -126,8 +126,8 @@ const handleResetParams = () => {
|
||||||
|
|
||||||
const staffList = ref([])
|
const staffList = ref([])
|
||||||
const getStaffList = async () => {
|
const getStaffList = async () => {
|
||||||
let res = await apiStaffLists()
|
let res = await apiStaffLists({ page_no: 1, page_size: 100 })
|
||||||
staffList.value = res
|
staffList.value = res.lists
|
||||||
}
|
}
|
||||||
getStaffList()
|
getStaffList()
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<el-card>
|
<el-card>
|
||||||
<div class="w-[800px]">
|
<div class="w-[600px]">
|
||||||
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
||||||
<el-tabs v-model="activeName" class="demo-tabs">
|
<el-tabs v-model="activeName" class="demo-tabs">
|
||||||
<el-tab-pane label="基础设置" name="first">
|
<el-tab-pane label="基础设置" name="first">
|
||||||
<el-form-item label="门店名称" prop="title">
|
<el-form-item label="门店名称">
|
||||||
<el-input v-model="formData.title" clearable placeholder="请输入店员名称" />
|
<el-input v-model="formData.store_name" clearable placeholder="请输入店员名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="门店手机号" prop="title">
|
<el-form-item label="门店手机号" prop="title">
|
||||||
<el-input v-model="formData.title" clearable placeholder="请输入店员名称" />
|
<el-input v-model="formData.phone" clearable placeholder="请输入店员名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="营业状态" prop="title">
|
<el-form-item label="营业状态" prop="title">
|
||||||
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0"></el-switch>
|
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<el-form-item label="门店地址" prop="title">
|
<el-form-item label="门店地址" prop="title">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-select class="flex-1" v-model="formData.city_id" clearable placeholder="请选择"
|
<el-select class="flex-1" v-model="formData.province_id" clearable placeholder="请选择"
|
||||||
@change="getCityList(formData.province_id, false)">
|
@change="getCityList(formData.province_id, false)">
|
||||||
<el-option v-for="(item, index) in address.provinceList" :key="index"
|
<el-option v-for="(item, index) in address.provinceList" :key="index"
|
||||||
:label="item.province_name" :value="parseInt(item.province_code)" />
|
:label="item.province_name" :value="parseInt(item.province_code)" />
|
||||||
|
@ -34,40 +34,30 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-select class="flex-1" v-model="formData.area_id" clearable placeholder="请选择"
|
<el-select class="flex-1" v-model="formData.area_id" clearable placeholder="请选择">
|
||||||
@change="getTownList(formData.area_id, false)">
|
|
||||||
<el-option v-for="(item, index) in address.areaList" :key="index"
|
<el-option v-for="(item, index) in address.areaList" :key="index"
|
||||||
:label="item.area_name" :value="parseInt(item.area_code)" />
|
:label="item.area_name" :value="parseInt(item.area_code)" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
|
||||||
<el-select class="flex-1" v-model="formData.street_id" clearable placeholder="请选择"
|
|
||||||
@change="getVilllageList(formData.street_id, false)">
|
|
||||||
<el-option v-for="(item, index) in address.townList" :key="index"
|
|
||||||
:label="item.street_name" :value="parseInt(item.street_code)" />
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="配送范围(km)" prop="title">
|
<el-form-item label="配送范围(km)" prop="title">
|
||||||
<el-input-number v-model="formData.num" :step="1" />
|
<el-input-number v-model="formData.range" :step="1" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="门店详细地址" prop="title">
|
<el-form-item label="门店详细地址" prop="title">
|
||||||
<myMap></myMap>
|
<myMap :formData="formData"></myMap>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<el-tab-pane label="配送设置" name="second">
|
<el-tab-pane label="配送设置" name="second">
|
||||||
<el-form-item label="同城配送" prop="title">
|
<el-form-item label="同城配送" prop="title">
|
||||||
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0"></el-switch>
|
<el-switch v-model="formData.isCity" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="到店自提" prop="title">
|
<el-form-item label="到店自提" prop="title">
|
||||||
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0"></el-switch>
|
<el-switch v-model="formData.isSelf" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="默认配送方式" prop="title">
|
<el-form-item label="默认配送方式" prop="title">
|
||||||
<el-radio-group v-model="formData.types" class="ml-4">
|
<el-radio-group v-model="formData.defalut_types" class="ml-4">
|
||||||
<el-radio label="1" size="large">配送</el-radio>
|
<el-radio label="1" size="large">配送</el-radio>
|
||||||
<el-radio label="2" size="large">自提</el-radio>
|
<el-radio label="2" size="large">自提</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
@ -77,17 +67,16 @@
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="handleSubmit">保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="oaPlanEdit">
|
<script lang="ts" setup name="oaPlanEdit">
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { timeFormat } from '@/utils/util'
|
import { apicityLists, apiAreaLists, apigetProvinceLists, apiGetStore, apiSaveStore } from "@/api/address"
|
||||||
import { apicityLists, apiAreaLists, apiStreetLists, apigetProvinceLists } from "@/api/address"
|
|
||||||
import myMap from "./myMap/index.vue"
|
import myMap from "./myMap/index.vue"
|
||||||
import axios from 'axios';
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
//
|
//
|
||||||
const formRef = shallowRef<FormInstance>()
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
@ -102,19 +91,20 @@ const address = reactive({
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
id: '',
|
id: '',
|
||||||
|
store_name: '',
|
||||||
status: 0,
|
status: 0,
|
||||||
title: '',
|
times: '',
|
||||||
province_id: '510000',
|
province_id: "",
|
||||||
city_id: '',
|
city_id: '',
|
||||||
area_id: '',
|
area_id: '',
|
||||||
street_id: '',
|
street_id: '',
|
||||||
types: '1',
|
lat: "",
|
||||||
times: '',
|
lng: "",
|
||||||
num: "",
|
range: '1',
|
||||||
start_time: '',
|
isCity: '',
|
||||||
end_time: '',
|
isSelf: "",
|
||||||
remind_type: '',
|
defalut_types: 1,
|
||||||
remark: '',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const chekcDate = (rule: any, value: any, callback: any) => {
|
const chekcDate = (rule: any, value: any, callback: any) => {
|
||||||
|
@ -127,20 +117,20 @@ const chekcDate = (rule: any, value: any, callback: any) => {
|
||||||
|
|
||||||
// 表单验证
|
// 表单验证
|
||||||
const formRules = reactive<any>({
|
const formRules = reactive<any>({
|
||||||
end_time: [{
|
// end_time: [{
|
||||||
required: true,
|
// required: true,
|
||||||
message: '请输入结束时间',
|
// message: '请输入结束时间',
|
||||||
trigger: ['blur']
|
// trigger: ['blur']
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
validator: chekcDate,
|
// validator: chekcDate,
|
||||||
trigger: ['blur']
|
// trigger: ['blur']
|
||||||
}],
|
// }],
|
||||||
remind_type: [{
|
// remind_type: [{
|
||||||
required: true,
|
// required: true,
|
||||||
message: '请输入提醒类型',
|
// message: '请输入提醒类型',
|
||||||
trigger: ['blur']
|
// trigger: ['blur']
|
||||||
}],
|
// }],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,14 +142,23 @@ const setFormData = async (data: Record<any, any>) => {
|
||||||
formData[key] = data[key]
|
formData[key] = data[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
apiGetStore().then(res => {
|
||||||
|
setFormData(res)
|
||||||
|
console.log(formData)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// 提交按钮
|
// 提交按钮
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
await formRef.value?.validate()
|
await formRef.value?.validate()
|
||||||
const data = { ...formData, }
|
const data = { ...formData, }
|
||||||
|
await apiSaveStore(data)
|
||||||
// mode.value == 'edit'
|
// mode.value == 'edit'
|
||||||
// ? await apiOaPlanEdit(data)
|
// ? await apiOaPlanEdit(data)
|
||||||
// : await apiOaPlanAdd(data)
|
// : await apiOaPlanAdd(data)
|
||||||
|
@ -177,7 +176,7 @@ const getProvinceList = async (isAsync: Boolean) => {
|
||||||
|
|
||||||
|
|
||||||
const getCityList = async (province_code: number | String, isAsync: Boolean) => {
|
const getCityList = async (province_code: number | String, isAsync: Boolean) => {
|
||||||
let res = await apicityLists({ province_code })
|
let res = await apicityLists({ code: province_code })
|
||||||
address.cityList = res
|
address.cityList = res
|
||||||
if (isAsync) {
|
if (isAsync) {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -188,7 +187,7 @@ const getCityList = async (province_code: number | String, isAsync: Boolean) =>
|
||||||
|
|
||||||
|
|
||||||
const getAreaList = async (city_code: number | String, isAsync: Boolean) => {
|
const getAreaList = async (city_code: number | String, isAsync: Boolean) => {
|
||||||
let res = await apiAreaLists({ city_code })
|
let res = await apiAreaLists({ code: city_code })
|
||||||
address.areaList = res
|
address.areaList = res
|
||||||
if (isAsync) {
|
if (isAsync) {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -198,14 +197,6 @@ const getAreaList = async (city_code: number | String, isAsync: Boolean) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const getTownList = async (area_code: number | String, isAsync: Boolean) => {
|
|
||||||
let res = await apiStreetLists({ area_code })
|
getProvinceList(false)
|
||||||
address.townList = res
|
|
||||||
if (isAsync) {
|
|
||||||
return Promise.resolve({
|
|
||||||
msg: '获取成功'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// getProvinceList(false)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,51 +1,71 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
{{ dataMap.latitude }}-{{ dataMap.lngitude }}
|
{{ dataMap.latitude }}-{{ dataMap.lngitude }}
|
||||||
|
<!-- {{ formData }} -->
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<el-autocomplete v-model="address" :fetch-suggestions="querySearch" placeholder="请输入详细地址"
|
<el-autocomplete v-model="address" :fetch-suggestions="querySearch" placeholder="请输入详细地址"
|
||||||
:trigger-on-focus="false" />
|
:trigger-on-focus="false" />
|
||||||
<!-- <el-button type="primary" @click="getLocations">
|
<el-button type="primary" @click="getLocations">
|
||||||
搜索
|
|
||||||
</el-button> -->
|
|
||||||
<el-button type="primary" @click="setMarkerBylatLon(30.629673, 103.775231)">
|
|
||||||
搜索
|
搜索
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="primary" @click="getLocation">
|
||||||
|
当前位置
|
||||||
|
</el-button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="amp-container" />
|
<div id="amp-container" class="w-[100%]" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, reactive, ref, } from 'vue';
|
import { onMounted, reactive, ref, defineProps } from 'vue';
|
||||||
import { jsonp } from "vue-jsonp"
|
import { jsonp } from "vue-jsonp"
|
||||||
|
|
||||||
const dataMap = reactive({
|
|
||||||
|
const props = defineProps({
|
||||||
|
formData: {
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataMap = ref({
|
||||||
map: '',
|
map: '',
|
||||||
markerLayer: '',
|
markerLayer: '',
|
||||||
latitude: '', //纬度
|
latitude: props.formData.lat, //纬度
|
||||||
lngitude: '', //经度
|
lngitude: props.formData.lng, //经度
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
watch(
|
||||||
|
dataMap.value,
|
||||||
|
(val: boolean) => {
|
||||||
|
props.formData.lat = val.latitude;
|
||||||
|
props.formData.lng = val.lngitude;
|
||||||
|
},
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
const TMap = (window as any).TMap;
|
const TMap = (window as any).TMap;
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init();
|
init();
|
||||||
getLocation();
|
// getLocation();
|
||||||
});
|
});
|
||||||
const init = () => {
|
const init = () => {
|
||||||
let center = new TMap.LatLng(dataMap.latitude, dataMap.lngitude);
|
let center = new TMap.LatLng(dataMap.value.latitude, dataMap.value.lngitude);
|
||||||
dataMap.map = new TMap.Map(document.getElementById('amp-container'), {
|
dataMap.value.map = new TMap.Map(document.getElementById('amp-container'), {
|
||||||
center: center,//设置地图中心点坐标
|
center: center,//设置地图中心点坐标
|
||||||
// zoom: 11, //设置地图缩放级别
|
// zoom: 11, //设置地图缩放级别
|
||||||
viewMode: '2D'
|
viewMode: '2D'
|
||||||
});
|
});
|
||||||
(dataMap.map as any).on('click', clickHandler); // 绑定点击地图获取地理位置的事件
|
(dataMap.value.map as any).on('click', clickHandler); // 绑定点击地图获取地理位置的事件
|
||||||
markerLayer(); // 标记地图
|
markerLayer(); // 标记地图
|
||||||
};
|
};
|
||||||
// 重载地图
|
// 重载地图
|
||||||
const reloadMap = () => {
|
const reloadMap = () => {
|
||||||
(document.getElementById('amp-container') as any).innerHTML = '';
|
(document.getElementById('amp-container') as any).innerHTML = '';
|
||||||
dataMap.markerLayer = '';
|
dataMap.value.markerLayer = '';
|
||||||
let center = new TMap.LatLng(dataMap.latitude, dataMap.lngitude);
|
let center = new TMap.LatLng(dataMap.value.latitude, dataMap.value.lngitude);
|
||||||
dataMap.map = new TMap.Map(document.getElementById('amp-container'), {
|
dataMap.value.map = new TMap.Map(document.getElementById('amp-container'), {
|
||||||
center: center,//设置地图中心点坐标
|
center: center,//设置地图中心点坐标
|
||||||
viewMode: '2D'
|
viewMode: '2D'
|
||||||
});
|
});
|
||||||
|
@ -55,11 +75,11 @@ const getLocation = async () => {
|
||||||
try {
|
try {
|
||||||
jsonp('https://apis.map.qq.com/ws/location/v1/ip?key=SMJBZ-WCHK4-ZPZUA-DSIXI-XDDVQ-XWFX7&output=jsonp').then(res => {
|
jsonp('https://apis.map.qq.com/ws/location/v1/ip?key=SMJBZ-WCHK4-ZPZUA-DSIXI-XDDVQ-XWFX7&output=jsonp').then(res => {
|
||||||
if (res.result) {
|
if (res.result) {
|
||||||
dataMap.latitude = res.result.location.lat;
|
dataMap.value.latitude = res.result.location.lat;
|
||||||
dataMap.lngitude = res.result.location.lng;
|
dataMap.value.lngitude = res.result.location.lng;
|
||||||
// dataMap.latitude = 30.629673;
|
// dataMap.latitude = 30.629673;
|
||||||
// dataMap.lngitude = 103.775231;
|
// dataMap.lngitude = 103.775231;
|
||||||
(dataMap.map as any).setCenter(new TMap.LatLng(dataMap.latitude, dataMap.lngitude));
|
(dataMap.value.map as any).setCenter(new TMap.LatLng(dataMap.value.latitude, dataMap.value.lngitude));
|
||||||
reloadMap();
|
reloadMap();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -71,9 +91,9 @@ const getLocation = async () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const setMarkerBylatLon = (lat, lng) => {
|
const setMarkerBylatLon = (lat, lng) => {
|
||||||
dataMap.latitude = lat;
|
dataMap.value.latitude = lat;
|
||||||
dataMap.lngitude = lng;
|
dataMap.value.lngitude = lng;
|
||||||
(dataMap.map as any).setCenter(new TMap.LatLng(dataMap.latitude, dataMap.lngitude));
|
(dataMap.value.map as any).setCenter(new TMap.LatLng(dataMap.value.latitude, dataMap.value.lngitude));
|
||||||
reloadMap();
|
reloadMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +101,6 @@ const setMarkerBylatLon = (lat, lng) => {
|
||||||
const clickHandler = (evt: any) => {
|
const clickHandler = (evt: any) => {
|
||||||
let lavting = evt.latLng
|
let lavting = evt.latLng
|
||||||
console.log(lavting.getLat(), lavting.getLng())
|
console.log(lavting.getLat(), lavting.getLng())
|
||||||
return
|
|
||||||
|
|
||||||
setMarkerBylatLon(evt.latLng.lat.toFixed(4), evt.latLng.lng.toFixed(4))
|
setMarkerBylatLon(evt.latLng.lat.toFixed(4), evt.latLng.lng.toFixed(4))
|
||||||
return
|
return
|
||||||
dataMap.latitude = evt.latLng.getLat().toFixed(6);
|
dataMap.latitude = evt.latLng.getLat().toFixed(6);
|
||||||
|
@ -92,8 +110,8 @@ const clickHandler = (evt: any) => {
|
||||||
};
|
};
|
||||||
//标记地图
|
//标记地图
|
||||||
const markerLayer = () => {
|
const markerLayer = () => {
|
||||||
dataMap.markerLayer = new TMap.MultiMarker({
|
dataMap.value.markerLayer = new TMap.MultiMarker({
|
||||||
map: dataMap.map, //指定地图容器
|
map: dataMap.value.map, //指定地图容器
|
||||||
//样式定义
|
//样式定义
|
||||||
styles: {
|
styles: {
|
||||||
//创建一个styleId为"myStyle"的样式(styles的子属性名即为styleId)
|
//创建一个styleId为"myStyle"的样式(styles的子属性名即为styleId)
|
||||||
|
@ -111,7 +129,7 @@ const markerLayer = () => {
|
||||||
{
|
{
|
||||||
"id": "1", //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
|
"id": "1", //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
|
||||||
"styleId": 'myStyle', //指定样式id
|
"styleId": 'myStyle', //指定样式id
|
||||||
"position": new TMap.LatLng(dataMap.latitude, dataMap.lngitude), //点标记坐标位置
|
"position": new TMap.LatLng(dataMap.value.latitude, dataMap.value.lngitude), //点标记坐标位置
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -121,9 +139,9 @@ const address = ref('');
|
||||||
const getLocations = async () => {
|
const getLocations = async () => {
|
||||||
try {
|
try {
|
||||||
let { result } = await jsonp(`https://apis.map.qq.com/ws/geocoder/v1/?key=SMJBZ-WCHK4-ZPZUA-DSIXI-XDDVQ-XWFX7&address=${address.value}&output=jsonp`);
|
let { result } = await jsonp(`https://apis.map.qq.com/ws/geocoder/v1/?key=SMJBZ-WCHK4-ZPZUA-DSIXI-XDDVQ-XWFX7&address=${address.value}&output=jsonp`);
|
||||||
dataMap.latitude = result.location.lat;
|
dataMap.value.latitude = result.location.lat;
|
||||||
dataMap.lngitude = result.location.lng;
|
dataMap.value.lngitude = result.location.lng;
|
||||||
(dataMap.map as any).setCenter(new TMap.LatLng(dataMap.latitude, dataMap.lngitude));
|
(dataMap.value.map as any).setCenter(new TMap.LatLng(dataMap.value.latitude, dataMap.value.lngitude));
|
||||||
reloadMap();
|
reloadMap();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<el-table :data="pager.lists">
|
||||||
|
<el-table-column label="订单号" prop="project_level_text" show-overflow-tooltip />
|
||||||
|
<el-table-column label="用户信息" prop="total_investment" show-overflow-tooltip />
|
||||||
|
<el-table-column label="实际支付" prop="total_investment" show-overflow-tooltip />
|
||||||
|
<el-table-column label="订单类型" prop="total_investment" show-overflow-tooltip />
|
||||||
|
<el-table-column label="支付方式" prop="total_investment" show-overflow-tooltip />
|
||||||
|
<el-table-column label="配送员名称" prop="total_investment" show-overflow-tooltip />
|
||||||
|
<el-table-column label="下单时间" prop="total_investment" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
<div class="flex mt-4 justify-end">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="manageProjectLists">
|
||||||
|
import { ref, reactive } from "vue"
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import { apiGoodsListLists, apiStatus, apiGoodsTypeLists } from '@/api/goodsList'
|
||||||
|
|
||||||
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
|
fetchFun: apiGoodsListLists,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// getLists()
|
||||||
|
</script>
|
|
@ -1,14 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
<el-table :data="pager.lists">
|
||||||
<el-table-column label="头像" prop="build_area_text" show-overflow-tooltip>
|
<el-table-column label="头像" prop="build_area_text" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<!-- <el-image style="width: 50px; height: 50px" :src="url" /> -->
|
<!-- <el-image style="width: 50px; height: 50px" :src="url" /> -->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="用户名称" prop="project_level_text" show-overflow-tooltip />
|
<el-table-column label="用户名称" prop="project_level_text" show-overflow-tooltip />
|
||||||
<el-table-column label="订单号" prop="total_investment" show-overflow-tooltip width="120" />
|
<el-table-column label="订单号" prop="total_investment" show-overflow-tooltip />
|
||||||
<el-table-column label="交易金额" prop="total_investment" show-overflow-tooltip width="120" />
|
<el-table-column label="交易金额" prop="total_investment" show-overflow-tooltip />
|
||||||
<el-table-column label="成交时间" prop="total_investment" show-overflow-tooltip width="120" />
|
<el-table-column label="成交时间" prop="total_investment" show-overflow-tooltip />
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="flex mt-4 justify-end">
|
<div class="flex mt-4 justify-end">
|
||||||
<pagination v-model="pager" @change="getLists" />
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
|
|
@ -1,114 +1,142 @@
|
||||||
<template>
|
<template>
|
||||||
<el-card>
|
<div class="workbench">
|
||||||
<el-form class="mb-[-16px]" :model="queryParams" label-width="80px">
|
<el-card shadow="never" class=" !border-none">
|
||||||
<el-col :span="6">
|
<div class="mb-6 flex justify-between items-center">
|
||||||
<el-form-item label="时间筛选">
|
<span class="text-2xl">商品概况</span>
|
||||||
<el-date-picker v-model="date" type="daterange" range-separator="-" start-placeholder="开始时间"
|
<div class="flex items-center text-sm">
|
||||||
end-placeholder="结束时间" />
|
<span class="mr-4">时间筛选: </span>
|
||||||
</el-form-item>
|
<el-date-picker v-model="startEndTime" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||||
</el-col>
|
end-placeholder="结束日期" unlink-panels :shortcuts="shortcuts" />
|
||||||
</el-form>
|
<el-button type="primary" class="ml-4" @click="getData">查询</el-button>
|
||||||
</el-card>
|
</div>
|
||||||
<el-card>
|
</div>
|
||||||
<el-row>
|
<div class="flex flex-wrap">
|
||||||
<el-col :span="6" class='flex mb-7' v-for="(item, index) in statisticLists" :key="index">
|
<div class="w-1/5 flex mb-6" v-for="(item, index) in basicList" :key="index">
|
||||||
<img class="w-[50px] h-[50px] mr-2" :src="item.src" />
|
<div class="mr-2">
|
||||||
<el-statistic :title="item.title" :value="item.value" />
|
<div class="rounded-full p-2" :style="{ 'background-color': colorList[index % 4] }">
|
||||||
</el-col>
|
<iconfont :iconName="item.icon" white className="text-6xl" />
|
||||||
</el-row>
|
</div>
|
||||||
</el-card>
|
</div>
|
||||||
<el-card>
|
<div>
|
||||||
<template #header>
|
<div class="text-info">{{ item.name }}</div>
|
||||||
营业趋势
|
<div class="text-6xl">{{ item.num }}</div>
|
||||||
</template>
|
<div class="text-info">环比增长: <span :class="item.percent > 0 ? 'text-success' : 'text-danger'">{{
|
||||||
<v-charts style="height: 350px" :option="visitorOption" :autoresize="true" />
|
item.percent }}%</span></div>
|
||||||
</el-card>
|
</div>
|
||||||
<el-row>
|
</div>
|
||||||
<el-col :span="14">
|
</div>
|
||||||
<el-card class="h-[100%]">
|
<div>
|
||||||
<template #header>
|
<v-charts style="height: 400px" :option="visitorOption" :autoresize="true" />
|
||||||
交易数据
|
</div>
|
||||||
</template>
|
</el-card>
|
||||||
<tradData></tradData>
|
<el-card shadow="never" class="mt-4 !border-none">
|
||||||
</el-card>
|
<div class="mb-6 flex justify-between items-center">
|
||||||
</el-col>
|
<span class="text-2xl">商品排行</span>
|
||||||
<el-col :span="10">
|
<div class="flex items-center text-sm">
|
||||||
<el-card>
|
<span class="mr-4">时间筛选: </span>
|
||||||
<template #header>
|
<el-date-picker v-model="startEndTime" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||||
交易类型
|
end-placeholder="结束日期" unlink-panels :shortcuts="shortcuts" />
|
||||||
</template>
|
<el-button type="primary" class="ml-4" @click="getData">查询</el-button>
|
||||||
<v-charts style="height: 350px" :option="tradTypeOption" :autoresize="true" />
|
</div>
|
||||||
</el-card>
|
</div>
|
||||||
</el-col>
|
<div>
|
||||||
</el-row>
|
<el-table :data="sotreList">
|
||||||
|
<el-table-column label="商品图片">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image :src="row.image" fit="cover" style="width: 50px; height: 50px" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品名称" prop="store_name" min-width="250" />
|
||||||
|
<el-table-column label="游览量" prop="visit" min-width="120" />
|
||||||
|
<el-table-column label="访客数" prop="user" min-width="120" />
|
||||||
|
<el-table-column label="加购件数" prop="cart" min-width="120" />
|
||||||
|
<el-table-column label="下单件数" prop="orders" min-width="120" />
|
||||||
|
<el-table-column label="支付件数" prop="pay" min-width="120" />
|
||||||
|
<el-table-column label="支付金额" prop="price" min-width="120" />
|
||||||
|
<el-table-column label="收藏数" prop="collect" min-width="120" />
|
||||||
|
<el-table-column label="毛利率(%)" prop="profit" min-width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span>{{ row.profit }}%</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="manageProjectLists">
|
<script lang="ts" setup name="product">
|
||||||
import { ref, reactive } from "vue"
|
// import { apiGetBasic, apiGetTrend, apiGetProductRanking } from '@/api/workbench'
|
||||||
import { getWorkbench } from '@/api/app'
|
import moment from 'moment'
|
||||||
import vCharts from 'vue-echarts'
|
import vCharts from 'vue-echarts'
|
||||||
import tradData from "./components/tradData.vue"
|
|
||||||
|
|
||||||
const src = ref('https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg')
|
const shortcuts = [
|
||||||
const date = ref("")
|
{
|
||||||
|
text: '近一周',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date()
|
||||||
|
const start = new Date()
|
||||||
|
start.setDate(start.getDate() - 7)
|
||||||
|
return [start, end]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '近一月',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date()
|
||||||
|
const start = new Date()
|
||||||
|
start.setMonth(start.getMonth() - 1)
|
||||||
|
return [start, end]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '近三月',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date()
|
||||||
|
const start = new Date()
|
||||||
|
start.setMonth(start.getMonth() - 3)
|
||||||
|
return [start, end]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const visitorOption: any = reactive({
|
||||||
const statisticLists = reactive([
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701552002039.png',
|
|
||||||
title: "核销订单金额",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "https://ceshi-engineering.lihaink.cn/uploads/files/20240604/2024060417170150a511510.png",
|
|
||||||
title: "余额消费金额",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701594ff8897.png',
|
|
||||||
title: "用户充值金额",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/202406041717018a22e1161.png',
|
|
||||||
title: "线下收银订单金额",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/202406041717013a08c6793.png',
|
|
||||||
title: "现金收银订单金额",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/2024060417170103b0a9686.png',
|
|
||||||
title: "门店新增用户数",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701469b91377.png',
|
|
||||||
title: "门店成交用户数",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701fbb680115.png',
|
|
||||||
title: "总订单金额",
|
|
||||||
value: 1000
|
|
||||||
},
|
|
||||||
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
const visitorOption = reactive({
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: []
|
data: [0],
|
||||||
|
axisLabel: {
|
||||||
|
rotate: 45,
|
||||||
|
color: '#333'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: [
|
||||||
type: 'value'
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '数量',
|
||||||
|
position: 'left',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: '{value}'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '金额',
|
||||||
|
position: 'right',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: '{value}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: ['营业额']
|
data: ['访问量']
|
||||||
},
|
},
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
// 点的颜色。
|
// 点的颜色。
|
||||||
|
@ -119,7 +147,7 @@ const visitorOption = reactive({
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '营业额',
|
name: '访问量',
|
||||||
data: [0],
|
data: [0],
|
||||||
type: 'line',
|
type: 'line',
|
||||||
smooth: true
|
smooth: true
|
||||||
|
@ -127,67 +155,136 @@ const visitorOption = reactive({
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const tradTypeOption = reactive(
|
// 颜色
|
||||||
|
const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1']
|
||||||
|
// 商品浏览量, 商品访客数, 加购件数, 下单件数, 支付件数, 支付金额, 成本金额, 退款金额, 退款件数, 访客-支付转化率
|
||||||
|
const basicList = reactive([
|
||||||
{
|
{
|
||||||
title: {
|
name: '商品浏览量',
|
||||||
text: '交易类型',
|
type: 'browse',
|
||||||
subtext: 'Fake Data',
|
icon: 'RectangleCopy21',
|
||||||
left: 'center'
|
num: 0,
|
||||||
},
|
percent: 0
|
||||||
tooltip: {
|
},
|
||||||
trigger: 'item'
|
{
|
||||||
},
|
name: '商品访客数',
|
||||||
legend: {
|
type: 'user',
|
||||||
orient: 'vertical',
|
icon: 'RectangleCopy5',
|
||||||
left: 'left'
|
num: 0,
|
||||||
},
|
percent: 0
|
||||||
series: [
|
},
|
||||||
{
|
{
|
||||||
name: 'Access From',
|
name: '加购件数',
|
||||||
type: 'pie',
|
type: 'cart',
|
||||||
radius: '50%',
|
icon: 'RectangleCopy13',
|
||||||
data: [
|
num: 0,
|
||||||
{ value: 1048, name: '线上收银订单' },
|
percent: 0
|
||||||
{ value: 735, name: '现金收银订单' },
|
},
|
||||||
{ value: 580, name: '核销订单' },
|
{
|
||||||
{ value: 484, name: '充值订单' },
|
name: '下单件数',
|
||||||
],
|
type: 'order',
|
||||||
emphasis: {
|
icon: 'RectangleCopy12',
|
||||||
itemStyle: {
|
num: 0,
|
||||||
shadowBlur: 10,
|
percent: 0
|
||||||
shadowOffsetX: 0,
|
},
|
||||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
{
|
||||||
}
|
name: '支付件数',
|
||||||
}
|
type: 'pay',
|
||||||
}
|
icon: 'RectangleCopy15',
|
||||||
]
|
num: 0,
|
||||||
|
percent: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '支付金额',
|
||||||
|
type: 'payPrice',
|
||||||
|
icon: 'RectangleCopy14',
|
||||||
|
num: 0,
|
||||||
|
percent: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '成本金额',
|
||||||
|
type: 'cost',
|
||||||
|
icon: 'RectangleCopy24',
|
||||||
|
num: 0,
|
||||||
|
percent: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '退款金额',
|
||||||
|
type: 'refundPrice',
|
||||||
|
icon: 'RectangleCopy32',
|
||||||
|
num: 0,
|
||||||
|
percent: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '退款件数',
|
||||||
|
type: 'refund',
|
||||||
|
icon: 'RectangleCopy19',
|
||||||
|
num: 0,
|
||||||
|
percent: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '访客-支付转化率',
|
||||||
|
type: 'payPercent',
|
||||||
|
icon: 'RectangleCopy4',
|
||||||
|
num: 0,
|
||||||
|
percent: 0
|
||||||
}
|
}
|
||||||
)
|
])
|
||||||
|
const startEndTime = ref(['', '']);
|
||||||
|
// 获取数据
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
getWorkbench()
|
let date = '';
|
||||||
.then((res: any) => {
|
if (startEndTime.value[0] && startEndTime.value[1]) date = moment(startEndTime.value[0]).format('YYYY/MM/DD') + '-' + moment(startEndTime.value[1]).format('YYYY/MM/DD');
|
||||||
|
|
||||||
// 清空echarts 数据
|
return
|
||||||
visitorOption.xAxis.data = []
|
apiGetBasic({
|
||||||
visitorOption.series[0].data = []
|
date: date
|
||||||
|
}).then(res => {
|
||||||
|
basicList.forEach((item: any) => {
|
||||||
|
item.num = res[item.type].num;
|
||||||
|
item.percent = res[item.type].percent;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
apiGetTrend({
|
||||||
|
date: date
|
||||||
|
}).then(res => {
|
||||||
|
// 清空echarts 数据
|
||||||
|
visitorOption.xAxis.data = []
|
||||||
|
visitorOption.series = []
|
||||||
|
|
||||||
// 写入从后台拿来的数据
|
visitorOption.legend.data = res.series.map((item: any) => item.name);
|
||||||
res.visitor.date.reverse().forEach((item: any) => {
|
|
||||||
visitorOption.xAxis.data.push(item)
|
// 写入从后台拿来的数据
|
||||||
})
|
res.xAxis.forEach((item: any) => {
|
||||||
res.visitor.list[0].data.forEach((item: any) => {
|
visitorOption.xAxis.data.push(item)
|
||||||
visitorOption.series[0].data.push(item)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((err: any) => {
|
|
||||||
console.log('err', err)
|
|
||||||
})
|
})
|
||||||
|
visitorOption.series = res.series.map((item: any) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
yAxis: item.type == 'line' ? 0 : 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const sotreList = ref([]);
|
||||||
|
const getList = () => {
|
||||||
|
let date = '';
|
||||||
|
if (startEndTime.value[0] && startEndTime.value[1]) date = moment(startEndTime.value[0]).format('YYYY/MM/DD') + '-' + moment(startEndTime.value[1]).format('YYYY/MM/DD');
|
||||||
|
|
||||||
|
return
|
||||||
|
apiGetProductRanking({
|
||||||
|
date: date
|
||||||
|
}).then(res => {
|
||||||
|
sotreList.value = res;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getData()
|
getData()
|
||||||
|
getList()
|
||||||
})
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
</script>
|
<style lang="scss" scoped></style>
|
||||||
|
|
|
@ -1,172 +1,219 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="workbench">
|
<el-card>
|
||||||
<div class="lg:flex">
|
<el-form class="mb-[-16px]" :model="queryParams" label-width="80px">
|
||||||
<el-card class="!border-none mb-4 lg:mr-4 lg:w-[350px]" shadow="never">
|
<el-col :span="6">
|
||||||
|
<el-form-item label="时间筛选">
|
||||||
|
<el-date-picker v-model="date" type="daterange" range-separator="-" start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-card>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="6" class='flex mb-7' v-for="(item, index) in statisticLists" :key="index">
|
||||||
|
<img class="w-[50px] h-[50px] mr-2" :src="item.src" />
|
||||||
|
<el-statistic :title="item.title" :value="item.value" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
营业趋势
|
||||||
|
</template>
|
||||||
|
<v-charts style="height: 350px" :option="visitorOption" :autoresize="true" />
|
||||||
|
</el-card>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="14">
|
||||||
|
<el-card class="h-[100%]">
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="card-title">版本信息</span>
|
交易数据
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<tradData></tradData>
|
||||||
<div class="flex leading-9">
|
|
||||||
<div class="w-20">平台名称</div>
|
|
||||||
<span> {{ workbenchData.version.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex leading-9">
|
|
||||||
<div class="w-20">当前版本</div>
|
|
||||||
<span> {{ workbenchData.version.version }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex leading-9">
|
|
||||||
<div class="w-20">获取渠道</div>
|
|
||||||
<div>
|
|
||||||
<a :href="workbenchData.version.channel.website" target="_blank">
|
|
||||||
<el-button type="success" size="small">官网</el-button>
|
|
||||||
</a>
|
|
||||||
<a class="ml-3" :href="workbenchData.version.channel.gitee" target="_blank">
|
|
||||||
<el-button type="danger" size="small">Gitee</el-button>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="!border-none mb-4 flex-1" shadow="never">
|
</el-col>
|
||||||
|
<el-col :span="10">
|
||||||
|
<el-card>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div>
|
交易类型
|
||||||
<span class="card-title">今日数据</span>
|
|
||||||
<span class="text-tx-secondary text-xs ml-4">
|
|
||||||
更新时间:{{ workbenchData.today.time }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
<v-charts style="height: 350px" :option="tradTypeOption" :autoresize="true" />
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
配送订单统计
|
||||||
|
</template>
|
||||||
|
<v-charts style="height: 350px" :option="sendOption" :autoresize="true" />
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<div class="flex flex-wrap">
|
<el-card>
|
||||||
<div class="w-1/2 md:w-1/4">
|
<template #header>
|
||||||
<div class="leading-10">销售额</div>
|
配送订单统计
|
||||||
<div class="text-6xl">{{ workbenchData.today.today_sales }}</div>
|
</template>
|
||||||
<div class="text-tx-secondary text-xs">
|
<sendData></sendData>
|
||||||
总:{{ workbenchData.today.total_sales }}
|
</el-card>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-1/2 md:w-1/4">
|
|
||||||
<div class="leading-10">成交订单</div>
|
|
||||||
<div class="text-6xl">{{ workbenchData.today.order_num }}</div>
|
|
||||||
<div class="text-tx-secondary text-xs">
|
|
||||||
总:{{ workbenchData.today.order_sum }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-1/2 md:w-1/4">
|
|
||||||
<div class="leading-10">新增用户</div>
|
|
||||||
<div class="text-6xl">{{ workbenchData.today.today_new_user }}</div>
|
|
||||||
<div class="text-tx-secondary text-xs">
|
|
||||||
总:{{ workbenchData.today.total_new_user }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-1/2 md:w-1/4">
|
|
||||||
<div class="leading-10">新增访问量</div>
|
|
||||||
<div class="text-6xl">{{ workbenchData.today.today_visitor }}</div>
|
|
||||||
<div class="text-tx-secondary text-xs">
|
|
||||||
总:{{ workbenchData.today.total_visitor }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
<div class="function mb-4">
|
|
||||||
<el-card class="flex-1 !border-none" shadow="never">
|
|
||||||
<template #header>
|
|
||||||
<span>常用功能</span>
|
|
||||||
</template>
|
|
||||||
<div class="flex flex-wrap">
|
|
||||||
<div v-for="item in workbenchData.menu" class="md:w-[12.5%] w-1/4 flex flex-col items-center"
|
|
||||||
:key="item">
|
|
||||||
<router-link :to="item.url" class="mb-3 flex flex-col items-center">
|
|
||||||
<image-contain width="40px" height="40px" :src="item?.image" />
|
|
||||||
<div class="mt-2">{{ item.name }}</div>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
<div class="md:flex">
|
|
||||||
<el-card class="flex-1 !border-none md:mr-4 mb-4" shadow="never">
|
|
||||||
<template #header>
|
|
||||||
<span>访问量趋势图</span>
|
|
||||||
</template>
|
|
||||||
<div>
|
|
||||||
<v-charts style="height: 350px" :option="workbenchData.visitorOption" :autoresize="true" />
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="workbench">
|
<script lang="ts" setup name="manageProjectLists">
|
||||||
|
import { ref, reactive } from "vue"
|
||||||
import { getWorkbench } from '@/api/app'
|
import { getWorkbench } from '@/api/app'
|
||||||
import vCharts from 'vue-echarts'
|
import vCharts from 'vue-echarts'
|
||||||
// 表单数据
|
import tradData from "./components/tradData.vue"
|
||||||
const workbenchData: any = reactive({
|
import sendData from "./components/sendData.vue"
|
||||||
version: {
|
|
||||||
version: '', // 版本号
|
|
||||||
website: '', // 官网
|
|
||||||
based: '',
|
|
||||||
channel: {
|
|
||||||
gitee: '',
|
|
||||||
website: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
support: [],
|
|
||||||
today: {}, // 今日数据
|
|
||||||
menu: [], // 常用功能
|
|
||||||
visitor: [], // 访问量
|
|
||||||
article: [], // 文章阅读量
|
|
||||||
|
|
||||||
visitorOption: {
|
const src = ref('https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg')
|
||||||
xAxis: {
|
const date = ref("")
|
||||||
type: 'category',
|
|
||||||
data: [0]
|
|
||||||
},
|
|
||||||
yAxis: {
|
const statisticLists = reactive([
|
||||||
type: 'value'
|
{
|
||||||
},
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701552002039.png',
|
||||||
legend: {
|
title: "核销订单金额",
|
||||||
data: ['访问量']
|
value: 1000
|
||||||
},
|
},
|
||||||
itemStyle: {
|
{
|
||||||
// 点的颜色。
|
src: "https://ceshi-engineering.lihaink.cn/uploads/files/20240604/2024060417170150a511510.png",
|
||||||
color: 'red'
|
title: "余额消费金额",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701594ff8897.png',
|
||||||
|
title: "门店收益金额",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/202406041717018a22e1161.png',
|
||||||
|
title: "线下收银订单金额",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/202406041717013a08c6793.png',
|
||||||
|
title: "现金收银订单金额",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/2024060417170103b0a9686.png',
|
||||||
|
title: "门店新增用户数",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701469b91377.png',
|
||||||
|
title: "门店成交用户数",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://ceshi-engineering.lihaink.cn/uploads/files/20240604/20240604171701fbb680115.png',
|
||||||
|
title: "门店营业额",
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
const visitorOption = reactive({
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['营业额']
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
// 点的颜色。
|
||||||
|
color: 'red'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '营业额',
|
||||||
|
data: [0],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const tradTypeOption = reactive(
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
text: '交易类型',
|
||||||
|
left: 'center'
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis'
|
trigger: 'item'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'left'
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '访问量',
|
type: 'pie',
|
||||||
data: [0],
|
radius: '50%',
|
||||||
type: 'line',
|
data: [
|
||||||
smooth: true
|
{ value: 1048, name: '线上收银订单' },
|
||||||
|
{ value: 735, name: '现金收银订单' },
|
||||||
|
{ value: 580, name: '核销订单' },
|
||||||
|
{ value: 484, name: '充值订单' },
|
||||||
|
],
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const sendOption = reactive({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取工作台主页数据
|
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
getWorkbench()
|
getWorkbench()
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
workbenchData.version = res.version
|
|
||||||
workbenchData.today = res.today
|
|
||||||
workbenchData.menu = res.menu
|
|
||||||
workbenchData.visitor = res.visitor
|
|
||||||
workbenchData.support = res.support
|
|
||||||
|
|
||||||
// 清空echarts 数据
|
// 清空echarts 数据
|
||||||
workbenchData.visitorOption.xAxis.data = []
|
visitorOption.xAxis.data = []
|
||||||
workbenchData.visitorOption.series[0].data = []
|
visitorOption.series[0].data = []
|
||||||
|
|
||||||
// 写入从后台拿来的数据
|
// 写入从后台拿来的数据
|
||||||
res.visitor.date.reverse().forEach((item: any) => {
|
res.visitor.date.reverse().forEach((item: any) => {
|
||||||
workbenchData.visitorOption.xAxis.data.push(item)
|
visitorOption.xAxis.data.push(item)
|
||||||
})
|
})
|
||||||
res.visitor.list[0].data.forEach((item: any) => {
|
res.visitor.list[0].data.forEach((item: any) => {
|
||||||
workbenchData.visitorOption.series[0].data.push(item)
|
visitorOption.series[0].data.push(item)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((err: any) => {
|
.catch((err: any) => {
|
||||||
|
@ -177,6 +224,5 @@ const getData = () => {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getData()
|
getData()
|
||||||
})
|
})
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
</script>
|
|
@ -0,0 +1,182 @@
|
||||||
|
<template>
|
||||||
|
<div class="workbench">
|
||||||
|
<div class="lg:flex">
|
||||||
|
<el-card class="!border-none mb-4 lg:mr-4 lg:w-[350px]" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<span class="card-title">版本信息</span>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<div class="flex leading-9">
|
||||||
|
<div class="w-20">平台名称</div>
|
||||||
|
<span> {{ workbenchData.version.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex leading-9">
|
||||||
|
<div class="w-20">当前版本</div>
|
||||||
|
<span> {{ workbenchData.version.version }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex leading-9">
|
||||||
|
<div class="w-20">获取渠道</div>
|
||||||
|
<div>
|
||||||
|
<a :href="workbenchData.version.channel.website" target="_blank">
|
||||||
|
<el-button type="success" size="small">官网</el-button>
|
||||||
|
</a>
|
||||||
|
<a class="ml-3" :href="workbenchData.version.channel.gitee" target="_blank">
|
||||||
|
<el-button type="danger" size="small">Gitee</el-button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="!border-none mb-4 flex-1" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div>
|
||||||
|
<span class="card-title">今日数据</span>
|
||||||
|
<span class="text-tx-secondary text-xs ml-4">
|
||||||
|
更新时间:{{ workbenchData.today.time }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div class="w-1/2 md:w-1/4">
|
||||||
|
<div class="leading-10">销售额</div>
|
||||||
|
<div class="text-6xl">{{ workbenchData.today.today_sales }}</div>
|
||||||
|
<div class="text-tx-secondary text-xs">
|
||||||
|
总:{{ workbenchData.today.total_sales }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 md:w-1/4">
|
||||||
|
<div class="leading-10">成交订单</div>
|
||||||
|
<div class="text-6xl">{{ workbenchData.today.order_num }}</div>
|
||||||
|
<div class="text-tx-secondary text-xs">
|
||||||
|
总:{{ workbenchData.today.order_sum }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 md:w-1/4">
|
||||||
|
<div class="leading-10">新增用户</div>
|
||||||
|
<div class="text-6xl">{{ workbenchData.today.today_new_user }}</div>
|
||||||
|
<div class="text-tx-secondary text-xs">
|
||||||
|
总:{{ workbenchData.today.total_new_user }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/2 md:w-1/4">
|
||||||
|
<div class="leading-10">新增访问量</div>
|
||||||
|
<div class="text-6xl">{{ workbenchData.today.today_visitor }}</div>
|
||||||
|
<div class="text-tx-secondary text-xs">
|
||||||
|
总:{{ workbenchData.today.total_visitor }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div class="function mb-4">
|
||||||
|
<el-card class="flex-1 !border-none" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<span>常用功能</span>
|
||||||
|
</template>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
<div v-for="item in workbenchData.menu" class="md:w-[12.5%] w-1/4 flex flex-col items-center"
|
||||||
|
:key="item">
|
||||||
|
<router-link :to="item.url" class="mb-3 flex flex-col items-center">
|
||||||
|
<image-contain width="40px" height="40px" :src="item?.image" />
|
||||||
|
<div class="mt-2">{{ item.name }}</div>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div class="md:flex">
|
||||||
|
<el-card class="flex-1 !border-none md:mr-4 mb-4" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<span>访问量趋势图</span>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<v-charts style="height: 350px" :option="workbenchData.visitorOption" :autoresize="true" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup name="workbench">
|
||||||
|
import { getWorkbench } from '@/api/app'
|
||||||
|
import vCharts from 'vue-echarts'
|
||||||
|
// 表单数据
|
||||||
|
const workbenchData: any = reactive({
|
||||||
|
version: {
|
||||||
|
version: '', // 版本号
|
||||||
|
website: '', // 官网
|
||||||
|
based: '',
|
||||||
|
channel: {
|
||||||
|
gitee: '',
|
||||||
|
website: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
support: [],
|
||||||
|
today: {}, // 今日数据
|
||||||
|
menu: [], // 常用功能
|
||||||
|
visitor: [], // 访问量
|
||||||
|
article: [], // 文章阅读量
|
||||||
|
|
||||||
|
visitorOption: {
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: [0]
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['访问量']
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
// 点的颜色。
|
||||||
|
color: 'red'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '访问量',
|
||||||
|
data: [0],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取工作台主页数据
|
||||||
|
const getData = () => {
|
||||||
|
getWorkbench()
|
||||||
|
.then((res: any) => {
|
||||||
|
workbenchData.version = res.version
|
||||||
|
workbenchData.today = res.today
|
||||||
|
workbenchData.menu = res.menu
|
||||||
|
workbenchData.visitor = res.visitor
|
||||||
|
workbenchData.support = res.support
|
||||||
|
|
||||||
|
// 清空echarts 数据
|
||||||
|
workbenchData.visitorOption.xAxis.data = []
|
||||||
|
workbenchData.visitorOption.series[0].data = []
|
||||||
|
|
||||||
|
// 写入从后台拿来的数据
|
||||||
|
res.visitor.date.reverse().forEach((item: any) => {
|
||||||
|
workbenchData.visitorOption.xAxis.data.push(item)
|
||||||
|
})
|
||||||
|
res.visitor.list[0].data.forEach((item: any) => {
|
||||||
|
workbenchData.visitorOption.series[0].data.push(item)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
console.log('err', err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
Loading…
Reference in New Issue