apps/cMiniApp/src/assets/tabbar/icon-mine-active.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
apps/cMiniApp/src/assets/tabbar/icon-task-active.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
apps/cMiniApp/src/components/Layout/PageLayoutWithBg.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
apps/cMiniApp/src/components/Menu/MenuItem.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
apps/cMiniApp/src/components/Searchbar/BlSearchbar.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
apps/cMiniApp/src/pages/home/constants/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
apps/cMiniApp/src/pages/home/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
packages/components/src/Card/TaskCard.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
packages/components/src/Card/TaskPrice.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
packages/components/src/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
apps/cMiniApp/src/assets/tabbar/icon-mine-active.pngapps/cMiniApp/src/assets/tabbar/icon-task-active.pngapps/cMiniApp/src/components/Layout/PageLayoutWithBg.vue
@@ -10,8 +10,8 @@ <template #bg> <img :src="OssAssets.common.CommonPageBg" class="common-page-bg" /> </template> <template #default> <slot /> <template #default="{ scrollViewHeight }"> <slot :scrollViewHeight="scrollViewHeight" /> </template> </PageLayout> </template> apps/cMiniApp/src/components/Menu/MenuItem.vue
@@ -53,10 +53,14 @@ </view> </template> <script lang="ts"> import { MenuItemOption } from '@nutui/nutui-taro/dist/types/__VUE/menuitem/type'; import { Check } from '@nutui/icons-vue-taro'; import { isArray } from 'lodash'; type MenuItemOption = { text: string; value: number | string; }; export default defineComponent({ name: 'bl-menu-item', props: { apps/cMiniApp/src/components/Searchbar/BlSearchbar.vue
@@ -25,5 +25,10 @@ .bole-search-bar { padding: 0; background-color: transparent; .nut-searchbar__search-input { box-shadow: none; border: 1px solid boleGetCssVar('color', 'primary'); } } </style> apps/cMiniApp/src/pages/home/constants/index.ts
New file @@ -0,0 +1,4 @@ export enum HomeOrderType { Recommend = 'Recommend', LastShelfTime = 'LastShelfTime', } apps/cMiniApp/src/pages/home/index.vue
@@ -1,31 +1,91 @@ <template> <PageLayoutWithBg class="index-page-wrapper" :title="'首页'" :need-auth="false"> <PageLayoutWithBg class="index-page-wrapper" :title="''" :need-auth="false"> <template #left> <div class="menu-btn-wrapper menu-logo"> <img :src="IconLogo" class="logo" /> </div> </template> <div class="home-header"> <div class="home-searchbar-wrapper"> <BlSearchbar v-model.trim="searchValue"></BlSearchbar> <div class="searchbar-container"> <BlSearchbar v-model.trim="searchValue" placeholder="搜索任务"></BlSearchbar> </div> <div class="city-btn" @click="goCitySelect"> <Location2 :size="16" /> <div class="city-btn-text">{{ locationCity }}</div> </div> </div> <div class="home-banner-wrapper"> <nut-swiper :auto-play="3000"> <nut-swiper-item v-for="(item, index) in list" :key="index"> <img :src="item" class="banner-img" draggable="false" /> </nut-swiper-item> </nut-swiper> </div> </div> <ProTabs v-model="queryState.orderType" name="home-tab" :showPaneContent="false" class="home-tabs" isTransparent title-gutter="12" title-scroll > <ProTabPane :title="`推荐`" :pane-key="HomeOrderType.Recommend"></ProTabPane> <ProTabPane :title="`最新`" :pane-key="HomeOrderType.LastShelfTime"></ProTabPane> <template #right> <Menu> <MenuItem v-model="queryState.orderByProperty" title="筛选" ref="selectItem" :options="[ { text: '排序', value: 'userId' }, { text: '按关注时间', value: 'creationTime' }, ]" /> </Menu> </template> </ProTabs> <InfiniteLoading scrollViewClassName="common-infinite-scroll-list home-list" v-bind="infiniteLoadingProps" :key="queryState.orderType" > <template #renderItem="{ item }"> <TaskCard /> </template> </InfiniteLoading> </PageLayoutWithBg> </template> <script setup lang="ts"> import { useUser } from '@/hooks'; import { useUserStore } from '@/stores/modules/user'; import { RectDown } from '@nutui/icons-vue-taro'; import { RectDown, Location2 } from '@nutui/icons-vue-taro'; import Taro from '@tarojs/taro'; import { LocationUtils, trim } from '@12333/utils'; import _ from 'lodash'; import IconLogo from '@/assets/home/icon-logo.png'; import { useInfiniteLoading } from '@12333/hooks'; import { OrderInputType } from '@12333/constants'; import * as orderServices from '@12333/services/api/Order'; import { TaskCard, ProTabs, ProTabPane } from '@12333/components'; import { HomeOrderType } from './constants'; const { locationCity } = useUser(); Taro.usePageScroll(() => { console.log('11', 11); }); const searchValue = ref(''); const queryState = reactive({ searchValueTrim: '', orderType: HomeOrderType.Recommend, orderByProperty: 'userId', }); const handleSearch = _.debounce(function () { @@ -39,13 +99,36 @@ url: RouterPath.citySelect, }); } // onMounted(async () => { // if (!isSetMatchMakingIdentity.value) { // Taro.navigateTo({ // url: RouterPath.toggleMatchMakingIdentity, // }); // } // }); const list = ref([ 'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg', 'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg', 'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg', 'https://storage.360buyimg.com/jdc-article/fristfabu.jpg', ]); const { infiniteLoadingProps } = useInfiniteLoading( ({ pageParam }) => { let params: API.FrontOrderListInput = { pageModel: { rows: 20, page: pageParam, orderInput: [ queryState.orderType === HomeOrderType.Recommend ? { property: 'isRecommend', order: OrderInputType.Desc } : { property: 'lastShelfTime', order: OrderInputType.Desc }, ], }, }; return orderServices.getFrontOrderList(params, { showLoading: false, }); }, { queryKey: ['orderServices/getFrontOrderList', queryState], } ); </script> <style lang="scss"> @@ -61,19 +144,44 @@ } } .home-searchbar-wrapper { padding: 32px 0; display: flex; .searchbar-container { flex: 1; min-width: 0; } .city-btn { display: flex; align-items: center; padding-left: 36px; color: boleGetCssVar('text-color', 'primary'); .city-btn-text { max-width: 200px; @include ellipsis; margin-right: 12px; margin-left: 12px; font-size: 30px; } } } .home-searchbar-wrapper { padding: 32px 0; .home-banner-wrapper { .banner-img { width: 100%; height: 260px; object-fit: cover; } } .home-header { padding: 0 boleGetCssVar('size', 'body-padding-h'); } } .home-list { @include infiniteLoadingInTabBarPage; } </style> packages/components/src/Card/TaskCard.vue
New file @@ -0,0 +1,131 @@ <template> <div class="task-card-wrapper"> <div class="task-card-title-wrapper"> <div class="task-card-title">客房服务员</div> <TaskPrice /> </div> <div class="task-card-welfare-list"> <div class="task-card-welfare-list-item">日结</div> <div class="task-card-welfare-list-item">男女不限</div> <div class="task-card-welfare-list-item">包三餐</div> </div> <div class="task-card-time">上班时间:07:00-15:30</div> <div class="task-card-footer"> <div class="task-card-left"> <div class="task-card-footer-tag">H</div> <div class="task-card-footer-address">宁波雷迪森酒店</div> </div> <div class="task-card-actions"> <slot name="actions"> <nut-button type="primary">报名</nut-button> </slot> </div> </div> </div> </template> <script setup lang="ts"> import TaskPrice from './TaskPrice.vue'; defineOptions({ name: 'TaskCard', }); type Props = { title?: string; }; const props = withDefaults(defineProps<Props>(), {}); </script> <style lang="scss"> @import '@/styles/common.scss'; .task-card-wrapper { padding: 24px 32px; margin-bottom: 24px; background-color: #fff; border-radius: 12px; &:last-child { margin-bottom: 0; } .task-card-title-wrapper { display: flex; align-items: center; margin-bottom: 14px; .task-card-title { flex: 1; min-width: 0; @include ellipsis; font-size: 30px; color: boleGetCssVar('text-color', 'primary'); line-height: 42px; } } .task-card-welfare-list { display: flex; flex-wrap: wrap; row-gap: 6px; column-gap: 18px; margin-bottom: 8px; .task-card-welfare-list-item { font-size: 24px; color: #ff7d00; line-height: 36px; } } .task-card-time { font-size: 24px; color: boleGetCssVar('text-color', 'secondary'); line-height: 36px; margin-bottom: 6px; } .task-card-footer { display: flex; align-items: center; .task-card-left { flex: 1; min-width: 0; display: flex; align-items: center; .task-card-footer-tag { width: 32px; height: 32px; background: #2a9e1b; margin-right: 8px; border-radius: 8px; text-align: center; line-height: 32px; color: #fff; font-size: 22px; } .task-card-footer-address { font-size: 22px; color: boleGetCssVar('text-color', 'secondary'); line-height: 36px; flex: 1; min-width: 0; @include ellipsis; } } .task-card-actions { --nut-button-default-font-size: 24px; .nut-button { height: 26px; } } } } </style> packages/components/src/Card/TaskPrice.vue
New file @@ -0,0 +1,39 @@ <template> <div class="task-price"> <div class="task-price-decimal">55</div> <div class="task-price-unit">元/小时</div> </div> </template> <script setup lang="ts"> defineOptions({ name: 'TaskPrice', }); type Props = { value?: number; }; const props = withDefaults(defineProps<Props>(), {}); </script> <style lang="scss"> @import '@/styles/common.scss'; .task-price { display: flex; align-items: flex-end; color: boleGetCssVar('color', 'primary'); .task-price-decimal { font-size: 32px; line-height: 40px; margin-right: 8px; } .task-price-unit { font-size: 20px; line-height: 32px; } } </style> packages/components/src/index.ts
@@ -17,3 +17,4 @@ export { default as AutoWidthImage } from './Image/AutoWidthImage.vue'; export { default as AreaTreeSelect } from './AreaTreeSelect/AreaTreeSelect.vue'; export { default as Elevator } from './Elevator/Elevator.vue'; export { default as TaskCard } from './Card/TaskCard.vue';