# org-app
**Repository Path**: zyjun/org-app
## Basic Information
- **Project Name**: org-app
- **Description**: APP机构端
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2021-09-24
- **Last Updated**: 2023-07-26
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# org-app(机构端APP)
项目相关
> 测试项目部署在`uniCloud`上面,需要将生成的`index.html`重命名成`index-backup.html`,再将`doc/index.html`放入`dist`文件夹中。
* [蓝湖地址 lanhuapp.com][lanhuapp]
* [接口文档地址][apidoc] `账号:zyj 密码:123456`
* [代码地址][gitee]



## 一、项目介绍
此`uni-app`项目是使用`vue-cli`方式创建的`uni-app项目`。这种方式的优点就是创建后可以使用其他自己熟悉的开发工具进行开发, 我是使用`IntelliJ IDEA`开发的,如果你更熟悉`vscode`
你也可以使用`vscode`进行开发。
因为`uni-app`的一些方法用起来很繁琐,组件支持的不太好。这里使用的第三方库是[**uviewui**][uviewui]
`iconfont`在真机不显示问题:[iconfont-bug][iconfont-bug]
### 1.项目运行
* 1.从git仓库clone代码到本地:`git clone https://gitee.com/zyjun/org-app.git`
* 2.使用命令行进入本地项目路径:`cd /org-app`
* 3.使用命令行执行安装依赖包操作:`npm install`
* 4.使用命令行运行项目到本地:`npm run serve`
* 5.运行成功后会提示`> App running at: - Local: `http://localhost:8080/art-h5/
* 6.使用浏览器打开上面的路径,`右键`->`检查`->`选择尺寸:iPhone6/7/8`
### 2.页面创建
* 1.在`src/pages/`路径下,分模块选择在`home`或`notice`或`mine`下创建对应的vue文件
* 2.在`src/pages.json`文件中添加页面配置。这里使用分包配置,选择`subPackages`下对应的模块添加路径。
* 3.在`src/router.js`文件中添加页面路径配置。
### 3.页面跳转
* 1.导入`router.js`中的页面路径
```
import {addCourse} from "@/router.js"
```
* 2.使用`uviewui`的`route`方法跳转
```
this.$u.route({url: addCourse})
```
### 4.页面尺寸适配
项目尺寸适配使用最常用的`375*667`,在使用蓝湖时选择设计图之后,选择右边的自定义->指定宽度`375px`

### 5.页面网络请求
* 网络请求统一封装到`src/api/request.js`文件中
* 登录接口会保存`token`,之后别的网络请求会将`token`拼接到`header`的`Authorization`属性中。
* 分模块将网络请求方法写到`src/api/`下的各模块的对应类中。
* 
* 一个模块下的不同界面写成对应的`class`类,界面中使用到的接口都写的对应的方法中。
* 这样`分模块-分界面`的管理接口会很方便,如果有需要公共的接口也可以提取到一个公共类里面进行使用。
* 在界面中使用时,导入对应的接口类`如CourseListApi`,创建对应的接口对象`engine`使用。
```
import {CourseListApi} from "@/api/courseList.js"
let engine = new CourseListApi()
engine.getCourseCateList().then(res => {
let cateList = res.data.map(item => {
return {value: item.id, label: item.title}
})
cateList.unshift({value: 0, label: '全部课程'})
this.cateList = cateList
this.selectCateValue = this.cateList[0].value
this.refreshData()
})
```
### 6.页面上拉加载更多
* 可以参考`src/pages/home/teacher/teacher`界面的写法
* 可以直接复制`refreshData`、`loadMore`、`loadFinish`三个方法,修改其中的几个方法为自己的方法即可
```
refreshData() {
this.loadingObj.current = 1
this.loadingObj.status = ''
this.courseList = [] //这里需要改成业务数组
this.getCourseList() //这里需要改成请求业务数据的方法
},
```
```
loadMore() {
if (this.loadingObj.current >= this.loadingObj.total) {
this.loadingObj.status = 'nomore'
} else {
this.loadingObj.status = 'loading'
this.loadingObj.current = this.loadingObj.current + 1
this.getCourseList() //这里需要改成请求业务数据的方法
}
},
```
```
loadFinish(total) {
this.loadingObj.total = Math.ceil(total / 10)
this.loadingObj.status = ''
if (this.loadingObj.current >= this.loadingObj.total
&& this.courseList.length > 0) { //这里需要改成业务数组
this.loadingObj.status = 'nomore'
}
},
```
* 在`onLoad`生命周期中调用`refreshData`方法,在`onReachBottom`钩子中调用`loadMore`方法。(不同界面可能有差异)
* 在`data()`方法中配置`loadingObj`属性
* 在请求业务数据逻辑时,页码参数使用`this.loadingObj.current`,对返回的数据使用`concat`拼接,使用`loadFinish`方法获得总页码数
```
getCourseList() {
engine.getCourseList({page: this.loadingObj.current, cate_id: this.selectCateValue}).then(res => {
this.courseList = this.courseList.concat(res.data)
this.loadFinish(res.total)
})
},
```
* 使用`block`判断业务数据是否存在,不存在显示`暂无数据`。(同时使用`v-for`和`v-if`会存在性能问题)
使用`u-loadmore`组件显示页面分页状态。
```
......
暂无数据
```
### 7.页面自定义标题栏实现
* 带搜索输入框的可以参考`src/pages/home/teacher/teacher`界面的写法
```
```
* 带背景图片的标题栏可以参考`src\pages\home\teacher\teacherInfo.vue`

### 8.页面图片上传功能(这里后期可以提取成一个公共的组件)
* 可以参考`src/pages/home/enter/editInfo/editInfo.vue`页面的写法
 
* 导入`uploadFile`方法
```
import uploadFile from '@/common/ossutil/uploadFile.js'
```
* 调用`uni.chooseImage`方法选择图片,调用`uploadFile`方法上传图片到阿里云oss,调用`saveImg`方法(调接口) 保存图片路径到自己的数据库。
* 页面使用的图片路径是逻辑字段`form.image`(和接口参数没有关系),`form.avatar`是接口需要的`图片id`字段
### 9.自定义`vue全局方法`使用
* 在`src/common/plugin.js`中定义了全局方法`$u.routeDelay`、`$u.pageCallBackDelay`
* `routeDelay`方法是延迟跳转方法。在二级界面需要`toast`之后再返回到上级界面时使用。
* `pageCallBackDelay`方法时延迟调用上级界面的方法。在二级界面修改数据后,通知一级界面刷新时使用。
* `pageRoute, call, params`三个参数分别对应:`一级页面路径、一级界面刷新数据方法、回传参数`
* 它两基本是同时出现,例如:`src/pages/home/goods/addGoods.vue`界面,添加商品后刷新商品列表界面
```
addGoods(status) {//status:状态【1上架0下架】
engine.addGoods({status, ...this.form}).then(res => {
this.$u.toast(res.message)
if (res.code === 200) {
this.$u.pageCallBackDelay(goodsList,'refreshData','')
this.$u.routeDelay({type: 'back'})
}
}).catch(err => this.$u.toast(err.message))
},
```
* 部分数据回传方法没有使用上面的`pageCallBackDelay`,后期可改成统一的方便管理
* 可参考`src/pages/home/intentStudent/addIntentStudent.vue`添加意向学员->
`src/pages/home/staffList/staffList.vue`选择顾问
```
confirmSelect() {
let selTea = this.teacherList.find(tea => tea.id === this.selectTeaId)
let pages = getCurrentPages();
console.log("confirmSelect", this.from, pages)
let createClassPage = pages.find(page => page.route === this.from)
createClassPage.$vm.confirmSelectAdviser(selTea);//重点$vm
this.$u.route({type: 'back'})
},
```
### 10.`uviewui`第三方库常用组件及方法
* toast方法:`this.$u.toast("报名成功!")`
* route方法:`this.$u.route({url: approvalOpinion, params: this.breakObj})`
* u-form组件
* u-select组件
* u-search组件
* u-radio-group组件
* u-switch组件
* u-loadmore组件
* u-tabs组件
## 二、项目打包
使用`Hbuilder`打开`org-app`项目,打开项目中任意文件。
### 1.项目打包成APP
* 点击`Hbuilder`工具栏的`发行`-`原生App-云打包`,在弹出的界面配置相关信息
  
* Android和IOS的包名都是:`com.art.org`
* Android配置:使用公共测试证书打包就行,影响不大。
* IOS配置:
* 证书私钥密码:`lvdong`
* 证书profile文件:项目中的该文件`doc/LDJYUniappADHoc.mobileprovision`
* 私钥证书:项目中的该文件`doc/正式证书.p12`
* 打包后的APP上传到[蒲公英托管平台][pgyer]即可。
### 2.打包成wgt包(h5资源包)
> `wgt包`和`App`的区别如下:
* 每天的`App云打包`次数有限制,而且比较慢。打包的app是一个完整的可直接给手机使用的`应用文件`。
* `wgt包`只是一个`h5资源包`,是项目的`vue文件`打包成`h5资源`供app使用。**使用前提:**
* 需要手机已经安装好`App`
* 并且项目中已经使用更新功能(后台有版本更新接口;uni-app项目调用版本更新接口并下载`wgt资源包`,下载后再安装)
* 正常的流程:`手机已经安装uni-app的App`->`uni-app项目新加功能后打包成wgt包`->`将wgt包放到服务器并添加版本号`
->`手机打开App通过接口检测到版本更新,下载更新的wgt资源包,安装wgt资源包,退出App重新进入更新生效`
* `App打包`产生的`应用文件`包含两部分:
* 1.是手机加载`uni-app`的h5的`基础运行框架`,包括基础的`webview`以及 在项目的`manifest.json`中配置的`App模块配置`、`App权限配置`等`对App框架的配置`
* 2.是应用页面功能的h5资源文件,实现`界面显示层`的相关功能。
* 通过`App打包`的版本号和`wgt打包`的版本号是对应各自的版本号,两者之间没有关系。具体可参考:`src/pages/mine/mine.vue`
* 但是在`uni-app`中使用到一些原生框架层的能力时,如`VideoPlayer-App模块`。 在使用`wgt包`时需要在`已经将VideoPlayer打包的App`上面使用,否则视频播放能力不能使用。
* 本项目中使用的是`unicloud`集成好的版本更新,有兴趣的可以自行尝试一下。
* 相关文档可参考`uniCloud`官方文档
* 相关客户端代码可参考:`src/uni_modules/uni-upgrade-center-app/utils/check-update.js`
* 相关管理端代码可参考:`https://gitee.com/zyjun/org-app-version-pc.git`
## 三、项目运行到手机调试
在一些个别情况下,uni-app需要在手机APP中才能看到不同的效果。比如:`自定义状态栏`、`版本更新`等功能。 使用`Hbuilder`打开`org-app`项目,打开项目中任意文件。
> 需要手机或者模拟器连接电脑,并打开发者模式
### 1.标准运行基座
大部分情况使用这种模式(默认的模式)运行到手机或者模拟器进行调试即可。
* 点击`Hbuilder`工具栏的`运行`->`运行到手机或模拟器`->`选择手机`即可运行项目到手机。
### 2.自定义基座
在需要使用`自定义包名`的app环境下进行调试时,需要使用自定义基座运行。比如`App版本更新`、`微信分享`等
* 点击`Hbuilder`工具栏的`运行`->`运行到手机或模拟器`->`制作自定义基座配置包名等`
* 点击`Hbuilder`工具栏的`运行`->`运行到手机或模拟器`->`运行基座选择`->`自定义调试基座`
* 点击`Hbuilder`工具栏的`运行`->`运行到手机或模拟器`->`选择手机`即可运行项目到手机。
[lanhuapp]:https://lanhuapp.com/url/SeZUl-T587O
[apidoc]:https://apidoc.yunmeitiweb.com/web/#/15
[gitee]:https://gitee.com/zyjun/org-app.git
[quickstart-cli]:https://uniapp.dcloud.io/quickstart-cli
[自定义调试基座]:https://ask.dcloud.net.cn/article/35115
[uviewui]:https://www.uviewui.com/js/route.html
[pgyer]:https://www.pgyer.com/manager
[iconfont-bug]:https://blog.csdn.net/qq_24343389/article/details/112568666