You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
6.0 KiB
Vue

2 years ago
<template>
1 year ago
<div class="carousel-management">
1 year ago
<div class="table-actions">
<a-button type="primary" @click="showAddModal"></a-button>
</div>
1 year ago
<a-table :columns="columns" :data-source="data" :rowKey="record => record.id">
1 year ago
<template #bodyCell="{ column, record }">
1 year ago
<template v-if="column.key === 'img'">
<a-image
:src="record.img"
:width="50"
:height="50"
style="margin-right: 5px;"
/>
</template>
<template v-if="column.key === 'status'">
<a-tag :color="record.status === 1 ? 'green' : 'red'">
{{ record.status === 1 ? '启用' : '不启用' }}
</a-tag>
1 year ago
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" @click="editItem(record)"></a-button>
<a-button type="link" @click="deleteItem(record)"></a-button>
</a-space>
</template>
</template>
</a-table>
<a-modal
v-model:visible="modalVisible"
1 year ago
:title="modalMode === 'add' ? '新增轮播图' : '编辑轮播图'"
1 year ago
@ok="handleModalOk"
@cancel="handleModalCancel"
width="800px"
>
<a-form :model="formState" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
1 year ago
<a-form-item label="标题" name="title" :rules="[{ required: true, message: '请输入标题' }]">
<a-input v-model:value="formState.title" />
1 year ago
</a-form-item>
1 year ago
<a-form-item label="图片" name="img" :rules="[{ required: true, message: '请上传图片' }]">
1 year ago
<a-upload
v-model:fileList="formState.images"
list-type="picture-card"
1 year ago
:max-count="1"
1 year ago
@preview="handlePreview"
@change="handleImageChange"
1 year ago
:customRequest="customRequest"
1 year ago
>
1 year ago
<div v-if="formState.images.length < 1">
1 year ago
<plus-outlined />
<div style="margin-top: 8px">上传图片</div>
</div>
</a-upload>
1 year ago
</a-form-item>
1 year ago
<a-form-item label="状态" name="status">
<a-switch v-model:checked="formState.status" :checked-value="1" :unchecked-value="0" />
1 year ago
</a-form-item>
</a-form>
</a-modal>
<a-modal v-model:visible="previewVisible" :title="previewTitle" :footer="null">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</div>
2 years ago
</template>
<script setup>
1 year ago
import { ref, reactive, onMounted } from 'vue';
1 year ago
import { message } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
1 year ago
import { getCarouselListApi, saveCarouselApi, deleteCarouselApi, updateCarouselApi, uploadImageApi } from "../../api/carouselConfig";
1 year ago
const modalVisible = ref(false);
const modalMode = ref('add');
const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
const columns = [
{ title: '标题', dataIndex: 'title', key: 'title' },
1 year ago
{ title: '图片', dataIndex: 'img', key: 'img' },
{ title: '状态', dataIndex: 'status', key: 'status' },
1 year ago
{ title: '操作', key: 'action' },
];
1 year ago
const data = reactive([]);
2 years ago
1 year ago
const formState = reactive({
id: null,
title: '',
images: [],
1 year ago
img: '',
status: 1,
1 year ago
});
2 years ago
1 year ago
const showAddModal = () => {
modalMode.value = 'add';
1 year ago
Object.assign(formState, { id: null, title: '', images: [], img: '', status: 1 });
1 year ago
modalVisible.value = true;
};
2 years ago
1 year ago
const editItem = (record) => {
modalMode.value = 'edit';
1 year ago
Object.assign(formState, {
id: record.id,
title: record.title,
images: [{
uid: -1,
name: 'image.jpg',
status: 'done',
url: record.img,
}],
img: record.img,
status: record.status,
});
1 year ago
modalVisible.value = true;
2 years ago
};
1 year ago
const deleteItem = async (record) => {
try {
await deleteCarouselApi(record.id);
1 year ago
message.success('删除成功');
1 year ago
fetchData();
} catch (error) {
message.error('删除失败');
1 year ago
}
2 years ago
};
1 year ago
const handleModalOk = async () => {
console.log(formState);
try {
const data = {
1 year ago
title: formState.title,
1 year ago
img: formState.img,
status: formState.status
};
if (modalMode.value === 'add') {
console.log(data);
await saveCarouselApi(data);
} else {
await updateCarouselApi({ ...data, id: formState.id });
1 year ago
}
1 year ago
message.success(modalMode.value === 'add' ? '添加成功' : '编辑成功');
modalVisible.value = false;
fetchData();
} catch (error) {
message.error(modalMode.value === 'add' ? '添加失败' : '编辑失败');
1 year ago
}
2 years ago
};
1 year ago
const handleModalCancel = () => {
modalVisible.value = false;
2 years ago
};
1 year ago
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
}
previewImage.value = file.url || file.preview;
previewVisible.value = true;
previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
2 years ago
};
1 year ago
const customRequest = async ({ file, onSuccess, onError }) => {
try {
const response = await uploadImageApi(file);
formState.img = response.data.url;
onSuccess(response, file);
} catch (error) {
onError(error);
}
};
1 year ago
const handleImageChange = ({ fileList }) => {
formState.images = fileList;
1 year ago
if (fileList.length > 0) {
const lastFile = fileList[fileList.length - 1];
formState.img = lastFile.response ? lastFile.response.data : lastFile.url;
}
2 years ago
};
1 year ago
const getBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
2 years ago
};
1 year ago
const fetchData = async () => {
try {
const response = await getCarouselListApi(1);
data.splice(0, data.length, ...response.data.records);
} catch (error) {
message.error('获取数据失败');
}
};
onMounted(() => {
fetchData();
});
2 years ago
</script>
1 year ago
<style scoped>
1 year ago
.carousel-management {
1 year ago
padding: 24px;
2 years ago
}
1 year ago
.table-actions {
margin-bottom: 16px;
text-align: right;
2 years ago
}
1 year ago
</style>