Repository: zhang2657977442/wuyou-frontend Branch: master Commit: 4ba119db48ba Files: 176 Total size: 1.1 MB Directory structure: gitextract_1uh0qe7r/ ├── .gitignore ├── App.vue ├── AppEntryController.js ├── LICENSE ├── README.md ├── apis/ │ ├── http.js │ └── index.js ├── common/ │ ├── auth.js │ ├── cityData.js │ ├── data.js │ ├── date.js │ ├── db.js │ ├── graceChecker.js │ ├── modalHelper.js │ ├── router.js │ └── utils.js ├── components/ │ ├── GoEasyAudioPlayer/ │ │ └── GoEasyAudioPlayer.vue │ ├── QS-tabs/ │ │ └── QS-tabs.vue │ ├── m-ad/ │ │ └── m-ad.vue │ ├── m-cc-btn/ │ │ └── m-cc-btn.vue │ ├── m-cc-popup/ │ │ └── m-cc-popup.vue │ ├── m-cell/ │ │ └── m-cell.vue │ ├── m-codedialog/ │ │ └── m-codedialog.vue │ ├── m-company/ │ │ └── m-company.vue │ ├── m-empty-data/ │ │ └── m-empty-data.vue │ ├── m-fail/ │ │ └── m-fail.vue │ ├── m-format-card/ │ │ └── m-format-card.vue │ ├── m-format-phone/ │ │ └── m-format-phone.vue │ ├── m-icon/ │ │ ├── m-icon.css │ │ └── m-icon.vue │ ├── m-input/ │ │ └── m-input.vue │ ├── m-page-view/ │ │ └── m-page-view.vue │ ├── m-popup/ │ │ └── m-popup.vue │ ├── m-popup-header/ │ │ └── m-popup-header.vue │ ├── m-position/ │ │ └── m-position.vue │ ├── m-qrcode/ │ │ ├── m-qrcode.vue │ │ └── qrcode.js │ ├── m-swiper/ │ │ └── m-swiper.vue │ ├── m-textarea/ │ │ └── m-textarea.vue │ ├── m-upimg/ │ │ ├── m-upimg.1.vue │ │ └── m-upimg.vue │ ├── mpvue-citypicker/ │ │ ├── city-data/ │ │ │ ├── area.js │ │ │ ├── city.js │ │ │ └── province.js │ │ └── mpvueCityPicker.vue │ ├── mpvue-picker/ │ │ └── mpvue-picker.vue │ ├── sunui-grand/ │ │ └── sunui-grand.vue │ ├── uni-load-more/ │ │ ├── readme.md │ │ └── uni-load-more.vue │ ├── uni-popup1/ │ │ └── uni-popup.vue │ └── yzb/ │ ├── yzb-about.vue │ ├── yzb-apply.vue │ ├── yzb-browse.vue │ ├── yzb-classification.vue │ ├── yzb-connected.vue │ ├── yzb-filterDropdown.vue │ ├── yzb-grid.vue │ ├── yzb-notice.vue │ └── yzb-resume.vue ├── config/ │ ├── assets.config.js │ ├── constData.config.js │ ├── formRule.config.js │ ├── index.config.js │ └── routes.config.js ├── lib/ │ ├── EmojiDecoder.js │ ├── imservice.js │ └── restapi.js ├── main.js ├── manifest.json ├── pages/ │ ├── chat/ │ │ ├── chat.vue │ │ ├── notice/ │ │ │ ├── noticeDetail.vue │ │ │ └── notices.vue │ │ └── privateChat.vue │ ├── common/ │ │ ├── industry.vue │ │ └── post.vue │ ├── company/ │ │ ├── detail.vue │ │ ├── list.vue │ │ └── resumeList.vue │ ├── login/ │ │ ├── bindphone.vue │ │ ├── index.vue │ │ ├── login.vue │ │ ├── reg.vue │ │ └── success.vue │ ├── main/ │ │ ├── main.vue │ │ └── search.vue │ ├── position/ │ │ ├── detail.vue │ │ └── list.vue │ ├── type/ │ │ └── type.vue │ └── user/ │ ├── aboutUs.vue │ ├── apply.vue │ ├── browse.vue │ ├── collect.vue │ ├── company/ │ │ ├── auth.vue │ │ ├── company.vue │ │ ├── enter.vue │ │ ├── position-edit.vue │ │ └── positions.vue │ ├── connected.vue │ ├── contactUs.vue │ ├── help.vue │ ├── helpcenterDetails.vue │ ├── hideSetting.vue │ ├── person/ │ │ ├── edit-edu.vue │ │ ├── edit-expect.vue │ │ ├── edit-pro-content.vue │ │ ├── edit-pro.vue │ │ ├── edit-skill.vue │ │ ├── edit-work-content.vue │ │ ├── edit-work.vue │ │ ├── resume.vue │ │ └── resumeDetail.vue │ ├── privacy.vue │ ├── promoCode.vue │ ├── robot.vue │ ├── settings.vue │ ├── terms.vue │ ├── user.vue │ └── userInfo.vue ├── pages.json ├── static/ │ ├── css/ │ │ ├── chatInterface.css │ │ ├── common.css │ │ └── yzb-icon.css │ └── icomoon/ │ ├── selection.json │ └── style.css ├── store/ │ └── index.js ├── uni.scss └── uni_modules/ ├── bctos-rich-text/ │ ├── changelog.md │ ├── components/ │ │ └── bctos-rich-text/ │ │ └── bctos-rich-text.vue │ ├── package.json │ └── readme.md ├── uni-collapse/ │ ├── changelog.md │ ├── components/ │ │ ├── uni-collapse/ │ │ │ └── uni-collapse.vue │ │ └── uni-collapse-item/ │ │ └── uni-collapse-item.vue │ ├── package.json │ └── readme.md ├── uni-grid/ │ ├── changelog.md │ ├── components/ │ │ ├── uni-grid/ │ │ │ └── uni-grid.vue │ │ └── uni-grid-item/ │ │ └── uni-grid-item.vue │ ├── package.json │ └── readme.md ├── uni-icons/ │ ├── changelog.md │ ├── components/ │ │ └── uni-icons/ │ │ ├── icons.js │ │ └── uni-icons.vue │ ├── package.json │ └── readme.md ├── uni-list/ │ ├── changelog.md │ ├── components/ │ │ ├── uni-list/ │ │ │ ├── uni-list - ╕▒▒╛.vue │ │ │ ├── uni-list.vue │ │ │ ├── uni-refresh.vue │ │ │ └── uni-refresh.wxs │ │ ├── uni-list-ad/ │ │ │ └── uni-list-ad.vue │ │ ├── uni-list-chat/ │ │ │ ├── uni-list-chat.scss │ │ │ └── uni-list-chat.vue │ │ └── uni-list-item/ │ │ └── uni-list-item.vue │ ├── package.json │ └── readme.md ├── uni-popup/ │ ├── changelog.md │ ├── components/ │ │ ├── uni-popup/ │ │ │ ├── keypress.js │ │ │ ├── message.js │ │ │ ├── popup.js │ │ │ ├── share.js │ │ │ └── uni-popup.vue │ │ ├── uni-popup-dialog/ │ │ │ ├── keypress.js │ │ │ └── uni-popup-dialog.vue │ │ ├── uni-popup-message/ │ │ │ └── uni-popup-message.vue │ │ └── uni-popup-share/ │ │ └── uni-popup-share.vue │ ├── package.json │ └── readme.md ├── uni-section/ │ ├── changelog.md │ ├── components/ │ │ └── uni-section/ │ │ └── uni-section.vue │ ├── package.json │ └── readme.md └── uni-transition/ ├── changelog.md ├── components/ │ └── uni-transition/ │ └── uni-transition.vue ├── package.json └── readme.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .hbuilderx .DS_Store node_modules /dist /unpackage ================================================ FILE: App.vue ================================================ ================================================ FILE: AppEntryController.js ================================================ import Vue from "vue" /* * APP入口页面控制器 * 中心思想:动态入口解决方案 描述见:http://ask.dcloud.net.cn/question/63270 */ class AppEntryController extends Vue { constructor(arg) { super(); } // 在应用的首页调用main方法 控制路由入口 async main(query) { return new Promise((resolve, reject) => { // H5环境保存openId // #ifdef H5 // H5环境推广码注册 if (query.referrer && query.referrer != " ") { this.$mRouter.reLaunch({ route: this.$mRoutesConfig.reg, query: query }) reject("不可以加载首页数据"); return; } // #endif // 读取配置文件 判断APP是否开启了游客模式 如果开启了无需判断是否登录逻辑 if (this.$mConfig.touristMode && (typeof this.$mConfig.touristMode === "boolean")) { // #ifdef APP-PLUS console.log("关闭启动页") plus.navigator.closeSplashscreen() // #endif resolve("可以加载首页数据"); return; } // 若APP没有开启游客模式 则检测是否登录? 去登录... if (!this.$store.getters.hasLogin) { this.$mRouter.redirectTo({ route: this.$mRoutesConfig.login, query: query }) // #ifdef APP-PLUS setTimeout(() => { console.log("关闭启动页") plus.navigator.closeSplashscreen() }, 800) // #endif reject("APP当前不是游客模式,请先登录后进入"); } }) } // 小程序端获取openId getWeChatOpenId() { // #ifdef H5 let url = window.location.href; let query = this.$mUtils.getRequestParameters(url); if (query.openId) this.$store.commit("SET_OPENID", query.openId); // #endif // #ifdef MP-WEIXIN | APP-PLUS // 登录微信小程序 获取openID this.$store.commit("SET_OPENID", this.$mConfig.testOpenId); // #endif } // 处理H5端 直接通过地址栏访问地址的情况 需要鉴权 handleH5BrowserAddressBarAuth() { // #ifdef H5 let hashPath = window.location.hash.substr(1); hashPath = hashPath.split("?")[0]; if (!/\/pages\//.test(hashPath)) return; for (let routeKey in this.$mRoutesConfig) { let route = this.$mRoutesConfig[routeKey]; // 如果当前访问的路由是权限页面,判断登录状态 if (route.path == hashPath) { if (route.requiresAuth && !this.$store.getters.hasLogin) { console.log("没有登录,无权进入") this.$mRouter.redirectTo({ route: this.$mRoutesConfig.login, query: { } }) } break; } } // #endif } /* * 用途:商户状态拦截器 * 说明:当store中的商户状态为 审核中 || 审核失败 的情况 拦截器会向服务器发送请求查询最新的商户状态。 * 场景:点击某一个功能按钮时需要校验商户状态,只有审核成功的商户方可进入,否则跳转到状态提示页面。 */ async customerStatusInterceptor() { return new Promise(async (resolve, reject) => { // store中的状态 let $storeCustomerStatus = this.$store.state.customerInfo.status; if ($storeCustomerStatus == "SUCCESS") { // 商户状态:审核通过 resolve($storeCustomerStatus); return; } // 服务器中的状态 try { let serverCustomerStatus = await this.$apis.getCustomerStatus(); resolve(serverCustomerStatus); } catch (e) { reject(e) } }) } /* * 登录状态下 全局路由获取商户信息 * 说明:APP打开后向服务器拉取最新商户信息,以及商户审核状态,保存在本地store中使用。 * 场景:H5端 每个页面打开后执行 APP或小程序打开后执行 */ /* async getCustomerInfo() { if (!this.$store.getters.hasLogin) return; let customerInfo = await this.$apis.getCustomer(); this.$store.commit("SET_CUSTOMERINFO", customerInfo); } */ } export default new AppEntryController() ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 DCloud Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # 招聘小程序无忧直聘(前端) :star:一款基于[uni-app](https://zh.uniapp.dcloud.io/)编写的招聘求职类前端,该前端包含了大部分核心页面和逻辑交互。前端分了两种角色:求职者和招聘者,通过角色切换可以进行页面和功能的切换。建议使用[Hbuilder X](https://hx.dcloud.net.cn/)打开,适合学习\二次开发等用途。 ## [快速开始](https://www.wuyoujobs.com/) ## 项目列表 + [项目官网](https://www.wuyoujobs.com/) + 无忧直聘前端(Uni-app+Vue2) + 无忧直聘后端(Java+SpringBoot2+MybatisPlus+Mysql) + 无忧直聘管理端(React+Ant Design+Ant Design Pro) ## 功能模块 + 职位发布 + 简历创建 + 公司创建 + 即时通讯(利用[GoEasy](https://www.goeasy.io/cn/websocket.html)实现) + 地理位置(利用[腾讯位置服务](https://lbs.qq.com/)实现) + 角色切换 + 收藏岗位 + 收藏简历 + 信息搜索 + 系统通知 + 谁看过我 ## 项目截图 ![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E6%88%AA%E5%B1%8F1.png)![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E6%88%AA%E5%B1%8F2.png)![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E6%88%AA%E5%B1%8F3.png)![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E6%88%AA%E5%B1%8F4.png)![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E6%88%AA%E5%B1%8F5.png)![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E6%88%AA%E5%B1%8F6.png) ## 运行步骤 + 启动无忧直聘后端服务 + 修改manifest.json文件中的AppID ![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E4%BF%AE%E6%94%B9appid.png) + 修改main.js文件中的GoEasy配置 ![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E4%BF%AE%E6%94%B9goeasy.png) + 修改pages/position/detail.vue文件中的腾讯位置服务配置 ![](https://raw.githubusercontent.com/zhang2657977442/MyPicGo/master/wuyou-frontend/%E4%BF%AE%E6%94%B9%E8%85%BE%E8%AE%AF%E4%BD%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1.png) 如有问题请联系 + QQ:2657977449 + 微信:zhang2657977449 ================================================ FILE: apis/http.js ================================================ import store from "@/store" function HTTP(obj, config) { let defaultConfig = { isRes: false, loading: false } config = { ...defaultConfig, ...config } // 如果需要显示loading,mask防止点击穿透 config.loading && uni.showLoading({ title: '加载中', mask: true }); return new Promise((resolve, reject) => { let options = { url: "", method: "GET", data: {}, dataType: "json", header: { "content-type": "application/json", "X-requested-With": "XMLHttpRequest" }, success: (res) => { // console.log("HTTP请求结果:",res) uni.hideLoading(); // 状态码为0 if (res.statusCode == 200) { let data = res.data; //自动校验用户是否登录过期 if (data.code == "40100") { store.dispatch("reLogin"); return; } //返回 { code:10000,msg:"消息",data:[] } if (config.isRes) { resolve(data) } // 返回 data:[] else { if (data.code === 0) { resolve(data.data) } else { wx.showToast({ title: data.message, icon: "none", duration: 2000 }) reject(data.msg); } } } else { reject("HTTP:状态码异常!"); } }, fail: (err) => { uni.hideLoading(); uni.showToast({ title: "网络异常,请稍后再试!", icon: "none", }) reject("网络异常,请稍后再试!"); }, complete: () => {} } options = { ...options, ...obj }; const OPENID = uni.getStorageSync("openId"); const Token=uni.getStorageSync("token"); // console.log("Token==="+Token); if (OPENID) options["header"]["openId"] = OPENID; if (Token) options["header"]["token"] = Token; if (options.url && options.method) { wx.request(options); } else { wx.showToast({ title: 'HTTP:缺失参数', icon: "none", duration: 2000 }) } }) } export default { GET(url, data = {}, config) { return HTTP({ url, data, method: "GET" }, config); }, POST(url, data = {}, config) { return HTTP({ url, data, method: "POST" }, config); }, DELETE(url, data = {}, config) { return HTTP({ url, data, method: "DELETE" }, config); }, POSTformdata(url, data = {}, config) { return HTTP({ url, data, method: "POST" }, config); } } ================================================ FILE: apis/index.js ================================================ import http from "./http.js"; import config from "@/config/index.config.js"; // 获取OpenId export const getOpenId = (data) => http.GET(`${config.baseUrl}/user/getOpenId`, data); // 绑定手机号 export const bindPhoneForWx = (data) => http.GET(`${config.baseUrl}/user/bindPhoneForWx`, data); // 小程序授权登录 export const xcxUserLogin = (data) => http.POST(`${config.baseUrl}/user/wxUserLogin`, data); // 获取用户资料 export const getUserInfo = (data) => http.GET(`${config.baseUrl}/user/getUserInfo`, data); // 用户角色切换 export const switchRole = (data) => http.POST(`${config.baseUrl}/user/switchRole`, data); // 新增简历信息 export const addResume = (data) => http.POST(`${config.baseUrl}/resume/addResume`, data); // 查询简历信息 export const getResumeInfo = (id) => http.GET(`${config.baseUrl}/resume/getResumeInfo/${id}`); // 查询用户简历 export const getUserResume = (data) => http.GET(`${config.baseUrl}/resume/getUserResume`, data); // 更新简历信息 export const updateResume = (data) => http.POST(`${config.baseUrl}/resume/updateResumeInfo`, data); // 获取简历列表 export const getResumeList = (data) => http.POST(`${config.baseUrl}/resume/getResumeList`, data); // 查询工作列表 export const getJobList = (data) => http.POST(`${config.baseUrl}/job/getJobList`, data); // 新增工作信息 export const addJob = (data) => http.POST(`${config.baseUrl}/job/addJob`, data); // 更新工作信息 export const updateJobInfo = (data) => http.POST(`${config.baseUrl}/job/updateJobInfo`, data); // 删除工作信息 export const deleteJob = (id) => http.DELETE(`${config.baseUrl}/job/deleteJob/${id}`); // 查询行业列表 export const getIndustryList = (data) => http.POST(`${config.baseUrl}/industry/getIndustryList`, data); // 查询职位列表 export const getPositionList = (data) => http.POST(`${config.baseUrl}/position/getPositionList`, data); // 查询福利列表 export const getWelfareList = (data) => http.POST(`${config.baseUrl}/welfare/getWelfareList`, data); // 新增公司信息 export const addCompany = (data) => http.POST(`${config.baseUrl}/company/addCompany`, data); // 查询公司职位列表 export const getCompanyJob = (data) => http.POST(`${config.baseUrl}/company/getCompanyJob`, data); // 查询公司列表 export const getCompanyList = (data) => http.POST(`${config.baseUrl}/company/getCompanyList`, data); // 查询公司信息 export const getCompanyInfo = (id) => http.GET(`${config.baseUrl}/company/getCompanyInfo/${id}`); // 更新公司信息 export const updateCompanyInfo = (data) => http.POST(`${config.baseUrl}/company/updateCompanyInfo`, data); // 新增/更新职位信息 export const updatePosition = (data) => http.POST(`${config.baseUrl}/company/updatePosition`, data); // 查询职位信息 export const getPositionDetail = (data) => http.GET(`${config.baseUrl}/company/getPositionDetail`, data); // 删除公司职位 export const deletePositionById = (data) => http.GET(`${config.baseUrl}/company/deletePositionById`, data); // 新增收藏信息 export const addCollect = (data) => http.POST(`${config.baseUrl}/collect/addCollect`, data); // 删除收藏信息 export const deleteCollect = (data) => http.POST(`${config.baseUrl}/collect/deleteCollect`, data); // 获取收藏信息 export const getCollectList = (data) => http.POST(`${config.baseUrl}/collect/getCollectList`, data); // 是否收藏 export const isCollect = (data) => http.POST(`${config.baseUrl}/collect/isCollect`, data); // 新增应聘信息 export const addApply = (data) => http.POST(`${config.baseUrl}/apply/addApply`, data); // 删除收藏信息 export const deleteApply = (data) => http.POST(`${config.baseUrl}/apply/deleteApply`, data); // 获取应聘信息 export const getApplyList = (data) => http.POST(`${config.baseUrl}/apply/getApplyList`, data); // 是否应聘 export const isApply = (data) => http.POST(`${config.baseUrl}/apply/isApply`, data); // 新增浏览信息 export const addBrowse = (data) => http.POST(`${config.baseUrl}/browse/addBrowse`, data); // 获取浏览信息 export const getBrowseList = (data) => http.POST(`${config.baseUrl}/browse/getBrowseList`, data); // 查询期望职位列表 export const getJobExpectList = (data) => http.GET(`${config.baseUrl}/person/getJobExpectList`, data); // 查询期望职位详情 export const getJobExpectDetail = (data) => http.GET(`${config.baseUrl}/person/getJobExpectDetail`, data); // 新增/更新期望职位 export const updateJobExpect = (data) => http.POST(`${config.baseUrl}/person/updateJobExpect`, data); // 删除期望职位 export const deleteJobExpectById = (data) => http.GET(`${config.baseUrl}/person/deleteJobExpectById`, data); // 查询工作经历列表 export const getWorkExpList = (data) => http.GET(`${config.baseUrl}/person/getWorkExpList`, data); // 查询工作经历详情 export const getWorkExpDetail = (data) => http.GET(`${config.baseUrl}/person/getWorkExpDetail`, data); // 新增/更新工作经历 export const updateWorkExp = (data) => http.POST(`${config.baseUrl}/person/updateWorkExp`, data); // 删除工作经历 export const deleteWorkExpById = (data) => http.GET(`${config.baseUrl}/person/deleteWorkExpById`, data); // 查询项目经历列表 export const getProExpList = (data) => http.GET(`${config.baseUrl}/person/getProExpList`, data); // 查询项目经历详情 export const getProExpDetail = (data) => http.GET(`${config.baseUrl}/person/getProExpDetail`, data); // 新增/更新项目经历 export const updateProExp = (data) => http.POST(`${config.baseUrl}/person/updateProExp`, data); // 删除项目经历 export const deleteProExpById = (data) => http.GET(`${config.baseUrl}/person/deleteProExpById`, data); // 查询教育经历列表 export const getEduExpList = (data) => http.GET(`${config.baseUrl}/person/getEduExpList`, data); // 查询教育经历详情 export const getEduExpDetail = (data) => http.GET(`${config.baseUrl}/person/getEduExpDetail`, data); // 新增/更新教育经历 export const updateEduExp = (data) => http.POST(`${config.baseUrl}/person/updateEduExp`, data); // 删除教育经历 export const deleteEduExpById = (data) => http.GET(`${config.baseUrl}/person/deleteEduExpById`, data); // 用户登录 export const postLogin = (data) => http.POST(`${config.baseUrl}/ums/xcxUserLogin`, data); // 获取短信验证码 export const getMsgCode = (data) => http.GET(`${config.baseUrl}/register/sendMsg`, data); // 校验注册验证码 export const postRegCode = (data) => http.POST(`${config.baseUrl}/register/verifySMSCode`, data); // 获取卡片信息 export const getCardBin = (data) => http.GET(`${config.baseUrl}/card/getCardBin`, data); // 图片上传 export const upload = (data) => http.POST(`${config.baseUrl}/register/upImg`, data); // 图片下载 export const downloadImg = (data) => http.GET(`${config.baseUrl}/my/downloadImg`, data); // 查询公告列表 export const getCmsList = (data) => http.POST(`${config.baseUrl}/cms/getCmsList`, data); ================================================ FILE: common/auth.js ================================================ function loginCheck(pageObj) { if (pageObj.onLoad) { let _onLoad = pageObj.onLoad; // 使用onLoad的话需要传递options pageObj.onLoad = function(options) { if (true) { // 获取当前页面 _onLoad.call(this, options); } else { //跳转到登录页 wx.redirectTo({ url: "/pages/login/login" }); } } } return pageObj; } export default loginCheck; ================================================ FILE: common/cityData.js ================================================ export default [{ "label": "福建省", "value": "3900", "children": [{ "label": "三明市", "value": "3950" }, { "label": "南平市", "value": "4010" }, { "label": "厦门市", "value": "3930" }, { "label": "宁德市", "value": "4030" }, { "label": "泉州市", "value": "3970" }, { "label": "漳州市", "value": "3990" }, { "label": "福州市", "value": "3910" }, { "label": "莆田市", "value": "3940" }, { "label": "龙岩市", "value": "4050" }], }, { "label": "西藏自治区", "value": "", "children": [{ "label": "山南地区", "value": "7740" }, { "label": "拉萨市", "value": "7710" }, { "label": "日喀则地区", "value": "7760" }, { "label": "昌都地区", "value": "7720" }, { "label": "林芝地区", "value": "7830" }, { "label": "那曲地区", "value": "7790" }, { "label": "阿里地区", "value": "7810" }], }, { "label": "贵州省", "value": "", "children": [{ "label": "六盘水市", "value": "7020" }, { "label": "安顺市", "value": "7110" }, { "label": "毕节市", "value": "7090" }, { "label": "贵阳市", "value": "7010" }, { "label": "遵义市", "value": "7030" }, { "label": "铜仁市", "value": "7050" }, { "label": "黔东南苗族", "value": "7130" }, { "label": "黔南布依族", "value": "7150" }, { "label": "黔西南布依族苗族自治州", "value": "7070" }], }, { "label": "上海市", "value": "2900", "children": [{ "label": "上海市", "value": "2900" }], }, { "label": "广东省", "value": "5800", "children": [{ "label": "东莞市", "value": "6020" }, { "label": "中山市", "value": "6030" }, { "label": "云浮市", "value": "6060" }, { "label": "佛山市", "value": "5880" }, { "label": "广州市", "value": "5810" }, { "label": "惠州市", "value": "5950" }, { "label": "揭阳市", "value": "6050" }, { "label": "梅州市", "value": "5960" }, { "label": "汕头市", "value": "5860" }, { "label": "汕尾市", "value": "5970" }, { "label": "江门市", "value": "5890" }, { "label": "河源市", "value": "5980" }, { "label": "深圳市", "value": "5840" }, { "label": "清远市", "value": "6010" }, { "label": "湛江市", "value": "5910" }, { "label": "潮州市", "value": "6040" }, { "label": "珠海市", "value": "5850" }, { "label": "肇庆市", "value": "5930" }, { "label": "茂名市", "value": "5920" }, { "label": "阳江市", "value": "5990" }, { "label": "韶关市", "value": "5820" }], }, { "label": "湖北省", "value": "3900", "children": [{ "label": "十堰市", "value": "5230" }, { "label": "咸宁市", "value": "5360" }, { "label": "孝感市", "value": "5350" }, { "label": "宜昌市", "value": "5250" }, { "label": "恩施土家族苗族自治州", "value": "5410" }, { "label": "武汉市", "value": "5210" }, { "label": "荆州市", "value": "5370" }, { "label": "荆门市", "value": "5320" }, { "label": "襄阳市", "value": "5280" }, { "label": "鄂州市", "value": "5310" }, { "label": "随州市", "value": "5270" }, { "label": "黄冈市", "value": "5330" }, { "label": "黄石市", "value": "5220" }], }, { "label": "湖南省", "value": "", "children": [{ "label": "娄底市", "value": "5620" }, { "label": "岳阳市", "value": "5570" }, { "label": "常德市", "value": "5580" }, { "label": "张家界市", "value": "5590" }, { "label": "怀化市", "value": "5670" }, { "label": "株洲市", "value": "5520" }, { "label": "永州市", "value": "5650" }, { "label": "湘潭市", "value": "5530" }, { "label": "湘西州", "value": "5690" }, { "label": "益阳市", "value": "5610" }, { "label": "衡阳市", "value": "5540" }, { "label": "邵阳市", "value": "5550" }, { "label": "郴州市", "value": "5630" }, { "label": "长沙市", "value": "5510" }], }, { "label": "四川省", "value": "6500", "children": [{ "label": "乐山市", "value": "6650" }, { "label": "内江市", "value": "6630" }, { "label": "凉山彝族州", "value": "6840" }, { "label": "南充市", "value": "6730" }, { "label": "宜宾市", "value": "6710" }, { "label": "巴中市", "value": "6870" }, { "label": "广元市", "value": "6610" }, { "label": "广安市", "value": "6690" }, { "label": "德阳市", "value": "6580" }, { "label": "成都市", "value": "6510" }, { "label": "攀枝花市", "value": "6560" }, { "label": "泸州市", "value": "6570" }, { "label": "甘孜藏族州", "value": "6810" }, { "label": "眉山市", "value": "6670" }, { "label": "绵阳市", "value": "6590" }, { "label": "自贡市", "value": "6550" }, { "label": "资阳市", "value": "6880" }, { "label": "达州市", "value": "6750" }, { "label": "遂宁市", "value": "6620" }, { "label": "阿坝藏族羌族州", "value": "6790" }, { "label": "雅安市", "value": "6770" }], }, { "label": "安徽省", "value": "3600", "children": [{ "label": "亳州市", "value": "3810" }, { "label": "六安市", "value": "3760" }, { "label": "合肥市", "value": "3610" }, { "label": "安庆市", "value": "3680" }, { "label": "宣城市", "value": "3770" }, { "label": "宿州市", "value": "3740" }, { "label": "池州市", "value": "3790" }, { "label": "淮北市", "value": "3660" }, { "label": "淮南市", "value": "3640" }, { "label": "滁州市", "value": "3750" }, { "label": "芜湖市", "value": "3620" }, { "label": "蚌埠市", "value": "3630" }, { "label": "铜陵市", "value": "3670" }, { "label": "阜阳市", "value": "3720" }, { "label": "马鞍山市", "value": "3650" }, { "label": "黄山市", "value": "3710" }], }, { "label": "广西省", "value": "6100", "children": [{ "label": "广西省", "value": "6100" }], }, { "label": "江苏省", "value": "3000", "children": [{ "label": "南京市", "value": "3010" }, { "label": "南通市", "value": "3060" }, { "label": "宿迁市", "value": "3180" }, { "label": "常州市", "value": "3040" }, { "label": "徐州市", "value": "3030" }, { "label": "扬州市", "value": "3120" }, { "label": "无锡市", "value": "3020" }, { "label": "泰州市", "value": "3160" }, { "label": "淮安市", "value": "3080" }, { "label": "盐城市", "value": "3110" }, { "label": "苏州市", "value": "3050" }, { "label": "连云港市", "value": "3070" }, { "label": "镇江市", "value": "3140" }], }, { "label": "吉林省", "value": "", "children": [{ "label": "吉林市", "value": "2420" }, { "label": "四平市", "value": "2430" }, { "label": "延边朝鲜族", "value": "2490" }, { "label": "松原市", "value": "2510" }, { "label": "白城市", "value": "2470" }, { "label": "白山市", "value": "2460" }, { "label": "辽源市", "value": "2440" }, { "label": "通化市", "value": "2450" }, { "label": "长春市", "value": "2410" }], }, { "label": "河南省", "value": "4900", "children": [{ "label": "三门峡市", "value": "5050" }, { "label": "信阳市", "value": "5150" }, { "label": "南阳市", "value": "5130" }, { "label": "周口市", "value": "5080" }, { "label": "商丘市", "value": "5060" }, { "label": "安阳市", "value": "4960" }, { "label": "平顶山市", "value": "4950" }, { "label": "开封市", "value": "4920" }, { "label": "新乡市", "value": "4980" }, { "label": "洛阳市", "value": "4930" }, { "label": "漯河市", "value": "5040" }, { "label": "濮阳市", "value": "5020" }, { "label": "焦作市", "value": "5010" }, { "label": "许昌市", "value": "5030" }, { "label": "郑州市", "value": "4910" }, { "label": "驻马店市", "value": "5110" }, { "label": "鹤壁市", "value": "4970" }], }, { "label": "河北省", "value": "1200", "children": [{ "label": "保定市", "value": "1340" }, { "label": "唐山市", "value": "1240" }, { "label": "廊坊市", "value": "1460" }, { "label": "张家口市", "value": "1380" }, { "label": "承德市", "value": "1410" }, { "label": "沧州市", "value": "1430" }, { "label": "石家庄市", "value": "1210" }, { "label": "秦皇岛市", "value": "1260" }, { "label": "衡水市", "value": "1480" }, { "label": "邢台市", "value": "1310" }, { "label": "邯郸市", "value": "1270" }], }, { "label": "海南省", "value": "6400", "children": [{ "label": "三亚市", "value": "6420" }, { "label": "三沙市", "value": "6440" }, { "label": "海口市", "value": "6410" }], }, { "label": "新疆自治区", "value": "", "children": [{ "label": "乌鲁木齐市", "value": "8810" }, { "label": "伊犁哈萨克", "value": "8980" }, { "label": "克孜勒苏柯尔克孜自治州", "value": "8930" }, { "label": "克拉玛依市", "value": "8820" }, { "label": "博尔塔拉", "value": "8870" }, { "label": "吐鲁番地区", "value": "8830" }, { "label": "和田地区", "value": "8960" }, { "label": "哈密地区", "value": "8840" }, { "label": "喀什地区", "value": "8940" }, { "label": "塔城地区", "value": "9010" }, { "label": "巴音郭楞", "value": "8880" }, { "label": "昌吉回族", "value": "8850" }, { "label": "阿克苏地区", "value": "8910" }, { "label": "阿勒泰地区", "value": "9020" }], }, { "label": "江西省", "value": "4200", "children": [{ "label": "上饶市", "value": "4330" }, { "label": "九江市", "value": "4240" }, { "label": "南昌市", "value": "4210" }, { "label": "吉安市", "value": "4350" }, { "label": "宜春市", "value": "4310" }, { "label": "抚州市", "value": "4370" }, { "label": "新余市", "value": "4260" }, { "label": "景德镇市", "value": "4220" }, { "label": "萍乡市", "value": "4230" }, { "label": "赣州市", "value": "4280" }, { "label": "鹰潭市", "value": "4270" }], }, { "label": "重庆市", "value": "6900", "children": [{ "label": "重庆市", "value": "6900" }], }, { "label": "云南省", "value": "7300", "children": [{ "label": "临沧市", "value": "7580" }, { "label": "丽江市", "value": "7550" }, { "label": "保山市", "value": "7530" }, { "label": "大理白族州", "value": "7510" }, { "label": "德宏州", "value": "7540" }, { "label": "怒江州", "value": "7560" }, { "label": "文山州", "value": "7450" }, { "label": "昆明市", "value": "7310" }, { "label": "昭通市", "value": "7340" }, { "label": "普洱市", "value": "7470" }, { "label": "曲靖市", "value": "7360" }, { "label": "楚雄彝族州", "value": "7380" }, { "label": "玉溪市", "value": "7410" }, { "label": "红河州", "value": "7430" }, { "label": "西双版纳州", "value": "7490" }, { "label": "迪庆州", "value": "7570" }], }, { "label": "北京市", "value": "1000", "children": [{ "label": "北京市", "value": "1000" }], }, { "label": "甘肃省", "value": "", "children": [{ "label": "临夏回族", "value": "8360" }, { "label": "兰州市", "value": "8210" }, { "label": "嘉峪关市", "value": "8220" }, { "label": "天水市", "value": "8250" }, { "label": "定西市", "value": "8290" }, { "label": "平凉市", "value": "8330" }, { "label": "庆阳市", "value": "8340" }, { "label": "张掖市", "value": "8270" }, { "label": "武威市", "value": "8280" }, { "label": "甘南藏族", "value": "8380" }, { "label": "白银市", "value": "8240" }, { "label": "酒泉市", "value": "8260" }, { "label": "金昌市", "value": "8230" }, { "label": "陇南市", "value": "8310" }], }, { "label": "山东省", "value": "4500", "children": [{ "label": "东营市", "value": "4550" }, { "label": "临沂市", "value": "4730" }, { "label": "威海市", "value": "4650" }, { "label": "德州市", "value": "4680" }, { "label": "日照市", "value": "4770" }, { "label": "枣庄市", "value": "4540" }, { "label": "泰安市", "value": "4630" }, { "label": "济南市", "value": "4510" }, { "label": "济宁市", "value": "4610" }, { "label": "淄博市", "value": "4530" }, { "label": "滨州市", "value": "4660" }, { "label": "潍坊市", "value": "4580" }, { "label": "烟台市", "value": "4560" }, { "label": "聊城市", "value": "4710" }, { "label": "莱芜市", "value": "4790" }, { "label": "菏泽市", "value": "4750" }, { "label": "青岛市", "value": "4520" }], }, { "label": "陕西省", "value": "7900", "children": [{ "label": "咸阳市", "value": "7950" }, { "label": "商洛市", "value": "8030" }, { "label": "安康市", "value": "8010" }, { "label": "宝鸡市", "value": "7930" }, { "label": "延安市", "value": "8040" }, { "label": "榆林市", "value": "8060" }, { "label": "汉中市", "value": "7990" }, { "label": "渭南市", "value": "7970" }, { "label": "西安市", "value": "7910" }, { "label": "铜川市", "value": "7920" }], }, { "label": "浙江省", "value": "3300", "children": [{ "label": "丽水市", "value": "3430" }, { "label": "台州市", "value": "3450" }, { "label": "嘉兴市", "value": "3350" }, { "label": "宁波市", "value": "3320" }, { "label": "杭州市", "value": "3310" }, { "label": "温州市", "value": "3330" }, { "label": "湖州市", "value": "3360" }, { "label": "绍兴市", "value": "3370" }, { "label": "舟山市", "value": "3420" }, { "label": "衢州市", "value": "3410" }, { "label": "金华市", "value": "3380" }], }, { "label": "内蒙古自治区", "value": "", "children": [{ "label": "乌兰察布市", "value": "2030" }, { "label": "乌海市", "value": "1930" }, { "label": "兴安盟", "value": "1980" }, { "label": "包头市", "value": "1920" }, { "label": "呼伦贝尔市", "value": "1960" }, { "label": "呼和浩特市", "value": "1910" }, { "label": "巴彦淖尔市", "value": "2070" }, { "label": "赤峰市", "value": "1940" }, { "label": "通辽市", "value": "1990" }, { "label": "鄂尔多斯市", "value": "2050" }, { "label": "锡林郭勒盟", "value": "2010" }, { "label": "阿拉善盟", "value": "2080" }], }, { "label": "青海省", "value": "", "children": [{ "label": "果洛藏族", "value": "8570" }, { "label": "海东市", "value": "8520" }, { "label": "海北藏族", "value": "8540" }, { "label": "海南藏族", "value": "8560" }, { "label": "海西蒙古族", "value": "8590" }, { "label": "玉树藏族", "value": "8580" }, { "label": "西宁市", "value": "8510" }, { "label": "黄南藏族", "value": "8550" }], }, { "label": "辽宁省", "value": "2200", "children": [{ "label": "丹东市", "value": "2260" }, { "label": "大连市", "value": "2220" }, { "label": "抚顺市", "value": "2240" }, { "label": "朝阳市", "value": "2340" }, { "label": "本溪市", "value": "2250" }, { "label": "沈阳市", "value": "2210" }, { "label": "盘锦市", "value": "2320" }, { "label": "营口市", "value": "2280" }, { "label": "葫芦岛市", "value": "2360" }, { "label": "辽阳市", "value": "2310" }, { "label": "铁岭市", "value": "2330" }, { "label": "锦州市", "value": "2270" }, { "label": "阜新市", "value": "2290" }, { "label": "鞍山市", "value": "2230" }], }, { "label": "天津市", "value": "1100", "children": [{ "label": "天津市", "value": "1100" }], }, { "label": "黑龙江省", "value": "2600", "children": [{ "label": "七台河市", "value": "2740" }, { "label": "伊春市", "value": "2710" }, { "label": "佳木斯市", "value": "2720" }, { "label": "双鸭山市", "value": "2680" }, { "label": "哈尔滨市", "value": "2610" }, { "label": "大兴安岭地区", "value": "2790" }, { "label": "大庆市", "value": "2690" }, { "label": "牡丹江市", "value": "2750" }, { "label": "绥化市", "value": "2760" }, { "label": "鸡西市", "value": "2660" }, { "label": "鹤岗市", "value": "2670" }, { "label": "黑河市", "value": "2780" }, { "label": "齐齐哈尔市", "value": "2640" }], }, { "label": "广西自治区", "value": "", "children": [{ "label": "北海市", "value": "6230" }, { "label": "南宁市", "value": "6110" }, { "label": "崇左市", "value": "6360" }, { "label": "来宾市", "value": "6350" }, { "label": "柳州市", "value": "6140" }, { "label": "桂林市", "value": "6170" }, { "label": "梧州市", "value": "6210" }, { "label": "河池市", "value": "6280" }, { "label": "玉林市", "value": "6240" }, { "label": "百色市", "value": "6260" }, { "label": "贵港市", "value": "6330" }, { "label": "贺州市", "value": "6340" }, { "label": "钦州市", "value": "6310" }, { "label": "防城港市", "value": "6320" }], }, { "label": "宁夏自治区", "value": "8700", "children": [{ "label": "中卫市", "value": "8750" }, { "label": "吴忠市", "value": "8730" }, { "label": "固原市", "value": "8740" }, { "label": "石嘴山市", "value": "8720" }, { "label": "银川市", "value": "8710" }], }, { "label": "山西省", "value": "1600", "children": [{ "label": "临汾市", "value": "1770" }, { "label": "吕梁市", "value": "1730" }, { "label": "大同市", "value": "1620" }, { "label": "太原市", "value": "1610" }, { "label": "忻州市", "value": "1710" }, { "label": "晋中市", "value": "1750" }, { "label": "晋城市", "value": "1680" }, { "label": "朔州市", "value": "1690" }, { "label": "运城市", "value": "1810" }, { "label": "长治市", "value": "1660" }, { "label": "阳泉市", "value": "1650" }] }] ================================================ FILE: common/data.js ================================================ // 数据格式,数据中只需要包含以下字段和数据格式,开发者可以添加字段,比如id等等,不影响组件显示, // 组件的返回结果是有菜单数组下标形式返回, // 如果传入数据中有value,也会返回value,开发者可根据返回的下标获取所选中的菜单 /* [ { "name":"", //字符串类型 选填项 菜单名称,如不填,则取第一个子菜单的name值,filter和radio类型则将设置为"筛选" "type":"" //字符串类型 必填项 可取值 hierarchy/filter/radio hierarchy单/多层级菜单(最多三级); filter筛选多选菜单; radio筛选单选菜单 "submenu":[ //对象数组类型 必填项 子菜单数据 { "name":"", //字符串类型 必填项 菜单名称 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null,filter类型此字段无效果 "submenu":[ //对象数组类型 必填项 子菜单数据 { "name":"", //字符串类型 必填项 菜单名称 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null "submenu":[ //对象数组类型 必填项 子菜单数据 filter类型无效 { "name":"", //字符串类型 必填项 菜单名称 hierarchy类型层级最多到此 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null } ] } ] } ] } ] */ //0.0.4版本起 返回结果将有两部分组成: /* { index:[], //旧版本的下标数组形式 value:[] //菜单中的valve,结构和下标结果数组一样,只是把下标替换成了value而已 } */ // 以下演示数据中,我故意把value设置成跟name一样,只是为了方便演示,使示例更加易懂,实际使用时候value应该是一个标识,给后台识别所用的. // 数据较长,请仔细查看。 export default [ { "name":'职位筛选', "type": 'hierarchy', "submenu": [ { "name": '休闲娱乐', "value": "休闲娱乐", "submenu": [{ "name": "足疗按摩", "value": "足疗按摩", "submenu": [{ "name": "按摩推拿", "value": "按摩推拿" }, { "name": "足浴足疗", "value": "足浴足疗" }, { "name": "中医养生", "value": "中医养生" }] } ] } ] }, { "name":'行业筛选', "type": 'hierarchy', "submenu": [ { "name": '休闲娱乐', "value": "休闲娱乐", "submenu": [{ "name": "足疗按摩", "value": "足疗按摩", "submenu": [{ "name": "按摩推拿", "value": "按摩推拿" }, { "name": "足浴足疗", "value": "足浴足疗" }, { "name": "中医养生", "value": "中医养生" }] } ] } ] }, { "name":'薪资范围', "type": 'hierarchy', "submenu": [ { "name": "全部分类", "value": "全部分类" }, { "name": "面议", "value": "面议" }, { "name": "1-3K", "value": "1-3K" }, { "name": "3-5K", "value": "3-5K" }, { "name": "5-8K", "value": "5-8K" }, { "name": "8-12K", "value": "8-12K" }, { "name": "12-15K", "value": "12-15K" }, { "name": "15-20K", "value": "15-20K" }, { "name": "20K以上", "value": "20K以上" } ] }, { "name":'经验要求', "type": 'hierarchy', "submenu": [ { "name": "全部分类", "value": "全部分类" }, { "name": "不限", "value": "不限" }, { "name": "1年以内", "value": "1年以内" }, { "name": "1-3年", "value": "1-3年" }, { "name": "3-5年", "value": "3-5年" }, { "name": "5-10年", "value": "5-10年" }, { "name": "10年以上", "value": "10年以上" } ] }, ] ================================================ FILE: common/date.js ================================================ // date.js export function formatDate(date, fmt) { if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); } let o = { 'M+': date.getMonth() + 1, 'd+': date.getDate(), 'h+': date.getHours(), 'm+': date.getMinutes(), 's+': date.getSeconds() }; for (let k in o) { if (new RegExp(`(${k})`).test(fmt)) { let str = o[k] + ''; fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str)); } } return fmt; } function padLeftZero(str) { return ('00' + str).substr(str.length); } export function str2Date(dateStr, separator) { if (!separator) { separator = "-"; } let dateArr = dateStr.split(separator); let year = parseInt(dateArr[0]); let month; //处理月份为04这样的情况 if (dateArr[1].indexOf("0") == 0) { month = parseInt(dateArr[1].substring(1)); } else { month = parseInt(dateArr[1]); } let day = parseInt(dateArr[2]); let date = new Date(year, month - 1, day); return date; } /** * 计算两个日期相隔年限,用于计算年龄等 * @param {Object} date1 * @param {Object} date2 */ export function calYear(date1,date2) { let a = new Date(date1).getFullYear(); let b = new Date(date2).getFullYear(); console.log(b-a); return b-a; } /** * 计算两个日期相隔年限,用于计算年龄等 * @param {Object} date1 * @param {Object} date2 */ export function calCurrentYear(date) { let a = new Date(date).getFullYear(); let b = new Date().getFullYear(); console.log(b-a); return b-a; } // 时间戳转日期 export function timestampToTime(timestamp) { // 时间戳为10位需*1000,时间戳为13位不需乘1000 var date = new Date(timestamp); var Y = date.getFullYear() + "-"; var M = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-"; var D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " "; var h = date.getHours() + ":"; var m = date.getMinutes() + ":"; var s = date.getSeconds(); return Y + M + D + h + m + s; } ================================================ FILE: common/db.js ================================================ //取值 function get(key,sync = true) { try { if(sync){ return uni.getStorageSync(key); }else{ let data = ''; uni.getStorage({ key:key, success: function (res) { data = res.data; } }); return data; } } catch (e) { return false; } } //赋值 function set(key, value, sync = true) { try { if (sync) { return uni.setStorageSync(key, value); } else { uni.setStorage({ key: key, data: value }); } } catch (e) { } } export { get, set } ================================================ FILE: common/graceChecker.js ================================================ /** 数据验证(表单验证) 来自 grace.hcoder.net 作者 hcoder 深海 */ module.exports = { error:'', check : function (data, rule){ for(var i = 0; i < rule.length; i++){ if (!rule[i].checkType){return true;} if (!rule[i].name) {return true;} if (!rule[i].errorMsg) {return true;} if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;} switch (rule[i].checkType){ case 'string': var reg = new RegExp('^.{' + rule[i].checkRule + '}$'); if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;} break; case 'int': var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$'); if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;} break; break; case 'between': if (!this.isNumber(data[rule[i].name])){ this.error = rule[i].errorMsg; return false; } var minMax = rule[i].checkRule.split(','); minMax[0] = Number(minMax[0]); minMax[1] = Number(minMax[1]); if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) { this.error = rule[i].errorMsg; return false; } break; case 'betweenD': var reg = /^-?[1-9][0-9]?$/; if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; } var minMax = rule[i].checkRule.split(','); minMax[0] = Number(minMax[0]); minMax[1] = Number(minMax[1]); if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) { this.error = rule[i].errorMsg; return false; } break; case 'betweenF': var reg = /^-?[0-9][0-9]?.+[0-9]+$/; if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;} var minMax = rule[i].checkRule.split(','); minMax[0] = Number(minMax[0]); minMax[1] = Number(minMax[1]); if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) { this.error = rule[i].errorMsg; return false; } break; case 'same': if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;} break; case 'notsame': if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; } break; case 'email': var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/; if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; } break; case 'phoneno': var reg = /^1[0-9]{10,10}$/; if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; } break; case 'zipcode': var reg = /^[0-9]{6}$/; if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; } break; case 'reg': var reg = new RegExp(rule[i].checkRule); if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; } break; case 'in': if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){ this.error = rule[i].errorMsg; return false; } break; case 'notnull': if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;} break; } } return true; }, isNumber : function (checkVal){ var reg = /^-?[1-9][0-9]?.?[0-9]*$/; return reg.test(checkVal); } } ================================================ FILE: common/modalHelper.js ================================================ export default (function (bodyCls) { var scrollTop; return { open: function () { scrollTop = document.scrollingElement.scrollTop; document.body.classList.add(bodyCls); document.body.style.top = -scrollTop + 'px'; document.querySelector('.uni-page-head').style.top = 0; }, close: function () { document.body.classList.remove(bodyCls); // scrollTop lost after set position:fixed, restore it back. document.scrollingElement.scrollTop = scrollTop; document.body.style.top = "auto"; } }; })('modal-open'); ================================================ FILE: common/router.js ================================================ /* * 路由对象 * 中心思想:需要路由鉴权,由于uni-app没有vue中的全局钩子函数,所以封装了Router对象。 * 说明:应用中的路由跳转尽量使用该Router的方法,并配合config中的路由表对象进行跳转。 * * 示例:this.$mRouter.push({route:this.$mRoutesConfig.main,query:{a:1}}) * */ class Router { constructor(arg) { this.callBack = () => {}; } beforeEach(callBack) { if (callBack instanceof Function) this.callBack = callBack; } push(to) { this.callBack("navigateTo", to); } redirectTo(to) { this.callBack("redirectTo", to); } reLaunch(to) { this.callBack("reLaunch", to); } switchTab(to) { this.callBack("switchTab", to); } back(delta) { uni.navigateBack({ delta }) } } export default new Router(); ================================================ FILE: common/utils.js ================================================ export default { /* * 将cityNo 转 cityName * cityData:原数据 * cityNo:二级地区编码 */ getCityName(cityData, cityNo) { if (!cityNo) return; if (!(cityData instanceof Array)) return; // 9112 cityNo += ""; for (let i = 0; i < cityData.length; i++) { let sheng = cityData[i]; for (let j = 0; j < sheng.children.length; j++) { let shi = sheng.children[j]; if (shi.value == cityNo) { // 使用return 终止循环 return `${sheng.label}-${shi.label}`; } } } }, /* * obj 转 params字符串参数 * 例子:{a:1,b:2} => a=1&b=2 */ objParseParam(obj) { let paramsStr = ""; if (obj instanceof Array) return paramsStr; if (!(obj instanceof Object)) return paramsStr; for (let key in obj) { paramsStr += `${key}=${obj[key]}&`; } return paramsStr.substring(0, paramsStr.length - 1); }, /* * obj 转 路由地址带参数 * 例子:{a:1,b:2} => /pages/index/index?a=1&b=2 */ objParseUrlAndParam(path, obj) { let url = path || "/"; let paramsStr = ""; if (obj instanceof Array) return url; if (!(obj instanceof Object)) return url; paramsStr = this.objParseParam(obj); paramsStr && (url += "?"); url += paramsStr; return url; }, /* * 获取url字符串参数 */ getRequestParameters(locationhref) { let href = locationhref || ""; let theRequest = new Object(); let str = href.split("?")[1]; if (str != undefined) { let strs = str.split("&"); for (let i = 0; i < strs.length; i++) { theRequest[strs[i].split("=")[0]] = (strs[i].split("=")[1]); } } return theRequest; }, /* * 银行卡每四位空格 */ formatCardNo(cardNo) { cardNo += ""; return cardNo.replace(/\s/g, '').replace(/[^\d]/g, '').replace(/(\d{4})(?=\d)/g, '$1 '); }, /** * 乘法,解决js精度损失问题 * @param {*} arg1 * @param {*} arg2 */ accMul(arg1, arg2) { arg1 = arg1 || 0; var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); try { m += s1.split(".")[1].length } catch (e) {} try { m += s2.split(".")[1].length } catch (e) {} return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m) }, // 生成树形结构 transData(jsonArr, idStr, pidStr, childrenStr){ // 存放的最终结果树数组 const result = []; const id = idStr; const parentId = pidStr; const children = childrenStr; const len = jsonArr.length; // 遍历得到以id为键名的对象(建立整棵树的索引) const hash = {}; jsonArr.forEach(item => { hash[item[id]] = item; }); for (let j = 0; j < len; j++) { const jsonArrItem = jsonArr[j]; const hashItem = hash[jsonArrItem[parentId]]; if (hashItem) { // 如果当前项还没有children属性,则添加该属性并设置为空数组 !hashItem[children] && (hashItem[children] = []); hashItem[children].push(jsonArrItem); } else { result.push(jsonArrItem); } } return result; } } ================================================ FILE: components/GoEasyAudioPlayer/GoEasyAudioPlayer.vue ================================================ ================================================ FILE: components/QS-tabs/QS-tabs.vue ================================================ ================================================ FILE: components/m-ad/m-ad.vue ================================================ ================================================ FILE: components/m-cc-btn/m-cc-btn.vue ================================================ ================================================ FILE: components/m-cc-popup/m-cc-popup.vue ================================================ ================================================ FILE: components/m-cell/m-cell.vue ================================================ ================================================ FILE: components/m-codedialog/m-codedialog.vue ================================================ ================================================ FILE: components/m-company/m-company.vue ================================================ ================================================ FILE: components/m-empty-data/m-empty-data.vue ================================================ ================================================ FILE: components/m-fail/m-fail.vue ================================================ ================================================ FILE: components/m-format-card/m-format-card.vue ================================================ ================================================ FILE: components/m-format-phone/m-format-phone.vue ================================================ ================================================ FILE: components/m-icon/m-icon.css ================================================ @font-face { font-family: uniicons; font-weight: normal; font-style: normal; src: url('https://img-cdn-qiniu.dcloud.net.cn/fonts/uni.ttf?t=1536565627510') format('truetype'); } .m-icon { font-family: uniicons; font-size: 48upx; font-weight: normal; font-style: normal; line-height: 1; display: inline-block; text-decoration: none; -webkit-font-smoothing: antialiased; } .m-icon.uni-active { color: #007aff; } .m-icon-contact:before { content: '\e100'; } .m-icon-person:before { content: '\e101'; } .m-icon-personadd:before { content: '\e102'; } .m-icon-contact-filled:before { content: '\e130'; } .m-icon-person-filled:before { content: '\e131'; } .m-icon-personadd-filled:before { content: '\e132'; } .m-icon-phone:before { content: '\e200'; } .m-icon-email:before { content: '\e201'; } .m-icon-chatbubble:before { content: '\e202'; } .m-icon-chatboxes:before { content: '\e203'; } .m-icon-phone-filled:before { content: '\e230'; } .m-icon-email-filled:before { content: '\e231'; } .m-icon-chatbubble-filled:before { content: '\e232'; } .m-icon-chatboxes-filled:before { content: '\e233'; } .m-icon-weibo:before { content: '\e260'; } .m-icon-weixin:before { content: '\e261'; } .m-icon-pengyouquan:before { content: '\e262'; } .m-icon-chat:before { content: '\e263'; } .m-icon-qq:before { content: '\e264'; } .m-icon-videocam:before { content: '\e300'; } .m-icon-camera:before { content: '\e301'; } .m-icon-mic:before { content: '\e302'; } .m-icon-location:before { content: '\e303'; } .m-icon-mic-filled:before, .m-icon-speech:before { content: '\e332'; } .m-icon-location-filled:before { content: '\e333'; } .m-icon-micoff:before { content: '\e360'; } .m-icon-image:before { content: '\e363'; } .m-icon-map:before { content: '\e364'; } .m-icon-compose:before { content: '\e400'; } .m-icon-trash:before { content: '\e401'; } .m-icon-upload:before { content: '\e402'; } .m-icon-download:before { content: '\e403'; } .m-icon-close:before { content: '\e404'; } .m-icon-redo:before { content: '\e405'; } .m-icon-undo:before { content: '\e406'; } .m-icon-refresh:before { content: '\e407'; } .m-icon-star:before { content: '\e408'; } .m-icon-plus:before { content: '\e409'; } .m-icon-minus:before { content: '\e410'; } .m-icon-circle:before, .m-icon-checkbox:before { content: '\e411'; } .m-icon-close-filled:before, .m-icon-clear:before { content: '\e434'; } .m-icon-refresh-filled:before { content: '\e437'; } .m-icon-star-filled:before { content: '\e438'; } .m-icon-plus-filled:before { content: '\e439'; } .m-icon-minus-filled:before { content: '\e440'; } .m-icon-circle-filled:before { content: '\e441'; } .m-icon-checkbox-filled:before { content: '\e442'; } .m-icon-closeempty:before { content: '\e460'; } .m-icon-refreshempty:before { content: '\e461'; } .m-icon-reload:before { content: '\e462'; } .m-icon-starhalf:before { content: '\e463'; } .m-icon-spinner:before { content: '\e464'; } .m-icon-spinner-cycle:before { content: '\e465'; } .m-icon-search:before { content: '\e466'; } .m-icon-plusempty:before { content: '\e468'; } .m-icon-forward:before { content: '\e470'; } .m-icon-back:before, .m-icon-left-nav:before { content: '\e471'; } .m-icon-checkmarkempty:before { content: '\e472'; } .m-icon-home:before { content: '\e500'; } .m-icon-navigate:before { content: '\e501'; } .m-icon-gear:before { content: '\e502'; } .m-icon-paperplane:before { content: '\e503'; } .m-icon-info:before { content: '\e504'; } .m-icon-help:before { content: '\e505'; } .m-icon-locked:before { content: '\e506'; } .m-icon-more:before { content: '\e507'; } .m-icon-flag:before { content: '\e508'; } .m-icon-home-filled:before { content: '\e530'; } .m-icon-gear-filled:before { content: '\e532'; } .m-icon-info-filled:before { content: '\e534'; } .m-icon-help-filled:before { content: '\e535'; } .m-icon-more-filled:before { content: '\e537'; } .m-icon-settings:before { content: '\e560'; } .m-icon-list:before { content: '\e562'; } .m-icon-bars:before { content: '\e563'; } .m-icon-loop:before { content: '\e565'; } .m-icon-paperclip:before { content: '\e567'; } .m-icon-eye:before { content: '\e568'; } .m-icon-arrowup:before { content: '\e580'; } .m-icon-arrowdown:before { content: '\e581'; } .m-icon-arrowleft:before { content: '\e582'; } .m-icon-arrowright:before { content: '\e583'; } .m-icon-arrowthinup:before { content: '\e584'; } .m-icon-arrowthindown:before { content: '\e585'; } .m-icon-arrowthinleft:before { content: '\e586'; } .m-icon-arrowthinright:before { content: '\e587'; } .m-icon-pulldown:before { content: '\e588'; } .m-icon-scan:before { content: "\e612"; } ================================================ FILE: components/m-icon/m-icon.vue ================================================ ================================================ FILE: components/m-input/m-input.vue ================================================ ================================================ FILE: components/m-page-view/m-page-view.vue ================================================ ================================================ FILE: components/m-popup/m-popup.vue ================================================ ================================================ FILE: components/m-popup-header/m-popup-header.vue ================================================ ================================================ FILE: components/m-position/m-position.vue ================================================ ================================================ FILE: components/m-qrcode/m-qrcode.vue ================================================ ================================================ FILE: components/m-qrcode/qrcode.js ================================================ let QRCode = {}; (function () { /** * 获取单个字符的utf8编码 * unicode BMP平面约65535个字符 * @param {num} code * return {array} */ function unicodeFormat8(code) { // 1 byte var c0, c1, c2; if (code < 128) { return [code]; // 2 bytes } else if (code < 2048) { c0 = 192 + (code >> 6); c1 = 128 + (code & 63); return [c0, c1]; // 3 bytes } else { c0 = 224 + (code >> 12); c1 = 128 + (code >> 6 & 63); c2 = 128 + (code & 63); return [c0, c1, c2]; } } /** * 获取字符串的utf8编码字节串 * @param {string} string * @return {array} */ function getUTF8Bytes(string) { var utf8codes = []; for (var i = 0; i < string.length; i++) { var code = string.charCodeAt(i); var utf8 = unicodeFormat8(code); for (var j = 0; j < utf8.length; j++) { utf8codes.push(utf8[j]); } } return utf8codes; } /** * 二维码算法实现 * @param {string} data 要编码的信息字符串 * @param {num} errorCorrectLevel 纠错等级 */ function QRCodeAlg(data, errorCorrectLevel) { this.typeNumber = -1; //版本 this.errorCorrectLevel = errorCorrectLevel; this.modules = null; //二维矩阵,存放最终结果 this.moduleCount = 0; //矩阵大小 this.dataCache = null; //数据缓存 this.rsBlocks = null; //版本数据信息 this.totalDataCount = -1; //可使用的数据量 this.data = data; this.utf8bytes = getUTF8Bytes(data); this.make(); } QRCodeAlg.prototype = { constructor: QRCodeAlg, /** * 获取二维码矩阵大小 * @return {num} 矩阵大小 */ getModuleCount: function () { return this.moduleCount; }, /** * 编码 */ make: function () { this.getRightType(); this.dataCache = this.createData(); this.createQrcode(); }, /** * 设置二位矩阵功能图形 * @param {bool} test 表示是否在寻找最好掩膜阶段 * @param {num} maskPattern 掩膜的版本 */ makeImpl: function (maskPattern) { this.moduleCount = this.typeNumber * 4 + 17; this.modules = new Array(this.moduleCount); for (var row = 0; row < this.moduleCount; row++) { this.modules[row] = new Array(this.moduleCount); } this.setupPositionProbePattern(0, 0); this.setupPositionProbePattern(this.moduleCount - 7, 0); this.setupPositionProbePattern(0, this.moduleCount - 7); this.setupPositionAdjustPattern(); this.setupTimingPattern(); this.setupTypeInfo(true, maskPattern); if (this.typeNumber >= 7) { this.setupTypeNumber(true); } this.mapData(this.dataCache, maskPattern); }, /** * 设置二维码的位置探测图形 * @param {num} row 探测图形的中心横坐标 * @param {num} col 探测图形的中心纵坐标 */ setupPositionProbePattern: function (row, col) { for (var r = -1; r <= 7; r++) { if (row + r <= -1 || this.moduleCount <= row + r) continue; for (var c = -1; c <= 7; c++) { if (col + c <= -1 || this.moduleCount <= col + c) continue; if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 && 2 <= c && c <= 4)) { this.modules[row + r][col + c] = true; } else { this.modules[row + r][col + c] = false; } } } }, /** * 创建二维码 * @return {[type]} [description] */ createQrcode: function () { var minLostPoint = 0; var pattern = 0; var bestModules = null; for (var i = 0; i < 8; i++) { this.makeImpl(i); var lostPoint = QRUtil.getLostPoint(this); if (i == 0 || minLostPoint > lostPoint) { minLostPoint = lostPoint; pattern = i; bestModules = this.modules; } } this.modules = bestModules; this.setupTypeInfo(false, pattern); if (this.typeNumber >= 7) { this.setupTypeNumber(false); } }, /** * 设置定位图形 * @return {[type]} [description] */ setupTimingPattern: function () { for (var r = 8; r < this.moduleCount - 8; r++) { if (this.modules[r][6] != null) { continue; } this.modules[r][6] = (r % 2 == 0); if (this.modules[6][r] != null) { continue; } this.modules[6][r] = (r % 2 == 0); } }, /** * 设置矫正图形 * @return {[type]} [description] */ setupPositionAdjustPattern: function () { var pos = QRUtil.getPatternPosition(this.typeNumber); for (var i = 0; i < pos.length; i++) { for (var j = 0; j < pos.length; j++) { var row = pos[i]; var col = pos[j]; if (this.modules[row][col] != null) { continue; } for (var r = -2; r <= 2; r++) { for (var c = -2; c <= 2; c++) { if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) { this.modules[row + r][col + c] = true; } else { this.modules[row + r][col + c] = false; } } } } } }, /** * 设置版本信息(7以上版本才有) * @param {bool} test 是否处于判断最佳掩膜阶段 * @return {[type]} [description] */ setupTypeNumber: function (test) { var bits = QRUtil.getBCHTypeNumber(this.typeNumber); for (var i = 0; i < 18; i++) { var mod = (!test && ((bits >> i) & 1) == 1); this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; } }, /** * 设置格式信息(纠错等级和掩膜版本) * @param {bool} test * @param {num} maskPattern 掩膜版本 * @return {} */ setupTypeInfo: function (test, maskPattern) { var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern; var bits = QRUtil.getBCHTypeInfo(data); // vertical for (var i = 0; i < 15; i++) { var mod = (!test && ((bits >> i) & 1) == 1); if (i < 6) { this.modules[i][8] = mod; } else if (i < 8) { this.modules[i + 1][8] = mod; } else { this.modules[this.moduleCount - 15 + i][8] = mod; } // horizontal var mod = (!test && ((bits >> i) & 1) == 1); if (i < 8) { this.modules[8][this.moduleCount - i - 1] = mod; } else if (i < 9) { this.modules[8][15 - i - 1 + 1] = mod; } else { this.modules[8][15 - i - 1] = mod; } } // fixed module this.modules[this.moduleCount - 8][8] = (!test); }, /** * 数据编码 * @return {[type]} [description] */ createData: function () { var buffer = new QRBitBuffer(); var lengthBits = this.typeNumber > 9 ? 16 : 8; buffer.put(4, 4); //添加模式 buffer.put(this.utf8bytes.length, lengthBits); for (var i = 0, l = this.utf8bytes.length; i < l; i++) { buffer.put(this.utf8bytes[i], 8); } if (buffer.length + 4 <= this.totalDataCount * 8) { buffer.put(0, 4); } // padding while (buffer.length % 8 != 0) { buffer.putBit(false); } // padding while (true) { if (buffer.length >= this.totalDataCount * 8) { break; } buffer.put(QRCodeAlg.PAD0, 8); if (buffer.length >= this.totalDataCount * 8) { break; } buffer.put(QRCodeAlg.PAD1, 8); } return this.createBytes(buffer); }, /** * 纠错码编码 * @param {buffer} buffer 数据编码 * @return {[type]} */ createBytes: function (buffer) { var offset = 0; var maxDcCount = 0; var maxEcCount = 0; var length = this.rsBlock.length / 3; var rsBlocks = new Array(); for (var i = 0; i < length; i++) { var count = this.rsBlock[i * 3 + 0]; var totalCount = this.rsBlock[i * 3 + 1]; var dataCount = this.rsBlock[i * 3 + 2]; for (var j = 0; j < count; j++) { rsBlocks.push([dataCount, totalCount]); } } var dcdata = new Array(rsBlocks.length); var ecdata = new Array(rsBlocks.length); for (var r = 0; r < rsBlocks.length; r++) { var dcCount = rsBlocks[r][0]; var ecCount = rsBlocks[r][1] - dcCount; maxDcCount = Math.max(maxDcCount, dcCount); maxEcCount = Math.max(maxEcCount, ecCount); dcdata[r] = new Array(dcCount); for (var i = 0; i < dcdata[r].length; i++) { dcdata[r][i] = 0xff & buffer.buffer[i + offset]; } offset += dcCount; var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); var modPoly = rawPoly.mod(rsPoly); ecdata[r] = new Array(rsPoly.getLength() - 1); for (var i = 0; i < ecdata[r].length; i++) { var modIndex = i + modPoly.getLength() - ecdata[r].length; ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0; } } var data = new Array(this.totalDataCount); var index = 0; for (var i = 0; i < maxDcCount; i++) { for (var r = 0; r < rsBlocks.length; r++) { if (i < dcdata[r].length) { data[index++] = dcdata[r][i]; } } } for (var i = 0; i < maxEcCount; i++) { for (var r = 0; r < rsBlocks.length; r++) { if (i < ecdata[r].length) { data[index++] = ecdata[r][i]; } } } return data; }, /** * 布置模块,构建最终信息 * @param {} data * @param {} maskPattern * @return {} */ mapData: function (data, maskPattern) { var inc = -1; var row = this.moduleCount - 1; var bitIndex = 7; var byteIndex = 0; for (var col = this.moduleCount - 1; col > 0; col -= 2) { if (col == 6) col--; while (true) { for (var c = 0; c < 2; c++) { if (this.modules[row][col - c] == null) { var dark = false; if (byteIndex < data.length) { dark = (((data[byteIndex] >>> bitIndex) & 1) == 1); } var mask = QRUtil.getMask(maskPattern, row, col - c); if (mask) { dark = !dark; } this.modules[row][col - c] = dark; bitIndex--; if (bitIndex == -1) { byteIndex++; bitIndex = 7; } } } row += inc; if (row < 0 || this.moduleCount <= row) { row -= inc; inc = -inc; break; } } } } }; /** * 填充字段 */ QRCodeAlg.PAD0 = 0xEC; QRCodeAlg.PAD1 = 0x11; //--------------------------------------------------------------------- // 纠错等级对应的编码 //--------------------------------------------------------------------- var QRErrorCorrectLevel = [1, 0, 3, 2]; //--------------------------------------------------------------------- // 掩膜版本 //--------------------------------------------------------------------- var QRMaskPattern = { PATTERN000: 0, PATTERN001: 1, PATTERN010: 2, PATTERN011: 3, PATTERN100: 4, PATTERN101: 5, PATTERN110: 6, PATTERN111: 7 }; //--------------------------------------------------------------------- // 工具类 //--------------------------------------------------------------------- var QRUtil = { /* 每个版本矫正图形的位置 */ PATTERN_POSITION_TABLE: [ [], [6, 18], [6, 22], [6, 26], [6, 30], [6, 34], [6, 22, 38], [6, 24, 42], [6, 26, 46], [6, 28, 50], [6, 30, 54], [6, 32, 58], [6, 34, 62], [6, 26, 46, 66], [6, 26, 48, 70], [6, 26, 50, 74], [6, 30, 54, 78], [6, 30, 56, 82], [6, 30, 58, 86], [6, 34, 62, 90], [6, 28, 50, 72, 94], [6, 26, 50, 74, 98], [6, 30, 54, 78, 102], [6, 28, 54, 80, 106], [6, 32, 58, 84, 110], [6, 30, 58, 86, 114], [6, 34, 62, 90, 118], [6, 26, 50, 74, 98, 122], [6, 30, 54, 78, 102, 126], [6, 26, 52, 78, 104, 130], [6, 30, 56, 82, 108, 134], [6, 34, 60, 86, 112, 138], [6, 30, 58, 86, 114, 142], [6, 34, 62, 90, 118, 146], [6, 30, 54, 78, 102, 126, 150], [6, 24, 50, 76, 102, 128, 154], [6, 28, 54, 80, 106, 132, 158], [6, 32, 58, 84, 110, 136, 162], [6, 26, 54, 82, 110, 138, 166], [6, 30, 58, 86, 114, 142, 170] ], G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), /* BCH编码格式信息 */ getBCHTypeInfo: function (data) { var d = data << 10; while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))); } return ((data << 10) | d) ^ QRUtil.G15_MASK; }, /* BCH编码版本信息 */ getBCHTypeNumber: function (data) { var d = data << 12; while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))); } return (data << 12) | d; }, /* 获取BCH位信息 */ getBCHDigit: function (data) { var digit = 0; while (data != 0) { digit++; data >>>= 1; } return digit; }, /* 获取版本对应的矫正图形位置 */ getPatternPosition: function (typeNumber) { return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; }, /* 掩膜算法 */ getMask: function (maskPattern, i, j) { switch (maskPattern) { case QRMaskPattern.PATTERN000: return (i + j) % 2 == 0; case QRMaskPattern.PATTERN001: return i % 2 == 0; case QRMaskPattern.PATTERN010: return j % 3 == 0; case QRMaskPattern.PATTERN011: return (i + j) % 3 == 0; case QRMaskPattern.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; case QRMaskPattern.PATTERN101: return (i * j) % 2 + (i * j) % 3 == 0; case QRMaskPattern.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 == 0; case QRMaskPattern.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 == 0; default: throw new Error("bad maskPattern:" + maskPattern); } }, /* 获取RS的纠错多项式 */ getErrorCorrectPolynomial: function (errorCorrectLength) { var a = new QRPolynomial([1], 0); for (var i = 0; i < errorCorrectLength; i++) { a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0)); } return a; }, /* 获取评价 */ getLostPoint: function (qrCode) { var moduleCount = qrCode.getModuleCount(), lostPoint = 0, darkCount = 0; for (var row = 0; row < moduleCount; row++) { var sameCount = 0; var head = qrCode.modules[row][0]; for (var col = 0; col < moduleCount; col++) { var current = qrCode.modules[row][col]; //level 3 评价 if (col < moduleCount - 6) { if (current && !qrCode.modules[row][col + 1] && qrCode.modules[row][col + 2] && qrCode.modules[row][col + 3] && qrCode.modules[row][col + 4] && !qrCode.modules[row][col + 5] && qrCode.modules[row][col + 6]) { if (col < moduleCount - 10) { if (qrCode.modules[row][col + 7] && qrCode.modules[row][col + 8] && qrCode.modules[row][col + 9] && qrCode.modules[row][col + 10]) { lostPoint += 40; } } else if (col > 3) { if (qrCode.modules[row][col - 1] && qrCode.modules[row][col - 2] && qrCode.modules[row][col - 3] && qrCode.modules[row][col - 4]) { lostPoint += 40; } } } } //level 2 评价 if ((row < moduleCount - 1) && (col < moduleCount - 1)) { var count = 0; if (current) count++; if (qrCode.modules[row + 1][col]) count++; if (qrCode.modules[row][col + 1]) count++; if (qrCode.modules[row + 1][col + 1]) count++; if (count == 0 || count == 4) { lostPoint += 3; } } //level 1 评价 if (head ^ current) { sameCount++; } else { head = current; if (sameCount >= 5) { lostPoint += (3 + sameCount - 5); } sameCount = 1; } //level 4 评价 if (current) { darkCount++; } } } for (var col = 0; col < moduleCount; col++) { var sameCount = 0; var head = qrCode.modules[0][col]; for (var row = 0; row < moduleCount; row++) { var current = qrCode.modules[row][col]; //level 3 评价 if (row < moduleCount - 6) { if (current && !qrCode.modules[row + 1][col] && qrCode.modules[row + 2][col] && qrCode.modules[row + 3][col] && qrCode.modules[row + 4][col] && !qrCode.modules[row + 5][col] && qrCode.modules[row + 6][col]) { if (row < moduleCount - 10) { if (qrCode.modules[row + 7][col] && qrCode.modules[row + 8][col] && qrCode.modules[row + 9][col] && qrCode.modules[row + 10][col]) { lostPoint += 40; } } else if (row > 3) { if (qrCode.modules[row - 1][col] && qrCode.modules[row - 2][col] && qrCode.modules[row - 3][col] && qrCode.modules[row - 4][col]) { lostPoint += 40; } } } } //level 1 评价 if (head ^ current) { sameCount++; } else { head = current; if (sameCount >= 5) { lostPoint += (3 + sameCount - 5); } sameCount = 1; } } } // LEVEL4 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; lostPoint += ratio * 10; return lostPoint; } }; //--------------------------------------------------------------------- // QRMath使用的数学工具 //--------------------------------------------------------------------- var QRMath = { /* 将n转化为a^m */ glog: function (n) { if (n < 1) { throw new Error("glog(" + n + ")"); } return QRMath.LOG_TABLE[n]; }, /* 将a^m转化为n */ gexp: function (n) { while (n < 0) { n += 255; } while (n >= 256) { n -= 255; } return QRMath.EXP_TABLE[n]; }, EXP_TABLE: new Array(256), LOG_TABLE: new Array(256) }; for (var i = 0; i < 8; i++) { QRMath.EXP_TABLE[i] = 1 << i; } for (var i = 8; i < 256; i++) { QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8]; } for (var i = 0; i < 255; i++) { QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; } //--------------------------------------------------------------------- // QRPolynomial 多项式 //--------------------------------------------------------------------- /** * 多项式类 * @param {Array} num 系数 * @param {num} shift a^shift */ function QRPolynomial(num, shift) { if (num.length == undefined) { throw new Error(num.length + "/" + shift); } var offset = 0; while (offset < num.length && num[offset] == 0) { offset++; } this.num = new Array(num.length - offset + shift); for (var i = 0; i < num.length - offset; i++) { this.num[i] = num[i + offset]; } } QRPolynomial.prototype = { get: function (index) { return this.num[index]; }, getLength: function () { return this.num.length; }, /** * 多项式乘法 * @param {QRPolynomial} e 被乘多项式 * @return {[type]} [description] */ multiply: function (e) { var num = new Array(this.getLength() + e.getLength() - 1); for (var i = 0; i < this.getLength(); i++) { for (var j = 0; j < e.getLength(); j++) { num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))); } } return new QRPolynomial(num, 0); }, /** * 多项式模运算 * @param {QRPolynomial} e 模多项式 * @return {} */ mod: function (e) { var tl = this.getLength(), el = e.getLength(); if (tl - el < 0) { return this; } var num = new Array(tl); for (var i = 0; i < tl; i++) { num[i] = this.get(i); } while (num.length >= el) { var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0)); for (var i = 0; i < e.getLength(); i++) { num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); } while (num[0] == 0) { num.shift(); } } return new QRPolynomial(num, 0); } }; //--------------------------------------------------------------------- // RS_BLOCK_TABLE //--------------------------------------------------------------------- /* 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数] */ var RS_BLOCK_TABLE = [ // L // M // Q // H // 1 [1, 26, 19], [1, 26, 16], [1, 26, 13], [1, 26, 9], // 2 [1, 44, 34], [1, 44, 28], [1, 44, 22], [1, 44, 16], // 3 [1, 70, 55], [1, 70, 44], [2, 35, 17], [2, 35, 13], // 4 [1, 100, 80], [2, 50, 32], [2, 50, 24], [4, 25, 9], // 5 [1, 134, 108], [2, 67, 43], [2, 33, 15, 2, 34, 16], [2, 33, 11, 2, 34, 12], // 6 [2, 86, 68], [4, 43, 27], [4, 43, 19], [4, 43, 15], // 7 [2, 98, 78], [4, 49, 31], [2, 32, 14, 4, 33, 15], [4, 39, 13, 1, 40, 14], // 8 [2, 121, 97], [2, 60, 38, 2, 61, 39], [4, 40, 18, 2, 41, 19], [4, 40, 14, 2, 41, 15], // 9 [2, 146, 116], [3, 58, 36, 2, 59, 37], [4, 36, 16, 4, 37, 17], [4, 36, 12, 4, 37, 13], // 10 [2, 86, 68, 2, 87, 69], [4, 69, 43, 1, 70, 44], [6, 43, 19, 2, 44, 20], [6, 43, 15, 2, 44, 16], // 11 [4, 101, 81], [1, 80, 50, 4, 81, 51], [4, 50, 22, 4, 51, 23], [3, 36, 12, 8, 37, 13], // 12 [2, 116, 92, 2, 117, 93], [6, 58, 36, 2, 59, 37], [4, 46, 20, 6, 47, 21], [7, 42, 14, 4, 43, 15], // 13 [4, 133, 107], [8, 59, 37, 1, 60, 38], [8, 44, 20, 4, 45, 21], [12, 33, 11, 4, 34, 12], // 14 [3, 145, 115, 1, 146, 116], [4, 64, 40, 5, 65, 41], [11, 36, 16, 5, 37, 17], [11, 36, 12, 5, 37, 13], // 15 [5, 109, 87, 1, 110, 88], [5, 65, 41, 5, 66, 42], [5, 54, 24, 7, 55, 25], [11, 36, 12], // 16 [5, 122, 98, 1, 123, 99], [7, 73, 45, 3, 74, 46], [15, 43, 19, 2, 44, 20], [3, 45, 15, 13, 46, 16], // 17 [1, 135, 107, 5, 136, 108], [10, 74, 46, 1, 75, 47], [1, 50, 22, 15, 51, 23], [2, 42, 14, 17, 43, 15], // 18 [5, 150, 120, 1, 151, 121], [9, 69, 43, 4, 70, 44], [17, 50, 22, 1, 51, 23], [2, 42, 14, 19, 43, 15], // 19 [3, 141, 113, 4, 142, 114], [3, 70, 44, 11, 71, 45], [17, 47, 21, 4, 48, 22], [9, 39, 13, 16, 40, 14], // 20 [3, 135, 107, 5, 136, 108], [3, 67, 41, 13, 68, 42], [15, 54, 24, 5, 55, 25], [15, 43, 15, 10, 44, 16], // 21 [4, 144, 116, 4, 145, 117], [17, 68, 42], [17, 50, 22, 6, 51, 23], [19, 46, 16, 6, 47, 17], // 22 [2, 139, 111, 7, 140, 112], [17, 74, 46], [7, 54, 24, 16, 55, 25], [34, 37, 13], // 23 [4, 151, 121, 5, 152, 122], [4, 75, 47, 14, 76, 48], [11, 54, 24, 14, 55, 25], [16, 45, 15, 14, 46, 16], // 24 [6, 147, 117, 4, 148, 118], [6, 73, 45, 14, 74, 46], [11, 54, 24, 16, 55, 25], [30, 46, 16, 2, 47, 17], // 25 [8, 132, 106, 4, 133, 107], [8, 75, 47, 13, 76, 48], [7, 54, 24, 22, 55, 25], [22, 45, 15, 13, 46, 16], // 26 [10, 142, 114, 2, 143, 115], [19, 74, 46, 4, 75, 47], [28, 50, 22, 6, 51, 23], [33, 46, 16, 4, 47, 17], // 27 [8, 152, 122, 4, 153, 123], [22, 73, 45, 3, 74, 46], [8, 53, 23, 26, 54, 24], [12, 45, 15, 28, 46, 16], // 28 [3, 147, 117, 10, 148, 118], [3, 73, 45, 23, 74, 46], [4, 54, 24, 31, 55, 25], [11, 45, 15, 31, 46, 16], // 29 [7, 146, 116, 7, 147, 117], [21, 73, 45, 7, 74, 46], [1, 53, 23, 37, 54, 24], [19, 45, 15, 26, 46, 16], // 30 [5, 145, 115, 10, 146, 116], [19, 75, 47, 10, 76, 48], [15, 54, 24, 25, 55, 25], [23, 45, 15, 25, 46, 16], // 31 [13, 145, 115, 3, 146, 116], [2, 74, 46, 29, 75, 47], [42, 54, 24, 1, 55, 25], [23, 45, 15, 28, 46, 16], // 32 [17, 145, 115], [10, 74, 46, 23, 75, 47], [10, 54, 24, 35, 55, 25], [19, 45, 15, 35, 46, 16], // 33 [17, 145, 115, 1, 146, 116], [14, 74, 46, 21, 75, 47], [29, 54, 24, 19, 55, 25], [11, 45, 15, 46, 46, 16], // 34 [13, 145, 115, 6, 146, 116], [14, 74, 46, 23, 75, 47], [44, 54, 24, 7, 55, 25], [59, 46, 16, 1, 47, 17], // 35 [12, 151, 121, 7, 152, 122], [12, 75, 47, 26, 76, 48], [39, 54, 24, 14, 55, 25], [22, 45, 15, 41, 46, 16], // 36 [6, 151, 121, 14, 152, 122], [6, 75, 47, 34, 76, 48], [46, 54, 24, 10, 55, 25], [2, 45, 15, 64, 46, 16], // 37 [17, 152, 122, 4, 153, 123], [29, 74, 46, 14, 75, 47], [49, 54, 24, 10, 55, 25], [24, 45, 15, 46, 46, 16], // 38 [4, 152, 122, 18, 153, 123], [13, 74, 46, 32, 75, 47], [48, 54, 24, 14, 55, 25], [42, 45, 15, 32, 46, 16], // 39 [20, 147, 117, 4, 148, 118], [40, 75, 47, 7, 76, 48], [43, 54, 24, 22, 55, 25], [10, 45, 15, 67, 46, 16], // 40 [19, 148, 118, 6, 149, 119], [18, 75, 47, 31, 76, 48], [34, 54, 24, 34, 55, 25], [20, 45, 15, 61, 46, 16] ]; /** * 根据数据获取对应版本 * @return {[type]} [description] */ QRCodeAlg.prototype.getRightType = function () { for (var typeNumber = 1; typeNumber < 41; typeNumber++) { var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel]; if (rsBlock == undefined) { throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + this.errorCorrectLevel); } var length = rsBlock.length / 3; var totalDataCount = 0; for (var i = 0; i < length; i++) { var count = rsBlock[i * 3 + 0]; var dataCount = rsBlock[i * 3 + 2]; totalDataCount += dataCount * count; } var lengthBytes = typeNumber > 9 ? 2 : 1; if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) { this.typeNumber = typeNumber; this.rsBlock = rsBlock; this.totalDataCount = totalDataCount; break; } } }; //--------------------------------------------------------------------- // QRBitBuffer //--------------------------------------------------------------------- function QRBitBuffer() { this.buffer = new Array(); this.length = 0; } QRBitBuffer.prototype = { get: function (index) { var bufIndex = Math.floor(index / 8); return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1); }, put: function (num, length) { for (var i = 0; i < length; i++) { this.putBit(((num >>> (length - i - 1)) & 1)); } }, putBit: function (bit) { var bufIndex = Math.floor(this.length / 8); if (this.buffer.length <= bufIndex) { this.buffer.push(0); } if (bit) { this.buffer[bufIndex] |= (0x80 >>> (this.length % 8)); } this.length++; } }; // xzedit let qrcodeAlgObjCache = []; /** * 二维码构造函数,主要用于绘制 * @param {参数列表} opt 传递参数 * @return {} */ QRCode = function (opt) { //设置默认参数 this.options = { text: '', size: 256, correctLevel: 3, background: '#ffffff', foreground: '#000000', image: '', imageSize: 30, canvasId: '_myQrCodeCanvas' }; if (typeof opt === 'string') { // 只编码ASCII字符串 opt = { text: opt }; } if (opt) { for (var i in opt) { this.options[i] = opt[i]; } } //使用QRCodeAlg创建二维码结构 var qrCodeAlg = null; for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) { if (qrcodeAlgObjCache[i].text == this.options.text && qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel) { qrCodeAlg = qrcodeAlgObjCache[i].obj; break; } } if (i == l) { qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel); qrcodeAlgObjCache.push({ text: this.options.text, correctLevel: this.options.correctLevel, obj: qrCodeAlg }); } /** * 计算矩阵点的前景色 * @param {Obj} config * @param {Number} config.row 点x坐标 * @param {Number} config.col 点y坐标 * @param {Number} config.count 矩阵大小 * @param {Number} config.options 组件的options * @return {String} */ let getForeGround = function (config) { var options = config.options; if (options.pdground && ( (config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) || (config.row > (config.count - 6) && config.row < (config.count - 2) && config.col > 1 && config.col < 5) || (config.row > 1 && config.row < 5 && config.col > (config.count - 6) && config.col < (config.count - 2)) )) { return options.pdground; } return options.foreground; } // 创建canvas let createCanvas = function (config) { uni.showLoading({ title: "二维码生成中", mask: true }); var options = config; var ctx = uni.createCanvasContext(options.canvasId); var count = qrCodeAlg.getModuleCount(); var ratioSize = options.size; var ratioImgSize = options.imageSize; //计算每个点的长宽 var tileW = (ratioSize / count).toPrecision(4); var tileH = (ratioSize / count).toPrecision(4); //绘制 for (var row = 0; row < count; row++) { for (var col = 0; col < count; col++) { var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)); var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)); var foreground = getForeGround({ row: row, col: col, count: count, options: options }); ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background); ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h); } } if (options.image) { var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2)); var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2)); drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true) ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize); // 画圆角矩形 function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) { ctxi.setLineWidth(lineWidth); ctxi.setFillStyle(options.background); ctxi.setStrokeStyle(options.background); ctxi.beginPath(); // draw top and top right corner ctxi.moveTo(x + r, y); ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner ctxi.arcTo(x, y, x + r, y, r); ctxi.closePath(); if (fill) { ctxi.fill(); } if (stroke) { ctxi.stroke(); } } } ctx.draw(false, () => { // 保存到临时区域 uni.canvasToTempFilePath({ width: options.width, height: options.height, destWidth: options.width, destHeight: options.height, canvasId: options.canvasId, quality: Number(1), success: function (res) { if (options.cbResult) { // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath if (!empty(res.tempFilePath)) { options.cbResult(res.tempFilePath) } else if (!empty(res.apFilePath)) { options.cbResult(res.apFilePath) } else { options.cbResult(res.tempFilePath) } } }, fail: function (res) { if (options.cbResult) { options.cbResult(res) } }, complete: function () { uni.hideLoading(); }, }) }) } createCanvas(this.options) // 空判定 let empty = function (v) { let tp = typeof v, rt = false; if (tp == "number" && String(v) == "") { rt = true } else if (tp == "undefined") { rt = true } else if (tp == "object") { if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true } else if (tp == "string") { if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true } else if (tp == "function") { rt = false } return rt } }; QRCode.prototype.clear = function (fn) { var ctx = uni.createCanvasContext(this.options.canvasId) ctx.clearRect(0, 0, this.options.size, this.options.size) ctx.draw(false, () => { if (fn) { fn() } }) }; })() export default QRCode ================================================ FILE: components/m-swiper/m-swiper.vue ================================================ ================================================ FILE: components/m-textarea/m-textarea.vue ================================================ ================================================ FILE: pages/user/help.vue ================================================ ================================================ FILE: pages/user/helpcenterDetails.vue ================================================ ================================================ FILE: pages/user/hideSetting.vue ================================================ ================================================ FILE: pages/user/person/edit-edu.vue ================================================ ================================================ FILE: pages/user/person/edit-expect.vue ================================================ ================================================ FILE: pages/user/person/edit-pro-content.vue ================================================