Skip to content

《uniapp类58同城招聘APP软件开发文档》

一、项目概述

  1. 项目名称
  • 类58同城招聘APP(以下简称“本APP”)
  1. 项目背景与目标

    • 随着互联网的发展,招聘市场逐渐向线上转移。本APP旨在为企业和求职者提供一个便捷、高效的招聘与求职平台,类似于58同城招聘板块的功能。通过uniapp框架进行开发,以便能够快速部署到多个平台,包括但不限于安卓和iOS系统。
  2. 目标用户

  • 本APP主要面向企业人力资源部门、企业招聘专员以及各类求职者。前者将使用本APP发布招聘信息、搜索合适的求职者并进行面试邀请等操作;后者则通过APP浏览招聘信息、投递简历等。

二、技术选型

  1. 框架
  • uniapp:选择uniapp是因为它可以使用一套代码构建多个平台的应用程序,大大减少了开发成本和时间。同时,uniapp具有丰富的插件和组件库,方便集成各种功能。
  1. 开发语言
  • 主要使用JavaScript/ES6 + CSS + HTML进行开发,这些是uniapp框架主要使用的语言和标记。在后端方面,可以选择node.js结合express框架或者其它适合的后端技术。
  1. 数据库
  • 推荐使用MySQL数据库。它拥有强大的数据处理能力、稳定性高并且易于维护。用于存储用户信息(企业和求职者)、招聘信息、简历信息等。

三、功能需求

(一)用户模块

  1. 注册与登录
  • 求职者注册:支持手机号注册,需要填写基本信息如姓名、性别、年龄、学历等,创建账号密码或者使用短信验证码登录。

  • 企业注册:企业注册需要提供企业名称、营业执照注册号、联系电话、法定代表人信息等进行审核。审核通过后,可使用账号密码或者短信验证码登录。

  1. 用户信息管理
  • 求职者:求职者可以修改自己的基本信息、补充工作经历、教育背景、技能特长和期望薪资等内容。

  • 企业用户:企业可以更新企业简介、联系方式等信息,并管理已发布的招聘信息。

(二)招聘模块

  1. 职位发布
  • 企业用户能够轻松发布职位信息,包括职位名称、职位类别、工作地点、薪资范围、职位描述、任职要求等。
  1. 职位搜索
  • 求职者可以根据自己的需求搜索职位,支持多种搜索方式,如按职位名称、工作地点、薪资范围等搜索过滤。
  1. 职位推荐
  • 根据求职者的简历信息和浏览历史,为求职者推荐可能感兴趣的职位。

(三)简历投递模块

  1. 求职者可以对感兴趣的职位投递自己的简历,简历包括基本信息、工作经历、教育背景、技能特长等内容的展示板。
  2. 企业用户可以查看收到的简历,标记为感兴趣、不合适等状态,并安排面试等相关操作。

四、页面设计

(一)首页

  1. 求职者视角
  • 显示热门职位推荐、搜索栏、最近浏览职位等。可以采用轮播图展示一些优质企业的招聘广告。
  1. 企业视角
  • 显示公司已发布职位的状态统计(如未处理简历数量等)、发布新职位的入口。

(二)职位列表页

  1. 按照搜索或推荐结果显示职位信息,每个职位信息项显示职位名称、企业名称、薪资范围、工作地点等简要信息。

(三)职位详情页

  1. 详细展示职位的所有信息,包括职位描述、任职要求,并显示企业背景信息等。求职者可以在此页面直接投递简历;企业用户可查看已投递简历情况。

(四)个人中心

  1. 求职者
  • 展示个人基本信息、我的简历、我的投递记录、收藏的职位等内容。可以对简历进行编辑,查看投递后的状态反馈。
  1. 企业
  • 展示企业基本信息、已发布职位列表、收到的简历库、企业资质审核状态等。

五、接口设计

  1. 用户接口
  • 注册接口/api/user/register,接受用户注册信息并返回注册结果(成功或失败以及原因)。

  • 登录接口/api/user/login,接受用户名和密码或者短信验证码登录信息,验证用户身份并返回用户相关信息。

  1. 招聘接口
  • 职位发布接口/api/job/publish,企业用户向该接口提交职位发布数据,返回发布成功或失败结果。

  • 职位搜索接口/api/job/search,接受用户的搜索关键词和过滤条件,返回匹配的职位列表。

  1. 简历投递接口
  • /api/resume/submit,求职者向接口发送简历投递信息(职位ID和自己的简历ID),返回投递是否成功结果。

六、项目进度安排

  1. 项目启动阶段(第1 - 2周)
  • 成立项目团队,召开项目启动会,明确项目目标、人员分工与职责;进行市场调研,完善功能需求文档。
  1. 技术选型与框架搭建(第3 - 4周)
  • 根据项目需求,确定技术选型,搭建uniapp项目框架,搭建后端开发环境,创建数据库架构基础模板。
  1. 功能开发阶段(第5 - 12周)
  • 按照功能模块进行详细开发,包括用户模块、招聘模块、简历投递模块等。
  1. 页面设计与整合阶段(第13 - 14周)
  • 根据页面设计稿优化APP页面,将开发好的功能与页面进行整合测试,修复整合过程中发现的界面结合问题。
  1. 测试与修复阶段(第15 - 16周)
  • 进行全面的功能测试,包括但不限于注册登录、职位发布与搜索、简历投递与管理等功能;进行兼容性测试,保证APP在不同平台和设备上的正常运行;根据测试结果进行问题修复。
  1. 上线准备与发布阶段(第17 - 18周)
  • 准备上线相关的资料,如应用商店的审核资料等;在各大应用商店发布APP。

七、项目测试计划

  1. 功能测试
  • 测试每个功能是否能执行正常操作并且达到预期结果。例如,注册登录是否成功、职位发布是否能够准确存储数据等。
  1. 兼容性测试
  • 测试APP在不同操作系统版本(安卓不同版本、iOS不同版本)、不同设备类型(不同手机型号、不同分辨率)上是否正常运行。
  1. 性能测试
  • 测试APP在大量数据情况下(例如列表加载很多招聘信息时)的加载速度和响应时间;测试服务器在高并发用户(例如大量求职者在高峰时段浏览职位)下的承受能力。

如果你还有其他需求,例如在某个功能上进行更详细的设计、对测试计划进行补充等,可以随时告诉我。

内容由AI大模型生成,仅供参考

一、开发准备

1.下载安装

  • Node.js
  • HBuilderX
  • 微信开发者工具

二、新建项目

1.打开HBuilderX

新建项目

新建uni-app项目

填写项目名称

填写项目路径

下载微信开发者工具

https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

进入 设置-安全

打开服务端口

运行小程序模拟器

三、导航栏页面

tabbar

https://uniapp.dcloud.net.cn/collocation/pages.html##tabbar

vue
<template>
  <view class="content">
    <image class="logo" src="/static/logo.jpg"></image>
    <view class="text-area">
      <text class="title">{{title}}</text>
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        title: '井字棋小游戏'
      }
    },
    onLoad() {

    },
    methods: {

    }
  }
</script>

<style>
  .content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .logo {
    height: 260rpx;
    width: 185rpx;
    margin-top: 200rpx;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 50rpx;
  }

  .text-area {
    display: flex;
    justify-content: center;
  }

  .title {
    font-size: 36rpx;
    color: ##8f8f94;
  }
</style>
vue
<template>
	<view>
		<span>{{title}}</span>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋小游戏'
			}
		},
		onLoad() {
	
		},
		methods: {
	
		}
	}
</script>

<style>
</style>
javascript
{
  "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "井字棋"
      }
    },
    {
      "path": "pages/index/game",
      "style": {
        "navigationBarTitleText": "井字棋"
      }
    }
  ],
    "globalStyle": {
    "navigationBarTextStyle": "black",
      "navigationBarTitleText": "uni-app",
      "navigationBarBackgroundColor": "##F8F8F8",
      "backgroundColor": "##F8F8F8"
  },
  "tabBar": {
    "color": "##7A7E83",
      "selectedColor": "##3cc51f",		
      "borderStyle": "black",
      "backgroundColor": "##ffffff",
      "list": [{
      "pagePath": "pages/index/index",
      "iconPath": "static/image/1.jpg",
      "selectedIconPath": "static/image/2.jpg",
      "text": "首页"
    }, {
      "pagePath": "pages/index/game",
      "iconPath": "static/image/3.jpg",
      "selectedIconPath": "static/image/4.jpg",
      "text": "井字游戏"
    }]
  }

  "uniIdRouter": {}
}

利用canvas组件完成游戏棋盘的导入

https://uniapp.dcloud.net.cn/component/canvas.html

vue
<template>
  <view>
    <span>{{title}}</span>
    <canvas id="id1" canvas-id="firstCanvas"></canvas>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        title: '欢迎来到井字棋小游戏'
      }
    },
    onLoad() {

    },
    methods: {

    }
  }
</script>

<style>
  ##id1{
    background-image: url(../../static/image/bj.png);
    width: 300px;
    height: 450px;
    margin: 30px;
  }
</style>

落子

使用vue2进行开发

RGB十六进制颜色对照表

https://www.toolhelper.cn/Color/RGBToHex

onready和onload的区别

https://blog.csdn.net/xiaoxinxin123456789/article/details/83443719

vue
<template>
	<view>
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到四二学堂',
				context:"",
				colorx:"##DC143C"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   console.log(x+":"+y)
			   
			   this.context.beginPath()
			   this.context.arc(x-30,y-100,40,0,2*Math.PI,false)
			   this.context.setFillStyle(this.colorx)
			   this.context.fill()
			   this.context.draw()
		   }
		}
	}
</script>

<style>
	##id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

交替落子

vue
<template>
	<view>
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋游戏',
				context:"",
				colorx:"##DC143C",
				position:[
					[0,0,0],
					[0,0,0],
					[0,0,0]
				],
				x1:"0",
				y1:"0"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(){
			   // var x=event.touches[0].pageX
			   // var y=event.touches[0].pageY
			   
			   this.b(event)
			   
			   var x=this.x1*80+61
			   var y=this.y1*80+210
			   
			   console.log(x+":"+y)
			   
			   this.context.beginPath()
			   this.context.arc(x-30+40,y-100+40,40,0,2*Math.PI,false)
			   this.context.setFillStyle(this.colorx)
			   this.context.fill()
			   this.context.draw()
		   },
		   b:function(){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   this.x1=parseInt((x-61)/80) 
			   this.y1=parseInt((y-210)/80)
			   
			   if(this.position[this.x1][this.y1]==0){
					if(this.colorx=="##DC143C"){
						this.position[this.x1][this.y1]==1
					}else{
						this.position[this.x1][this.y1]==2
					}
					
					if(this.colorx=="##DC143C"){
						this.colorx="##1676dc"
					}else{
						this.colorx="##DC143C"
					}
				}
		   }
		}
	}
</script>

<style>
	##id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

记忆位置

vue
<template>
	<view>
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋游戏',
				context:"",
				colorx:"##DC143C",
				position:[
					[0,0,0],
					[0,0,0],
					[0,0,0]
				],
				x1:"0",
				y1:"0"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(){
			   // var x=event.touches[0].pageX
			   // var y=event.touches[0].pageY
			   
			   this.b(event)
			   
			   // var x=this.x1*80+61
			   // var y=this.y1*80+210
			   
			   // console.log(x+":"+y)
			   
			   for(var i=0;i<3;i++){
				   for(var j=0;j<3;j++){
					   if(this.position[i][j]!=0){
						   this.context.beginPath()
						   this.context.arc(i*80+61-30+40,j*80+210-100+40,40,0,2*Math.PI,false)
						   if(this.position[i][j]==1){
						   	   this.context.setFillStyle("##DC143C")
						   }
						   else{
						   	   this.context.setFillStyle("##4B0082")
						   }					   
						   this.context.fill()
					   }					   
				   }
			   }
			   
			   // this.context.beginPath()
			   // this.context.arc(x-30+40,y-100+40,40,0,2*Math.PI,false)
			   // this.context.setFillStyle(this.colorx)
			   // this.context.fill()
			   this.context.draw()
			   								  
			},
		   b:function(event){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   this.x1=parseInt((x-61)/80)
			   this.y1=parseInt((y-210)/80)
			   
			   if(this.position[this.x1][this.y1]==0){
				   if(this.colorx=="##DC143C"){
					   this.position[this.x1][this.y1]=1
				   }else{
					   this.position[this.x1][this.y1]=2
				   }
				   
				   if(this.colorx=="##DC143C"){
					   this.colorx="##4B0082"
				   }else{
					   this.colorx="##DC143C"
				   }
			   }
		   }		   
			 
		}
	}
</script>

<style>
	##id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

最终代码

vue
<template>
	<view @tap="d">
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋游戏',
				context:"",
				colorx:"##DC143C",
				position:[
					[0,0,0],
					[0,0,0],
					[0,0,0]
				],
				x1:"0",
				y1:"0",
				isclose:"0"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(event){
			   // var x=event.touches[0].pageX
			   // var y=event.touches[0].pageY
			   
			   if(this.isclose=="1"){
				   this.title="游戏已结束"
				   return
			   }
			   
			   this.b(event)
			   
			   // var x=this.x1*80+61
			   // var y=this.y1*80+210
			   
			   // console.log(x+":"+y)
			   
			   for(var i=0;i<3;i++){
				   for(var j=0;j<3;j++){
					   if(this.position[i][j]!=0){
						   this.context.beginPath()
						   this.context.arc(i*80+61-30+40,j*80+210-100+40,40,0,2*Math.PI,false)
						   if(this.position[i][j]==1){
						   	   this.context.setFillStyle("##DC143C")
						   }
						   else{
						   	   this.context.setFillStyle("##1515c3")
						   }					   
						   this.context.fill()
					   }					   
				   }
			   }
			   
			   // this.context.beginPath()
			   // this.context.arc(x-30+40,y-100+40,40,0,2*Math.PI,false)
			   // this.context.setFillStyle(this.colorx)
			   // this.context.fill()
			   this.context.draw()
			   	
				this.c()
			},
		   b:function(event){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   this.x1=parseInt((x-61)/80)
			   this.y1=parseInt((y-210)/80)
			   
			   if(this.position[this.x1][this.y1]==0){
				   if(this.colorx=="##DC143C"){
					   this.position[this.x1][this.y1]=1
				   }else{
					   this.position[this.x1][this.y1]=2
				   }
				   
				   if(this.colorx=="##DC143C"){
					   this.colorx="##1515c3"
				   }else{
					   this.colorx="##DC143C"
				   }
			   }
		   },
					  
			 c(){
				 //竖一
				 if(this.position[0][0]==this.position[0][1]&&this.position[0][1]==this.position[0][2]){
					this.e(this.position[0][0])
				 }
				 //竖二
				 if(this.position[1][0]==this.position[1][1]&&this.position[1][1]==this.position[1][2]){
				 	this.e(this.position[1][0])
				 }
				 //竖三
				 if(this.position[2][0]==this.position[2][1]&&this.position[2][1]==this.position[2][2]){
				 	this.e(this.position[2][0])
				 }
				 //横一
				 if(this.position[0][0]==this.position[1][0]&&this.position[1][0]==this.position[2][0]){
				 	this.e(this.position[0][0])
				 }
				 //横二
				 if(this.position[0][1]==this.position[1][1]&&this.position[1][1]==this.position[2][1]){
				 	this.e(this.position[0][1])
				 }
				 //横三
				 if(this.position[0][2]==this.position[1][2]&&this.position[1][2]==this.position[2][2]){
				 	this.e(this.position[0][2])
				 }
				 //左斜
				 if(this.position[0][0]==this.position[1][1]&&this.position[1][1]==this.position[2][2]){
					this.e(this.position[0][0])
				 }
				 //右斜
				 if(this.position[0][2]==this.position[1][1]&&this.position[1][1]==this.position[2][0]){
				 	this.e(this.position[0][2])
				 }
				
				var sum=0
				for(var i=0;i<3;i++){
					for(var j=0;j<3;j++){
						if(this.position[i][j]!=0){
							sum+=1
						}
					}
				}
				
				if(sum==9&&this.isclose==0){
					this.title="和棋,点我重开"
				}
			 },
			 e(a){
				 if(a!=0){
					 this.isclose=1
					 if(a==1){
						 this.title="红方胜利,点我重开"
						 // alert("红方胜利")
					 }else{
						 this.title="蓝方胜利,点我重开"
						 // alert("蓝方胜利")
					 }
				 }
			 },
			 d(event){
				 var x=event.touches[0].pageX
				 var y=event.touches[0].pageY
				 if(x>=0&&x<=210&&y>=0&&y<=20){
					 for(var i=0;i<3;i++){
						 for(var j=0;j<3;j++){
							 this.position[i][j]=0
						 }
					 }
					 this.isclose="0"
					 this.title="欢迎来到井字棋游戏"
					 
					 this.context.beginPath()
					 this.context.draw()
				 }
			 }
		}
	}
</script>

<style>
	##id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

uni-app项目打包成apk(本地打包篇)

blog.csdn.net成就一亿技术人!

最近可能要接一个uni-app的项目,之前没有接触过,因此学习了一下,好在uni-app基本算是vue和微信小程序的结合体,所以写代码方面问题不是太多,不懂的百度一下基本都能处理。写完demo之后,demo的内容应该能告诉客户我可以做,但我一开始是先用手机录制视频,然后把录制的视频给客户看的。但这样不够好,因为不知道打包成apk后会遇到什么问题,因此还是自己摸索着去打包成可安装的apk,直接让客户试用。

下面的步骤,不要跳步,一步步看,肯定是可以成功的。

{#t0}1. 本次用到的工具:

  1. 代码开发工具:HBuilder X
  2. apk打包工具:Android Studio
  3. apk打包SDK:Android离线SDK(下载地址:Android离线SDK
  4. 生成签名证书的工具:jdk1.8 (网上说只要装jre就行,但jdk里包含jre,所以直接装jdk吧,jdk装完要配置环境变量,jdk环境变量的配置可以看这个:jdk环境变量配置
  5. 生成appkey的网站:DCLOUD的开发者中心(网址:开发者中心

{#t1}2. 导出前的配置

HBuilder X 中打开uni-app项目中的 mainifest.json文件,会弹出来一些可配置的内容,这次我们简单一点,只配置基础配置。其中 **uni-app应用标识(AppID)**如果默认没有的话,点后面的 重新获取即可,它会警告你,不过点了没事,且会为你生成一个AppID。然后就是选择开发使用的vue版本,按实际选择即可,其它的貌似可以随便填(如果只是做打包测试的话)。

{#t2}3. 导出uni-app项目供打包使用

项目代码在自己手机上测试运行成功后,我们需要把uni-app的项目导出。点击 HBuilder X 上方的 发行 -->原生App-本地打包 -->生成本地打包App资源 即可。如果是第一次点击,可能会提示你装什么东西,按提示的来,同意安装就可以了。

导出成功后,HBuilder X 下方的控制台会告诉你导出路径。至此,HBuilder X的任务完成。

{#t3} 4. 下载Android离线SDK

Android离线SDK下载地址:Android离线SDK

这个sdk可能不止用来打包apk,但目前我只是用来打包apk。

{#t4} 5. 将HBuilder X导出的文件夹移动到离线SDK中

将刚才 HBuilder X 导出的以AppID命名的文件夹(www文件夹的上一级)整个移动到离线SDK的HBuilder-Integrate-AS\simpleDemo\src\main\assets\apps路径下,该路径下默认会有一个叫 __UNI__A 的文件夹,这个直接删除,我们用不到。

{#t5} 6. Android Studio 导入SDK中的示例项目

如果第一次安装 Android Studio,安装过程中会提示你缺啥好像,记不太清了,直接cancel那个提示,然后跟着引导一步步安装就行了,安装结束后,好像也没什么问题。

接着导入离线SDK中的 HBuilder-Integrate-AS 文件夹到 Android Studio 中。注意:文件路径中不要出现中文!否则会报错!

{#t6}7. 修改dcloud_control.xml 中的 appid

接下来,别纠结截图中我 Android Studio的文件结构为什么你不一样,截图中有些文件夹或者路径好像被隐藏了,这不重要,我只是来打包的。

找到 assets/data 下的 dcloud_control.xml文件,点开它,将文件中appid的值,改成 HBuilder X中生成的appid。appid记不住没关系,还记得第5步中让你移动的那个文件夹吗,它的文件名就是appid

{#t7}8. 生成Android证书签名

这一步我参考了别人的文章,所以不多讲了,按他的步骤做(jdk环境变量的配置虽然他文章里写了,小白最好还是看这个:jdk环境变量配置),记下生成证书的文件路径、证书的SHA1安全码、证书的alias(别名)以及设置的两个密码(怕忘记,两个密码设一样的),后续步骤会用得到。参考网址(生成Android证书签名)。

{#t8}9. 生成appkey

前往 DCLOUD 的开发者中心(网址:开发者中心),如果按照我的步骤做,那在第2步 HBuilder X中生成appid后,就能在开发者中心我的应用中看到这条应用,点击应用名称会跳转到该条应用的管理页面。

点击上方的 离线打包Key管理按钮,进入生成appkey的菜单。我的这个菜单是已经生成appkey的,所以会和你第一次点进来有所不同,不用担心。

**选择平台:**我们选择Android,因为我们这次是打包apk。

**Android包名:*包名不能随便写,否则安装apk打开后会报错! 它的值在离线SDK的 \HBuilder-Integrate-AS\simpleDemo\src\main*AndroidManifest.xml 中,没改过的话应该跟我一样,是 com.android.simple

Android证书签名SHA1:第8步中让你记下的SHA1安全码。

这些填完后,点确认还是啥的,应该就可以生成appkey了。

{#t9}10. 在 AndroidManifest.xml 中配置appKey

回到Android Studio ,在 AndroidManifest.xml 中配置appKey

{#t10}11. 打包apk

现在万事俱备,只剩打包了,点击 Android Studio 上方的 Build-->Generate Signed Bundle / APK...

弹出打包窗口,选择 APK,然后点击 Next

点击 Choose existing...,选择第8步让你记下的证书存放路径,Key store path就会自动填充,Key store password、Key alias、key password ,这三项也在第8步中设置。如果两个password记不住了,那就按第8步的教程重新生成一个证书吧。Remember passwords 根据自己需要吧(小白还是勾吧,记住密码)。全部填完后点击下方 Next

最后就是选择导出路径,然后选择 release,然后点击下方Finish

导出成功后,Android Studio 下方的 Build控制台会提示 BUILD SUCCESSFUL

然后就可以在导出路劲的release文件夹里找到打包好的apk文件了,截图里的是默认导出路径,你可以在release的时候选择你的导出路径。

然后在手机上安装刚才的apk并打开,如果正常打开,那基本就成功了。

我在摸索的时候,打包成功后,安装到手机,打开app的时候提示appkey不存在或配置错误,后来发现是第9步生成appkey的时候,包名写错了,一定要和 AndroidManifest.xml文件中的包名一样。

更多进阶的内容,等我摸索完再发文章,多多点赞,感谢支持!

跳转到 Cubox 查看

一、环境搭建

HBuilderX

二、开始

打开HBuilderX

新建项目

新建uni-app项目

填写项目名称

填写项目路径

下载微信开发者工具

https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

进入 设置-安全

打开服务端口

运行小程序模拟器

三、添加新页面

tabbar

https://uniapp.dcloud.net.cn/collocation/pages.html#tabbar

vue
<template>
  <view class="content">
    <image class="logo" src="/static/logo.jpg"></image>
    <view class="text-area">
      <text class="title">{{title}}</text>
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        title: '井字棋小游戏'
      }
    },
    onLoad() {

    },
    methods: {

    }
  }
</script>

<style>
  .content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .logo {
    height: 260rpx;
    width: 185rpx;
    margin-top: 200rpx;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 50rpx;
  }

  .text-area {
    display: flex;
    justify-content: center;
  }

  .title {
    font-size: 36rpx;
    color: #8f8f94;
  }
</style>
vue
<template>
	<view>
		<span>{{title}}</span>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋小游戏'
			}
		},
		onLoad() {
	
		},
		methods: {
	
		}
	}
</script>

<style>
</style>
javascript
{
  "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "井字棋"
      }
    },
    {
      "path": "pages/index/game",
      "style": {
        "navigationBarTitleText": "井字棋"
      }
    }
  ],
    "globalStyle": {
    "navigationBarTextStyle": "black",
      "navigationBarTitleText": "uni-app",
      "navigationBarBackgroundColor": "#F8F8F8",
      "backgroundColor": "#F8F8F8"
  },
  "tabBar": {
    "color": "#7A7E83",
      "selectedColor": "#3cc51f",		
      "borderStyle": "black",
      "backgroundColor": "#ffffff",
      "list": [{
      "pagePath": "pages/index/index",
      "iconPath": "static/image/1.jpg",
      "selectedIconPath": "static/image/2.jpg",
      "text": "首页"
    }, {
      "pagePath": "pages/index/game",
      "iconPath": "static/image/3.jpg",
      "selectedIconPath": "static/image/4.jpg",
      "text": "井字游戏"
    }]
  }

  "uniIdRouter": {}
}

https://uniapp.dcloud.net.cn/component/canvas.html

vue
<template>
  <view>
    <span>{{title}}</span>
    <canvas id="id1" canvas-id="firstCanvas"></canvas>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        title: '欢迎来到井字棋小游戏'
      }
    },
    onLoad() {

    },
    methods: {

    }
  }
</script>

<style>
  #id1{
    background-image: url(../../static/image/bj.png);
    width: 300px;
    height: 450px;
    margin: 30px;
  }
</style>

落子

使用vue2进行开发

RGB十六进制颜色对照表

https://www.toolhelper.cn/Color/RGBToHex

onready和onload的区别

https://blog.csdn.net/xiaoxinxin123456789/article/details/83443719

vue
<template>
	<view>
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到四二学堂',
				context:"",
				colorx:"#DC143C"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   console.log(x+":"+y)
			   
			   this.context.beginPath()
			   this.context.arc(x-30,y-100,40,0,2*Math.PI,false)
			   this.context.setFillStyle(this.colorx)
			   this.context.fill()
			   this.context.draw()
		   }
		}
	}
</script>

<style>
	#id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

交替落子

vue
<template>
	<view>
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋游戏',
				context:"",
				colorx:"#DC143C",
				position:[
					[0,0,0],
					[0,0,0],
					[0,0,0]
				],
				x1:"0",
				y1:"0"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(){
			   // var x=event.touches[0].pageX
			   // var y=event.touches[0].pageY
			   
			   this.b(event)
			   
			   var x=this.x1*80+61
			   var y=this.y1*80+210
			   
			   console.log(x+":"+y)
			   
			   this.context.beginPath()
			   this.context.arc(x-30+40,y-100+40,40,0,2*Math.PI,false)
			   this.context.setFillStyle(this.colorx)
			   this.context.fill()
			   this.context.draw()
		   },
		   b:function(){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   this.x1=parseInt((x-61)/80) 
			   this.y1=parseInt((y-210)/80)
			   
			   if(this.position[this.x1][this.y1]==0){
					if(this.colorx=="#DC143C"){
						this.position[this.x1][this.y1]==1
					}else{
						this.position[this.x1][this.y1]==2
					}
					
					if(this.colorx=="#DC143C"){
						this.colorx="#1676dc"
					}else{
						this.colorx="#DC143C"
					}
				}
		   }
		}
	}
</script>

<style>
	#id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

记忆位置

vue
<template>
	<view>
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋游戏',
				context:"",
				colorx:"#DC143C",
				position:[
					[0,0,0],
					[0,0,0],
					[0,0,0]
				],
				x1:"0",
				y1:"0"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(){
			   // var x=event.touches[0].pageX
			   // var y=event.touches[0].pageY
			   
			   this.b(event)
			   
			   // var x=this.x1*80+61
			   // var y=this.y1*80+210
			   
			   // console.log(x+":"+y)
			   
			   for(var i=0;i<3;i++){
				   for(var j=0;j<3;j++){
					   if(this.position[i][j]!=0){
						   this.context.beginPath()
						   this.context.arc(i*80+61-30+40,j*80+210-100+40,40,0,2*Math.PI,false)
						   if(this.position[i][j]==1){
						   	   this.context.setFillStyle("#DC143C")
						   }
						   else{
						   	   this.context.setFillStyle("#4B0082")
						   }					   
						   this.context.fill()
					   }					   
				   }
			   }
			   
			   // this.context.beginPath()
			   // this.context.arc(x-30+40,y-100+40,40,0,2*Math.PI,false)
			   // this.context.setFillStyle(this.colorx)
			   // this.context.fill()
			   this.context.draw()
			   								  
			},
		   b:function(event){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   this.x1=parseInt((x-61)/80)
			   this.y1=parseInt((y-210)/80)
			   
			   if(this.position[this.x1][this.y1]==0){
				   if(this.colorx=="#DC143C"){
					   this.position[this.x1][this.y1]=1
				   }else{
					   this.position[this.x1][this.y1]=2
				   }
				   
				   if(this.colorx=="#DC143C"){
					   this.colorx="#4B0082"
				   }else{
					   this.colorx="#DC143C"
				   }
			   }
		   }		   
			 
		}
	}
</script>

<style>
	#id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>

最终代码

vue
<template>
	<view @tap="d">
		<span>{{title}}</span>
		<canvas id="id1" canvas-id="firstCanvas" @tap="a"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '欢迎来到井字棋游戏',
				context:"",
				colorx:"#DC143C",
				position:[
					[0,0,0],
					[0,0,0],
					[0,0,0]
				],
				x1:"0",
				y1:"0",
				isclose:"0"
			}
		},
		
		methods: {
	       onReady(){
			   this.context=uni.createCanvasContext('firstCanvas')
			   this.context.setFillStyle(this.colorx)
		   },
		   
		   a(event){
			   // var x=event.touches[0].pageX
			   // var y=event.touches[0].pageY
			   
			   if(this.isclose=="1"){
				   this.title="游戏已结束"
				   return
			   }
			   
			   this.b(event)
			   
			   // var x=this.x1*80+61
			   // var y=this.y1*80+210
			   
			   // console.log(x+":"+y)
			   
			   for(var i=0;i<3;i++){
				   for(var j=0;j<3;j++){
					   if(this.position[i][j]!=0){
						   this.context.beginPath()
						   this.context.arc(i*80+61-30+40,j*80+210-100+40,40,0,2*Math.PI,false)
						   if(this.position[i][j]==1){
						   	   this.context.setFillStyle("#DC143C")
						   }
						   else{
						   	   this.context.setFillStyle("#1515c3")
						   }					   
						   this.context.fill()
					   }					   
				   }
			   }
			   
			   // this.context.beginPath()
			   // this.context.arc(x-30+40,y-100+40,40,0,2*Math.PI,false)
			   // this.context.setFillStyle(this.colorx)
			   // this.context.fill()
			   this.context.draw()
			   	
				this.c()
			},
		   b:function(event){
			   var x=event.touches[0].pageX
			   var y=event.touches[0].pageY
			   
			   this.x1=parseInt((x-61)/80)
			   this.y1=parseInt((y-210)/80)
			   
			   if(this.position[this.x1][this.y1]==0){
				   if(this.colorx=="#DC143C"){
					   this.position[this.x1][this.y1]=1
				   }else{
					   this.position[this.x1][this.y1]=2
				   }
				   
				   if(this.colorx=="#DC143C"){
					   this.colorx="#1515c3"
				   }else{
					   this.colorx="#DC143C"
				   }
			   }
		   },
					  
			 c(){
				 //竖一
				 if(this.position[0][0]==this.position[0][1]&&this.position[0][1]==this.position[0][2]){
					this.e(this.position[0][0])
				 }
				 //竖二
				 if(this.position[1][0]==this.position[1][1]&&this.position[1][1]==this.position[1][2]){
				 	this.e(this.position[1][0])
				 }
				 //竖三
				 if(this.position[2][0]==this.position[2][1]&&this.position[2][1]==this.position[2][2]){
				 	this.e(this.position[2][0])
				 }
				 //横一
				 if(this.position[0][0]==this.position[1][0]&&this.position[1][0]==this.position[2][0]){
				 	this.e(this.position[0][0])
				 }
				 //横二
				 if(this.position[0][1]==this.position[1][1]&&this.position[1][1]==this.position[2][1]){
				 	this.e(this.position[0][1])
				 }
				 //横三
				 if(this.position[0][2]==this.position[1][2]&&this.position[1][2]==this.position[2][2]){
				 	this.e(this.position[0][2])
				 }
				 //左斜
				 if(this.position[0][0]==this.position[1][1]&&this.position[1][1]==this.position[2][2]){
					this.e(this.position[0][0])
				 }
				 //右斜
				 if(this.position[0][2]==this.position[1][1]&&this.position[1][1]==this.position[2][0]){
				 	this.e(this.position[0][2])
				 }
				
				var sum=0
				for(var i=0;i<3;i++){
					for(var j=0;j<3;j++){
						if(this.position[i][j]!=0){
							sum+=1
						}
					}
				}
				
				if(sum==9&&this.isclose==0){
					this.title="和棋,点我重开"
				}
			 },
			 e(a){
				 if(a!=0){
					 this.isclose=1
					 if(a==1){
						 this.title="红方胜利,点我重开"
						 // alert("红方胜利")
					 }else{
						 this.title="蓝方胜利,点我重开"
						 // alert("蓝方胜利")
					 }
				 }
			 },
			 d(event){
				 var x=event.touches[0].pageX
				 var y=event.touches[0].pageY
				 if(x>=0&&x<=210&&y>=0&&y<=20){
					 for(var i=0;i<3;i++){
						 for(var j=0;j<3;j++){
							 this.position[i][j]=0
						 }
					 }
					 this.isclose="0"
					 this.title="欢迎来到井字棋游戏"
					 
					 this.context.beginPath()
					 this.context.draw()
				 }
			 }
		}
	}
</script>

<style>
	#id1{
		background-image: url(../../static/image/bj.png);
		width: 300px;
		height: 450px;
		margin: 30px;
	}
</style>