提交 464dd2bf authored 作者: lidongxu's avatar lidongxu

'阶段'

上级 cd67b396
......@@ -17,7 +17,6 @@ export const getAttendanceDetailAPI = (ruleId) => {
* @returns
*/
export const addAttendanceAPI = (data) => {
console.log(data)
return request({
url: '/operation/kqmx/core',
method: 'POST',
......
......@@ -16,4 +16,23 @@ export function submitUserInfoAPI(data) {
'method': 'post',
'data': data
})
}
// 获取appId secret 和 accesstoken 微信的
export function getAppIdAPI() {
return request({
'url': '/wechat/miniapp/wxtoken'
})
}
// 获取手机号
export function getPhoneNumberAPI(accessToken, code) {
return request({
'url': `/wechat/miniapp/phone?accessToken=${accessToken}&code=${code}`
})
}
// 获取 openId
export function getOpenIdAPI(jsCode) {
return request({
'url': `/wechat/miniapp/openid?jsCode=${jsCode}`
})
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ export function uploadFile(fileName, filePath) {
//上传参数
const formData = {
key: fileName, // 上传文件名称(拼接路径格式字符串来决定文件夹)
policy: policy, //表单域
policy: policy, // 表单域
'x-oss-signature-version': xOssSignatureVersion, //指定签名的版本和算法
'x-oss-credential': xOssCredential, //指明派生密钥的参数集
'x-oss-date': xOssDate, //请求的时间
......
......@@ -40,7 +40,7 @@ export function getOnWorkRecordAPI(id) {
// 上班卡+下班打卡等
export function getOnWorkCardAPI(data) {
return request({
url: '/activity/temporary/core/today/clock',
url: '/activity/temporary/core/today/v2/clock',
method: 'POST',
data
})
......
......@@ -2,19 +2,25 @@
const {miniProgram} = wx.getAccountInfoSync()
const { envVersion } = miniProgram
const urlObj = {
'release': '正式环境',
'trial': 'http://111.198.15.68:85/promotion-api',
'develop': 'http://192.168.100.39:8010'
'release': 'https://promotion.wxl66.cn', // 正式环境
'trial': 'https://promotion.wxl66.cn', // 体验环境
// 'trial': 'http://111.198.15.68:85/promotion-api', // 体验环境
'develop': 'http://192.168.100.39:8010' // 开发环境
// 'develop': 'https://promotion.wxl66.cn' // 开发环境
}
const ossWebURL = {
'release': 'https://link-promotion.oss-cn-shanghai.aliyuncs.com/', // 正式环境
'trial': 'https://link-promotion.oss-cn-shanghai.aliyuncs.com/',
// 'trial': 'https://link-promotion-dev.oss-cn-shanghai.aliyuncs.com/',
'develop': 'https://link-promotion-dev.oss-cn-shanghai.aliyuncs.com/'
// 'develop': 'https://link-promotion.oss-cn-shanghai.aliyuncs.com/'
}
module.exports = {
mapBaseUrl: 'https://apis.map.qq.com', // 腾讯地图 API 域名
mapKey: 'EOGBZ-US2RW-YF5RC-OKB5O-R6BUK-2LFVS', // 腾讯地图 API key(TODO:后期换成后台的)
mapKey: 'EOGBZ-US2RW-YF5RC-OKB5O-R6BUK-2LFVS', // 腾讯地图 API key
coordtype: 'gcj02', // 坐标类型-国测局坐标(小程序使用的是这个,让百度地图也使用这个)
baseUrl: urlObj[envVersion],
// baseUrl: envVersion === 'release' ? '正式地址' : 'http://111.198.15.68:85/promotion-api',
ossWebUrl: 'https://link-promotion-dev.oss-cn-shanghai.aliyuncs.com/',
wxAppId: 'wx5d89065bb4725557', // 微信小程序 appId (TODO:后期换成后台的)
wxSecret: '7395e91baf6b49ca9b84b1301989f77e', // 微信小程序 appSecret(TODO:后期换成后台的)
ossWebUrl: ossWebURL[envVersion],
// 应用信息
appInfo: {
// 应用名称
......@@ -22,7 +28,7 @@ module.exports = {
// 应用版本
version: "1.0.0",
// 应用logo
logo: "/static/logo.png",
logo: `https://link-promotion-${envVersion !== 'release' ? 'dev' : ''}.oss-cn-shanghai.aliyuncs.com/logo.png`,
// 官方网站
site_url: "http://www.wangxiaolu.com.cn/",
// 政策协议
......
......@@ -3,21 +3,17 @@ import App from './App'
import store from './store'
import plugins from './plugins'
import './permission'
import config from './config.js'
import { setWxAccessToken } from './utils/auth.js'
import { getAppIdAPI } from './api/index.js'
Vue.use(plugins)
// 发起请求
uni.request({
// TODO:将来 TOKEN 从后台获取,再看看如何判定过期与否是响应拦截器里统一处理吗?
url: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.wxAppId}&secret=${config.wxSecret}`,
success: function (res) {
setWxAccessToken(res.data.access_token)
}
getAppIdAPI().then(res => {
const { appId, appSecret, access_token } = res.data
store.commit('SET_WXAPPID', appId)
store.commit('SET_WXAPPSECRET', appSecret)
store.commit('SET_WXACCESSTOKEN', access_token)
});
// console.log(uni.getSystemSetting())
Vue.config.productionTip = false
Vue.prototype.$store = store
......
{
"name" : "小卤促销员平台",
"appid" : "wx5474d56c6eea0083",
"appid" : "__UNI__EFA7037",
"description" : "小卤促销员平台",
"versionName" : "1.0.0",
"versionCode" : "100",
......@@ -41,7 +41,7 @@
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "wx5d89065bb4725557",
"appid" : "wxac14dc7765484d7d",
"setting" : {
"urlCheck" : false,
"es6" : false,
......
......@@ -42,8 +42,16 @@
<li>为了使用手机号注册/登录小程序,开发者将在获取你的明示同意后,收集你的手机号。</li>
</ul>
<h4>第三方插件信息/SDK信息</h4>
<p>关于你的个人信息,你可以通过以下方式与开发者联系,行使查阅、复制、更正、删除等法定权利。
若你在小程序中注册了账号,你可以通过以下方式与开发者联系,申请注销你在小程序中使用的账号。在受理你的申请后,开发者承诺在十五个工作日内完成核查和处理,并按照法律法规要求处理你的相关信息。</p>
<p>为实现特定功能,开发者可能会接入由第三方提供的插件/SDK。第三方插件/SDK的个人信息处理规则,请以其公示的官方说明为准。小卤促销员平台小程序接入的第三方插件信息/SDK信息如下:
SDK名称: 阿里云SDK
SDK提供方名称: 阿里云
开发者收集你选中的照片或视频信息 ,用于食品销售成交照片。
开发者访问你的摄像头 ,用于拍摄视频销售成交照片。
SDK名称: 腾讯地图SDK
SDK提供方名称: 腾讯
开发者收集你的位置信息 ,用于基于地理位置上班打卡。
开发者收集你的地址 ,用于基于地理位置上班打卡。
开发者获取你选择的位置信息 ,用于基于地理位置上班打卡。</p>
<ul class="agreement_ul">
<li>邮箱:liqiulin@wangxiaolu.com.cn</li>
</ul>
......@@ -65,9 +73,9 @@
</template>
<script>
import { getWxAccessToken } from '@/utils/auth';
import storage from '../utils/storage'
import constant from '../utils/constant';
import storage from '@/utils/storage'
import constant from '@/utils/constant';
import { getPhoneNumberAPI } from '@/api';
export default {
data() {
......@@ -89,14 +97,7 @@ export default {
this.$modal.loading("登录中,请耐心等待...")
// 通过微信小程序 API 获取手机号
const [err, { data: { phone_info: { phoneNumber } } }] = await uni.request({
url: `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${getWxAccessToken()}`,
method: 'POST',
data: {
code: e.detail.code
}
})
if (err) return this.$modal.msgError('微信 API 获取手机号出错')
const { data: { phone_info: { phoneNumber } } } = await getPhoneNumberAPI(this.$store.getters.wxAccessToten, e.detail.code)
// 调用微信登录接口,获取 openID
const openId = await this.$store.dispatch('getOpenId')
......@@ -108,7 +109,7 @@ export default {
// 手机号从未注册过-需要填写资料完成注册
if (loginRes.code === 3004) {
setTimeout(() => {
this.$tab.reLaunch('/pages/register')
this.$tab.reLaunch('/modules/otherModules/register')
}, 1500)
} else {
// 之前注册提交过资料,直接登录成功去首页
......
......@@ -52,10 +52,10 @@
</template>
<script>
import { uploadFile, submitUserInfoAPI, loginAPI } from '../api'
import { uploadFile, submitUserInfoAPI, loginAPI } from '@/api'
import { v4 as uuidv4 } from 'uuid'
import storage from '../utils/storage'
import constant from '../utils/constant'
import storage from '@/utils/storage'
import constant from '@/utils/constant'
export default {
created() {
......@@ -114,8 +114,7 @@ export default {
name: this.formData.name,
idenFrontPhotoUrl: this.formData.idenFrontUrl,
idenReversePhotoUrl: this.formData.idenBackUrl,
phone: this.phone,
phoneCode: '111111' // 先随便写一个
phone: this.phone
})
// 单独调用登录拿到 token
const { data } = await loginAPI({
......
......@@ -12,23 +12,11 @@
"navigationBarTitleText": "今日打卡"
}
},
{
"path": "pages/login",
"style": {
"navigationBarTitleText": "登录"
}
},
{
"path": "pages/work/index",
"style": {
"navigationBarTitleText": "上传推广照片"
}
},
{
"path": "pages/register",
"style": {
"navigationBarTitleText": "注册"
}
}
],
"tabBar": {
......@@ -51,6 +39,26 @@
}
]
},
"subPackages": [
{
"root": "modules/otherModules",
"name": "otherModules",
"pages": [
{
"path": "login",
"style": {
"navigationBarTitleText": "登录"
}
},
{
"path": "register",
"style": {
"navigationBarTitleText": "注册"
}
}
]
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
......@@ -63,5 +71,6 @@
"van-uploader": "wxcomponents/@vant/weapp/uploader/index",
"van-checkbox": "wxcomponents/@vant/weapp/checkbox/index"
}
}
},
"lazyCodeLoading": "requiredComponents"
}
\ No newline at end of file
<template>
<view class="wrap">
<div class="button_wrap">
<div v-for="obj in attTimeKeyList" class="btn_item" :class="{ 'active': !obj.timeOut && !obj.ready }"
@click="attendanceClickFn(obj)">
<!-- 动画层 -->
<div :class="{ 'ani': !obj.timeOut && !obj.ready }"></div>
<!-- 内容层 -->
<div class="content" :class="(obj.timeOut || obj.ready) ? 'workbtn_disabled' : obj.class">
<span>{{ obj.title }}</span>
<span v-if="obj.timeOut && !obj.ready" class="over">请补卡</span>
<span v-if="obj.ready" class="right">已打卡</span>
<span v-if="!obj.timeOut && !obj.ready">{{ obj.beginValue }}</span>
</div>
</div>
</div>
<uni-list class="list_wrap">
<uni-list-item v-for="item in attendanceList">
<template v-slot:header>
<span>{{ parseTime(item.time, '{y}-{m}-{d} 星期{a}') }}</span>
</template>
<!-- 自定义 body -->
<template v-slot:body>
<div class="item_body">
<div class="item" v-for="obj in item.kqTimeList">
<text class="time">{{ obj.kqTime ? parseTime(obj.kqTime, '{h}:{i}:{s}') : '暂未打卡' }}</text>
<text class="title">{{ attendanceDict[obj.kqType] }}打卡</text>
</div>
</div>
</template>
</uni-list-item>
<uni-list-item v-if="attendanceList.length === 0">
<template v-slot:body>
<view class="empty-box">
<text class="empty-text">暂无打卡记录</text>
</view>
</template>
</uni-list-item>
</uni-list>
</view>
</template>
<script>
import { getAttendanceDetailAPI, addAttendanceAPI, getAttendanceListAPI } from '@/api'
import { checkStartLessEndTime, parseTime, isSameDay, zeroTo24, checkTimeIsBetween } from '@/utils/common'
export default {
data() {
return {
attTimeKeyList: [], // 循环按钮配置列表
attendanceList: [], // 近 7 天考勤列表
attendanceDict: { // 考勤字典
1: '上班',
2: '午班',
3: '下班'
},
currently: '' // 服务器当前时间(格式:时:分:秒.毫秒)
}
},
created() {
this.getRuleInfoFn()
},
methods: {
parseTime,
// 获取考勤规则详情
async getRuleInfoFn() {
const list = [{ // 需要考勤列表
beginKey: 'firBegintime',
beginValue: '',
endKey: 'firEndtime',
endValue: '',
class: 'go_work',
title: '上班打卡',
timeOut: false, // 是否过了打卡时间
ready: false, // 是否已经打过卡了
type: 1, // 考勤类型
},
{
beginKey: 'secBegintime',
beginValue: '',
endKey: 'secEndtime',
endValue: '',
class: 'after_work',
title: '午班打卡',
timeOut: false,
ready: false,
type: 2,
},
{
beginKey: 'thiBegintime',
beginValue: '',
endKey: 'thiEndtime',
endValue: '',
class: 'off_work',
title: '下班打卡',
timeOut: false,
ready: false,
type: 3,
}]
// 需要提取打卡的时间
const { data } = await getAttendanceDetailAPI(this.$store.getters.user.ruleId)
for (let i = 0; i < list.length; i++) {
const obj = list[i]
if (!data[obj.beginKey]) {
// 如果打卡开始时间是空的(例如:有的人没有午班打卡,则删除数据结构中的一项)
list.splice(i, 1)
i--
continue
}
obj['beginValue'] = data[obj.beginKey]
obj['endValue'] = data[obj.endKey]
// 判断服务器时间
obj['timeOut'] = checkStartLessEndTime(zeroTo24(data[obj.endKey]), data.currently)
}
this.attTimeKeyList = list
// 保存服务器时间
this.currently = data.currently.split(".")[0]
// 考勤打卡记录
this.getAttendanceListFn()
},
// 考勤打卡
async attendanceClickFn(attObj) {
const { addressComponent, location } = this.$store.getters.location
const { lng, lat } = location
const { province, city, district, street } = addressComponent
if (attObj.timeOut) {
// 超过打卡时间
return this.$modal.msgError('超过了打卡时间')
}
// 判断它打卡时间范围是否合法(在开始之后,结束之前)
if (checkTimeIsBetween(attObj.beginValue, attObj.endValue, this.currently)) {
await addAttendanceAPI({
"kqLocal": [
lng,
lat
],
"kqProvinc": province,
"kqCity": city,
"kqCounty": district,
"kqAddress": street,
"kqPicurl": "https://www.baidu.com",
"kqType": attObj.type
})
this.$modal.msgSuccess('打卡成功')
// 考勤打卡记录
this.getAttendanceListFn()
} else {
this.$modal.msgError('打卡还未开始')
}
},
// 获取考勤列表
async getAttendanceListFn() {
const { data: { current, data } } = await getAttendanceListAPI()
const list = []
// 如果有打卡时间,则转换后台的结构数据
if (Object.keys(data).length > 0) {
Object.entries(data).forEach(([key, value]) => {
const attTime = [] // 打卡时间
value.forEach(obj => {
attTime.push({
kqTime: obj.kqTime,
kqType: obj.kqType
})
})
list.push({
time: key,
kqTimeList: attTime
})
})
// 考勤记录
this.attendanceList = list
// 默认第 0 条就是今日打卡的记录,判断是否打卡
this.attTimeKeyList.forEach((obj, index) => {
// 从按钮数组里去已打卡时间数组里取出,打卡时间对象
const readyObj = this.attendanceList[0].kqTimeList[index]
if (readyObj.kqTime) {
// 如果找到了打卡时间,证明已经打过卡了
obj.ready = true
}
})
}
}
}
}
</script>
<style scoped lang="scss">
.wrap {
background-color: #f0f1f3;
height: 100vh;
display: flex;
flex-direction: column;
.button_wrap {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 50rpx;
padding: 50rpx 0;
flex: 1;
.btn_item {
width: 250rpx;
height: 250rpx;
position: relative;
transition: all 0.1s linear;
.ani,
.content {
width: 100%;
height: 100%;
position: absolute;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0 !important;
align-items: center;
color: white;
}
.content {
.over {
font-size: 28rpx;
color: #d9322c;
margin-top: 10rpx;
}
.right {
font-size: 28rpx;
color: #32cdbf;
margin-top: 10rpx;
}
&.workbtn_disabled {
background-color: #c7c8c8;
color: rgb(160, 156, 156);
}
&.go_work {
background-color: #32cdbf;
}
&.after_work {
background-color: #e0bd47;
}
&.off_work {
background-color: #5dabed;
}
}
.ani {
&:before,
&:after {
content: '';
width: 100%;
height: 100%;
border-radius: 50%;
position: absolute;
animation: eff68 1.4s linear infinite;
// animation: eff68 5s linear infinite;
}
&:after {
animation-delay: .7s;
// animation-delay: 2.5s;
}
@keyframes eff68 {
0% {
// box-shadow: 0 0 0 0px #0093E9;
background-color: rgba(0, 147, 233, 0.2);
transform: scale(1);
// opacity: 0.2;
}
100% {
// box-shadow: 0 0 0 20px #0093E9;
background-color: rgba(0, 147, 233, 0);
transform: scale(1.4);
// opacity: 0;
}
}
}
// 打卡按钮动画
&.active:active {
transform: scale(0.8);
}
}
}
.list_wrap {
height: 700rpx;
overflow-y: scroll;
::v-deep .uni-list-item__container {
display: block !important;
}
.item_body {
display: flex;
justify-content: space-between;
padding-top: 24rpx;
.item {
display: flex;
flex-direction: column;
.time {
color: #d9572c;
}
.title {
font-size: 24rpx;
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<view>
<uni-card class="view-title" :title="title">
<text class="uni-body view-content">{{ content }}</text>
</uni-card>
</view>
</template>
<script>
export default {
data() {
return {
title: '',
content: ''
}
},
onLoad(options) {
this.title = options.title
this.content = options.content
uni.setNavigationBarTitle({
title: options.title
})
}
}
</script>
<style scoped>
page {
background-color: #ffffff;
}
.view-title {
font-weight: bold;
}
.view-content {
font-size: 26rpx;
padding: 12px 5px 0;
color: #333;
line-height: 24px;
font-weight: normal;
}
</style>
<template>
<view v-if="params.url">
<web-view :webview-styles="webviewStyles" :src="`${params.url}`"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
params: {},
webviewStyles: {
progress: {
color: "#FF3333"
}
}
}
},
props: {
src: {
type: [String],
default: null
}
},
onLoad(event) {
this.params = event
if (event.title) {
uni.setNavigationBarTitle({
title: event.title
})
}
}
}
</script>
......@@ -179,8 +179,8 @@ export default {
city: this.baseFormData.type === 1 ? this.typeList[this.baseFormData.type]?.text : '',
storeNameLike: this.baseFormData.storeName
})
this.oriPlanList = res.data
this.planList = res.data.map(item => {
this.oriPlanList = res.data || []
this.planList = this.oriPlanList.map(item => {
return item.storeName
})
},
......
<template>
<view class="about-container">
<view class="header-section text-center">
<image style="width: 150rpx;height: 150rpx;" src="/static/logo200.png" mode="widthFix">
</image>
<uni-title type="h2" title="若依移动端"></uni-title>
</view>
<view class="content-section">
<view class="menu-list">
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>版本信息</view>
<view class="text-right">v{{version}}</view>
</view>
</view>
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>官方邮箱</view>
<view class="text-right">ruoyi@xx.com</view>
</view>
</view>
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>服务热线</view>
<view class="text-right">400-999-9999</view>
</view>
</view>
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>公司网站</view>
<view class="text-right">
<uni-link :href="url" :text="url" showUnderLine="false"></uni-link>
</view>
</view>
</view>
</view>
</view>
<view class="copyright">
<view>Copyright &copy; 2022 ruoyi.vip All Rights Reserved.</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
url: getApp().globalData.config.appInfo.site_url,
version: getApp().globalData.config.appInfo.version
}
}
}
</script>
<style lang="scss">
page {
background-color: #f8f8f8;
}
.copyright {
margin-top: 50rpx;
text-align: center;
line-height: 60rpx;
color: #999;
}
.header-section {
display: flex;
padding: 30rpx 0 0;
flex-direction: column;
align-items: center;
}
</style>
差异被折叠。
<template>
<view class="help-container">
<view v-for="(item, findex) in list" :key="findex" :title="item.title" class="list-title">
<view class="text-title">
<view :class="item.icon"></view>{{ item.title }}
</view>
<view class="childList">
<view v-for="(child, zindex) in item.childList" :key="zindex" class="question" hover-class="hover"
@click="handleText(child)">
<view class="text-item">{{ child.title }}</view>
<view class="line" v-if="zindex !== item.childList.length - 1"></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [{
icon: 'iconfont icon-github',
title: '若依问题',
childList: [{
title: '若依开源吗?',
content: '开源'
}, {
title: '若依可以商用吗?',
content: '可以'
}, {
title: '若依官网地址多少?',
content: 'http://ruoyi.vip'
}, {
title: '若依文档地址多少?',
content: 'http://doc.ruoyi.vip'
}]
},
{
icon: 'iconfont icon-help',
title: '其他问题',
childList: [{
title: '如何退出登录?',
content: '请点击[我的] - [应用设置] - [退出登录]即可退出登录',
}, {
title: '如何修改用户头像?',
content: '请点击[我的] - [选择头像] - [点击提交]即可更换用户头像',
}, {
title: '如何修改登录密码?',
content: '请点击[我的] - [应用设置] - [修改密码]即可修改登录密码',
}]
}
]
}
},
methods: {
handleText(item) {
this.$tab.navigateTo(`/pages/common/textview/index?title=${item.title}&content=${item.content}`)
}
}
}
</script>
<style lang="scss" scoped>
page {
background-color: #f8f8f8;
}
.help-container {
margin-bottom: 100rpx;
padding: 30rpx;
}
.list-title {
margin-bottom: 30rpx;
}
.childList {
background: #ffffff;
box-shadow: 0px 0px 10rpx rgba(193, 193, 193, 0.2);
border-radius: 16rpx;
margin-top: 10rpx;
}
.line {
width: 100%;
height: 1rpx;
background-color: #F5F5F5;
}
.text-title {
color: #303133;
font-size: 32rpx;
font-weight: bold;
margin-left: 10rpx;
.iconfont {
font-size: 16px;
margin-right: 10rpx;
}
}
.text-item {
font-size: 28rpx;
padding: 24rpx;
}
.question {
color: #606266;
font-size: 28rpx;
}
</style>
<template>
<view class="mine-container" :style="{height: `${windowHeight}px`}">
<!--顶部个人信息栏-->
<view class="header-section">
<view class="flex padding justify-between">
<view class="flex align-center">
<view v-if="!avatar" class="cu-avatar xl round bg-white">
<view class="iconfont icon-people text-gray icon"></view>
</view>
<image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
</image>
<view v-if="!name" @click="handleToLogin" class="login-tip">
点击登录
</view>
<view v-if="name" @click="handleToInfo" class="user-info">
<view class="u_title">
用户名:{{ name }}
</view>
</view>
</view>
<view @click="handleToInfo" class="flex align-center">
<text>个人信息</text>
<view class="iconfont icon-right"></view>
</view>
</view>
</view>
<view class="content-section">
<view class="mine-actions grid col-4 text-center">
<view class="action-item" @click="handleJiaoLiuQun">
<view class="iconfont icon-friendfill text-pink icon"></view>
<text class="text">交流群</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-service text-blue icon"></view>
<text class="text">在线客服</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-community text-mauve icon"></view>
<text class="text">反馈社区</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-dianzan text-green icon"></view>
<text class="text">点赞我们</text>
</view>
</view>
<view class="menu-list">
<view class="list-cell list-cell-arrow" @click="handleToEditInfo">
<view class="menu-item-box">
<view class="iconfont icon-user menu-icon"></view>
<view>编辑资料</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleHelp">
<view class="menu-item-box">
<view class="iconfont icon-help menu-icon"></view>
<view>常见问题</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleAbout">
<view class="menu-item-box">
<view class="iconfont icon-aixin menu-icon"></view>
<view>关于我们</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleToSetting">
<view class="menu-item-box">
<view class="iconfont icon-setting menu-icon"></view>
<view>应用设置</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import storage from '@/utils/storage'
export default {
data() {
return {
name: this.$store.state.user.name,
version: getApp().globalData.config.appInfo.version
}
},
computed: {
avatar() {
return this.$store.state.user.avatar
},
windowHeight() {
return uni.getSystemSetting().windowHeight - 50
}
},
methods: {
handleToInfo() {
this.$tab.navigateTo('/pages/mine/info/index')
},
handleToEditInfo() {
this.$tab.navigateTo('/pages/mine/info/edit')
},
handleToSetting() {
this.$tab.navigateTo('/pages/mine/setting/index')
},
handleToLogin() {
this.$tab.reLaunch('/pages/login')
},
handleToAvatar() {
this.$tab.navigateTo('/pages/mine/avatar/index')
},
handleLogout() {
this.$modal.confirm('确定注销并退出系统吗?').then(() => {
this.$store.dispatch('LogOut').then(() => {
this.$tab.reLaunch('/pages/home/index')
})
})
},
handleHelp() {
this.$tab.navigateTo('/pages/mine/help/index')
},
handleAbout() {
this.$tab.navigateTo('/pages/mine/about/index')
},
handleJiaoLiuQun() {
this.$modal.showToast('QQ群:①133713780、②146013835')
},
handleBuilding() {
this.$modal.showToast('模块建设中~')
}
}
}
</script>
<style lang="scss">
page {
background-color: #f5f6f7;
}
.mine-container {
width: 100%;
height: 100%;
.header-section {
padding: 15px 15px 45px 15px;
background-color: #3c96f3;
color: white;
.login-tip {
font-size: 18px;
margin-left: 10px;
}
.cu-avatar {
border: 2px solid #eaeaea;
.icon {
font-size: 40px;
}
}
.user-info {
margin-left: 15px;
.u_title {
font-size: 18px;
line-height: 30px;
}
}
}
.content-section {
position: relative;
top: -50px;
.mine-actions {
margin: 15px 15px;
padding: 20px 0px;
border-radius: 8px;
background-color: white;
.action-item {
.icon {
font-size: 28px;
}
.text {
display: block;
font-size: 13px;
margin: 8px 0px;
}
}
}
}
}
</style>
<template>
<view class="container">
<view class="example">
<uni-forms ref="form" :model="user" labelWidth="80px">
<uni-forms-item label="用户昵称" name="nickName">
<uni-easyinput v-model="user.nickName" placeholder="请输入昵称" />
</uni-forms-item>
<uni-forms-item label="手机号码" name="phonenumber">
<uni-easyinput v-model="user.phonenumber" placeholder="请输入手机号码" />
</uni-forms-item>
<uni-forms-item label="邮箱" name="email">
<uni-easyinput v-model="user.email" placeholder="请输入邮箱" />
</uni-forms-item>
<uni-forms-item label="性别" name="sex" required>
<uni-data-checkbox v-model="user.sex" :localdata="sexs" />
</uni-forms-item>
</uni-forms>
<button type="primary" @click="submit">提交</button>
</view>
</view>
</template>
<script>
import { getUserProfile } from "@/api/system/user"
import { updateUserProfile } from "@/api/system/user"
export default {
data() {
return {
user: {
nickName: "",
phonenumber: "",
email: "",
sex: ""
},
sexs: [{
text: '男',
value: "0"
}, {
text: '女',
value: "1"
}],
rules: {
nickName: {
rules: [{
required: true,
errorMessage: '用户昵称不能为空'
}]
},
phonenumber: {
rules: [{
required: true,
errorMessage: '手机号码不能为空'
}, {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
errorMessage: '请输入正确的手机号码'
}]
},
email: {
rules: [{
required: true,
errorMessage: '邮箱地址不能为空'
}, {
format: 'email',
errorMessage: '请输入正确的邮箱地址'
}]
}
}
}
},
onLoad() {
this.getUser()
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data
})
},
submit(ref) {
this.$refs.form.validate().then(res => {
updateUserProfile(this.user).then(response => {
this.$modal.msgSuccess("修改成功")
})
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.example {
padding: 15px;
background-color: #fff;
}
.segmented-control {
margin-bottom: 15px;
}
.button-group {
margin-top: 15px;
display: flex;
justify-content: space-around;
}
.form-item {
display: flex;
align-items: center;
flex: 1;
}
.button {
display: flex;
align-items: center;
height: 35px;
line-height: 35px;
margin-left: 10px;
}
</style>
<template>
<view class="container">
<uni-list>
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'person-filled'}" title="昵称" :rightText="user.nickName" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'phone-filled'}" title="手机号码" :rightText="user.phonenumber" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'email-filled'}" title="邮箱" :rightText="user.email" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'auth-filled'}" title="岗位" :rightText="postGroup" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'staff-filled'}" title="角色" :rightText="roleGroup" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'calendar-filled'}" title="创建日期" :rightText="user.createTime" />
</uni-list>
</view>
</template>
<script>
import { getUserProfile } from "@/api/system/user"
export default {
data() {
return {
user: {},
roleGroup: "",
postGroup: ""
}
},
onLoad() {
this.getUser()
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup
this.postGroup = response.postGroup
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
</style>
<template>
<view class="pwd-retrieve-container">
<uni-forms ref="form" :value="user" labelWidth="80px">
<uni-forms-item name="oldPassword" label="旧密码">
<uni-easyinput type="password" v-model="user.oldPassword" placeholder="请输入旧密码" />
</uni-forms-item>
<uni-forms-item name="newPassword" label="新密码">
<uni-easyinput type="password" v-model="user.newPassword" placeholder="请输入新密码" />
</uni-forms-item>
<uni-forms-item name="confirmPassword" label="确认密码">
<uni-easyinput type="password" v-model="user.confirmPassword" placeholder="请确认新密码" />
</uni-forms-item>
<button type="primary" @click="submit">提交</button>
</uni-forms>
</view>
</template>
<script>
import { updateUserPwd } from "@/api/system/user"
export default {
data() {
return {
user: {
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined
},
rules: {
oldPassword: {
rules: [{
required: true,
errorMessage: '旧密码不能为空'
}]
},
newPassword: {
rules: [{
required: true,
errorMessage: '新密码不能为空',
},
{
minLength: 6,
maxLength: 20,
errorMessage: '长度在 6 到 20 个字符'
}
]
},
confirmPassword: {
rules: [{
required: true,
errorMessage: '确认密码不能为空'
}, {
validateFunction: (rule, value, data) => data.newPassword === value,
errorMessage: '两次输入的密码不一致'
}
]
}
}
}
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
submit() {
this.$refs.form.validate().then(res => {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
this.$modal.msgSuccess("修改成功")
})
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.pwd-retrieve-container {
padding-top: 36rpx;
padding: 15px;
}
</style>
<template>
<view class="setting-container" :style="{height: `${windowHeight}px`}">
<view class="menu-list">
<view class="list-cell list-cell-arrow" @click="handleToPwd">
<view class="menu-item-box">
<view class="iconfont icon-password menu-icon"></view>
<view>修改密码</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleToUpgrade">
<view class="menu-item-box">
<view class="iconfont icon-refresh menu-icon"></view>
<view>检查更新</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleCleanTmp">
<view class="menu-item-box">
<view class="iconfont icon-clean menu-icon"></view>
<view>清理缓存</view>
</view>
</view>
</view>
<view class="cu-list menu">
<view class="cu-item item-box">
<view class="content text-center" @click="handleLogout">
<text class="text-black">退出登录</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
windowHeight: uni.getSystemSetting().windowHeight
}
},
methods: {
handleToPwd() {
this.$tab.navigateTo('/pages/mine/pwd/index')
},
handleToUpgrade() {
this.$modal.showToast('模块建设中~')
},
handleCleanTmp() {
this.$modal.showToast('模块建设中~')
},
handleLogout() {
this.$modal.confirm('确定注销并退出系统吗?').then(() => {
this.$store.dispatch('LogOut').then(() => {
this.$tab.reLaunch('/pages/home/index')
})
})
}
}
}
</script>
<style lang="scss" scoped>
.page {
background-color: #f8f8f8;
}
.item-box {
background-color: #FFFFFF;
margin: 30rpx;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 10rpx;
border-radius: 8rpx;
color: #303133;
font-size: 32rpx;
}
</style>
......@@ -10,7 +10,7 @@ export default {
mounted() {
wx.hideTabBar()
setTimeout(() => {
this.$tab.redirectTo('/pages/login')
this.$tab.redirectTo('/modules/otherModules/login')
}, 2000)
}
}
......
......@@ -4,11 +4,11 @@ import constant from './utils/constant'
import { getToken } from '@/utils/auth'
// 登录页面
const loginPage = "/pages/login"
const loginPage = "/modules/otherModules/login"
// 页面白名单
const whiteList = [
'/pages/login', '/pages/register', '/pages/common/webview/index'
'/modules/otherModules/login', '/modules/otherModules/register'
]
// 检查地址白名单
......
......@@ -6,17 +6,6 @@
"ignore": [],
"include": []
},
"env": {
"NODE_ENV": "development",
"development": {
"baseUrl": "http://192.168.100.39:8010",
"ossBucketWebUrl": "https://link-promotion-dev.oss-cn-shanghai.aliyuncs.com/"
},
"production": {
"baseUrl": "",
"ossBucketWebUrl": ""
}
},
"setting": {
"coverView": true,
"es6": true,
......
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "小卤促销员平台",
"setting": {
"compileHotReLoad": true
}
}
\ No newline at end of file
......@@ -7,5 +7,9 @@ const getters = {
permissions: state => state.user.permissions,
delayTime: state => 3000, // 延迟弹窗关闭时间
location: (state) => state.map.location,
wxAccessToten: state => state.user.wxAccessToken,
wxOpenId: state => state.user.wxOpenId,
wxAppId: state => state.user.wxAppId,
wxSecret: state => state.user.wxSecret,
}
export default getters
import config from '@/config'
import storage from '@/utils/storage'
import constant from '@/utils/constant'
import { login, logout, getUserInfoAPI, loginAPI } from '@/api'
import { login, logout, getUserInfoAPI, loginAPI, getOpenIdAPI } from '@/api'
import { getToken, setToken, removeToken } from '@/utils/auth'
const baseUrl = config.baseUrl
......@@ -13,7 +13,11 @@ const user = {
avatar: storage.get(constant.avatar),
roles: storage.get(constant.roles),
permissions: storage.get(constant.permissions),
user: storage.get(constant.user)
user: storage.get(constant.user),
wxAppId: storage.get(constant.wxAppId),
wxSecret: storage.get(constant.wxSecret),
wxAccessToken: storage.get(constant.wxAccessToken),
wxOpenId: storage.get(constant.wxOpenId)
},
mutations: {
......@@ -44,12 +48,28 @@ const user = {
SET_OPENID: (state, openid) => {
state.openid = openid
storage.set(constant.loginOpenId, openid)
},
SET_WXAPPID: (state, id) => {
state.wxAppId = id
storage.set(constant.wxAppId, id)
},
SET_WXAPPSECRET: (state, secret) => {
state.wxSecret = secret
storage.set(constant.wxSecret, secret)
},
SET_WXACCESSTOKEN: (state, token) => {
state.wxAccessToken = token
storage.set(constant.wxAccessToken, token)
},
SET_WXOPENID: (state, token) => {
state.wxOpenId = token
storage.set(constant.wxOpenId, token)
}
},
actions: {
// 微信登录(获取 openId)
getOpenId({ commit }) {
getOpenId({ commit, state }) {
return new Promise(async (resolve, reject) => {
// 调用微信登录接口,获取一次性 code
const [loginErr, loginRes] = await uni.login({
......@@ -57,16 +77,9 @@ const user = {
})
// 通过 code 获取永久唯一身份标识 openid
const [openErr, openRes] = await uni.request({
url: `https://api.weixin.qq.com/sns/jscode2session?appid=${config.wxAppId}&secret=${config.wxSecret}&js_code=${loginRes.code}&grant_type=authorization_code`
});
if (loginErr || openErr) {
reject(loginErr || openErr)
} else {
commit('SET_OPENID', openRes.data.openid)
resolve(openRes.data.openid)
}
const openRes = await getOpenIdAPI(loginRes.code)
commit('SET_OPENID', openRes.data.openid)
resolve(openRes.data.openid)
})
},
......
......@@ -6,9 +6,7 @@
*/
export const debounce = function(func, wait = 1000, immediate = true) {
let timer;
console.log(1);
return function() {
console.log(123);
let context = this,
args = arguments;
if (timer) clearTimeout(timer);
......@@ -53,4 +51,4 @@ export const throttle = (func, wait = 1000, type = 1) => {
}
}
}
}
}
......@@ -9,6 +9,13 @@ const constant = {
// 登录使用手机号
loginPhone: 'vuex_login_phone',
loginOpenId: 'vuex_login_openid',
// 微信 AppId 和 SecretId
wxAppId: 'vuex_wx_appid',
wxSecret: 'vuex_wx_secret',
// 微信 AccessToken
wxAccessToken: 'vuex_wx_access_token',
// 微信用户 openId
wxOpenId: 'vuex_wx_open_id'
}
export default constant
......@@ -42,7 +42,7 @@ const request = config => {
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
if (res.confirm) {
store.dispatch('LogOut').then(res => {
uni.reLaunch({ url: '/pages/login' })
uni.reLaunch({ url: '/modules/otherModules/login' })
})
}
})
......
......@@ -38,7 +38,7 @@ const upload = config => {
showConfirm("登录状态已过期,您可以继续留在该页面,或者重新登录?").then(res => {
if (res.confirm) {
store.dispatch('LogOut').then(res => {
uni.reLaunch({ url: '/pages/login/login' })
uni.reLaunch({ url: '/modules/otherModules/login/login' })
})
}
})
......@@ -67,4 +67,4 @@ const upload = config => {
})
}
export default upload
export default upload
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论