*Vw#Z7AT1NsXFyr`8<`1HZ}XjS(&tA^pYV>qw^Pm^FnFL~4jU_{Qel{E*|76-
zkG$RR%7p6JKQ29fZL*p5qXkL10_wA#G?glVu_
z75t31nC|r!vkJ@xZUMduyusd0FGIjLfN|a=`~)z~Q>9Js-1C7k-sCwA_@wu}E&EBK
z0^n!fL~HP_bAz{dcJmZr;A_CQJuunkEwt-^FM4K6+lP4kGS37`0RK7&h@9b>NUH|f
z{oew<=`HZ_-Zj4BJ>z@cf(vwqrFZUg-u(^l8s`9Sc_szk=d(Pm
z5bud&+MBAoCmz(^|97_mhX9=-yH-zU-K6J
zX79PSdY^Cc`q1u~J6R9h?f^ns)c<})+jS+Hs`AV0&N~0{6?NI$|MJfKf8GA6X&ITK
zuCbM1$WL#-A?|s6>7A>WZTrHUxwY4P?4-k^({>48k(Xc&gSl;5~Ew-92$1okcQJIdn}&i5vT=}pL}r*iK;
zKj!^@rw1@kdlPVh_dUa#u=9WmJRq3wfx_M7wt-*fE%H^~MBKdxYQAW-goK9gJ#l`h~akF#m=#y;U`C{GW1##O*O9@+bt
zM-FGb=Xwlyz|%qo2ANm}@Qh|3q#j^X#{griOU%!G{hSN_^4)(v^YeezeE$cZKKZBH
zn|diL9>&PwHR6ePwvV58%EZrKHgDpCQ^t?t+jl?vmqm-VUNwDc$u&WLcxyvj?`icr
zTi-nQgjsDbzO{g`A>aG@#nVPU`o_k4o|(VxrBRg~FBTUEZdwwk=$vooaY}47r-hTe
zZTr|(IjrHtx&DR;?VBHSn|F~26(U0s>=zy_icOyr@)wtghGolojbl#g_jR>W=u_BU
zHI;knvP`ZW!?%tq=F!F5_)B|$s89>WXxmI{FFu
zbo%=fY~I!XDcejp9)Hxdw~v}Q{OR*f9rN_?@*)&$(peKdWb7&k`JDWMD20WE3@;7y
zhi6w@y!?UrSDg9vv%i1rxU%i5H?$%S8ed=e-w6b+Hwl+|6Ka1|zS^5y-}NR>%K=P>
zPEX?QPDEHqZsSa!HyJB{FL;Dv!=Q!n6Axs*0esy1d;cKvl0kn*+HPK{^MeF?b91M9m6X+B-vGxY8^p7x;61B1LB($h3nc<<#e9@w4d^KZydgj(+XN-F5(v!w4TD!FmpAm3xzy6XlWV{Jm82tW;
zMdvTv*mlj2zk6Y2>#oL@p8hzAfqv_r2Vc74%a!Zu7D-AJ07Xv~OWs^ve3mF&j>=ELdLZZ{+24lpbG<
z^UlieIx1>+6Z}>$M+5p*KY8lLv}pzIy6IDYo<6y>vAH?JutGlz)-{#i`JI0}QF`3?Wk3Dm
zS-17ZO+rC`E)@EIPdku1W}D}B`x-FUBbVMd09fpoB!Ii$=i#1&@7V9$9p0ju>D}M)
z?D+%P`X7l3{)p%8E(U1r=aSrii)EkJ?*k$FBc29vl?MdVy}u9UL}q(t(F)JhkRD*F
z-ohJvkL&@wGP^uC@O8k6zz;ol=Kjy39OQkA1B`7S@O$8|p2_kzkArvx$SN7r;edzb
z(3i~6)Sclc*Pe5gf5Nc3?|t*Wcb9K!DVbOsBbmxjm>(cx3*KJ2mDiSRy6pU8$9{kI
z_}Z3mehFuud=#25IDXaUjI#Ztfx1teIq{<7rj}mmN@1+p
z+V|W$Z>_kyalGC9T#5OtA2WQUFQvpW?wdE<-E`Ghi#_5
z#LEBjmhJ5~z8()pnn%r~erwa$%+}Ps>Gsy@fem%Crz3v!%8i}R#naA+Ig`r2cG(%@
zP90NSym;abzo=}=W54|Lk58R7;x<>hQ7e;R!;T)d?Ci9{
z0kProGv+K9UY6fjw=+pmp`ZG$IA8nD{i_N2v_YiT;AVR2ugak}UH_=sjy%LQl!Gi}vEMj-SWxK#
z{^_aZ(><+d`+fi!^UR&Ko>{QOBUzUmz_X(qV9`3B$@P8DO!%i~p8Y$KY0@J_w|l0;
zDDOU-0I68n3MZCQ|AO6va`?KjpOMPSih12#@IDT5m#TTA5
z`rJ{K(brsC5)OrMZJU+rwoP%v6(2wEymOti=8nB%!G@M!EZ*8Vy{WyYdiCbEc@Mp@
z<%{#zwjH%#*@oDRQu~=XyES^!b?gE97W1T{
zy&p(f2k762t%Ta`Nx1TZERKNpeBB2D9(jnr9c*Wp&rGx6>LB>JQS*n%TH
zZ9(7f+WX(5*fR}&=6(NJPkXy;2>sq|&KxL!YA0|XaH@ChRi5VqrL-W*2OYzTqogt>
zXU?h~_|@;fFwNZ3T=0pn-?z#LKyzC=OIL4U+PD#1d-=R4lkr~u_1yfU>vr{C@||Bk
zyK7jX@8vIEbnIP)6*auOweQxk6GkmBjOgjcy3K0OK*}G`9F7`YL?UHjndZ(@XH>mf
zQ>ZErKKITK4MTTERTjwNydcxY7Oj~*w)D0Y8+M&k7z-|+TwB8FGl#c~tqk3?qa$_f
z3kx@#y=mJH(rGI&V`k0cwN=qqUSG2Ql!E+7TSZZ%p|dYVOwUqNWRS?Z(f*Wq5{fpm
zxvj%#@8~jb{`^_@o^jN;pI`UYzr1(S^xD5x6^GtizoX~M4GnGI!!ZLT0mqC7jAy&(dJiH&i?FwU2^HACrntsvwZ-+VW8>04?GTYEAbZcDc)iWc=oP5hy)z`
z_i>*6xtp~6p(n-j2LXz50QFe&w1(Y_yV+AQPxD-iyW1RZBHz8A7J>&FQO`D>?R~HK
zLz)Rqz)RjWuGr5_81=jx&H-GV@&NbQ?Sgdov$c1-DD8vz@L%x=*3LoRnBDDZPgD4v
z_q?URERQ@?Jm9lEAU}`^GKO6Aq~;N>Kk|sZ;{BdQJ&3jx@!n;DXPOLdk9*^HzNfL|
z>Vbad`X3?`YPly+m?Ybr6QwAwFfzOF;=>PV>5$CSVNnRDheu3q|%`|kW#tYBePekdweR#sy5d&3a#cctDfu(DA#EL@73*Wl>%x4T;lWpytG`9D0+@uQC
zwq^OP53XEt!D&aW{@95V9uanC!|i$C97r5tWm?eh>GEv{ih#2*%Z(8}YLq
zPm$-j+s^Y?`@eXuGX}XZFZ4K(I`6ss9Aa5@koH
zb!_iIQqG+??Co(QtIeR_U|4a8MA}lex5Q=bu!4buP>TBd-}N5XC6O&+x%tg=#+`2k4vS@h%%Y5N-5W|3!nekZ~UH
zEbzvznY|(4DR2CB@4l+%x~v;yI^=t<+B&cAy91fFc!%R@h?@`4znPvku*akkZ)_WS
z&bnb33=G8Cwq+}eH?^Gl$o)%S3)K|0U3KobshVqb3}hi-XaoZROv|F8$j>9MZ~jWk
z(ayf*3#XrBN)4Y*^!}$8UOi{Zh(8aD8R?1D1|BTGjX~*wx*o5t5$H->}gzl&dDrUu!J|>d6!VhFvgD=O~cMz%BIFHHy|7}Dh7P-
zb%wt%a#;SF%T5~q)+2AM)0S*%{ajJlSa9^z5gR6stl;|Jyd0l0y7=yi)v^033W9Yh
z)2(%dYK$FTv}Jo!cfM^}$rGp6mY<+uEPx|P}q7bU4va_X~(KVHvcEZtojuUfS1*b-{$kypD?POhyi46NEV@KB$neG|=4{r=#X
z*VpyDY5I#xPCsUnJ#BP(_t~ePU{zODjoEM-|?}zs1u`>OF0Rj|2p}C6Vh&n!8g>8&SIC^OsMmP;hoV`NXD0OEz_UBO20B
zaaq20E1Mfyx#FbS&BsivynEHgZR6fpu<~?6ldI1-X~vSmq9Q75D%sJM#_$CwDJ=p$
z$Urhva^jTAJ1#iyTx-@*$6C7K3l6U+=ovF^e0s~yzL}r+&L7vrhK=R;vo1|7+0;DY
z^~D<^y5Uc1nqHf<^yyV2C&aJ+3z54RY>Y~N(Qe0Na
zkH2)m%~@BSdhfHVfA{LrjVJj?KYaXzk|*kRG}F-1jbpn+0t$7liA(?W*v7heU$X47
zkBy&s^!V~eTYFNNmXj;7exw~~|2JB|BPxI3nS{UJ-wabe>Xn6n_P#U)L8JBKXN{;H
zKB4&0H(sr~^MMyOzhMM?g#}@a2cLSAJ0E?Ipx}=^BrE4lRkiy
z86{%@<&~D+|F6BX|83*0d?LZfbaeCxtC7w&-Xr`R%||1Mo-8yQEO_xP@n@Uq433>cO0!|
z7Jjtvzz?PyIzM{c(MzfDPn-SByK%#`XVSL=PPmTt5(f~n~l&Sb=%ryhG?&m&Kty75P<
z@r?ubZGNHJqII`u!ogG5(q%GMDA$mU=dodEEq?#wgWr7qR9bv>RL|Z+zj;?=QZHio$N&)qiy7rr>zKP(h)l-c|xI
zP3vpj;+7%*CN%tKvi#*okKFQU3`0XvRHT-3&2zIu^>vljRw;pu&_*knX
zEpAIbwg^lB&87-butTb=2>RXCk$&%S%0Wk?>Bb|`%ek-Q6n&@H#a-_7@;3+}5Cs7&
z#{s4ZMQI|H$;0h(Va@7}=u$Ghcs`omRxC=rV|NY34<8si%M%^1pT01dmB_vTFHdaf
z^A;T*fA;Ok*x`rv?s$5~#t7o6oO|+0<{^*McA?Wr66Zdg#MN{Qk-i?Z+qrbBStSC`
zgJMOrXb~K3LgXl9i*n@5O!3$UXHv&%iqXIA?%>xxyQAm9zK}1I$lRQbpsFo!9BYZd
z;{O)rzj>I=Mxjzuq3aq(*9Bh~8SMJQnW^O`E==dXyR;x(?C$Zre`nbBL3Dl*Qni8Ja1ar{_-=RCzfJK3rliP#*QUV3X?3ZPJ3qE(OsE!e%E9}#
z9^-ZSQBiCl8bPO%0>jdX
zrKP)P618v7&lUFqCe{yk{_Nf@k)u3gR-^_&L2ANAQLy3w3rht5VTfoLCJK^*jy5OR
zKJ5RVTWCEc6XEM0MvG6Tq0B$X
z*Y0G`ctz%{*TGJC1To&!v?9woh-sS0mm~z*orp5PwRj3cy?%%sW2-i_wpN|=O0qJX
zuc)KthQ2*lYK)+%0hA5Aiz{s&4*YOcJ9i=ya9^fvHpmJ=zN$ji467w*VTs_A;HD4^
zl1I#*9P~S(4reUX)rLa3
zhI&&2F#sDyfn{i`3M?!Ue9{l3aC7%aLnX*d3W#Px;OSKV>h==?&zvYpGFrs6Yo@Iy
zTdEJp3K^<4_3mO#?NBw%SCoi7m(0^}iiW^KWofz`3_0^2fk|;Rt_FPWn47mP!Zd1L
zj{`&_sK`yUbRaJ&keeD9nzlkf3yY7wm)6A;3k!>X03s`y(w=u)B>(^b07*qoM6N<$
Ef_{&z(f|Me
literal 0
HcmV?d00001
diff --git a/src/cart/cart.ts b/src/cart/cart.ts
new file mode 100644
index 0000000..efecbf7
--- /dev/null
+++ b/src/cart/cart.ts
@@ -0,0 +1,68 @@
+import { defineStore } from 'pinia'
+
+export interface CartItem {
+ id: number
+ name: string
+ price: number
+ quantity: number
+ imageUrl: string
+}
+
+export const useCartStore = defineStore('cart', {
+ state: () => ({
+ cartItems: [] as CartItem[],
+ }),
+
+ getters: {
+ // 总价计算
+ totalPrice(state): number {
+ return state.cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0)
+ },
+ },
+
+ actions: {
+ addToCart(item: CartItem) {
+ const existing = this.cartItems.find(i => i.id === item.id)
+ if (existing) {
+ existing.quantity += item.quantity
+ } else {
+ this.cartItems.push(item)
+ }
+ this.saveToLocalStorage()
+ },
+
+ updateQuantity(id: number, quantity: number) {
+ const item = this.cartItems.find(i => i.id === id);
+ if (item && quantity >= 1) {
+ item.quantity = quantity;
+ this.saveToLocalStorage();
+ }
+ },
+
+ removeFromCart(id: number) {
+ this.cartItems = this.cartItems.filter(i => i.id !== id)
+ this.saveToLocalStorage()
+ },
+
+ clearCart() {
+ this.cartItems = []
+ this.saveToLocalStorage()
+ },
+
+ loadFromLocalStorage() {
+ const stored = localStorage.getItem('cart')
+ if (stored) {
+ this.cartItems = JSON.parse(stored)
+ }
+ },
+
+ saveToLocalStorage() {
+ localStorage.setItem('cart', JSON.stringify(this.cartItems))
+ },
+
+ setCart(items: CartItem[]) {
+ this.cartItems = items
+ this.saveToLocalStorage()
+ },
+ },
+})
\ No newline at end of file
diff --git a/src/components/Aside.vue b/src/components/Aside.vue
new file mode 100644
index 0000000..58d46f1
--- /dev/null
+++ b/src/components/Aside.vue
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+
diff --git a/src/components/Breadcrumb.vue b/src/components/Breadcrumb.vue
new file mode 100644
index 0000000..eb0f467
--- /dev/null
+++ b/src/components/Breadcrumb.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
diff --git a/src/components/ChatPanel.vue b/src/components/ChatPanel.vue
new file mode 100644
index 0000000..e1df6bc
--- /dev/null
+++ b/src/components/ChatPanel.vue
@@ -0,0 +1,7 @@
+
+ 聊天框组件
+
+
+
+
+
diff --git a/src/components/Footer.vue b/src/components/Footer.vue
new file mode 100644
index 0000000..3f9aa11
--- /dev/null
+++ b/src/components/Footer.vue
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
diff --git a/src/components/Header.vue b/src/components/Header.vue
new file mode 100644
index 0000000..8fa1bcb
--- /dev/null
+++ b/src/components/Header.vue
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ user.name }}
+
+
+ 账号管理
+ 资质认证
+ 退出账号
+
+
+
+
+
|
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Map.vue b/src/components/Map.vue
new file mode 100644
index 0000000..b9116c7
--- /dev/null
+++ b/src/components/Map.vue
@@ -0,0 +1,542 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ poi.name }}
+
{{ poi.address }}
+
距离: {{ poi.distance }}米
+
+
+
+
+
暂无附近地点
+
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..fb0e625
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,35 @@
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import 'element-plus/theme-chalk/src/index.scss'
+import App from './App.vue'
+import router from './router'
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+import zhCn from 'element-plus/es/locale/lang/zh-cn'
+import VueAMap, { initAMapApiLoader } from '@vuemap/vue-amap'
+
+const app = createApp(App)
+
+initAMapApiLoader({
+ // 在这里替换成你申请的 Key
+ key: '5a5935de1c13991663c5b222e1ad2392',
+ // 你需要使用的插件列表
+ plugins: ['AMap.ToolBar', 'AMap.Scale', 'AMap.Geolocation', 'AMap.Geocoder'],
+ // 其他安全密钥等配置
+ securityJsCode: '52dec9705905111f788fcc1ba9b385d6', // 如果你设置了安全密钥
+})
+
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+ app.component(key, component)
+}
+
+app.use(router)
+
+app.use(ElementPlus, {
+ locale: zhCn,
+})
+app.use(createPinia())
+app.use(VueAMap)
+app.mount('#app')
diff --git a/src/router/admin.ts b/src/router/admin.ts
new file mode 100644
index 0000000..2a34f2b
--- /dev/null
+++ b/src/router/admin.ts
@@ -0,0 +1,25 @@
+import { createRouter, createWebHistory } from 'vue-router'
+
+import FrontLayout from '@/views/admin/FrontLayout.vue'
+import Home from '@/views/admin/Home.vue'
+import MerchantManagement from '@/views/admin/MerchantManagement.vue'
+import DishManagement from '@/views/admin/DishManagement.vue'
+import BranchManagement from '@/views/admin/BranchManagement.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/admin',
+ component: FrontLayout,
+ children: [
+ { path: '', name: 'Home', component: Home },
+ { path: 'merchantmanagement', name: 'merchantmanagement', component: MerchantManagement },
+ { path: 'dishmanagement', name: 'dishmanagement', component: DishManagement },
+ { path: 'branchmanagement', name: 'branchmanagement', component: BranchManagement },
+ ],
+ },
+ ],
+})
+
+export default router
diff --git a/src/router/index.ts b/src/router/index.ts
new file mode 100644
index 0000000..7c27182
--- /dev/null
+++ b/src/router/index.ts
@@ -0,0 +1,24 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import adminRouter from './admin'
+import merchantRouter from './merchant'
+import userRouter from './user'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/admin',
+ children: [...adminRouter.options.routes],
+ },
+ {
+ path: '/merchant',
+ children: [...merchantRouter.options.routes],
+ },
+ {
+ path: '/user',
+ children: [...userRouter.options.routes],
+ },
+ ],
+})
+
+export default router
diff --git a/src/router/merchant.ts b/src/router/merchant.ts
new file mode 100644
index 0000000..c11628e
--- /dev/null
+++ b/src/router/merchant.ts
@@ -0,0 +1,138 @@
+import { createRouter, createWebHistory } from 'vue-router'
+
+const merchantRouter = createRouter({
+ history: createWebHistory('/'),
+ routes: [
+ {
+ path: '/merchant',
+ component: () => import('@/views/merchant/Home.vue'), // 主布局组件
+ redirect: '/merchant/dashboard', // 当访问 /merchant 时,重定向到 /merchant/dashboard
+ children: [
+ // 首页 - 默认路由
+ {
+ path: 'dashboard',
+ name: 'Dashboard',
+ component: () => import('@/views/merchant/Dashboard/index.vue'),
+ meta: { title: '首页', icon: 'HomeFilled' },
+ },
+
+ // 订单管理模块
+ {
+ path: 'orders',
+ name: 'Orders',
+ component: () => import('@/views/merchant/Orders/index.vue'),
+ meta: { title: '订单管理', icon: 'Document' },
+ redirect: 'pending', // 当访问 /merchant/orders 时,重定向到其子路由 'pending'
+ children: [
+ {
+ path: 'pending',
+ name: 'OrdersPending',
+ component: () => import('@/views/merchant/Orders/Pending.vue'),
+ meta: { title: '待办订单' },
+ },
+ {
+ path: 'refund',
+ name: 'OrdersRefund',
+ component: () => import('@/views/merchant/Orders/Refund.vue'),
+ meta: { title: '退款管理' },
+ },
+ ],
+ },
+
+ // 顾客评价模块
+ {
+ path: 'reviews',
+ name: 'Reviews',
+ component: () => import('@/views/merchant/Reviews/index.vue'),
+ meta: { title: '顾客评价', icon: 'Star' },
+ redirect: 'store-reviews',
+ children: [
+ {
+ path: 'store-reviews',
+ name: 'StoreReviews',
+ component: () => import('@/views/merchant/Reviews/StoreReviews.vue'),
+ meta: { title: '门店评价' },
+ },
+ {
+ path: 'reply-management',
+ name: 'ReviewReplyManagement',
+ component: () => import('@/views/merchant/Reviews/ReplyManagement.vue'),
+ meta: { title: '评价回复' },
+ },
+ ],
+ },
+
+ // 商品管理模块
+ {
+ path: 'products',
+ name: 'Products',
+ component: () => import('@/views/merchant/Products/index.vue'),
+ meta: { title: '商品管理', icon: 'Goods' },
+ redirect: 'list',
+ children: [
+ {
+ path: 'list',
+ name: 'ProductList',
+ component: () => import('@/views/merchant/Products/ProductList.vue'),
+ meta: { title: '菜品列表' },
+ },
+ ],
+ },
+
+ // 门店管理模块
+ {
+ path: 'stores',
+ name: 'Stores',
+ component: () => import('@/views/merchant/Stores/index.vue'),
+ meta: { title: '门店管理', icon: 'Shop' },
+ redirect: 'store-info',
+ children: [
+ {
+ path: 'store-info',
+ name: 'StoreInfo',
+ component: () => import('@/views/merchant/Stores/StoreInfo.vue'),
+ meta: { title: '门店信息' },
+ },
+ ],
+ },
+
+ // 财务管理模块
+ {
+ path: 'finance',
+ name: 'Finance',
+ component: () => import('@/views/merchant/Finance/index.vue'),
+ meta: { title: '财务管理', icon: 'Coin' },
+ redirect: 'daily-revenue',
+ children: [
+ {
+ path: 'daily-revenue',
+ name: 'DailyRevenue',
+ component: () => import('@/views/merchant/Finance/DailyRevenue.vue'),
+ meta: { title: '每日收益' },
+ },
+ {
+ path: 'revenue-management',
+ name: 'RevenueManagement',
+ component: () => import('@/views/merchant/Finance/RevenueManagement.vue'),
+ meta: { title: '收支管理' },
+ },
+ {
+ path: 'finance-download',
+ name: 'FinanceDownload',
+ component: () => import('@/views/merchant/Finance/FinanceDownload.vue'),
+ meta: { title: '财务下载' },
+ },
+ {
+ path: 'account-collection',
+ name: 'AccountCollection',
+ component: () => import('@/views/merchant/Finance/AccountCollection.vue'),
+ meta: { title: '收款账号' },
+ },
+ ],
+ },
+ ],
+ },
+ ],
+})
+
+export default merchantRouter
diff --git a/src/router/user.ts b/src/router/user.ts
new file mode 100644
index 0000000..1b27d31
--- /dev/null
+++ b/src/router/user.ts
@@ -0,0 +1,88 @@
+// 从 vue-router 导入 createRouter(创建路由实例)和 createWebHistory(使用 HTML5 History 模式)
+import { createRouter, createWebHistory } from 'vue-router'
+
+// 导入组件
+import Home from '@/views/user/Home.vue'
+import Search from '@/views/user/Search.vue'
+import FrontLayout from '@/views/user/FrontLayout.vue'
+import Detail from '@/views/user/detail.vue'
+import Type from '@/views/user/type.vue'
+import Shopping from '@/views/user/Shopping.vue'
+import Orders from '@/views/user/orders.vue'
+import Location from '@/views/user/location.vue'
+import SpendingChart from '@/views/user/SpendingChart.vue'
+import About from '@/views/user/About.vue'
+import Contact from '@/views/user/Contact.vue'
+
+// 合并后的路由配置
+const routes = [
+ {
+ path: '/user',
+ component: FrontLayout,
+ children: [
+ {
+ path: '',
+ name: 'UserHome',
+ component: Home,
+ },
+ {
+ path: 'search',
+ name: 'Search',
+ component: Search,
+ },
+ {
+ path: 'charts',
+ name: 'SpendingChart',
+ component: SpendingChart,
+ },
+ {
+ path: 'detail/:id', // 路径包含动态参数 :id
+ name: 'Detail', // 路由名称
+ component: Detail, // 映射到 detail.vue 组件
+ props: true, // 允许通过 props 传递路由参数
+ },
+ {
+ path: 'type',
+ name: 'Type',
+ component: Type,
+ props: (route: { query: { category: any; name: any } }) => ({
+ category: route.query.category,
+ name: route.query.name,
+ }),
+ },
+ {
+ path: 'shopping',
+ name: 'Shopping',
+ component: Shopping,
+ },
+ {
+ path: 'orders',
+ name: 'Orders',
+ component: Orders,
+ },
+ {
+ path: 'location',
+ name: 'Location',
+ component: Location,
+ },
+ {
+ path: 'about',
+ name: 'About',
+ component: About,
+ },
+ {
+ path: 'contact',
+ name: 'Contact',
+ component: Contact,
+ },
+ ],
+ },
+]
+
+// 创建路由实例
+export const router = createRouter({
+ history: createWebHistory(),
+ routes,
+})
+
+export default router
diff --git a/src/stores/store.ts b/src/stores/store.ts
new file mode 100644
index 0000000..7e3c12c
--- /dev/null
+++ b/src/stores/store.ts
@@ -0,0 +1,25 @@
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export const useStoreStore = defineStore('store', () => {
+ const selectedStoreName = ref('未选择门店');
+ const selectedStoreId = ref(null);
+
+ function setStore(name: string, id: number) {
+ selectedStoreName.value = name;
+ selectedStoreId.value = id;
+ localStorage.setItem('selectedStoreName', name);
+ localStorage.setItem('selectedStoreId', id.toString());
+ }
+
+ function loadStoreFromLocal() {
+ const name = localStorage.getItem('selectedStoreName');
+ const id = Number(localStorage.getItem('selectedStoreId'));
+ if (name && !isNaN(id)) {
+ selectedStoreName.value = name;
+ selectedStoreId.value = id;
+ }
+ }
+
+ return { selectedStoreName, selectedStoreId, setStore, loadStoreFromLocal }
+})
\ No newline at end of file
diff --git a/src/user/user.ts b/src/user/user.ts
new file mode 100644
index 0000000..994a22d
--- /dev/null
+++ b/src/user/user.ts
@@ -0,0 +1,34 @@
+import { defineStore } from 'pinia'
+import axios from 'axios'
+
+export const useUserStore = defineStore('user', {
+ state: () => ({
+ userId: 10, // 默认用户 ID
+ username: '', // 新增:用户名
+ }),
+ getters: {
+ getUserId: (state) => state.userId,
+ getUsername: (state) => state.username, // 新增 getter
+ },
+ actions: {
+ setUserId(id: number) {
+ this.userId = id
+ },
+ setUsername(name: string) {
+ this.username = name
+ },
+ async fetchUsernameById(id: number) {
+ try {
+ // 设置 userId
+ this.userId = id
+
+ const response = await axios.get(`/api/user/customers/${id}`)//ok
+
+ // 后端返回的用户数据结构中包含 accountName
+ this.username = response.data.accountName
+ } catch (error) {
+ console.error('获取用户名失败:', error)
+ }
+ },
+ },
+})
diff --git a/src/views/admin/BranchManagement.vue b/src/views/admin/BranchManagement.vue
new file mode 100644
index 0000000..238e295
--- /dev/null
+++ b/src/views/admin/BranchManagement.vue
@@ -0,0 +1,1101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加分店
+
+
+
+
+
+
+
+
+
+
+ {{ currentBranch.branchAddress }}
+ {{ currentBranch.branchPhone }}
+
+ {{ currentBranch.branchStart }} - {{ currentBranch.branchEnd }}
+
+
+
+ {{ currentBranch.branchStatus }}
+
+
+ {{ formatDate(currentBranch.createdAt) }}
+ {{ formatDate(currentBranch.updatedAt) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentBoss.accountId }}
+ {{ currentBoss.accountName }}
+ {{ currentBoss.accountGender }}
+ {{ currentBoss.accountPhone }}
+ {{ currentBoss.salary }}
+
+
+
+
+ 编辑负责人信息
+
+
+
+
+
+
+
+
+ 营业情况 - {{ currentBranch.branchName }}
+
+
+
+
+
+
+ ¥{{ row.totalAmount }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/admin/DishManagement.vue b/src/views/admin/DishManagement.vue
new file mode 100644
index 0000000..b06a21c
--- /dev/null
+++ b/src/views/admin/DishManagement.vue
@@ -0,0 +1,807 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 在售
+ 停售
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/admin/FrontLayout.vue b/src/views/admin/FrontLayout.vue
new file mode 100644
index 0000000..b739d96
--- /dev/null
+++ b/src/views/admin/FrontLayout.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/admin/Header.vue b/src/views/admin/Header.vue
new file mode 100644
index 0000000..e0e6f5d
--- /dev/null
+++ b/src/views/admin/Header.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
diff --git a/src/views/admin/Home.vue b/src/views/admin/Home.vue
new file mode 100644
index 0000000..1340ce3
--- /dev/null
+++ b/src/views/admin/Home.vue
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/admin/MerchantManagement.vue b/src/views/admin/MerchantManagement.vue
new file mode 100644
index 0000000..7d5e9b4
--- /dev/null
+++ b/src/views/admin/MerchantManagement.vue
@@ -0,0 +1,711 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/merchant/Dashboard/index.vue b/src/views/merchant/Dashboard/index.vue
new file mode 100644
index 0000000..baef9b8
--- /dev/null
+++ b/src/views/merchant/Dashboard/index.vue
@@ -0,0 +1,15 @@
+
+
+
首页
+
+
+
+
+
+
diff --git a/src/views/merchant/Finance/AccountCollection.vue b/src/views/merchant/Finance/AccountCollection.vue
new file mode 100644
index 0000000..b74995d
--- /dev/null
+++ b/src/views/merchant/Finance/AccountCollection.vue
@@ -0,0 +1,15 @@
+
+
+
收款账号
+
+
+
+
+
+
diff --git a/src/views/merchant/Finance/DailyRevenue.vue b/src/views/merchant/Finance/DailyRevenue.vue
new file mode 100644
index 0000000..6d11f46
--- /dev/null
+++ b/src/views/merchant/Finance/DailyRevenue.vue
@@ -0,0 +1,15 @@
+
+
+
每日收益
+
+
+
+
+
+
diff --git a/src/views/merchant/Finance/FinanceDownload.vue b/src/views/merchant/Finance/FinanceDownload.vue
new file mode 100644
index 0000000..98fe055
--- /dev/null
+++ b/src/views/merchant/Finance/FinanceDownload.vue
@@ -0,0 +1,15 @@
+
+
+
财务下载
+
+
+
+
+
+
diff --git a/src/views/merchant/Finance/RevenueManagement.vue b/src/views/merchant/Finance/RevenueManagement.vue
new file mode 100644
index 0000000..57af60f
--- /dev/null
+++ b/src/views/merchant/Finance/RevenueManagement.vue
@@ -0,0 +1,15 @@
+
+
+
收支管理
+
+
+
+
+
+
diff --git a/src/views/merchant/Finance/index.vue b/src/views/merchant/Finance/index.vue
new file mode 100644
index 0000000..231f89b
--- /dev/null
+++ b/src/views/merchant/Finance/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Home.vue b/src/views/merchant/Home.vue
new file mode 100644
index 0000000..99e7a3e
--- /dev/null
+++ b/src/views/merchant/Home.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Orders/Pending.vue b/src/views/merchant/Orders/Pending.vue
new file mode 100644
index 0000000..c9ce757
--- /dev/null
+++ b/src/views/merchant/Orders/Pending.vue
@@ -0,0 +1,448 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+ {{ formatDateTime(scope.row.orderTime) }}
+
+
+
+
+ ¥{{ scope.row.orderMoney.toFixed(2) }}
+
+
+
+
+
+
+ {{ getOrderStatusText(scope.row.orderStatus) }}
+
+
+
+
+
+
+ 详情
+
+
+ 完成
+
+
+ 退款
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentOrder.orderId }}
+ {{ currentOrder.accountId }}
+ {{
+ formatDateTime(currentOrder.orderTime)
+ }}
+ ¥{{ currentOrder.orderMoney.toFixed(2) }}
+
+
+ {{ getOrderStatusText(currentOrder.orderStatus) }}
+
+
+ {{
+ currentOrder.branchName
+ }}
+
+ {{ currentOrder.orderRemarks || '无备注' }}
+
+
+
+
+
+
订单明细
+
+
+
+
+ ¥{{ scope.row.price.toFixed(2) }}
+
+
+
+
+
+ ¥{{ (scope.row.price * scope.row.number).toFixed(2) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Orders/Refund.vue b/src/views/merchant/Orders/Refund.vue
new file mode 100644
index 0000000..8a00ae7
--- /dev/null
+++ b/src/views/merchant/Orders/Refund.vue
@@ -0,0 +1,15 @@
+
+
+
退款管理
+
+
+
+
+
+
diff --git a/src/views/merchant/Orders/index.vue b/src/views/merchant/Orders/index.vue
new file mode 100644
index 0000000..c1aed28
--- /dev/null
+++ b/src/views/merchant/Orders/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Products/ProductList.vue b/src/views/merchant/Products/ProductList.vue
new file mode 100644
index 0000000..755670b
--- /dev/null
+++ b/src/views/merchant/Products/ProductList.vue
@@ -0,0 +1,754 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ scope.row.dishName }}
+
+
+
+
+
+
+ ¥{{ scope.row.price }}
+
+
+
+
+
+ {{ scope.row.stock }}
+
+
+
+
+
+
+ {{ scope.row.status }}
+
+
+
+
+
+
+
+ {{ scope.row.tag }}
+
+
+
+
+
+ {{ formatDateTime(scope.row.createdAt) }}
+
+
+
+
+
+ 查看
+
+
+ 编辑
+
+
+ {{ scope.row.status === '在售' ? '停售' : '上架' }}
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentDish.dishId }}
+ {{ currentDish.dishName }}
+ {{ currentDish.category }}
+ ¥{{ currentDish.price }}
+ {{ currentDish.stock }}
+ {{ currentDish.sales }}
+
+
+ {{ currentDish.status }}
+
+
+
+ {{ currentDish.tag }}
+ 无
+
+
+ {{ formatDateTime(currentDish.createdAt) }}
+
+
+ {{ formatDateTime(currentDish.updatedAt) }}
+
+
+ {{ currentDish.description || '无描述' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 在售
+ 停售
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 在售
+ 停售
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Products/index.vue b/src/views/merchant/Products/index.vue
new file mode 100644
index 0000000..ec4ac03
--- /dev/null
+++ b/src/views/merchant/Products/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Reviews/ReplyManagement.vue b/src/views/merchant/Reviews/ReplyManagement.vue
new file mode 100644
index 0000000..78f000d
--- /dev/null
+++ b/src/views/merchant/Reviews/ReplyManagement.vue
@@ -0,0 +1,15 @@
+
+
+
评价回复
+
+
+
+
+
+
diff --git a/src/views/merchant/Reviews/StoreReviews.vue b/src/views/merchant/Reviews/StoreReviews.vue
new file mode 100644
index 0000000..3406ba3
--- /dev/null
+++ b/src/views/merchant/Reviews/StoreReviews.vue
@@ -0,0 +1,607 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatDateTime(rScope.row.createdAt) }}
+
+
+
+
+
+ 删除
+
+
+
+
+
+ 暂无回复
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatDateTime(scope.row.createdAt) }}
+
+
+
+
+
+ 查看
+
+
+ 回复
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Reviews/index.vue b/src/views/merchant/Reviews/index.vue
new file mode 100644
index 0000000..9982800
--- /dev/null
+++ b/src/views/merchant/Reviews/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Stores/StoreInfo.vue b/src/views/merchant/Stores/StoreInfo.vue
new file mode 100644
index 0000000..5dd3c2d
--- /dev/null
+++ b/src/views/merchant/Stores/StoreInfo.vue
@@ -0,0 +1,718 @@
+
+
+
+
+
+
+
+ 基础信息设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存信息
+
+
+
+ 重置
+
+
+
+
+
+
+
+
+ 营业状况设置
+
+
+
+
+
+
+
+
+ 营业中
+
+
+ 暂停营业
+
+
+ 停业整顿
+
+
+
+
+
+
+
+
+
+
+
+ 至
+
+
+
+
+
+
+
+
+
+ 保存设置
+
+
+
+ 重置
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/merchant/Stores/index.vue b/src/views/merchant/Stores/index.vue
new file mode 100644
index 0000000..ede5290
--- /dev/null
+++ b/src/views/merchant/Stores/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/user/About.vue b/src/views/user/About.vue
new file mode 100644
index 0000000..32f993d
--- /dev/null
+++ b/src/views/user/About.vue
@@ -0,0 +1,121 @@
+
+
+
团队成员
+
+
+
+
![头像]()
+
+
+
{{ member.name }}
+
学号:{{ member.studentId }}
+
具体分工:
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/user/Contact.vue b/src/views/user/Contact.vue
new file mode 100644
index 0000000..82ec5aa
--- /dev/null
+++ b/src/views/user/Contact.vue
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/src/views/user/FrontLayout.vue b/src/views/user/FrontLayout.vue
new file mode 100644
index 0000000..ae8582d
--- /dev/null
+++ b/src/views/user/FrontLayout.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/user/Header.vue b/src/views/user/Header.vue
new file mode 100644
index 0000000..e40721a
--- /dev/null
+++ b/src/views/user/Header.vue
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
diff --git a/src/views/user/Home.vue b/src/views/user/Home.vue
new file mode 100644
index 0000000..87aecec
--- /dev/null
+++ b/src/views/user/Home.vue
@@ -0,0 +1,285 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 火热新品
+
+
+
+
+
![图片]()
+
+
{{ item.dishName || '未命名' }}
+
+ ¥{{ item.price?.toFixed(2) || '0.00' }}
+
+ 查看详情
+
+
+
+
+
+
+
+
+
+
+
+ 热门菜品
+
+
+
+
+
![图片]()
+
+
{{ item.dishName || '未命名' }}
+
+ ¥{{ item.price?.toFixed(2) || '0.00' }}
+
+ 查看详情
+
+
+
+
+
+
+
+
+
+
+
+ 猜你想吃
+
+
+
+
![图片]()
+
+
{{ item.dishName || '未命名' }}
+
+ ¥{{ item.price?.toFixed(2) || '0.00' }}
+
+ 查看详情
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/user/Search.vue b/src/views/user/Search.vue
new file mode 100644
index 0000000..c107b28
--- /dev/null
+++ b/src/views/user/Search.vue
@@ -0,0 +1,173 @@
+
+
+
美食菜品搜索
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
搜索结果
+
+
+
+
+ 菜名: {{ dish.dishName }}
+ {{ dish.description }}
+ 价格: ¥{{ dish.price }}
+ 查看菜品详情
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/user/Shopping.vue b/src/views/user/Shopping.vue
new file mode 100644
index 0000000..2f782b9
--- /dev/null
+++ b/src/views/user/Shopping.vue
@@ -0,0 +1,246 @@
+
+
+ 总金额:¥{{ totalPrice.toFixed(2) }}
+
+ 生成订单
+ 取消
+ 确认支付
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/user/SpendingChart.vue b/src/views/user/SpendingChart.vue
new file mode 100644
index 0000000..fe7edc3
--- /dev/null
+++ b/src/views/user/SpendingChart.vue
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
diff --git a/src/views/user/detail.vue b/src/views/user/detail.vue
new file mode 100644
index 0000000..1ddf40e
--- /dev/null
+++ b/src/views/user/detail.vue
@@ -0,0 +1,539 @@
+
+
+
+
+
+
+
+
![]()
+
+ {{ product.dishName }}
+
+ 价格:
+ {{ product.price }}
+
+
+
+ 标签:
+
+ {{ tag }}
+
+
+
+
+ 库存:
+
+ {{ product.stock }} 件
+
+
+
+
+ 状态:
+
+ {{ product.status }}
+
+
+
+
+
菜品描述
+
{{ product.description }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/user/location.vue b/src/views/user/location.vue
new file mode 100644
index 0000000..842a42b
--- /dev/null
+++ b/src/views/user/location.vue
@@ -0,0 +1,186 @@
+
+
+
定位
+
{{ address || '未定位' }}
+
+
+
店名: {{ store.branchName }}
+
地址: {{ store.branchAddress }}
+
电话: {{ store.branchPhone }}
+
+
+ 选择
+ 导航
+
+
+
+
+ 确认选择 {{ selectedStore?.branchName }} 吗?
+
+
+ 取消
+ 选择
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/user/orders.vue b/src/views/user/orders.vue
new file mode 100644
index 0000000..2c80943
--- /dev/null
+++ b/src/views/user/orders.vue
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
订单号: {{ order.orderId }}
+
创建时间: {{ order.orderTime }}
+
金额: ¥{{ order.orderMoney ? order.orderMoney.toFixed(2) : '0.00' }}
+
+
+ {{ getOrderStatusText(order.orderStatus) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.dishDetail?.dishName || '未知菜品' }}
+
+
+ 单价:¥{{ item.dishDetail?.price?.toFixed(2) || '0.00' }}
+ 数量:{{ item.number }}
+ 小计:¥{{ (item.dishDetail?.price * item.number).toFixed(2) }}
+
+
+
+
+
+
+ 总计:¥{{ selectedOrder?.orderMoney?.toFixed(2) || '0.00' }}
+
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/user/type.vue b/src/views/user/type.vue
new file mode 100644
index 0000000..68972cb
--- /dev/null
+++ b/src/views/user/type.vue
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
+
+ {{ currentCategoryName }} - 菜品列表
+ 全部菜品
+
+
+
+
+
+
+
+ 菜名: {{ product.dishName }}
+ {{ product.description }}
+ 价格: ¥{{ product.price }}
+ 查看菜品详情
+
+
+
+
已经到底了
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..913b8f2
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,12 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..66b5e57
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..a83dfc9
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node22/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*",
+ "eslint.config.*"
+ ],
+ "compilerOptions": {
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..4217010
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueDevTools from 'vite-plugin-vue-devtools'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueDevTools(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ },
+ },
+})