Bootstrap

校园二手商品交易小程序系统源码

目录

一、整体目录(示范):

文档含项目技术介绍、E-R图、数据字典、项目功能介绍与截图等

二、运行截图

三、代码部分(示范):

四、数据库表(示范):

数据库表有注释,可以导出数据字典及更新数据库时间,欢迎交流学习

五、主要技术介绍:

六、项目调试学习(点击查看)

七、项目交流


一、整体目录(示范):

文档含项目技术介绍、E-R图、数据字典、项目功能介绍与截图等

 

二、运行截图

三、代码部分(示范):

登录页面代码:

<template>
	<view class="content">
		<view class="box" :style='{"padding":"48rpx","boxShadow":"0 0px 0px 20rpx #6B7D90","margin":"0 auto","borderColor":"rgba(255, 255, 255, 1)","backgroundColor":"rgba(107, 125, 144, 1)","borderRadius":"60rpx","borderWidth":"40rpx 40rpx 0","width":"90%","borderStyle":"solid","height":"auto"}'>
			<view class="logo" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0 0 24rpx","borderColor":"#ccc","backgroundColor":"rgba(107, 125, 144, 1)","borderRadius":"0","borderWidth":"0","width":"100%","borderStyle":"solid","height":"auto"}'>
				<image :style='{"padding":"0","boxShadow":"0 0 0px #59f43e","margin":"0 auto","borderColor":"#ccc","borderRadius":"100rpx","borderWidth":"0","width":"160rpx","borderStyle":"solid","url":"http://codegen.caihongy.cn/20220217/783a2e74c5964c179d1986988ad79181.jfif","isShow":true,"height":"160rpx"}' src='http://codegen.caihongy.cn/20220217/783a2e74c5964c179d1986988ad79181.jfif' mode="aspectFill"></image>
			</view>
			<view class="uni-form-item uni-column" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0 0 24rpx","borderColor":"#ccc","backgroundColor":"rgba(107, 125, 144, 1)","borderRadius":"0","borderWidth":"0","width":"100%","borderStyle":"solid","height":"auto"}'>
				<input v-model="username" :style='{"padding":"0 24rpx","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0","borderColor":"#ccc","backgroundColor":"#fff","color":"#333","textAlign":"left","borderRadius":"0","borderWidth":"0","width":"100%","fontSize":"28rpx","borderStyle":"solid","height":"88rpx"}' type="text" class="uni-input" name="" placeholder="请输入账号" />
			</view>
			<view class="uni-form-item uni-column" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0 0 24rpx","borderColor":"#ccc","backgroundColor":"rgba(107, 125, 144, 1)","borderRadius":"0","borderWidth":"0","width":"100%","borderStyle":"solid","height":"auto"}'>
				<input v-model="password" :style='{"padding":"0 24rpx","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0","borderColor":"#ccc","backgroundColor":"#fff","color":"#333","textAlign":"left","borderRadius":"0","borderWidth":"0","width":"100%","fontSize":"28rpx","borderStyle":"solid","height":"88rpx"}' type="password" class="uni-input" name="" placeholder="请输入密码" />
			</view>
			<view class="uni-form-item uni-column" v-if="roleNum>1" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0 0 24rpx","borderColor":"#ccc","backgroundColor":"rgba(107, 125, 144, 1)","borderRadius":"0","borderWidth":"0","width":"100%","borderStyle":"solid","height":"auto"}'>
				<picker @change="optionsChange" :value="index" :range="options">
					<view class="uni-picker-type" :style='{"padding":"0 24rpx","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0","borderColor":"#ccc","backgroundColor":"rgba(255, 255, 255, 1)","color":"#333","textAlign":"left","borderRadius":"0","borderWidth":"0","width":"100%","lineHeight":"88rpx","fontSize":"28rpx","borderStyle":"solid"}'>{{options[index]}}</view>
				</picker>
			</view>
			<button class="btn-submit" @tap="onLoginTap" type="primary" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0","borderColor":"rgba(255, 255, 255, 1)","backgroundColor":"rgba(180, 153, 80, 0)","borderRadius":"40rpx","color":"rgba(255, 255, 255, 1)","borderWidth":"4rpx","width":"40%","fontSize":"32rpx","borderStyle":"solid","height":"88rpx"}'>登录</button>
			<view class="links" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0 0 24rpx","borderColor":"#ccc","backgroundColor":"rgba(107, 125, 144, 1)","borderRadius":"0","borderWidth":"0","width":"100%","borderStyle":"solid","height":"auto"}'>
												<view class="link-highlight" @tap="onRegisterTap('yonghu')" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0 24rpx 0 0","borderColor":"#ccc","backgroundColor":"rgba(0,0,0,0)","color":"rgba(255, 255, 255, 1)","textAlign":"left","borderRadius":"0","borderWidth":"0","width":"auto","lineHeight":"36rpx","fontSize":"24rpx","borderStyle":"solid"}'>注册用户</view>
				<!-- <view>|</view> -->
																																																																																																												<view @tap="onForgetTap" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0","borderColor":"#ccc","backgroundColor":"rgba(0,0,0,0)","color":"rgba(164, 164, 164, 1)","textAlign":"right","borderRadius":"0","borderWidth":"0","width":"auto","lineHeight":"36rpx","fontSize":"24rpx","borderStyle":"solid"}'>忘记密码?</view>
			</view>
			<!-- <view class="links">
				<view @tap="onForgetTap" :style='{"padding":"0","boxShadow":"0 2rpx 12rpx rgba(0,0,0,0)","margin":"0","borderColor":"#ccc","backgroundColor":"rgba(0,0,0,0)","color":"rgba(164, 164, 164, 1)","textAlign":"right","borderRadius":"0","borderWidth":"0","width":"auto","lineHeight":"36rpx","fontSize":"24rpx","borderStyle":"solid"}'>忘记密码?</view>
			</view> -->
		</view>
	</view>
</template>

<style>
	.btn-submit {
		height: auto !important;
		line-height: 88rpx;
	}
</style>

<script>
	import menu from '@/utils/menu'
	export default {
		data() {
			return {
				username: '',
				password: '',
				codes: [{
				  num: 1,
				  color: '#000',
				  rotate: '10deg',
				  size: '16px'
				}, {
				  num: 2,
				  color: '#000',
				  rotate: '10deg',
				  size: '16px'
				}, {
				  num: 3,
				  color: '#000',
				  rotate: '10deg',
				  size: '16px'
				}, {
				  num: 4,
				  color: '#000',
				  rotate: '10deg',
				  size: '16px'
				}],
				options: [
					'请选择登录用户类型'
				],
                		optionsValues: [
					'',
                    			'yonghu',
				],
				index: 0,
				roleNum:0
			}
		},
		onLoad() {
			let options = ['请选择登录用户类型'];
			let menus = menu.list();
			this.menuList = menus;
			for(let i=0;i<this.menuList.length;i++){
				if(this.menuList[i].hasFrontLogin=='是'){
					options.push(this.menuList[i].roleName);
					this.roleNum++;
				}
			}
			if(this.roleNum==1) {
				this.index = 1;
			}	
			this.options = options;
			this.styleChange()
		},
		methods: {
			styleChange() {
				this.$nextTick(()=>{
					// document.querySelectorAll('.uni-input .uni-input-input').forEach(el=>{
					//   el.style.backgroundColor = this.loginFrom.content.input.backgroundColor
					// })
				})
			},
			onRegisterTap(tableName) {
                uni.setStorageSync("loginTable", tableName);
				this.$utils.jump('../register/register')
			},
			onForgetTap() {
				this.$utils.jump('../forget/forget')
			},
			async onLoginTap() {
                if (!this.username) {
					this.$utils.msg('请输入用户名')
					return
				}
                if (!this.password) {
					this.$utils.msg('请输入用户密码')
					return
				}
                if (!this.optionsValues[this.index]) {
					this.$utils.msg('请选择登陆用户类型')
					return
				}
				let res = await this.$api.login(`${this.optionsValues[this.index]}`, {
					username: this.username,
					password: this.password
				});
                uni.removeStorageSync("useridTag");
				uni.setStorageSync("token", res.token);
				uni.setStorageSync("nickname",this.username);
				uni.setStorageSync("nowTable", `${this.optionsValues[this.index]}`);
				res = await this.$api.session(`${this.optionsValues[this.index]}`);
				// 保存用户id
				uni.setStorageSync("userid", res.data.id);
				if(res.data.vip) {
					uni.setStorageSync("vip", res.data.vip);
				}
				uni.setStorageSync("role", `${this.options[this.index]}`);
				this.$utils.tab('../index/index');
			},
			optionsChange(e) {
				this.index = e.target.value
			}
		}
	}
</script>

<style lang="scss" scoped>
	$color-primary: #b49950;

	.content {
		display: flex;
		justify-content: center;
		flex-direction: column;
		height: calc(100vh - 44px);
		box-sizing: border-box;
	}
	
	.content:after {
		position: fixed;
		top: 0;
		right: 0;
		left: 0;
		bottom: 0;
		content: '';
				background-image: url(http://codegen.caihongy.cn/20220217/2620e8ae20a2414fa14e412fd065e171.png);
				background-attachment: fixed;
		background-size: cover;
		background-position: center;
	}

	.logo {
		text-align: center;

		image {
			height: 200upx;
			width: 200upx;
			margin: 0 0 60upx;
		}
	}

	.uni-form-item {
		margin-bottom: 40upx;
		padding: 0;

		.uni-input {
			font-size: 30upx;
			padding: 7px 0;
		}
	}

	button[type="primary"] {
		background-color: $color-primary;
		border-radius: 0;
		font-size: 34upx;
		margin-top: 60upx;
	}

	.links {
		margin-top: 40upx;
		font-size: 26upx;
		color: #999;

		view {
			display: inline-block;
			vertical-align: top;
			margin: 0 10upx;
		}

		.link-highlight {
			margin: 0;
			color: $color-primary
		}
	}
	
	
</style>

推荐算法代码

//智能推荐商品业务步骤
1.获取当前用户信息
2.判断当前是否有收藏信息
3.如有收藏信息按收藏推荐信息推荐,无推荐信息默认按点击次数

//================以下是相关类和方法==============
//商品信息后端接口类
com.controller.ShangpinxinxiController

/**
 * 商品信息前端智能排序
 */
@IgnoreAuth
@RequestMapping("/autoSort")
public R autoSort(@RequestParam Map<String, Object> params,ShangpinxinxiEntity shangpinxinxi, HttpServletRequest request,String pre){
	EntityWrapper<ShangpinxinxiEntity> ew = new EntityWrapper<ShangpinxinxiEntity>();
	Map<String, Object> newMap = new HashMap<String, Object>();
	Map<String, Object> param = new HashMap<String, Object>();
	boolean flag = false;
	String isRecommend =(String) params.get("isRecommend");
	if("1".equals(isRecommend)){ //是否推荐
		String  userId =  (String) params.get("userId");
		YonghuEntity user = yonghuService.selectById(Long.valueOf(userId));
		params.remove("isRecommend");
		params.remove("userId");
		StringBuffer refIds = new  StringBuffer();
		List<StoreupView>  storeupList = storeupService.selectListView(new EntityWrapper<StoreupEntity>().eq("userid",userId));
		if(storeupList!=null && storeupList.size()>0){
			for(StoreupView storeupView: storeupList){
				refIds.append(storeupView.getRefid()+",");
			}
			flag =true;
			ew.in("id",refIds.toString());
		}
	}
	Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
	while (it.hasNext()) {
		Map.Entry<String, Object> entry = it.next();
		String key = entry.getKey();
		String newKey = entry.getKey();
		if (pre.endsWith(".")) {
			newMap.put(pre + newKey, entry.getValue());
		} else if (StringUtils.isEmpty(pre)) {
			newMap.put(newKey, entry.getValue());
		} else {
			newMap.put(pre + "." + newKey, entry.getValue());
		}
	}
	params.put("sort", "clicknum");
	params.put("order", "desc");
	PageUtils page = shangpinxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinxinxi), params), params));
	return R.ok().put("data", page);
}



//收藏表后端接口
com.controller.StoreupController
/**
 * 收藏表后端保存方法 
 */
@RequestMapping("/save")
public R save(@RequestBody StoreupEntity storeup, HttpServletRequest request){
	storeup.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
	//ValidatorUtils.validateEntity(storeup);
	storeup.setUserid((Long)request.getSession().getAttribute("userId"));
	storeupService.insert(storeup);
	return R.ok();
}

/**
 * 收藏表删除方法
 */
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
	storeupService.deleteBatchIds(Arrays.asList(ids));
	return R.ok();
}




四、数据库表(示范):

数据库表有注释,可以导出数据字典及更新数据库时间,欢迎交流学习

 

五、主要技术介绍:

MVVM模式介绍:

MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。微软的WPF带来了新的技术体验,如Silverlight、音频视频3D动画……,这导致了软件UI层更加细节化、可定制化。同时,在技术层面,WPF也带来了 诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。

B/S体系结构介绍:

B/S结构(Browser/Server,浏览器/服务器模式),是WEB兴起后的一种网络结构模式,WEB浏览器是客户端最主要的应用软件。这种模式统一了客户端,将系统功能实现的核心部分集中到服务器上,简化了系统的开发、维护和使用。客户机上只要安装一个浏览器,如ChromeSafariMicrosoft EdgeNetscape NavigatorInternet Explorer,服务器安装SQL ServerOracleMYSQL等数据库。浏览器通过Web Server同数据库进行数据交互。 

ssm框架介绍:

SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容)。常作为数据源较简单的web项目的框架。

1.8.1 Spring
Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。
Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地`new`一个对象,而是让Spring框架帮你来完成这一切。
1.8.2 SpringMVC
SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。SpringMVC相当于SSH框架中struts。
1.8.3 mybatis
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。

页面发送请求给控制器,控制器调用业务层处理逻辑,逻辑层向持久层发送请求,持久层与数据库交互,后将结果返回给业务层,业务层将处理逻辑发送给控制器,控制器再调用视图展现数据。

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

DCloud公司拥有900万开发者、数百万应用、12亿手机端月活用户、数千款uni-app插件、70+微信/qq群。阿里小程序工具官方内置uni-app,腾讯课堂官方为uni-app录制培训课程,开发者可以放心选择。

六、项目调试学习点击查看

七、项目交流

;