JAVA SpringBoot および UniAPP に基づくペット サービス予約アプレット

        特に近年、社会の発展と人々の生活水準の向上に伴い、ペットは急速に人々の家庭に入り込み、人々の生活における重要な娯楽コンテンツの一つとなり、人々の精神性の向上とともにそのあり方が広く認識されるようになりました。文明が進み、ペットがますます増えています。これで私たちは良い友達になりました。しかし、どうやって彼らに対処し、彼らを守るのでしょうか?結局のところ、彼らは人間とは大きく異なるので、私たちは彼らに何を与えるべきでしょうか?彼らに何を食べさせるべきでしょうか?ほとんどの人は知りません。彼らは子供のように世話をすることを知っています。しかし、彼らは話さない。中には子供として彼らのことを気にしない人もいます。したがって、ペットサービスに関する情報は重要なトピックになります。ペットは私たちのフレンドリーな友人であり、人間の幸福と健康の重要な源です。

        ペットを飼うことは、人々の生活をより豊かで幸せなものにすると同時に、ペットと一緒に運動することは、血圧や血中脂質を効果的に下げるなど、体にとても良いことであり、競争が激化する今日の社会において、ペットは良い精神を提供することができます。サポート。特にイライラしているときはそうです。ペットとのコミュニケーションを通じて、感情の調整や精神的健康の管理、生活上のさまざまなプレッシャーの軽減、仕事の効率の向上などの効果が得られる一方、かわいいペットを飼うことで、子どもの責任感や愛情、社会性を育むことができます。 「犬は楽しんでいます。犬はたくさんのポジティブなエネルギーを伝えます。最も重要なことは、ペットを飼うことは家族の財産を守り、盗難から守り、家族全員が安心できるようにすることです。また、ペットは私たちと将来の世代に無限の喜びをもたらします」 、喜びと幸福、人生の源になります。人々が活動的になり、身体活動を促進できるよう支援することで、他の人とつながる多くの機会が得られます。現在、ペットの飼い主は急速に増加しており、時代の要請に応じてペット情報サイトも数多く誕生しています。

実装された機能:

このシステムの機能には、ユーザーのログインと登録、ホームページの表示、訪問サービス、ペットコミュニティ、バックグラウンド管理(PC ブラウザのバックグラウンド)などの機能が含まれる必要があります。

登録とログイン: ユーザーの WeChat ニックネームと WeChat アカウントを取得してログインします。システムでは匿名アクセスが許可されていますが、匿名アクセスではインターフェイスの閲覧のみが可能であり、サービスの予約はできません。

ホームページの表示: ホームページには、主に情報の閲覧と収集のためのペットのコレクションが含まれています。ペットの里親募集・里親募集について詳しくご相談いただけます。

ドアツードアサービス:顧客のペットにドアツードアの餌やり、ペットの散歩サービス、専門的な清掃、基本的な医療相談を含む4つのモジュールの機能を提供します。

ペットコミュニティ: 主にペットの写真をアップロードしたり、ペットの興味深い話を共有したりするためのものです。

バックグラウンド管理: 管理者によるサービス予約管理のオーダーの追加、削除、変更をサポートします。ペットコミュニティでは、ユーザーが投稿した面白い話を管理し、規約に違反する情報は削除します。

使用されているテクノロジー:

バックエンド: Java 言語の SpringBoot フレームワーク、MySql データベース、Maven 依存関係管理など。

フロントエンド: Vue.js 構文を使用した UniApp フレームワーク。

 コード表示の一部

<template>
	<view class="wrap">
		<u-navbar :is-back="false" :title="title" title-color="#000">
			<!-- <view class="slot-wrap" @tap="navTo('/pages/pet/city')">	
				<i class="iconfont iconicon-test" :class="'text-' + themeColor.name"/> 
				<view class="city">{
   
   {city.title}} <text class="iconfont iconxiajiantou2" /></view>
			</view> -->
		</u-navbar>

		<view class="swiper-adv" v-if="advs.index_top.length">
			<!-- <u-swiper :list="advs.index_top" name="cover" :current="current" field="content" mode="round" height="300" border-radius="15" @click="navToIndex" ></u-swiper> -->
			
			<uni-swiper-dot :info="advs.index_top" :current="current" field="content" mode="round" :dotsStyles="{ backgroundColor: '#FFF', color: themeColor.color, selectedBackgroundColor: themeColor.color, border: 'none', selectedBorder: 'none' }">
				<swiper class="swiper-box" :current="current" circular autoplay :indicator-dots="false" indicator-color="#FFF" :indicator-active-color="themeColor.color" @animationfinish="animationfinish">
					<swiper-item v-for="(item, index) in advs.index_top" :key="index" @click="navToIndex">
						<u-image :src="item.cover" width="100%" height="300" border-radius="15" mode="aspectFill" /> 
					</swiper-item>
				</swiper>
			</uni-swiper-dot>
		</view>
		
		<!-- <view class="swiper">
			<view class="swiper-box">
				<rf-swipe-dot :info="advs.index_top" mode="dot" :current="current" field="title">
					<swiper @change="handleDotChange" autoplay="true">
						<swiper-item v-for="(item, index) in advs.index_top" @tap="indexTopToDetailPage(item)" :key="index">
							<view class="swiper-item">
								<u-image :src="item.cover" width="100%" height="240" border-radius="20" mode="aspectFill" />
							</view>
						</swiper-item>
					</swiper>
				</rf-swipe-dot>
			</view>
		</view>

		<!-- 公告 -->
		<!-- <rf-swiper-slide v-if="notices.length > 0" :list="notices" class="rf-skeleton" @navTo="navTo('/pages/index/notice/notice')">
			<view slot="header" class="swiper-slide-header">
				<text class="iconfont icongonggao" :class="'text-' + themeColor.name"></text>
			</view>
		</rf-swiper-slide> -->
		
		<!-- 频道 -->
		<swiper :indicator-active-color="themeColor.color" indicator-color="#666" :indicator-dots="false" class="channel-wrap">
			<swiper-item class="channel-list">
				<view class="channel" v-for="(item, index) in channels" :key="index" @tap.stop="navToChannel(index)">
					<view class="icon-wrap">
						<!-- <u-image :src="'/static/pet/icon-' + item.key  + '.png'" width="84" height="84" borderRadius="15" mode="aspectFill" /> -->					<u-icon :name="item.icon" custom-prefix="custom-icon" size="66" :color="themeColor.color" />
					</view>
					<view class="text">{
   
   { item.name}}</view>
				</view>
			</swiper-item>
		</swiper>
		
		<!--列表-->
		<view class="pet-wrap">
			<view class="sticky">
				<view class="sticky-tabs">
					<u-tabs-swiper ref="tabs" :list="tabList" :current="tabsCurrent" @change="tabsChange" :is-scroll="false" bar-height="6" bar-width="40" :active-color="themeColor.color"></u-tabs-swiper>
				</view>
				
			</view>
			
			<view>
				<view class="item" v-for="(item, index) in items" :key="index" @tap="switchTab('/pages/pet/pet-view?id='+item.id)">
					<view class="left"><u-image :src="getPicUrl(item.pic1)" width="100%" height="220" border-radius="20" mode="aspectFill" /></view>
					
					<view class="right">
						<view class="title u-line-2">{
   
   {item.title}}</view>
							
						<view class="base" >
							<view class="tag" v-for="(item2,index2) in splitTag(item.tag)" :key="index2">{
   
   {item2}}</view>
						</view>
						<!-- 
						<view class="reward">悬赏¥<text class="money">{
   
   {item.money}}</text></view> -->
						<view class="summary u-line-2">{
   
   {item.content}}</view>
					</view>
					<view class="bottom">
						<view class="datetime">{
   
   {item.createTime}}</view>
						<!-- <view class="view">{
   
   {item.view}}查看</view>
						<view class="share">{
   
   {item.share}}转发</view> -->
					</view>
					<u-line color="info" :hair-line="false" margin="30rpx 0 0 0" />
					
				</view>
				
			</view>
			
			<!-- <swiper :current="swiperCurrent" @transition="swiperTransition" @animationfinish="swiperAnimationfinish" style="height:1150rpx;">
				<swiper-item v-for="(item, tabsIndex) in $mData.types" :key="tabsIndex">
					<pet-index-mescroll-item ref="mescrollItem" :i="tabsIndex" :index="tabsIndex" :params="params" :items="items"></pet-index-mescroll-item>
				</swiper-item>
			</swiper> -->
		</view>
		
		<u-gap height="20" />

		<!--备案-->
		<!--#ifdef H5-->
		<view class="copyright" v-if="config.web_site_icp">
			{
   
   { config.copyright_desc }}
			
			<a href="http://www.beian.miit.gov.cn">{
   
   { config.web_site_icp }}</a>
		</view>
		<!-- #endif -->

		<!--页面加载动画-->
		<rfLoading isFullScreen :active="loading"></rfLoading>
		<!-- <rf-back-top :scrollTop="scrollTop"></rf-back-top> -->
		<!-- <rf-back-home></rf-back-home> -->
	</view>
</template>

<script>
import rfSwipeDot from '@/components/rf-swipe-dot';
import rfSwiperSlide from '@/components/rf-swiper-slide';
import { mapMutations } from 'vuex';
import PetIndexMescrollItem from '../pet/mescroll-item/pet-index-mescroll-item';
// import { indexList } from '@/api/product';
// import { petIndex, petList } from '@/api/pet';
import appRequest from "@/common/appRequestUrl.js";
// const QQMapWX = require('@/common/qqmap-wx-jssdk.min.js');

export default {
	components: {
		rfSwipeDot,
		rfSwiperSlide,
		PetIndexMescrollItem,
	},
	data() {
		return {
			userInfo:{},
			items:[],
			$mData: this.$mData,
			appName: this.$mSettingConfig.appName,
			path: '/pages/index/index',
			title: this.$mSettingConfig.appName + '',
			qqmapsdk: null,
			city: { 
				id: 0,
				title: '全国'
			},
			current: 0, // 轮播图index
			advs: {
				index_top: []
			}, // 广告图
			notices: [],
			channels: [
				{
					key: 'find',
					icon: 'pet',
					name: '领养寄养',
					route: '/pages/pet/list',
					type: 'switchTab'
				},
				{
					key: 'mall',
					icon: 'ask',
					name: '养宠宝典',
					route: '/pages/pet/ask',
					type: 'switchTab'
				},
				{
					key: 'blocklist',
					icon: 'forum',
					name: '分享社区',
					route: '/pages/pet/forum',
					type: 'push'
				},
				
			],
			tabsCurrent: 0, // tabs组件的current值,表示当前活动的tab选项
			swiperCurrent: 0, // swiper组件的current值,表示当前那个swiper-item是活动的
			config: {}, // 配置
			loading: true,
			scrollTop: 0,
			kefuShow: true,
			loadingType: 'more',
			newsBg: this.$mAssetsPath.newsBg,
			errorImage: this.$mAssetsPath.errorImage,
			pages: [1, 1, 1, 1],
			// type: 1,
			// cate: 0,
			moneySymbol: this.moneySymbol,
			genders: ['不限', '男孩', '女孩'],
			ages: ['不限', '幼年', '成年', '老年'],
			sizes: ['不限', '小型', '中型', '大型'],
			hairs: ['不限', '长毛', '短毛', '无毛'],
			states: ['不限', '已免疫', '已绝育', '已驱虫'],
			activeStyle: {
				background: '#FFCE0C',
				color: '#01040A'
			},
			filterShow: false,
			params: {},
			tabList:[{ key: 1, name: '领养', title: '领养', content: 'Ta的故事', tips: '为小可爱找新家' },
		{ key: 3, name: '寄养', title: '拾得', content: '宠物详情', tips: '为小可爱寻找原主人' },{ key: 4, name: '养宠宝典', title: '拾得', content: '宠物详情', tips: '为小可爱寻找原主人' }]
		};
	},
	onLoad() {
		// this.qqmapsdk = new QQMapWX({
		// 	key: this.$mData.maps[0].key
		// });
		
		//this.initData();
		this.getData(0);
		this.advs = {index_top:[
		   {"cover": "/static/tab/banner01.png"},
		   {"cover": "/static/tab/banner02.png"},
		   {"cover": "/static/tab/banner03.png"},
		]}
		this.loading = false;
	},
	onShow() {
		let userInfo = appRequest.getUserInfo();
		if(!userInfo){
			
		}else{
			this.userInfo = userInfo;
		}
		// let city = uni.getStorageSync('city');

		// if (city && this.city.id != city.id) {
		// 	this.city = city;
			
		// 	this.$nextTick(() => {
		// 		for (let tab of this.$mData.types) {
		// 			this.getMescroll(tab.key-1).triggerDownScroll();
		// 		}
		// 	});
		// }
	},
	onPageScroll(e) {
		this.scrollTop = e.scrollTop;
	},
	/* onReachBottom() {
		this.mescroll && this.mescroll.onReachBottom();
	},
	onPageScroll(e) {
		this.mescroll && this.mescroll.onPageScroll(e);
	}, */
	onPullDownRefresh() {
		// this.getIndexList('refresh');
	},
	onShareAppMessage(res) {
		return { 
			title: this.title,
			path: this.path
		};
	},
	computed: {
		statusBar() {
			const e = uni.getSystemInfoSync();
			return e.statusBarHeight;
		},
		bottom() {
			let bottom = 0;
			/*  #ifdef H5  */
			bottom = 90;
			/*  #endif */
			return bottom;
		}
	},
	methods: {
		splitTag(text){
			return text.split(" ");
		},
		getPicUrl(info) {
			if(info){
				if( info.length > 10 ){
					return info;
				}else {
					return appRequest.urlMap.getPicById + info;
				}
			}else {
				return "";
			}
		
		},
		getData(type){
			var _this = this;
			appRequest.request({
				method: "POST",
				url: appRequest.urlMap.findNmArticleList,
				data:{
					validFlag:1,
					type:type
				},
				success: function(res) {
					if (res.data.code == 200) {
						let obj = res.data.data;
						_this.items = obj;
					}else{
						uni.showToast({
							title:"获取失败",
							icon:"none"
						})
					}
				},
				fail: function(res) {
					uni.showToast({
						title:"网络异常",
						icon:"none"
					})
				}
			})
		},
		// 数据初始化
		initData() {
			this.getCity();
			this.getIndexList();
		},
		// 监听轮播图切换
		handleDotChange(e) {
			this.current = e.detail.current;
		},
		// 通用跳转
		navTo(route) {
			this.$mRouter.push({ route });
		},
		// Tabbar跳转
		switchTab(route) {
			uni.navigateTo({
				url:route
			})
			//this.$mRouter.switchTab({ route });
		},
		navToChannel(index) {
			if(index==2){
				uni.navigateTo({
					url:"/pages/pet/public"
				})
			}else{
				index = index == 1 ? 2:index;
				this.swiperCurrent = index;
				this.tabsCurrent = index;
				let jump = index == 2 ? 3 :index;
				this.getData(jump);
			}
		},
		navToIndex() {
			switch (this.current) {
				case 0:
					this.navTo(`/pages/index/notice/notice`);
					break;
				case 1:
					this.switchTab(`/pages/pet/list`);
					break;
				case 2:
					this.switchTab(`/pages/pet/forum`);
					break;
				default:
					break;
			}
		},
		// 跳至广告图指定页面
		indexTopToDetailPage(item) {
			this.$mHelper.handleBannerNavTo(item.jump_type, item.jump_link, item.id);
		},
		// 获取主页数据
		async getIndexList(refresh) {
			// await this.$http.get(`${indexList}`, {}).then(async r => {
			// 	uni.setNavigationBarTitle({ title: this.appName });
			// 	if (refresh === 'refresh') uni.stopPullDownRefresh();
			// 	this.initIndexData(r.data);
			// 	this.loading = false;
			// }).catch(() => {
			// 	this.loading = false;
			// 	if (refresh === 'refresh') uni.stopPullDownRefresh();
			// });
		},
		// 首页参数赋值
		initIndexData(data) {
			this.advs = {index_top:[
			   {"cover": "/static/tab/banner01.png"},
			   {"cover": "/static/tab/banner02.png"},
			   {"cover": "/static/tab/banner03.png"},
			]}
			this.notices = data.announce;
			this.config = data.config;
			this.$mHelper.handleWxH5Share(this.share.share_title || this.appName, this.share.share_desc || `欢迎来到${this.appName}`, this.share.share_link || this.$mConfig.hostUrl, this.share.share_cover || this.$mSettingConfig.appLogo);
		},
		// 跳转至商品详情页
		navToDetailPage(data) {
			const { id } = data;
			if (!id) return;
			this.navTo(`/pages/pet/view?id=${id}`);
		},
		animationfinish(e) {
			this.current = e.detail.current;
		},
		// tabs通知swiper切换
		tabsChange(index) {
			this.swiperCurrent = index;
			this.tabsCurrent = index;
			let jump = index == 2 ? 3 :index;
			this.getData(jump);
		},
		// swiper-item左右移动,通知tabs的滑块跟随移动
		swiperTransition(e) {
			let dx = e.detail.dx;
			this.$refs.tabs.setDx(dx);
		},
		// 由于swiper的内部机制问题,快速切换swiper不会触发dx的连续变化,需要在结束时重置状态
		// swiper滑动结束,分别设置tabs和swiper的状态
		swiperAnimationfinish(e) {
			let tabsCurrent = e.detail.current;
			this.$refs.tabs.setFinishCurrent(tabsCurrent);
			this.swiperCurrent = tabsCurrent;
			this.tabsCurrent = tabsCurrent;
			
			this.cate = tabsCurrent;
		},
		getMescroll(i) {
			let mescrollItems = this.$refs.mescrollItem;
		
			if (mescrollItems) {
				let item = mescrollItems[i];
				if (item) return item.mescroll;
			}
		
			return null;
		},
		getCity() {
			let city = uni.getStorageSync('city');
			
			if (city) {
				this.city = city;
			} else {
				let _this = this;
				// #ifdef MP
				uni.authorize({
					scope: 'scope.userLocation',
					success() {
				// #endif
						uni.getLocation({
							type: 'gcj02',
							geocode: true,
							success(res) {
								_this.qqmapsdk.reverseGeocoder({
									location: {
										latitude: res.latitude,
										longitude: res.longitude
									},
									success(res) {
										let city = {
											id: res.result.ad_info.city_code - 156000000,
											title: res.result.ad_info.city
										}
										uni.setStorageSync('city', city);
										_this.city = city;
										_this.getMescroll(_this.swiperCurrent).triggerDownScroll();
									},
									fail(error) {
										console.error(error);
									}
								});
							},
							fail(error) {
								console.error(error);
							}
						});
				// #ifdef MP
					}
				});
				// #endif
			}
		}
	}
};
</script>

SpringBoot と UniAPP に基づくペット サービス予約アプレット

おすすめ

転載: blog.csdn.net/qq_28245905/article/details/132467415