APP文件新增

This commit is contained in:
geht
2026-07-20 14:10:39 +08:00
parent 99987d9d2e
commit 395a52b4c6
710 changed files with 227084 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
//APP更新
export default function appUpdate() {
console.log('plus.runtime.appid', plus.runtime.appid)
console.log('plus.runtime.version', plus.runtime.version)
console.log('plus.device.imei', plus.device.imei)
uni.request({
url: 'http://app.myhjdc.cn/update.json', //检查更新的服务器地址
data: {
appid: plus.runtime.appid,
version: plus.runtime.version,
imei: plus.device.imei,
},
success: (res: any) => {
plus.runtime.getProperty(plus.runtime.appid, function (wgtinfo) {
console.log('客户端版本信息 wgtinfo', wgtinfo)
console.log('服务端版本信息 res', res)
// 客户端版本
let client_version = wgtinfo.version
//------------------------前两位大版本有改动-----------------------------------------------
// 大版本是否一致 版本号1.1.0,前两位如果有改动,就是大版本更新;否则就是小版本热更新
const flag_update =
client_version.split('.').splice(0, 2).join('.') !=
res.data.version.split('.').splice(0, 2).join('.')
//------------------------前两位大版本有改动-----------------------------------------------
//------------------------第三位小版本有改动-热更新-----------------------------------------------
// 客户端版本号
let client_version_number = Number(client_version.split('.')[2])
// 服务器版本号
let current_version_number = Number(res.data.version.split('.')[2])
// 如果客户端版本号小于服务器版本号,则提醒用户更新
const flag_hot = !flag_update && client_version_number < current_version_number
//------------------------第三位小版本有改动-热更新-----------------------------------------------
console.log('客户端版本 client_version', client_version)
console.log('客户端版本号 client_version_number', client_version_number)
console.log('服务器版本号 current_version_number', current_version_number)
console.log('升级更新 flag_update', flag_update)
console.log('热更新 flag_hot', flag_hot)
if (flag_update) {
console.log('*****开始大版本更新*****')
// 提醒用户更新
uni.showModal({
title: '更新提示',
content: res.data.note,
success: (showResult) => {
if (showResult.confirm) {
plus.nativeUI.toast('正在准备环境,请稍后!')
console.log(res.data.url)
const downloadTask = plus.downloader.createDownload(
res.data.url,
{
method: 'GET',
filename: '_doc/update/',
},
function (d, status) {
if (status == 200) {
const path = d.filename; //下载apk
plus.runtime.install(path) // 自动安装apk文件
} else {
plus.nativeUI.alert('版本更新失败:' + status)
}
},
)
downloadTask.start()
}
},
})
} else if (flag_hot) {
console.log('*****开始小版本热更新*****')
uni.downloadFile({
url: res.data.wgtUrl,
success: (downloadResult) => {
console.log("热更新downloadResult",downloadResult.tempFilePath)
if (downloadResult.statusCode === 200) {
plus.nativeUI.toast(`正在热更新!${res.data.versionCode}`)
plus.runtime.install(
downloadResult.tempFilePath,
{
force: false,
},
function () {
plus.nativeUI.toast('热更新成功')
plus.runtime.restart()
},
function (e) {
console.log(e)
plus.nativeUI.toast(`热更新失败:${e.message}`)
},
)
}
},
})
}
})
},
})
}

View File

@@ -0,0 +1,179 @@
import {pcaa as REGION_DATA} from "./pcaUtils";
/**
* Area 属性all的类型
*/
interface PlainPca {
id: string;
text: string;
pid: string;
index: Number;
}
/**
* 省市区工具类 -解决列表省市区组件的翻译问题
*/
class Area {
all: PlainPca[];
/**
* 构造器
* @param pcaa
*/
constructor(pcaa?) {
if (!pcaa) {
pcaa = REGION_DATA;
}
let arr: PlainPca[] = [];
const province = pcaa['86'];
Object.keys(province).map((key) => {
arr.push({ id: key, text: province[key], pid: '86', index: 1 });
const city = pcaa[key];
Object.keys(city).map((key2) => {
arr.push({ id: key2, text: city[key2], pid: key, index: 2 });
const qu = pcaa[key2];
if (qu) {
Object.keys(qu).map((key3) => {
arr.push({ id: key3, text: qu[key3], pid: key2, index: 3 });
});
}
});
});
this.all = arr;
}
getPca() {
return this.all;
}
getCode(text) {
if (!text || text.length == 0) {
return '';
}
for (let item of this.all) {
if (item.text === text) {
return item.id;
}
}
}
//update-begin-author:liusq---date:20230404--for: [issue/382]省市区组件JAreaLinkage数据不回显---
getText(code,index=3) {
if (!code || code.length == 0) {
return '';
}
let arr = [];
this.getAreaBycode(code, arr, index);
return arr.join('/');
}
//update-end-author:liusq---date:20230404--for: [issue/382]省市区组件JAreaLinkage数据不回显---
getRealCode(code) {
let arr = [];
this.getPcode(code, arr, 3);
return arr;
}
getPcode(id, arr, index) {
for (let item of this.all) {
if (item.id === id && item.index == index) {
arr.unshift(id);
if (item.pid != '86') {
this.getPcode(item.pid, arr, --index);
}
}
}
}
getAreaBycode(code, arr, index) {
for (let item of this.all) {
if (item.id === code && item.index == index) {
arr.unshift(item.text);
if (item.pid != '86') {
this.getAreaBycode(item.pid, arr, --index);
}
}
}
}
}
interface RegionItem {
id: string;
text: string;
pid: string;
index: number;
}
interface TransformedItem {
label: string;
value: string;
}
type TransformedData = Record<string, TransformedItem[]>;
export function transformRegionData(originalData: RegionItem[]): TransformedData {
const result: TransformedData = {};
// 首先处理省级数据 (pid 为 '86' 的项)
const provinces = originalData.filter(item => item.pid === '86');
result['0'] = provinces.map(province => ({
label: province.text,
value: province.id
}));
// 然后处理市级数据
const cities = originalData.filter(item =>
provinces.some(province => province.id === item.pid)
);
cities.forEach(city => {
if (!result[city.pid]) {
result[city.pid] = [];
}
result[city.pid].push({
label: city.text,
value: city.id
});
});
// 最后处理区县级数据
const districts = originalData.filter(item =>
cities.some(city => city.id === item.pid)
);
districts.forEach(district => {
if (!result[district.pid]) {
result[district.pid] = [];
}
result[district.pid].push({
label: district.text,
value: district.id
});
});
return result;
}
const jeecgAreaData = new Area();
// 根据code找文本
const getAreaTextByCode = function (code) {
let index = 3;
//update-begin-author:liusq---date:20220531--for: 判断code是否是多code逗号分割的字符串是的话获取最后一位的code ---
if (code && code.includes(',')) {
index = code.split(",").length;
code = code.substr(code.lastIndexOf(',') + 1);
}
//update-end-author:liusq---date:20220531--for: 判断code是否是多code逗号分割的字符串是的话获取最后一位的code ---
return jeecgAreaData.getText(code,index);
};
// 根据code找文本
const getAreaArrByCode = function (code) {
return jeecgAreaData.getRealCode(code);
};
// 获取下拉地图option
const getPcaOptionData = function () {
let pca:any = jeecgAreaData.getPca();
return transformRegionData(pca);
};
export { getAreaTextByCode,getAreaArrByCode,getPcaOptionData };

View File

@@ -0,0 +1,57 @@
import {areaList} from '@vant/area-data'
// 扁平化的省市区数据
export const pcaa = freezeDeep(usePlatPcaaData())
/**
* 获取扁平化的省市区数据
*/
function usePlatPcaaData() {
const {city_list: city, county_list: county, province_list: province} = areaList;
const dataMap = new Map<string, Recordable>()
const flatData: Recordable = {'86': province}
// 省
Object.keys(province).forEach((code) => {
flatData[code] = {}
dataMap.set(code.slice(0, 2), flatData[code])
})
// 市区
Object.keys(city).forEach((code) => {
flatData[code] = {}
dataMap.set(code.slice(0, 4), flatData[code])
// 填充上一级
const getProvince = dataMap.get(code.slice(0, 2))
if (getProvince) {
getProvince[code] = city[code]
}
});
// 县
Object.keys(county).forEach((code) => {
// 填充上一级
const getCity = dataMap.get(code.slice(0, 4))
if (getCity) {
getCity[code] = county[code]
}
});
return flatData
}
/**
*
* 深度冻结对象
* @param obj Object or Array
*/
export function freezeDeep(obj: Recordable | Recordable[]) {
if (obj != null) {
if (Array.isArray(obj)) {
obj.forEach(item => freezeDeep(item))
} else if (typeof obj === 'object') {
Object.values(obj).forEach(value => {
freezeDeep(value)
})
}
Object.freeze(obj)
}
return obj
}

View File

@@ -0,0 +1,140 @@
export const ACCESS_TOKEN = 'Access-Token'
export const USER_NAME = 'login_username'
export const USER_INFO = 'login_user_info'
export const NAV_BAR_COLOR = 'bg-gradual-blue'
export const APP_ROUTE = 'app_route_list'
export const APP_CONFIG = 'app_config'
export const X_TENANT_ID = 'X-Tenant-Id'
export const X_Low_App_ID = 'X-Low-App-ID'
export const TENANT_LIST = 'tenant_list'
export const ROUTE_PARAMS = "cacheRouteParams"
export const HOME_PAGE = "/pages/message/message"
/**
* 组件名称前缀
*/
export const COMP_NAME_PREFIX = 'jeecg-drag';
//首页配置项缓存时间10分钟
export const HOME_CONFIG_EXPIRED_TIME = 10*60
export const phone = '---'
export const email = '---'
export const company = '---'
const STORAGE_OPTIONS = {
namespace: 'pro__', // key prefix
name: 'ls', // name variable Vue.[ls] or this.[$ls],
storage: 'local', // storage name session, local, memory
}
export default STORAGE_OPTIONS;
//类型条件
export const conditionObj = {
input:[{label:"包含",value:"like"},{label:"以...开始",value:"right_like"},{label:"以...结尾",value:"left_like"},{label:"在...中",value:"in"}],
number:[{label:"大于",value:"gt"},{label:"大于等于",value:"ge"},{label:"小于",value:"lt"},{label:"小于等于",value:"le"}],
date:[{label:"大于",value:"gt"},{label:"大于等于",value:"ge"},{label:"小于",value:"lt"},{label:"小于等于",value:"le"}],
select:[],
checkbox:[{label:"多词匹配",value:"elemMatch"}],
}
/**
* 颜色板
* classic经典
* technology科技
* business商务
* botany植物
* natural自然
* colour彩色
*/
export const colorPanel = {
classic:["#64b5f6","#4db6ac","#ffb74d","#e57373","#9575cd","#a1887f","#90a4ae","#4dd0e1","#81c784","#ff8a65"],
technology:["#3a5b84","#4d6e98","#7594b9","#bfd7f2","#18619f","#408aca","#5ea8e9","#81c3fc","#71a5cb","#a1cae4"],
business:["#ccedf7","#b9dcf0","#12a0e7","#0663a4","#458890","#97d9cd","#4bb8bf","#20899c","#f44336 ","#a2c7d9"],
botany:["#34b392","#4ac2a6","#8ed1c0","#ccdec6","#61bdb5","#7993a1","#93a889","#5e8d83","#115040","#bcc5b4"],
natural:["#85cacd","#a7d676","#fee159","#fbc78e","#ef918b","#a9b5ff","#e7daca","#fc803a","#fea1ac","#c2a3cd"],
colour:["#fddb9c","#f9ae91","#f59193","#d47f97","#bd86a6","#f595a1","#624772","#fe7156","#ffbda3","#877fa8"]
};
//所有条件
export const allCondition = [
{label:"包含",value:"like"},
{label:"以...开始",value:"right_like"},
{label:"以...结尾",value:"left_like"},
{label:"在...中",value:"in"},
{label:"大于",value:"gt"},
{label:"大于等于",value:"ge"},
{label:"小于",value:"lt"},
{label:"小于等于",value:"le"},
{label:"多词匹配",value:"elemMatch"},
{label:"等于",value:"eq"},
{label:"不等于",value:"ne"},
{label:"为空",value:"empty"},
{label:"不为空",value:"not_empty"}
]
//仪表盘组件
export const compList = [
"JBar",
"JStackBar",
"JMultipleBar",
"JNegativeBar",
"JProgress",
"JLine",
"JMultipleLine",
"DoubleLineBar",
"JPie",
"JRing",
"JFunnel",
"JPyramidFunnel",
"JRadar",
"JCircleRadar",
"JGauge",
"JColorGauge",
"JScatter",
"JBubble",
"JDragEditor",
"JCarousel",
"JIframe",
"JNumber",
"JCustomButton",
"JPivotTable",
"JBubbleMap",
"JBarMap",
"JHeatMap",
];
//不包含操作的组件
export const noActionList = [
"JCustomButton",
"JIframe",
"JCarousel",
"JDragEditor",
];
//系统字段
export const systemFields = [{
dataIndex:"create_time",
key:"create_time",
title:"创建时间",
type:'date',
width:200
},{
dataIndex:"create_by",
key:"create_by",
title:"创建人",
width:150
},{
dataIndex:"update_time",
key:"update_time",
title:"修改时间",
type:'date',
width:200
},{
dataIndex:"update_by",
key:"update_by",
title:"修改人",
width:150
}]

View File

@@ -0,0 +1,108 @@
const toString = Object.prototype.toString
export function is(val: unknown, type: string) {
return toString.call(val) === `[object ${type}]`
}
export function isDef<T = unknown>(val?: T): val is T {
return typeof val !== 'undefined'
}
export function isUnDef<T = unknown>(val?: T): val is T {
return !isDef(val)
}
export function isObject(val: any): val is Record<any, any> {
return val !== null && is(val, 'Object')
}
export function isEmpty<T = unknown>(val: T): val is T {
if (isArray(val) || isString(val)) {
return val.length === 0
}
if (val instanceof Map || val instanceof Set) {
return val.size === 0
}
if (isObject(val)) {
return Object.keys(val).length === 0
}
return false
}
export function isDate(val: unknown): val is Date {
return is(val, 'Date')
}
export function isNull(val: unknown): val is null {
return val === null
}
export function isNullAndUnDef(val: unknown): val is null | undefined {
return isUnDef(val) && isNull(val)
}
export function isNullOrUnDef(val: unknown): val is null | undefined {
return isUnDef(val) || isNull(val)
}
export function isNumber(val: unknown): val is number {
return is(val, 'Number')
}
export function isPromise<T = any>(val: any): val is Promise<T> {
// update-begin--author:sunjianlei---date:20211022---for: 不能既是 Promise 又是 Object --------
return is(val, 'Promise') && isFunction(val.then) && isFunction(val.catch)
// update-end--author:sunjianlei---date:20211022---for: 不能既是 Promise 又是 Object --------
}
export function isString(val: unknown): val is string {
return is(val, 'String')
}
export function isJsonObjectString(val: string): val is string {
if (!val) {
return false
}
return val.startsWith('{') && val.endsWith('}')
}
export function isFunction(val: unknown): val is Function {
return typeof val === 'function'
}
export function isBoolean(val: unknown): val is boolean {
return is(val, 'Boolean')
}
export function isRegExp(val: unknown): val is RegExp {
return is(val, 'RegExp')
}
export function isArray(val: any): val is Array<any> {
return val && Array.isArray(val)
}
export function isWindow(val: any): val is Window {
return typeof window !== 'undefined' && is(val, 'Window')
}
export function isElement(val: unknown): val is Element {
return isObject(val) && !!val.tagName
}
export function isMap(val: unknown): val is Map<any, any> {
return is(val, 'Map')
}
export const isServer = typeof window === 'undefined'
export const isClient = !isServer
export function isUrl(path: string): boolean {
const reg =
/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/
return reg.test(path)
}

View File

@@ -0,0 +1,18 @@
//获取地图
export default function MapLoader() {
return new Promise((resolve, reject) => {
if (window.AMap) {
resolve(window.AMap);
} else {
var script = document.createElement('script');
script.type = "text/javascript";
script.async = true;
script.src = "https://webapi.amap.com/maps?v=1.4.15&key=21f194a0d33197f874f7bbdd198419be&callback=initAMap";
script.onerror = reject;
document.head.appendChild(script);
}
window.initAMap = () => {
resolve(window.AMap);
};
})
}

View File

@@ -0,0 +1,418 @@
function AMapWX(a) {
;(this.key = a.key),
(this.requestConfig = {
key: a.key,
s: 'rsx',
platform: 'WXJS',
appname: a.key,
sdkversion: '1.2.0',
logversion: '2.0',
})
}
;(AMapWX.prototype.getWxLocation = function (a, b) {
wx.getLocation({
type: 'gcj02',
success: function (a) {
var c = a.longitude + ',' + a.latitude
wx.setStorage({ key: 'userLocation', data: c }), b(c)
},
fail: function (c) {
wx.getStorage({
key: 'userLocation',
success: function (a) {
a.data && b(a.data)
},
}),
a.fail({ errCode: '0', errMsg: c.errMsg || '' })
},
})
}),
(AMapWX.prototype.getRegeo = function (a) {
function c(c) {
var d = b.requestConfig
wx.request({
url: 'https://restapi.amap.com/v3/geocode/regeo',
data: {
key: b.key,
location: c,
extensions: 'all',
s: d.s,
platform: d.platform,
appname: b.key,
sdkversion: d.sdkversion,
logversion: d.logversion,
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
var d, e, f, g, h, i, j, k, l
b.data.status && '1' == b.data.status
? ((d = b.data.regeocode),
(e = d.addressComponent),
(f = []),
(g = ''),
d && d.roads[0] && d.roads[0].name && (g = d.roads[0].name + '附近'),
(h = c.split(',')[0]),
(i = c.split(',')[1]),
d.pois &&
d.pois[0] &&
((g = d.pois[0].name + '附近'),
(j = d.pois[0].location),
j && ((h = parseFloat(j.split(',')[0])), (i = parseFloat(j.split(',')[1])))),
e.provice && f.push(e.provice),
e.city && f.push(e.city),
e.district && f.push(e.district),
e.streetNumber && e.streetNumber.street && e.streetNumber.number
? (f.push(e.streetNumber.street), f.push(e.streetNumber.number))
: ((k = ''),
d && d.roads[0] && d.roads[0].name && (k = d.roads[0].name),
f.push(k)),
(f = f.join('')),
(l = [
{
iconPath: a.iconPath,
width: a.iconWidth,
height: a.iconHeight,
name: f,
desc: g,
longitude: h,
latitude: i,
id: 0,
regeocodeData: d,
},
]),
a.success(l))
: a.fail({ errCode: b.data.infocode, errMsg: b.data.info })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}
var b = this
a.location
? c(a.location)
: b.getWxLocation(a, function (a) {
c(a)
})
}),
(AMapWX.prototype.getWeather = function (a) {
function d(d) {
var e = 'base'
a.type && 'forecast' == a.type && (e = 'all'),
wx.request({
url: 'https://restapi.amap.com/v3/weather/weatherInfo',
data: {
key: b.key,
city: d,
extensions: e,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
function c(a) {
var b = {
city: { text: '城市', data: a.city },
weather: { text: '天气', data: a.weather },
temperature: { text: '温度', data: a.temperature },
winddirection: { text: '风向', data: a.winddirection + '风' },
windpower: { text: '风力', data: a.windpower + '级' },
humidity: { text: '湿度', data: a.humidity + '%' },
}
return b
}
var d, e
b.data.status && '1' == b.data.status
? b.data.lives
? ((d = b.data.lives),
d && d.length > 0 && ((d = d[0]), (e = c(d)), (e['liveData'] = d), a.success(e)))
: b.data.forecasts &&
b.data.forecasts[0] &&
a.success({ forecast: b.data.forecasts[0] })
: a.fail({ errCode: b.data.infocode, errMsg: b.data.info })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}
function e(e) {
wx.request({
url: 'https://restapi.amap.com/v3/geocode/regeo',
data: {
key: b.key,
location: e,
extensions: 'all',
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
var c, e
b.data.status && '1' == b.data.status
? ((e = b.data.regeocode),
e.addressComponent
? (c = e.addressComponent.adcode)
: e.aois && e.aois.length > 0 && (c = e.aois[0].adcode),
d(c))
: a.fail({ errCode: b.data.infocode, errMsg: b.data.info })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}
var b = this,
c = b.requestConfig
a.city
? d(a.city)
: b.getWxLocation(a, function (a) {
e(a)
})
}),
(AMapWX.prototype.getPoiAround = function (a) {
function d(d) {
var e = {
key: b.key,
location: d,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
}
a.querytypes && (e['types'] = a.querytypes),
a.querykeywords && (e['keywords'] = a.querykeywords),
wx.request({
url: 'https://restapi.amap.com/v3/place/around',
data: e,
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
var c, d, e, f
if (b.data.status && '1' == b.data.status) {
if (((b = b.data), b && b.pois)) {
for (c = [], d = 0; d < b.pois.length; d++)
(e = 0 == d ? a.iconPathSelected : a.iconPath),
c.push({
latitude: parseFloat(b.pois[d].location.split(',')[1]),
longitude: parseFloat(b.pois[d].location.split(',')[0]),
iconPath: e,
width: 22,
height: 32,
id: d,
name: b.pois[d].name,
address: b.pois[d].address,
})
;(f = { markers: c, poisData: b.pois }), a.success(f)
}
} else a.fail({ errCode: b.data.infocode, errMsg: b.data.info })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}
var b = this,
c = b.requestConfig
a.location
? d(a.location)
: b.getWxLocation(a, function (a) {
d(a)
})
}),
(AMapWX.prototype.getStaticmap = function (a) {
function f(b) {
c.push('location=' + b),
a.zoom && c.push('zoom=' + a.zoom),
a.size && c.push('size=' + a.size),
a.scale && c.push('scale=' + a.scale),
a.markers && c.push('markers=' + a.markers),
a.labels && c.push('labels=' + a.labels),
a.paths && c.push('paths=' + a.paths),
a.traffic && c.push('traffic=' + a.traffic)
var e = d + c.join('&')
a.success({ url: e })
}
var e,
b = this,
c = [],
d = 'https://restapi.amap.com/v3/staticmap?'
c.push('key=' + b.key),
(e = b.requestConfig),
c.push('s=' + e.s),
c.push('platform=' + e.platform),
c.push('appname=' + e.appname),
c.push('sdkversion=' + e.sdkversion),
c.push('logversion=' + e.logversion),
a.location
? f(a.location)
: b.getWxLocation(a, function (a) {
f(a)
})
}),
(AMapWX.prototype.getInputtips = function (a) {
var b = this,
c = b.requestConfig,
d = {
key: b.key,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
}
a.location && (d['location'] = a.location),
a.keywords && (d['keywords'] = a.keywords),
a.type && (d['type'] = a.type),
a.city && (d['city'] = a.city),
a.citylimit && (d['citylimit'] = a.citylimit),
wx.request({
url: 'https://restapi.amap.com/v3/assistant/inputtips',
data: d,
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
b && b.data && b.data.tips && a.success({ tips: b.data.tips })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}),
(AMapWX.prototype.getDrivingRoute = function (a) {
var b = this,
c = b.requestConfig,
d = {
key: b.key,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
}
a.origin && (d['origin'] = a.origin),
a.destination && (d['destination'] = a.destination),
a.strategy && (d['strategy'] = a.strategy),
a.waypoints && (d['waypoints'] = a.waypoints),
a.avoidpolygons && (d['avoidpolygons'] = a.avoidpolygons),
a.avoidroad && (d['avoidroad'] = a.avoidroad),
wx.request({
url: 'https://restapi.amap.com/v3/direction/driving',
data: d,
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
b &&
b.data &&
b.data.route &&
a.success({ paths: b.data.route.paths, taxi_cost: b.data.route.taxi_cost || '' })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}),
(AMapWX.prototype.getWalkingRoute = function (a) {
var b = this,
c = b.requestConfig,
d = {
key: b.key,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
}
a.origin && (d['origin'] = a.origin),
a.destination && (d['destination'] = a.destination),
wx.request({
url: 'https://restapi.amap.com/v3/direction/walking',
data: d,
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
b && b.data && b.data.route && a.success({ paths: b.data.route.paths })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}),
(AMapWX.prototype.getTransitRoute = function (a) {
var b = this,
c = b.requestConfig,
d = {
key: b.key,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
}
a.origin && (d['origin'] = a.origin),
a.destination && (d['destination'] = a.destination),
a.strategy && (d['strategy'] = a.strategy),
a.city && (d['city'] = a.city),
a.cityd && (d['cityd'] = a.cityd),
wx.request({
url: 'https://restapi.amap.com/v3/direction/transit/integrated',
data: d,
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
if (b && b.data && b.data.route) {
var c = b.data.route
a.success({
distance: c.distance || '',
taxi_cost: c.taxi_cost || '',
transits: c.transits,
})
}
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
}),
(AMapWX.prototype.getRidingRoute = function (a) {
var b = this,
c = b.requestConfig,
d = {
key: b.key,
s: c.s,
platform: c.platform,
appname: b.key,
sdkversion: c.sdkversion,
logversion: c.logversion,
}
a.origin && (d['origin'] = a.origin),
a.destination && (d['destination'] = a.destination),
wx.request({
url: 'https://restapi.amap.com/v4/direction/bicycling',
data: d,
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (b) {
b && b.data && b.data.data && a.success({ paths: b.data.data.paths })
},
fail: function (b) {
a.fail({ errCode: '0', errMsg: b.errMsg || '' })
},
})
})
// 修改导出方式
const amap = {
AMapWX: AMapWX
};
// ES6 导出方式
export default amap;

View File

@@ -0,0 +1,63 @@
import { h } from 'vue'
import { filterMultiDictText, getFileAccessHttpUrl } from '@/common/uitls'
const render = {
/**
* 渲染图片
* @param text
*/
renderImage: ({ text }) => {
if (!text) {
return ;
}
let avatarList = text.split(',')
return h(
'span',
avatarList.map((item) => {
return h(Image, {
src: getFileAccessHttpUrl(item),
width: 30,
height: 30,
style: { marginRight: '5px' },
})
}),
)
//update-end-author:taoyan date:2022-5-24 for: VUEN-1084 【vue3】online表单测试发现的新问题 41、生成的代码树默认图大小未改
},
/**
* 渲染a标签
* @param text
*/
renderHref: ({ text }) => {
if (!text) {
return ''
}
const len = 20
if (text.length > len) {
text = text.substr(0, len)
}
return h('a', { href: text, target: '_blank' }, text)
},
/**
* 根据字典渲染
* @param v
* @param array
*/
renderDictNative: (v, array, renderTag = false) => {
let text = ''
let color = ''
let obj = array.filter((item) => {
return item.value == v
})
if (obj.length > 0) {
text = obj[0].label
color = obj[0].color
}
return h('span', text)
},
renderSwitch: (text, arr) => {
return text ? filterMultiDictText(arr, text) : ''
},
}
export { render }

View File

@@ -0,0 +1,136 @@
// @ts-nocheck
import { randomString } from './uitls'
import { useUserStore } from '@/store/user'
const baseUrl = import.meta.env.VITE_SERVER_BASEURL
class socket {
constructor() {
this.socketUrl = baseUrl
this.socketStart = false
this.socketType = ''
this.monitorSocketError()
this.monitorSocketClose()
this.socketReceive()
}
init(socket_type, callback?) {
const userStore = useUserStore()
if (baseUrl) {
if (this.socketStart) {
console.log('webSocket已经启动了')
} else {
this.socketType = socket_type
let url =
this.socketUrl.replace('https://', 'wss://').replace('http://', 'ws://') +
'/' +
socket_type +
'/' +
userStore.userInfo.userid +
'_app'
if (socket_type == 'eoaNewChatSocket') {
let randomMessageId = randomString(6)
url =
this.socketUrl.replace('https://', 'wss://').replace('http://', 'ws://') +
'/eoaNewChatSocket/' +
userStore.userInfo.userid +
'/' +
randomMessageId
}
console.log('启动this.socketUrl连接地址', url)
// update-begin-author:taoyan date:20220422 for:v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
let token = userStore.userInfo.token
uni.connectSocket({
url: url,
method: 'GET',
protocols: [token],
})
// update-end-author:taoyan date:20220422 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
uni.onSocketOpen((res) => {
this.socketStart = true
callback && callback()
console.log('WebSocket连接已打开')
})
/* setTimeout(() => {
this.getHeartbeat();
}, 5000); */
}
} else {
console.log('config/baseUrl socketUrl为空')
}
}
// Socket给服务器发送消息
send(data, callback) {
const userStore = useUserStore()
if (userStore.userInfo.userid) {
data.userUid = userStore.userInfo.userid
}
console.log(data)
uni.sendSocketMessage({
data: JSON.stringify(data),
success: () => {
callback && callback(true)
},
fail: () => {
callback && callback(false)
},
})
}
acceptMessage(msg) {
console.log(msg)
}
// Socket接收服务器发送过来的消息
socketReceive() {
uni.onSocketMessage((res) => {
console.log('APP:--》收到服务器内容:')
let data = JSON.parse(res.data)
// console.log('收到服务器内容:', data);
this.acceptMessage && this.acceptMessage(data)
})
}
// 关闭Socket
closeSocket() {
uni.closeSocket()
this.socketStart = false
}
// 监听Socket关闭
monitorSocketClose() {
uni.onSocketClose((res) => {
console.log('WebSocket 已关闭!')
this.socketStart = false
setTimeout(() => {
this.init(this.socketType)
}, 3000)
})
}
// 监听Socket错误
monitorSocketError() {
uni.onSocketError(function (res) {
this.socketStart = false
console.log('WebSocket连接打开失败请检查')
})
}
// 心跳
getHeartbeat() {
const userStore = useUserStore()
this.send(
{
type: '心跳',
userUid: userStore.userInfo.userid,
},
(val) => {
setTimeout(() => {
if (val) {
// this.getHeartbeat();
} else {
if (!this.socketStart) {
// this.init();
}
}
}, 10000)
},
)
}
}
const mySocket = new socket()
export default mySocket

View File

@@ -0,0 +1,132 @@
/**
* 提示与加载工具类
*/
export default class Tips {
// 声明 isLoading 属性
static isLoading: boolean
// 移除无用的构造函数,因为静态属性不需要在构造函数中初始化
/**
* 弹出提示框
*/
static success(title, duration = 1000) {
setTimeout(() => {
uni.showToast({
title,
icon: 'success',
mask: true,
duration,
})
}, 300)
if (duration > 0) {
return new Promise<void>((resolve, reject) => {
setTimeout(() => {
resolve()
}, duration)
})
}
}
/**
* 弹出确认窗口
*/
static confirm(text, showCancel, payload = {}, title = '提示') {
return new Promise((resolve, reject) => {
uni.showModal({
title,
content: text,
showCancel,
success: (res) => {
if (res.confirm) {
resolve(payload)
} else if (res.cancel) {
reject(payload)
}
},
fail: (res) => {
reject(payload)
},
})
})
}
static toast(title, onHide, icon = 'none') {
setTimeout(() => {
uni.showToast({
title,
// 确保 icon 的值是合法的
icon: icon as 'success' | 'loading' | 'error' | 'none' | 'fail' | 'exception',
mask: true,
duration: 1000,
})
}, 300)
// 隐藏结束回调
if (onHide) {
setTimeout(() => {
onHide()
}, 500)
}
}
/**
* 警告框
*/
static alert(title) {
uni.showToast({
title,
image: '/static/alert.png',
mask: true,
duration: 1500,
})
}
/**
* 错误框
*/
static error(title, onHide) {
uni.showToast({
title,
image: '/static/error.png',
mask: true,
duration: 1500,
})
// 隐藏结束回调
if (onHide) {
setTimeout(() => {
onHide()
}, 500)
}
}
/**
* 弹出加载提示
*/
static loading(title = '加载中') {
if (Tips.isLoading) {
return
}
Tips.isLoading = true
uni.showLoading({
title,
mask: true,
})
}
/**
* 加载完毕
*/
static loaded() {
if (Tips.isLoading) {
Tips.isLoading = false
uni.hideLoading()
}
}
}
/**
* 静态变量,是否加载中
*/
Tips.isLoading = false

View File

@@ -0,0 +1,756 @@
import pagesJson from '../pages.json'
// 引入uni-parse-pages
import pagesJsonToRoutes from 'uni-parse-pages'
import { colorPanel } from './constants'
import tip from './tip'
import { platform, isH5, isApp, isMp, isMpWeixin, isMpAplipay, isMpToutiao } from '@/utils/platform'
import { isString } from './is'
/**
* 缓存,默认有效期2小时
* @param key 缓存key
* @param value 缓存值
* @param seconds 缓存时间(秒)
* @returns {*}
*/
export function cache(key, value = null, seconds = 2 * 3600) {
const timestamp = +new Date() / 1000
if (key && value === null) {
// 获取缓存
const val = uni.getStorageSync(key)
if (val && val.length > 0) {
const tmp = val.split('|')
if (!tmp[2] || timestamp >= tmp[2]) {
console.log('key已失效')
// 删除缓存
uni.removeStorageSync(key)
return ''
} else {
console.log('key未失效')
if (tmp[1] == 'json') {
return JSON.parse(tmp[0])
}
return tmp[0]
}
}
} else if (key && value) {
// 设置缓存
const expire = timestamp + seconds
console.log('typeof value', typeof value)
if (typeof value === 'object') {
value = JSON.stringify(value) + '|json|' + expire
} else {
value = value + '|string|' + expire
}
uni.setStorageSync(key, value)
} else {
console.log('key不能空')
}
}
// 获取静态文件地址
export const getStaticDomainURL = () => {
return import.meta.env.VITE_SERVER_BASEURL + '/sys/common/static'
}
export const getFileAccessHttpUrl = function (avatar, subStr?) {
if (!avatar) return ''
if (!subStr) subStr = 'http'
if (avatar) {
avatar = avatar.replace(/user_imgs\\/, 'user_imgs/')
}
if (avatar && avatar.startsWith(subStr)) {
return avatar
} else {
return getStaticDomainURL() + '/' + avatar
}
}
interface hasRouteType {
name?: string
path?: string
routeList?: any
}
// 判断路由是否存在
export const hasRoute = ({ name, path, routeList }: hasRouteType) => {
routeList = routeList ?? pagesJsonToRoutes(pagesJson)
if (path) {
return !!routeList.find((item) => item.path === path)
}
if (name) {
return !!routeList.find((item) => item.path.split('/').pop() === name)
}
}
/**
* 人性化显示时间
*
* @param {Object} datetime
*/
export function beautifyTime(datetime = '') {
if (datetime == null) {
return ''
}
datetime = datetime.toString().replace(/-/g, '/')
const time = new Date()
let outTime = new Date(datetime)
if (/^[1-9]\d*$/.test(datetime)) {
outTime = new Date(parseInt(datetime))
}
if (time.getTime() < outTime.getTime()) {
return parseTime(outTime, '{y}/{m}/{d}')
}
if (time.getFullYear() != outTime.getFullYear()) {
return parseTime(outTime, '{y}/{m}/{d}')
}
if (time.getMonth() != outTime.getMonth()) {
return parseTime(outTime, '{m}/{d}')
}
if (time.getDate() != outTime.getDate()) {
const day = outTime.getDate() - time.getDate()
if (day == -1) {
return parseTime(outTime, '昨天 {h}:{i}')
}
if (day == -2) {
return parseTime(outTime, '前天 {h}:{i}')
}
return parseTime(outTime, '{m}-{d}')
}
if (time.getHours() != outTime.getHours()) {
return parseTime(outTime, '{h}:{i}')
}
let minutes = outTime.getMinutes() - time.getMinutes()
if (minutes == 0) {
return '刚刚'
}
minutes = Math.abs(minutes)
return `${minutes}分钟前`
}
/**
* 格式化时间
* @param {Object} time
* @param {Object} cFormat
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}
let date
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
if (typeof time === 'object') {
date = time
} else {
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
time = parseInt(time)
} else {
time = new Date(time)
}
date = new Date(time.toString().replace(/-/g, '/'))
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay(),
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
return value.toString().padStart(2, '0')
})
return time_str
}
/**
* 随机生成字符串
* @param length 字符串的长度
* @param chats 可选字符串区间(只会生成传入的字符串中的字符)
* @return string 生成的字符串
*/
export function randomString(length, chats?) {
if (!length) length = 1
if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm'
let str = ''
for (let i = 0; i < length; i++) {
// @ts-ignore
const num = randomNumber(0, chats.length - 1)
str += chats[num]
}
return str
}
/**
* 随机生成数字
*
* 示例:生成长度为 12 的随机数randomNumber(12)
* 示例:生成 3~23 之间的随机数randomNumber(3, 23)
*
* @param1 最小值 | 长度
* @param2 最大值
* @return int 生成后的数字
*/
export function randomNumber() {
// 生成 最小值 到 最大值 区间的随机数
const random = (min, max) => {
return Math.floor(Math.random() * (max - min + 1) + min)
}
if (arguments.length === 1) {
// @ts-ignore
const [length] = arguments
// 生成指定长度的随机数字,首位一定不是 0
// @ts-ignore
const nums = [...Array(length).keys()].map((i) => (i > 0 ? random(0, 9) : random(1, 9)))
return parseInt(nums.join(''))
} else if (arguments.length >= 2) {
// @ts-ignore
const [min, max] = arguments
return random(min, max)
} else {
return Number.NaN
}
}
/**
* 时间格式化
* @param value
* @param fmt
* @returns {*}
*/
export function formatDate(value, fmt) {
const regPos = /^\d+(\.\d+)?$/
if (regPos.test(value)) {
// 如果是数字
const getDate = new Date(value)
const o = {
'M+': getDate.getMonth() + 1,
'd+': getDate.getDate(),
'h+': getDate.getHours(),
'H+': getDate.getHours(),
'm+': getDate.getMinutes(),
's+': getDate.getSeconds(),
'q+': Math.floor((getDate.getMonth() + 3) / 3),
S: getDate.getMilliseconds(),
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (getDate.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length),
)
}
}
return fmt
} else {
// TODO
if (value && value.length > 0) {
value = value.trim()
return value.substr(0, fmt.length)
}
return value
}
}
// 通过时间或者时间戳获取对应antd的年、月、周、季度。
export function getWeekMonthQuarterYear(date) {
// 获取 ISO 周数的函数
const getISOWeek = (date) => {
const jan4 = new Date(date.getFullYear(), 0, 4)
const oneDay = 86400000 // 一天的毫秒数
return Math.ceil(((date - jan4.getTime()) / oneDay + jan4.getDay() + 1) / 7)
}
// 将时间戳转换为日期对象
const dateObj = new Date(date)
// 计算周
const week = getISOWeek(dateObj)
// 计算月
const month = dateObj.getMonth() + 1 // 月份是从0开始的所以要加1
// 计算季度
const quarter = Math.floor(dateObj.getMonth() / 3) + 1
// 计算年
const year = dateObj.getFullYear()
return {
year: `${year}`,
month: `${year}-${month.toString().padStart(2, '0')}`,
week: `${year}-${week}`,
quarter: `${year}-Q${quarter}`,
}
}
// 生成 1 到 10 之间的随机整数
export function getRandomIntBetweenOneAndTen() {
return Math.floor(Math.random() * 10) + 1
}
/**
* 获取随机颜色
* @param {any} color
* 颜色板
* classic经典
* technology科技
* business商务
* botany植物
* natural自然
* colour彩色
* @return
*/
export function getRandomColor() {
const colorType = ['classic', 'technology', 'business', 'botany', 'natural', 'colour']
// 生成一个随机索引,范围是从 0 到数组长度减 1
const randomIndex = Math.floor(Math.random() * colorType.length)
// 根据随机索引从数组中获取一个随机类型
const randomColorType = colorType[randomIndex]
return colorPanel.natural[getRandomIntBetweenOneAndTen()] || '#00bcd4'
}
// 消除后缀:
export const getPlaceholder = (attrs: any = {}) => {
let label = attrs.label
if (label.endsWith('') || label.endsWith(':')) {
label = label.substr(0, label.length - 1)
}
return `请选择${label}`
}
/**
* 日期格式化
* @param text
*/
export function getFormatDate(text, column) {
if (!text) {
return ''
}
let a = text
if (a.length > 10) {
a = a.substring(0, 10)
}
let fieldExtendJson = column?.fieldExtendJson
console.log('getFormat Datetext', text)
console.log('getFormatDate fieldExtendJson', fieldExtendJson)
if (fieldExtendJson) {
fieldExtendJson = JSON.parse(fieldExtendJson)
if (fieldExtendJson.picker && fieldExtendJson.picker != 'default') {
const result = getWeekMonthQuarterYear(a)
return result[fieldExtendJson.picker]
}
}
return a
}
/**
* 字典值替换文本通用方法(多选)
* @param dictOptions 字典数组
* @param text 字典值
* @return String
*/
export function filterMultiDictText(dictOptions, text) {
// js “!text” 认为0为空所以做提前处理
if (text === 0 || text === '0') {
if (dictOptions) {
for (const dictItem of dictOptions) {
if (text == dictItem.value) {
return dictItem.text
}
}
}
}
if (!text || text == 'undefined' || text == 'null' || !dictOptions || dictOptions.length == 0) {
return ''
}
let re = ''
text = text.toString()
const arr = text.split(',')
dictOptions.forEach(function (option) {
if (option) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === option.value) {
re += option.text + ','
break
}
}
}
})
if (re == '') {
return text
}
return re.substring(0, re.length - 1)
}
/** 获取url参数
* @param {Object} url
*/
export function getQueryVariable(url) {
if (!url) return
let t
let n
let r
const i = url.split('?')[1]
const s = {}
;(t = i.split('&')), (r = null), (n = null)
for (const o in t) {
const u = t[o].indexOf('=')
u !== -1 && ((r = t[o].substr(0, u)), (n = t[o].substr(u + 1)), (s[r] = n))
}
return s
}
/**
* 是否oauth环境
*/
export function isOAuth2AppEnv() {
let isOAuthEnv = false
// #ifdef H5
isOAuthEnv = /wxwork|dingtalk/i.test(navigator.userAgent)
// #endif
return isOAuthEnv
}
/**
* 获取url中的参数
* @param url
*/
export const getUrlParams = (url) => {
const result = {
url: '',
params: {},
}
const list = url.split('?')
result.url = list[0]
const params = list[1]
if (params) {
const list = params.split('&')
list.forEach((ele) => {
const dic = ele.split('=')
const label = dic[0]
const value = dic[1]
result.params[label] = value
})
}
return result
}
/**
* 判断文件地址是否支持存在
* @param url
* @returns {Promise<any>}
*/
export function downloadAbled(url) {
return new Promise((resolve, reject) => {
let xmlHttp
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest() // 其他浏览器
} else if ((window as any).ActiveXObject) {
// try {
// xmlHttp = new window.ActiveXObject("Microsoft.XMLHTTP");//IE
// }catch (e) {
// console.log('创建xmlHttp失败',e)
// }
}
if (!xmlHttp) {
reject('创建xmlHttp失败')
}
xmlHttp.open('GET', url, false)
xmlHttp.send()
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
resolve(true)
} else if (xmlHttp.status == 404) {
reject('文件不存在!')
} else {
reject('请求失败status' + xmlHttp.status)
}
} else {
reject('请求失败readyState:' + xmlHttp.readyState)
}
})
}
/**
* app获取url地址的传参问题
* @param url
* @returns {Object}
*/
export function appGetUrlParams(url) {
const theRequest = new Object()
const index = url.indexOf('?')
if (index != -1) {
const str = url.substring(index + 1)
const strs = str.split('&')
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
}
}
return theRequest
}
/**
*
* @param lat1 纬度1
* @param lng1 经度1
* @param lat2 纬度2
* @param lng2 经度2
* 返回 米
*/
export function geoDistance(lng1, lat1, lng2, lat2) {
let radLat1 = rad(lat1)
let radLat2 = rad(lat2)
let a = radLat1 - radLat2
let b = rad(lng1) - rad(lng2)
let s =
2 *
Math.asin(
Math.sqrt(
Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2),
),
)
s = s * 6378.137 // EARTH_RADIUS;
s = Math.round(s * 10000) / 10
return s
}
//经纬度转换成三角函数中度分表形式。
function rad(d) {
return (d * Math.PI) / 180.0
}
export function downloadFile(obj) {
let url = ''
if (isMp) {
if (obj.currentTarget) {
url = encodeURI(obj.currentTarget.dataset.url)
downloadNH5(url)
} else if (isString(obj)) {
// 为字符串类型时可认为就是url
url = getFileAccessHttpUrl(obj)
downloadNH5(url)
}
} else if (isApp) {
url = encodeURI(obj)
downloadNH5(url)
} else if (isH5) {
url = getFileAccessHttpUrl(obj)
window.open(url)
}
}
/**
* 非H5文件下载地址
* @param 文件路径 url
*/
function downloadNH5(url) {
const image_arr = ['png', 'jpg', 'jpeg']
const fileType = url.split('.').pop()
uni.downloadFile({
url,
success: (res) => {
if (res.statusCode == 200) {
let filePath = res.tempFilePath
const system = uni.getSystemInfoSync().platform
if (system == 'ios') {
filePath = encodeURI(filePath)
}
if (isMp) {
const suffix = getSuffix(url).toLowerCase()
if (image_arr.indexOf(suffix) != -1) {
// 预览图片
uni.previewImage({
urls: [filePath],
})
} else {
uni.openDocument({
filePath,
fileType,
success: (res) => {
console.log('打开文档成功')
},
fail: (res) => {
console.log('打开文档失败')
tip.error('不支持打开此格式', true)
},
})
}
} else if (isApp) {
const suffix = getSuffix(url).toLowerCase()
if (image_arr.indexOf(suffix) != -1) {
// 预览图片
uni.previewImage({
urls: [filePath],
})
} else {
uni.saveFile({
tempFilePath: filePath,
success: (res) => {
// 保存成功并打开文件
tip.success('保存成功')
uni.openDocument({
filePath: res.savedFilePath,
success: function (res) {
console.log('openDocument', res)
},
fail() {
uni.showToast({
title: '暂不支持打开此类型',
duration: 2000,
})
},
})
},
fail: () => tip.alert('保存失败'),
})
}
}
} else {
tip.alert('文件异常')
}
},
fail: (err) => {
tip.alert('下载失败')
},
})
}
// 获取后缀
export function getSuffix(text) {
if (text) {
const arr = text.split('.')
const suffix = arr[arr.length - 1]
return suffix
}
return text
}
/**
* 获取后缀图标
* @param {Object} doctype
*/
export function getFileIcon(doctype) {
const file_doc_type_arr = ['doc', 'excel', 'file', 'folder', 'image', 'pdf', 'video']
if (file_doc_type_arr.indexOf(doctype) >= 0) {
return `/static/${doctype}.png`
} else {
return '/static/file.png'
}
}
/**
* 获取uuid
*/
export function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
export const queryString = (params) => {
return Object.entries(params)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value as string)}`)
.join('&')
}
/**
* 将任意日期转换为对应季度的首日
* @param {Date|string} date - 日期对象或日期字符串
* @returns {string} 格式为'YYYY-MM-DD'的季度首日
*/
export function dateToQuarterStart(date) {
if (!date){
return ''
}
// 如果传入的是字符串转换为Date对象
if (typeof date === 'string') {
date = new Date(date)
}
const year = date.getFullYear()
const month = date.getMonth() // 0-11
// 计算季度
const quarter = Math.floor(month / 3)
// 确定季度首月的月份 (0=1月, 3=4月, 6=7月, 9=10月)
const quarterStartMonth = quarter * 3
// 格式化为'YYYY-MM-DD'
return `${year}-${String(quarterStartMonth + 1).padStart(2, '0')}-01`
}
//时间数组
export function timeData(startTime = '08:00', endTime = '18:30', timeInterval = 0.5) {
const time = []
const date = timeStamp(Date.now()).allDate
const startDate = `${date} ${startTime}`
const endDate = `${date} ${endTime}`
const startTimeStamp = new Date(startDate).getTime()
const endTimeStamp = new Date(endDate).getTime()
const timeStr = 3600 * 1000 * timeInterval
console.log(startTimeStamp)
for (let i = startTimeStamp; i <= endTimeStamp; i = i + timeStr) {
const timeObj:any = {}
timeObj.time = timeStamp(i).hour
timeObj.disable = 0
time.push(timeObj)
}
return time
}
//字符串拼接
function strFormat(str) {
return str < 10 ? `0${str}` : str
}
//时间戳转字符串
export function timeStamp(time) {
const dates = new Date(time)
const year = dates.getFullYear()
const month = dates.getMonth() + 1
const date = dates.getDate()
const day = dates.getDay()
const hour = dates.getHours()
const min = dates.getMinutes()
const days = ['日', '一', '二', '三', '四', '五', '六']
return {
allDate: `${year}/${strFormat(month)}/${strFormat(date)}`,
date: `${strFormat(month)}-${strFormat(date)}`, //返回的日期 07-01
day: `星期${days[day]}`, //返回的礼拜天数 星期一
hour: strFormat(hour) + ':' + strFormat(min) //返回的时钟 08:00
}
}
/**
* 字符串转时间
* @param {Object} dateString
*/
export function stringToDate(dateString) {
var newDate = new Date();
var yearNum = Number(dateString.substr(0,4));
var monthNum = Number(dateString.substr(5,2))-1;
var dayNum = Number(dateString.substr(8,2));
var hourNum = Number(dateString.substr(11,2));
var minuteNum = Number(dateString.substr(14,2));
//var secondNum = Number(dateString.substr(12,2));
newDate.setFullYear(yearNum);
newDate.setMonth(monthNum);
newDate.setDate(dayNum);
newDate.setHours(hourNum);
newDate.setMinutes(minuteNum);
//newDate.setSeconds(secondNum);
return newDate;
}

View File

@@ -0,0 +1,143 @@
/**
* 常用服务
* useful server
*/
const icon_prefix = '/static/index/128/'
/*
*/
export const us = {
data: [
{
title: 'online',
icon: icon_prefix + 'qingjia1.png',
description: 'online',
useCount: 10000,
routeIndex: 'online',
enabled: true,
},
{
title: '仪表盘',
icon: icon_prefix + 'chart.png',
description: '仪表盘',
useCount: 10000,
routeIndex: 'workHome',
enabled: true,
},
{
title: '组件示例',
icon: icon_prefix + 'chuchai.png',
description: '组件示例',
useCount: 10000,
routeIndex: 'demo',
enabled: true,
},
{
title: '流程待办',
icon: icon_prefix + 'gongwen.png',
description: '流程待办',
useCount: 10000,
routeIndex: 'flowIndex',
},
{
title: '知识库',
icon: icon_prefix + 'qingjia1.png',
description: '知识库',
useCount: 10000,
routeIndex: 'knowledge',
enabled: true,
},
{
title: '通知公告',
icon: icon_prefix + 'tongzhi.png',
description: '查看企业对员工下发的通知公告',
useCount: 10000,
routeIndex: 'annotationList',
enabled: true,
},
{
title: '请假申请',
icon: icon_prefix + 'richang.png',
description: '请假申请',
useCount: 10000,
routeIndex: 'leave',
enabled: true,
},
{
title: '出差申请',
icon: icon_prefix + 'zhoubao.png',
description: '出差申请',
useCount: 10000,
routeIndex: 'businesStrip',
enabled: true,
},
{
title: '公文发文',
icon: icon_prefix + 'zhoubao.png',
description: '公文发文',
useCount: 10000,
routeIndex: 'docSend',
enabled: true,
},
{
title: '日程',
icon: icon_prefix + 'richeng.png',
description: '建立和查看个人工作安排',
useCount: 10000,
routeIndex: 'schedule',
},
{
title: '考勤',
icon: icon_prefix + 'kaoqin.png',
description: '工作考勤',
routeIndex: 'ClockIn',
useCount: 10000,
enabled: true,
},
{
title: '内部邮件',
icon: icon_prefix + 'youjian.png',
description: '查看内部消息',
useCount: 10000,
dot: false,
routeIndex: 'mailHome',
enabled: true,
},
],
}
/**
* other server 其他服务
*/
export const os = {
data: [
{
title: '新闻中心',
icon: icon_prefix + 'xinwen.png',
description: '新闻中心',
routeIndex: 'news',
useCount: 10000,
},
{
title: '会议',
icon: icon_prefix + 'huiyi.png',
description: '会议',
useCount: 10000,
routeIndex: 'meeting',
enabled: true,
},
{
title: '任务中心',
icon: icon_prefix + 'renwu.png',
description: '任务中心',
useCount: 10000,
},
{
title: '合同',
icon: icon_prefix + 'hetong.png',
description: '合同',
useCount: 10000,
},
],
}