leaf 5 месяцев назад
Родитель
Сommit
7468b75e27
9 измененных файлов с 641 добавлено и 0 удалено
  1. 57 0
      lib/auth/token.ts
  2. 47 0
      lib/auth/weixin.ts
  3. 36 0
      lib/check.ts
  4. 19 0
      lib/config/index.ts
  5. 61 0
      lib/dlg.ts
  6. 63 0
      lib/link.ts
  7. 181 0
      lib/util.ts
  8. 9 0
      pages/index/index.vue
  9. 168 0
      stores/rest.ts

+ 57 - 0
lib/auth/token.ts

@@ -0,0 +1,57 @@
+import {TOKEN_KEY, TENANT_KEY} from "@/lib/config"
+
+
+
+export function getConfig(key:string) {
+  try {
+	  let val = uni.getStorageSync(key);
+      if(val==null || typeof(val)==='undefined' ||val==""){
+		  return null
+	  }
+	  return val;
+  } catch (e) {
+	console.log("获取"+key+"出错",e);
+	return null;
+  }
+}
+
+export function setConfig(key:string, val: string) {
+  try {
+	  if(val == null || val ==""){
+		  uni.setStorageSync(key, val);
+		  uni.removeStorageSync(key)
+		  return;
+	  }
+      uni.setStorageSync(key, val);
+	  return;
+  } catch (e) {
+  	console.log("设置"+key+"出错",e);
+  	return null;
+  }
+}
+
+
+
+export function getToken() {
+	return getConfig(TOKEN_KEY)
+}
+
+export function setToken(token: string) {
+	return setConfig(TOKEN_KEY, token)
+}
+
+
+export function getTenant() {
+	return getConfig(TENANT_KEY)
+}
+
+export function setTenant(val: string) {
+	return setConfig(TENANT_KEY, val)
+}
+
+export default {
+	getToken,
+	setToken,
+	getTenant,
+	setTenant
+}

+ 47 - 0
lib/auth/weixin.ts

@@ -0,0 +1,47 @@
+// 认证接口: 获取 open_id 后登录
+
+//https://mt5t6sp5cd.feishu.cn/docx/SftAdyxGzoQwAWxCnDrc3F8en3g
+import rest from '@/stores/rest'
+import { OPEN_ID } from '@/lib/config';
+
+//获取 JsCode
+export const wxLogin = async () => {
+	console.log("WxLogin")
+	return new Promise((resolve, reject) => {
+		wx.login({
+			timeout:3000,
+			success(res) {
+				console.log("wx.login success", res)
+				if (res.code) {
+					resolve(res.code)
+					return;
+				}
+				reject(res.errMsg)
+			},
+			fail(err){
+				reject(err.errMsg)
+			}
+		})
+	});
+}
+
+export const getOpenId = async () => {
+	let openid = await uni.getStorageSync(OPEN_ID)
+	if (openid) return
+	try {
+		let jsCode = await wxLogin()
+		let url = '/member/user/jscode2session?jsCode=' + jsCode
+		let result = await rest.post(url, null)
+		if (result['openid']) {
+			uni.setStorageSync(OPEN_ID, result['openid'])
+		}
+	} catch (e) {
+		console.log(e)
+	}
+}
+
+
+//通过获取 jsCode 自动登录
+export const userLogin = async (jsCode:string) => {
+	
+}

+ 36 - 0
lib/check.ts

@@ -0,0 +1,36 @@
+//校验手机号的有效性
+export function phone(val) {
+	//手机号正则
+	var phoneReg = /(^1[3|4|5|7|8|9]\d{9}$)|(^09\d{8}$)/;
+	//电话
+	if (!phoneReg.test(val)) {
+		throw "手机号码不正确";
+		return false;
+	}
+	return true;
+}
+
+
+//是否为空
+export function empty(val){	
+	if(val=="" ||val==null||typeof(val)==undefined){
+		return true;
+	}
+	return false;
+}
+
+
+//不为空
+export function required(val, name=""){	
+	if(empty(val)){
+		throw name+"不为空";
+		return false;
+	}
+	return true;
+}
+
+export default {
+	phone,
+	empty,
+	required
+}

+ 19 - 0
lib/config/index.ts

@@ -0,0 +1,19 @@
+
+//--- 本地调试
+// const  SERVER= 'http://127.0.0.1:48080'
+
+// //--- 测试服务器
+//export const  SERVER= 'https://'
+
+// //--- 正式服务器
+export const SERVER = 'http://47.100.229.147:22082'//todo
+
+export const BASE_URL = SERVER //+ '/dev-api'
+
+export const VITE_UPLOAD_URL = 'http://192.168.31.36:9099'
+
+export const TOKEN_KEY = "token";
+export const TENANT_KEY = "tenant-id";
+export const TENANT_NAME = "tenant-name"
+export const TENANT_TYPE = "tenant-type"
+export const OPEN_ID = "open_id"

+ 61 - 0
lib/dlg.ts

@@ -0,0 +1,61 @@
+//常用对话框
+export const success = (title : string, duration = 1500, mask = false) => {
+	return toast(title, duration, mask, 'success');
+}
+
+export const toast = function (title : string, duration : number, mask : boolean, icon : any) {
+	return new Promise((resolve, reject) => {
+		uni.showToast({
+			title, duration, mask, icon,
+			success: res => {
+
+				setTimeout(function () {
+					resolve(res);
+				}, duration);
+			},
+			fail: err => {
+				reject(err)
+			}
+		});
+
+	});
+}
+
+
+
+//获取 错误提示
+export const error = (title : string) => {
+	let duration = 2000;
+	let mask = false;
+	return new Promise((resolve, reject) => {
+		uni.showToast({
+			title, duration, mask,
+			icon: "none",
+			success: res => {
+				setTimeout(function () {
+					resolve(res);
+				}, duration);
+			},
+			fail: err => {
+				reject(err)
+			}
+		});
+	});
+}
+
+
+
+//顶部信息
+export const tip = (title : string) => {
+	uni.showToast({
+		title,
+		position: 'top',
+		duration: 1500,
+		mask: false,
+		icon: 'none'
+	});
+}
+
+export default {
+	success, toast, error, tip,
+}

+ 63 - 0
lib/link.ts

@@ -0,0 +1,63 @@
+export const navToAsync = (url) => {
+	return new Promise((resolve, reject) => {
+		uni.navigateTo({
+			url: url,
+			success: res => {
+				return true;
+			},
+			fail: err => {
+				return false;
+			}
+		});
+	});
+}
+
+export const navto = (url, replace = false) => {
+	if (replace) {
+		return uni.redirectTo({
+			url: url
+		});
+	}
+	return uni.navigateTo({
+		url: url
+	});
+}
+
+
+
+export const home = () => {
+	return navto('/pages/index/index', true);
+}
+
+
+
+export const back = () => {
+	return new Promise((resolve, reject) => {
+		uni.navigateBack({
+			success: res => {
+				return true;
+			},
+			fail: err => {
+				uni.reLaunch({
+					url: '/pages/index/index',
+				});
+				return false;
+			}
+		});
+	});
+
+	// return uni.navigateBack();
+}
+
+export const login = () => {
+	let url : String
+	// #ifdef MP-WEIXIN
+	url = '/pages/user/login'
+	// #endif
+	// #ifdef APP
+	url = '/pages/user/login_other'
+	// #endif
+	uni.navigateTo({
+		url: url,
+	})
+}

+ 181 - 0
lib/util.ts

@@ -0,0 +1,181 @@
+export function parseTime(time, cFormat) {
+	if (!time) {
+		return null
+	}
+	const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
+	let date
+	if (typeof time === 'object') {
+		date = time
+	} else {
+		if ((typeof time === 'string')) {
+			if ((/^[0-9]+$/.test(time))) {
+				// support "1548221490638"
+				time = parseInt(time)
+			} else {
+				// support safari
+				// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
+				time = time.replace(new RegExp(/-/gm), '/')
+			}
+		}
+
+		if ((typeof time === 'number') && (time.toString().length === 10)) {
+			time = time * 1000
+		}
+		date = new Date(time)
+	}
+	const formatObj = {
+		y: date.getFullYear(),
+		m: date.getMonth() + 1,
+		d: date.getDate(),
+		h: date.getHours(),
+		i: date.getMinutes(),
+		s: date.getSeconds(),
+		a: date.getDay(),
+		p: date.getHours(),
+	}
+	const time_str = format.replace(/{([ymdhisap])+}/g, (result, key) => {
+		const value = formatObj[key]
+		// Note: getDay() returns 0 on Sunday
+		if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+		if (key === 'p') {
+			if (value < 12) {
+				return '上午'
+			}
+			return '下午'
+		}
+		return value.toString().padStart(2, '0')
+	})
+	return time_str
+}
+
+/**
+ * 时间日期转换
+ * @param date 当前时间,new Date() 格式
+ * @param format 需要转换的时间格式字符串
+ * @returns 返回拼接后的时间字符串
+ */
+export function formatDate(date : Date | string, format ?: string) : string {
+	// 日期不存在,则返回空
+	if (!date) {
+		return ''
+	}
+	const _date = typeof date === 'string' || 'object' ? new Date(date) : date
+	// 日期存在,则进行格式化
+	if (format === undefined) {
+		format = '{y}-{m}-{d} {h}:{i}:{s}'
+	}
+	return parseTime(_date, format)
+}
+
+/**
+ * 将时间转换为 `几秒前`、`几分钟前`、`几小时前`、`几天前`
+ * @param param 当前时间,new Date() 格式或者字符串时间格式
+ * @param format 需要转换的时间格式字符串
+ * @returns 返回拼接后的时间字符串
+ */
+export function formatPast(param : string | Date, format = '{y}-{m}-{d} {h}:{i}:{s}') : string {
+	// 传入格式处理、存储转换值
+	let t : any, s : number
+	// 获取js 时间戳
+	let time : number = new Date().getTime()
+	// 是否是对象
+	typeof param === 'string' || 'object' ? (t = new Date(param).getTime()) : (t = param)
+	// 当前时间戳 - 传入时间戳
+	time = Number.parseInt(`${time - t}`)
+	if (time < 10000) {
+		// 10秒内
+		return '刚刚'
+	} else if (time < 60000 && time >= 10000) {
+		// 超过10秒少于1分钟内
+		s = Math.floor(time / 1000)
+		return `${s}秒前`
+	} else if (time < 3600000 && time >= 60000) {
+		// 超过1分钟少于1小时
+		s = Math.floor(time / 60000)
+		return `${s}分钟前`
+	} else if (time < 86400000 && time >= 3600000) {
+		// 超过1小时少于24小时
+		s = Math.floor(time / 3600000)
+		return `${s}小时前`
+	} else if (time < 259200000 && time >= 86400000) {
+		// 超过1天少于3天内
+		s = Math.floor(time / 86400000)
+		return `${s}天前`
+	} else {
+		// 超过3天
+		const date = typeof param === 'string' || 'object' ? new Date(param) : param
+		return formatDate(date, format)
+	}
+}
+
+//根据出生日期计算年龄
+export const calculateAge = (birthDate) => {
+	const today = new Date(); // 获取当前日期
+	// 将传入的出生日期字符串转换为Date对象
+	const birth = new Date(birthDate);
+	let age = today.getFullYear() - birth.getFullYear(); // 计算年份差值
+	// 检查是否已经过了生日
+	const hasPassedBirthday = today.getMonth() > birth.getMonth() ||
+		(today.getMonth() === birth.getMonth() && today.getDate() >= birth.getDate());
+	if (!hasPassedBirthday) {
+		age--; // 如果还没过生日,则减去1年
+	}
+	return age;
+}
+/**
+ * 身份证号获得1:男/2:女
+ */
+export const getSexByCardNo = (cardNo: string): string => {  
+  let letter = '';
+  if (cardNo.length == 15) {    
+    letter= cardNo.substring(14)
+  } else if (cardNo.length == 18) {
+    letter= cardNo.substring(16,17)
+  }
+  if (letter != '') {
+    return Number(letter)%2?'1':'2'
+  }
+  return ''
+}
+
+
+/**
+ * 身份证号获得出身年月
+ */
+export const getBirthByCardNo = (cardNo: string,split:string='-'): string => {
+  let year: string = '';
+  let month: string = '';
+  let day: string = '';
+
+  if (cardNo.length == 15) {
+    var org_birthday = cardNo.substring(6, 12);
+    //获取出生年月日
+    year = "19" + org_birthday.substring(0, 2);
+    month = org_birthday.substring(2, 4);
+    day = org_birthday.substring(4, 6);
+
+  } else if (cardNo.length == 18) {
+    year = cardNo.substring(6,10);
+    month = cardNo.substring(10,12);
+    day = cardNo.substring(12,14);
+  }
+  return year+split+month+split+day
+}
+/**
+ * 身份证号获得年龄
+ */
+export const getAgeByCardNo = (cardNo: string): number => {
+  let birth = getBirthByCardNo(cardNo)
+  if (birth == '') {
+    return 0
+  }
+  let birthArr = birth.split('-');
+  var newDate = new Date();
+  var month = newDate.getMonth() + 1;
+  var day = newDate.getDate();
+  var age = newDate.getFullYear() - Number(birthArr[0]) - 1;
+  if (Number(birthArr[1])< month || Number(birthArr[1]) == month && Number(birthArr[2]) <= day) {
+      age++;
+  }
+  return age;
+}

+ 9 - 0
pages/index/index.vue

@@ -20,6 +20,8 @@
 
 <script lang="ts" setup>
 	import { ref, nextTick, onMounted } from 'vue'
+	import rest from '@/stores/rest'
+
 	import TopCard from './TopCard.vue'
 	import CfStatus from './CfStatus.vue'
 	import CfLogistics from './CfLogistics.vue'
@@ -74,7 +76,14 @@
 		tabClick(_inx);
 	}
 
+	const getInfo = async () => {
+		//todo。测试接口
+		let res = await rest.get('/tcm-cloud/admin-api/zyyp/command-center/zzjgStatistic', {})
+		console.log("res", res)
+	}
+
 	onMounted(() => {
+		getInfo()
 	})
 </script>
 

+ 168 - 0
stores/rest.ts

@@ -0,0 +1,168 @@
+import { BASE_URL } from "@/lib/config"
+import dlg from "@/lib/dlg"
+import { getToken, getTenant } from "@/lib/auth/token"
+
+
+function getHeader() {
+	let header = {
+		"Content-Type": "application/json"
+	};
+	//获取token
+	let token = getToken()
+	let tenant = getTenant()
+	if (token) {
+		header["Authorization"] = "Bearer " + token;
+		// header["token"] = token;
+	}
+
+	if (tenant) {
+		header["tenant-id"] = tenant;
+	}
+	header["source-type"] = "app"
+	// #ifdef APP
+	let systemInfo = uni.getSystemInfoSync()
+	let osName = systemInfo.osName
+	let brand = systemInfo.brand
+	let model = systemInfo.model
+	let osVersion = systemInfo.osVersion
+	let appVersion = systemInfo.appWgtVersion
+	let channel = "uniapp"
+	let userAgent = `app-${osName} ${brand} ${model}_${osVersion} APP_V${appVersion} CHANNEL_${channel}`
+	header["user-agent"] = userAgent
+	// #endif
+
+	return header;
+}
+
+
+
+const fetch = async (method : any, url : string, data : any, loading = false) => {
+
+	return await new Promise((resolve, reject) => {
+		//显示加载动画
+		if (loading) {
+			uni.showLoading();
+		}
+		if (url.indexOf("http") == -1) {
+			url = BASE_URL + url;
+		}
+		// console.log('request url = ' + url);
+		try {
+			//发起请求
+			uni.request({
+				url,
+				method,
+				data,
+				header: getHeader(),
+				success: res => {
+					let statusCode = res.statusCode;
+					console.log("res", res)
+					if (statusCode == 200) {
+						let { code, msg, data, message } = res.data
+						// console.log(method + "[" + url + "]success", res);
+						if (!isSuccess(code)) {
+							if (msg) {
+								reject(msg);
+							}
+							if (message) {
+								dlg.error(message);
+								reject(message);
+							}
+						}
+						resolve(res.data['data']);
+					} else {
+						console.log(`\x1b[31m${res.data['status']} ${res.data['path']} ${res.data['error']}\x1b[0m`)
+						reject(res.data)
+					}
+				},
+				fail: err => {
+					console.log("请求fail", err);
+					reject(err);
+					return null;
+				},
+				complete: () => {
+					//结束加载动画
+					if (loading) {
+						uni.hideLoading();
+					}
+				}
+			});
+
+		} catch (e) {
+			reject(e.message);
+		}
+	});
+
+}
+
+//文件上传
+const uploadSync = (filePath) => {
+	return new Promise((resolve, reject) => {
+		uni.uploadFile({
+			url: BASE_URL + '/infra/file/upload',
+			// file: image,
+			header: getHeader(),
+			filePath: filePath,
+			name: 'file',
+			success: (res) => {
+				let result = JSON.parse(res.data);
+				console.log("upload ", result);
+				if (result.code < 0) {
+					// console.log("请求出错" + url, result);
+					dlg.error('上传出错' + result.message);
+					reject(result)
+					return null;
+				}
+
+				let data = result.data;
+				console.log("upload data= ", data);
+				resolve(data);
+				return data;
+			},
+			fail: err => {
+				dlg.error('上传出错' + err);
+				reject(err)
+				return null;
+			},
+		});
+	});
+}
+
+//上传
+const upload = async (file) => {
+	console.log("file==>", JSON.stringify(file));
+	return await uploadSync(file);
+}
+
+
+function isSuccess(code : number) {
+	return code == 0 || code == 200 || code == 2001;
+}
+
+export const get = (url : string, params : any, loading = false) => {
+	return fetch('GET', url, params, loading)
+}
+
+export const post = (url : string, params : any, loading = false) => {
+	return fetch('POST', url, params, loading)
+}
+
+export const put = (url : string, params : any, loading = false) => {
+	return fetch('PUT', url, params, loading)
+}
+
+export const del = (url : string, params : any, loading = false) => {
+	return fetch('DELETE', url, params, loading)
+}
+
+
+export const checkErr = (fun : Function) => {
+	try {
+		return fun()
+	} catch (e) {
+		dlg.error(e.message)
+		return null
+	}
+}
+
+export default { get, post, put, del, checkErr, upload }