提交 33a53258 authored 作者: lidongxu's avatar lidongxu

开发考勤打卡功能

上级 17f51236
......@@ -10,7 +10,7 @@
methods: {
// 初始化应用
initApp() {
// 初始化应用配置
// 初始化应用配置
this.initConfig()
// 检查用户登录状态
//#ifdef H5
......
import request from '@/utils/request.js'
/**
* 获取考勤规则详情
*/
export const getAttendanceDetail = (ruleId) => {
return request({
url: `/system/kq_rule/${ruleId}`
})
}
\ No newline at end of file
export * from './map.js'
\ No newline at end of file
import request from '@/utils/request.js'
import {
mapBaseUrl,
mapKey,
coordtype
} from '@/config.js'
import { tansParams } from '@/utils/common.js'
// 所有服务均基于 百度地图
/**
* 逆地理位置编码
*/
export const reverseGeocoding = ({
params
}) => {
const urlParams = tansParams(params)
return request({
baseUrl: mapBaseUrl + `/reverse_geocoding/v3/?ak=${mapKey}&output=json&coordtype=${coordtype}&${urlParams}`
})
}
\ No newline at end of file
......@@ -9,7 +9,7 @@ export function login(username, password, code, uuid) {
uuid
}
return request({
'url': '/login',
'url': '/auth/login',
headers: {
isToken: false
},
......@@ -21,7 +21,7 @@ export function login(username, password, code, uuid) {
// 注册方法
export function register(data) {
return request({
url: '/register',
url: '/auth/register',
headers: {
isToken: false
},
......@@ -33,7 +33,7 @@ export function register(data) {
// 获取用户详细信息
export function getInfo() {
return request({
'url': '/getInfo',
'url': '/system/user/getInfo',
'method': 'get'
})
}
......@@ -41,7 +41,7 @@ export function getInfo() {
// 退出方法
export function logout() {
return request({
'url': '/logout',
'url': '/auth/logout',
'method': 'post'
})
}
......@@ -49,7 +49,7 @@ export function logout() {
// 获取验证码
export function getCodeImg() {
return request({
'url': '/captchaImage',
'url': '/auth/captchaImage',
headers: {
isToken: false
},
......
<template>
<view class="uni-section">
<view class="uni-section-header" @click="onClick">
<view class="uni-section-header__decoration" v-if="type" :class="type" />
<slot v-else name="decoration"></slot>
<view class="uni-section-header__decoration" v-if="type" :class="type" />
<slot v-else name="decoration"></slot>
<view class="uni-section-header__content">
<text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
<text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
</view>
<view class="uni-section-header__content">
<text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title"
:class="{'distraction':!subTitle}">{{ title }}</text>
<text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}"
class="uni-section-header__content-sub">{{ subTitle }}</text>
</view>
<view class="uni-section-header__slot-right">
<slot name="right"></slot>
</view>
<view class="uni-section-header__slot-right">
<slot name="right"></slot>
</view>
</view>
<view class="uni-section-content" :style="{padding: _padding}">
......@@ -21,7 +23,6 @@
</template>
<script>
/**
* Section 标题栏
* @description 标题栏
......@@ -40,7 +41,7 @@
export default {
name: 'UniSection',
emits:['click'],
emits: ['click'],
props: {
type: {
type: String,
......@@ -51,11 +52,11 @@
required: true,
default: ''
},
titleFontSize: {
type: String,
default: '14px'
},
titleColor:{
titleFontSize: {
type: String,
default: '14px'
},
titleColor: {
type: String,
default: '#333'
},
......@@ -63,28 +64,28 @@
type: String,
default: ''
},
subTitleFontSize: {
type: String,
default: '12px'
},
subTitleColor: {
type: String,
default: '#999'
},
subTitleFontSize: {
type: String,
default: '12px'
},
subTitleColor: {
type: String,
default: '#999'
},
padding: {
type: [Boolean, String],
default: false
}
},
computed:{
_padding(){
if(typeof this.padding === 'string'){
return this.padding
}
return this.padding?'10px':''
}
},
computed: {
_padding() {
if (typeof this.padding === 'string') {
return this.padding
}
return this.padding ? '10px' : ''
}
},
watch: {
title(newVal) {
if (uni.report && newVal !== '') {
......@@ -92,76 +93,79 @@
}
}
},
methods: {
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" >
<style lang="scss">
$uni-primary: #2979ff !default;
.uni-section {
background-color: #fff;
.uni-section-header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 12px 10px;
font-weight: normal;
&__decoration{
margin-right: 6px;
background-color: $uni-primary;
&.line {
width: 4px;
height: 12px;
border-radius: 10px;
}
&.circle {
width: 8px;
height: 8px;
border-top-right-radius: 50px;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
}
&.square {
width: 8px;
height: 8px;
}
}
&__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
color: #333;
.distraction {
flex-direction: row;
align-items: center;
}
&-sub {
margin-top: 2px;
}
}
&__slot-right{
font-size: 14px;
}
}
.uni-section-content{
font-size: 14px;
}
.uni-section-header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 12px 10px;
font-weight: normal;
&__decoration {
margin-right: 6px;
background-color: $uni-primary;
&.line {
width: 4px;
height: 12px;
border-radius: 10px;
}
&.circle {
width: 8px;
height: 8px;
border-top-right-radius: 50px;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
}
&.square {
width: 8px;
height: 8px;
}
}
&__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
color: #333;
.distraction {
flex-direction: row;
align-items: center;
}
&-sub {
margin-top: 2px;
}
}
&__slot-right {
font-size: 14px;
}
}
.uni-section-content {
font-size: 14px;
}
}
</style>
</style>
\ No newline at end of file
// 应用全局配置
module.exports = {
baseUrl: 'https://vue.ruoyi.vip/prod-api',
// baseUrl: 'http://localhost:8080',
// baseUrl: 'https://vue.ruoyi.vip/prod-api',
mapBaseUrl: 'https://api.map.baidu.com',
mapKey: 'mryaav7xyp0Z3ItwUT3oMssYAmG8sTSU',
coordtype: 'gcj02', // 坐标类型(小程序获取和百度地图 API 使用类型要对应上)
// baseUrl: 'http://192.168.100.39:8080/api',
// baseUrl: 'http://localhost:8080',
baseUrl: 'http://192.168.140.189:8080', // 局域网请求
// 应用信息
appInfo: {
// 应用名称
......
......@@ -14,4 +14,4 @@ const app = new Vue({
...App
})
app.$mount()
app.$mount()
{
"name" : "若依移动端",
"appid" : "__UNI__25A9D80",
"description" : "",
"versionName" : "1.1.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
"sdkConfigs" : {}
}
"name": "若依移动端",
"appid": "__UNI__EF8B6D6",
"description": "",
"versionName": "1.1.0",
"versionCode": "100",
"transformPx": false,
"app-plus": {
"usingComponents": true,
"nvueCompiler": "uni-app",
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "wxccd7e2a0911b3397",
"setting" : {
"urlCheck" : false,
"es6" : false,
"minified" : true,
"postcss" : true
},
"optimization" : {
"subPackages" : true
},
"usingComponents" : true
"modules": {},
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios": {},
"sdkConfigs": {}
}
},
"quickapp": {},
"mp-weixin": {
"appid": "wxb22cd2d07f55e295",
"setting": {
"urlCheck": false,
"es6": false,
"minified": true,
"postcss": true
},
"optimization": {
"subPackages": true
},
"usingComponents": true,
"requiredPrivateInfos": [
"chooseAddress",
"getLocation",
"chooseLocation"
],
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于考勤打卡定位"
}
}
},
"vueVersion": "2",
"h5": {
"template": "static/index.html",
"devServer": {
"port": 9090,
"https": false
},
"vueVersion" : "2",
"h5" : {
"template" : "static/index.html",
"devServer" : {
"port" : 9090,
"https" : false
},
"title" : "RuoYi-App",
"router" : {
"mode" : "hash",
"base" : "./"
}
"title": "RuoYi-App",
"router": {
"mode": "hash",
"base": "./"
}
}
}
}
\ No newline at end of file
{
"pages": [{
"path": "pages/login",
"style": {
"navigationBarTitleText": "登录"
}
}, {
"path": "pages/register",
"style": {
"navigationBarTitleText": "注册"
}
}, {
"path": "pages/index",
"style": {
"navigationBarTitleText": "若依移动端框架",
"navigationStyle": "custom"
}
}, {
"path": "pages/work/index",
"style": {
"navigationBarTitleText": "工作台"
}
}, {
"path": "pages/mine/index",
"style": {
"navigationBarTitleText": "我的"
}
}, {
"path": "pages/mine/avatar/index",
"style": {
"navigationBarTitleText": "修改头像"
}
}, {
"path": "pages/mine/info/index",
"style": {
"navigationBarTitleText": "个人信息"
}
}, {
"path": "pages/mine/info/edit",
"style": {
"navigationBarTitleText": "编辑资料"
}
}, {
"path": "pages/mine/pwd/index",
"style": {
"navigationBarTitleText": "修改密码"
}
}, {
"path": "pages/mine/setting/index",
"style": {
"navigationBarTitleText": "应用设置"
}
}, {
"path": "pages/mine/help/index",
"style": {
"navigationBarTitleText": "常见问题"
}
}, {
"path": "pages/mine/about/index",
"style": {
"navigationBarTitleText": "关于我们"
}
}, {
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "浏览网页"
}
}, {
"path": "pages/common/textview/index",
"style": {
"navigationBarTitleText": "浏览文本"
"pages": [
{
"path": "pages/login",
"style": {
"navigationBarTitleText": "登录"
}
},
{
"path": "pages/index",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/attendance/index",
"style": {
"navigationBarTitleText": "考勤打卡"
}
},
{
"path": "pages/work/index",
"style": {
"navigationBarTitleText": "工作台"
}
},
{
"path": "pages/register",
"style": {
"navigationBarTitleText": "注册"
}
},
{
"path": "pages/mine/index",
"style": {
"navigationBarTitleText": "我的"
}
},
{
"path": "pages/mine/avatar/index",
"style": {
"navigationBarTitleText": "修改头像"
}
},
{
"path": "pages/mine/info/index",
"style": {
"navigationBarTitleText": "个人信息"
}
},
{
"path": "pages/mine/info/edit",
"style": {
"navigationBarTitleText": "编辑资料"
}
},
{
"path": "pages/mine/pwd/index",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "pages/mine/setting/index",
"style": {
"navigationBarTitleText": "应用设置"
}
},
{
"path": "pages/mine/help/index",
"style": {
"navigationBarTitleText": "常见问题"
}
},
{
"path": "pages/mine/about/index",
"style": {
"navigationBarTitleText": "关于我们"
}
},
{
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "浏览网页"
}
},
{
"path": "pages/common/textview/index",
"style": {
"navigationBarTitleText": "浏览文本"
}
}
}],
],
"tabBar": {
"color": "#000000",
"selectedColor": "#000000",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [{
"list": [
{
"pagePath": "pages/index",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home_.png",
"text": "首页"
}, {
},
{
"pagePath": "pages/work/index",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "工作台"
}, {
},
{
"pagePath": "pages/mine/index",
"iconPath": "static/images/tabbar/mine.png",
"selectedIconPath": "static/images/tabbar/mine_.png",
......@@ -97,6 +121,8 @@
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
"navigationBarBackgroundColor": "#FFFFFF"
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#FFFFFF"
}
}
}
\ No newline at end of file
<template>
<view class="wrap">
<div class="button_wrap">
<button v-for="obj in attTimeKeyList" :class="obj.disabled ? 'workbtn_disabled' : obj.class"
:disabled="obj.disabled">{{ obj.title }}</button>
</div>
</view>
</template>
<script>
import { getAttendanceDetail } from '@/api/attendance'
import { checkStartLessEndTime } from '@/utils/common'
export default {
data() {
return {
attTimeKeyList: [{ // 需要考勤列表
beginKey: 'firBegintime',
beginValue: '',
endKey: 'firEndtime',
endValue: '',
class: 'go_work',
title: '上班打卡',
disabled: false // 是否可以交互
},
{
beginKey: 'secBegintime',
beginValue: '',
endKey: 'secEndtime',
endValue: '',
class: 'after_work',
title: '午班打卡',
disabled: false
},
{
beginKey: 'thiBegintime',
beginValue: '',
endKey: 'thiEndtime',
endValue: '',
class: 'off_work',
title: '下班打卡',
disabled: false
}]
}
},
created() {
this.getRuleInfo()
},
methods: {
async getRuleInfo() {
// 需要提取打卡的时间
const { data } = await getAttendanceDetail(this.$store.getters.user.ruleId)
this.attTimeKeyList.forEach(obj => {
obj['beginValue'] = data[obj.beginKey]
obj['endValue'] = data[obj.endKey]
// 判断服务器时间
obj['disabled'] = checkStartLessEndTime(data[obj.endKey], data.currently)
})
}
}
}
</script>
<style scoped lang="scss">
.wrap {
background-color: #f0f1f3;
height: 100vh;
.button_wrap {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 50rpx;
.go_work,
.after_work,
.off_work,
.workbtn_disabled {
width: 250rpx;
height: 250rpx;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: white;
}
.workbtn_disabled {
background-color: #c7c8c8;
}
.go_work {
background-color: #32cdbf;
}
.after_work {
background-color: #e0bd47;
}
.off_work {
background-color: #5dabed;
}
}
}
</style>
<template>
<view class="content">
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title">Hello RuoYi</text>
</view>
<view class="wrap">
<uni-nav-bar dark :fixed="true" shadow background-color="#007AFF" status-bar title="首页" />
<uni-section class="section" title="基础分组" padding>
<uni-grid :column="4" :showBorder="false">
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="list" :size="30" color="#777" />
<text class="text">网点列表</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="folder-add" :size="30" color="#777" />
<text class="text">新增网点</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="person-filled" :size="30" color="#777" />
<text class="text">经销商列表</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="shop-filled" :size="30" color="#777" />
<text class="text">新增二批商</text>
</view>
</uni-grid-item>
</uni-grid>
</uni-section>
<uni-section class="section" title="拜访分组" padding>
<uni-grid :column="4" :showBorder="false">
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="home" :size="30" color="#777" />
<text class="text">网点拜访</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="settings" :size="30" color="#777" />
<text class="text">经销商拜访</text>
</view>
</uni-grid-item>
</uni-grid>
</uni-section>
<uni-section class="section" title="日常分组" padding>
<uni-grid :column="4" :showBorder="false">
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="upload-filled" :size="30" color="#777" />
<text class="text">付费阵列上报</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box" @click="addendanceClick">
<uni-icons type="compose" :size="30" color="#777" />
<text class="text">考勤打卡</text>
</view>
</uni-grid-item>
</uni-grid>
</uni-section>
</view>
</template>
<script>
export default {
onLoad: function() {
import { reverseGeocoding } from '@/api/common'
export default {
onLoad: function () { },
methods: {
addendanceClick() {
// getLocation 获取经纬度
// chooseLocation 让用户在地图手选位置
uni.getLocation({
success: async (res) => {
const result = await reverseGeocoding({
params: {
location: res.latitude + "," + res.longitude
}
})
// 判断用户位置和获取位置-城市是否一致
if (result.result.addressComponent.city.startsWith(this.$store.getters.user.workCityName)) {
// 跳转到打卡页面
this.$tab.navigateTo('/pages/attendance/index')
} else {
// 不一致,提示
this.$modal.msgError("工作地点与定位地点不同");
}
}
})
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
<style scoped lang="scss">
.wrap {
height: 100vh;
background-color: #f7f8fa;
.text-area {
display: flex;
justify-content: center;
}
.section {
background-color: white;
.title {
font-size: 36rpx;
color: #8f8f94;
.grid-item-box {
height: 100%;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
</style>
}
</style>
\ No newline at end of file
......@@ -17,23 +17,23 @@
<view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
<view class="iconfont icon-code icon"></view>
<input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
<view class="login-code">
<image :src="codeUrl" @click="getCode" class="login-code-img"></image>
<view class="login-code">
<image :src="codeUrl" @click="getCode" class="login-code-img"></image>
</view>
</view>
<view class="action-btn">
<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
</view>
<view class="reg text-center" v-if="register">
<text class="text-grey1">没有账号?</text>
<text @click="handleUserRegister" class="text-blue">立即注册</text>
</view>
<view class="xieyi text-center">
<text class="text-grey1">登录即代表同意</text>
<text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
<text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
</view>
</view>
<view class="reg text-center" v-if="register">
<text class="text-grey1">没有账号?</text>
<text @click="handleUserRegister" class="text-blue">立即注册</text>
</view>
<view class="xieyi text-center">
<text class="text-grey1">登录即代表同意</text>
<text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
<text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
</view>
</view>
</view>
</template>
......@@ -45,25 +45,26 @@
data() {
return {
codeUrl: "",
captchaEnabled: true,
// 用户注册开关
captchaEnabled: false,
// 用户注册开关
register: false,
globalConfig: getApp().globalData.config,
loginForm: {
username: "admin",
password: "admin123",
code: "",
username: "testlql01",
password: "123456",
// code: "",
uuid: ''
}
}
},
created() {
this.getCode()
// this.getCode()
},
methods: {
// 用户注册
handleUserRegister() {
this.$tab.redirectTo(`/pages/register`)
methods: {
// 用户注册
handleUserRegister() {
this.$tab.redirectTo(`/pages/register`)
},
// 隐私协议
handlePrivacy() {
......@@ -91,9 +92,11 @@
this.$modal.msgError("请输入您的账号")
} else if (this.loginForm.password === "") {
this.$modal.msgError("请输入您的密码")
} else if (this.loginForm.code === "" && this.captchaEnabled) {
this.$modal.msgError("请输入验证码")
} else {
}
// else if (this.loginForm.code === "" && this.captchaEnabled) {
// this.$modal.msgError("请输入验证码")
// }
else {
this.$modal.loading("登录中,请耐心等待...")
this.pwdLogin()
}
......@@ -175,28 +178,28 @@
margin-top: 40px;
height: 45px;
}
.reg {
margin-top: 15px;
}
.reg {
margin-top: 15px;
}
.xieyi {
color: #333;
margin-top: 20px;
}
.login-code {
height: 38px;
float: right;
.login-code-img {
height: 38px;
position: absolute;
margin-left: 10px;
width: 200rpx;
}
}
.login-code {
height: 38px;
float: right;
.login-code-img {
height: 38px;
position: absolute;
margin-left: 10px;
width: 200rpx;
}
}
}
}
</style>
<template>
<view class="work-container">
<!-- 轮播图 -->
<uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
<swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
......@@ -75,109 +76,115 @@
</template>
<script>
export default {
data() {
return {
current: 0,
swiperDotIndex: 0,
data: [{
image: '/static/images/banner/banner01.jpg'
},
{
image: '/static/images/banner/banner02.jpg'
},
{
image: '/static/images/banner/banner03.jpg'
}
]
}
},
methods: {
clickBannerItem(item) {
console.info(item)
export default {
data() {
return {
current: 0,
swiperDotIndex: 0,
data: [{
image: '/static/images/banner/banner01.jpg'
},
changeSwiper(e) {
this.current = e.detail.current
{
image: '/static/images/banner/banner02.jpg'
},
changeGrid(e) {
this.$modal.showToast('模块建设中~')
{
image: '/static/images/banner/banner03.jpg'
}
]
}
},
methods: {
clickBannerItem(item) {
console.info(item)
},
changeSwiper(e) {
this.current = e.detail.current
},
changeGrid(e) {
this.$modal.showToast('模块建设中~')
// uni.setTabBarItem({
// index: 1, // tabIndex,tabbar列表的索引,从0开始
// text: '我的消息', // 更新后的文字
// iconPath: '/static/message-icon.png', // 更新后的图标路径
// selectedIconPath: '/static/message-icon-active.png' // 更新后的选中图标路径
// });
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
min-height: 100%;
height: auto;
}
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
/* #endif */
.text {
text-align: center;
font-size: 26rpx;
margin-top: 10rpx;
}
.text {
text-align: center;
font-size: 26rpx;
margin-top: 10rpx;
}
.grid-item-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.grid-item-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.uni-margin-wrap {
width: 690rpx;
width: 100%;
;
}
.uni-margin-wrap {
width: 690rpx;
width: 100%;
;
}
.swiper {
height: 300rpx;
}
.swiper {
height: 300rpx;
}
.swiper-box {
height: 150px;
}
.swiper-box {
height: 150px;
}
.swiper-item {
.swiper-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
height: 300rpx;
line-height: 300rpx;
}
@media screen and (min-width: 500px) {
.uni-swiper-dot-box {
width: 400px;
/* #ifndef APP-NVUE */
display: flex;
margin: 0 auto;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
height: 300rpx;
line-height: 300rpx;
margin-top: 8px;
}
@media screen and (min-width: 500px) {
.uni-swiper-dot-box {
width: 400px;
/* #ifndef APP-NVUE */
margin: 0 auto;
/* #endif */
margin-top: 8px;
}
.image {
width: 100%;
}
.image {
width: 100%;
}
}
</style>
import { getToken } from '@/utils/auth'
// 登录页面
// 登录页面
const loginPage = "/pages/login"
// 页面白名单
......@@ -17,6 +17,7 @@ function checkWhite(url) {
// 页面跳转验证拦截器
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]
list.forEach(item => {
// 全局添加 API 属性等(拦截路由)
uni.addInterceptor(item, {
invoke(to) {
if (getToken()) {
......@@ -28,6 +29,7 @@ list.forEach(item => {
if (checkWhite(to.url)) {
return true
}
console.log(to.url)
uni.reLaunch({ url: loginPage })
return false
}
......@@ -36,4 +38,4 @@ list.forEach(item => {
console.log(err)
}
})
})
})
import store from '@/store'
export default {
// 消息提示
msg(content) {
......@@ -10,7 +11,8 @@ export default {
msgError(content) {
uni.showToast({
title: content,
icon: 'error'
icon: 'none',
duration: store.getters.delayTime
})
},
// 成功消息
......@@ -71,4 +73,4 @@ export default {
closeLoading() {
uni.hideLoading()
}
}
}
{
"appid": "wx5474d56c6eea0083",
"compileType": "miniprogram",
"libVersion": "3.6.4",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"coverView": true,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true,
"showShadowRootInWxmlPanel": true,
"packNpmRelationList": [],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}
\ No newline at end of file
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "ruoyi-uni",
"setting": {
"compileHotReLoad": true
}
}
\ No newline at end of file
const getters = {
token: state => state.user.token,
avatar: state => state.user.avatar,
user: state => state.user.user,
name: state => state.user.name,
roles: state => state.user.roles,
permissions: state => state.user.permissions
permissions: state => state.user.permissions,
delayTime: state => 3000 // 延迟弹窗关闭时间
}
export default getters
......@@ -12,7 +12,8 @@ const user = {
name: storage.get(constant.name),
avatar: storage.get(constant.avatar),
roles: storage.get(constant.roles),
permissions: storage.get(constant.permissions)
permissions: storage.get(constant.permissions),
user: storage.get(constant.user)
},
mutations: {
......@@ -34,6 +35,10 @@ const user = {
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
storage.set(constant.permissions, permissions)
},
SET_USER: (state, user) => {
state.user = user
storage.set(constant.user, user)
}
},
......@@ -46,8 +51,8 @@ const user = {
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
setToken(res.data.access_token)
commit('SET_TOKEN', res.data.access_token)
resolve()
}).catch(error => {
reject(error)
......@@ -70,6 +75,7 @@ const user = {
}
commit('SET_NAME', username)
commit('SET_AVATAR', avatar)
commit('SET_USER', user)
resolve(res)
}).catch(error => {
reject(error)
......@@ -95,4 +101,4 @@ const user = {
}
}
export default user
export default user
/**
* 显示消息提示框
* @param content 提示的标题
*/
export function toast(content) {
uni.showToast({
icon: 'none',
title: content
})
}
*/
export function toast(content) {
uni.showToast({
icon: 'none',
title: content
})
}
/**
* 显示模态弹窗
* @param content 提示的标题
*/
export function showConfirm(content) {
return new Promise((resolve, reject) => {
uni.showModal({
title: '提示',
content: content,
cancelText: '取消',
confirmText: '确定',
success: function(res) {
resolve(res)
}
})
})
}
*/
export function showConfirm(content) {
return new Promise((resolve, reject) => {
uni.showModal({
title: '提示',
content: content,
cancelText: '取消',
confirmText: '确定',
success: function (res) {
resolve(res)
}
})
})
}
/**
* 参数处理
* @param params 参数
......@@ -51,4 +51,19 @@ export function tansParams(params) {
}
}
return result
}
// 判断时间 1 是否小于时间 2
export function checkStartLessEndTime(startTime, endTime) {
if (startTime === null || startTime?.length === 0 || endTime === null) return true
// 把数组里的空值过滤掉
const startDate = new Date()
startDate.setHours(startTime.split(":")[0])
startDate.setMinutes(startTime.split(":")[1])
startDate.setSeconds(startTime.split(":")[2])
const endDate = new Date()
endDate.setHours(endTime.split(":")[0])
endDate.setMinutes(endTime.split(":")[1])
endDate.setSeconds(endTime.split(":")[2])
return startDate.getTime() - endDate.getTime() < 0
}
\ No newline at end of file
......@@ -2,7 +2,8 @@ const constant = {
avatar: 'vuex_avatar',
name: 'vuex_name',
roles: 'vuex_roles',
permissions: 'vuex_permissions'
permissions: 'vuex_permissions',
user: 'vuex_user'
}
export default constant
export default constant
......@@ -70,4 +70,4 @@ const request = config => {
})
}
export default request
export default request
......@@ -4,7 +4,7 @@ import constant from './constant'
let storageKey = 'storage_data'
// 存储节点变量名
let storageNodeKeys = [constant.avatar, constant.name, constant.roles, constant.permissions]
let storageNodeKeys = [constant.avatar, constant.name, constant.roles, constant.permissions, constant.user]
const storage = {
set: function(key, value) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论