新增角色模板优化店铺装修
This commit is contained in:
55
src/api/account/roleTemplate.js
Normal file
55
src/api/account/roleTemplate.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import request from "@/utils/request";
|
||||
const baseURL = "/account";
|
||||
|
||||
/**
|
||||
* 角色模板 添加/编辑
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function roleTemplateAdd(data) {
|
||||
return request({
|
||||
url: `${baseURL}/admin/roleTemplate`,
|
||||
method: data.id ? "put" : "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色模板 列表
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function roleTemplateList(params) {
|
||||
return request({
|
||||
url: `${baseURL}/admin/roleTemplate/list`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色模板 删除
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function roleTemplateDel(id) {
|
||||
return request({
|
||||
url: `${baseURL}/admin/roleTemplate?id=${id}`,
|
||||
method: "DELETE"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色模板 根据模板保存角色
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function saveByTemplate(data) {
|
||||
return request({
|
||||
url: `${baseURL}/admin/role/saveByTemplate`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
<el-icon><zoom-in /></el-icon>
|
||||
</span>
|
||||
<!-- 删除 -->
|
||||
<!-- <span @click="handleRemove(file.url!)">
|
||||
<span @click="handleRemove(file.url!)">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</span> -->
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -87,14 +87,20 @@ const fileList = ref<UploadUserFile[]>([]);
|
||||
* 删除图片
|
||||
*/
|
||||
function handleRemove(imageUrl: string) {
|
||||
FileAPI.delete(imageUrl).then(() => {
|
||||
const index = modelValue.value.indexOf(imageUrl);
|
||||
if (index !== -1) {
|
||||
// 直接修改数组避免触发整体更新
|
||||
modelValue.value.splice(index, 1);
|
||||
fileList.value.splice(index, 1); // 同步更新 fileList
|
||||
}
|
||||
});
|
||||
// FileAPI.delete(imageUrl).then(() => {
|
||||
// const index = modelValue.value.indexOf(imageUrl);
|
||||
// if (index !== -1) {
|
||||
// // 直接修改数组避免触发整体更新
|
||||
// modelValue.value.splice(index, 1);
|
||||
// fileList.value.splice(index, 1); // 同步更新 fileList
|
||||
// }
|
||||
// });
|
||||
const index = modelValue.value.indexOf(imageUrl);
|
||||
if (index !== -1) {
|
||||
// 直接修改数组避免触发整体更新
|
||||
modelValue.value.splice(index, 1);
|
||||
fileList.value.splice(index, 1); // 同步更新 fileList
|
||||
}
|
||||
}
|
||||
function handleProgress(event: any, file: any, fileList: any) {
|
||||
// console.log("handleProgress", evt, file, fileList);
|
||||
|
||||
@@ -123,6 +123,15 @@ export const useUserStore = defineStore("user", () => {
|
||||
clearToken();
|
||||
usePermissionStoreHook().resetRouter();
|
||||
useDictStoreHook().clearDictionaryCache();
|
||||
|
||||
let loginType = localStorage.getItem('loginType')
|
||||
|
||||
localStorage.clear()
|
||||
|
||||
localStorage.setItem('loginType', loginType)
|
||||
|
||||
window.location.reload()
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
175
src/views/admin/system/role/components/roleTemplateDialog.vue
Normal file
175
src/views/admin/system/role/components/roleTemplateDialog.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<el-dialog title="选择角色模板" width="677px" v-model="visible">
|
||||
<div class="content">
|
||||
<div class="title">选择模板,快速创建好角色</div>
|
||||
<div class="role_template">
|
||||
<div class="item" v-for="item in list" :key="item.id" @click="selectRoleHandle(item)">
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<el-radio v-model="item.cehcked" :value="true" readonly size="large"></el-radio>
|
||||
</div>
|
||||
<div class="role_list">
|
||||
<div class="rl_t">包含角色:</div>
|
||||
<div class="rl_r">
|
||||
<div class="row" v-for="val in item.children" :key="val.id">{{ val.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<div class="btn">
|
||||
<el-button @click="visible = false" size="large" style="width: 100%;">自己创建</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" size="large" @click="submitHandle" :loading="loading" style="width: 100%;">确
|
||||
定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { roleTemplateList, saveByTemplate } from '@/api/account/roleTemplate'
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
const loading = ref(false)
|
||||
const list = ref([])
|
||||
|
||||
// 获取角色模板列表
|
||||
async function roleTemplateListAjax() {
|
||||
try {
|
||||
const res = await roleTemplateList()
|
||||
res.forEach(el => {
|
||||
el.cehcked = false
|
||||
});
|
||||
list.value = res
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function show() {
|
||||
visible.value = true
|
||||
roleTemplateListAjax()
|
||||
}
|
||||
|
||||
function selectRoleHandle(item) {
|
||||
list.value.forEach(item => item.cehcked = false)
|
||||
item.cehcked = true
|
||||
}
|
||||
|
||||
// 提交
|
||||
const emits = defineEmits(['success'])
|
||||
async function submitHandle() {
|
||||
try {
|
||||
let item = list.value.find(item => item.cehcked)
|
||||
if (item === undefined) {
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '请选择角色模板',
|
||||
type: 'error'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
await saveByTemplate({
|
||||
id: item.id
|
||||
})
|
||||
emits('success')
|
||||
visible.value = false
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 500);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
roleTemplateListAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
padding: 28px 0;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.role_template {
|
||||
padding: 14px 0 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-column-gap: 14px;
|
||||
grid-row-gap: 14px;
|
||||
|
||||
.item {
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 8px;
|
||||
padding: 14px 18px;
|
||||
transition: all .3s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.role_list {
|
||||
display: flex;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.rl_t {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.rl_r {
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -101,7 +101,7 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-x-between">
|
||||
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单菜单名称">
|
||||
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单名称">
|
||||
<template #prefix>
|
||||
<Search />
|
||||
</template>
|
||||
@@ -156,6 +156,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
<roleTemplateDialog ref="roleTemplateDialogRef" @success="handleQuery" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -170,6 +171,9 @@ const shopUser = useUserStore();
|
||||
import menuSelect from "./components/menus.vue";
|
||||
import RoleApi, { SysRole, addRequest, getListRequest } from "@/api/account/role";
|
||||
import MenuAPI, { type RouteVO, CashMenu } from "@/api/account/menu";
|
||||
import roleTemplateDialog from "./components/roleTemplateDialog.vue";
|
||||
|
||||
const roleTemplateDialogRef = ref(null)
|
||||
|
||||
const queryFormRef = ref();
|
||||
const addRequestRef = ref();
|
||||
@@ -241,6 +245,10 @@ function handleQuery() {
|
||||
.then((data) => {
|
||||
roleList.value = data.records;
|
||||
total.value = data.totalRow;
|
||||
|
||||
if (data.records.length == 0) {
|
||||
roleTemplateDialogRef?.value.show()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
<el-input placeholder="请输入" :maxlength="30" v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序值">
|
||||
<el-input placeholder="请输入" :maxlength="20" v-model="form.sort"></el-input>
|
||||
<el-input placeholder="请输入" :maxlength="20" v-model="form.sort"
|
||||
@input="e => form.sort = filterNumberInput(e, 0)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<el-switch v-model="form.isEnable" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -28,6 +29,8 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { filterNumberInput } from '@/utils'
|
||||
import { roleTemplateAdd } from "@/api/account/roleTemplate";
|
||||
|
||||
// 1添加模板 2添加类型
|
||||
const type = ref(1)
|
||||
@@ -36,13 +39,18 @@ const typeObj = ref({
|
||||
2: '角色'
|
||||
})
|
||||
|
||||
// 1添加 2编辑
|
||||
const addType = ref(1)
|
||||
|
||||
const visible = ref(false)
|
||||
const formRef = ref(null)
|
||||
const loading = ref(false)
|
||||
const form = ref({
|
||||
name: '',
|
||||
sort: '',
|
||||
status: 1
|
||||
sort: 0,
|
||||
isEnable: 1,
|
||||
roleId: '',
|
||||
pid: ''
|
||||
})
|
||||
const rules = ref({
|
||||
name: [
|
||||
@@ -58,18 +66,32 @@ function resetForm() {
|
||||
form.value = {
|
||||
name: '',
|
||||
sort: '',
|
||||
status: 1
|
||||
isEnable: 1
|
||||
}
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 提交
|
||||
const emits = defineEmits(['success'])
|
||||
function submitHandle() {
|
||||
formRef.value.validate(async vaild => {
|
||||
try {
|
||||
if (vaild) {
|
||||
loading.value = true
|
||||
// const res = await abc()
|
||||
if (form.value.sort === '') {
|
||||
form.value.sort = 0
|
||||
}
|
||||
await roleTemplateAdd(form.value)
|
||||
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '添加成功',
|
||||
type: 'success'
|
||||
})
|
||||
|
||||
emits('success')
|
||||
|
||||
visible.value = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@@ -80,11 +102,23 @@ function submitHandle() {
|
||||
})
|
||||
}
|
||||
|
||||
function show(t, obj) {
|
||||
// t=1模板 2角色 obj=row数据 At=添加还是编辑
|
||||
function show(t = 1, obj = {}, At = 1) {
|
||||
visible.value = true
|
||||
type.value = t
|
||||
if (obj && obj.id) {
|
||||
form.value = { ...obj }
|
||||
if (At == 1) {
|
||||
if (form.value.pid === null) {
|
||||
form.value.pid = form.value.id
|
||||
form.value.id = ''
|
||||
form.value.name = ''
|
||||
form.value.sort = 0
|
||||
form.value.isEnable = 1
|
||||
form.value.roleId = ''
|
||||
}
|
||||
}
|
||||
console.log('form.value===', form.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="gyq_container">
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<el-button type="primary" @click="addTempateDialogRef.show(1)">添加</el-button>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading" stripe border>
|
||||
<el-table-column label="ID"></el-table-column>
|
||||
<el-table-column label="模版名称"></el-table-column>
|
||||
<el-table-column label="启用状态"></el-table-column>
|
||||
<el-table-column label="排序值"></el-table-column>
|
||||
<el-table-column label="创建时间"></el-table-column>
|
||||
<el-table-column label="操作人"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<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" width="80"></el-table-column>
|
||||
<el-table-column label="模版名称" prop="name"></el-table-column>
|
||||
<el-table-column label="启用状态" prop="isEnable" width="120">
|
||||
<template v-slot="scope">
|
||||
<el-button link type="primary">添加角色</el-button>
|
||||
<el-button link type="primary">分配权限</el-button>
|
||||
<el-button link type="danger">删除</el-button>
|
||||
<el-switch v-model="scope.row.isEnable" :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="操作人" prop=""></el-table-column> -->
|
||||
<el-table-column label="操作" width="250">
|
||||
<template v-slot="scope">
|
||||
<el-button link type="primary" @click="showMenusHandle(scope.row)"
|
||||
v-if="scope.row.pid !== null">分配权限</el-button>
|
||||
<el-button link type="primary" @click="addTempateDialogRef.show(2, scope.row)" v-else>添加角色</el-button>
|
||||
<el-button link type="primary" @click="addTempateDialogRef.show(2, scope.row, 2)"
|
||||
v-if="scope.row.pid">编辑</el-button>
|
||||
<el-button link type="primary" @click="addTempateDialogRef.show(1, scope.row, 2)" v-else>编辑</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>
|
||||
<!-- <div class="row mt14">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||
:page-sizes="[10, 30, 50, 100]" background layout="total" :total="tableData.total" />
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- 添加模板/角色 -->
|
||||
<addTempateDialog ref="addTempateDialogRef" />
|
||||
<addTempateDialog ref="addTempateDialogRef" @success="roleTemplateListAjax" />
|
||||
<!-- 分配菜单弹窗 -->
|
||||
<el-drawer v-model="assignPermDialogVisible" size="500">
|
||||
<template #header>
|
||||
@@ -42,7 +60,7 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-x-between">
|
||||
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单菜单名称">
|
||||
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单名称">
|
||||
<template #prefix>
|
||||
<Search />
|
||||
</template>
|
||||
@@ -104,6 +122,8 @@
|
||||
import { ref, reactive } from 'vue'
|
||||
import addTempateDialog from './components/addTempateDialog.vue';
|
||||
import MenuAPI from "@/api/account/menu";
|
||||
import RoleApi from "@/api/account/role";
|
||||
import { roleTemplateList, roleTemplateDel, roleTemplateAdd } from '@/api/account/roleTemplate'
|
||||
|
||||
const addTempateDialogRef = ref(null)
|
||||
|
||||
@@ -111,11 +131,25 @@ const tableData = reactive({
|
||||
loading: false,
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
list: []
|
||||
})
|
||||
|
||||
function showMenusHandle(row) {
|
||||
checkedRole.value = { ...row }
|
||||
getMenuIds(row.roleId)
|
||||
assignPermDialogVisible.value = true
|
||||
}
|
||||
|
||||
const assignPermDialogVisible = ref(false)
|
||||
|
||||
// 弹窗
|
||||
const dialog = reactive({
|
||||
title: "",
|
||||
visible: false,
|
||||
row: {},
|
||||
});
|
||||
|
||||
const checkedRole = ref({})
|
||||
|
||||
const platformType = ref(0);
|
||||
@@ -192,6 +226,9 @@ const rules = reactive({
|
||||
|
||||
// 回显角色已拥有的菜单
|
||||
function getMenuIds(roleId) {
|
||||
console.log('回显角色已拥有的菜单===', roleId);
|
||||
|
||||
|
||||
roleId = roleId ? roleId : dialog.row.id;
|
||||
if (!roleId) {
|
||||
return;
|
||||
@@ -237,43 +274,107 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// 分配菜单菜单提交
|
||||
function handleAssignPermSubmit() {
|
||||
const roleId = checkedRole.value.id;
|
||||
const name = checkedRole.value.name;
|
||||
if (roleId) {
|
||||
const checkedMenuIds = permTreeRef
|
||||
.value.getCheckedNodes(false, true)
|
||||
.map((node) => node.value);
|
||||
const loading = ref(false)
|
||||
const permTreeRef = ref(null)
|
||||
|
||||
loading.value = true;
|
||||
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;
|
||||
handleResetQuery();
|
||||
// 分配菜单菜单提交
|
||||
async function handleAssignPermSubmit() {
|
||||
try {
|
||||
const roleId = checkedRole.value.roleId;
|
||||
const name = checkedRole.value.name;
|
||||
if (roleId) {
|
||||
const checkedMenuIds = permTreeRef
|
||||
.value.getCheckedNodes(false, true)
|
||||
.map((node) => node.value);
|
||||
|
||||
loading.value = true;
|
||||
RoleApi.update(roleId, {
|
||||
name,
|
||||
adminMenuIdList: checkedMenuIds,
|
||||
cashMenuIdList: cashMenuIdList.value.filter((id) =>
|
||||
casher_windows_menus.value.find((v) => v.menuId == id)
|
||||
),
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
.then(() => {
|
||||
ElMessage.success("分配菜单成功");
|
||||
assignPermDialogVisible.value = false;
|
||||
roleTemplateListAjax();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取角色模板列表
|
||||
async function roleTemplateListAjax() {
|
||||
try {
|
||||
tableData.loading = true
|
||||
const res = await roleTemplateList()
|
||||
tableData.list = res
|
||||
tableData.total = res.length
|
||||
// console.log('tableData.list===', JSON.stringify(tableData.list));
|
||||
// console.log('tableData.list===', tableData.list);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
tableData.loading = false
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 展开懒加载
|
||||
async function loadChildNodes(row, treeNode, resolve) {
|
||||
try {
|
||||
const res = await roleTemplateList({ pid: row.id })
|
||||
resolve(res)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
async function deleteHandle(row) {
|
||||
try {
|
||||
await roleTemplateDel(row.id)
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '已删除',
|
||||
type: 'success'
|
||||
})
|
||||
|
||||
roleTemplateListAjax()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 状态变化
|
||||
async function isEnableChange(e, row) {
|
||||
console.log('isEnableChange.e===', e);
|
||||
console.log('isEnableChange.row===', row);
|
||||
try {
|
||||
await roleTemplateAdd(row)
|
||||
roleTemplateListAjax()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getMenuPermOptions();
|
||||
getCashMenus();
|
||||
roleTemplateListAjax()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
.gyq_container {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ export const newMenus = [
|
||||
{
|
||||
name: "弹窗广告",
|
||||
icon: "tcgg",
|
||||
pathName: "",
|
||||
pathName: "advertisement",
|
||||
intro: "设置弹窗广告"
|
||||
},
|
||||
]
|
||||
@@ -120,12 +120,12 @@ export const newMenus = [
|
||||
pathName: "birthdayGift",
|
||||
intro: "用户生日管理设置"
|
||||
},
|
||||
{
|
||||
name: "推送活动消息",
|
||||
icon: "tshdxx",
|
||||
pathName: "",
|
||||
intro: "给用户推送服务通知"
|
||||
}
|
||||
// {
|
||||
// name: "推送活动消息",
|
||||
// icon: "tshdxx",
|
||||
// pathName: "",
|
||||
// intro: "给用户推送服务通知"
|
||||
// }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="btn_wraps">
|
||||
<div
|
||||
class="btn"
|
||||
:class="{ active: tableActive == item.autoKey }"
|
||||
v-for="item in tableData"
|
||||
:key="item.autoKey"
|
||||
@click="selectItemChange(item.autoKey)"
|
||||
>
|
||||
<div class="btn" :class="{ active: tableActive == item.autoKey }" v-for="item in tableData" :key="item.autoKey"
|
||||
@click="selectItemChange(item.autoKey)">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -15,17 +10,16 @@
|
||||
<div class="preview_wrap">
|
||||
<div class="phone_wrap">
|
||||
<div class="index_bg" v-if="tableActive == 'index_bg'">
|
||||
<img class="bg" :src="selectItem.value" />
|
||||
<el-carousel height="500px">
|
||||
<el-carousel-item v-for="item in JSON.parse(selectItem.value)">
|
||||
<img class="bg" :src="item" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="menu_wrap">
|
||||
<div class="menu_wrap_div">
|
||||
<div class="left">
|
||||
<div class="icon_wrap">
|
||||
<SvgIcon
|
||||
style="margin-right: 0"
|
||||
color="rgb(0,0,0)"
|
||||
size="30"
|
||||
iconClass="Coffee"
|
||||
></SvgIcon>
|
||||
<SvgIcon style="margin-right: 0" color="rgb(0,0,0)" size="30" iconClass="Coffee"></SvgIcon>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="t1">点餐</div>
|
||||
@@ -34,24 +28,14 @@
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="btn">
|
||||
<SvgIcon
|
||||
style="margin-right: 0"
|
||||
size="30"
|
||||
color="rgb(0,0,0)"
|
||||
iconClass="postcard"
|
||||
></SvgIcon>
|
||||
<SvgIcon style="margin-right: 0" size="30" color="rgb(0,0,0)" iconClass="postcard"></SvgIcon>
|
||||
<div class="info">
|
||||
<div class="t1">会员</div>
|
||||
<div class="t2">入会享权益</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<SvgIcon
|
||||
style="margin-right: 0"
|
||||
color="rgb(0,0,0)"
|
||||
size="30"
|
||||
iconClass="wallet"
|
||||
></SvgIcon>
|
||||
<SvgIcon style="margin-right: 0" color="rgb(0,0,0)" size="30" iconClass="wallet"></SvgIcon>
|
||||
<div class="info">
|
||||
<div class="t1">充值</div>
|
||||
<div class="t2">充值享更多优惠</div>
|
||||
@@ -171,7 +155,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="shopinfo_bg" v-if="tableActive == 'shopinfo_bg'">
|
||||
<img class="bg" :src="selectItem.value" />
|
||||
<el-carousel height="120px">
|
||||
<el-carousel-item v-for="item in JSON.parse(selectItem.value)">
|
||||
<img class="bg" :src="item" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="shop_name">{{ shopName }}</div>
|
||||
<img class="content" src="@/assets/images/shop_editor_bg.png" alt="" />
|
||||
</div>
|
||||
@@ -203,10 +191,19 @@
|
||||
<div class="t2">注:点击图片更换</div>
|
||||
</div>
|
||||
<div class="form_item">
|
||||
<SingleImageUpload v-model="selectItem.value" @onSuccess="onSuccess">
|
||||
<img v-if="selectItem.value" :src="selectItem.value" class="avatar" />
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</SingleImageUpload>
|
||||
<div class="upload_wrap" style="display: flex;flex-direction: column;gap: 28px;"
|
||||
v-if="isJsonArrayString(selectItem.value)">
|
||||
<MultiImageUpload v-model="imgList" @upDataEvent="MultiOnSuccess" />
|
||||
<div>
|
||||
<el-button type="primary" size="large" @click="doSubmit">确认修改</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<SingleImageUpload v-model="selectItem.value" @onSuccess="onSuccess">
|
||||
<img v-if="selectItem.value" :src="selectItem.value" class="avatar" />
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</SingleImageUpload>
|
||||
</div>
|
||||
<!-- <el-upload
|
||||
:headers="headers"
|
||||
class="avatar-uploader"
|
||||
@@ -237,6 +234,7 @@ export default {
|
||||
tableData: [],
|
||||
selectItem: {},
|
||||
imageUrl: "",
|
||||
imgList: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -255,14 +253,53 @@ export default {
|
||||
});
|
||||
this.getList();
|
||||
},
|
||||
// 单图上传成功
|
||||
onSuccess(response) {
|
||||
this.doSubmit();
|
||||
},
|
||||
// 多图上传成功
|
||||
async MultiOnSuccess(response) {
|
||||
if (!response && this.imgList.length > 0) {
|
||||
console.log(this.imgList);
|
||||
await nextTick()
|
||||
this.selectItem.value = JSON.stringify(this.imgList)
|
||||
console.log('onSuccess.selectItem.value', this.selectItem.value);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 判断字符串是否为合法的 JSON 数组
|
||||
* @param {string} str - 待判断的字符串
|
||||
* @returns {boolean} true=是JSON数组字符串 / false=普通字符串/其他
|
||||
*/
|
||||
isJsonArrayString(str) {
|
||||
// 1. 非字符串直接返回 false
|
||||
if (typeof str !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 空字符串返回 false(根据业务可调整)
|
||||
if (str.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 3. 尝试解析 JSON
|
||||
const parsed = JSON.parse(str);
|
||||
// 4. 校验解析结果是否为数组
|
||||
return Array.isArray(parsed);
|
||||
} catch (e) {
|
||||
// 解析失败(普通字符串/非法 JSON)→ 返回 false
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// 切换类型
|
||||
selectItemChange(key) {
|
||||
this.tableActive = key;
|
||||
const { autoKey, id, name, value } = this.tableData.find((item) => item.autoKey == key);
|
||||
this.selectItem = { autoKey, id, name, value };
|
||||
if (this.isJsonArrayString(value)) {
|
||||
this.imgList = JSON.parse(value)
|
||||
}
|
||||
console.log(this.selectItem);
|
||||
},
|
||||
// 获取装修数据
|
||||
@@ -319,6 +356,7 @@ export default {
|
||||
|
||||
.index_bg {
|
||||
padding-bottom: 50px;
|
||||
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
|
||||
Reference in New Issue
Block a user