feat: wx news init
							parent
							
								
									d6cd366c12
								
							
						
					
					
						commit
						e9a7b476aa
					
				|  | @ -72,11 +72,12 @@ import { computed, onMounted, ref } from 'vue' | |||
| import { EditOutlined, EllipsisOutlined, RedoOutlined, TableOutlined } from '@ant-design/icons-vue' | ||||
| import { List, Card, Image, Typography, Tooltip, Slider, Avatar } from 'ant-design-vue' | ||||
| import { Dropdown } from '@/components/Dropdown' | ||||
| import { BasicForm, useForm } from '@/components/Form' | ||||
| import { BasicForm, useForm, FormSchema } from '@/components/Form' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { Button } from '@/components/Button' | ||||
| import { isFunction } from '@/utils/is' | ||||
| import { useSlider, grid } from './data' | ||||
| 
 | ||||
| const ListItem = List.Item | ||||
| const CardMeta = Card.Meta | ||||
| const TypographyText = Typography.Text | ||||
|  | @ -87,7 +88,10 @@ const props = defineProps({ | |||
|   // 请求API的参数 | ||||
|   params: propTypes.object.def({}), | ||||
|   //api | ||||
|   api: propTypes.func | ||||
|   api: propTypes.func, | ||||
|   searchSchema: { | ||||
|     type: Array | ||||
|   } | ||||
| }) | ||||
| //暴露内部方法 | ||||
| const emit = defineEmits(['getMethod', 'delete']) | ||||
|  | @ -102,7 +106,7 @@ const height = computed(() => { | |||
| }) | ||||
| //表单 | ||||
| const [registerForm, { validate }] = useForm({ | ||||
|   schemas: [{ field: 'type', component: 'Input', label: '类型' }], | ||||
|   schemas: props.searchSchema as FormSchema[], | ||||
|   labelWidth: 80, | ||||
|   baseColProps: { span: 6 }, | ||||
|   actionColOptions: { span: 24 }, | ||||
|  | @ -129,7 +133,7 @@ async function fetch(p = {}) { | |||
|   const { api, params } = props | ||||
|   if (api && isFunction(api)) { | ||||
|     const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p }) | ||||
|     data.value = res.items | ||||
|     data.value = res.list | ||||
|     total.value = res.total | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,150 @@ | |||
| <template> | ||||
|   <div class="p-2"> | ||||
|     <div class="p-4 mb-2 bg-white"> | ||||
|       <BasicForm @register="registerForm" /> | ||||
|     </div> | ||||
|     <div class="p-2 bg-white"> | ||||
|       <List :grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }" :data-source="data" :pagination="paginationProp"> | ||||
|         <template #header> | ||||
|           <div class="flex justify-end space-x-2"> | ||||
|             <slot name="header"></slot> | ||||
|             <Tooltip> | ||||
|               <template #title> | ||||
|                 <div class="w-50">每行显示数量</div> | ||||
|                 <Slider id="slider" v-bind="sliderProp" v-model:value="grid" @change="sliderChange" /> | ||||
|               </template> | ||||
|               <a-button><TableOutlined /></a-button> | ||||
|             </Tooltip> | ||||
|             <Tooltip @click="fetch"> | ||||
|               <template #title>刷新</template> | ||||
|               <a-button><RedoOutlined /></a-button> | ||||
|             </Tooltip> | ||||
|           </div> | ||||
|         </template> | ||||
|         <template #renderItem="{ item }"> | ||||
|           <ListItem> | ||||
|             <Card> | ||||
|               <template #title>{{ item.content.newsItem[0].title }}</template> | ||||
|               <template #cover> | ||||
|                 <div :class="height"> | ||||
|                   <Image :src="item.content.newsItem[0].thumbUrl" /> | ||||
|                 </div> | ||||
|               </template> | ||||
|               <template #actions> | ||||
|                 <Icon icon="ant-design:delete-outlined" @click="handleDelete.bind(null, item.id)" /> | ||||
|               </template> | ||||
| 
 | ||||
|               <CardMeta> | ||||
|                 <template #title> | ||||
|                   <TypographyText :content="item.name" :ellipsis="{ tooltip: item.address }" /> | ||||
|                 </template> | ||||
|                 <template #avatar> | ||||
|                   <Avatar :src="item.avatar" /> | ||||
|                 </template> | ||||
|                 <template #description>{{ item.time }}</template> | ||||
|               </CardMeta> | ||||
|             </Card> | ||||
|           </ListItem> | ||||
|         </template> | ||||
|       </List> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { computed, onMounted, ref } from 'vue' | ||||
| import { RedoOutlined, TableOutlined } from '@ant-design/icons-vue' | ||||
| import { List, Card, Image, Typography, Tooltip, Slider, Avatar } from 'ant-design-vue' | ||||
| import { Icon } from '@/components/Icon' | ||||
| import { BasicForm, useForm, FormSchema } from '@/components/Form' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { isFunction } from '@/utils/is' | ||||
| import { useSlider, grid } from './data' | ||||
| 
 | ||||
| const ListItem = List.Item | ||||
| const CardMeta = Card.Meta | ||||
| const TypographyText = Typography.Text | ||||
| // 获取slider属性 | ||||
| const sliderProp = computed(() => useSlider(4)) | ||||
| // 组件接收参数 | ||||
| const props = defineProps({ | ||||
|   // 请求API的参数 | ||||
|   params: propTypes.object.def({}), | ||||
|   //api | ||||
|   api: propTypes.func, | ||||
|   searchSchema: { | ||||
|     type: Array | ||||
|   } | ||||
| }) | ||||
| //暴露内部方法 | ||||
| const emit = defineEmits(['getMethod', 'delete']) | ||||
| //数据 | ||||
| const data = ref([]) | ||||
| // 切换每行个数 | ||||
| // cover图片自适应高度 | ||||
| //修改pageSize并重新请求数据 | ||||
| 
 | ||||
| const height = computed(() => { | ||||
|   return `h-${120 - grid.value * 6}` | ||||
| }) | ||||
| //表单 | ||||
| const [registerForm, { validate }] = useForm({ | ||||
|   schemas: props.searchSchema as FormSchema[], | ||||
|   labelWidth: 80, | ||||
|   baseColProps: { span: 6 }, | ||||
|   actionColOptions: { span: 24 }, | ||||
|   autoSubmitOnEnter: true, | ||||
|   submitFunc: handleSubmit | ||||
| }) | ||||
| //表单提交 | ||||
| async function handleSubmit() { | ||||
|   const data = await validate() | ||||
|   await fetch(data) | ||||
| } | ||||
| function sliderChange(n: number) { | ||||
|   pageSize.value = n * 4 | ||||
|   fetch() | ||||
| } | ||||
| 
 | ||||
| // 自动请求并暴露内部方法 | ||||
| onMounted(() => { | ||||
|   fetch() | ||||
|   emit('getMethod', fetch) | ||||
| }) | ||||
| 
 | ||||
| async function fetch(p = {}) { | ||||
|   const { api, params } = props | ||||
|   if (api && isFunction(api)) { | ||||
|     const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p }) | ||||
|     data.value = res.list | ||||
|     total.value = res.total | ||||
|   } | ||||
| } | ||||
| //分页相关 | ||||
| const page = ref(1) | ||||
| const pageSize = ref(36) | ||||
| const total = ref(0) | ||||
| const paginationProp = ref({ | ||||
|   showSizeChanger: false, | ||||
|   showQuickJumper: true, | ||||
|   pageSize, | ||||
|   current: page, | ||||
|   total, | ||||
|   showTotal: (total: number) => `总 ${total} 条`, | ||||
|   onChange: pageChange, | ||||
|   onShowSizeChange: pageSizeChange | ||||
| }) | ||||
| 
 | ||||
| function pageChange(p: number, pz: number) { | ||||
|   page.value = p | ||||
|   pageSize.value = pz | ||||
|   fetch() | ||||
| } | ||||
| function pageSizeChange(_current, size: number) { | ||||
|   pageSize.value = size | ||||
|   fetch() | ||||
| } | ||||
| 
 | ||||
| async function handleDelete(id) { | ||||
|   emit('delete', id) | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,25 @@ | |||
| import { ref } from 'vue' | ||||
| // 每行个数
 | ||||
| export const grid = ref(12) | ||||
| // slider属性
 | ||||
| export const useSlider = (min = 6, max = 12) => { | ||||
|   // 每行显示个数滑动条
 | ||||
|   const getMarks = () => { | ||||
|     const l = {} | ||||
|     for (let i = min; i < max + 1; i++) { | ||||
|       l[i] = { | ||||
|         style: { | ||||
|           color: '#fff' | ||||
|         }, | ||||
|         label: i | ||||
|       } | ||||
|     } | ||||
|     return l | ||||
|   } | ||||
|   return { | ||||
|     min, | ||||
|     max, | ||||
|     marks: getMarks(), | ||||
|     step: 1 | ||||
|   } | ||||
| } | ||||
|  | @ -1,138 +1,39 @@ | |||
| <template> | ||||
|   <PageWrapper :class="prefixCls" title="公众号图文"> | ||||
|     <template #headerContent> | ||||
|       请选择公众号 | ||||
|       <div :class="`${prefixCls}__link`"> | ||||
|         <Select :value="queryParams.accountId as any" style="width: 200px" @change="getList"> | ||||
|           <SelectOption v-for="item in accounts" :label="item.name" :value="parseInt(item.id)" :key="parseInt(item.id)" /> | ||||
|         </Select> | ||||
|         <!-- <a><Icon icon="bx:bx-paper-plane" color="#1890ff" /><span>开始</span></a> | ||||
|         <a><Icon icon="carbon:warning" color="#1890ff" /><span>简介</span></a> | ||||
|         <a><Icon icon="ion:document-text-outline" color="#1890ff" /><span>文档</span></a> --> | ||||
|       </div> | ||||
|     </template> | ||||
| 
 | ||||
|     <div :class="`${prefixCls}__content`"> | ||||
|       <List :grid="{ gutter: 16, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: 3, xxxl: 2 }" :data-source="cardList"> | ||||
|         <template v-for="item in cardList" :key="item.title"> | ||||
|           <ListItem> | ||||
|             <Card :hoverable="true" :class="`${prefixCls}__card`"> | ||||
|               <List> | ||||
|                 <template v-for="(article, index) in item.content.newsItem" :key="index"> | ||||
|                   <ListItem> | ||||
|                     <Image :src="article.picUrl" :key="index" /> | ||||
|                     <div :class="`${prefixCls}__card-title`"> | ||||
|                       {{ article.title }} | ||||
|                     </div> | ||||
|                     <div :class="`${prefixCls}__card-detail`"></div> | ||||
|                   </ListItem> | ||||
|                 </template> | ||||
|               </List> | ||||
|               <!-- <div :class="`${prefixCls}__card-title`"> | ||||
|                 <Icon class="icon" v-if="item.icon" :icon="item.icon" :color="item.color" /> | ||||
|                 {{ item.title }} | ||||
|               </div> | ||||
|               <div :class="`${prefixCls}__card-detail`"> 基于Vue Next, TypeScript, Ant Design Vue实现的一套完整的企业级后台管理系统 </div> --> | ||||
|             </Card> | ||||
|           </ListItem> | ||||
|         </template> | ||||
|       </List> | ||||
|       <Pagination showLessItems size="small" :pageSize="queryParams.queryParamsSize" :total="queryParams.total" @change="getList" /> | ||||
|     </div> | ||||
|   <PageWrapper title="公众号图文"> | ||||
|     <NewsList :search-schema="searchSchema" :api="getFreePublishPage" @get-method="getMethod" @delete="handleDelete" /> | ||||
|   </PageWrapper> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| // import { Icon } from '@/components/Icon' | ||||
| import { PageWrapper } from '@/components/Page' | ||||
| import { Card, List, Image, Select, Pagination } from 'ant-design-vue' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| import { ref, reactive, onMounted } from 'vue' | ||||
| import NewsList from './NewsList.vue' | ||||
| import { getSimpleAccounts } from '@/api/mp/account' | ||||
| import { useMessage } from '@/hooks/web/useMessage' | ||||
| import { getFreePublishPage } from '@/api/mp/freePublish' | ||||
| import { deleteFreePublish, getFreePublishPage } from '@/api/mp/freePublish' | ||||
| import { FormSchema } from '@/components/Form' | ||||
| 
 | ||||
| const ListItem = List.Item | ||||
| const SelectOption = Select.Option | ||||
| 
 | ||||
| const { prefixCls } = useDesign('list-card') | ||||
| const { createMessage } = useMessage() | ||||
| 
 | ||||
| const cardList = ref<any[]>([]) | ||||
| 
 | ||||
| const accounts = ref() | ||||
| 
 | ||||
| const queryParams = reactive({ | ||||
|   accountId: null, | ||||
|   total: 0, | ||||
|   currentPage: 1, | ||||
|   queryParamsSize: 20 | ||||
| }) | ||||
| 
 | ||||
| async function init() { | ||||
|   const res = await getSimpleAccounts() | ||||
|   accounts.value = res | ||||
|   if (accounts.value.length > 0) { | ||||
|     queryParams.accountId = accounts.value[0].id | ||||
| const searchSchema: FormSchema[] = [ | ||||
|   { | ||||
|     label: '公众号', | ||||
|     field: 'accountId', | ||||
|     component: 'ApiSelect', | ||||
|     componentProps: { | ||||
|       api: () => getSimpleAccounts(), | ||||
|       labelField: 'name', | ||||
|       valueField: 'id' | ||||
|     }, | ||||
|     colProps: { span: 8 } | ||||
|   } | ||||
|   await getList() | ||||
| ] | ||||
| 
 | ||||
| let reload = () => {} | ||||
| // 获取内部fetch方法; | ||||
| function getMethod(m: any) { | ||||
|   reload = m | ||||
| } | ||||
| 
 | ||||
| async function getList() { | ||||
|   if (!queryParams.accountId) { | ||||
|     createMessage.error('未选中公众号,无法查询已发表图文!') | ||||
|     return false | ||||
|   } | ||||
|   const res = await getFreePublishPage(queryParams) | ||||
|   cardList.value = res.list | ||||
|   queryParams.total = res.total | ||||
| //删除按钮事件 | ||||
| function handleDelete(id) { | ||||
|   deleteFreePublish(id, id) | ||||
|   reload() | ||||
| } | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|   await init() | ||||
| }) | ||||
| </script> | ||||
| <style lang="less" scoped> | ||||
| .list-card { | ||||
|   &__link { | ||||
|     margin-top: 10px; | ||||
|     font-size: 14px; | ||||
| 
 | ||||
|     a { | ||||
|       margin-right: 30px; | ||||
|     } | ||||
| 
 | ||||
|     span { | ||||
|       margin-left: 5px; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &__card { | ||||
|     width: 100%; | ||||
|     margin-bottom: -8px; | ||||
| 
 | ||||
|     .ant-card-body { | ||||
|       padding: 16px; | ||||
|     } | ||||
| 
 | ||||
|     &-title { | ||||
|       margin-bottom: 5px; | ||||
|       font-size: 16px; | ||||
|       font-weight: 500; | ||||
|       color: @text-color; | ||||
| 
 | ||||
|       .icon { | ||||
|         margin-top: -5px; | ||||
|         margin-right: 10px; | ||||
|         font-size: 38px !important; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &-detail { | ||||
|       padding-top: 10px; | ||||
|       padding-left: 30px; | ||||
|       font-size: 14px; | ||||
|       color: @text-color-secondary; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 xingyu
						xingyu