first commit

This commit is contained in:
2026-02-26 09:32:03 +08:00
commit 36a8e4c51b
845 changed files with 116474 additions and 0 deletions
+19
View File
@@ -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'
+119
View File
@@ -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,
},
)
+46
View File
@@ -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,
},
)
+276
View File
@@ -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,
},
)