|
|
|
|
@ -4,6 +4,7 @@
|
|
|
|
|
<a-tab-pane key="recommendations" tab="今日推荐"></a-tab-pane>
|
|
|
|
|
<a-tab-pane key="stores" tab="门店"></a-tab-pane>
|
|
|
|
|
<a-tab-pane key="events" tab="赛事分析"></a-tab-pane>
|
|
|
|
|
<!-- <a-tab-pane key="highlights" tab="划重点"></a-tab-pane> -->
|
|
|
|
|
<template #rightExtra>
|
|
|
|
|
<a-button type="primary" @click="showAddModal">新增</a-button>
|
|
|
|
|
</template>
|
|
|
|
|
@ -11,7 +12,7 @@
|
|
|
|
|
|
|
|
|
|
<a-table :columns="columns" :data-source="filteredData" :rowKey="record => record.id">
|
|
|
|
|
<template #bodyCell="{ column, record }">
|
|
|
|
|
<template v-if="column.key === 'content'">
|
|
|
|
|
<template v-if="column.key === 'content' && activeTab !== 'highlights'">
|
|
|
|
|
<div v-if="record.classify === 1">
|
|
|
|
|
<a-image
|
|
|
|
|
:src="record.img"
|
|
|
|
|
@ -22,7 +23,10 @@
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else v-text="record.content1"></span>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-if="column.key === 'status'">
|
|
|
|
|
<template v-if="column.key === 'relatedOption' && activeTab === 'highlights'">
|
|
|
|
|
<span>{{ getRelatedOptionLabel(record.relatedOption) }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-if="column.key === 'status' && activeTab !== 'highlights'">
|
|
|
|
|
<a-tag :color="record.status === 1 ? 'green' : 'orange'">
|
|
|
|
|
{{ record.status === 1 ? '已发布' : '未发布' }}
|
|
|
|
|
</a-tag>
|
|
|
|
|
@ -30,7 +34,7 @@
|
|
|
|
|
<template v-if="column.key === 'action'">
|
|
|
|
|
<a-space>
|
|
|
|
|
<a-button type="link" @click="editItem(record)">编辑</a-button>
|
|
|
|
|
<a-button type="link" @click="deleteItem(record)" v-if="activeTab != 'recommendations'">删除</a-button>
|
|
|
|
|
<a-button v-if="activeTab !== 'recommendations'" type="link" @click="deleteItem(record)">删除</a-button>
|
|
|
|
|
</a-space>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
@ -44,7 +48,7 @@
|
|
|
|
|
width="800px"
|
|
|
|
|
>
|
|
|
|
|
<a-form :model="formState" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
|
|
|
|
<a-form-item label="类型">
|
|
|
|
|
<a-form-item label="类型" v-if="activeTab !== 'highlights'">
|
|
|
|
|
<a-select v-model:value="formState.classify" :disabled="modalMode === 'edit'">
|
|
|
|
|
<a-select-option :value="1">今日推荐</a-select-option>
|
|
|
|
|
<a-select-option :value="0">门店</a-select-option>
|
|
|
|
|
@ -54,26 +58,35 @@
|
|
|
|
|
<a-form-item label="标题">
|
|
|
|
|
<a-input v-model:value="formState.title" placeholder="输入标题"/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="主图">
|
|
|
|
|
<a-upload
|
|
|
|
|
v-model:fileList="formState.images"
|
|
|
|
|
list-type="picture-card"
|
|
|
|
|
:max-count="1"
|
|
|
|
|
@preview="handlePreview"
|
|
|
|
|
@change="handleImageChange"
|
|
|
|
|
:customRequest="customRequest"
|
|
|
|
|
>
|
|
|
|
|
<div v-if="formState.images.length < 1">
|
|
|
|
|
<plus-outlined />
|
|
|
|
|
<div style="margin-top: 8px">上传图片</div>
|
|
|
|
|
</div>
|
|
|
|
|
</a-upload>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="内容" v-if="formState.classify !== 1">
|
|
|
|
|
<wysiwyg-editor v-model="formState.content" @image-upload="handleEditorImageUpload" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="状态">
|
|
|
|
|
<a-switch v-model:checked="formState.status" :checked-value="1" :unchecked-value="0" />
|
|
|
|
|
<template v-if="activeTab !== 'highlights'">
|
|
|
|
|
<a-form-item label="主图">
|
|
|
|
|
<a-upload
|
|
|
|
|
v-model:fileList="formState.images"
|
|
|
|
|
list-type="picture-card"
|
|
|
|
|
:max-count="1"
|
|
|
|
|
@preview="handlePreview"
|
|
|
|
|
@change="handleImageChange"
|
|
|
|
|
:customRequest="customRequest"
|
|
|
|
|
>
|
|
|
|
|
<div v-if="formState.images.length < 1">
|
|
|
|
|
<plus-outlined />
|
|
|
|
|
<div style="margin-top: 8px">上传图片</div>
|
|
|
|
|
</div>
|
|
|
|
|
</a-upload>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="内容" v-if="formState.classify !== 1">
|
|
|
|
|
<wysiwyg-editor v-model="formState.content" @image-upload="handleEditorImageUpload" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="状态">
|
|
|
|
|
<a-switch v-model:checked="formState.status" :checked-value="1" :unchecked-value="0" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
<a-form-item label="关联选项" v-if="activeTab === 'highlights'">
|
|
|
|
|
<a-select v-model:value="formState.relatedOption">
|
|
|
|
|
<a-select-option v-for="option in relatedOptions" :key="option.key" :value="option.key">
|
|
|
|
|
{{ option.label }}
|
|
|
|
|
</a-select-option>
|
|
|
|
|
</a-select>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</a-modal>
|
|
|
|
|
@ -89,7 +102,7 @@ import { ref, reactive, computed, onMounted } from 'vue';
|
|
|
|
|
import { message } from 'ant-design-vue';
|
|
|
|
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
import WysiwygEditor from './WysiwygEditor.vue';
|
|
|
|
|
import { saveContentApi, updateContentApi, getContentListApi, deleteContentApi, uploadImageApi } from "../../api/contentConfig";
|
|
|
|
|
import { saveContentApi,getHzd, updateContentApi, getContentListApi, deleteContentApi, uploadImageApi } from "../../api/contentConfig";
|
|
|
|
|
|
|
|
|
|
const activeTab = ref('recommendations');
|
|
|
|
|
const modalVisible = ref(false);
|
|
|
|
|
@ -98,13 +111,24 @@ const previewVisible = ref(false);
|
|
|
|
|
const previewImage = ref('');
|
|
|
|
|
const previewTitle = ref('');
|
|
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
|
{ title: '类型', dataIndex: 'classify', key: 'classify' },
|
|
|
|
|
{ title: '标题', dataIndex: 'title', key: 'title' },
|
|
|
|
|
{ title: '内容', dataIndex: 'content', key: 'content' },
|
|
|
|
|
{ title: '状态', dataIndex: 'status', key: 'status' },
|
|
|
|
|
{ title: '操作', key: 'action' },
|
|
|
|
|
];
|
|
|
|
|
const columns = computed(() => {
|
|
|
|
|
if (activeTab.value === 'highlights') {
|
|
|
|
|
return [
|
|
|
|
|
{ title: '类型', dataIndex: 'classify', key: 'classify' },
|
|
|
|
|
{ title: '标题', dataIndex: 'title', key: 'title' },
|
|
|
|
|
{ title: '关联', dataIndex: 'relatedOption', key: 'relatedOption' },
|
|
|
|
|
{ title: '操作', key: 'action' },
|
|
|
|
|
];
|
|
|
|
|
} else {
|
|
|
|
|
return [
|
|
|
|
|
{ title: '类型', dataIndex: 'classify', key: 'classify' },
|
|
|
|
|
{ title: '标题', dataIndex: 'title', key: 'title' },
|
|
|
|
|
{ title: '内容', dataIndex: 'content', key: 'content' },
|
|
|
|
|
{ title: '状态', dataIndex: 'status', key: 'status' },
|
|
|
|
|
{ title: '操作', key: 'action' },
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const data = reactive([]);
|
|
|
|
|
const classify = ref(1);
|
|
|
|
|
@ -117,13 +141,27 @@ const formState = reactive({
|
|
|
|
|
img: '',
|
|
|
|
|
images: [],
|
|
|
|
|
status: 0,
|
|
|
|
|
relatedOption: null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const relatedOptions = [
|
|
|
|
|
{ key: 1, label: '足球总进球' },
|
|
|
|
|
{ key: 2, label: '足球2.0' },
|
|
|
|
|
{ key: 3, label: '足球3.0' },
|
|
|
|
|
{ key: 4, label: '足球中高倍' },
|
|
|
|
|
{ key: 5, label: '足球高倍' },
|
|
|
|
|
{ key: 6, label: '足球8.0' },
|
|
|
|
|
{ key: 7, label: '篮球' },
|
|
|
|
|
{ key: 8, label: '排列三' },
|
|
|
|
|
{ key: 9, label: '快乐八' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const filteredData = computed(() => {
|
|
|
|
|
const tabToClassify = {
|
|
|
|
|
'recommendations': 1,
|
|
|
|
|
'stores': 0,
|
|
|
|
|
'events': 2
|
|
|
|
|
'events': 2,
|
|
|
|
|
'highlights': 61,
|
|
|
|
|
};
|
|
|
|
|
return data.filter(item => item.classify === tabToClassify[activeTab.value]);
|
|
|
|
|
});
|
|
|
|
|
@ -133,9 +171,19 @@ const showAddModal = () => {
|
|
|
|
|
const tabToClassify = {
|
|
|
|
|
'recommendations': 1,
|
|
|
|
|
'stores': 0,
|
|
|
|
|
'events': 2
|
|
|
|
|
'events': 2,
|
|
|
|
|
'highlights': 61,
|
|
|
|
|
};
|
|
|
|
|
Object.assign(formState, { id: null, classify: tabToClassify[activeTab.value], title: '', content: '', img: '', images: [], status: 0 });
|
|
|
|
|
Object.assign(formState, {
|
|
|
|
|
id: null,
|
|
|
|
|
classify: tabToClassify[activeTab.value],
|
|
|
|
|
title: '',
|
|
|
|
|
content: '',
|
|
|
|
|
img: '',
|
|
|
|
|
images: [],
|
|
|
|
|
status: activeTab.value === 'highlights' ? 1 : 0,
|
|
|
|
|
relatedOption: null
|
|
|
|
|
});
|
|
|
|
|
modalVisible.value = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -148,7 +196,8 @@ const editItem = (record) => {
|
|
|
|
|
name: 'image.jpg',
|
|
|
|
|
status: 'done',
|
|
|
|
|
url: record.img,
|
|
|
|
|
}] : []
|
|
|
|
|
}] : [],
|
|
|
|
|
relatedOption: record.relatedOption,
|
|
|
|
|
});
|
|
|
|
|
modalVisible.value = true;
|
|
|
|
|
};
|
|
|
|
|
@ -163,22 +212,21 @@ const deleteItem = async (record) => {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleModalOk = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const data = {
|
|
|
|
|
classify: formState.classify,
|
|
|
|
|
classify: activeTab.value === 'highlights' ? 61 : formState.classify,
|
|
|
|
|
title: formState.title,
|
|
|
|
|
content: formState.classify === 1 ? '' : formState.content,
|
|
|
|
|
img: processImagePath(formState.img),
|
|
|
|
|
status: formState.status ? 1 : 0,
|
|
|
|
|
content: activeTab.value === 'highlights' ? '' : (formState.classify === 1 ? '' : formState.content),
|
|
|
|
|
img: activeTab.value === 'highlights' ? '' : processImagePath(formState.img),
|
|
|
|
|
status: activeTab.value === 'highlights' ? 1 : formState.status,
|
|
|
|
|
relatedOption: activeTab.value === 'highlights' ? formState.relatedOption : undefined,
|
|
|
|
|
remark: activeTab.value === 'highlights' ? formState.relatedOption : undefined,
|
|
|
|
|
};
|
|
|
|
|
if (modalMode.value === 'add') {
|
|
|
|
|
await saveContentApi(data);
|
|
|
|
|
} else {
|
|
|
|
|
await updateContentApi({ ...data, recordId: formState.id });
|
|
|
|
|
await updateContentApi({ ...data, recordId: activeTab.value === 'highlights' ? 61 : formState.id });
|
|
|
|
|
}
|
|
|
|
|
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
|
|
|
|
|
modalVisible.value = false;
|
|
|
|
|
@ -191,6 +239,7 @@ const handleModalOk = async () => {
|
|
|
|
|
const handleModalCancel = () => {
|
|
|
|
|
modalVisible.value = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const processImagePath = (imgPath) => {
|
|
|
|
|
const urlPrefix = 'http://123.249.121.26:8801/images/';
|
|
|
|
|
if (imgPath.startsWith(urlPrefix)) {
|
|
|
|
|
@ -200,7 +249,7 @@ const processImagePath = (imgPath) => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const tabChange = (activeKey) => {
|
|
|
|
|
classify.value = activeKey === 'recommendations' ? 1 : activeKey === 'stores' ? 0 : 2;
|
|
|
|
|
classify.value = activeKey === 'recommendations' ? 1 : activeKey === 'stores' ? 0 : activeKey === 'events' ? 2 : 61;
|
|
|
|
|
fetchData();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -227,7 +276,6 @@ const handleImageChange = ({ fileList }) => {
|
|
|
|
|
formState.images = fileList;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleEditorImageUpload = async (file) => {
|
|
|
|
|
try {
|
|
|
|
|
const response = await uploadImageApi(file);
|
|
|
|
|
@ -250,6 +298,16 @@ const getBase64 = (file) => {
|
|
|
|
|
|
|
|
|
|
const fetchData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
console.log(activeTab.value);
|
|
|
|
|
if (activeTab.value == 'highlights') {
|
|
|
|
|
const response = await getHzd();
|
|
|
|
|
const records = response.data;
|
|
|
|
|
console.log(records);
|
|
|
|
|
//对象转数组
|
|
|
|
|
|
|
|
|
|
data.splice(0, data.length, ...records);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
const response = await getContentListApi(1, 10, classify.value);
|
|
|
|
|
const records = response.data.records.map(record => {
|
|
|
|
|
if (record.img) {
|
|
|
|
|
@ -260,11 +318,18 @@ const fetchData = async () => {
|
|
|
|
|
return record;
|
|
|
|
|
});
|
|
|
|
|
data.splice(0, data.length, ...records);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
message.error('获取数据失败');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getRelatedOptionLabel = (optionKey) => {
|
|
|
|
|
const option = relatedOptions.find(option => option.key === optionKey);
|
|
|
|
|
return option ? option.label : '';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
fetchData();
|
|
|
|
|
});
|
|
|
|
|
|