wwp преди 2 месеца
родител
ревизия
fccd0fbbd3
променени са 16 файла, в които са добавени 280 реда и са изтрити 207 реда
  1. +10
    -77
      monitorMobile/api/user.js
  2. +47
    -19
      monitorMobile/common/mixins.vue
  3. +4
    -17
      monitorMobile/common/setting.js
  4. +28
    -39
      monitorMobile/http/api.js
  5. +1
    -1
      monitorMobile/http/config.js
  6. +1
    -3
      monitorMobile/main.js
  7. +15
    -0
      monitorMobile/manifest.json
  8. +14
    -0
      monitorMobile/package-lock.json
  9. +1
    -0
      monitorMobile/package.json
  10. +32
    -28
      monitorMobile/pages.json
  11. +24
    -0
      monitorMobile/pages/blankPage.vue
  12. +34
    -10
      monitorMobile/pages/login.vue
  13. +4
    -1
      monitorMobile/pages/my/index.vue
  14. +0
    -1
      monitorMobile/store/$u.mixin.js
  15. +35
    -11
      monitorMobile/store/index.js
  16. +30
    -0
      monitorMobile/utils/smCrypto.js

+ 10
- 77
monitorMobile/api/user.js Целия файл

@@ -1,85 +1,18 @@
import http from '@/http/api.js'
// 获取token
export const token = (tenantId, username, password, type) => {
let url = '/api/sys/auth/b'
// 登录
export const login = (data) => {
return http.request({
url: '/api/blade-auth/oauth/token',
url: url + '/login',
method: 'POST',
header: {
'Tenant-Id': tenantId
},
params: {
tenantId,
username,
password,
grant_type: "password",
scope: "all",
type
}
data
})
}
export const getTenantId = (params) => {
// 获取登录用户信息
export const getLoginUser = (params) => {
return http.request({
url: '/api/blade-auth/oauth/getTenantId',
method: 'get',
params: {
...params
}
})
}

export const refreshToken = (refresh_token, tenantId) => {
return http.request({
url: '/api/blade-auth/oauth/token',
method: 'post',
header: {
'Tenant-Id': tenantId
},
params: {
tenantId,
refresh_token,
grant_type: "refresh_token",
scope: "all",
}
})
}

// 获取用户信息
export const userInfo = () => {
return http.request({
url: '/api/blade-user/info',
method: 'GET',
})
}

// 获取用户信息
export const getUser = (id) => {
return http.request({
url: '/api/blade-user/detail',
url: url + '/getLoginUser',
method: 'GET',
params: { id }
params
})
}
/* 修改用户信息 */
export const updateInfo = (row) => {
return http.request({
url: '/api/blade-user/update-info',
method: 'post',
data: row
})
}
// 修改密码
export const updatePassword = (data) => {
return http.request({
url: '/api/blade-user/update-password',
method: 'post',
params: data
})
}
// 修改密码
export const passwordCheck = (data) => {
return http.request({
url: '/api/blade-user/passwordCheck',
method: 'post',
params: data
})
}
}

+ 47
- 19
monitorMobile/common/mixins.vue Целия файл

@@ -6,10 +6,6 @@
import {
Base64
} from '@/utils/base64.js';
import {
clientId,
clientSecret
} from '@/common/setting'
export default{
methods:{
// 暂存一个跨页面变量 (与 this.GET_PARAM 成对使用)
@@ -58,6 +54,42 @@
return url + query
},
// 获取一个全局变量
// key 为键名
GET_GLOBAL(key) {
return this.$store.state[key]
},
// 设置一个全局变量
// key 为键名
// val 为值
SET_GLOBAL(key, val) {
this.$store.commit(key, val)
},
// 清空全局变量
CLEAR_GLOBAL() {
this.$store.commit('clear')
uni.removeStorageSync('token')
},
// 将数据写入本地缓存
SET_STORAGE(key, data) {
if (data === null) {
uni.removeStorageSync(key)
} else {
uni.setStorageSync(key, data)
}
},
// 获取之前写入本地缓存的数据
GET_STORAGE(key) {
return uni.getStorageSync(key)
},
// 清空本地缓存
CLEAR_STORAGE() {
uni.clearStorageSync()
},
// 设置页面标题
SET_TITLE(title) {
uni.setNavigationBarTitle({
@@ -103,6 +135,10 @@
});
})
},
// 展示提示框
// title 为提示文字
// mask 为是否禁止点击
// icon 为显示图标,可以改为 'success'
TOAST(title){
uni.showToast({
icon: "none",
@@ -110,17 +146,18 @@
duration: 2000,
});
},
// 停止展示 toast 提示框
HIDE_TOAST() {
uni.hideToast()
},
UPLOAD_FILE(filePath){
let that = this
// 假设有token值需要在头部需要携带
let header = {}
let accessToken = uni.getStorageSync('accessToken');
if (accessToken) {
header['Blade-Auth'] = 'bearer ' + accessToken;
let token = uni.getStorageSync('token');
if (token) {
config.header['Authorization'] = 'Bearer ' + token;
}
// 客户端认证参数
header['Authorization'] = 'Basic ' + Base64.encode(clientId + ':' + clientSecret);
console.log(filePath)
return new Promise(resovle=>{
uni.uploadFile({
url:options.baseURL + '/api/blade-resource/oss/endpoint/put-uplaod-file?bucketName=',
@@ -179,18 +216,9 @@
data: item, // 要复制的路径
success: function(res) {
resolve(true)
// uni.getClipboardData({
// success: function(data) {
// resolve(true)
// },
// fail: function(data1) {
// resolve(false)
// }
// });
}
});
})
},
},
}

+ 4
- 17
monitorMobile/common/setting.js Целия файл

@@ -3,7 +3,6 @@
*/
// #ifdef H5
let origin = window.location.origin
console.log(window.location.origin)
// #endif
module.exports = {
// 应用名
@@ -25,16 +24,11 @@ module.exports = {
// 小程序接口Url
// #ifndef H5
// devUrl: 'http://192.168.10.46',
devUrl: 'https://www.bjjyp.org.cn/rider',//开发环境接口Url
prodUrl: `https://www.bjjyp.org.cn/rider`,//线上环境接口Url
// prodUrl: 'http://192.168.100.236:1888',
// prodUrl: 'http://114.255.136.189:1888',
devUrl: `${origin}/`,//开发环境接口Url
prodUrl: `${origin}/`,//线上环境接口Url
// #endif
// 后端数据的接收方式application/json;charset=UTF-8或者application/x-www-form-urlencoded;charset=UTF-8
contentType: 'application/json;charset=UTF-8',
// 后端返回状态码
@@ -43,15 +37,8 @@ module.exports = {
successCode: 200,
// 登录失效code
invalidCode: 401,
// 客户端ID
clientId: 'rider',
// 客户端密钥
clientSecret: 'rider_secret',
// token过期时间
tokenTime: 3000,
switchMode: true, // 是否开启部门切换模式
//本地
previewUrl: 'http://cp.qjkjedu.com/onlinePreview',
//金隅生产
// previewUrl: 'https://www.bjjyp.org.cn/preview/onlinePreview',
//文件预览地址
previewUrl: '',
}

+ 28
- 39
monitorMobile/http/api.js Целия файл

@@ -1,52 +1,22 @@
import {
devUrl,
clientId,
clientSecret
} from '@/common/setting'
import {
options
} from '@/http/config.js';
import {
Base64
} from '@/utils/base64.js';
import Request from '@/utils/luch-request/index.js';
const http = new Request(options);
http.interceptors.request.use((config) => { // 可使用async await 做异步操作
// 假设有token值需要在头部需要携带
let accessToken = uni.getStorageSync('accessToken');
if (accessToken) {
config.header['Blade-Auth'] = 'bearer ' + accessToken;
let token = uni.getStorageSync('token');
if (token) {
config.header['Authorization'] = 'Bearer ' + token;
}
// 客户端认证参数
config.header['Authorization'] = 'Basic ' + Base64.encode(clientId + ':' + clientSecret);

// #ifndef H5
let url = config.url
if (process.env.NODE_ENV == 'development' && !url.startsWith("http")) {
// url = url.substring(url.indexOf('/api') + 4)
config.url = url
}
// #endif

// 额外参数
// config.data = config.data || {};
// config.data.pf = uni.getSystemInfoSync().platform;
// config.data.sys = uni.getSystemInfoSync().system;

// 演示custom 用处
// if (config.custom.auth) {
// config.header.token = 'token'
// }
// if (config.custom.loading) {
// uni.showLoading()
// }
/**
/* 演示
if (!token) { // 如果token不存在,return Promise.reject(config) 会取消本次请求
return Promise.reject(config)
}
**/
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
@@ -58,7 +28,7 @@ http.interceptors.response.use((response) => {
}
// 服务端返回的状态码不等于200,则reject()
if (response.data.code && response.data.code !== 200) {
setTimeout(()=>{
setTimeout(() => {
uni.showToast({
title: response.data.msg,
icon: 'none'
@@ -69,20 +39,39 @@ http.interceptors.response.use((response) => {
return response.data;
}, (response) => {
/* 对响应错误做点什么 (statusCode !== 200)*/
setTimeout(()=>{
setTimeout(() => {
uni.showToast({
title: response.data.msg || response.data.error_description || '网络错误',
icon: 'none'
});
})
if (response.statusCode == 401) {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
uni.redirectTo({
url: `/pages/login/login?redirect=/${currentPage.route}`
url: `/pages/login?redirect=/${currentPage.route}`
})
}
return Promise.reject(response)
})
export default http;
/**
* @description 解密 JWT token 的信息
* @param token jwt token 字符串
* @returns <any>object
*/
function decryptJWT(token) {
token = token.replace(/_/g, "/").replace(/-/g, "+");
const json = decodeURIComponent(escape(window.atob(token.split(".")[1])));
return JSON.parse(json);
}

/**
* @description 将 JWT 时间戳转换成 Date,主要针对 `exp`,`iat`,`nbf`
* @param timestamp 时间戳
* @returns Date 对象
*/
function getJWTDate(timestamp) {
return new Date(timestamp * 1000);
}
export default http;

+ 1
- 1
monitorMobile/http/config.js Целия файл

@@ -44,6 +44,6 @@ var options = {
// previewUrl: 'https://www.bjjyp.org.cn/preview/onlinePreview',
// previewUrl: 'http://114.255.136.189:6696/onlinePreview',
// previewUrl: 'http://192.168.100.236:85/onlinePreview',
previewUrl: 'http://cp.qjkjedu.com/onlinePreview',
previewUrl: '',
};
export { options };

+ 1
- 3
monitorMobile/main.js Целия файл

@@ -1,12 +1,9 @@
import App from './App'
import Vue from 'vue'
import store from '@/store';
import mixins from '@/common/mixins.vue'

Vue.mixin(mixins)

// 引入vuex
Vue.prototype.$u = {}
const vuexStore = require("@/store/$u.mixin.js");
Vue.mixin(vuexStore);

@@ -34,6 +31,7 @@ export function createApp() {
}
// #endif

// 添加http实例
import http from '@/http/api.js'
Vue.prototype.$http = http



+ 15
- 0
monitorMobile/manifest.json Целия файл

@@ -65,6 +65,21 @@
"mp-toutiao" : {
"usingComponents" : true
},
"h5" : {
"devServer" : {
"port" : 1888,
"proxy" : {
"/api" : {
"target" : "http://192.168.10.186:8003",
"changeOrigin" : true,
"pathRewrite" : {
"^/api" : ""
}
}
},
"https" : false
}
},
"uniStatistics" : {
"enable" : false
},


+ 14
- 0
monitorMobile/package-lock.json Целия файл

@@ -5,6 +5,7 @@
"packages": {
"": {
"dependencies": {
"sm-crypto": "^0.3.13",
"uview-ui": "^2.0.36",
"vuex": "^3.6.2"
},
@@ -801,6 +802,11 @@
"node": ">= 10.13.0"
}
},
"node_modules/jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
@@ -1137,6 +1143,14 @@
"randombytes": "^2.1.0"
}
},
"node_modules/sm-crypto": {
"version": "0.3.13",
"resolved": "https://registry.npmmirror.com/sm-crypto/-/sm-crypto-0.3.13.tgz",
"integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
"dependencies": {
"jsbn": "^1.1.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",


+ 1
- 0
monitorMobile/package.json Целия файл

@@ -1,5 +1,6 @@
{
"dependencies": {
"sm-crypto": "^0.3.13",
"uview-ui": "^2.0.36",
"vuex": "^3.6.2"
},


+ 32
- 28
monitorMobile/pages.json Целия файл

@@ -2,14 +2,13 @@
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
"tabBar":{
"color":"#777777",
"selectedColor":"#2388FF",
"backgroundColor":"#FFFFFF",
"borderStyle":"white",
"fontSize":"18rpx",
"list": [
{
"tabBar": {
"color": "#777777",
"selectedColor": "#2388FF",
"backgroundColor": "#FFFFFF",
"borderStyle": "white",
"fontSize": "18rpx",
"list": [{
"pagePath": "pages/earlyWarning/index",
"iconPath": "/static/image/tabbar/earlyWarning.png",
"selectedIconPath": "/static/image/tabbar/earlyWarning_active.png",
@@ -30,6 +29,14 @@
]
},
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/blankPage",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
// 预警
{
"path": "pages/earlyWarning/index",
@@ -54,12 +61,11 @@
}
},
{
"path" : "pages/work/returnBed/detail",
"style" :
{
"navigationBarTitleText": "归寝",
"enablePullDownRefresh": false
}
"path": "pages/work/returnBed/detail",
"style": {
"navigationBarTitleText": "归寝",
"enablePullDownRefresh": false
}
},
// 客流
{
@@ -69,12 +75,11 @@
}
},
{
"path" : "pages/work/passengerFlow/detail",
"style" :
{
"navigationBarTitleText": "分片详情",
"enablePullDownRefresh": false
}
"path": "pages/work/passengerFlow/detail",
"style": {
"navigationBarTitleText": "分片详情",
"enablePullDownRefresh": false
}
},
// 点名
{
@@ -84,12 +89,11 @@
}
},
{
"path" : "pages/work/rollCall/detail",
"style" :
{
"navigationBarTitleText": "查看",
"enablePullDownRefresh": false
}
"path": "pages/work/rollCall/detail",
"style": {
"navigationBarTitleText": "查看",
"enablePullDownRefresh": false
}
},
// 巡警
{
@@ -132,7 +136,7 @@
"navigationStyle": "custom"
}
}
],
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "校园监控预警平台",
@@ -140,4 +144,4 @@
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}
}

+ 24
- 0
monitorMobile/pages/blankPage.vue Целия файл

@@ -0,0 +1,24 @@
<template>
<view></view>
</template>

<script>
export default {
created() {
// token标志来判断
let token = uni.getStorageSync('token');
if (!token) {
uni.reLaunch({
url: '/pages/login'
})
} else {
uni.switchTab({
url: '/pages/earlyWarning/index'
})
}
}
}
</script>

<style>
</style>

+ 34
- 10
monitorMobile/pages/login.vue Целия файл

@@ -37,7 +37,10 @@
</template>

<script>
import {token} from '@/api/user.js'
import {
login,
} from '@/api/user.js'
import smCrypto from '@/utils/smCrypto'
export default {
data() {
return {
@@ -47,13 +50,14 @@
},
passType: 'password',
isLoading: false,
redirect: '',
rules: {
account: [{
required: true,
message: '请输入账号',
trigger: ['blur', 'change']
}],
pass: [{
password: [{
required: true,
message: '请输入密码',
trigger: ['blur', 'change']
@@ -69,12 +73,32 @@
}
}
},
onLoad(e) {
if (e.redirect) this.redirect = redirect
this.form.account = 'superAdmin'
this.form.password = '123456'
},
methods: {
login() {
token()
this.$refs.uForm.validate(valid => {
if (!valid) return
this.isLoading = true
async login() {
this.$refs.uForm.validate().then(() => {
login({
...this.form,
password: smCrypto.doSm2Encrypt(this.form.password)
}).then(res => {
if (res.code != 200) return
let data = res.data
this.$store.dispatch('setToken',{token:data.token})
this.$store.dispatch('getUserInfo')
this.NAV_TO('/')
}).finally(() => {
this.isLoading = false
})
})
},
getLoginUser(){
return getLoginUser().then(res=>{
if (res.code != 200) return
this.$u.vuex('userInfo', res.data)
})
}
},
@@ -99,7 +123,7 @@
}

input[type="password"]::-ms-reveal {
display: none!important;
display: none !important;
}

.logoBox {
@@ -138,8 +162,8 @@
margin-bottom: 30rpx;
// font-weight: 700;
}
/deep/.u-form-item__body{
/deep/.u-form-item__body {
padding: 15rpx 0;
}
}

+ 4
- 1
monitorMobile/pages/my/index.vue Целия файл

@@ -124,7 +124,10 @@
this.date = e.detail.value
},
loginOut() {
this.CONFIRM('您是否确认退出登录?')
this.CONFIRM('您是否确认退出登录?').then(()=>{
this.$store.dispatch('clearToken')
this.JUMP_TO('/pages/login')
})
}
}
}


+ 0
- 1
monitorMobile/store/$u.mixin.js Целия файл

@@ -15,7 +15,6 @@ module.exports = {
mounted() {
// 将vuex方法挂在到$u中
// 使用方法为:如果要修改vuex的state中的user.name变量为"史诗" => this.$u.vuex('user.name', '史诗')
// 如果要修改vuex的state的version变量为1.0.1 => this.$u.vue x('version', '1.0.1')
this.$u.vuex = (name, value) => {
this.$store.commit('$uStore', {
name,


+ 35
- 11
monitorMobile/store/index.js Целия файл

@@ -1,6 +1,9 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import {
getLoginUser
} from '@/api/user.js'

let lifeData = {};

@@ -12,7 +15,7 @@ try {
}

// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
let saveStateKeys = [];
let saveStateKeys = ['token', 'userInfo'];

// 保存变量到本地存储中
const saveLifeData = function(key, value) {
@@ -27,7 +30,7 @@ const saveLifeData = function(key, value) {
uni.setStorageSync(key, value);
uni.setStorageSync('lifeData', tmp);
}
if(key == 'refreshToken') {
if (key == 'refreshToken') {
uni.setStorageSync('token', {
content: value,
datetime: new Date().getTime()
@@ -35,16 +38,37 @@ const saveLifeData = function(key, value) {
}
}
const store = new Vuex.Store({
// 下面这些值仅为示例,使用过程中请删除
state: {
// 如果上面从本地获取的lifeData对象下有对应的属性,就赋值给state中对应的变量
userInfo: lifeData.userInfo ? lifeData.userInfo : {
avatar: '',
nick_name: '游客',
tenant_id: '暂无'
userInfo: lifeData.userInfo || null,
token: lifeData.accessToken || '',
refreshToken: '',
},
actions: {
async getUserInfo(context) {
const {
data
} = await getLoginUser();
if(data){
context.commit('$uStore', {
name: 'userInfo',
value: data
})
}
return data;
},
setToken(context,payload){
context.commit('$uStore', {
name: 'token',
value: payload.token
})
},
accessToken: lifeData.accessToken ? lifeData.accessToken : '',
isLogin: lifeData.isLogin ? lifeData.isLogin : false,
clearToken(context){
context.commit('$uStore', {
name: 'token',
value: ''
})
}
},
mutations: {
$uStore(state, payload) {
@@ -69,5 +93,5 @@ const store = new Vuex.Store({
}
}
})
export default store
Vue.prototype.$store = store
export default store

+ 30
- 0
monitorMobile/utils/smCrypto.js Целия файл

@@ -0,0 +1,30 @@
/**
* @description smCrypto 加密解密工具
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/

import smCrypto from "sm-crypto";
const { sm2 } = smCrypto;
const cipherMode = 0; // 1 - C1C3C2,0 - C1C2C3,默认为1
const publicKey =
"04BD62406DF6789B1FBE8C457AECAE6D7C806CDB39316F190519905C24DF395E8952C47798D76ADECF8CA28C935702AFCDD9B17DE77121FA6448F0EDEFBD8365D6";

/**
* 国密加解密工具类
*/
export default {
// SM2加密
doSm2Encrypt(msgString) {
return sm2.doEncrypt(msgString, publicKey, cipherMode);
}
};

Зареждане…
Отказ
Запис