Files
pda-cli/src/store/index.js
T

243 lines
7.3 KiB
JavaScript

/**
* Copyright (c) 2013-Now http://aidex.vip All rights reserved.
*/
import config, { getDefaultApiUrl } from '@/common/config.js';
import util from '@/common/util.js';
import Vue from 'vue'
import Vuex from 'vuex'
import { audioManager } from '@/utils/audioManager'
import dayjs from 'dayjs'
Vue.use(Vuex)
let lifeData = {};
try{
// 尝试获取本地是否存在lifeData变量,第一次启动APP时是不存在的
lifeData = uni.getStorageSync('lifeData');
}catch(e){
}
// 初始化API URL(默认正式环境)
function initApiUrl() {
const defaultUrl = getDefaultApiUrl();
try {
uni.setStorageSync('ApiUrl', defaultUrl);
} catch (e) {
console.log('写入正式环境地址失败', e);
}
return defaultUrl;
}
// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
let saveStateKeys = ['vuex_user', 'vuex_token', 'vuex_remember', 'vuex_locale','vuex_isAgent', 'vuex_notificationEnabled'];
// 保存变量到本地存储中
const saveLifeData = function(key, value){
// 判断变量名是否在需要存储的数组中
if(saveStateKeys.indexOf(key) != -1) {
// 获取本地存储的lifeData对象,将变量添加到对象中
let tmp = uni.getStorageSync('lifeData');
// 第一次打开APP,不存在lifeData变量,故放一个{}空对象
tmp = tmp ? tmp : {};
tmp[key] = value;
// 执行这一步后,所有需要存储的变量,都挂载在本地的lifeData对象中
uni.setStorageSync('lifeData', tmp);
}
}
// 简化 vuex 操作,文档:https://uviewui.com/components/vuexDetail.html
const store = new Vuex.Store({
state: {
// 如果上面从本地获取的lifeData对象下有对应的属性,就赋值给state中对应的变量
// 加上vuex_前缀,是防止变量名冲突,也让人一目了然
vuex_user: lifeData.vuex_user ? lifeData.vuex_user : {userName: 'Aidex'},
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',
vuex_remember: lifeData.vuex_remember ? lifeData.vuex_remember : '',
vuex_locale: lifeData.vuex_locale ? lifeData.vuex_locale : '',
vuex_isAgent: lifeData.vuex_isAgent ? lifeData.vuex_isAgent : '',
// 如果vuex_version无需保存到本地永久存储,无需lifeData.vuex_version方式
vuex_config: config,
// 自定义tabbar数据
// 新增通知相关状态
vuex_notificationEnabled: lifeData.vuex_notificationEnabled != null ? lifeData.vuex_notificationEnabled : true,
vuex_deliveryIds: [], // 存储已知的配布单ID
vuex_messageList: [], // 存储消息列表
vuex_notificationAudio: null,
vuex_pollingTimer: null,
apiurl: initApiUrl() // 根据环境初始化URL
},
mutations: {
$uStore(state, payload) {
// 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
let nameArr = payload.name.split('.');
let saveKey = '';
let len = nameArr.length;
if(len >= 2) {
let obj = state[nameArr[0]];
for(let i = 1; i < len - 1; i ++) {
obj = obj[nameArr[i]];
}
obj[nameArr[len - 1]] = payload.value;
saveKey = nameArr[0];
} else {
// 单层级变量,在state就是一个普通变量的情况
state[payload.name] = payload.value;
saveKey = payload.name;
}
// 保存变量到本地,见顶部函数定义
saveLifeData(saveKey, state[saveKey])
},
// 新增通知相关 mutation
setPollingTimer(state, timer) {
state.vuex_pollingTimer = timer;
},
setNotificationAudio(state, audio) {
state.vuex_notificationAudio = audio;
},
SET_API_URL(state, url) {
state.apiurl = url
uni.setStorageSync('ApiUrl', url)
}
},
actions: {
// 初始化通知
initNotification({ state, commit, dispatch }) {
// 创建音频实例
const audio = uni.createInnerAudioContext();
audio.src = '/static/audio/ninyouxindepeibudan.mp3';
// 监听音频播放错误
audio.onError((res) => {
console.error('Audio error:', res.errMsg);
});
// 监听音频播放结束
audio.onEnded(() => {
console.log('Audio playback completed');
});
commit('setNotificationAudio', audio);
if(!state.vuex_notificationEnabled || !uni.getStorageSync("RemoteTokenData").token) return
dispatch('stopPolling');
// 开始轮询
dispatch('startPolling');
// 监听网络状态
uni.onNetworkStatusChange(function(res) {
if (res.isConnected) {
dispatch('startPolling');
} else {
dispatch('stopPolling');
}
});
},
// 开始轮询
startPolling({ state, commit, dispatch }) {
if (state.vuex_pollingTimer || !state.vuex_notificationEnabled) return;
const timer = setInterval(() => {
dispatch('checkNewDeliveries');
}, 20 * 1000);
// }, 1 * 1000);
commit('setPollingTimer', timer);
},
// 停止轮询
stopPolling({ state, commit }) {
if (state.vuex_pollingTimer) {
clearInterval(state.vuex_pollingTimer);
commit('setPollingTimer', null);
}
},
// 检查新配布单
async checkNewDeliveries({ state, commit, dispatch }) {
uni.request({
url: util.apiurl + "/product/fpmArrangeOrder/getFpmArrangeOrderList",
method: "GET",
// #ifdef APP-PLUS
sslVerify: false,
// #endif
header: {
platform: "2",
Authorization: uni.getStorageSync("RemoteTokenData").token,
},
data: {
business_status_ids: '1,2', // 根据tab传递对应的状态组合
page: 1,
size: 10,
},
success: (res) => {
console.log('res',res)
if (res.data.code != 0) {
throw new Error('检查配布单失败');
}
console.log("data", res.data.data.list);
const data = res.data.data.list
// 获取所有配布单ID
const newDeliveryIds = data.map(item => item.id);
// 找出新增的配布单ID
const newIds = newDeliveryIds.filter(id => !state.vuex_deliveryIds.includes(id));
console.log("newIds", newIds.length);
// 如果有新增配布单,触发通知
if (newIds.length > 0) {
// 播放声音
audioManager.play()
// 触发振动
uni.vibrateLong();
// 显示通知消息
// uni.showToast({
// title: `有${newIds.length}个新的配布单待处理`,
// icon: 'none',
// });
// 构建新的消息列表项
const newMessages = data.filter(item => newIds.includes(item.id)).map((item) => ({
title: '新配布单通知',
content: `销售单号:${item.order_no}`,
path: `/pages/saleship/salepickscandetail?billid=${item.id}`,
time: dayjs().format('HH:mm')
}));
const newList = [...newMessages, ...state.vuex_messageList]
// 更新消息列表
commit('$uStore', {
name: 'vuex_messageList',
value: newList
});
}
// 使用 $uStore 方式更新状态
commit('$uStore', {
name: 'vuex_deliveryIds',
value: newDeliveryIds
});
},
fail: (error) => {
console.log('error',error)
if (error.code === 401 || error.errMsg.includes('Failed to connect')) {
dispatch('stopPolling');
}
},
complete: () => {
},
});
},
updateApiUrl({ commit }, url) {
commit('SET_API_URL', url)
}
},
getters: {
apiurl: state => state.apiurl
}
})
export default store