|
@@ -0,0 +1,388 @@
|
|
|
|
|
+import { ref } from 'vue'
|
|
|
|
|
+import request from '@/utils/request'
|
|
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
|
|
+
|
|
|
|
|
+export function useNews() {
|
|
|
|
|
+ const loading = ref(false)
|
|
|
|
|
+ const articles = ref([])
|
|
|
|
|
+ const article = ref({})
|
|
|
|
|
+ const categories = ref([])
|
|
|
|
|
+ const category = ref({})
|
|
|
|
|
+ const pagination = ref({
|
|
|
|
|
+ page: 1,
|
|
|
|
|
+ limit: 20,
|
|
|
|
|
+ total: 0
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 获取文章列表
|
|
|
|
|
+ const getArticleList = async (params = {}) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.get('/news/news', {
|
|
|
|
|
+ params: {
|
|
|
|
|
+ page: Number(pagination.value.page),
|
|
|
|
|
+ limit: Number(pagination.value.limit),
|
|
|
|
|
+ ...params
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ console.log('Articles API response:', response.data);
|
|
|
|
|
+
|
|
|
|
|
+ // 处理各种可能的响应格式
|
|
|
|
|
+ let articleData = [];
|
|
|
|
|
+ let totalCount = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (Array.isArray(response.data)) {
|
|
|
|
|
+ // 直接返回数组
|
|
|
|
|
+ articleData = response.data;
|
|
|
|
|
+ totalCount = response.data.length;
|
|
|
|
|
+ } else if (response.data && response.data.data) {
|
|
|
|
|
+ if (Array.isArray(response.data.data)) {
|
|
|
|
|
+ // 返回 {code, data: [...]} 格式
|
|
|
|
|
+ articleData = response.data.data;
|
|
|
|
|
+ totalCount = response.data.data.length;
|
|
|
|
|
+ } else if (response.data.data.list && Array.isArray(response.data.data.list)) {
|
|
|
|
|
+ // 返回 {code, data: {list: [...], total: number}} 格式
|
|
|
|
|
+ articleData = response.data.data.list;
|
|
|
|
|
+ totalCount = response.data.data.total || articleData.length;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 转换字段名称为小写
|
|
|
|
|
+ const formattedList = convertKeysToLowerCase(articleData);
|
|
|
|
|
+ console.log('Formatted article data:', formattedList);
|
|
|
|
|
+
|
|
|
|
|
+ articles.value = formattedList;
|
|
|
|
|
+ pagination.value.total = totalCount;
|
|
|
|
|
+
|
|
|
|
|
+ if (articles.value.length === 0) {
|
|
|
|
|
+ console.log('没有文章数据');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log('文章数据加载成功,数量:', articles.value.length);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true; // 返回成功状态
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取文章列表失败:', error)
|
|
|
|
|
+ ElMessage.error('获取文章列表失败')
|
|
|
|
|
+ return false;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取文章详情
|
|
|
|
|
+ const getArticleDetail = async (id) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ console.log('获取文章详情,ID:', id)
|
|
|
|
|
+ const response = await request.get(`/news/news/${id}`)
|
|
|
|
|
+ console.log('文章详情原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ console.log('文章详情响应处理后:', response)
|
|
|
|
|
+
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ const articleData = response.data || {}
|
|
|
|
|
+ article.value = articleData
|
|
|
|
|
+ // 转换字段名称
|
|
|
|
|
+ const convertedData = convertKeysToLowerCase(articleData)
|
|
|
|
|
+ console.log('转换后的文章详情:', convertedData)
|
|
|
|
|
+ return convertedData
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '获取文章详情失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取文章详情失败:', error)
|
|
|
|
|
+ ElMessage.error('获取文章详情失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建文章
|
|
|
|
|
+ const createArticle = async (articleData) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ console.log('创建文章数据:', articleData)
|
|
|
|
|
+ const response = await request.post('/news/news', articleData)
|
|
|
|
|
+ console.log('创建文章原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ console.log('创建文章响应处理后:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 后端返回成功
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ ElMessage.success('创建文章成功')
|
|
|
|
|
+ // 存储数据并返回true表示成功
|
|
|
|
|
+ article.value = response.data || {}
|
|
|
|
|
+ return true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '创建文章失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('创建文章失败:', error)
|
|
|
|
|
+ ElMessage.error('创建文章失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新文章
|
|
|
|
|
+ const updateArticle = async (id, articleData) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ console.log('更新文章数据:', articleData)
|
|
|
|
|
+ const response = await request.put(`/news/news/${id}`, articleData)
|
|
|
|
|
+ console.log('更新文章原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ console.log('更新文章响应处理后:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 后端返回成功
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ ElMessage.success('更新文章成功')
|
|
|
|
|
+ // 存储数据并返回true表示成功
|
|
|
|
|
+ article.value = response.data || {}
|
|
|
|
|
+ return true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '更新文章失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('更新文章失败:', error)
|
|
|
|
|
+ ElMessage.error('更新文章失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 删除文章
|
|
|
|
|
+ const deleteArticle = async (id) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.delete(`/news/news/${id}`)
|
|
|
|
|
+ console.log('删除文章原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ ElMessage.success('删除文章成功')
|
|
|
|
|
+ return true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '删除文章失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('删除文章失败:', error)
|
|
|
|
|
+ ElMessage.error('删除文章失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 转换大写字段为小写
|
|
|
|
|
+ function convertKeysToLowerCase(data) {
|
|
|
|
|
+ if (!data) return [];
|
|
|
|
|
+
|
|
|
|
|
+ if (Array.isArray(data)) {
|
|
|
|
|
+ return data.map(item => {
|
|
|
|
|
+ const newItem = {};
|
|
|
|
|
+ Object.keys(item).forEach(key => {
|
|
|
|
|
+ // 处理大写字段名
|
|
|
|
|
+ // 多种情况处理:ID、Id、NAME、Name等
|
|
|
|
|
+ let newKey = key;
|
|
|
|
|
+ if (key === key.toUpperCase()) {
|
|
|
|
|
+ // 全部大写的情况,如ID -> id
|
|
|
|
|
+ newKey = key.toLowerCase();
|
|
|
|
|
+ } else if (key.charAt(0) === key.charAt(0).toUpperCase()) {
|
|
|
|
|
+ // 首字母大写的情况,如Name -> name
|
|
|
|
|
+ newKey = key.charAt(0).toLowerCase() + key.slice(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ newItem[newKey] = item[key];
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 调试日志
|
|
|
|
|
+ if (newItem.id) {
|
|
|
|
|
+ console.log('转换后的分类项:', newItem);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return newItem;
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const newItem = {};
|
|
|
|
|
+ Object.keys(data).forEach(key => {
|
|
|
|
|
+ let newKey = key;
|
|
|
|
|
+ if (key === key.toUpperCase()) {
|
|
|
|
|
+ newKey = key.toLowerCase();
|
|
|
|
|
+ } else if (key.charAt(0) === key.charAt(0).toUpperCase()) {
|
|
|
|
|
+ newKey = key.charAt(0).toLowerCase() + key.slice(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ newItem[newKey] = data[key];
|
|
|
|
|
+ });
|
|
|
|
|
+ return newItem;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取分类列表
|
|
|
|
|
+ const getCategoryList = async () => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.get('/news/category')
|
|
|
|
|
+ console.log('Category API response:', response.data);
|
|
|
|
|
+
|
|
|
|
|
+ // 处理各种可能的响应格式
|
|
|
|
|
+ let categoryData;
|
|
|
|
|
+ if (Array.isArray(response.data)) {
|
|
|
|
|
+ // 直接返回数组
|
|
|
|
|
+ categoryData = response.data;
|
|
|
|
|
+ } else if (response.data && response.data.data && Array.isArray(response.data.data)) {
|
|
|
|
|
+ // 返回 {code, data} 对象
|
|
|
|
|
+ categoryData = response.data.data;
|
|
|
|
|
+ } else if (response.data && response.data.code === 200) {
|
|
|
|
|
+ // 返回 {code, data} 对象
|
|
|
|
|
+ categoryData = response.data.data || [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ categoryData = [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 转换字段名称为小写
|
|
|
|
|
+ const formattedData = convertKeysToLowerCase(categoryData);
|
|
|
|
|
+ console.log('Formatted category data:', formattedData);
|
|
|
|
|
+ categories.value = formattedData;
|
|
|
|
|
+
|
|
|
|
|
+ if (categories.value.length === 0) {
|
|
|
|
|
+ console.log('没有分类数据');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log('分类数据加载成功,数量:', categories.value.length);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取分类列表失败:', error);
|
|
|
|
|
+ ElMessage.error('获取分类列表失败');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取分类详情
|
|
|
|
|
+ const getCategoryDetail = async (id) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { data } = await request.get(`/news/category/${id}`)
|
|
|
|
|
+ if (data.code === 200) {
|
|
|
|
|
+ const formattedData = convertKeysToLowerCase(data.data);
|
|
|
|
|
+ category.value = formattedData;
|
|
|
|
|
+ return formattedData;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(data.msg || '获取分类详情失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取分类详情失败:', error)
|
|
|
|
|
+ ElMessage.error('获取分类详情失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建分类
|
|
|
|
|
+ const createCategory = async (categoryData) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.post('/news/category', categoryData)
|
|
|
|
|
+ console.log('创建分类原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ ElMessage.success('创建分类成功')
|
|
|
|
|
+ const formattedData = convertKeysToLowerCase(response.data);
|
|
|
|
|
+ return formattedData;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '创建分类失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('创建分类失败:', error)
|
|
|
|
|
+ ElMessage.error('创建分类失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新分类
|
|
|
|
|
+ const updateCategory = async (id, categoryData) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.put(`/news/category/${id}`, categoryData)
|
|
|
|
|
+ console.log('更新分类原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ ElMessage.success('更新分类成功')
|
|
|
|
|
+ const formattedData = convertKeysToLowerCase(response.data);
|
|
|
|
|
+ return formattedData;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '更新分类失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('更新分类失败:', error)
|
|
|
|
|
+ ElMessage.error('更新分类失败')
|
|
|
|
|
+ return null
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 删除分类
|
|
|
|
|
+ const deleteCategory = async (id) => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await request.delete(`/news/category/${id}`)
|
|
|
|
|
+ console.log('删除分类原始响应:', response)
|
|
|
|
|
+
|
|
|
|
|
+ // 响应拦截器已经返回了处理后的数据,不需要再访问 .data
|
|
|
|
|
+ if (response && response.code === 200) {
|
|
|
|
|
+ ElMessage.success('删除分类成功')
|
|
|
|
|
+ return true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(response?.msg || '删除分类失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('删除分类失败:', error)
|
|
|
|
|
+ ElMessage.error('删除分类失败')
|
|
|
|
|
+ return false
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ loading,
|
|
|
|
|
+ articles,
|
|
|
|
|
+ article,
|
|
|
|
|
+ categories,
|
|
|
|
|
+ category,
|
|
|
|
|
+ pagination,
|
|
|
|
|
+ getArticleList,
|
|
|
|
|
+ getArticleDetail,
|
|
|
|
|
+ createArticle,
|
|
|
|
|
+ updateArticle,
|
|
|
|
|
+ deleteArticle,
|
|
|
|
|
+ getCategoryList,
|
|
|
|
|
+ getCategoryDetail,
|
|
|
|
|
+ createCategory,
|
|
|
|
|
+ updateCategory,
|
|
|
|
|
+ deleteCategory
|
|
|
|
|
+ }
|
|
|
|
|
+}
|