diff --git a/.env b/.env
index 5685e149..1e542811 100644
--- a/.env
+++ b/.env
@@ -10,8 +10,8 @@ SHOPRO_VERSION=v2.4.1
SHOPRO_API_PATH=/app-api
# 后端接口 - 测试环境(通过 process.env.NODE_ENV == development)
-SHOPRO_DEV_BASE_URL = https://api.htysapp.com
-# SHOPRO_DEV_BASE_URL=https://baac9a029ea84f36ba28c023fed4fc5f.hd.takin.cc
+# SHOPRO_DEV_BASE_URL = https://api.htysapp.com
+SHOPRO_DEV_BASE_URL=https://baac9a029ea84f36ba28c023fed4fc5f.hd.takin.cc
# 后端接口 - 正式环境(通过 process.env.NODE_ENV != development)
SHOPRO_BASE_URL=https://api.htysapp.com
diff --git a/@html/download.html b/@html/download.html
index 7c86d87c..834880c3 100644
--- a/@html/download.html
+++ b/@html/download.html
@@ -1,456 +1,356 @@
-
-
-
+
+
荷塘月色 - app下载
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
-
+
-
-

-
荷塘月色
-
同城交友平台
-
-
-
-
-
+
-
-
+
-
-
\ No newline at end of file
+ var hm = document.createElement('script');
+ hm.src = 'https://hm.baidu.com/hm.js?8841fecf6f4a06974ef8797421c60dc0';
+ var s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(hm, s);
+ })();
+
+
diff --git a/@html/归档.zip b/@html/归档.zip
new file mode 100644
index 00000000..7e984d88
Binary files /dev/null and b/@html/归档.zip differ
diff --git a/package.json b/package.json
index f392c5ba..f29bdf1c 100644
--- a/package.json
+++ b/package.json
@@ -58,7 +58,7 @@
"lodash-es": "^4.17.21",
"luch-request": "^3.0.8",
"pinia": "^2.0.33",
- "pinia-plugin-persist-uni": "^1.2.0",
+ "pinia-plugin-persistedstate": "3.2.3",
"pinyin-pro": "^3.23.1",
"quill": "^1.3.7",
"quill-image-resize-mp": "^3.0.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 368f3c1c..177f5003 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -77,9 +77,9 @@ importers:
pinia:
specifier: ^2.0.33
version: 2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5))
- pinia-plugin-persist-uni:
- specifier: ^1.2.0
- version: 1.3.2(pinia@2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5)))(vue@3.5.30(typescript@4.9.5))
+ pinia-plugin-persistedstate:
+ specifier: 3.2.3
+ version: 3.2.3(pinia@2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5)))
pinyin-pro:
specifier: ^3.23.1
version: 3.28.0
@@ -3266,15 +3266,10 @@ packages:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
- pinia-plugin-persist-uni@1.3.2:
- resolution: {integrity: sha512-Z47MWlAI3dnm9xENwodYyT6B3TMDuwFK7MHHymwQyrTchuhG2Yu26w7bYlIap7df0fCwNCmAo0n7n1RK3Ute+w==}
+ pinia-plugin-persistedstate@3.2.3:
+ resolution: {integrity: sha512-Cm819WBj/s5K5DGw55EwbXDtx+EZzM0YR5AZbq9XE3u0xvXwvX2JnWoFpWIcdzISBHqy9H1UiSIUmXyXqWsQRQ==}
peerDependencies:
- '@vue/composition-api': ^1.0.0
- pinia: '>2.0.0'
- vue: ^2.0.0 || >=3.0.0
- peerDependenciesMeta:
- '@vue/composition-api':
- optional: true
+ pinia: ^2.0.0
pinia@2.3.1:
resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==}
@@ -3968,17 +3963,6 @@ packages:
terser:
optional: true
- vue-demi@0.12.5:
- resolution: {integrity: sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==}
- engines: {node: '>=12'}
- hasBin: true
- peerDependencies:
- '@vue/composition-api': ^1.0.0-rc.1
- vue: ^3.0.0-0 || ^2.6.0
- peerDependenciesMeta:
- '@vue/composition-api':
- optional: true
-
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
@@ -8435,11 +8419,9 @@ snapshots:
pify@2.3.0: {}
- pinia-plugin-persist-uni@1.3.2(pinia@2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5)))(vue@3.5.30(typescript@4.9.5)):
+ pinia-plugin-persistedstate@3.2.3(pinia@2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5))):
dependencies:
pinia: 2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5))
- vue: 3.5.30(typescript@4.9.5)
- vue-demi: 0.12.5(vue@3.5.30(typescript@4.9.5))
pinia@2.3.1(typescript@4.9.5)(vue@3.5.30(typescript@4.9.5)):
dependencies:
@@ -9207,10 +9189,6 @@ snapshots:
sass: 1.78.0
terser: 5.46.1
- vue-demi@0.12.5(vue@3.5.30(typescript@4.9.5)):
- dependencies:
- vue: 3.5.30(typescript@4.9.5)
-
vue-demi@0.14.10(vue@3.5.30(typescript@4.9.5)):
dependencies:
vue: 3.5.30(typescript@4.9.5)
diff --git a/src/App.vue b/src/App.vue
index 3e09f2be..c4eba21b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -536,7 +536,6 @@ export default {
);
// #endif
// #ifndef MP-WEIXIN
- this.$mountStore();
this.closeSplashscreen(1000); // 延迟1s,避免用户看到页面跳转
let loginInfo = uni.getStorageSync('loginInfo');
if (!loginInfo || !loginInfo.refreshToken) {
diff --git a/src/chat-store/chatStore.js b/src/chat-store/chatStore.js
index 84dddab3..551ed8ac 100644
--- a/src/chat-store/chatStore.js
+++ b/src/chat-store/chatStore.js
@@ -546,4 +546,4 @@ export default defineStore('chatStore', {
return null;
}
}
-});
\ No newline at end of file
+});
diff --git a/src/chat-store/friendStore.js b/src/chat-store/friendStore.js
index c846e754..c3503a83 100644
--- a/src/chat-store/friendStore.js
+++ b/src/chat-store/friendStore.js
@@ -5,27 +5,27 @@ import { TERMINAL_TYPE } from '../common/enums.js'
export default defineStore('friendStore', {
state: () => {
return {
- friendMap: new Map(),
+ friendMap: {},
timer: null
}
},
actions: {
setFriends(friends) {
- this.friendMap.clear();
- friends.forEach(f => this.friendMap.set(f.id, f))
+ this.friendMap = {};
+ friends.forEach(f => this.friendMap[f.id] = f)
},
updateFriend(friend) {
let f = this.findFriend(friend.id);
friend.online = f.online;
friend.onlineWeb = f.onlineWeb;
friend.onlineApp = f.onlineApp;
- this.friendMap.set(friend.id, friend)
+ this.friendMap[friend.id] = friend
},
removeFriend(id) {
- this.friendMap.get(id).deleted = true;
+ this.friendMap[id].deleted = true;
},
addFriend(friend) {
- this.friendMap.set(friend.id, friend)
+ this.friendMap[friend.id] = friend
},
setOnlineStatus(onlineTerminals) {
this.friends.forEach((f) => {
@@ -59,10 +59,10 @@ export default defineStore('friendStore', {
}, 30000)
},
setDnd(id, isDnd) {
- this.friendMap.get(id).isDnd = isDnd;
+ this.friendMap[id].isDnd = isDnd;
},
clear() {
- this.friendMap.clear();
+ this.friendMap = {};
clearTimeout(this.timer);
this.timer = null;
},
@@ -83,14 +83,20 @@ export default defineStore('friendStore', {
},
getters: {
friends: (state) => {
- return Array.from(state.friendMap.values());
+ return Object.values(state.friendMap);
},
findFriend: (state) => (userId) => {
- return state.friendMap.get(userId);
+ return state.friendMap[userId];
},
isFriend: (state) => (userId) => {
let f = state.findFriend(userId)
return f && !f.deleted
}
+ },
+ persist: {
+ paths: ['friendMap'],
+ afterRestore: ({ store }) => {
+ store.timer = null;
+ }
}
-})
\ No newline at end of file
+})
diff --git a/src/chat-store/groupStore.js b/src/chat-store/groupStore.js
index 3409b10c..9e41cfd0 100644
--- a/src/chat-store/groupStore.js
+++ b/src/chat-store/groupStore.js
@@ -4,28 +4,28 @@ import http from '@/common/request';
export default defineStore('groupStore', {
state: () => {
return {
- groupMap: new Map()
+ groupMap: {}
}
},
actions: {
setGroups(groups) {
- this.groupMap.clear();
- groups.forEach(g => this.groupMap.set(g.id, g))
+ this.groupMap = {};
+ groups.forEach(g => this.groupMap[g.id] = g)
},
addGroup(group) {
- this.groupMap.set(group.id, group);
+ this.groupMap[group.id] = group;
},
removeGroup(id) {
- this.groupMap.get(id).quit = true;
+ this.groupMap[id].quit = true;
},
updateGroup(group) {
- this.groupMap.set(group.id, group);
+ this.groupMap[group.id] = group;
},
setDnd(id, isDnd) {
- this.groupMap.get(id).isDnd = isDnd;
+ this.groupMap[id].isDnd = isDnd;
},
clear() {
- this.groupMap.clear();
+ this.groupMap = {};
},
loadGroup() {
return new Promise((resolve, reject) => {
@@ -43,14 +43,15 @@ export default defineStore('groupStore', {
},
getters: {
groups: (state) => {
- return Array.from(state.groupMap.values());
+ return Object.values(state.groupMap);
},
findGroup: (state) => (id) => {
- return state.groupMap.get(id);
+ return state.groupMap[id];
},
isGroup: (state) => (id) => {
let group = state.findGroup(id);
return group && !group.quit
}
- }
-})
\ No newline at end of file
+ },
+ persist: true
+})
diff --git a/src/chat-store/userStore.js b/src/chat-store/userStore.js
index a7163fb9..b5aabc59 100644
--- a/src/chat-store/userStore.js
+++ b/src/chat-store/userStore.js
@@ -30,4 +30,5 @@ export default defineStore('userStore', {
});
},
},
+ persist: true,
});
diff --git a/src/common/emotion.js b/src/common/emotion.js
index 5287e8a1..b503a712 100644
--- a/src/common/emotion.js
+++ b/src/common/emotion.js
@@ -34,37 +34,11 @@ const emoTextList = [
'享受',
'鼻涕',
'快乐',
- '雀跃',
- '微笑',
- '贪婪',
- '红心',
- '粉心',
- '星星',
- '大火',
- '眼睛',
- '音符',
- '叹号',
- '问号',
- '绿叶',
- '燃烧',
- '喇叭',
- '警告',
- '信封',
- '房子',
- '礼物',
- '点赞',
- '举手',
- '拍手',
- '点头',
- '摇头',
- '偷瞄',
- '庆祝',
- '疾跑',
- '打滚',
- '惊吓',
- '起跳',
+ '雀跃', '微笑',
+ '贪婪', '红心', '粉心', '星星', '大火', '眼睛', '音符', "叹号", "问号", "绿叶",
+ "燃烧", "喇叭", "警告", "信封", "房子", "礼物", "点赞", "举手", "拍手", "点头",
+ "摇头", "偷瞄", "庆祝", "疾跑", "打滚", "惊吓", "起跳"
];
-
const regex = /\#[\u4E00-\u9FA5]{1,3}\;/gi;
let containEmoji = (content) => {
@@ -88,7 +62,7 @@ let transform = (content, extClass) => {
let textToPath = (emoText) => {
let word = emoText.replace(/\#|\;/gi, '');
let idx = emoTextList.indexOf(word);
- return EMO_URL + idx + '.png';
+ return EMO_URL + idx + '.gif';
};
export default {
diff --git a/src/common/request.js b/src/common/request.js
index 390d96b2..d286f7af 100644
--- a/src/common/request.js
+++ b/src/common/request.js
@@ -1,7 +1,9 @@
import CHAT_ENV from '@/chat-env.js';
-// 请求队列
-let requestList = [];
+const TOKEN_REFRESH_THRESHOLD_SECONDS = 5 * 60;
+
+// 等待同一次 token 刷新结果的请求队列
+let refreshWaitList = [];
// 是否正在刷新中
let isRefreshToken = false;
@@ -20,36 +22,41 @@ const request = (options) => {
timeout: options.timeout || 3000,
async success(res) {
if (res.data.code == 200) {
+ const currentLoginInfo = uni.getStorageSync('loginInfo');
+ if (isAccessTokenExpiringSoon(currentLoginInfo?.accessToken)) {
+ try {
+ await refreshAccessToken(currentLoginInfo);
+ } catch (error) {
+ console.log('刷新token失败', error);
+ getApp().$vm.exit();
+ return reject(error);
+ }
+ }
return resolve(res.data.data);
} else if (res.data.code == 400) {
console.log('code 400');
getApp().$vm.exit();
} else if (res.data.code == 401) {
console.log('token失效,尝试重新获取');
- if (isRefreshToken) {
- // 正在刷新token,把其他请求存起来
- requestList.push(() => {
- resolve(request(options));
- });
- return;
+ const currentLoginInfo = uni.getStorageSync('loginInfo');
+
+ // 当前请求使用的是旧 token,直接用已刷新的 token 重试。
+ if (
+ currentLoginInfo?.accessToken &&
+ currentLoginInfo.accessToken !== header.accessToken
+ ) {
+ return resolve(request(options));
}
- isRefreshToken = true;
- // 发送请求, 进行刷新token操作, 获取新的token
- const res = await reqRefreshToken(loginInfo);
- if (!res || res.data.code != 200) {
- requestList = [];
- isRefreshToken = false;
- console.log('刷新token失败');
+
+ try {
+ await refreshAccessToken(currentLoginInfo);
+ // 重新发送刚才的请求
+ return resolve(request(options));
+ } catch (error) {
+ console.log('刷新token失败', error);
getApp().$vm.exit();
- return;
+ return reject(error);
}
- let newInfo = res.data.data;
- uni.setStorageSync('loginInfo', newInfo);
- requestList.forEach((cb) => cb());
- requestList = [];
- isRefreshToken = false;
- // 重新发送刚才的请求
- return resolve(request(options));
} else {
uni.showToast({
icon: 'none',
@@ -71,6 +78,64 @@ const request = (options) => {
});
};
+const isAccessTokenExpiringSoon = (accessToken) => {
+ if (!accessToken) {
+ return false;
+ }
+
+ try {
+ const payload = accessToken.split('.')[1];
+ const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
+ const paddedBase64 = base64.padEnd(Math.ceil(base64.length / 4) * 4, '=');
+ const bytes = new Uint8Array(uni.base64ToArrayBuffer(paddedBase64));
+ let decodedPayload = '';
+ bytes.forEach((byte) => {
+ decodedPayload += String.fromCharCode(byte);
+ });
+ const expMatch = decodedPayload.match(/"exp"\s*:\s*(\d+)/);
+ if (!expMatch) {
+ return false;
+ }
+ const remainingSeconds = Number(expMatch[1]) - Math.floor(Date.now() / 1000);
+ console.log("remainingSeconds:", remainingSeconds);
+
+ return remainingSeconds <= TOKEN_REFRESH_THRESHOLD_SECONDS;
+ } catch (error) {
+ console.warn('解析 accessToken 过期时间失败', error);
+ return false;
+ }
+};
+
+const refreshAccessToken = (loginInfo) => {
+ if (!loginInfo?.refreshToken) {
+ return Promise.reject(new Error('缺少 refreshToken'));
+ }
+ if (isRefreshToken) {
+ return new Promise((resolve, reject) => {
+ refreshWaitList.push({ resolve, reject });
+ });
+ }
+ isRefreshToken = true;
+ return reqRefreshToken(loginInfo)
+ .then((res) => {
+ if (!res || res.data.code != 200) {
+ throw res?.data || new Error('刷新token失败');
+ }
+ const newInfo = res.data.data;
+ uni.setStorageSync('loginInfo', newInfo);
+ refreshWaitList.forEach(({ resolve }) => resolve(newInfo));
+ return newInfo;
+ })
+ .catch((error) => {
+ refreshWaitList.forEach(({ reject }) => reject(error));
+ throw error;
+ })
+ .finally(() => {
+ refreshWaitList = [];
+ isRefreshToken = false;
+ });
+};
+
const reqRefreshToken = (loginInfo) => {
return new Promise(function (resolve, reject) {
uni.request({
diff --git a/src/components/head-image/head-image.vue b/src/components/head-image/head-image.vue
index 51edfa94..18d78c06 100644
--- a/src/components/head-image/head-image.vue
+++ b/src/components/head-image/head-image.vue
@@ -1,13 +1,6 @@
-
+
{{ name?.substring(0, 1).toUpperCase() }}
@@ -16,117 +9,117 @@
diff --git a/src/main.ts b/src/main.ts
index e32db1e3..c3eac2b5 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -23,8 +23,8 @@ import { initH5HostShell } from '@/sheep/platform/h5-shell';
window.Quill = Quill;
window.ImageResize = { default: ImageResize };
// 调试器
-import VConsole from 'vconsole';
-new VConsole();
+// import VConsole from 'vconsole';
+// new VConsole();
initH5HostShell();
patchH5Navigation();
// #endif
@@ -48,7 +48,7 @@ import switchBar from '@/components/bar/switch-bar';
export function createApp() {
const app = createSSRApp(App);
- setupPinia(app);
+ const pinia = setupPinia(app);
// 聊天common模块挂载为全局属性
app.config.globalProperties.$http = request;
@@ -67,14 +67,16 @@ export function createApp() {
app.component('btn-bar', btnBar);
app.component('switch-bar', switchBar);
- // $mountStore挂载为全局属性,等app初始化时再挂载chat-store到全局属性,方便页面中直接this使用
- app.config.globalProperties.$mountStore = () => {
- app.config.globalProperties.chatStore = useChatStore();
- app.config.globalProperties.friendStore = useFriendStore();
- app.config.globalProperties.groupStore = useGroupStore();
- app.config.globalProperties.configStore = useConfigStore();
- app.config.globalProperties.userStore = useUserStore();
+ // 在页面首次渲染前挂载聊天仓库,避免刷新页面时全局 store 尚未可用。
+ const mountStores = () => {
+ app.config.globalProperties.chatStore = useChatStore(pinia);
+ app.config.globalProperties.friendStore = useFriendStore(pinia);
+ app.config.globalProperties.groupStore = useGroupStore(pinia);
+ app.config.globalProperties.configStore = useConfigStore(pinia);
+ app.config.globalProperties.userStore = useUserStore(pinia);
};
+ app.config.globalProperties.$mountStore = mountStores;
+ mountStores();
return {
app,
diff --git a/src/pages/goods/comment/add.vue b/src/pages/goods/comment/add.vue
index c52024c0..b5d80966 100644
--- a/src/pages/goods/comment/add.vue
+++ b/src/pages/goods/comment/add.vue
@@ -6,13 +6,9 @@
-
+
@@ -27,23 +23,12 @@
-
+
- uploadSuccess(payload, index)"
- />
+ @success="(payload) => uploadSuccess(payload, index)" />
@@ -69,122 +54,122 @@
diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue
index 592b16de..7847c151 100644
--- a/src/pages/login/login.vue
+++ b/src/pages/login/login.vue
@@ -1,5 +1,5 @@
-
+
@@ -11,16 +11,19 @@
+ placeholder="请输入账号" placeholder-style="color: rgba(255, 255, 255, 0.6)" v-model="phone" maxlength="11"
+ :adjust-position="false" />
+ placeholder="请输入手机号" placeholder-style="color: rgba(255, 255, 255, 0.6)" v-model="phone" maxlength="11"
+ :adjust-position="false" />
+ placeholder="验证码" placeholder-style="color: rgba(255, 255, 255, 0.6)" v-model="smsCode" maxlength="4"
+ :adjust-position="false" />
获取验证码 ({{ countDown }}s)
@@ -75,7 +78,7 @@
+
+
diff --git a/src/pages/message/chat-box.vue b/src/pages/message/chat-box.vue
index 1d916e6f..10166222 100644
--- a/src/pages/message/chat-box.vue
+++ b/src/pages/message/chat-box.vue
@@ -3,12 +3,14 @@
-
-
-
-
-
- {{ title }}
+
+
+
+
+
+
+ {{ title }}
+
@@ -182,6 +184,9 @@
import CHAT_ENV from '@/chat-env.js';
import RecentApi from '@/sheep/api/member/recent';
import sheep from '@/sheep';
+// #ifdef H5
+import { getH5StatusBarHeight } from '@/sheep/platform/h5-shell';
+// #endif
import WarningCar from "./components/warning-car.vue"
import UserInfoCar from "./components/user-info-car.vue"
@@ -208,6 +213,7 @@ export default {
screenHeight: 1000, // 屏幕高度
windowHeight: 1000, // 窗口高度
initHeight: 1000, // h5初始高度
+ h5StatusBarHeight: 0, // h5套壳状态栏高度
atUserIds: [],
showMinIdx: 0, // 下标小于showMinIdx的消息不显示,否则可能很卡
reqQueue: [], // 请求队列
@@ -933,14 +939,15 @@ export default {
});
},
async ensureChatStoreReady() {
- if (!this.userStore.userInfo?.id) {
- await this.userStore.loadUser();
+ this.$mountStore?.();
+ if (!this.userStore?.userInfo?.id) {
+ await this.userStore?.loadUser?.();
}
- if (!this.chatStore.curChats?.length) {
- await this.chatStore.loadChat();
+ if (!this.chatStore?.curChats?.length) {
+ await this.chatStore?.loadChat?.();
}
if (
- this.chatStore.refreshChats &&
+ this.chatStore?.refreshChats &&
this.chatStore.curChats?.length !== this.chatStore.chats.length
) {
this.chatStore.refreshChats();
@@ -1024,7 +1031,11 @@ export default {
let sysInfo = uni.getSystemInfoSync();
let h = this.windowHeight;
// 减去标题栏高度
- h -= 50;
+ h -= 44;
+ // #ifdef H5
+ // h5套壳场景下,页面内容还需要减去宿主状态栏高度
+ h -= this.h5StatusBarHeight;
+ // #endif
// 减去键盘高度
if (this.isShowKeyBoard || this.chatTabBox != 'none') {
// ios app的键盘高度不准,需要减去屏幕和窗口差
@@ -1059,6 +1070,21 @@ export default {
}
// #endif
},
+ syncH5StatusBarHeight() {
+ // #ifdef H5
+ this.h5StatusBarHeight = getH5StatusBarHeight();
+ // #endif
+ },
+ handleH5ShellStatusBarChange(event) {
+ // #ifdef H5
+ const nextHeight = Number.parseFloat(event?.detail?.height);
+ this.h5StatusBarHeight = Number.isFinite(nextHeight)
+ ? Math.max(nextHeight, 0)
+ : getH5StatusBarHeight();
+ this.windowHeight = uni.getSystemInfoSync().windowHeight;
+ this.reCalChatMainHeight();
+ // #endif
+ },
listenKeyBoard() {
// #ifdef H5
if (navigator.platform == 'Win32') {
@@ -1414,10 +1440,17 @@ export default {
this.windowHeight = uni.getSystemInfoSync().windowHeight;
this.screenHeight = uni.getSystemInfoSync().screenHeight;
+ // #ifdef H5
+ this.syncH5StatusBarHeight();
+ // #endif
this.reCalChatMainHeight();
this.$nextTick(() => {
// 上面获取的windowHeight可能不准,重新计算一次聊天窗口高度
this.windowHeight = uni.getSystemInfoSync().windowHeight;
+ // #ifdef H5
+ this.syncH5StatusBarHeight();
+ window.addEventListener('app-shell-status-bar-change', this.handleH5ShellStatusBarChange);
+ // #endif
this.reCalChatMainHeight();
this.scrollToBottom();
// #ifdef H5
@@ -1437,6 +1470,9 @@ export default {
},
onUnload() {
this.unListenKeyboard();
+ // #ifdef H5
+ window.removeEventListener('app-shell-status-bar-change', this.handleH5ShellStatusBarChange);
+ // #endif
},
};
@@ -1474,6 +1510,9 @@ export default {
// #ifndef APP-PLUS
top: $im-nav-bar-height;
// #endif
+ // #ifdef H5
+ top: calc($im-nav-bar-height + var(--status-bar-height, 0px));
+ // #endif
// #ifdef APP-PLUS
top: calc($im-nav-bar-height + var(--status-bar-height));
// #endif
diff --git a/src/pages/moments/publish.vue b/src/pages/moments/publish.vue
index f909f78e..ecb8dd5d 100644
--- a/src/pages/moments/publish.vue
+++ b/src/pages/moments/publish.vue
@@ -16,7 +16,7 @@
-
+
+
+
+
+
+
+
+
+
+
-
-
@@ -72,10 +75,8 @@ const params = reactive({
issueCity: '',
issueDistrict: '',
});
-const coverPic = computed(() => params.coverPic?.join(',') || []);
-const coverVideo = computed(() => {
- return params.coverVideo.map((item: any) => JSON.parse(item.response).data);
-});
+const coverPic = computed(() => params.coverPic?.join(',') || '');
+const coverVideo = computed(() => params.coverVideo?.join(',') || '');
const area = ref([
colPickerData.map((item) => {
return {
@@ -123,8 +124,10 @@ const header = {
// 发布朋友圈
const publishMoments = async () => {
if (!params.description) return uni.showToast({ title: '请填写内容', icon: 'error' });
- if (!params.coverPic || !params.coverPic.length)
+ if (activeTab.value === 0 && (!params.coverPic || !params.coverPic.length))
return uni.showToast({ title: '请上传图片', icon: 'error' });
+ if (activeTab.value === 1 && (!params.coverVideo || !params.coverVideo.length))
+ return uni.showToast({ title: '请上传视频', icon: 'error' });
// 获取经纬度位置信息
uni.getLocation({
@@ -134,8 +137,8 @@ const publishMoments = async () => {
const { code, msg } = await RecentApi.createMoment({
...params,
- coverPic: coverPic.value,
- coverVideo: coverVideo.value.join(','),
+ coverPic: activeTab.value === 0 ? coverPic.value : '',
+ coverVideo: activeTab.value === 1 ? coverVideo.value : '',
});
if (code !== 0)
return toast.error({
diff --git a/src/pages/profile/feedback.vue b/src/pages/profile/feedback.vue
index ea6530c5..9a60b290 100644
--- a/src/pages/profile/feedback.vue
+++ b/src/pages/profile/feedback.vue
@@ -15,6 +15,8 @@
图片
diff --git a/src/pages/profile/recharge.vue b/src/pages/profile/recharge.vue
index b657d072..413281ae 100644
--- a/src/pages/profile/recharge.vue
+++ b/src/pages/profile/recharge.vue
@@ -108,6 +108,7 @@ import sheep from '@/sheep';
// @ts-ignore
import PayOrderApi from '@/sheep/api/pay/order';
import { jumpToWechatMiniProgram, wechatNavBack } from '@/sheep/util/wechat-tool';
+import appConfig from '@/sheep/config';
const messageBox = useMessage();
@@ -199,16 +200,24 @@ const handleRecharge = (item: any) => {
msg: `确认使用${payMethodItem.title}${fen2yuanSimple(item.payPrice)}元获取${fen2yuanSimple(item.bonusPrice + item.payPrice)}砖石?`,
})
.then(async () => {
- // #ifdef MP-WEIXIN
- if (payMethod.value === 'wechat') {
- disposeWechatPay(item.id);
+ if (appConfig.buildTarget === 'H5') {
+ if (payMethod.value === 'wechat') {
+ disposeWechatPay(item.id);
+ } else {
+ disposeAlipayPay(item.id);
+ }
} else {
- disposeAlipayPay(item.id);
+ // #ifdef MP-WEIXIN
+ if (payMethod.value === 'wechat') {
+ disposeWechatPay(item.id);
+ } else {
+ disposeAlipayPay(item.id);
+ }
+ // #endif
+ // #ifndef MP-WEIXIN
+ jumpToWechatPage(item.id);
+ // #endif
}
- // #endif
- // #ifndef MP-WEIXIN
- jumpToWechatPage(item.id);
- // #endif
})
.catch(() => { });
};
diff --git a/src/pages/tabbar/components/user-ablum.vue b/src/pages/tabbar/components/user-ablum.vue
index 6f553e8e..01afd899 100644
--- a/src/pages/tabbar/components/user-ablum.vue
+++ b/src/pages/tabbar/components/user-ablum.vue
@@ -1,5 +1,5 @@
-
+
我的相册
{
max-width: 70% !important;
}
}
-
\ No newline at end of file
+
diff --git a/src/pages/tabbar/message.vue b/src/pages/tabbar/message.vue
index 96b1cee9..08dbec55 100644
--- a/src/pages/tabbar/message.vue
+++ b/src/pages/tabbar/message.vue
@@ -19,7 +19,6 @@
-
{{ pageReady ? '消息接收中...' : '正在初始化...' }}
@@ -33,7 +32,6 @@
-
diff --git a/src/pages/tabbar/profile.vue b/src/pages/tabbar/profile.vue
index c0d1a7c9..7f8437b3 100644
--- a/src/pages/tabbar/profile.vue
+++ b/src/pages/tabbar/profile.vue
@@ -12,7 +12,7 @@
-
+
@@ -101,12 +101,15 @@
-
+
+
+
+
+
-
-
+
@@ -173,6 +176,7 @@ import { formatDate } from '@/sheep/helper/utils';
// @ts-ignore
import { fen2yuanSimple } from '@/sheep/hooks/useGoods';
import { useMessage } from '@/uni_modules/wot-design-uni';
+import { saveImageToPhotosAlbum } from "@/sheep/util/file-tool"
const { ablumList } = useAblum();
@@ -253,10 +257,8 @@ onShow(async () => {
sheep.$store('user').updateUserData();
const { data: totalData } = await RecentApi.recentTotal();
recentTotal.value = totalData ?? {};
-
const { data: issueTotalData } = await RecentApi.recentIssueTotal();
recentTotal.value.selfRecentTotal = issueTotalData?.selfRecentTotal || 0;
-
getMemberSetting()
});
@@ -287,16 +289,19 @@ const subOfficial = () => {
confirmButtonText: "保存图片",
})
.then(async () => {
- uni.saveImageToPhotosAlbum({
- filePath: "http://download.htysapp.com/gzh.jpg",
- success: () => {
+ let imagePath = "http://download.htysapp.com/gzh.jpg";
+ // #ifdef H5
+ imagePath = "/static/gzh/gzh.jpg";
+ // #endif
+ saveImageToPhotosAlbum(imagePath,
+ () => {
uni.showToast({ title: '保存成功', icon: 'success' });
},
- fail: (err) => {
+ (err) => {
uni.showToast({ title: '保存失败', icon: 'none' });
- console.error('|保存海报|,意外的错误:', err);
- },
- });
+ console.error('|保存图片|,意外的错误:', err);
+ }
+ )
})
};
@@ -312,7 +317,7 @@ const MenuCellList = ref([
// { title: '我的收益', value: '', icon: 'wallet', to: '/pages/wechat-tabbar/index' },
{ title: '访客记录', value: '', icon: 'browse', to: '/pages/profile/view-record' },
// { title: '认证中心', value: '', icon: 'discount-filled', to: '/pages/profile/verify-status' },
- { title: '联系方式', value: '', icon: 'user', to: '/pages/profile/set-wechat' },
+ { title: '联系方式', value: '', icon: 'chat', to: '/pages/profile/set-wechat' },
// { title: '我的动态', value: '', icon: 'star', to: '/pages/profile/my-moment' },
{ title: '我的评价', value: '', icon: 'view-module', to: '', onClick: lookMyEvaluation },
{ title: '问题反馈', value: '', icon: 'backtop-rectangle', to: '', onClick: goFeedback },
@@ -339,4 +344,4 @@ const onTapMenu = (item: any) => {
}
-
\ No newline at end of file
+
diff --git a/src/pages/wechat-tabbar/index.vue b/src/pages/wechat-tabbar/index.vue
index 89042edb..1b106a5e 100644
--- a/src/pages/wechat-tabbar/index.vue
+++ b/src/pages/wechat-tabbar/index.vue
@@ -11,7 +11,6 @@
-
@@ -120,6 +119,7 @@ import TradeConfigApi from '@/sheep/api/trade/config.js';
import { useMessage } from '@/uni_modules/wot-design-uni';
import useBindWechat from "@/sheep/hooks/use-bind-wechat"
import { jumpToWechatMiniProgram } from '@/sheep/util/wechat-tool';
+import { saveImageToPhotosAlbum } from "@/sheep/util/file-tool"
const message = useMessage();
const jumpWechatMessage = useMessage('jump-wechat');
@@ -290,16 +290,15 @@ const savePoster = () => {
uni.showToast({ title: '海报不存在', icon: 'none' });
return;
}
- uni.saveImageToPhotosAlbum({
- filePath: state.posterPic,
- success: () => {
+ saveImageToPhotosAlbum(state.posterPic,
+ () => {
uni.showToast({ title: '保存成功', icon: 'success' });
},
- fail: (err) => {
+ (err) => {
uni.showToast({ title: '保存失败', icon: 'none' });
console.error('|保存海报|,意外的错误:', err);
- },
- });
+ }
+ )
};
const doLogin = () => {
diff --git a/src/pages/wechat/pages/poster.vue b/src/pages/wechat/pages/poster.vue
index 1c427e9a..fa8fd54f 100644
--- a/src/pages/wechat/pages/poster.vue
+++ b/src/pages/wechat/pages/poster.vue
@@ -7,22 +7,24 @@
-
-
-
-
- 复制链接
-
-
-
- 保存海报
+
+
+
+
+
+ 复制链接
+
+
+
+ 保存海报
+
-
+
@@ -32,6 +34,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import BrokerageApi from '@/sheep/api/trade/brokerage';
+import { saveImageToPhotosAlbum } from "@/sheep/util/file-tool"
const state = reactive({
posterPic: ''
@@ -80,16 +83,15 @@ const savePoster = () => {
uni.showToast({ title: '海报不存在', icon: 'none' });
return;
}
- uni.saveImageToPhotosAlbum({
- filePath: state.posterPic,
- success: () => {
+ saveImageToPhotosAlbum(state.posterPic,
+ () => {
uni.showToast({ title: '保存成功', icon: 'success' });
},
- fail: (err) => {
+ (err) => {
uni.showToast({ title: '保存失败', icon: 'none' });
console.error('|保存海报|,意外的错误:', err);
- },
- });
+ }
+ )
};
\ No newline at end of file
diff --git a/src/sheep/components/s-share-modal/canvas-poster/index.vue b/src/sheep/components/s-share-modal/canvas-poster/index.vue
index 9e67943b..aa4e4581 100644
--- a/src/sheep/components/s-share-modal/canvas-poster/index.vue
+++ b/src/sheep/components/s-share-modal/canvas-poster/index.vue
@@ -2,21 +2,12 @@
diff --git a/src/sheep/components/s-uploader/choose-and-upload-file.js b/src/sheep/components/s-uploader/choose-and-upload-file.js
index 878ca11d..bc17d02c 100644
--- a/src/sheep/components/s-uploader/choose-and-upload-file.js
+++ b/src/sheep/components/s-uploader/choose-and-upload-file.js
@@ -1,7 +1,6 @@
'use strict';
import FileApi from '@/sheep/api/infra/file';
-const ERR_MSG_OK = 'chooseAndUploadFile:ok';
const ERR_MSG_FAIL = 'chooseAndUploadFile:fail';
function chooseImage(opts) {
@@ -30,8 +29,55 @@ function chooseImage(opts) {
}
function chooseVideo(opts) {
- const { camera, compressed, maxDuration, sourceType = ['album', 'camera'], extension } = opts;
+ const {
+ count,
+ camera,
+ compressed,
+ maxDuration,
+ sourceType = ['album', 'camera'],
+ extension,
+ } = opts;
return new Promise((resolve, reject) => {
+ // 微信小程序的 chooseMedia 会直接返回视频缩略图。
+ // #ifdef MP-WEIXIN
+ uni.chooseMedia({
+ count,
+ mediaType: ['video'],
+ sourceType,
+ sizeType: compressed ? ['compressed'] : ['original'],
+ maxDuration,
+ camera,
+ success(res) {
+ resolve(
+ normalizeChooseAndUploadFileRes(
+ {
+ errMsg: 'chooseVideo:ok',
+ tempFiles: res.tempFiles.map((item) => ({
+ name: item.name || '',
+ path: item.tempFilePath,
+ thumbTempFilePath: item.thumbTempFilePath || '',
+ size: item.size,
+ type: item.type || '',
+ width: item.width,
+ height: item.height,
+ duration: item.duration,
+ fileType: 'video',
+ cloudPath: '',
+ })),
+ },
+ 'video',
+ ),
+ );
+ },
+ fail(res) {
+ reject({
+ errMsg: res.errMsg.replace('chooseMedia:fail', ERR_MSG_FAIL),
+ });
+ },
+ });
+ // #endif
+
+ // #ifndef MP-WEIXIN
uni.chooseVideo({
camera,
compressed,
@@ -39,7 +85,7 @@ function chooseVideo(opts) {
sourceType,
extension,
success(res) {
- const { tempFilePath, duration, size, height, width } = res;
+ const { tempFilePath, thumbTempFilePath, duration, size, height, width } = res;
resolve(
normalizeChooseAndUploadFileRes(
{
@@ -49,6 +95,7 @@ function chooseVideo(opts) {
{
name: (res.tempFile && res.tempFile.name) || '',
path: tempFilePath,
+ thumbTempFilePath: thumbTempFilePath || '',
size,
type: (res.tempFile && res.tempFile.type) || '',
width,
@@ -69,6 +116,7 @@ function chooseVideo(opts) {
});
},
});
+ // #endif
});
}
diff --git a/src/sheep/components/s-uploader/s-uploader.vue b/src/sheep/components/s-uploader/s-uploader.vue
index d86aaf31..39dd18fd 100644
--- a/src/sheep/components/s-uploader/s-uploader.vue
+++ b/src/sheep/components/s-uploader/s-uploader.vue
@@ -8,671 +8,656 @@
{{ subtitle }}
-
+
-
+
diff --git a/src/sheep/components/s-uploader/upload-file.vue b/src/sheep/components/s-uploader/upload-file.vue
index 233d281f..abe56e9b 100644
--- a/src/sheep/components/s-uploader/upload-file.vue
+++ b/src/sheep/components/s-uploader/upload-file.vue
@@ -7,15 +7,9 @@
-
+
+
+
+
+
+
+
+
+
@@ -26,12 +41,23 @@
+
+
+