This commit is contained in:
gyq
2026-01-05 13:36:28 +08:00
13 changed files with 802 additions and 28 deletions

68
src/api/account/quick.ts Normal file
View File

@@ -0,0 +1,68 @@
import request from "@/utils/request";
import { Account_BaseUrl } from "@/api/config";
const baseURL = Account_BaseUrl + "/admin/quick";
const API = {
getList(data: any) {
return request<any, QuickMenu[]>({
url: `${baseURL}`,
method: "get",
params: data
});
},
add(data: any) {
return request({
url: `${baseURL}`,
method: "post",
data: data,
});
},
delete(ids: [string | number]) {
return request({
url: `${baseURL}`,
method: "delete",
data: ids,
});
},
edit(data: any) {
return request({
url: `${baseURL}`,
method: "put",
data: data,
});
},
}
export default API;
/**
* 悬浮窗配置 实体类。
*
* QuickMenu
*/
export interface QuickMenu {
createTime?: string;
id?: number;
/**
* 菜单Id
*/
menuId: number;
/**
* 店铺Id
*/
shopId?: number;
/**
* 排序
*/
sort?: number;
/**
* 状态 1-启用 0-禁用
*/
status?: number;
updateTime?: string;
/**
* 菜单图标
*/
url?: string;
[property: string]: any;
}

BIN
src/assets/images/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
src/assets/images/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -0,0 +1,266 @@
<template>
<el-dialog :title="form.id ? '编辑' : '添加'" width="400px" v-model="visible" @closed="resetForm">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" label-position="left">
<el-form-item label="菜单" prop="menuId">
<el-tree-select
:check-strictly="true"
v-model="form.menuId"
:data="menus"
:render-after-expand="false"
style="width: 240px"
node-key="menuId"
:disabled-key="disabled"
></el-tree-select>
</el-form-item>
<el-form-item label="排序值">
<el-input-number v-model="form.sort" :step="1" step-strictly />
</el-form-item>
<el-form-item label="启用状态">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog_footer">
<div class="btn">
<el-button size="large" style="width: 100%" @click="visible = false"> </el-button>
</div>
<div class="btn">
<el-button
size="large"
type="primary"
:loading="loading"
style="width: 100%"
@click="submitHandle"
>
</el-button>
</div>
</div>
</template>
</el-dialog>
</template>
<script setup>
// 补充缺失的导入
import { ref, onMounted, watch } from "vue";
import { ElNotification, ElMessage } from "element-plus"; // 导入提示组件
import { filterNumberInput } from "@/utils";
import { roleTemplateAdd } from "@/api/account/roleTemplate";
import MenuAPI from "@/api/account/menu";
import quickApi from "@/api/account/quick";
const props = defineProps({
isGetMenu: {
type: Boolean,
required: false,
default: false, // 补充默认值
},
parMenus: {
type: Array,
required: false,
default: () => [], // 补充默认值
},
item: {
type: Object,
required: false,
default: () => null,
},
});
const menus = ref([]);
/**
* 格式化菜单数据:核心逻辑 - 禁用有子菜单的父节点,仅允许选叶子节点
* @param arr 原始菜单数组
* @returns 格式化后带禁用标记的菜单数组
*/
function returnMenu(arr) {
let result = [];
for (let menu of arr) {
// 过滤掉"默认接口目录"
if (menu.title === "默认接口目录") continue;
// 筛选有效子菜单:非隐藏 + 类型为0
const children = menu.children ? menu.children.filter((v) => !v.hidden && v.type === 0) : [];
// 递归处理子菜单
const formattedChildren = returnMenu(children);
// 核心:判断是否为叶子节点(无有效子菜单)
const isLeaf = formattedChildren.length === 0;
// 组装节点有子菜单则禁用disabled: true无则允许选择
const menuNode = {
...menu,
label: menu.title,
value: menu.menuId,
menuId: menu.menuId, // 保持node-key一致
disabled: !isLeaf, // 有子菜单 → 禁用,无 → 启用
children: formattedChildren,
};
// 特殊处理如果子菜单只有1个直接扁平化保持原有逻辑
if (formattedChildren.length === 1) {
result.push({
...formattedChildren[0],
disabled: formattedChildren[0].children.length > 0, // 子节点仍判断是否有后代
});
} else {
result.push(menuNode);
}
}
return result;
}
onMounted(async () => {
if (!props.isGetMenu) return;
try {
const res = await MenuAPI.getRoutes();
menus.value = returnMenu(res);
} catch (error) {
ElMessage.error("菜单数据加载失败");
console.error("getRoutes error:", error);
}
});
// 监听父组件传入的菜单变化
watch(
() => props.parMenus,
(newVal) => {
if (newVal.length) {
menus.value = returnMenu(newVal);
}
},
{ deep: true } // 监听数组内部变化
);
// 对话框显隐绑定
const visible = defineModel({
type: Boolean,
required: false,
default: false,
});
const formRef = ref(null);
const loading = ref(false);
// 表单初始化
const form = ref({
menuId: "",
sort: 0,
url: "",
status: 1,
});
/**
* 自定义校验规则:确保选中的是叶子节点(兜底验证)
* @param rule 校验规则
* @param value 选中的menuId
* @param callback 回调函数
*/
function validateLeafMenu(rule, value, callback) {
if (!value) {
return callback(new Error("请选择菜单"));
}
// 递归查找节点,判断是否为叶子节点
const findNode = (nodes, menuId) => {
for (let node of nodes) {
if (node.menuId === menuId) return node;
if (node.children) {
const res = findNode(node.children, menuId);
if (res) return res;
}
}
return null;
};
const selectedNode = findNode(menus.value, value);
if (!selectedNode) {
callback(new Error("选择的菜单不存在"));
} else if (selectedNode.disabled) {
callback(new Error("有子菜单的父节点不可选,请选择子菜单"));
} else {
callback(); // 校验通过
}
}
// 表单校验规则:修复拼写错误 + 新增自定义叶子节点校验
const rules = ref({
menuId: [
{
required: true,
validator: validateLeafMenu, // 替换原有规则为自定义校验
trigger: "change", // 选择变化时校验原triiger拼写错误
},
],
});
// 重置表单
function resetForm() {
form.value = {
menuId: "",
sort: 0,
url: "",
status: 1,
};
if (formRef.value) {
formRef.value.resetFields(); // 避免null调用
}
}
// 提交事件
const emits = defineEmits(["success"]);
async function submitHandle() {
try {
// 修复vaild拼写错误
const valid = await formRef.value.validate();
if (!valid) return;
loading.value = true;
// 排序值兜底
form.value.sort = form.value.sort === "" ? 0 : form.value.sort;
// 区分新增/编辑
if (form.value.id) {
await quickApi.edit(form.value);
ElNotification({ title: "成功", message: "编辑成功", type: "success" });
} else {
await quickApi.add(form.value);
ElNotification({ title: "成功", message: "添加成功", type: "success" });
}
emits("success");
visible.value = false;
} catch (error) {
ElMessage.error(form.value.id ? "编辑失败" : "添加失败");
console.error("submit error:", error);
} finally {
loading.value = false; // 无论成败都关闭loading
}
}
// 监听props.item初始化表单
watch(
() => props.item,
(newval) => {
if (newval) {
form.value = { ...newval }; // 深拷贝,避免修改原对象
}
},
{ deep: true, immediate: true } // 初始化触发
);
</script>
<style scoped lang="scss">
.dialog_footer {
display: flex;
gap: 14px;
.btn {
flex: 1;
}
}
// 可选:美化禁用节点的样式
.el-select-dropdown__item.is-disabled {
color: var(--el-text-color-regular);
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,183 @@
<template>
<div class="container">
<div class="table-box">
<div class="row mb-sm">
<el-button type="primary" @click="showAdd = true">添加</el-button>
</div>
<el-table
:data="tableData.list"
v-loading="tableData.loading"
stripe
border
row-key="id"
:tree-props="{ children: 'children' }"
default-expand-all
style="width: 100%"
>
<el-table-column label="ID" prop="id"></el-table-column>
<el-table-column label="菜单名称" prop="isEnable">
<template #default="scope">
{{ returnMenuName(scope.row) }}
</template>
</el-table-column>
<el-table-column label="启用状态" prop="isEnable">
<template #default="scope">
<el-switch
v-model="scope.row.status"
:active-value="1"
:inactive-value="0"
@change="isEnableChange($event, scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="排序值" prop="sort"></el-table-column>
<el-table-column label="创建时间" prop="createTime"></el-table-column>
<el-table-column label="操作" width="250">
<template #default="scope">
<el-button link type="primary" @click="editMenu(scope.row)">编辑</el-button>
<el-popconfirm title="确认要删除吗?" @confirm="deleteHandle(scope.row)">
<template #reference>
<el-button type="danger" link>删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<dialogAdd
v-model="showAdd"
:parMenus="menus"
@success="Refresh()"
:item="nowEditMenu"
></dialogAdd>
</div>
</template>
<script setup>
import { useQuickStore, usePermissionStore } from "@/store";
const quickStore = useQuickStore();
import { ref, reactive, onMounted, toRaw } from "vue";
import MenuAPI from "@/api/account/menu";
import quickApi from "@/api/account/quick";
import dialogAdd from "./dialog-add.vue";
const showAdd = ref(false);
const nowEditMenu = ref(null);
function editMenu(item) {
nowEditMenu.value = { ...item };
showAdd.value = true;
}
const tableData = reactive({
loading: false,
page: 1,
size: 10,
total: 0,
list: [],
});
function Refresh() {
quickStore.getQuickMenus();
getList();
}
function getList() {
tableData.loading = true;
quickApi
.getList({
page: tableData.page,
size: tableData.size,
isEdit: 1,
})
.then((res) => {
tableData.list = res;
tableData.total = res.length;
})
.finally(() => {
tableData.loading = false;
});
}
const menus = ref([]);
async function getMenus() {
const res = await MenuAPI.getRoutes();
menus.value = res;
console.log("menus", res);
}
const menusIdMap = computed(() => {
const map = getMenuMap();
console.log("map", map);
return map;
});
function returnMenuName(item) {
const menu = menusIdMap.value.get(`${item.menuId}`);
console.log("menuId", item.menuId);
console.log("menu", menu);
return menu ? menu.title : "";
}
function getMenuMap() {
// 初始化Map
const map = new Map();
// 定义递归函数处理菜单节点
function processMenuNode(menuNode) {
// 将当前节点存入Map
map.set(menuNode.menuId, menuNode);
// 如果有子节点且子节点数组不为空,则递归处理每个子节点
if (menuNode.children && Array.isArray(menuNode.children) && menuNode.children.length > 0) {
menuNode.children.forEach((childNode) => {
processMenuNode(childNode);
});
}
}
// 遍历根级菜单,逐个处理
if (menus.value && Array.isArray(menus.value)) {
menus.value.forEach((rootMenu) => {
processMenuNode(rootMenu);
});
}
return map;
}
function isEnableChange(value, item) {
quickApi
.edit({
...item,
status: value,
})
.then((res) => {
ElMessage({
message: "修改成功",
type: "success",
});
Refresh();
});
}
function deleteHandle(item) {
quickApi.delete([item.id]).then(() => {
Refresh();
});
}
onMounted(async () => {
await getMenus();
getList();
});
</script>
<style lang="scss" scoped>
.container {
padding: 14px;
width: 100%;
.table-box {
border-radius: 8px;
background-color: #fff;
padding: 14px;
}
}
</style>

View File

@@ -0,0 +1,95 @@
<template>
<div class="fast-menu">
<el-dropdown
trigger="click"
@command="menuClick"
placement="top-end"
@visible-change="handleVisibleChange"
append-to-body="true"
>
<img class="img" :src="imgsrc" alt="" />
<!-- <el-icon color="#fff" size="24px">
<Plus v-if="!showMenu" />
<Close v-else />
</el-icon> -->
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="(item, index) in quickStore.quickMenus"
:key="index"
:command="item.menuId"
>
{{ returnMenuName(item.menuId) }}
</el-dropdown-item>
<el-dropdown-item :command="-1">
<el-icon>
<Edit color="#4080FF" />
</el-icon>
<span style="color: #4080ff">编辑</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from "vue";
import { useQuickStore, usePermissionStore, useUserStore } from "@/store";
import router from "@/router";
const userStore = useUserStore();
const quickStore = useQuickStore();
const permissionStore = usePermissionStore();
console.log("permissionStore", permissionStore.menus);
function menuClick(menuId: number) {
console.log("menuId", menuId);
if (menuId == -1) {
if (userStore.userInfo.id == 1) {
return router.push("/system/commonlyUsedMenu");
} else {
return router.push("/commonlyUsedMenu");
}
}
permissionStore.menuJump(menuId);
}
function returnMenuName(menuId: number) {
return permissionStore.returnMenuName(menuId);
}
const imgsrc = computed(() => {
return showMenu.value
? new URL("/src/assets/images/close.png", import.meta.url).href
: new URL("/src/assets/images/plus.png", import.meta.url).href;
});
const showMenu = ref(false);
function handleVisibleChange(visible: boolean) {
showMenu.value = visible;
}
</script>
<style lang="scss" scoped>
.fast-menu {
position: fixed;
$size: 40px;
right: 40px;
bottom: 40px;
width: $size;
height: $size;
.img {
width: $size;
height: $size;
}
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
// background: linear-gradient(135deg, #409eff, #3a84ff);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
.svg-icon {
margin-right: 0;
color: #fff;
}
}
</style>

View File

@@ -27,10 +27,11 @@
<TagsView v-if="showTagsView" />
<AppMain />
<Settings v-if="defaultSettings.showSettings" />
<!-- 返回顶部 -->
<el-backtop target=".app-main">
<!-- <el-backtop target=".app-main">
<svg-icon icon-class="backtop" size="24px" />
</el-backtop>
</el-backtop> -->
</div>
</div>
@@ -42,11 +43,15 @@
</div>
<AppMain />
<Settings v-if="defaultSettings.showSettings" />
<!-- 返回顶部 -->
<el-backtop target=".app-main">
<!-- <el-backtop target=".app-main">
<svg-icon icon-class="backtop" size="24px" />
</el-backtop>
</el-backtop> -->
</div>
<!-- 悬浮球 -->
<FastMenu></FastMenu>
</div>
</template>
@@ -105,6 +110,7 @@ function handleOutsideClick() {
function toggleSidebar() {
appStore.toggleSidebar();
}
function showFastMenu() {}
const route = useRoute();
watch(route, () => {

View File

@@ -14,5 +14,6 @@ export * from "./modules/settings";
export * from "./modules/tags-view";
export * from "./modules/user";
export * from "./modules/dict";
export * from "./modules/quick";
export { store };

View File

@@ -16,6 +16,7 @@ export const usePermissionStore = defineStore("permission", () => {
// 路由是否加载完成
const isRoutesLoaded = ref(false);
const menus = ref<RouteVO[]>([])
/**
@@ -31,10 +32,9 @@ export const usePermissionStore = defineStore("permission", () => {
}
MenuAPI.getRoutes()
.then((data) => {
menus.value = data
if (!isTest) {
const dynamicRoutes = parseDynamicRoutes(data.filter(v => v.type == 0));
console.log('dynamicRoutes')
console.log(dynamicRoutes)
dynamicRoutes.forEach((route) => {
//过滤出可见子节点
let onlyOneChild = null
@@ -95,8 +95,60 @@ export const usePermissionStore = defineStore("permission", () => {
});
isRoutesLoaded.value = false;
};
function getMenuMap() {
// 初始化Map
const map = new Map();
// 定义递归函数处理菜单节点
function processMenuNode(menuNode) {
// 将当前节点存入Map
map.set(menuNode.menuId, menuNode);
// 如果有子节点且子节点数组不为空,则递归处理每个子节点
if (menuNode.children && Array.isArray(menuNode.children) && menuNode.children.length > 0) {
menuNode.children.forEach((childNode) => {
processMenuNode(childNode);
});
}
}
// 遍历根级菜单,逐个处理
if (menus.value && Array.isArray(menus.value)) {
menus.value.forEach((rootMenu) => {
processMenuNode(rootMenu);
});
}
return map;
}
function returnMenuName(menuId: number | string) {
const menu = menusIdMap.value.get(`${menuId}`);
return menu ? menu.title : '';
}
const menusIdMap = computed(() => {
const map = getMenuMap();
return map;
});
function menuJump(menuId: number | string) {
const menu = menusIdMap.value.get(`${menuId}`);
console.log('menu', menu);
if (menu) {
if (menu.name) {
router.push({ name: menu.name as string })
} else {
router.push({ path: menu.path as string })
}
}
}
return {
menuJump,
returnMenuName,
menus,
routes,
mixedLayoutLeftRoutes,
isRoutesLoaded,

View File

@@ -0,0 +1,37 @@
import { store } from "@/store";
import quickApi, { type QuickMenu } from "@/api/account/quick";
import { usePermissionStoreHook } from "@/store/modules/permission";
export const useQuickStore = defineStore("quick", () => {
const quickMenus = ref<QuickMenu[]>([]);
async function getQuickMenus() {
const res = await quickApi.getList({ isEdit: 0 });
const obj: any = {}
let arr = []
for (let menu of res) {
if (obj.hasOwnProperty(menu.menuId) || menu.status != 1 || !usePermissionStoreHook().returnMenuName(menu.menuId)) {
continue;
} else {
obj[menu.menuId] = true;
arr.push(menu)
}
}
quickMenus.value = arr;
}
getQuickMenus()
return {
quickMenus, getQuickMenus
};
});
/**
* 用于在组件外部如在Pinia Store 中)使用 Pinia 提供的 store 实例。
* 官方文档解释了如何在组件外部使用 Pinia Store
* https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
*/
export function useQuickStoreHook() {
return useQuickStore(store);
}

View File

@@ -0,0 +1,5 @@
<template>
<div>
<FastMenuConfig></FastMenuConfig>
</div>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<div>
<FastMenuConfig></FastMenuConfig>
</div>
</template>

View File

@@ -4,22 +4,38 @@
<template v-if="carts.list && carts.list.length >= 1">
<!-- 当前购物车 -->
<div v-for="(item, index) in carts.list" :key="index">
<carts-item :item="item" :useVipPrice="carts.useVipPrice" @changeNumber="changeNumber"
:selCart="carts.selCart" @itemClick="itemClick(item)" @editNote="editNote"></carts-item>
<carts-item
:item="item"
:useVipPrice="carts.useVipPrice"
@changeNumber="changeNumber"
:selCart="carts.selCart"
@itemClick="itemClick(item)"
@editNote="editNote"
></carts-item>
</div>
</template>
<!-- 赠菜 -->
<div class="cart-title" v-if="carts.giftList.length > 0"><span>以下是优惠菜品</span></div>
<div v-for="(item, index) in carts.giftList" :key="index">
<carts-item :item="item" @changeNumber="changeNumber" :useVipPrice="carts.useVipPrice" :selCart="carts.selCart"
@itemClick="itemClick(item)" @editNote="editNote"></carts-item>
<carts-item
:item="item"
@changeNumber="changeNumber"
:useVipPrice="carts.useVipPrice"
:selCart="carts.selCart"
@itemClick="itemClick(item)"
@editNote="editNote"
></carts-item>
</div>
<el-empty :image-size="60" v-if="carts.isEmpty" description="点餐列表为空" />
<!-- 打包费 -->
<template v-if="carts.packNum > 0">
<div class="cart-title"><span>打包费</span></div>
<extra-fee name="打包费" :number="carts.packNum" :price="carts.orderCostSummary.packFee"></extra-fee>
<extra-fee
name="打包费"
:number="carts.packNum"
:price="carts.orderCostSummary.packFee"
></extra-fee>
</template>
<!-- 餐位费 -->
<template v-if="perpole >= 1 && carts.dinnerType == 'dine-in'">
@@ -40,9 +56,17 @@
</div>
<div v-for="(detaiItem, index) in item" :key="index">
<carts-item :useVipPrice="carts.useVipPrice" :canChangeNumber="false" isOld :dinerType="dinerType"
:item="detaiItem" @changeNumber="changeNumber" :selCart="carts.selCart" @itemClick="itemClick(detaiItem)"
@editNote="editNote"></carts-item>
<carts-item
:useVipPrice="carts.useVipPrice"
:canChangeNumber="false"
isOld
:dinerType="dinerType"
:item="detaiItem"
@changeNumber="changeNumber"
:selCart="carts.selCart"
@itemClick="itemClick(detaiItem)"
@editNote="editNote"
></carts-item>
</div>
</template>
@@ -50,9 +74,14 @@
</div>
<div class="bottom">
<div class="u-flex u-row-right">
<el-tooltip placement="top" effect="light" popper-class="youhui-tips" :popper-options="{
'background-color': '#fff',
}">
<el-tooltip
placement="top"
effect="light"
popper-class="youhui-tips"
:popper-options="{
'background-color': '#fff',
}"
>
<template #content>
<div class="u-flex color-000 u-font-14 u-row-between">
<span class="font-bold">会员优惠</span>
@@ -74,20 +103,36 @@
</div>
<div class="u-flex u-row-between">
<el-link type="primary">打印制作单</el-link>
<!-- <el-link type="primary">打印制作单</el-link> -->
<div></div>
<div>
<span class="totalNumber">{{ customTruncateToTwoDecimals(carts.totalNumber) }}</span>
<span class="totalPrice">{{ customTruncateToTwoDecimals(carts.payMoney) }}</span>
</div>
</div>
<div class="btn-group" v-if="isXianFuKuan">
<el-button type="primary" size="large" :disabled="!disabledMorePay" @click="createOrder('wx-aiplay')">
<el-button
type="primary"
size="large"
:disabled="!disabledMorePay"
@click="createOrder('wx-aiplay')"
>
微信/支付宝
</el-button>
<el-button type="primary" size="large" :disabled="!disabledMorePay" @click="createOrder('cash')">
<el-button
type="primary"
size="large"
:disabled="!disabledMorePay"
@click="createOrder('cash')"
>
现金
</el-button>
<el-button type="primary" size="large" :disabled="!disabledMorePay" @click="createOrder('more-pay')">
<el-button
type="primary"
size="large"
:disabled="!disabledMorePay"
@click="createOrder('more-pay')"
>
更多支付
</el-button>
</div>
@@ -100,20 +145,31 @@
<el-button type="primary" size="large" :disabled="disabledMorePay" @click="createOrder('to-pay')">
去结账
</el-button> -->
<el-button type="primary" size="large"
<el-button
type="primary"
size="large"
:disabled="carts.list.length == 0 || carts.oldOrder.detailMap.length == 0"
@click="createOrder('only-create')">
@click="createOrder('only-create')"
>
仅下单
</el-button>
<el-button type="primary" size="large"
<el-button
type="primary"
size="large"
:disabled="carts.list.length == 0 && isEmptyObject(carts.oldOrder.detailMap)"
@click="createOrder('to-pay')">
@click="createOrder('to-pay')"
>
去结账
</el-button>
</template>
<template v-else>
<el-button type="default" size="large" @click="hideOrder()">加菜/返回</el-button>
<el-button type="primary" size="large" :disabled="!carts.isLinkFinshed" @click="createOrder('to-pay')">
<el-button
type="primary"
size="large"
:disabled="!carts.isLinkFinshed"
@click="createOrder('to-pay')"
>
立即支付
</el-button>
</template>
@@ -131,7 +187,7 @@ import { useUserStore } from "@/store/modules/user";
function isEmptyObject(obj) {
// 步骤1排除null和非对象类型
if (obj === null || typeof obj !== 'object') {
if (obj === null || typeof obj !== "object") {
return false;
}
// 步骤2排除数组数组也是对象需单独判断
@@ -313,4 +369,4 @@ defineExpose({
margin-left: 10px;
}
}
</style>
</style>