first commit
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import * as Pinia from 'pinia'
|
||||
import { createPersistedState } from 'pinia-plugin-persistedstate' // 数据持久化
|
||||
|
||||
const store = Pinia.createPinia()
|
||||
store.use(
|
||||
createPersistedState({
|
||||
storage: {
|
||||
getItem: uni.getStorageSync,
|
||||
setItem: uni.setStorageSync,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
export { Pinia, store }
|
||||
|
||||
// 模块统一导出
|
||||
export * from './module/user'
|
||||
export * from './module/search'
|
||||
export * from './module/config'
|
||||
@@ -0,0 +1,119 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {ref, computed} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
import {DictType, DictValue} from "@/constant/enums";
|
||||
|
||||
export const useConfigStore = defineStore(
|
||||
'config',
|
||||
() => {
|
||||
|
||||
// 显示网络服务
|
||||
const showNetworkAnomaly = ref(false)
|
||||
|
||||
// 当前时间
|
||||
const serverTime = ref('')
|
||||
|
||||
// 待付款订单取消时间,单位分钟
|
||||
const orderCancelTime = ref<string | number>('')
|
||||
// 待付款订单取消时间,单位分钟
|
||||
const refundOrderAutoAuditTime = ref<string | number>('')
|
||||
// 设备 id
|
||||
const deviceId = ref('')
|
||||
|
||||
// 运行平台 app | web | mp-weixin
|
||||
const uniPlatform = ref('')
|
||||
|
||||
// 系统名称
|
||||
const osName = ref('')
|
||||
|
||||
// 系统版本
|
||||
const osVersion = ref('')
|
||||
|
||||
// app版本
|
||||
const appVersion = ref('')
|
||||
|
||||
// 状态栏高度
|
||||
const statusBarHeight = ref(0)
|
||||
|
||||
// 窗口高度
|
||||
const windowHeight = ref(0)
|
||||
|
||||
// 窗口宽度
|
||||
const windowWidth = ref(0)
|
||||
|
||||
// 屏幕宽度
|
||||
const screenWidth = ref(0)
|
||||
|
||||
// 屏幕高度
|
||||
const screenHeight = ref(0)
|
||||
|
||||
// tabbar索引
|
||||
const tabbarIndex = ref<string | null>(null)
|
||||
|
||||
// 是否展示过引导页
|
||||
const isShowedGuidePage = ref(false)
|
||||
|
||||
// 是否展示过语言选择页面
|
||||
const isShowedLanguageSelectPage = ref(false)
|
||||
|
||||
// 安全距离
|
||||
const safeAreaInsets = ref<{
|
||||
bottom: number
|
||||
top: number
|
||||
}>({
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
})
|
||||
// 是否是App
|
||||
const isApp = computed(() => {
|
||||
return uniPlatform.value === 'app'
|
||||
})
|
||||
|
||||
// 是否是ios
|
||||
const isIos = computed(() => {
|
||||
return osName.value === 'ios'
|
||||
})
|
||||
|
||||
// 是否是android
|
||||
const isAndroid = computed(() => {
|
||||
return osName.value === 'android'
|
||||
})
|
||||
|
||||
// ios底部安全区占位
|
||||
const iosSafeBottomPlaceholder = computed(() => {
|
||||
if (isIos.value) {
|
||||
return {
|
||||
paddingBottom: safeAreaInsets.value.bottom + 'px',
|
||||
}
|
||||
}
|
||||
return {}
|
||||
})
|
||||
return {
|
||||
showNetworkAnomaly,
|
||||
isApp,
|
||||
isIos,
|
||||
isAndroid,
|
||||
appVersion,
|
||||
osName,
|
||||
osVersion,
|
||||
uniPlatform,
|
||||
statusBarHeight,
|
||||
windowHeight,
|
||||
windowWidth,
|
||||
screenWidth,
|
||||
screenHeight,
|
||||
safeAreaInsets,
|
||||
deviceId,
|
||||
iosSafeBottomPlaceholder,
|
||||
serverTime,
|
||||
tabbarIndex,
|
||||
orderCancelTime,
|
||||
refundOrderAutoAuditTime,
|
||||
isShowedGuidePage,
|
||||
isShowedLanguageSelectPage,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
import {defineStore} from 'pinia'
|
||||
|
||||
type historyListType = {
|
||||
text: string
|
||||
time: number
|
||||
}
|
||||
|
||||
export const useSearchStore = defineStore(
|
||||
'searchStore',
|
||||
() => {
|
||||
const historyList = ref<historyListType[]>([])
|
||||
|
||||
function setHistoryList(keyword: string) {
|
||||
const historyListCopy = [...historyList.value]
|
||||
let index = historyListCopy.findIndex((item) => item.text === keyword)
|
||||
|
||||
if (index === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (index > 0) {
|
||||
historyListCopy.splice(index, 1)
|
||||
historyListCopy.unshift({
|
||||
text: keyword,
|
||||
time: new Date().getTime(),
|
||||
})
|
||||
} else {
|
||||
historyListCopy.unshift({
|
||||
text: keyword,
|
||||
time: new Date().getTime(),
|
||||
})
|
||||
}
|
||||
|
||||
historyList.value = historyListCopy
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
historyList,
|
||||
setHistoryList,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,276 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {ref} from 'vue'
|
||||
import {
|
||||
appUserGetLoginUserGet,
|
||||
appAppointmentTimeQueryAppointmentTimePost,
|
||||
appMerchantCartListMerchantPost
|
||||
} from '@/service'
|
||||
import Config from '@/config'
|
||||
import * as R from 'ramda'
|
||||
import {EventEnum} from "@/constant/enums";
|
||||
import {dayjs} from '@/plugin'
|
||||
import {useConfigStore} from "@/store";
|
||||
|
||||
export const useUserStore = defineStore(
|
||||
'user',
|
||||
() => {
|
||||
|
||||
// 登录邀请码
|
||||
const invitationCode = ref('')
|
||||
|
||||
// 登录token
|
||||
const token = ref('')
|
||||
|
||||
// 是否登录
|
||||
const isLogin = ref(false)
|
||||
|
||||
// 用户信息
|
||||
const userInfo = ref<Partial<IUserInfo>>({})
|
||||
|
||||
// 未读消息数量
|
||||
const unreadMessageCount = ref(0)
|
||||
|
||||
// 地址
|
||||
const address = ref(null)
|
||||
|
||||
// 预约时间
|
||||
const appointmentTime = ref('')
|
||||
|
||||
// 首页展示的预约时间
|
||||
const appointmentTimeShow = computed(()=> {
|
||||
const now = dayjs()
|
||||
const tomorrow = now.add(1, 'day')
|
||||
|
||||
// 如果预约时间不存在,显示明天的星期几
|
||||
if(!appointmentTime.value) {
|
||||
return `${tomorrow.format('dddd')}`
|
||||
}
|
||||
|
||||
const endTime = dayjs(+appointmentTime.value.endTime)
|
||||
|
||||
// 如果预约时间已经过去,显示明天的星期几
|
||||
if(endTime.isBefore(now)) {
|
||||
return `${tomorrow.format('dddd')}`
|
||||
}
|
||||
|
||||
// 如果预约时间还没过去,保持原有格式
|
||||
return endTime.format('MM-DD HH:mm')
|
||||
})
|
||||
|
||||
// 用户购物车信息
|
||||
const userCartAllData = ref(null)
|
||||
|
||||
// 获取用户购物车信息
|
||||
const getUserCartAllData = () => {
|
||||
if(isLogin.value) {
|
||||
appMerchantCartListMerchantPost({}).then(res=> {
|
||||
console.log('获取用户购物车', res)
|
||||
if(res.data) {
|
||||
userCartAllData.value = res.data|| []
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 查询用户的预约时间
|
||||
function getAppointmentTime() {
|
||||
if (!isLogin.value) return
|
||||
appAppointmentTimeQueryAppointmentTimePost({}).then(res => {
|
||||
console.log('查询用户的预约时间', res)
|
||||
appointmentTime.value = res.data || ''
|
||||
})
|
||||
}
|
||||
|
||||
// 自动定位位置
|
||||
const location = ref<{
|
||||
location: string;
|
||||
formattedAddress?: string;
|
||||
longitude: string | number;
|
||||
latitude: string | number;
|
||||
}>({
|
||||
location: '',
|
||||
formattedAddress: '',
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
})
|
||||
|
||||
// 用户手动定位的位置
|
||||
const userSetLocation = ref({
|
||||
location: '',
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
})
|
||||
|
||||
// 用户位置信息
|
||||
const userLocation = computed(() => {
|
||||
if (location.value.location && !userSetLocation.value.location) {
|
||||
return location.value
|
||||
} else if(!location.value.location && userSetLocation.value.location) {
|
||||
return userSetLocation.value
|
||||
} else if(location.value.location && userSetLocation.value.location) {
|
||||
return userSetLocation.value
|
||||
} else {
|
||||
return {
|
||||
formattedAddress: '',
|
||||
location: '',
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
token,
|
||||
(newVal) => {
|
||||
isLogin.value = !!newVal
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
)
|
||||
|
||||
const configStore = useConfigStore()
|
||||
const isMember = computed(() => {
|
||||
if (!isLogin.value) {
|
||||
return false
|
||||
}
|
||||
if (!userInfo.value?.memberRechargeRecord) {
|
||||
return false
|
||||
}
|
||||
const {memberExpireTime} = userInfo.value.memberRechargeRecord || {}
|
||||
if (!memberExpireTime || !configStore.serverTime) {
|
||||
return false
|
||||
}
|
||||
|
||||
return dayjs(+memberExpireTime).isAfter(dayjs(+configStore.serverTime));
|
||||
|
||||
})
|
||||
|
||||
const checkLogin = (): boolean => {
|
||||
console.log('isLogin.value', isLogin.value)
|
||||
if (!isLogin.value) {
|
||||
uni.navigateTo({
|
||||
url: Config.loginPath,
|
||||
})
|
||||
}
|
||||
|
||||
return isLogin.value
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
userInfo.value = {}
|
||||
token.value = ''
|
||||
isLogin.value = false
|
||||
invitationCode.value = ''
|
||||
address.value = null
|
||||
}
|
||||
|
||||
const getUserInfo = async () => {
|
||||
if (!isLogin.value) return
|
||||
try {
|
||||
const res = await appUserGetLoginUserGet({})
|
||||
userInfo.value = res.data || {}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
const {locale} = useI18n()
|
||||
function getCityName(latitude: number, longitude: number) {
|
||||
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${Config.googleMapKey}&language=${locale.value === 'zh-Hans' ? 'zh-CN' : locale.value}`;
|
||||
|
||||
uni.request({
|
||||
url,
|
||||
method: 'GET',
|
||||
timeout: 10000,
|
||||
success: (res: any) => {
|
||||
const results = res.data?.results || [];
|
||||
console.log('geocode results:', results);
|
||||
|
||||
if (!results.length) {
|
||||
return handleFail();
|
||||
}
|
||||
|
||||
const addr = results[0]; // 最高匹配度
|
||||
const components = addr.address_components || [];
|
||||
|
||||
// 提取城市名的工具函数
|
||||
const pickAddress = (types: string[]) => {
|
||||
return components.find((item) => item.types.some((t) => types.includes(t)));
|
||||
};
|
||||
|
||||
// 寻找城市名(多层兜底)
|
||||
let cityObj =
|
||||
pickAddress(["locality"]) ||
|
||||
pickAddress(["administrative_area_level_2"]) ||
|
||||
pickAddress(["administrative_area_level_1"]) ||
|
||||
pickAddress(["political"]);
|
||||
|
||||
const cityName = cityObj?.long_name || null;
|
||||
|
||||
// 从 Google 获取完整地址
|
||||
const formattedAddress = addr.formatted_address || cityName || "";
|
||||
|
||||
console.log("city:", cityObj);
|
||||
console.log("formattedAddress:", formattedAddress);
|
||||
|
||||
if (!cityName) {
|
||||
return handleFail();
|
||||
}
|
||||
|
||||
// 存入 store
|
||||
location.value = {
|
||||
location: cityName,
|
||||
formattedAddress,
|
||||
longitude,
|
||||
latitude
|
||||
};
|
||||
},
|
||||
fail: () => handleFail()
|
||||
});
|
||||
|
||||
function handleFail() {
|
||||
console.log('getLocation fail')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const getLocation = () => {
|
||||
uni.getLocation({
|
||||
isHighAccuracy: true,
|
||||
type: 'wgs84',
|
||||
success: async (res) => {
|
||||
console.log('res', res)
|
||||
getCityName(res.latitude, res.longitude)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log(err)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
invitationCode,
|
||||
token,
|
||||
isLogin,
|
||||
isMember,
|
||||
userInfo,
|
||||
location,
|
||||
userSetLocation,
|
||||
userLocation,
|
||||
address,
|
||||
unreadMessageCount,
|
||||
appointmentTime,
|
||||
appointmentTimeShow,
|
||||
userCartAllData,
|
||||
getUserCartAllData,
|
||||
getUserInfo,
|
||||
checkLogin,
|
||||
clear,
|
||||
getLocation,
|
||||
getAppointmentTime,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user