feat: move project

This commit is contained in:
ckaaaa 2025-09-16 13:41:49 +08:00
commit 4a940f28ba
97 changed files with 5047 additions and 0 deletions

29
utils/constant.js Normal file
View file

@ -0,0 +1,29 @@
const _ = {
// cdnHost: 'http://civcar2.zhonganonline.top/newslist',
// apiHost: 'http://civcar2.zhonganonline.top/newslist',
cdnHost: 'http://cdn.liiistem.cn/liiistem',
apiHost: 'https://prxy.liiistem.cn/liiistem',
};
if (wx.getStorageSync('mode') == 'dev') {
_.cdnHost = 'http://civcar2.zhonganonline.top/liiistem';
_.apiHost = 'http://civcar2.zhonganonline.top/liiistem';
}
export const STATUS_LIST = [{
key: 'init',
label: '待审核'
},
{
key: 'resolve',
label: '审核通过'
},
{
key: 'reject',
label: '审核未通过'
},
]
export const STATUS_MAP = STATUS_LIST.reduce((r, c) => {
r[c.key] = c;
return r;
}, {})
export default _;

162
utils/func.js Normal file
View file

@ -0,0 +1,162 @@
import C from './constant.js';
export const getHost = () => {
return C.apiHost;
};
export const isDev = () => {
return true;
}
export const parseDate = (time, type = 1) => {
const val = [time.getFullYear(), time.getMonth() + 1, time.getDate()].map((o) => { return o < 10 ? '0' + o : o });
const val2 = [time.getHours(), time.getMinutes(), time.getSeconds()].map((o) => { return o < 10 ? '0' + o : o });
if (type === 1) {
return val.join('-');
}
if (type === 2) {
return val2.join(':');
}
if (type === 3) {
return [val[0], '年', val[1], '月', val[2], '日'].join('');
}
if (type === 4) {
return val[0] + '年';
}
if (type === 5) {
return [val[1], '月'].join('');
}
if (type === 6) {
return [val[1], '月', val[2], '日'].join('');
}
if (type === 7) {
return val.join('.');
}
return val.join('-') + ' ' + val2.join(':');
}
export const safeStrToDate = (str) => {
const arr = str.split(/[-\ \:]/g);
const arr2 = [0, 0, 0, 0, 0, 0];
arr.map((one, idx) => {
arr2[idx] = one * 1;
});
if (arr2[1] > 0) {
arr2[1] -= 1;
}
return new Date(arr2[0], arr2[1], arr2[2], arr2[3], arr2[4], arr2[5]);
}
export const sizeTool = (size) => {
if (size > 1024 * 1024 * 1024) {
return (size / 1024 / 1024 / 1024).toFixed(2) + 'G';
}
if (size > 1024 * 1024) {
return (size / 1024 / 1024).toFixed(2) + 'M';
}
if (size > 1024) {
return (size / 1024).toFixed(2) + 'K';
}
return size + 'B'
}
export const getQueryString = (params) => {
const list = [];
for (const k in params) {
if (!(params[k] == undefined || params[k] == null)) {
list.push([encodeURIComponent(k), encodeURIComponent(params[k])].join('='));
}
}
return list.join('&');
}
export const parseQueryString = (str) => {
const l = str.split('&');
const m = {};
l.forEach((o) => {
const _ = o.split('=');
m[decodeURIComponent(_[0])] = decodeURIComponent(_[1] || '');
})
return m;
}
export const filterProperties = (obj, propKeys) => {
if (propKeys.length == 0) {
return { ...obj };
}
const reObj = {};
propKeys.map((k) => {
reObj[k] = obj[k];
});
return reObj;
}
export const filterPropertiesList = (list, propKeys) => {
return list.map((obj => filterProperties(obj, propKeys)));
}
export const secToTimeStr = (n) => {
const h = Math.floor(n * 1.0 / 60 / 60);
const m = Math.floor((n - h * 60 * 60) / 60);
const s = n % 60;
return h + '时' + m + '分' + s + '秒';
}
export const dateToWeek = (date) => {
const arr = '日一二三四五六'.split('');
return arr[date.getDay()];
}
export const fixPage = (pageData, oldPage) => {
// console.log('fixPage', pageData.page, oldPage);
const { page, pageSize, total } = pageData;
if (total == 0) {
return {
...pageData,
page: 1, pageSize, total: 0
};
}
const maxPage = Math.ceil(total * 1.0 / pageSize);
if (oldPage > maxPage) {
return {
...pageData,
list: [],
page: oldPage, pageSize, total: 0
};
}
return {
...pageData,
page, pageSize, total
};
}
// 分转元,并移除小数点后多余的0
export const formatePrice = (price) => {
return (price / 100).toFixed(2).replace(/\.00$/, '')
}
// 时间12:22加上分钟后的时间
export const timeAddMinute = (time, minute) => {
const tmpTime = safeStrToDate('2020-01-01 ' + time + ':00').getTime() + minute * 60 * 1000;
return parseDate(new Date(tmpTime), 9);
}
// 手机号隐藏中间几位
export const hidePhone = (phone) => {
return (phone || '').replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
export const fix0 = (n) => {
if (!/[0-9\.]+/.test(n + '')) {
return 0;
}
const t = n + '';
if (n.indexOf('.') == -1) {
return t;
}
const tt = t.split('.');
const f0 = (tt[1].split('').reverse().join('') * 1 + '').split('').reverse().join('');
if (f0 == 0) {
return tt[0];
}
return [tt[0], f0].join('.');
}

45
utils/getPermission.js Normal file
View file

@ -0,0 +1,45 @@
const getPermission = ({ code, name }) => {
return new Promise((resolve, reject) => {
wx.getSetting({
success: (res) => {
if (res.authSetting[code] === false) {
wx.showModal({
title: `获取${name}失败`,
content: `获取${name}失败,请在【右上角】-小程序【设置】项中,将【${name}】开启。`,
confirmText: '去设置',
confirmColor: '#FA550F',
cancelColor: '取消',
success(res) {
if (res.confirm) {
wx.openSetting({
success(settinRes) {
if (settinRes.authSetting[code] === true) {
resolve();
} else {
console.warn('用户未打开权限', name, code);
reject();
}
},
});
} else {
reject();
}
},
fail() {
reject();
},
});
} else {
resolve();
}
},
fail() {
reject();
},
});
});
};
module.exports = {
getPermission,
};

53
utils/log.js Normal file
View file

@ -0,0 +1,53 @@
const A = {
isLog: false,
logList: [],
}
A.info = (msg) => {
if (A.isLog) {
return;
}
console.log('info', msg);
A.logList.push({
time: new Date(),
msg: msg,
type: 'info',
});
// console.log('logList', A.logList);
}
A.warn = (msg) => {
if (A.isLog) {
return;
}
console.log('warn', msg);
A.logList.push({
time: new Date(),
msg: msg,
type: 'warn',
});
}
A.error = (msg) => {
if (A.isLog) {
return;
}
console.log('error', msg);
A.logList.push({
time: new Date(),
msg: msg,
type: 'error',
});
}
A.getLogList = (type) => {
if (type) {
return A.logList.filter((o) => {
return o.type == type;
})
}
console.log('llllll', A.logList, type);
return A.logList;
}
A.setIslog = (f) => {
// console.log('setIslog', f);
A.isLog = f;
}
module.exports = A

51
utils/mock.js Normal file
View file

@ -0,0 +1,51 @@
/**
* 随机打散字符串
* @param {number} n 长度
* @param {string} str 字符串
* @returns
*/
function generateMixed(n, str) {
var res = '';
for (var i = 0; i < n; i++) {
var id = Math.ceil(Math.random() * 35);
res += str[id];
}
return res;
}
/**
* 生成随机数
* @param {number} min 最小值
* @param {number} max 最大值
* @returns
*/
function getRandomNum(min, max) {
var range = max - min;
var rand = Math.random();
return min + Math.round(rand * range);
}
/**
* 生成随机IP
* @returns
*/
function mockIp() {
return `10.${getRandomNum(1, 254)}.${getRandomNum(1, 254)}.${getRandomNum(
1,
254,
)}`;
}
function mockReqId() {
return `${getRandomNum(100000, 999999)}.${new Date().valueOf()}${getRandomNum(
1000,
9999,
)}.${getRandomNum(10000000, 99999999)}`;
}
module.exports = {
generateMixed,
mockIp,
mockReqId,
getRandomNum,
};

226
utils/request.js Normal file
View file

@ -0,0 +1,226 @@
import * as F from './func.js';
const Log = require('./log.js');
import C from './constant.js';
let lockToLogin = false;
const login = () => {
const user_id = wx.getStorageSync('user_id');
if (user_id) {
return Promise.resolve(user_id);
}
// return Promise.resolve();
return new Promise((resolve, reject) => {
wx.login({
success({ code }) {
console.log('aaaa', code);
// code = 'test';
// code:'test'
post('/index.php/api/v1/wx_login', { code }, true).then(({ model }) => {
console.log('wx_login', model);
wx.setStorageSync('user_id', model.user_id);
resolve(model);
}).catch((e) => {
reject(e)
})
},
fail(e) {
reject(e)
}
})
});
}
const post = (path, params, notLogin = false) => {
Log.info('post 请求:' + path + 'params:' + JSON.stringify(params));
const _ = ((resolve, reject) => {
const user_id = wx.getStorageSync('user_id');
if (!user_id && !notLogin) {
return reject(-1002);
}
wx.request({
url: F.getHost() + path,
data: params,
header: {
Cookie: 'user_id=' + user_id,
},
method: 'POST',
success: (res) => {
console.log('res', res);
const {
data,
statusCode,
cookies
} = res;
if (statusCode != 200) {
wx.showToast({
icon:'none',
title: 'statusCode:' + statusCode
});
Log.error('post 请求失败1:' + statusCode + '|' + path + ' params:' + JSON.stringify(params));
reject(-1);
} else {
const message = data.errorMsg || data.message;
const errorCode = data.errorCode;
if (errorCode == -1000) {
wx.showToast({
icon:'none',
title: "登录超时,请重新登录"
});
if (!lockToLogin) {
lockToLogin = true;
wx.navigateTo({
url: '/pages/login/index'
});
setTimeout(() => {
lockToLogin = false;
}, 1000)
}
reject(-4);
} else if (errorCode < 0) {
wx.showToast({
icon:'none',
title: message || errorCode + '请求失败' ,
});
Log.error('post 请求失败2:' + message + '|' + path + ' params:' + JSON.stringify(params));
reject(-3);
} else {
resolve(data);
}
}
},
fail: ({
errMsg,
errno
}) => {
wx.showToast({
icon:'none',
title: '接口异常:' + errMsg
});
console.error('post fail:', errMsg, errno);
Log.error('post error:' + errMsg + '|errno:' + errno + '|' + path + ' params:' + JSON.stringify(params));
reject(-2);
}
});
})
if (notLogin) {
return new Promise(_);
} else {
return login().then(() => new Promise(_));
}
}
const get = (path, params, notLogin = false) => {
Log.info('get 请求:' + path + 'params:' + JSON.stringify(params));
const _ = ((resolve, reject) => {
const user_id = wx.getStorageSync('user_id');
if (!user_id && !notLogin) {
return reject(-1002);
}
wx.request({
url: F.getHost() + path,
data: params,
header: {
Cookie: 'user_id=' + user_id,
},
method: 'GET',
success: ({
data,
statusCode,
cookies
}) => {
if (statusCode != 200) {
wx.showToast({
icon:'none',
title: 'statusCode:' + statusCode
});
Log.error('get 请求失败1:' + statusCode + '|' + path + ' params:' + JSON.stringify(params));
reject(-1);
} else {
const message = data.errorMsg || data.message;
const errorCode = data.errorCode;
if (errorCode == -1000) {
wx.showToast({
icon:'none',
title: "登录超时,请重新登录"
});
if (!lockToLogin) {
lockToLogin = true;
wx.navigateTo({
url: '/pages/login/index'
});
setTimeout(() => {
lockToLogin = false;
}, 1000)
}
reject(-4);
} else if (errorCode < 0) {
wx.showToast({
icon:'none',
title: message || errorCode + '请求失败' ,
});
Log.error('get 请求失败2:' + message + '|' + path + ' params:' + JSON.stringify(params));
reject(-3);
} else {
resolve(data);
}
}
},
fail: ({
errMsg,
errno
}) => {
wx.showToast({
icon:'none',
title: '接口异常:' + errMsg
});
console.error('get fail:', errMsg, errno);
Log.error('get error:' + errMsg + '|errno:' + errno + '|' + path + ' params:' + JSON.stringify(params));
reject(-2);
}
});
})
if (notLogin) {
return new Promise(_);
} else {
return login().then(() => new Promise(_));
}
}
const upload = (params, name, filePath, processCb) => {
const _ = new Promise((resolve, reject) => {
const user_id = wx.getStorageSync('user_id');
const task = wx.uploadFile({
url: F.getHost() + '/index.php/api/v1/wx_upload',
formData: params,
name,
filePath,
header: {
Cookie: 'user_id=' + user_id,
'Content-Type': 'multipart/form-data',
},
timeout: 120000,
method: 'POST',
success: (res) => {
resolve(res);
},
fail: (res) => {
const {
errMsg,
errno
} = res;
console.error('post fail:', errMsg, errno);
Log.error('upload post fail:' + errMsg + '|errno' + errno);
reject(res);
}
});
if (processCb) {
task.onProgressUpdate(processCb);
}
})
return login().then(() => _);
}
export default {
login,
post,
get,
upload,
};

203
utils/requestAct1.js Normal file
View file

@ -0,0 +1,203 @@
import * as F from './func.js';
const Log = require('./log.js');
import C from './constant.js';
let lockToLogin = false;
const login = () => {
return Promise.resolve();
}
const post = (path, params, notLogin = false) => {
Log.info('post 请求:' + path + 'params:' + JSON.stringify(params));
const _ = new Promise((resolve, reject) => {
const user_id = wx.getStorageSync('act_user_id');
if (!user_id && !notLogin) {
return reject(-1001);
}
wx.request({
url: F.getHost() + path,
data: params,
header: {
Cookie: 'act_user_id=' + user_id,
},
method: 'POST',
success: (res) => {
console.log('res', res);
const {
data,
statusCode,
cookies
} = res;
if (statusCode != 200) {
wx.showToast({
icon: 'none',
title: 'statusCode:' + statusCode
});
Log.error('post 请求失败1:' + statusCode + '|' + path + ' params:' + JSON.stringify(params));
reject(-1);
} else {
const message = data.errorMsg || data.message;
const errorCode = data.errorCode;
if (errorCode == -1000) {
wx.showToast({
icon: 'none',
title: "登录超时,请重新登录"
});
if (!lockToLogin) {
lockToLogin = true;
wx.navigateTo({
url: '/pages/login/index'
});
setTimeout(() => {
lockToLogin = false;
}, 1000)
}
reject(-4);
} else if (errorCode < 0) {
wx.showToast({
icon: 'none',
title: message || errorCode + '请求失败'
});
Log.error('post 请求失败2:' + message + '|' + path + ' params:' + JSON.stringify(params));
reject(-3);
} else {
resolve(data);
}
}
},
fail: ({
errMsg,
errno
}) => {
wx.showToast({
icon: 'none',
title: '接口异常:' + errMsg
});
console.error('post fail:', errMsg, errno);
Log.error('post error:' + errMsg + '|errno:' + errno + '|' + path + ' params:' + JSON.stringify(params));
reject(-2);
}
});
})
if (notLogin) {
return _;
} else {
return login().then(() => _);
}
}
const get = (path, params, notLogin = false) => {
Log.info('get 请求:' + path + 'params:' + JSON.stringify(params));
const _ = new Promise((resolve, reject) => {
const user_id = wx.getStorageSync('act_user_id');
if (!user_id && !notLogin) {
return reject(-1001);
}
wx.request({
url: F.getHost() + path,
data: params,
header: {
Cookie: 'act_user_id=' + user_id,
},
method: 'GET',
success: ({
data,
statusCode,
cookies
}) => {
if (statusCode != 200) {
wx.showToast({
icon: 'none',
title: 'statusCode:' + statusCode
});
Log.error('get 请求失败1:' + statusCode + '|' + path + ' params:' + JSON.stringify(params));
reject(-1);
} else {
const message = data.errorMsg || data.message;
const errorCode = data.errorCode;
if (errorCode == -1000) {
wx.showToast({
icon: 'none',
title: "登录超时,请重新登录"
});
if (!lockToLogin) {
lockToLogin = true;
wx.navigateTo({
url: '/pages/login/index'
});
setTimeout(() => {
lockToLogin = false;
}, 1000)
}
reject(-4);
} else if (errorCode < 0) {
wx.showToast({
icon: 'none',
title: message || errorCode + '请求失败'
});
Log.error('get 请求失败2:' + message + '|' + path + ' params:' + JSON.stringify(params));
reject(-3);
} else {
resolve(data);
}
}
},
fail: ({
errMsg,
errno
}) => {
wx.showToast({
icon: 'none',
title: '接口异常:' + errMsg
});
console.error('get fail:', errMsg, errno);
Log.error('get error:' + errMsg + '|errno:' + errno + '|' + path + ' params:' + JSON.stringify(params));
reject(-2);
}
});
})
if (notLogin) {
return _;
} else {
return login().then(() => _);
}
}
const upload = (params, name, filePath, processCb) => {
const _ = new Promise((resolve, reject) => {
const user_id = wx.getStorageSync('act_user_id');
const task = wx.uploadFile({
url: F.getHost() + '/index.php/api/act1/wx_upload',
formData: params,
name,
filePath,
header: {
Cookie: 'act_user_id=' + user_id,
'Content-Type': 'multipart/form-data',
},
timeout: 120000,
method: 'POST',
success: (res) => {
resolve(res);
},
fail: (res) => {
const {
errorMsg,
errorCode
} = res;
console.error('post fail:', errorMsg, errorCode);
Log.error('upload post fail:' + errorMsg + '|errorCode' + errorCode);
reject(res);
}
});
if (processCb) {
task.onProgressUpdate(processCb);
}
})
return login().then(() => _);
}
export default {
login,
post,
get,
upload,
};

133
utils/util.js Normal file
View file

@ -0,0 +1,133 @@
import dayjs from 'dayjs';
const formatTime = (date, template) => dayjs(date).format(template);
/**
* 格式化价格数额为字符串
* 可对小数部分进行填充默认不填充
* @param price 价格数额以分为单位!
* @param fill 是否填充小数部分 0-不填充 1-填充第一位小数 2-填充两位小数
*/
function priceFormat(price, fill = 0) {
if (isNaN(price) || price === null || price === Infinity) {
return price;
}
let priceFormatValue = Math.round(parseFloat(`${price}`) * 10 ** 8) / 10 ** 8; // 恢复精度丢失
priceFormatValue = `${Math.ceil(priceFormatValue) / 100}`; // 向上取整,单位转换为元,转换为字符串
if (fill > 0) {
// 补充小数位数
if (priceFormatValue.indexOf('.') === -1) {
priceFormatValue = `${priceFormatValue}.`;
}
const n = fill - priceFormatValue.split('.')[1]?.length;
for (let i = 0; i < n; i++) {
priceFormatValue = `${priceFormatValue}0`;
}
}
return priceFormatValue;
}
/**
* 获取cdn裁剪后链接
*
* @param {string} url 基础链接
* @param {number} width 宽度单位px
* @param {number} [height] 可选高度不填时与width同值
*/
const cosThumb = (url, width, height = width) => {
if (url.indexOf('?') > -1) {
return url;
}
if (url.indexOf('http://') === 0) {
url = url.replace('http://', 'https://');
}
return `${url}?imageMogr2/thumbnail/${~~width}x${~~height}`;
};
const get = (source, paths, defaultValue) => {
if (typeof paths === 'string') {
paths = paths
.replace(/\[/g, '.')
.replace(/\]/g, '')
.split('.')
.filter(Boolean);
}
const { length } = paths;
let index = 0;
while (source != null && index < length) {
source = source[paths[index++]];
}
return source === undefined || index === 0 ? defaultValue : source;
};
let systemWidth = 0;
/** 获取系统宽度,为了减少启动消耗所以在函数里边做初始化 */
export const loadSystemWidth = () => {
if (systemWidth) {
return systemWidth;
}
try {
({ screenWidth: systemWidth, pixelRatio } = wx.getSystemInfoSync());
} catch (e) {
systemWidth = 0;
}
return systemWidth;
};
/**
* 转换rpx为px
*
* @description
* 什么时候用
* - 布局(width: 172rpx)已经写好, 某些组件只接受px作为style或者prop指定
*
*/
const rpx2px = (rpx, round = false) => {
loadSystemWidth();
// px / systemWidth = rpx / 750
const result = (rpx * systemWidth) / 750;
if (round) {
return Math.floor(result);
}
return result;
};
/**
* 手机号码*加密函数
* @param {string} phone 电话号
* @returns
*/
const phoneEncryption = (phone) => {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
};
// 内置手机号正则字符串
const innerPhoneReg =
'^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$';
/**
* 手机号正则校验
* @param phone 手机号
* @param phoneReg 正则字符串
* @returns true - 校验通过 false - 校验失败
*/
const phoneRegCheck = (phone) => {
const phoneRegExp = new RegExp(innerPhoneReg);
return phoneRegExp.test(phone);
};
module.exports = {
formatTime,
priceFormat,
cosThumb,
get,
rpx2px,
phoneEncryption,
phoneRegCheck,
};