mirror of
https://gitee.com/ShopeX/ECShopX_desktop-frontend
synced 2026-05-15 02:45:39 +08:00
chore(release): 4.1.0
This commit is contained in:
8
.env
8
.env
@@ -1,5 +1,5 @@
|
||||
VUE_APP_TITLE=Ecshopx pc
|
||||
VUE_APP_HOST=https://demo-ecshopx.ishopex.cn
|
||||
VUE_APP_API_BASE_URL=https://demo-ecshopx.ishopex.cn
|
||||
VUE_APP_COMPANYID=5
|
||||
VUE_APP_TITLE=
|
||||
VUE_APP_HOST=
|
||||
VUE_APP_API_BASE_URL=
|
||||
VUE_APP_COMPANYID=
|
||||
VUE_APP_DEFAULT_LANG=en
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
openspec
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
|
||||
243
CHANGELOG.md
243
CHANGELOG.md
@@ -2,4 +2,247 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [4.1.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v4.1.0...v4.1.1) (2025-12-10)
|
||||
|
||||
## [4.0.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.21.0...v4.0.0) (2025-11-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 去除一些非必要文档 ([9ae272f](https://git.ishopex.cn/onex/ecshopx-newpc/commit/9ae272fd384479cfc020f4120cd68bb5e1784aaa))
|
||||
* **scope:** update package ([d733a9c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/d733a9c64a652b38483f3db16a483296806f3669))
|
||||
* **scope:** update readme ([958707f](https://git.ishopex.cn/onex/ecshopx-newpc/commit/958707f09f91aa2b6716012aa0d0791cd90b1f28))
|
||||
|
||||
## [3.21.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.20.0...v3.21.0) (2025-05-29)
|
||||
|
||||
## [3.20.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.4...v3.20.0) (2025-04-27)
|
||||
|
||||
### [3.19.4](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.3...v3.19.4) (2025-04-23)
|
||||
|
||||
### [3.19.3](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.2...v3.19.3) (2025-04-23)
|
||||
|
||||
### [3.19.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.1...v3.19.2) (2025-04-16)
|
||||
|
||||
### [3.19.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.1...v3.19.2) (2025-04-16)
|
||||
|
||||
### [3.19.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.1...v3.19.2) (2025-04-16)
|
||||
|
||||
### [3.19.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.3...v3.19.2) (2025-04-16)
|
||||
|
||||
### [3.19.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.3...v3.19.2) (2025-04-16)
|
||||
|
||||
### [3.19.3](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.2...v3.19.3) (2025-04-16)
|
||||
|
||||
### [3.19.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.1...v3.19.2) (2025-04-09)
|
||||
|
||||
### [3.19.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.19.0...v3.19.1) (2025-04-09)
|
||||
|
||||
## [3.19.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.18.0...v3.19.0) (2025-03-27)
|
||||
|
||||
## [3.18.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.17.0...v3.18.0) (2025-03-18)
|
||||
|
||||
## [3.17.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.16.0...v3.17.0) (2025-02-14)
|
||||
|
||||
## [3.16.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.15.3...v3.16.0) (2024-10-28)
|
||||
|
||||
### [3.15.3](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.15.2...v3.15.3) (2024-08-28)
|
||||
|
||||
### [3.15.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.15.1...v3.15.2) (2024-08-16)
|
||||
|
||||
### [3.15.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.15.0...v3.15.1) (2024-07-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 添加储值支付 ([c74f28c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/c74f28cd9b5ec1bffed7ed225e737d258ef8440a))
|
||||
|
||||
## [3.15.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.14.1...v3.15.0) (2024-07-08)
|
||||
|
||||
### [3.14.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.14.0...v3.14.1) (2024-04-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 登录页logo、背景图,支持后台配置 ([4ff9b07](https://git.ishopex.cn/onex/ecshopx-newpc/commit/4ff9b07cea9c71e9cbaa29466a250d47d1dbbac5))
|
||||
|
||||
## [3.14.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.13.5...v3.14.0) (2024-03-11)
|
||||
|
||||
### [3.13.5](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.13.4...v3.13.5) (2024-03-10)
|
||||
|
||||
### [3.13.4](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.13.3...v3.13.4) (2023-09-27)
|
||||
|
||||
### [3.13.3](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.13.2...v3.13.3) (2023-09-26)
|
||||
|
||||
### [3.13.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.13.1...v3.13.2) (2023-09-26)
|
||||
|
||||
### [3.13.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.13.0...v3.13.1) (2023-06-05)
|
||||
|
||||
## [3.13.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.12.1...v3.13.0) (2023-06-01)
|
||||
|
||||
### [3.12.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.12.0...v3.12.1) (2023-05-24)
|
||||
|
||||
## 3.12.0 (2023-05-18)
|
||||
|
||||
## [3.11.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.10.1...v3.11.0) (2023-04-24)
|
||||
|
||||
### [3.10.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.10.0...v3.10.1) (2023-03-14)
|
||||
|
||||
## [3.10.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.9.0...v3.10.0) (2023-02-09)
|
||||
|
||||
## [3.9.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.8.0...v3.9.0) (2023-01-05)
|
||||
|
||||
## [3.8.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.7.0...v3.8.0) (2022-12-15)
|
||||
|
||||
## [3.7.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.6.1...v3.7.0) (2022-11-24)
|
||||
|
||||
## [3.6.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.4.0...v3.6.0) (2022-10-31)
|
||||
|
||||
## [3.5.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.4.0...v3.5.0) (2022-09-29)
|
||||
|
||||
## [3.4.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.3.0...v3.4.0) (2022-09-16)
|
||||
|
||||
## [3.3.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.2.1...v3.3.0) (2022-08-31)
|
||||
|
||||
### [3.2.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.2.0...v3.2.1) (2022-08-25)
|
||||
|
||||
## [3.2.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.1.0...v3.2.0) (2022-08-04)
|
||||
|
||||
## [3.1.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v3.0.0...v3.1.0) (2022-07-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 3.1.0 ([ef0bff5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/ef0bff5862e674cba3e42f7f02d4ebb24efdee4b))
|
||||
|
||||
## [2.10.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v2.9.0...v2.10.0) (2022-06-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 2.10.0 ([0099412](https://git.ishopex.cn/onex/ecshopx-newpc/commit/0099412d996328a8d91e654adfeb0e0cfcdac553))
|
||||
|
||||
## [2.9.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v2.8.0...v2.9.0) (2022-06-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 2.9.0 ([484948c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/484948ca8650d0858909e67fb408d9fcf4cf43c9))
|
||||
|
||||
## [2.8.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v2.7.0...v2.8.0) (2022-05-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 2.8.0 ([9671a24](https://git.ishopex.cn/onex/ecshopx-newpc/commit/9671a24740c3692c534b644da377a96d6c9a693f))
|
||||
|
||||
## [2.7.0](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v2.6.3...v2.7.0) (2022-05-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 2.7.0 ([db36624](https://git.ishopex.cn/onex/ecshopx-newpc/commit/db36624112ce32d8d73183b565d239b3bd390c9c))
|
||||
|
||||
### [2.6.3](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v2.6.2...v2.6.3) (2022-05-09)
|
||||
|
||||
### [2.6.2](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v2.6.1...v2.6.2) (2022-05-09)
|
||||
|
||||
### [1.1.1](https://git.ishopex.cn/onex/ecshopx-newpc/compare/v1.1.0...v1.1.1) (2021-05-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add changelog ([f71d9a0](https://git.ishopex.cn/onex/ecshopx-newpc/commit/f71d9a0230785d59ca9326538756df310197df3e))
|
||||
|
||||
## 1.1.0 (2021-05-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* 添加会员价 ([f2ee434](https://git.ishopex.cn/onex/ecshopx-newpc/commit/f2ee434f50739c4d75d123c7b8a631a6a0ee45ac))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* bug修复 ([4ae80aa](https://git.ishopex.cn/onex/ecshopx-newpc/commit/4ae80aa99726076aeac0b9a91952b4bb43ca8bc3))
|
||||
* merge ([38754a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/38754a51326cb1fb5b5dfa5ac5e99a921a39e6df))
|
||||
* merge ([c1c7075](https://git.ishopex.cn/onex/ecshopx-newpc/commit/c1c70751953cdc5e33a732f43492516a2727f311))
|
||||
* package.json ([389b447](https://git.ishopex.cn/onex/ecshopx-newpc/commit/389b4476bf467ec2b0b5986d0550c9cf4fcff227))
|
||||
* por ([2e14978](https://git.ishopex.cn/onex/ecshopx-newpc/commit/2e14978d6ee02938d8491590ad7e892be1ffb006))
|
||||
* port ([81137a0](https://git.ishopex.cn/onex/ecshopx-newpc/commit/81137a08cde3ba5aa7b932681be9ac66d9fafb1f))
|
||||
* release version ([137e48a](https://git.ishopex.cn/onex/ecshopx-newpc/commit/137e48aa5dfb240d42ee14216f41f8b7931214ed))
|
||||
* saas 独立域名 ([6aaefd2](https://git.ishopex.cn/onex/ecshopx-newpc/commit/6aaefd2cde30abfaac84f58533163a4b72e6829e))
|
||||
* saas取消companyid ([9caac88](https://git.ishopex.cn/onex/ecshopx-newpc/commit/9caac881e7b73bbc98cb7a6ff3c883ae79e435cb))
|
||||
* store commit ([fb04ec8](https://git.ishopex.cn/onex/ecshopx-newpc/commit/fb04ec82b18af6baac363d1dfbfb6566c656b464))
|
||||
* 优化 ([572b09c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/572b09cb69a4f860c86d247f88298271a1ef70cf))
|
||||
* 会员价 ([c04ac5e](https://git.ishopex.cn/onex/ecshopx-newpc/commit/c04ac5e6546cdfd7d54dbd1aaa9b8c322af4efa2))
|
||||
* 修改bug ([27be6e3](https://git.ishopex.cn/onex/ecshopx-newpc/commit/27be6e323fe46f6945dee0c9300f3227e8220165))
|
||||
* 修改saas env变量 ([21367a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/21367a59f9532ee7c20b13e458433b57038d98a9))
|
||||
* 修改UI ([628b85e](https://git.ishopex.cn/onex/ecshopx-newpc/commit/628b85ea4ac6e7c45119ddd835629b320e4e54ee))
|
||||
* 修改购物车 ([bd158de](https://git.ishopex.cn/onex/ecshopx-newpc/commit/bd158de24e968a21e5d9ca4e8457636c996c023b))
|
||||
* 注册优化 ([785a8ba](https://git.ishopex.cn/onex/ecshopx-newpc/commit/785a8ba837dfbec1524f10d1b5049d49c3949f65))
|
||||
* 购物车优惠券选择 ([fdd4261](https://git.ishopex.cn/onex/ecshopx-newpc/commit/fdd42611d6299e367840cf99a4b481ea91cff8b9))
|
||||
|
||||
### 1.0.2 (2021-05-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* bug修复 ([4ae80aa](https://git.ishopex.cn/onex/ecshopx-newpc/commit/4ae80aa99726076aeac0b9a91952b4bb43ca8bc3))
|
||||
* merge ([38754a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/38754a51326cb1fb5b5dfa5ac5e99a921a39e6df))
|
||||
* merge ([c1c7075](https://git.ishopex.cn/onex/ecshopx-newpc/commit/c1c70751953cdc5e33a732f43492516a2727f311))
|
||||
* package.json ([389b447](https://git.ishopex.cn/onex/ecshopx-newpc/commit/389b4476bf467ec2b0b5986d0550c9cf4fcff227))
|
||||
* por ([2e14978](https://git.ishopex.cn/onex/ecshopx-newpc/commit/2e14978d6ee02938d8491590ad7e892be1ffb006))
|
||||
* port ([81137a0](https://git.ishopex.cn/onex/ecshopx-newpc/commit/81137a08cde3ba5aa7b932681be9ac66d9fafb1f))
|
||||
* release version ([137e48a](https://git.ishopex.cn/onex/ecshopx-newpc/commit/137e48aa5dfb240d42ee14216f41f8b7931214ed))
|
||||
* saas 独立域名 ([6aaefd2](https://git.ishopex.cn/onex/ecshopx-newpc/commit/6aaefd2cde30abfaac84f58533163a4b72e6829e))
|
||||
* saas取消companyid ([9caac88](https://git.ishopex.cn/onex/ecshopx-newpc/commit/9caac881e7b73bbc98cb7a6ff3c883ae79e435cb))
|
||||
* store commit ([fb04ec8](https://git.ishopex.cn/onex/ecshopx-newpc/commit/fb04ec82b18af6baac363d1dfbfb6566c656b464))
|
||||
* 优化 ([572b09c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/572b09cb69a4f860c86d247f88298271a1ef70cf))
|
||||
* 修改bug ([27be6e3](https://git.ishopex.cn/onex/ecshopx-newpc/commit/27be6e323fe46f6945dee0c9300f3227e8220165))
|
||||
* 修改saas env变量 ([21367a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/21367a59f9532ee7c20b13e458433b57038d98a9))
|
||||
* 修改UI ([628b85e](https://git.ishopex.cn/onex/ecshopx-newpc/commit/628b85ea4ac6e7c45119ddd835629b320e4e54ee))
|
||||
* 修改购物车 ([bd158de](https://git.ishopex.cn/onex/ecshopx-newpc/commit/bd158de24e968a21e5d9ca4e8457636c996c023b))
|
||||
* 注册优化 ([785a8ba](https://git.ishopex.cn/onex/ecshopx-newpc/commit/785a8ba837dfbec1524f10d1b5049d49c3949f65))
|
||||
|
||||
### 1.0.1 (2021-05-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* bug修复 ([4ae80aa](https://git.ishopex.cn/onex/ecshopx-newpc/commit/4ae80aa99726076aeac0b9a91952b4bb43ca8bc3))
|
||||
* merge ([38754a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/38754a51326cb1fb5b5dfa5ac5e99a921a39e6df))
|
||||
* merge ([c1c7075](https://git.ishopex.cn/onex/ecshopx-newpc/commit/c1c70751953cdc5e33a732f43492516a2727f311))
|
||||
* package.json ([389b447](https://git.ishopex.cn/onex/ecshopx-newpc/commit/389b4476bf467ec2b0b5986d0550c9cf4fcff227))
|
||||
* por ([2e14978](https://git.ishopex.cn/onex/ecshopx-newpc/commit/2e14978d6ee02938d8491590ad7e892be1ffb006))
|
||||
* port ([81137a0](https://git.ishopex.cn/onex/ecshopx-newpc/commit/81137a08cde3ba5aa7b932681be9ac66d9fafb1f))
|
||||
* release version ([137e48a](https://git.ishopex.cn/onex/ecshopx-newpc/commit/137e48aa5dfb240d42ee14216f41f8b7931214ed))
|
||||
* saas 独立域名 ([6aaefd2](https://git.ishopex.cn/onex/ecshopx-newpc/commit/6aaefd2cde30abfaac84f58533163a4b72e6829e))
|
||||
* saas取消companyid ([9caac88](https://git.ishopex.cn/onex/ecshopx-newpc/commit/9caac881e7b73bbc98cb7a6ff3c883ae79e435cb))
|
||||
* store commit ([fb04ec8](https://git.ishopex.cn/onex/ecshopx-newpc/commit/fb04ec82b18af6baac363d1dfbfb6566c656b464))
|
||||
* 优化 ([572b09c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/572b09cb69a4f860c86d247f88298271a1ef70cf))
|
||||
* 修改bug ([27be6e3](https://git.ishopex.cn/onex/ecshopx-newpc/commit/27be6e323fe46f6945dee0c9300f3227e8220165))
|
||||
* 修改saas env变量 ([21367a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/21367a59f9532ee7c20b13e458433b57038d98a9))
|
||||
* 修改UI ([628b85e](https://git.ishopex.cn/onex/ecshopx-newpc/commit/628b85ea4ac6e7c45119ddd835629b320e4e54ee))
|
||||
* 修改购物车 ([bd158de](https://git.ishopex.cn/onex/ecshopx-newpc/commit/bd158de24e968a21e5d9ca4e8457636c996c023b))
|
||||
* 注册优化 ([785a8ba](https://git.ishopex.cn/onex/ecshopx-newpc/commit/785a8ba837dfbec1524f10d1b5049d49c3949f65))
|
||||
|
||||
### 0.1.1 (2021-05-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* bug修复 ([4ae80aa](https://git.ishopex.cn/onex/ecshopx-newpc/commit/4ae80aa99726076aeac0b9a91952b4bb43ca8bc3))
|
||||
* merge ([38754a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/38754a51326cb1fb5b5dfa5ac5e99a921a39e6df))
|
||||
* merge ([c1c7075](https://git.ishopex.cn/onex/ecshopx-newpc/commit/c1c70751953cdc5e33a732f43492516a2727f311))
|
||||
* package.json ([389b447](https://git.ishopex.cn/onex/ecshopx-newpc/commit/389b4476bf467ec2b0b5986d0550c9cf4fcff227))
|
||||
* por ([2e14978](https://git.ishopex.cn/onex/ecshopx-newpc/commit/2e14978d6ee02938d8491590ad7e892be1ffb006))
|
||||
* port ([81137a0](https://git.ishopex.cn/onex/ecshopx-newpc/commit/81137a08cde3ba5aa7b932681be9ac66d9fafb1f))
|
||||
* saas 独立域名 ([6aaefd2](https://git.ishopex.cn/onex/ecshopx-newpc/commit/6aaefd2cde30abfaac84f58533163a4b72e6829e))
|
||||
* saas取消companyid ([9caac88](https://git.ishopex.cn/onex/ecshopx-newpc/commit/9caac881e7b73bbc98cb7a6ff3c883ae79e435cb))
|
||||
* store commit ([fb04ec8](https://git.ishopex.cn/onex/ecshopx-newpc/commit/fb04ec82b18af6baac363d1dfbfb6566c656b464))
|
||||
* 优化 ([572b09c](https://git.ishopex.cn/onex/ecshopx-newpc/commit/572b09cb69a4f860c86d247f88298271a1ef70cf))
|
||||
* 修改bug ([27be6e3](https://git.ishopex.cn/onex/ecshopx-newpc/commit/27be6e323fe46f6945dee0c9300f3227e8220165))
|
||||
* 修改saas env变量 ([21367a5](https://git.ishopex.cn/onex/ecshopx-newpc/commit/21367a59f9532ee7c20b13e458433b57038d98a9))
|
||||
* 修改UI ([628b85e](https://git.ishopex.cn/onex/ecshopx-newpc/commit/628b85ea4ac6e7c45119ddd835629b320e4e54ee))
|
||||
* 修改购物车 ([bd158de](https://git.ishopex.cn/onex/ecshopx-newpc/commit/bd158de24e968a21e5d9ca4e8457636c996c023b))
|
||||
* 注册优化 ([785a8ba](https://git.ishopex.cn/onex/ecshopx-newpc/commit/785a8ba837dfbec1524f10d1b5049d49c3949f65))
|
||||
|
||||
16
README.md
16
README.md
@@ -1,4 +1,4 @@
|
||||
<p align="center"><img width="500" height="auto" alt="logo1" src="https://github.com/user-attachments/assets/097cbde6-cedd-42d0-a2d8-a0a0430289b5" /></p>
|
||||
<p align="center"><img width="600" height="416" alt="logo2" src="https://github.com/user-attachments/assets/abf6c4c7-8cb1-477e-aea4-9e526cd8225a" /></p>
|
||||
|
||||
### <p align="center">Desktop Frontend</p>
|
||||
|
||||
@@ -7,7 +7,7 @@ Node.js (current LTS) and npm are required to run the project. To be sure about
|
||||
|
||||
### Installation
|
||||
```
|
||||
cd ecshopx-pc
|
||||
cd ECShopX_desktop-frontend
|
||||
npm i
|
||||
```
|
||||
|
||||
@@ -21,6 +21,9 @@ VUE_APP_HOST=
|
||||
|
||||
# Backend API Base URL
|
||||
VUE_APP_API_BASE_URL=
|
||||
|
||||
# Default Language Version(Chinese:zhcn/English:en)
|
||||
VUE_APP_DEFAULT_LANG=en
|
||||
```
|
||||
|
||||
### Run project
|
||||
@@ -32,3 +35,12 @@ npm run dev
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
## License
|
||||
Each ECShopX source file included in this distribution is licensed under the Apache License 2.0, together with the additional terms imposed by ShopeX.
|
||||
|
||||
Open Software License (Apache 2.0) – Please see LICENSE.txt for the full text of the Apache 2.0 license.
|
||||
|
||||
每个包含在本发行版中的 ECShopX 源文件,均依据 Apache 2.0 开源许可证与ShopeX商派附加条款进行授权。
|
||||
|
||||
开源软件许可协议(Apache 2.0) —— 请参阅 LICENSE.txt 文件以获取 Apache 2.0 协议的完整文本。
|
||||
|
||||
73
package-lock.json
generated
73
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ecshopx-pc",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ecshopx-pc",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.1",
|
||||
"dependencies": {
|
||||
"@nuxtjs/component-cache": "^1.1.5",
|
||||
"@nuxtjs/device": "^1.2.4",
|
||||
@@ -61,7 +61,7 @@
|
||||
"qn-webpack": "^2.0.3",
|
||||
"sass": "1.77.6",
|
||||
"sass-loader": "10.5.2",
|
||||
"standard-version": "^9.3.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"webpack-merge": "^4.2.1"
|
||||
}
|
||||
},
|
||||
@@ -10331,13 +10331,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmmirror.com/buffer/-/buffer-4.9.2.tgz",
|
||||
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://packages.aliyun.com/664eb139ced1b9e566e182d4/npm/businesstech-apac/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4",
|
||||
"isarray": "^1.0.0"
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
@@ -20028,6 +20044,17 @@
|
||||
"vm-browserify": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/node-libs-browser/node_modules/buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://packages.aliyun.com/664eb139ced1b9e566e182d4/npm/businesstech-apac/buffer/-/buffer-4.9.2.tgz",
|
||||
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4",
|
||||
"isarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-libs-browser/node_modules/punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz",
|
||||
@@ -25407,9 +25434,10 @@
|
||||
},
|
||||
"node_modules/standard-version": {
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/standard-version/-/standard-version-9.5.0.tgz",
|
||||
"resolved": "https://packages.aliyun.com/664eb139ced1b9e566e182d4/npm/businesstech-apac/standard-version/-/standard-version-9.5.0.tgz",
|
||||
"integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"chalk": "^2.4.2",
|
||||
"conventional-changelog": "3.1.25",
|
||||
@@ -36440,13 +36468,14 @@
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmmirror.com/buffer/-/buffer-4.9.2.tgz",
|
||||
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://packages.aliyun.com/664eb139ced1b9e566e182d4/npm/businesstech-apac/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4",
|
||||
"isarray": "^1.0.0"
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
@@ -43862,6 +43891,16 @@
|
||||
"vm-browserify": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://packages.aliyun.com/664eb139ced1b9e566e182d4/npm/businesstech-apac/buffer/-/buffer-4.9.2.tgz",
|
||||
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4",
|
||||
"isarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz",
|
||||
@@ -48029,7 +48068,7 @@
|
||||
},
|
||||
"standard-version": {
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/standard-version/-/standard-version-9.5.0.tgz",
|
||||
"resolved": "https://packages.aliyun.com/664eb139ced1b9e566e182d4/npm/businesstech-apac/standard-version/-/standard-version-9.5.0.tgz",
|
||||
"integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
||||
16
package.json
16
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ecshopx-pc",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.1",
|
||||
"private": true,
|
||||
"repository": "https://git.ishopex.cn/onex/ecshopx-newpc.git",
|
||||
"scripts": {
|
||||
@@ -19,10 +19,8 @@
|
||||
"upload": "node build/upload.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"nuxt": "^2.15.8",
|
||||
"nuxt-i18n": "^6.28.1",
|
||||
"@nuxtjs/device": "^1.2.4",
|
||||
"@nuxtjs/component-cache": "^1.1.5",
|
||||
"@nuxtjs/device": "^1.2.4",
|
||||
"@nuxtjs/proxy": "^1.3.3",
|
||||
"axios": "^0.26.0",
|
||||
"cache-manager": "^2.10.0",
|
||||
@@ -32,6 +30,8 @@
|
||||
"lodash-es": "^4.17.11",
|
||||
"md5": "^2.2.1",
|
||||
"moment": "^2.24.0",
|
||||
"nuxt": "^2.15.8",
|
||||
"nuxt-i18n": "^6.28.1",
|
||||
"qrcode": "^1.4.4",
|
||||
"social-share.js": "^1.0.16",
|
||||
"ssr-window": "^1.0.1",
|
||||
@@ -45,8 +45,8 @@
|
||||
"vue-hotzone": "^1.1.0",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-lazyload": "^1.2.6",
|
||||
"vuex-persistedstate": "3.0.0",
|
||||
"vue-template-compiler": "^2.7.10"
|
||||
"vue-template-compiler": "^2.7.10",
|
||||
"vuex-persistedstate": "3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/babel-preset-app": "^3.7.0",
|
||||
@@ -66,13 +66,13 @@
|
||||
"glob": "^7.1.4",
|
||||
"husky": "^4.3.0",
|
||||
"lint-staged": "^10.5.4",
|
||||
"postcss-html": "^1.5.0",
|
||||
"prettier-eslint-cli": "^5.0.0",
|
||||
"process-argv-parser": "0.0.1",
|
||||
"qn-webpack": "^2.0.3",
|
||||
"sass": "1.77.6",
|
||||
"sass-loader": "10.5.2",
|
||||
"postcss-html": "^1.5.0",
|
||||
"standard-version": "^9.3.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"webpack-merge": "^4.2.1"
|
||||
},
|
||||
"postcss": {
|
||||
|
||||
@@ -8,3 +8,7 @@ import req from './req'
|
||||
export function getGlobalTdk(params) {
|
||||
return req.get('/api/h5app/wxapp/pagestemplate/gettdk', params)
|
||||
}
|
||||
|
||||
export function getPrivacySetting(params = {}) {
|
||||
return req.get('/api/h5app/wxapp/company/privacy_setting_ck', params)
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ const setCountryCode = (config) => {
|
||||
// 根据语言设置 country_code
|
||||
if (locale === 'en') {
|
||||
country_code = 'en-CN'
|
||||
} else if (locale === 'ar') {
|
||||
country_code = 'ar-SA'
|
||||
} else {
|
||||
country_code = 'zh-CN'
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.3 KiB |
1752
src/assets/lang/ar.json
Normal file
1752
src/assets/lang/ar.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1748,5 +1748,8 @@
|
||||
"W0010.index.258451-1": "A total of {0} products, total",
|
||||
"W0010.index.258451-2": "enter the shopping cart",
|
||||
"W0010.index.258451-3": "shopping cart",
|
||||
"W0008.index.695137-0": "search"
|
||||
"W0008.index.695137-0": "search",
|
||||
"cookieConsent.description": "We Use Cookies\nIn addition to the cookies that are strictly necessary for the operation of this website, we use cookies and other tracking tools to remember your preference, to measure our website performance, to improve our understanding of your interests, and to send you cart notifications. Our partners use trackers to deliver personalised advertising based on your browsing habits and your profile, including by using profiling, or to allow you to share our content on your social networks.\n\nYou can click on \"Accept all cookies\" to consent to the above mentioned uses, click on \"Cookie Settings\" to configure your choices, or click on \"Continue without accepting\" button to refuse all the optional cookies. You may change your preferences, and in particular withdraw your consent, on our website at any moment.\n\nFor more information about these technologies and their use on this website, please consult our Cookie Policy.",
|
||||
"cookieConsent.accept": "ACCEPT ALL",
|
||||
"cookieConsent.reject": "REJECT ALL"
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import commonEn from './en.json'
|
||||
import commonZh from './zh.json'
|
||||
import commonAr from './ar.json'
|
||||
|
||||
export default {
|
||||
'en': {
|
||||
@@ -12,5 +13,8 @@ export default {
|
||||
},
|
||||
'zh': {
|
||||
...commonZh
|
||||
},
|
||||
'ar': {
|
||||
...commonAr
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1748,5 +1748,8 @@
|
||||
"W0010.index.258451-1": "共{0}件商品,合计",
|
||||
"W0010.index.258451-2": "进入购物车",
|
||||
"W0010.index.258451-3": "购物车",
|
||||
"W0008.index.695137-0": "搜索"
|
||||
"W0008.index.695137-0": "搜索",
|
||||
"cookieConsent.description": "我们使用 Cookie\n除了网站运行所必需的 Cookie 之外,我们还使用 Cookie 和其他跟踪工具来记住您的偏好、衡量网站性能、更好地了解您的兴趣,并向您发送购物车通知。我们的合作伙伴使用跟踪器根据您的浏览习惯和个人资料提供个性化广告(包括使用用户画像),或允许您在社交网络上分享我们的内容。\n\n您可以点击\"接受全部 Cookie\"来同意上述用途,点击\"Cookie 设置\"来配置您的选择,或点击\"继续而不接受\"按钮来拒绝所有可选 Cookie。您可以随时在我们的网站上更改您的偏好,特别是撤回您的同意。\n\n有关这些技术及其在本网站上的使用的更多信息,请查阅我们的 Cookie 政策。",
|
||||
"cookieConsent.accept": "接受全部",
|
||||
"cookieConsent.reject": "拒绝全部"
|
||||
}
|
||||
@@ -195,7 +195,9 @@
|
||||
.category-list {
|
||||
position: absolute;
|
||||
top: 42px;
|
||||
left: 0;
|
||||
width: 1000px;
|
||||
direction: ltr;
|
||||
// display: none;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
|
||||
9
src/components/cookie-consent/index.js
Normal file
9
src/components/cookie-consent/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright © ShopeX (http://www.shopex.cn). All rights reserved.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
import CookieConsent from './index.vue'
|
||||
|
||||
export default CookieConsent
|
||||
|
||||
301
src/components/cookie-consent/index.vue
Normal file
301
src/components/cookie-consent/index.vue
Normal file
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
* Copyright © ShopeX (http://www.shopex.cn). All rights reserved.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
<template>
|
||||
<transition name="cookie-consent-fade">
|
||||
<div v-if="visible" class="cookie-consent">
|
||||
<div class="cookie-consent__mask" @click="handleMaskClick"></div>
|
||||
<div class="cookie-consent__content">
|
||||
<div class="cookie-consent__body">
|
||||
<div class="cookie-consent__text">
|
||||
<div
|
||||
class="cookie-consent__description"
|
||||
v-if="privacyContent"
|
||||
v-html="privacyContent"
|
||||
></div>
|
||||
<!-- <p class="cookie-consent__description" v-else>{{ $t('cookieConsent.description') }}</p> -->
|
||||
</div>
|
||||
<div class="cookie-consent__actions">
|
||||
<button
|
||||
@click="handleReject"
|
||||
class="cookie-consent__btn cookie-consent__btn--reject"
|
||||
>
|
||||
{{ $t('cookieConsent.reject') }}
|
||||
</button>
|
||||
<button
|
||||
@click="handleAccept"
|
||||
class="cookie-consent__btn cookie-consent__btn--accept"
|
||||
>
|
||||
{{ $t('cookieConsent.accept') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import cookie from '@/utils/cookie'
|
||||
import { getPrivacySetting } from '@/api/global'
|
||||
|
||||
export default {
|
||||
name: 'CookieConsent',
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
privacyContent: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.fetchPrivacyContent()
|
||||
this.checkAndShow()
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取隐私协议内容
|
||||
*/
|
||||
async fetchPrivacyContent() {
|
||||
try {
|
||||
const res = await getPrivacySetting()
|
||||
if (res && res.pc_privacy_content) {
|
||||
this.privacyContent = res.pc_privacy_content
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to fetch privacy content:', error)
|
||||
// 如果接口失败,使用 i18n 翻译作为后备
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 检查授权状态并显示弹框
|
||||
*/
|
||||
checkAndShow() {
|
||||
// 仅在客户端执行
|
||||
if (process.client) {
|
||||
const consent = cookie.getCookieConsent()
|
||||
// 如果未授权,显示弹框
|
||||
if (consent === null) {
|
||||
this.show()
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 显示弹框
|
||||
*/
|
||||
show() {
|
||||
this.visible = true
|
||||
},
|
||||
/**
|
||||
* 隐藏弹框
|
||||
*/
|
||||
hide() {
|
||||
this.visible = false
|
||||
},
|
||||
/**
|
||||
* 处理同意操作
|
||||
*/
|
||||
handleAccept() {
|
||||
cookie.setCookieConsent(true)
|
||||
this.hide()
|
||||
this.$emit('consent', true)
|
||||
},
|
||||
/**
|
||||
* 处理拒绝操作
|
||||
*/
|
||||
handleReject() {
|
||||
cookie.setCookieConsent(false)
|
||||
this.hide()
|
||||
this.$emit('reject', false)
|
||||
},
|
||||
/**
|
||||
* 处理遮罩层点击(不允许点击关闭)
|
||||
*/
|
||||
handleMaskClick() {
|
||||
// 根据设计需求,可能不允许点击遮罩关闭
|
||||
// 如果需要允许,可以取消下面的注释
|
||||
// this.handleReject()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/style/variables';
|
||||
@import '@/style/mixins';
|
||||
@import '@/style/mixins/rtl';
|
||||
|
||||
.cookie-consent {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: $z-index-level-12;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&__mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 80%;
|
||||
max-width: 815px;
|
||||
min-width: 320px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 0px 10.7px 7px rgba(0, 0, 0, 0.17);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&__body {
|
||||
padding: 55px 44px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
&__text {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-family: 'Noto Sans SC', -apple-system, PingFang SC, Microsoft YaHei, "微软雅黑", Hiragino Sans GB, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
|
||||
// HTML 内容样式
|
||||
:deep(div) {
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(p) {
|
||||
margin: 0 0 12px 0;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
@include justify-content-end;
|
||||
gap: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__btn {
|
||||
font-family: 'Noto Sans SC', -apple-system, PingFang SC, Microsoft YaHei, "微软雅黑", Hiragino Sans GB, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
outline: none;
|
||||
transition: all 0.3s ease;
|
||||
min-width: 140px;
|
||||
padding: 12px 24px;
|
||||
border-radius: 2px;
|
||||
|
||||
&--reject {
|
||||
background-color: #fff;
|
||||
color: #666666;
|
||||
border: 1px solid #e5e5e5;
|
||||
|
||||
&:hover {
|
||||
background-color: #f6f6f6;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
|
||||
&--accept {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
border: 1px solid #000;
|
||||
|
||||
&:hover {
|
||||
background-color: #333;
|
||||
border-color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@include respond(sm) {
|
||||
.cookie-consent {
|
||||
&__content {
|
||||
width: 90%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&__body {
|
||||
padding: 40px 30px;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__btn {
|
||||
width: 100%;
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 淡入淡出动画
|
||||
.cookie-consent-fade {
|
||||
&-enter-active,
|
||||
&-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
&-enter,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&-enter-active .cookie-consent__content,
|
||||
&-leave-active .cookie-consent__content {
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
&-enter .cookie-consent__content,
|
||||
&-leave-to .cookie-consent__content {
|
||||
transform: scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,19 +4,30 @@
|
||||
*/
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div :dir="direction">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCurrentDirection } from '@/utils/rtl'
|
||||
|
||||
export default {
|
||||
name: 'LayoutHoc',
|
||||
computed: {
|
||||
direction() {
|
||||
return getCurrentDirection(this)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const getlanguageByPath = (path) => {
|
||||
const zhKey = 'zh'
|
||||
const enKey = 'en'
|
||||
return path.includes(zhKey) ? 'zh' : path.includes(enKey) ? 'en' : null
|
||||
const arKey = 'ar'
|
||||
if (path.includes(zhKey)) return 'zh'
|
||||
if (path.includes(enKey)) return 'en'
|
||||
if (path.includes(arKey)) return 'ar'
|
||||
return null
|
||||
}
|
||||
const language = getlanguageByPath(this.$route.path)
|
||||
if (language && this.$store.state.locale != language) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
.topbar-login {
|
||||
a,
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
@include margin-inline-end(10px);
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
@@ -22,17 +22,104 @@
|
||||
.member-phone {
|
||||
font-size: 13px;
|
||||
color: $color-brand-primary;
|
||||
margin-right: 10px;
|
||||
@include margin-inline-end(10px);
|
||||
}
|
||||
.exit-btn {
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.language-selector {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@include margin-inline-start(10px);
|
||||
z-index: 1001;
|
||||
pointer-events: auto;
|
||||
|
||||
&__current {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
user-select: none;
|
||||
pointer-events: auto;
|
||||
position: relative;
|
||||
z-index: 1002;
|
||||
|
||||
.ec-icon {
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
color: #999;
|
||||
|
||||
&.active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $color-brand-primary;
|
||||
}
|
||||
}
|
||||
|
||||
&__dropdown {
|
||||
@include text-align-start;
|
||||
position: fixed !important;
|
||||
background: #fff;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
min-width: 120px;
|
||||
z-index: 10000 !important;
|
||||
list-style: none;
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
|
||||
li {
|
||||
padding: 8px 16px;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: #f5f5f5;
|
||||
color: $color-brand-primary;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #f0f0f0;
|
||||
color: $color-brand-primary;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 过渡动画
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-enter-to,
|
||||
.fade-leave {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.topbar-member {
|
||||
a {
|
||||
color: #666;
|
||||
margin-right: 10px;
|
||||
@include margin-inline-end(10px);
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +131,7 @@
|
||||
}
|
||||
.logo-con {
|
||||
width: 25%;
|
||||
float: left;
|
||||
@include float-start;
|
||||
img {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
@@ -52,14 +139,14 @@
|
||||
}
|
||||
.search-con {
|
||||
width: 50%;
|
||||
float: left;
|
||||
@include float-start;
|
||||
margin-top: 7px;
|
||||
}
|
||||
.cart-con {
|
||||
width: 25%;
|
||||
float: left;
|
||||
@include float-start;
|
||||
margin-top: 7px;
|
||||
text-align: right;
|
||||
@include text-align-end;
|
||||
.cart-link {
|
||||
background: $color-brand-primary;
|
||||
color: $color-primary-text;
|
||||
@@ -70,10 +157,10 @@
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
.cart-icon {
|
||||
.cart-icon {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin-right: 5px;
|
||||
@include margin-inline-end(5px);
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
.ec-icon-cart {
|
||||
@@ -83,7 +170,7 @@
|
||||
.count {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 10px;
|
||||
@include right(10px);
|
||||
transform: translateY(-35%) translateX(100%);
|
||||
border: 1px solid $color-brand-primary;
|
||||
background: #fff;
|
||||
@@ -121,7 +208,7 @@
|
||||
}
|
||||
}
|
||||
&__btn {
|
||||
float: left;
|
||||
@include float-start;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
width: 200px;
|
||||
@@ -133,7 +220,9 @@
|
||||
.category-list {
|
||||
position: absolute;
|
||||
top: 42px;
|
||||
left: 0;
|
||||
width: 1000px;
|
||||
direction: ltr;
|
||||
// display: none;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
@@ -206,11 +295,11 @@
|
||||
}
|
||||
}
|
||||
.navs-con {
|
||||
float: left;
|
||||
margin-left: 60px;
|
||||
@include float-start;
|
||||
@include margin-inline-start(60px);
|
||||
.nav-item {
|
||||
float: left;
|
||||
margin-right: 60px;
|
||||
@include float-start;
|
||||
@include margin-inline-end(60px);
|
||||
a {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<template>
|
||||
<div class="header-bar">
|
||||
<div class="header-bar__topbar">
|
||||
<div class="container clearfix">
|
||||
<div class="container ">
|
||||
<div class="topbar-login fl">
|
||||
<div class="no-login active">
|
||||
<NuxtLink to="/" class="index-link">{{ $t('sp-header.index.663900-0') }}</NuxtLink>
|
||||
@@ -32,9 +32,30 @@
|
||||
<span class="member-phone">{{ userInfo.memberInfo.mobile }}</span>
|
||||
<span class="exit-btn" @click="handleLogout()">{{ $t('sp-header.index.663900-4') }}</span>
|
||||
</template>
|
||||
<span @click="handleChangeLanguage">
|
||||
{{ $t('sp-header.index.061123-0') }}{{ $i18n.locale == 'zh' ? $t('sp-header.index.061123-1') : $t('sp-header.index.061123-2') }}
|
||||
</span>
|
||||
<div class="language-selector" v-on-clickaway="closeLanguageDropdown">
|
||||
<span
|
||||
class="language-selector__current"
|
||||
@click="toggleLanguageDropdown"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
{{ getCurrentLanguageName() }}
|
||||
<i class="ec-icon ec-icon-unfold" :class="{ 'active': showLanguageDropdown }"></i>
|
||||
</span>
|
||||
<ul
|
||||
class="language-selector__dropdown"
|
||||
v-if="showLanguageDropdown"
|
||||
v-show="showLanguageDropdown"
|
||||
>
|
||||
<li
|
||||
v-for="lang in availableLanguages"
|
||||
:key="lang.code"
|
||||
:class="{ 'active': lang.code === $i18n.locale }"
|
||||
@click="handleChangeLanguage(lang.code)"
|
||||
>
|
||||
{{ lang.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topbar-member fr">
|
||||
@@ -76,13 +97,36 @@ import S from '@/spx'
|
||||
export default {
|
||||
name: 'SpHeader',
|
||||
mixins: [clickaway],
|
||||
mounted() {
|
||||
// 验证指令是否注册
|
||||
console.log('SpHeader mounted')
|
||||
console.log('Available directives:', Object.keys(this.$options.directives || {}))
|
||||
console.log('onClickaway directive:', this.$options.directives?.onClickaway)
|
||||
console.log('closeLanguageDropdown method:', typeof this.closeLanguageDropdown)
|
||||
|
||||
// 检查元素是否存在
|
||||
this.$nextTick(() => {
|
||||
const selector = this.$el.querySelector('.language-selector')
|
||||
const current = this.$el.querySelector('.language-selector__current')
|
||||
console.log('Language selector element:', selector)
|
||||
console.log('Language selector current element:', current)
|
||||
|
||||
if (current) {
|
||||
// 添加原生事件监听器测试
|
||||
current.addEventListener('click', (e) => {
|
||||
console.log('Native click event on language selector!', e)
|
||||
this.toggleLanguageDropdown(e)
|
||||
}, true) // 使用捕获阶段
|
||||
}
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
message: '',
|
||||
basefile: 'newwapmall/block/header.html',
|
||||
fixed: false,
|
||||
showSubNav: null,
|
||||
message: ''
|
||||
showLanguageDropdown: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -100,12 +144,77 @@ export default {
|
||||
pageConfig: (state) => {
|
||||
return state.pageConfig
|
||||
}
|
||||
})
|
||||
}),
|
||||
availableLanguages() {
|
||||
return [
|
||||
{ code: 'zh', name: '中文' },
|
||||
{ code: 'en', name: 'English' },
|
||||
{ code: 'ar', name: 'العربية' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChangeLanguage() {
|
||||
this.$store.commit('SET_LANG', this.$i18n.locale == 'zh' ? 'en' : 'zh')
|
||||
this.$i18n.setLocale(this.$i18n.locale == 'zh' ? 'en' : 'zh')
|
||||
getCurrentLanguageName() {
|
||||
if (!this.$i18n || !this.$i18n.locale) {
|
||||
return '中文'
|
||||
}
|
||||
const currentLocale = this.$i18n.locale
|
||||
const lang = this.availableLanguages.find(l => l.code === currentLocale)
|
||||
return lang ? lang.name : '中文'
|
||||
},
|
||||
toggleLanguageDropdown(e) {
|
||||
if (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
this.showLanguageDropdown = !this.showLanguageDropdown
|
||||
|
||||
// 计算下拉菜单位置
|
||||
if (this.showLanguageDropdown) {
|
||||
this.$nextTick(() => {
|
||||
const current = this.$el.querySelector('.language-selector__current')
|
||||
const dropdown = this.$el.querySelector('.language-selector__dropdown')
|
||||
if (current && dropdown) {
|
||||
const rect = current.getBoundingClientRect()
|
||||
dropdown.style.top = `${rect.bottom + 5}px`
|
||||
dropdown.style.left = `${rect.left}px`
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
closeLanguageDropdown() {
|
||||
this.showLanguageDropdown = false
|
||||
},
|
||||
handleChangeLanguage(locale) {
|
||||
if (locale === this.$i18n.locale) {
|
||||
this.closeLanguageDropdown()
|
||||
return
|
||||
}
|
||||
|
||||
this.$store.commit('SET_LANG', locale)
|
||||
this.$i18n.setLocale(locale)
|
||||
|
||||
// 更新路由路径
|
||||
const currentPath = this.$route.path
|
||||
const pathLang = this.getlanguageByPath(currentPath)
|
||||
let newPath = currentPath
|
||||
|
||||
if (pathLang) {
|
||||
// 替换路径中的语言代码
|
||||
newPath = currentPath.replace(`/${pathLang}`, `/${locale}`)
|
||||
} else {
|
||||
// 如果路径中没有语言代码,添加语言前缀
|
||||
newPath = `/${locale}${currentPath === '/' ? '' : currentPath}`
|
||||
}
|
||||
|
||||
this.closeLanguageDropdown()
|
||||
this.$router.push({ path: newPath, query: this.$route.query })
|
||||
},
|
||||
getlanguageByPath(path) {
|
||||
if (path.includes('/zh')) return 'zh'
|
||||
if (path.includes('/en')) return 'en'
|
||||
if (path.includes('/ar')) return 'ar'
|
||||
return ''
|
||||
},
|
||||
handleLogout() {
|
||||
this.$cookies.remove('ECSHOPX_TOKEN')
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
.category-list {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 0;
|
||||
direction: ltr;
|
||||
font-size: 16px;
|
||||
// width: 1000px;
|
||||
// display: none;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<template>
|
||||
<LayoutHoc>
|
||||
<div class="system-auth">
|
||||
<div class="system-auth" :dir="direction">
|
||||
<auth-header :logo="logo" />
|
||||
<div class="page-body" :style="{ backgroundImage: `url(${bg})` }">
|
||||
<Nuxt />
|
||||
@@ -31,6 +31,7 @@ import "@/main";
|
||||
import { mapActions, mapState } from "vuex";
|
||||
import { Tracker } from "@/service";
|
||||
import { isNativeBrower } from "@/utils";
|
||||
import { getCurrentDirection } from '@/utils/rtl'
|
||||
import backgroundImage from '@/assets/imgs/login_background.png'
|
||||
import logoImage from '@/assets/imgs/login_yundian.jpg'
|
||||
|
||||
@@ -57,7 +58,10 @@ export default {
|
||||
|
||||
return res.params ? JSON.parse(res.params) : [];
|
||||
}
|
||||
})
|
||||
}),
|
||||
direction() {
|
||||
return getCurrentDirection(this)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getPic()
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
|
||||
<template>
|
||||
<LayoutHoc>
|
||||
<div class="system-container">
|
||||
<div class="system-container" :dir="direction">
|
||||
<SpHeader />
|
||||
<div class="page-body">
|
||||
<Nuxt />
|
||||
</div>
|
||||
<SpFooter />
|
||||
<CookieConsent />
|
||||
</div>
|
||||
</LayoutHoc>
|
||||
</template>
|
||||
@@ -24,9 +25,20 @@ import { mapActions, mapState } from 'vuex'
|
||||
import { Tracker } from '@/service'
|
||||
import { isNativeBrower } from '@/utils'
|
||||
import { mixin } from '@/mixins'
|
||||
import { getCurrentDirection } from '@/utils/rtl'
|
||||
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
computed: {
|
||||
...mapState({
|
||||
pageSeo: (state) => {
|
||||
return state.pageSeo
|
||||
}
|
||||
}),
|
||||
direction() {
|
||||
return getCurrentDirection(this)
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
// title: this.pageSeo.title,
|
||||
@@ -37,13 +49,6 @@ export default {
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
pageSeo: (state) => {
|
||||
return state.pageSeo
|
||||
}
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageOptions: {}
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
|
||||
<template>
|
||||
<LayoutHoc>
|
||||
<div class="shop-auth">
|
||||
<div class="shop-auth" :dir="direction">
|
||||
<shop-header v-if="show" />
|
||||
<div class="page-body">
|
||||
<Nuxt />
|
||||
</div>
|
||||
<sp-footer />
|
||||
<CookieConsent />
|
||||
</div>
|
||||
</LayoutHoc>
|
||||
</template>
|
||||
@@ -30,6 +31,7 @@ import '@/main'
|
||||
import { mapActions, mapState } from 'vuex'
|
||||
import { Tracker } from '@/service'
|
||||
import { isNativeBrower } from '@/utils'
|
||||
import { getCurrentDirection } from '@/utils/rtl'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
@@ -55,7 +57,10 @@ export default {
|
||||
|
||||
return res.params ? JSON.parse(res.params) : []
|
||||
}
|
||||
})
|
||||
}),
|
||||
direction() {
|
||||
return getCurrentDirection(this)
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
|
||||
29
src/main.js
29
src/main.js
@@ -3,26 +3,6 @@
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
// 开源标注信息
|
||||
const licenseInfo = `
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ ECShopX open source E-commerce ║
|
||||
║ ECShopX 开源商城系统 ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ Copyright (c) 2003-2025 ShopeX,Inc.All rights reserved. ║
|
||||
║ Corporate Website: https://www.shopex.cn ║
|
||||
║ Licensed under the Apache License, Version 2.0 ║
|
||||
║ http://www.apache.org/licenses/LICENSE-2.0 ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ The removal of shopeX copyright information without ║
|
||||
║ authorization is prohibited. ║
|
||||
║ 未经授权不可去除shopeX商派相关版权 ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ Author: shopeX Team <mkt@shopex.cn> ║
|
||||
║ Contact: 400-821-3106 ║
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
`
|
||||
|
||||
import Vue from 'vue'
|
||||
import VueLazyload from 'vue-lazyload'
|
||||
// import ElementUI from 'element-ui';
|
||||
@@ -73,6 +53,7 @@ import Widgets from "./espier-widgets";
|
||||
import * as Filters from '@/filters'
|
||||
import { TrackerPlugin } from '@/service'
|
||||
import store from 'store'
|
||||
import { directive as onClickawayDirective } from '@/plugins/clickaway'
|
||||
|
||||
// import 'swiper/css/swiper.css'
|
||||
import plugin from './components/sp-modal/src/plugin'
|
||||
@@ -187,6 +168,9 @@ const install = function(Vue, opts = {}) {
|
||||
Vue.directive(name, directive)
|
||||
})
|
||||
|
||||
// 全局注册 clickaway 指令(支持 v-on-clickaway 和 v-onClickaway)
|
||||
Vue.directive('onClickaway', onClickawayDirective)
|
||||
|
||||
Object.keys(Filters).forEach((key) => {
|
||||
const { name, filter } = Filters[key]
|
||||
if (key == 'formatPrice' || key == 'formatPriceToHundred' || key == 'parseTime') {
|
||||
@@ -235,8 +219,3 @@ Vue.use(VueLazyload)
|
||||
// }
|
||||
|
||||
Vue.prototype.$EventBus = new Vue()
|
||||
|
||||
// 在应用启动时打印开源标注信息(仅客户端)
|
||||
if (process.client) {
|
||||
console.log('%c' + licenseInfo, 'color: #3e76f6; font-family: monospace; line-height: 1.4;')
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ export default function (context) {
|
||||
|
||||
const enPath = `en`
|
||||
const zhPath = 'zh'
|
||||
const arPath = 'ar'
|
||||
|
||||
const pathLang = getlanguageByPath(route.path)
|
||||
let lang = pathLang || app.i18n.locale || defaultLocale
|
||||
@@ -22,18 +23,17 @@ export default function (context) {
|
||||
routePath.indexOf(`${lang}`) === -1 &&
|
||||
defaultLocale !== lang
|
||||
) {
|
||||
const trans = routePath.indexOf(zhPath) !== -1
|
||||
? {
|
||||
c: zhPath,
|
||||
r: enPath
|
||||
}
|
||||
: routePath.indexOf(enPath) !== -1
|
||||
? {
|
||||
c: enPath,
|
||||
r: zhPath
|
||||
}
|
||||
: null;
|
||||
const path = trans ? routePath.replace(trans.c, trans.r) : `/${`${lang}`}${routePath}`
|
||||
// 支持三种语言之间的路径转换
|
||||
let trans = null
|
||||
if (routePath.indexOf(zhPath) !== -1) {
|
||||
trans = { c: zhPath, r: lang }
|
||||
} else if (routePath.indexOf(enPath) !== -1) {
|
||||
trans = { c: enPath, r: lang }
|
||||
} else if (routePath.indexOf(arPath) !== -1) {
|
||||
trans = { c: arPath, r: lang }
|
||||
}
|
||||
|
||||
const path = trans ? routePath.replace(trans.c, trans.r) : `/${lang}${routePath}`
|
||||
return redirect({ path: path, query: route.query })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,13 @@
|
||||
.page-auth-login {
|
||||
// margin: 50px auto 100px;
|
||||
background: transparent;
|
||||
height: 590px;
|
||||
min-height: 590px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@include justify-content-end;
|
||||
position: relative;
|
||||
@include padding-inline-end(100px);
|
||||
@include padding-inline-start(100px);
|
||||
.login-logo{
|
||||
left: auto;
|
||||
// top: 100px;
|
||||
@@ -19,10 +24,10 @@
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
width: 350px;
|
||||
// height: 372px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
top: 82px;;
|
||||
left: 844px;
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
.login-title {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
@import 'mixins/rtl';
|
||||
|
||||
@import "variables";
|
||||
|
||||
@function strip-unit($number) {
|
||||
|
||||
@@ -56,11 +56,11 @@ ul {
|
||||
}
|
||||
|
||||
.fl {
|
||||
float: left;
|
||||
@include float-start;
|
||||
}
|
||||
|
||||
.fr {
|
||||
float: right;
|
||||
@include float-end;
|
||||
}
|
||||
|
||||
.txt-center {
|
||||
|
||||
211
src/style/mixins/_rtl.scss
Normal file
211
src/style/mixins/_rtl.scss
Normal file
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright © ShopeX (http://www.shopex.cn). All rights reserved.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* RTL (Right-to-Left) Mixin
|
||||
* 用于支持从右到左的语言布局
|
||||
*/
|
||||
|
||||
/**
|
||||
* RTL 模式下的样式
|
||||
* 用法: @include rtl { ... }
|
||||
*/
|
||||
@mixin rtl {
|
||||
[dir="rtl"] & {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LTR 模式下的样式
|
||||
* 用法: @include ltr { ... }
|
||||
*/
|
||||
@mixin ltr {
|
||||
[dir="ltr"] &,
|
||||
&:not([dir]) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 margin-inline-start
|
||||
* 在 LTR 中为 margin-left,在 RTL 中为 margin-right
|
||||
*/
|
||||
@mixin margin-inline-start($value) {
|
||||
margin-left: $value;
|
||||
|
||||
@include rtl {
|
||||
margin-left: 0;
|
||||
margin-right: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 margin-inline-end
|
||||
* 在 LTR 中为 margin-right,在 RTL 中为 margin-left
|
||||
*/
|
||||
@mixin margin-inline-end($value) {
|
||||
margin-right: $value;
|
||||
|
||||
@include rtl {
|
||||
margin-right: 0;
|
||||
margin-left: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 padding-inline-start
|
||||
* 在 LTR 中为 padding-left,在 RTL 中为 padding-right
|
||||
*/
|
||||
@mixin padding-inline-start($value) {
|
||||
padding-left: $value;
|
||||
|
||||
@include rtl {
|
||||
padding-left: 0;
|
||||
padding-right: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 padding-inline-end
|
||||
* 在 LTR 中为 padding-right,在 RTL 中为 padding-left
|
||||
*/
|
||||
@mixin padding-inline-end($value) {
|
||||
padding-right: $value;
|
||||
|
||||
@include rtl {
|
||||
padding-right: 0;
|
||||
padding-left: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 border-inline-start
|
||||
*/
|
||||
@mixin border-inline-start($value) {
|
||||
border-left: $value;
|
||||
|
||||
@include rtl {
|
||||
border-left: none;
|
||||
border-right: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 border-inline-end
|
||||
*/
|
||||
@mixin border-inline-end($value) {
|
||||
border-right: $value;
|
||||
|
||||
@include rtl {
|
||||
border-right: none;
|
||||
border-left: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Float 到开始位置(LTR 中为 left,RTL 中为 right)
|
||||
*/
|
||||
@mixin float-start {
|
||||
float: left;
|
||||
|
||||
@include rtl {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Float 到结束位置(LTR 中为 right,RTL 中为 left)
|
||||
*/
|
||||
@mixin float-end {
|
||||
float: right;
|
||||
|
||||
@include rtl {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本对齐到开始位置(LTR 中为 left,RTL 中为 right)
|
||||
*/
|
||||
@mixin text-align-start {
|
||||
text-align: left;
|
||||
|
||||
@include rtl {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本对齐到结束位置(LTR 中为 right,RTL 中为 left)
|
||||
*/
|
||||
@mixin text-align-end {
|
||||
text-align: right;
|
||||
|
||||
@include rtl {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 left 定位
|
||||
* 在 RTL 模式下转换为 right
|
||||
*/
|
||||
@mixin left($value) {
|
||||
left: $value;
|
||||
|
||||
@include rtl {
|
||||
left: auto;
|
||||
right: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向感知的 right 定位
|
||||
* 在 RTL 模式下转换为 left
|
||||
*/
|
||||
@mixin right($value) {
|
||||
right: $value;
|
||||
|
||||
@include rtl {
|
||||
right: auto;
|
||||
left: $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexbox 方向感知
|
||||
* 在 RTL 模式下反转 flex-direction
|
||||
*/
|
||||
@mixin flex-direction-row {
|
||||
flex-direction: row;
|
||||
|
||||
@include rtl {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Justify-content 到开始位置
|
||||
*/
|
||||
@mixin justify-content-start {
|
||||
justify-content: flex-start;
|
||||
|
||||
@include rtl {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Justify-content 到结束位置
|
||||
*/
|
||||
@mixin justify-content-end {
|
||||
justify-content: flex-end;
|
||||
|
||||
@include rtl {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,19 +152,19 @@ textarea {
|
||||
}
|
||||
|
||||
.f-l {
|
||||
float: left;
|
||||
@include float-start;
|
||||
}
|
||||
|
||||
.f-r {
|
||||
float: right;
|
||||
@include float-end;
|
||||
}
|
||||
|
||||
.t-r {
|
||||
text-align: right !important;
|
||||
@include text-align-end;
|
||||
}
|
||||
|
||||
.t-l {
|
||||
text-align: left !important;
|
||||
@include text-align-start;
|
||||
}
|
||||
|
||||
.t-c {
|
||||
|
||||
@@ -33,6 +33,37 @@ class Cookie {
|
||||
if (cval != null)
|
||||
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Cookie 授权状态
|
||||
* @returns {string|null} 'true' | 'false' | null
|
||||
*/
|
||||
getCookieConsent() {
|
||||
if (typeof window === 'undefined' || !window.localStorage) {
|
||||
return null
|
||||
}
|
||||
return window.localStorage.getItem('cookie_consent_authorized')
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 Cookie 授权状态
|
||||
* @param {boolean} value - 授权状态
|
||||
*/
|
||||
setCookieConsent(value) {
|
||||
if (typeof window === 'undefined' || !window.localStorage) {
|
||||
return
|
||||
}
|
||||
window.localStorage.setItem('cookie_consent_authorized', String(value))
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已授权 Cookie
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasCookieConsent() {
|
||||
const consent = this.getCookieConsent()
|
||||
return consent === 'true'
|
||||
}
|
||||
}
|
||||
|
||||
const cookie = new Cookie()
|
||||
|
||||
@@ -11,6 +11,10 @@ export const getLanguage = () => {
|
||||
export const getlanguageByPath = (path) => {
|
||||
const zhKey = 'zh'
|
||||
const enKey = 'en'
|
||||
return path.includes(zhKey) ? 'zh' : path.includes(enKey) ? 'en' : ''
|
||||
const arKey = 'ar'
|
||||
if (path.includes(zhKey)) return 'zh'
|
||||
if (path.includes(enKey)) return 'en'
|
||||
if (path.includes(arKey)) return 'ar'
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@ export const locales = [
|
||||
name: '中文',
|
||||
iso: 'zh-CN',
|
||||
language: 'zh-CN'
|
||||
},
|
||||
{
|
||||
code: 'ar',
|
||||
name: 'العربية',
|
||||
iso: 'ar-SA',
|
||||
language: 'ar-SA'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
88
src/utils/rtl.js
Normal file
88
src/utils/rtl.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright © ShopeX (http://www.shopex.cn). All rights reserved.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* RTL (Right-to-Left) 工具函数
|
||||
* 用于检测和处理从右到左的语言布局
|
||||
*/
|
||||
|
||||
/**
|
||||
* RTL 语言列表
|
||||
*/
|
||||
const RTL_LOCALES = ['ar', 'he', 'fa', 'ur']
|
||||
|
||||
/**
|
||||
* 检测指定语言是否为 RTL 语言
|
||||
* @param {string} locale - 语言代码,如 'ar', 'zh', 'en'
|
||||
* @returns {boolean} 是否为 RTL 语言
|
||||
*/
|
||||
export function isRTL(locale) {
|
||||
if (!locale) {
|
||||
return false
|
||||
}
|
||||
return RTL_LOCALES.includes(locale.toLowerCase())
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定语言的文本方向
|
||||
* @param {string} locale - 语言代码
|
||||
* @returns {string} 'rtl' 或 'ltr'
|
||||
*/
|
||||
export function getDirection(locale) {
|
||||
return isRTL(locale) ? 'rtl' : 'ltr'
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Vue 实例或上下文获取当前语言
|
||||
* @param {Object} context - Vue 实例或包含 $i18n 的对象
|
||||
* @returns {string} 当前语言代码
|
||||
*/
|
||||
export function getCurrentLocale(context = null) {
|
||||
// 如果在 Vue 组件中,尝试从 $i18n 获取
|
||||
if (context && context.$i18n) {
|
||||
return context.$i18n.locale || 'en'
|
||||
}
|
||||
|
||||
// 如果在 Nuxt 上下文中
|
||||
if (process.client && window.$nuxt && window.$nuxt.$i18n) {
|
||||
return window.$nuxt.$i18n.locale || 'en'
|
||||
}
|
||||
|
||||
// 从 localStorage 获取
|
||||
if (process.client) {
|
||||
const stored = localStorage.getItem('i18n_redirected')
|
||||
if (stored) {
|
||||
try {
|
||||
return JSON.parse(stored) || 'en'
|
||||
} catch {
|
||||
return stored || 'en'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 默认返回英文
|
||||
return process.env.VUE_APP_DEFAULT_LANG || 'en'
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测当前语言是否为 RTL
|
||||
* @param {Object} context - Vue 实例或上下文
|
||||
* @returns {boolean} 是否为 RTL 语言
|
||||
*/
|
||||
export function isCurrentRTL(context = null) {
|
||||
const locale = getCurrentLocale(context)
|
||||
return isRTL(locale)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前语言的文本方向
|
||||
* @param {Object} context - Vue 实例或上下文
|
||||
* @returns {string} 'rtl' 或 'ltr'
|
||||
*/
|
||||
export function getCurrentDirection(context = null) {
|
||||
const locale = getCurrentLocale(context)
|
||||
return getDirection(locale)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user