diff --git a/package-lock.json b/package-lock.json index 748fcbd..51155e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@vant/area-data": "^2.1.0", "@zxing/library": "^0.21.3", "html-to-image": "^1.11.13", + "html2canvas": "^1.4.1", "image-conversion": "^2.1.1", "pinia": "^3.0.4", "postcss-px-to-viewport-8-plugin": "^1.2.5", @@ -665,6 +666,15 @@ "node": ">=0.4.0" } }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/birpc": { "version": "2.9.0", "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.9.0.tgz", @@ -711,6 +721,15 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", @@ -829,6 +848,19 @@ "integrity": "sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==", "license": "MIT" }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -1643,6 +1675,15 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.16.tgz", @@ -1825,6 +1866,15 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/vant": { "version": "4.9.24", "resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.24.tgz", diff --git a/package.json b/package.json index b397e3f..1e505ff 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@vant/area-data": "^2.1.0", "@zxing/library": "^0.21.3", "html-to-image": "^1.11.13", + "html2canvas": "^1.4.1", "image-conversion": "^2.1.1", "pinia": "^3.0.4", "postcss-px-to-viewport-8-plugin": "^1.2.5", diff --git a/public/img/PointMall_Active.png b/public/img/PointMall_Active.png new file mode 100644 index 0000000..328d83c Binary files /dev/null and b/public/img/PointMall_Active.png differ diff --git a/public/img/PointMall_Inactive.png b/public/img/PointMall_Inactive.png new file mode 100644 index 0000000..7bd1000 Binary files /dev/null and b/public/img/PointMall_Inactive.png differ diff --git a/public/img/address.png b/public/img/address.png new file mode 100644 index 0000000..99a35aa Binary files /dev/null and b/public/img/address.png differ diff --git a/src/App.vue b/src/App.vue index 87ed26e..04934c3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,3 +1,19 @@ \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/src/components/BaseList.vue b/src/components/BaseList.vue index 37c1473..dac65c7 100644 --- a/src/components/BaseList.vue +++ b/src/components/BaseList.vue @@ -25,6 +25,7 @@ export default { pageSize: { type: Number, default: 10 }, finishedText: { type: String, default: '没有更多了' }, parseData: { type: Function, default: (res) => res.data.items }, + cacheKey: { type: String, default: '' }, }, data() { return { @@ -34,6 +35,8 @@ export default { page: 1, requestId: 0, observer: null, + _cacheKey: null, + _dataCache: null, } }, emits: ['update:list', 'load', 'refresh'], @@ -50,6 +53,19 @@ export default { deep: true } }, + created() { + if (this.cacheKey) { + const cached = sessionStorage.getItem(this.cacheKey) + if (cached) { + try { + const { list, page, finished, params } = JSON.parse(cached) + if (JSON.stringify(this.params) === JSON.stringify(params)) { + this._dataCache = { list, page, finished } + } + } catch (e) { } + } + } + }, mounted() { this.$nextTick(() => { this.observer = new IntersectionObserver((entries) => { @@ -66,6 +82,14 @@ export default { beforeUnmount() { this.observer?.disconnect() window.removeEventListener('scroll', this.onWindowScroll) + if (this.cacheKey && this.list.length > 0) { + sessionStorage.setItem(this.cacheKey, JSON.stringify({ + list: this.list, + page: this.page, + finished: this.finished, + params: this.params + })) + } }, methods: { onWindowScroll() { @@ -79,6 +103,13 @@ export default { }, loadMore() { if (this.loading) return + if (this._dataCache && this._dataCache.params && JSON.stringify(this.params) === JSON.stringify(this._dataCache.params)) { + this.list = this._dataCache.list + this.page = this._dataCache.page + this.finished = this._dataCache.finished + this.loading = false + return + } const currentRequestId = this.requestId this.loading = true const request = this.method === 'get' ? this.$get : this.$post @@ -123,6 +154,8 @@ export default {