Ver Fonte

Merge remote-tracking branch 'origin/lyz_dev'

# Conflicts:
#	src/views/layout/components/Menu.vue
#	src/views/layout/index.vue
suwenjiang há 1 semana atrás
pai
commit
82ffa07aef

+ 1 - 0
package.json

@@ -32,6 +32,7 @@
     "@vitejs/plugin-vue": "^5.2.1",
     "sass-embedded": "^1.85.0",
     "typescript": "^5.7.3",
+    "unplugin-element-plus": "^0.9.1",
     "vite": "^6.0.3"
   },
   "pnpm": {

+ 82 - 0
pnpm-lock.yaml

@@ -54,6 +54,9 @@ importers:
       typescript:
         specifier: ^5.7.3
         version: 5.7.3
+      unplugin-element-plus:
+        specifier: ^0.9.1
+        version: 0.9.1
       vite:
         specifier: ^6.0.3
         version: 6.1.1(jiti@2.4.2)(lightningcss@1.29.1)(sass-embedded@1.85.0)
@@ -297,51 +300,61 @@ packages:
     resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==}
     cpu: [arm]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-arm-musleabihf@4.34.8':
     resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==}
     cpu: [arm]
     os: [linux]
+    libc: [musl]
 
   '@rollup/rollup-linux-arm64-gnu@4.34.8':
     resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==}
     cpu: [arm64]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-arm64-musl@4.34.8':
     resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==}
     cpu: [arm64]
     os: [linux]
+    libc: [musl]
 
   '@rollup/rollup-linux-loongarch64-gnu@4.34.8':
     resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==}
     cpu: [loong64]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-powerpc64le-gnu@4.34.8':
     resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==}
     cpu: [ppc64]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-riscv64-gnu@4.34.8':
     resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==}
     cpu: [riscv64]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-s390x-gnu@4.34.8':
     resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==}
     cpu: [s390x]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-x64-gnu@4.34.8':
     resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==}
     cpu: [x64]
     os: [linux]
+    libc: [glibc]
 
   '@rollup/rollup-linux-x64-musl@4.34.8':
     resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==}
     cpu: [x64]
     os: [linux]
+    libc: [musl]
 
   '@rollup/rollup-win32-arm64-msvc@4.34.8':
     resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==}
@@ -399,24 +412,28 @@ packages:
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
+    libc: [glibc]
 
   '@tailwindcss/oxide-linux-arm64-musl@4.0.8':
     resolution: {integrity: sha512-5tz2IL7LN58ssGEq7h/staD7pu/izF/KeMWdlJ86WDe2Ah46LF3ET6ZGKTr5eZMrnEA0M9cVFuSPprKRHNgjeg==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
+    libc: [musl]
 
   '@tailwindcss/oxide-linux-x64-gnu@4.0.8':
     resolution: {integrity: sha512-KSzMkhyrxAQyY2o194NKVKU9j/c+NFSoMvnHWFaNHKi3P1lb+Vq1UC19tLHrmxSkKapcMMu69D7+G1+FVGNDXQ==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
+    libc: [glibc]
 
   '@tailwindcss/oxide-linux-x64-musl@4.0.8':
     resolution: {integrity: sha512-yFYKG5UtHTRimjtqxUWXBgI4Tc6NJe3USjRIVdlTczpLRxq/SFwgzGl5JbatCxgSRDPBFwRrNPxq+ukfQFGdrw==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
+    libc: [musl]
 
   '@tailwindcss/oxide-win32-arm64-msvc@4.0.8':
     resolution: {integrity: sha512-tndGujmCSba85cRCnQzXgpA2jx5gXimyspsUYae5jlPyLRG0RjXbDshFKOheVXU4TLflo7FSG8EHCBJ0EHTKdQ==}
@@ -465,24 +482,28 @@ packages:
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
+    libc: [glibc]
 
   '@tauri-apps/cli-linux-arm64-musl@2.2.7':
     resolution: {integrity: sha512-+8HZ+txff/Y3YjAh80XcLXcX8kpGXVdr1P8AfjLHxHdS6QD4Md+acSxGTTNbplmHuBaSHJvuTvZf9tU1eDCTDg==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
+    libc: [musl]
 
   '@tauri-apps/cli-linux-x64-gnu@2.2.7':
     resolution: {integrity: sha512-ahlSnuCnUntblp9dG7/w5ZWZOdzRFi3zl0oScgt7GF4KNAOEa7duADsxPA4/FT2hLRa0SvpqtD4IYFvCxoVv3Q==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
+    libc: [glibc]
 
   '@tauri-apps/cli-linux-x64-musl@2.2.7':
     resolution: {integrity: sha512-+qKAWnJRSX+pjjRbKAQgTdFY8ecdcu8UdJ69i7wn3ZcRn2nMMzOO2LOMOTQV42B7/Q64D1pIpmZj9yblTMvadA==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
+    libc: [musl]
 
   '@tauri-apps/cli-win32-arm64-msvc@2.2.7':
     resolution: {integrity: sha512-aa86nRnrwT04u9D9fhf5JVssuAZlUCCc8AjqQjqODQjMd4BMA2+d4K9qBMpEG/1kVh95vZaNsLogjEaqSTTw4A==}
@@ -582,6 +603,11 @@ packages:
   '@vueuse/shared@9.13.0':
     resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
 
+  acorn@8.14.0:
+    resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+
   async-validator@4.2.5:
     resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
 
@@ -622,6 +648,9 @@ packages:
     resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
     engines: {node: '>=0.12'}
 
+  es-module-lexer@1.6.0:
+    resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
+
   esbuild@0.24.2:
     resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
     engines: {node: '>=18'}
@@ -688,24 +717,28 @@ packages:
     engines: {node: '>= 12.0.0'}
     cpu: [arm64]
     os: [linux]
+    libc: [glibc]
 
   lightningcss-linux-arm64-musl@1.29.1:
     resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==}
     engines: {node: '>= 12.0.0'}
     cpu: [arm64]
     os: [linux]
+    libc: [musl]
 
   lightningcss-linux-x64-gnu@1.29.1:
     resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==}
     engines: {node: '>= 12.0.0'}
     cpu: [x64]
     os: [linux]
+    libc: [glibc]
 
   lightningcss-linux-x64-musl@1.29.1:
     resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==}
     engines: {node: '>= 12.0.0'}
     cpu: [x64]
     os: [linux]
+    libc: [musl]
 
   lightningcss-win32-arm64-msvc@1.29.1:
     resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==}
@@ -753,12 +786,19 @@ packages:
   normalize-wheel-es@1.2.0:
     resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
 
+  pathe@2.0.3:
+    resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
   perfect-debounce@1.0.0:
     resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
 
   picocolors@1.1.1:
     resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
 
+  picomatch@4.0.2:
+    resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+    engines: {node: '>=12'}
+
   pinia@3.0.1:
     resolution: {integrity: sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==}
     peerDependencies:
@@ -947,6 +987,18 @@ packages:
     engines: {node: '>=14.17'}
     hasBin: true
 
+  unplugin-element-plus@0.9.1:
+    resolution: {integrity: sha512-TtQ7bj82gM1Hw5A+LmG/oFrvYb6L0BqhxVUl7djMiicvk7LjdUiP70QhTKaBY/tiFR9NJCIPYSmw4naCuhK7Hg==}
+    engines: {node: '>=18.12.0'}
+
+  unplugin-utils@0.2.4:
+    resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==}
+    engines: {node: '>=18.12.0'}
+
+  unplugin@2.2.0:
+    resolution: {integrity: sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw==}
+    engines: {node: '>=18.12.0'}
+
   varint@6.0.0:
     resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
 
@@ -1020,6 +1072,9 @@ packages:
       typescript:
         optional: true
 
+  webpack-virtual-modules@0.6.2:
+    resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
 snapshots:
 
   '@babel/helper-string-parser@7.25.9': {}
@@ -1424,6 +1479,8 @@ snapshots:
       - '@vue/composition-api'
       - vue
 
+  acorn@8.14.0: {}
+
   async-validator@4.2.5: {}
 
   birpc@0.2.19: {}
@@ -1470,6 +1527,8 @@ snapshots:
 
   entities@4.5.0: {}
 
+  es-module-lexer@1.6.0: {}
+
   esbuild@0.24.2:
     optionalDependencies:
       '@esbuild/aix-ppc64': 0.24.2
@@ -1584,10 +1643,14 @@ snapshots:
 
   normalize-wheel-es@1.2.0: {}
 
+  pathe@2.0.3: {}
+
   perfect-debounce@1.0.0: {}
 
   picocolors@1.1.1: {}
 
+  picomatch@4.0.2: {}
+
   pinia@3.0.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3)):
     dependencies:
       '@vue/devtools-api': 7.7.2
@@ -1750,6 +1813,23 @@ snapshots:
 
   typescript@5.7.3: {}
 
+  unplugin-element-plus@0.9.1:
+    dependencies:
+      es-module-lexer: 1.6.0
+      magic-string: 0.30.17
+      unplugin: 2.2.0
+      unplugin-utils: 0.2.4
+
+  unplugin-utils@0.2.4:
+    dependencies:
+      pathe: 2.0.3
+      picomatch: 4.0.2
+
+  unplugin@2.2.0:
+    dependencies:
+      acorn: 8.14.0
+      webpack-virtual-modules: 0.6.2
+
   varint@6.0.0: {}
 
   vite@6.1.1(jiti@2.4.2)(lightningcss@1.29.1)(sass-embedded@1.85.0):
@@ -1788,3 +1868,5 @@ snapshots:
       '@vue/shared': 3.5.13
     optionalDependencies:
       typescript: 5.7.3
+
+  webpack-virtual-modules@0.6.2: {}

+ 5 - 0
src/assets/img/menu/add.svg

@@ -0,0 +1,5 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.333333" y="0.333333" width="39.3333" height="39.3333" rx="7.66667" fill="#F67F20"/>
+<rect x="0.333333" y="0.333333" width="39.3333" height="39.3333" rx="7.66667" stroke="#E6E6E6" stroke-width="0.666667"/>
+<path d="M20.0003 12.2917V20M20.0003 27.7084V20M20.0003 20H27.7087M20.0003 20H12.292" stroke="white" stroke-width="1.85" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 4 - 0
src/assets/img/menu/delete.svg

@@ -0,0 +1,4 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.699148" y="0.699148" width="38.6017" height="38.6017" rx="9.73563" stroke="#E03B1F" stroke-width="1.3983"/>
+<path d="M29.969 15.7202L30.1132 15.722C30.6481 15.7618 31.0581 16.1615 31.0865 16.6427L31.0727 16.911L30.6169 21.9343L30.1388 26.8366C30.0376 27.8152 29.9471 28.6407 29.8689 29.2904C29.5973 31.5549 27.964 32.9552 25.5019 32.9967C21.6653 33.0605 17.9775 33.0598 14.3962 32.9901C12.0053 32.9449 10.3961 31.5295 10.1293 29.2996L9.94489 27.6567L9.62263 24.4701L9.29252 20.9732L8.91507 16.7755C8.86815 16.237 9.30317 15.7653 9.8867 15.722C10.4216 15.6823 10.8956 16.0163 11.007 16.4871L11.0504 16.8718L11.4048 20.807L11.7918 24.886C11.9654 26.6517 12.116 28.0807 12.2364 29.0845C12.3885 30.3552 13.132 31.0092 14.4403 31.0339C17.9935 31.1031 21.6538 31.1038 25.4634 31.0404C26.8513 31.0171 27.6066 30.3695 27.7619 29.0748L27.9455 27.4408C27.9992 26.9372 28.0567 26.3813 28.1174 25.7774L28.5048 21.7658L28.9714 16.6185C29.0146 16.1248 29.4477 15.7464 29.969 15.7202ZM8.01604 13.4642C7.43063 13.4642 6.95605 13.0262 6.95605 12.4859C6.95605 11.9906 7.35483 11.5813 7.87221 11.5165L8.01604 11.5076H12.6339C13.1827 11.5076 13.6631 11.1817 13.8349 10.7121L13.877 10.5671L14.2358 8.92001C14.5519 7.82911 15.5781 7.0524 16.7807 6.9648L17.0081 6.95654H22.9907C24.2132 6.95654 25.2928 7.66908 25.7084 8.77009L25.7784 8.981L26.1217 10.5668C26.2295 11.0636 26.6699 11.4346 27.2025 11.498L27.3649 11.5076H31.983C32.5684 11.5076 33.043 11.9456 33.043 12.4859C33.043 12.9811 32.6442 13.3905 32.1269 13.4552L31.983 13.4642H8.01604ZM22.9907 8.91314H17.0081C16.7107 8.91314 16.4463 9.07379 16.3365 9.27571L16.2993 9.36442L15.9558 10.951C15.9137 11.1446 15.8528 11.3311 15.7751 11.5089L24.2239 11.5091C24.1753 11.3982 24.1334 11.2839 24.0984 11.1666L24.0429 10.9506L23.7149 9.42541C23.6383 9.16078 23.4015 8.96704 23.1158 8.92274L22.9907 8.91314Z" fill="#E03B1F"/>
+</svg>

+ 5 - 0
src/assets/img/menu/reduce.svg

@@ -0,0 +1,5 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.333333" y="0.333333" width="39.3333" height="39.3333" rx="7.66667" fill="#F67F20"/>
+<rect x="0.333333" y="0.333333" width="39.3333" height="39.3333" rx="7.66667" stroke="#E6E6E6" stroke-width="0.666667"/>
+<path d="M27.7087 20H20.0003H12.292" stroke="white" stroke-width="1.85" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 10 - 0
src/components/noProduct.vue

@@ -0,0 +1,10 @@
+<template>
+    <div class="w-full h-[80%] flex flex-col items-center justify-center">
+        <img class="w-[45%]" src="/imgs/noFoods.svg" alt="" />
+        <div class="text-[15px] font-semibold">{{ t('menu.noProducts') }}</div>
+    </div>
+</template>
+<script setup>
+import { useI18n } from 'vue-i18n'
+const { t } = useI18n()
+</script>

+ 10 - 5
src/element.scss

@@ -9,8 +9,13 @@
   )
 );
 
-:root {
-  --el-color-primary: rgba(246, 127, 32, 1);
-  --el-color-primary-light-3: rgba(246, 127, 32, 0.8);
-  --el-color-primary-dark-2: rgba(246, 127, 32, 0.95);
-}
+// :root {
+//   --el-color-primary: rgba(246, 127, 32, 1);
+//   --el-color-primary-light-3: rgba(246, 127, 32, 0.8);
+//   --el-color-primary-dark-2: rgba(246, 127, 32, 0.95);
+//   // --el-color-primary-light-5: rgba(246, 127, 32, 1);
+//   // --el-color-primary-light-9: rgba(246, 127, 32, 0);
+// }
+// 如果只是按需导入,则可以忽略以下内容。
+// 如果你想导入所有样式:
+@use 'element-plus/theme-chalk/src/index.scss' as *;

+ 2 - 2
src/views/layout/components/Header.vue

@@ -1,7 +1,7 @@
 <template>
-    <header class="flex h-[100px] items-center px-[48px] border-b-[1px] border-b-[#e6e6e6] justify-between ">
+    <header class="flex h-[60px] items-center px-[48px] border-b-[1px] border-b-[#e6e6e6] justify-between ">
             <div class="flex items-center">
-                <img class="w-[156px] mr-[10px]" src="/imgs/logo.svg" alt="">
+                <img class="w-[100px] mr-[10px]" src="/imgs/logo.svg" alt="">
                 <el-input v-model="keword" :input-style="{ boxShadow: 'none' }" style="width: 240px"
                     placeholder="Please input" :prefix-icon="Search" />
             </div>

+ 14 - 19
src/views/layout/components/Menu.vue

@@ -1,18 +1,12 @@
 <template>
-  <div class="flex flex-col items-center">
-    <div
-      class="rounded-[20px] flex items-center justify-center w-[75px] h-[75px]"
-      :class="[props.info.slected ? 'active' : '']"
-    >
-      <img :src="props.info?.img" class="w-[70px] h-[70px]" />
+    <div class="flex flex-col items-center">
+        <div class="rounded-[20px] flex items-center justify-center  w-[45px] h-[45px]" :class="[props.info.slected?'active':'']">
+            <img :src="props.info?.img" class="w-full h-full" />
+        </div>
+        <div class=" text-center text-[12px] w-[75px]" :class="[props.info.slected?'font-semibold':'']">
+            {{ t(props.info.name) }}
+        </div>
     </div>
-    <div
-      class="text-[16px] text-center text-[16px] w-[75px]"
-      :class="[props.info.slected ? 'font-semibold' : '']"
-    >
-      {{ info.name }}
-    </div>
-  </div>
 </template>
 <script setup>
 import { watch } from 'vue'
@@ -36,9 +30,10 @@ const changeLanguage = (lang) => {
 }
 </script>
 <style scoped>
-.active {
-  border-radius: 19.296px;
-  background: #f67f20;
-  box-shadow: 0px 12.864px 38.593px 0px rgba(234, 124, 105, 0.32);
-}
-</style>
+    .active{
+        border-radius: 19.296px;
+        background: #F67F20;
+        box-shadow: 0px 12.864px 38.593px 0px rgba(234, 124, 105, 0.32);
+    }
+
+</style>

+ 10 - 10
src/views/layout/index.vue

@@ -1,15 +1,15 @@
 <template>
-  <div class="main flex flex-col">
-    <Header></Header>
-    <div class="flex-1 flex shrink-0" style="height: calc(100vh - 100px)">
-      <div class="h-full w-[168px] border-r-[1px] border-r-[#e6e6e6] flex flex-col justify-around">
-        <Menu @click="handleClick(item)" v-for="item in menus" :info="item" />
-      </div>
-      <div class="h-full flex-1 overflow-y-auto">
-        <router-view />
-      </div>
+    <div class="main flex flex-col">
+        <Header></Header>
+        <div class="flex-1 flex shrink-0" style="height:calc(100vh - 100px)">
+            <div class="h-full w-[75px] border-r-[1px] border-r-[#e6e6e6] flex flex-col justify-around">
+                <Menu @click="handleClick(item)" v-for="item in menus" :info="item" />
+            </div>
+            <div class=" flex-1 overflow-y-auto">
+                <router-view />
+            </div>
+        </div>
     </div>
-  </div>
 </template>
 <script setup>
 import { ref } from 'vue'

+ 2 - 2
src/views/menu/components/order-drawer.vue

@@ -8,8 +8,8 @@
     </template>
     <template #footer>
       <div style="flex: auto">
-        <el-button type="primary" @click="cancelClick">cancel</el-button>
-        <el-button type="primary" @click="confirmClick">confirm</el-button>
+        <el-button type="primary" @click="cancelClick" plain>close window</el-button>
+        <el-button type="primary" @click="confirmClick">Join the checkout counter</el-button>
       </div>
     </template>
   </el-drawer>

+ 122 - 0
src/views/menu/components/rightOrder/components/order.vue

@@ -0,0 +1,122 @@
+<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
+
+<template>
+    <div class="h-full bg-gray-50">
+      <div class="w-full mx-auto ">
+        <div class="bg-white rounded-lg  p-3">
+          <div class="flex items-center justify-between mb-3">
+            <h1 class="text-sm font-medium">Orders #45892</h1>
+          </div>
+  
+          <div class="space-y-4 mb-6 overflow-auto h-[200px]">
+            <div v-for="(item, index) in orderItems" :key="index" 
+              class="flex items-center justify-between p-4 bg-white border border-gray-100 rounded-lg">
+              <div class="flex items-center space-x-4">
+                <div class="w-16 h-16 rounded-full overflow-hidden">
+                  <img :src="item.image" :alt="item.name" class="w-full h-full object-cover"/>
+                </div>
+                <div>
+                  <h3 class="font-sm">{{ item.name }}</h3>
+                  <p class="text-xxs text-gray-500">Size: Large, Middle, Small</p>
+                  <p class="text-orange-500 font-medium mt-1">${{ item.price.toFixed(2) }}</p>
+                </div>
+              </div>
+              <div class="flex items-center space-x-4">
+                <button class="w-4 h-4 flex items-center justify-center bg-orange-100 text-orange-500 rounded-lg !rounded-button whitespace-nowrap"
+                  @click="decreaseQuantity(index)">
+                  <img src="@/assets/img/menu/reduce.svg" alt="">
+                  
+                </button>
+                <span class="w-4 text-center">{{ item.quantity }}</span>
+                <button class="w-4 h-4 flex items-center justify-center bg-orange-500 text-white rounded-lg !rounded-button whitespace-nowrap"
+                  @click="increaseQuantity(index)">
+                  <img src="@/assets/img/menu/add.svg" alt="">
+
+                </button>
+                <button class="w-4 h-4 flex items-center justify-center text-gray-400 hover:text-red-500 !rounded-button whitespace-nowrap"
+                  @click="removeItem(index)">
+                  <img src="@/assets/img/menu/delete.svg" alt="">
+                </button>
+              </div>
+            </div>
+          </div>
+  
+          <div class="border-t border-gray-100 pt-4">
+            <div class="mb-4">
+              <h3 class="font-medium mb-2">Order Notes</h3>
+              <p class="text-gray-600 text-sm">No Chili, No Cilantro</p>
+            </div>
+            
+            <div class="flex items-center justify-between pt-4 border-t border-gray-100">
+              <span class="font-medium">Total</span>
+              <span class="text-sm font-medium">${{ total.toFixed(2) }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </template>
+  
+  <script lang="ts" setup>
+  import { ref, computed } from 'vue';
+  
+  interface OrderItem {
+    name: string;
+    price: number;
+    quantity: number;
+    image: string;
+  }
+  
+  const orderItems = ref<OrderItem[]>([
+    {
+      name: 'Spicy Seasoned Seafood',
+      price: 4.85,
+      quantity: 2,
+      image: 'https://ai-public.mastergo.com/ai/img_res/1c3d3c5704265a819a659a8d3589bc21.jpg'
+    },
+    {
+      name: 'Premium Grade Mackerel (Cleaned)',
+      price: 4.65,
+      quantity: 2,
+      image: 'https://ai-public.mastergo.com/ai/img_res/6d4be10ce5e234dcec1509d199a41a99.jpg'
+    },
+    {
+      name: 'Grilled Sea Bass',
+      price: 4.85,
+      quantity: 2,
+      image: 'https://ai-public.mastergo.com/ai/img_res/a20aaccbc775fd5729c8b8c6dac46563.jpg'
+    }
+  ]);
+  
+  const total = computed(() => {
+    return orderItems.value.reduce((sum, item) => sum + item.price * item.quantity, 0);
+  });
+  
+  const increaseQuantity = (index: number) => {
+    orderItems.value[index].quantity += 1;
+  };
+  
+  const decreaseQuantity = (index: number) => {
+    if (orderItems.value[index].quantity > 1) {
+      orderItems.value[index].quantity -= 1;
+    }
+  };
+  
+  const removeItem = (index: number) => {
+    orderItems.value.splice(index, 1);
+  };
+  </script>
+  
+  <style scoped>
+  .order-item {
+    transition: all 0.3s ease;
+  }
+  
+  input[type="number"]::-webkit-inner-spin-button,
+  input[type="number"]::-webkit-outer-spin-button {
+    -webkit-appearance: none;
+    margin: 0;
+  }
+  </style>
+  
+  

+ 36 - 0
src/views/menu/components/rightOrder/rightOrder.vue

@@ -0,0 +1,36 @@
+<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
+
+<template>
+    <div class=" h-full bg-white flex flex-col items-center justify-between ">
+      <!-- Empty state section -->
+      <div class="h-[80%]">
+        <noProduct v-if="false"></noProduct>
+        <order v-else></order>
+      </div>
+      <!-- Action buttons section -->
+      <div class="w-full max-w-md px-1  h-[20%] bg-white">
+        <div class="grid grid-cols-2 gap-4 mb-1">
+          <button class="rounded text-sm py-3 px-6 bg-white border border-gray-200 text-gray-700 !rounded-button whitespace-nowrap hover:bg-gray-50 transition-colors">
+            Registration
+          </button>
+          <button class="rounded text-sm py-3 px-6 bg-white border border-gray-200 text-gray-700 !rounded-button whitespace-nowrap hover:bg-gray-50 transition-colors">
+            Kitchen Receipt
+          </button>
+        </div>
+        <button class="rounded text-sm w-full py-3 px-6 mb-1 text-white bg-[#999]  !rounded-button whitespace-nowrap hover:bg-gray-200 transition-colors">
+          Choose A Table For Payment
+        </button>
+      </div>
+    </div>
+  </template>
+  
+  <script lang="ts" setup>
+  import noProduct from '@/components/noProduct.vue';
+  import order from './components/order.vue';
+  </script>
+  
+  <style scoped>
+
+  </style>
+  
+  

+ 110 - 0
src/views/menu/components/test.vue

@@ -0,0 +1,110 @@
+<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
+
+<template>
+    <div class="min-h-screen bg-gray-50">
+      <div class="container mx-auto px-4 py-8">
+        <header class="mb-8">
+          <h1 class="text-3xl font-bold text-gray-900">Fresh Food Menu</h1>
+          <div class="flex items-center mt-4">
+            <div class="relative flex-1 max-w-lg">
+              <input
+                type="text"
+                placeholder="Search for dishes..."
+                class="w-full pl-10 pr-4 py-2 text-sm text-gray-700 bg-white rounded-lg border-none shadow-sm"
+              />
+              <i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm"></i>
+            </div>
+          </div>
+        </header>
+  
+        <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
+          <div v-for="product in products" :key="product.id" class="bg-white rounded-xl shadow-sm p-4 transition-transform hover:scale-105">
+            <div class="relative aspect-square mb-4 rounded-full overflow-hidden">
+              <img :src="product.image" :alt="product.name" class="w-full h-full object-cover" />
+            </div>
+            <div class="text-center">
+              <h3 class="text-gray-800 font-medium text-sm mb-2">{{ product.name }}</h3>
+              <p class="text-orange-500 font-semibold">${{ product.price.toFixed(2) }}</p>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </template>
+  
+  <script lang="ts" setup>
+  import { ref } from 'vue';
+  
+  interface Product {
+    id: number;
+    name: string;
+    price: number;
+    image: string;
+  }
+  
+  const products = ref<Product[]>([
+    {
+      id: 1,
+      name: 'Spicy Seasoned Seafood Noodles',
+      price: 2.29,
+      image: 'https://ai-public.mastergo.com/ai/img_res/e53b11a05b7778db2bc50338e47047c4.jpg'
+    },
+    {
+      id: 2,
+      name: 'Grilled Salmon Bowl',
+      price: 3.49,
+      image: 'https://ai-public.mastergo.com/ai/img_res/07e4619fc2f26fe9f6a0afaebc47dceb.jpg'
+    },
+    {
+      id: 3,
+      name: 'Teriyaki Chicken Rice',
+      price: 2.99,
+      image: 'https://ai-public.mastergo.com/ai/img_res/1709d2e0e3495f8089da24be4ad2d26a.jpg'
+    },
+    {
+      id: 4,
+      name: 'Vegetable Stir Fry Noodles',
+      price: 2.49,
+      image: 'https://ai-public.mastergo.com/ai/img_res/043e50f136a6ec7f5f37eb448cf298c7.jpg'
+    },
+    {
+      id: 5,
+      name: 'Spicy Tuna Poke Bowl',
+      price: 3.99,
+      image: 'https://ai-public.mastergo.com/ai/img_res/7f8ad399ad651c8de6896bc611be1936.jpg'
+    },
+    {
+      id: 6,
+      name: 'Beef Bulgogi Bowl',
+      price: 3.79,
+      image: 'https://ai-public.mastergo.com/ai/img_res/49b0d0fbf6654dcef422a7e3334c8b6a.jpg'
+    },
+    {
+      id: 7,
+      name: 'Shrimp Pad Thai',
+      price: 3.29,
+      image: 'https://ai-public.mastergo.com/ai/img_res/ca1fef96dffcfa401768314721606c8f.jpg'
+    },
+    {
+      id: 8,
+      name: 'Miso Ramen Bowl',
+      price: 2.89,
+      image: 'https://ai-public.mastergo.com/ai/img_res/210debe79bb22fec1944cab575f2759f.jpg'
+    }
+  ]);
+  </script>
+  
+  <style scoped>
+  .container {
+    max-width: 1440px;
+    min-height: 1024px;
+  }
+  
+  input[type="number"]::-webkit-inner-spin-button,
+  input[type="number"]::-webkit-outer-spin-button {
+    -webkit-appearance: none;
+    margin: 0;
+  }
+  </style>
+  
+  

+ 142 - 22
src/views/menu/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="w-full h-full overflow-hidden flex justify-between">
-    <div class="shrink-0 min-w-[800px] flex-1">
+    <div class="shrink-0 min-w-[600px] flex-1">
       <div class="w-full h-full overflow-y-auto relative hide-bar">
         <div class="sticky top-0 w-full bg-[#fff] p-[10px]">
           <div class="h-[60px] flex justify-between items-center">
@@ -8,6 +8,7 @@
               class="flex-1 h-full pr-[10px] flex items-center justify-between cursor-pointer overflow-hidden"
             >
               <div
+                @click="handleLeftClick"
                 class="text-[#999] shrink-0 flex items-center justify-center h-[34px] w-[44px] border border-[#e6e6e6] rounded-[12px]"
               >
                 <el-icon>
@@ -16,16 +17,16 @@
               </div>
               <div
                 ref="scrollRef"
-                class="overflow-x-auto bg-[#666]"
+                class="overflow-x-auto bg-[#fff]"
                 style="width: calc(100% - 108px)"
               >
                 <div ref="" class="flex flex-nowrap items-center">
                   <div
                     @click="catgroyClick"
-                    v-for="item in 50"
-                    class="flex items-center shrink-0 mr-[20px] h-[34px] w-[55px] border"
+                    v-for="item in products"
+                    class="flex items-center shrink-0 mr-[20px] h-[34px]"
                   >
-                    {{ item }}
+                    {{ item.name }}
                   </div>
                 </div>
               </div>
@@ -37,53 +38,172 @@
                   <ArrowRight />
                 </el-icon>
               </div>
-              <!-- <div class="w-full h-full overflow-hidden flex items-center justify-between">
-                                
-                                
-                            </div> -->
             </div>
+          </div>
+          <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
             <div
-              class="h-[34px] px-[10px] cursor-pointer shrink-0 border rounded border-[#e6e6e6] flex items-center justify-between hover:bg-[#f67f20] hover:text-[#fff]"
+              v-for="product in products"
+              :key="product.id"
+              @click="show = true"
+              class="bg-white rounded-xl shadow-sm transition-transform"
             >
-              <span>{{ t('menu.pendingOrders') }}</span>
-              <div class="ml-[10px] text-[#fff] rounded-full bg-[#f67f20] text-[14px] px-[3px]">
-                99+
+              <div
+                class="relative flex items-center bg-[#fef8f4] justify-center mb-4 rounded overflow-hidden"
+              >
+                <img
+                  :src="product.image"
+                  :alt="product.name"
+                  class="w-25 h-25 my-1 object-cover rounded-full"
+                />
+              </div>
+              <div class="text-left px-2">
+                <h3
+                  class="text-gray-800 font-medium text-sm mb-2 text-container w-full text-nowrap line-clamp-2 sm:line-clamp-1 md:line-clamp-2 lg:line-clamp-3"
+                >
+                  {{ product.name }}
+                </h3>
+                <p class="text-orange-500 font-semibold">${{ product.price.toFixed(2) }}</p>
               </div>
             </div>
           </div>
         </div>
-        <div @click="show = !show" class="h-[50px] border" v-for="item in 50">
-          {{ item }}
-        </div>
       </div>
     </div>
-    <div class="w-[700px] h-full overflow-hidden border-l border-gray-200"></div>
-
-    <OrderDrawer v-model:="show" />
+    <div class="w-[500px] h-full overflow-hidden border-l border-gray-200">
+      <rightOrder></rightOrder>
+    </div>
+    <OrderDrawer v-model:show="show" />
   </div>
 </template>
 <script setup>
-import { ref, onMounted } from 'vue'
+import { ref, onMounted, nextTick } from 'vue'
 import { useStore } from '../../stores'
 import { storeToRefs } from 'pinia'
 import { useI18n } from 'vue-i18n'
 import { ArrowRight, ArrowLeft } from '@element-plus/icons-vue'
+import rightOrder from './components/rightOrder/rightOrder.vue'
 import OrderDrawer from './components/order-drawer.vue'
 
 const { t } = useI18n()
 const store = useStore()
 const { count } = storeToRefs(store)
+// 响应式数据
+const currentIndex = ref(0)
+const itemWidth = ref(0)
 const scrollRef = ref(null)
-function handleRightClick() {
-  scrollRef.value.scrollLeft += 100
+
+// 计算元素宽度
+const calculateItemWidth = () => {
+  nextTick(() => {
+    const element = scrollRef.value?.children[0]
+    if (element) {
+      const style = window.getComputedStyle(element)
+      itemWidth.value = element.offsetWidth + parseInt(style.marginRight)
+    }
+  })
 }
+// function handleRightClick() {
+//   scrollRef.value.scrollLeft += 100
+// }
 
 const show = ref(false)
 
 onMounted(() => {})
+
+const products = ref([
+  {
+    id: 1,
+    name: 'Spicy Seasoned Seafood Noodles',
+    price: 2.29,
+    image: 'https://ai-public.mastergo.com/ai/img_res/e53b11a05b7778db2bc50338e47047c4.jpg',
+  },
+  {
+    id: 2,
+    name: 'Grilled Salmon Bowl',
+    price: 3.49,
+    image: 'https://ai-public.mastergo.com/ai/img_res/07e4619fc2f26fe9f6a0afaebc47dceb.jpg',
+  },
+  {
+    id: 3,
+    name: 'Teriyaki Chicken Rice',
+    price: 2.99,
+    image: 'https://ai-public.mastergo.com/ai/img_res/1709d2e0e3495f8089da24be4ad2d26a.jpg',
+  },
+  {
+    id: 4,
+    name: 'Vegetable Stir Fry Noodles',
+    price: 2.49,
+    image: 'https://ai-public.mastergo.com/ai/img_res/043e50f136a6ec7f5f37eb448cf298c7.jpg',
+  },
+  {
+    id: 5,
+    name: 'Spicy Tuna Poke Bowl',
+    price: 3.99,
+    image: 'https://ai-public.mastergo.com/ai/img_res/7f8ad399ad651c8de6896bc611be1936.jpg',
+  },
+  {
+    id: 6,
+    name: 'Beef Bulgogi Bowl',
+    price: 3.79,
+    image: 'https://ai-public.mastergo.com/ai/img_res/49b0d0fbf6654dcef422a7e3334c8b6a.jpg',
+  },
+  {
+    id: 7,
+    name: 'Shrimp Pad Thai',
+    price: 3.29,
+    image: 'https://ai-public.mastergo.com/ai/img_res/ca1fef96dffcfa401768314721606c8f.jpg',
+  },
+  {
+    id: 8,
+    name: 'Miso Ramen Bowl',
+    price: 2.89,
+    image: 'https://ai-public.mastergo.com/ai/img_res/210debe79bb22fec1944cab575f2759f.jpg',
+  },
+])
+// 生命周期钩子
+onMounted(() => {
+  calculateItemWidth()
+})
+
+// 左按钮点击
+const handleLeftClick = () => {
+  if (currentIndex.value <= 0) return
+  currentIndex.value--
+  scrollToPosition()
+}
+
+// 右按钮点击
+const handleRightClick = () => {
+  // 假设products通过props传入
+  if (currentIndex.value >= products.value.length - 1) return
+  currentIndex.value++
+  scrollToPosition()
+}
+
+// 执行滚动
+const scrollToPosition = () => {
+  scrollRef.value?.scrollTo({
+    left: itemWidth.value * currentIndex.value,
+    behavior: 'smooth',
+  })
+}
 </script>
 <style scoped>
 ::-webkit-scrollbar-thumb {
   background-color: red;
 }
+/* 隐藏整个滚动条 */
+::-webkit-scrollbar {
+  display: none;
+}
+
+/* 或者仅隐藏滚动条的轨道,保留滑块可操作性,但视觉上不显示滚动条 */
+::-webkit-scrollbar-track {
+  display: none;
+}
+.text-container {
+  width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
 </style>

+ 18 - 1
vite.config.ts

@@ -1,18 +1,28 @@
 import { defineConfig } from 'vite'
 import vue from '@vitejs/plugin-vue'
 import tailwindcss from '@tailwindcss/vite'
+ // @ts-expect-error process is a nodejs global
 import path from 'node:path'
 
+import ElementPlus from 'unplugin-element-plus/vite'
+ // @ts-expect-error process is a nodejs global
 const host = process.env.TAURI_DEV_HOST
 
 // https://vitejs.dev/config/
 export default defineConfig(async () => ({
   resolve: {
     alias: {
+      // @ts-expect-error process is a nodejs global
       '@': path.join(process.cwd(), './src'),
     },
   },
-  plugins: [vue(), tailwindcss()],
+  plugins: [
+    vue(),
+    tailwindcss(),
+    ElementPlus({
+      useSource: true, // 可选,是否使用源码
+    }),
+  ],
 
   // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
   //
@@ -42,5 +52,12 @@ export default defineConfig(async () => ({
     //     ],
     //   },
     // },
+    // css: {
+    //   preprocessorOptions: {
+    //     scss: {
+    //       additionalData: `@use "~/styles/element/index.scss" as *;`,
+    //     },
+    //   },
+    // },
   },
 }))