This commit is contained in:
18500206848
2024-02-02 14:44:30 +08:00
parent 6647042acb
commit 91172a730c
255 changed files with 24805 additions and 0 deletions

32
.gitignore vendored Normal file
View File

@@ -0,0 +1,32 @@
.DS_Store
node_modules
/dist
/tests/e2e/videos/
/tests/e2e/screenshots/
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
unpackage
node_modules
.idea
.hbuilderx
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
*.lock
# Mac #
.DS_Store
._.DS_Store

63
App.vue Normal file
View File

@@ -0,0 +1,63 @@
<script>
import {
mapGetters
} from 'vuex'
// #ifdef H5
import {
setPlatformByHostName
} from '@/untils/customized.js'
// #endif
export default {
onLaunch: function() {
if (this.$store.state.user.token) {
this.$store.dispatch('startRefreshTokenTimer')
this.$store.dispatch('startRefreshNewsTimer')
this.$store.dispatch('refreshAuthState')
}
// #ifdef H5
// 企业定制
setPlatformByHostName(this.$store)
// #endif
},
onShow: function() {},
onHide: function() {},
computed: {
...mapGetters(['news']),
allUnread() {
return this.news.allUnread
}
},
watch: {
allUnread(value) {
if (!this.$store.state.user.token) {} else if (value > 0) {
uni.showTabBarRedDot({
index: 2
})
uni.$once('newsReadChange', () => {
uni.showTabBarRedDot({
index: 2
})
})
} else {
uni.hideTabBarRedDot({
index: 2
})
uni.$once('newsReadChange', () => {
uni.hideTabBarRedDot({
index: 2
})
})
}
}
}
};
</script>
<style>
/*每个页面公共css */
/* tabbar 字体大小 */
/* .uni-tabbar__label{
font-size: 14px !important;
} */
</style>

36
README.en.md Normal file
View File

@@ -0,0 +1,36 @@
# 招聘
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

131
README.md Normal file
View File

@@ -0,0 +1,131 @@
# 通用框架
- 编码工具 使用 VSCODE
```bash
安装如下插件:
Chinese (Simplified)
ESLint
HTML CSS Support
minapp
Prettier - Code formatter
Prettier ESLint
Protobuf support
stylelint
Vetur
Vue 2 Snippets
markdownlint
```
- 版本控制
```bash
该项目未做版本控制,无公共或私有代码托管仓库
```
- 页面说明
```bash
"pages/index/index", //首页
"pages/mycomment/mycomment", //评价提交/评价查看页面
"pages/comment/comment",//我的评价页面
"pages/help/help",//帮助反馈
"pages/projectInfo/projectInfo",//任务详情
"pages/sala/sala",//我的工资
"pages/myProject/myProject",//我的任务
"pages/mapSeach/mapSeach",//地图搜索
"pages/project/project",//抢任务
"pages/addIcCard/addIcCard",//添加银行卡认证
"pages/icCard/icCard",//我的银行卡认证
"pages/realName/realName",//实名认证
"pages/setUserBase/setUserBase",//设置个人信息
"pages/userBase/userBase",//个人信息
"pages/resume/resume",//简历
"pages/my/my",//我的页面
"pages/news/news",//消息页面
"pages/newsList/newsList",//消息列表
"pages/newsDetail/newsDetail",//消息详情
"pages/set/set",//设置页面
"pages/login/login",//登录页面
"pages/addSkill/addSkill",//编辑职业技能
"pages/skillLevel/skillLevel",//职业技能水平
"pages/skill/skill",//我的技能
"pages/addInd/addInd",//添加行业
"pages/changePhone/changePhone",//修改手机号
"pages/setCode/setCode",//验证码获取
"pages/seach/seach",//公共搜索页面
"pages/bankList/bankList",//银行列表
"pages/setCity/setCity",//选择省份
"pages/cityInfo/cityInfo",//选择城市
"pages/setWskill/setWskill"//想学习的技能
```
- 目录命令规范
```bash
unpackage/dist/build 生成的目标代码,用小程序开发者工具最终打开的代码,并上传到小程序服务器的最终运行代码
docs/ 当前项目相关的说明文档
node_modules/ 当前项目编译所依赖的 JS 扩展
/ 源码目录
/main.js 入口文件
/pages.json 入口文件配置
/uni.wxss 全局样式
/components/ 组件存放
/static/ 本地图片存放
/utils/ 自己写的工具类函数方法
/utils/filters.wxs 在页面中使用的工具类函数
/lib/ 外部引入的工具类函数方法
/api/ api请求函数方法(可不使用)
/pages/ 主包页面,里面一级文件夹代表一个模块,二级文件夹代表一页 eg /pages/index/index 首页; /pages/my/my 我的页
/packageXXX/ 子包以 package 开头,再加特性名,比如 packageCard 里面一个文件夹代表 1 个页面(该项目未用分包)
```
- 技术规范和要求,参见如下
```bash
项目未使用云开发及云存储
未使用小程序鉴权授权及h5鉴权授权
服务器需配置ssl证书保证h5访问及接口访问地址为htts://(http://访问会导致h5或小程序不可用)
```
- 跨域问题
```bash
官方解决方案
https://ask.dcloud.net.cn/article/35267
最方便的还是后端设置允许跨域
跨域问题仅存在于h5生产/测试环境
```
- components使用
```bash
页面与组件之间通过数据属性和事件属性来通信
/companyList 任务列表组件 传入单个任务信息 项目内所有任务列表均使用该组件。
使用时需传入comment参数 开始或关闭评价列表样式
/uni-nav-bar 头部导航组件
/v-tabs tabs切换组件
/mark-slid-list 搜索组件-搜索结果高亮
```
- testdata测试数据
```bash
/common/textdata.js 测试数据存放地址
```
- 其他注意事项
```bash
当项目在华为手机上运行时 并且页面存在两个包括两个以上input时
注意两个input的type类型要一致
ep
<input type='text' />
<input type='text' />
当不一致时会出现闪屏输入框消失等bug
ep:
<input type='number' />
<input type='text' />
***
在华为手机上运行h5并且页面中存在input时 页面样式慎用 position: fixed;position: absolute;
input聚焦弹起输入框会使页面真实高度发生改变
```

118
api/auth.js Normal file
View File

@@ -0,0 +1,118 @@
import {
request
} from '@/untils/AxiosUtils.js';
import website from "@/config/website";
const authUrl = '/api/jobslink-api/user/user/auth/auth'
export const findAuth = () => request({
url: '/api/jobslink-api/user/user/find',
method: 'get'
});
export const cheakValue = () => request({
url: authUrl,
method: 'post',
data: {
cheakvalue: 1,
bakvalue: 0
}
});
export const realName = (realName, idNumber) => request({
url: authUrl,
method: 'post',
data: {
cheakvalue: 2,
realName,
idNumber
}
});
export const bank = (bankName, realName, cardNumber, def, id) => request({
url: authUrl,
method: 'post',
data: {
cheakvalue: 3,
bankName,
cardNumber,
realName,
def,
id
}
});
export const insure = (bakvalue) => request({
url: authUrl,
method: 'post',
data: {
cheakvalue: 4,
bakvalue
}
});
// 判断当前用户是否采集签名
export const isGather = () => request({
url: "/api/jobslink-api/doc/docUserSeal/isGather",
method: 'get',
});
// 个人端签名采集
export const signGather = (signSrcUrl, password, confirmPassword) => request({
url: "/api/jobslink-api/doc/docUserSeal/signGather",
method: 'post',
data: {
signSrcUrl,
password,
confirmPassword
}
});
// 获取短信接口
export const sendValidate = (mobile) => request({
url: "/api/jobslink-api/doc/docUserCert/resetPass/sendValidate",
method: 'get',
data: {
mobile
}
});
// 密码重置接口
export const resetPass = (mobile, code, password) => request({
url: "/api/jobslink-api/doc/docUserCert/resetPass",
method: 'post',
headers: {
'SCaptcha-Key': mobile,
'SCaptcha-Code': code,
'password': password
}
});
// 我的合同
export const contractList = (params) => request({
url: "/api/jobslink-api/doc/contract/personal/contractList",
method: 'get',
data: params
});
// 签名密码 /jobslink-api/doc/docUserCert/checkPass
export const checkPass = (params) => request({
url: "/api/jobslink-api/doc/docUserCert/checkPass",
method: 'get',
data: params
});
// 返回的是base64格式的pdf
export const viewContract = (params) => request({
url: "/api/jobslink-api/doc/contract/viewContract",
method: 'get',
data: params
});
//新实名认证api
export const newCertification = (bakvalue, realName, idNumber, cardNumber, bankCode,def,bankName) => request({
url: '/api/jobslink-api/user/user/auth/authNew',
method: 'post',
data: {
bakvalue,
realName,
idNumber,
cardNumber,
bankCode,
def,
bankName
}
});

22
api/bank.js Normal file
View File

@@ -0,0 +1,22 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const getList = () => request({
url: '/api/jobslink-api/system/base/bank/find',
method: 'get'
});
export const getUserCards = (id) => request({
url: '/api/jobslink-api/user/user/bank/find',
method: 'get'
});
export const remove = (id) => request({
url: '/api/jobslink-api/user/user/bank/delete',
method: 'post',
data:{
id
}
});

13
api/changePassword.js Normal file
View File

@@ -0,0 +1,13 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const changePassword = (oldPassword, newPassword, newPassword1) => request({
url: '/api/jobslink-api/user/account/update-password',
method: 'post',
params: {
oldPassword,
newPassword,
newPassword1
}
});

25
api/changePhone.js Normal file
View File

@@ -0,0 +1,25 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const changePhone = (account, password, code) => request({
url: '/api/jobslink-api/user/account/updateAccount',
method: 'post',
headers: {
'SCaptcha-Key': account,
'SCaptcha-Code': code,
},
params: {
account,
password
}
});
export const sendValidate = (account, password) => request({
url: '/api/jobslink-api/user/account/sendValidate',
method: 'get',
params: {
account,
password
}
});

47
api/federation.js Normal file
View File

@@ -0,0 +1,47 @@
import {
request
} from '@/untils/AxiosUtils.js';
import website from "../config/website.js"
import store from '@/store/';
// 设置民族政治面貌 jobslink-api/user/user/setInfo
export const setInfo = (params) => request({
url: "/api/jobslink-api/user/user/setInfo",
method: 'post',
data: params
});
// 获取用户工会状态 /jobslink-api/doc/user/labourUnion/info
export const labourUnionInfo = () => request({
url: "/api/jobslink-api/doc/user/labourUnion/info",
method: 'get'
});
// 申请入会
export const contract = (params) => request({
url: "/api/jobslink-api/doc/user/labourUnion/apply",
method: 'post',
data: params
});
//会员信息--判断用户是否加入工会
export const labourUnionDetail = (no) => request({
url: "/api/jobslink-api/doc/jkLabourUnionAppl/list",
method: 'get',
params:{no}
});
//提交会员申请
export const saveApplication = (labourunionId,applType,applComment) =>{
applComment=applComment.substring(0,200)
return request({
url: "/api/jobslink-api/doc/jkLabourUnionDetail/save",
method: 'post',
data:{labourunionId,applType,applComment}
});
}
//查询提交的申请内容
export const applicationInfo = (no) => request({
url: "/api/jobslink-api/doc/jkLabourUnionDetail/list",
method: 'get',
params:{no}
});

42
api/forgetPW.js Normal file
View File

@@ -0,0 +1,42 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const forgetPW = (mobile, password, code) => request({
url: '/api/jobslink-api/user/front/account/password',
method: 'post',
headers: {
'SCaptcha-Key': mobile,
'SCaptcha-Code': code,
},
params: {
mobile,
password,
}
});
export const accountsendValidate = (mobile, key, code) => request({
url: '/api/jobslink-api/user/front/account/password/sendValidate',
method: 'get',
headers: {
'Captcha-Key': key,
'Captcha-Code': code,
},
params: {
mobile
}
});
export const getCaptcha = () => request({
url: '/api/jobslink-api/user/front/account/oauth/captcha',
method: 'get'
});
export const validateCode = (mobile, code) => request({
url: '/api/jobslink-api/user/front/account/validate/code',
method: 'get',
headers: {
'SCaptcha-Key': mobile,
'SCaptcha-Code': code,
}
});

25
api/map.js Normal file
View File

@@ -0,0 +1,25 @@
import {request} from '@/untils/AxiosUtils.js';
/*逆地址解析*/
export const getcoder = (location, key, get_poi) => {
return request({
url: '/api/map/ws/geocoder/v1',
method: 'get',
params: {
location,
key,
get_poi
}
})
}
/*关键词输入提示*/
export const querySearch = (keyword, key) => {
return request({
url: '/api/map/ws/place/v1/suggestion',
method: 'get',
params: {
keyword,
key
}
})
}

120
api/mission.js Normal file
View File

@@ -0,0 +1,120 @@
import {
request
} from '@/untils/AxiosUtils.js';
import {
getStore
} from '@/untils/store.js'
function getHeader() {
const platformId = getStore({
name: 'platformId'
})
if (platformId) {
return {
'Platform-Id': platformId
}
} else {
return {}
}
}
/*首页 最新任务(10条)*/
export const newMission = () => {
return request({
url: '/api/jobslink-api/missions/front/mission/guestList',
method: 'get',
headers: getHeader()
})
}
/*首页 推荐任务(10条)*/
export const recMission = () => {
return request({
url: '/api/jobslink-api/missions/user/mission/interestedList',
method: 'get',
headers: getHeader()
})
}
/*抢任务-附近任务*/
export const nearMission = (current, size, lat, lon, distance) => {
return request({
url: '/api/jobslink-api/missions/user/mission/nearByList',
method: 'get',
params: {
current,
size,
lat,
lon,
distance
},
headers: getHeader()
})
}
/*抢任务-推荐任务*/
export const recommendMission = (current, size, seaStr) => {
return request({
url: '/api/jobslink-api/missions/user/mission/recommendList',
method: 'get',
params: {
current,
size,
seaStr
},
headers: getHeader()
})
}
/*抢任务-最新任务*/
export const newMissionAll = (current, size, seaStr) => {
return request({
url: '/api/jobslink-api/missions/user/mission/lastList',
method: 'get',
params: {
current,
size,
seaStr
},
headers: getHeader()
})
}
/*提交抢任务*/
export const submit = (missionNo) => {
return request({
url: '/api/jobslink-api/missions/user/mission/missionApply',
method: 'post',
params: {
missionNo
}
})
}
/*我的任务*/
export const myMission = (current, size, status) => {
return request({
url: '/api/jobslink-api/missions/user/mission/getUserMissionList',
method: 'get',
params: {
current,
size,
status
}
})
}
/*任务详情*/
export const missionDetail = (missionNo) => {
return request({
url: '/api/jobslink-api/missions/front/mission/detail',
method: 'get',
params: {
missionNo
}
})
}

56
api/newIndex.js Normal file
View File

@@ -0,0 +1,56 @@
import {
request
} from '@/untils/AxiosUtils.js';
//轮播图
export const getSwiperList = (type) => request({
url: '/api/jobslink-api/desk/carousel/getCarouselList',
method: 'get'
});
//国家新政
export const getPolicyContent=(type, id)=>request({
url:'/api/jobslink-api/desk/article/getAllArticle',
method:'get',
params: {
type,
id
}
})
//常见问题
export const getQuestionList=(sidebarId, type, source, current, size)=>request({
url:'/api/jobslink-api/desk/sidebarContent/getSidebarContentList',
method:'get',
params: {
sidebarId,
type,
source,
current,
size,
}
})
export const questionDetail=(id)=>request({
url:'/api/jobslink-api/desk/content/getContentList',
method:'get',
params: {
id
}
})
//法律咨询 userId name 用户姓名telephone 手机号, type (1 法律咨询 2技能提升content 申请内容
export const submitApplication=(userId,name,telephone,type,content)=>request({
url:'/api/jobslink-api/desk/applContent/save',
method:'post',
data:{
userId,name,telephone,type,content
}
})
//我的申请
export const getApplContentList=()=>request({
url:'/api/jobslink-api/desk/applContent/getApplContentList',
method:'get',
})

114
api/news.js Normal file
View File

@@ -0,0 +1,114 @@
import {
request
} from '@/untils/AxiosUtils.js';
/* 任务邀请列表 */
export const inviteList = (current, size) => {
return request({
url: '/api/jobslink-api/desk/user/notice/list',
method: 'get',
params: {
current,
size
}
})
}
/* 获取任务邀请未读数量 */
export const inviteCount = () => {
return new Promise(function(resolve, reject) {
request({
url: '/api/jobslink-api/desk/user/notice/count',
method: 'get'
})
.then((resp) => {
const result = resp.data.data;
resolve(result);
})
.catch(reject)
})
}
/* 任务邀请设置已读 */
export const inviteRead = (id) => {
return request({
url: '/api/jobslink-api/desk/user/notice/update',
method: 'post',
data: {
id
}
})
}
/* 任务邀请删除 */
export const inviteRemove = (ids) => {
return request({
url: '/api/jobslink-api/desk/notice/missions/remove',
method: 'post',
params: {
ids
}
})
}
function getDesc(desc){
let re = desc.replace(/<\/?.+?\/?>/g,'')
return re.substring(0,50)
}
/* 通知列表 */
export const noticeList = (current, size) => {
return new Promise(function(resolve, reject) {
request({
url: '/api/jobslink-api/desk/notice/user/list',
method: 'get',
params: {
current,
size
}
}).then(resp => {
resp.data.data.records.forEach(item=>{
item.desc = getDesc(item.content)
})
resolve(resp)
}).catch(reject)
})
}
/* 获取通知未读数量 */
export const noticeCount = () => {
return new Promise(function(resolve, reject) {
request({
url: '/api/jobslink-api/desk/notice/user/read',
method: 'get'
})
.then((resp) => {
const result = resp.data.data;
resolve(result);
})
.catch(reject)
})
}
/* 通知列表设置已读 */
export const noticeRead =
(ids) => {
return request({
url: '/api/jobslink-api/desk/notice/status/read',
method: 'post',
params: {
ids
}
})
}
/* 通知列表删除 */
export const noticeRemove = (ids) => {
return request({
url: '/api/jobslink-api/desk/notice/status/remove',
method: 'post',
params: {
ids
}
})
}

33
api/rate.js Normal file
View File

@@ -0,0 +1,33 @@
import {request} from '@/untils/AxiosUtils.js';
/*我的评价*/
export const myRate = () => {
return request({
url: '/api/jobslink-api/missions/user/mission/missionUserScore/list',
method: 'get'
})
}
/*提交评价*/
export const rate = (missionNo,scoreAll,remarks) => {
return request({
url: '/api/jobslink-api/missions/user/mission/missionUserScore/save',
method: 'post',
data: {
missionNo,
scoreAll,
remarks
}
})
}
/*评价详情*/
export const rateDetail = (missionNo) => {
return request({
url: '/api/jobslink-api/missions/user/mission/missionUserScore/detail',
method: 'get',
params: {
missionNo
}
})
}

42
api/reg.js Normal file
View File

@@ -0,0 +1,42 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const accountsendValidate = (mobile, key, code) => request({
url: '/api/jobslink-api/user/front/account/reg/sendValidate',
method: 'get',
headers: {
'Captcha-Key': key,
'Captcha-Code': code,
},
params: {
mobile
}
});
export const validateCode = (mobile, code) => request({
url: '/api/jobslink-api/user/front/account/validate/code',
method: 'get',
headers: {
'SCaptcha-Key': mobile,
'SCaptcha-Code': code,
}
});
export const reg = (mobile, password, code) => request({
url: '/api/jobslink-api/user/front/account/reg',
method: 'post',
headers: {
'SCaptcha-Key': mobile,
'SCaptcha-Code': code,
},
params: {
mobile,
password,
}
});
export const getCaptcha = () => request({
url: '/api/jobslink-api/user/front/account/oauth/captcha',
method: 'get'
});

98
api/resume.js Normal file
View File

@@ -0,0 +1,98 @@
import {request} from '@/untils/AxiosUtils.js';
/*我的简历-查看*/
export const myResume = () => {
return request({
url: '/api/jobslink-api/user/user/resume/find',
method: 'get'
})
}
/*我的简历-查看-我的职业技能*/
export const mySkills = () => {
return request({
url: '/api/jobslink-api/user/user/skills/find',
method: 'get'
})
}
/*我的简历-删除-我的职业技能*/
export const removeSkills = (id) => {
return request({
url: '/api/jobslink-api/user/user/skills/remove',
method: 'post',
params:{
id
}
})
}
/*我的简历-设置我想工作的地点*/
export const setCity = (id,cityId) => {
return request({
url: '/api/jobslink-api/user/user/resume/update',
method: 'post',
data:{
id,
cityId
}
})
}
/*我的简历-设置我想学习的技能*/
export const setLearn = (id,learnSkill) => {
return request({
url: '/api/jobslink-api/user/user/resume/update',
method: 'post',
data:{
id,
learnSkill
}
})
}
/*行业库*/
export const getTrade = () => {
return request({
url: '/api/jobslink-api/tenant/base/config/trade',
method: 'get'
})
}
/*工种库*/
export const getWorktypes = (id) => {
return request({
url: '/api/jobslink-api/tenant/base/config/worktypes',
method: 'get',
params:{
id
}
})
}
/*技能库*/
export const getSkills = (id) => {
return request({
url: '/api/jobslink-api/tenant/base/config/skills',
method: 'get',
params:{
id
}
})
}
/*新增职业技能*****/
export const addSkills = (trade,worktypes,skills) => {
return request({
url: '/api/jobslink-api/user/user/skills/save',
method: 'post',
params:{
trade,
worktypes,
skills
}
})
}

14
api/test.js Normal file
View File

@@ -0,0 +1,14 @@
import * as AxiosUtils from '../untils/AxiosUtils.js';
export async function test(req) {
const url = '/checkIn/checkInCancel';
const rsp = await DoPost(url, req);
if (rsp.code !== 0) {
throw new Error(rsp.msg);
}
const result = rsp.data;
return result;
}

69
api/user.js Normal file
View File

@@ -0,0 +1,69 @@
import {
request
} from '@/untils/AxiosUtils.js';
import {
getStore
} from '@/untils/store.js'
import website from "@/config/website";
export const loginByUsername = (tenantId, username, password, type, key, code) => request({
url: '/api/jobslink-auth/oauth/token',
method: 'post',
headers: {
'Login-Type': 'Type-U',
'Captcha-Key': key,
'Captcha-Code': code,
'Platform-Id': getStore({
name: 'platformId'
}) || ''
},
params: {
tenantId,
username,
password,
grant_type: (website.captchaMode ? "captcha" : "password"),
scope: "all",
type
}
});
export const refreshToken = (refresh_token, tenantId) => request({
url: '/api/jobslink-auth/oauth/token',
method: 'post',
headers: {
'Tenant-Id': tenantId,
'Login-Type': 'Type-U',
},
params: {
tenantId,
refresh_token,
grant_type: "refresh_token",
scope: "all",
}
});
export const getCaptcha = () => request({
url: '/api/jobslink-auth/oauth/captcha',
method: 'get'
});
export const logout = () => request({
url: '/api/jobslink-auth/oauth/logout',
method: 'get'
});
export const getUserInfo = () => request({
url: '/api/jobslink-auth/oauth/user-info',
method: 'get'
});
export const sendLogs = (list) => request({
url: '/api/jobslink-auth/oauth/logout',
method: 'post',
data: list
});
export const clearCache = () => request({
url: '/api/jobslink-auth/oauth/clear-cache',
method: 'get'
});

24
api/vip.js Normal file
View File

@@ -0,0 +1,24 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const getVipCode = (idNumber) => {
return request({
url: '/api/jobslink-api/tenant/invite/user/inviteCode',
method: 'get',
params: {
idNumber
}
})
}
export const bindVip = (idNumber, inviteCode) => {
return request({
url: '/api/jobslink-api/tenant/invite/user/bind/inviteCode',
method: 'post',
params: {
idNumber,
inviteCode
}
})
}

24
api/wage.js Normal file
View File

@@ -0,0 +1,24 @@
import {
request
} from '@/untils/AxiosUtils.js';
export const getList = (userId, current, size, status) => {
return request({
url: '/api/jobslink-api/payment/userOrder/user/list',
method: 'get',
params: {
userId,
current,
size,
status
}
})
}
export const userOrderList = (params) => {
return request({
url: '/api/jobslink-api/payment/userOrder/userOrderList',
method: 'get',
params
})
}

75
common/nationPolitics.js Normal file
View File

@@ -0,0 +1,75 @@
export default{
nation: [
{id:1 ,name:'汉族'},
{id:2 ,name:'蒙古族'},
{id:3 ,name:'回族'},
{id:4 ,name:'藏族'},
{id:5 ,name:'维吾尔族'},
{id:6 ,name:'苗族'},
{id:7 ,name:'彝族'},
{id:8 ,name:'壮族'},
{id:9 ,name:'布依族'},
{id:10,name:'朝鲜族'},
{id:11,name:'满族'},
{id:12,name:'侗族'},
{id:13,name:'瑶族'},
{id:14,name:'白族'},
{id:15,name:'土家族'},
{id:16,name:'哈尼族'},
{id:17,name:'哈萨克族'},
{id:18,name:'傣族'},
{id:19,name:'黎族'},
{id:20,name:'傈僳族'},
{id:21,name:'佤族'},
{id:22,name:'畲族'},
{id:23,name:'高山族'},
{id:24,name:'拉祜族'},
{id:25,name:'水族'},
{id:26,name:'东乡族'},
{id:27,name:'纳西族'},
{id:28,name:'景颇族'},
{id:29,name:'柯尔克孜族'},
{id:30,name:'土族'},
{id:31,name:'达翰尔族'},
{id:32,name:'么佬族'},
{id:33,name:'羌族'},
{id:34,name:'布朗族'},
{id:35,name:'撒拉族'},
{id:36,name:'毛南族'},
{id:37,name:'仡佬族'},
{id:38,name:'锡伯族'},
{id:39,name:'阿昌族'},
{id:40,name:'普米族'},
{id:41,name:'塔吉克族'},
{id:42,name:'怒族'},
{id:43,name:'乌孜别克族'},
{id:44,name:'俄罗斯族'},
{id:45,name:'鄂温克族'},
{id:46,name:'德昂族'},
{id:47,name:'保安族'},
{id:48,name:'裕固族'},
{id:49,name:'京族'},
{id:50,name:'塔塔尔族'},
{id:51,name:'独龙族'},
{id:52,name:'鄂伦春族'},
{id:53,name:'赫哲族'},
{id:54,name:'门巴族'},
{id:55,name:'珞巴族'},
{id:56,name:'基诺族'},
],
politics: [
{id:1,name:'群众'},
{id:2,name:'中共正式党员'},
{id:3,name:'中共预备党员'},
{id:4,name:'中国国民党革命委员会'},
{id:5,name:'中国民主同盟'},
{id:6,name:'中国民主建国会'},
{id:7,name:'中国民主促进会'},
{id:8,name:'中国农工民主党'},
{id:9,name:'中国致公党'},
{id:10,name:'九三学社'},
{id:11,name:'台湾民主自治同盟'},
{id:12,name:'共青团员'},
{id:13,name:'青年'}
]
}

4737
common/textdata.js Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,154 @@
//搜索
<template lang='pug'>
view.item-out-view
view.search-view
view.search-item
image(src='../../static/img/search.svg')
input(
v-model="inputValue"
@input='onInputListen'
:placeholder='placeholder'
:placeholder-class='placeholderClass')
view.search-content(
v-if="historyDatas&&historyDatas.length>0&&inputValue.length<=0")
view.title-view
text 搜索历史
image(src='./icon_delete.png' @tap.stop='onDelete(ALL)')
view.item-view(v-for="(item,index) in historyDatas" :key="index" @tap.stop='onItemClick(item,index)')
text {{item.key}}
image(src='./icon_close.png' @tap.stop='onDelete(index)')
view.search-content(v-if="keyworkDatas&&keyworkDatas.length>0")
view.item-view(v-for="(item,index) in keyworkDatas" :key="index" @tap.stop='onItemClick(item,index)')
text(v-for="textContent in item.keyword"
:key="item.id"
:class="textContent===inputValue?'__vital':''") {{textContent}}
</template>
<script>
export default {
data() {
return {
inputValue: '',
ALL: 'ALL',
SEARCH_DATA: 'SEARCH_DATA'
}
},
props: {
//搜索历史内容
historyDatas: {
type: Array,
default: () => {
return [];
}
},
//搜索关键内容
keyworkDatas: {
type: Array,
default: () => {
return [];
}
},
placeholder: {
type: String,
default: '请输入搜索内容'
},
},
methods: {
//监听输入框内容变化
onInputListen(event) {
let detail = event.detail;
let value = detail.value;
this.inputValue = value;
this.$emit('onInputListen', value);
},
//清除搜索历史
onDelete(event) {
this.$emit('onDelete', event);
},
//列表点击事件
onItemClick(item, index) {
this.$emit('onItemClick', {
item,
index
});
}
},
}
</script>
<style scoped lang='scss'>
.item-out-view {
flex-direction: column;
.search-view {
border-bottom: 1rpx solid #dddddd;
flex-direction: column;
padding: 10rpx 32rpx;
background: rgba(255, 255, 255, 1);
.search-item {
width: 80%;
padding: 0 24rpx;
height: 60rpx;
line-height: 60rpx;
background: rgba(249, 249, 249, 1);
border-radius: 200px;
align-items: center;
input {
padding: 0 24rpx;
height: 80rpx;
font-weight: 400;
flex: 1;
text-align: start;
font-size: 28rpx;
font-family: PingFang-SC-Bold, PingFang-SC;
color: rgba(51, 51, 51, 1);
}
.placeholderClass {
color: #CCCCCC;
}
image {
height: 32rpx;
width: 32rpx;
}
}
.search-content {
padding: 40rpx 0;
flex-direction: column;
.title-view {
text {
color: rgba(51, 51, 51, 1);
}
}
.item-view {
align-items: center;
width: 100%;
padding: 32rpx 0;
border-bottom: 1px solid rgba(245, 245, 245, 1);
text {
color: rgba(102, 102, 102, 1);
}
.next-ico {
width: 24rpx;
height: 24rpx;
}
.__vital {
color: rgba(51, 130, 255, 1);
}
}
image {
margin-left: auto;
width: 44rpx;
height: 44rpx;
}
}
text {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
}
view {
flex-direction: row;
display: flex;
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

View File

@@ -0,0 +1,208 @@
<template>
<view class="body" @click="goInfo(companyitem.missionNo)">
<view class="heads">
<view class="head_left">
<rich-text :nodes="string">
</rich-text>
</view>
<view class="head_right">
{{companyitem.wage}}{{wageUnit[companyitem.wageUnitCategory]}}
</view>
</view>
<view class="ask">
<view class="askList" v-for="(item,index) in skillNames" :key="index">
{{item}}
</view>
</view>
<view class="allName">
{{companyitem.companyName}}
</view>
<view class="timeAddress">
<view>
报名截止日期{{dateFormat(companyitem.etimePub)}}
</view>
<view v-if="near">
{{companyitem.distanceStr}}km
</view>
<view v-else>
{{getCity(companyitem.cityId)}}
</view>
</view>
<view class="comment" v-if='comment' @tap.stop="goComment(companyitem.missionNo)">
<view class="comment_content commentimg" v-if='companyitem.scoreAll>0'>
<image class="commentimg_image" src="../../static/img/star.full.svg" v-for="index1 in companyitem.scoreAll" mode=""
:key="index1"></image>
<image class="commentimg_image" src="../../static/img/star.empty.svg" v-for="index2 in (5-companyitem.scoreAll)"
mode="" :key="index2"></image>
</view>
<view class="comment_content allName gocomment" v-else>
评价
</view>
</view>
</view>
</template>
<script>
import {
toDoller,
dateFormat
} from "../../untils/format.js";
import dictionary from '@/common/textdata.js';
export default {
beforeCreate: function() {},
props: {
companyitem: {
type: Object,
default(){ return [] }
},
comment: {
type: Boolean,
default: false
},
noApply: {
type: Boolean,
default: true
},
near: {
type: Boolean,
default: false
}
},
data() {
return {
...dictionary,
string: "<div style='overflow: hidden;white-space: nowrap;text-overflow: ellipsis;'>" + this.companyitem.missionTitle +
"</div>"
};
},
computed: {
skillNames() {
return this.companyitem.skillNames.split(',')
}
},
methods: {
goComment: function(no) {
uni.navigateTo({
url: `../../pageMy/mycomment/mycomment?missionNo=${encodeURIComponent(no)}`
})
},
goInfo: function(no) {
const isCan = this.noApply === false ? '0' : '1'
uni.navigateTo({
url: `/pages/projectInfo/projectInfo?missionNo=${encodeURIComponent(no)}&isCan=${isCan}`
})
},
getCity: function(val) {
if (val) {
let areas = this.$store.getters.getAreaParents(val)
if (areas.length === 3) {
return areas[0].label + '-' + areas[1].label + '-' + areas[2].label
}
}
},
toDoller,
dateFormat
}
}
</script>
<style>
.commentimg_image {
width: 40rpx;
height: 40rpx;
}
.commentimg {
display: flex;
align-items: center;
justify-content: flex-end;
}
.gocomment {
font-size: 26rpx !important;
border-radius: 5rpx;
border: 1rpx solid #c3c3c3;
width: 160rpx;
text-align: center;
float: right;
height: 50rpx;
line-height: 50rpx;
}
.timeAddress {
display: flex;
align-items: center;
justify-content: space-between;
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #999999;
margin: 10rpx 0;
}
.allName {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
}
.askList {
width: 14%;
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #666666;
background-color: #f6f6f6;
padding: 5rpx 15rpx;
margin-right: 10rpx;
margin-bottom: 10rpx;
}
.ask {
overflow: hidden;
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: flex-start;
margin: 20rpx 0;
}
.head_right {
ont-family: PingFangSC-Medium;
font-size: 28rpx;
color: #F46161;
font-weight: bold;
}
.head_left {
font-family: PingFangSC-Medium;
font-size: 32rpx;
font-weight: bold;
color: #333333;
width: 400rpx;
overflow: hidden;
white-space: nowrap;
/*不换行*/
text-overflow: ellipsis;
/*超出部分文字以...显示*/
}
.highlight {
color: #F46161;
}
.body {
width: 690rpx;
margin: 0rpx auto;
padding: 20rpx 0;
background-color: #fefefe;
overflow: hidden;
}
.heads {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>

View File

@@ -0,0 +1,30 @@
<template>
<!-- #ifdef MP-WEIXIN -->
<button type="default" open-type="contact">
<image src="../../static/img/cs.svg" class="cs" mode=""></image>
</button>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<!-- #endif -->
</template>
<script>
</script>
<style>
.csimage {
width: 88rpx;
height: 88rpx;
position: fixed;
right: 22rpx;
bottom: 112rpx;
}
.cs {
width: 88rpx;
height: 88rpx;
position: fixed;
right: 22rpx;
bottom: 22rpx;
}
</style>

View File

@@ -0,0 +1,83 @@
<template>
<view :class="className" @click="click">
<slot></slot>
</view>
</template>
<script>
export default {
props: {
loading: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
type: {
type: String
},
inline: {
Boolean,
default: false,
}
},
methods: {
click(e) {
if (this.loading || this.disabled) {
return;
}
this.$emit('click', e)
}
},
computed: {
className() {
let name = "jl-button"
if (this.inline) {
name += ' inline'
}
if (this.disabled) {
name += ' disabled'
}
if (this.loading) {
name += " loading"
}
if (this.type) {
name += " " + this.type
}
return name
}
},
};
</script>
<style>
.jl-button {
display: inline-block;
padding: 15rpx 47rpx;
border-radius: 10rpx;
text-align: center;
font-size: 32rpx;
color: #666666;
border: 1rpx solid #c8c7cc;
}
.jl-button.inline {
display: block;
height: 80rpx;
line-height: 80rpx;
padding:0;
}
.jl-button.primary {
color: #fefefe;
background-color: #1b66ff;
border-color: #1b66ff;
}
.jl-button.loading,
.jl-button.disabled {
opacity: 0.3;
}
</style>

View File

@@ -0,0 +1,39 @@
<template>
<view class="jl-form-item">
<view class="jl-form-item__label">{{prop}}</view>
<view class="jl-form-item__content">
<slot></slot>
</view>
</view>
</template>
<script>
export default {
props: {
prop: String,
},
};
</script>
<style>
.jl-form-item {
margin-bottom: 30rpx;
}
.jl-form-item__label {
float: left;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
letter-spacing: 0;
line-height: 88rpx;
}
.jl-form-item__content {
position: relative;
}
.jl-form-item__content .jl-input-intext {
padding: 0;
}
</style>

View File

@@ -0,0 +1,15 @@
<template>
<view class="jl-form">
<slot></slot>
</view>
</template>
<script>
export default {};
</script>
<style>
.jl-form {
display: block;
}
</style>

View File

@@ -0,0 +1,92 @@
<template>
<view class="jl-input">
<input class="jl-input-intext" :type="type" :password="pwShow" :value="value" :placeholder="placeholder"
:placeholder-class="placeholderClass" @input="setValue" @blur="setValue" @confirm="$emit('confirm')" :maxlength="maxlength" />
<slot></slot>
<slot name="icon"></slot>
<image v-if="showPassword && pwShow" class="jl-input_image_eye" src="/static/img/eyeopen.svg" mode="" @click="changePasType"></image>
<image v-else-if="showPassword" class="jl-input_image_eye" src="/static/img/eyeclosed.svg" mode="" @click="changePasType"></image>
<image v-if="clearable" class="jl-input_image_delete" src="/static/img/delate.svg" mode="" @click="delpas"></image>
</view>
</template>
<script>
export default {
props: {
maxlength: {
type: Number,
default: -1
},
type: {
type: String,
default: "text",
},
placeholderClass: {
type: String,
default: "jl-input-inPla",
},
placeholder: String,
value: {
type: String,
default: "",
},
clearable: Boolean,
showPassword: Boolean,
},
computed: {},
data() {
return {
pwShow: this.showPassword
}
},
methods: {
setValue(e) {
this.$emit("input", e.detail.value);
},
delpas() {
this.$emit("input", '');
},
changePasType() {
this.pwShow = !this.pwShow
}
},
};
</script>
<style>
.jl-input {
margin: 0 auto;
/* margin-top: 30rpx; */
border-bottom: 1rpx solid #dddddd;
display: flex;
align-items: center;
justify-content: flex-start;
opacity: hidden;
}
.jl-input-intext {
font-family: PingFangSC-Regular;
font-size: 1rem;
padding: 30rpx 0;
color: #333333;
flex-grow: 1;
}
.jl-input-inPla {
font-family: PingFangSC-Regular;
font-size: 1rem;
color: #d8d8d8;
}
.jl-input_image_delete {
width: 32rpx;
height: 32rpx;
margin-left: 20rpx;
}
.jl-input_image_eye {
width: 40rpx;
height: 40rpx;
margin-left: 20rpx;
}
</style>

View File

@@ -0,0 +1,296 @@
<template>
<uni-popup :custom="true" type="bottom" ref="keyboardPackage">
<view class="keyboardbox">
<view class="numkeyboard" v-if="type==='number'">
<view class="num-area">
<view class="row" v-for="(item,index) in numKeybordList" :key="index">
<view :class="['item',ite===0?'z':'',(disableDot && ite==='.')?'disabled':'']" v-for="(ite,idx) in item"
hover-class="active" :hover-start-time="0" :hover-stay-time="5" :key="idx" @tap="input(ite)">{{ite}}</view>
</view>
</view>
<view class="btn-area">
<view :class="['item','del']" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
删除
</view>
<view class="confirem item" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="confirm">
完成
</view>
</view>
</view>
<view class="numkeyboard" v-if="type==='idCard'">
<view class="num-area">
<view class="row" v-for="(item,index) in idCardList" :key="index">
<view :class="['item',ite===0?'z':'',(disableDot && ite==='.')?'disabled':'']" v-for="(ite,idx) in item"
hover-class="active" :hover-start-time="0" :hover-stay-time="5" :key="idx" @tap="input(ite)">{{ite}}</view>
</view>
</view>
<view class="btn-area">
<view :class="['item','del']" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
删除
</view>
<view class="confirem item" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="confirm">
完成
</view>
</view>
</view>
<view class="platenumber" v-if="type==='plateNumber'">
<view class="header">
<view @tap="active=active===1?2:1" hover-class="active" :hover-start-time="0" :hover-stay-time="5">{{active===1?'地区':'车牌号'}}</view>
<view hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="confirm">完成</view>
</view>
<view class="main">
<view class="normal" v-if="active===1">
<view class="row" v-for="(item,index) in EngKeyBoardList" :key="index">
<view class="item" v-for="(ite,idx) in item" :key="idx" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="input(ite)">
{{ite}}
</view>
<view class="item img" v-if="index===EngKeyBoardList.length-1" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
<image src="/static/delete.png" mode=""></image>
</view>
</view>
</view>
<view class="area" v-if="active===2">
<view class="row" v-for="(item,index) in areaList" :key="index">
<view class="item" v-for="(ite,idx) in item" :key="idx" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="input(ite)">
{{ite}}
</view>
<view class="item img" v-if="index===EngKeyBoardList.length-1" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
<image src="/static/delete.png" mode=""></image>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="safe-area" v-if="safeAreaInsetBottom"></view>
</uni-popup>
</template>
<script>
import uniPopup from "@/components/uni-popup/uni-popup.vue"
export default {
components: {
uniPopup
},
props: {
type: {
type: String,
default: 'number'
},
safeAreaInsetBottom: { //是否设置安全区
type: Boolean,
default: false
},
disableDot: { //数字键盘是否禁止点击.仅type为number生效
type: Boolean,
default: false
}
},
data() {
return {
numKeybordList: [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, '.']
],
idCardList: [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, 'X']
],
areaList: [
['京', '沪', '粤', '津', '冀', '豫', '云', '辽', '黑', '湘'],
['皖', '鲁', '苏', '浙', '赣', '鄂', '桂', '甘', '晋', '陕'],
['蒙', '吉', '闽', '贵', '渝', '川', '青', '琼', '宁'],
['藏', '新', '使', '港', '澳', '学']
],
EngKeyBoardList: [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
['Z', 'X', 'C', 'V', 'B', 'N', 'M']
],
active: 1
};
},
methods: {
open() {
this.$refs.keyboardPackage.open();
},
confirm() {
this.close();
this.$emit('onConfirm');
},
deleteVal() {
this.$emit('onDelete');
},
input(val) {
if (val === '.' && this.disableDot) return;
this.$emit('onInput', val);
},
close() {
this.$refs.keyboardPackage.close();
}
}
}
</script>
<style lang="scss" scoped>
.keyboardbox {
background-color: #FFFFFF;
.numkeyboard {
height: 432rpx;
display: flex;
background-color: #ebedf0;
.btn-area {
width: 180rpx;
height: 100%;
display: flex;
flex-direction: column;
.item {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
.del {
background-color: #ebedf0;
color: #333;
&.active {
background-color: #f1f3f5;
}
}
.confirem {
background-color: #1989fa;
color: #FFFFFF;
&.active {
background-color: #0570db;
}
}
}
.num-area {
flex-grow: 1;
display: flex;
flex-wrap: wrap;
.row {
width: 100%;
height: 25%;
display: flex;
margin-top: 1px;
.item {
flex-grow: 1;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #FFFFFF;
border-right: 1px solid #ebedf0;
width: 33.33%;
&.active {
background-color: #ebedf0;
}
&.z {
flex-grow: 2;
width: 66.66%;
}
&.disabled {
background: #FFFFFF;
color: #B9B9B9;
}
}
}
}
}
}
.safe-area {
padding-bottom: 0rpx;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.platenumber {
background-color: #f5f5f5;
.header {
height: 76rpx;
background-color: #FFFFFF;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
border-top: 1px solid #f5f5f5;
&>view {
padding: 0 45rpx;
color: #00a7ea;
height: 100%;
display: flex;
align-items: center;
&.active {
background-color: #ebedf0;
}
}
}
.main {
height: 435rpx;
.row {
margin: 13rpx 0;
display: flex;
justify-content: center;
align-items: center;
.item {
width: 56rpx;
height: 94rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #FFFFFF;
border-radius: 6rpx;
margin: 0 7rpx;
font-size: 24rpx;
&.active {
background-color: #ebedf0;
}
&.img {
background-color: #c2cacc;
width: 94rpx;
&.active {
background-color: #ddd;
}
&>image {
width: 49rpx;
height: 48rpx;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,59 @@
const defaultOptions = {
only: true
}
export default function markSlideListController(options = defaultOptions) {
const instances = {};
const opened = {};
const moving = {};
let index = 0;
const pipelines = {
moving: [],
opened: [],
closed: [],
};
init()
function init() {
if (options.only) {
pipelines.moving.push(only)
}
}
function pipelinesHandler(type, key) {
pipelines[type].forEach(item => {
item.call(this, key)
})
}
function only() {
for (let key in opened) {
const item = opened[key]
item.hide()
}
}
this.reg = ({
instance,
cb
}) => {
instances[index] = instance
cb(index++)
}
this.moving = (key) => {
moving[key] = instances[key]
delete opened[key]
pipelinesHandler('moving', key)
}
this.opened = (key) => {
opened[key] = instances[key]
delete moving[key]
pipelinesHandler('opened', key)
}
this.closed = (key) => {
delete opened[key]
delete moving[key]
pipelinesHandler('closed', key)
}
}

View File

@@ -0,0 +1,186 @@
<template>
<view class="slide-list">
<view class="slide-list-item" @touchstart="touchStart" @touchend="touchEnd" @touchmove="touchMove" :style="{transform}">
<slot></slot>
</view>
<view class="group-btn">
<view class="btn-div" v-for="(btn, key) in button" :key="key" @click.stop="btnClick(btn,key)" :style="{background: btn.background}">
<text class="btn-title">{{btn.title}}</text>
</view>
</view>
</view>
</template>
<script>
import handler from './slideHandler.js'
/**
* m-slide-list 滑动操作列表
* @description 滑动操作列表组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=209
* @property {Array} list 数据源,格式为:[{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0},{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0}]
* @property {Array} button 按钮数据源,格式为:[{title: 'xxx', background:'xxx'},{title: 'xxx', background:'xxx'}]
* @property {Boolean} border 边框
*/
export default {
name: 'mark-slide-list',
props: {
button: { //按钮数据list
type: Array,
default () {
return [];
}
}
},
computed: {
windowWidth() {
return uni.getSystemInfoSync().windowWidth;
},
transform() {
return `translate3d(${ this.slide_x }px, 0, 0)`
}
},
data() {
return {
key: null,
moving: false,
btnState: 'hide',
hideLimit: 0,
showLimit: 0,
btnWidth: 0,
slide_x: 0,
handler: null
};
},
mounted() {
this.$emit('controller-reg', {
instance:{
show: this.show,
hide: this.hide
},
cb: (key) => {
this.key = key
}
})
const cb = res => {
this.btnWidth = res[0].width * -1;
this.showLimit = res[0].width / 3;
this.hideLimit = res[0].width / 3;
}
// 按钮宽度
uni.createSelectorQuery().in(this).select('.group-btn').boundingClientRect().exec(cb);
},
methods: {
btnClick(btn, key) {
this.$emit(btn.clickName, {
btn,
key
})
},
setSlideX(offset) {
const val = offset + this.slide_x
if (val < 0 && val >= this.btnWidth) {
this.slide_x = val
} else if (val > 0) {
this.slide_x = 0
}
},
// 滑动开始
touchStart(e) {
this.$emit('controller-moving', this.key)
this.moving = true
this.handler = new handler(e.timeStamp, e.touches[0].pageX, e.touches[0].pageY)
},
// 滑动中
touchMove(e) {
const slide_x = this.handler.move(e.touches[0])
this.setSlideX(slide_x)
},
// 滑动结束
touchEnd(e) {
this.moving = false
const endTime = e.timeStamp,
endY = e.changedTouches[0].pageY,
endX = e.changedTouches[0].pageX;
const x_end_distance = this.startX - this.lastX;
const end = this.handler.endMove(endTime, endX, endY)
if (end.invalid) {} else if ((end.quick && end.dir === 'l') || (end.dir === 'l' && end.move > this.showLimit)) {
this.show()
} else if ((end.quick && end.dir === 'r') || (end.dir === 'r' && end.move > this.hideLimit)) {
this.hide()
} else {
this.recover()
}
this.handler = null
},
// 点击回复原状
recover() {
if (this.btnState === 'show') {
this.show()
} else if (this.btnState === 'hide') {
this.hide()
}
},
show() {
this.btnState = 'show'
this.slide_x = this.btnWidth;
this.$emit('controller-opened', this.key)
},
hide() {
this.btnState = 'hide'
this.slide_x = 0;
this.$emit('controller-closed', this.key)
},
}
};
</script>
<style lang="scss" scoped>
.slide-list {
position: relative;
width: 100%;
.slide-list-item {
width: 100%;
overflow: hidden;
position: relative;
z-index: 2;
transition: all 100ms;
transition-timing-function: ease-out;
}
.group-btn {
position: absolute;
top: 0;
right: 0;
height: 100%;
min-width: 100rpx;
align-items: center;
z-index: 1;
display: flex;
flex-direction: row;
.btn-div {
height: 100%;
color: #fff;
text-align: center;
padding: 0 50rpx;
font-size: 34rpx;
display: table;
.btn-title {
display: table-cell;
vertical-align: middle;
}
}
.top {
background-color: #c4c7cd;
}
.removeM {
background-color: #ff3b32;
}
}
}
</style>

View File

@@ -0,0 +1,54 @@
class handler {
constructor(startTime, startX, startY) {
this.startTime = startTime
this.lastX = this.startX = startX
this.startY = startY
this._moveFunc = this.firstMove
}
move({
timeStamp,
pageX,
pageY
}) {
return this._moveFunc(timeStamp, pageX, pageY)
}
firstMove(timeStamp, pageX, pageY) {
if (Math.abs(pageX - this.startX) > Math.abs(pageY - this.startY)) {
this._moveFunc = this.nextMove
} else {
this._moveFunc = () => {
return 0
}
this.endMove = () => {
return {
invalid: true
}
}
}
return 0
}
nextMove(timeStamp, pageX, pageY) {
const r = pageX - this.lastX
this.lastX = pageX
return r
}
isQuick(endTime, endX) {
return endTime - this.startTime < 200 && Math.abs(endX - this.startX) > 50
}
endMove(endTime, pageX, pageY) {
return {
invalid: false,
quick: this.isQuick(endTime, pageX),
dir: pageX > this.startX ? 'r' : 'l',
move: Math.abs(pageX - this.startX)
}
}
}
export default handler

View File

@@ -0,0 +1,120 @@
<template>
<!-- 首字母检索 -->
<view>
<view class="letter touch" @touchstart.stop="searchStart" @touchmove.stop="searchMove" @touchend.stop="searchEnd">
<!-- 右边字母数据数据 触摸事件-->
<view class="letter-item" v-for="item in options" :key="item.key">{{item.key}}</view>
<!-- 左边字母跟右边字母true时 屏幕中心显示选中的首字母-->
</view>
<!-- 居中首字母样式 -->
<view class="cont-letter" v-if="isShowLetter">
{{showLetter}}
</view>
</view>
</template>
<script>
export default {
props: {
options: {
type: Array
},
length: {
type: Number
}
},
data() {
let windowHeight = uni.getSystemInfoSync().windowHeight
let startHeight = windowHeight * 0.1
return {
startHeight,
letterHeight: windowHeight - startHeight,
isShowLetter: false,
showLetter: ''
}
},
computed: {
letters() {
const arr = []
for (let key in this.options) {
arr.push(this.options[key])
}
return arr.key
}
},
methods: {
getLetter(pageY) {
let index = ((pageY - this.startHeight) / this.letterHeight) * this.options.length
return this.options[parseInt(index)].key
},
/* 检索字母拖动开始 */
searchStart(e) {
let pageY = e.touches[0].clientY;
this.showLetter = this.getLetter(pageY);
this.$emit("touchmove", this.showLetter)
this.isShowLetter = true
return false
},
/* 检索字母拖动中 */
searchMove(e) {
let pageY = e.touches[0].clientY;
this.showLetter = this.getLetter(pageY);
this.$emit("touchmove", this.showLetter)
return false
},
/* 检索字母拖动结束 */
searchEnd() {
setTimeout(() => {
this.isShowLetter = false
}, 1000)
},
}
}
</script>
<style lang="scss" scoped>
/* 首字母样式 */
.letter {
position: absolute;
right: 0;
top: 10%;
width: 30px;
height: 90%;
text-align: center;
justify-content: center;
display: flex;
flex-direction: column;
color: #666;
background-color: transparent;
z-index: 1;
}
/* 右边首字母样式 */
.touch {
color: #666;
font-size: 28rpx;
}
.letter-item {
color: #1B66FF;
flex-grow: 1;
}
/* 居中显示的选中首字母 */
.cont-letter {
background-color: #666;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 50%;
left: 50%;
margin: -50px;
width: 100px;
height: 100px;
border-radius: 10px;
font-size: 26px;
z-index: 1
}
</style>

View File

@@ -0,0 +1,192 @@
<template>
<view>
<!-- 搜索框 -->
<view class='search'>
搜索<input type='text' v-model="keyValue" placeholder='请输入银行名称' placeholder-style="font-size:32rpx;color:#cccccc" />
</view>
<scroll-view ref="view" scroll-y="true" :scroll-top="scrollTop" :style="{height:`${winHeight}px`}">
<!-- 循环城市数据 -->
<view v-for="group in data.data" :key="group.key">
<!-- 循环首字母检索信息 -->
<view class="list_letter">{{group.key}}</view>
<!-- 城市ID城市名称 -->
<view class="item_city" v-for="item in group.value" :key="item.id" @tap="click(item)">{{item.name}}</view>
</view>
</scroll-view>
<letter-list :options="data.letters" @touchmove="setScrollTop"></letter-list>
</view>
</template>
<script>
import letterList from './letter-list.vue'
function getFirstLetter(str) {
return str[0];
}
function fortmat(data, itemH, tHeight) {
let index = 0
const letters = []
const scrollTop = {}
for (var i = 0; i < data.length; i++) {
const value = data[i].value
const key = data[i].key
letters.push({
key,
value: value.length
})
scrollTop[key] = index
index += value.length
}
return {
data,
letters,
scrollTop
}
}
export default {
components: {
letterList
},
name: "NynCityList",
props: {
options: {
type: Array,
required: true
},
prop: {
type: Object,
default () {
return {
name: 'name'
}
}
}
},
data() {
return {
keyValue: '',
itemH: 0, //字母列表的高度
scrollTop: 0,
tHeight: 0,
winHeight: 0, //城市列表窗口高度
}
},
created() {},
mounted() {
this.initList()
},
methods: {
/* 列表初始化 */
initList() {
const sysInfo = uni.getSystemInfoSync();
const query = uni.createSelectorQuery().in(this);
query.select(".item_city").boundingClientRect(scrollx=>{
this.itemH = scrollx.height
})
query.select(".list_letter").boundingClientRect(scrollx=>{
this.tHeight = scrollx.height
})
query.select('.search').boundingClientRect(data => {
let top = data.height
this.winHeight = sysInfo.windowHeight - top - 1;
}).exec();
},
click(item) {
this.$emit('change', item)
},
/* 设置scroll-view滚动距离 */
setScrollTop(showLetter) {
var letters = this.data.letters
var letterIndex = 0
for (var i = 0; i < letters.length; i++) {
if (showLetter === letters[i].key) {
letterIndex = i
}
}
this.scrollTop = (this.data.scrollTop[showLetter] * this.itemH) + (letterIndex * this.tHeight)
},
},
computed: {
data() {
return fortmat(this.options, this.itemH, this.tHeight)
}
},
watch: {
keyValue(value) {
this.$emit('filter-method', value)
}
}
}
</script>
<style lang="scss" scoped>
.search {
display: flex;
align-items: center;
justify-content: flex-start;
background-color: #ffffff;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
// border-radius:100rpx;
padding: 20rpx 0;
width: 730rpx;
margin-left: 20rpx;
border-bottom: 1rpx solid #ddd;
input {
line-height: 60rpx;
text-align: left;
padding-left: 20rpx;
font-family: PingFangSC-Regular;
font-size: 32rpx !important;
}
}
/* 循环数据首字母检索 */
.list_letter {
display: flex;
background-color: #f8f8f8;
height: 60rpx;
color: #2a2a2a;
font-size: 26rpx;
padding-left: 10px;
align-items: center;
}
/* 城市样式 */
.item_city {
display: flex;
background-color: #fff;
height: 60rpx;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
letter-spacing: 0;
align-items: center;
padding: 10rpx 0;
width: 730rpx;
margin-left: 20rpx;
border-bottom: 2rpx solid #ddd;
}
.list {
.eng {
background: #ffffff;
padding: 30rpx;
color: #212121;
}
.text {
color: #212121;
font-size: 26rpx;
margin: 30rpx 0 0 30rpx;
padding-bottom: 30rpx;
border-bottom: 1px solid #E6E6E6
}
}
</style>

View File

@@ -0,0 +1,168 @@
<!--
自定义验证码输入密码输入使用
使用方法
maxlength输入最大长度
isPwd是否是密码模式
@finish回调函数
<validcode :maxlength="4" :isPwd="false" @finish="finish"></validcode>
-->
<template>
<view class="code-area">
<view class="flex-box">
<input :value="val" type="number" :focus="true" :maxlength="maxlength" class="hide-input" @input="getVal" @focus="focus"
@blur="blur" />
<view :key="index" v-for="(i,index) in maxlength - 1" v-bind:class="['item', { active: focusing && codeIndex === index }]">
<view class="line"></view>
<block v-if="val.length - 1 < index"></block>
<block v-else-if="isPwd">
<text class="dot">.</text>
</block>
<block v-else> {{ val[index] }}</block>
</view>
<view v-bind:class="['item', { active: focusing && codeIndex >= maxlength - 1 }]">
<view class="line" v-if="val.length - 1 < maxlength - 1"></view>
<block v-else-if="isPwd">
<text class="dot">.</text>
</block>
<block v-else> {{ val[maxlength - 1] }}</block>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
//最大长度 值为4或者6
maxlength: {
type: Number,
default: 4
},
//是否是密码
isPwd: {
type: Boolean,
default: false
}
},
data() {
return {
focusing: true,
val: '', //输入框的值
};
},
methods: {
//取值
getVal(e) {
let {
value
} = e.detail;
if (value.length <= this.maxlength) {
this.val = value;
}
},
//清除验证码或者密码
clear() {
this.val = "";
},
blur() {
this.focusing = false
},
focus() {
this.focusing = true
}
},
computed: {
codeIndex() {
return this.val.length
}
},
watch: {
val(val) {
if (val.length === this.maxlength) {
this.$emit('finish', val);
}
}
}
};
</script>
<style lang="scss">
.code-area {
text-align: center;
.flex-box {
display: flex;
flex-wrap: wrap;
position: relative;
justify-content: space-between;
}
.item {
position: relative;
width: 80upx;
height: 80upx;
margin-right: 18upx;
font-size: 30upx;
font-weight: bold;
color: #333333;
line-height: 80upx;
box-sizing: border-box;
border: 2upx solid #cccccc;
}
.item:last-child {
margin-right: 0;
}
.active {
border-color: #1B66FF
}
.active .line {
display: block;
}
.line {
display: none;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 2upx;
height: 40upx;
background: #1B66FF;
animation: twinkling 1s infinite ease;
}
.hide-input {
position: absolute;
top: 0;
left: -100%;
width: 200%;
height: 100%;
text-align: left;
z-index: 9;
opacity: 1;
}
@keyframes twinkling {
0% {
opacity: 0.2;
}
50% {
opacity: 0.5;
}
100% {
opacity: 0.2;
}
}
.dot {
font-size: 80upx;
line-height: 40upx;
}
}
</style>

View File

@@ -0,0 +1,69 @@
<template>
<view class="stepBarWrap">
<view class="stepBarContent" v-for="(item, index) in stepList" :key="index" >
<view class="number" :class="{'activeNum':active >= index}">{{index+1}}</view>
<view :class="{'active':active >= index}" style="color: #979797;margin-top: 20rpx;">{{item}}</view>
<view class="br" v-if="index > 0" :class="{'activeBr': active>=index}"></view>
</view>
</view>
</template>
<script>
export default{
data (){
return {
}
},
props: {
stepList: {
type: Array,
default: []
},
active: 0
},
methods:{
}
}
</script>
<style>
.stepBarWrap{
display: flex;
justify-content: space-between;
padding: 0 15px;
}
.stepBarContent{
flex:1;
display: flex;
flex-flow: column;
align-items: center;
position: relative;
font-size: 14px;
}
.stepBarContent .number{
width:60rpx;
height: 60rpx;
line-height: 30px;
border-radius: 50%;
text-align: center;
color: #FFFFFF;
background-color: #97979747;
}
.stepBarContent .br{
width: 40%;
height:2px;
background-color: #979797;
position: absolute;
top: 28%;
left: -20%;
}
.active{
color: #1C66FF !important;
}
.activeNum{
background-color: #1C66FF !important;
}
.activeBr{
background-color: #1C66FF !important;
}
</style>

View File

@@ -0,0 +1,96 @@
export default {
'contact': '\ue100',
'person': '\ue101',
'personadd': '\ue102',
'contact-filled': '\ue130',
'person-filled': '\ue131',
'personadd-filled': '\ue132',
'phone': '\ue200',
'email': '\ue201',
'chatbubble': '\ue202',
'chatboxes': '\ue203',
'phone-filled': '\ue230',
'email-filled': '\ue231',
'chatbubble-filled': '\ue232',
'chatboxes-filled': '\ue233',
'weibo': '\ue260',
'weixin': '\ue261',
'pengyouquan': '\ue262',
'chat': '\ue263',
'qq': '\ue264',
'videocam': '\ue300',
'camera': '\ue301',
'mic': '\ue302',
'location': '\ue303',
'mic-filled': '\ue332',
'speech': '\ue332',
'location-filled': '\ue333',
'micoff': '\ue360',
'image': '\ue363',
'map': '\ue364',
'compose': '\ue400',
'trash': '\ue401',
'upload': '\ue402',
'download': '\ue403',
'close': '\ue404',
'redo': '\ue405',
'undo': '\ue406',
'refresh': '\ue407',
'star': '\ue408',
'plus': '\ue409',
'minus': '\ue410',
'circle': '\ue411',
'checkbox': '\ue411',
'close-filled': '\ue434',
'clear': '\ue434',
'refresh-filled': '\ue437',
'star-filled': '\ue438',
'plus-filled': '\ue439',
'minus-filled': '\ue440',
'circle-filled': '\ue441',
'checkbox-filled': '\ue442',
'closeempty': '\ue460',
'refreshempty': '\ue461',
'reload': '\ue462',
'starhalf': '\ue463',
'spinner': '\ue464',
'spinner-cycle': '\ue465',
'search': '\ue466',
'plusempty': '\ue468',
'forward': '\ue470',
'back': '\ue471',
'left-nav': '\ue471',
'checkmarkempty': '\ue472',
'home': '\ue500',
'navigate': '\ue501',
'gear': '\ue502',
'paperplane': '\ue503',
'info': '\ue504',
'help': '\ue505',
'locked': '\ue506',
'more': '\ue507',
'flag': '\ue508',
'home-filled': '\ue530',
'gear-filled': '\ue532',
'info-filled': '\ue534',
'help-filled': '\ue535',
'more-filled': '\ue537',
'settings': '\ue560',
'list': '\ue562',
'bars': '\ue563',
'loop': '\ue565',
'paperclip': '\ue567',
'eye': '\ue568',
'arrowup': '\ue580',
'arrowdown': '\ue581',
'arrowleft': '\ue582',
'arrowright': '\ue583',
'arrowthinup': '\ue584',
'arrowthindown': '\ue585',
'arrowthinleft': '\ue586',
'arrowthinright': '\ue587',
'pulldown': '\ue588',
'closefill': '\ue589',
'sound': '\ue590',
'scan': '\ue612'
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,47 @@
<template>
<!-- #ifdef H5 || APP-PLUS -->
<view class="jl-mask" v-if="maskShow" style="top: 44px;">
<slot></slot>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="jl-mask" v-if="maskShow">
<slot></slot>
</view>
<!-- #endif -->
</template>
<script>
export default{
data () {
return {
}
},
props: {
maskShow: false
},
methods:{
clear(e){
return
}
}
}
</script>
<style>
.jl-mask{
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0,0,0,.1);
/* overflow: auto; */
z-index: 999;
}
.maskClose{
position: absolute;
right: 100rpx;
top: 100rpx;
}
</style>

View File

@@ -0,0 +1,206 @@
<template>
<view class="uni-navbar">
<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
class="uni-navbar__content">
<uni-status-bar v-if="statusBar" />
<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
<view class="uni-navbar__header-container uni-navbar__content_view">
<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
</view>
<!-- 标题插槽 -->
<slot />
</view>
</view>
</view>
<view class="uni-navbar__placeholder" v-if="fixed">
<uni-status-bar v-if="statusBar" />
<view class="uni-navbar__placeholder-view" />
</view>
</view>
</template>
<script>
import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
import uniIcons from "../uni-icons/uni-icons.vue";
export default {
name: "UniNavBar",
components: {
uniStatusBar,
uniIcons
},
props: {
title: {
type: String,
default: ""
},
leftText: {
type: String,
default: ""
},
rightText: {
type: String,
default: ""
},
leftIcon: {
type: String,
default: ""
},
rightIcon: {
type: String,
default: ""
},
fixed: {
type: [Boolean, String],
default: false
},
color: {
type: String,
default: "#000000"
},
backgroundColor: {
type: String,
default: "#FFFFFF"
},
statusBar: {
type: [Boolean, String],
default: false
},
shadow: {
type: [String, Boolean],
default: false
},
border: {
type: [String, Boolean],
default: true
}
},
mounted() {
if(uni.report && this.title !== '') {
uni.report('title', this.title)
}
},
methods: {
onClickLeft() {
this.$emit("clickLeft");
},
onClickRight() {
this.$emit("clickRight");
}
}
};
</script>
<style lang="scss" scoped>
$nav-height: 44px;
.uni-nav-bar-text {
/* #ifdef APP-PLUS */
font-size: 34rpx;
/* #endif */
/* #ifndef APP-PLUS */
font-size: $uni-font-size-lg;
/* #endif */
}
.uni-nav-bar-right-text {
font-size: $uni-font-size-base;
}
.uni-navbar {
width: 750rpx;
}
.uni-navbar__content {
position: relative;
width: 750rpx;
background-color: $uni-bg-color;
overflow: hidden;
}
.uni-navbar__content_view {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
flex-direction: row;
// background-color: #FFFFFF;
}
.uni-navbar__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
width: 750rpx;
height: $nav-height;
line-height: $nav-height;
font-size: 16px;
justify-content: center;
// background-color: #ffffff;
}
.uni-navbar__header-btns {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-wrap: nowrap;
width: 120rpx;
padding: 0 6px;
justify-content: center;
align-items: center;
}
.uni-navbar__header-btns-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 150rpx;
justify-content: flex-start;
}
.uni-navbar__header-btns-right {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 150rpx;
padding-right: 30rpx;
justify-content: flex-end;
}
.uni-navbar__header-container {
flex: 1;
}
.uni-navbar__header-container-inner {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
align-items: center;
justify-content: center;
font-size: $uni-font-size-base;
}
.uni-navbar__placeholder-view {
height: $nav-height;
}
.uni-navbar--fixed {
position: fixed;
z-index: 998;
}
.uni-navbar--shadow {
/* #ifndef APP-NVUE */
box-shadow: 0 1px 6px #ccc;
/* #endif */
}
.uni-navbar--border {
// border-bottom-width: 1rpx;
// border-bottom-style: solid;
// border-bottom-color: $uni-border-color;
}
</style>

View File

@@ -0,0 +1,187 @@
<template>
<view v-if="showPopup" class="uni-popup">
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" />
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)">
<view class="uni-popup__wrapper-box" @click.stop="clear">
<slot />
</view>
</view>
</view>
</template>
<script>
export default {
name: 'UniPopup',
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
type: {
type: String,
default: 'center'
},
// 是否开启自定义
custom: {
type: Boolean,
default: false
},
// maskClick
maskClick: {
type: Boolean,
default: true
},
show: {
type: Boolean,
default: true
}
},
data() {
return {
ani: '',
showPopup: false
}
},
watch: {
show(newValue) {
if (newValue) {
this.open()
} else {
this.close()
}
}
},
created() {},
methods: {
clear() {},
open() {
this.$emit('change', {
show: true
})
this.showPopup = true
this.$nextTick(() => {
setTimeout(() => {
this.ani = 'uni-' + this.type
}, 30)
})
},
close(type) {
if (!this.maskClick && type) return
this.$emit('change', {
show: false
})
this.ani = ''
this.$nextTick(() => {
setTimeout(() => {
this.showPopup = false
}, 300)
})
}
}
}
</script>
<style>
@charset "UTF-8";
.uni-popup {
position: fixed;
top: 0;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 99999;
overflow: hidden
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 998;
/* background: rgba(0, 0, 0, .4); */
opacity: 0
}
.uni-popup__mask.ani {
transition: all .3s
}
.uni-popup__mask.uni-bottom,
.uni-popup__mask.uni-center,
.uni-popup__mask.uni-top {
opacity: 1
}
.uni-popup__wrapper {
position: absolute;
z-index: 999;
box-sizing: border-box
}
.uni-popup__wrapper.ani {
transition: all .3s
}
.uni-popup__wrapper.top {
top: 0;
left: 0;
width: 100%;
transform: translateY(-100%)
}
.uni-popup__wrapper.bottom {
bottom: 0;
left: 0;
width: 100%;
transform: translateY(100%)
}
.uni-popup__wrapper.center {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
transform: scale(1.2);
opacity: 0
}
.uni-popup__wrapper-box {
position: relative;
box-sizing: border-box
}
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
padding: 30upx;
background: #fff
}
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
position: relative;
max-width: 80%;
max-height: 80%;
overflow-y: scroll
}
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
width: 100%;
max-height: 500px;
overflow-y: scroll
}
.uni-popup__wrapper.uni-bottom,
.uni-popup__wrapper.uni-top {
transform: translateY(0)
}
.uni-popup__wrapper.uni-center {
transform: scale(1);
opacity: 1
}
</style>

View File

@@ -0,0 +1,346 @@
<template>
<view class="sealWrapBox">
<view class="wrapper" v-show="showCanvas">
<view class="handBtn">
<view class="lookBtn" @click="look">图例示范</view>
<view class="delBtn" @click="clear">清除</view>
<view v-if="paintBrush" class="saveBtn saveBtnActive" @click="finish">下一步</view>
<view v-else class="saveBtn">下一步</view>
<!-- <view class="previewBtn" @click="close">关闭</view> -->
</view>
<view class="handCenter">
<canvas v-show="!maskShow" canvas-id="canvasid" id="test" class="handWriting" disable-scroll="true" @touchstart="touchstart"
@touchmove="touchmove" @touchend="touchend"></canvas>
</view>
<view class="handRight">
<image src="../../pageMy/static/img/seal/tips.png" mode=""></image>
<view class="handTitle">手写签名需与本人姓名保持一致</view>
</view>
</view>
<uniMask :maskShow="maskShow">
<view class="maskBody" :style="maskBodyStyle">
<view class="closeMask" @click.stop="closeMask">关闭</view>
</view>
</uniMask>
</view>
</template>
<script>
import {
baseUrl
} from '@/config/env.js'
import {
getStore
} from '@/untils/store.js'
import uniMask from '@/components/uni-mask/mask.vue'
var x = 20;
var y = 20;
export default {
data() {
return {
oc: "",
src: "",
//路径点集合
points: [],
maskBodyStyle: '',
showCanvas: true,
maskShow: false,
paintBrush: false
};
},
components: {
uniMask
},
mounted() {
this.initCanvas()
},
methods: {
look() {
uni.getSystemInfo({
success: res => {
var scrollH = res.windowHeight
var scrollW = res.windowWidth
// #ifdef H5
this.maskBodyStyle =
`width:${scrollH-144}px;height:${scrollW-100}px;top:${(scrollW/2)+94}px;left:-${(scrollW-100)/2}px`
// #endif
// #ifdef MP-WEIXIN
this.maskBodyStyle =
`width:${scrollH-144}px;height:${scrollW-100}px;top:${(scrollW/2)}px;left:-${(scrollW-100)/2}px`
// #endif
}
});
this.maskShow = true
},
closeMask() {
this.maskShow = false
},
imgFile() {
var token = getStore({
name: 'token'
})
const that = this
uni.uploadFile({
url: `${baseUrl}/api/jobslink-api/resource/oss/endpoint/put-file?Jobslink-Auth=${token}`,
filePath: that.src,
name: 'file',
success: (uploadFileRes) => {
that.$emit('finish', uploadFileRes)
that.paintBrush = true
}
});
},
finish() {
const that = this
this.paintBrush = false
this.oc.draw(true, uni.canvasToTempFilePath({
destWidth: 300,
destHeight: 300,
quality: 1,
canvasId: 'canvasid',
fileType: 'png',
success: function(res) {
that.src = res.tempFilePath
that.imgFile()
},
fail: function(err) {
console.log(err)
}
}, this))
},
close: function() {
this.showCanvas = false;
this.clear();
},
initCanvas() {
this.showCanvas = true;
this.oc = uni.createCanvasContext('canvasid', this);
//设置画笔样式
this.oc.lineWidth = 10;
this.oc.lineCap = "round";
this.oc.lineJoin = "round";
// 画笔颜色
// this.oc.setStrokeStyle("#ffffff");
},
//触摸开始,获取到起点
touchstart(e) {
const startX = e.changedTouches[0].x;
const startY = e.changedTouches[0].y;
let startPoint = {
X: startX,
Y: startY
};
this.points.push(startPoint);
//每次触摸开始,开启新的路径
this.oc.beginPath();
},
//触摸移动,获取到路径点
touchmove(e) {
let moveX = e.changedTouches[0].x;
let moveY = e.changedTouches[0].y;
let movePoint = {
X: moveX,
Y: moveY
};
this.points.push(movePoint); //存点
let len = this.points.length;
if (len >= 2) {
this.draw(); //绘制路径
}
},
// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
touchend() {
this.points = [];
this.paintBrush = true
},
/*
# 绘制笔迹
# 1.为保证笔迹实时显示,必须在移动的同时绘制笔迹
# 2.为保证笔迹连续每次从路径集合中区两个点作为起点moveTo和终点(lineTo)
# 3.将上一次的终点作为下一次绘制的起点(即清除第一个点)
*/
draw() {
let point1 = this.points[0]
let point2 = this.points[1]
this.points.shift()
this.oc.moveTo(point1.X, point1.Y)
this.oc.lineTo(point2.X, point2.Y)
this.oc.stroke()
this.oc.draw(true)
},
//清空画布
clear() {
let that = this;
uni.getSystemInfo({
success: function(res) {
that.paintBrush = false
let canvasw = res.windowWidth;
let canvash = res.windowHeight;
that.oc.clearRect(0, 0, canvasw, canvash);
that.oc.draw(true);
}
})
}
}
};
</script>
<style>
page {
background: #fbfbfb;
height: auto;
}
.maskBody {
position: fixed;
transform: rotate(90deg);
background: url(../../static/img/anli.png) no-repeat;
background-size: contain;
}
.maskBody .closeMask {
background-color: #FFFFFF;
position: fixed;
right: 16rpx;
top: 12rpx;
width: 108rpx;
height: 45rpx;
font-size: 32rpx;
font-weight: 400;
color: #999999;
line-height: 45rpx;
text-align: right;
}
.sealWrapBox {
background: #FFFFFF;
padding: 15px;
height: -webkit-fill-available;
}
.wrapper {
width: 100%;
overflow: hidden;
display: flex;
align-content: center;
flex-direction: row;
justify-content: center;
font-size: 28rpx;
}
.handWriting {
background: #fff;
width: 100%;
height: 100%;
}
.handRight {
display: inline-flex;
align-items: space-between;
width: 100%;
height: 50rpx;
transform: rotate(90deg);
position: absolute;
left: 300rpx;
bottom: 40%;
}
.handRight image {
width: 40rpx;
height: 40rpx;
}
.handCenter {
border-left: 4rpx dashed #e9e9e9;
flex: 5;
overflow: hidden;
box-sizing: border-box;
}
.handTitle {
flex: 1;
color: #666;
width: 100%;
height: 40rpx;
line-height: 40rpx;
}
.handBtn button {
font-size: 28rpx;
}
.handBtn {
height: 95vh;
display: inline-flex;
flex-direction: column;
justify-content: space-between;
align-content: space-between;
flex: 1;
}
.lookBtn {
position: absolute;
top: 40px;
left: 0;
transform: rotate(90deg);
width: 128rpx;
height: 45rpx;
font-size: 32rpx;
font-weight: 400;
color: #1C66FF;
line-height: 45rpx;
}
.delBtn {
position: absolute;
bottom: 90px;
left: 0rpx;
transform: rotate(90deg);
color: #979797;
width: 120rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
}
.delBtn image {
position: absolute;
top: 13rpx;
left: 25rpx;
}
.saveBtnActive {
background-color: #1C66FF !important;
color: #FFFFFF !important;
}
.saveBtn {
position: absolute;
bottom: 37px;
left: 0rpx;
transform: rotate(90deg);
color: #979797;
width: 120rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
background: #D6D6D6;
border-radius: 8rpx;
}
.previewBtn {
position: absolute;
top: 500rpx;
left: 0rpx;
transform: rotate(90deg);
color: #666;
}
</style>

View File

@@ -0,0 +1,183 @@
<template>
<view class="uni-searchbar">
<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box" @click="searchClick">
<!-- #ifdef MP-ALIPAY -->
<view class="uni-searchbar__box-icon-search">
<uni-icons color="#999999" size="18" type="search" />
</view>
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<uni-icons color="#999999" class="uni-searchbar__box-icon-search" size="18" type="search" />
<!-- #endif -->
<input v-if="show" :focus="showSync" :placeholder="placeholder" :maxlength="maxlength" @confirm="confirm" class="uni-searchbar__box-search-input"
confirm-type="search" type="text" v-model="searchVal" />
<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='')" class="uni-searchbar__box-icon-clear" @click="clear">
<uni-icons color="#999999" class="" size="24" type="clear" />
</view>
</view>
<text @click="cancel" class="uni-searchbar__cancel" v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelText}}</text>
</view>
</template>
<script>
import uniIcons from "../uni-icons/uni-icons.vue";
export default {
name: "UniSearchBar",
components: {
uniIcons
},
props: {
placeholder: {
type: String,
default: "请输入搜索内容"
},
radius: {
type: [Number, String],
default: 5
},
clearButton: {
type: String,
default: "auto"
},
cancelButton: {
type: String,
default: "auto"
},
cancelText: {
type: String,
default: '取消'
},
bgColor: {
type: String,
default: "#F8F8F8"
},
maxlength: {
type: [Number, String],
default: 100
}
},
data() {
return {
show: false,
showSync: false,
searchVal: ""
}
},
watch: {
searchVal() {
this.$emit("input", {
value: this.searchVal
})
}
},
methods: {
searchClick() {
if (this.show) {
return
}
this.searchVal = ""
this.show = true;
this.$nextTick(() => {
this.showSync = true;
})
},
clear() {
this.searchVal = ""
},
cancel() {
this.$emit("cancel", {
value: this.searchVal
});
this.searchVal = ""
this.show = false
this.showSync = false
// #ifndef APP-PLUS
uni.hideKeyboard()
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
},
confirm() {
// #ifndef APP-PLUS
uni.hideKeyboard();
// #endif
// #ifdef APP-PLUS
plus.key.hideSoftKeybord()
// #endif
this.$emit("confirm", {
value: this.searchVal
})
}
}
};
</script>
<style lang="scss" scoped>
$uni-searchbar-height: 36px;
.uni-searchbar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
position: relative;
padding: $uni-spacing-col-base;
background-color: $uni-bg-color;
}
.uni-searchbar__box {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
overflow: hidden;
position: relative;
flex: 1;
justify-content: center;
flex-direction: row;
align-items: center;
height: $uni-searchbar-height;
padding: 5px 8px 5px 0px;
border-width: 0.5px;
border-style: solid;
border-color: $uni-border-color;
}
.uni-searchbar__box-icon-search {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
width: 32px;
justify-content: center;
align-items: center;
color: $uni-text-color-placeholder;
}
.uni-searchbar__box-search-input {
flex: 1;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-searchbar__box-icon-clear {
align-items: center;
line-height: 24px;
padding-left: 5px;
}
.uni-searchbar__text-placeholder {
font-size: $uni-font-size-base;
color: $uni-text-color-placeholder;
margin-left: 5px;
}
.uni-searchbar__cancel {
padding-left: 10px;
line-height: $uni-searchbar-height;
font-size: 14px;
color: $uni-text-color;
}
</style>

View File

@@ -0,0 +1,25 @@
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
<slot />
</view>
</template>
<script>
var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: statusBarHeight
}
}
}
</script>
<style lang="scss" scoped>
.uni-status-bar {
width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>

View File

@@ -0,0 +1,82 @@
## 调用方式
- 视图调用
```html
<v-tabs
:tabs="[1,2,3,4]"
height="45px"
v-model="activeTab"
color="#333"
activeColor="#1abc9c"
fontSize="14px"
activeFontSize="16px"
:lineHeight="4px"
:lineScale="0.8"
lineColor="#1abc9c"
/>
```
- js 调用
```js
import vTabs from '@/components/v-tabs'
export default {
components: {
vTabs,
},
data() {
activeTab: 0
},
}
```
- 参数说明
| 参数 | 类型 | 默认值 | 说明 |
| :-------------: | :--------------: | :-----: | :----------: |
| value | String 或 Number | 0 | 必传 |
| tabs | Array | [] | tabs 数量 |
| height | String | '45px' | tab 高度 |
| backgroundColor | String | '' | 选中背景 |
| borderRadius | String | 5px | 圆角 |
| color | String | #333333 | 默认文字颜色 |
| activeColor | String | #333333 | 选中文字颜色 |
| fontSize | String | 14px | 默认文字大小 |
| activeFontSize | String | 14px | 选中文字大小 |
| lineScale | Number | 0.6 | 下划线缩放 |
| lineHeight | [Number, String] | 3 | 下划线高度 |
| lineColor | Sring | #007AFF | 下划线颜色 |
## 事件
|事件名称|参数|
|:-----:|:-----:|
|@change|activeTab|
## 更新日志
### 2020-06-09
1. 修复小程序端选中的下划线不显示问题
2. 新增 tab 高度设置
3. `lineHeight` 修改为只支持 `String` 方式
### 2020-06-11
1. 添加 `change` 事件
2. 修复插件内容问题
3. 修复下划线不居中问题
### 2020-06-11
1. 添加注释
2. 修复 bug
### 2020-07-05
1. 新增 `padding` 的可配置
2. 修复 `v-model` 双向绑定问题
3. 修复初始化下划线没定位的为题

View File

@@ -0,0 +1,241 @@
<template>
<view class="v-tabs" :style="{ height: height }">
<scroll-view class="scroll-view" :show-scrollbar="false" scroll-x scroll-with-animation :scroll-left="scrollLeft" style="width: auto; height: 100%; overflow: hidden;">
<view class="v-tabs__inner">
<view
class="v-tabs__item"
:style="{
color: activeTab == i ? activeColor : color,
fontSize: activeTab == i ? activeFontSize : fontSize,
backgroundColor: activeTab == i ? backgroundColor : '',
borderRadius,
padding,
}"
:data-index="i"
:class="{ active: activeTab == i }"
@tap="handleTapItem"
v-for="(v, i) in tabs"
:key="i"
>
<view class="">
{{ v }}
</view>
<view class="bottomborder"></view>
</view>
</view>
<!-- <view
class="v-tabs__line"
:style="{ width: `${lineWidth}px`, height: `${lineHeight}`, backgroundColor: lineColor, transform: `translateX(${lineLeft}px)`, top: `calc(${height} - ${lineHeight})` }"
></view> -->
</scroll-view>
</view>
</template>
<script>
/**
* tabs 选项卡
* @description tabs选项卡
* @property {String|Number} value 双向绑定的选中值
* @property {String} height=50px 高度
* @property {Array} tabs 选项卡列表 ['测试1', '测试2', '测试3']
* @property {String} backgroundColor 选中背景色
* @property {String} borderRadius 选中圆角
* @property {String} color 默认文字的颜色
* @property {String} activeColor 选中文字颜色
* @property {String} fontSize 默认文字大小
* @property {String} activeFontSize 选中文字大小
* @property {Number} lineScale 选中标签下划线的缩放级别
* @property {String} lineHeight 选中标签下划线的高度
* @property {String} lineColor 选中下划线的颜色
*
* @event {Function(activeTab)} change 改变标签触发
*/
export default {
name: 'VTabs',
props: {
value: {
type: [String, Number],
default: 0
},
height: {
type: String,
default: '45px'
},
tabs: {
type: Array,
default() {
return []
}
},
backgroundColor: {
type: String,
default: 'transparent'
},
borderRadius: {
type: String,
default: '5px'
},
color: {
type: String,
default: '#333333'
},
activeColor: {
type: String,
default: '#007AFF'
},
fontSize: {
type: String,
default: '14px'
},
activeFontSize: {
type: String,
default: '14px'
},
padding: {
type: String,
default: '10rpx 20rpx'
},
lineScale: {
type: Number,
default: 0.6
},
lineHeight: {
type: String,
default: '3px'
},
lineColor: {
type: String,
default: '#007AFF'
}
},
data() {
return {
scrollLeft: 0,
activeTab: 0,
width: 0,
lineLeft: 0,
lineWidth: 0
}
},
watch: {
activeTab(newVal) {
this.$emit('input', newVal * 1)
},
value(newVal) {
this.activeTab = newVal
this.getTabsWidth(0)
}
},
methods: {
handleTapItem(e) {
const index = e.currentTarget.dataset.index
if (this.activeTab != index) {
this.activeTab = index
this.getTabsWidth(e.currentTarget.offsetLeft)
this.$emit('change', this.activeTab)
}
},
getTabsWidth(offsetLeft) {
const query = uni.createSelectorQuery().in(this)
query
.select('.v-tabs')
.boundingClientRect(data => {
this.width = data.width
})
.exec()
setTimeout(() => {
let i = 0
let width = 0
query
.selectAll('.v-tabs__item')
.boundingClientRect(data => {
width = data.reduce((total, currentValue, currentIndex, arr) => {
if (currentIndex < this.activeTab) {
total = total + currentValue.width
}
return total
}, 0)
const padding = this.padding.split(' ')[0]
const res = /(\d+)(upx|rpx|px)/.exec(padding)
if (res && (res[2] == 'upx' || res[2] == 'rpx')) {
width += uni.upx2px(res[1]) * 2 * this.activeTab
} else {
width += res[1] * this.activeTab
}
})
.exec()
query
.select('.v-tabs__item.active')
.boundingClientRect(data => {
const ol = offsetLeft ? offsetLeft : width
if (data.width) {
this.lineLeft = ol + (data.width * (1 - this.lineScale)) / 2
this.lineWidth = data.width * this.lineScale
this.scrollLeft = ol - (this.width - data.width) / 2
}
})
.exec()
}, 10)
}
},
mounted() {
this.activeTab = this.value
this.getTabsWidth(0)
}
}
</script>
<style lang="scss" scoped>
.v-tabs {
position: relative;
width: 100%;
white-space: nowrap;
overflow: hidden;
border-bottom: 1rpx solid #dddddd;
.v-tabs__inner {
position: relative;
display: flex;
align-items: center;
height: 100%;
justify-content: center;
background-color: #fefefe;
// border-bottom: 1rpx solid #dddddd;
border-bottom: 0;
}
.active{
border-radius: 0 !important;
.bottomborder{
width: 42rpx;
height: 6rpx;
margin: 0 auto;
background-color: #1B66FF;
border-radius: 20rpx;
overflow: hidden;
display: block !important;
margin-top: 10rpx;
}
}
.v-tabs__item {
// display: inline-flex;
margin-right: 20upx;
transition: all 0.3s ease;
&:last-child {
margin-right: 0;
}
}
.v-tabs__line {
position: absolute;
z-index: 99;
transition: all 0.3s linear;
border-radius: 4upx;
}
}
/deep/ ::-webkit-scrollbar {
display: none;
}
</style>

23
config/env.js Normal file
View File

@@ -0,0 +1,23 @@
let baseUrl = '';
const env = process.env
if (env.NODE_ENV == 'development') {
if (env.VUE_APP_PLATFORM === 'mp-weixin') {
baseUrl = `https://testapi.jlhrms.cn`; // 开发环境地址
}
} else if (env.NODE_ENV == 'production') {
if (env.VUE_APP_PLATFORM === 'mp-weixin') {
baseUrl = `https://wxapi.jlhrms.cn`; //生产环境地址
}
} else if (env.NODE_ENV == 'test') {
if (env.VUE_APP_PLATFORM === 'mp-weixin') {
baseUrl = `https://testapi.jlhrms.cn`; //测试环境地址
} {
baseUrl = ``; //测试环境地址
}
}
export {
baseUrl,
env
}

19
config/website.js Normal file
View File

@@ -0,0 +1,19 @@
/**
* 全局配置文件
*/
export default {
title: 'jobslink',
logo: 'S',
key: 'jobslink', //配置主键,目前用于存储
indexTitle: 'Jobslink Admin',
clientId: 'jobslink_clientA', // 客户端id
clientSecret: 'jobslink_clientA_secret', // 客户端密钥
tenantMode: true, // 是否开启租户模式
tenantId: '000000', // 管理组租户编号
captchaMode: true, // 是否开启验证码模式
tokenName: 'Jobslink-Auth',
tokenTime: 3000,
newsRefreshTime:600000,// 消息刷新时间
//http的status默认放行不才用统一处理的,
statusWhiteList: [],
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

25
index.html Normal file
View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
})
</script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -0,0 +1,42 @@
export default function uniCopy({content,success,error}) {
if(!content) return error('复制的内容不能为空 !')
content = typeof content === 'string' ? content : content.toString() // 复制内容,必须字符串,数字需要转换为字符串
/**
* 小程序端 和 app端的复制逻辑
*/
//#ifndef H5
uni.setClipboardData({
data: content,
success: function() {
success("复制成功~")
console.log('success');
},
fail:function(){
success("复制失败~")
}
});
//#endif
/**
* H5端的复制逻辑
*/
// #ifdef H5
if (!document.queryCommandSupported('copy')) { //为了兼容有些浏览器 queryCommandSupported 的判断
// 不支持
error('浏览器不支持')
}
let textarea = document.createElement("textarea")
textarea.value = content
textarea.readOnly = "readOnly"
document.body.appendChild(textarea)
textarea.select() // 选择对象
textarea.setSelectionRange(0, content.length) //核心
let result = document.execCommand("copy") // 执行浏览器复制命令
if(result){
success("复制成功~")
}else{
error("复制失败请检查h5中调用该方法的方式是不是用户点击的方式调用的如果不是请改为用户点击的方式触发该方法因为h5中安全性不能js直接调用")
}
textarea.remove()
// #endif
}

1
lib/Rx.js Normal file

File diff suppressed because one or more lines are too long

29
main.js Normal file
View File

@@ -0,0 +1,29 @@
import Vue from 'vue'
import store from './store';
import App from './App'
import util from './untils/func.js'
// 注册全局组件
// import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue"
// import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue"
// Vue.component('mescroll-body', MescrollBody)
// Vue.component('mescroll-uni', MescrollUni)
// 注册全局组件
import JlButton from "@/components/jl-button/main.vue"
import JlForm from "@/components/jl-form/main.vue"
import JlFormItem from "@/components/jl-form/item.vue"
import CSButton from "@/components/cs-button/main.vue"
Vue.component('jl-button', JlButton)
Vue.component('jl-form', JlForm)
Vue.component('jl-form-item', JlFormItem)
Vue.component('cs-button', CSButton)
Vue.config.productionTip = false
Vue.use(util)
App.mpType = 'app'
const app = new Vue({
...App,store
})
app.$mount()

76
manifest.json Normal file
View File

@@ -0,0 +1,76 @@
{
"name" : "招聘",
"appid" : "__UNI__0775612",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"compilerVersion" : 3,
/* 5+App */
"modules" : {},
/* */
"distribute" : {
/* */
"android" : {
/* android */
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
/* ios */
"sdkConfigs" : {}
}
},
/* SDK */
"quickapp" : {},
/* */
"mp-weixin" : {
/* */
"appid" : "wx77580889aaf15eb4",
"setting" : {
"urlCheck" : false,
"minified" : true,
"es6" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "获取您的位置,以便给您推荐合适工作信息"
}
}
},
"h5" : {
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "FW3BZ-6JTK6-GCUS5-MZCRR-3GPR5-HJFEI"
}
}
},
"template" : "index.html"
}
}

23
package-lock.json generated Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "jobslink-user-clent",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"decimal.js": {
"version": "10.2.0",
"resolved": "https://r.cnpmjs.org/decimal.js/download/decimal.js-10.2.0.tgz",
"integrity": "sha1-OUZhE6ngNhEdAvgkibX9awte0jE="
},
"js-base64": {
"version": "2.4.9",
"resolved": "https://r.cnpmjs.org/js-base64/download/js-base64-2.4.9.tgz",
"integrity": "sha1-dIkR+wT0imDEdxs3XKxFqA3xHAM="
},
"js-md5": {
"version": "0.7.3",
"resolved": "https://r.cnpmjs.org/js-md5/download/js-md5-0.7.3.tgz",
"integrity": "sha1-tPL7sLMnRV9ZjWcn447Ccs0Jw/I="
}
}
}

24
package.json Normal file
View File

@@ -0,0 +1,24 @@
{
"name": "jobslink-user-clent",
"version": "1.0.0",
"description": "{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}",
"main": "main.js",
"directories": {
"lib": "lib"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@192.168.22.101:clent/jobslink-user-clent.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"decimal.js": "^10.2.0",
"js-base64": "^2.4.9",
"js-md5": "^0.7.3"
}
}

View File

@@ -0,0 +1,108 @@
<template>
<view class="application-body">
<view class="application-content" v-if="applicatinList.length!=0">
<view class="application-item" v-for="(item,index) in applicatinList" :key="index" @click="goApplyPage(item.type,item.content)">
<view class="apply_boldText">{{item.type | type}}</view>
<view class="apply_normalText">{{item.applTime}}</view>
</view>
</view>
<view class="noData" v-else>暂无申请信息</view>
</view>
</template>
<script>
import {getApplContentList} from '@/api/newIndex.js'
import {mapGetters} from 'vuex'
export default {
data() {
return {
applicatinList:[],
}
},
computed:{
...mapGetters(['authInfo','auth'])
},
onPullDownRefresh() {
this.applicatinList=[];
this.getList();
},
filters:{
type(type){
switch (type){
case 1:
return '法律咨询';
break;
case 2:
return '技能提升';
break;
}
}
},
methods: {
getList(){
if(this.auth.realNameState){
getApplContentList().then(res=>{
this.applicatinList=res.data.data.records;
uni.stopPullDownRefresh();
})
}
else{
this.applicatinList=[];
uni.stopPullDownRefresh();
}
},
goApplyPage(type,comment){
var data=encodeURIComponent(comment)
if(type==1){
uni.navigateTo({
url:`/pageMy/apply/rights?type=${type}&data=${data}`
})
}
else if(type==2){
uni.navigateTo({
url:`/pageMy/my/resume/setWskill?type=${type}&data=${data}`
})
}
}
},
onShow() {
this.getList();
}
}
</script>
<style>
.application-body{
width: 690rpx;
margin: 20rpx auto;
}
.application-item{
width: 100%;
height: 120rpx;
border-bottom:1px solid #eaeaea;
padding: 40rpx 30rpx 0 0rpx;
}
.apply_boldText{
font-size: 32rpx;
font-weight: bold;
color: #333333;
line-height: 36rpx;
margin-bottom: 14rpx;
}
.apply_normalText{
font-size: 28rpx;
font-weight: 400;
color: #CCCCCC;
line-height: 36rpx;
}
.noData{
text-align: center;
height: 100px;
line-height: 100px;
}
</style>

138
pageMy/apply/rights.vue Normal file
View File

@@ -0,0 +1,138 @@
<template>
<view>
<!-- <apply-template placeholder="请描述你遇到的法律问题" @submit="handel"></apply-template> -->
<textarea :auto-height="true" style="padding: 20px;" v-model="inputValue" placeholder="请描述你遇到的法律问题" maxlength="200" placeholder-class="textClass"/>
<view class="errTips" v-if="errShow && btnShow">抱歉您输入的内容已超出字数限制</view>
<view class="" v-if="btnShow">
<view class="submitBtn" v-if="validate" @click="handleSubmit">提交</view>
<view class="submitBtn" v-if="loading">提交中</view>
<view class="submitBtn disabledBtn" v-if="!validate">提交</view>
</view>
</view>
</template>
<script>
import {
labourUnionDetail
} from '@/api/federation.js'
import {mapGetters} from 'vuex'
import {showUniModal} from '@/untils/uniModal.js'
import {submitApplication} from '@/api/newIndex.js'
export default {
data() {
return {
inputValue:'',
validate:false,
applyType:1,
btnShow:true,
pageTitle:'',
placeholder:'',
loading:false,
errShow:false,
submitType:1,//申请类型1 法律咨询 2技能提升
}
},
onShow() {
if (!this.$store.state.user.token){
//modalTitle, content, whetherCancel, confirmText, pageUrl, cancelUrl
showUniModal('提示','您还未登录,点击确认去登录',true,'确定','/pages/login/login','/pages/index/index')
}else{
if (!this.auth.realNameState) { //未实名需要提示
showUniModal('提示', '检查到您还未实名认证,实名认证之后才可加入工会', true, '立即认证', '/pageMy/setUserBase/index','/pages/index/index')
} else {
labourUnionDetail(this.authInfo.idNumber).then(res => { //判断是否加入工会
const data = res.data.data.records;
if (data.length == 0) { //未查到数据,代表未加入工会
showUniModal('提示', '加入工会后可使用此服务', true, '加入工会', '/pageMy/federation/forMembership/Notice','/pages/index/index')
}
})
}
}
},
watch: {
inputValue(value) {
if(value.length!=0){
this.validate=true;
}
else{
this.validate=false;
}
if(value.length>=200){
this.errShow=true;
}
else{
this.errShow=false;
}
},
},
onLoad(option) {
this.applyType=option.type;
if(option.data && option.type){
this.inputValue=decodeURIComponent(option.data);
this.btnShow=false;
}
},
methods: {
handleSubmit(){
this.loading=true;
uni.showLoading({
title:'请求中'
})
let uid=this.authInfo.userId;
let uname=this.authInfo.realName;
let tel=this.authInfo.telphone;
submitApplication(uid,uname,tel,this.submitType,this.inputValue).then(res=>{
this.loading=false;
uni.hideLoading()
setTimeout(() => {
uni.showToast({
title: '提交成功',
icon: 'none'
});
}, 1000)
uni.switchTab({
url:'/pages/index/index'
})
})
},
},
computed:{
...mapGetters(['authInfo','auth'])
}
}
</script>
<style>
.textClass{
color: #cccccc;
}
.submitBtn{
width: 60%;
height: 80rpx;
line-height: 80rpx;
border-radius: 10px;
text-align: center;
background-color: #1b66ff;
color: #f1f1f1;
position: absolute;
bottom: 100px;
left: 20%;
}
.disabledBtn{
background-color: #7f7f7f;
}
.teset{
width: 100px;
height: 100px;
border: 1px solid;
}
.errTips{
color: red;
padding-left: 40rpx;
}
</style>

View File

@@ -0,0 +1,59 @@
<template>
<view class="bodys">
<block v-if="companyList.length>0" v-for="(item,index) in companyList" :key="item.id">
<companyList :companyitem="item" :comment='true' :noApply="false"></companyList>
<view class="baddd"></view>
</block>
<view v-if="companyList.length<=0">
<image src="../../static/img/pic_nocom.svg" mode="" class="nothing"></image>
<view class="nothingContnt">
暂无评价信息
</view>
</view>
</view>
</template>
<script>
import companyList from '@/components/companyList/companyList.vue';
import testData from '@/common/textdata.js';
import {myRate} from '@/api/rate.js';
export default {
components: { companyList },
data() {
return {
companyList: []
}
},
onShow: function() {
myRate().then(res => {
this.companyList = res.data.data.records;
})
},
methods: {
}
}
</script>
<style>
.nothingContnt{
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666;
margin-top: 30rpx;
text-align: center;
}
.nothing{
width: 400rpx;
height: 200rpx;
display: block;
margin: 0 auto;
margin-top: 50%;
}
.baddd{
background: #f6f6f6;
height: 20rpx;
}
.bodys{background-color: #fefefe;}
page{background-color: #fff;}
</style>

232
pageMy/contract/index.vue Normal file
View File

@@ -0,0 +1,232 @@
<template>
<view>
<view class="nothing" v-if="ContractList.length === 0">
<image src="../../static/img/pic.svg" mode=""></image>
<view class="nothingText">
暂无合同信息
</view>
</view>
<view class="contractBoxList" v-for="item in ContractList">
<view>
<view class="title">任务名称{{item.servicesName}}</view>
<view class="time" style="margin: 10px 0;font-weight:500;">合同编号{{item.contractNo}}</view>
<view class="time">合同有效期{{item.stime | time}} {{item.etime | time}}</view>
</view>
<view class="lookBtn" @click="look(item)">
查看合同
</view>
</view>
</view>
</template>
<script>
import {
contractList,
viewContract
} from '@/api/auth.js'
export default {
data() {
return {
ContractList: [],
maskShow: false,
src: '',
current: 1,
size: 10,
total: 0
}
},
onLoad() {
this.initContractList()
},
filters: {
time(date) {
var d = date.slice(0, 10)
return d.replace(/\//g, "-")
}
},
/*页面滚动到底部 换页*/
onReachBottom: function() {
if (this.ContractList.length >= this.total) {
uni.showToast({
title: '到底了',
icon: 'none'
})
return
}
this.initContractList()
},
/*下拉刷新*/
onPullDownRefresh: function() {
this.current = 1
this.ContractList = []
this.initContractList()
},
methods: {
initContractList() {
var params = {
size: this.size,
current: this.current
}
contractList(params).then(e => {
this.current++
this.ContractList = [...this.ContractList, ...e.data.data.records]
this.total = e.data.data.total
uni.stopPullDownRefresh();
}).catch(err => {
uni.stopPullDownRefresh();
})
},
look(item) {
/*预览合同图片改为预览PDF*/
uni.showLoading({
title:'请求中',
})
// #ifdef H5
uni.hideLoading()
window.open(item.contractSecondUrl);
return;
// #endif
uni.downloadFile({
url: item.contractSecondUrl,
success: function(res) {
var filePath = res.tempFilePath;
uni.openDocument({
filePath: filePath,
success: function(res) {
uni.hideLoading()
},
fail: function() {
uni.showToast({
title: '打开合同失败,请稍后重试',
icon: 'none'
})
}
});
},
});
},
},
computed: {
imgSrc() {
const obj = {
'backgroundImage:': `url(${this.src})`,
"backgroundColor": 'red'
}
return obj
}
}
}
</script>
<style lang="scss">
a {
text-decoration: none
}
page {
background: #F6F6F6;
width: 100%;
height: 100%;
}
.nothingText {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
text-align: center;
margin-top: 20rpx;
}
.nothing image {
width: 400rpx;
height: 200rpx;
display: block;
padding-top: 50%;
margin: 0 auto;
}
.nothing {
width: 100%;
height: 100vh;
background-color: #fefefe;
}
.contractMask {
background-color: #FFFFFF;
margin: 30rpx;
position: relative;
border-radius: 4px;
height: 96%;
overflow: auto;
.close {
width: 23px;
height: 23px;
color: #1B66FF;
position: fixed;
right: 60rpx;
top: 60rpx;
transform: rotate(45deg);
font-size: 40px;
}
.down {
position: fixed;
bottom: 30px;
left: 14%;
width: 545rpx;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background: #1B66FF;
font-size: 36rpx;
font-weight: 400;
color: #FFFFFF;
}
}
.contractBoxList {
padding: 30rpx 18rpx 26rpx 30rpx;
margin-bottom: 20rpx;
font-size: 14px;
background-color: #FEFEFE;
position: relative;
.title {
height: 32rpx;
font-size: 32rpx;
font-weight: 500;
color: #333333;
line-height: 32rpx;
}
.time {
height: 38rpx;
font-size: 24rpx;
font-weight: 400;
color: #999999;
line-height: 38rpx;
}
.lookBtn {
position: absolute;
right: 18rpx;
bottom: 34rpx;
height: 33rpx;
font-size: 28rpx;
font-weight: 400;
color: #007AFF;
line-height: 33rpx;
}
}
</style>

View File

@@ -0,0 +1,85 @@
<template>
<view style="height: 100%;">
<view class="notice">
<view class="body">
<view>
<view class="list" v-for="(item, index) in list" :key="index">
{{item}}
</view>
</view>
<view style="height:65rpx;"></view>
<view class="nextBtn" @click="go('/pageMy/federation/forMembership/perfectXin')">下一步</view>
</view>
</view>
</view>
</template>
<script>
export default{
data(){
return {
list: [
'1、选举权、被选举权和表决权。',
'2、对工会工作监督提出意见和建议。',
'3、对用人单位工作提出批评与建议。',
'4、在合法权益受到侵犯时要求工会给予保护。',
'5、工会提供的法律服务、就业服务等优惠待遇。',
'6、参加关于工会工作和会员关心问题的讨论。'
]
}
},
methods: {
go(url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss">
page{
height:100%;
background-color: #2354fd;
}
.notice{
width: 100%;
height:100%;
background: url('../../static/img/federation/notice.png') no-repeat;
background-size: contain;
margin-top: -50px;
position: absolute;
}
.body{
width: 590rpx;
height: 711rpx;
background: #FFFFFF;
border-radius: 10rpx;
z-index: 999;
position: absolute;
top: 534rpx;
// bottom: 220rpx;
left: 6%;
padding: 38rpx;
.list{
font-size: 30rpx;
font-weight: 400;
color: #333333;
line-height: 55rpx;
}
.nextBtn{
margin: 45rpx 0 0 93rpx;
width: 402rpx;
height: 80rpx;
background: #1B66FF;
border-radius: 8rpx;
font-size: 30rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 80rpx;
text-align: center;
}
}
</style>

View File

@@ -0,0 +1,115 @@
<template>
<view>
<view class="bookBox">
<view class="title">入会申请书</view>
<view class="content">{{content}}</view>
<view class="time people">申请人</view>
<view class="time">
<view class="day">日期</view>
<view class="year"> <view></view> </view>
</view>
</view>
<view style="height: 49rpx;"></view>
<view class="nextBtn" @click="submit">
确定入会
</view>
</view>
</template>
<script>
import {contract} from '@/api/federation.js'
export default{
data(){
return{
password: false,
maxlength: 6,
content: '我自愿加入石家庄新业态职工工会联合会,遵守工会章程,执行工会决议,积极参加工会活动,为把我国建设成为富强、民主、文明的社会主义国家而努力奋斗。'
}
},
methods:{
submit(){
uni.showLoading({
title:'请求中'
})
contract().then(e => {
uni.hideLoading()
uni.switchTab({
url: '/pages/my/my'
})
})
},
go(url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss">
page{
background: #F6F6F6;
}
.bookBox{
width: 630rpx;
height: 691rpx;
background: #FFFFFF;
margin: 53rpx 30rpx;
padding: 60rpx 30rpx 0 30rpx;
position: relative;
.title{
font-size: 40rpx;
font-weight: 500;
color: #333333;
line-height: 56rpx;
text-align: center;
margin-bottom: 47rpx;
}
.content{
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 50rpx;
text-indent:2em;
}
.people{
position: absolute;
bottom: 203rpx;
right: 223rpx;
}
.time{
font-size: 32rpx;
font-weight: 500;
color: #333333;
line-height: 45rpx;
.day{
position: absolute;
bottom: 128rpx;
right: 255rpx;
}
.year{
width: 192rpx;
display: flex;
justify-content: space-between;
position: absolute;
bottom: 128rpx;
right: 30rpx;
}
}
}
.nextBtn{
margin: 50rpx 30rpx;
height: 80rpx;
background: #1B66FF;
border-radius: 8rpx;
font-size: 30rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 80rpx;
text-align: center;
}
</style>

View File

@@ -0,0 +1,101 @@
<template>
<view class="codeSealBox">
<!-- #ifdef H5 || APP-PLUS -->
<view class="closeCode" @click="closeShowCode" style="top: 124rpx;">+</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="closeCode" @click="closeShowCode">+</view>
<!-- #endif -->
<view class="title">
<view class="name">签名密码</view>
<view class="tip">6位数字签名密码</view>
</view>
<view style="height: 36px;"></view>
<valid-code ref="validCode" @finish="getInpCode" :maxlength="maxlength"></valid-code>
<view style="height: 36px;"></view>
<view class="forget" @click="forget">忘记密码</view>
</view>
</template>
<script>
import validCode from '@/components/p-valid-code/p-valid-code.vue'
import {contract} from '@/api/federation.js'
export default {
data () {
return {
maxlength: 6
}
},
components: {validCode},
methods:{
closeShowCode () {
uni.navigateBack()
},
getInpCode (e){
var params = {
password: e
}
uni.showLoading({
title:'请求中'
})
contract(params).then(e => {
uni.hideLoading()
uni.switchTab({
url: '/pages/my/my'
})
})
},
// 忘记密码
forget(){
uni.navigateTo({
url: `/pageMy/setUserBase/seal/forget?`
})
}
}
}
</script>
<style lang="scss">
.codeSealBox{
padding: 285rpx 72rpx 0 72rpx;
.closeCode{
position: absolute;
right: 30rpx;
top: 120rpx;
color: #1B66FF;
transform: rotate(45deg);
font-size: 40px;
}
.title{
display: flex;
align-items: center;
}
.name{
height: 46rpx;
font-size: 46rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 46rpx;
margin-right: 28rpx;
}
.tip{
height: 38rpx;
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 38rpx;
}
.forget{
height: 38rpx;
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #5AA0FA;
line-height: 38rpx;
text-align: right;
}
}
</style>

View File

@@ -0,0 +1,170 @@
<template>
<view class="">
<view class="paymentList">
<view class="title">支付方式</view>
<view style="height: 45rpx;"></view>
<view class="payment" :class="{'active': jianhangValue}" @click="jianhangchange">
<view style="display: flex;align-items: center;">
<image class="img" v-if="jianhangValue" src="../../static/img/federation/jiansheyinhanglan.png" ></image>
<image class="img" v-else src="../../static/img/federation/jiansheyinhanghui.png"></image>
<view class="name">建行卡号支付</view>
<view class="price">手续费0.00</view>
</view>
<checkbox :checked="jianhangValue" style="transform:scale(0.8)"/>
</view>
<view style="height: 45rpx;"></view>
<view class="payment" :class="{'active': yinlianValue}" @click="yinlianchange">
<view style="display: flex;align-items: center;">
<image class="img" v-if="yinlianValue" src="../../static/img/federation/yilianlan.png" ></image>
<image class="img" v-else src="../../static/img/federation/yinlianhui.png"></image>
<view class="name">银联支付</view>
<view class="price">手续费0.00</view>
</view>
<checkbox :checked="yinlianValue" style="transform:scale(0.8)"/>
</view>
</view>
<view class="paymentPrice">
<view class="title">结算信息</view>
<view class="bodyPrice">
<view class="price"><view style="font-size: 46rpx;height: 20px;"></view>20.00</view>
<view class="tip">应付费用</view>
</view>
<view class="bottomPrice">
<view class="priceBox">
<view>缴费金额</view>
<view>¥ 20.00 </view>
</view>
<view class="priceBox">
<view>支付手续费</view>
<view>¥ 0.00 </view>
</view>
</view>
</view>
<view class="nextBtn" @click="payment">
确认支付
</view>
</view>
</template>
<script>
export default{
data (){
return {
jianhangValue: false,
yinlianValue: false,
}
},
methods: {
jianhangchange (){
this.yinlianValue = false
this.jianhangValue = !this.jianhangValue
},
yinlianchange (){
this.jianhangValue = false
this.yinlianValue = !this.jianhangValue
},
payment (){
console.log('支付')
}
}
}
</script>
<style lang="scss">
page{
background: #F6F6F6;;
}
.paymentPrice{
width: 690rpx;
height: 469rpx;
background: #FFFFFF;
margin: 0 30rpx;
.title{
font-size: 32rpx;
font-weight: 500;
color: #333333;
padding: 30rpx 0 0 30rpx;
}
.bodyPrice{
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
height: 205rpx;
.price{
font-size: 73rpx;
font-weight: normal;
color: #333333;
display: flex;
align-items: center;
}
.tip{
font-size: 28rpx;
font-weight: 400;
color: #999999;
}
}
.bottomPrice{
border-top: 1px solid #E8E8E8;
padding: 30rpx;
font-size: 30rpx;
font-weight: 400;
color: #999999;
.priceBox{
display: flex;
justify-content: space-between;
line-height: 36px;
}
}
}
.paymentList{
width: 630rpx;
height: 319rpx;
background: #FFFFFF;
margin:30rpx;
padding: 0 30rpx;
.title{
font-size: 32rpx;
font-weight: 500;
color: #333333;
border-bottom: 1px solid #E8E8E8;
padding: 15px 0 10px 0;
}
.payment{
display: flex;
justify-content: space-between;
align-items: center;
.img{
width: 50rpx;height: 50rpx;
}
.name{
font-size: 28rpx;
font-weight: 500;
color: #999999;
width: 170rpx;
margin: 0 20rpx;
}
.price{
font-size: 22rpx;
font-weight: 400;
color: #999999;
}
}
.active{
color: #1B66FF !important;
}
}
.nextBtn{
margin: 50rpx 30rpx;
height: 80rpx;
background: #1B66FF;
border-radius: 8rpx;
font-size: 30rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 80rpx;
text-align: center;
}
</style>

View File

@@ -0,0 +1,264 @@
<template>
<view >
<view class="vip">
<view class="body">
<view class="name">
<view class="">
姓名{{authInfo.realName}}
</view>
<view class="Gender">
性别{{authInfo.sex | sex}}
</view>
</view>
<view class="idcard">
身份证号{{authInfo.idNumber}}
</view>
<view class="">
手机号码{{authInfo.telphone}}
</view>
</view>
</view>
<view v-if="status" class="informationWrap">
<view class="informationBox">
<view class="title">民族</view>
<view class="btn btnGray">
<view style="margin-right:23rpx;">{{authInfo.nation}}</view>
</view>
</view>
<view class="informationBox">
<view class="title">政治面貌</view>
<view class="btn btnGray">
<view style="margin-right:23rpx;">{{authInfo.politics}}</view>
</view>
</view>
</view>
<view v-else class="informationWrap">
<picker @change="nationPickerChange" :value="nationIndex" :range="nation" range-key="name">
<view class="informationBox">
<view class="title">民族</view>
<view class="btn">
<view v-if="nationStatus" style="margin-right:23rpx;">{{nation[nationIndex].name}}</view>
<view v-else style="margin-right:23rpx;">请选择</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
</view>
</picker>
<picker @change="politicsPickerChange" :value="politicsIndex" :range="politics" range-key="name">
<view class="informationBox">
<view class="title">政治面貌</view>
<view class="btn">
<view v-if="politicsStatus" style="margin-right:23rpx;">{{politics[politicsIndex].name}}</view>
<view v-else style="margin-right:23rpx;">请选择</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
</view>
</picker>
</view>
<view class="tips">
确定后不可更改
</view>
<view class="checkbox" :class="{'active': checkedValue}" @click="change">
<img v-if="checkedValue" src="../../static/img/federation/checkOk.png" alt="" style="width: 30rpx;height:30rpx;margin-right:12rpx;">
<view v-else class="checkBoxView"></view>
我申请加入石家庄新业态职工工会联合会
</view>
<view class="nextBtn" :class="{'nextBtnActive': checkedValue}" @click="submit">
下一步
</view>
</view>
</template>
<script>
import nationPolitics from '@/common/nationPolitics.js'
import {setInfo} from '@/api/federation.js'
import {
mapGetters
} from 'vuex'
export default{
data () {
return {
nation: nationPolitics.nation,
politics: nationPolitics.politics,
checkedValue: false,
nationStatus: false,
politicsStatus: false,
status: false,
nationIndex: 0,
politicsIndex: 0,
}
},
filters:{
sex(number){
if (number === 1) {
return '男'
} else
if (number === 2) {
return '女'
}
}
},
onShow() {
var that = this
this.$store.dispatch('refreshAuthState').then(e => {
if(that.authInfo.nation && that.authInfo.politics) {
that.status = true
that.nationStatus = true
that.politicsStatus = true
that.checkedValue = true
}
})
},
methods:{
submit(){
if(!this.checkedValue) {
uni.showToast({
title: '请先勾选申请加入石家庄新业态职工工会联合会',
icon: 'none'
})
return
}
if (!this.nationStatus || !this.politicsStatus) {
uni.showToast({
title: '请先填写完整信息',
icon: 'none'
})
return
}
if(this.status) {
this.go('/pageMy/federation/forMembership/forBook')
return
}
var params = {
nation: this.nation[this.nationIndex].name,
politics: this.politics[this.politicsIndex].name
}
setInfo(params).then(res =>{
this.go('/pageMy/federation/forMembership/forBook')
})
},
nationPickerChange(e){
this.nationStatus = true
this.nationIndex = e.target.value
},
politicsPickerChange(e){
this.politicsStatus = true
this.politicsIndex = e.target.value
},
change(){
this.checkedValue = !this.checkedValue
},
go(url) {
uni.navigateTo({
url
})
}
},
computed: {
...mapGetters(['auth', 'authInfo'])
}
}
</script>
<style lang="scss">
.active{
color: #333333 !important;
}
.nextBtnActive{
opacity: 1 !important;
}
.nextBtn{
margin: 50rpx 30rpx;
height: 80rpx;
background: #1B66FF;
opacity: 0.5;
border-radius: 8rpx;
font-size: 30rpx;
font-weight: 400;
color: #FFFFFF;
line-height: 80rpx;
text-align: center;
}
.checkbox{
font-size: 28rpx;
font-weight: 400;
color: #999999;
margin: 0 30rpx;
display: flex;
align-items: center;
.checkBoxView{
width: 26rpx;
height: 26rpx;
border-radius: 50%;
border: 2rpx solid #999999;
margin-right:12rpx;
}
}
.tips{
font-size: 26rpx;
font-weight: 400;
color: #1B66FF;
line-height: 46rpx;
margin: 60rpx 0 20rpx 30rpx;
}
.informationWrap{
padding: 0 30rpx;
.informationBox{
height: 32rpx;
background: #FEFEFE;
padding: 64rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom:1px solid #F2F2F2;
.title{
font-size: 32rpx;
font-weight: 400;
color: #333333;
}
.btn{
display: flex;
align-items: center;
font-size: 28rpx;
font-weight: 400;
color: #1B66FF;
image {
width: 19rpx;
height: 32rpx;
margin-top: 4rpx;
}
}
.btnGray{
color: #999999 !important;
}
}
}
.vip{
height: 138px;
margin: 20rpx;
background: url('../../static/img/federation/icon.png') no-repeat;
background-size: cover;
font-size: 32rpx;
font-weight: 400;
color: #FFFFFF;
.body{
padding: 59rpx 49rpx;
.name{
display: flex;
justify-content: space-between;
}
.Gender{
margin-right: 30px;
}
.idcard{
margin: 20rpx 0;
}
}
}
</style>

View File

@@ -0,0 +1,167 @@
<template>
<view class="informationWrap">
<view class="informationBox">
<view class="title">会员编号</view>
<view class="content">{{labourUnion.no}}</view>
</view>
<view class="informationBox">
<view class="title">入会日期</view>
<view class="content">{{dateFormat(labourUnion.createTime)}}</view>
</view>
<view class="informationBox">
<view class="title">入会申请书</view>
<view class="lookbtn" @click="status(true)">
<view>查看</view>
<image src="../../../static/img/right.svg" mode="" style="width: 19rpx;height: 32rpx;margin-left: 20rpx;margin-top: 4rpx;"></image>
</view>
</view>
<uniMask :maskShow="maskShow">
<view class="informationMask">
<view class="close" @click="status(false)">+</view>
<view class="bookBox">
<view class="title">入会申请书</view>
<view class="content">{{content}}</view>
<view class="time people">申请人{{authInfo.realName}}</view>
<view class="time dayYear">
<view class="">日期<i></i></view>
<view class="">{{dateFormat(labourUnion.createTime, 'yyyy年MM月dd日')}}</view>
</view>
</view>
<!-- <image :src="labourUnion.contractUrl" class="img"></image> -->
</view>
</uniMask>
</view>
</template>
<script>
import {
mapGetters
} from 'vuex'
import uniMask from '@/components/uni-mask/mask.vue'
import {labourUnionInfo} from '@/api/federation.js'
import {dateFormat} from '@/untils/format.js'
export default{
data(){
return {
maskShow: false,
labourUnion: {},
content: '我自愿加入石家庄新业态职工工会联合会,遵守工会章程,执行工会决议,积极参加工会活动,为把我国建设成为富强、民主、文明的社会主义国家而努力奋斗。'
}
},
components:{uniMask},
onLoad() {
this.labourUnionInfoInit()
},
methods: {
dateFormat,
status(status){
this.maskShow = status
},
labourUnionInfoInit(){
labourUnionInfo().then(e=>{
this.labourUnion = e.data.data
})
},
},
computed: {
...mapGetters(['authInfo'])
}
}
</script>
<style lang="scss">
.bookBox{
height: 691rpx;
background: #FFFFFF;
margin: 53rpx 30rpx;
padding: 60rpx 30rpx 0 30rpx;
position: relative;
.title{
font-size: 40rpx;
font-weight: 500;
color: #333333;
line-height: 56rpx;
text-align: center;
margin-bottom: 47rpx;
}
.content{
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 50rpx;
text-indent:2em;
}
.people{
position: absolute;
bottom: 203rpx;
left: 250rpx;
}
.dayYear{
position: absolute;
bottom: 128rpx;
left: 250rpx;
display: flex;
align-items: center;
}
.time{
font-size: 32rpx;
font-weight: 500;
color: #333333;
line-height: 45rpx;
}
}
.informationMask{
width: 690rpx;
// height: 750rpx;
background: #FFFFFF;
border-radius: 4rpx;
margin: 0 auto;
margin-top: 30%;
position: relative;
.close{
width: 23px;
height: 23px;
color: #1B66FF;
position: fixed;
right: 60rpx;
transform: rotate(45deg);
font-size: 40px;
z-index: 9999;
}
.img{
width: 690rpx;
height: 1040rpx;
}
}
.informationWrap{
padding: 0 30rpx;
}
.informationBox{
height: 32rpx;
background: #FEFEFE;
padding: 64rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom:1px solid #F2F2F2;
}
.title{
height: 36rpx;
font-size: 32rpx;
font-weight: 400;
color: #333333;
}
.content{
height: 32rpx;
font-size: 28rpx;
font-weight: 400;
color: #999999;
}
.lookbtn{
display: flex;
font-size: 28rpx;
font-weight: 400;
color: #1B66FF;
}
</style>

View File

@@ -0,0 +1,18 @@
<template>
<view>
<image class="img" src="../static/img/help/auth.jpg"></image>
</view>
</template>
<script>
</script>
<style>
page{
background-color: #1B66FF;
}
.img{
width: 100%;
height: 1379rpx;
}
</style>

51
pageMy/help/help.vue Normal file
View File

@@ -0,0 +1,51 @@
<template>
<view class="body">
<view class="helpList" @click="go('./passWord')">
如何修改密码?
</view>
<view class="helpList" @click="go('./phone')">
如何修改手机号
</view>
<view class="helpList" @click="go('./userInfo')">
个人如何完善信息
</view>
<view class="helpList" @click="go('./authentication')">
实名认证时提示认证信息不匹配
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
go(url){
uni.navigateTo({
url
})
}
}
}
</script>
<style>
.helpList{
padding: 30rpx;
padding-left: 0;
border-bottom: 1rpx solid #ddd;
font-family: PingFangSC-Regular;
font-size: 30rpx;
color: #333333;
padding: 30rpx 0;
}
.body{
background-color: #fefefe;
margin-top: 20rpx;
padding-left: 30rpx;
}
page{background-color: #f6f6f6;}
</style>

18
pageMy/help/passWord.vue Normal file
View File

@@ -0,0 +1,18 @@
<template>
<view>
<image class="img" src="../static/img/help/password.jpg"></image>
</view>
</template>
<script>
</script>
<style>
page{
background-color: #1B66FF;
}
.img{
width: 100%;
height: 1960rpx;
}
</style>

18
pageMy/help/phone.vue Normal file
View File

@@ -0,0 +1,18 @@
<template>
<view>
<image class="img" src="../static/img/help/phone.jpg"></image>
</view>
</template>
<script>
</script>
<style>
page{
background-color: #1B66FF;
}
.img{
width: 100%;
height: 1379rpx;
}
</style>

View File

@@ -0,0 +1,32 @@
<template>
<view class="question-detail" v-html="text">
</view>
</template>
<script>
import {questionDetail} from '@/api/newIndex.js'
export default {
onLoad(option) {
if(option.id){
questionDetail(option.id).then(res => {
this.text=res.data.data.records[0].content
})
}
},
data() {
return {
text:''
}
}
}
</script>
<style>
.question-detail{
width: 690rpx;
height: auto;
margin: 0 auto;
padding-top: 6rpx;
overflow: auto;
}
</style>

View File

@@ -0,0 +1,145 @@
<template>
<view class="question-body">
<view class="nothing" v-if="questionList.length === 0">
<image src="/static/img/pic.svg" mode=""></image>
<view class="nothingText">
暂无常见问题
</view>
</view>
<view class="questionItem" v-for="(item,index) in questionList" :key="index" @click="goQuestionDetail(item.id)">
<view class="questionTitle">
{{item.title}}
</view>
<view class="">
<image src="/static/img/right.svg" mode="" style="width: 19rpx;height: 32rpx;"></image>
</view>
</view>
</view>
</template>
<script>
import {getQuestionList} from '@/api/newIndex.js'
export default {
data() {
return {
questionList:[],
current: 1,
size: 20,
total: 0
}
},
mounted() {
this.initQuestionList()
},
methods: {
/*页面滚动到底部 换页*/
onReachBottom: function() {
if (this.questionList.length >= this.total) {
uni.showToast({
title: '到底了',
icon: 'none'
})
return
}
this.initQuestionList()
},
/*下拉刷新*/
onPullDownRefresh: function() {
this.current = 1
this.questionList = []
this.initQuestionList()
},
goQuestionDetail(data){
uni.navigateTo({
url:`/pageMy/help/questions/questionDetail?id=${data}`
})
},
initQuestionList(){
uni.showLoading({
title:'请求中'
})
getQuestionList(
"",
"",
"",
this.current,
this.size
).then(e=>{
this.current++
this.questionList = [...this.questionList, ...e.data.data.records]
this.total = e.data.data.total
uni.hideLoading()
uni.stopPullDownRefresh();
}).catch(err => {
uni.hideLoading()
uni.stopPullDownRefresh();
})
}
}
}
</script>
<style>
.nothingText {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
text-align: center;
margin-top: 20rpx;
}
.nothing image {
width: 400rpx;
height: 200rpx;
display: block;
padding-top: 50%;
margin: 0 auto;
}
.nothing {
width: 100%;
height: 100vh;
background-color: #fefefe;
}
.questionItem{
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
height: 110rpx;
line-height: 110rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.question-body{
background-color: #fefefe;
margin-top: 20rpx;
padding:0 30rpx;
}
.questionTitle{
color: #333333;
}
.questionContent{
display: flex;
justify-content: start;
align-items: center;
font-size: 26rpx;
}
.contentText{
color: #7F7F7F;
width: 600rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.toQuestionDetail{
color: #02A7F0;
cursor: pointer;
width: 60rpx;
text-align: center;
}
page{background-color: #f6f6f6;}
</style>

18
pageMy/help/userInfo.vue Normal file
View File

@@ -0,0 +1,18 @@
<template>
<view>
<image class="img" src="../static/img/help/userInfo.jpg"></image>
</view>
</template>
<script>
</script>
<style>
page{
background-color: #1B66FF;
}
.img{
width: 100%;
height: 1379rpx;
}
</style>

View File

@@ -0,0 +1,107 @@
<template>
<view class="change-password-body">
<view class="nothing" style="height: 200rpx;"></view>
<jl-input type="text" v-model="oldPassword" placeholder="请输入旧密码" showPassword clearable></jl-input>
<jl-input type="text" v-model="newPassword" placeholder="设置长度6至20位的密码" showPassword clearable></jl-input>
<jl-input type="text" v-model="newPassword1" placeholder="请重新输入新密码" showPassword clearable></jl-input>
<view class="btn" v-if='loading'>
正在修改...
</view>
<view class="btn" v-else-if="validate" @click="submit">
确认修改
</view>
<view class="btn nocheck" v-else>
确认修改
</view>
</view>
</template>
<script>
import {
changePassword
} from '@/api/changePassword.js'
import {
password
} from '@/untils/validate.js'
import jlInput from '@/components/jl-input/main.vue'
import md5 from 'js-md5'
const resendTime = 120
export default {
components: {
jlInput
},
data() {
return {
loading: false,
oldPassword: '',
newPassword: '',
newPassword1: ''
}
},
methods: {
submit() {
if(password(this.newPassword)) {
uni.showToast({
title: '请设置长度6至20位的密码',
icon: 'none'
});
return
}
if (this.newPassword1 !== this.newPassword) {
uni.showToast({
title: '两次输入的新密码不一致',
icon: 'none'
});
return
}
this.loading = true
changePassword(md5(this.oldPassword), md5(this.newPassword), md5(this.newPassword1)).then(() => {
uni.navigateBack();
uni.showToast({
title: '操作成功',
icon: 'none'
});
}).catch(() => {
this.loading = false
})
}
},
computed: {
validate() {
return this.newPassword && this.oldPassword && this.newPassword1
}
}
}
</script>
<style>
.phoneDel {
margin-left: auto !important;
}
.nocheck {
opacity: 0.3;
}
.btn {
margin: 0 auto;
margin-top: 50rpx;
background-color: #1B66FF;
color: #fefefe;
border-radius: 10rpx;
text-align: center;
font-size: 32rpx;
height: 80rpx;
line-height: 80rpx;
}
page {
background-color: #fefefe;
}
.change-password-body{
width: 80%;
margin: 0 auto;
}
</style>

155
pageMy/my/changePhone.vue Normal file
View File

@@ -0,0 +1,155 @@
<template>
<view class="change-phone-body">
<view class="nothing" style="height: 200rpx;"></view>
<jl-input type="text" v-model="password" placeholder="请输入登录密码" showPassword clearable></jl-input>
<jl-input type="number" v-model="phone" placeholder="请输入新手机号"></jl-input>
<jl-input type="text" v-model="sms" placeholder="请输入验证码">
<view v-if="isMobile(phone) && password" class="code" @click="getCode">{{ code }}</view>
<view v-else class="code nocheck">{{ code }}</view>
</jl-input>
<view class="btn nocheck" v-if='loading'>
正在变更...
</view>
<view class="btn" v-else-if='sms && isMobile(phone) && password' @click="submit">
确认变更
</view>
<view class="btn nocheck" v-else>
确认变更
</view>
</view>
</template>
<script>
import {
changePhone,
sendValidate
} from '@/api/changePhone.js'
import {
isMobile
} from '@/untils/validate.js'
import jlInput from '@/components/jl-input/main.vue'
import md5 from 'js-md5'
const resendTime = 120
export default {
components: {
jlInput
},
data() {
return {
loading: false,
pastype: 'text',
code: '获取验证码',
password: '',
phone: '',
sms: ''
}
},
methods: {
changePasType: function() {
var pastype = this.pastype;
if (pastype == 'password') {
this.pastype = 'text';
} else {
this.pastype = 'password'
}
},
delpho: function(e) {
this.phone = '';
},
delpas: function(e) {
this.password = '';
},
setsms: function(e) {
this.sms = e.detail.value
},
setpho: function(e) {
this.phone = e.detail.value
},
setpas: function(e) {
this.password = e.detail.value
},
getCode: function() {
var code = this.code;
if (code != '获取验证码' && code != '重新发送') {
return;
}
this.code = '发送中...'
sendValidate(this.phone, md5(this.password)).then(() => {
let sendCode = setInterval(() => {
if (code == '获取验证码' || code == '重新发送') {
code = resendTime;
}
code--;
var codes = '重新发送(' + code + 's)';
this.code = codes;
if (code <= 0) {
code = '重新发送';
this.code = code;
clearInterval(sendCode);
return;
}
}, 1000)
}).catch(() => {
this.code = '重新发送';
})
},
isMobile,
submit() {
this.loading = true
changePhone(this.phone, md5(this.password), this.sms).then(() => {
this.loading = false
this.$store.dispatch('LogOut').then(() => {
this.$store.dispatch('clearAuthState')
this.$store.dispatch('endRefreshNewsTimer')
uni.reLaunch({
url: '/pages/login/login'
})
})
}).catch(() => {
this.loading = false
})
}
},
computed: {}
}
</script>
<style>
.phoneDel {
margin-left: auto !important;
}
.nocheck {
opacity: 0.3;
}
.btn {
margin: 0 auto;
margin-top: 50rpx;
background-color: #1B66FF;
color: #fefefe;
border-radius: 10rpx;
text-align: center;
font-size: 32rpx;
height: 80rpx;
line-height: 80rpx;
}
.code {
margin-left: auto;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #1b66ff;
text-align: center;
}
page {
background-color: #fefefe;
}
.change-phone-body {
width: 80%;
margin: 0 auto;
}
</style>

View File

@@ -0,0 +1,48 @@
<template>
<select-template ref="select" title="请选择行业" slo="请选择行业,帮你定制个性化推荐任务信息" :list="skillLevel" @submit="goAdd"></select-template>
</template>
<script>
import {
getTrade
} from '@/api/resume.js'
import selectTemplate from './selectTemplate.vue'
export default {
components: {
selectTemplate
},
data() {
return {
id: "",
skillLevel: [],
}
},
// 在test.vue页面接受参数
onLoad: function({
id
}) {
this.id = id
},
onShow: function() {
this.getData()
},
mounted() {
this.$refs.select.setActiveId(this.tradeId)
},
methods: {
getData: function() {
getTrade().then(res => {
this.skillLevel = res.data.data
})
},
goAdd(res) {
uni.$emit('setInd', res)
uni.navigateBack()
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,297 @@
<template>
<view style="background-color: #fefefe;">
<view class="titles">
添加职业技能
</view>
<view class="slo">
添加职业技能获得个性化的职位推荐
</view>
<view class="jobcontent" @click="goAddind">
<view class="jobinfo">
<view class="jobAddress">
我从事的行业
</view>
<view v-if="tradeName" class="jobText">{{tradeName}}</view>
<view v-else class="jobText nochoose">请选择</view>
</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
<view class="border"></view>
<view class="jobcontent" @click="skill">
<view class="jobinfo">
<view class="jobAddress">
我具备的技能
</view>
<view v-if="worktypesName" class="jobText">{{worktypesName}}</view>
<view v-else class="jobText nochoose">请选择</view>
</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
<view class="border"></view>
<view class="jobcontent" @click="skillLevel">
<view class="jobinfo">
<view class="jobAddress">
我的技能水平
</view>
<view v-if="skillsName" class="jobText">{{skillsName}}</view>
<view v-else class="jobText nochoose">请选择</view>
</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
<view class="border"></view>
<view class="btn">
<view v-if="skillsId " class="bottombtn" @click="submit">确定</view>
<view v-else class="bottombtn disabledBtn">确定</view>
</view>
</view>
</template>
<script>
import {
addSkills
} from '@/api/resume.js'
export default {
data() {
return {
tradeId: '',
tradeName: '',
worktypesId: '',
worktypesName: '',
skillsId: '',
skillsName: '',
}
},
onLoad(query) {
uni.$off('setInd')
uni.$on('setInd', ({
id,
name
}) => {
this.tradeId = id
this.tradeName = name
this.worktypesId = ''
this.worktypesName = ''
this.skillsId = ''
this.skillsName = ''
})
uni.$off('setworkTypes')
uni.$on('setworkTypes', ({
id,
name
}) => {
this.worktypesId = id
this.worktypesName = name
this.skillsId = ''
this.skillsName = ''
})
uni.$off('setSkill')
uni.$on('setSkill', ({
id,
name
}) => {
this.skillsId = id
this.skillsName = name
})
},
methods: {
goAddind: function() {
uni.navigateTo({
url: './addInd?id=' + this.tradeId
})
},
skill: function() {
if (this.tradeId) {
uni.navigateTo({
url: `./skill?id=${this.worktypesId}&tradeId=${this.tradeId}`
})
} else {
uni.showToast({
title: '请先选择从事的行业',
icon: 'none'
});
}
},
skillLevel: function() {
if (!this.tradeId) {
uni.showToast({
title: '请先选择从事的行业',
icon: 'none'
});
} else if (!this.worktypesId) {
uni.showToast({
title: '请先选择具备的技能',
icon: 'none'
});
} else {
uni.navigateTo({
url: `./skillLevel?id=${this.skillsId}&worktypesId=${this.worktypesId}`
})
}
},
submit: function() {
addSkills(this.tradeName, this.worktypesName, this.skillsName).then(res => {
uni.navigateBack()
})
}
}
}
</script>
<style>
.slo {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
padding: 0 30rpx;
padding-top: 10rpx;
}
.titles {
font-family: PingFangSC-Medium;
font-size: 36rpx;
color: #333333;
padding: 0 30rpx;
padding-top: 30rpx;
}
.border {
margin-left: 30rpx;
width: 720rpx;
border-bottom: 2rpx solid #ddd;
opacity: 0.6;
}
.jobText {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666666;
}
.nochoose {
color: #ccc;
}
.jobAddress {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #999999;
}
.jobcontent {
padding: 30rpx;
background: #fefefe;
display: flex;
/* align-items: center; */
align-items: flex-end;
justify-content: space-between;
line-height: 63rpx;
}
.jobcontent image {
width: 40rpx;
height: 40rpx;
margin-bottom: 5px;
}
.listBody {}
.list_text {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666666;
}
.list image {
width: 40rpx;
height: 40rpx;
margin-left: auto;
}
.list {
padding: 0 30rpx;
height: 126rpx;
background: #fefefe;
display: flex;
align-items: center;
justify-content: space-between;
}
.title image {
width: 40rpx;
height: 40rpx;
}
.title {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
display: flex;
padding: 10rpx 30rpx;
background-color: #fefefe;
align-items: center;
justify-content: space-between;
}
.userInfo {
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #999999;
}
.name {
margin-left: 20rpx;
font-family: PingFangSC-Medium;
font-size: 36rpx;
color: #333333;
line-height: 50rpx;
}
.head image:last-child {
width: 40rpx;
height: 40rpx;
margin-left: auto;
}
.head image {
width: 100rpx;
height: 100rpx;
}
.head {
padding: 30rpx;
width: 690rpx;
background-color: #fefefe;
display: flex;
align-items: center;
justify-content: flex-start;
}
.bottombtn {
background-color: #1b66ff;
color: #fff;
text-align: center;
border-radius: 10rpx;
font-family: PingFangSC-Medium;
font-size: 32rpx;
height: 90rpx;
line-height: 90rpx;
}
.btn {
background-color: #fefefe;
width: 690rpx;
padding: 30rpx;
padding-bottom: 80rpx;
position: fixed;
bottom: 0;
left: 0;
}
.disabledBtn {
background-color: #c8c9cc;
}
</style>

299
pageMy/my/resume/index.vue Normal file
View File

@@ -0,0 +1,299 @@
<template>
<view style="background-color: #fff;">
<view class="head" @click="goUserBase">
<image v-if="userInfo.avatar" :src="userInfo.avatar" mode=""></image>
<image v-else src="../../../static/img/head.svg" mode=""></image>
<view class="name">
<view class="userName">
{{auth.authInfo.realName}}
</view>
<view class="userInfo">
个人基本信息
</view>
</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
<view class="title">
<view class="title_text">
我的职业技能
</view>
<image v-if="mySkills.length<10" src="../../../static/img/add.gray.svg" mode="" @click="goAdd"></image>
</view>
<view class="listBody">
<m-slide-list @controller-reg="controller.reg" @controller-moving="controller.moving" @controller-opened="controller.opened"
@controller-closed="controller.closed" @remove="removeSkills(item.id,index)" v-for="(item,index) in mySkills" :key="item.id"
:button="buttonList">
<view class="list">
<view class="list_text">
{{item.trade}}·{{item.worktypes}}·{{item.skills}}
</view>
</view>
</m-slide-list>
</view>
<view class="jobcontent" @click="goSetCity">
<view class="jobinfo">
<view class="jobAddress">
您想工作的地点
</view>
<view v-bind:class="['jobText',{nochoose: !myResume.cityId}]">
{{myResume.cityId ? getCity(myResume.cityId) : '请选择'}}
</view>
</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>
<view class="border"></view>
<!--<view class="jobcontent" @click="goWantSkill">
<view class="jobinfo">
<view class="jobAddress">
我想学习的技能选填
</view>
<view class="jobText" v-bind:class="myResume.learnSkill?'':'nochoose'">
{{myResume.learnSkill?myResume.learnSkill:'请填写'}}
</view>
</view>
<image src="../../../static/img/right.svg" mode=""></image>
</view>-->
</view>
</template>
<script>
import {
mapGetters
} from 'vuex'
import {
mySkills,
myResume,
removeSkills,
setCity,
setLearn
} from '@/api/resume.js';
import mSlideList from '@/components/mark-slide-list/mark-slide-list.vue';
import controller from '@/components/mark-slide-list/controller';
export default {
components: {
mSlideList
},
data() {
return {
controller: new controller(),
myResume: {},
mySkills: [],
id: '',
buttonList: [{
title: '删除',
background: '#ff3b32',
clickName: 'remove'
}]
}
},
onShow() {
this.getResume()
this.getSkill()
},
computed: {
...mapGetters(['userInfo', 'auth'])
},
methods: {
getResume() {
myResume().then(res => {
const data = res.data.data
this.myResume = data
if (data && data.id) {
this.id = data.id
}
});
},
getSkill() {
mySkills().then(res => {
this.mySkills = res.data.data;
})
},
goWantSkill: function() {
uni.$off('getWantSkill')
uni.$once('getWantSkill', (cb) => {
cb(this.myResume.learnSkill)
})
uni.$off('setWantSkill')
uni.$once('setWantSkill', ({
skill,
done
}) => {
setLearn(this.id, skill).then(res => {
uni.navigateBack()
}).catch(() => {
done && done()
})
this.getResume()
})
uni.navigateTo({
url: './setWskill?id=' + this.id
})
},
goSetCity: function() {
uni.$off('setCity')
uni.$on('setCity', (id) => {
setCity(this.id, id).then(res => {
this.myResume.cityId = id
this.getResume()
})
})
uni.navigateTo({
url: `/pages/setCity/setCity?maxLayer=2`
})
},
goAdd: function() {
uni.navigateTo({
url: './addSkill'
})
},
goUserBase: function() {
uni.navigateTo({
url: '../userBase'
})
},
getCity: function(val) {
if (val) {
let areas = this.$store.getters.getAreaParents(val)
if (areas.length) {
return areas[0].label + '-' + areas[1].label
}
}
},
removeSkills: function(id, index) {
removeSkills(id).then(res => {
uni.showToast({
title: '操作成功',
icon: 'none'
});
this.mySkills.splice(index, 1)
})
}
}
}
</script>
<style>
.border {
margin-left: 30rpx;
width: 720rpx;
border: 1rpx solid #f2f2f2;
/* height: 1rpx;
background-color: #ddd; */
}
.jobText {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666666;
}
.jobAddress {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
}
.nochoose {
color: #ccc;
}
.jobcontent {
padding: 30rpx;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
line-height: 63rpx;
}
.jobcontent image {
width: 40rpx;
height: 40rpx;
}
.listBody {}
.list_text {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666666;
background: #ffffff;
overflow-y: auto;
white-space: nowrap;
}
.list image {
width: 40rpx;
height: 40rpx;
margin-left: auto;
}
.list {
padding: 0 15px 0 30rpx;
height: 126rpx;
line-height: 126rpx;
background: #fff;
border-bottom: 1px solid #f2f2f2;
}
.title image {
width: 40rpx;
height: 40rpx;
}
.title {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
display: flex;
padding: 25rpx 30rpx;
/* padding-top: 30rpx; */
background-color: #fff;
align-items: center;
justify-content: space-between;
border: 1rpx solid #f2f2f2;
}
.userInfo {
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #999999;
}
.name {
margin-left: 20rpx;
font-family: PingFangSC-Medium;
font-size: 36rpx;
color: #333333;
line-height: 50rpx;
}
.head image:last-child {
width: 40rpx;
height: 40rpx;
margin-left: auto;
}
.head image {
width: 100rpx;
height: 100rpx;
}
page {
background-color: #f6f6f6;
}
.head {
padding: 30rpx;
width: 690rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: flex-start;
}
</style>

View File

@@ -0,0 +1,370 @@
<template>
<view class="select-template">
<view class="select-template-head">
<view class="titles">
{{title}}
</view>
<view class="slo">
{{slo}}
</view>
<view class="seach" v-if="search">
<image class="seach-image" src="../../../static/img/search.svg" mode=""></image>
<input type="text" v-model="inputValue" placeholder="请输入技能名称" placeholder-style="color:#ccc" />
</view>
<view class="borderbotom" v-if="search"></view>
<view class="scroll-view" v-if="searchShow" :style="{top:height}">
<ul class="search-result">
<li class="search-result-list" v-for="(item,index) in searchResultList" :key="index" @click="handlerSelect(item)">
<div class="search-result-list-title">
<rich-text :nodes="getInf(item)"></rich-text>
</div>
</li>
</ul>
</view>
</view>
<view :style="{height}"></view>
<view class="levelbody" v-if="!searchShow">
<block v-for="(item,index) in list" :key="index">
<view v-bind:class="['levellist', {checked:item[prop.key] === activeId}]" @click="chooseLev(item)">
{{item[prop.name]}}
</view>
</block>
</view>
<view class="bottom"></view>
<view class="btn">
<view v-if="activeId" class="bottombtn" @click="submit">确定</view>
<view v-else class="bottombtn disabledBtn">确定</view>
</view>
</view>
</template>
<script>
export default {
props: {
search: Boolean,
title: String,
slo: String,
list: Array,
prop: {
type: Object,
default () {
return {
name: 'name',
key: 'id'
}
}
}
},
data() {
return {
height: '0px',
inputValue: '',
activeName: '',
activeId: '',
searchShow: false,
}
},
// 在test.vue页面接受参数
onLoad: function({
id
}) {
this.activeId = id
},
mounted() {
uni.createSelectorQuery().in(this).select('.select-template-head').boundingClientRect().exec((node) => {
this.height = node[0].height + 'px'
});
},
computed: {
searchResultList() {
const prop = this.prop
if (this.inputValue && this.searchShow) {
return this.list.filter(item => {
return item[prop.name].indexOf(this.inputValue) !== -1
})
} else {
return undefined
}
}
},
methods: {
getInf(item) {
const key = this.inputValue
const str = item[this.prop.name]
let replaceReg = new RegExp(key, 'g') // 匹配关键字正则
let replaceString = "<span style='color: #1b66ff;'>" + key + "</span>" // 高亮替换
return str.replace(replaceReg, replaceString);
},
setActiveId(id) {
this.activeId = id
},
chooseLev(item) {
const prop = this.prop
this.activeId = item[prop.key]
this.activeName = item[prop.name]
},
handlerSelect(item) {
this.searchShow = false
this.chooseLev(item)
},
submit() {
this.$emit('submit', {
id: this.activeId,
name: this.activeName
})
}
},
watch: {
inputValue(val) {
this.searchShow = !!val
}
}
}
</script>
<style scoped>
.select-template {
background-color: #fefefe;
}
.select-template-head {
background-color: #fefefe;
position: fixed;
width: 100%;
top: 0;
}
/*搜索结果*/
.scroll-view {
width: 100%;
flex: 1;
position: fixed;
bottom: 0;
left: 0;
}
.search-result {
background-color: #fff;
padding: 0rpx;
}
.search-result-list {
font-weight: normal;
text-align: left;
border-bottom: 1rpx solid #f2f2f2;
padding: 28rpx 30rpx;
list-style: none;
}
.search-result-list-title {
font-size: 32rpx;
color: #333333;
}
.highlight {
color: #1b66ff;
}
.borderbotom {
width: 720rpx;
margin-left: 30rpx;
border-bottom: 2rpx solid #ddd;
}
.seach-image {
width: 32rpx;
height: 32rpx;
margin-right: 15rpx;
}
.seach {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 30rpx;
}
.levellist.checked {
color: #1B66FF !important;
border: 1rpx solid #1B66FF;
background: rgba(77, 136, 255, 0.10) !important;
}
.levellist {
background: #f6f6f6;
border: 1rpx solid #f6f6f6;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
text-align: center;
margin-right: 15rpx;
padding: 10rpx 15rpx;
border-radius: 5rpx;
margin: 0 30rpx;
margin-top: 25rpx;
}
.levelbody {
padding: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.bottom {
height: 200rpx;
}
.bottombtn {
background-color: #1b66ff;
color: #fff;
text-align: center;
border-radius: 10rpx;
font-family: PingFangSC-Medium;
font-size: 32rpx;
height: 90rpx;
line-height: 90rpx;
}
.disabledBtn {
background-color: #c8c9cc;
}
.btn {
background-color: #fefefe;
width: 690rpx;
padding: 30rpx;
padding-bottom: 80rpx;
position: fixed;
bottom: 0;
left: 0;
}
.slo {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
padding: 0 30rpx;
padding-top: 10rpx;
}
.titles {
font-family: PingFangSC-Medium;
font-size: 40rpx;
color: #333333;
font-weight: bold;
padding: 0 30rpx;
padding-top: 30rpx;
}
.border {
margin-left: 30rpx;
width: 720rpx;
border-bottom: 2rpx solid #ddd;
opacity: 0.6;
}
.jobText {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666666;
}
.jobAddress {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
}
.jobcontent {
padding: 30rpx;
background: #fefefe;
display: flex;
align-items: center;
justify-content: space-between;
line-height: 63rpx;
}
.jobcontent image {
width: 40rpx;
height: 40rpx;
}
.listBody {}
.list_text {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666666;
}
.list image {
width: 40rpx;
height: 40rpx;
margin-left: auto;
}
.list {
padding: 0 30rpx;
height: 126rpx;
background: #fefefe;
display: flex;
align-items: center;
justify-content: space-between;
}
.title image {
width: 40rpx;
height: 40rpx;
}
.title {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
display: flex;
padding: 10rpx 30rpx;
background-color: #fefefe;
align-items: center;
justify-content: space-between;
}
.userInfo {
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #999999;
}
.name {
margin-left: 20rpx;
font-family: PingFangSC-Medium;
font-size: 36rpx;
color: #333333;
line-height: 50rpx;
}
.head image:last-child {
width: 40rpx;
height: 40rpx;
margin-left: auto;
}
.head image {
width: 100rpx;
height: 100rpx;
}
.head {
padding: 30rpx;
width: 690rpx;
background-color: #fefefe;
display: flex;
align-items: center;
justify-content: flex-start;
}
</style>

View File

@@ -0,0 +1,133 @@
<template>
<view>
<view class="noComment">
<view class="textview">
<textarea v-model.trim="skill" placeholder="请输入18字以内" placeholder-class="textClass" maxlength="18" />
</view>
<view class="btn" v-if="btnShow">
<view class="bottombtn" @click="sendCom">确认</view>
<!-- <view v-else class="bottombtn disabledBtn">确认</view> -->
</view>
</view>
</view>
</template>
<script>
import{mySkills} from '@/api/resume.js';
import {submitApplication} from '@/api/newIndex.js'
import {mapGetters} from 'vuex'
export default {
data() {
return {
skill:'',
submitType:2,//申请类型1 法律咨询 2技能提升
btnShow:true,
}
},
onLoad(option) {
if(option.data && option.type){
this.skill=decodeURIComponent(option.data);
this.btnShow=false;
}
},
computed:{
...mapGetters(['authInfo'])
},
methods: {
settext:function(e){
this.skill = e.detail.value;
},
getWantSkill(){
mySkills().then(res=>{
console.log(res,'skill')
})
},
sendCom:function(){
if(!this.skill){
uni.showToast({
icon:'none',
title:'请输入想学习的技能',
duration:3000
})
return;
}
uni.showLoading({
title:'请求中'
})
let uid=this.authInfo.userId;
let uname=this.authInfo.realName;
let tel=this.authInfo.telphone;
submitApplication(uid,uname,tel,this.submitType,this.skill).then(res=>{
this.loading=false;
uni.hideLoading()
setTimeout(() => {
uni.showToast({
title: '提交成功',
icon: 'none'
});
}, 1000)
uni.switchTab({
url:'/pages/index/index'
})
})
}
}
}
</script>
<style>
.bottombtn {
background-color: #1b66ff;
color: #fff;
text-align: center;
border-radius: 10rpx;
font-family: PingFangSC-Medium;
font-size: 32rpx;
height: 90rpx;
line-height: 90rpx;
}
.disabledBtn {
background-color: #c8c9cc;
}
.btn {
background-color: #fefefe;
width: 690rpx;
padding: 30rpx;
padding-bottom: 80rpx;
position: fixed;
bottom: 0;
left: 0;
}
.textview{
padding: 20rpx;
}
textarea{
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666;
}
.textClass{
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #CCCCCC;
}
.start image:first-child{
margin-left: 20rpx;
}
.start image{
width: 40rpx;
height: 40rpx;
}
.start{
padding: 20rpx;
border-bottom: 1rpx solid #f6f6f6;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
display: flex;
align-items: center;
justify-content: flex-start;
}
page{background-color: #fefefe;}
</style>

View File

@@ -0,0 +1,51 @@
<template>
<select-template ref="select" title="请选择技能" slo="请选择最符合你能力的标签,标签会帮你定制个性化推荐任务信息" :list="skillLevel" search @submit="goAdd"></select-template>
</template>
<script>
import {
getWorktypes
} from '@/api/resume.js'
import selectTemplate from './selectTemplate.vue'
export default {
components: {
selectTemplate
},
data() {
return {
skillLevel: [],
tradeId: '',
id: ''
}
},
onLoad: function({
id,
tradeId
}) {
this.tradeId = tradeId
},
onShow: function() {
this.getData()
},
mounted() {
this.$refs.select.setActiveId(this.tradeId)
},
methods: {
getData: function() {
if (this.tradeId) {
getWorktypes(this.tradeId).then(res => {
this.skillLevel = res.data.data
})
}
},
goAdd(res) {
uni.$emit('setworkTypes', res)
uni.navigateBack()
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,55 @@
<template>
<select-template ref="select" title="请选择技能水平" slo="请选择最符合你能力的标签,标签会帮你定制个性化推荐任务信息" :list="skillLevel" @submit="goAdd"></select-template>
</template>
<script>
import testData from '@/common/textdata.js';
import {
getSkills
} from '@/api/resume.js'
import selectTemplate from './selectTemplate.vue'
export default {
components: {
selectTemplate
},
data() {
return {
skillLevel: [],
worktypesId: null,
activeName: '',
activeId: '',
id: ''
}
},
onLoad({
id,
worktypesId
}) {
this.id = id
this.worktypesId = worktypesId
},
onShow: function() {
this.getData()
},
mounted() {
this.$refs.select.setActiveId(this.id)
},
methods: {
getData: function() {
if (this.worktypesId) {
getSkills(this.worktypesId).then(res => {
this.skillLevel = res.data.data
})
}
},
goAdd(res) {
uni.$emit('setSkill', res)
uni.navigateBack()
},
}
}
</script>
<style>
</style>

259
pageMy/my/sala.vue Normal file
View File

@@ -0,0 +1,259 @@
<template>
<view class="body">
<!-- <v-tabs :tabs="['已发放','未发放']" height="45px" v-model="activeTab" color="#999" activeColor="#000" fontSize="36rx"
activeFontSize="36rpx" @change='changeTab' /> -->
<view class="list" v-for="item in data" :key="item.missionNo">
<view class="list_head">
<view class="list_head_left">
{{item.title}}
</view>
<!--<view class="list_head_right">
{{moneyFormat(item.wageReal)}}
</view>-->
<view class="list_head_right" v-if="item.payType === 1 || item.payType === 0">{{moneyComdify(item.wageReal)}}</view>
<view class="list_head_right" v-if="item.payType === 2">申报个税:<view class="price">{{moneyComdify(item.wageReal)}}</view></view>
</view>
<view class="allName">
{{item.companyName}}
</view>
<view class="timeBox" v-if="activeTab === 0">
<view class="time">发放日期{{dateFormat(item.accountTime,'yyyy年MM月dd日')}}</view>
<view class="list_head_right" v-if="item.payType === 1">预扣个税:<view class="price">{{moneyComdify(item.tax)}}</view></view>
<view class="list_head_right" v-if="item.payType === 2">个税补发:<view class="price">{{moneyComdify(item.tax)}}</view></view>
</view>
</view>
<view class="nothing" v-if="data.length === 0">
<image src="../../static/img/pic.svg" mode=""></image>
<view class="nothingText">
暂无工资信息
</view>
</view>
</view>
</template>
<script>
import {
getList,userOrderList
} from '@/api/wage.js'
import {
mapGetters
} from 'vuex'
import {
moneyFormat,
moneyComdify,
dateFormat
} from '@/untils/format.js'
export default {
data() {
return {
tabs: ['已发放', '未发放'],
dataDepository: [
[],
[]
],
page: [{
current: 0,
size: 20,
maxPage: 1,
loading: false,
status: 1
}, {
current: 0,
size: 20,
maxPage: 1,
loading: false,
status: 0
}],
activeTab: 0,
}
},
created() {
this.getData()
},
onReachBottom() {
this.getData()
},
/*页面滚动到底部 换页*/
onReachBottom: function() {
const page = this.page[this.activeTab]
const activeTab = this.activeTab
const current = page.current + 1
if (page.current <= Math.ceil(page.maxPage / page.size)) {
this.getData();
} else {
uni.showToast({
icon: "none",
title: '已经是最后一页',
})
}
},
/*下拉刷新*/
onPullDownRefresh:function(){
const page = this.page[this.activeTab]
page.current = 0
this.dataDepository[this.activeTab] = []
this.getData()
},
methods: {
changeTab: function(e) {
this.activeTab = e;
},
getData() {
const page = this.page[this.activeTab]
const activeTab = this.activeTab
const current = page.current + 1
if (page.loading || current > page.maxPage) {
return
}
page.loading = true
/* getList(this.userInfo.user_id, current, page.size, page.status).then((resp) => {
uni.stopPullDownRefresh();
const data = resp.data.data
this.$set(this.dataDepository, activeTab, this.dataDepository[activeTab].concat(data.records))
page.maxPage = parseInt(data.total / data.size) + 1
page.current = current
page.loading = false
}) */
var params = {
current: current,
size: page.size
}
userOrderList(params).then((resp) => {
uni.stopPullDownRefresh();
const data = resp.data.data
this.$set(this.dataDepository, activeTab, this.dataDepository[activeTab].concat(data.records))
page.maxPage = parseInt(data.total / data.size) + 1
page.current = current
page.loading = false
})
},
refrush() {
this.page = {
current: 1,
size: 20,
maxPage: 1,
}
this.getData()
},
moneyComdify,
moneyFormat,
dateFormat
},
watch: {
activeTab(val) {
this.getData()
}
},
computed: {
...mapGetters(['userInfo']),
data() {
return this.dataDepository[this.activeTab]
}
}
}
</script>
<style>
.nothingText {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
text-align: center;
margin-top: 20rpx;
}
.nothing image {
width: 400rpx;
height: 200rpx;
display: block;
padding-top: 50%;
margin: 0 auto;
}
.nothing {
width: 100%;
height: 100%;
background-color: #fefefe;
}
.timeBox {
display: flex;
justify-content: space-between;
}
.time{
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #6D6D6D;
}
.allName {
width: 280rpx;
height: 76rpx;
line-height: 76rpx;
overflow: hidden;
white-space: nowrap;
/*不换行*/
text-overflow: ellipsis;
/*超出部分文字以...显示*/
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
}
.list_head_right {
display: flex;
font-size: 24rpx;
font-weight: 500;
color: #F46161;
}
.price{
width: 137rpx;text-align: right;
}
.list_head_left {
width: 347rpx;
overflow: hidden;
white-space: nowrap;
/*不换行*/
text-overflow: ellipsis;
/*超出部分文字以...显示*/
font-family: PingFangSC-Medium;
font-size: 32rpx;
color: #333333;
font-weight: bold;
}
.list_head {
display: flex;
align-items: center;
justify-content: space-between;
}
.list {
/* height: 132rpx; */
/* line-height: 50rpx; */
padding: 30rpx 30rpx 32rpx 30rpx;
border-bottom: 20rpx solid #f6f6f6;
background-color: #fefefe;
}
.body {
width: 100%;
height: 100%;
}
page {
background-color: #f6f6f6;
width: 100%;
height: 100%;
}
</style>

121
pageMy/my/set.vue Normal file
View File

@@ -0,0 +1,121 @@
<template>
<view>
<view class="listBody">
<view class="list">
<view class="list_left">
我的账号
</view>
<view class="list_right">
{{userInfo.account}}
</view>
</view>
<view class="list" @click="password">
<view class="list_left">
修改密码
</view>
<view class="list_right">
<image src="../../static/img/right.svg" mode=""></image>
</view>
</view>
</view>
<view class="listBody">
<view class="list" @click="agreement">
<view class="list_left">
服务及隐私协议
</view>
<view class="list_right">
<image src="../../static/img/right.svg" mode=""></image>
</view>
</view>
</view>
<view class="btn" @click="logout">
退出登录
</view>
</view>
</template>
<script>
import {
mapGetters
} from 'vuex'
export default {
data() {
return {
}
},
onLoad() {},
methods: {
logout() {
this.$store.dispatch('LogOut').then(() => {
uni.reLaunch({
url: '/pages/login/login'
})
this.$store.dispatch('clearAuthState')
this.$store.dispatch('endRefreshNewsTimer')
})
},
password(){
uni.navigateTo({
url: '/pageMy/my/changePassword'
})
},
agreement() {
uni.navigateTo({
url: '/pages/user/agreement'
})
}
},
computed: {
...mapGetters(['userInfo'])
}
}
</script>
<style>
.btn {
background-color: #fefefe;
margin-top: 20rpx;
padding: 20rpx 0;
text-align: center;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #F46161;
}
.list_right image {
width: 40rpx;
height: 40rpx;
}
.list_right {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
}
.list_left {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
}
.list {
padding: 20rpx;
padding-left: 0;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1rpx solid #ddd;
}
.listBody {
background-color: #fefefe;
margin-top: 20rpx;
padding-left: 20rpx;
}
page {
background-color: #f6f6f6;
}
</style>

140
pageMy/my/userBase.vue Normal file
View File

@@ -0,0 +1,140 @@
<template>
<view class="centerNothing">
<view class="userBase" v-if="auth.realNameState === true">
<view class="userBaseList">
<view class="user_left">
姓名
</view>
<view class="user_Right">
{{auth.authInfo.realName}}
</view>
</view>
<view class="userBaseList">
<view class="user_left">
性别
</view>
<view class="user_Right">
{{auth.authInfo.sex===1?'男':'女'}}
</view>
</view>
<view class="userBaseList">
<view class="user_left">
出生年月
</view>
<view class="user_Right">
{{birthday}}
</view>
</view>
<view class="userBaseList">
<view class="user_left">
手机号
</view>
<view class="user_Right">
{{auth.authInfo.telphone}}
</view>
</view>
<view class="userBaseList">
<view class="user_left">
身份
</view>
<view class="user_Right">
<block v-if="auth.laborState">农村劳动力</block>
</view>
</view>
</view>
<!-- 没有认证的情况 -->
<view v-else>
<image src="../../static/img/pic_noid.svg" mode="" class="nothing"></image>
<view class="nothingText" @click="goSetUserBase">
暂无信息请先<text>填写认证信息</text>
</view>
</view>
</view>
</template>
<script>
import {
userInfo
} from '@/api/resume.js';
import {
dateFormat
} from "../../untils/format.js";
import {
mapGetters
} from 'vuex'
export default {
data() {
return {
userInfo: {}
}
},
computed: {
...mapGetters(['auth', 'authInfo']),
birthday() {
return dateFormat(new Date(this.authInfo.birthday.replace(/\-/g, "/").replace('T',' ')), "yyyy-MM");
}
},
onShow() {},
methods: {
goSetUserBase: function() {
uni.navigateTo({
url: '../setUserBase/index'
})
}
}
}
</script>
<style>
.nothingText text {
color: #1B66FF;
}
.nothingText {
text-align: center;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
margin-top: 20rpx;
}
.nothing {
display: block;
margin: 0 auto;
width: 400rpx;
height: 200rpx;
margin-top: 50%;
}
.user_Right {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
}
.user_left {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
}
.userBaseList {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
padding-left: 0;
border-bottom: 1rpx solid #dddddd;
}
.userBase {
background-color: #fefefe;
padding-left: 30rpx;
margin-top: 30rpx;
}
page {
background-color: #fff;
}
</style>

96
pageMy/my/vip/bind.vue Normal file
View File

@@ -0,0 +1,96 @@
<template>
<view class="vip">
<view class="vip-title">
输入邀请码
</view>
<view class="vip-tip">通过客服获取由字母数字组成不少于10位的编码</view>
<jl-form>
<jl-form-item>
<jl-input v-model="code" placeholder="请输入" clearable></jl-input>
</jl-form-item>
</jl-form>
<view class="vip-btn">
<jl-button inline type="primary" :disabled="valid" :loading="loading" @click="confirm">申请绑定</jl-button>
</view>
<view class="vip-bottom">
未实名认证用户请先进行实名认证未完成实名认证申请VIP会员无法成功
</view>
</view>
</template>
<script>
import {
bind
} from "@/api/vip.js"
import jlInput from "@/components/jl-input/main.vue"
import {
mapGetters
} from "vuex"
export default {
components: {
jlInput
},
data() {
return {
loading: false,
code: ""
}
},
methods: {
confirm() {
this.loading = true
this.$store.dispatch("bindVipCode", this.code).then(() => {
this.loading = false
}).catch(() => {
this.loading = false
})
}
},
computed: {
...mapGetters(["authInfo"]),
valid() {
return this.code.length < 10
}
}
}
</script>
<style>
.vip {
width: 80%;
padding-top: 108rpx;
margin: 0 auto;
}
.vip-title {
font-size: 46rpx;
color: #333333;
letter-spacing: 0;
line-height: 46rpx;
margin-bottom: 30rpx;
}
.vip-tip {
font-size: 28rpx;
color: #999999;
line-height: 28rpx;
margin-bottom: 43rpx;
}
.vip-btn {
padding-top: 50rpx;
}
.vip-btn-invit .jl-button {
display: block;
}
.vip-bottom {
padding-top: 41rpx;
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
}
</style>

33
pageMy/my/vip/index.vue Normal file
View File

@@ -0,0 +1,33 @@
<template>
<success v-if="isVip"></success>
<bind v-else></bind>
</template>
<script>
import bind from "./bind.vue"
import success from "./success.vue"
import {
mapGetters
} from "vuex"
export default {
components: {
bind,
success
},
data() {
return {
state: ""
}
},
computed: {
...mapGetters(["isVip"])
}
}
</script>
<style>
page{
height: 100%;
}
</style>

74
pageMy/my/vip/success.vue Normal file
View File

@@ -0,0 +1,74 @@
<template>
<view class="vip-success">
<view class="vip-success-body">
<image class="vip-success-img" src="/static/img/noauth.svg"></image>
<view class="vip-success-text">我的邀请码{{vipCode}}</view>
<jl-button class="vip-success-btn" @click="copy">复制</jl-button>
</view>
<view class="vip-success-footer">说明邀请码用作企业自主注册时填写的邀请码</view>
</view>
</template>
<script>
import {
mapGetters
} from "vuex"
import uniCopy from '@/js_sdk/xb-copy/uni-copy.js'
export default {
methods: {
copy() {
uniCopy({
content: `企业登录链接https://www.jlhrms.cn/manage/#/login\r\n企业邀请码:${this.vipCode}`,
success: (res) => {
uni.showToast({
title: "复制成功",
icon: 'none'
})
},
})
}
},
computed: {
...mapGetters(["vipCode"])
}
}
</script>
<style>
.vip-success {
height: 100%;
text-align: center;
}
.vip-success-body {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.vip-success-img {
width: 337rpx;
height: 188rpx;
margin: 0 auto 43.2rpx auto;
}
.vip-success-text {
font-size: 28rpx;
color: #666666;
letter-spacing: 0;
line-height: 32rpx;
margin-bottom: 20rpx;
}
.vip-success-footer {
width: 100%;
position: absolute;
bottom: 128rpx;
font-size: 24rpx;
color: #999999;
letter-spacing: 0;
line-height: 24rpx;
}
</style>

131
pageMy/myProject/list.vue Normal file
View File

@@ -0,0 +1,131 @@
<template>
<scroll-view v-if="show && data.length > 0" @scrolltolower="upLoad" scroll-y>
<block v-for="(page, pIndex) in data" :key="pIndex">
<block v-for="(item, index) in page" :key="index">
<view class="probody">
<company-list :companyitem="item" :noApply="false"></company-list>
<view class="baddd"></view>
<block v-if="mark">
<image src="/static/img/tab.orange.svg" mode="" v-if="item.status === 1"></image>
<image src="/static/img/tab.blue.svg" mode="" v-else-if="item.status === 2"></image>
<image src="/static/img/tab.green.svg" mode="" v-else-if="item.status === 3"></image>
<image src="/static/img/tab.gray.svg" mode="" v-else></image>
</block>
</view>
</block>
</block>
</scroll-view>
<view class="nothing" v-else-if="show">
<image src="/static/img/pic_notask.svg" mode=""></image>
<view class="nothingContnt">
暂无任务信息
</view>
</view>
</template>
<script>
import companyList from '@/components/companyList/companyList.vue';
import {
myMission
} from '@/api/mission.js';
export default {
components: {
companyList
},
props: {
show: Boolean,
mark: Boolean,
status: Number
},
data() {
return {
initialized: false,
data: [],
current: 1,
size: 10,
total: 0
}
},
created() {
this.init()
},
methods: {
init() {
if (this.show && !this.initialized) {
this.getData()
this.initialized = true
}
},
getData(point) {
myMission(this.current, this.size, this.status).then(res => {
if (this.current === 1) {
this.data = [];
}
this.current += 1;
this.total = res.data.data.total;
if (res.data.data && res.data.data.records.length) {
this.data.push(res.data.data.records);
}
})
},
upLoad() {
if (this.current <= Math.ceil(this.total / this.size)) {
this.getData();
} else {
uni.showToast({
icon: "none",
title: '已经是最后一页',
})
}
}
},
watch: {
show(val) {
this.init()
}
}
}
</script>
<style scoped>
.probody image {
width: 88rpx;
height: 88rpx;
position: absolute;
right: 0;
top: 0;
}
.probody {
width: 100%;
position: relative;
}
.baddd {
background: #f6f6f6;
height: 20rpx;
}
.nothing {
height: 100%;
padding-top: 50%;
box-sizing: border-box;
}
.nothing image {
width: 400rpx;
height: 200rpx;
display: block;
margin: 0 auto;
}
.nothingContnt {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666;
margin-top: 30rpx;
text-align: center;
}
</style>

View File

@@ -0,0 +1,153 @@
<template>
<view class="body">
<view class="tab">
<v-tabs :tabs="['全部任务','抢成功','抢失败']" v-model="activeTab" color="#999" activeColor="#000" fontSize="36rx"
activeFontSize="36rpx" @change='changeTab' />
</view>
<block v-for="(page, pIndex) in data" :key="pIndex">
<block v-for="(item, index) in page" :key="item.id">
<view class="probody">
<company-list :companyitem="item" :noApply="false"></company-list>
<view class="baddd"></view>
<block>
<image src="/static/img/tab.orange.svg" mode="" v-if="item.status === 1"></image>
<image src="/static/img/tab.blue.svg" mode="" v-else-if="item.status === 2"></image>
<image src="/static/img/tab.green.svg" mode="" v-else-if="item.status === 3"></image>
<image src="/static/img/tab.gray.svg" mode="" v-else></image>
</block>
</view>
</block>
</block>
<view class="nothing" v-if="data.length === 0">
<image src="/static/img/pic_notask.svg" mode=""></image>
<view class="nothingContnt">
暂无任务信息
</view>
</view>
</view>
</template>
<script>
import vTabs from '@/components/v-tabs/v-tabs.vue';
import companyList from '@/components/companyList/companyList.vue';
import {
myMission
} from '@/api/mission.js';
export default {
components: {
vTabs,
companyList
},
data() {
return {
data: [],
activeTab: 0,
current: 1,
size: 10,
total: 0
}
},
onLoad: function() {
this.init()
},
/*页面滚动到底部 换页*/
onReachBottom: function() {
if (this.current <= Math.ceil(this.total / this.size)) {
this.getData();
} else {
uni.showToast({
icon: "none",
title: '已经是最后一页',
})
}
},
/*下拉刷新*/
onPullDownRefresh:function(){
this.init()
},
methods: {
init(){
this.current = 1
this.data = []
this.getData()
},
getData() {
var status = Number(this.activeTab) + 1
myMission(this.current, this.size, status).then(res => {
uni.stopPullDownRefresh();
if (this.current === 1) {
this.data = [];
}
this.current += 1;
this.total = res.data.data.total;
if (res.data.data && res.data.data.records.length) {
this.data.push(res.data.data.records);
}
})
},
gomap: function() {
uni.navigateTo({
url: '../mapSeach/mapSeach'
})
},
changeTab: function(e) {
this.activeTab = e;
this.init()
}
}
}
</script>
<style scoped>
page {
height: 100%;
}
.tab {
height: 46px;
}
.body {
height: 100%;
}
.probody image {
width: 88rpx;
height: 88rpx;
position: absolute;
right: 0;
top: 0;
}
.probody {
width: 100%;
position: relative;
}
.baddd {
background: #f6f6f6;
height: 20rpx;
}
.nothing {
height: 100%;
padding-top: 50%;
box-sizing: border-box;
}
.nothing image {
width: 400rpx;
height: 200rpx;
display: block;
margin: 0 auto;
}
.nothingContnt {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666;
margin-top: 30rpx;
text-align: center;
}
</style>

View File

@@ -0,0 +1,145 @@
<template>
<view>
<view class="noComment" v-if='comment.scoreAll <= 0 || JSON.stringify(comment) == "{}"'>
<view class="start">
<view @click="setScore(index + 1)" :key="index" v-for="(i,index) in 5">
<image src="../../static/img/star.full.svg" v-if="index + 1 <= commentscore"></image>
<image src="../../static/img/star.empty.svg" v-else></image>
</view>
</view>
<view class="textview">
<textarea value="" @input="settext" placeholder="评论(选填)100字以内" placeholder-class="textClass" maxlength="100" />
</view>
<view class="btn" @click="sendCom"><view class="bottombtn">确认</view></view>
</view>
<view class="noComment" v-if='comment.scoreAll>0'>
<view class="start">
评分
<image src="../../static/img/star.full.svg" v-for="index in comment.scoreAll" mode="" :key="index"></image>
<image src="../../static/img/star.empty.svg" v-for="index in (5-comment.scoreAll)" mode="" :key="index"></image>
</view>
<view class="textview">
<textarea :value="comment.remarks" disabled />
</view>
</view>
</view>
</template>
<script>
import {myRate,rate,rateDetail } from '@/api/rate.js';
import testData from '@/common/textdata.js';
export default {
data() {
return {
comment:{},
missionNo:'',
commenttext:'',
commentscore:0
}
},
onLoad: function (option) {
if(option.missionNo){
this.missionNo = decodeURIComponent(option.missionNo);
}
},
onShow: function() {
/*获取评价详情*/
rateDetail(this.missionNo).then(res => {
this.comment = res.data.data;
});
},
methods: {
settext:function(e){
this.commenttext=e.detail.value;
},
setScore:function(score){
this.commentscore = score
},
/*提交*/
sendCom:function(){
if(!this.commentscore){
uni.showToast({
icon:'none',
title:'请完成评分',
duration:3000
})
return
}else{
rate(this.missionNo,this.commentscore,this.commenttext).then(res => {
uni.showToast({
icon:'none',
title:'提交成功',
duration:3000,
success: function (res) {
uni.navigateBack({
delta: 1
})
}
})
}, error => {
uni.showToast({
icon:'none',
title:'操作失败',
duration:3000
})
});
}
}
}
}
</script>
<style>
.bottombtn {
background-color: #1b66ff;
color: #fff;
text-align: center;
border-radius: 10rpx;
font-family: PingFangSC-Medium;
font-size: 32rpx;
height: 90rpx;
line-height: 90rpx;
}
.btn {
background-color: #fefefe;
width: 690rpx;
padding: 30rpx;
padding-bottom: 80rpx;
position: fixed;
bottom: 0;
left: 0;
}
.textview{
padding: 20rpx;
}
textarea{
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #666;
}
.textClass{
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #CCCCCC;
}
.start view:first-child{
margin-left: 20rpx;
}
.start image{
width: 40rpx;
height: 40rpx;
}
.start{
padding: 20rpx;
border-bottom: 1rpx solid #f6f6f6;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
display: flex;
align-items: center;
justify-content: flex-start;
}
page{background-color: #fefefe;}
</style>

View File

@@ -0,0 +1,198 @@
<template>
<view class="body">
<view class="list">
<view class="listName">
开户银行
</view>
<view class="listContent" @click="goBankList">
{{bankName}}
<image src="@/static/img/right.svg" mode=""></image>
</view>
</view>
<view class="list">
<view class="listName">
银行卡号
</view>
<text v-if="edit">{{bankCardFilter(cardNumber)}}</text>
<input v-else type="number" v-model="cardNumber" placeholder="请输入银行卡号" placeholder-style="color:#cccccc;" />
</view>
<view class="list">
<view class="listName">
默认银行卡
</view>
<switch :disabled="!canEditDef" :checked="def" @change="switchChange" />
</view>
<view v-if="loading" class="btn">
<view class="bottombtn nocheck">{{btnText}}</view>
</view>
<view v-else-if="validate" class="btn">
<view class="bottombtn nocheck">{{btnText}}</view>
</view>
<view v-else class="btn" @click="goSet">
<view class="bottombtn">{{btnText}}</view>
</view>
</view>
</template>
<script>
import {
bank
} from '@/api/auth.js'
import {
validatenull
} from '@/untils/validate.js'
import {
mapGetters
} from 'vuex'
import {
bankCardFilter
} from '@/untils/format.js'
export default {
data() {
return {
edit: false,
canEditDef: false,
loading: false,
id: null,
bankId: '',
bankName: '选择银行',
cardNumber: '',
def: true,
btnText: "认证"
};
},
onLoad({
id,
name,
card,
def
}) {
if (id) {
this.edit = true
this.id = id
this.bankId = this.bankName = name
this.cardNumber = card
this.def = def === '1'
this.canEditDef = !this.def && this.auth.bankCardState
this.btnText = '修改'
} else {
this.canEditDef = this.auth.bankCardState
this.btnText = '认证'
}
},
methods: {
goBankList: function() {
uni.$once('icCardSetBank', (data) => {
this.bankId = data.id;
this.bankName = data.name;
})
uni.navigateTo({
url: '/pages/bankList/bankList'
})
},
goSet() {
this.loading = true
bank(this.bankName, this.auth.authInfo.realName, this.cardNumber, this.def ? 1 : 0, this.id).then(resp => {
this.loading = false
this.$store.commit('SET_AUTH_BANKCARD', true)
uni.navigateBack()
}).catch(() => {
this.loading = false
})
},
switchChange(e) {
if (this.auth.bankCardState && this.canEditDef) {
this.def = !this.def
}
},
bankCardFilter
},
computed: {
...mapGetters(['auth']),
validate() {
return validatenull(this.bankId) || validatenull(this.cardNumber)
}
}
};
</script>
<style>
.list switch {
margin-left: auto;
}
.nocheck {
opacity: 0.3;
}
.listName {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
width: 200rpx;
}
.listContent image {
width: 40rpx;
height: 40rpx;
}
.listContent {
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
margin-left: auto;
}
.list input,
.list text {
margin-left: auto;
text-align: right;
}
.list input{
flex:1;
}
.list {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 30rpx;
padding-left: 0;
border-bottom: 1rpx solid #f2f2f2;
}
.body {
background-color: #fefefe;
margin-top: 30rpx;
padding-left: 30rpx;
}
page {
background-color: #f6f6f6;
}
.bottombtn {
background-color: #1b66ff;
color: #fff;
text-align: center;
border-radius: 10rpx;
font-family: PingFangSC-Medium;
font-size: 32rpx;
height: 90rpx;
line-height: 90rpx;
}
.btn {
background-color: #fefefe;
width: 690rpx;
padding: 30rpx;
padding-bottom: 80rpx;
position: fixed;
bottom: 0;
left: 0;
}
</style>

View File

@@ -0,0 +1,182 @@
<template>
<view>
<view class="cardList" v-for="item in cards" :key="item.id" @click="editIc(item)">
<image src="@/static/img/exp/map.svg" class="cardBack" mode=""></image>
<view class="cardName">
{{item.bankName}}
</view>
<view class="cardType">
储蓄卡
</view>
<view class="cardNo">
{{bankCardFilter(item.cardNumber)}}
</view>
<view class="delect" @click.stop="delect(item.id)" v-if="cards.length > 1 && item.def != 1">
<image src="@/static/img/exp/link.svg" mode=""></image>
<view class="delectContent">
解绑银行卡
</view>
</view>
</view>
<view class="btn" @click="addIc">
<image src="@/static/img/add.svg" mode=""></image>
添加银行卡
</view>
<view class="tx">
目前仅支持储蓄卡
</view>
</view>
</template>
<script>
import {
getUserCards,
remove
} from '@/api/bank.js'
import {
bankCardFilter
} from '@/untils/format.js'
export default {
data() {
return {
cards: []
}
},
onShow() {
this.getData()
},
methods: {
getData() {
getUserCards().then(res => {
this.cards = res.data.data
})
},
addIc: function() {
uni.navigateTo({
url: './add'
})
},
editIc(ic) {
uni.navigateTo({
url: `./add?id=${ic.id}&name=${ic.bankName}&card=${ic.cardNumber}&def=${ic.def}`
})
},
delect(id) {
uni.showModal({
title: '解绑银行卡',
content: '解绑银行卡后工资将不会发放到此银行卡中',
cancelText: '保持绑定',
cancelColor: '#1B66FF',
confirmText: '仍要解绑',
confirmColor: '#1B66FF',
success: (res) => {
if (res.confirm) {
remove(id).then(() => {
this.getData()
})
}
}
});
},
bankCardFilter
}
}
</script>
<style>
.cardBack {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
/* z-index: -1; */
}
.tx {
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #999999;
text-align: center;
margin-top: 20rpx;
}
.btn image {
width: 40rpx;
height: 40rpx;
}
.btn {
width: 690rpx;
margin: 30rpx;
background-color: #1B66FF;
color: #fff;
height: 90rpx;
line-height: 90rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8rpx;
}
.delect image {
width: 20rpx;
height: 20rpx;
}
.delect {
position: absolute;
right: 40rpx;
top: 30rpx;
background-color: rgba(255, 255, 255, 0.3) !important;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #FFFFFF;
height: 36rpx;
width: 170rpx;
}
.cardNo {
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #FFFFFF;
position: absolute;
left: 40rpx;
bottom: 40rpx;
}
.cardType {
font-family: PingFangSC-Regular;
font-size: 26rpx;
color: #FFFFFF;
padding-left: 40rpx;
padding-top: 15rpx;
}
.cardName {
padding-left: 40rpx;
padding-top: 50rpx;
font-family: PingFangSC-Medium;
font-size: 36rpx;
color: #FFFFFF;
}
.cardList {
position: relative;
width: 690rpx;
margin: 30rpx;
background-image: linear-gradient(-31deg, #3E8EED 0%, #6BA5FF 24%, #84BDFF 45%, #397AFF 100%);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.30);
border-radius: 15rpx;
height: 280rpx;
}
page {
background-color: #f6f6f6;
}
</style>

View File

@@ -0,0 +1,304 @@
<template>
<view class="body">
<view class="head">
<image src="@/static/img/pic_logo.svg" class="logo" mode=""></image>
<view class="headuser">
<image src="@/static/img/head.svg" class="headuserImg" mode=""></image>
<view v-if="auth.realNameState" class="name">
<view class="userName">{{authInfo.realName}}</view>
<view class="userInfo">{{idNumberFilter(authInfo.idNumber)}}</view>
</view>
<view v-else class="name">
<view class="userName">姓名</view>
<view class="userInfo">身份证号</view>
</view>
<image v-if="auth.realNameState" src="@/static/img/exp/stamp2.svg" class="stamp" mode=""></image>
<image v-else src="@/static/img/exp/stamp1.svg" class="stamp" mode=""></image>
</view>
<view class="tx">
<image src="@/static/img/bao.svg" mode=""></image>
<view class="txText">个人隐私信息安全保障中</view>
</view>
</view>
<view class="border"></view>
<!--<picker @change="bindPickerChange" :value="index" :range="laborType">
<view class="list">
<view class="listLeft">
<view class="listTitle">身份信息</view>
<view class="listContent">选择个人身份获得精准推荐</view>
</view>
<view class="listRight">
<view class="rightContent nochoose">
<view v-if="auth.laborState" class="uni-input">{{ laborType[0] }}</view>
<view v-else class="uni-input">未选择</view>
</view>
<image src="@/static/img/right.svg" mode=""></image>
</view>
</view>
</picker>-->
<view class="border"></view>
<view class="list" @click="goRealName">
<view class="listLeft">
<view class="listTitle">实名认证</view>
<view class="listContent">完成实名认证提高信息可信度</view>
</view>
<view class="listRight">
<view v-if="auth.realNameState" class="rightContent nochoose">已认证</view>
<view v-else class="rightContent nochoose">未认证</view>
<image src="@/static/img/right.svg" mode=""></image>
</view>
</view>
<view class="border"></view>
<view class="list" @click="setIcCard">
<view class="listLeft">
<view class="listTitle">银行卡认证</view>
<view class="listContent">完善银行卡信息方便领工资</view>
</view>
<view class="listRight">
<view v-if="auth.bankCardState" class="rightContent nochoose">已认证</view>
<view v-else class="rightContent nochoose">未认证</view>
<image src="@/static/img/right.svg" mode=""></image>
</view>
</view>
<view class="border"></view>
<!--<picker @change="bindPickerChangeBao" :value="indexbao" :range="insureType">
<view class="list">
<view class="listLeft">
<view class="listTitle">社保信息</view>
<view class="listContent">选择个人身份获得精准推荐</view>
</view>
<view class="listRight">
<view class="rightContent nochoose">
<view v-if="auth.insureState" class="uni-input">{{ insureType[indexbao] }}</view>
<view v-else class="uni-input">未选择</view>
</view>
<image src="@/static/img/right.svg" mode=""></image>
</view>
</view>
</picker>-->
<view class="border"></view>
<view class="list" @click="setSeal">
<view class="listLeft">
<view class="listTitle">个人签名</view>
<view class="listContent">采集手写签名便于维护自身利益</view>
</view>
<view class="listRight">
<view v-if="autograph.data && autograph.data.signSrcUrl" class="rightContent nochoose">已采集</view>
<view v-else class="rightContent nochoose">未采集</view>
<image src="@/static/img/right.svg" mode=""></image>
</view>
</view>
</view>
</template>
<script>
import textdata from '@/common/textdata.js'
import {
mapGetters
} from 'vuex'
import {
idNumberFilter
} from '@/untils/format.js'
export default {
data() {
return {
laborType: textdata.laborType,
index: 0,
insureType: textdata.insureType,
};
},
onLoad() {
this.$store.dispatch('setAutograph')
},
computed: {
...mapGetters(['auth', 'authInfo', 'autograph']),
indexbao() {
if (this.auth.insureState) {
return this.authInfo.bakValue - 1
} else {
return 0
}
}
},
methods: {
setSeal(){
if (this.auth.realNameState) {
uni.navigateTo({
url: '/pageMy/setUserBase/seal/index'
})
} else {
uni.showToast({
title: '请先完成实名认证',
icon: 'none'
})
}
},
setIcCard: function() {
if (this.auth.realNameState) {
uni.navigateTo({
url: '/pageMy/setUserBase/icCard/index'
})
} else {
uni.showToast({
title: '请先完成实名认证',
icon: 'none'
})
}
},
goRealName: function() {
uni.navigateTo({
url: '/pageMy/setUserBase/realName'
})
},
bindPickerChangeBao: function(e) {
uni.showLoading()
this.$store.dispatch('authInsure', e.target.value * 1 + 1).then(resp => {
uni.hideLoading()
}).catch(() => {
uni.hideLoading()
})
},
bindPickerChange: function(e) {
uni.showLoading()
this.$store.dispatch('authLabor').then(resp => {
this.index = e.target.value;
uni.hideLoading()
}).catch(() => {
uni.hideLoading()
})
},
idNumberFilter
}
};
</script>
<style>
.nochoose {
color: #1b66ff;
}
.listRight {
display: flex;
align-items: center;
justify-content: space-between;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #999999;
}
.listRight image {
width: 40rpx;
height: 40rpx;
margin-left: 15rpx;
}
.listContent {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #666666;
}
.list {
display: flex;
align-items: center;
justify-content: space-between;
font-family: PingFangSC-Regular;
font-size: 32rpx;
color: #333333;
padding: 30rpx;
line-height: 50rpx;
}
.border {
margin-left: 30rpx;
width: 720rpx;
height: 2rpx;
background-color: #f2f2f2;
/* border-bottom: 1rpx solid #dddddd; */
}
.tx image {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
.tx {
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #ffffff;
padding: 30rpx;
padding-top: 0;
display: flex;
align-items: center;
justify-content: flex-start;
}
.userInfo {
font-family: PingFangSC-Regular;
font-size: 26rpx;
color: #ffffff;
font-weight: normal;
}
.name {
margin-left: 20rpx;
font-family: PingFangSC-Medium;
font-size: 36rpx;
color: #ffffff;
font-weight: bold;
line-height: 50rpx;
}
.headuserImg {
width: 100rpx;
height: 100rpx;
}
.headuser {
padding: 30rpx;
display: flex;
align-items: center;
justify-content: flex-start;
}
.stamp {
position: absolute;
top: 30rpx;
right: 30rpx;
/* opacity: 0.6; */
width: 200rpx;
height: 200rpx;
}
.logo {
position: absolute;
bottom: 0;
left: 0;
opacity: 0.1;
width: 200rpx;
height: 200rpx;
}
.head {
width: 690rpx;
height: 250rpx;
padding-top: 30rpx;
margin: 30rpx;
margin-top: 0;
border-radius: 15rpx;
position: relative;
background: #1b66ff;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
}
.body {
background-color: #fefefe;
padding-top: 30rpx;
}
page {
background-color: #f6f6f6;
}
</style>

Some files were not shown because too many files have changed in this diff Show More