
21 changed files with 1631 additions and 80 deletions
@ -1,8 +1,7 @@ |
|||
|
|||
VITE_SOCKET_URL=wss://server.gxwebsoft.com |
|||
VITE_SERVER_URL=https://server.gxwebsoft.com/api |
|||
#VITE_API_URL=https://modules.gxwebsoft.com/api |
|||
|
|||
#VITE_API_URL=http://127.0.0.1:9090/api |
|||
VITE_API_URL=http://127.0.0.1:9090/api |
|||
#VITE_SOCKET_URL=ws://localhost:9191 |
|||
VITE_API_URL=http://103.233.255.195:9300/api |
|||
#VITE_API_URL=http://103.233.255.195:9300/api |
|||
|
@ -1,5 +1,5 @@ |
|||
VITE_SERVER_URL=https://server.gxwebsoft.com/api |
|||
VITE_SOCKET_URL=wss://server.gxwebsoft.com |
|||
|
|||
#VITE_API_URL=https://modules.gxwebsoft.com/api |
|||
VITE_API_URL=http://103.233.255.195:9300/api |
|||
VITE_API_URL=https://modules.gxwebsoft.com/api |
|||
#VITE_API_URL=http://103.233.255.195:9300/api |
|||
|
@ -0,0 +1,126 @@ |
|||
import request from '@/utils/request'; |
|||
import type { ApiResult, PageResult } from '@/api'; |
|||
import type { FormRecord, FormRecordParam } from './model'; |
|||
import { MODULES_API_URL } from '@/config/setting'; |
|||
|
|||
/** |
|||
* 分页查询表单设计 |
|||
*/ |
|||
export async function pageFormRecord(params: FormRecordParam) { |
|||
const res = await request.get<ApiResult<PageResult<FormRecord>>>( |
|||
MODULES_API_URL + '/cms/form-record/page', |
|||
{ |
|||
params |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询表单设计列表 |
|||
*/ |
|||
export async function listFormRecord(params?: FormRecordParam) { |
|||
const res = await request.get<ApiResult<FormRecord[]>>( |
|||
MODULES_API_URL + '/cms/form-record', |
|||
{ |
|||
params |
|||
} |
|||
); |
|||
if (res.data.code === 0 && res.data.data) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加表单设计 |
|||
*/ |
|||
export async function addFormRecord(data: FormRecord) { |
|||
const res = await request.post<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form-record', |
|||
data |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改表单设计 |
|||
*/ |
|||
export async function updateFormRecord(data: FormRecord) { |
|||
const res = await request.put<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form-record', |
|||
data |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除表单设计 |
|||
*/ |
|||
export async function removeFormRecord(id?: number) { |
|||
const res = await request.delete<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form-record/' + id |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除表单设计 |
|||
*/ |
|||
export async function removeBatchFormRecord(data: (number | undefined)[]) { |
|||
const res = await request.delete<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form-record/batch', |
|||
{ |
|||
data |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 根据id查询表单设计 |
|||
*/ |
|||
export async function getFormRecord(id: number) { |
|||
const res = await request.get<ApiResult<FormRecord>>( |
|||
MODULES_API_URL + '/cms/form-record/' + id |
|||
); |
|||
if (res.data.code === 0 && res.data.data) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 检查IP是否存在 |
|||
*/ |
|||
export async function checkExistence( |
|||
field: string, |
|||
value: string, |
|||
id?: number |
|||
) { |
|||
const res = await request.get<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form-record/existence', |
|||
{ |
|||
params: { field, value, id } |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
@ -0,0 +1,25 @@ |
|||
import type { PageParam } from '@/api'; |
|||
|
|||
/** |
|||
* 表单数据 |
|||
*/ |
|||
export interface FormRecord { |
|||
formRecordId?: number; |
|||
formId?: number; |
|||
name?: string; |
|||
formData?: string; |
|||
userId?: number; |
|||
sortNumber?: number; |
|||
comments?: string; |
|||
status?: number; |
|||
createTime?: string; |
|||
layout?: string; |
|||
} |
|||
|
|||
/** |
|||
* 搜索条件 |
|||
*/ |
|||
export interface FormRecordParam extends PageParam { |
|||
formRecordId?: string; |
|||
name?: number; |
|||
} |
@ -0,0 +1,143 @@ |
|||
import request from '@/utils/request'; |
|||
import type { ApiResult, PageResult } from '@/api'; |
|||
import type { Form, FormParam } from './model'; |
|||
import { MODULES_API_URL } from '@/config/setting'; |
|||
|
|||
/** |
|||
* 分页查询表单设计 |
|||
*/ |
|||
export async function pageForm(params: FormParam) { |
|||
const res = await request.get<ApiResult<PageResult<Form>>>( |
|||
MODULES_API_URL + '/cms/form/page', |
|||
{ |
|||
params |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询表单设计列表 |
|||
*/ |
|||
export async function listForm(params?: FormParam) { |
|||
const res = await request.get<ApiResult<Form[]>>( |
|||
MODULES_API_URL + '/cms/form', |
|||
{ |
|||
params |
|||
} |
|||
); |
|||
if (res.data.code === 0 && res.data.data) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加表单设计 |
|||
*/ |
|||
export async function addForm(data: Form) { |
|||
const res = await request.post<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form', |
|||
data |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改表单设计 |
|||
*/ |
|||
export async function updateForm(data: Form) { |
|||
const res = await request.put<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form', |
|||
data |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除表单设计 |
|||
*/ |
|||
export async function removeForm(id?: number) { |
|||
const res = await request.delete<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form/' + id |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除表单设计 |
|||
*/ |
|||
export async function removeBatchForm(data: (number | undefined)[]) { |
|||
const res = await request.delete<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form/batch', |
|||
{ |
|||
data |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改用户状态 |
|||
*/ |
|||
export async function updateFormStatus(formId?: number, status?: number) { |
|||
const res = await request.put<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form/status', |
|||
{ |
|||
formId, |
|||
status |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 根据id查询表单设计 |
|||
*/ |
|||
export async function getForm(id: number) { |
|||
const res = await request.get<ApiResult<Form>>( |
|||
MODULES_API_URL + '/cms/form/' + id |
|||
); |
|||
if (res.data.code === 0 && res.data.data) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 检查IP是否存在 |
|||
*/ |
|||
export async function checkExistence( |
|||
field: string, |
|||
value: string, |
|||
id?: number |
|||
) { |
|||
const res = await request.get<ApiResult<unknown>>( |
|||
MODULES_API_URL + '/cms/form/existence', |
|||
{ |
|||
params: { field, value, id } |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
@ -0,0 +1,31 @@ |
|||
import type { PageParam } from '@/api'; |
|||
|
|||
/** |
|||
* 表单设计 |
|||
*/ |
|||
export interface Form { |
|||
formId?: number; |
|||
name?: string; |
|||
photo?: string; |
|||
background?: string; |
|||
submitNumber?: number; |
|||
layout?: any; |
|||
userId?: number; |
|||
sortNumber?: number; |
|||
comments?: string; |
|||
status?: number; |
|||
createTime?: string; |
|||
hidePhoto?: any; |
|||
hideBackground?: number; |
|||
opacity?: number; |
|||
data?: any[]; |
|||
clearCache?: number; |
|||
} |
|||
|
|||
/** |
|||
* 搜索条件 |
|||
*/ |
|||
export interface FormParam extends PageParam { |
|||
formId?: number; |
|||
name?: number; |
|||
} |
@ -0,0 +1,156 @@ |
|||
<template> |
|||
<div class="photo-list-bg" :class="screenWidth > 567 ? 'hidden-sm-and-down' : 'hidden-sm-and-up'"> |
|||
<div class="breadcrumb"> |
|||
<a-breadcrumb> |
|||
<a-breadcrumb-item> |
|||
<a @click="openUrl(`/`)"><HomeOutlined /> 首页</a> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item v-if="form.parentName"> |
|||
<span>{{ form.parentName }}</span> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<span>{{ form.title }}</span> |
|||
</a-breadcrumb-item> |
|||
</a-breadcrumb> |
|||
</div> |
|||
<a-row :gutter="[16,16]" style="padding: 16px"> |
|||
<a-col |
|||
v-for="(item, index) in list" |
|||
:key="index" |
|||
v-bind=" |
|||
styleResponsive |
|||
? { xl: 6, lg: 8, md: 12, sm: 12, xs: 12 } |
|||
: { span: 6 } |
|||
" |
|||
> |
|||
<a-card :bordered="false" hoverable style="margin-top: 16px"> |
|||
<template #cover> |
|||
<a :href="`/a/${item.articleId}`"> |
|||
<a-image |
|||
:src="`${item.image}`" |
|||
:preview="false" |
|||
/> |
|||
</a> |
|||
</template> |
|||
<a-card-meta :title="item.title" @click="openUrl(`/a/${item.articleId}`)"> |
|||
<template #description> |
|||
<div |
|||
class="project-list-desc" |
|||
:title="item.title" |
|||
> |
|||
</div> |
|||
</template> |
|||
</a-card-meta> |
|||
</a-card> |
|||
</a-col> |
|||
</a-row> |
|||
<div class="pagination"> |
|||
<a-pagination v-model:current="currentPage" :total="total" @change="reload" /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import {timeAgo, toDateString} from "ele-admin-pro"; |
|||
import {ref, unref, watch} from "vue"; |
|||
import {Article} from "@/api/cms/article/model"; |
|||
import {pageArticle} from "@/api/cms/article"; |
|||
import {useThemeStore} from "@/store/modules/theme"; |
|||
import {storeToRefs} from "pinia"; |
|||
import { RightOutlined } from '@ant-design/icons-vue'; |
|||
import {useRouter} from "vue-router"; |
|||
import useFormData from "@/utils/use-form-data"; |
|||
import {getArticleCategory, listArticleCategory} from "@/api/cms/category"; |
|||
import {ArticleCategory} from "@/api/cms/category/model"; |
|||
import { HomeOutlined, UserOutlined } from '@ant-design/icons-vue'; |
|||
import {openUrl} from "@/utils/common"; |
|||
|
|||
const { currentRoute } = useRouter(); |
|||
const themeStore = useThemeStore(); |
|||
const { screenWidth, styleResponsive } = storeToRefs(themeStore); |
|||
const list = ref<Article[]>([]); |
|||
const categoryId = ref<number>(0); |
|||
const currentPage = ref(1); |
|||
const total = ref(); |
|||
const selectedKeys = ref<string[]>(['sub1']); |
|||
const subCategoryList = ref<ArticleCategory[]>(); |
|||
const ellipsis = ref<boolean>(true); |
|||
|
|||
// 表单数据 |
|||
const { form,assignFields } = useFormData<ArticleCategory>({ |
|||
categoryId: undefined, |
|||
title: '', |
|||
image: '', |
|||
parentId: undefined, |
|||
parentName: '', |
|||
avatar: '' |
|||
}); |
|||
|
|||
const linkTo = (url: string) => { |
|||
window.location.href = url |
|||
} |
|||
|
|||
const reload = () => { |
|||
getArticleCategory(categoryId.value).then(data => { |
|||
assignFields(data); |
|||
if(data.parentId && data.parentId > 0){ |
|||
listArticleCategory({parentId: data.parentId}).then(list => { |
|||
subCategoryList.value = list |
|||
}) |
|||
} |
|||
}) |
|||
pageArticle({categoryId: categoryId.value,page: currentPage.value}).then(res => { |
|||
if(res?.list){ |
|||
list.value = res.list; |
|||
total.value = res?.count; |
|||
} |
|||
}) |
|||
} |
|||
|
|||
watch( |
|||
currentRoute, |
|||
(route) => { |
|||
const { redirectedFrom } = unref(route); |
|||
if(redirectedFrom){ |
|||
const { params } = redirectedFrom; |
|||
const { id } = params; |
|||
if (id) { |
|||
categoryId.value = Number(id); |
|||
selectedKeys.value = [] |
|||
selectedKeys.value.push(`sub${id}`) |
|||
} |
|||
} |
|||
reload(); |
|||
}, |
|||
{ immediate: true } |
|||
); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
|
|||
.hidden-sm-and-down{ |
|||
width: 1180px; |
|||
.ant-list-sm .ant-list-item{ |
|||
padding: 8px 0; |
|||
} |
|||
} |
|||
.hidden-sm-and-up{ |
|||
width: 100%; |
|||
:deep(.ant-list-sm .ant-list-item){ |
|||
padding: 8px 0; |
|||
} |
|||
:deep(.ant-image img){ |
|||
} |
|||
} |
|||
.photo-list-bg{ |
|||
margin: 0 auto; |
|||
margin-bottom: 20px; |
|||
.breadcrumb{ |
|||
padding-top: 20px; |
|||
padding-left: 5px; |
|||
} |
|||
} |
|||
.pagination{ |
|||
text-align: center; |
|||
padding: 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,233 @@ |
|||
<template> |
|||
<div class="news-list-bg"> |
|||
<div class="news-list" :style="screenWidth > 980 ? 'width: 1180px' : ''"> |
|||
<div class="breadcrumb"> |
|||
<a-breadcrumb> |
|||
<a-breadcrumb-item> |
|||
<a @click="openUrl(`/`)"><HomeOutlined /> Home</a> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item v-if="form.parentName"> |
|||
<span>{{ form.parentName }}</span> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<span>{{ form.title }}</span> |
|||
</a-breadcrumb-item> |
|||
</a-breadcrumb> |
|||
</div> |
|||
<template v-if="form.parentId > 0"> |
|||
<a-row :gutter="[16,16]"> |
|||
<a-col :xl="5" :lg="12" :md="12" :sm="24"> |
|||
<a-menu v-model:selectedKeys="selectedKeys"> |
|||
<a-menu-item v-for="(item,index) in subCategoryList" :key="`sub${item.categoryId}`" @click="linkTo(`/article/${item.categoryId}`)"> |
|||
{{ item.title }} |
|||
</a-menu-item> |
|||
</a-menu> |
|||
</a-col> |
|||
<a-col :xl="19" :lg="12" :md="12" :sm="24"> |
|||
<template v-if="list"> |
|||
<a-card :title="form.title"> |
|||
<a-list :size="`small`" :data-source="list" style="padding: 0px"> |
|||
<template #renderItem="{ item }"> |
|||
<a-list-item key="item.title"> |
|||
<a-list-item-meta> |
|||
<template #title> |
|||
<div class="title-box"> |
|||
<a class="title-text" :href="`/article/detail/${item.articleId}`">{{ item.title }}</a> |
|||
<div class="ele-text-secondary">{{ item.comments }}</div> |
|||
<div class="actions ele-text-placeholder"> |
|||
<a-space :size="20"> |
|||
<span>浏览 {{ item.likes }}</span> |
|||
<span>{{ toDateString(item.createTime, 'YYYY-MM-dd')}}</span> |
|||
</a-space> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<template #avatar> |
|||
<a-image :src="item.image" :preview="false" /> |
|||
</template> |
|||
</a-list-item-meta> |
|||
</a-list-item> |
|||
</template> |
|||
</a-list> |
|||
</a-card> |
|||
<div class="pagination"> |
|||
<a-pagination v-model:current="currentPage" :total="total" @change="reload" /> |
|||
</div> |
|||
</template> |
|||
</a-col> |
|||
</a-row> |
|||
</template> |
|||
<template v-else> |
|||
<a-card :title="form.title"> |
|||
<a-list :size="`small`" :data-source="list" style="padding: 0px"> |
|||
<template #renderItem="{ item }"> |
|||
<a-list-item key="item.title"> |
|||
<a-list-item-meta> |
|||
<template #title> |
|||
<div class="ele-cell" v-if="item.files.length > 0"> |
|||
<a class="ele-cell-content" target="_blank" :href="`${item.files[0].url}`">{{ item.files[0].name }}</a> |
|||
<div class="actions ele-text-placeholder"> |
|||
{{ toDateString(item.createTime, 'YYYY-MM-dd')}} |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<template #avatar> |
|||
<a-image :src="item.image" :preview="false" /> |
|||
</template> |
|||
</a-list-item-meta> |
|||
</a-list-item> |
|||
</template> |
|||
</a-list> |
|||
</a-card> |
|||
<div class="pagination"> |
|||
<a-pagination v-model:current="currentPage" :total="total" @change="reload" /> |
|||
</div> |
|||
</template> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import {toDateString} from "ele-admin-pro"; |
|||
import {ref, unref, watch} from "vue"; |
|||
import {Article} from "@/api/cms/article/model"; |
|||
import {pageArticle} from "@/api/cms/article"; |
|||
import {useThemeStore} from "@/store/modules/theme"; |
|||
import {storeToRefs} from "pinia"; |
|||
import {getAd} from "@/api/cms/ad"; |
|||
import { RightOutlined } from '@ant-design/icons-vue'; |
|||
import {useRouter} from "vue-router"; |
|||
import useFormData from "@/utils/use-form-data"; |
|||
import {getArticleCategory, listArticleCategory} from "@/api/cms/category"; |
|||
import {ArticleCategory} from "@/api/cms/category/model"; |
|||
import { HomeOutlined, UserOutlined } from '@ant-design/icons-vue'; |
|||
import {openUrl} from "@/utils/common"; |
|||
|
|||
const { currentRoute } = useRouter(); |
|||
const themeStore = useThemeStore(); |
|||
const { screenWidth, styleResponsive } = storeToRefs(themeStore); |
|||
const list = ref<Article[]>([]); |
|||
const newsBg3 = ref(''); |
|||
const categoryId = ref<number>(0); |
|||
const currentPage = ref(1); |
|||
const total = ref(); |
|||
const selectedKeys = ref<string[]>(['sub1']); |
|||
const subCategoryList = ref<ArticleCategory[]>(); |
|||
|
|||
// 表单数据 |
|||
const { form,assignFields } = useFormData<ArticleCategory>({ |
|||
categoryId: undefined, |
|||
title: '', |
|||
image: '', |
|||
parentId: undefined, |
|||
parentName: '', |
|||
avatar: '' |
|||
}); |
|||
|
|||
const linkTo = (url: string) => { |
|||
window.location.href = url |
|||
} |
|||
|
|||
const reload = () => { |
|||
getArticleCategory(categoryId.value).then(data => { |
|||
assignFields(data); |
|||
if(data.parentId && data.parentId > 0){ |
|||
listArticleCategory({parentId: data.parentId}).then(list => { |
|||
subCategoryList.value = list |
|||
}) |
|||
} |
|||
}) |
|||
pageArticle({categoryId: categoryId.value,page: currentPage.value}).then(res => { |
|||
if(res?.list){ |
|||
list.value = res.list.map(d => { |
|||
if(d.files){ |
|||
d.files = JSON.parse(d.files); |
|||
} |
|||
return d |
|||
}); |
|||
total.value = res?.count; |
|||
} |
|||
}) |
|||
} |
|||
|
|||
watch( |
|||
currentRoute, |
|||
(route) => { |
|||
const { redirectedFrom } = unref(route); |
|||
if(redirectedFrom){ |
|||
const { params } = redirectedFrom; |
|||
const { id } = params; |
|||
if (id) { |
|||
categoryId.value = Number(id); |
|||
selectedKeys.value = [] |
|||
selectedKeys.value.push(`sub${id}`) |
|||
} |
|||
} |
|||
reload(); |
|||
}, |
|||
{ immediate: true } |
|||
); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.news-list-bg{ |
|||
padding-bottom: 70px; |
|||
.news-list{ |
|||
.breadcrumb{ |
|||
padding-bottom: 20px; |
|||
padding-left: 5px; |
|||
} |
|||
margin: 0 auto; |
|||
padding: 20px 0; |
|||
.title{ |
|||
margin-top: 10px; |
|||
padding-bottom: 20px; |
|||
display: flex; |
|||
align-items: center; |
|||
h4{ |
|||
color: #ffffff; |
|||
font-weight: 500; |
|||
font-size: 26px; |
|||
} |
|||
.title-bar{ |
|||
width: 6px; |
|||
height: 28px; |
|||
margin-right: 14px; |
|||
background: linear-gradient(to bottom, #b7a381, #e5cc8c); |
|||
} |
|||
} |
|||
.img-list{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding-bottom: 30px; |
|||
} |
|||
} |
|||
.title-box{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
height: 120px; |
|||
.title-text { |
|||
font-weight: bold; font-size: 16px; |
|||
color: #333333; |
|||
} |
|||
.title-text:hover{ |
|||
color: #ff0000; |
|||
} |
|||
.desc{ |
|||
font-size: 14px; |
|||
} |
|||
.actions{ |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
} |
|||
.pagination{ |
|||
text-align: center; |
|||
padding: 20px; |
|||
} |
|||
:deep(.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected){ |
|||
background-color: #ffffff; |
|||
color: #999999; |
|||
border-bottom: 2px solid #fff1de; |
|||
} |
|||
</style> |
@ -0,0 +1,150 @@ |
|||
<template> |
|||
<div class="news-list-bg"> |
|||
<div class="news-list" :style="screenWidth > 980 ? 'width: 1180px' : ''"> |
|||
<div class="breadcrumb"> |
|||
<a-breadcrumb> |
|||
<a-breadcrumb-item> |
|||
<a @click="openUrl(`/`)"><HomeOutlined /> Home</a> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<a :href="`/article/${form.categoryId}`">{{ form.categoryName }}</a> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<span>{{ form.title }}</span> |
|||
</a-breadcrumb-item> |
|||
</a-breadcrumb> |
|||
</div> |
|||
<a-card :title="form.title"> |
|||
<div v-html="form.content"></div> |
|||
</a-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import {toDateString} from "ele-admin-pro"; |
|||
import {ref, unref, watch} from "vue"; |
|||
import {Article} from "@/api/cms/article/model"; |
|||
import {pageArticle,getArticle} from "@/api/cms/article"; |
|||
import {useThemeStore} from "@/store/modules/theme"; |
|||
import {storeToRefs} from "pinia"; |
|||
import {getAd} from "@/api/cms/ad"; |
|||
import { RightOutlined } from '@ant-design/icons-vue'; |
|||
import {useRouter} from "vue-router"; |
|||
import useFormData from "@/utils/use-form-data"; |
|||
import {getArticleCategory, listArticleCategory} from "@/api/cms/category"; |
|||
import {ArticleCategory} from "@/api/cms/category/model"; |
|||
import { HomeOutlined, UserOutlined } from '@ant-design/icons-vue'; |
|||
import {openUrl} from "@/utils/common"; |
|||
|
|||
const { currentRoute } = useRouter(); |
|||
const themeStore = useThemeStore(); |
|||
const { screenWidth, styleResponsive } = storeToRefs(themeStore); |
|||
const list = ref<Article[]>([]); |
|||
const activeKey = ref('1'); |
|||
const newsBg3 = ref(''); |
|||
const articleId = ref<number>(0); |
|||
const currentPage = ref(1); |
|||
const total = ref(); |
|||
|
|||
// 表单数据 |
|||
const { form,assignFields } = useFormData<Article>({ |
|||
categoryId: undefined, |
|||
categoryName: '', |
|||
title: '', |
|||
image: '', |
|||
content: '', |
|||
parentId: undefined, |
|||
parentName: '', |
|||
source: '', |
|||
virtualViews: undefined, |
|||
actualViews: undefined |
|||
}); |
|||
|
|||
// getAd(253).then(data => { |
|||
// const { images } = data; |
|||
// if(images){ |
|||
// newsBg3.value = JSON.parse(images)[0].url; |
|||
// } |
|||
// }) |
|||
|
|||
const reload = () => { |
|||
// getArticleCategory(categoryId.value).then(data => { |
|||
// assignFields(data); |
|||
// }) |
|||
getArticle(articleId.value).then(data => { |
|||
assignFields(data) |
|||
}) |
|||
} |
|||
|
|||
watch( |
|||
currentRoute, |
|||
(route) => { |
|||
const { params } = unref(route); |
|||
const { id } = params; |
|||
if (id) { |
|||
articleId.value = Number(id); |
|||
} |
|||
reload(); |
|||
}, |
|||
{ immediate: true } |
|||
); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.news-list-bg{ |
|||
padding-bottom: 70px; |
|||
.news-list{ |
|||
.breadcrumb{ |
|||
padding-bottom: 20px; |
|||
padding-left: 5px; |
|||
} |
|||
margin: 0 auto; |
|||
padding: 20px 0; |
|||
.title{ |
|||
margin-top: 10px; |
|||
padding-bottom: 20px; |
|||
display: flex; |
|||
align-items: center; |
|||
h4{ |
|||
color: #ffffff; |
|||
font-weight: 500; |
|||
font-size: 26px; |
|||
} |
|||
.title-bar{ |
|||
width: 6px; |
|||
height: 28px; |
|||
margin-right: 14px; |
|||
background: linear-gradient(to bottom, #b7a381, #e5cc8c); |
|||
} |
|||
} |
|||
.img-list{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding-bottom: 30px; |
|||
} |
|||
} |
|||
.title-box{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
height: 120px; |
|||
.title-text { |
|||
font-weight: bold; font-size: 16px; |
|||
color: #333333; |
|||
} |
|||
.title-text:hover{ |
|||
color: #ff0000; |
|||
} |
|||
.desc{ |
|||
font-size: 14px; |
|||
} |
|||
.actions{ |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
} |
|||
.pagination{ |
|||
text-align: center; |
|||
padding: 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<a-layout> |
|||
<Header /> |
|||
<Banner /> |
|||
<a-layout-content> |
|||
<NewsDetail /> |
|||
</a-layout-content> |
|||
<Footer /> |
|||
</a-layout> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import Banner from "@/components/Banner/index.vue"; |
|||
import NewsDetail from "./components/news-detail.vue"; |
|||
</script> |
|||
|
|||
<script lang="ts"> |
|||
export default { |
|||
name: 'ArticleDetail' |
|||
}; |
|||
</script> |
|||
<style lang="less"> |
|||
|
|||
</style> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<a-layout> |
|||
<Banner /> |
|||
<Header /> |
|||
<a-layout-content> |
|||
<List /> |
|||
</a-layout-content> |
|||
<Footer /> |
|||
</a-layout> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import Banner from "@/components/Banner/index.vue"; |
|||
import List from "./components/list.vue"; |
|||
</script> |
|||
|
|||
<script lang="ts"> |
|||
export default { |
|||
name: 'DownIndex' |
|||
}; |
|||
</script> |
|||
<style lang="less"> |
|||
|
|||
</style> |
@ -0,0 +1,195 @@ |
|||
<template> |
|||
<div class="news-list-bg"> |
|||
<div class="news-list" :style="screenWidth > 980 ? 'width: 1180px' : ''"> |
|||
<div class="breadcrumb"> |
|||
<a-breadcrumb> |
|||
<a-breadcrumb-item> |
|||
<HomeOutlined @click="openUrl(`/`)" /> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<a :href="`/article/parent/${form.parentId}`">{{ form.parentName }}</a> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<span>{{ form.title }}</span> |
|||
</a-breadcrumb-item> |
|||
</a-breadcrumb> |
|||
</div> |
|||
{{ form }} |
|||
<a-card :title="form.title"> |
|||
<a-list :size="`small`" :data-source="list" style="padding: 0px"> |
|||
<template #renderItem="{ item }"> |
|||
<a-list-item key="item.title"> |
|||
<a-list-item-meta> |
|||
<template #title> |
|||
<div class="title-box"> |
|||
<a class="title-text" :href="`/article/detail/${item.articleId}`">{{ item.title }}</a> |
|||
<div class="ele-text-secondary">{{ item.comments }}</div> |
|||
<div class="actions ele-text-placeholder"> |
|||
<a-space :size="20"> |
|||
<span>浏览 {{ item.likes }}</span> |
|||
<span>{{ toDateString(item.createTime, 'YYYY-MM-dd')}}</span> |
|||
</a-space> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<template #avatar> |
|||
<a-image :src="item.image" :preview="false" /> |
|||
</template> |
|||
</a-list-item-meta> |
|||
</a-list-item> |
|||
</template> |
|||
</a-list> |
|||
</a-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import {toDateString} from "ele-admin-pro"; |
|||
import {ref, unref, watch} from "vue"; |
|||
import {Article} from "@/api/cms/article/model"; |
|||
import {pageArticle} from "@/api/cms/article"; |
|||
import {useThemeStore} from "@/store/modules/theme"; |
|||
import {storeToRefs} from "pinia"; |
|||
import {getAd} from "@/api/cms/ad"; |
|||
import { RightOutlined } from '@ant-design/icons-vue'; |
|||
import {useRouter} from "vue-router"; |
|||
import useFormData from "@/utils/use-form-data"; |
|||
import {getArticleCategory, listArticleCategory} from "@/api/cms/category"; |
|||
import {ArticleCategory} from "@/api/cms/category/model"; |
|||
import { HomeOutlined, UserOutlined } from '@ant-design/icons-vue'; |
|||
import {openUrl} from "@/utils/common"; |
|||
|
|||
const { currentRoute } = useRouter(); |
|||
const themeStore = useThemeStore(); |
|||
const { screenWidth, styleResponsive } = storeToRefs(themeStore); |
|||
const list = ref<Article[]>([]); |
|||
const activeKey = ref('1'); |
|||
const newsBg3 = ref(''); |
|||
const categoryId = ref<number>(0); |
|||
|
|||
const routes = [ |
|||
{ |
|||
path: '首页', |
|||
breadcrumbName: 'First-level Menu', |
|||
}, |
|||
{ |
|||
path: 'first', |
|||
breadcrumbName: 'Second-level Menu', |
|||
}, |
|||
{ |
|||
path: 'second', |
|||
breadcrumbName: 'Third-level Menu', |
|||
}, |
|||
]; |
|||
|
|||
// 表单数据 |
|||
const { form,assignFields } = useFormData<ArticleCategory>({ |
|||
categoryId: undefined, |
|||
title: '', |
|||
image: '', |
|||
parentId: undefined, |
|||
parentName: '', |
|||
avatar: '' |
|||
}); |
|||
|
|||
getAd(253).then(data => { |
|||
const { images } = data; |
|||
if(images){ |
|||
newsBg3.value = JSON.parse(images)[0].url; |
|||
} |
|||
}) |
|||
|
|||
const reload = () => { |
|||
getArticleCategory(categoryId.value).then(data => { |
|||
console.log(data) |
|||
assignFields(data); |
|||
console.log(form) |
|||
routes.push({ |
|||
path: '', |
|||
breadcrumbName: '' |
|||
}) |
|||
}) |
|||
pageArticle({categoryId: categoryId.value}).then(res => { |
|||
if(res?.list){ |
|||
list.value = res.list; |
|||
} |
|||
}) |
|||
} |
|||
|
|||
watch( |
|||
currentRoute, |
|||
(route) => { |
|||
const { params } = unref(route); |
|||
const { id } = params; |
|||
if (id) { |
|||
categoryId.value = Number(id); |
|||
} |
|||
reload(); |
|||
}, |
|||
{ immediate: true } |
|||
); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.news-list-bg{ |
|||
padding-bottom: 70px; |
|||
.news-list{ |
|||
.breadcrumb{ |
|||
padding-bottom: 20px; |
|||
padding-left: 5px; |
|||
} |
|||
margin: 0 auto; |
|||
padding: 20px 0; |
|||
.title{ |
|||
margin-top: 10px; |
|||
padding-bottom: 20px; |
|||
display: flex; |
|||
align-items: center; |
|||
h4{ |
|||
color: #ffffff; |
|||
font-weight: 500; |
|||
font-size: 26px; |
|||
} |
|||
.title-bar{ |
|||
width: 6px; |
|||
height: 28px; |
|||
margin-right: 14px; |
|||
background: linear-gradient(to bottom, #b7a381, #e5cc8c); |
|||
} |
|||
} |
|||
.img-list{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding-bottom: 30px; |
|||
} |
|||
} |
|||
.title-box{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
height: 120px; |
|||
.title-text { |
|||
font-weight: bold; font-size: 16px; |
|||
color: #333333; |
|||
} |
|||
.title-text:hover{ |
|||
color: #ff0000; |
|||
} |
|||
.desc{ |
|||
font-size: 14px; |
|||
} |
|||
.actions{ |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
} |
|||
.ant-list-sm .ant-list-item{ |
|||
padding: 8px 0 !important; |
|||
} |
|||
.ant-tabs-nav-list .ant-tabs-tab{ |
|||
background-color: #ff0000 !important; |
|||
} |
|||
.ant-tabs-nav-list .ant-tabs-tab-active{ |
|||
background-color: #ff00fe !important; |
|||
} |
|||
</style> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<a-layout> |
|||
<Header /> |
|||
<Banner /> |
|||
<a-layout-content> |
|||
<NewsList /> |
|||
</a-layout-content> |
|||
<Footer /> |
|||
</a-layout> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import Banner from "@/components/Banner/index.vue"; |
|||
import NewsList from "./components/news-list.vue"; |
|||
</script> |
|||
|
|||
<script lang="ts"> |
|||
export default { |
|||
name: 'ArticleIndex' |
|||
}; |
|||
</script> |
|||
<style lang="less"> |
|||
|
|||
</style> |
@ -0,0 +1,377 @@ |
|||
<template> |
|||
<div class="news-list-bg" v-if="formInfo"> |
|||
<div class="news-list" :style="screenWidth > 980 ? 'width: 1180px' : ''"> |
|||
<div class="breadcrumb"> |
|||
<a-breadcrumb> |
|||
<a-breadcrumb-item> |
|||
<a @click="openUrl(`/`)"><HomeOutlined /> Home</a> |
|||
</a-breadcrumb-item> |
|||
<a-breadcrumb-item> |
|||
<span>{{ formInfo.name }}</span> |
|||
</a-breadcrumb-item> |
|||
</a-breadcrumb> |
|||
</div> |
|||
<a-space direction="vertical"> |
|||
<div>{{ form }}</div> |
|||
<a-divider /> |
|||
<div>{{ rules }}</div> |
|||
</a-space> |
|||
<a-card :title="formInfo.name" :bordered="false" hoverable :head-style="{ backgroundColor: '#e0f0fd', color: '#0096FF', fontSize: '24px'}" :style="{ boxShadow: '2px 0px 10px #ccc', marginBottom: '20px'}"> |
|||
<a-form ref="formRef" |
|||
:model="form" |
|||
:rules="rules" |
|||
labelAlign="left" |
|||
:label-col="styleResponsive ? { md: 3, sm: 5, xs: 24 } : { flex: '90px' }" |
|||
:wrapper-col=" |
|||
styleResponsive ? { md: 12, sm: 19, xs: 24 } : { flex: '1' } |
|||
"> |
|||
<template v-for="(item, index) in formInfo.layout" :key="index"> |
|||
<a-form-item v-if="item.name" :name="item.name"> |
|||
<template #label> |
|||
<a-space> |
|||
<span>{{ item.name }}</span> |
|||
</a-space> |
|||
</template> |
|||
<template v-if="item.type == 'text'"> |
|||
<a-input |
|||
allow-clear |
|||
:maxlength="200" |
|||
v-model:value="form[item.name]" |
|||
:placeholder="`${ |
|||
item.placeholder ? `请填写${item.name}` : '请输入' |
|||
}`" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'textarea'"> |
|||
<a-textarea |
|||
:rows="4" |
|||
:maxlength="200" |
|||
show-count |
|||
:placeholder="`请输入${item.name}`" |
|||
v-model:value="form[item.name]" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'radio'"> |
|||
<a-radio-group v-model:value="form[item.name]"> |
|||
<template |
|||
v-for="(radio, radioIndex) in item.options" |
|||
:key="radioIndex" |
|||
> |
|||
<a-radio :value="radio">{{ radio }}</a-radio> |
|||
</template> |
|||
</a-radio-group> |
|||
</template> |
|||
<template v-if="item.type == 'checkbox'"> |
|||
<a-checkbox-group |
|||
v-model:value="item.checkedList" |
|||
:options="item.options" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'phone'"> |
|||
<a-input |
|||
allow-clear |
|||
:maxlength="11" |
|||
:placeholder="`${ |
|||
item.placeholder ? `请填写${item.name}` : '请输入' |
|||
}`" |
|||
v-model:value="form[item.name]" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'email'"> |
|||
<a-input |
|||
allow-clear |
|||
:maxlength="30" |
|||
:placeholder="`${ |
|||
item.placeholder ? `请填写${item.name}` : '请输入' |
|||
}`" |
|||
v-model:value="form[item.name]" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'time'"> |
|||
<a-time-picker |
|||
v-model:value="timeItem" |
|||
format="HH:mm" |
|||
@change="onTimeItem(index)" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'date'"> |
|||
<a-date-picker |
|||
v-model:value="item.value" |
|||
value-format="YYYY-MM-DD" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'image'"> |
|||
<ele-image-upload |
|||
v-model:value="imageItem" |
|||
:limit="1" |
|||
:upload-handler="uploadHandlerItem" |
|||
@click="onClickItem(index)" |
|||
@upload="onUploadItem" |
|||
/> |
|||
</template> |
|||
<template v-if="item.type == 'video'"></template> |
|||
</a-form-item> |
|||
</template> |
|||
<a-form-item label="操作"> |
|||
<div class="submit-btn"> |
|||
<a-button type="primary" size="large" @click="save">提交</a-button> |
|||
</div> |
|||
</a-form-item> |
|||
</a-form> |
|||
</a-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import {toDateString} from "ele-admin-pro"; |
|||
import {reactive, ref, unref, watch} from "vue"; |
|||
import { getForm } from '@/api/cms/form'; |
|||
import { addFormRecord } from '@/api/cms/form-record'; |
|||
import {useThemeStore} from "@/store/modules/theme"; |
|||
import {storeToRefs} from "pinia"; |
|||
import {useRouter} from "vue-router"; |
|||
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types'; |
|||
import useFormData from "@/utils/use-form-data"; |
|||
import { HomeOutlined, UserOutlined } from '@ant-design/icons-vue'; |
|||
import {openUrl} from "@/utils/common"; |
|||
import {FormInstance} from "ant-design-vue/es/form"; |
|||
import {message} from "ant-design-vue"; |
|||
import {Dayjs} from "dayjs"; |
|||
import {uploadFile} from "@/api/system/file"; |
|||
|
|||
|
|||
const formData = ref<any[]>([ |
|||
{ id: 1, type: 'text', name: '姓名', checked: true }, |
|||
{ id: 2, type: 'phone', name: '手机号码', checked: true }, |
|||
{ id: 3, type: 'date', name: '日期', checked: false } |
|||
]); |
|||
|
|||
// 表格选中数据 |
|||
const formRef = ref<FormInstance | null>(null); |
|||
const { currentRoute } = useRouter(); |
|||
const themeStore = useThemeStore(); |
|||
const { screenWidth, styleResponsive } = storeToRefs(themeStore); |
|||
const formId = ref<number>(268); |
|||
const total = ref(); |
|||
const formInfo = ref<any>(); |
|||
// 时间 |
|||
const timeItem = ref<Dayjs>(); |
|||
// 表单数据里的图片 |
|||
const imageItem = ref<ItemType[]>([]); |
|||
const currentItemIndex = ref<number>(0); |
|||
const formRules = ref<any>({}); |
|||
|
|||
// 表单数据 |
|||
const { form,assignFields,resetFields } = useFormData<any>({}); |
|||
|
|||
const onTimeItem = (index: number) => { |
|||
formData.value[index].value = toDateString(timeItem.value, 'HH:mm'); |
|||
}; |
|||
|
|||
const onClickItem = (index: number) => { |
|||
currentItemIndex.value = index; |
|||
}; |
|||
|
|||
const reload = () => { |
|||
getForm(formId.value).then(data => { |
|||
data.layout = JSON.parse(data.layout) |
|||
formInfo.value = data; |
|||
resetFields(); |
|||
// 表单初始化 |
|||
data.layout.map(d => { |
|||
console.log(d) |
|||
let item2 = {} |
|||
item2[d.name] = '' |
|||
Object.assign(form,item2) |
|||
}) |
|||
// 表单验证规则 |
|||
data.layout.filter(d => d.checked == true).map(d => { |
|||
let item = {} |
|||
item[d.name] = [{ |
|||
"required": true, |
|||
"type": 'string', |
|||
"message": `请填写${d.name}`, |
|||
"trigger": 'blur' |
|||
}] |
|||
Object.assign(rules,item) |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
const rules = reactive({}); |
|||
|
|||
const onSelect = (item: any, index: number) => { |
|||
if (item.type == 'checkbox') { |
|||
formData.value[index].checkedList = ['aaa']; |
|||
formData.value[index].options = ['aaa', 'bbb']; |
|||
} |
|||
if (item.type == 'radio') { |
|||
formData.value[index].radio = 'A'; |
|||
formData.value[index].options = ['A', 'B', 'C', 'D']; |
|||
} |
|||
}; |
|||
|
|||
/* 上传事件 */ |
|||
const uploadHandlerItem = (file: File) => { |
|||
const item: ItemType = { |
|||
file, |
|||
uid: (file as any).uid, |
|||
name: file.name |
|||
}; |
|||
if (file.type.startsWith('video')) { |
|||
if (file.size / 1024 / 1024 > 200) { |
|||
message.error('大小不能超过 200MB'); |
|||
return; |
|||
} |
|||
} |
|||
if (file.type.startsWith('image')) { |
|||
if (file.size / 1024 / 1024 > 5) { |
|||
message.error('大小不能超过 5MB'); |
|||
return; |
|||
} |
|||
} |
|||
onUploadItem(item); |
|||
}; |
|||
|
|||
const onUploadItem = (item: any) => { |
|||
const { file } = item; |
|||
if (currentItemIndex.value > 0) { |
|||
uploadFile(file) |
|||
.then((data) => { |
|||
// console.log(data); |
|||
// console.log(formData.value[currentItemIndex.value]) |
|||
formData.value[currentItemIndex.value].image = data.path; |
|||
imageItem.value.push({ |
|||
uid: data.id, |
|||
url: data.path, |
|||
status: 'done' |
|||
}); |
|||
currentItemIndex.value = 0; |
|||
}) |
|||
.catch((e) => { |
|||
message.error(e.message); |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
const objToArray = (obj) => { |
|||
return Object.keys(obj).map((key) => { |
|||
return { |
|||
name: key, |
|||
value: obj[key] |
|||
} |
|||
}); |
|||
} |
|||
|
|||
|
|||
/* 保存编辑 */ |
|||
const save = () => { |
|||
if (!formRef.value) { |
|||
return; |
|||
} |
|||
formRef.value |
|||
.validate() |
|||
.then(() => { |
|||
const saveData = { |
|||
formId: 268, |
|||
formData: JSON.stringify(objToArray(form)) |
|||
}; |
|||
addFormRecord(saveData) |
|||
.then((msg) => { |
|||
message.success(msg); |
|||
reload(); |
|||
}) |
|||
.catch((e) => { |
|||
message.error(e.message); |
|||
}); |
|||
}) |
|||
.catch(() => {}); |
|||
}; |
|||
|
|||
|
|||
watch( |
|||
currentRoute, |
|||
(route) => { |
|||
console.log(route) |
|||
const { params } = unref(route); |
|||
const { id } = params; |
|||
if (id) { |
|||
formId.value = Number(id); |
|||
} |
|||
reload(); |
|||
}, |
|||
{ immediate: true } |
|||
); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.news-list-bg{ |
|||
padding-bottom: 70px; |
|||
.news-list{ |
|||
.breadcrumb{ |
|||
padding-bottom: 20px; |
|||
padding-left: 5px; |
|||
} |
|||
margin: 0 auto; |
|||
padding: 20px 0; |
|||
.title{ |
|||
margin-top: 10px; |
|||
padding-bottom: 20px; |
|||
display: flex; |
|||
align-items: center; |
|||
h4{ |
|||
color: #ffffff; |
|||
font-weight: 500; |
|||
font-size: 26px; |
|||
} |
|||
.title-bar{ |
|||
width: 6px; |
|||
height: 28px; |
|||
margin-right: 14px; |
|||
background: linear-gradient(to bottom, #b7a381, #e5cc8c); |
|||
} |
|||
} |
|||
.img-list{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding-bottom: 30px; |
|||
} |
|||
} |
|||
.title-box{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
height: 120px; |
|||
.title-text { |
|||
font-weight: bold; font-size: 16px; |
|||
color: #333333; |
|||
} |
|||
.title-text:hover{ |
|||
color: #ff0000; |
|||
} |
|||
.desc{ |
|||
font-size: 14px; |
|||
} |
|||
.actions{ |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
} |
|||
.pagination{ |
|||
text-align: center; |
|||
padding: 20px; |
|||
} |
|||
|
|||
.ele-text-secondary{ |
|||
font-size: 16px; |
|||
} |
|||
.ele-text-heading{ |
|||
line-height: 1.6em; |
|||
font-size: 16px; |
|||
} |
|||
.line-height-d5{ |
|||
p{ |
|||
line-height: .7; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<a-layout> |
|||
<Banner /> |
|||
<Header /> |
|||
<a-layout-content> |
|||
<Detail /> |
|||
</a-layout-content> |
|||
<Footer /> |
|||
</a-layout> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import Banner from "@/components/Banner/index.vue"; |
|||
import Detail from "./components/detail.vue"; |
|||
</script> |
|||
|
|||
<script lang="ts"> |
|||
export default { |
|||
name: 'Form' |
|||
}; |
|||
</script> |
|||
<style lang="less"> |
|||
|
|||
</style> |
Loading…
Reference in new issue