Compare commits

...

7 Commits

13 changed files with 684 additions and 213 deletions

View File

@ -4,7 +4,7 @@
## 正式宝塔
<https://121.40.128.145:38279/>
<https://121.40.128.145:38279/mianban/>
chaozg
chaozg123

View File

@ -9,6 +9,12 @@ const MenuApi = {
method: "get",
});
},
getCashMenus() {
return request<any, CashMenu[]>({
url: `${baseURL}/list/cash`,
method: "get",
});
},
/**获取所有菜单 */
getList(data: getListRequest) {
return request<any, MenuVO[]>({
@ -48,6 +54,13 @@ const MenuApi = {
};
export default MenuApi;
export interface CashMenu {
component?: null | string;
menuId: number;
name: null | string;
path?: null | string;
[property: string]: any;
}
/** RouteVO路由对象 */
export interface RouteVO {

View File

@ -33,11 +33,11 @@ const RoleApi = {
});
},
// 获取角色对应的菜单id
getMenu(id: number) {
getMenu(id: number, type: number = 0) {
return request<any, any[]>({
url: `${baseURL}/menu`,
method: "get",
params: { id },
params: { id, type },
});
},
};

View File

@ -515,6 +515,7 @@ import {
import ExcelJS from "exceljs";
import { reactive, ref } from "vue";
import type { IContentConfig, IObject, IOperatData } from "./types";
import { el } from "element-plus/es/locale";
//
const props = defineProps<{
@ -592,6 +593,45 @@ const selectionData = ref<IObject[]>([]);
// ID
const removeIds = ref<(number | string)[]>([]);
function handleSelectionChange(selection: any[]) {
console.log("selectionData.value", selectionData.value);
// if(selection.length==0){
// selectionData.value=selectionData.value.filter((item) => {
// return pageData.value.find(v=>v[pk]===item[pk])!=undefined
// });
// }else{
// selectionData.value=selectionData.value.filter((item) => {
// return pageData.value.find(v=>v[pk]===item[pk])==undefined
// });
// }
//
if (selection.length == 0 && selectionData.value.length > 0) {
defaultSelData.value = defaultSelData.value.filter((item) => {
return pageData.value.find((v) => v[pk] === item[pk]) != undefined;
});
}
//
if (selection.length > 0 && selectionData.value.length == 0) {
defaultSelData.value = selection;
}
//
if (selection.length > 0 && selectionData.value.length > 0) {
defaultSelData.value = defaultSelData.value.filter((item) => {
const isNowPageData = pageData.value.find((v) => v[pk] === item[pk]);
if (isNowPageData) {
return selection.find((v) => v[pk] === item[pk]) != undefined;
} else {
return true;
}
});
for (let i of selection) {
if (defaultSelData.value.find((v) => v[pk] === i[pk]) == undefined) {
defaultSelData.value.push(i);
}
}
}
console.log("defaultSelData.value", defaultSelData.value);
selectionData.value = selection;
removeIds.value = selection.map((item) => item[pk]);
}
@ -990,6 +1030,9 @@ function fetchPageData(formData: IObject = {}, isRestart = false) {
} else {
pageData.value = data;
}
nextTick(() => {
setSelectTable(defaultSelData.value);
});
})
.finally(() => {
loading.value = false;
@ -1030,14 +1073,42 @@ function saveXlsx(fileData: BlobPart, fileName: string) {
document.body.removeChild(downloadLink);
window.URL.revokeObjectURL(downloadUrl);
}
function test(rows: any[]) {
console.log(tableRef, "tioshi222222222222222222222");
// rows.forEach((row) => {
// tableRef.value!.toggleRowSelection(row, undefined)
// })
function test(rows: any[]) {}
const defaultSelData = ref<IObject[]>([]);
//
function setSelectTable(rows: any[]) {
selectionData.value = rows;
defaultSelData.value = rows;
pageData.value.forEach((element: IObject) => {
rows.forEach((row) => {
if (element.id == row.id) {
console.log("selected", element);
tableRef.value!.toggleRowSelection(element, true);
}
});
});
}
//
function clearSelectTable() {
selectionData.value = [];
defaultSelData.value = [];
pageData.value.forEach((element: IObject) => {
tableRef.value!.toggleRowSelection(element, false);
});
}
//
defineExpose({ fetchPageData, exportPageData, getFilterParams, getselectTable, pagination, test });
defineExpose({
clearSelectTable,
fetchPageData,
exportPageData,
getFilterParams,
getselectTable,
pagination,
test,
setSelectTable,
});
</script>
<style lang="scss" scoped>

View File

@ -1,45 +1,44 @@
<template>
<el-dialog v-model="dialogVisible" :title="props.title" :width="props.width">
<el-dialog v-model="dialogVisible" :title="props.title" :width="props.width" @close="close">
<slot></slot>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="Confirm">
确定
</el-button>
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="Confirm">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'
import { ref } from "vue";
import { ElMessageBox } from "element-plus";
let props = defineProps({
title: {
type: String,
default: 'Dialog'
default: "Dialog",
},
width: {
type: String,
default: '30%'
}
})
const emit = defineEmits(['confirm'])
const dialogVisible = ref(false)
default: "30%",
},
});
const emit = defineEmits(["confirm", "close"]);
const dialogVisible = ref(false);
function open() {
dialogVisible.value = true
dialogVisible.value = true;
}
function Confirm() {
emit('confirm')
emit("confirm");
}
function close() {
dialogVisible.value = false
dialogVisible.value = false;
emit("close");
}
defineExpose({ open, close })
defineExpose({ open, close });
</script>
<style scoped>
.dialog-footer button:first-child {

98
src/data/menus.ts Normal file
View File

@ -0,0 +1,98 @@
//收银机菜单列表
export const casher_windows_menus = [
{
title: '销售汇总',
icon: '/static/indexImg/PAGE_SALES_SUMMARY.svg',
pageUrl: 'PAGES_SALES_SUMMARY'
},
{
title: '代客下单',
icon: '/static/indexImg/icon-substitute-ordering.svg',
pageUrl: 'PAGES_CREATE_ORDER',
},
{
title: '桌台',
icon: '/static/indexImg/icon-table.svg',
pageUrl: 'PAGES_TABLE'
},
{
title: '商品管理',
icon: '/static/indexImg/icon-product-control.svg',
pageUrl: 'PAGES_PRODUCT'
},
{
title: '分组管理',
icon: '/static/indexImg/goods-group.svg',
pageUrl: 'PAGES_GOODS_GROUP'
},
{
title: '分类管理',
icon: '/static/indexImg/icon-category.svg',
pageUrl: 'PAGES_CATEGORY'
},
{
title: '会员管理',
icon: '/static/indexImg/icon-user.svg',
pageUrl: 'PAGES_USER_CONTROL'
},
{
title: '员工管理',
icon: '/static/indexImg/icon-staff.svg',
pageUrl: 'PAGES_STAFF'
},
{
title: '耗材管理',
icon: '/static/indexImg/PAGE_SALES_SUMMARY.svg',
pageUrl: 'PAGES_SALES_CONSUMABLES'
},
{
title: '订单管理',
icon: '/static/indexImg/icon-order.svg',
pageUrl: 'PAGES_ORDER_INDEX'
},
{
title: '设备管理',
icon: '/static/indexImg/icon-printer.svg',
pageUrl: 'PAGES_PRINTER_INDEX'
},
{
title: '交班',
icon: '/static/indexImg/icon-work.svg',
pageUrl: 'PAGES_WORK_INDEX'
},
{
title: '排队',
icon: '/static/indexImg/icon-line-up.svg',
pageUrl: 'PAGES_LINE_UP'
},
{
title: '霸王餐',
icon: '/static/indexImg/icon-bwc.svg',
pageUrl: 'PAGES_BWC'
},
{
title: '优惠券',
icon: '/static/coupon/icon_coupon.svg',
pageUrl: 'PAGES_COUPON_INDEX'
},
{
title: '订阅通知',
icon: '/static/indexImg/icon-notification.svg',
pageUrl: 'PAGES_NOTIFICATION_INDEX'
},
{
title: '挂账管理',
icon: '/static/indexImg/icon_credit.svg',
pageUrl: 'PAGES_CREDIT_BUYER_INDEX'
},
{
title: '核销管理',
icon: '/static/indexImg/pagewriteoff.svg',
pageUrl: 'PAGES_WEITEOFF'
},
{
title: '退出登录',
icon: '/static/indexImg/icon-login-out.svg',
pageUrl: 'PAGES_LOGIN',
}
]

View File

@ -22,6 +22,11 @@ export const useCartsStore = defineStore("carts", () => {
let dinnerType = ref<string>('dine-in');
//就餐模式 先付 后付
const isPayBefore = computed(() => {
return shopUser.userInfo.registerType == 'before' ? true : false;
});
//是否启用会员价
const useVipPrice = computed(() => {
@ -776,7 +781,7 @@ export const useCartsStore = defineStore("carts", () => {
changeTable,
rotTable,
getGoods,
setGoodsMap
setGoodsMap, isPayBefore
};
});

View File

@ -233,6 +233,49 @@
</el-input>
</el-form-item>
<el-form-item label="小程序路径" prop="miniPath">
<el-input v-model="formData.miniPath" placeholder="pages/index/index" />
</el-form-item>
<el-form-item label="小程序组件" prop="miniComponent">
<el-input v-model="formData.miniComponent" placeholder="小程序组件名称" />
</el-form-item>
<el-form-item label="小程序图标">
<single-image-upload
style="width: 100px; height: 100px"
v-model="formData.miniIcon"
></single-image-upload>
</el-form-item>
<el-form-item label="接口路径" prop="miniPage">
<div class="w-full">
<div>
<el-button @click="apiInfoPush" icon="plus" type="primary">添加</el-button>
</div>
<div class="u-flex u-m-t-10" v-for="(item, index) in formData.apiInfo" :key="index">
<el-form-item label="请求方式" label-position="left">
<el-select v-model="item.method" style="width: 100px">
<el-option
v-for="(item, index) in apiMethodOptions"
:key="index"
:value="item.value"
>
{{ item.label }}
</el-option>
</el-select>
</el-form-item>
<el-form-item label="接口地址" style="flex: 1">
<el-input v-model="item.url" placeholder="支持通配符*和?" />
</el-form-item>
<el-icon
style="margin-left: 10px"
size="20"
color="#F56c6c"
@click="formData.apiInfo.splice(index, 1)"
>
<RemoveFilled />
</el-icon>
</div>
</div>
</el-form-item>
<el-form-item v-if="formData.type !== MenuTypeEnum.BUTTON" prop="hidden" label="显示状态">
<el-radio-group v-model="formData.hidden">
<el-radio :value="1">隐藏</el-radio>
@ -302,7 +345,19 @@ const dialog = reactive({
title: "新增菜单",
visible: false,
});
const apiMethodOptions = ref([
{ value: "All", label: "All" },
{ value: "GET", label: "GET" },
{ value: "POST", label: "POST" },
{ value: "PUT", label: "PUT" },
{ value: "DELETE", label: "DELETE" },
]);
function apiInfoPush() {
if (!formData.value.apiInfo) {
formData.value.apiInfo = [];
}
formData.value.apiInfo.push({ method: "All", url: "" });
}
//
const queryParams = reactive<getListRequest>({});
//
@ -326,6 +381,10 @@ const initialeditRequestData = ref<editRequest>({
path: "",
component: "",
name: "",
miniPath: "",
miniComponent: "",
miniIcon: "",
apiInfo: [],
});
//
const formData = ref({ ...initialeditRequestData.value });
@ -414,6 +473,7 @@ function handleOpenDialog(pid?: string, menuId?: string) {
path: data.path || "", // Ensure path is always a string
title: data.title || "", // Ensure title is always a string
type: data.type ?? 0, // Ensure type is always a number
apiInfo: data.apiInfo ? JSON.parse(data.apiInfo) : [],
};
});
} else {

View File

@ -3,7 +3,12 @@
<div class="search-bar">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item prop="keywords" label="关键字">
<el-input v-model="queryParams.key" placeholder="角色名称" clearable @keyup.enter="handleQuery" />
<el-input
v-model="queryParams.key"
placeholder="角色名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
@ -21,8 +26,14 @@
</el-button> -->
</div>
<el-table ref="dataTableRef" v-loading="loading" :data="roleList" highlight-current-row :border="true"
@selection-change="handleSelectionChange">
<el-table
ref="dataTableRef"
v-loading="loading"
:data="roleList"
highlight-current-row
:border="true"
@selection-change="handleSelectionChange"
>
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="角色名称" prop="name" />
<el-table-column label="角色级别" prop="level" />
@ -30,33 +41,60 @@
<el-table-column label="创建日期" prop="createTime" />
<el-table-column fixed="right" label="操作" width="220">
<template #default="scope">
<el-button type="primary" size="small" link icon="position" @click="handleOpenAssignPermDialog(scope.row)">
<el-button
type="primary"
size="small"
link
icon="position"
@click="handleOpenAssignPermDialog(scope.row)"
>
分配菜单
</el-button>
<el-button type="primary" size="small" link icon="edit" @click="handleOpenDialog(scope.row)">
<el-button
type="primary"
size="small"
link
icon="edit"
@click="handleOpenDialog(scope.row)"
>
编辑
</el-button>
<el-button v-if="scope.row.level > 0" type="danger" size="small" link icon="delete"
@click="handleDelete(scope.row.id)">
<el-button
type="danger"
size="small"
link
icon="delete"
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.page"
v-model:limit="queryParams.size" @pagination="handleQuery" />
<pagination
v-if="total > 0"
v-model:total="total"
v-model:page="queryParams.page"
v-model:limit="queryParams.size"
@pagination="handleQuery"
/>
</el-card>
<!-- 角色表单弹窗 -->
<el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" @close="handleCloseDialog">
<el-dialog
v-model="dialog.visible"
:title="dialog.title"
width="500px"
@close="handleCloseDialog"
>
<el-form ref="addRequestRef" :model="formData" :rules="rules" label-width="100px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入角色名称" />
</el-form-item>
<el-form-item label="角色等级" prop="level">
<el-input-number v-model="formData.level" placeholder="角色等级" :min="1" :precision="0" />
<el-input-number placeholder="角色等级" v-model="formData.level"></el-input-number>
</el-form-item>
<!-- <el-form-item label="数据菜单" prop="dataScope">
@ -68,12 +106,12 @@
</el-select>
</el-form-item> -->
<el-form-item label="描述" prop="description">
<el-input v-model="formData.description" type="textarea" placeholder="描述" />
</el-form-item>
<el-form-item label="菜单分配" prop="menuIdList">
<menuSelect ref="refmenuSelect" v-model="formData.menuIdList" />
<el-input type="textarea" v-model="formData.description" placeholder="描述" />
</el-form-item>
<el-alert title="角色菜单请点击角色列表的分配菜单按钮编辑" type="success" effect="dark" />
<!-- <el-form-item label="菜单分配" prop="menuIdList">
<menuSelect ref="refmenuSelect" v-model="formData.menuIdList"></menuSelect>
</el-form-item> -->
</el-form>
<template #footer>
@ -85,43 +123,90 @@
</el-dialog>
<!-- 分配菜单弹窗 -->
<el-drawer v-model="assignPermDialogVisible" :title="'【' + checkedRole.name + '】菜单分配'" size="500">
<div class="flex-x-between">
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单菜单名称">
<template #prefix>
<Search />
<el-drawer v-model="assignPermDialogVisible" size="500">
<template #header>
<div>
<div>
<h3>
{{ "【" + checkedRole.name + "】菜单分配" }}
</h3>
</div>
<div>
<el-form-item label="平台类型">
<el-radio-group v-model="platformType" @change="handlePlatformTypeChange">
<el-radio :value="0">管理端</el-radio>
<el-radio :value="1">收银机</el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="flex-x-between">
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单菜单名称">
<template #prefix>
<Search />
</template>
</el-input>
<div class="flex-center ml-5">
<el-button type="primary" size="small" plain @click="togglePermTree">
<template #icon>
<Switch />
</template>
{{ isExpanded ? "收缩" : "展开" }}
</el-button>
<el-checkbox
v-model="parentChildLinked"
class="ml-5"
@change="handleparentChildLinkedChange"
>
父子联动
</el-checkbox>
<el-tooltip placement="bottom">
<template #content>
如果只需勾选菜单菜单不需要勾选子菜单或者按钮菜单请关闭父子联动
</template>
<el-icon class="ml-1 color-[--el-color-primary] inline-block cursor-pointer">
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
</div>
</div>
</template>
<div class="u-relative" style="overflow-x: hidden">
<el-tree
ref="permTreeRef"
node-key="value"
show-checkbox
:data="menuPermOptions"
:default-checked-keys="adminMenuIdList"
:filter-node-method="handlePermFilter"
:default-expand-all="true"
:check-strictly="!parentChildLinked"
class="mt-5"
>
<template #default="{ data }">
{{ data.label }}
</template>
</el-input>
<div class="flex-center ml-5">
<el-button type="primary" size="small" plain @click="togglePermTree">
<template #icon>
<Switch />
</template>
{{ isExpanded ? "收缩" : "展开" }}
</el-button>
<el-checkbox v-model="parentChildLinked" class="ml-5" @change="handleparentChildLinkedChange">
父子联动
</el-checkbox>
<el-tooltip placement="bottom">
<template #content>
如果只需勾选菜单菜单不需要勾选子菜单或者按钮菜单请关闭父子联动
</template>
<el-icon class="ml-1 color-[--el-color-primary] inline-block cursor-pointer">
<QuestionFilled />
</el-icon>
</el-tooltip>
</el-tree>
<div
class="cashMenuIdList"
:style="{
transform: `translateX(${(platformType == 1 ? 0 : 1) * 100}%)`,
}"
>
<el-checkbox-group v-model="cashMenuIdList">
<el-checkbox
v-for="(item, index) in casher_windows_menus"
:key="index"
:value="item.menuId"
>
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<el-tree ref="permTreeRef" node-key="value" show-checkbox :data="menuPermOptions"
:filter-node-method="handlePermFilter" :default-expand-all="true" :check-strictly="!parentChildLinked"
class="mt-5">
<template #default="{ data }">
{{ data.label }}
</template>
</el-tree>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="handleAssignPermSubmit"> </el-button>
@ -138,11 +223,11 @@ defineOptions({
inheritAttrs: false,
});
import { useUserStore } from "@/store/modules/user";
// import { casher_windows_menus } from "@/data/menus";
const shopUser = useUserStore();
import menuSelect from "./components/menus.vue";
import RoleApi, { SysRole, addRequest, getListRequest } from "@/api/account/role";
import MenuAPI, { type RouteVO } from "@/api/account/menu";
import MenuAPI, { type RouteVO, CashMenu } from "@/api/account/menu";
const queryFormRef = ref();
const addRequestRef = ref();
@ -168,6 +253,7 @@ const menuPermOptions = ref<RouteVO[]>([]);
const dialog = reactive({
title: "",
visible: false,
row: {},
});
//
const formData = reactive<addRequest>({
@ -179,7 +265,7 @@ const formData = reactive<addRequest>({
menuIdList: [],
description: "",
});
const cashMenuIdList = ref<number[]>([]);
const rules = reactive({
name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
level: [{ required: false, message: "请输入角色等级", trigger: "blur" }],
@ -198,6 +284,14 @@ const isExpanded = ref(true);
const parentChildLinked = ref(false);
const platformType = ref(0);
function handlePlatformTypeChange(e: string | number | boolean | undefined) {
const value = Number(e); // Ensure the value is cast to a number
console.log("handlePlatformTypeChange");
platformType.value = value;
handleOpenAssignPermDialog(dialog.row);
}
//
function handleQuery() {
loading.value = true;
@ -228,15 +322,16 @@ function handleSelectionChange(selection: any) {
//
async function handleOpenDialog(row: SysRole) {
dialog.visible = true;
dialog.row = row;
if (row && row.id) {
dialog.title = "修改角色";
//
const data = await RoleApi.getMenu(row.id);
const data = await RoleApi.getMenu(row.id, platformType.value);
console.log(data);
Object.assign(formData, row);
formData.menuIdList = data;
setTimeout(() => {
refmenuSelect.value.setChecked(data);
// refmenuSelect.value.setChecked(data);
}, 300);
console.log(formData);
} else {
@ -248,11 +343,12 @@ async function handleOpenDialog(row: SysRole) {
function handleSubmit() {
addRequestRef.value.validate((valid: any) => {
if (valid) {
const checkedMenuIds: number[] = refmenuSelect.value.getPerms();
// const checkedMenuIds: number[] = refmenuSelect.value.getPerms();
loading.value = true;
const roleId = formData.id;
if (roleId) {
RoleApi.update(roleId, { ...formData, menuIdList: checkedMenuIds })
// RoleApi.update(roleId, { ...formData, menuIdList: checkedMenuIds })
RoleApi.update(roleId, formData)
.then(() => {
ElMessage.success("修改成功");
handleCloseDialog();
@ -276,9 +372,9 @@ function handleSubmit() {
//
function handleCloseDialog() {
addRequestRef.value.resetFields();
addRequestRef.value.clearValidate();
refmenuSelect.value.reset();
addRequestRef.value?.resetFields();
addRequestRef.value?.clearValidate();
refmenuSelect.value?.reset();
formData.id = undefined;
formData.sort = 1;
formData.status = 1;
@ -330,6 +426,13 @@ function returnMenu(menu) {
});
}
const casher_windows_menus = ref<CashMenu[]>([]);
//
async function getCashMenus() {
const res = await MenuAPI.getCashMenus();
console.log(res);
casher_windows_menus.value = res;
}
//
async function getMenuPermOptions() {
let arr =
@ -337,27 +440,43 @@ async function getMenuPermOptions() {
menuPermOptions.value = returnMenu(arr);
}
getMenuPermOptions();
getCashMenus();
const adminMenuIdList = ref<number[]>([]);
//
async function handleOpenAssignPermDialog(row: SysRole) {
const roleId = row.id;
dialog.row = row;
if (roleId) {
assignPermDialogVisible.value = true;
loading.value = true;
checkedRole.value.id = roleId;
checkedRole.value.name = row.name as string;
//
RoleApi.getMenu(roleId)
.then((data) => {
const checkedMenuIds = data;
checkedMenuIds.forEach((menuId) => permTreeRef.value!.setChecked(menuId, true, false));
})
.finally(() => {
loading.value = false;
});
getMenuIds(roleId);
}
}
//
function getMenuIds(roleId: number) {
roleId = roleId ? roleId : dialog.row.id;
if (!roleId) {
return;
}
RoleApi.getMenu(roleId, platformType.value)
.then((data) => {
if (platformType.value == 0) {
const checkedMenuIds = data;
adminMenuIdList.value = data;
// checkedMenuIds.forEach((menuId) => permTreeRef.value!.setChecked(menuId, true, false));
}
if (platformType.value == 1) {
cashMenuIdList.value = data;
}
})
.finally(() => {
loading.value = false;
});
}
//
function handleAssignPermSubmit() {
@ -369,7 +488,13 @@ function handleAssignPermSubmit() {
.map((node: any) => node.value);
loading.value = true;
RoleApi.update(roleId, { name, menuIdList: checkedMenuIds })
RoleApi.update(roleId, {
name,
adminMenuIdList: checkedMenuIds,
cashMenuIdList: cashMenuIdList.value.filter((id) =>
casher_windows_menus.value.find((v) => v.menuId == id)
),
})
.then(() => {
ElMessage.success("分配菜单成功");
assignPermDialogVisible.value = false;
@ -417,6 +542,9 @@ watch(
(val) => {
if (!val) {
permTreeRef.value.setCheckedKeys([]);
platformType.value = 0;
cashMenuIdList.value = [];
adminMenuIdList.value = [];
}
}
);
@ -440,3 +568,14 @@ onMounted(() => {
handleQuery();
});
</script>
<style scoped lang="scss">
.cashMenuIdList {
position: absolute;
box-sizing: border-box;
padding: var(--el-drawer-padding-primary);
inset: 0;
background-color: #fff;
z-index: 2;
transition: all 0.3s ease-in-out;
}
</style>

View File

@ -4,11 +4,18 @@
<template v-if="isA">
<!-- 搜索 -->
<!-- 列表 -->
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
<page-content
ref="contentRef"
:content-config="contentConfig"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
@ -22,7 +29,11 @@
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
<copy-button
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template>
</page-content>
@ -51,7 +62,11 @@
</page-modal> -->
<!-- 编辑 -->
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
<page-modal
ref="editModalRef"
:modal-config="editModalConfig"
@submit-click="handleSubmitClick"
>
<template #gender="scope">
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
</template>
@ -60,23 +75,37 @@
<el-button type="primary" @click="addgoods">
<el-icon>
<Plus />
</el-icon>
</el-icon>
添加商品
</el-button>
<!-- 选责商品列表 -->
<selectGoodslist @deleteItememit="deleteItem($event)" :list="selectData"></selectGoodslist>
<selectGoodslist
@deleteItememit="deleteItem($event)"
:list="selectData"
></selectGoodslist>
</div>
</template>
<template #addmanagementtime="scope">
<template v-if="scope.formData.useTime == 1">
{{ scope.formData }}
<el-time-picker value-format="HH:mm:ss" v-model="scope.formData.saleTime" is-range range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" />
<el-time-picker
value-format="HH:mm:ss"
v-model="scope.formData.saleTime"
is-range
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</template>
</template>
</page-modal>
</template>
<template v-else>
<page-content ref="contentRef" :content-config="contentConfig2" @operat-click="handleOperatClick">
<page-content
ref="contentRef"
:content-config="contentConfig2"
@operat-click="handleOperatClick"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
@ -85,12 +114,31 @@
</page-content>
</template>
<!-- 新增添加商品 -->
<myDialog title="选择商品" width="50%" ref="myDialogRef" @Confirm="subitgood">
<page-search ref="searchRefs" :search-config="searchConfig2" @query-click="searchs"
@reset-click="handleResetClick" />
<page-content ref="contentRefs" v-if="switchref" :content-config="contentConfig2" @add-click="handleAddClick"
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
<myDialog
title="选择商品"
width="50%"
ref="myDialogRef"
@Confirm="subitgood"
@close="resetSelectData"
>
<page-search
ref="searchRefs"
:search-config="searchConfig2"
@query-click="searchs"
@reset-click="handleResetClick"
/>
<page-content
ref="contentRefs"
v-if="switchref"
:content-config="contentConfig2"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
@ -104,13 +152,14 @@
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
<copy-button
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template>
</page-content>
<!-- <el-table :data="selectData" border style="width: 100%">
<el-table-column prop="date" align="center" label="Date" />
<el-table-column prop="address" align="center" label="Address" />
@ -127,7 +176,10 @@
</el-form-item>
<el-form-item label="" v-if="selectData.length">
<!-- 选责商品列表 -->
<selectGoodslist @deleteItememit="deleteItem($event)" :list="selectData"></selectGoodslist>
<selectGoodslist
@deleteItememit="deleteItem($event)"
:list="selectData"
></selectGoodslist>
</el-form-item>
<el-form-item label="分组状态">
<el-radio-group v-model="forms.status">
@ -142,8 +194,14 @@
</el-radio-group>
</el-form-item>
<el-form-item label="时间选择" v-if="forms.useTime == 1">
<el-time-picker value-format="HH:mm:ss" v-model="forms.time" is-range range-separator=""
start-placeholder="开始时间" end-placeholder="结束时间" />
<el-time-picker
value-format="HH:mm:ss"
v-model="forms.time"
is-range
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</el-form-item>
<el-form-item label="排列方式">
<el-radio-group v-model="forms.sortMode">
@ -174,8 +232,8 @@ import contentConfig2 from "./goodsGroupconfig/content2";
import editModalConfig from "./goodsGroupconfig/edit";
import searchConfig from "./goodsGroupconfig/search";
import searchConfig2 from "./goodsGroupconfig/search2";
import myDialog from '@/components/mycomponents/myDialog.vue'
import selectGoodslist from "./goodsGroupconfig/selectGoodslist.vue"
import myDialog from "@/components/mycomponents/myDialog.vue";
import selectGoodslist from "./goodsGroupconfig/selectGoodslist.vue";
import { isSyncStatus } from "@/utils/index";
const {
@ -197,57 +255,56 @@ const {
} = usePage();
if (isSyncStatus()) {
contentConfig.toolbar[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = true
contentConfig.cols[3].templet = "custom"
contentConfig.toolbar[0].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = true;
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = true;
contentConfig.cols[3].templet = "custom";
} else {
contentConfig.toolbar[0].hidden = false
contentConfig.cols[3].templet = "switch"
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = false
contentConfig.toolbar[0].hidden = false;
contentConfig.cols[3].templet = "switch";
contentConfig.cols[contentConfig.cols.length - 1].operat[0].hidden = false;
contentConfig.cols[contentConfig.cols.length - 1].operat[1].hidden = false;
}
let switchref = ref(false)
let switchref = ref(false);
//
async function handleAddClick() {
addModalRef.value?.setModalVisible();
selectData.value = []
//
selectData.value = [];
//
// addModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
//
// addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
}
const myDialogRef = ref(null)
const myDialogRefAdd = ref(null)
const elFormref = ref(null)
let title = ref("新增分组")
const myDialogRef = ref(null);
const myDialogRefAdd = ref(null);
const elFormref = ref(null);
let title = ref("新增分组");
//
let selectData = ref([])
let selectData = ref([]);
let forms = reactive({
name: "",
status: 1,
useTime: 0,
sortMode: '0',
sortMode: "0",
sort: 1,
time: ""
})
time: "",
});
//
function addgoods() {
async function addgoods() {
// console.log(selectData.value, '')
switchref.value = true
myDialogRef.value.open()
switchref.value = true;
myDialogRef.value.open();
await nextTick();
contentRefs.value.setSelectTable(selectData.value);
}
const rules = reactive<FormRules<RuleForm>>({
name: [
{ required: true, message: '请输入分组名称', trigger: 'blur' },
],
})
name: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
});
interface RuleForm {
name: string
name: string;
}
//
@ -257,76 +314,71 @@ async function addConfirm() {
if (valid) {
let obj = {
...forms,
selectgoods: selectData.value
}
selectgoods: selectData.value,
};
//
if (selectData.value.length) {
let arr = []
let arr = [];
selectData.value.forEach((item, index) => {
arr.push(item.id)
})
obj.productIds = arr
arr.push(item.id);
});
obj.productIds = arr;
}
console.log(obj, '商品分组的参数')
console.log(obj, "商品分组的参数");
if (obj.time && obj.time.length) {
obj.saleStartTime = obj.time[0]
obj.saleEndTime = obj.time[1]
obj.saleStartTime = obj.time[0];
obj.saleEndTime = obj.time[1];
}
if (title.value == "新增分组") {
let res = await UserAPI.addunit(obj)
let res = await UserAPI.addunit(obj);
if (res.code == 200) {
ElMessage.success("添加成功");
myDialogRefAdd.value.close()
myDialogRefAdd.value.close();
}
} else {
if (obj.useTime == 0) {
obj.saleStartTime = null
obj.saleEndTime = null
obj.saleStartTime = null;
obj.saleEndTime = null;
}
let res = await UserAPI.update(obj)
let res = await UserAPI.update(obj);
if (res.code == 200) {
ElMessage.success("编辑成功");
myDialogRefAdd.value.close()
myDialogRefAdd.value.close();
}
}
// contentConfig.indexAction()
handleQueryClick()
handleQueryClick();
} else {
console.log('error submit!', fields)
console.log("error submit!", fields);
}
})
});
}
//
function subitgood() {
if (title.value == "编辑分组") {
let arr = selectData.value
let arr = selectData.value;
contentRefs.value.getselectTable().forEach((item: any) => {
let selectdata = selectData.value.find(ele => ele.id == item.id)
let selectdata = selectData.value.find((ele) => ele.id == item.id);
if (!selectdata) {
arr.push(item)
arr.push(item);
}
})
selectData.value = arr
});
selectData.value = arr;
} else {
selectData.value = contentRefs.value.getselectTable()
selectData.value = contentRefs.value.getselectTable();
}
switchref.value = false
myDialogRef.value.close()
switchref.value = false;
myDialogRef.value.close();
}
//
function deleteItem(data: any) {
selectData.value = data
selectData.value = data;
}
//
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
title.value = "编辑分组"
title.value = "编辑分组";
//
// editModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
// editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
@ -334,13 +386,13 @@ async function handleEditClick(row: IObject) {
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
// id
const data = await UserAPI.getunitinfo(row.id);
let obj = { ...data }
selectData.value = data.productList
obj.time = [obj.saleStartTime, obj.saleEndTime]
let obj = { ...data };
selectData.value = data.productList;
obj.time = [obj.saleStartTime, obj.saleEndTime];
for (let key in obj) {
forms[key] = obj[key]
forms[key] = obj[key];
}
myDialogRefAdd.value.open()
myDialogRefAdd.value.open();
// editModalRef.value?.setFormData(obj);
// editModalRef.value?.setModalVisible();
}
@ -352,15 +404,15 @@ function handleToolbarClick(name: string) {
name: "",
status: 1,
useTime: 0,
sortMode: '0',
sortMode: "0",
sort: 1,
time: ""
})
selectData.value = []
title.value = "新增分组"
time: "",
});
selectData.value = [];
title.value = "新增分组";
//
myDialogRefAdd.value.open()
myDialogRefAdd.value.open();
}
}
//
@ -398,6 +450,12 @@ async function handleOperatClick(data: IOperatData) {
}
}
//
function resetSelectData() {
contentRefs.value?.clearSelectTable();
switchref.value = false;
}
//
const isA = ref(true);
</script>

View File

@ -29,7 +29,7 @@ const contentConfig: IContentConfig = {
// // return OrderApi.edit(data);
// },
pk: "id",
toolbar: ["add"],
toolbar: [],
defaultToolbar: ["refresh", "filter", "search"],
cols: [
{ type: "selection", width: 50, align: "center" },

View File

@ -2,12 +2,24 @@
<div class="app-container">
<!-- 列表 -->
<!-- 搜索 -->
<page-search ref="searchRef" :search-config="searchConfig" @query-click="handleQueryClick"
@reset-click="handleResetClick" />
<page-search
ref="searchRef"
:search-config="searchConfig"
@query-click="handleQueryClick"
@reset-click="handleResetClick"
/>
<!-- 列表 -->
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
<page-content
ref="contentRef"
:content-config="contentConfig"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
@ -21,14 +33,18 @@
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
<copy-button
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template>
</page-content>
<!-- 新增 -->
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
<template #formFooter>
<h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3>
<!-- <h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3>
<div>
<el-checkbox-group v-model="addPagePathIdList">
<el-checkbox v-for="(item, index) in pagePathIdLists" :key="index" :value="item.value"
@ -37,24 +53,33 @@
</div>
<h3 style="color: rgb(63, 158, 255)">员工权限设置</h3>
<selectPermission v-model="addSelPermissionList" :list="permissionList"></selectPermission>
<selectPermission v-model="addSelPermissionList" :list="permissionList"></selectPermission> -->
</template>
</page-modal>
<!-- 编辑 -->
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
<page-modal
ref="editModalRef"
:modal-config="editModalConfig"
@submit-click="handleSubmitClick"
>
<template #formFooter>
<h3 style="color: rgb(63, 158, 255)">收银机权限设置</h3>
<div>
<el-checkbox-group v-model="editPagePathIdList">
<el-checkbox v-for="(item, index) in pagePathIdLists" :key="index" :value="item.value"
:label="item.label" />
<el-checkbox
v-for="(item, index) in pagePathIdLists"
:key="index"
:value="item.value"
:label="item.label"
/>
</el-checkbox-group>
</div>
<h3 style="color: rgb(63, 158, 255)">员工权限设置</h3>
<selectPermission v-model="selPermissionList" :list="permissionList"></selectPermission>
</template>
-->
</page-modal>
<!-- 修改密码 -->
@ -115,8 +140,11 @@ const oldeditSubmitFunc = editModalConfig.formAction;
//
async function init() {
//
if (JSON.parse(localStorage.getItem('userInfo') || '{}').isHeadShop == 0 && localStorage.getItem('loginType') == '0') {
searchConfig.formItems.splice(0, 1)
if (
JSON.parse(localStorage.getItem("userInfo") || "{}").isHeadShop == 0 &&
localStorage.getItem("loginType") == "0"
) {
searchConfig.formItems.splice(0, 1);
}
addModalConfig.formAction = function (data) {
return ShopStaffApi.add({

View File

@ -52,7 +52,7 @@
v-for="item in tableList"
:key="item.id"
class="item"
:style="{ 'background-color': status[item.status].type }"
:style="{ 'background-color': status[item.status] ? status[item.status].type : '' }"
>
<div class="new-top flex u-row-between">
<div class="u-flex u-flex-1 u-p-r-10">