浏览代码

✨ feat: 新增商品列表, 功能组件化

WanGxC 1 年之前
父节点
当前提交
0fd99c4516

+ 155 - 0
package-lock.json

@@ -2128,6 +2128,18 @@
 			"resolved": "https://registry.npmmirror.com/@cropper/utils/-/utils-2.0.0-beta.4.tgz",
 			"resolved": "https://registry.npmmirror.com/@cropper/utils/-/utils-2.0.0-beta.4.tgz",
 			"integrity": "sha512-mrUTA3LbEq1Y3nPTC5X6koTd2Dk8P+6xTuhp4P8X3mg5Z7d8AVK+0OU5kbB49OLAaEfvGEqbZJ84rLwgMy9RHw=="
 			"integrity": "sha512-mrUTA3LbEq1Y3nPTC5X6koTd2Dk8P+6xTuhp4P8X3mg5Z7d8AVK+0OU5kbB49OLAaEfvGEqbZJ84rLwgMy9RHw=="
 		},
 		},
+		"@css-render/plugin-bem": {
+			"version": "0.15.12",
+			"resolved": "https://registry.npmmirror.com/@css-render/plugin-bem/-/plugin-bem-0.15.12.tgz",
+			"integrity": "sha512-Lq2jSOZn+wYQtsyaFj6QRz2EzAnd3iW5fZeHO1WSXQdVYwvwGX0ZiH3X2JQgtgYLT1yeGtrwrqJdNdMEUD2xTw==",
+			"dev": true
+		},
+		"@css-render/vue3-ssr": {
+			"version": "0.15.12",
+			"resolved": "https://registry.npmmirror.com/@css-render/vue3-ssr/-/vue3-ssr-0.15.12.tgz",
+			"integrity": "sha512-AQLGhhaE0F+rwybRCkKUdzBdTEM/5PZBYy+fSYe1T9z9+yxMuV/k7ZRqa4M69X+EI1W8pa4kc9Iq2VjQkZx4rg==",
+			"dev": true
+		},
 		"@ctrl/tinycolor": {
 		"@ctrl/tinycolor": {
 			"version": "3.6.1",
 			"version": "3.6.1",
 			"resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
 			"resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
@@ -2138,6 +2150,12 @@
 			"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
 			"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
 			"integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg=="
 			"integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg=="
 		},
 		},
+		"@emotion/hash": {
+			"version": "0.8.0",
+			"resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz",
+			"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
+			"dev": true
+		},
 		"@esbuild/android-arm": {
 		"@esbuild/android-arm": {
 			"version": "0.18.20",
 			"version": "0.18.20",
 			"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
 			"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -2753,6 +2771,12 @@
 				"@jridgewell/sourcemap-codec": "^1.4.14"
 				"@jridgewell/sourcemap-codec": "^1.4.14"
 			}
 			}
 		},
 		},
+		"@juggle/resize-observer": {
+			"version": "3.4.0",
+			"resolved": "https://registry.npmmirror.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
+			"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==",
+			"dev": true
+		},
 		"@nodelib/fs.scandir": {
 		"@nodelib/fs.scandir": {
 			"version": "2.1.5",
 			"version": "2.1.5",
 			"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
 			"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -3395,6 +3419,12 @@
 			"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
 			"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
 			"dev": true
 			"dev": true
 		},
 		},
+		"@types/katex": {
+			"version": "0.16.7",
+			"resolved": "https://registry.npmmirror.com/@types/katex/-/katex-0.16.7.tgz",
+			"integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==",
+			"dev": true
+		},
 		"@types/lodash": {
 		"@types/lodash": {
 			"version": "4.14.202",
 			"version": "4.14.202",
 			"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.202.tgz",
 			"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.202.tgz",
@@ -4451,6 +4481,24 @@
 			"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz",
 			"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz",
 			"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
 			"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
 		},
 		},
+		"css-render": {
+			"version": "0.15.12",
+			"resolved": "https://registry.npmmirror.com/css-render/-/css-render-0.15.12.tgz",
+			"integrity": "sha512-eWzS66patiGkTTik+ipO9qNGZ+uNuGyTmnz6/+EJIiFg8+3yZRpnMwgFo8YdXhQRsiePzehnusrxVvugNjXzbw==",
+			"dev": true,
+			"requires": {
+				"@emotion/hash": "~0.8.0",
+				"csstype": "~3.0.5"
+			},
+			"dependencies": {
+				"csstype": {
+					"version": "3.0.11",
+					"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.0.11.tgz",
+					"integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==",
+					"dev": true
+				}
+			}
+		},
 		"cssesc": {
 		"cssesc": {
 			"version": "3.0.0",
 			"version": "3.0.0",
 			"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
 			"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@@ -4482,6 +4530,21 @@
 				}
 				}
 			}
 			}
 		},
 		},
+		"date-fns": {
+			"version": "2.30.0",
+			"resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz",
+			"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+			"dev": true,
+			"requires": {
+				"@babel/runtime": "^7.21.0"
+			}
+		},
+		"date-fns-tz": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmmirror.com/date-fns-tz/-/date-fns-tz-2.0.0.tgz",
+			"integrity": "sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==",
+			"dev": true
+		},
 		"dateformat": {
 		"dateformat": {
 			"version": "2.2.0",
 			"version": "2.2.0",
 			"resolved": "https://registry.npmmirror.com/dateformat/-/dateformat-2.2.0.tgz",
 			"resolved": "https://registry.npmmirror.com/dateformat/-/dateformat-2.2.0.tgz",
@@ -5028,6 +5091,12 @@
 			"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-2.0.3.tgz",
 			"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-2.0.3.tgz",
 			"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
 			"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
 		},
 		},
+		"evtd": {
+			"version": "0.2.4",
+			"resolved": "https://registry.npmmirror.com/evtd/-/evtd-0.2.4.tgz",
+			"integrity": "sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==",
+			"dev": true
+		},
 		"ext": {
 		"ext": {
 			"version": "1.7.0",
 			"version": "1.7.0",
 			"resolved": "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz",
 			"resolved": "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz",
@@ -5404,6 +5473,12 @@
 				}
 				}
 			}
 			}
 		},
 		},
+		"highlight.js": {
+			"version": "11.9.0",
+			"resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.9.0.tgz",
+			"integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==",
+			"dev": true
+		},
 		"html-tags": {
 		"html-tags": {
 			"version": "3.3.1",
 			"version": "3.3.1",
 			"resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-3.3.1.tgz",
 			"resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-3.3.1.tgz",
@@ -6066,6 +6141,41 @@
 				"thenify-all": "^1.0.0"
 				"thenify-all": "^1.0.0"
 			}
 			}
 		},
 		},
+		"naive-ui": {
+			"version": "2.38.1",
+			"resolved": "https://registry.npmmirror.com/naive-ui/-/naive-ui-2.38.1.tgz",
+			"integrity": "sha512-AnU1FQ7K/CbhguAX++V4kCFjk7h7RvWt4nvZPRjORMpq+fUIlzD+EcQ5Cv1VqDloNF8+eMv4Akc2Ogacc9S+5A==",
+			"dev": true,
+			"requires": {
+				"@css-render/plugin-bem": "^0.15.12",
+				"@css-render/vue3-ssr": "^0.15.12",
+				"@types/katex": "^0.16.2",
+				"@types/lodash": "^4.14.198",
+				"@types/lodash-es": "^4.17.9",
+				"async-validator": "^4.2.5",
+				"css-render": "^0.15.12",
+				"csstype": "^3.1.3",
+				"date-fns": "^2.30.0",
+				"date-fns-tz": "^2.0.0",
+				"evtd": "^0.2.4",
+				"highlight.js": "^11.8.0",
+				"lodash": "^4.17.21",
+				"lodash-es": "^4.17.21",
+				"seemly": "^0.3.8",
+				"treemate": "^0.3.11",
+				"vdirs": "^0.1.8",
+				"vooks": "^0.2.12",
+				"vueuc": "^0.4.58"
+			},
+			"dependencies": {
+				"csstype": {
+					"version": "3.1.3",
+					"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
+					"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+					"dev": true
+				}
+			}
+		},
 		"namespace-emitter": {
 		"namespace-emitter": {
 			"version": "2.0.1",
 			"version": "2.0.1",
 			"resolved": "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
 			"resolved": "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
@@ -6711,6 +6821,12 @@
 				"get-ready": "~1.0.0"
 				"get-ready": "~1.0.0"
 			}
 			}
 		},
 		},
+		"seemly": {
+			"version": "0.3.8",
+			"resolved": "https://registry.npmmirror.com/seemly/-/seemly-0.3.8.tgz",
+			"integrity": "sha512-MW8Qs6vbzo0pHmDpFSYPna+lwpZ6Zk1ancbajw/7E8TKtHdV+1DfZZD+kKJEhG/cAoB/i+LiT+5msZOqj0DwRA==",
+			"dev": true
+		},
 		"select": {
 		"select": {
 			"version": "1.1.2",
 			"version": "1.1.2",
 			"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
 			"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
@@ -7111,6 +7227,12 @@
 				"is-number": "^7.0.0"
 				"is-number": "^7.0.0"
 			}
 			}
 		},
 		},
+		"treemate": {
+			"version": "0.3.11",
+			"resolved": "https://registry.npmmirror.com/treemate/-/treemate-0.3.11.tgz",
+			"integrity": "sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==",
+			"dev": true
+		},
 		"ts-interface-checker": {
 		"ts-interface-checker": {
 			"version": "0.1.13",
 			"version": "0.1.13",
 			"resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
 			"resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@@ -7384,6 +7506,15 @@
 				"@sphinxxxx/color-conversion": "^2.2.2"
 				"@sphinxxxx/color-conversion": "^2.2.2"
 			}
 			}
 		},
 		},
+		"vdirs": {
+			"version": "0.1.8",
+			"resolved": "https://registry.npmmirror.com/vdirs/-/vdirs-0.1.8.tgz",
+			"integrity": "sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==",
+			"dev": true,
+			"requires": {
+				"evtd": "^0.2.2"
+			}
+		},
 		"vite": {
 		"vite": {
 			"version": "4.4.11",
 			"version": "4.4.11",
 			"resolved": "https://registry.npmmirror.com/vite/-/vite-4.4.11.tgz",
 			"resolved": "https://registry.npmmirror.com/vite/-/vite-4.4.11.tgz",
@@ -7465,6 +7596,15 @@
 				}
 				}
 			}
 			}
 		},
 		},
+		"vooks": {
+			"version": "0.2.12",
+			"resolved": "https://registry.npmmirror.com/vooks/-/vooks-0.2.12.tgz",
+			"integrity": "sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==",
+			"dev": true,
+			"requires": {
+				"evtd": "^0.2.2"
+			}
+		},
 		"vue": {
 		"vue": {
 			"version": "3.3.4",
 			"version": "3.3.4",
 			"resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz",
 			"resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz",
@@ -7610,6 +7750,21 @@
 				}
 				}
 			}
 			}
 		},
 		},
+		"vueuc": {
+			"version": "0.4.58",
+			"resolved": "https://registry.npmmirror.com/vueuc/-/vueuc-0.4.58.tgz",
+			"integrity": "sha512-Wnj/N8WbPRSxSt+9ji1jtDHPzda5h2OH/0sFBhvdxDRuyCZbjGg3/cKMaKqEoe+dErTexG2R+i6Q8S/Toq1MYg==",
+			"dev": true,
+			"requires": {
+				"@css-render/vue3-ssr": "^0.15.10",
+				"@juggle/resize-observer": "^3.3.1",
+				"css-render": "^0.15.10",
+				"evtd": "^0.2.4",
+				"seemly": "^0.3.6",
+				"vdirs": "^0.1.4",
+				"vooks": "^0.2.4"
+			}
+		},
 		"vxe-table": {
 		"vxe-table": {
 			"version": "4.5.20",
 			"version": "4.5.20",
 			"resolved": "https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.20.tgz",
 			"resolved": "https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.20.tgz",

+ 1 - 0
package.json

@@ -66,6 +66,7 @@
 		"@vue/compiler-sfc": "^3.2.45",
 		"@vue/compiler-sfc": "^3.2.45",
 		"eslint": "^8.29.0",
 		"eslint": "^8.29.0",
 		"eslint-plugin-vue": "^9.8.0",
 		"eslint-plugin-vue": "^9.8.0",
+		"naive-ui": "^2.38.1",
 		"prettier": "^2.8.1",
 		"prettier": "^2.8.1",
 		"sass": "^1.56.2",
 		"sass": "^1.56.2",
 		"typescript": "^4.9.4",
 		"typescript": "^4.9.4",

+ 54 - 44
src/main.ts

@@ -1,36 +1,36 @@
-import { createApp } from 'vue';
-import App from './App.vue';
-import router from './router';
-import { directive } from '/@/utils/directive';
-import { i18n } from '/@/i18n';
-import other from '/@/utils/other';
-import '/@/assets/style/tailwind.css'; // 先引入tailwind css, 以免element-plus冲突
-import ElementPlus from 'element-plus';
-import 'element-plus/dist/index.css';
-import '/@/theme/index.scss';
-import mitt from 'mitt';
-import VueGridLayout from 'vue-grid-layout';
-import piniaPersist from 'pinia-plugin-persist';
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import { directive } from '/@/utils/directive'
+import { i18n } from '/@/i18n'
+import other from '/@/utils/other'
+import '/@/assets/style/tailwind.css' // 先引入tailwind css, 以免element-plus冲突
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+import '/@/theme/index.scss'
+import mitt from 'mitt'
+import VueGridLayout from 'vue-grid-layout'
+import piniaPersist from 'pinia-plugin-persist'
 // @ts-ignore
 // @ts-ignore
-import fastCrud from './settings.ts';
-import pinia from './stores';
-import permission from '/@/plugin/permission/index';
+import fastCrud from './settings.ts'
+import pinia from './stores'
+import permission from '/@/plugin/permission/index'
 // @ts-ignore
 // @ts-ignore
-import eIconPicker, { iconList, analyzingIconForIconfont } from 'e-icon-picker';
-import 'e-icon-picker/icon/default-icon/symbol.js'; //基本彩色图标库
-import 'e-icon-picker/index.css'; // 基本样式,包含基本图标
-import 'font-awesome/css/font-awesome.min.css';
-import elementPlus from 'e-icon-picker/icon/ele/element-plus.js'; //element-plus的图标
-import fontAwesome470 from 'e-icon-picker/icon/fontawesome/font-awesome.v4.7.0.js'; //fontAwesome470的图标
-import eIconList from 'e-icon-picker/icon/default-icon/eIconList.js';
-import iconfont from '/@/assets/iconfont/iconfont.json'; //引入json文件
-import '/@/assets/iconfont/iconfont.css'; //引入css
+import eIconPicker, { iconList, analyzingIconForIconfont } from 'e-icon-picker'
+import 'e-icon-picker/icon/default-icon/symbol.js' //基本彩色图标库
+import 'e-icon-picker/index.css' // 基本样式,包含基本图标
+import 'font-awesome/css/font-awesome.min.css'
+import elementPlus from 'e-icon-picker/icon/ele/element-plus.js' //element-plus的图标
+import fontAwesome470 from 'e-icon-picker/icon/fontawesome/font-awesome.v4.7.0.js' //fontAwesome470的图标
+import eIconList from 'e-icon-picker/icon/default-icon/eIconList.js'
+import iconfont from '/@/assets/iconfont/iconfont.json' //引入json文件
+import '/@/assets/iconfont/iconfont.css' //引入css
 // 自动注册插件
 // 自动注册插件
-import { scanAndInstallPlugins } from '/@/views/plugins/index';
+import { scanAndInstallPlugins } from '/@/views/plugins/index'
 import VXETable from 'vxe-table'
 import VXETable from 'vxe-table'
 import 'vxe-table/lib/style.css'
 import 'vxe-table/lib/style.css'
 
 
-import '/@/assets/style/reset.scss';
+import '/@/assets/style/reset.scss'
 import 'element-tree-line/dist/style.css'
 import 'element-tree-line/dist/style.css'
 
 
 import dayjs from 'dayjs'
 import dayjs from 'dayjs'
@@ -38,34 +38,44 @@ import UTC from 'dayjs/plugin/utc'
 import Timezon from 'dayjs/plugin/timezone'
 import Timezon from 'dayjs/plugin/timezone'
 import IsSameOrBefore from 'dayjs/plugin/isSameOrBefore'
 import IsSameOrBefore from 'dayjs/plugin/isSameOrBefore'
 import 'dayjs/locale/zh-cn'
 import 'dayjs/locale/zh-cn'
+import {
+  // create naive ui
+  create,
+  // component
+  NButton,
+} from 'naive-ui'
 
 
 dayjs.extend(UTC)
 dayjs.extend(UTC)
 dayjs.extend(Timezon)
 dayjs.extend(Timezon)
 dayjs.extend(IsSameOrBefore)
 dayjs.extend(IsSameOrBefore)
 dayjs.locale('zh-cn')
 dayjs.locale('zh-cn')
 
 
-let forIconfont = analyzingIconForIconfont(iconfont); //解析class
-iconList.addIcon(forIconfont.list); // 添加iconfont dvadmin3的icon
-iconList.addIcon(elementPlus); // 添加element plus的图标
-iconList.addIcon(fontAwesome470); // 添加fontAwesome 470版本的图标
+let forIconfont = analyzingIconForIconfont(iconfont) //解析class
+iconList.addIcon(forIconfont.list) // 添加iconfont dvadmin3的icon
+iconList.addIcon(elementPlus) // 添加element plus的图标
+iconList.addIcon(fontAwesome470) // 添加fontAwesome 470版本的图标
 
 
-let app = createApp(App);
+const naive = create({
+  components: [NButton],
+})
 
 
-scanAndInstallPlugins(app);
+let app = createApp(App)
 
 
-app.use(eIconPicker, {
-	addIconList: eIconList, //全局添加图标
-	removeIconList: [], //全局删除图标
-	zIndex: 3100, //选择器弹层的最低层,全局配置
-});
+scanAndInstallPlugins(app)
 
 
-pinia.use(piniaPersist);
-directive(app);
-other.elSvg(app);
+app.use(eIconPicker, {
+  addIconList: eIconList, //全局添加图标
+  removeIconList: [], //全局删除图标
+  zIndex: 3100, //选择器弹层的最低层,全局配置
+})
 
 
+pinia.use(piniaPersist)
+directive(app)
+other.elSvg(app)
 
 
+app.use(naive)
 app.use(VXETable)
 app.use(VXETable)
-app.use(permission);
-app.use(pinia).use(router).use(ElementPlus, { i18n: i18n.global.t }).use(i18n).use(VueGridLayout).use(fastCrud).mount('#app');
+app.use(permission)
+app.use(pinia).use(router).use(ElementPlus, { i18n: i18n.global.t }).use(i18n).use(VueGridLayout).use(fastCrud).mount('#app')
 
 
-app.config.globalProperties.mittBus = mitt();
+app.config.globalProperties.mittBus = mitt()

+ 21 - 0
src/views/productCenter/productList/components/ProductLineDialog.vue

@@ -0,0 +1,21 @@
+<template>
+  <el-dialog v-model="createProductDialog" title="Tips" width="500">
+    <span>This is a message</span>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import { onBeforeUnmount, ref } from 'vue'
+import emitter from '/@/utils/emitter'
+
+const createProductDialog = ref(false)
+emitter.on('create-product-dialog', (value: any) => {
+  createProductDialog.value = value.isVisible
+})
+
+onBeforeUnmount(() => {
+  emitter.all.clear()
+})
+</script>
+
+<style scoped></style>

+ 34 - 0
src/views/productCenter/productList/components/ProductTab.vue

@@ -0,0 +1,34 @@
+<template>
+  <div style="width: 100%; padding: 12px">
+    <el-scrollbar>
+      <div class="scrollbar-flex-content">
+        <el-card v-for="item in 50" :key="item" class="scrollbar-demo-item">
+          {{ item }}
+        </el-card>
+      </div>
+    </el-scrollbar>
+  </div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped>
+.scrollbar-flex-content {
+  display: flex;
+}
+.scrollbar-demo-item {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100px;
+  height: 50px;
+  margin: 10px;
+  text-align: center;
+  border-radius: 4px;
+  background: var(--el-color-danger-light-9);
+  color: var(--el-color-danger);
+}
+</style>

+ 24 - 0
src/views/productCenter/productList/components/TopFilters.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="filters">
+      <el-input placeholder="ASIN/父ASIN/标题/SKU"></el-input>
+      <el-select style="width: 300px"></el-select>
+      <DateRangePicker v-model="dateRange"></DateRangePicker>
+    </div>
+</template>
+
+<script setup lang="ts">
+import DateRangePicker from '/@/components/DateRangePicker/index.vue'
+import { storeToRefs } from 'pinia'
+import { usePublicData } from '/@/stores/publicData'
+
+const publicData = usePublicData()
+const { dateRange } = storeToRefs(publicData)
+</script>
+
+<style scoped>
+.filters {
+  display: flex;
+  justify-content: space-between;
+  gap: 10px;
+}
+</style>

+ 18 - 0
src/views/productCenter/productList/hooks/index.ts

@@ -0,0 +1,18 @@
+import { ref } from 'vue'
+
+export function useButtonGroup() {
+  const buttons = ['产品线', '父ASIN', 'ASIN', 'SKU'] // 按钮列表
+  const activeButton = ref('')
+  const activeStyle = {
+    color: '#3a83f7',
+    backgroundColor: '#ebeef5',
+  }
+
+  function handleClickBtn(buttonName) {
+    activeButton.value = buttonName // 更新当前激活的按钮
+    console.log(activeButton.value)
+  }
+
+  // 返回需要在模板中使用的响应式数据和方法
+  return { buttons, activeButton, activeStyle, handleClickBtn }
+}

+ 81 - 54
src/views/productCenter/productList/index.vue

@@ -1,10 +1,6 @@
 <template>
 <template>
   <div class="outer-container">
   <div class="outer-container">
-    <div class="filters">
-      <el-input placeholder="ASIN/父ASIN/标题/SKU"></el-input>
-      <el-select style="width: 300px"></el-select>
-      <DateRangePicker v-model="dateRange"></DateRangePicker>
-    </div>
+    <TopFilters></TopFilters>
     <div class="table-tips">
     <div class="table-tips">
       <el-icon><Warning /></el-icon>
       <el-icon><Warning /></el-icon>
       <p style="margin-left: 3px">商品中心广告数据统计不包含SB广告</p>
       <p style="margin-left: 3px">商品中心广告数据统计不包含SB广告</p>
@@ -19,46 +15,62 @@
       </DataTendencyChart>
       </DataTendencyChart>
     </el-card>
     </el-card>
   </div>
   </div>
-
-  <div style="width: 100%; padding: 12px">
-    <el-scrollbar>
-      <div class="scrollbar-flex-content">
-        <el-card v-for="item in 50" :key="item" class="scrollbar-demo-item">
-          {{ item }}
-        </el-card>
-      </div>
-    </el-scrollbar>
-  </div>
-
+  <ProductTab></ProductTab>
   <div class="pl-and-asin-tables">
   <div class="pl-and-asin-tables">
     <div class="asin-table-container">
     <div class="asin-table-container">
       <div class="xp-radio-group-wrapper">
       <div class="xp-radio-group-wrapper">
         <el-button-group>
         <el-button-group>
-          <el-button bg pain>产品线</el-button>
-          <el-button bg pain>父ASIN</el-button>
-          <el-button bg pain>ASIN</el-button>
-          <el-button bg pain>SKU</el-button>
+          <el-button
+            bg
+            text
+            v-for="button in buttons"
+            :key="button"
+            :style="activeButton === button ? activeStyle : {}"
+            @click="() => handleClickBtn(button)">
+            {{ button }}
+          </el-button>
         </el-button-group>
         </el-button-group>
       </div>
       </div>
-      <div style="width: auto">
-        <el-table :data="tableData">
-          <el-table-column prop="date" label="Date" />
-          <el-table-column prop="name" label="Name" />
-          <el-table-column prop="address" label="Address" />
-        </el-table>
+      <div>
+        <vxe-toolbar ref="toolbarRef" custom>
+          <template #buttons>
+            <vxe-button type="text" status="primary" content="创建产品线" icon="vxe-icon-add" @click="visibleDialog"></vxe-button>
+          </template>
+          <template #tools>
+            <vxe-button type="text" icon="vxe-icon-undo" class="tool-btn"></vxe-button>
+            <vxe-button type="text" icon="vxe-icon-funnel" class="tool-btn" @click="funnelEvent"></vxe-button>
+          </template>
+        </vxe-toolbar>
+      </div>
+      <div style="overflow: hidden; width: 100%; height: 600px">
+        <vxe-table ref="tableRef" round height="auto" :data="tableData" :column-config="{ resizable: true }" :row-config="{ isHover: true }">
+          <vxe-column field="name" title="Name" width="300"></vxe-column>
+          <vxe-column field="sex" title="最小列宽" min-width="300"></vxe-column>
+          <vxe-column field="age" title="Age"></vxe-column>
+          <vxe-column field="time" title="Time"></vxe-column>
+          <vxe-column field="address" title="Address" show-overflow></vxe-column>
+        </vxe-table>
+      </div>
+      <div>
+        <vxe-pager v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize" :total="pagination.total" size="small" />
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
+<ProductLineDialog></ProductLineDialog>
 </template>
 </template>
 
 
-<script setup lang="ts">
+<script setup>
+import ProductTab from './components/ProductTab.vue'
+import ProductLineDialog from './components/ProductLineDialog.vue'
+import TopFilters from './components/TopFilters.vue'
+import { ref, reactive, nextTick } from 'vue'
 import { storeToRefs } from 'pinia'
 import { storeToRefs } from 'pinia'
 import { usePublicData } from '/@/stores/publicData'
 import { usePublicData } from '/@/stores/publicData'
-import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
 import DataTendencyChart from '/@/views/adManage/sb/chartComponents/dataTendency.vue'
 import { useShopInfo } from '/@/stores/shopInfo'
 import { useShopInfo } from '/@/stores/shopInfo'
 import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
 import { getCardData, getLineData, getLineMonthData, getLineWeekData } from './api'
-import { ref } from 'vue'
+import { useButtonGroup } from './hooks/index'
+import emitter from '/@/utils/emitter'
 
 
 const publicData = usePublicData()
 const publicData = usePublicData()
 const { dateRange } = storeToRefs(publicData)
 const { dateRange } = storeToRefs(publicData)
@@ -69,23 +81,56 @@ const queryParams = ref({
   dateRange,
   dateRange,
 })
 })
 
 
+// 按钮组
+const { buttons, activeButton, activeStyle, handleClickBtn } = useButtonGroup()
+
+// Table相关
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 10,
+})
+const tableRef = ref()
+const toolbarRef = ref()
+
+function funnelEvent() {
+  VXETable.modal.alert({ content: '点击事件' })
+}
+nextTick(() => {
+  // 将表格和工具栏进行关联
+  const $table = tableRef.value
+  const $toolbar = toolbarRef.value
+  if ($table && $toolbar) {
+    $table.connect($toolbar)
+  }
+})
+
 const tableData = ref([
 const tableData = ref([
   { id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
   { id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
   { id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
   { id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
   { id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
   { id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
-  { id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
+  { id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 23, address: 'test abc' },
+  { id: 10005, name: 'Test5', role: 'Develop', sex: 'Women', age: 30, address: 'Shanghai' },
+  { id: 10006, name: 'Test6', role: 'Designer', sex: 'Women', age: 21, address: 'test abc' },
+  { id: 10007, name: 'Test7', role: 'Test', sex: 'Man', age: 29, address: 'test abc' },
+  { id: 10008, name: 'Test8', role: 'Develop', sex: 'Man', age: 35, address: 'test abc' },
+  { id: 10009, name: 'Test9', role: 'Develop', sex: 'Man', age: 35, address: 'test abc' },
+  { id: 100010, name: 'Test10', role: 'Develop', sex: 'Man', age: 35, address: 'test abc' },
+  { id: 100011, name: 'Test11', role: 'Develop', sex: 'Man', age: 35, address: 'test abc' },
+  { id: 100012, name: 'Test12', role: 'Develop', sex: 'Man', age: 35, address: 'test abc' },
+  { id: 100013, name: 'Test13', role: 'Develop', sex: 'Man', age: 35, address: 'test abc' },
 ])
 ])
+
+// 激活弹窗
+function visibleDialog() {
+  emitter.emit('create-product-dialog', {isVisible: true})
+}
 </script>
 </script>
 
 
 <style scoped>
 <style scoped>
 .outer-container {
 .outer-container {
   padding: 5px 10px 0 10px;
   padding: 5px 10px 0 10px;
 }
 }
-.filters {
-  display: flex;
-  justify-content: space-between;
-  gap: 10px;
-}
 .table-tips {
 .table-tips {
   color: #8d9095;
   color: #8d9095;
   display: flex;
   display: flex;
@@ -95,9 +140,6 @@ const tableData = ref([
 .pl-and-asin-tables {
 .pl-and-asin-tables {
   padding: 10px 12px 0 12px;
   padding: 10px 12px 0 12px;
 }
 }
-.product-lines {
-  display: flex;
-}
 .asin-table-container {
 .asin-table-container {
   width: 100%;
   width: 100%;
   padding: 8px;
   padding: 8px;
@@ -112,20 +154,5 @@ const tableData = ref([
   margin-bottom: 12px;
   margin-bottom: 12px;
   align-items: center;
   align-items: center;
 }
 }
-.scrollbar-flex-content {
-  display: flex;
-}
-.scrollbar-demo-item {
-  flex-shrink: 0;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 100px;
-  height: 50px;
-  margin: 10px;
-  text-align: center;
-  border-radius: 4px;
-  background: var(--el-color-danger-light-9);
-  color: var(--el-color-danger);
-}
+
 </style>
 </style>