初始提交
This commit is contained in:
95
pages/my/abouts/index.vue
Normal file
95
pages/my/abouts/index.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<view class="abouts-v">
|
||||
<view class="head-box u-flex-col">
|
||||
<view class="head-inner">
|
||||
<view class="version">
|
||||
{{sysVersion}}
|
||||
</view>
|
||||
<image src="/static/image/jnpf.png" mode="widthFix" class="head-img"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="content u-p-l-32 u-p-r-32 u-p-t-30 u-font-28">
|
||||
<text>引迈信息技术有限公司是一家做快速开发平台的企业,针对软件传统开发遇到招人难、留人难、用人成本高、技术更新换代快等一系列问题,只需要一套JNPF平台、您遇到的一系列问题就依然而解。
|
||||
JNPF采用主流的两大技术Java/.Net开发,是一套低代码开发平台,可视化开发环境,有拖拽式的代码生成器,灵活的权限配置、SaaS服务,强大的接口对接,随心可变的工作流引擎,一站式开发多端使用Web、Android、IOS、微信小程序,并且有以构建业务流程、逻辑和数据模型等所需的功能;为企业项目节省80%的重回工作,让开发者将重心放在业务逻辑,不必烦恼底层架构设计,可短时间开发出如ERP、OA、CRM、HR、MIS以及电信、银行、政府、企业等各行业的企业应用系统。
|
||||
引迈信息技术有限公司以诚信为根本、服务为基础理念,通过持续不断地研发技术创新、强化平台质量和颜值,为企业保驾护航!</text>
|
||||
</view>
|
||||
<view class="copyright">{{copyright}}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import resources from '@/libs/resources.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
logoSrc: resources.banner.loginlogo,
|
||||
copyright: 'Copyright © 2024 引迈信息技术有限公司出品',
|
||||
sysVersion: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.sysVersion = uni.getStorageSync('sysVersion') || this.define.sysVersion
|
||||
this.copyright = uni.getStorageSync('copyright') || 'Copyright © 2024 引迈信息技术有限公司出品'
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.abouts-v {
|
||||
.head-box {
|
||||
height: 308rpx;
|
||||
background: url('@/pages/my/static/image/about-head.png') center no-repeat;
|
||||
background-size: 100% 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.head-inner {
|
||||
position: relative;
|
||||
|
||||
.head-img {
|
||||
width: 212rpx;
|
||||
height: 60rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.version {
|
||||
position: absolute;
|
||||
background-color: #FFFFFF;
|
||||
color: #0F5BD2;
|
||||
padding: 0 8rpx;
|
||||
border-radius: 20rpx 0rpx 20rpx 0rpx;
|
||||
top: -34rpx;
|
||||
left: 218rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.abouts-hd {
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
background-color: #3281ff;
|
||||
height: 280rpx;
|
||||
color: #FFFFFF;
|
||||
padding-top: 20rpx;
|
||||
|
||||
image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.copyright {
|
||||
height: 80rpx;
|
||||
bottom: 0;
|
||||
line-height: 80rpx;
|
||||
|
||||
}
|
||||
|
||||
.content {
|
||||
height: calc(100vh - 486rpx);
|
||||
overflow-y: scroll;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
82
pages/my/accountSecurity/index.vue
Normal file
82
pages/my/accountSecurity/index.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<view class="accountSecurity-v">
|
||||
<u-cell-group style="padding: 0 20rpx;">
|
||||
<u-cell-item :title="$t('app.my.accountSecurity.changePassword')"
|
||||
@click="handelClick('/pages/my/modifyPsd/index','password')">
|
||||
</u-cell-item>
|
||||
<u-cell-item :title="$t('app.my.accountSecurity.mobilePhone')" :value="userInfo.mobilePhone"
|
||||
@click="handelClick('/pages/my/modifyPsd/index','mobilePhone',userInfo.mobilePhone)">
|
||||
</u-cell-item>
|
||||
<u-cell-item :title="$t('app.my.accountSecurity.email')" :value="userInfo.email"
|
||||
@click="handelClick('/pages/my/modifyPsd/index','email',userInfo.email)">
|
||||
</u-cell-item>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<u-cell-item title="注销账号" @click="openPage('/pages/my/cancellation/index')"></u-cell-item>
|
||||
<!-- #endif -->
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserSettingInfo
|
||||
} from "@/api/common.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {},
|
||||
needRefresh: false
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (this.needRefresh) {
|
||||
this.needRefresh = false;
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
getUserSettingInfo().then(res => {
|
||||
this.userInfo = res.data || {}
|
||||
})
|
||||
},
|
||||
openPage(path, type) {
|
||||
uni.navigateTo({
|
||||
url: path
|
||||
})
|
||||
},
|
||||
handelClick(path, type, vuale) {
|
||||
if (!path) return
|
||||
this.needRefresh = true
|
||||
let config = {
|
||||
type,
|
||||
vuale
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: path + '?config=' + encodeURIComponent(JSON.stringify(config))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
:deep(.u-cell) {
|
||||
height: 112rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.accountSecurity-v {
|
||||
background-color: #fff;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
height: 360rpx;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
124
pages/my/cancellation/index.vue
Normal file
124
pages/my/cancellation/index.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<view class="cancellation-v">
|
||||
<view class="cancellation-hd">
|
||||
<image :src="accountSecurity"></image>
|
||||
</view>
|
||||
<view class="content u-flex-col">
|
||||
<view class="content-text u-flex-col">
|
||||
<text class="content-title u-font-36 u-type-primary">确认注销账户?</text>
|
||||
<text class="content-tip u-font-28">注销账户后以下数据将全部清空</text>
|
||||
<view class="list u-flex-col u-font-26">
|
||||
<text class="item">企业组织架构和员工信息</text>
|
||||
<text class="item">所有数据和聊天记录</text>
|
||||
<text class="item">删除和永久注销JNPF账户</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
<u-button type="primary" @click="handleClick">注销账号</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
accountCancel,
|
||||
logout
|
||||
} from '@/api/common.js'
|
||||
import resources from '@/libs/resources.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
accountSecurity: resources.banner.accountSecurity
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
token() {
|
||||
return uni.getStorageSync('token')
|
||||
},
|
||||
userInfo() {
|
||||
return uni.getStorageSync('userInfo') || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您的JNPF账号将被删除,您确定要注销JNPF账号么?',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
if (this.userInfo.isAdministrator) return this.$u.toast('管理员账号不能注销')
|
||||
accountCancel(this.token).then((res) => {
|
||||
this.$u.toast(res.msg)
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index'
|
||||
})
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.cancellation-v {
|
||||
.cancellation-hd {
|
||||
width: 100%;
|
||||
height: 280rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
.content-text {
|
||||
justify-content: center;
|
||||
padding: 176rpx 0 0 190rpx;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
height: 100rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.content-tip {
|
||||
height: 80rpx;
|
||||
color: #252B3A;
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
margin-bottom: 35rpx;
|
||||
color: #666;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #356efe;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0 32rpx;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 40rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
132
pages/my/changeSystem/index.vue
Normal file
132
pages/my/changeSystem/index.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<view class="change-system-v">
|
||||
<view class="u-p-l-20 u-p-r-20 change-system-search">
|
||||
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72" :show-action="false"
|
||||
@change="onSearchChange" bg-color="#f0f2f6" shape="square" style="width: 100%;">
|
||||
</u-search>
|
||||
</view>
|
||||
<view class="system-box u-m-t-20">
|
||||
<view class="system-container" v-if="systemList.length">
|
||||
<view class="item u-flex-col u-col-center" v-for="(item, i) in systemList" :key="i"
|
||||
@click="handelClick(item)">
|
||||
<text class="u-font-40 item-icon" :class="item.icon"
|
||||
:style="{ background: item.backgroundColor || '#008cff' }" />
|
||||
<text class="u-font-24 u-line-1 item-text"
|
||||
:style="{color:userInfo.systemId==item.id?'#008cff':''}">{{item.fullName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<JnpfEmpty v-else />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getSystemList
|
||||
} from "@/api/system";
|
||||
import {
|
||||
setMajor,
|
||||
} from "@/api/common";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
systemList: [],
|
||||
userInfo: {}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.keyword = ''
|
||||
this.getUserInfo()
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
onSearchChange(val) {
|
||||
this.init()
|
||||
},
|
||||
init() {
|
||||
getSystemList({
|
||||
keyword: this.keyword
|
||||
}).then(res => {
|
||||
this.systemList = res.data || []
|
||||
})
|
||||
},
|
||||
async getUserInfo() {
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
},
|
||||
handelClick(item) {
|
||||
if (item.id === this.userInfo.systemId) return
|
||||
let query = {
|
||||
majorId: item.id,
|
||||
majorType: "system",
|
||||
menuType: 1,
|
||||
};
|
||||
setMajor(query).then((res) => {
|
||||
this.$u.toast(res.msg);
|
||||
uni.setStorageSync('systemCode', item.enCode)
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 500)
|
||||
}).catch((err) => {
|
||||
this.$u.toast(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.change-system-v {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.change-system-search {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
line-height: 120rpx;
|
||||
}
|
||||
|
||||
.system-box {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.system-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
overflow: auto;
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
margin-bottom: 32rpx;
|
||||
width: 25%;
|
||||
|
||||
.item-icon {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
margin-bottom: 8rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-radius: 30rpx;
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.item-text {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 0 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
193
pages/my/contactUs/index.vue
Normal file
193
pages/my/contactUs/index.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<view class="contacts-v" v-show="show">
|
||||
<view class="contactusBanner">
|
||||
<image :src="contactus" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="contactus u-flex-col">
|
||||
<view class="u-flex items u-m-b-20" v-for="(item,index) in list" @click="Jump(index)" :key="index">
|
||||
<view :class="item.bcg" style="" class="items-iconBox u-m-r-50 u-padding-15">
|
||||
<u-icon :name="item.icon" color="#ffffff" size="54"></u-icon>
|
||||
</view>
|
||||
<view class="u-flex-col u-flex-1">
|
||||
<text>{{item.name}}</text>
|
||||
<text class="againColor">{{item.title}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<u-icon name="arrow-right" color="#969799" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="serviceTime u-flex-col u-p-l-32 u-p-b-20 u-p-t-20">
|
||||
<text class="u-font-xl" type='title'>服务时间</text>
|
||||
<text class="textSize">工作日:{{workingHours}}</text>
|
||||
<text class="textSize">节假日:{{holidayWorkingHours}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="copyright">{{copyright}}</view>
|
||||
<u-popup v-model="showPopup" mode="center">
|
||||
<view class="center-box">
|
||||
<image class="image" :src="wechat_qrcode" :data-path="wechat_qrcode" @longpress="saveImage" />
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import resources from '@/libs/resources.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
contactus: resources.banner.contactus,
|
||||
wechat_qrcode: resources.common.wechat_qrcode,
|
||||
holidayWorkingHours: '9:30-12:00 ,13:30-17:30',
|
||||
workingHours: '8:30-12:00 ,13:00-20:00',
|
||||
tell: '400-6868-969',
|
||||
url: 'https://www.jnpfsoft.com',
|
||||
showPopup: false,
|
||||
list: [{
|
||||
name: '微信公众号',
|
||||
title: '扫码关注官网微信公众号',
|
||||
icon: 'weixin-fill',
|
||||
bcg: 'u-type-success-bg'
|
||||
},
|
||||
{
|
||||
name: '服务热线',
|
||||
title: '400-6868-969',
|
||||
icon: 'kefu-ermai',
|
||||
bcg: 'u-type-warning-bg'
|
||||
},
|
||||
{
|
||||
name: '官方网站',
|
||||
title: 'www.jnpfsoft.com',
|
||||
icon: 'ie',
|
||||
bcg: 'u-type-primary-bg'
|
||||
}
|
||||
],
|
||||
copyright: 'Copyright © 2024 引迈信息技术有限公司出品',
|
||||
show: false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
this.copyright = uni.getStorageSync('copyright') || 'Copyright © 2024 引迈信息技术有限公司出品'
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
this.show = true
|
||||
}, 800)
|
||||
|
||||
},
|
||||
methods: {
|
||||
Jump(index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
this.showPopup = true
|
||||
break;
|
||||
case 1:
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: this.tell,
|
||||
})
|
||||
break;
|
||||
case 2:
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(this.url);
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.navigateTo({
|
||||
url: '/pages/apply/externalLink/index?fullName=福建引迈信息技术有限公司&url=' + encodeURIComponent(
|
||||
this.url)
|
||||
})
|
||||
// #endif
|
||||
break;
|
||||
}
|
||||
},
|
||||
saveImage(e) {
|
||||
// #ifdef APP-PLUS
|
||||
uni.getImageInfo({
|
||||
src: e.currentTarget.dataset.path,
|
||||
success: (res) => {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.path,
|
||||
success: function() {
|
||||
helper.msg('保存成功', 'success');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
width: 100%;
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.contacts-v {
|
||||
width: 100%;
|
||||
|
||||
.contactusBanner {
|
||||
width: 100%;
|
||||
height: 280rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.contactus {
|
||||
margin: 18rpx 16rpx 0;
|
||||
|
||||
.againColor {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.items {
|
||||
padding: 20rpx 32rpx;
|
||||
background-color: #FFFFFF;
|
||||
justify-content: start;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.items-iconBox {
|
||||
border-radius: 50%;
|
||||
height: 88rpx;
|
||||
width: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.serviceTime {
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.center-box {
|
||||
width: 420rpx;
|
||||
height: 420rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.textSize {
|
||||
height: 66rpx;
|
||||
line-height: 66rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
text[type="title"] {
|
||||
height: 86rpx;
|
||||
line-height: 86rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
204
pages/my/contacts/index.vue
Normal file
204
pages/my/contacts/index.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<view class="contacts-v">
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :sticky="true"
|
||||
:down="downOption" :up="upOption" :bottombar="false">
|
||||
<view class="search-box search-box_sticky">
|
||||
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72"
|
||||
:show-action="false" @change="search" bg-color="#f0f2f6" shape="square">
|
||||
</u-search>
|
||||
<view class="organization u-border-bottom">{{keyword?'联系人':'组织列表'}}</view>
|
||||
</view>
|
||||
<view class="list-cell u-p-l-20 u-p-r-20" v-if="!keyword">
|
||||
<scroll-view :scroll-y="true" style="height: 100%">
|
||||
<ly-tree :tree-data="list" :node-key="defaultProps.value" :props="defaultProps"
|
||||
:load="loadNode" lazy :default-expand-all='false' :show-node-icon="true"
|
||||
:defaultExpandedKeys="defaultExpandedKeys" child-visible-for-filter-node
|
||||
@node-click="handleNodeClick" ref="tree">
|
||||
</ly-tree>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="list-cell u-p-l-20 u-p-r-20" v-for="(item, i) in list" :key="i" @click="detail(item)" v-else>
|
||||
<view class="u-border-bottom list-item u-font-28 u-flex" v-if="list.length">
|
||||
<u-avatar :src="baseURL+item.headIcon"></u-avatar>
|
||||
<view class="list-cell-txt">
|
||||
<view class="u-font-30 u-m-b-4" style="color: #303133;font-size: 28rpx;">
|
||||
{{item.realName}}/{{item.account}}
|
||||
</view>
|
||||
<view class="u-font-24 department u-m-t-4">{{item.department}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getOrgAndPosSelector
|
||||
} from '@/api/message.js'
|
||||
import {
|
||||
getUserList
|
||||
} from '@/api/common.js'
|
||||
import resources from '@/libs/resources.js'
|
||||
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
|
||||
export default {
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
downOption: {
|
||||
use: true,
|
||||
auto: true
|
||||
},
|
||||
upOption: {
|
||||
page: {
|
||||
num: 0,
|
||||
size: 20,
|
||||
time: null
|
||||
},
|
||||
empty: {
|
||||
use: true,
|
||||
icon: resources.message.nodata,
|
||||
tip: this.$t('common.noData'),
|
||||
fixed: true,
|
||||
top: "300rpx",
|
||||
},
|
||||
textNoMore: this.$t('app.apply.noMoreData'),
|
||||
},
|
||||
keyword: '',
|
||||
list: [],
|
||||
defaultProps: {
|
||||
label: 'fullName',
|
||||
value: 'id',
|
||||
icon: 'icon',
|
||||
children: 'children',
|
||||
isLeaf: 'isLeaf'
|
||||
},
|
||||
level: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.baseURL
|
||||
},
|
||||
defaultExpandedKeys() {
|
||||
return this.list.length ? [this.list[0].id] : []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
upCallback(page) {
|
||||
let query = this.keyword ? {
|
||||
currentPage: page.num,
|
||||
pageSize: page.size,
|
||||
keyword: this.keyword,
|
||||
organizeId: '',
|
||||
organizeName: '',
|
||||
positionId: ''
|
||||
} : {
|
||||
id: '0',
|
||||
type: 'organize'
|
||||
};
|
||||
|
||||
let method = this.keyword ? getUserList(query) : getOrgAndPosSelector(query);
|
||||
method.then(res => {
|
||||
const list = res.data.list || [];
|
||||
if (!this.keyword) {
|
||||
this.list = list;
|
||||
return this.mescroll.endSuccess(true);
|
||||
}
|
||||
this.mescroll.endSuccess(list.length);
|
||||
if (page.num === 1) this.list = [];
|
||||
this.list = this.list.concat(list);
|
||||
|
||||
}).catch(() => {
|
||||
this.mescroll.endErr();
|
||||
});
|
||||
},
|
||||
loadNode(node, resolve) {
|
||||
let query = {
|
||||
id: node.key || 0,
|
||||
type: node.data.type || 'organize'
|
||||
}
|
||||
getOrgAndPosSelector(query).then(res => {
|
||||
resolve(res.data.list)
|
||||
})
|
||||
},
|
||||
search() {
|
||||
// 节流,避免输入过快多次请求
|
||||
this.searchTimer && clearTimeout(this.searchTimer)
|
||||
this.searchTimer = setTimeout(() => {
|
||||
this.list = [];
|
||||
this.mescroll.resetUpScroll();
|
||||
}, 300)
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
const type = data.data.type
|
||||
const config = {
|
||||
organizeId: type === 'organize' ? data.key : data.data?.organizeId,
|
||||
organizeName: data.label,
|
||||
...(type === 'position' ? {
|
||||
positionId: data.key
|
||||
} : {})
|
||||
};
|
||||
uni.navigateTo({
|
||||
url: '/pages/my/contacts/userList?config=' + encodeURIComponent(JSON.stringify(
|
||||
config)),
|
||||
})
|
||||
},
|
||||
detail(item) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/my/userDetail/index?data=' + encodeURIComponent(JSON.stringify(
|
||||
item))
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #eef0f4;
|
||||
}
|
||||
|
||||
.contacts-v {
|
||||
::v-deep .ly-tree-node__icon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
overflow: hidden;
|
||||
margin-right: 0.5rem;
|
||||
background: #43a1f3;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 1.5rem;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.organization {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.list-item {
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
color: $u-content-color;
|
||||
height: 136rpx;
|
||||
|
||||
.list-cell-txt {
|
||||
margin-left: 20rpx;
|
||||
|
||||
.department {
|
||||
color: #909399;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
147
pages/my/contacts/userList.vue
Normal file
147
pages/my/contacts/userList.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<view class="contacts-v">
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :sticky="true"
|
||||
:down="downOption" :up="upOption" :bottombar="false">
|
||||
<view class="search-box search-box_sticky">
|
||||
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72"
|
||||
:show-action="false" @change="search" bg-color="#f0f2f6" shape="square">
|
||||
</u-search>
|
||||
</view>
|
||||
<view class="list-cell u-p-l-20 u-p-r-20" v-for="(item, i) in list" :key="i" @click="detail(item)">
|
||||
<view class="u-border-bottom list-item u-font-28 u-flex">
|
||||
<u-avatar :src="baseURL+item.headIcon"></u-avatar>
|
||||
<view class="list-cell-txt">
|
||||
<view class="u-font-30 u-m-b-4" style="color: #303133;font-size: 28rpx;">
|
||||
{{item.realName}}/{{item.account}}
|
||||
</view>
|
||||
<view class="u-font-24 department u-m-t-4">{{item.department}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserList
|
||||
} from '@/api/common.js'
|
||||
import resources from '@/libs/resources.js'
|
||||
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
|
||||
export default {
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
downOption: {
|
||||
use: true,
|
||||
auto: true
|
||||
},
|
||||
upOption: {
|
||||
page: {
|
||||
num: 0,
|
||||
size: 20,
|
||||
time: null
|
||||
},
|
||||
empty: {
|
||||
use: true,
|
||||
icon: resources.message.nodata,
|
||||
tip: this.$t('common.noData'),
|
||||
fixed: true,
|
||||
top: "300rpx",
|
||||
},
|
||||
textNoMore: this.$t('app.apply.noMoreData'),
|
||||
},
|
||||
keyword: '',
|
||||
list: [],
|
||||
organizeId: '',
|
||||
organizeName: '',
|
||||
positionId: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.baseURL
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
const config = JSON.parse(decodeURIComponent(e.config))
|
||||
this.organizeId = config.organizeId
|
||||
this.organizeName = config.organizeName
|
||||
this.positionId = config.positionId
|
||||
uni.setNavigationBarTitle({
|
||||
title: config.organizeName
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
upCallback(page) {
|
||||
let query = {
|
||||
currentPage: page.num,
|
||||
pageSize: page.size,
|
||||
keyword: this.keyword,
|
||||
organizeId: this.organizeId,
|
||||
organizeName: this.organizeName,
|
||||
positionId: this.positionId || ""
|
||||
}
|
||||
getUserList(query).then(res => {
|
||||
this.mescroll.endSuccess(res.data.list.length);
|
||||
if (page.num == 1) this.list = [];
|
||||
const list = res.data.list || [];
|
||||
this.list = this.list.concat(list);
|
||||
}).catch(() => {
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
},
|
||||
search() {
|
||||
// 节流,避免输入过快多次请求
|
||||
this.searchTimer && clearTimeout(this.searchTimer)
|
||||
this.searchTimer = setTimeout(() => {
|
||||
this.list = [];
|
||||
this.mescroll.resetUpScroll();
|
||||
}, 300)
|
||||
},
|
||||
detail(item) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/my/userDetail/index?data=' + encodeURIComponent(JSON.stringify(
|
||||
item))
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #eef0f4;
|
||||
}
|
||||
|
||||
.contacts-v {
|
||||
|
||||
.organization {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.list-item {
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
color: $u-content-color;
|
||||
height: 136rpx;
|
||||
|
||||
.list-cell-txt {
|
||||
margin-left: 20rpx;
|
||||
|
||||
.department {
|
||||
color: #909399;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
177
pages/my/identity/index.vue
Normal file
177
pages/my/identity/index.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<view class="page_v u-flex-col">
|
||||
<view class="lists_box u-m-b-20" v-if="show" v-for="(item,index) in list" :key="index"
|
||||
:class="item.isDefault ? 'active' : '' " @click="clickRadio(item)">
|
||||
<view class="icon-checked-box" v-if="item.isDefault">
|
||||
<text>默认</text>
|
||||
<view class="icon-checked">
|
||||
<u-icon name="checkbox-mark" color="#fff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list_inner">
|
||||
<text class="icon-ym" :class="item.icon"></text>
|
||||
<text class="txt">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<JnpfEmpty v-if="!show"></JnpfEmpty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserOrganizes,
|
||||
setMajor,
|
||||
} from '@/api/common'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
majorType: '',
|
||||
show: true,
|
||||
disabled: false,
|
||||
userInfo: {}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
this.majorType = e.majorType
|
||||
this.getUserOrganizes()
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.$t('app.my.myIdentity')
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getUserOrganizes() {
|
||||
let data = this.userInfo?.standingList || []
|
||||
if (!data.length) return this.show = this.list.length > 0
|
||||
this.list = JSON.parse(JSON.stringify(data));
|
||||
this.show = this.list.length > 0
|
||||
this.list.map(o => {
|
||||
if (o.currentStanding) o.isDefault = true
|
||||
})
|
||||
},
|
||||
clickRadio(item) {
|
||||
if (this.disabled || item.isDefault) return
|
||||
this.changeMajor(item.id)
|
||||
},
|
||||
change(id) {
|
||||
this.list.map((o, i) => {
|
||||
o.isDefault = false;
|
||||
if (o.id === id) o.isDefault = true;
|
||||
})
|
||||
},
|
||||
changeMajor(majorId) {
|
||||
let query = {
|
||||
majorId,
|
||||
majorType: this.majorType
|
||||
}
|
||||
setMajor(query).then(res => {
|
||||
this.$u.toast(res.msg)
|
||||
if (res.code === 200) {
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.page_v {
|
||||
/* #ifdef MP */
|
||||
background-color: #f0f2f6;
|
||||
/* #endif */
|
||||
padding: 20rpx 20rpx 0 20rpx;
|
||||
|
||||
.active {
|
||||
border: 1rpx solid #2979FF;
|
||||
color: #2979FF;
|
||||
|
||||
.icon-ym-organization {
|
||||
&::before {
|
||||
color: #2979FF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lists_box {
|
||||
width: 100%;
|
||||
min-height: 160rpx;
|
||||
border-radius: 8rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.icon-checked-box {
|
||||
display: flex;
|
||||
width: 140rpx;
|
||||
height: 80rpx;
|
||||
position: absolute;
|
||||
transform: scale(0.9);
|
||||
right: -4rpx;
|
||||
bottom: -2rpx;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.icon-checked {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border: 40rpx solid #1890ff;
|
||||
border-left: 40rpx solid transparent;
|
||||
border-top: 40rpx solid transparent;
|
||||
border-bottom-right-radius: 12rpx;
|
||||
position: absolute;
|
||||
transform: scale(0.95);
|
||||
right: -8rpx;
|
||||
bottom: -6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.list_inner {
|
||||
width: 100%;
|
||||
min-height: 160rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 0 20rpx;
|
||||
align-items: center;
|
||||
|
||||
.icon-ym-wf-outgoingApply {
|
||||
&::before {
|
||||
margin-right: 6rpx;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-ym-organization {
|
||||
&::before {
|
||||
margin-right: 6rpx;
|
||||
font-size: 40rpx;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.txt_icon {}
|
||||
|
||||
.txt {
|
||||
width: 100%;
|
||||
align-items: flex-end;
|
||||
word-wrap: break-word;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
314
pages/my/modifyPsd/index.vue
Normal file
314
pages/my/modifyPsd/index.vue
Normal file
@@ -0,0 +1,314 @@
|
||||
<template>
|
||||
<view class="jnpf-wrap jnpf-wrap-workflow">
|
||||
<view class="" style="background-color: #fff">
|
||||
<u-form :model="dataForm" :rules="rules" ref="dataForm" :errorType="['toast']" label-position="left"
|
||||
label-width="150" label-align="left">
|
||||
<view v-if="type == 'mobilePhone'">
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-form-item label="新手机" prop="mobilePhone" required>
|
||||
<u-input v-model="dataForm[type]" placeholder="请输入"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="type == 'email'">
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-form-item label="新邮箱" prop="email" required>
|
||||
<u-input v-model="dataForm[type]" placeholder="请输入"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="type == 'password'">
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-form-item label="旧密码" prop="oldPassword" required>
|
||||
<u-input v-model="dataForm.oldPassword" placeholder="请输入" type="password"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-form-item label="新密码" prop="password" required>
|
||||
<u-input v-model="dataForm.password" placeholder="请输入" type="password"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-form-item label="重复密码" prop="repeatPsd" required>
|
||||
<u-input v-model="dataForm.repeatPsd" placeholder="请输入" type="password"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-form-item label="验证码" prop="code" required>
|
||||
<view class="u-flex">
|
||||
<u-input v-model="dataForm.code" placeholder="请输入"></u-input>
|
||||
<view style="flex: 0.1">
|
||||
<u-image :showLoading="true" :src="baseURL + imgUrl" width="130px" height="38px"
|
||||
@click="changeCode">
|
||||
</u-image>
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 底部按钮 -->
|
||||
<view class="flowBefore-actions">
|
||||
<u-button class="buttom-btn" type="primary" @click.stop="dataFormSubmit">保存</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import md5Libs from "@/uni_modules/vk-uview-ui/libs/function/md5";
|
||||
import {
|
||||
updatePassword,
|
||||
updateUserInfo
|
||||
} from "@/api/common.js";
|
||||
import {
|
||||
useUserStore
|
||||
} from "@/store/modules/user";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
var validatePass = (rule, value, callback) => {
|
||||
// const passwordreg = /(?=.*\d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{6,16}/
|
||||
//是否包含数字
|
||||
const containsNumbers = /[0-9]+/;
|
||||
//是否包含小写字符
|
||||
const includeLowercaseLetters = /[a-z]+/;
|
||||
//是否包含大写字符
|
||||
const includeUppercaseLetters = /[A-Z]+/;
|
||||
//是否包含字符
|
||||
const containsCharacters = /\W/;
|
||||
if (value === "") {
|
||||
callback(new Error("新密码不能为空"));
|
||||
} else if (this.baseForm.passwordStrengthLimit == 1) {
|
||||
if (this.baseForm.passwordLengthMin) {
|
||||
if (value.length < this.baseForm.passwordLengthMinNumber) {
|
||||
callback(
|
||||
new Error(
|
||||
"新密码长度不能小于" +
|
||||
this.baseForm.passwordLengthMinNumber +
|
||||
"位"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (this.baseForm.containsNumbers) {
|
||||
if (!containsNumbers.test(value)) {
|
||||
callback(new Error("新密码必须包含数字"));
|
||||
}
|
||||
}
|
||||
if (this.baseForm.includeLowercaseLetters) {
|
||||
if (!includeLowercaseLetters.test(value)) {
|
||||
callback(new Error("新密码必须包含小写字母"));
|
||||
}
|
||||
}
|
||||
if (this.baseForm.includeUppercaseLetters) {
|
||||
if (!includeUppercaseLetters.test(value)) {
|
||||
callback(new Error("新密码必须包含大写字字母"));
|
||||
}
|
||||
}
|
||||
if (this.baseForm.containsCharacters) {
|
||||
if (!containsCharacters.test(value)) {
|
||||
callback(new Error("新密码必须包含字符"));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
var validatePass2 = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("重复密码不能为空"));
|
||||
} else if (value !== this.dataForm.password) {
|
||||
callback(new Error("两次密码输入不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
var validatPphone = (rule, value, callback) => {
|
||||
// 手机号正则表达式
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
if (value === "" || !value) {
|
||||
callback(new Error('请输入手机号'));
|
||||
} else if (!phoneRegex.test(value)) {
|
||||
callback(new Error("手机号格式错误"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
var validateEmail = (rule, value, callback) => {
|
||||
// 邮箱验证正则表达式
|
||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
if (value === "" || !value) {
|
||||
callback(new Error("请输入邮箱"));
|
||||
} else if (!emailRegex.test(value)) {
|
||||
callback(new Error("邮箱格式错误"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
return {
|
||||
imgUrl: "",
|
||||
timestamp: "",
|
||||
dataForm: {
|
||||
oldPassword: "",
|
||||
password: "",
|
||||
repeatPsd: "",
|
||||
code: "",
|
||||
timestamp: "",
|
||||
mobilePhone: "",
|
||||
email: "",
|
||||
},
|
||||
baseForm: {
|
||||
passwordStrengthLimit: 0,
|
||||
passwordLengthMin: false,
|
||||
passwordLengthMinNumber: 0,
|
||||
containsNumbers: false,
|
||||
includeLowercaseLetters: false,
|
||||
includeUppercaseLetters: false,
|
||||
containsCharacters: false,
|
||||
},
|
||||
rules: {
|
||||
oldPassword: [{
|
||||
required: true,
|
||||
message: "旧密码不能为空",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
password: [{
|
||||
required: true,
|
||||
validator: validatePass,
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
repeatPsd: [{
|
||||
required: true,
|
||||
validator: validatePass2,
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
code: [{
|
||||
required: true,
|
||||
message: "验证码不能为空",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
mobilePhone: [{
|
||||
required: true,
|
||||
validator: validatPphone,
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
email: [{
|
||||
required: true,
|
||||
validator: validateEmail,
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
type: "",
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.baseURL;
|
||||
},
|
||||
},
|
||||
onLoad(e) {
|
||||
this.loading = false;
|
||||
const config = JSON.parse(decodeURIComponent(e.config));
|
||||
this.type = config.type;
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.type == "mobilePhone" ?
|
||||
"修改手机" : this.type == "email" ?
|
||||
"修改邮箱" : "修改密码",
|
||||
});
|
||||
if (this.type != "password")
|
||||
return (this.dataForm[this.type] = config.vuale);
|
||||
this.changeCode();
|
||||
this.initData();
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.dataForm.setRules(this.rules);
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
this.$nextTick(() => {
|
||||
const config = uni.getStorageSync("sysConfigInfo") || {};
|
||||
const {
|
||||
passwordLengthMin = false,
|
||||
containsNumbers = false,
|
||||
includeLowercaseLetters = false,
|
||||
includeUppercaseLetters = false,
|
||||
containsCharacters = false,
|
||||
passwordStrengthLimit = 0,
|
||||
passwordLengthMinNumber = 0,
|
||||
} = config;
|
||||
Object.assign(this.baseForm, {
|
||||
passwordLengthMin: !!passwordLengthMin,
|
||||
containsNumbers: !!containsNumbers,
|
||||
includeLowercaseLetters: !!includeLowercaseLetters,
|
||||
includeUppercaseLetters: !!includeUppercaseLetters,
|
||||
containsCharacters: !!containsCharacters,
|
||||
passwordStrengthLimit: Number(passwordStrengthLimit) || 0,
|
||||
passwordLengthMinNumber: Number(passwordLengthMinNumber) || 0,
|
||||
});
|
||||
});
|
||||
},
|
||||
changeCode() {
|
||||
let timestamp = Math.random();
|
||||
this.timestamp = timestamp;
|
||||
this.imgUrl = `/api/file/ImageCode/${timestamp}`;
|
||||
},
|
||||
dataFormSubmit() {
|
||||
this.$refs["dataForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
let query = {};
|
||||
if (this.type == "mobilePhone" || this.type == "email") {
|
||||
query = {
|
||||
[this.type]: this.dataForm[this.type],
|
||||
};
|
||||
updateUserInfo(query)
|
||||
.then((res) => {
|
||||
this.dataForm[this.type] = query[this.type];
|
||||
this.$u.toast(res.msg);
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
query = {
|
||||
oldPassword: md5Libs.md5(this.dataForm.oldPassword),
|
||||
password: md5Libs.md5(this.dataForm.password),
|
||||
code: this.dataForm.code,
|
||||
timestamp: this.timestamp,
|
||||
};
|
||||
updatePassword(query)
|
||||
.then((res) => {
|
||||
this.$u.toast(res.msg);
|
||||
this.loading = false;
|
||||
const userStore = useUserStore();
|
||||
userStore.logout().then(() => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/login/index",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.changeImg();
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.jnpf-wrap.jnpf-wrap-workflow {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
:deep(.u-form-item) {
|
||||
background-color: #fff;
|
||||
min-height: 112rpx;
|
||||
}
|
||||
</style>
|
||||
183
pages/my/organization/index.vue
Normal file
183
pages/my/organization/index.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<view class="page_v u-flex-col">
|
||||
<view class="u-m-t-20 u-m-b-20">
|
||||
<JnpfAlert type="warning" :title="description" effect="dark" />
|
||||
</view>
|
||||
<view class="organization_box u-m-b-20" v-if="show" v-for="(item,index) in list" :key="index"
|
||||
:class="item.isDefault ? 'active' : '' " @click="clickRadio(item)">
|
||||
<view class="icon-checked-box" v-if="item.isDefault">
|
||||
<text>默认</text>
|
||||
<view class="icon-checked">
|
||||
<u-icon name="checkbox-mark" color="#fff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list_inner u-flex-col">
|
||||
<view class="inner_item">
|
||||
<text>所属组织</text>
|
||||
<text class="txt u-line-1"
|
||||
:style="{color:item.isDefault ? '#2979FF' : ''}">{{item.orgTreeName}}</text>
|
||||
</view>
|
||||
<view class="inner_item">
|
||||
<text>任职岗位</text>
|
||||
<text class="txt u-line-1" :style="{color:item.isDefault ? '#2979FF' : ''}">{{item.fullName}}</text>
|
||||
</view>
|
||||
<view class="inner_item">
|
||||
<text>上级岗位</text>
|
||||
<text class="txt u-line-1"
|
||||
:style="{color:item.isDefault ? '#2979FF' : ''}">{{ item.parentName || '-' }}</text>
|
||||
</view>
|
||||
<view class="inner_item">
|
||||
<text>上级责任人</text>
|
||||
<text class="txt u-line-1"
|
||||
:style="{color:item.isDefault ? '#2979FF' : ''}">{{item.managerName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<JnpfEmpty v-if="!show"></JnpfEmpty>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserPositions,
|
||||
setMajor,
|
||||
} from '@/api/common'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
majorType: '',
|
||||
show: true,
|
||||
disabled: false,
|
||||
userInfo: {},
|
||||
description: '默认组织仅逐级审批时使用'
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
this.majorType = e.majorType
|
||||
this.getUserPositions()
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.$t('app.my.organization')
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getUserPositions() {
|
||||
getUserPositions().then(res => {
|
||||
let data = res.data || []
|
||||
if (!data.length) return this.show = this.list.length > 0
|
||||
this.list = JSON.parse(JSON.stringify(data));
|
||||
this.show = this.list.length > 0
|
||||
this.list.map(o => {
|
||||
if (o.currentStanding) o.isDefault = true
|
||||
})
|
||||
})
|
||||
},
|
||||
clickRadio(item) {
|
||||
if (this.disabled || item.isDefault) return
|
||||
this.changeMajor(item.id)
|
||||
},
|
||||
change(id) {
|
||||
this.list.map((o, i) => {
|
||||
o.isDefault = false;
|
||||
if (o.id === id) o.isDefault = true;
|
||||
})
|
||||
},
|
||||
changeMajor(majorId) {
|
||||
let query = {
|
||||
majorId,
|
||||
majorType: this.majorType
|
||||
}
|
||||
setMajor(query).then(res => {
|
||||
this.$u.toast(res.msg)
|
||||
if (res.code === 200) {
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.page_v {
|
||||
/* #ifdef MP */
|
||||
background-color: #f0f2f6;
|
||||
/* #endif */
|
||||
padding: 0 20rpx;
|
||||
|
||||
.active {
|
||||
border: 1rpx solid #2979FF;
|
||||
color: #2979FF;
|
||||
}
|
||||
|
||||
.organization_box {
|
||||
width: 100%;
|
||||
border-radius: 8rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
|
||||
.icon-checked-box {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
width: 140rpx;
|
||||
height: 80rpx;
|
||||
transform: scale(0.9);
|
||||
right: -4rpx;
|
||||
bottom: -2rpx;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.icon-checked {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border: 40rpx solid #1890ff;
|
||||
border-left: 40rpx solid transparent;
|
||||
border-top: 40rpx solid transparent;
|
||||
border-bottom-right-radius: 12rpx;
|
||||
position: absolute;
|
||||
transform: scale(0.95);
|
||||
right: -8rpx;
|
||||
bottom: -6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.list_inner {
|
||||
width: 100%;
|
||||
min-height: 160rpx;
|
||||
padding: 0 20rpx;
|
||||
align-items: flex-start;
|
||||
|
||||
.inner_item {
|
||||
width: 100%;
|
||||
padding: 20rpx 0;
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.txt {
|
||||
flex: 1.2;
|
||||
white-space: nowrap;
|
||||
color: #606266;
|
||||
width: 400rpx;
|
||||
overflow-x: auto;
|
||||
display: inline-flex;
|
||||
margin-left: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
208
pages/my/personalData/components/personalData.vue
Normal file
208
pages/my/personalData/components/personalData.vue
Normal file
@@ -0,0 +1,208 @@
|
||||
<template>
|
||||
<view class="jnpf-wrap personalData">
|
||||
<view style="background-color: #fff;" class="u-p-l-20 u-p-r-20">
|
||||
<u-form :model="dataForm" :errorType="['toast']" label-position="left" label-width="150" label-align="right"
|
||||
ref="dataForm">
|
||||
<u-form-item label="姓名" prop='realName' required>
|
||||
<u-input input-align='right' v-model="dataForm.realName" placeholder="请输入"></u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="民族">
|
||||
<JnpfSelect v-model="dataForm.nation" placeholder="请选择" :options='nationOptions' />
|
||||
</u-form-item>
|
||||
<u-form-item label="性别">
|
||||
<JnpfSelect v-model="dataForm.gender" placeholder="请选择" :options='genderOptions' :props='props' />
|
||||
</u-form-item>
|
||||
<u-form-item label="籍贯">
|
||||
<u-input input-align='right' v-model="dataForm.nativePlace" placeholder="请输入"></u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="证件类型">
|
||||
<JnpfSelect v-model="dataForm.certificatesType" placeholder="请选择"
|
||||
:options='certificatesTypeOptions' />
|
||||
</u-form-item>
|
||||
<u-form-item label="证件号码">
|
||||
<u-input input-align='right' v-model="dataForm.certificatesNumber" placeholder="请输入">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="文化程度">
|
||||
<JnpfSelect v-model="dataForm.education" placeholder="请选择" :options='educationOptions' />
|
||||
</u-form-item>
|
||||
<u-form-item label="出生年月">
|
||||
<JnpfDatePicker v-model="dataForm.birthday" placeholder="请选择" />
|
||||
</u-form-item>
|
||||
<u-form-item label="办公电话">
|
||||
<u-input input-align='right' v-model="dataForm.telePhone" placeholder="请输入">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="办公座机">
|
||||
<u-input input-align='right' v-model="dataForm.landline" placeholder="请输入">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="紧急联系">
|
||||
<u-input input-align='right' v-model="dataForm.urgentContacts" placeholder="请输入">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="紧急电话">
|
||||
<u-input input-align='right' v-model="dataForm.urgentTelePhone" placeholder="请输入">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="通讯地址">
|
||||
<u-input input-align='right' v-model="dataForm.postalAddress" placeholder="请输入">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item label="自我介绍">
|
||||
<u-input input-align='right' v-model="dataForm.signature" placeholder="请输入" type="textarea" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<view class="flowBefore-actions">
|
||||
<u-button class="buttom-btn" type="primary" @click='submit'>保存</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
UpdateUser
|
||||
} from '@/api/common'
|
||||
import {
|
||||
useBaseStore
|
||||
} from '@/store/modules/base'
|
||||
const baseStore = useBaseStore()
|
||||
export default {
|
||||
props: {
|
||||
personalData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const data = {
|
||||
show: false,
|
||||
props: {
|
||||
label: 'fullName',
|
||||
value: 'enCode'
|
||||
},
|
||||
dataForm: {
|
||||
birthday: null,
|
||||
certificatesNumber: "",
|
||||
certificatesType: "",
|
||||
education: "",
|
||||
email: "",
|
||||
gender: "",
|
||||
landline: "",
|
||||
mobilePhone: "",
|
||||
nation: "",
|
||||
nativePlace: "",
|
||||
postalAddress: "",
|
||||
realName: "",
|
||||
signature: null,
|
||||
telePhone: "",
|
||||
urgentContacts: "",
|
||||
urgentTelePhone: "",
|
||||
id: null
|
||||
},
|
||||
nationOptions: [],
|
||||
genderOptions: [],
|
||||
certificatesTypeOptions: [],
|
||||
educationOptions: [],
|
||||
rules: {
|
||||
realName: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['change', 'blur'],
|
||||
}]
|
||||
}
|
||||
}
|
||||
return data
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.baseURL
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
personalData: {
|
||||
handler(val) {
|
||||
this.init()
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.dataForm.setRules(this.rules);
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
let initData = JSON.parse(JSON.stringify(this.personalData))
|
||||
for (let key in initData) {
|
||||
for (let k in this.dataForm) {
|
||||
if (key === k) {
|
||||
this.dataForm[key] = initData[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
this.getOptions()
|
||||
},
|
||||
getOptions() {
|
||||
baseStore.getDictionaryData({
|
||||
sort: 'Education'
|
||||
}).then((res) => {
|
||||
this.educationOptions = JSON.parse(JSON.stringify(res))
|
||||
baseStore.getDictionaryData({
|
||||
sort: 'certificateType'
|
||||
}).then((res) => {
|
||||
this.certificatesTypeOptions = JSON.parse(JSON.stringify(res))
|
||||
})
|
||||
baseStore.getDictionaryData({
|
||||
sort: 'sex'
|
||||
}).then(res => {
|
||||
this.genderOptions = JSON.parse(JSON.stringify(res))
|
||||
})
|
||||
baseStore.getDictionaryData({
|
||||
sort: 'Nation'
|
||||
}).then(res => {
|
||||
this.nationOptions = JSON.parse(JSON.stringify(res))
|
||||
})
|
||||
})
|
||||
this.show = true
|
||||
},
|
||||
submit() {
|
||||
this.$refs.dataForm.validate(valid => {
|
||||
if (valid) {
|
||||
UpdateUser(this.dataForm).then(res => {
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
duration: 800,
|
||||
icon: 'none'
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.slot-btn {
|
||||
width: 329rpx;
|
||||
height: 140rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgb(244, 245, 246);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.slot-btn__hover {
|
||||
background-color: rgb(235, 236, 238);
|
||||
}
|
||||
</style>
|
||||
63
pages/my/personalData/index.vue
Normal file
63
pages/my/personalData/index.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<view class="personalData-v">
|
||||
<view class="content">
|
||||
<personalData ref="personalData" :personalData="baseInfo"></personalData>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import personalData from './components/personalData.vue';
|
||||
export default {
|
||||
components: {
|
||||
personalData,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
baseInfo: {}
|
||||
};
|
||||
},
|
||||
onLoad(e) {
|
||||
// this.baseInfo = JSON.parse(e.baseInfo)
|
||||
// #ifdef MP-WEIXIN || APP-HARMONY
|
||||
this.baseInfo = JSON.parse(decodeURIComponent(e.baseInfo))
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN || APP-HARMONY
|
||||
this.baseInfo = JSON.parse(decodeURIComponent(this.jnpf.encodeContent(e.baseInfo)))
|
||||
|
||||
// #endif
|
||||
|
||||
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.notice-warp {
|
||||
height: 100rpx;
|
||||
|
||||
.search-box {
|
||||
padding: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.personalData-v {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 100rpx;
|
||||
|
||||
::v-deep .buttom-btn {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
180
pages/my/personalSetting/components/commonText.vue
Normal file
180
pages/my/personalSetting/components/commonText.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<view class="common_v">
|
||||
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption"
|
||||
:bottombar="false" top="120">
|
||||
<SwipeItem :list="commonWordsList" :buttons="actionData" @action="bindClick" ref="swipeItem" :marginB="20">
|
||||
<template v-slot="{ item }">
|
||||
<view class="action-item">
|
||||
{{item.commonWordsText}}
|
||||
</view>
|
||||
</template>
|
||||
</SwipeItem>
|
||||
</mescroll-uni>
|
||||
<view class="flowBefore-actions">
|
||||
<u-button class="buttom-btn" type="primary" @click='editCommonWord'>添加常用语</u-button>
|
||||
</view>
|
||||
</view>
|
||||
<uni-popup ref="inputDialog" type="dialog">
|
||||
<uni-popup-dialog ref="inputClose" @confirm="confirm" mode="input" class="popup-dialog"
|
||||
borderRadius="20px 20px 20px 20px" beforeClose @close="close" title="审批常用语">
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<u-input v-model="commonWordsText" type="textarea" placeholder="请输入内容" :auto-height="false"
|
||||
maxlength="99999" height="150" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<textarea v-model="commonWordsText" :maxlength="99999" placeholder="请输入内容"
|
||||
style="padding: 20rpx 0; "></textarea>
|
||||
<!-- #endif -->
|
||||
</uni-popup-dialog>
|
||||
</uni-popup>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
commonWords,
|
||||
Create,
|
||||
Update,
|
||||
Delete
|
||||
} from "@/api/commonWords.js";
|
||||
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
|
||||
import resources from '@/libs/resources.js'
|
||||
import SwipeItem from "@/components/SwipeItem/index"
|
||||
export default {
|
||||
mixins: [MescrollMixin],
|
||||
components: {
|
||||
SwipeItem
|
||||
},
|
||||
props: {
|
||||
showCommonWords: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
downOption: {
|
||||
use: true,
|
||||
auto: true
|
||||
},
|
||||
upOption: {
|
||||
page: {
|
||||
num: 0,
|
||||
size: 30,
|
||||
time: null
|
||||
},
|
||||
empty: {
|
||||
use: true,
|
||||
icon: resources.message.nodata,
|
||||
tip: this.$t('common.noData'),
|
||||
fixed: true,
|
||||
top: "360rpx"
|
||||
},
|
||||
textNoMore: this.$t('app.apply.noMoreData')
|
||||
},
|
||||
actionData: [{
|
||||
style: {
|
||||
backgroundColor: '#1890ff'
|
||||
},
|
||||
value: 'edit',
|
||||
text: '编辑'
|
||||
},
|
||||
{
|
||||
style: {
|
||||
backgroundColor: '#F56C6C'
|
||||
},
|
||||
value: 'delete',
|
||||
text: '删除'
|
||||
}
|
||||
],
|
||||
commonWordsText: '',
|
||||
commonWordsData: {},
|
||||
commonWordsList: [],
|
||||
showAdd: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
upCallback(page) {
|
||||
const query = {
|
||||
currentPage: page.num,
|
||||
pageSize: page.size,
|
||||
commonWordsType: 1
|
||||
}
|
||||
commonWords(query).then(res => {
|
||||
const curPageData = res.data.list || [] // 当前页数据
|
||||
if (page.num == 1) this.commonWordsList = []; // 第一页需手动制空列表
|
||||
this.mescroll.endSuccess(res.data.list.length);
|
||||
this.commonWordsList = this.commonWordsList.concat(curPageData); //追加新数据
|
||||
}).catch(() => {
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
},
|
||||
bindClick(item) {
|
||||
if (item.btn.value == 'edit') this.editCommonWord(item.item)
|
||||
if (item.btn.value == 'delete') this.delCommonWord(item.item)
|
||||
},
|
||||
editCommonWord(item) {
|
||||
this.$refs.inputDialog.open()
|
||||
let data = {
|
||||
commonWordsText: "",
|
||||
enabledMark: 1,
|
||||
id: 0,
|
||||
sortCode: 0,
|
||||
systemIds: [],
|
||||
systemNames: [],
|
||||
};
|
||||
if (item.id) {
|
||||
this.commonWordsText = item.commonWordsText;
|
||||
this.commonWordsData = {
|
||||
...item,
|
||||
systemIds: [],
|
||||
systemNames: []
|
||||
};
|
||||
} else {
|
||||
this.commonWordsText = "";
|
||||
this.commonWordsData = data;
|
||||
}
|
||||
},
|
||||
delCommonWord(item) {
|
||||
Delete(item.id).then(res => {
|
||||
this.$u.toast(res.msg)
|
||||
this.mescroll.resetUpScroll()
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.$refs.inputDialog.close()
|
||||
},
|
||||
confirm() {
|
||||
this.commonWordsData.commonWordsText = this.commonWordsText;
|
||||
this.commonWordsData.commonWordsType = 1
|
||||
if (!this.commonWordsText) return this.$u.toast(`审批常用语不能为空`);
|
||||
let funs = this.commonWordsData.id === 0 ? Create : Update;
|
||||
funs(this.commonWordsData).then((res) => {
|
||||
this.close()
|
||||
this.commonWordsText = "";
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: "none",
|
||||
complete: () => {
|
||||
this.mescroll.resetUpScroll()
|
||||
},
|
||||
});
|
||||
}).catch(() => {
|
||||
this.close()
|
||||
this.mescroll.resetUpScroll()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.action-item {
|
||||
width: 100%;
|
||||
min-height: 3.6rem;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
padding: 10rpx 20rpx;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
256
pages/my/personalSetting/components/signList.vue
Normal file
256
pages/my/personalSetting/components/signList.vue
Normal file
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="page_v u-flex-col">
|
||||
<view>
|
||||
<view v-if="show" v-for="(item,index) in signImg" :key="index" :class="item.isDefault ? 'active' : '' "
|
||||
class="lists_box" @longpress="handleTouchStart(item,index)">
|
||||
<view class="signImgBox">
|
||||
<image :src="item.signImg" mode="scaleToFill" class="signImg"></image>
|
||||
</view>
|
||||
<view class="icon-checked-box" v-if="item.isDefault">
|
||||
<view class="icon-checked">
|
||||
<u-icon name="checkbox-mark" color="#fff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sign-mask" v-if="!item.isDefault && item.isSet" :id="index">
|
||||
<view class="sign-mask-btn">
|
||||
<u-button @click.prevent="del(item.id,index)">删除</u-button>
|
||||
<u-button type="primary" @click.prevent="setDefault(item.id,index)">设为默认</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<JnpfSign ref="signRef" @change="signData" :showBtn="false" />
|
||||
<JnpfEmpty v-if="!show" />
|
||||
</view>
|
||||
<view class="flowBefore-actions">
|
||||
<u-button class="buttom-btn" type="primary" @click='showAction = true'>添加签名</u-button>
|
||||
</view>
|
||||
<u-action-sheet @click="handleAction" :list="actionList" :tips="{ text: '' , color: '#000' , fontSize: 30 }"
|
||||
v-model="showAction">
|
||||
</u-action-sheet>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
pathToBase64
|
||||
} from '@/libs/file.js'
|
||||
import {
|
||||
getSignImgList,
|
||||
createSignImg,
|
||||
setDefSignImg,
|
||||
delSignImg
|
||||
} from '@/api/common'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
show: true,
|
||||
signImg: [],
|
||||
isSet: false,
|
||||
showAction: false,
|
||||
actionList: [{
|
||||
text: '在线签名',
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
text: '图片上传',
|
||||
id: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.comUploadUrl
|
||||
},
|
||||
token() {
|
||||
return uni.getStorageSync('token')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getSignImgList()
|
||||
},
|
||||
methods: {
|
||||
getSignImgList() {
|
||||
getSignImgList().then(res => {
|
||||
let signList = JSON.parse(JSON.stringify(res.data)) || []
|
||||
this.show = signList.length > 0 ? true : false
|
||||
this.signImg = signList.map(o => ({
|
||||
isSet: false,
|
||||
...o
|
||||
}))
|
||||
})
|
||||
},
|
||||
signData(e) {
|
||||
if (e) {
|
||||
let data = {
|
||||
'signImg': e,
|
||||
'isDefault': 0
|
||||
}
|
||||
createSignImg(data).then((res) => {
|
||||
this.getSignImgList()
|
||||
})
|
||||
}
|
||||
},
|
||||
handleTouchStart(item, index) {
|
||||
this.signImg.map((o, i) => {
|
||||
o.isSet = false
|
||||
})
|
||||
item.isSet = true
|
||||
},
|
||||
del(id, index) {
|
||||
delSignImg(id, index).then((res) => {
|
||||
this.signImg.splice(index, 1)
|
||||
})
|
||||
},
|
||||
setDefault(id, index) {
|
||||
let userInfo = uni.getStorageSync('userInfo')
|
||||
setDefSignImg(id).then((res) => {
|
||||
this.signImg.map((o, i) => {
|
||||
o.isDefault = false;
|
||||
if (index == i) {
|
||||
o.isDefault = true
|
||||
o.isSet = false
|
||||
userInfo.signImg = o.signImg
|
||||
uni.setStorageSync('userInfo', userInfo)
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
},
|
||||
handleAction(e) {
|
||||
if (e == 0) {
|
||||
this.$refs.signRef.addSign();
|
||||
} else {
|
||||
uni.chooseImage({
|
||||
count: 1, //默认9
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album'],
|
||||
success: (res) => {
|
||||
let tempFilePaths = res.tempFilePaths[0]
|
||||
// #ifdef H5
|
||||
let isAccept = new RegExp('image/*').test(res.tempFiles[0].type)
|
||||
if (!isAccept) return this.$u.toast(`请上传图片`)
|
||||
// #endif
|
||||
if ((res.tempFiles[0].size / 1024) > 500) return this.$u.toast('操作失败,图片大小超出500K')
|
||||
// #ifdef APP-HARMONY
|
||||
this.harmony(tempFilePaths)
|
||||
// #endif
|
||||
// #ifndef APP-HARMONY
|
||||
pathToBase64(tempFilePaths).then(base64 => {
|
||||
this.signData(base64)
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
harmony(tempFilePaths) {
|
||||
uni.uploadFile({
|
||||
url: this.baseURL + 'imgToBase64',
|
||||
filePath: tempFilePaths,
|
||||
name: 'file',
|
||||
header: {
|
||||
'Authorization': this.token
|
||||
},
|
||||
success: (uploadFileRes) => {
|
||||
let res = JSON.parse(uploadFileRes.data)
|
||||
this.signData(res.data)
|
||||
},
|
||||
fail: (err) => {}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.page_v {
|
||||
height: 100%;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.active {
|
||||
border: 1rpx solid #2979FF;
|
||||
color: #2979FF;
|
||||
|
||||
.icon-ym-organization {
|
||||
&::before {
|
||||
color: #2979FF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sign-mask {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
background: rgba(0, 0, 0, .3);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.sign-mask-btn {
|
||||
width: 60%;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.lists_box {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
border-radius: 8rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
background-color: #FFFFFF;
|
||||
margin-bottom: 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.signImgBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
|
||||
.signImg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-checked-box {
|
||||
display: flex;
|
||||
width: 140rpx;
|
||||
height: 80rpx;
|
||||
position: absolute;
|
||||
transform: scale(0.9);
|
||||
right: -4rpx;
|
||||
bottom: -2rpx;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.icon-checked {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border: 40rpx solid #1890ff;
|
||||
border-left: 40rpx solid transparent;
|
||||
border-top: 40rpx solid transparent;
|
||||
border-bottom-right-radius: 12rpx;
|
||||
position: absolute;
|
||||
transform: scale(0.95);
|
||||
right: -8rpx;
|
||||
bottom: -6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
72
pages/my/personalSetting/index.vue
Normal file
72
pages/my/personalSetting/index.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<view class="personalData-v">
|
||||
<view class="notice-warp">
|
||||
<u-tabs :list="tabBars" :is-scroll="false" v-model="current" @change="tabChange" height="100">
|
||||
</u-tabs>
|
||||
</view>
|
||||
<view class="content">
|
||||
<signList ref="signList" v-if="current == 0"></signList>
|
||||
<commonText ref="commonText" v-if="current == 1"></commonText>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import signList from './components/signList.vue';
|
||||
import commonText from './components/commonText.vue';
|
||||
export default {
|
||||
components: {
|
||||
signList,
|
||||
commonText
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabBars: [{
|
||||
name: '个人签名'
|
||||
}, {
|
||||
name: '审批常用语'
|
||||
}],
|
||||
current: 0,
|
||||
baseInfo: {}
|
||||
};
|
||||
},
|
||||
onLoad(e) {
|
||||
this.current = 0
|
||||
this.baseInfo = e.baseInfo && JSON.parse(decodeURIComponent(e.baseInfo))
|
||||
},
|
||||
methods: {
|
||||
tabChange(index) {
|
||||
this.current = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.notice-warp {
|
||||
height: 100rpx;
|
||||
|
||||
.search-box {
|
||||
padding: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 120rpx;
|
||||
}
|
||||
|
||||
.personalData-v {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 100rpx;
|
||||
|
||||
::v-deep .buttom-btn {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
32
pages/my/scanResult/index.vue
Normal file
32
pages/my/scanResult/index.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<view class="scanResult-v">
|
||||
<view class="text">
|
||||
{{result}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'scanResult',
|
||||
data() {
|
||||
return {
|
||||
result: '',
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.result = option.result;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.scanResult-v {
|
||||
height: 100%;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
</style>
|
||||
115
pages/my/settings/index.vue
Normal file
115
pages/my/settings/index.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<view class="settings-v">
|
||||
<u-cell-group class="u-p-l-20 u-p-r-20" :border="false">
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<u-cell-item :title="$t('app.my.settings.language')" @click="selectLocaleShow=true"
|
||||
:title-style="titleStyle"></u-cell-item>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<u-cell-item :title="$t('app.my.settings.userAgreement')" @click='openPage(agreement)'
|
||||
:title-style="titleStyle"></u-cell-item>
|
||||
<u-cell-item :title="$t('app.my.settings.privacyPolicy')" @click='openPage(policy)'
|
||||
:title-style="titleStyle"></u-cell-item>
|
||||
<!-- #endif -->
|
||||
<u-cell-item :title="$t('app.my.settings.contact')" @click="modifyPsd('/pages/my/contactUs/index')"
|
||||
:title-style="titleStyle">
|
||||
</u-cell-item>
|
||||
<u-cell-item :title="$t('app.my.settings.about')" @click="modifyPsd('/pages/my/abouts/index')"
|
||||
:title-style="titleStyle" :border-bottom="false">
|
||||
</u-cell-item>
|
||||
</u-cell-group>
|
||||
<u-select v-model="selectLocaleShow" :list="localeList" mode="single-column" :default-value="defaultLocale"
|
||||
@confirm="localeConfirm"></u-select>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import resources from '@/libs/resources.js'
|
||||
import {
|
||||
useLocale
|
||||
} from '@/locale/useLocale';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// #ifdef APP-PLUS
|
||||
agreement: resources.userAgreement,
|
||||
policy: resources.privacyPolicy,
|
||||
// #endif
|
||||
titleStyle: {
|
||||
color: '#303133'
|
||||
},
|
||||
localeList: [{
|
||||
label: '简体中文',
|
||||
value: 'zh-Hans'
|
||||
},
|
||||
{
|
||||
label: '繁体中文',
|
||||
value: 'zh-Hant'
|
||||
},
|
||||
{
|
||||
label: 'English',
|
||||
value: 'en'
|
||||
}
|
||||
],
|
||||
selectLocaleShow: false,
|
||||
defaultLocale: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.defaultLocale = [this.localeList.findIndex(o => o.value === uni.getLocale())];
|
||||
},
|
||||
methods: {
|
||||
modifyPsd(path) {
|
||||
if (!path) return
|
||||
uni.navigateTo({
|
||||
url: path
|
||||
})
|
||||
},
|
||||
// #ifdef APP-PLUS
|
||||
openPage(url) {
|
||||
plus.runtime.openURL(url);
|
||||
},
|
||||
// #endif
|
||||
localeConfirm(e) {
|
||||
if (e[0].index === this.defaultLocale[0]) return
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
const isAndroid = systemInfo.platform.toLowerCase() === 'android';
|
||||
if (isAndroid) {
|
||||
uni.showModal({
|
||||
content: '应用此设置将重启App',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.handleChangeLocale(e[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.handleChangeLocale(e[0])
|
||||
}
|
||||
},
|
||||
handleChangeLocale(e) {
|
||||
this.defaultLocale = [e.index];
|
||||
const {
|
||||
changeLocale
|
||||
} = useLocale();
|
||||
changeLocale(e.value)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
:deep(.u-cell) {
|
||||
height: 112rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.settings-v {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
BIN
pages/my/static/image/about-head.png
Normal file
BIN
pages/my/static/image/about-head.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
128
pages/my/userDetail/index.vue
Normal file
128
pages/my/userDetail/index.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<view class="userDetail-v">
|
||||
<view class="userDetail-hd u-flex-col">
|
||||
<view class="u-m-t-60">
|
||||
<u-avatar :src="define.baseURL+userData.headIcon" size="120"></u-avatar>
|
||||
</view>
|
||||
<view class="u-m-t-32 u-font-32 name">
|
||||
<text>{{userData.realName}}/{{userData.account}}</text>
|
||||
</view>
|
||||
<view class="u-m-t-20 u-font-24 positionName">
|
||||
<text>{{userData.organize}}</text>
|
||||
</view>
|
||||
<view class="u-m-t-32 u-flex userDetail-hd-btn">
|
||||
<view class="u-m-r-40 btn" @click="call()">
|
||||
<text class="ym-custom ym-custom-phone u-font-40" />
|
||||
</view>
|
||||
<view class="u-m-l-40 btn" @click="toIm()">
|
||||
<text class="ym-custom ym-custom-comment u-font-40" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-p-l-20 u-p-r-20">
|
||||
<u-cell-group>
|
||||
<u-cell-item title="手机号" :value="userData.mobilePhone || '未填写'" :arrow="false"
|
||||
:title-style="titleStyle">
|
||||
</u-cell-item>
|
||||
<u-cell-item title="邮箱" :value="userData.email || '未填写'" :arrow="false" :title-style="titleStyle">
|
||||
</u-cell-item>
|
||||
<u-cell-item title="岗位" :value="userData.position || '未填写'" :arrow="false" :title-style="titleStyle">
|
||||
</u-cell-item>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUesrDetail
|
||||
} from '@/api/common.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userData: {},
|
||||
titleStyle: {
|
||||
color: '#303133'
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.baseURL
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.userData = JSON.parse(decodeURIComponent(e.data))
|
||||
},
|
||||
methods: {
|
||||
call() {
|
||||
if (!this.userData.mobilePhone) return
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: this.userData.mobilePhone
|
||||
})
|
||||
},
|
||||
toIm() {
|
||||
const userData = this.userData
|
||||
const name = userData.realName + '/' + userData.account
|
||||
uni.$emit('updateMsgNum', userData.id)
|
||||
uni.navigateTo({
|
||||
url: '/pages/message/im/index?name=' + name + '&formUserId=' + userData.id + '&headIcon=' +
|
||||
userData.headIcon
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.userDetail-v {
|
||||
:deep(.u-cell) {
|
||||
height: 112rpx;
|
||||
|
||||
.u-cell__value {
|
||||
color: #606266;
|
||||
white-space: nowrap;
|
||||
width: 400rpx;
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(uni-text) {
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.userDetail-hd {
|
||||
height: 482rpx;
|
||||
background-color: #f0f2f6;
|
||||
color: #FFFFFF;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.name {
|
||||
// font-weight: 700;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.positionName {
|
||||
color: #909399;
|
||||
width: 400rpx;
|
||||
text-align: center;
|
||||
white-space: nowrap !important;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.userDetail-hd-btn {
|
||||
.btn {
|
||||
width: 84rpx;
|
||||
height: 84rpx;
|
||||
border: 2rpx solid #606266;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user