优化修复网站导航的bug
This commit is contained in:
@@ -141,3 +141,13 @@ export async function checkExistence(
|
|||||||
}
|
}
|
||||||
return Promise.reject(new Error(res.data.message));
|
return Promise.reject(new Error(res.data.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getCount(params: ArticleParam) {
|
||||||
|
const res = await request.get(MODULES_API_URL + '/cms/article/data', {
|
||||||
|
params
|
||||||
|
});
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export interface ArticleParam extends PageParam {
|
|||||||
articleId?: number;
|
articleId?: number;
|
||||||
categoryId?: number;
|
categoryId?: number;
|
||||||
navigationId?: number;
|
navigationId?: number;
|
||||||
status?: string;
|
status?: number;
|
||||||
sortNumber?: string;
|
sortNumber?: string;
|
||||||
createTime?: string;
|
createTime?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
|
|||||||
@@ -4,13 +4,20 @@
|
|||||||
export interface Navigation {
|
export interface Navigation {
|
||||||
navigationId?: number;
|
navigationId?: number;
|
||||||
parentId?: number;
|
parentId?: number;
|
||||||
|
parentName?: string;
|
||||||
|
parentPath?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
code?: string;
|
||||||
path?: string;
|
path?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
component?: string;
|
component?: string;
|
||||||
|
model?: string;
|
||||||
|
modelName?: string;
|
||||||
type?: number;
|
type?: number;
|
||||||
sortNumber?: number;
|
sortNumber?: number;
|
||||||
hide?: number;
|
hide?: number;
|
||||||
|
permission?: number;
|
||||||
|
password?: string;
|
||||||
home?: number;
|
home?: number;
|
||||||
position?: number;
|
position?: number;
|
||||||
top?: number;
|
top?: number;
|
||||||
@@ -31,6 +38,8 @@ export interface Navigation {
|
|||||||
pageName?: string;
|
pageName?: string;
|
||||||
createTime?: string;
|
createTime?: string;
|
||||||
isMpWeixin?: boolean;
|
isMpWeixin?: boolean;
|
||||||
|
label?: string;
|
||||||
|
value?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ export interface WebsiteField {
|
|||||||
value?: string;
|
value?: string;
|
||||||
comments?: string;
|
comments?: string;
|
||||||
userId?: number;
|
userId?: number;
|
||||||
|
defaultValue?: string;
|
||||||
|
modifyRange?: string;
|
||||||
type?: number;
|
type?: number;
|
||||||
status?: any;
|
status?: any;
|
||||||
sortNumber?: any;
|
sortNumber?: any;
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import type {
|
|||||||
Config,
|
Config,
|
||||||
WebsiteField,
|
WebsiteField,
|
||||||
WebsiteFieldParam
|
WebsiteFieldParam
|
||||||
} from "@/api/cms/website/field/model";
|
} from '@/api/cms/website/field/model';
|
||||||
import { MODULES_API_URL } from '@/config/setting';
|
import { MODULES_API_URL, SERVER_API_URL } from "@/config/setting";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询项目参数
|
* 分页查询项目参数
|
||||||
*/
|
*/
|
||||||
export async function pageWebsiteField(params: WebsiteFieldParam) {
|
export async function pageWebsiteField(params: WebsiteFieldParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<WebsiteField>>>(
|
const res = await request.get<ApiResult<PageResult<WebsiteField>>>(
|
||||||
MODULES_API_URL + '/cms/website-field/page',
|
SERVER_API_URL + '/system/website-field/page',
|
||||||
{
|
{
|
||||||
params
|
params
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ export async function pageWebsiteField(params: WebsiteFieldParam) {
|
|||||||
*/
|
*/
|
||||||
export async function listWebsiteField(params?: WebsiteFieldParam) {
|
export async function listWebsiteField(params?: WebsiteFieldParam) {
|
||||||
const res = await request.get<ApiResult<WebsiteField[]>>(
|
const res = await request.get<ApiResult<WebsiteField[]>>(
|
||||||
'https://modules.gxwebsoft.com/api/cms/website-field',
|
SERVER_API_URL + '/system/website-field',
|
||||||
{
|
{
|
||||||
params
|
params
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ export async function listWebsiteField(params?: WebsiteFieldParam) {
|
|||||||
*/
|
*/
|
||||||
export async function getWebsiteField(id: number) {
|
export async function getWebsiteField(id: number) {
|
||||||
const res = await request.get<ApiResult<WebsiteField>>(
|
const res = await request.get<ApiResult<WebsiteField>>(
|
||||||
MODULES_API_URL + '/cms/website-field/' + id
|
SERVER_API_URL + '/system/website-field/' + id
|
||||||
);
|
);
|
||||||
if (res.data.code === 0 && res.data.data) {
|
if (res.data.code === 0 && res.data.data) {
|
||||||
return res.data.data;
|
return res.data.data;
|
||||||
@@ -57,7 +57,7 @@ export async function getWebsiteField(id: number) {
|
|||||||
*/
|
*/
|
||||||
export async function addWebsiteField(data: WebsiteField) {
|
export async function addWebsiteField(data: WebsiteField) {
|
||||||
const res = await request.post<ApiResult<unknown>>(
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
MODULES_API_URL + '/cms/website-field',
|
SERVER_API_URL + '/system/website-field',
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
@@ -71,7 +71,7 @@ export async function addWebsiteField(data: WebsiteField) {
|
|||||||
*/
|
*/
|
||||||
export async function updateWebsiteField(data: WebsiteField) {
|
export async function updateWebsiteField(data: WebsiteField) {
|
||||||
const res = await request.put<ApiResult<unknown>>(
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
MODULES_API_URL + '/cms/website-field',
|
SERVER_API_URL + '/system/website-field',
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
@@ -85,7 +85,7 @@ export async function updateWebsiteField(data: WebsiteField) {
|
|||||||
*/
|
*/
|
||||||
export async function removeWebsiteField(id?: number) {
|
export async function removeWebsiteField(id?: number) {
|
||||||
const res = await request.delete<ApiResult<unknown>>(
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
MODULES_API_URL + '/cms/website-field/' + id
|
SERVER_API_URL + '/system/website-field/' + id
|
||||||
);
|
);
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
return res.data.message;
|
return res.data.message;
|
||||||
@@ -98,7 +98,7 @@ export async function removeWebsiteField(id?: number) {
|
|||||||
*/
|
*/
|
||||||
export async function removeBatchWebsiteField(data: (number | undefined)[]) {
|
export async function removeBatchWebsiteField(data: (number | undefined)[]) {
|
||||||
const res = await request.delete<ApiResult<unknown>>(
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
MODULES_API_URL + '/cms/website-field/batch',
|
SERVER_API_URL + '/system/website-field/batch',
|
||||||
{
|
{
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ export async function checkExistence(
|
|||||||
id?: number
|
id?: number
|
||||||
) {
|
) {
|
||||||
const res = await request.get<ApiResult<unknown>>(
|
const res = await request.get<ApiResult<unknown>>(
|
||||||
MODULES_API_URL + '/cms/website-field/existence',
|
SERVER_API_URL + '/system/website-field/existence',
|
||||||
{
|
{
|
||||||
params: { field, value, id }
|
params: { field, value, id }
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ export async function checkExistence(
|
|||||||
*/
|
*/
|
||||||
export async function configWebsiteField(params?: WebsiteFieldParam) {
|
export async function configWebsiteField(params?: WebsiteFieldParam) {
|
||||||
const res = await request.get<ApiResult<Config>>(
|
const res = await request.get<ApiResult<Config>>(
|
||||||
'https://modules.gxwebsoft.com/api/cms/website-field/config',
|
'https://modules.gxwebsoft.com/api/system/website-field/config',
|
||||||
{
|
{
|
||||||
params
|
params
|
||||||
}
|
}
|
||||||
@@ -144,3 +144,16 @@ export async function configWebsiteField(params?: WebsiteFieldParam) {
|
|||||||
}
|
}
|
||||||
return Promise.reject(new Error(res.data.message));
|
return Promise.reject(new Error(res.data.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复项目参数
|
||||||
|
*/
|
||||||
|
export async function undeleteWebsiteField(id?: number) {
|
||||||
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
|
MODULES_API_URL + '/cms/website-field/undelete/' + id
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,10 +9,31 @@ export interface WebsiteField {
|
|||||||
value?: string;
|
value?: string;
|
||||||
comments?: string;
|
comments?: string;
|
||||||
userId?: number;
|
userId?: number;
|
||||||
websiteId?: number;
|
defaultValue?: string;
|
||||||
|
modifyRange?: string;
|
||||||
|
type?: number;
|
||||||
status?: any;
|
status?: any;
|
||||||
sortNumber?: any;
|
sortNumber?: any;
|
||||||
createTime?: string;
|
createTime?: string;
|
||||||
|
deleted?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 约定的网站参数名称
|
||||||
|
export interface WebsiteParam {
|
||||||
|
// 网站名称
|
||||||
|
site_logo?: string;
|
||||||
|
// 登录页面标题
|
||||||
|
login_name?: string;
|
||||||
|
// 登录页面的背景图片
|
||||||
|
login_bg_img?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 约定的小程序参数名称
|
||||||
|
export interface MpWeixinParam {
|
||||||
|
// 小程序LOGO
|
||||||
|
site_logo?: string;
|
||||||
|
// 我的页面顶部背景图片
|
||||||
|
mp_user_top?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,5 +42,22 @@ export interface WebsiteField {
|
|||||||
export interface WebsiteFieldParam extends PageParam {
|
export interface WebsiteFieldParam extends PageParam {
|
||||||
id?: number;
|
id?: number;
|
||||||
userId?: number;
|
userId?: number;
|
||||||
|
name?: string;
|
||||||
websiteId?: number;
|
websiteId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Config {
|
||||||
|
siteName?: string;
|
||||||
|
siteLogo?: string;
|
||||||
|
domain?: string;
|
||||||
|
icpNo?: string;
|
||||||
|
copyright?: string;
|
||||||
|
loginBgImg?: string;
|
||||||
|
address?: string;
|
||||||
|
tel?: string;
|
||||||
|
kefu2?: string;
|
||||||
|
kefu1?: string;
|
||||||
|
email?: string;
|
||||||
|
loginTitle?: string;
|
||||||
|
sysLogo?: string;
|
||||||
|
}
|
||||||
|
|||||||
72
src/components/ChooseDictionary/index.vue
Normal file
72
src/components/ChooseDictionary/index.vue
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<!-- 公共参数数据源 -->
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
:allow-clear="allowClear"
|
||||||
|
show-search
|
||||||
|
optionFilterProp="label"
|
||||||
|
:options="data"
|
||||||
|
:value="value"
|
||||||
|
class="w-full"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@update:value="updateValue"
|
||||||
|
@change="change"
|
||||||
|
@blur="onBlur"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { listDictionaryData } from '@/api/system/dictionary-data';
|
||||||
|
import type { DictionaryData } from '@/api/system/dictionary-data/model';
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:value', value: string): void;
|
||||||
|
(e: 'index', index: number): void;
|
||||||
|
(e: 'blur'): void;
|
||||||
|
(e: 'done', item: DictionaryData): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
value?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
allowClear?: boolean;
|
||||||
|
width?: number;
|
||||||
|
index?: number;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
placeholder: '请选择'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = ref<DictionaryData[]>();
|
||||||
|
|
||||||
|
/* 更新选中数据 */
|
||||||
|
const updateValue = (value: string) => {
|
||||||
|
emit('update:value', value);
|
||||||
|
emit('index', Number(props.index));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 失去焦点 */
|
||||||
|
const onBlur = () => {
|
||||||
|
emit('blur');
|
||||||
|
};
|
||||||
|
|
||||||
|
const change = (e: any, item: any) => {
|
||||||
|
emit('done', item);
|
||||||
|
};
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
data.value = [];
|
||||||
|
listDictionaryData({ dictCode: 'NavigationModel' }).then((list) => {
|
||||||
|
data.value = list.map((d) => {
|
||||||
|
return {
|
||||||
|
label: d.dictDataName,
|
||||||
|
value: d.dictDataCode
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reload();
|
||||||
|
</script>
|
||||||
72
src/components/ChooseWebsiteField/index.vue
Normal file
72
src/components/ChooseWebsiteField/index.vue
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<!-- 公共参数数据源 -->
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
:allow-clear="allowClear"
|
||||||
|
show-search
|
||||||
|
optionFilterProp="label"
|
||||||
|
:options="data"
|
||||||
|
:value="value"
|
||||||
|
class="w-full"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@update:value="updateValue"
|
||||||
|
@change="change"
|
||||||
|
@blur="onBlur"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { listWebsiteField } from '@/api/system/website/field';
|
||||||
|
import { WebsiteField } from '@/api/cms/website/field/model';
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:value', value: string): void;
|
||||||
|
(e: 'index', index: number): void;
|
||||||
|
(e: 'blur'): void;
|
||||||
|
(e: 'done', item: WebsiteField): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
value?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
allowClear?: boolean;
|
||||||
|
width?: number;
|
||||||
|
index?: number;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
placeholder: '请选择'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = ref<WebsiteField[]>();
|
||||||
|
|
||||||
|
/* 更新选中数据 */
|
||||||
|
const updateValue = (value: string) => {
|
||||||
|
emit('update:value', value);
|
||||||
|
emit('index', Number(props.index));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 失去焦点 */
|
||||||
|
const onBlur = () => {
|
||||||
|
emit('blur');
|
||||||
|
};
|
||||||
|
|
||||||
|
const change = (e, item) => {
|
||||||
|
emit('done', item);
|
||||||
|
};
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
data.value = [];
|
||||||
|
listWebsiteField({}).then((list) => {
|
||||||
|
data.value = list.map((d) => {
|
||||||
|
return {
|
||||||
|
label: d.name,
|
||||||
|
value: d.value
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reload();
|
||||||
|
</script>
|
||||||
@@ -48,9 +48,8 @@
|
|||||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
import { EleProTable } from 'ele-admin-pro';
|
import { EleProTable } from 'ele-admin-pro';
|
||||||
import useSearch from '@/utils/use-search';
|
import useSearch from '@/utils/use-search';
|
||||||
import { pageDictData } from '@/api/system/dict-data';
|
|
||||||
import { DictData, DictDataParam } from '@/api/system/dict-data/model';
|
import { DictData, DictDataParam } from '@/api/system/dict-data/model';
|
||||||
import { pageDictionaryData } from "@/api/system/dictionary-data";
|
import { pageDictionaryData } from '@/api/system/dictionary-data';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
// 弹窗是否打开
|
// 弹窗是否打开
|
||||||
|
|||||||
@@ -47,9 +47,23 @@
|
|||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'title'">
|
||||||
|
<a-button
|
||||||
|
size="small"
|
||||||
|
type="link"
|
||||||
|
@click="onRadio"
|
||||||
|
:disabled="record.type == model"
|
||||||
|
class="cursor-pointer"
|
||||||
|
>{{ record.title }}</a-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
<template v-if="column.key === 'action'">
|
<template v-if="column.key === 'action'">
|
||||||
<template v-if="pageId == record.id">
|
<template v-if="pageId == record.id">
|
||||||
<a-radio v-model:checked="checked" @click="onRadio(record)" />
|
<a-radio
|
||||||
|
v-model:checked="checked"
|
||||||
|
disabled
|
||||||
|
@click="onRadio(record)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<lebal>
|
<lebal>
|
||||||
@@ -65,14 +79,16 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import {
|
|
||||||
ColumnItem,
|
|
||||||
DatasourceFunction
|
|
||||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
|
||||||
import { listNavigation, pageNavigation } from '@/api/cms/navigation';
|
import { listNavigation, pageNavigation } from '@/api/cms/navigation';
|
||||||
import { EleProTable } from 'ele-admin-pro';
|
import { EleProTable } from 'ele-admin-pro';
|
||||||
import { toTreeData } from 'ele-admin-pro/es';
|
import { toTreeData, eachTreeData } from 'ele-admin-pro/es';
|
||||||
|
import type {
|
||||||
|
DatasourceFunction,
|
||||||
|
ColumnItem,
|
||||||
|
EleProTableDone
|
||||||
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
import type { Navigation, NavigationParam } from '@/api/cms/navigation/model';
|
import type { Navigation, NavigationParam } from '@/api/cms/navigation/model';
|
||||||
|
import type { Menu } from '@/api/system/menu/model';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
// 弹窗是否打开
|
// 弹窗是否打开
|
||||||
@@ -81,6 +97,8 @@
|
|||||||
title?: string;
|
title?: string;
|
||||||
// 修改回显的数据
|
// 修改回显的数据
|
||||||
data?: Navigation | null;
|
data?: Navigation | null;
|
||||||
|
// 当前模型
|
||||||
|
model?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -100,6 +118,8 @@
|
|||||||
const expandedRowKeys = ref<number[]>([]);
|
const expandedRowKeys = ref<number[]>([]);
|
||||||
const searchText = ref('');
|
const searchText = ref('');
|
||||||
const position = ref(1);
|
const position = ref(1);
|
||||||
|
// 菜单数据
|
||||||
|
const menuData = ref<Navigation[]>([]);
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
@@ -137,9 +157,13 @@
|
|||||||
return listNavigation({ ...where });
|
return listNavigation({ ...where });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 表格渲染完成回调 */
|
||||||
|
const onDone: EleProTableDone<Navigation> = ({ data }) => {
|
||||||
|
menuData.value = data;
|
||||||
|
};
|
||||||
|
|
||||||
/* 数据转为树形结构 */
|
/* 数据转为树形结构 */
|
||||||
const parseData = (data: Navigation[]) => {
|
const parseData = (data: Navigation[]) => {
|
||||||
console.log(data);
|
|
||||||
return toTreeData({
|
return toTreeData({
|
||||||
data: data.map((d) => {
|
data: data.map((d) => {
|
||||||
return { ...d, key: d.navigationId, value: d.navigationId };
|
return { ...d, key: d.navigationId, value: d.navigationId };
|
||||||
@@ -149,6 +173,22 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 展开全部 */
|
||||||
|
const expandAll = () => {
|
||||||
|
let keys: number[] = [];
|
||||||
|
eachTreeData(menuData.value, (d) => {
|
||||||
|
if (d.children && d.children.length && d.navigationId) {
|
||||||
|
keys.push(d.navigationId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expandedRowKeys.value = keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 折叠全部 */
|
||||||
|
const foldAll = () => {
|
||||||
|
expandedRowKeys.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
/* 点击展开图标时触发 */
|
/* 点击展开图标时触发 */
|
||||||
const onExpand = (expanded: boolean, record: Navigation) => {
|
const onExpand = (expanded: boolean, record: Navigation) => {
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
v-model:visible="showEdit"
|
v-model:visible="showEdit"
|
||||||
:data="current"
|
:data="current"
|
||||||
:title="placeholder"
|
:title="placeholder"
|
||||||
|
:model="model"
|
||||||
@done="onChange"
|
@done="onChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
defineProps<{
|
defineProps<{
|
||||||
value?: any;
|
value?: any;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
model?: string;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
placeholder: '请选择'
|
placeholder: '请选择'
|
||||||
|
|||||||
170
src/components/SelectWebsiteField/components/select-data.vue
Normal file
170
src/components/SelectWebsiteField/components/select-data.vue
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
<ele-modal
|
||||||
|
width="70%"
|
||||||
|
:visible="visible"
|
||||||
|
:maskClosable="false"
|
||||||
|
:title="title"
|
||||||
|
:footer="null"
|
||||||
|
:body-style="{ paddingBottom: '28px' }"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
>
|
||||||
|
<ele-pro-table
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="id"
|
||||||
|
:datasource="datasource"
|
||||||
|
:columns="columns"
|
||||||
|
:customRow="customRow"
|
||||||
|
:pagination="false"
|
||||||
|
>
|
||||||
|
<template #toolbar>
|
||||||
|
<a-input-search
|
||||||
|
allow-clear
|
||||||
|
v-model:value="searchText"
|
||||||
|
placeholder="请输入搜索关键词"
|
||||||
|
style="width: 200px"
|
||||||
|
@search="reload"
|
||||||
|
@pressEnter="reload"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'name'">
|
||||||
|
<div class="ele-text-heading" @click="onRadio(record)">
|
||||||
|
{{ record.name }}
|
||||||
|
</div>
|
||||||
|
<div class="ele-text-placeholder">{{ record.comments }}</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'value'">
|
||||||
|
<a-image v-if="record.type === 1" :src="record.value" :width="120" />
|
||||||
|
<div v-else>{{ record.value }}</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'comments'">
|
||||||
|
<a-popover>
|
||||||
|
<template #content>
|
||||||
|
{{ record.comments }}
|
||||||
|
</template>
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a @click="onRadio(record)">选择</a>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</ele-pro-table>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import {
|
||||||
|
ColumnItem,
|
||||||
|
DatasourceFunction
|
||||||
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { EleProTable } from 'ele-admin-pro';
|
||||||
|
import { Company, CompanyParam } from '@/api/oa/company/model';
|
||||||
|
import { pageWebsiteField } from '@/api/system/website/field';
|
||||||
|
import { WebsiteField } from '@/api/system/website/field/model';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
// 标题
|
||||||
|
title?: string;
|
||||||
|
// 修改回显的数据
|
||||||
|
data?: WebsiteField | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done', data: Company): void;
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 搜索内容
|
||||||
|
const searchText = ref(null);
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
|
|
||||||
|
// 表格配置
|
||||||
|
const columns = ref<ColumnItem[]>([
|
||||||
|
{
|
||||||
|
title: '参数名',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 180,
|
||||||
|
key: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '描述',
|
||||||
|
dataIndex: 'comments',
|
||||||
|
key: 'comments',
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '默认值',
|
||||||
|
width: 120,
|
||||||
|
align: 'center',
|
||||||
|
dataIndex: 'defaultValue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '可设置范围',
|
||||||
|
width: 120,
|
||||||
|
align: 'center',
|
||||||
|
dataIndex: 'modifyRange'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 180,
|
||||||
|
align: 'center',
|
||||||
|
hideInSetting: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 表格数据源
|
||||||
|
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||||
|
where = {};
|
||||||
|
// 搜索条件
|
||||||
|
if (searchText.value) {
|
||||||
|
where.keywords = searchText.value;
|
||||||
|
}
|
||||||
|
return pageWebsiteField({
|
||||||
|
...where,
|
||||||
|
...orders,
|
||||||
|
page,
|
||||||
|
limit
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 搜索 */
|
||||||
|
const reload = (where?: CompanyParam) => {
|
||||||
|
tableRef?.value?.reload({ page: 1, where });
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRadio = (record: Company) => {
|
||||||
|
updateVisible(false);
|
||||||
|
emit('done', record);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 自定义行属性 */
|
||||||
|
const customRow = (record: Company) => {
|
||||||
|
return {
|
||||||
|
// 行点击事件
|
||||||
|
// onClick: () => {
|
||||||
|
// updateVisible(false);
|
||||||
|
// emit('done', record);
|
||||||
|
// },
|
||||||
|
// 行双击事件
|
||||||
|
onDblclick: () => {
|
||||||
|
updateVisible(false);
|
||||||
|
emit('done', record);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="less"></style>
|
||||||
61
src/components/SelectWebsiteField/index.vue
Normal file
61
src/components/SelectWebsiteField/index.vue
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input
|
||||||
|
disabled
|
||||||
|
style="width: calc(100% - 32px)"
|
||||||
|
v-model:value="value"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
/>
|
||||||
|
<a-button @click="openEdit">
|
||||||
|
<template #icon><BulbOutlined class="ele-text-warning" /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-input-group>
|
||||||
|
<!-- 选择弹窗 -->
|
||||||
|
<SelectData
|
||||||
|
v-model:visible="showEdit"
|
||||||
|
:data="current"
|
||||||
|
:title="placeholder"
|
||||||
|
:customer-type="customerType"
|
||||||
|
@done="onChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { BulbOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import SelectData from './components/select-data.vue';
|
||||||
|
import { Company } from '@/api/system/company/model';
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
value?: any;
|
||||||
|
customerType?: string;
|
||||||
|
placeholder?: string;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
placeholder: '请选择数据'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done', Customer): void;
|
||||||
|
(e: 'clear'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 是否显示编辑弹窗
|
||||||
|
const showEdit = ref(false);
|
||||||
|
// 当前编辑数据
|
||||||
|
const current = ref<Company | null>(null);
|
||||||
|
|
||||||
|
/* 打开编辑弹窗 */
|
||||||
|
const openEdit = (row?: Company) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = (row) => {
|
||||||
|
emit('done', row);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -30,16 +30,16 @@ export const routes = [
|
|||||||
// component: () => import('@/views/passport/token-login/index.vue'),
|
// component: () => import('@/views/passport/token-login/index.vue'),
|
||||||
// meta: { title: '快捷登录' }
|
// meta: { title: '快捷登录' }
|
||||||
// },
|
// },
|
||||||
{
|
// {
|
||||||
path: '/cms/category/:id',
|
// path: '/cms/category/:id',
|
||||||
component: () => import('@/views/cms/category/preview/index.vue'),
|
// component: () => import('@/views/cms/category/preview/index.vue'),
|
||||||
meta: { title: '文章列表' }
|
// meta: { title: '文章列表' }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: '/cms/article/:id',
|
// path: '/cms/article/:id',
|
||||||
component: () => import('@/views/cms/article/preview/index.vue'),
|
// component: () => import('@/views/cms/article/preview/index.vue'),
|
||||||
meta: { title: '文章详情' }
|
// meta: { title: '文章详情' }
|
||||||
},
|
// },
|
||||||
// 404
|
// 404
|
||||||
{
|
{
|
||||||
path: '/:path(.*)*',
|
path: '/:path(.*)*',
|
||||||
|
|||||||
@@ -21,13 +21,17 @@
|
|||||||
>
|
>
|
||||||
<a-tabs type="card" v-model:active-key="active" @change="onChange">
|
<a-tabs type="card" v-model:active-key="active" @change="onChange">
|
||||||
<a-tab-pane tab="基本信息" key="base">
|
<a-tab-pane tab="基本信息" key="base">
|
||||||
<a-form-item label="选择栏目" name="categoryId">
|
<a-form-item label="文章标题" name="categoryId">
|
||||||
<SelectNavigsation
|
<a-tree-select
|
||||||
:data="data"
|
allow-clear
|
||||||
placeholder="请选择栏目"
|
:tree-data="navigationList"
|
||||||
|
tree-default-expand-all
|
||||||
style="width: 558px"
|
style="width: 558px"
|
||||||
v-model:value="form.categoryName"
|
placeholder="请选择栏目"
|
||||||
@done="chooseCategory"
|
:value="form.categoryId || undefined"
|
||||||
|
:dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
|
||||||
|
@update:value="(value?: number) => (form.categoryId = value)"
|
||||||
|
@change="onCategoryId"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="文章标题" name="title">
|
<a-form-item label="文章标题" name="title">
|
||||||
@@ -177,6 +181,8 @@
|
|||||||
data?: Article | null;
|
data?: Article | null;
|
||||||
// 商户ID
|
// 商户ID
|
||||||
merchantId?: number;
|
merchantId?: number;
|
||||||
|
// 栏目数据
|
||||||
|
navigationList?: Navigation[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -340,14 +346,13 @@
|
|||||||
form.image = data.path;
|
form.image = data.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseCategory = (data: Navigation) => {
|
// 选择栏目
|
||||||
form.categoryName = data.title
|
const onCategoryId = (id: number) => {
|
||||||
form.categoryId = data.navigationId
|
form.categoryId = id;
|
||||||
}
|
};
|
||||||
|
|
||||||
const onChange = (text: string) => {
|
const onChange = () => {
|
||||||
// 加载文章多规格
|
// 加载文章多规格
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDeleteItem = (index: number) => {
|
const onDeleteItem = (index: number) => {
|
||||||
@@ -9,27 +9,25 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
<a-radio-group v-model:value="type" @change="handleSearch">
|
<a-radio-group v-model:value="type" @change="handleSearch">
|
||||||
<a-radio-button value="已发布"
|
<a-radio-button value="已发布"
|
||||||
>已发布({{ goodsCount?.totalNum }})</a-radio-button
|
>已发布({{ articleCount?.totalNum }})</a-radio-button
|
||||||
>
|
>
|
||||||
<a-radio-button value="待审核"
|
<a-radio-button value="待审核"
|
||||||
>待审核({{ goodsCount?.totalNum2 }})</a-radio-button
|
>待审核({{ articleCount?.totalNum2 }})</a-radio-button
|
||||||
>
|
>
|
||||||
<a-radio-button value="已驳回"
|
<a-radio-button value="已驳回"
|
||||||
>已驳回({{ goodsCount?.totalNum3 }})</a-radio-button
|
>已驳回({{ articleCount?.totalNum3 }})</a-radio-button
|
||||||
>
|
>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
<!-- <SelectMerchant-->
|
<a-tree-select
|
||||||
<!-- :placeholder="`选择商户`"-->
|
allow-clear
|
||||||
<!-- class="input-item"-->
|
:tree-data="navigationList"
|
||||||
<!-- v-if="!merchantId"-->
|
tree-default-expand-all
|
||||||
<!-- v-model:value="where.merchantName"-->
|
style="width: 230px"
|
||||||
<!-- @done="chooseMerchantId"-->
|
placeholder="请选择栏目"
|
||||||
<!-- />-->
|
:value="where.categoryId || undefined"
|
||||||
<SelectNavigsation
|
:dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
|
||||||
class="input-item"
|
@update:value="(value?: number) => (where.categoryId = value)"
|
||||||
:placeholder="`选择栏目`"
|
@change="onCategoryId"
|
||||||
v-model:value="where.categoryName"
|
|
||||||
@done="chooseArticleCategory"
|
|
||||||
/>
|
/>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -45,10 +43,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { getCount } from '@/api/shop/goods';
|
import { getCount } from '@/api/cms/article';
|
||||||
import type { ArticleCount, ArticleParam } from '@/api/cms/article/model';
|
import type { ArticleCount, ArticleParam } from '@/api/cms/article/model';
|
||||||
import useSearch from '@/utils/use-search';
|
import useSearch from '@/utils/use-search';
|
||||||
import { Merchant } from '@/api/shop/merchant/model';
|
|
||||||
import { Navigation } from '@/api/cms/navigation/model';
|
import { Navigation } from '@/api/cms/navigation/model';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
@@ -56,13 +53,15 @@
|
|||||||
// 选中的角色
|
// 选中的角色
|
||||||
selection?: [];
|
selection?: [];
|
||||||
merchantId?: number;
|
merchantId?: number;
|
||||||
|
navigationList?: Navigation[];
|
||||||
|
model?: string;
|
||||||
}>(),
|
}>(),
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
const type = ref<string>();
|
const type = ref<string>();
|
||||||
// 统计数据
|
// 统计数据
|
||||||
const goodsCount = ref<ArticleCount>();
|
const articleCount = ref<ArticleCount>();
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const { where, resetFields } = useSearch<ArticleParam>({
|
const { where, resetFields } = useSearch<ArticleParam>({
|
||||||
@@ -70,6 +69,7 @@
|
|||||||
navigationId: undefined,
|
navigationId: undefined,
|
||||||
categoryId: undefined,
|
categoryId: undefined,
|
||||||
merchantId: undefined,
|
merchantId: undefined,
|
||||||
|
status: undefined,
|
||||||
keywords: ''
|
keywords: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -89,10 +89,10 @@
|
|||||||
const text = e.target.value;
|
const text = e.target.value;
|
||||||
resetFields();
|
resetFields();
|
||||||
if (text === '已发布') {
|
if (text === '已发布') {
|
||||||
where.status = 1;
|
where.status = 0;
|
||||||
}
|
}
|
||||||
if (text === '待审核') {
|
if (text === '待审核') {
|
||||||
where.status = 0;
|
where.status = 1;
|
||||||
}
|
}
|
||||||
if (text === '已驳回') {
|
if (text === '已驳回') {
|
||||||
where.status = 2;
|
where.status = 2;
|
||||||
@@ -102,22 +102,15 @@
|
|||||||
|
|
||||||
const reload = () => {
|
const reload = () => {
|
||||||
getCount(where).then((data: any) => {
|
getCount(where).then((data: any) => {
|
||||||
goodsCount.value = data;
|
articleCount.value = data;
|
||||||
});
|
});
|
||||||
emit('search', where);
|
emit('search', where);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 搜索 */
|
// 按分类查询
|
||||||
const chooseMerchantId = (item: Merchant) => {
|
const onCategoryId = (id: number) => {
|
||||||
where.merchantName = item.merchantName;
|
where.categoryId = id;
|
||||||
where.merchantId = item.merchantId;
|
emit('search', where);
|
||||||
reload();
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseArticleCategory = (category: Navigation) => {
|
|
||||||
where.categoryName = category.title;
|
|
||||||
where.navigationId = category.navigationId;
|
|
||||||
reload();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 重置 */
|
/* 重置 */
|
||||||
@@ -127,10 +120,6 @@
|
|||||||
reload();
|
reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
// watch(
|
|
||||||
// () => props.selection,
|
|
||||||
// () => {}
|
|
||||||
// );
|
|
||||||
watch(
|
watch(
|
||||||
() => props.merchantId,
|
() => props.merchantId,
|
||||||
(id) => {
|
(id) => {
|
||||||
@@ -1,220 +1,292 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ele-body">
|
<div class="page">
|
||||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
<div class="ele-body">
|
||||||
<ele-split-layout
|
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||||
width="266px"
|
<ele-pro-table
|
||||||
allow-collapse
|
ref="tableRef"
|
||||||
:right-style="{ overflow: 'hidden' }"
|
row-key="articleId"
|
||||||
:style="{ minHeight: 'calc(100vh - 152px)' }"
|
:columns="columns"
|
||||||
>
|
:datasource="datasource"
|
||||||
<div>
|
:customRow="customRow"
|
||||||
<ele-toolbar theme="default">
|
:scroll="{ x: 1200 }"
|
||||||
<a-space :size="10">
|
tool-class="ele-toolbar-form"
|
||||||
<a-button
|
class="sys-org-table"
|
||||||
type="primary"
|
>
|
||||||
:size="`small`"
|
<template #toolbar>
|
||||||
class="ele-btn-icon"
|
<search
|
||||||
@click="openEdit()"
|
@search="reload"
|
||||||
|
:selection="selection"
|
||||||
|
:navigationList="navigationList"
|
||||||
|
:merchantId="merchantId"
|
||||||
|
:model="model"
|
||||||
|
@add="openEdit"
|
||||||
|
@remove="removeBatch"
|
||||||
|
@batchMove="openMove"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'title'">
|
||||||
|
<a
|
||||||
|
@click="
|
||||||
|
openSpmUrl(
|
||||||
|
`/article/detail/${record.articleId}.html`,
|
||||||
|
record,
|
||||||
|
record.articleId
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>{{ record.title }}</a
|
||||||
>
|
>
|
||||||
<template #icon>
|
</template>
|
||||||
<plus-outlined />
|
<template v-if="column.key === 'type'">
|
||||||
</template>
|
<a-tag v-if="record.type === 0">虚拟文章</a-tag>
|
||||||
</a-button>
|
<a-tag v-if="record.type === 1">实物文章</a-tag>
|
||||||
<a-button
|
</template>
|
||||||
type="primary"
|
<template v-if="column.key === 'image'">
|
||||||
:size="`small`"
|
<a-image :src="record.image" :width="80" />
|
||||||
:disabled="!current"
|
</template>
|
||||||
class="ele-btn-icon"
|
<template v-if="column.key === 'salePrice'">
|
||||||
@click="openEdit(current)"
|
¥{{ formatNumber(record.salePrice) }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'status'">
|
||||||
|
<a-tag
|
||||||
|
:color="record.status == 0 ? 'green' : 'red'"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="onUpdate(record)"
|
||||||
|
>{{ record.statusText }}</a-tag
|
||||||
>
|
>
|
||||||
<template #icon>
|
</template>
|
||||||
<edit-outlined />
|
<template v-if="column.key === 'action'">
|
||||||
</template>
|
<a-space>
|
||||||
</a-button>
|
<a @click="openEdit(record)">修改</a>
|
||||||
<a-button
|
<a-divider type="vertical" />
|
||||||
danger
|
<a-popconfirm
|
||||||
type="primary"
|
title="确定要删除此记录吗?"
|
||||||
:size="`small`"
|
@confirm="remove(record)"
|
||||||
:disabled="!current"
|
>
|
||||||
class="ele-btn-icon"
|
<a class="ele-text-danger">删除</a>
|
||||||
@click="remove"
|
</a-popconfirm>
|
||||||
>
|
</a-space>
|
||||||
<template #icon>
|
</template>
|
||||||
<delete-outlined />
|
</template>
|
||||||
</template>
|
</ele-pro-table>
|
||||||
</a-button>
|
</a-card>
|
||||||
</a-space>
|
|
||||||
</ele-toolbar>
|
<!-- 编辑弹窗 -->
|
||||||
<div class="ele-border-split sys-category-list">
|
<ArticleEdit
|
||||||
<a-tree
|
v-model:visible="showEdit"
|
||||||
:tree-data="data"
|
:navigationList="navigationList"
|
||||||
v-model:expanded-keys="expandedRowKeys"
|
:data="current"
|
||||||
v-model:selected-keys="selectedRowKeys"
|
@done="reload"
|
||||||
@select="onTreeSelect"
|
/>
|
||||||
>
|
</div>
|
||||||
<template #title="{ type, key: treeKey, title }">
|
|
||||||
<a-dropdown :trigger="['contextmenu']">
|
|
||||||
<span>{{ title }}</span>
|
|
||||||
<template #overlay v-if="type == 0">
|
|
||||||
<a-menu
|
|
||||||
@click="
|
|
||||||
({ key: menuKey }) =>
|
|
||||||
onContextMenuClick(treeKey, menuKey)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<a-menu-item key="1">修改</a-menu-item>
|
|
||||||
<a-menu-item key="2">删除</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
</template>
|
|
||||||
</a-tree>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<template #content>
|
|
||||||
<list
|
|
||||||
v-if="current"
|
|
||||||
:category-list="data"
|
|
||||||
:data="current"
|
|
||||||
:category-id="current.categoryId"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</ele-split-layout>
|
|
||||||
</a-card>
|
|
||||||
<!-- 编辑弹窗 -->
|
|
||||||
<category-edit
|
|
||||||
v-model:visible="showEdit"
|
|
||||||
:data="editData"
|
|
||||||
:category-list="data"
|
|
||||||
:category-id="current?.categoryId"
|
|
||||||
@done="query"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { createVNode, ref } from 'vue';
|
import { createVNode, ref, watch } from 'vue';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||||
|
import type { EleProTable } from 'ele-admin-pro';
|
||||||
|
import type {
|
||||||
|
DatasourceFunction,
|
||||||
|
ColumnItem
|
||||||
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
|
import Search from './components/search.vue';
|
||||||
|
import ArticleEdit from './components/articleEdit.vue';
|
||||||
import {
|
import {
|
||||||
PlusOutlined,
|
pageArticle,
|
||||||
EditOutlined,
|
removeArticle,
|
||||||
DeleteOutlined,
|
removeBatchArticle
|
||||||
ExclamationCircleOutlined
|
} from '@/api/cms/article';
|
||||||
} from '@ant-design/icons-vue';
|
import type { Article, ArticleParam } from '@/api/cms/article/model';
|
||||||
import { toTreeData, eachTreeData } from 'ele-admin-pro';
|
import { formatNumber } from 'ele-admin-pro/es';
|
||||||
import List from './list.vue';
|
import router from '@/router';
|
||||||
import CategoryEdit from './components/category-edit.vue';
|
import { toTreeData } from 'ele-admin-pro';
|
||||||
import {
|
import { openSpmUrl } from '@/utils/common';
|
||||||
listArticleCategory,
|
import { getSiteDomain } from '@/utils/domain';
|
||||||
removeArticleCategory
|
import { listNavigation } from '@/api/cms/navigation';
|
||||||
} from '@/api/cms/category';
|
import { Navigation } from '@/api/cms/navigation/model';
|
||||||
import { ArticleCategory } from '@/api/cms/category/model';
|
|
||||||
|
|
||||||
// 加载状态
|
// 表格实例
|
||||||
const loading = ref(true);
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
|
|
||||||
// 树形数据
|
// 表格选中数据
|
||||||
const data = ref<ArticleCategory[]>([]);
|
const selection = ref<Article[]>([]);
|
||||||
|
// 当前编辑数据
|
||||||
// 树展开的key
|
const current = ref<Article | null>(null);
|
||||||
const expandedRowKeys = ref<number[]>([]);
|
// 是否显示编辑弹窗
|
||||||
|
|
||||||
// 树选中的key
|
|
||||||
const selectedRowKeys = ref<number[]>([]);
|
|
||||||
|
|
||||||
// 选中数据
|
|
||||||
const current = ref<ArticleCategory | any>(null);
|
|
||||||
|
|
||||||
// 是否显示表单弹窗
|
|
||||||
const showEdit = ref(false);
|
const showEdit = ref(false);
|
||||||
|
// 是否显示批量移动弹窗
|
||||||
|
const showMove = ref(false);
|
||||||
|
// 店铺ID
|
||||||
|
const merchantId = ref<number>();
|
||||||
|
// 栏目ID
|
||||||
|
const categoryId = ref<number>();
|
||||||
|
// 当前模型
|
||||||
|
const model = ref<number>();
|
||||||
|
// 网站域名
|
||||||
|
const domain = getSiteDomain();
|
||||||
|
// 随机数
|
||||||
|
const token = ref<any>('');
|
||||||
|
// 栏目数据
|
||||||
|
const navigationList = ref<Navigation[]>();
|
||||||
|
|
||||||
// 编辑回显数据
|
// 表格数据源
|
||||||
const editData = ref<ArticleCategory | null>(null);
|
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||||
|
if (categoryId.value) {
|
||||||
|
where.categoryId = categoryId.value;
|
||||||
|
}
|
||||||
|
return pageArticle({
|
||||||
|
...where,
|
||||||
|
...orders,
|
||||||
|
page,
|
||||||
|
limit
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/* 查询 */
|
// 表格列配置
|
||||||
const query = () => {
|
const columns = ref<ColumnItem[]>([
|
||||||
loading.value = true;
|
{
|
||||||
listArticleCategory()
|
title: 'ID',
|
||||||
.then((list) => {
|
dataIndex: 'articleId',
|
||||||
loading.value = false;
|
key: 'articleId',
|
||||||
const eks: number[] = [];
|
align: 'center',
|
||||||
list.forEach((d) => {
|
width: 90
|
||||||
d.key = d.categoryId;
|
},
|
||||||
d.value = d.categoryId;
|
{
|
||||||
if (typeof d.categoryId === 'number') {
|
title: '文章标题',
|
||||||
eks.push(d.categoryId);
|
dataIndex: 'title',
|
||||||
}
|
key: 'title'
|
||||||
});
|
},
|
||||||
expandedRowKeys.value = eks;
|
{
|
||||||
data.value = toTreeData({
|
title: '封面图',
|
||||||
data: list.map((d) => {
|
dataIndex: 'image',
|
||||||
d.disabled = d.type != 0;
|
key: 'image',
|
||||||
return d;
|
width: 120,
|
||||||
}),
|
align: 'center'
|
||||||
idField: 'categoryId',
|
},
|
||||||
parentIdField: 'parentId'
|
{
|
||||||
});
|
title: '所属栏目',
|
||||||
if (list.length) {
|
dataIndex: 'categoryId',
|
||||||
if (typeof list[0].categoryId === 'number') {
|
key: 'categoryId',
|
||||||
selectedRowKeys.value = [list[0].categoryId];
|
align: 'center',
|
||||||
}
|
hideInTable: true
|
||||||
current.value = list[0];
|
},
|
||||||
} else {
|
{
|
||||||
selectedRowKeys.value = [];
|
title: '实际阅读量',
|
||||||
current.value = null;
|
dataIndex: 'actualViews',
|
||||||
}
|
key: 'actualViews',
|
||||||
|
sorter: true,
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '虚拟阅读量',
|
||||||
|
dataIndex: 'virtualViews',
|
||||||
|
key: 'virtualViews',
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '推荐',
|
||||||
|
dataIndex: 'recommend',
|
||||||
|
key: 'recommend',
|
||||||
|
sorter: true,
|
||||||
|
align: 'center',
|
||||||
|
hideInTable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
sorter: true,
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序号',
|
||||||
|
dataIndex: 'sortNumber',
|
||||||
|
key: 'sortNumber',
|
||||||
|
sorter: true,
|
||||||
|
align: 'center',
|
||||||
|
hideInTable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
key: 'createTime',
|
||||||
|
align: 'center',
|
||||||
|
width: 180,
|
||||||
|
sorter: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 180,
|
||||||
|
fixed: 'right',
|
||||||
|
align: 'center',
|
||||||
|
hideInSetting: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
/* 搜索 */
|
||||||
|
const reload = (where?: ArticleParam) => {
|
||||||
|
selection.value = [];
|
||||||
|
tableRef?.value?.reload({ where: where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 打开编辑弹窗 */
|
||||||
|
const openEdit = (row?: Article) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 打开批量移动弹窗 */
|
||||||
|
const openMove = () => {
|
||||||
|
showMove.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onUpdate = (row?: Article) => {
|
||||||
|
// const isShow = row?.isShow == 0 ? 1 : 0;
|
||||||
|
// updateArticle({ ...row, isShow }).then((msg) => {
|
||||||
|
// message.success(msg);
|
||||||
|
// reload();
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 删除单个 */
|
||||||
|
const remove = (row: Article) => {
|
||||||
|
const hide = message.loading('请求中..', 0);
|
||||||
|
removeArticle(row.articleId)
|
||||||
|
.then((msg) => {
|
||||||
|
hide();
|
||||||
|
message.success(msg);
|
||||||
|
reload();
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
loading.value = false;
|
hide();
|
||||||
message.error(e.message);
|
message.error(e.message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 选择数据 */
|
/* 批量删除 */
|
||||||
const onTreeSelect = () => {
|
const removeBatch = () => {
|
||||||
current.value = {};
|
if (!selection.value.length) {
|
||||||
eachTreeData(data.value, (d) => {
|
message.error('请至少选择一条数据');
|
||||||
if (
|
return;
|
||||||
typeof d.categoryId === 'number' &&
|
|
||||||
selectedRowKeys.value.includes(d.categoryId)
|
|
||||||
) {
|
|
||||||
current.value = d;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onContextMenuClick = (treeKey: number, menuKey: number) => {
|
|
||||||
// 修改
|
|
||||||
if (menuKey == 1) {
|
|
||||||
openEdit(current.value);
|
|
||||||
}
|
}
|
||||||
// 删除
|
|
||||||
if (menuKey == 2) {
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 打开编辑弹窗 */
|
|
||||||
const openEdit = (item?: ArticleCategory | null) => {
|
|
||||||
editData.value = item ?? null;
|
|
||||||
showEdit.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 删除 */
|
|
||||||
const remove = () => {
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '确定要删除选中的分类吗?',
|
content: '确定要删除选中的记录吗?',
|
||||||
icon: createVNode(ExclamationCircleOutlined),
|
icon: createVNode(ExclamationCircleOutlined),
|
||||||
maskClosable: true,
|
maskClosable: true,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
const hide = message.loading('请求中..', 0);
|
const hide = message.loading('请求中..', 0);
|
||||||
removeArticleCategory(current.value?.categoryId)
|
removeBatchArticle(selection.value.map((d) => d.articleId))
|
||||||
.then((msg) => {
|
.then((msg) => {
|
||||||
hide();
|
hide();
|
||||||
message.success(msg);
|
message.success(msg);
|
||||||
query();
|
reload();
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
hide();
|
hide();
|
||||||
@@ -224,21 +296,55 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
query();
|
/* 自定义行属性 */
|
||||||
|
const customRow = (record: Article) => {
|
||||||
|
return {
|
||||||
|
// 行点击事件
|
||||||
|
onClick: () => {
|
||||||
|
// console.log(record);
|
||||||
|
},
|
||||||
|
// 行双击事件
|
||||||
|
onDblclick: () => {
|
||||||
|
openEdit(record);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载栏目数据
|
||||||
|
if (!navigationList.value) {
|
||||||
|
listNavigation({}).then((res) => {
|
||||||
|
navigationList.value = toTreeData({
|
||||||
|
data: res?.map((d) => {
|
||||||
|
d.value = d.navigationId;
|
||||||
|
d.label = d.title;
|
||||||
|
if (d.type != 2) {
|
||||||
|
d.disabled = true;
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}),
|
||||||
|
idField: 'navigationId',
|
||||||
|
parentIdField: 'parentId'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => router.currentRoute.value.query,
|
||||||
|
(query) => {
|
||||||
|
if (query) {
|
||||||
|
categoryId.value = Number(query.categoryId);
|
||||||
|
model.value = Number(query.type);
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
name: 'ArticleIndex'
|
name: 'ArticleV2'
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped></style>
|
||||||
.sys-category-list {
|
|
||||||
padding: 12px 6px;
|
|
||||||
height: calc(100vh - 242px);
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
244
src/views/cms/articleV0/index.vue
Normal file
244
src/views/cms/articleV0/index.vue
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ele-body">
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||||
|
<ele-split-layout
|
||||||
|
width="266px"
|
||||||
|
allow-collapse
|
||||||
|
:right-style="{ overflow: 'hidden' }"
|
||||||
|
:style="{ minHeight: 'calc(100vh - 152px)' }"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<ele-toolbar theme="default">
|
||||||
|
<a-space :size="10">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
:size="`small`"
|
||||||
|
class="ele-btn-icon"
|
||||||
|
@click="openEdit()"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<plus-outlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
:size="`small`"
|
||||||
|
:disabled="!current"
|
||||||
|
class="ele-btn-icon"
|
||||||
|
@click="openEdit(current)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<edit-outlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
danger
|
||||||
|
type="primary"
|
||||||
|
:size="`small`"
|
||||||
|
:disabled="!current"
|
||||||
|
class="ele-btn-icon"
|
||||||
|
@click="remove"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<delete-outlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</ele-toolbar>
|
||||||
|
<div class="ele-border-split sys-category-list">
|
||||||
|
<a-tree
|
||||||
|
:tree-data="data"
|
||||||
|
v-model:expanded-keys="expandedRowKeys"
|
||||||
|
v-model:selected-keys="selectedRowKeys"
|
||||||
|
@select="onTreeSelect"
|
||||||
|
>
|
||||||
|
<template #title="{ type, key: treeKey, title }">
|
||||||
|
<a-dropdown :trigger="['contextmenu']">
|
||||||
|
<span>{{ title }}</span>
|
||||||
|
<template #overlay v-if="type == 0">
|
||||||
|
<a-menu
|
||||||
|
@click="
|
||||||
|
({ key: menuKey }) =>
|
||||||
|
onContextMenuClick(treeKey, menuKey)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-menu-item key="1">修改</a-menu-item>
|
||||||
|
<a-menu-item key="2">删除</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #content>
|
||||||
|
<list
|
||||||
|
v-if="current"
|
||||||
|
:category-list="data"
|
||||||
|
:data="current"
|
||||||
|
:category-id="current.categoryId"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ele-split-layout>
|
||||||
|
</a-card>
|
||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<category-edit
|
||||||
|
v-model:visible="showEdit"
|
||||||
|
:data="editData"
|
||||||
|
:category-list="data"
|
||||||
|
:category-id="current?.categoryId"
|
||||||
|
@done="query"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { createVNode, ref } from 'vue';
|
||||||
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
import {
|
||||||
|
PlusOutlined,
|
||||||
|
EditOutlined,
|
||||||
|
DeleteOutlined,
|
||||||
|
ExclamationCircleOutlined
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
|
import { toTreeData, eachTreeData } from 'ele-admin-pro';
|
||||||
|
import List from './list.vue';
|
||||||
|
import CategoryEdit from './components/category-edit.vue';
|
||||||
|
import {
|
||||||
|
listArticleCategory,
|
||||||
|
removeArticleCategory
|
||||||
|
} from '@/api/cms/category';
|
||||||
|
import { ArticleCategory } from '@/api/cms/category/model';
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
// 树形数据
|
||||||
|
const data = ref<ArticleCategory[]>([]);
|
||||||
|
|
||||||
|
// 树展开的key
|
||||||
|
const expandedRowKeys = ref<number[]>([]);
|
||||||
|
|
||||||
|
// 树选中的key
|
||||||
|
const selectedRowKeys = ref<number[]>([]);
|
||||||
|
|
||||||
|
// 选中数据
|
||||||
|
const current = ref<ArticleCategory | any>(null);
|
||||||
|
|
||||||
|
// 是否显示表单弹窗
|
||||||
|
const showEdit = ref(false);
|
||||||
|
|
||||||
|
// 编辑回显数据
|
||||||
|
const editData = ref<ArticleCategory | null>(null);
|
||||||
|
|
||||||
|
/* 查询 */
|
||||||
|
const query = () => {
|
||||||
|
loading.value = true;
|
||||||
|
listArticleCategory()
|
||||||
|
.then((list) => {
|
||||||
|
loading.value = false;
|
||||||
|
const eks: number[] = [];
|
||||||
|
list.forEach((d) => {
|
||||||
|
d.key = d.categoryId;
|
||||||
|
d.value = d.categoryId;
|
||||||
|
if (typeof d.categoryId === 'number') {
|
||||||
|
eks.push(d.categoryId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expandedRowKeys.value = eks;
|
||||||
|
data.value = toTreeData({
|
||||||
|
data: list.map((d) => {
|
||||||
|
d.disabled = d.type != 0;
|
||||||
|
return d;
|
||||||
|
}),
|
||||||
|
idField: 'categoryId',
|
||||||
|
parentIdField: 'parentId'
|
||||||
|
});
|
||||||
|
if (list.length) {
|
||||||
|
if (typeof list[0].categoryId === 'number') {
|
||||||
|
selectedRowKeys.value = [list[0].categoryId];
|
||||||
|
}
|
||||||
|
current.value = list[0];
|
||||||
|
} else {
|
||||||
|
selectedRowKeys.value = [];
|
||||||
|
current.value = null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 选择数据 */
|
||||||
|
const onTreeSelect = () => {
|
||||||
|
current.value = {};
|
||||||
|
eachTreeData(data.value, (d) => {
|
||||||
|
if (
|
||||||
|
typeof d.categoryId === 'number' &&
|
||||||
|
selectedRowKeys.value.includes(d.categoryId)
|
||||||
|
) {
|
||||||
|
current.value = d;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onContextMenuClick = (treeKey: number, menuKey: number) => {
|
||||||
|
// 修改
|
||||||
|
if (menuKey == 1) {
|
||||||
|
openEdit(current.value);
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
if (menuKey == 2) {
|
||||||
|
remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 打开编辑弹窗 */
|
||||||
|
const openEdit = (item?: ArticleCategory | null) => {
|
||||||
|
editData.value = item ?? null;
|
||||||
|
showEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 删除 */
|
||||||
|
const remove = () => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要删除选中的分类吗?',
|
||||||
|
icon: createVNode(ExclamationCircleOutlined),
|
||||||
|
maskClosable: true,
|
||||||
|
onOk: () => {
|
||||||
|
const hide = message.loading('请求中..', 0);
|
||||||
|
removeArticleCategory(current.value?.categoryId)
|
||||||
|
.then((msg) => {
|
||||||
|
hide();
|
||||||
|
message.success(msg);
|
||||||
|
query();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
hide();
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
query();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ArticleIndex'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.sys-category-list {
|
||||||
|
padding: 12px 6px;
|
||||||
|
height: calc(100vh - 242px);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
* 加载数据
|
* 加载数据
|
||||||
*/
|
*/
|
||||||
const reload = (id: number) => {
|
const reload = (id: number) => {
|
||||||
console.log(id);
|
console.log(id,'0000');
|
||||||
// 加载项目详情
|
// 加载项目详情
|
||||||
getArticle(id).then((data) => {
|
getArticle(id).then((data) => {
|
||||||
assignFields(data);
|
assignFields(data);
|
||||||
@@ -1,324 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="page">
|
|
||||||
<div class="ele-body">
|
|
||||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
|
||||||
<ele-pro-table
|
|
||||||
ref="tableRef"
|
|
||||||
row-key="articleId"
|
|
||||||
:columns="columns"
|
|
||||||
:datasource="datasource"
|
|
||||||
:customRow="customRow"
|
|
||||||
:scroll="{ x: 1200 }"
|
|
||||||
tool-class="ele-toolbar-form"
|
|
||||||
class="sys-org-table"
|
|
||||||
>
|
|
||||||
<template #toolbar>
|
|
||||||
<search
|
|
||||||
@search="reload"
|
|
||||||
:selection="selection"
|
|
||||||
:merchantId="merchantId"
|
|
||||||
@add="openEdit"
|
|
||||||
@remove="removeBatch"
|
|
||||||
@batchMove="openMove"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template v-if="column.key === 'title'">
|
|
||||||
<a
|
|
||||||
@click="
|
|
||||||
openSpmUrl(
|
|
||||||
`/article/detail/${record.articleId}.html`,
|
|
||||||
record,
|
|
||||||
record.articleId
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>{{ record.title }}</a
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'type'">
|
|
||||||
<a-tag v-if="record.type === 0">虚拟文章</a-tag>
|
|
||||||
<a-tag v-if="record.type === 1">实物文章</a-tag>
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'image'">
|
|
||||||
<a-image :src="record.image" :width="80" />
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'salePrice'">
|
|
||||||
¥{{ formatNumber(record.salePrice) }}
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'status'">
|
|
||||||
<a-tag
|
|
||||||
:color="record.status == 0 ? 'green' : 'red'"
|
|
||||||
class="cursor-pointer"
|
|
||||||
@click="onUpdate(record)"
|
|
||||||
>{{ record.statusText }}</a-tag
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'action'">
|
|
||||||
<a-space>
|
|
||||||
<a @click="openEdit(record)">修改</a>
|
|
||||||
<a-divider type="vertical" />
|
|
||||||
<a-popconfirm
|
|
||||||
title="确定要删除此记录吗?"
|
|
||||||
@confirm="remove(record)"
|
|
||||||
>
|
|
||||||
<a class="ele-text-danger">删除</a>
|
|
||||||
</a-popconfirm>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</ele-pro-table>
|
|
||||||
</a-card>
|
|
||||||
|
|
||||||
<!-- 编辑弹窗 -->
|
|
||||||
<ArticleEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { createVNode, ref, watch } from 'vue';
|
|
||||||
import { message, Modal } from 'ant-design-vue';
|
|
||||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
|
||||||
import type { EleProTable } from 'ele-admin-pro';
|
|
||||||
import { uuid } from 'ele-admin-pro';
|
|
||||||
import type {
|
|
||||||
DatasourceFunction,
|
|
||||||
ColumnItem
|
|
||||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
|
||||||
import Search from './components/search.vue';
|
|
||||||
import ArticleEdit from './components/articleEdit.vue';
|
|
||||||
import {
|
|
||||||
pageArticle,
|
|
||||||
removeArticle,
|
|
||||||
removeBatchArticle
|
|
||||||
} from '@/api/cms/article';
|
|
||||||
import type { Article, ArticleParam } from '@/api/cms/article/model';
|
|
||||||
import { formatNumber } from 'ele-admin-pro/es';
|
|
||||||
import router from '@/router';
|
|
||||||
import { openSpmUrl, openUrl, openUrlSpm } from '@/utils/common';
|
|
||||||
import { getSiteDomain } from '@/utils/domain';
|
|
||||||
|
|
||||||
// 表格实例
|
|
||||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
|
||||||
|
|
||||||
// 表格选中数据
|
|
||||||
const selection = ref<Article[]>([]);
|
|
||||||
// 当前编辑数据
|
|
||||||
const current = ref<Article | null>(null);
|
|
||||||
// 是否显示编辑弹窗
|
|
||||||
const showEdit = ref(false);
|
|
||||||
// 是否显示批量移动弹窗
|
|
||||||
const showMove = ref(false);
|
|
||||||
// 店铺ID
|
|
||||||
const merchantId = ref<number>();
|
|
||||||
// 网站域名
|
|
||||||
const domain = getSiteDomain();
|
|
||||||
// 随机数
|
|
||||||
const token = ref<any>('');
|
|
||||||
|
|
||||||
// 表格数据源
|
|
||||||
const datasource: DatasourceFunction = ({
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
where,
|
|
||||||
orders,
|
|
||||||
filters
|
|
||||||
}) => {
|
|
||||||
if (filters) {
|
|
||||||
where.status = filters.status;
|
|
||||||
}
|
|
||||||
if (merchantId.value) {
|
|
||||||
where.merchantId = merchantId.value;
|
|
||||||
}
|
|
||||||
return pageArticle({
|
|
||||||
...where,
|
|
||||||
...orders,
|
|
||||||
page,
|
|
||||||
limit
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 表格列配置
|
|
||||||
const columns = ref<ColumnItem[]>([
|
|
||||||
{
|
|
||||||
title: 'ID',
|
|
||||||
dataIndex: 'articleId',
|
|
||||||
key: 'articleId',
|
|
||||||
align: 'center',
|
|
||||||
width: 90
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '文章标题',
|
|
||||||
dataIndex: 'title',
|
|
||||||
key: 'title'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '封面图',
|
|
||||||
dataIndex: 'image',
|
|
||||||
key: 'image',
|
|
||||||
width: 120,
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '所属栏目',
|
|
||||||
dataIndex: 'categoryId',
|
|
||||||
key: 'categoryId',
|
|
||||||
align: 'center',
|
|
||||||
hideInTable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '实际阅读量',
|
|
||||||
dataIndex: 'actualViews',
|
|
||||||
key: 'actualViews',
|
|
||||||
sorter: true,
|
|
||||||
width: 120,
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '虚拟阅读量',
|
|
||||||
dataIndex: 'virtualViews',
|
|
||||||
key: 'virtualViews',
|
|
||||||
width: 120,
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '推荐',
|
|
||||||
dataIndex: 'recommend',
|
|
||||||
key: 'recommend',
|
|
||||||
sorter: true,
|
|
||||||
align: 'center',
|
|
||||||
hideInTable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '状态',
|
|
||||||
dataIndex: 'status',
|
|
||||||
key: 'status',
|
|
||||||
sorter: true,
|
|
||||||
width: 120,
|
|
||||||
align: 'center'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '排序号',
|
|
||||||
dataIndex: 'sortNumber',
|
|
||||||
key: 'sortNumber',
|
|
||||||
sorter: true,
|
|
||||||
align: 'center',
|
|
||||||
hideInTable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '创建时间',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
key: 'createTime',
|
|
||||||
align: 'center',
|
|
||||||
width: 180,
|
|
||||||
sorter: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
width: 180,
|
|
||||||
fixed: 'right',
|
|
||||||
align: 'center',
|
|
||||||
hideInSetting: true
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
/* 搜索 */
|
|
||||||
const reload = (where?: ArticleParam) => {
|
|
||||||
selection.value = [];
|
|
||||||
tableRef?.value?.reload({ where: where });
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 打开编辑弹窗 */
|
|
||||||
const openEdit = (row?: Article) => {
|
|
||||||
current.value = row ?? null;
|
|
||||||
showEdit.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 打开批量移动弹窗 */
|
|
||||||
const openMove = () => {
|
|
||||||
showMove.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onUpdate = (row?: Article) => {
|
|
||||||
// const isShow = row?.isShow == 0 ? 1 : 0;
|
|
||||||
// updateArticle({ ...row, isShow }).then((msg) => {
|
|
||||||
// message.success(msg);
|
|
||||||
// reload();
|
|
||||||
// });
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 删除单个 */
|
|
||||||
const remove = (row: Article) => {
|
|
||||||
const hide = message.loading('请求中..', 0);
|
|
||||||
removeArticle(row.articleId)
|
|
||||||
.then((msg) => {
|
|
||||||
hide();
|
|
||||||
message.success(msg);
|
|
||||||
reload();
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
hide();
|
|
||||||
message.error(e.message);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 批量删除 */
|
|
||||||
const removeBatch = () => {
|
|
||||||
if (!selection.value.length) {
|
|
||||||
message.error('请至少选择一条数据');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Modal.confirm({
|
|
||||||
title: '提示',
|
|
||||||
content: '确定要删除选中的记录吗?',
|
|
||||||
icon: createVNode(ExclamationCircleOutlined),
|
|
||||||
maskClosable: true,
|
|
||||||
onOk: () => {
|
|
||||||
const hide = message.loading('请求中..', 0);
|
|
||||||
removeBatchArticle(selection.value.map((d) => d.articleId))
|
|
||||||
.then((msg) => {
|
|
||||||
hide();
|
|
||||||
message.success(msg);
|
|
||||||
reload();
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
hide();
|
|
||||||
message.error(e.message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 自定义行属性 */
|
|
||||||
const customRow = (record: Article) => {
|
|
||||||
return {
|
|
||||||
// 行点击事件
|
|
||||||
onClick: () => {
|
|
||||||
// console.log(record);
|
|
||||||
},
|
|
||||||
// 行双击事件
|
|
||||||
onDblclick: () => {
|
|
||||||
openEdit(record);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => router.currentRoute.value.params.id,
|
|
||||||
(id) => {
|
|
||||||
merchantId.value = Number(id);
|
|
||||||
token.value = uuid();
|
|
||||||
reload();
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
export default {
|
|
||||||
name: 'ArticleV2'
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
:width="500"
|
:width="500"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
:title="isUpdate ? '编辑字段' : '添加字段'"
|
:title="isUpdate ? '编辑参数' : '添加参数'"
|
||||||
:body-style="{ paddingBottom: '28px' }"
|
:body-style="{ paddingBottom: '28px' }"
|
||||||
@update:visible="updateVisible"
|
@update:visible="updateVisible"
|
||||||
@ok="save"
|
@ok="save"
|
||||||
@@ -13,23 +13,34 @@
|
|||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="form"
|
:model="form"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
:label-col="{ md: { span: 4 }, sm: { span: 4 }, xs: { span: 24 } }"
|
:label-col="{ md: { span: 5 }, sm: { span: 4 }, xs: { span: 24 } }"
|
||||||
:wrapper-col="{ md: { span: 21 }, sm: { span: 22 }, xs: { span: 24 } }"
|
:wrapper-col="{ md: { span: 21 }, sm: { span: 22 }, xs: { span: 24 } }"
|
||||||
>
|
>
|
||||||
<a-form-item label="键" name="name">
|
<a-form-item label="参数名" name="name">
|
||||||
<a-input
|
<SelectWebsiteField
|
||||||
allow-clear
|
:placeholder="`添加参数`"
|
||||||
placeholder="site_name"
|
class="input-item"
|
||||||
v-model:value="form.name"
|
v-model:value="form.name"
|
||||||
|
@done="chooseData"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="值" name="value">
|
<a-form-item label="配置值" name="value">
|
||||||
<a-input allow-clear placeholder="淘宝网" v-model:value="form.value" />
|
<a-input allow-clear placeholder="淘宝网" v-model:value="form.value" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="图片">
|
||||||
|
<SelectFile
|
||||||
|
:placeholder="`请选择图片`"
|
||||||
|
:limit="1"
|
||||||
|
:data="images"
|
||||||
|
@done="chooseImage"
|
||||||
|
@del="onDeleteItem"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="描述" name="comments">
|
<a-form-item label="描述" name="comments">
|
||||||
<a-input
|
<a-textarea
|
||||||
allow-clear
|
:rows="4"
|
||||||
placeholder="网站名称"
|
:maxlength="200"
|
||||||
|
placeholder="描述"
|
||||||
v-model:value="form.comments"
|
v-model:value="form.comments"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -41,15 +52,6 @@
|
|||||||
v-model:value="form.sortNumber"
|
v-model:value="form.sortNumber"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="(选填)">
|
|
||||||
<SelectFile
|
|
||||||
:placeholder="`请选择图片`"
|
|
||||||
:limit="1"
|
|
||||||
:data="images"
|
|
||||||
@done="chooseImage"
|
|
||||||
@del="onDeleteItem"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</ele-modal>
|
</ele-modal>
|
||||||
</template>
|
</template>
|
||||||
@@ -92,6 +94,8 @@
|
|||||||
type: 0,
|
type: 0,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
value: undefined,
|
value: undefined,
|
||||||
|
modifyRange: undefined,
|
||||||
|
defaultValue: undefined,
|
||||||
comments: '',
|
comments: '',
|
||||||
status: 0,
|
status: 0,
|
||||||
sortNumber: 100
|
sortNumber: 100
|
||||||
@@ -142,6 +146,11 @@
|
|||||||
form.type = 0;
|
form.type = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const chooseData = (data: WebsiteField) => {
|
||||||
|
assignFields(data);
|
||||||
|
form.value = data.defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
/* 保存编辑 */
|
/* 保存编辑 */
|
||||||
const save = () => {
|
const save = () => {
|
||||||
if (!formRef.value) {
|
if (!formRef.value) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
:datasource="datasource"
|
:datasource="datasource"
|
||||||
:customRow="customRow"
|
:customRow="customRow"
|
||||||
|
:need-page="false"
|
||||||
tool-class="ele-toolbar-form"
|
tool-class="ele-toolbar-form"
|
||||||
class="sys-org-table"
|
class="sys-org-table"
|
||||||
>
|
>
|
||||||
@@ -17,8 +18,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'name'">
|
<template v-if="column.key === 'name'">
|
||||||
<div class="ele-text-heading">{{ record.name }}</div>
|
<div
|
||||||
<span class="ele-text-placeholder">{{ record.comments }}</span>
|
class="ele-text-heading"
|
||||||
|
@click="copyText(`config.${record.name}`)"
|
||||||
|
>{{ record.name }}</div
|
||||||
|
>
|
||||||
|
<!-- <span class="ele-text-placeholder">{{ record.comments }}</span>-->
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'value'">
|
<template v-if="column.key === 'value'">
|
||||||
<a-image
|
<a-image
|
||||||
@@ -26,7 +31,15 @@
|
|||||||
:src="record.value"
|
:src="record.value"
|
||||||
:width="120"
|
:width="120"
|
||||||
/>
|
/>
|
||||||
<span v-else>{{ record.value }}</span>
|
<div v-else>{{ record.value }}</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'comments'">
|
||||||
|
<a-popover>
|
||||||
|
<template #content>
|
||||||
|
{{ record.comments }}
|
||||||
|
</template>
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
</a-popover>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'action'">
|
<template v-if="column.key === 'action'">
|
||||||
<a @click="copyText('{{ config.' + record.name + ' }}')">调用</a>
|
<a @click="copyText('{{ config.' + record.name + ' }}')">调用</a>
|
||||||
@@ -66,6 +79,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import type { EleProTable } from 'ele-admin-pro';
|
import type { EleProTable } from 'ele-admin-pro';
|
||||||
import type { DatasourceFunction } from 'ele-admin-pro/es/ele-pro-table/types';
|
import type { DatasourceFunction } from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
@@ -77,6 +91,7 @@
|
|||||||
WebsiteFieldParam
|
WebsiteFieldParam
|
||||||
} from '@/api/cms/website/field/model';
|
} from '@/api/cms/website/field/model';
|
||||||
import {
|
import {
|
||||||
|
listWebsiteField,
|
||||||
pageWebsiteField,
|
pageWebsiteField,
|
||||||
removeWebsiteField,
|
removeWebsiteField,
|
||||||
undeleteWebsiteField,
|
undeleteWebsiteField,
|
||||||
@@ -100,7 +115,7 @@
|
|||||||
// 表格数据源
|
// 表格数据源
|
||||||
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
return pageWebsiteField({
|
return listWebsiteField({
|
||||||
...where,
|
...where,
|
||||||
...orders,
|
...orders,
|
||||||
page,
|
page,
|
||||||
@@ -111,14 +126,32 @@
|
|||||||
// 表格列配置
|
// 表格列配置
|
||||||
const columns = ref<any[]>([
|
const columns = ref<any[]>([
|
||||||
{
|
{
|
||||||
title: '键',
|
title: '参数名',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
width: 180,
|
||||||
key: 'name'
|
key: 'name'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '值',
|
title: '描述',
|
||||||
|
dataIndex: 'comments',
|
||||||
|
key: 'comments',
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '配置值',
|
||||||
dataIndex: 'value',
|
dataIndex: 'value',
|
||||||
key: 'value'
|
key: 'value',
|
||||||
|
width: 400,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '默认值',
|
||||||
|
dataIndex: 'defaultValue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '可设置范围',
|
||||||
|
dataIndex: 'modifyRange'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<template>
|
<template>
|
||||||
<ele-modal
|
<ele-modal
|
||||||
:width="740"
|
:width="800"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
:confirm-loading="loading"
|
:confirm-loading="loading"
|
||||||
:title="isUpdate ? '修改导航' : '新建导航'"
|
:title="isUpdate ? '修改导航' : '新建导航'"
|
||||||
@@ -41,123 +41,70 @@
|
|||||||
@pressEnter="save"
|
@pressEnter="save"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="选择页面" v-if="form.type == 1">
|
|
||||||
<SelectDesign
|
|
||||||
:placeholder="`请选择页面`"
|
|
||||||
v-model:value="form.pageName"
|
|
||||||
@done="choosePageId"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="选择列表" v-if="form.type == 2">
|
|
||||||
<SelectArticleCategory
|
|
||||||
:placeholder="`请选择列表`"
|
|
||||||
v-model:value="form.pageName"
|
|
||||||
@done="chooseArticleCategoryId"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="选择文章" v-if="form.type == 3">
|
|
||||||
<SelectArticle
|
|
||||||
:placeholder="`请选择文章`"
|
|
||||||
v-model:value="form.pageName"
|
|
||||||
@done="chooseArticle"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="选择表单" v-if="form.type == 4">
|
|
||||||
<SelectForm
|
|
||||||
:placeholder="`请选择表单`"
|
|
||||||
v-model:value="form.pageName"
|
|
||||||
@done="chooseForm"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="选择文档" v-if="form.type == 5">
|
|
||||||
<SelectDocsBook
|
|
||||||
:placeholder="`请选择知识文档`"
|
|
||||||
v-model:value="form.title"
|
|
||||||
@done="chooseDocsBook"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="选择分类" v-if="form.type == 6">
|
|
||||||
<SelectGoodsCategory
|
|
||||||
:placeholder="`请选择商品分类`"
|
|
||||||
v-model:value="form.title"
|
|
||||||
@done="chooseGoodsCategory"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="选择商品详情" v-if="form.type == 7">
|
|
||||||
<SelectDocsBook
|
|
||||||
:placeholder="`请选择商品详情`"
|
|
||||||
v-model:value="form.title"
|
|
||||||
@done="chooseGoods"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="form.type == 9 ? '链接地址' : '路由地址'"
|
:label="form.type == 9 ? '链接地址' : '路由地址'"
|
||||||
name="path"
|
name="path"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
:placeholder="form.type == 9 ? '请输入链接地址' : '/about.html'"
|
:placeholder="
|
||||||
|
form.type == 9 ? '请输入链接地址' : '/iphone-15-pro'
|
||||||
|
"
|
||||||
v-model:value="form.path"
|
v-model:value="form.path"
|
||||||
@pressEnter="save"
|
@pressEnter="save"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="组件路径" name="component" v-if="form.type == 0">
|
<a-form-item label="组件路径" name="component">
|
||||||
<a-input
|
<a-input
|
||||||
allow-clear
|
allow-clear
|
||||||
placeholder="/custom/index"
|
placeholder="/pages/[custom].vue"
|
||||||
v-model:value="form.component"
|
v-model:value="form.component"
|
||||||
@pressEnter="save"
|
@pressEnter="save"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="描述" name="comments">
|
||||||
|
<a-textarea
|
||||||
|
:rows="4"
|
||||||
|
:maxlength="200"
|
||||||
|
placeholder="请输入描述"
|
||||||
|
v-model:value="form.comments"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col
|
<a-col
|
||||||
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
|
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
|
||||||
>
|
>
|
||||||
<!-- <a-form-item label="模型" name="type">-->
|
<a-form-item label="模型" name="model">
|
||||||
<!-- <a-select-->
|
<ChooseDictionary
|
||||||
<!-- ref="select"-->
|
dict-code="NavigationModel"
|
||||||
<!-- v-model:value="form.type"-->
|
:placeholder="`选择模型`"
|
||||||
<!-- style="width: 253px"-->
|
v-model:value="form.model"
|
||||||
<!-- @change="onType"-->
|
@done="chooseModel"
|
||||||
<!-- >-->
|
/>
|
||||||
<!-- <a-select-option :value="0">通用模型</a-select-option>-->
|
</a-form-item>
|
||||||
<!-- <a-select-option :value="1">单页内容</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="2">新闻分类</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="3">新闻详情</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="4">表单设计</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="5">知识文档</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="6">商品分类</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="7">商品详情</a-select-option>-->
|
|
||||||
<!-- <a-select-option :value="9">外部链接</a-select-option>-->
|
|
||||||
<!-- </a-select>-->
|
|
||||||
<!-- </a-form-item>-->
|
|
||||||
<!-- <a-form-item label="位置" name="position">-->
|
|
||||||
<!-- <a-radio-group v-model:value="form.position">-->
|
|
||||||
<!-- <a-radio :value="0">全部</a-radio>-->
|
|
||||||
<!-- <a-radio :value="1">顶部</a-radio>-->
|
|
||||||
<!-- <a-radio :value="2">底部</a-radio>-->
|
|
||||||
<!-- </a-radio-group>-->
|
|
||||||
<!-- </a-form-item>-->
|
|
||||||
<a-form-item label="位置" name="top">
|
<a-form-item label="位置" name="top">
|
||||||
<a-radio-group v-model:value="form.position" @change="onPosition">
|
<a-radio-group v-model:value="form.position" @change="onPosition">
|
||||||
<a-radio-button :value="0">不限</a-radio-button>
|
<a-radio :value="1">顶部</a-radio>
|
||||||
<a-radio-button :value="1">顶部</a-radio-button>
|
<a-radio :value="2">底部</a-radio>
|
||||||
<a-radio-button :value="2">底部</a-radio-button>
|
<a-radio :value="0">不限</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
<!-- <a-space>-->
|
</a-form-item>
|
||||||
<!-- <a-switch-->
|
<a-form-item label="权限" name="">
|
||||||
<!-- checked-children="显示"-->
|
<a-radio-group v-model:value="form.permission">
|
||||||
<!-- un-checked-children="隐藏"-->
|
<a-radio :value="0">所有人</a-radio>
|
||||||
<!-- :checked="form.top === 0"-->
|
<a-radio :value="1">登录可见</a-radio>
|
||||||
<!-- @update:checked="updateTopValue"-->
|
<a-radio :value="2">密码可见</a-radio>
|
||||||
<!-- />-->
|
</a-radio-group>
|
||||||
<!-- <a-switch-->
|
</a-form-item>
|
||||||
<!-- checked-children="显示"-->
|
<a-form-item label="允许评论" name="">
|
||||||
<!-- un-checked-children="隐藏"-->
|
<a-space>
|
||||||
<!-- :checked="form.bottom === 0"-->
|
<a-switch
|
||||||
<!-- @update:checked="updateBottomValue"-->
|
checked-children="是"
|
||||||
<!-- />-->
|
un-checked-children="否"
|
||||||
<!-- </a-space>-->
|
:checked="form.hide === 0"
|
||||||
|
@update:checked="updateHideValue"
|
||||||
|
/>
|
||||||
|
</a-space>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="状态" name="hide">
|
<a-form-item label="状态" name="hide">
|
||||||
<a-space>
|
<a-space>
|
||||||
@@ -191,26 +138,6 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<!-- <div style="margin-bottom: 22px">-->
|
|
||||||
<!-- <a-divider />-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <a-form-item-->
|
|
||||||
<!-- label="备注"-->
|
|
||||||
<!-- name="comments"-->
|
|
||||||
<!-- :label-col="-->
|
|
||||||
<!-- styleResponsive ? { md: 3, sm: 4, xs: 24 } : { flex: '90px' }-->
|
|
||||||
<!-- "-->
|
|
||||||
<!-- :wrapper-col="-->
|
|
||||||
<!-- styleResponsive ? { md: 21, sm: 20, xs: 24 } : { flex: '1' }-->
|
|
||||||
<!-- "-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- <a-textarea-->
|
|
||||||
<!-- :rows="4"-->
|
|
||||||
<!-- :maxlength="200"-->
|
|
||||||
<!-- placeholder="请输入备注信息"-->
|
|
||||||
<!-- v-model:value="form.comments"-->
|
|
||||||
<!-- />-->
|
|
||||||
<!-- </a-form-item>-->
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</ele-modal>
|
</ele-modal>
|
||||||
</template>
|
</template>
|
||||||
@@ -224,16 +151,10 @@
|
|||||||
import useFormData from '@/utils/use-form-data';
|
import useFormData from '@/utils/use-form-data';
|
||||||
import { Navigation } from '@/api/cms/navigation/model';
|
import { Navigation } from '@/api/cms/navigation/model';
|
||||||
import { addNavigation, updateNavigation } from '@/api/cms/navigation';
|
import { addNavigation, updateNavigation } from '@/api/cms/navigation';
|
||||||
import { Design } from '@/api/cms/design/model';
|
|
||||||
import { removeSiteInfoCache } from '@/api/cms/website';
|
import { removeSiteInfoCache } from '@/api/cms/website';
|
||||||
import { ArticleCategory } from '@/api/cms/category/model';
|
|
||||||
import { Article } from '@/api/cms/article/model';
|
|
||||||
import { Form } from '@/api/cms/form/model';
|
|
||||||
import { DocsBook } from '@/api/cms/docs-book/model';
|
|
||||||
import { Goods } from '@/api/shop/goods/model';
|
|
||||||
import { GoodsCategory } from '@/api/shop/goodsCategory/model';
|
|
||||||
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
|
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
|
||||||
import { FileRecord } from '@/api/system/file/model';
|
import { FileRecord } from '@/api/system/file/model';
|
||||||
|
import { uuid } from 'ele-admin-pro';
|
||||||
|
|
||||||
// 是否开启响应式布局
|
// 是否开启响应式布局
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
@@ -269,15 +190,22 @@
|
|||||||
// 表单数据
|
// 表单数据
|
||||||
const { form, resetFields, assignFields } = useFormData<Navigation>({
|
const { form, resetFields, assignFields } = useFormData<Navigation>({
|
||||||
navigationId: undefined,
|
navigationId: undefined,
|
||||||
|
model: '[custom]',
|
||||||
|
code: undefined,
|
||||||
|
modelName: '',
|
||||||
type: 0,
|
type: 0,
|
||||||
title: '',
|
title: '',
|
||||||
parentId: 0,
|
parentId: 0,
|
||||||
path: '',
|
parentName: undefined,
|
||||||
component: '',
|
parentPath: undefined,
|
||||||
|
path: undefined,
|
||||||
|
component: undefined,
|
||||||
sortNumber: 100,
|
sortNumber: 100,
|
||||||
hide: 0,
|
hide: 0,
|
||||||
|
permission: 0,
|
||||||
|
password: uuid(),
|
||||||
position: 1,
|
position: 1,
|
||||||
top: 1,
|
top: 0,
|
||||||
bottom: 1,
|
bottom: 1,
|
||||||
status: 0,
|
status: 0,
|
||||||
pageId: 0,
|
pageId: 0,
|
||||||
@@ -297,6 +225,14 @@
|
|||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择模型',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
// component: [
|
// component: [
|
||||||
// {
|
// {
|
||||||
// required: true,
|
// required: true,
|
||||||
@@ -367,77 +303,10 @@
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
const onType = (index: number) => {
|
const chooseModel = (item: Navigation) => {
|
||||||
if (index == 0) {
|
form.model = `${item.value}`;
|
||||||
form.path = '/';
|
form.modelName = `${item.label}`;
|
||||||
form.component = '';
|
form.component = `/pages/${item.value}`;
|
||||||
}
|
|
||||||
if (index == 1) {
|
|
||||||
form.path = '';
|
|
||||||
form.component = '';
|
|
||||||
}
|
|
||||||
if (index == 2) {
|
|
||||||
form.path = '';
|
|
||||||
form.component = '';
|
|
||||||
}
|
|
||||||
if (index == 9) {
|
|
||||||
form.path = undefined;
|
|
||||||
form.component = '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const choosePageId = (data: Design) => {
|
|
||||||
form.pageId = data.pageId;
|
|
||||||
form.pageName = data.name;
|
|
||||||
form.title = data.name;
|
|
||||||
form.path = data.path;
|
|
||||||
form.component = data.component;
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseArticleCategoryId = (data: ArticleCategory) => {
|
|
||||||
form.articleCategoryId = data.categoryId;
|
|
||||||
form.pageName = data.title;
|
|
||||||
form.title = data.title;
|
|
||||||
form.path = '/article/' + data.categoryId;
|
|
||||||
form.component = '/article/index';
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseArticle = (data: Article) => {
|
|
||||||
form.articleId = data.articleId;
|
|
||||||
form.title = data.title;
|
|
||||||
form.pageName = data.title;
|
|
||||||
form.path = '/a/' + data.articleId;
|
|
||||||
form.component = '/article/detail';
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseForm = (data: Form) => {
|
|
||||||
form.formId = data.formId;
|
|
||||||
form.title = data.name;
|
|
||||||
form.pageName = data.name;
|
|
||||||
form.path = '/form/' + data.formId;
|
|
||||||
form.component = '/form/detail';
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseDocsBook = (data: DocsBook) => {
|
|
||||||
form.bookCode = data.code;
|
|
||||||
form.title = data.name;
|
|
||||||
form.pageName = data.name;
|
|
||||||
form.path = '/docs/' + data.code;
|
|
||||||
form.component = '/docs/index';
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseGoodsCategory = (data: GoodsCategory) => {
|
|
||||||
form.goodsCategoryId = data.categoryId;
|
|
||||||
form.title = data.title;
|
|
||||||
form.pageName = data.title;
|
|
||||||
form.path = '/goods/search?categoryId=' + data.categoryId;
|
|
||||||
form.component = '/goods/search';
|
|
||||||
};
|
|
||||||
|
|
||||||
const chooseGoods = (data: Goods) => {
|
|
||||||
form.goodsId = data.goodsId;
|
|
||||||
form.path = '/goods/detail/' + data.goodsId;
|
|
||||||
form.component = '/goods/search';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseFile = (data: FileRecord) => {
|
const chooseFile = (data: FileRecord) => {
|
||||||
@@ -480,10 +349,6 @@
|
|||||||
const navigationForm = {
|
const navigationForm = {
|
||||||
...form
|
...form
|
||||||
};
|
};
|
||||||
// if (form.path != '' && form.path?.charAt(0) != '/') {
|
|
||||||
// message.error('路由必须以"/"开头');
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
const saveOrUpdate = isUpdate.value ? updateNavigation : addNavigation;
|
const saveOrUpdate = isUpdate.value ? updateNavigation : addNavigation;
|
||||||
saveOrUpdate(navigationForm)
|
saveOrUpdate(navigationForm)
|
||||||
.then((msg) => {
|
.then((msg) => {
|
||||||
@@ -509,14 +374,6 @@
|
|||||||
form.hide = value ? 0 : 1;
|
form.hide = value ? 0 : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateTopValue = (value: boolean) => {
|
|
||||||
form.top = value ? 0 : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateBottomValue = (value: boolean) => {
|
|
||||||
form.bottom = value ? 0 : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.visible,
|
||||||
(visible) => {
|
(visible) => {
|
||||||
@@ -525,8 +382,7 @@
|
|||||||
if (props.data) {
|
if (props.data) {
|
||||||
assignFields({
|
assignFields({
|
||||||
...props.data,
|
...props.data,
|
||||||
parentId:
|
parentId: props.data.parentId ? props.data.parentId : 0,
|
||||||
props.data.parentId === 0 ? undefined : props.data.parentId,
|
|
||||||
tempPath: props.data.path
|
tempPath: props.data.path
|
||||||
});
|
});
|
||||||
if (props.data.type == 2) {
|
if (props.data.type == 2) {
|
||||||
@@ -534,7 +390,6 @@
|
|||||||
}
|
}
|
||||||
isUpdate.value = true;
|
isUpdate.value = true;
|
||||||
} else {
|
} else {
|
||||||
form.parentId = props.parentId;
|
|
||||||
isUpdate.value = false;
|
isUpdate.value = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -60,19 +60,22 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'type'">
|
<template v-if="column.key === 'type'">
|
||||||
<a-tag v-if="isExternalLink(record.path)" color="red">外链</a-tag>
|
<a-tag v-if="isExternalLink(record.path)" color="purple"
|
||||||
|
>外部链接</a-tag
|
||||||
|
>
|
||||||
<a-tag v-else-if="index === 0" color="orange">首页</a-tag>
|
<a-tag v-else-if="index === 0" color="orange">首页</a-tag>
|
||||||
<a-tag v-else-if="isExternalLink(record.component)" color="orange">
|
<a-tag v-else-if="isExternalLink(record.component)" color="orange">
|
||||||
内链
|
内链
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<span v-else-if="isDirectory(record)"></span>
|
<span v-else-if="isDirectory(record)"></span>
|
||||||
<a-tag v-else-if="record.type === 0">通用</a-tag>
|
<a-tag v-else-if="record.type === 0">通用模型</a-tag>
|
||||||
<a-tag v-else-if="record.type === 1" color="purple">页面</a-tag>
|
<a-tag v-else-if="record.type === 1" color="purple">页面</a-tag>
|
||||||
<a-tag v-else-if="record.type === 2">列表</a-tag>
|
<a-tag v-else-if="record.type === 2" color="blue">文章列表</a-tag>
|
||||||
<a-tag v-else-if="record.type === 3">文章</a-tag>
|
<a-tag v-else-if="record.type === 3">文章</a-tag>
|
||||||
<a-tag v-else-if="record.type === 4" color="cyan">表单</a-tag>
|
<a-tag v-else-if="record.type === 4" color="cyan">表单</a-tag>
|
||||||
<a-tag v-else-if="record.type === 5" color="green">文档</a-tag>
|
<a-tag v-else-if="record.type === 5" color="green">文档</a-tag>
|
||||||
<a-tag v-else-if="record.type === 9" color="orange">链接</a-tag>
|
<a-tag v-else-if="record.type === 6" color="pink">图片列表</a-tag>
|
||||||
|
<a-tag v-else-if="record.type === 9" color="purple">外部链接</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'title'">
|
<template v-else-if="column.key === 'title'">
|
||||||
<a-avatar
|
<a-avatar
|
||||||
@@ -82,10 +85,9 @@
|
|||||||
style="margin-right: 10px"
|
style="margin-right: 10px"
|
||||||
v-if="record.image"
|
v-if="record.image"
|
||||||
/>
|
/>
|
||||||
<a v-if="!isDirectory(record)" @click="openSpmUrl(record.path)">{{
|
<a @click="openSpmUrl(record.path, record, record.navigationId)">{{
|
||||||
record.title
|
record.title
|
||||||
}}</a>
|
}}</a>
|
||||||
<a v-else>{{ record.title }}</a>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'showIndex'">
|
<template v-if="column.key === 'showIndex'">
|
||||||
<a-tag v-if="record.showIndex === 1" color="green">显示</a-tag>
|
<a-tag v-if="record.showIndex === 1" color="green">显示</a-tag>
|
||||||
@@ -112,7 +114,9 @@
|
|||||||
<a-space>
|
<a-space>
|
||||||
<a class="text-fuchsia-300" @click="openLayout(record)">布局</a>
|
<a class="text-fuchsia-300" @click="openLayout(record)">布局</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a class="text-gray-400" @click="openDesign(record)">设置</a>
|
<a-tooltip :title="`配置SEO及页面元素`">
|
||||||
|
<a class="text-gray-400" @click="openDesign(record)">内容</a>
|
||||||
|
</a-tooltip>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a @click="openEdit(null, record.navigationId)">添加</a>
|
<a @click="openEdit(null, record.navigationId)">添加</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
@@ -183,10 +187,11 @@
|
|||||||
updateNavigation
|
updateNavigation
|
||||||
} from '@/api/cms/navigation';
|
} from '@/api/cms/navigation';
|
||||||
import type { Navigation, NavigationParam } from '@/api/cms/navigation/model';
|
import type { Navigation, NavigationParam } from '@/api/cms/navigation/model';
|
||||||
import { openPreview, openSpmUrl, openUrl } from '@/utils/common';
|
import { openSpmUrl } from '@/utils/common';
|
||||||
import { getSiteInfo } from '@/api/layout';
|
import { getSiteInfo } from '@/api/layout';
|
||||||
import { Design } from '@/api/cms/design/model';
|
import { Design } from '@/api/cms/design/model';
|
||||||
import { listDesign } from '@/api/cms/design';
|
import { listDesign } from '@/api/cms/design';
|
||||||
|
import router from '@/router';
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
@@ -294,7 +299,7 @@
|
|||||||
// 表格数据源
|
// 表格数据源
|
||||||
const datasource: DatasourceFunction = ({ where }) => {
|
const datasource: DatasourceFunction = ({ where }) => {
|
||||||
where = {};
|
where = {};
|
||||||
where.title = searchText.value;
|
where.keywords = searchText.value;
|
||||||
// where.position = position.value;
|
// where.position = position.value;
|
||||||
where.top = 0;
|
where.top = 0;
|
||||||
where.bottom = undefined;
|
where.bottom = undefined;
|
||||||
@@ -350,6 +355,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const openDesign = (row?: Navigation) => {
|
const openDesign = (row?: Navigation) => {
|
||||||
|
// TODO 通用模型
|
||||||
listDesign({
|
listDesign({
|
||||||
navigationId: row?.navigationId,
|
navigationId: row?.navigationId,
|
||||||
limit: 1
|
limit: 1
|
||||||
@@ -361,6 +367,15 @@
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
showDesignEdit.value = true;
|
showDesignEdit.value = true;
|
||||||
});
|
});
|
||||||
|
// TODO 文章列表
|
||||||
|
if (row?.type === 2) {
|
||||||
|
router.push({
|
||||||
|
path: '/cms/article',
|
||||||
|
query: { categoryId: row.navigationId, type: row.type }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(row);
|
||||||
|
// /cms/article
|
||||||
};
|
};
|
||||||
|
|
||||||
const openLayout = (row?: Navigation) => {
|
const openLayout = (row?: Navigation) => {
|
||||||
|
|||||||
230
src/views/system/field/components/website-field-edit.vue
Normal file
230
src/views/system/field/components/website-field-edit.vue
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
<!-- 用户编辑弹窗 -->
|
||||||
|
<template>
|
||||||
|
<ele-modal
|
||||||
|
:width="500"
|
||||||
|
:visible="visible"
|
||||||
|
:maskClosable="false"
|
||||||
|
:title="isUpdate ? '编辑参数' : '添加参数'"
|
||||||
|
:body-style="{ paddingBottom: '28px' }"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
@ok="save"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ md: { span: 5 }, sm: { span: 4 }, xs: { span: 24 } }"
|
||||||
|
:wrapper-col="{ md: { span: 21 }, sm: { span: 22 }, xs: { span: 24 } }"
|
||||||
|
>
|
||||||
|
<a-form-item label="参数名" name="name">
|
||||||
|
<!-- <ChooseWebsiteField-->
|
||||||
|
<!-- v-model:value="form.name"-->
|
||||||
|
<!-- :placeholder="`选择参数`"-->
|
||||||
|
<!-- @done="chooseData"-->
|
||||||
|
<!-- />-->
|
||||||
|
<SelectWebsiteField
|
||||||
|
:placeholder="`添加参数`"
|
||||||
|
class="input-item"
|
||||||
|
v-model:value="form.name"
|
||||||
|
@done="chooseData"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="配置值" name="value">
|
||||||
|
<a-input allow-clear placeholder="淘宝网" v-model:value="form.value" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="图片格式">
|
||||||
|
<SelectFile
|
||||||
|
:placeholder="`请选择图片`"
|
||||||
|
:limit="1"
|
||||||
|
:data="images"
|
||||||
|
@done="chooseImage"
|
||||||
|
@del="onDeleteItem"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="可配置范围" name="modifyRange">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="[0-1]"
|
||||||
|
v-model:value="form.modifyRange"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="默认值" name="defaultValue">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="0"
|
||||||
|
v-model:value="form.defaultValue"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="描述" name="comments">
|
||||||
|
<a-textarea
|
||||||
|
:rows="4"
|
||||||
|
:maxlength="200"
|
||||||
|
placeholder="描述"
|
||||||
|
v-model:value="form.comments"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="排序" name="sortNumber">
|
||||||
|
<a-input-number
|
||||||
|
:min="0"
|
||||||
|
:max="99999"
|
||||||
|
placeholder="请输入排序号"
|
||||||
|
v-model:value="form.sortNumber"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { FormInstance } from 'ant-design-vue/es/form';
|
||||||
|
import { WebsiteField } from '@/api/system/website/field/model';
|
||||||
|
import useFormData from '@/utils/use-form-data';
|
||||||
|
import { addWebsiteField, updateWebsiteField } from '@/api/system/website/field';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import { removeSiteInfoCache } from '@/api/system/website';
|
||||||
|
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
|
||||||
|
import { FileRecord } from '@/api/system/file/model';
|
||||||
|
import { uuid } from 'ele-admin-pro';
|
||||||
|
|
||||||
|
// 是否是修改
|
||||||
|
const isUpdate = ref(false);
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
websiteId: number | null | undefined;
|
||||||
|
// 修改回显的数据
|
||||||
|
data?: WebsiteField | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done'): void;
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 提交状态
|
||||||
|
const loading = ref(false);
|
||||||
|
const images = ref<ItemType[]>([]);
|
||||||
|
const formRef = ref<FormInstance | null>(null);
|
||||||
|
|
||||||
|
const { form, resetFields, assignFields } = useFormData<WebsiteField>({
|
||||||
|
id: undefined,
|
||||||
|
type: 0,
|
||||||
|
name: undefined,
|
||||||
|
value: undefined,
|
||||||
|
modifyRange: undefined,
|
||||||
|
defaultValue: undefined,
|
||||||
|
comments: '',
|
||||||
|
status: 0,
|
||||||
|
sortNumber: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
message: '请输入参数名称(英语)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// comments: [
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// type: 'string',
|
||||||
|
// message: '请输入描述'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
message: '请填写参数值'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const chooseImage = (data: FileRecord) => {
|
||||||
|
images.value.push({
|
||||||
|
uid: data.id,
|
||||||
|
url: data.path,
|
||||||
|
status: 'done'
|
||||||
|
});
|
||||||
|
form.value = data.downloadUrl;
|
||||||
|
form.type = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDeleteItem = (index: number) => {
|
||||||
|
images.value.splice(index, 1);
|
||||||
|
form.type = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const chooseData = (data: WebsiteField) => {
|
||||||
|
assignFields(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 保存编辑 */
|
||||||
|
const save = () => {
|
||||||
|
if (!formRef.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
const data = {
|
||||||
|
...form,
|
||||||
|
// name: form.name?.toUpperCase(),
|
||||||
|
websiteId: props.websiteId
|
||||||
|
};
|
||||||
|
const saveOrUpdate = isUpdate.value
|
||||||
|
? updateWebsiteField
|
||||||
|
: addWebsiteField;
|
||||||
|
saveOrUpdate(data)
|
||||||
|
.then((msg) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.success(msg);
|
||||||
|
updateVisible(false);
|
||||||
|
// 清除缓存
|
||||||
|
removeSiteInfoCache('SiteInfo:' + localStorage.getItem('TenantId'));
|
||||||
|
emit('done');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
images.value = [];
|
||||||
|
if (props.data) {
|
||||||
|
assignFields(props.data);
|
||||||
|
form.comments = props.data.comments;
|
||||||
|
if (form.type == 1) {
|
||||||
|
images.value.push({
|
||||||
|
uid: uuid(),
|
||||||
|
url: props.data.value,
|
||||||
|
status: 'done'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
isUpdate.value = true;
|
||||||
|
} else {
|
||||||
|
isUpdate.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resetFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
13
src/views/system/field/components/website-field-search.vue
Normal file
13
src/views/system/field/components/website-field-search.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<a-button @click="add">添加参数</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'add'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const add = () => {
|
||||||
|
emit('add');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
252
src/views/system/field/index.vue
Normal file
252
src/views/system/field/index.vue
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
<template>
|
||||||
|
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<div class="website-field">
|
||||||
|
<!-- 表格 -->
|
||||||
|
<ele-pro-table
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="websiteId"
|
||||||
|
:columns="columns"
|
||||||
|
:datasource="datasource"
|
||||||
|
:customRow="customRow"
|
||||||
|
:need-page="false"
|
||||||
|
tool-class="ele-toolbar-form"
|
||||||
|
class="sys-org-table"
|
||||||
|
>
|
||||||
|
<template #toolbar>
|
||||||
|
<WebsiteFieldSearch @add="openEdit" />
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'name'">
|
||||||
|
<div
|
||||||
|
class="ele-text-heading"
|
||||||
|
@click="copyText(`config.${record.name}`)"
|
||||||
|
>{{ record.name }}</div
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'value'">
|
||||||
|
<a-image
|
||||||
|
v-if="record.type === 1"
|
||||||
|
:src="record.value"
|
||||||
|
:width="120"
|
||||||
|
/>
|
||||||
|
<div v-else>{{ record.value }}</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'comments'">
|
||||||
|
<a-popover>
|
||||||
|
<template #content>
|
||||||
|
{{ record.comments }}
|
||||||
|
</template>
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
</a-popover>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a @click="copyText('{{ config.' + record.name + ' }}')">调用</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a @click="openEdit(record)">编辑</a>
|
||||||
|
<template v-if="record.deleted == 0">
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a-popconfirm
|
||||||
|
title="确定要删除此记录吗?"
|
||||||
|
@confirm="remove(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">删除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
<template v-if="record.deleted == 1">
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a-popconfirm
|
||||||
|
title="确定要放回原处吗?"
|
||||||
|
@confirm="recovery(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">恢复</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</ele-pro-table>
|
||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<WebsiteFieldEdit
|
||||||
|
v-model:visible="showEdit"
|
||||||
|
:data="current"
|
||||||
|
@done="reload"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
</a-page-header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import type { EleProTable } from 'ele-admin-pro';
|
||||||
|
import type { DatasourceFunction } from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
|
import WebsiteFieldSearch from './components/website-field-search.vue';
|
||||||
|
import { Website } from '@/api/system/website/model';
|
||||||
|
import WebsiteFieldEdit from './components/website-field-edit.vue';
|
||||||
|
import {
|
||||||
|
WebsiteField,
|
||||||
|
WebsiteFieldParam
|
||||||
|
} from '@/api/system/website/field/model';
|
||||||
|
import {
|
||||||
|
listWebsiteField,
|
||||||
|
removeWebsiteField,
|
||||||
|
undeleteWebsiteField,
|
||||||
|
updateWebsiteField
|
||||||
|
} from '@/api/system/website/field';
|
||||||
|
import { copyText, getPageTitle } from '@/utils/common';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
websiteId: any;
|
||||||
|
data: Website;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
|
const selection = ref<any[]>();
|
||||||
|
// 当前编辑数据
|
||||||
|
const current = ref<WebsiteField | null>(null);
|
||||||
|
// 是否显示编辑弹窗
|
||||||
|
const showEdit = ref(false);
|
||||||
|
|
||||||
|
// 表格数据源
|
||||||
|
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||||
|
// 搜索条件
|
||||||
|
return listWebsiteField({
|
||||||
|
...where,
|
||||||
|
...orders,
|
||||||
|
page,
|
||||||
|
limit
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = ref<any[]>([
|
||||||
|
{
|
||||||
|
title: '参数名',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 180,
|
||||||
|
key: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '描述',
|
||||||
|
dataIndex: 'comments',
|
||||||
|
key: 'comments',
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '配置值',
|
||||||
|
dataIndex: 'value',
|
||||||
|
key: 'value',
|
||||||
|
width: 300,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '默认值',
|
||||||
|
width: 180,
|
||||||
|
dataIndex: 'defaultValue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '可设置范围',
|
||||||
|
width: 180,
|
||||||
|
dataIndex: 'modifyRange'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序',
|
||||||
|
dataIndex: 'sortNumber',
|
||||||
|
width: 120,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 180,
|
||||||
|
align: 'center',
|
||||||
|
hideInSetting: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const moveUp = (row?: WebsiteField) => {
|
||||||
|
updateWebsiteField({
|
||||||
|
id: row?.id,
|
||||||
|
sortNumber: Number(row?.sortNumber) + 1
|
||||||
|
}).then((msg) => {
|
||||||
|
message.success(msg);
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 打开编辑弹窗 */
|
||||||
|
const openEdit = (row?: WebsiteField) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 搜索 */
|
||||||
|
const reload = (where?: WebsiteFieldParam) => {
|
||||||
|
selection.value = [];
|
||||||
|
tableRef?.value?.reload({ where: where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 删除单个 */
|
||||||
|
const remove = (row: WebsiteField) => {
|
||||||
|
const hide = message.loading('请求中..', 0);
|
||||||
|
removeWebsiteField(row.id)
|
||||||
|
.then((msg) => {
|
||||||
|
hide();
|
||||||
|
message.success(msg);
|
||||||
|
reload();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
hide();
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 从回收站放回原处
|
||||||
|
const recovery = (row: WebsiteField) => {
|
||||||
|
const hide = message.loading('请求中..', 0);
|
||||||
|
undeleteWebsiteField(row.id)
|
||||||
|
.then((msg) => {
|
||||||
|
hide();
|
||||||
|
message.success(msg);
|
||||||
|
reload();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
hide();
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 自定义行属性 */
|
||||||
|
const customRow = (record: WebsiteField) => {
|
||||||
|
return {
|
||||||
|
// 行点击事件
|
||||||
|
onClick: () => {
|
||||||
|
// console.log(record);
|
||||||
|
},
|
||||||
|
// 行双击事件
|
||||||
|
onDblclick: () => {
|
||||||
|
openEdit(record);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.websiteId,
|
||||||
|
(websiteId) => {
|
||||||
|
if (websiteId) {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'WebsiteFieldIndex'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user