初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
var app = {
appkey: 'cashier',
version: '5.5.3',
version_no: '553250709001',
}
var config = {
// 站点ID
siteId: 0,
// api请求地址 https://abc.com
baseUrl: '{{$baseUrl}}',
// 图片域名 https://abc.com
imgDomain: '{{$imgDomain}}',
//长链接 wss://abc.com/wss
webSocket: '{{$webSocket}}',
// app版本信息
app: app,
}
export default config;

View File

@@ -0,0 +1,110 @@
import Config from './config.js'
import Util from './util.js'
const app_type = 'pc';
const app_type_name = 'PC';
export default {
sendRequest(params) {
var method = params.method ?? 'POST', // 请求方式
url = Config.baseUrl + params.url, // 请求路径
data = {
app_type,
app_type_name
};
if (uni.getStorageSync('cashierToken')) data.token = uni.getStorageSync('cashierToken');
if (uni.getStorageSync('siteId')) data.site_id = uni.getStorageSync('siteId');
if (uni.getStorageSync('globalStoreId')) data.store_id = uni.getStorageSync('globalStoreId');
if (params.data != undefined) Object.assign(data, params.data);
if (params.async === false) {
//同步
return new Promise((resolve, reject) => {
uni.request({
url: url,
method: method,
data: data,
header: params.header || {
'content-type': 'application/x-www-form-urlencoded;application/json'
},
dataType: params.dataType || 'json',
responseType: params.responseType || 'json',
success: (res) => {
if (res.data.code == -10009 || res.data.code == -10010) {
uni.removeStorage({
key: 'cashierToken'
});
if (Util.getCurrRoute() != 'pages/login/login') {
Util.redirectTo('/pages/login/login', {}, 'reLaunch');
return;
}
}
resolve(res.data);
},
fail: (res) => {
reject(res);
},
complete: (res) => {
// reject(res);
}
});
})
} else {
//异步
uni.request({
url: url,
method: method,
data: data,
header: params.header || {
'content-type': 'application/x-www-form-urlencoded;application/json'
},
dataType: params.dataType || 'json',
responseType: params.responseType || 'text',
success: (res) => {
if (res.data.code == -10009 || res.data.code == -10010) {
uni.removeStorage({
key: 'cashierToken'
});
if (Util.getCurrRoute() != 'pages/login/login') {
Util.redirectTo('/pages/login/login', {}, 'reLaunch');
return;
}
}
typeof params.success == 'function' && params.success(res.data);
},
fail: (res) => {
typeof params.fail == 'function' && params.fail(res);
},
complete: (res) => {
typeof params.complete == 'function' && params.complete(res);
}
});
}
},
post(url, params) {
const option = {
url,
method: 'post',
async: false
};
return this.sendRequest({
...params,
...option
});
},
get(url, params) {
const option = {
url,
method: 'get',
async: false
};
return this.sendRequest({
...params,
...option
});
}
}

View File

@@ -0,0 +1,150 @@
import {mapGetters} from 'vuex';
export default {
data() {
return {
// 左侧菜单,支持触发的按键集合
menuKeyCode: ['F6', 'F7', 'F8', 'F9', 'F10', 'F11'],
themeColor: ''
};
},
onShow() {
this.setNavigationBarTitleText();
// 监听键盘回调
window.POS_HOTKEY_CALLBACK = (control, code) => {
this.$store.commit('billing/setIsShowCashBox',true);
// 触发左侧菜单按键回调
this.menuTriggerKeyCodeCallBack(code);
};
},
computed: {
cashierToken() {
return uni.getStorageSync('cashierToken');
},
...mapGetters([
'rootSize', 'defaultImg', 'addon', 'menu', 'userInfo', 'themeConfig',
'globalStoreId', 'globalStoreInfo', 'globalMemberId', 'globalMemberInfo'
])
},
watch: {
'globalStoreInfo.store_id': {
handler(nval, oval) {
if (oval && typeof this.switchStoreAfter == 'function') {
this.switchStoreAfter();
this.setNavigationBarTitleText();
}
},
deep: true
},
themeConfig:{
handler(nval,oval){
if(nval && oval && oval.color && nval.color != oval.color) {
this.loadThemeColor();
}
},
deep:true
}
},
methods: {
/**
* 设置页面标题
*/
setNavigationBarTitleText() {
let pages = getCurrentPages();
let currentPage = pages[pages.length - 1];
if (currentPage && currentPage.$holder && currentPage.$holder.navigationBarTitleText) {
let title = currentPage.$holder.navigationBarTitleText;
if (this.globalStoreInfo) title += '-' + this.globalStoreInfo.store_name;
if (title != currentPage.$holder.navigationBarTitleText) uni.setNavigationBarTitle({
title: title
})
} else {
setTimeout(() => {
this.setNavigationBarTitleText();
}, 800)
}
},
// 触发左侧菜单按键回调
menuTriggerKeyCodeCallBack(code) {
if (this.menuKeyCode.indexOf(code) != -1) {
let data = null;
for (let i = 0; i < this.menu.length; i++) {
let item = this.menu[i];
if (item.keyCode == code) {
data = item;
break;
}
}
if (data) {
// #ifdef H5
if (data.path == this.$route.path) return;
// #endif
// #ifdef APP-PLUS
if (data.path == '/' + this.$mp.page.route) return;
// #endif
this.$util.redirectTo(data.path, data.query ?? {});
}
}
},
themeColorSet() {
let theme = this.themeConfig;
this.themeColor = `--primary-color:${theme.color};`;
for (let i = 9; i >= 1; i--) {
let color = this.$util.colourBlend(theme.color, '#ffffff', (i / 10));
this.themeColor += `--primary-color-light-${i}:${color};`;
}
},
loadThemeColor(){
let time = setInterval(() => {
let theme = this.themeConfig;
if (theme && theme.color) {
this.themeColorSet();
clearInterval(time);
}
}, 50);
}
},
filters: {
/**
* 金额格式化
* @param {Object} money
*/
moneyFormat(money) {
if (isNaN(money)) return money;
return parseFloat(money).toFixed(2);
},
/**
* 时间格式化
* @param {Object} time 时间戳
* @param {Object} format 输出格式
*/
timeFormat(time, format = 'Y-m-d H:i:s') {
var date = new Date();
date.setTime(time * 1000);
var y = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
var h = date.getHours();
var i = date.getMinutes();
var s = date.getSeconds();
format = format.replace('Y', y);
format = format.replace('m', (m < 10 ? '0' + m : m));
format = format.replace('d', (d < 10 ? '0' + d : d));
format = format.replace('H', (h < 10 ? '0' + h : h));
format = format.replace('i', (i < 10 ? '0' + i : i));
format = format.replace('s', (s < 10 ? '0' + s : s));
return format;
},
mobileFormat(mobile) {
return mobile.substring(0, 4 - 1) + '****' + mobile.substring(6 + 1);
}
}
}

View File

@@ -0,0 +1,14 @@
// import { ipcRenderer } from 'electron';
export default {
send(call, param) {
if (window.ipcRenderer != undefined) {
window.ipcRenderer.send(call, param);
}
if (window.POS_ != undefined) {
window.POS_.send(call, param);
}
//window.ipcRenderer.send('Print', '渲染进程')
//window.ipcRenderer.invoke('Print', '渲染进程')
},
}

View File

@@ -0,0 +1,51 @@
import Config from './config.js'
const prefix = Config.baseUrl.replace(/(http:\/\/)|(https:\/\/)/g, '');
var oldPrefix = uni.getStorageSync('prefix');
// 域名不一致,清空
if (oldPrefix != prefix) {
uni.clearStorageSync();
}
uni.setStorageSync('prefix', prefix);
const handleKey = (key) => {
const storageKey = (prefix ? `${prefix}_` : '') + key;
return storageKey;
};
export function uniStorage() {
const setStorageSync = uni.setStorageSync;
const setStorage = uni.setStorage;
const getStorage = uni.getStorage;
const getStorageSync = uni.getStorageSync;
const removeStorage = uni.removeStorage;
const removeStorageSync = uni.removeStorageSync;
uni.setStorage = (options) => {
options.key = handleKey(options.key);
setStorage(options)
};
uni.setStorageSync = (key, data) => {
setStorageSync(handleKey(key), data)
};
uni.getStorage = (options) => {
options.key = handleKey(options.key);
getStorage(options)
};
uni.getStorageSync = (key) => {
return getStorageSync(handleKey(key))
};
uni.removeStorage = (options) => {
options.key = handleKey(options.key);
removeStorage(options)
};
uni.removeStorageSync = (key) => {
return removeStorageSync(handleKey(key))
}
}

View File

@@ -0,0 +1,340 @@
import Config from './config.js'
import Store from '@/store/index.js'
export default {
/**
* 页面跳转
* @param {string} to 跳转链接 /pages/idnex/index
* @param {Object} param 参数 {key : value, ...}
* @param {string} mode 模式
*/
redirectTo(to, param, mode) {
let tabbar = [
"/pages/billing/index", // 开单
"/pages/reserve/index", // 预约
"/pages/buycard/index", // 售卡
"/pages/recharge/index", // 充值
"/pages/verify/index" // 核销
];
if (tabbar.indexOf(to) != -1) mode = 'tabbar';
Store.commit('app/setCurrRoute', to);
let url = to;
if (param != undefined) {
Object.keys(param).forEach(function (key) {
if (url.indexOf('?') != -1) {
url += "&" + key + "=" + param[key];
} else {
url += "?" + key + "=" + param[key];
}
});
}
switch (mode) {
case 'tabbar':
// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
uni.switchTab({
url
});
break;
case 'redirectTo':
// 关闭当前页面,跳转到应用内的某个页面。
uni.redirectTo({
url
});
break;
case 'reLaunch':
// 关闭所有页面,打开到应用内的某个页面。
uni.reLaunch({
url
});
break;
default:
// 保留当前页面,跳转到应用内的某个页面
uni.navigateTo({
url
});
}
},
/**
* 图片路径转换
* @param {String} img_path 图片地址
* @param {Object} params 参数针对商品、相册里面的图片区分大中小size: big、mid、small
*/
img(img_path, params) {
var path = "";
if (img_path != undefined && img_path != "") {
if (img_path.split(',').length > 1) {
img_path = img_path.split(',')[0];
}
if (params && img_path) {
// 过滤默认图
let arr = img_path.split(".");
let suffix = arr[arr.length - 1];
arr.pop();
arr[arr.length - 1] = arr[arr.length - 1] + "_" + params.size.toUpperCase();
arr.push(suffix);
img_path = arr.join(".");
}
if (img_path.indexOf("http://") == -1 && img_path.indexOf("https://") == -1) {
path = Config.imgDomain + "/" + img_path;
} else {
path = img_path;
}
}
return path;
},
/**
* 验证当前数组或对象是否为空
* @param param 校验对象
*/
checkIsNotNull(param) {
if (param) {
if (typeof (param) == 'object') {
if (Array.isArray(param)) {
if (param.length > 0) return true
} else {
if (JSON.stringify(param) != '{}') return true
}
} else {
return true;
}
}
return false;
},
/**
* 金额格式化
* @param {Object} money
*/
moneyFormat(money) {
if (isNaN(parseFloat(money))) return money;
return parseFloat(money).toFixed(2);
},
/**
* 时间格式化
* @param {Object} time 时间戳
* @param {Object} format 输出格式
*/
timeFormat(time, format = 'y-m-d h:i:s') {
//一律用小写转换
format = format.toLowerCase();
if(time == 0) return '--';
var date = new Date();
date.setTime(time * 1000);
var y = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
var h = date.getHours();
var i = date.getMinutes();
var s = date.getSeconds();
format = format.replace('y', y);
format = format.replace('m', (m < 10 ? '0' + m : m));
format = format.replace('d', (d < 10 ? '0' + d : d));
format = format.replace('h', (h < 10 ? '0' + h : h));
format = format.replace('i', (i < 10 ? '0' + i : i));
format = format.replace('s', (s < 10 ? '0' + s : s));
return format;
},
/**
* 日期格式转时间戳
* @param {Object} string
*/
timeTurnTimeStamp(string) {
var f = string.split(' ', 2);
var d = (f[0] ? f[0] : '').split('-', 3);
var t = (f[1] ? f[1] : '').split(':', 3);
return (new Date(
parseInt(d[0], 10) || null,
(parseInt(d[1], 10) || 1) - 1,
parseInt(d[2], 10) || null,
parseInt(t[0], 10) || null,
parseInt(t[1], 10) || null,
parseInt(t[2], 10) || null
)).getTime() / 1000;
},
/**
* 获取当前页面路由
*/
getCurrRoute() {
let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
return routes.length ? routes[routes.length - 1].route : '';
},
/**
* 显示消息提示框
* @param {Object} params 参数
*/
showToast(params = {}) {
params.title = params.title || "";
params.icon = params.icon || "none";
// params.position = params.position || 'bottom';
params.duration = params.duration || 1500;
uni.showToast(params);
if (params.success) params.success();
},
/*
* 深度拷贝对象
* @param {Object} obj
*/
deepClone(obj) {
const isObject = function (obj) {
return typeof obj == 'object';
}
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
//判断传进来的是对象还是数组
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [] : {}
//通过for...in来拷贝
for (let key in obj) {
cloneObj[key] = isObject(obj[key]) ? this.deepClone(obj[key]) : obj[key]
}
return cloneObj
},
/**
* 图片选择加上传
* @param num
* @param params
* @param callback
* @param url
*/
upload: function (num, params, callback, url) {
const app_type = 'pc';
const app_type_name = 'PC';
var data = {
token: uni.getStorageSync('cashierToken'),
app_type: app_type,
app_type_name: app_type_name
}
data = Object.assign(data, params);
var imgs_num = num;
var _self = this;
uni.chooseImage({
count: imgs_num,
sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], //从相册或者拍照
success: async function (res) {
const tempFilePaths = res.tempFilePaths;
var _data = data;
var imgs = [];
for (var i = 0; i < tempFilePaths.length; i++) {
var path = await _self.upload_file_server(tempFilePaths[i], _data, params.path, url);
imgs.push(path);
}
typeof callback == 'function' && callback(imgs);
},
fail: err => {
console.log('图片上传错误', err)
}
});
},
//上传
upload_file_server(tempFilePath, data, path, url = "") {
if (url) {
var uploadUrl = Config.baseUrl + url
} else {
var uploadUrl = Config.baseUrl + '/cashier/storeapi/upload/' + path
}
data.site_id = uni.getStorageSync('siteId');
return new Promise((resolve, reject) => {
uni.uploadFile({
url: uploadUrl,
filePath: tempFilePath,
name: 'file',
formData: data,
success: function (res) {
var path_str = JSON.parse(res.data);
if (path_str.code >= 0) {
resolve(path_str.data.pic_path);
} else {
reject("error");
}
},
});
});
},
/**
* 验证手机号
* @param {string} mobile 被验证的mobile
* @return {object} 验证后的结果
**/
verifyMobile(mobile) {
var parse =/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/.test(mobile);
return parse;
},
clearStoreData() {
Store.commit('app/setGlobalStoreInfo', null);
Store.commit('app/setGlobalStoreId', 0);
Store.commit('app/setGlobalMemberInfo', null);
Store.commit('app/setUserInfo', null);
Store.commit('app/setMenu', []);
// 开单
Store.commit('billing/setGoodsData', {});
Store.commit('billing/setPendOrderId',0);
Store.commit('billing/setGoodsIds', []);
Store.commit('billing/setOrderData', {});
Store.commit('billing/setActive', '');
Store.commit('billing/setIsScanTrigger', false);
// 售卡
Store.commit('buycard/setGoodsData', {});
Store.commit('buycard/setOrderData', {});
Store.commit('buycard/setActive', '');
// 充值
Store.commit('recharge/setActive', '');
},
/**
* 颜色减值
* @param {Object} c1
* @param {Object} c2
* @param {Object} ratio
*/
colourBlend(c1, c2, ratio) {
ratio = Math.max(Math.min(Number(ratio), 1), 0)
let r1 = parseInt(c1.substring(1, 3), 16)
let g1 = parseInt(c1.substring(3, 5), 16)
let b1 = parseInt(c1.substring(5, 7), 16)
let r2 = parseInt(c2.substring(1, 3), 16)
let g2 = parseInt(c2.substring(3, 5), 16)
let b2 = parseInt(c2.substring(5, 7), 16)
let r = Math.round(r1 * (1 - ratio) + r2 * ratio)
let g = Math.round(g1 * (1 - ratio) + g2 * ratio)
let b = Math.round(b1 * (1 - ratio) + b2 * ratio)
r = ('0' + (r || 0).toString(16)).slice(-2)
g = ('0' + (g || 0).toString(16)).slice(-2)
b = ('0' + (b || 0).toString(16)).slice(-2)
return '#' + r + g + b
},
//商品类型字典
goodsClassDict:{
real:1,
virtual:2,
virtualcard:3,
service:4,
card:5,
weigh:6,
},
setLocalConfig(obj){
var local_config = this.getLocalConfig();
local_config = Object.assign(local_config, obj);
uni.setStorageSync('local_config', local_config);
},
getLocalConfig(){
var local_config = uni.getStorageSync('local_config');
if(!local_config) local_config = {};
local_config = Object.assign({
printerSelectType:'all',
printerSelectIds:[],
}, local_config);
return local_config;
},
}

View File

@@ -0,0 +1,173 @@
/**
* 数据验证(表单验证)
*/
module.exports = {
error: '',
check: function(data, rule) {
for (var i = 0; i < rule.length; i++) {
if (!rule[i].checkType) {
return true;
}
if (!rule[i].name) {
return true;
}
if (!rule[i].errorMsg) {
return true;
}
if (!data[rule[i].name]) {
this.error = rule[i].errorMsg;
return false;
}
switch (rule[i].checkType) {
case 'custom':
if (typeof rule[i].validate == 'function') {
if (!rule[i].validate(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
}
break;
case 'required':
var reg = new RegExp('/[\S]+/');
if (reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'string':
var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'int':
var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'between':
if (!this.isNumber(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'betweenD':
var reg = /^-?[1-9][0-9]?$/;
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'betweenF':
var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'same':
if (data[rule[i].name] != rule[i].checkRule) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'notsame':
if (data[rule[i].name] == rule[i].checkRule) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'email':
var reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'phoneno':
var reg = /^\d{11}$/;
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'zipcode':
var reg = /^[0-9]{6}$/;
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'reg':
var reg = new RegExp(rule[i].checkRule);
if (!reg.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'in':
if (rule[i].checkRule.indexOf(data[rule[i].name]) == -1) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'notnull':
if (data[rule[i].name] == 0 || data[rule[i].name] == undefined || data[rule[i].name] ==
null || data[rule[i].name]
.length < 1) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'lengthMin':
if (data[rule[i].name].length < rule[i].checkRule) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'lengthMax':
if (data[rule[i].name].length > rule[i].checkRule) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'numberId':
var pattern = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
if (!pattern.test(data[rule[i].name])) {
this.error = rule[i].errorMsg;
return false
}
break;
}
}
return true;
},
isNumber: function(checkVal) {
var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
return reg.test(checkVal);
}
}