Compare commits

...

251 Commits

Author SHA1 Message Date
王景 2c494200c2 Merge branch 'msb_prod'
2 years ago
王景 e40200199b merge: merge conflict
2 years ago
ch ea10aa3d17 Merge branch 'fix/add_publishCertificates_ch' into msb_prod
2 years ago
ch 408a4667ce fix: 添加营业执照
2 years ago
ch 43c000eae2 Merge branch 'fix/add_publishCertificates_ch' into msb_prod
2 years ago
ch 4145f90ac9 fix: 修改服务端口
2 years ago
ch 9e6b270987 Merge branch 'msb_prod' of https://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into msb_prod
2 years ago
ch 24bb9c8c42 Merge branch 'fix/add_publishCertificates_ch' into msb_prod
2 years ago
ch cc51bc8709 fix: nuxt version
2 years ago
陈辉 425f630b2a Merge branch 'fix/add_publishCertificates_ch' into 'msb_prod'
2 years ago
ch 89c0ce7cf5 fix: node 版本
2 years ago
陈辉 29841ba9c4 Merge branch 'fix/add_publishCertificates_ch' into 'msb_prod'
2 years ago
ch a10143b26d fix: 文字样式
2 years ago
ch fde9ef42ef feature: add publish certificates
2 years ago
ch 99c6010bb7 pref:打包命令统一
2 years ago
ch c7199f96db pref:优化获取支付二维码提示
2 years ago
ch 090fd92d51 clear
2 years ago
ch 64287e9c3f fix:点赞,已购买bug
2 years ago
ch 8142659b0c Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 58fdbb7236 提交最后一个评价跳转页面
2 years ago
ch 3d5673bbe7 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 2117d22715 提交最后一个有提示
2 years ago
ch 2fe0933c25 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 35823e2c4a 修改分页为加载更多
2 years ago
ch 33f83236a7 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch b4b38d8a4a 修改分页为加载更多
2 years ago
ch 7374cdfdaf Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch ca9c17ba69 修改追评图片
2 years ago
ch 30cb0f66a0 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 0c7494a097 修改分页
2 years ago
ch 1f398092d2 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 9288f0ac43 评论跳转
2 years ago
ch 9f0a219fa1 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch cd1032d988 pc验收问题
2 years ago
ch a0bd0ca45c Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 09ba7e8819 修改
2 years ago
覃昌波 56991e2fba 更新 Dockerfile
2 years ago
覃昌波 b3b6db82e5 更新 Dockerfile
2 years ago
覃昌波 4669a69b12 更新 Dockerfile
2 years ago
覃昌波 20b9748f64 更新 Dockerfile
2 years ago
覃昌波 a8ec9b7c77 更新 Dockerfile
2 years ago
覃昌波 1ef83e8765 更新 Dockerfile
2 years ago
ch 7af76834f6 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch e17951e223 回复添加到第一条
2 years ago
ch 9ec022fc0f 回复undefind
2 years ago
ch 887cea6f90 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 430399c54f fix:修改标签数据统计
2 years ago
ch 10a22e7e52 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch b067e2130b 修改图片预览箭头
2 years ago
ch 302c0b9e40 Merge branch 'feature/zfbpay-0629-ch' into msb_test
2 years ago
ch ebc3039353 支付宝图标过大问题
2 years ago
ch 593a3cfcd2 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 47deb31894 评论500
2 years ago
ch f04113a6d8 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 41c35825fa 有评价时提示
2 years ago
ch 9f07b75bea Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 3a65dd736f 修改评论显示问题
2 years ago
ch 428e3165d1 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch 510408068d 纯空格不让提交
2 years ago
ch 85fc3fb293 Merge branch 'feature/comment-0624-ch' into msb_test
2 years ago
ch ddc982a35d token
2 years ago
ch 2375f95fcb Merge branch 'feature/zfbpay-0629-ch' into msb_test
2 years ago
ch 96176a68cc 修改命名
2 years ago
ch 1e73cdfbce Merge branch 'feature/zfbpay-0629-ch' into msb_test
2 years ago
ch c8302cf9ef 修改token
2 years ago
ch 60b1f0be39 添加支付宝支付
2 years ago
ch 11878e566f fix:修复立即购买跳空页面问题
2 years ago
ch 91812512bc 修改评论数量,点击追评的效果
2 years ago
ch e771928e88 fix:放开提交评论注释
2 years ago
ch b81c463e9b fix:评价跳转
2 years ago
ch 8d00cb4242 修复去追评
2 years ago
ch 845ad5dba8 修改bug
2 years ago
ch 264a108a33 评价跳转
2 years ago
ch e96d372369 其他宝贝评价
2 years ago
ch a93838e595 商品评价
2 years ago
ch e78c41f6c2 评价
2 years ago
ch 5864830b29 fix:提交订单订单来源
2 years ago
ch e7540706b9 fix:支付弹窗偶现黑屏问题
2 years ago
ch 3cce4c2c14 二维码生成
2 years ago
ch 0b70cd4f49 fate: 支持接口修改
2 years ago
ch 69e86583ec 请求地址
2 years ago
ch 00d5bb7c82 请求地址
2 years ago
ch 22dab20d79 fix:update sdk
2 years ago
ch 150f61315e fix: update im SDK
2 years ago
ch 69abc97570 fix: update im SDK
2 years ago
ch 9876af66ad fix:sdk修改
2 years ago
ch b8a6c1e9f5 fix:imSDK close
2 years ago
ch adafa9ff2c pref: update imSDK
2 years ago
ch b96a231952 fix:通知消息不更新问题
2 years ago
ch d04791081c fea: im改造
2 years ago
ch 30cdc50558 fix:修改uuid报错
3 years ago
ch af06861fc9 fix: 修改uuid不重复问题
3 years ago
ch ff49fedd42 fix: 每次刷新UUID不一样
3 years ago
ch 1c5402a7b0 修改uuid
3 years ago
ch c259a61025 添加uuid
3 years ago
ch 8b18ca4f73 下载页
3 years ago
ch b07a9f04c2 Merge branch 'feature/ad-0531-ch' into msb_test
3 years ago
ch 0f98983398 fix: 广告请求前缀
3 years ago
ch 01a05c6916 Merge branch 'feature/ad-0531-ch' into msb_test
3 years ago
ch 666bee10e1 fat:添加分类跳转
3 years ago
ch da8bb5704e Merge branch 'feature/ad-0531-ch' into msb_test
3 years ago
ch f81e70891e fat:添加分类跳转
3 years ago
ch 536ff98861 Merge branch 'feature/ad-0531-ch' into msb_test
3 years ago
ch 27d2e49aff fix:banner不显示
3 years ago
ch 72408674a7 Merge branch 'feature/ad-0531-ch' into msb_test
3 years ago
ch 295537b06c 广告请求
3 years ago
ch 23113a3e7c Merge branch 'feature/task315-0526-ch' into msb_test
3 years ago
ch 4ecf12211a 下载样式
3 years ago
ch 7bb20db2d8 下载页
3 years ago
ch 4d1a40b5d0 广告
3 years ago
ch e8fd578806 添加动效
3 years ago
ch 8d5f2d6a2c Merge branch 'fix/goods-0525' into msb_prod
3 years ago
ch 68619cea53 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch f0e60a44c7 弹框判断
3 years ago
ch cb274ee8a4 Merge branch 'fix/goods-0525' into msb_prod
3 years ago
ch c9ad86300e Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 5741b4ecf9 弹框
3 years ago
ch be4082e868 Merge branch 'msb_test' into msb_prod
3 years ago
ch c700fdf8c8 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch a959ab5036 加跳转按钮
3 years ago
ch 78b693c788 Merge branch 'fix/im-0526' into msb_prod
3 years ago
ch 3f9b83e419 修改生产地址
3 years ago
ch df94ad7575 下载页
3 years ago
ch 9eb41b5297 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 466ae538a8 修改发货消息
3 years ago
ch c102995fdc Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 53152aa224 修改
3 years ago
ch d89bb54566 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 802a17906b 修改
3 years ago
ch 21987554f8 Merge branch 'fix/im-0526' into msb_test
3 years ago
ch fed8881529 添加已读
3 years ago
ch 2a63673248 修改消息已读
3 years ago
ch e3341ac65f Merge branch 'fix/im-0526' into msb_test
3 years ago
ch 697b08c666 修改点击区域
3 years ago
ch dca519590e Merge branch 'fix/im-0526' into msb_test
3 years ago
ch abdf037373 处理文件消息
3 years ago
ch a0099fddc1 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 0f8d21bd2d 修改改虚拟商品提交订单
3 years ago
ch 6aa4eec34f Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 469270c769 修改提交订单的地址问题
3 years ago
ch 487254db76 修改
3 years ago
ch 66f9530883 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 8370bdd5f0 报错
3 years ago
ch 235d8e0cff 页面html
3 years ago
ch 494c288e20 Merge branch 'fix/goods-0525' into msb_test
3 years ago
ch 9bf02bfc56 pref:虚拟商品订单详情
3 years ago
ch d11be41163 pref:下载页面
3 years ago
ch e0ce483a2b Merge branch 'fix/im-0526' into msb_test
3 years ago
ch 7d26167a30 修改im store问
3 years ago
ch 3672052d81 Merge branch 'fix/im-0526' into msb_test
3 years ago
ch 49e78efda8 IM收货消息
3 years ago
ch efaa39c832 pref:虚拟商品提交订单
3 years ago
ch 9df955e8d6 添加请求超时时间
3 years ago
张征 581a6385e5 fix:修改冲突
3 years ago
张征 3c2ff793ab merge:合并修复bug以及首页修改
3 years ago
张征 e4f8336673 fix:修改首页,修改bug
3 years ago
张征 3200e2492e Merge branch 'fix/ui-0521-zz' into msb_test
3 years ago
张征 f4a4435c8e feat:修改首页
3 years ago
ch 8e339ea56a Merge branch 'fix/code-0520-ch' into msb_test
3 years ago
ch f3deb67326 修改APP二维码为公众号二维码
3 years ago
ch dd58b90d97 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
张征 b6d530da8f fix:修改banner
3 years ago
张征 44234d4659 Merge branch 'feature/task1.0.0' into feature/task1.0.0-0507-zz
3 years ago
张征 c73b8cc2b2 fix:修改ui
3 years ago
肖广 8336805b1f Merge branch 'feature/task1.0.0' into 'msb_prod'
3 years ago
肖广 5fd5690c50 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 ff037a1bca Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'
3 years ago
xiaoguang 641ea8a7fe feat: 首页支持上拉刷新,首页固定图标位置适配屏宽,UI调整
3 years ago
ch bc378dc73d Merge branch 'feature/task1.0.0-0505-ch' into msb_prod
3 years ago
ch 112f3ac1fc Merge branch 'feature/task1.0.0-0505-ch' into msb_prod
3 years ago
ch ac257746d4 Merge branch 'feature/task1.0.0-0505-ch' into msb_test
3 years ago
肖广 e0458dd21e Merge branch 'feature/task1.0.0' into 'msb_prod'
3 years ago
张征 950a2d3699 Merge branch 'feature/task1.0.0-0507-zz' into feature/task1.0.0
3 years ago
张征 2aad2172e3 Merge branch 'feature/task1.0.0-0507-zz' into msb_test
3 years ago
张征 c14ce44b14 fix:修改收货地址
3 years ago
肖广 b6ea4af6ed Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'
3 years ago
xiaoguang ed326844ce feat: 首页分类UI调整
3 years ago
张征 84cb8d281b Merge branch 'feature/task1.0.0-0507-zz' into feature/task1.0.0
3 years ago
张征 ea82937dad fix:修改申请售后
3 years ago
张征 480fe88330 Merge branch 'msb_test' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into msb_test
3 years ago
张征 8517931645 fix:修改申请售后
3 years ago
肖广 827cb7c36b Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 7f06e29597 Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'
3 years ago
xiaoguang 4bdf753c6e feat: 点击吸顶栏搜索滚动到顶部并且输入框聚焦
3 years ago
张征 c71a4ea7bb Merge branch 'feature/task1.0.0-0507-zz' into msb_test
3 years ago
张征 15b7867528 Merge branch 'feature/task1.0.0-0507-zz' into feature/task1.0.0
3 years ago
张征 bc24c7511a fix:修改最大库存
3 years ago
肖广 2d213cf6c6 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 e5bc34804b Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'
3 years ago
xiaoguang 944a2416da feat: 替换banner图片
3 years ago
张征 a4c147c2ad Merge branch 'feature/task1.0.0' into msb_test
3 years ago
张征 971784c627 Merge branch 'feature/task1.0.0' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into feature/task1.0.0
3 years ago
张征 f40ae45a0d Merge branch 'feature/task1.0.0-0507-zz' into feature/task1.0.0
3 years ago
张征 bd881886cf fix:修改待支付
3 years ago
肖广 1b84783101 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 76d3173ad4 Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'
3 years ago
xiaoguang 3e5325fab9 feat: 添加404页面
3 years ago
张征 ae326e6f6b Merge branch 'feature/task1.0.0-0507-zz' into msb_test
3 years ago
张征 dcf0404a30 Merge branch 'feature/task1.0.0-0507-zz' into feature/task1.0.0
3 years ago
张征 c097a9251c fix:修改im
3 years ago
肖广 ca20e3a37a Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 9cb021e001 Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'
3 years ago
xiaoguang 0f9e6aa0e7 feat: 删除个人中心消息模块
3 years ago
xiaoguang e332e95afa feat: 调整UI
3 years ago
张征 67176fa1fb Merge branch 'feature/task1.0.0' into feature/task1.0.0-0507-zz
3 years ago
张征 b944477d8d fix:修改sku价格
3 years ago
张征 688fd6ea8c Merge branch 'msb_test' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into msb_test
3 years ago
张征 f8d393661f fix:修改sku价格
3 years ago
ch cf8ea99afb Merge branch 'feature/task1.0.0' into msb_test
3 years ago
ch d43b2d77da Merge branch 'feature/task1.0.0-0505-ch' into feature/task1.0.0
3 years ago
张征 fd33b79f7e Merge branch 'feature/task1.0.0' into msb_test
3 years ago
张征 37ef0f9d04 fix:修复二次添加
3 years ago
张征 09199ee816 Merge branch 'feature/task1.0.0' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into feature/task1.0.0
3 years ago
张征 1a0aa89c65 fix:修复二次添加地址
3 years ago
肖广 a9b35a9672 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
张征 1bc1a46999 fix:修改看了又看
3 years ago
张征 8f7e940158 Merge branch 'feature/task1.0.0-0507-zz' into msb_test
3 years ago
张征 d52997cc07 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 2f1c3d9ba1 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
张征 442614a67a Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 80a73d11d8 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
张征 8e1fac846f Merge branch 'msb_test' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into msb_test
3 years ago
肖广 24201b110e Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
张征 e1cfc41ebb Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 21c967e12a Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
张征 597a3c8aae Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 0ed9fc9885 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 de75b1bbaa Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
ch 73ce946530 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 17b1346ff1 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 4c47b8d78b Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
张征 a8c54f76d2 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
张征 e636883bd6 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
ch 262d51d993 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 c45d530980 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
ch 468179c860 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
张征 01d6e31ae0 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 750d1ea0f4 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 d230fab63a Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
ch 55ead5e145 Merge branch 'feature/task1.0.0-0505-ch' into msb_test
3 years ago
ch 7d0f236488 Merge branch 'feature/task1.0.0-0505-ch' into msb_test
3 years ago
肖广 f4d5383420 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
ch f3ce1e00dc Merge branch 'msb_test' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into msb_test
3 years ago
ch 1567936184 Merge branch 'feature/task1.0.0' into msb_test
3 years ago
肖广 10f2033592 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 f71938ace0 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 62e1b9ac6a Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 d16c9e002d Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 30d31c925d Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 16a70bd821 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago
肖广 d261e30fb8 Merge branch 'feature/task1.0.0' into 'msb_test'
3 years ago

@ -1,4 +1,4 @@
FROM node:12.13.1 FROM node:14.17.0
WORKDIR /workload WORKDIR /workload
COPY nuxt.config.js /workload/nuxt.config.js COPY nuxt.config.js /workload/nuxt.config.js

@ -5,30 +5,59 @@
* @LastEditTime: 2022-05-07 11:39:38 * @LastEditTime: 2022-05-07 11:39:38
* @Description: file content * @Description: file content
--> -->
# shop-pc # shop-pc
## 前置环境
由于项目依赖问题,开发 `node` 版本必须是 `14`
如果电脑安装 `Node 18`,那么怎么添多个 `node` 版本,可以使用 `nvm` 版本管理工具。具体安装可以参考下面教程
[window install nvm](https://juejin.cn/post/7074108351524634655)
[mac install nvm](https://juejin.cn/post/7206882855200047161)
## 修改前端接口请求地址
进入到 ` plugins/config/env.js` 中:
```js
// 修改对应值即可
const ENV = {
base_url: "https://k8s-horse-gateway.mashibing.cn",
imUrl: "wss://k8s-horse-gateway.mashibing.cn",
};
export default ENV;
```
> `注意 ⚠️`:通常本地开发访问线上接口地址时会出现跨越(协议、域名、端口不一样时就会出现跨越问题),此时后端服务需要配置跨域相关的内容。
## 运行&打包 ## 运行&打包
- 运行直接执行 npm run dev 打包执行npm run build 即可,会根据分支读取不同环境变量配置;
- 运行直接执行 npm run dev 打包执行 npm run build 即可,会根据分支读取不同环境变量配置;
## 环境变量配置 ## 环境变量配置
- 环境变量配置文件env.config;
- 配置与分支对应关系msb_prod -> prod msb_beta -> beta msb_test -> test msb-其他 -> dev - 环境变量配置文件 env.config;
- 配置与分支对应关系msb_prod -> prod msb_beta -> beta msb_test -> test msb-其他 -> dev
- 输出的环境变量文件plugins/config/env.js - 输出的环境变量文件plugins/config/env.js
- 修改环境变量配置后需要执行 “ node env.config " 输出的环境变量才会更新 - 修改环境变量配置后需要执行 “ node env.config " 输出的环境变量才会更新
``` js
```js
// 直接引入输出的配置文件即可 // 直接引入输出的配置文件即可
import ENV from '@/plugins/config/env.js'; import ENV from "@/plugins/config/env.js";
// 直接访问你在配置文件中定义的属性 // 直接访问你在配置文件中定义的属性
console.log(ENV.baseUrl); console.log(ENV.baseUrl);
``` ```
## 公共方法utils ## 公共方法 utils
- 公共方法统一放置utils文件夹内可以按分类建方法文件 如验证类verify.js 请求类request.js
- 公共方法统一放置 utils 文件夹内,可以按分类建方法文件 如:验证类 verify.js 请求类 request.js
- 所有公共方法采用大驼峰命名法 - 所有公共方法采用大驼峰命名法
- 所有的方法都从index.js输出引入时统一引入index不允许直接引入方法文件 - 所有的方法都从 index.js 输出,引入时统一引入 index不允许直接引入方法文件
- 所有方法文件如果导出的是多个方法,不允许在定义方法时导出,必须在文件底部一一导出,并附上方法简单的注释 - 所有方法文件如果导出的是多个方法,不允许在定义方法时导出,必须在文件底部一一导出,并附上方法简单的注释
``` js
```js
// 正确 // 正确
import {Req, IsPhone} from '@/common/utils'; import {Req, IsPhone} from '@/common/utils';
@ -46,21 +75,25 @@ export {
IsEmail IsEmail
} }
``` ```
## 组件 ## 组件
- 根目录的components 只放置真正的组件某个页面的业务模块应该在pages的相应目录下新建module目录放置
- 所有的自定义组件文件名以大驼峰命名且在templet中使用也用大驼峰形式使用(包括页面内的模块组件)
## storage的使用 - 根目录的 components 只放置真正的组件,某个页面的业务模块应该在 pages 的相应目录下新建 module 目录放置
- 不要在页面内直接使用loaclStorage全都放置到vuex中做一次管理 - 所有的自定义组件文件名以大驼峰命名,且在 templet 中使用也用大驼峰形式使用(包括页面内的模块组件)
## storage 的使用
- 不要在页面内直接使用 loaclStorage全都放置到 vuex 中做一次管理
## 请求 ## 请求
- 项目中有两个axios请求实例一个事nuxt自带的不需要Token请使用这个一个是额外封装的需要Token请使用这个
- 需要Token的请求不要写在asyncData中 - 项目中有两个 axios 请求实例,一个事 nuxt 自带的(不需要 Token 请使用这个),一个是额外封装的(需要 Token 请使用这个);
- 需要 Token 的请求,不要写在 asyncData 中;
- 所有请求方法命名以Api+请求类型+具体方) 法命名 - 所有请求方法命名以Api+请求类型+具体方) 法命名
- 所有请求使用ToAsyncAwait 包裹 - 所有请求使用 ToAsyncAwait 包裹
- 不允许使用try catch 和 then 处理返回结果 - 不允许使用 try catch 和 then 处理返回结果
``` js
```js
// 使用示例 // 使用示例
// xxapi.js // xxapi.js
import {ToAsyncAwait, ReqestTk} from '@/common/utils' import {ToAsyncAwait, ReqestTk} from '@/common/utils'
@ -71,7 +104,7 @@ export {
} }
// user.vue // user.vue
improt {ApiGetUserInfo} from '@/common/api/xxapi.js'; improt {ApiGetUserInfo} from '@/common/api/xxapi.js';
const getUserInfo = async () =>{ const getUserInfo = async () =>{
const {error, result} = await ApiGetUserInfo(); const {error, result} = await ApiGetUserInfo();
if(error){ if(error){
@ -82,46 +115,47 @@ export {
} }
``` ```
## css ## css
- 采用BEM命名法
### 兼容CSS - 采用 BEM 命名法
``` css
### 兼容 CSS
```css
/* 以下兼容方式的样式请使用util.css中的adj方法 */ /* 以下兼容方式的样式请使用util.css中的adj方法 */
.my-class{ .my-class {
transform: translate3d(-50%, 0, 0); transform: translate3d(-50%, 0, 0);
-webkit-transform: translate3d(-50%, 0, 0); -webkit-transform: translate3d(-50%, 0, 0);
-moz-transform: translate3d(-50%, 0, 0); -moz-transform: translate3d(-50%, 0, 0);
-o-transform: translate3d(-50%, 0, 0); -o-transform: translate3d(-50%, 0, 0);
-ms-transform: translate3d(-50%, 0, 0); -ms-transform: translate3d(-50%, 0, 0);
} }
/* 使用以下方法 */ /* 使用以下方法 */
@import "~/assets/scss/util.scss"; @import "~/assets/scss/util.scss";
.my-class{ .my-class {
@include adj(transform, translate3d(-50%, 0, 0)); @include adj(transform, translate3d(-50%, 0, 0));
} }
``` ```
## 登录相关 ## 登录相关
```javascript ```javascript
// 访问token // 访问token
this.$store.state.token this.$store.state.token;
// 设置token // 设置token
this.$store.commit('setToken') this.$store.commit("setToken");
// 退出登录 // 退出登录
this.$store.commit('setLoginOut') this.$store.commit("setLoginOut");
// 获取登录的用户信息 // 获取登录的用户信息
this.$store.state.userInfo this.$store.state.userInfo;
// 登录拦截 // 登录拦截
// 示例:点击购买课程前需要判断当前用户是否登录,未登录则弹出登录弹窗 // 示例:点击购买课程前需要判断当前用户是否登录,未登录则弹出登录弹窗
function onPurchaseCourse() { function onPurchaseCourse() {
if (!this.$isLoginValidate()) { if (!this.$isLoginValidate()) {
return; return;
} }
// 此处省略其他业务代码... // 此处省略其他业务代码...
} }
``` ```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -78,12 +78,13 @@
</div> </div>
<div class="address__msg-line flex flex-middle"> <div class="address__msg-line flex flex-middle">
<span class="address__msg-line--type">收货人</span> <span class="address__msg-line--type">收货人</span>
<el-input v-model="addressUser" class="min-ipt"></el-input> <el-input v-model="addressUser" class="min-ipt" maxlength="8"></el-input>
<span class="address__msg-line--type">手机号码</span> <span class="address__msg-line--type">手机号码</span>
<el-input <el-input
v-model="addressPhone" v-model="addressPhone"
oninput="value=value.replace(/[^\d]/g,'')" oninput="value=value.replace(/[^\d]/g,'')"
class="min-ipt" class="min-ipt"
maxlength="18"
></el-input> ></el-input>
</div> </div>
</article> </article>
@ -98,7 +99,7 @@
:class="isAccount ? 'clearmargin' : ''" :class="isAccount ? 'clearmargin' : ''"
> >
<UiButton <UiButton
v-if="addressList[0].id && !isAccount" v-if="addressList[0]&&addressList[0].id && !isAccount"
type="grey" type="grey"
@click="onCanceloperation()" @click="onCanceloperation()"
>取消</UiButton >取消</UiButton
@ -212,13 +213,7 @@ export default {
onCanceloperation() { onCanceloperation() {
let vm = this; let vm = this;
vm.isOperation = false; vm.isOperation = false;
vm.$set(vm.selectData.area, "value", ""); vm.clearForm();
vm.$set(vm.selectData.city, "value", "");
vm.$set(vm.selectData.province, "value", "");
vm.$set(vm, "detailAddress", "");
vm.$set(vm, "defaultAddress", "");
vm.$set(vm, "addressUser", "");
vm.$set(vm, "addressPhone", "");
vm.$emit("onSaveSuccess"); vm.$emit("onSaveSuccess");
}, },
onEdit() { onEdit() {
@ -244,6 +239,8 @@ export default {
} else { } else {
vm.defaultAddress = true; vm.defaultAddress = true;
vm.isOperation = true; vm.isOperation = true;
vm.addressList = [];
vm.$emit("getList", vm.addressList);
} }
console.log("获取收货地址", res); console.log("获取收货地址", res);
}, },
@ -274,8 +271,8 @@ export default {
}, },
async onAddAddress() { async onAddAddress() {
let vm = this; let vm = this;
let curItem = vm.addressList[vm.editIndex] let curItem = vm.addressList[vm.editIndex];
console.log(`vm.addressPhone != curItem.phone`,vm.addressPhone , curItem); console.log(`vm.addressPhone != curItem.phone`, vm.addressPhone, curItem);
if (!vm.selectData?.area?.code) { if (!vm.selectData?.area?.code) {
vm.$message.error("请选择所在区域~"); vm.$message.error("请选择所在区域~");
return; return;
@ -313,13 +310,7 @@ export default {
} }
if (!res.error) { if (!res.error) {
vm.$message.success("添加成功!"); vm.$message.success("添加成功!");
vm.$set(vm.selectData.area, "value", ""); vm.clearForm();
vm.$set(vm.selectData.city, "value", "");
vm.$set(vm.selectData.province, "value", "");
vm.$set(vm, "detailAddress", "");
vm.$set(vm, "defaultAddress", "");
vm.$set(vm, "addressUser", "");
vm.$set(vm, "addressPhone", "");
vm.$emit("onSaveSuccess"); vm.$emit("onSaveSuccess");
vm.isEdit = false; vm.isEdit = false;
vm.getAddressData(); vm.getAddressData();
@ -332,6 +323,19 @@ export default {
vm.$emit("emitAddress", item); vm.$emit("emitAddress", item);
vm.dialogVisible = false; vm.dialogVisible = false;
}, },
clearForm() {
let vm = this;
vm.$set(vm.selectData.area, "value", "");
vm.$set(vm.selectData.city, "value", "");
vm.$set(vm.selectData.province, "value", "");
vm.$set(vm.selectData.area, "code", "");
vm.$set(vm.selectData.city, "code", "");
vm.$set(vm.selectData.province, "code", "");
vm.$set(vm, "detailAddress", "");
vm.$set(vm, "defaultAddress", false);
vm.$set(vm, "addressUser", "");
vm.$set(vm, "addressPhone", "");
},
}, },
}; };
</script> </script>

@ -1,8 +1,15 @@
<!--
* @Author: ch
* @Date: 2022-05-26 10:41:45
* @LastEditors: ch
* @LastEditTime: 2022-06-15 15:43:49
* @Description: file content
-->
<template> <template>
<div class="chosen"> <div class="chosen">
<div class="chosen-title flex flex-between flex-middle"> <div class="chosen-title flex flex-between flex-middle">
<h3 class="chosen-title--txt">为你精选</h3> <h3 class="chosen-title--txt">为你精选</h3>
<div class="chosen-title--btn flex" @click="getRecommendedGoodsList()"> <div class="chosen-title--btn flex" @click="onRest()">
<img src="@/assets/img/goods/each.png" alt="切换推荐" /> <img src="@/assets/img/goods/each.png" alt="切换推荐" />
<span>换一组</span> <span>换一组</span>
</div> </div>
@ -23,6 +30,8 @@ export default {
components: { UiGoodsItem }, components: { UiGoodsItem },
data() { data() {
return { return {
pages: 0,
pageIndex: 1,
recommendedData: [], recommendedData: [],
}; };
}, },
@ -30,17 +39,21 @@ export default {
this.getRecommendedGoodsList(); this.getRecommendedGoodsList();
}, },
methods: { methods: {
onRest() {
this.pageIndex < this.pages ? this.pageIndex++ : (this.pageIndex = 1);
this.getRecommendedGoodsList();
},
async getRecommendedGoodsList() { async getRecommendedGoodsList() {
let vm = this; let vm = this;
let res = await ApiGetGoodsList({ let res = await ApiGetGoodsList({
length: 20, length: 20,
pageIndex: 1, pageIndex: vm.pageIndex,
name: "", name: "",
categoryId: "", categoryId: "",
order: "", order: "",
}); });
console.log(res.result)
vm.recommendedData = res.result.records; vm.recommendedData = res.result.records;
vm.pages = res.result.pages;
}, },
}, },
}; };

@ -0,0 +1,58 @@
<!--
* @Author: ch
* @Date: 2022-06-23 10:40:04
* @LastEditors: ch
* @LastEditTime: 2022-06-30 22:11:19
* @Description: file content
-->
<template>
<div class="follow">
<b class="follow--title">{{day}}追评:</b>
<p class="follow--ctx">{{followComment.commentContent}}</p>
<UiImgs v-if="imgs.length" :list="imgs" class="follow--imgs" />
</div>
</template>
<script>
import UiImgs from './UiImgs.vue';
export default {
components: { UiImgs },
props : {
followComment : {
type : Object,
default : () => ({})
},
commentTime : {
type : String,
default : ''
}
},
computed:{
day(){
const followTime = (new Date(this.followComment.createTime)).getTime();
const commentTime = (new Date(this.commentTime)).getTime();
const day = Math.floor((followTime - commentTime) / (24 * 60 * 60 * 1000));
return day > 0 ? `${day}天后` : `当天`;
},
imgs (){
let urls = this.followComment.pictureUrl || '';
return urls ? urls.split(',') : [];
}
}
}
</script>
<style lang="scss" scoped>
.follow{
margin-top: 30px;
&--title{
color: #FF6A19;
font-weight: normal;
}
&--ctx{
line-height: 24px;
word-break: break-all;
}
&--imgs{
margin-top: 10px;
}
}
</style>

@ -0,0 +1,408 @@
<!--
* @Author: ch
* @Date: 2022-06-24 11:43:04
* @LastEditors: ch
* @LastEditTime: 2022-07-01 18:13:33
* @Description: file content
-->
<template>
<div class="comment-info">
<div class="side-user" v-if="source == 'detail'">
<el-avatar :size="55" :src="commentDetail.userAvatar" />
<p>{{commentDetail.userName}}</p>
</div>
<div class="side-product" v-else>
<img :src="commentDetail.productPicture"/>
<p>{{commentDetail.productName}}</p>
<span>{{commentDetail.skuName}}</span>
</div>
<main>
<BsCommentSubmit v-if="!commentDetail.id" :commentDetail="commentDetail" @submit="handleSubmit"
@editStatusChange="editStatusChange"/>
<template v-else>
<div class="top">
<el-rate :value="commentDetail.commentScore" disabled/>
<span class="time">{{FormatDate(commentDetail.createTime, 'yyyy-mm-dd hh:ii')}}</span>
</div>
<p class="sku" v-if="commentDetail.skuName">{{commentDetail.skuName}}</p>
<div class="ctx">{{commentDetail.commentContent}}</div>
<!-- 图片预览 -->
<UiImgs v-if="imgs.length" :list="imgs" class="imgs" />
<!-- 追评 -->
<UiButton class="follow-btn" type="yellow_line" radius="4px"
v-if="isCanFollowComment && !showFollowForm" @click="showFollowForm = true">发起追评</UiButton>
<BsCommentSubmit v-if="showFollowForm && !followComment" :type="COMMENT.TYPE.FOLLOW_COMMENT"
:commentDetail="commentDetail" @submit="handleSubmitFollow" @editStatusChange="editStatusChange"/>
<BsCommentFollowInfo v-if="followComment"
:followComment="followComment" :commentTime="commentDetail.commentTime"/>
<!-- 点赞评论Bar -->
<div class="operation">
<div>
<span class="operation--chat" @click="answerVisible = !answerVisible">
<template v-if="replyCount">{{replyCount}}</template>
</span>
<span class="operation--show" v-if="answerCommentList.length" @click="answerVisible = !answerVisible">
{{answerVisible ? '收起' : '展开'}}
</span>
</div>
<span class="operation--thumb" :class="{'operation--thumb__active':isLike}" @click="handleUseful">{{usefulCount || ''}}</span>
</div>
<!-- 评论内容 -->
<div class="answer" v-if="showAnswerBox">
<b class="answer--title">全部评论({{replyCount}})</b>
<ul>
<li class="answer--item" v-if="commentDetail.merchantComment">
<div class="answer--name"><b>{{commentDetail.merchantComment.userName}}</b><span>{{commentDetail.merchantComment.createTime}}</span></div>
<p class="answer--ctx">{{commentDetail.merchantComment.commentContent}}</p>
</li>
<template v-if="answerVisible">
<li class="answer--item" v-for="(item, idx) in answerCommentList" :key="idx">
<div class="answer--name">
<b>{{item.userName}} {{item.parentId !== commentDetail.id ? ` 回复 ${item.parentUserName}` : ''}}</b>
<span>{{FormatDate(item.createTime, 'yyyy-mm-dd hh:ii')}}</span>
</div>
<p class="answer--ctx">{{item.commentContent}}</p>
<span class="answer--answer" @click="handleAnswer(item)"></span>
</li>
</template>
</ul>
<div v-if="answerVisible" class="answer--form">
<input v-model="answerContent" class="answer--input" maxlength="500"
@keydown="handleClearAnswer" :placeholder="answerPlaceholder"/>
<UiButton :disabled="!answerContent.trim()" @click="handleSubmitAnswer"
radius="4px" class="answer--btn" type="red_panel">发表</UiButton>
</div>
</div>
</template>
</main>
</div>
</template>
<script>
import BsCommentFollowInfo from './BsCommentFollowInfo.vue';
import {ApiPostComment, ApiPutCommentUseful} from '@/plugins/api/comment';
import {Debounce, FormatDate } from '@/plugins/utils';
import UiImgs from './UiImgs.vue';
import UiButton from './UiButton.vue';
import BsCommentSubmit from './BsCommentSubmit.vue';
import {COMMENT} from '@/constants'
export default {
components: { BsCommentFollowInfo, UiImgs, UiButton, BsCommentSubmit },
props:{
// commentdetail
source:{
type : String,
default : 'comment'
},
//
isFollowForm : {
type : Boolean,
default : false,
require : true
},
commentDetail : {
type : Object,
default : () => ({})
}
},
data(){
return {
COMMENT,
answerCommentList : this.commentDetail.answerCommentList || [],
answerVisible : false,
answerContent : '',
answer : null,
isLike : this.commentDetail.isLike,
usefulCount : this.commentDetail.usefulCount,
replyCount : this.commentDetail.replyCount,
showFollowForm : this.isFollowForm,
followComment : this.commentDetail.followComment || null
}
},
computed:{
showAnswerBox(){
return (this.commentDetail.merchantComment || this.answerVisible) ? true : false
},
answerPlaceholder (){
return this.answer ? `回复:${this.answer.userName}` : '说点什么吧?'
},
imgs (){
let imgs = this.commentDetail.pictureUrl;
return imgs ? imgs.split(',') : [];
},
/**
* 是否需要显示追评按钮
* 如果是在订单里进来的且没有追评则显示
*/
isCanFollowComment(){
let status = (!this.followComment && this.source === 'comment')
return status;
}
},
watch:{
commentDetail:{
handler(){
this.followComment = this.commentDetail.followComment;
this.replyCount = this.commentDetail.replyCount || 0;
this.answerCommentList = this.commentDetail.answerCommentList || [];
this.isLike = this.commentDetail.isLike;
this.usefulCount = this.commentDetail.usefulCount;
},
deep : true
}
},
mounted(){
this.answerCommentList = this.commentDetail.answerCommentList || [];
},
methods : {
FormatDate,
/**
* 评价成功后抛出事件方便父组件做数据处理
*/
handleSubmit(result){
this.$emit('submit', result)
},
/**
* 追评提交成功抛出事件方便父组件做数据处理
*/
handleSubmitFollow(result){
this.followComment = result;
},
handleAnswer (item){
this.answer = item;
},
/**
* 有回复用户时取消回复对象
* 输入框没有内容后再按一次退格删除回复对象直接回复评价
*/
handleClearAnswer(e){
if(e.code === 'Backspace' && !this.answerContent && this.answer){
this.answer = null;
}
},
/**
* 评论回复请求成功往列表添加一条记录
*/
async handleSubmitAnswer(){
let data = {
commentContent : this.answerContent,
commentType : 3,
originId : this.commentDetail.id,
parentId : this.answer ? this.answer.id : this.commentDetail.id
}
const {error, result} = await ApiPostComment(data);
if(error){
this.$message.error(error.message);
return false
}
this.answerCommentList.unshift({
...result,
userName : this.$store.state.userInfo.nickname,
parentUserName: this.answer ? this.answer.userName : ''
});
this.answerContent = '';
this.replyCount++;
this.$message.success('评论成功!');
},
/**
* 点击点赞做防抖处理
*/
handleUseful(){
this.isLike = !this.isLike
if(this.isLike){
this.usefulCount++;
}else{
this.usefulCount--;
}
if(!this.debounce){
this.debounce = Debounce(this.updateUseFul, 500);
}
this.debounce();
},
/**
* 更新点赞请求
*/
async updateUseFul(){
if(this.isLike === this.commentDetail.isLike){
return false
}
const {error, result} = await ApiPutCommentUseful({
commentId : this.commentDetail.id,
isLike : this.isLike
});
this.commentDetail.isLike = this.isLike;
},
/**
* 动态监听是否有输入内容的评价或追评
*/
editStatusChange(val){
this.$emit('editStatusChange', val)
}
}
}
</script>
<style lang="scss" scoped>
.comment-info{
display: flex;
border-top: 1px solid #f2f2f2;
padding: 35px 20px 50px 0;
main{
flex: 1;
}
}
.side-user{
width: 170px;
text-align: center;
p{
margin-top: 10px;
@include ellipses(2)
}
}
.side-product{
width: 230px;
padding: 0 45px;
text-align: left;
img{
width: 140px;
height: 140px;
object-fit: contain;
}
p{
margin-top: 10px;
@include ellipses(2);
}
span{
margin-top: 5px;
display: block;
color: #999;
font-size: 12px;
}
}
.top{
display: flex;
justify-content: space-between;
margin-bottom: 10px;
/deep/.el-rate__icon{
margin-right: 0;
font-size: 24px;
}
}
.time, .sku{
color: #999;
font-size: 12px;
}
.ctx{
word-break: break-all;
line-height: 24px;
margin-top: 8px;
}
.imgs{
margin-top: 10px;
}
.follow-btn{
margin-top:30px
}
.follow{
margin-top: 30px;
&--title{
color: #FF6A19;
font-weight: normal;
}
}
.operation{
color: #999;
display: flex;
justify-content: space-between;
margin-top: 30px;
&--show{
color: #3083FF;
margin-left: 28px;
cursor: pointer;
}
&--chat,&--thumb{
background: url('@/assets/img/comment/chat.png') no-repeat left center;
background-size: 16px;
padding-left: 24px;
cursor: pointer;
&__active,&:hover{
background-image: url('@/assets/img/comment/chat_active.png');
color: #FF6A19;
}
}
&--thumb{
background-image: url('@/assets/img/comment/thumb.png');
&__active,&:hover{
background-image: url('@/assets/img/comment/thumb_active.png');
}
}
}
.answer{
background: #F8F8F8;
margin-top: 14px;
padding: 0 24px 20px;
&--item{
border-top: 1px solid #eee;
padding: 20px 0;
}
&--title{
height: 54px;
line-height: 54px;
font-weight: normal;
color: #666;
}
&--name{
color: #999;
font-size: 12px;
display: flex;
justify-content: space-between;
}
&--ctx{
color: #666;
margin: 15px 0 0;
word-break: break-all;
}
&--answer{
font-size: 12px;
color: #666;
text-align: right;
cursor: pointer;
display: block;
}
&--form{
display: flex;
}
&--input{
flex: 1;
height: 40px;
border: 1px solid #eee;
border-radius: 4px;
margin-right: 15px;
padding: 0 20px;
}
&--btn{
height: 40px;
font-size: 14px;
}
/deep/.ui-button__disabled{
background: #eee;
color: #999;
}
}
</style>

@ -0,0 +1,205 @@
<!--
* @Author: ch
* @Date: 2022-06-25 15:29:43
* @LastEditors: ch
* @LastEditTime: 2022-06-30 22:53:16
* @Description: file content
-->
<template>
<div class="submit">
<p class="rate-box" v-if="type === COMMENT.TYPE.COMMENT">
<b>满意度评分</b>
<el-rate v-model="rate"></el-rate>
<span>{{reteDesc}}</span>
</p>
<el-input type="textarea" class="textarea" placeholder="从多个维度评价,可以帮助更多想买的人哦~"
v-model="commentContent" show-word-limit :maxlength="500" :rows="6"/>
<div class="operation">
<el-upload list-type="picture-card"
:on-remove="handleRemove" :limit="6"
:action="uploadAction" :data="uploadData"
:before-upload="handleBeforeUpload"
:on-exceed="handleUploadExceed"
:on-error="handleUploadError">
<i class="el-icon-plus"></i>
<p class="upload-txt">我要晒图</p>
</el-upload>
<UiButton class="upload-btn" :disabled="isDisabled" @click="handleSubmit"></UiButton>
</div>
</div>
</template>
<script>
import {ApiPostComment} from '@/plugins/api/comment';
import {ApiPostGetOssConfig} from '@/plugins/api/oss';
import {COMMENT} from '@/constants';
export default {
props : {
type : {
type : String | Number,
default : COMMENT.TYPE.COMMENT
},
commentDetail : {
type : Object,
default : () => ({})
}
},
data(){
return {
COMMENT,
rate: 5,
commentContent : '',
uploadData : {},
uploadAction : '',
fileList : []
}
},
computed:{
isEdit(){
return (this.commentContent || this.fileList.length > 0) ? true : false
},
reteDesc(){
return COMMENT.RATE_LEVEL[this.rate];
},
isDisabled(){
let status = false
if(this.type === COMMENT.TYPE.COMMENT){
status = !this.rate || !this.commentContent.trim();
}
if(this.type === COMMENT.TYPE.FOLLOW_COMMENT){
status = !this.commentContent.trim();
}
return status;
}
},
watch : {
isEdit(val){
this.$emit('editStatusChange', val)
}
},
methods : {
async handleSubmit(){
let data = {
commentContent : this.commentContent,
commentType : this.type,
orderProductId : this.commentDetail.orderProductId,
pictureUrl : this.fileList.map(i => i.url).join(',')
}
if(this.type === COMMENT.TYPE.COMMENT){
data.productId = this.commentDetail.productId;
data.commentScore = this.rate;
}else if(this.type === COMMENT.TYPE.FOLLOW_COMMENT){
data.originId = data.parentId = this.commentDetail.id;
}
const {error, result} = await ApiPostComment(data);
if(error){
this.$message.error(error.message);
return false;
}
this.commentContent = '';
this.fileList = [];
this.$nextTick(()=>{
this.$emit('submit',result);
})
},
/**
* 获取OSS鉴权信息
* configId 自定义文件夹 图片存储的文件夹名称
* serviceName 服务名
*/
async getOssCon(){
const {error, result} = await ApiPostGetOssConfig({
configId : 'account-comment/',
serviceName : 'comment'
});
if(error){
this.$message.error(error.message);
return false
}
return result
},
async handleBeforeUpload(file) {
let result = await this.getOssCon();
if(result){
this.uploadAction = result.host;
this.uploadData = {
...this.uploadData,
policy : result.policy,
OSSAccessKeyId: result.accessId,
success_action_status: 200,
signature: result.signature,
}
}
Object.assign(this.uploadData, {
key: `${result.dir}${"${filename}"}`,
name: file.name,
});
this.fileList.push({
url : `${result.host}/${result.dir}${file.name}`,
uid : file.uid
})
},
handleUploadError(error, file) {
this.handleRemove(file)
},
handleRemove(file) {
this.fileList = this.fileList.filter(i => i.uid != file.uid );
},
handleUploadExceed(){
this.$message.warning('最多只能上传6张照片哦~')
}
}
}
</script>
<style lang="scss" scoped>
.rate-box{
display: flex;
b{
font-weight: normal;
margin-right: 10px;
color: #666;
}
span{
color: #FF6A19;
margin-left: 10px;
}
}
.textarea{
height: 138px;
margin-top: 30px;
}
.operation{
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
.upload-txt{
font-size: 12px;
color: #999;
}
.upload-btn{
height: 40px;
width: 100px;
border-radius: 4px;
font-size: 14px;
padding: 0;
}
}
/deep/{
.el-upload--picture-card,.el-upload-list__item{
height: 70px !important;
width: 70px !important;
line-height: 20px;
}
.el-upload--picture-card{
padding-top: 10px;
}
}
</style>

@ -64,6 +64,7 @@ import { mapState } from "vuex";
import { Message } from "element-ui"; import { Message } from "element-ui";
import { ApiGetCode, ApiPostLogin } from "@/plugins/api/account"; import { ApiGetCode, ApiPostLogin } from "@/plugins/api/account";
import { IsPhone } from "/plugins/utils"; import { IsPhone } from "/plugins/utils";
import {Im, ImInit} from '@/plugins/chat'
const COUNT_DOWN_TIME = 60; // const COUNT_DOWN_TIME = 60; //
export default { export default {
@ -167,7 +168,12 @@ export default {
this.dialogVisible = false; this.dialogVisible = false;
this.$store.commit("setToken", result.token); this.$store.commit("setToken", result.token);
this.$store.dispatch("getUserInfo"); this.$store.dispatch("getUserInfo");
this.$startWebSockets() // this.$startWebSockets()
// IM
ImInit().then(() => {
//
Im.getSessionList();
});
} }
} }
}); });

@ -2,30 +2,45 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-08 00:39:50 * @Date: 2022-05-08 00:39:50
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-12 11:44:04 * @LastEditTime: 2022-07-11 11:32:27
* @Description: file content * @Description: file content
--> -->
<template> <template>
<el-dialog title="打开微信扫描付款" width="380px" class="box" center <el-dialog :title="title" width="380px" class="box" center
:visible.sync="myVisible" @open="open" @close="close"> :visible.sync="myVisible" @open="open" @close="close" :modal="false">
<div class="pay"> <div class="pay-type" v-if="!myPayType">
<el-radio-group v-model="myPayType">
<el-radio label="wx" class="pay-type--item" >
<img class="pay-type--wx" src="@/assets/img/order/wx.png"/>
</el-radio>
<el-radio label="ali" class="pay-type--item" >
<img class="pay-type--ali" src="@/assets/img/order/zfb.png"/>
</el-radio>
</el-radio-group>
</div>
<div class="pay" v-else>
<span class="pay--timer">{{timerTxt}}</span> <span class="pay--timer">{{timerTxt}}</span>
<UiMoney class="money" sufSize="14px" preSize="14px" size="20px" <UiMoney class="money" sufSize="14px" preSize="14px" size="20px"
float suffix prefix :money="orderInfo.payAmount"/> float suffix prefix :money="orderInfo.payAmount"/>
<div class="pay--code"> <div class="pay--code">
<img :src="imgUrl" v-if="imgUrl"/> <img :src="imgUrl" v-if="imgUrl"/>
<!-- <p v-if="!timer"></p> --> <span v-else>{{imgTip}}</span>
</div> </div>
<p class="pay--tips">如支付后没有自动跳转请点击 <span class="pay--finish" @click="finish"></span></p> <p class="pay--tips">如支付后没有自动跳转请点击 <span class="pay--finish" @click="finish"></span></p>
<UiButton class="pay--btn" type='yellow_gradual' @click="back"></UiButton>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script> <script>
import {ApiPostPayCdoeImg} from '@/plugins/api/wx' import {ApiPostWxPayCdoeImg, ApiPostAliPayCdoeImg} from '@/plugins/api/pay'
import {ApiGetOrderDetail} from '@/plugins/api/order' import {ApiGetOrderDetail} from '@/plugins/api/order'
import UiMoney from './UiMoney.vue' import UiMoney from './UiMoney.vue';
import UiButton from './UiButton.vue';
import QRcode from 'qrcode';
import {CreateUUID} from '@/plugins/utils';
export default { export default {
components: { UiMoney }, components: { UiMoney, UiButton },
props : { props : {
visible : { visible : {
type : Boolean, type : Boolean,
@ -34,15 +49,30 @@ export default {
orderId : { orderId : {
type : Number | String, type : Number | String,
default : '' default : ''
},
payType:{
type : String | null,
require : true
} }
}, },
data(){ data(){
return { return {
orderInfo: {}, orderInfo: {},
imgUrl : '', imgUrl : '',
imgTip : '二维码获取中',
timerTxt : '', timerTxt : '',
startSecondNum : 0, startSecondNum : 0,
timerStop : null, timerStop : null,
myPayType : null,
payUUID : null
}
},
watch:{
myPayType(val){
// change使watch
if(val){
this.getQrCode();
}
} }
}, },
computed:{ computed:{
@ -53,12 +83,25 @@ export default {
set(val){ set(val){
this.$emit('update:visible', val) this.$emit('update:visible', val)
} }
},
title(){
let str = '请选择支付方式';
if(this.myPayType === 'wx'){
str = '打开微信扫描付款';
}else if(this.myPayType === 'ali'){
str = '打开支付宝扫描付款';
};
return str;
} }
}, },
methods : { methods : {
open(){ open(){
this.getOrderInfo(); this.getOrderInfo();
this.getCodeImg(); this.myPayType = this.payType;
if(this.myPayType){
this.getQrCode();
}
}, },
/** /**
* 获取订单最新信息 * 获取订单最新信息
@ -80,12 +123,52 @@ export default {
} }
}, },
async getCodeImg(){ getQrCode(){
const {error, result} = await ApiPostPayCdoeImg({orderId : this.orderId});
this.payUUID = CreateUUID();
if(this.myPayType == 'wx'){
this.getWxCodeImg(this.payUUID);
}else if(this.myPayType === 'ali'){
this.getAliCodeImg(this.payUUID);
}
},
/**
* 支付宝二维码
*/
async getAliCodeImg(uid){
const {error, result} = await ApiPostAliPayCdoeImg({orderId : this.orderId});
if(this.payUUID !== uid){
return false;
}
if(error){ if(error){
this.imgTip = error.message;
return false; return false;
} }
this.imgUrl = result.dataInfo.codeImgData; QRcode.toDataURL(result.payDataInfo.qrCodeData,{
width : 200
}, (err, url)=>{
this.imgUrl = url;
})
},
/**
* 微信二维码
*/
async getWxCodeImg(uid){
const {error, result} = await ApiPostWxPayCdoeImg({orderId : this.orderId});
if(this.payUUID !== uid){
return false;
}
if(error){
this.imgTip = error.message;
return false;
}
QRcode.toDataURL(result.payDataInfo.codeUrlData,{
width : 200
}, (err, url)=>{
this.imgUrl = url;
})
}, },
/** /**
@ -116,22 +199,62 @@ export default {
close(){ close(){
clearInterval(this.timerStop); clearInterval(this.timerStop);
this.timerStop = null; this.timerStop = null;
this.myPayType = this.payType;
this.$emit('cancel'); this.$emit('cancel');
}, },
finish(){ finish(){
this.myVisible = false; this.myVisible = false;
this.$emit('finish') this.$emit('finish')
},
back(){
this.myPayType = null;
this.imgUrl = null;
this.imgTip = '二维码获取中'
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box{
background: rgba(0,0,0, .5);
}
.pay-type{
width: 270px;
padding: 0 30px;
&--item{
width: 270px;
height: 56px;
display: flex;
align-items: center;
border: 1px solid #ccc;
padding-left: 55px;
margin-bottom: 20px;
}
&--wx{
width: 108px;
}
&--ali{
width: 78px;
}
}
.pay{ .pay{
text-align: center; text-align: center;
&--code{ &--code{
width: 160px; width: 160px;
height: 160px; height: 160px;
margin: 15px auto 20px; margin: 15px auto 20px;
position: relative;
overflow: hidden;
img{
width: 200px;
position: absolute;
left: -20px;
top: -20px;
}
span{
line-height: 100px;
color: #999;
}
} }
&--timer{ &--timer{
color: #999; color: #999;
@ -145,6 +268,12 @@ export default {
color: #FF512B; color: #FF512B;
cursor: pointer; cursor: pointer;
} }
&--btn{
border-radius: 4px;
width: 143px;
height: 32px;
margin-top: 20px;
}
} }
.money{ .money{
color: #FF512B; color: #FF512B;

@ -51,24 +51,30 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-item { .goods-item {
width: 232px; width: 228px;
height: 340px; height: 320px;
cursor: pointer; cursor: pointer;
background: #ffffff; background: #ffffff;
transition: all 0.3s;
padding: 30px;
&:hover { &:hover {
box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.10000000149011612); box-shadow: 0px 4px 40px 1px rgba(0, 0, 0, 0.10000000149011612);
margin-top: -3px;
} }
&__img { &__img {
width: 232px; width: 130px!important;
height: 232px; height: 130px;
display: block;
margin: 0 auto 44px;
} }
&__title { &__title {
width: 200px; width: 170px;
height: 45px; height: 45px;
line-height: 22px; line-height: 22px;
margin: 17px auto 10px; // margin: 17px auto 10px;
margin-bottom: 10px;
font-size: 14px; font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
@ -80,12 +86,15 @@ export default {
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
&-label { &-label {
display: inline-block; display: inline-block;
padding: 2px 8px; width: 40px;
background: rgba(255, 135, 91, 0.1); height: 18px;
text-align: center;
line-height: 18px;
background: #FF6A19;
font-size: 12px; font-size: 12px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
color: #ff875b; color: #fff;
text-align: center; text-align: center;
margin-right: 8px; margin-right: 8px;
} }
@ -95,7 +104,7 @@ export default {
margin: 0 auto; margin: 0 auto;
&--txt { &--txt {
font-size: 14px; font-size: 16px;
color: #ff512b; color: #ff512b;
&::before { &::before {
content: "¥"; content: "¥";

@ -0,0 +1,137 @@
<!--
* @Author: ch
* @Date: 2022-06-24 19:07:45
* @LastEditors: ch
* @LastEditTime: 2022-06-30 19:40:36
* @Description: file content
-->
<template>
<div class="preview-imgs">
<ul>
<li v-for="(i, idx) in list" :key="idx" :class="{'active' : curIndex == idx}" >
<img :src="i" @click="curIndex = idx"/>
</li>
</ul>
<p v-if="curIndex > -1">
<img :src="list[curIndex]" @click="curIndex = -1"/>
<span class="prev" @click="prev" v-if="curIndex > 0"></span>
<span class="next" @click="next" v-if="curIndex < list.length-1"></span>
</p>
</div>
</template>
<script>
export default {
props : {
list : {
type : Array,
default : () => ([])
}
},
data(){
return {
curIndex : -1,
}
},
methods:{
next(){
this.curIndex++;
},
prev(){
this.curIndex--;
}
}
}
</script>
<style lang="scss" scoped>
.preview-imgs{
ul{
display: flex;
}
li{
width: 46px;
height : 46px;
border: 1px solid #eee;
margin-right: 10px;
padding: 1px;
cursor: pointer;
img{
width: 42px;
height: 42px;
object-fit: contain;
}
&.active{
border-color: #FF512B;
position: relative;
&::after{
content: '';
height: 3px;
width: 3px;
bottom: -7px;
left: 17px;
display: block;
position: absolute;
// transform: rotate(45deg);
border: 3px solid #FF512B;
border-left-color: transparent;
border-right-color: transparent;
border-bottom-color: transparent;
}
}
}
p{
width: 300px;
margin-top: 20px;
position: relative;
border: 1px solid #eee;
img{
width: 300px;
height: 300px;
object-fit: contain;
cursor: zoom-out;
}
&:hover span{
display: block;
}
span{
display: none;
position: absolute;
width: 40px;
height: 40px;
background: rgba(0,0,0, .5);
top : 130px;
cursor: pointer;
&::after,&::before{
position: absolute;
display: block;
content: '';
background: #fff;
height: 20px;
width: 4px;
border-radius: 4px;
left: 16px;
top: 4px;
transform: rotate(45deg);
}
&::after{
transform: rotate(-45deg);
top: 16px;
}
&.prev{
left: 10px;
}
&.next{
right: 10px;
&::after{
left: 20px;
transform: rotate(45deg);
}
&::before{
left: 20px;
transform: rotate(-45deg);
}
}
}
}
}
</style>

@ -1,15 +1,26 @@
/*
* @Author: ch
* @Date: 2022-05-17 18:17:00
* @LastEditors: ch
* @LastEditTime: 2022-06-27 16:20:31
* @Description: file content
*/
/** /**
* 全局常量请避免使用魔法数字 * 全局常量请避免使用魔法数字
*/ */
// 用户凭证名 // 用户凭证名
const TOKEN_KEY = "msbPcToken"; const TOKEN_KEY = "msbPcToken";
const UUID_KEY = "msbPcUuid";
// 订单状态 // 订单状态
const ORDER_STATUS = { const ORDER_STATUS = {
WAIT_PAY: 1, // 待付款 WAIT_PAY: 1, // 待付款
WAIT_SEND: 3, //待发货 WAIT_SEND: 3, //待发货
WAIT_RECEIVE: 4, // 待收货 WAIT_RECEIVE: 4, // 待收货
WAIT_COMMENT: 5,//评价
FINISH: 6,
FINISH_FOLLOW_COMMENT : 7
}; };
// 性别 // 性别
@ -30,5 +41,23 @@ const SECKILL_STATUS = {
NOT_START: 1, // 未开始 NOT_START: 1, // 未开始
GOING: 2, // 进行中 GOING: 2, // 进行中
}; };
const COMMENT = {
TYPE: {
// 评价
COMMENT: 1,
// 追评
FOLLOW_COMMENT: 2,
// 回复
ANSWER: 3,
},
RATE_LEVEL: {
1 : '很不满意',
2 : '不太满意',
3 : '一般',
4 : '满意',
5 : '非常满意'
}
}
export { TOKEN_KEY, ORDER_STATUS, SEX_TYPE, CATEGROY_LEVEL, SECKILL_STATUS }; export { TOKEN_KEY, UUID_KEY, ORDER_STATUS, SEX_TYPE, CATEGROY_LEVEL, SECKILL_STATUS, COMMENT };

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-05 14:40:00 * @Date: 2022-05-05 14:40:00
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-07 10:51:53 * @LastEditTime: 2022-06-24 14:21:20
* @Description: 根据git分支生成对应环境的环境变量 * @Description: 根据git分支生成对应环境的环境变量
* 开发时如果环境变量换了可以不用重启服务直接运行node env.config.js即可 * 开发时如果环境变量换了可以不用重启服务直接运行node env.config.js即可
*/ */
@ -12,19 +12,22 @@ const getRepoInfo = require('git-repo-info');
const envConfig = { const envConfig = {
dev : { dev : {
base_url: 'https://k8s-horse-gateway.mashibing.cn' base_url: 'https://k8s-horse-gateway.mashibing.cn',
imUrl : 'wss://k8s-horse-gateway.mashibing.cn'
}, },
test : { test : {
base_url: 'https://k8s-horse-gateway.mashibing.cn' base_url: 'https://k8s-horse-gateway.mashibing.cn',
imUrl : 'wss://k8s-horse-gateway.mashibing.cn'
}, },
beta : { beta : {
base_url: 'https://you-gateway.mashibing.com' base_url: 'https://you-gateway.mashibing.com',
imUrl : 'wss://you-gateway.mashibing.com'
}, },
prod : { prod : {
base_url: 'https://you-gateway.mashibing.com' base_url: 'https://you-gateway.mashibing.com',
imUrl : 'wss://you-gateway.mashibing.com'
} }
} }
const branch = getRepoInfo().branch; // 调用获取git信息
let curEnvConfig = null; let curEnvConfig = null;
const argv = global.process.argv; const argv = global.process.argv;
for(key in envConfig){ for(key in envConfig){

@ -2,14 +2,16 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:56:39 * @Date: 2022-05-04 17:56:39
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-08 15:53:49 * @LastEditTime: 2022-06-25 10:10:25
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div class="layout"> <div class="layout">
<BsLogin :visible.sync="loginVisible" /> <BsLogin :visible.sync="loginVisible" />
<Header :is-sticky="isSticky" /> <Header :is-sticky="isSticky" />
<Nuxt /> <div class="layout-content">
<Nuxt />
</div>
<Footer /> <Footer />
</div> </div>
</template> </template>
@ -50,3 +52,10 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss" scoped>
.layout {
.layout-content {
min-height: calc(100vh - 400px);
}
}
</style>

@ -0,0 +1,60 @@
<!--
* @Author: ch
* @Date: 2022-05-04 17:56:39
* @LastEditors: ch
* @LastEditTime: 2022-06-02 17:49:00
* @Description: file content
-->
<template>
<div class="layout">
<BsLogin :visible.sync="loginVisible" />
<Header :is-sticky="isSticky" />
<div class="layout-content">
<Nuxt />
</div>
</div>
</template>
<script>
import BsLogin from "@/components/BsLogin.vue";
import Header from "./module/header/index.vue";
import Footer from "./module/footer/index.vue";
export default {
name: "down",
components: { Header, Footer, BsLogin },
data() {
return {
isSticky: false,
};
},
computed: {
loginVisible: {
get() {
return this.$store.state.loginVisible;
},
set(val) {
this.$store.commit("setLoginVisible", val);
},
},
},
mounted() {
//
window.addEventListener("scroll", this.scrollEventMethod);
},
destroyed() {
window.removeEventListener("scroll", this.scrollEventMethod);
},
methods: {
scrollEventMethod() {
this.isSticky = window.scrollY > 300;
},
},
};
</script>
<style lang="scss" scoped>
.layout {
.layout-content {
min-height: calc(100vh - 400px);
}
}
</style>

@ -0,0 +1,51 @@
<template>
<div class="error-page flex flex-middle flex-center">
<img class="error-page-cover" src="~/assets/img/layout/error.png" />
<div class="error-page-content">
<div>此页面不存在或找不到</div>
<div class="error-page-content__tip">
<p>检查您的网址是否拼写正确</p>
<p>检查您是否使用了错误的网址转接</p>
</div>
<UiButton :radius="true" type="yellow_gradual" @click="onJumpHomePage"
>回到首页</UiButton
>
</div>
</div>
</template>
<script>
import UiButton from "@/components/UiButton";
export default {
name: "ErrorPage",
components: { UiButton },
methods: {
onJumpHomePage() {
this.$router.replace("/");
},
},
};
</script>
<style lang="scss" scoped>
.error-page {
height: calc(100vh - 400px);
.error-page-cover {
width: 286px;
height: 254px;
margin-right: 109px;
}
.error-page-content {
font-size: 20px;
color: #666666;
}
.error-page-content__tip {
font-size: 14px;
line-height: 20px;
color: #999999;
margin: 30px 0;
}
/deep/.ui-button {
width: 121px;
height: 30px;
}
}
</style>

@ -17,7 +17,9 @@
<div class="layout-footer-wrap__line"></div> <div class="layout-footer-wrap__line"></div>
<div class="layout-footer-wrap__address"> <div class="layout-footer-wrap__address">
© 2020 马士兵北京教育科技有限公司 © 2020 马士兵北京教育科技有限公司
地址北京市海淀区北三环中路44号4号楼1层114 京ICP备17012835号-1 地址北京市海淀区北三环中路44号4号楼1层114 京ICP备17012835号-1
<a href="https://oss-cdn.mashibing.com/teacher_attachment/user_00020172/yyzz.jpg" target="_blank">营业页执照</a>
<a href="https://oss-cdn.mashibing.com/default/cbwxkz.jpg" target="_blank">出版物经营许可证新出发京零字第海210140号</a>
</div> </div>
</div> </div>
</div> </div>
@ -89,6 +91,9 @@ export default {
color: #999999; color: #999999;
text-align: center; text-align: center;
line-height: 20px; line-height: 20px;
a{
color: #999;
}
} }
} }
} }

@ -13,7 +13,6 @@
@click="onJumCartPage" @click="onJumCartPage"
> >
<img src="~/assets/img/layout/icon-shop.png" /> <img src="~/assets/img/layout/icon-shop.png" />
<span>购物车</span>
<div <div
v-if="cartCount > 0" v-if="cartCount > 0"
class="wrap-right-cart__tip flex flex-middle flex-center" class="wrap-right-cart__tip flex flex-middle flex-center"
@ -43,7 +42,7 @@
</div> </div>
<div class="products-wrap-info__bottom flex flex-between"> <div class="products-wrap-info__bottom flex flex-between">
<span class="wrap-info-bottom__skuname">{{ <span class="wrap-info-bottom__skuname">{{
item.productSku.name item.productSku ? item.productSku.name : '--'
}}</span> }}</span>
<span class="wrap-info-bottom__count">{{ item.number }}</span> <span class="wrap-info-bottom__count">{{ item.number }}</span>
</div> </div>
@ -76,7 +75,7 @@
</div> </div>
<div class="products-wrap-info__bottom flex flex-between"> <div class="products-wrap-info__bottom flex flex-between">
<span class="wrap-info-bottom__skuname">{{ <span class="wrap-info-bottom__skuname">{{
item.productSku.name item.productSku ? item.productSku.name : '--'
}}</span> }}</span>
<span class="wrap-info-bottom__count">{{ item.number }}</span> <span class="wrap-info-bottom__count">{{ item.number }}</span>
</div> </div>
@ -145,31 +144,26 @@ export default {
}, },
methods: { methods: {
onJumpGoodsDetail(id) { onJumpGoodsDetail(id) {
this.$router.push(`/goods/detail/${id}`); window.open(`${location.origin}/goods/detail/${id}`);
}, },
onJumCartPage() { onJumCartPage() {
if (!this.$isLoginValidate()) { if (!this.$isLoginValidate()) {
return; return;
} }
this.$router.push("/cart"); window.open(`${location.origin}/cart`);
}, },
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.header-cart-popover { .header-cart-popover {
padding: 16px 20px !important; padding: 16px 20px 50px 20px !important;
} }
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.header-cart-popover__refrence { .header-cart-popover__refrence {
padding: 0 18px;
height: 42px;
line-height: 42px;
color: #999999;
border-radius: 4px;
border: 1px solid #eeeeee;
cursor: pointer; cursor: pointer;
position: relative;
.wrap-right-cart__tip { .wrap-right-cart__tip {
width: 16px; width: 16px;
height: 16px; height: 16px;
@ -177,12 +171,16 @@ export default {
background: #ff512b; background: #ff512b;
border-radius: 50%; border-radius: 50%;
color: #ffffff; color: #ffffff;
margin-left: 4px; left: 10px;
padding-top: 2px; top: -7px;
position: absolute;
&--more { &--more {
width: unset; // width: unset;
padding: 2px 5px 0 4px; top: -8px;
right: 0px;
padding: 5;
border-radius: 7px; border-radius: 7px;
position: absolute;
} }
} }
img { img {
@ -192,17 +190,19 @@ export default {
} }
} }
.header-cart-popover { .header-cart-popover {
padding: 20px 16px;
.header-cart-products { .header-cart-products {
padding: 0 10px 20px 0;
max-height: 360px; max-height: 360px;
overflow: auto; overflow: auto;
padding: 0 10px 16px 0;
&--failure-color { &--failure-color {
color: #999999 !important; color: #999999 !important;
} }
.header-cart-products__wrap { .header-cart-products__wrap {
margin-bottom: 20px; margin-bottom: 20px;
cursor: pointer; cursor: pointer;
&:last-child {
margin-bottom: 0;
}
.cart_products-wrap_cover { .cart_products-wrap_cover {
width: 60px; width: 60px;
height: 60px; height: 60px;

@ -2,23 +2,21 @@
<div class="header-category"> <div class="header-category">
<!-- 热门分类 --> <!-- 热门分类 -->
<div <div
v-show="showCategroyTab"
class="header-box-tab__category" class="header-box-tab__category"
@mouseenter="handleCategoryChange(true)" @mouseenter="handleCategoryChange(true)"
@mouseleave="handleCategoryChange(false)" @mouseleave="handleCategoryChange(false)"
> >
<div class="tab-category__label flex flex-center flex-middle"> <!-- <div class="tab-category__label flex flex-middle">
<img src="~/assets/img/layout/icon-category.png" /> <img src="~/assets/img/layout/icon-category.png" />
<span>热门分类</span> <span>热门分类</span>
</div> </div> -->
<div <div
v-show="isCategroyOpen || categroyVisible" class="tab-category__menu"
class="tab-category__menu flex"
@mouseenter="handleCategoryTwoChange(true)" @mouseenter="handleCategoryTwoChange(true)"
@mouseleave="handleCategoryTwoChange(false)" @mouseleave="handleCategoryTwoChange(false)"
> >
<!-- 左侧一级分类 --> <!-- 左侧一级分类 -->
<div class="tab-category-menu__left"> <div class="tab-category-menu__left flex flex-between flex-middle">
<div <div
v-for="item in categroyData" v-for="item in categroyData"
:key="item.id" :key="item.id"
@ -29,31 +27,27 @@
'menu-left__item--light': item.id === currentCategroyId, 'menu-left__item--light': item.id === currentCategroyId,
}" }"
> >
<img :src="item.icon" />
<span>{{ item.name }}</span> <span>{{ item.name }}</span>
</div> <div class="menu-left__item--bottom"></div>
</div> <!-- 右侧二级分类 -->
<!-- 右侧二级分类 --> <div class="tab-category-menu__right flex-1 flex-wrap flex-between">
<div <div
v-show="categroyTwoVisible" v-for="itemList in getList(item.id)"
class="tab-category-menu__right flex-1" :key="itemList.id"
> class="menu-right-wrap__item"
<div @click="onCategoryClick(itemList.id, CATEGROY_LEVEL.TWO)"
v-for="item in list" >
:key="item.id" <img :src="itemList.picture" alt="商品分类" />
@mouseenter="handleCategoryHover(item.id)" {{ itemList.name }}
class="category-menu-right__wrap" </div>
:class="{ <!-- <div
'category-menu-right__wrap--light': item.id === currentCategroyId, v-for="item in list"
}" :key="item.id"
> @mouseenter="handleCategoryHover(item.id)"
<span class="category-menu-right__wrap"
v-for="itemList in item.list" v-show="item.id === currentCategroyId"
:key="itemList.id" ></div> -->
class="menu-right-wrap__item" </div>
@click="onCategoryClick(itemList.id, CATEGROY_LEVEL.TWO)"
>{{ itemList.name }}</span
>
</div> </div>
</div> </div>
</div> </div>
@ -72,7 +66,7 @@ export default {
return { return {
CATEGROY_LEVEL, CATEGROY_LEVEL,
categroyTwoVisible: false, // categroyTwoVisible: false, //
categroyVisible: false, // categroyVisible: true, //
currentCategroyId: 0, // id currentCategroyId: 0, // id
list: [], list: [],
}; };
@ -101,6 +95,11 @@ export default {
}, },
}, },
methods: { methods: {
getList(id) {
let list = this.list.filter((item) => item && item.id == id);
// console.log(`list[0]?.list`, list[0]?.list);
return list[0]?.list || [];
},
// //
async getCategroyData() { async getCategroyData() {
this.list = await Promise.all( this.list = await Promise.all(
@ -146,12 +145,15 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.header-category { .header-category {
height: 100%; height: 100%;
width: 700px;
.header-box-tab__category { .header-box-tab__category {
position: relative; position: relative;
height: 100%; height: 100%;
width: 700px;
.tab-category__label { .tab-category__label {
width: 190px; width: 190px;
height: 100%; height: 100%;
padding-left: 41px;
background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%); background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%);
border-radius: 4px 4px 0px 0px; border-radius: 4px 4px 0px 0px;
font-weight: bold; font-weight: bold;
@ -164,63 +166,69 @@ export default {
} }
} }
.tab-category__menu { .tab-category__menu {
position: absolute; // position: absolute;
top: 38px; // top: 38px;
left: 0; // left: 0;
height: 360px; // height: 360px;
font-size: 14px; // font-size: 14px;
color: #333333; // color: #333333;
width: 100%;
height: 100%;
padding: 0 55px;
.tab-category-menu__left { .tab-category-menu__left {
width: 190px; width: 100%;
padding: 15px 0; height: 100%;
background: #ffffff;
.menu-left__item { .menu-left__item {
height: 36px; height: 100%;
font-size: 16px;
font-weight: 400;
color: #333333;
position: relative;
cursor: pointer; cursor: pointer;
padding: 0 24px 0 41px;
margin-top: 23px; .menu-left__item--bottom {
&:first-child { width: 68px;
margin-top: 0; height: 3px;
background: #ff6a19;
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
display: none;
} }
&:hover, &:hover,
&--light { &--light {
color: #ff875b; color: #ff6a19;
} .tab-category-menu__right,
img { .menu-left__item--bottom {
width: 20px; display: flex;
height: 20px; }
margin-right: 16px;
} }
} }
} }
.tab-category-menu__right { .tab-category-menu__right {
padding: 15px 26px; position: absolute;
box-shadow: 7px 0px 10px 1px rgba(0, 0, 0, 0.1); top: 90px;
border: 1px solid #eeeeee; left: -54px;
width: 350px;
padding: 25px 25px 9px;
background: #ffffff; background: #ffffff;
border-radius: 0 4px 4px 0; box-shadow: 0px 0px 40px 1px rgba(0, 0, 0, 0.1);
.category-menu-right__wrap { border-radius: 4px;
height: 36px; display: none;
margin-top: 23px;
line-height: 36px; .menu-right-wrap__item {
padding: 0 16px; width: 140px;
font-size: 12px; height: 40px;
color: #999999; cursor: pointer;
white-space: nowrap; color: #333;
&:first-child { margin-bottom: 16px;
margin-top: 0; img {
} height: 40px;
&:hover, width: 40px;
&--light {
background: #f8f8f8;
} }
.menu-right-wrap__item { &:hover {
color: #999999; color: #ff875b;
margin-right: 20px;
cursor: pointer;
&:hover {
color: #ff875b;
}
} }
} }
} }

@ -84,43 +84,19 @@
<img v-show="!orderHover" src="~/assets/img/layout/icon-order.png" /> <img v-show="!orderHover" src="~/assets/img/layout/icon-order.png" />
<span>我的订单</span> <span>我的订单</span>
</div> </div>
<div class="header-wrap-content--line"></div> <div class="header-wrap-content__common flex flex-middle down"
<!-- 下载app --> @click="$router.push('/down')">
<el-popover <img class="down--icon" src="~/assets/img/layout/icon-phone.png"/>
popper-class="header-info-bar__popover" <img class="down--icon__hover" src="~/assets/img/layout/icon-phone-light.png"/>
placement="bottom" <span>下载app</span>
width="230" </div>
trigger="hover"
@show="phoneHover = true"
@hide="phoneHover = false"
>
<div
slot="reference"
class="header-wrap-content__common flex flex-middle"
>
<img
v-show="phoneHover"
src="~/assets/img/layout/icon-phone-light.png"
/>
<img
v-show="!phoneHover"
src="~/assets/img/layout/icon-phone.png"
/>
<span :class="{ 'wrap-content-common--light': phoneHover }"
>下载app</span
>
</div>
<div class="info-bar-popover__qrcode">
<img src="~/assets/img/common/app-qrcode.png" />
<span>扫一扫上方二维码 下载APP</span>
</div>
</el-popover>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapState } from "vuex";
import {Im, ImInit} from '@/plugins/chat'
const MENU_VALUE = { const MENU_VALUE = {
PERSONAL: 1, PERSONAL: 1,
ADDRESS: 2, ADDRESS: 2,
@ -133,7 +109,6 @@ export default {
return { return {
menuVisible: false, menuVisible: false,
orderHover: false, orderHover: false,
phoneHover: false,
messageHover: false, messageHover: false,
menuList: [ menuList: [
{ {
@ -160,9 +135,23 @@ export default {
}, },
}, },
mounted() { mounted() {
this.$startWebSockets();
this.initSocket();
}, },
methods: { methods: {
initSocket(){
if(!this.userInfo.id){
setTimeout(()=>{
this.initSocket();
},1000)
return false;
}
// IM
ImInit().then(() => {
//
Im.getSessionList();
}).catch(e => {});
},
onLoginClick() { onLoginClick() {
this.$isLoginValidate(); this.$isLoginValidate();
}, },
@ -176,6 +165,7 @@ export default {
break; break;
case MENU_VALUE.LOGON_OUT: case MENU_VALUE.LOGON_OUT:
this.$store.dispatch("logout"); this.$store.dispatch("logout");
Im.close();
} }
}, },
@ -196,6 +186,10 @@ export default {
display: none !important; display: none !important;
} }
} }
.header-info-bar__popover {
padding: 22px !important;
margin-top: 8px !important;
}
</style> </style>
<style lang="scss" scoped> <style lang="scss" scoped>
.header-info-bar__dropdown { .header-info-bar__dropdown {
@ -210,8 +204,8 @@ export default {
height: 42px; height: 42px;
font-size: 14px; font-size: 14px;
img { img {
width: 8px; width: 6px;
height: 14px; height: 12px;
} }
} }
.menu-item__wrap { .menu-item__wrap {
@ -237,17 +231,19 @@ export default {
font-size: 14px; font-size: 14px;
color: #666666; color: #666666;
text-align: center; text-align: center;
width: 186px;
margin: 0 auto;
img { img {
width: 186px; width: 100%;
height: 186px; height: 186px;
margin-bottom: 15px; margin-bottom: 15px;
} }
} }
} }
.info-bar-header { .info-bar-header {
height: 30px; height: 40px;
color: #999999; color: #969696;
background: #f1f1f1; background: #333333;
font-size: 12px; font-size: 12px;
.info-bar-header-wrap { .info-bar-header-wrap {
height: 100%; height: 100%;
@ -258,14 +254,10 @@ export default {
padding: 0 18px; padding: 0 18px;
.content-login-text--light { .content-login-text--light {
margin-left: 6px; margin-left: 6px;
color: #ff875b; color: #969696;
cursor: pointer; cursor: pointer;
} }
} }
.wrap-content-login__info--hover {
background: #ffffff !important;
color: #ff875b;
}
.wrap-content-login__info { .wrap-content-login__info {
position: relative; position: relative;
padding: 0 18px; padding: 0 18px;
@ -279,6 +271,10 @@ export default {
margin-left: 4px; margin-left: 4px;
} }
} }
.wrap-content-login__info--hover {
background: #ffffff;
color: #ff875b;
}
} }
.wrap-content-message__tip { .wrap-content-message__tip {
width: 14px; width: 14px;
@ -297,7 +293,7 @@ export default {
.header-wrap-content--line { .header-wrap-content--line {
width: 1px; width: 1px;
height: 10px; height: 10px;
background: #d8d8d8; background: #969696;
} }
.header-wrap-content__common { .header-wrap-content__common {
cursor: pointer; cursor: pointer;
@ -311,6 +307,26 @@ export default {
margin-right: 4px; margin-right: 4px;
} }
} }
.down{
background:#474747;
padding: 0 10px;
height: 26px;
display: flex;
align-items: center;
border-radius: 4px;
.down--icon__hover{
display: none;
}
&:hover{
color: #ff875b;
.down--icon{
display: none;
}
.down--icon__hover{
display: inline-block;
}
}
}
} }
} }
} }

@ -11,47 +11,27 @@
<div class="bar-header-wrap__logo" @click="onOpenHomePage"> <div class="bar-header-wrap__logo" @click="onOpenHomePage">
<img src="~/assets/img/layout/logo-sticky.png" /> <img src="~/assets/img/layout/logo-sticky.png" />
</div> </div>
<el-menu <HeaderCategory />
:default-active="tabPath" <div class="header-box-wrap__right flex flex-middle">
mode="horizontal" <div class="box-wrap-right__search flex">
@select="onTabSelect" <div class="search-input">
> <el-input
<el-menu-item ref="searchInput"
v-for="item in tabList" v-model="searchContent"
:key="item.value" clearable
:index="item.value" placeholder="请输入商品名称"
>{{ item.label }}</el-menu-item @keyup.enter.native="onSearch"
> >
</el-menu> <img
</div> slot="suffix"
<div class="bar-header-wrap__icons flex flex-middle"> class="search-icon"
<img src="~/assets/img/layout/icon-search.png"
src="~/assets/img/layout/icon-search-sticky.png" />
@click="$router.push('/goods/list')" </el-input>
/> </div>
<div class="header-wrap-icons__shop" @click="onOpenCartPage">
<img src="~/assets/img/layout/icon-shop-sticky.png" />
<div
v-if="cartCount > 0"
:class="{ 'wrap-icons-shop__tip--more': cartCount > 10 }"
class="wrap-icons-shop__tip flex flex-middle flex-center"
>
{{ cartCount }}
</div> </div>
</div> <!-- 购物车 -->
<div <HeaderCart />
v-if="token"
class="header-wrap-icons__login"
@click="$router.push('/account/home')"
>
<img :src="userInfo.avatar" />
</div>
<div
v-else
class="header-wrap-icons__unlogin"
@click="onLoginClick"
>
登录
</div> </div>
</div> </div>
</div> </div>
@ -61,48 +41,33 @@
<HeaderInfoBar /> <HeaderInfoBar />
<div class="default-bar-header"> <div class="default-bar-header">
<div class="bar-header-box"> <div class="bar-header-box">
<div class="bar-header-box__wrap flex flex-between flex-middle"> <div class="bar-header-box__wrap flex flex-middle">
<div class="header-box-wrap__logo" @click="onOpenHomePage"> <div class="header-box-wrap__logo" @click="onOpenHomePage">
<img src="~/assets/img/layout/logo.png" /> <img src="~/assets/img/layout/logo.png" />
</div> </div>
<HeaderCategory />
<div class="header-box-wrap__right flex flex-middle"> <div class="header-box-wrap__right flex flex-middle">
<div class="box-wrap-right__search flex"> <div class="box-wrap-right__search flex">
<div class="search-input"> <div class="search-input">
<el-input <el-input
ref="searchInput"
v-model="searchContent" v-model="searchContent"
clearable clearable
placeholder="请输入商品名称" placeholder="请输入商品名称"
@keyup.enter.native="onSearch" @keyup.enter.native="onSearch"
> >
<img
slot="suffix"
class="search-icon"
src="~/assets/img/layout/icon-search.png"
/>
</el-input> </el-input>
</div> </div>
<div
slot="suffix"
class="search-icon flex flex-center flex-middle"
@click="onSearch"
>
<img src="~/assets/img/layout/icon-search.png" />
</div>
</div> </div>
<!-- 购物车 --> <!-- 购物车 -->
<HeaderCart /> <HeaderCart />
</div> </div>
</div> </div>
<div class="bar-header-box__tab flex flex-middle">
<HeaderCategory />
<div
v-for="item in tabList"
:key="item.value"
class="header-box-tab__common flex flex-center flex-middle"
:class="{
'header-box-tab__common--light':
item.value === $nuxt.$route.fullPath,
}"
@click="onTabSelect(item.value)"
>
{{ item.label }}
</div>
</div>
</div> </div>
</div> </div>
<div v-if="!hideBarLine" class="layout-header-line"></div> <div v-if="!hideBarLine" class="layout-header-line"></div>
@ -174,6 +139,12 @@ export default {
this.getSeckillData(); this.getSeckillData();
}, },
methods: { methods: {
onEnterSearch() {
document.querySelector("body").scrollIntoView({ behavior: "smooth" });
setTimeout(() => {
this.$refs.searchInput.focus();
}, 500);
},
async getSeckillData() { async getSeckillData() {
const { result } = await ApiGetHomeSeckill(); const { result } = await ApiGetHomeSeckill();
if (result && result.activityTimeVO) { if (result && result.activityTimeVO) {
@ -197,6 +168,9 @@ export default {
}); });
}, },
onOpenCartPage() { onOpenCartPage() {
if (!this.$isLoginValidate()) {
return;
}
window.open(`${location.origin}/cart`); window.open(`${location.origin}/cart`);
}, },
onOpenHomePage() { onOpenHomePage() {
@ -214,10 +188,11 @@ export default {
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 50px; height: 70px;
z-index: 10; z-index: 10;
background: #ffffff; background: #ffffff;
box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.1); box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.1);
&--hide-shadow { &--hide-shadow {
box-shadow: none; box-shadow: none;
/deep/.el-menu { /deep/.el-menu {
@ -229,10 +204,14 @@ export default {
.sticky-bar-header__wrap { .sticky-bar-header__wrap {
@include layout-box; @include layout-box;
height: 100%; height: 100%;
> div {
height: 100%;
width: 100%;
}
.bar-header-wrap__logo { .bar-header-wrap__logo {
width: 164px; width: 160px;
height: 28px; height: 40px;
margin-right: 50px; margin-right: 20px;
cursor: pointer; cursor: pointer;
img { img {
width: 100%; width: 100%;
@ -298,49 +277,50 @@ export default {
padding: 0 5px; padding: 0 5px;
} }
} }
/deep/.tab-category-menu__right {
top: 70px!important;
}
} }
} }
.header-box-wrap__right {
margin-left: auto;
.box-wrap-right__search {
margin-right: 23px;
.search-input {
width: 240px;
z-index: 1;
border-radius: 4px;
/deep/.el-input__suffix {
display: flex;
align-items: center;
// margin-right: 16px;
}
.search-icon {
width: 32px;
height: 16px;
padding-right: 16px;
// margin-right: 16px;
// margin-top: 12px;
}
}
}
}
.default-bar-header { .default-bar-header {
padding-top: 32px;
position: relative; position: relative;
z-index: 3; z-index: 3;
.bar-header-box { .bar-header-box {
@include layout-box; @include layout-box;
background: #ffffff; background: #ffffff;
.bar-header-box__wrap { .bar-header-box__wrap {
height: 40px; height: 90px;
font-size: 14px; font-size: 14px;
margin-bottom: 38px;
padding-right: 50px;
cursor: pointer; cursor: pointer;
.header-box-wrap__logo { .header-box-wrap__logo {
width: 244px; width: 198px;
height: 100%; height: 50px;
}
.header-box-wrap__right {
.box-wrap-right__search {
margin-right: 23px;
.search-input {
width: 551px;
z-index: 1;
border-radius: 4px;
/deep/.el-input__inner:focus {
border-color: #ff512b;
}
}
.search-icon {
width: 77px;
margin-left: -2px;
background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%);
border-radius: 0px 4px 4px 0px;
z-index: 2;
cursor: pointer;
img {
width: 26px;
height: 26px;
}
}
}
} }
} }
.bar-header-box__tab { .bar-header-box__tab {

@ -2,95 +2,90 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-03 22:14:16 * @Date: 2022-05-03 22:14:16
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-10 14:18:39 * @LastEditTime: 2023-04-21 16:14:15
* @Description: file content * @Description: file content
*/ */
export default { export default {
// Global page headers: https://go.nuxtjs.dev/config-head // Global page headers: https://go.nuxtjs.dev/config-head
head: { head: {
title: '马士兵严选', title: "马士兵严选",
htmlAttrs: { htmlAttrs: {
lang: 'zh' lang: "zh",
}, },
meta: [ meta: [
{ charset: 'utf-8' }, { charset: "utf-8" },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }, { name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: 'description', name: 'description', content: '' }, { hid: "description", name: "description", content: "" },
{ name: 'format-detection', content: 'telephone=no' } { name: "format-detection", content: "telephone=no" },
], ],
link: [ link: [{ rel: "icon", type: "image/x-icon", href: "/logo.ico" }],
{ rel: 'icon', type: 'image/x-icon', href: '/logo.ico' } },
] router: {
}, extendRoutes(routes, resolve) {
router: { routes.push({
extendRoutes(routes, resolve) { name: "custom",
routes.push({ path: "/",
name: 'custom', component: resolve(__dirname, "pages/index/index.vue"),
path: '/', });
component: resolve(__dirname, 'pages/index/index.vue') },
}) middleware: ["redirect"],
}, },
middleware: ['redirect']
},
// Global CSS: https://go.nuxtjs.dev/config-css // Global CSS: https://go.nuxtjs.dev/config-css
css: [ css: ["@assets/scss/global.scss", "element-ui/lib/theme-chalk/index.css"],
'@assets/scss/global.scss',
'element-ui/lib/theme-chalk/index.css'
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [ plugins: [
'@/plugins/element-ui', "@/plugins/element-ui",
'@/plugins/axios', "@/plugins/axios",
'@plugins/axiosTk.js', "@/plugins/axiosTk.js",
'@plugins/vue-inject.js', "@plugins/vue-inject.js",
'@/plugins/v-distpicker', "@/plugins/v-distpicker",
'@/plugins/router', "@/plugins/router",
'@/plugins/im' "@/plugins/im",
], "@/plugins/chat",
],
// Auto import components: https://go.nuxtjs.dev/config-components // Auto import components: https://go.nuxtjs.dev/config-components
components: true, components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [ buildModules: [],
],
build: { build: {
vendor: ['v-distpicker'] vendor: ["v-distpicker"],
}, },
styleResources: { styleResources: {
scss: '@/assets/scss/global.scss' scss: "@/assets/scss/global.scss",
}, },
// Modules: https://go.nuxtjs.dev/config-modules // Modules: https://go.nuxtjs.dev/config-modules
modules: [ modules: [
'@nuxtjs/axios', "@nuxtjs/axios",
'cookie-universal-nuxt', "cookie-universal-nuxt",
'@nuxtjs/style-resources' "@nuxtjs/style-resources",
], ],
// Build Configuration: https://go.nuxtjs.dev/config-build // Build Configuration: https://go.nuxtjs.dev/config-build
build: { build: {
transpile: [/^element-ui/], transpile: [/^element-ui/],
}, },
axios: { axios: {
// 表示开启代理 // 表示开启代理
proxy: true, // proxy: true,
}, },
proxy: { proxy: {
'/mall/': { // '/mall/': {
// target: 'http://114.55.64.39:3004', // 目标接口域名 // target: 'https://you-gateway.mashibing.com/', // 目标接口域名
target: 'https://you-gateway.mashibing.com/', // 目标接口域名 // // target: 'https://k8s-horse-gateway.mashibing.cn/', // 目标接口域名
pathRewrite: { // pathRewrite: {
changeOrigin: true, // 表示是否跨域 // changeOrigin: true, // 表示是否跨域
}, // },
}, // },
}, },
server: { server: {
port: 3000, // default: 3000 port: 3000,
host: '0.0.0.0' // default: localhost, host: "0.0.0.0",
}, },
} };

26559
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -3,9 +3,9 @@
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "node env.config.js & nuxt", "server": "node env.config.js & nuxt",
"dev:beta": "node env.config.js --ENV:beta & nuxt", "server:beta": "node env.config.js --ENV:beta & nuxt",
"dev:prod": "node env.config.js --ENV:prod & nuxt", "server:prod": "node env.config.js --ENV:prod & nuxt",
"build:test": "node env.config.js --ENV:test & nuxt build", "build:test": "node env.config.js --ENV:test & nuxt build",
"build:beta": "node env.config.js --ENV:beta & nuxt build", "build:beta": "node env.config.js --ENV:beta & nuxt build",
"build:prod": "node env.config.js --ENV:prod & nuxt build", "build:prod": "node env.config.js --ENV:prod & nuxt build",
@ -21,25 +21,26 @@
"element-ui": "^2.15.8", "element-ui": "^2.15.8",
"js-util-all": "^1.0.6", "js-util-all": "^1.0.6",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"nuxt": "^2.15.8", "nuxt": "2.15.8",
"qrcode": "^1.5.0",
"v-distpicker": "^1.2.13", "v-distpicker": "^1.2.13",
"vue": "^2.6.14", "vue": "2.6.14",
"vue-server-renderer": "^2.6.14", "vue-server-renderer": "2.6.14",
"vue-template-compiler": "^2.6.14" "vue-template-compiler": "2.6.14"
}, },
"devDependencies": { "devDependencies": {
"@vue/test-utils": "^1.3.0", "@vue/test-utils": "^1.3.0",
"babel-core": "7.0.0-bridge.0", "babel-core": "7.0.0-bridge.0",
"webpack": "^4.46.0",
"node-sass": "^4.14.1",
"sass": "^1.32.13",
"sass-loader": "^7.3.1",
"babel-jest": "^27.4.4", "babel-jest": "^27.4.4",
"eslint": "^8.15.0", "eslint": "^8.15.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"git-repo-info": "^2.1.1", "git-repo-info": "^2.1.1",
"jest": "^27.4.4", "jest": "^27.4.4",
"node-sass": "^4.14.1",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"vue-jest": "^3.0.4" "sass": "^1.32.13",
"sass-loader": "^7.3.1",
"vue-jest": "^3.0.4",
"webpack": "^4.46.0"
} }
} }

@ -0,0 +1,153 @@
<!--
* @Author: ch
* @Date: 2022-06-27 11:46:34
* @LastEditors: ch
* @LastEditTime: 2022-06-30 23:40:44
* @Description: file content
-->
<template>
<div class="main">
<div class="tab">
<router-link class="tab--link" to="/account/home">个人中心</router-link>
<router-link class="tab--link" to="/account/order/list">我的订单</router-link>
<span>商品评价</span>
</div>
<div class="title">商品评价</div>
<div class="ctx">
<UiLoading v-if="loading"></UiLoading>
<BsCommentInfo v-else source="comment" :isFollowForm="isFollow" v-for="(item, idx) in list" :key="idx"
:commentDetail="item" @submit="handleSubmitComment($event, idx)"
@submitFollow="handleSubmitFollow($event, idx)" @editStatusChange="editChange($event, idx)"/>
</div>
</div>
</template>
<script>
import {
ApiGetOrderCommentDetail,
ApiGetCommentTabCount,
ApiGetProductSatisfaction,
ApiGetCommentCount,
ApiGetCommentDetail
} from "@/plugins/api/comment";
import {COMMENT} from '@/constants'
import BsCommentInfo from '../../../components/BsCommentInfo.vue';
export default {
components: { BsCommentInfo },
data(){
let query = this.$route.query;
return {
isFollow : query.follow ? true : false, //
orderId: query.orderId,
commentId : query.commentId,
list:[],
loading : true
}
},
mounted(){
if(this.orderId){
this.getOrderCommentDetail();
}else if(this.commentId){
this.getCommentDetail();
}
},
beforeRouteLeave(to, from, next) {
if(this.list.findIndex(i => i.isEdit) > -1){
this.$confirm('你正在进行商品评价,退出后评价的内容将不保存!','提示').then(()=>{
next()
}).catch(()=>{
})
}else{
next()
}
},
methods:{
/**
* 按订单查询评价详情
*/
async getOrderCommentDetail() {
this.loading = true;
const { error, result } = await ApiGetOrderCommentDetail({
orderId: this.orderId,
});
this.loading = false;
if (error) {
this.$message.warning(error.message);
return false;
}
this.list = result;
},
/**
* 按评论查询追评时用
*/
async getCommentDetail(){
this.loading = true;
const {error, result} = await ApiGetCommentDetail({
commentId : this.commentId
});
this.loading = false;
if (error) {
this.$message.warning(error.message);
return false;
}
this.list = [result];
},
/**
* 提交评论成功事件
* 如果还有未评论的则弹窗提示并更新当前行的数据
* 如果是最好一条产品评论则跳到评论成功页
*/
handleSubmitComment(result, idx){
this.$set(this.list, idx, {...this.list[idx],...result});
if(this.list.findIndex(i => !i.id) > -1){
this.$message.success('评论成功~');
}else{
this.$router.replace('/account/comment/success');
}
},
editChange(isEdit, idx){
this.$set(this.list[idx], 'isEdit', isEdit);
},
}
}
</script>
<style lang="scss" scoped>
.main{
@include layout-box;
margin-bottom: 32px;
}
.tab{
margin: 10px 0;
height: 40px;
line-height: 40px;
color: #999;
&--link{
background: url('@/assets/img/comment/right.png') no-repeat right center;
padding-right: 15px;
margin-right: 10px;
background-size: 5px;
color: #666;
}
}
.title{
width: 100%;
height: 40px;
line-height: 40px;
background: #f7f7f7;
border: 1px solid #f2f2f2;
padding: 0 16px;
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #666666;
display: flex;
justify-content: space-between;
}
.ctx{
border: 1px solid #f2f2f2;
border-top: 0;
}
</style>

@ -0,0 +1,114 @@
<!--
* @Author: ch
* @Date: 2022-05-08 01:11:33
* @LastEditors: ch
* @LastEditTime: 2022-06-28 10:39:35
* @Description: file content
-->
<template>
<div>
<div class="main">
<img class="icon" src="@/assets/img/order/pay_success.png" />
<p>评价成功</p>
<div>
<UiButton type="grey" @click="$router.back()" :radius="true">返回</UiButton>
</div>
<div v-if="goodsList.length">
<b class="product-title">这些宝贝还在等你得评价哦~</b>
<ul class="product">
<li v-for="(item, idx) in goodsList" :key="idx">
<img :src="item.productPicture"/>
<p>{{item.productName}}</p>
<UiButton type="grey" @click="$router.replace(`/account/comment?orderId=${item.orderId}`)" >
{{item.commentStatus == 1 ? '立即评价' : '立即追评'}}
</UiButton>
</li>
</ul>
</div>
</div>
<BsChosen class="chosen"/>
</div>
</template>
<script>
import UiButton from '@/components/UiButton.vue';
import {ApiGetCommentOrderDetailList} from '@/plugins/api/order';
export default {
components: { UiButton },
data(){
return {
goodsList : []
}
},
mounted(){
this.getAwaitGoodsList();
},
methods:{
async getAwaitGoodsList (){
const {error, result} = await ApiGetCommentOrderDetailList({
length:6,
pageIndex : 1
});
if(error){
this.$message.warning(error.message)
}
this.goodsList = result.records.map(item => {
return {
productPicture : item.productImageUrl,
productName : item.productName,
commentStatus : item.commentStatus,
orderId : item.orderId
}
});
}
}
}
</script>
<style lang="scss" scoped>
.main{
@include layout-box;
text-align: center;
padding: 100px 0 40px;
}
.icon{
width: 239px;
}
b{
display: block;
}
p{
margin: 10px 0 25px 0;
color: #999;
}
button{
margin: 0 10px 30px;
}
.product-title{
height: 40px;
line-height: 40px;
text-align: left;
background: #F7F7F7;
font-weight: normal;
color: #666;
padding: 0 16px;
}
.product{
display: flex;
// justify-content: flex-start;
li{
margin:40px 0 0 48px;
width: 140px;
img{
width: 140px;
height: 140px;
object-fit: contain;
}
p{
@include ellipses(2);
height: 40px;
margin: 10px 0;
}
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:27:37 * @Date: 2022-05-04 17:27:37
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 17:27:39 * @LastEditTime: 2022-06-28 16:38:18
* @Description: file content * @Description: file content
--> -->
@ -36,7 +36,6 @@
</div> </div>
<div class="account-home-content flex"> <div class="account-home-content flex">
<LogisitcsInfo /> <LogisitcsInfo />
<Message />
</div> </div>
</div> </div>
</template> </template>
@ -48,11 +47,10 @@ import {
ApiGetRefundStatistisc, ApiGetRefundStatistisc,
} from "@/plugins/api/order"; } from "@/plugins/api/order";
import LogisitcsInfo from "./module/LogisitcsInfo.vue"; import LogisitcsInfo from "./module/LogisitcsInfo.vue";
import Message from "./module/Message.vue";
export default { export default {
name: "AccountHome", name: "AccountHome",
components: { LogisitcsInfo, Message }, components: { LogisitcsInfo },
data() { data() {
function getOrderTypeIcon(path) { function getOrderTypeIcon(path) {
return require(`~/assets/img/account/home/${path}.png`); return require(`~/assets/img/account/home/${path}.png`);
@ -81,17 +79,24 @@ export default {
path: `/account/order/list?type=${ORDER_STATUS.WAIT_RECEIVE}`, path: `/account/order/list?type=${ORDER_STATUS.WAIT_RECEIVE}`,
count: 0, count: 0,
}, },
{
key: "waitComment",
label: "待评价",
icon: getOrderTypeIcon("icon-order4"),
path: `/account/order/list?type=${ORDER_STATUS.WAIT_COMMENT}`,
count: 0,
},
{ {
key: "progressCount", key: "progressCount",
label: "退款/售后", label: "退款/售后",
icon: getOrderTypeIcon("icon-order4"), icon: getOrderTypeIcon("icon-order5"),
path: "/account/order/saleAfter/list", path: "/account/order/saleAfter/list",
count: 0, count: 0,
}, },
{ {
key: "", key: "",
label: "全部订单", label: "全部订单",
icon: getOrderTypeIcon("icon-order5"), icon: getOrderTypeIcon("icon-order6"),
path: "/account/order/list", path: "/account/order/list",
}, },
], ],
@ -130,6 +135,9 @@ export default {
background-size: 100% 100%; background-size: 100% 100%;
padding: 49px 26px; padding: 49px 26px;
margin-right: 30px; margin-right: 30px;
border: 1px solid #ffffff;
box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.06);
border-radius: 4px;
.home-head-info__avatar { .home-head-info__avatar {
width: 65px; width: 65px;
height: 65px; height: 65px;
@ -156,13 +164,16 @@ export default {
padding: 0 58px; padding: 0 58px;
background: #ffffff; background: #ffffff;
border-radius: 4px; border-radius: 4px;
box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.1); box-shadow: 0px 4px 10px 1px rgba(0, 0, 0, 0.06);
cursor: pointer; cursor: pointer;
.account-home-content__item { .account-home-content__item {
position: relative; position: relative;
font-size: 14px; font-size: 14px;
color: #333333; color: #333333;
text-align: center; text-align: center;
&:last-child {
padding-right: 0;
}
.account-home-content__item--count { .account-home-content__item--count {
position: absolute; position: absolute;
top: -3px; top: -3px;
@ -176,8 +187,8 @@ export default {
border: 2px solid #ffffff; border: 2px solid #ffffff;
} }
img { img {
width: 54px; width: 50px;
height: 54px; height: 50px;
} }
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:49:21 * @Date: 2022-05-04 17:49:21
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 17:50:11 * @LastEditTime: 2022-05-27 15:40:36
* @Description: file content * @Description: file content
--> -->
@ -35,8 +35,8 @@
{{ item.logisticsContext }} {{ item.logisticsContext }}
</p> </p>
<div class="item-info-wrap__orderNo"> <div class="item-info-wrap__orderNo">
<span>{{ <span v-if="item.logistics.companyName">{{
`${item.logistics.companyName}: ${item.logistics.trackingNo}` `${item.logistics.companyName }: ${item.logistics.trackingNo}`
}}</span> }}</span>
<span class="item-info-wrap__orderNo--light">查看详情</span> <span class="item-info-wrap__orderNo--light">查看详情</span>
</div> </div>
@ -193,10 +193,13 @@ export default {
display: inline-block; display: inline-block;
color: #999999; color: #999999;
font-size: 12px; font-size: 12px;
span{
margin-right: 30px;
}
} }
.item-info-wrap__orderNo--light { .item-info-wrap__orderNo--light {
color: #ff875b; color: #ff875b;
margin-left: 30px;
cursor: pointer; cursor: pointer;
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:48:12 * @Date: 2022-05-04 17:48:12
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 17:53:11 * @LastEditTime: 2022-06-13 11:49:37
* @Description: file content * @Description: file content
--> -->
@ -11,44 +11,111 @@
<main class="main"> <main class="main">
<h3 class="title">消息通知</h3> <h3 class="title">消息通知</h3>
<section class="section"> <section class="section">
<div class="section__item flex" v-for="item in socketMsgData" :key="item.id"> <div
class="section__item flex"
:class="item.payload.customType !== 'orderAutoDelivery' && 'section__pointer'"
v-for="item in msgData"
:key="item.id"
@click="handleDetail(item)"
>
<img <img
class="section__item-img" class="section__item-img"
src="https://img1.baidu.com/it/u=3384796346,381674655&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500" :src="item.payload.productImageUrls ? item.payload.productImageUrls[0] : require('@/assets/img/account/im/system.png')"
alt="消息通知" alt="消息通知"
/> />
<div class="section__item-content flex flex-column"> <div class="section__item-content flex flex-column">
<div class="section__item-content--title flex"> <div class="section__item-content--title flex">
<span>{{ JSON.parse(item.payload).title || `` }}</span> <span>{{ item.payload.title || `` }}</span>
<span class="section__item-content--time">{{ <span class="section__item-content--time">{{item.createTimeStamp}}</span>
item.createTimeStamp
}}</span>
</div> </div>
<div class="section__item-content--txt"> <div class="section__item-content--txt" >{{ item.payload.content }}</div>
{{ <div class="section__item-content--txt" v-if="item.payload.customType === 'orderAutoDelivery'">
JSON.parse(item.payload).content || <template v-for="i in item.payload.virtualProductContentList" @click="openLink(i)">
`` <a v-if="i.shipType === 1" :key="i.shipContent" :href="i.shipContent" target="_blank">[]</a>
}} <span v-else :key="i.shipContent" >{{i.shipContent}}</span>
</template>
</div> </div>
</div> </div>
</div> </div>
<UiEmpty
v-if="!msgData.length"
desc="暂无消息通知"
:icon="require('@/assets/img/account/order/empty.png')"
>
</UiEmpty>
</section> </section>
</main> </main>
</div> </div>
</template> </template>
<script> <script>
import { mapState } from "vuex"; import UiEmpty from "@/components/UiEmpty.vue";
import {FormatDate, CreateUUID} from '@/plugins/utils';
import {Im, ImInit} from '@/plugins/chat'
export default { export default {
components: { UiEmpty },
data() { data() {
return {}; return {};
}, },
watch:{
curSession(nv,ov){
if(nv.id != ov.id){
Im.getHistoryMsg();
}
}
},
computed: { computed: {
...mapState(["token","socketMsgData"]), curSession(){
let data = this.$store.state.socketMsgData
Im.setCurSessionId(data.id);
return data;
},
msgData(){
let data = this.curSession.messageList || [];
return data.map(i => {
let item = {...i}
item.createTimeStamp = FormatDate(i.createTimeStamp, 'mm-dd hh:ii:ss')
return item;
}).reverse();
},
}, },
mounted(){ mounted() {
console.log(`socketMsgData`,this.$store.state)
setTimeout(()=>{
this.readMsg();
},5000)
}, },
methods: {}, methods: {
/**
* 把当前会话消息置为已读
*/
readMsg(){
Im.setRead({
content: {
sessionId : this.curSession.id
}
});
},
/**
* 点击详情跳转
*/
handleDetail(item){
if(item.payload.customType === 'orderAutoDelivery'){
return false;
}else if(['orderPay','orderDelivery','orderCancel'].includes(item.payload.customType)){
this.$router.push(`/account/order/detail?id=${item.payload.primaryId}`)
}else if(['refundFail','refundSuccess'].includes(item.payload.customType)){
this.$message.warning('请在移动端查看售后详情~');
}else if(item.payload.linkJump){
window.location.href = item.payload.linkJump;
}
}
},
destroyed(){
Im.setCurSessionId(null);
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -71,20 +138,25 @@ export default {
padding: 22px 20px 0; padding: 22px 20px 0;
border: 1px solid #ddd; border: 1px solid #ddd;
margin-top: -1px; margin-top: -1px;
max-height: 600px;
overflow-y: auto;
&__pointer{
cursor: pointer;
}
&__item { &__item {
margin-bottom: 20px; margin-bottom: 20px;
&-img { &-img {
width: 110px; width: 50px;
height: 110px; height: 50px;
margin-right: 20px; margin-right: 20px;
} }
&-content { &-content {
width: 840px; width: 840px;
&--title { &--title {
margin-top: 8px; margin: 8px 0;
font-size: 16px; font-size: 16px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
@ -104,6 +176,9 @@ export default {
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
color: #999999; color: #999999;
a{
color: #FF875B;
}
} }
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-08 01:14:03 * @Date: 2022-05-08 01:14:03
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-11 22:22:15 * @LastEditTime: 2022-05-27 15:37:30
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -11,16 +11,17 @@
<StatusInfo :orderInfo="orderInfo" @changeStatus="getOrderInfo"/> <StatusInfo :orderInfo="orderInfo" @changeStatus="getOrderInfo"/>
<StatusStep :orderInfo="orderInfo" /> <StatusStep :orderInfo="orderInfo" />
</div> </div>
<LogisitcsInfo :orderInfo="orderInfo" /> <LogisitcsInfo v-if="orderInfo.orderType !== ORDER_TYPE.VIRTUAL" :orderInfo="orderInfo" />
<div class="pay-type" v-if="orderInfo.payType !== 1"> <div class="pay-type" v-if="orderInfo.payType !== 1">
<p>支付方式{{orderInfo.payTypeDesc}}</p> <p>支付方式{{orderInfo.payTypeDesc}}</p>
<p>支付时间{{orderInfo.submitTime}}</p> <p>支付时间{{orderInfo.payTime}}</p>
</div> </div>
<GoodsInfo :orderInfo="orderInfo"/> <GoodsInfo :orderInfo="orderInfo"/>
</div> </div>
</template> </template>
<script> <script>
import {ApiGetOrderDetail} from '@/plugins/api/order'; import {ApiGetOrderDetail} from '@/plugins/api/order';
import {ORDER_TYPE} from '@/plugins/dicts/order';
import StatusInfo from './module/StatusInfo.vue'; import StatusInfo from './module/StatusInfo.vue';
import StatusStep from './module/StatusStep.vue'; import StatusStep from './module/StatusStep.vue';
import LogisitcsInfo from './module/LogisitcsInfo.vue'; import LogisitcsInfo from './module/LogisitcsInfo.vue';
@ -29,7 +30,10 @@ export default {
components: { StatusInfo, StatusStep, LogisitcsInfo, GoodsInfo }, components: { StatusInfo, StatusStep, LogisitcsInfo, GoodsInfo },
data(){ data(){
return { return {
orderInfo : {} ORDER_TYPE,
orderInfo : {
orderType : ORDER_TYPE.VIRTUAL
}
} }
}, },
mounted(){ mounted(){
@ -53,11 +57,14 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box{ .box{
min-width: 1000px;
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 4px; border-radius: 4px;
display: flex; display: flex;
margin: 0 0 30px 0;
} }
.pay-type{ .pay-type{
margin: 30px 0;
border: 1px solid #ddd; border: 1px solid #ddd;
background: #f8f8f8; background: #f8f8f8;
height: 59px; height: 59px;

@ -13,7 +13,7 @@
<th>商品信息</th> <th>商品信息</th>
<th width="96">单价</th> <th width="96">单价</th>
<th width="96">数量</th> <th width="96">数量</th>
<th width="163">实付</th> <th width="163" v-if="orderInfo.orderStatus > 2"></th>
<th width="135">操作</th> <th width="135">操作</th>
</tr> </tr>
</thead> </thead>
@ -24,12 +24,12 @@
<UiMoney :money="i.realAmount" float/> <UiMoney :money="i.realAmount" float/>
</td> </td>
<td class="not-border">{{i.quantity}}</td> <td class="not-border">{{i.quantity}}</td>
<td> <td v-if="orderInfo.orderStatus > 2">
<UiMoney :money="i.realAmount" float/> <UiMoney :money="i.realAmount" float/>
</td> </td>
<td> <td>
<template v-if="i.afterSaleApplyFlag || [2,3,4].includes(i.detailStatus)"> <template v-if="i.afterSaleApplyFlag || [2,3,4].includes(i.detailStatus)">
<a v-if="i.afterSaleApplyFlag"></a> <nuxt-link v-if="i.afterSaleApplyFlag" to="/account/order/saleAfter/list"></nuxt-link>
<span v-else> <span v-else>
{{ i.detailStatus === 2 ? '退款中' : i.detailStatus === 3 ? '已退款' : '退款关闭'}} {{ i.detailStatus === 2 ? '退款中' : i.detailStatus === 3 ? '已退款' : '退款关闭'}}
</span> </span>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-09 14:41:37 * @Date: 2022-05-09 14:41:37
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-16 18:27:52 * @LastEditTime: 2022-06-30 20:01:46
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -13,6 +13,8 @@
<div class="operation--btns"> <div class="operation--btns">
<!-- 已发货可以确认收货 --> <!-- 已发货可以确认收货 -->
<UiButton v-if="orderInfo.orderStatus === 4" type="yellow_gradual" :radius="true" @click="receive"></UiButton> <UiButton v-if="orderInfo.orderStatus === 4" type="yellow_gradual" :radius="true" @click="receive"></UiButton>
<UiButton v-if="orderInfo.orderStatus === 5" type="yellow_gradual" :radius="true" @click="handelComment"></UiButton>
<UiButton v-if="orderInfo.orderStatus === 6" type="yellow_gradual" :radius="true" @click="handelComment"></UiButton>
<!-- 待支付可以取消支付订单 --> <!-- 待支付可以取消支付订单 -->
<template v-if="orderInfo.orderStatus === 1"> <template v-if="orderInfo.orderStatus === 1">
<UiButton type="yellow_gradual" :radius="true" @click="payVisible = true">去支付</UiButton> <UiButton type="yellow_gradual" :radius="true" @click="payVisible = true">去支付</UiButton>
@ -51,6 +53,7 @@ export default {
'5' : {name:'已收货'}, '5' : {name:'已收货'},
// //
'6' : {name:'交易成功'}, '6' : {name:'交易成功'},
'7' : {name:'交易成功'},
}, },
ctxCon : {}, ctxCon : {},
startSecondNum : 0, startSecondNum : 0,
@ -127,11 +130,21 @@ export default {
uni.$toast(error.message); uni.$toast(error.message);
return false; return false;
} }
this.$message({
type: 'success', this.handelComment()
message: '成功收货!' // this.$message({
}); // type: 'success',
this.emitStatus() // message: '!'
// });
// this.emitStatus()
});
},
handelComment(){
this.$router.push({
path : '/account/comment',
query : {
orderId : this.orderInfo.orderId
}
}); });
}, },
emitStatus(){ emitStatus(){

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 20:47:29 * @Date: 2022-05-04 20:47:29
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-16 17:51:43 * @LastEditTime: 2022-06-29 11:50:49
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -55,11 +55,13 @@
<UiButton type="yellow_gradual" @click="pay(item)"></UiButton> <UiButton type="yellow_gradual" @click="pay(item)"></UiButton>
<span class="link-btn" @click="cancelPay(item)"></span> <span class="link-btn" @click="cancelPay(item)"></span>
</template> </template>
<router-link :to="`./detail?id=${item.orderId}`" v-if="item.orderStatus > 4"></router-link> <UiButton type="yellow_gradual" v-if="item.orderStatus === 4" @click="receive(item)"></UiButton>
<template v-if="item.orderStatus === 4"> <UiButton type="yellow_gradual" v-if="item.orderStatus === 5"
<UiButton type="yellow_gradual" @click="receive(item)"></UiButton> @click="$router.push(`/account/comment?orderId=${item.orderId}`)">去评价</UiButton>
<router-link class="link-btn" :to="`./detail?id=${item.orderId}`">查看物流</router-link> <UiButton type="yellow_gradual" v-if="item.orderStatus === 6"
</template> @click="$router.push(`/account/comment?orderId=${item.orderId}&follow=true`)">去追评</UiButton>
<router-link class="link-btn" :to="`./detail?id=${item.orderId}`" v-if="item.orderStatus >= 4"></router-link>
</td> </td>
</template> </template>
</tr> </tr>
@ -165,11 +167,17 @@ export default {
this.$$message.error(error.message); this.$$message.error(error.message);
return false; return false;
} }
this.$message({ this.$router.push({
type: 'success', path : '/account/tradeSuccess',
message: '成功收货!' query : {
orderId : item.orderId
}
}); });
this.reloadData() // this.$message({
// type: 'success',
// message: '!'
// });
// this.reloadData();
}); });
}, },
handleDetail(id){ handleDetail(id){

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2019-01-01 08:04:09 * @Date: 2019-01-01 08:04:09
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-11 21:34:49 * @LastEditTime: 2022-06-27 11:38:50
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -30,6 +30,7 @@ export default {
{label : '待付款', value : 1, code: 'unpaidCount'}, {label : '待付款', value : 1, code: 'unpaidCount'},
{label : '待发货', value : 3, code: 'waitDeliveryCount'}, {label : '待发货', value : 3, code: 'waitDeliveryCount'},
{label : '待收货', value : 4, code: 'deliveredCount'}, {label : '待收货', value : 4, code: 'deliveredCount'},
{label : '待评价', value : 5, code: 'waitComment'},
] ]
} }
}, },

@ -2,15 +2,15 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:48:12 * @Date: 2022-05-04 17:48:12
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 17:53:11 * @LastEditTime: 2022-05-20 10:19:35
* @Description: file content * @Description: file content
--> -->
<template> <template>
<main class="main flex flex-column flex-middle"> <main class="main flex flex-column flex-middle">
<p class="main-title">售后订单</p> <p class="main-title">售后订单</p>
<img class="main-img" src="@/assets/img/common/app-qrcode.png" alt="" /> <img class="main-img" src="@/assets/img/common/app-qrcode.jpg" alt="" />
<p class="main-txt">请前往APP查看售后订单</p> <p class="main-txt">请前往移动端查看售后订单</p>
</main> </main>
</template> </template>
<script> <script>

@ -1,3 +1,10 @@
<!--
* @Author: ch
* @Date: 2022-05-20 09:59:05
* @LastEditors: ch
* @LastEditTime: 2022-06-25 15:40:05
* @Description: file content
-->
<!-- <!--
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:52:50 * @Date: 2022-05-04 17:52:50
@ -37,7 +44,7 @@
</el-upload> </el-upload>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="昵称" prop="nickname"> <el-form-item label="昵称" prop="nickname" class="form-item__nickname">
<el-input <el-input
class="user-info-content__nickname" class="user-info-content__nickname"
placeholder="请输入昵称" placeholder="请输入昵称"
@ -203,6 +210,9 @@ export default {
border: 1px solid #eeeeee; border: 1px solid #eeeeee;
} }
} }
.form-item__nickname {
margin-left: -10px;
}
.user-info-content__nickname { .user-info-content__nickname {
height: 35px; height: 35px;
width: 210px; width: 210px;

@ -0,0 +1,59 @@
<!--
* @Author: ch
* @Date: 2022-05-08 01:11:33
* @LastEditors: ch
* @LastEditTime: 2022-06-27 15:37:53
* @Description: file content
-->
<template>
<div>
<div class="main">
<img class="icon" src="@/assets/img/order/pay_success.png" />
<!-- <b>交易成功</b> -->
<p>交易成功</p>
<div>
<UiButton type="grey" @click="$router.replace(`/`)" :radius="true">返回首页</UiButton>
<UiButton type="yellow_gradual" @click="$router.replace(`./comment?orderId=${orderId}`)" :radius="true">去评价</UiButton>
</div>
</div>
<BsChosen class="chosen"/>
</div>
</template>
<script>
import UiButton from '@/components/UiButton.vue';
import {ApiGetOrderPaySatus} from '@/plugins/api/order';
export default {
components: { UiButton },
data(){
return {
orderId : this.$route.query.orderId
}
},
mounted(){
},
methods:{
}
}
</script>
<style lang="scss" scoped>
.main{
@include layout-box;
text-align: center;
padding: 100px 0 40px;
}
.icon{
width: 239px;
}
b{
display: block;
}
p{
margin: 10px 0 25px 0;
color: #999;
}
button{
margin: 0 10px 30px;
}
</style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-03 22:41:15 * @Date: 2022-05-03 22:41:15
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-16 20:40:48 * @LastEditTime: 2022-05-25 17:57:25
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -232,13 +232,26 @@ export default {
* 点击去结算 * 点击去结算
*/ */
settlement(){ settlement(){
this.$router.push({ const ids = this.checkedIds;
path : '/order/submit', //
query : { const baseType = this.list.find(i => ids[0] === i.id).productType;
mode: 'cart', for(let id of ids){
ids:this.checkedIds.join(',') const item = this.list.find(i => id === i.id);
if(item.productType != baseType){
this.$message.warning('虚拟商品需要单独结算,不可和其他实物订单合并结算哦~');
return false;
} }
}) }
if (ids.length) {
this.$router.push({
path : '/order/submit',
query : {
mode: 'cart',
productType : baseType,
ids:ids.join(',')
}
})
}
} }
} }
} }

@ -0,0 +1,231 @@
<!--
* @Author: ch
* @Date: 2022-05-26 16:08:17
* @LastEditors: ch
* @LastEditTime: 2022-06-02 17:56:04
* @Description: file content
-->
<template>
<div class="main">
<h2 class="title">下载马士兵严选APP</h2>
<p class="desc"><b>精选好物</b><span></span><b>精致生活</b></p>
<ul class="group">
<li class="group--item">
<div class="qrcode">
<img class="qrcode--img" src="@/assets/img/down/app-qrcode.png"/>
<img class="qrcode--icon" src="@/assets/img/down/android.png"/>
</div>
<span class="group--item-title">Android</span>
</li>
<li class="group--item">
<div class="qrcode qrcode__disabled">
<img class="qrcode--img" src="@/assets/img/down/app-qrcode.png"/>
<img class="qrcode--icon" src="@/assets/img/down/ios.png"/>
</div>
<span class="group--item-title">iOS</span>
<span class="group--item-btn">规划中...</span>
</li>
<li class="group--item">
<div class="qrcode">
<img class="qrcode--img" src="@/assets/img/down/wx-qrcode.jpg"/>
<img class="qrcode--icon" src="@/assets/img/down/wx.png"/>
</div>
<span class="group--item-title">微信公众号</span>
</li>
<li class="group--item">
<div class="qrcode">
<img class="qrcode--img" src="@/assets/img/down/h5-qrcode.png"/>
<img class="qrcode--icon" src="@/assets/img/down/browser.png"/>
</div>
<span class="group--item-title">H5</span>
</li>
</ul>
<div class="bg">
<i class="bg--icon1"></i>
<i class="bg--icon2"></i>
<i class="bg--icon3"></i>
<i class="bg--icon4"></i>
<i class="bg--icon5"></i>
</div>
</div>
</template>
<script>
export default {
layout : 'down'
}
</script>
<style lang="scss" scoped>
.main{
height: calc(100vh - 132px);
overflow: hidden;
position: relative;
}
.title{
text-align: center;
font-size: 40px;
font-family: 'PingFang SC-粗体, PingFang SC';
font-weight: bold;
color: #191919;
margin-top: 115px;
}
.desc{
text-align: center;
font-size: 24px;
font-family: 'PingFang SC-常规体, PingFang SC';
color: #A8A8A8;
line-height: 21px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 24px;
span{
margin: 0 15px;
display: inline-block;
width: 6px;
height: 6px;
background: #A8A8A8;
border-radius: 6px;
}
}
.group{
width: 930px;
margin: 73px auto;
display: flex;
justify-content: space-between;
z-index: 1;
position: relative;
&--item{
text-align: center;
&-title{
display: block;
font-size: 20px;
margin: 25px 0;
}
&-btn{
border: 1px solid #ddd;
color: #A7A7A7;
font-size: 16px;
width: 142px;
height: 40px;
line-height: 40px;
display: inline-block;
}
}
}
// .qrcode--img:hover + .qrcode--icon{
// opacity: 0;
// }
.qrcode{
width: 180px;
height: 180px;
background: url('@/assets/img/down/qrcode.png') no-repeat #F4F3F3 right top;
background-size: 52px;
cursor: pointer;
text-align: center;
position: relative;
&--icon{
position: absolute;
z-index: 1;
width: 57px;
height: 96px;
left: 62px;
top: 42px;
transition: opacity .8s;
opacity: 1;
}
&--img{
position: absolute;
z-index: 2;
left: 0;
top: 0;
transition: opacity 1s;
opacity: 0;
&:hover{
opacity: 1;
+ .qrcode--icon{
opacity: 0;
}
}
}
&__disabled{
cursor: no-drop;
.qrcode--img:hover{
opacity: 0;
+ .qrcode--icon{
opacity: 1;
}
}
}
}
.bg{
width: 1920px;
height: 100%;
@include adj(transform, translateX(-50%));
z-index: 0;
position: absolute;
left: 50%;
top: 0;
i{
position: absolute;
display: block;
background-size: 100%;
}
&--icon1{
bottom: 45px;
width: 152px;
height: 257px;
background-image: url('@/assets/img/down/bg1.png');
}
&--icon2{
top: 148px;
left: 140px;
width: 197px;
height: 214px;
background-image: url('@/assets/img/down/bg2.png');
animation: float 4s ease-in-out infinite;
}
&--icon3{
top: 549px;
left: 960px;
width: 116px;
height: 126px;
background-image: url('@/assets/img/down/bg3.png');
animation: float 5s ease-in-out infinite;
}
&--icon4{
top: 456px;
right: 261px;
width: 133px;
height: 137px;
background-image: url('@/assets/img/down/bg4.png');
animation: float 4s ease-in-out infinite;
}
&--icon5{
top: -72px;
right: -20px;
width: 200px;
height: 200px;
box-shadow: 0 0 50px #ffc9b6;
background: #FFF8F2;
border-radius: 50%;
filter: blur(50px);
// background-image: url('@/assets/img/down/bg5.png');
// background-size: 246px !important ;
// background-repeat: no-repeat;
// background-position: center;
}
}
@keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-50px);
}
100% {
transform: translateY(0px);
}
}
</style>

@ -41,6 +41,7 @@
</main> </main>
</div> </div>
<div v-else> <div v-else>
<HeaderBar v-show="showHeaderBar" :tabKey="headerKey" @jump="handleJump" @addCart="addCart" />
<nav class="nav flex flex-middle flex-center"> <nav class="nav flex flex-middle flex-center">
<p class="nav__crumbs"> <p class="nav__crumbs">
全部商品 全部商品
@ -104,11 +105,7 @@
<div class="main__details-msg"> <div class="main__details-msg">
<div class="main__details-msg--price flex flex-middle"> <div class="main__details-msg--price flex flex-middle">
<span class="msg-txt">售价</span> <span class="msg-txt">售价</span>
<strong class="msg-price">{{ <strong class="msg-price">{{ getPrice }}</strong>
detailData.productActivityVO.isStartActivity
? detailData.productActivityVO.activityPrice
: detailData.startingPrice
}}</strong>
<div <div
v-if=" v-if="
detailData.productActivityVO.isActivity && detailData.productActivityVO.isActivity &&
@ -163,7 +160,7 @@
<div class="main__details-option--line flex flex-middle"> <div class="main__details-option--line flex flex-middle">
<span class="line-txt">数量</span> <span class="line-txt">数量</span>
<div class="line-btns"> <div class="line-btns">
<el-input-number v-model="curBuyNum" :min="1"></el-input-number> <el-input-number v-model="curBuyNum" :min="1" :max='maxBuyNum'></el-input-number>
</div> </div>
</div> </div>
</div> </div>
@ -192,17 +189,15 @@
></UiGoodsItem> ></UiGoodsItem>
</div> </div>
<div class="section-details"> <div class="section-details">
<p class="section-title">商品详情</p> <p class="section-title" ref="detailRef">商品详情</p>
<div <div class="rich" v-html="detailData.detail" v-if="detailData.detail" ></div>
class="rich"
v-html="detailData.detail"
v-if="detailData.detail"
></div>
<div class="section-details--none" v-else> <div class="section-details--none" v-else>
<img src="@/assets/img/goods/none.png" alt="" /> <img src="@/assets/img/goods/none.png" alt="" />
<p>暂无详情</p> <p>暂无详情</p>
</div> </div>
<Comment ref="commentRef" />
</div> </div>
</section> </section>
<BsChosen v-else></BsChosen> <BsChosen v-else></BsChosen>
@ -239,14 +234,16 @@ import UiMoney from "@/components/UiMoney.vue";
import UiButton from "@/components/UiButton.vue"; import UiButton from "@/components/UiButton.vue";
import UiGoodsItem from "@/components/UiGoodsItem.vue"; import UiGoodsItem from "@/components/UiGoodsItem.vue";
import BsChosen from "@/components/BsChosen.vue"; import BsChosen from "@/components/BsChosen.vue";
import Comment from './module/Comment.vue';
import { ApiPutAddCart } from "@/plugins/api/cart"; import { ApiPutAddCart } from "@/plugins/api/cart";
import { import {
ApiGetGoodsDetail, ApiGetGoodsDetail,
ApiGetGoodsSkus, ApiGetGoodsSkus,
ApiGetGoodsList, ApiGetGoodsList,
} from "@/plugins/api/goods"; } from "@/plugins/api/goods";
import HeaderBar from './module/HeaderBar.vue';
export default { export default {
componetns: { UiMoney, UiButton, UiGoodsItem, BsChosen }, components: { UiMoney, UiButton, UiGoodsItem, BsChosen, Comment, HeaderBar },
data() { data() {
return { return {
pageLoading: true, pageLoading: true,
@ -264,6 +261,8 @@ export default {
startTime: "", startTime: "",
endTime: "", endTime: "",
showService: false, showService: false,
showHeaderBar : false,
headerKey: 'detail'
}; };
}, },
async created() { async created() {
@ -272,16 +271,16 @@ export default {
let res1 = await ApiGetGoodsDetail({ id }); let res1 = await ApiGetGoodsDetail({ id });
let res2 = await ApiGetGoodsSkus({ productId: id }); let res2 = await ApiGetGoodsSkus({ productId: id });
let res3 = await ApiGetGoodsList({ let res3 = await ApiGetGoodsList({
length: 3, length: 3,
pageIndex: 1, pageIndex: 1,
name: "", name: "",
categoryId: "", categoryId: "",
order: "", order: "",
}); });
vm.detailData = res1.result; vm.detailData = res1.result;
vm.skuData = res2.result; vm.skuData = res2.result;
vm.recommendedData = res3.result.records; vm.recommendedData = res3.result ? res3.result.records : [];
vm.pageLoading = false; vm.pageLoading = false;
if ( if (
vm.detailData.productActivityVO.isActivity && vm.detailData.productActivityVO.isActivity &&
@ -335,8 +334,47 @@ export default {
const stock = this.curSku.stock; const stock = this.curSku.stock;
return singleBuyLimit ? Math.min(singleBuyLimit, stock || 1) : stock; return singleBuyLimit ? Math.min(singleBuyLimit, stock || 1) : stock;
}, },
getPrice() {
if (this.curSku.sellPrice) {
return this.curSku.sellPrice;
} else {
return this.detailData.productActivityVO.isStartActivity
? this.detailData.productActivityVO.activityPrice
: this.detailData.startingPrice;
}
},
},
mounted(){
window.addEventListener("scroll", this.setHeaderBar);
this.setHeaderBar()
},
destroyed() {
window.removeEventListener("scroll", this.setHeaderBar);
}, },
methods: { methods: {
setHeaderBar(){
const y = window.scrollY
this.showHeaderBar = y > 700;
if(this.showHeaderBar){
const dY = this.$refs.detailRef.offsetTop;
const cY = this.$refs.commentRef.$el.offsetTop;
if(y >= cY){
this.headerKey = 'comment';
}else if(y > dY){
this.headerKey = 'detail';
}
}
},
handleJump(val){
if(val === 'detail'){
this.$refs.detailRef.scrollIntoView();
}else{
this.$refs.commentRef.$el.scrollIntoView();
}
this.headerKey = val;
},
onShowService() { onShowService() {
this.showService = true; this.showService = true;
}, },
@ -488,9 +526,9 @@ export default {
mode: "buyNow", mode: "buyNow",
skuId: this.curSku.skuId, skuId: this.curSku.skuId,
num: this.curBuyNum, num: this.curBuyNum,
productType : this.detailData.productType,
activityType: 1, activityType: 1,
}; };
console.log(query);
this.$router.push({ this.$router.push({
path: "/order/submit", path: "/order/submit",
query, query,
@ -521,6 +559,8 @@ export default {
this.$store.dispatch("getCartProducts"); this.$store.dispatch("getCartProducts");
// this.$Router.push('/cart'); // this.$Router.push('/cart');
}, },
}, },
}; };
</script> </script>
@ -532,6 +572,9 @@ export default {
margin-bottom: 14px; margin-bottom: 14px;
&__crumbs { &__crumbs {
width: 1200px; width: 1200px;
color: #666;
@include ellipsis;
padding-right: 970px
} }
} }
.main { .main {
@ -600,6 +643,7 @@ export default {
} }
&__details { &__details {
width: 714px; width: 714px;
padding-top: 10px;
&-title { &-title {
font-size: 16px; font-size: 16px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
@ -808,7 +852,7 @@ export default {
width: 1200px; width: 1200px;
margin: 64px auto 0; margin: 64px auto 0;
&-recommend { &-recommend {
width: 232px; width: 228px;
margin-right: 30px; margin-right: 30px;
/deep/.goods-item { /deep/.goods-item {

@ -0,0 +1,318 @@
<!--
* @Author: ch
* @Date: 2022-06-24 14:39:38
* @LastEditors: ch
* @LastEditTime: 2022-06-30 22:42:19
* @Description: file content
-->
<template>
<div>
<div class="title">
<b>商品评价</b>
<div>
<el-dropdown class="title--sort" @command="handleCommand">
<span>{{sortActive.label}}<i class="el-icon-arrow-down el-icon--right"></i></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item in sortData" :key="item.val" :command="item">{{item.label}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-checkbox v-model="isContent" @change="handledContent"></el-checkbox>
</div>
</div>
<div class="ctx">
<div class="ctx--top">
<div class="ctx--top-rate" v-if="productRate">
<b>商品满意度</b>
<p>{{productRate}}</p>
<el-rate :value="productRate" disabled size="16px"></el-rate>
</div>
<div class="ctx--top-tabs" v-if="tabs.length > 1">
<span v-for="i in tabs" :key="i.labelType" @click="handleTabChanage(i)"
:class="{'active':i.labelType == tabActive}">
{{i.labelName}}({{i.commentCount}})
</span>
</div>
</div>
<UiEmpty v-if="!list.length && loading=='finish'" :icon="require('@/assets/img/comment/empty.png')" desc="暂时没有评论"/>
<template v-else>
<BsCommentInfo v-for="item in list" :key="item.id" :commentDetail="item" source="detail"/>
</template>
<div v-if="loading === 'loading'" class="loading">....</div>
<div v-if="loading === 'finish'" class="more" @click="next">></div>
</div>
<!-- <el-pagination class="pagination flex flex-right" layout="prev, pager, next"
@current-change="handleCurrentChange" :current-page.sync="pageIndex"
:page-size="pageSize" :total="total"></el-pagination> -->
</div>
</template>
<script>
import {
ApiGetCommentList,
ApiGetCommentTabCount,
ApiGetProductSatisfaction,
ApiGetCommentCount
} from "@/plugins/api/comment";
import BsCommentInfo from '../../../../components/BsCommentInfo.vue';
export default {
components: { BsCommentInfo },
props : {
},
data(){
return {
productId : this.$route.params.id,
tabActive : -1,
sortData : [{
val : 1,
label : '默认排序'
},{
val : 2,
label : '按时间排序'
}],
sortActive : {
val : 1,
label : '默认排序'
},
productRate : 0,
isContent : true,
pageIndex : 1,
pageSize : 10,
total:0,
tabs : [
{
labelName : '全部',
labelType : -1,
commentCount : 0
}
],
pageSize : 10,
list : [],
loading : 'finish'
}
},
mounted(){
this.getList();
this.getTabCount();
this.getProductSatisfaction();
this.getCount();
},
methods:{
async getList(){
if(this.loading === 'loading'){
return false;
}
this.loading = 'loading';
const {error, result} = await ApiGetCommentList({
pageIndex : this.pageIndex,
length : this.pageSize,
productId : this.productId,
commentLabel : this.tabActive == -1 ? null : this.tabActive,
sortType : this.sortActive.val,
isContent : this.isContent || null
});
this.loading = 'finish';
if(error){
return false;
}
this.list = this.list.concat(result.records);
//
if(result.records.length == 0 && this.pageIndex < result.pages){
this.next();
return false;
}
if(this.pageIndex === result.pages){
this.loading = 'nomore'
}
// this.total = result.total
},
next(){
this.pageIndex++;
this.getList();
},
async getTabCount (){
const {error, result} = await ApiGetCommentTabCount({
productId : this.productId
});
if(error){
return false;
}
this.tabs = this.tabs.concat(result.filter(i => i.commentCount > 0));
},
async getCount(){
const {error, result} = await ApiGetCommentCount({
productId : this.productId
});
if(error){
return false;
}
this.$set(this.tabs[0],'commentCount', result.allCommentCount)
},
async getProductSatisfaction (){
const {error, result} = await ApiGetProductSatisfaction({
productId : this.productId
});
if(error){
return false;
}
this.productRate = Number(result.productSatisfaction);
},
handleCurrentChange(val) {
this.pageIndex = val;
this.getList();
},
handleTabChanage(i){
if(this.tabActive == i.labelType){
return false
}
this.tabActive = i.labelType;
this.pageIndex = 1;
this.list = [];
this.getList();
},
handleCommand(val){
this.sortActive = val;
this.pageIndex = 1;
this.list = [];
this.getList();
},
handledContent(){
this.pageIndex = 1;
this.list = [];
this.getList();
}
}
}
</script>
<style lang="scss" scoped>
.title {
margin-top: 30px;
width: 100%;
height: 40px;
line-height: 40px;
background: #f7f7f7;
border: 1px solid #f2f2f2;
padding: 0 16px;
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #666666;
display: flex;
justify-content: space-between;
&--sort{
margin-right: 30px;
cursor: pointer;
&:hover{
color: #FF512B;
}
}
}
.ctx{
border: 1px solid #f2f2f2;
border-top: 0;
overflow: hidden;
margin-bottom: 40px;
&--top{
display: flex;
&-rate{
width: 170px;
height: 136px;
text-align: center;
padding-top: 26px;
color: #666;
position: relative;
b{
font-weight: normal;
display: block;
height: 14px;
}
p{
font-size: 40px;
height: 40px;
line-height: 40px;
font-weight: bold;
margin-top: 6px;
}
&::after{
content: '';
display: block;
height: 90px;
width: 1px;
background: #eee;
position: absolute;
right: 0;
top: 26px;
}
/deep/.el-rate__icon{
margin-right: 0;
font-size: 24px;
}
}
&-tabs{
margin: 34px 0;
padding-left: 40px;
display: flex;
align-items: center;
span{
display: inline-block;
height: 24px;
line-height: 22px;
border: 1px solid #eee;
color: #999;
padding: 0 12px;
font-size: 12px;
border-radius: 4px;
margin-right: 16px;
cursor: pointer;
&.active{
background: #FF6A19;
border-color: #FF6A19;
color: #fff;
}
}
}
}
}
.loading,.more{
color: #999;
text-align: center;
margin-bottom: 40px;
}
.more{
cursor: pointer;
}
.pagination {
margin: 50px 0;
/deep/.el-pager {
margin-left: 8px;
}
/deep/button,
/deep/.number,
/deep/.btn-quicknext,
/deep/.btn-quickprev {
width: 32px;
height: 32px;
text-align: center;
line-height: 32px;
margin-left: 8px;
border-radius: 2px 2px 2px 2px;
border: 1px solid rgba(0, 0, 0, 0.15);
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: rgba(0, 0, 0, 0.65);
}
/deep/.active {
background: #ff512b;
color: #fff;
}
}
</style>

@ -0,0 +1,84 @@
<!--
* @Author: ch
* @Date: 2022-06-25 07:24:32
* @LastEditors: ch
* @LastEditTime: 2022-06-29 14:19:36
* @Description: file content
-->
<template>
<div class="header">
<div class="header--layout">
<ul>
<li @click="handleJump('detail')" :class="{'active': tabKey =='detail'}">商品详情</li>
<li @click="handleJump('comment')" :class="{'active': tabKey =='comment'}">商品评价</li>
</ul>
<UiButton @click="handleAddCart"></UiButton>
</div>
</div>
</template>
<script>
import UiButton from '@/components/UiButton.vue'
export default {
components: { UiButton },
props:{
tabKey : {
type : String,
default : 'detail'
}
},
data(){
return {}
},
methods:{
handleJump(val){
this.$emit('jump', val)
},
handleAddCart(){
this.$emit('addCart')
}
}
}
</script>
<style lang="scss" scoped>
.header{
position: fixed;
top: 0;
left: 0;
right: 0;
height: 70px;
background: #fff;
z-index: 11;
&--layout{
@include layout-box;
padding-left: 256px;
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
ul{
display: flex;
font-size: 16px;
li{
margin-right: 50px;
height: 70px;
line-height: 70px;
&.active{
color: #FF6A19;
position: relative;
&::after{
display: block;
content: '';
position: absolute;
height: 2px;
width: 40px;
background: #FF6A19;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
}
}
}
}
}
</style>

@ -11,7 +11,7 @@
<el-skeleton <el-skeleton
v-for="item in 5" v-for="item in 5"
:key="item" :key="item"
style="width: 230px;margin-right:20px;" style="width: 230px; margin-right: 20px"
:loading="true" :loading="true"
animated animated
> >
@ -194,8 +194,8 @@ export default {
if (vm.levelType == 1) { if (vm.levelType == 1) {
vm.params.categoryId = vm.categoryOneList[vm.levelActive].id; vm.params.categoryId = vm.categoryOneList[vm.levelActive].id;
} }
if(vm.params.name){ if (vm.params.name) {
vm.params.categoryId = '' vm.params.categoryId = "";
} }
let res = await ApiGetGoodsList(vm.params); let res = await ApiGetGoodsList(vm.params);
vm.pageloading = false; vm.pageloading = false;
@ -259,6 +259,9 @@ export default {
&-btn { &-btn {
margin-right: 50px; margin-right: 50px;
cursor: pointer; cursor: pointer;
&:hover {
color: #ff512b;
}
} }
&-active { &-active {
color: #ff512b; color: #ff512b;

@ -2,12 +2,12 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-03 22:14:16 * @Date: 2022-05-03 22:14:16
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 22:21:04 * @LastEditTime: 2022-06-13 10:28:21
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div class="home"> <div class="home">
<Banner /> <Banner :data="bannerList"/>
<div class="home-wrap"> <div class="home-wrap">
<Seckil <Seckil
v-if="seckillData.activityTimeVO" v-if="seckillData.activityTimeVO"
@ -31,12 +31,6 @@
:key="item.id" :key="item.id"
></UiGoodsItem> ></UiGoodsItem>
</div> </div>
<UiPagination
:current-page="currentPage"
:page-size="query.length"
:total="total"
@current-change="handleCurrentChange"
/>
</div> </div>
</div> </div>
</div> </div>
@ -45,8 +39,8 @@
</template> </template>
<script> <script>
import _ from "lodash";
import UiGoodsItem from "@/components/UiGoodsItem.vue"; import UiGoodsItem from "@/components/UiGoodsItem.vue";
import UiPagination from "@/components/UiPagination.vue";
import { import {
ApiGetHomeSeckill, ApiGetHomeSeckill,
ApiGetCurrentTime, ApiGetCurrentTime,
@ -56,15 +50,20 @@ import {
ApiGetRecommendedGoodsList, ApiGetRecommendedGoodsList,
ApiGetGoodsList, ApiGetGoodsList,
} from "@/plugins/api/goods"; } from "@/plugins/api/goods";
import {
ApiGetAdList
} from "@/plugins/api/ad";
import Banner from "./module/Banner.vue"; import Banner from "./module/Banner.vue";
import Seckil from "./module/Seckill.vue"; import Seckil from "./module/Seckill.vue";
import Pick from "./module/Pick.vue"; import Pick from "./module/Pick.vue";
import { AD_LOCATION } from '@/plugins/dicts/ad';
import TabbarFixed from "./module/TabbarFixed.vue"; import TabbarFixed from "./module/TabbarFixed.vue";
const SECKILL_COUNT = 20; // const SECKILL_COUNT = 20; //
const NEW_COUNT = 5; // const NEW_COUNT = 5; //
const FOOTER_BAR_HEIGHT = 200; //
export default { export default {
components: { Banner, Seckil, Pick, UiGoodsItem, UiPagination, TabbarFixed }, components: { Banner, Seckil, Pick, UiGoodsItem, TabbarFixed },
async asyncData({ store }) { async asyncData({ store }) {
// //
let seckillData = { activityTimeVO: null }; let seckillData = { activityTimeVO: null };
@ -100,9 +99,16 @@ export default {
if (newDataResult) { if (newDataResult) {
newData = newDataResult.records || []; newData = newDataResult.records || [];
} }
let {result:bannerList} = await ApiGetAdList({
location : AD_LOCATION.HOME_BANNER
});
bannerList = bannerList || [];
return { return {
currentTime, currentTime,
bannerList,
newData, newData,
sekillGoodsList, sekillGoodsList,
seckillData, seckillData,
@ -120,12 +126,16 @@ export default {
loading: false, loading: false,
currentPage: 0, currentPage: 0,
scrollTop: 0, scrollTop: 0,
ticking: false,
}; };
}, },
created() { created() {
this.getSelectProducts(); this.getSelectProducts();
}, },
mounted() { async mounted() {
let {result:bannerList} = await ApiGetAdList({
location : AD_LOCATION.HOME_BANNER
});
// //
window.addEventListener("scroll", this.scrollEventMethod); window.addEventListener("scroll", this.scrollEventMethod);
}, },
@ -133,9 +143,21 @@ export default {
window.removeEventListener("scroll", this.scrollEventMethod); window.removeEventListener("scroll", this.scrollEventMethod);
}, },
methods: { methods: {
scrollEventMethod() { scrollEventMethod: _.debounce(function () {
this.scrollTop = window.scrollY; this.scrollTop = window.scrollY;
}, const contentHeight = document.body.scrollHeight; //
const clientHeight = document.body.clientHeight; //
if (
window.scrollY + clientHeight >= contentHeight - FOOTER_BAR_HEIGHT &&
this.total &&
this.selectProducts.length < this.total
) {
this.query.pageIndex += 1;
//
this.getSelectProducts();
}
}, 200),
// //
async handleSeckillRefresh() { async handleSeckillRefresh() {
@ -153,13 +175,9 @@ export default {
if (result) { if (result) {
const { total, records } = result; const { total, records } = result;
this.total = total; this.total = total;
this.selectProducts = records; this.selectProducts = this.selectProducts.concat(records);
} }
}, },
handleCurrentChange(page) {
this.query.pageIndex = page;
this.getSelectProducts();
},
}, },
}; };
</script> </script>

@ -2,17 +2,17 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:50:33 * @Date: 2022-05-04 17:50:33
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-04 22:15:26 * @LastEditTime: 2022-06-01 11:40:32
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div class="home-banner"> <div class="home-banner">
<el-carousel height="360px" indicator-position="outside"> <el-carousel height="360px" indicator-position="outside">
<el-carousel-item v-for="item in bannerList" :key="item.id"> <el-carousel-item v-for="item in data" :key="item.id">
<el-image <el-image
@click="onBannerClick(item.id)" @click="onBannerClick(item)"
:src="item.url" :src="item.pictureUrl"
fit="cover" fit="cover"
></el-image> ></el-image>
</el-carousel-item> </el-carousel-item>
@ -20,39 +20,42 @@
</div> </div>
</template> </template>
<script> <script>
import { AD_JUMP_TYPE } from '@/plugins/dicts/ad';
export default { export default {
name: "HomtBanner", name: "HomtBanner",
props : {
data : {
type : Array,
default : () => ([])
}
},
data() { data() {
return { return {
bannerList: [
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods13.jpg",
id: 13,
},
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods30.jpg",
id: 30,
},
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods15.jpg",
id: 15,
},
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods40.jpg",
id: 40,
},
],
}; };
}, },
methods: { methods: {
onBannerClick(goodsId) { onBannerClick(item) {
window.open(`${location.origin}/goods/detail/${goodsId}`); switch (item.jumpType) {
}, case AD_JUMP_TYPE.GOODS:
window.open(`${location.origin}/goods/detail/${item.jumpUrl}`);
break;
case AD_JUMP_TYPE.CATEGORY:
window.open(`${location.origin}/goods/list?id=${item.jumpUrl}&levelType=2`);
break;
case AD_JUMP_TYPE.LINK:
window.open(item.jumpUrl, '_blank');
break;
default:
break
}
}
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.home-banner { .home-banner {
@include layout-box;
/deep/.el-carousel { /deep/.el-carousel {
.el-carousel__container { .el-carousel__container {
i { i {
@ -67,7 +70,7 @@ export default {
display: none; display: none;
} }
.el-carousel__arrow--left { .el-carousel__arrow--left {
left: calc(50% - 380px) !important; left: calc(50% - 550px) !important;
} }
.el-carousel__arrow--right { .el-carousel__arrow--right {
right: calc(50% - 550px) !important; right: calc(50% - 550px) !important;

@ -42,9 +42,11 @@
v-for="(item, index) in recommendArray" v-for="(item, index) in recommendArray"
:key="index" :key="index"
@click="onJumpGoodsDetail(item.id)" @click="onJumpGoodsDetail(item.id)"
class="recommend-products-right__item" class="recommend-products-right__item flex flex-column"
> >
<strong class="home-pick-recommend--title">{{ item.title }}</strong> <strong class="home-pick-recommend--title2">{{
item.title
}}</strong>
<p class="home-pick-recommend--subtitle"> <p class="home-pick-recommend--subtitle">
{{ recommendGoodsOne.subtitle }} {{ recommendGoodsOne.subtitle }}
</p> </p>
@ -68,43 +70,70 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 新品上架 --> <!-- 新品上架 -->
<div v-if="showNew" class="home-pick-new"> <div v-if="showNew" class="home-pick-recommend">
<div class="home-pick--label flex flex-middle"> <div class="home-pick--label flex flex-middle">
<strong>新品上架</strong> <strong>新品上架</strong>
</div> </div>
<div class="home-pick-new__products flex"> <div class="home-pick-recommend__products flex flex-middle flex-between">
<!-- 左侧商品 --> <!-- 左侧商品 -->
<div <div
@click="onJumpGoodsDetail(newGoodsOne.id)" @click="onJumpGoodsDetail(newGoodsOne.id)"
class="pick-new-products__left" class="pick-recommend-products__left"
> >
<img <strong class="home-pick-recommend--title">
:src="newGoodsOne.mainPicture" {{ newGoodsOne.name }}
class="new-products-left__cover" </strong>
/> <!-- 商品标签 -->
<div class="new-products-left__wrap"> <div
<p>{{ newGoodsOne.name }}</p> v-for="item in newGoodsOne.labelList"
<strong class="home-pick--price__16">{{ :key="item.code"
newGoodsOne.startingPrice class="home-pick-recommend--tag-wrap flex"
}}</strong> >
<div :class="`tag-wrap__item tag-wrap__item--${item.code}`">
{{ item.text }}
</div>
</div>
<p class="home-pick-recommend--subtitle">
{{ newGoodsOne.subtitle }}
</p>
<strong class="home-pick--price__18">{{
newGoodsOne.startingPrice
}}</strong>
<div class="recommend-products-left__cover">
<img :src="newGoodsOne.mainPicture" />
</div> </div>
</div> </div>
<div class="pick-new-products__right flex flex-wrap flex-between"> <!-- 右侧商品 -->
<div
class="pick-recommend-products__right flex flex-column flex-between"
>
<div <div
v-for="(item, index) in newArray" v-for="(item, index) in newArray"
:key="index" :key="index"
@click="onJumpGoodsDetail(item.id)" @click="onJumpGoodsDetail(item.id)"
class="new-products-right__wrap flex flex-middle" class="recommend-products-right__item flex flex-column"
> >
<div class="products-right-wrap__cover"> <strong class="home-pick-recommend--title2">{{ item.name }}</strong>
<img :src="item.mainPicture" /> <p class="home-pick-recommend--subtitle">
{{ item.subtitle }}
</p>
<!-- 商品标签 -->
<div
v-for="itemLabel in item.labelList"
:key="itemLabel.code"
class="home-pick-recommend--tag-wrap flex"
>
<div :class="`tag-wrap__item tag-wrap__item--${itemLabel.code}`">
{{ itemLabel.text }}
</div>
</div> </div>
<div class="products-right-wrap__info"> <strong class="home-pick--price__18">{{
<p>{{ item.name }}</p> item.startingPrice
<strong class="home-pick--price__14">{{ }}</strong>
item.startingPrice <div class="recommend-products-right__cover flex-1">
}}</strong> <img :src="item.mainPicture" />
</div> </div>
</div> </div>
</div> </div>
@ -114,7 +143,7 @@
</template> </template>
<script> <script>
const RECOMMEND_MIN_COUNT = 3; // const RECOMMEND_MIN_COUNT = 3; //
const NEW_MIN_COUNT = 5; // const NEW_MIN_COUNT = 3; //
export default { export default {
name: "HomePick", name: "HomePick",
@ -176,7 +205,7 @@ export default {
margin-top: 30px; margin-top: 30px;
&--label { &--label {
font-size: 24px; font-size: 24px;
margin-bottom: 16px; margin-bottom: 30px;
img { img {
width: 16px; width: 16px;
height: 16px; height: 16px;
@ -185,6 +214,7 @@ export default {
} }
&--price { &--price {
&__18 { &__18 {
margin-top: auto;
font-size: 18px; font-size: 18px;
color: #ff512b; color: #ff512b;
&::before { &::before {
@ -211,10 +241,9 @@ export default {
} }
.home-pick-recommend { .home-pick-recommend {
width: 590px; width: 50%;
height: 340px; min-height: 340px;
padding: 16px 20px; padding: 16px 20px 20px;
background: #ffffff;
border-radius: 4px; border-radius: 4px;
&--tag-wrap { &--tag-wrap {
margin-bottom: 8px; margin-bottom: 8px;
@ -240,7 +269,14 @@ export default {
} }
&--title { &--title {
display: block; display: block;
width: 140px; width: 200px;
font-size: 16px;
margin-bottom: 6px;
@include ellipsis;
}
&--title2 {
display: block;
width: 150px;
font-size: 16px; font-size: 16px;
margin-bottom: 6px; margin-bottom: 6px;
@include ellipsis; @include ellipsis;
@ -251,20 +287,27 @@ export default {
margin-bottom: 8px; margin-bottom: 8px;
} }
&__products { &__products {
height: 264px; // height: 264px;
cursor: pointer; cursor: pointer;
.pick-recommend-products__left { .pick-recommend-products__left {
position: relative; position: relative;
width: 264px; width: 292px;
height: 100%; height: 302px;
background: #f8f8f9; background: #fff;
padding: 12px 0 0 20px; padding: 20px;
margin-right: 16px;
transition: all 0.3s;
&:hover {
box-shadow: 0px 4px 40px 1px rgba(0, 0, 0, 0.10000000149011612);
margin-top: -3px;
}
.recommend-products-left__cover { .recommend-products-left__cover {
position: absolute; position: absolute;
right: 0; right: 18px;
bottom: 0; bottom: 18px;
width: 158px; width: 170px;
height: 158px; height: 170px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -275,11 +318,21 @@ export default {
width: 266px; width: 266px;
height: 100%; height: 100%;
.recommend-products-right__item { .recommend-products-right__item {
width: 100%; width: 284px;
height: 122px; height: 144px;
border-radius: 4px;
position: relative; position: relative;
background: #f8f7f8; background: #fff;
padding: 10px 0 10px 20px; padding: 20px;
transition: all 0.3s;
&:hover {
box-shadow: 0px 4px 40px 1px rgba(0, 0, 0, 0.10000000149011612);
}
&:nth-child(1) {
margin-bottom: 16px;
}
} }
.recommend-products-right__cover { .recommend-products-right__cover {
position: absolute; position: absolute;
@ -296,63 +349,5 @@ export default {
} }
} }
} }
.home-pick-new {
width: 590px;
height: 340px;
padding: 14px 20px 16px 20px;
background: #ffffff;
border-radius: 4px;
&__products {
cursor: pointer;
.pick-new-products__left {
width: 170px;
height: 264px;
background: #f8f8f9;
margin-right: 20px;
.new-products-left__cover {
width: 170px;
height: 170px;
}
.new-products-left__wrap {
padding: 10px 0;
text-align: center;
font-size: 14px;
p {
width: 140px;
margin: 0 auto 12px auto;
@include ellipsis;
}
}
}
.pick-new-products__right {
.new-products-right__wrap {
width: 170px;
height: 100px;
background: #ffffff;
padding: 16px 8px 16px 0;
&:nth-child(-n + 2) {
margin-bottom: 40px;
}
.products-right-wrap__cover {
width: 68px;
height: 68px;
margin-right: 16px;
img {
width: 100%;
height: 100%;
}
}
.products-right-wrap__info {
font-size: 14px;
p {
width: 78px;
margin-bottom: 8px;
@include ellipses(2);
}
}
}
}
}
}
} }
</style> </style>

@ -7,61 +7,73 @@
--> -->
<template> <template>
<div class="home-sckill flex" @click="onJumpSeckill"> <main class="main">
<div class="home-sckill-bar" :style="{ backgroundImage: `url(${bkgUrl})` }"> <div class="home-sckill-bar flex flex-middle">
<strong class="home-sckill-title">限时秒杀</strong> <img
class="home-sckill-title"
src="~/assets/img/sckill/title.png"
alt=""
/>
<div class="home-sckill-wrap"> <div class="home-sckill-wrap">
<div class="home-sckill-wrap__tip"> <div class="home-sckill-wrap__tip">
<strong>{{ data.activityTimeVO.timeName }}</strong> {{ data.activityTimeVO.timeName }} {{ seckillText }}
<span>{{ seckillText }}</span>
</div> </div>
<div class="home-sckill-wrap__countdown flex flex-middle flex-center"> </div>
<div class="sckill-wrap-countdown__time">{{ countdown.hour }}</div> <div class="home-sckill-wrap__countdown flex flex-middle flex-center">
<span class="sckill-wrap-countdown--mark">:</span> <div class="sckill-wrap-countdown__time">{{ countdown.hour }}</div>
<div class="sckill-wrap-countdown__time">{{ countdown.minute }}</div> <span class="sckill-wrap-countdown--mark">:</span>
<span class="sckill-wrap-countdown--mark">:</span> <div class="sckill-wrap-countdown__time">
<div class="sckill-wrap-countdown__time">{{ countdown.second }}</div> {{ countdown.minute }}
</div>
<span class="sckill-wrap-countdown--mark">:</span>
<div class="sckill-wrap-countdown__time">
{{ countdown.second }}
</div> </div>
</div> </div>
</div> </div>
<div class="home-sckill-carousel"> <div class="home-sckill flex" @click="onJumpSeckill">
<el-carousel <div class="home-sckill-carousel">
height="260px" <el-carousel
arrow="always" height="300px"
:autoplay="false" arrow="always"
:loop="false" :autoplay="false"
> :loop="false"
<el-carousel-item v-for="(item, index) in goodsList" :key="index"> >
<div class="carousel-goods flex"> <el-carousel-item v-for="(item, index) in goodsList" :key="index">
<div <div class="carousel-goods flex">
v-for="(itemChild, indexChild) in item"
:key="itemChild.productId"
class="carousel-goods-box flex flex-middle"
>
<div <div
v-if="indexChild !== 0" v-for="(itemChild, indexChild) in item"
class="carousel-goods-box--line" :key="itemChild.productId"
></div> class="carousel-goods-box flex flex-middle"
<div class="carousel-goods-box__item"> >
<img <div
class="goods-box-item__cover" class="carousel-goods-box__item flex flex-column flex-middle"
:src="itemChild.productMainPicture" >
/> <img
<div class="goods-box-item__wrap"> class="goods-box-item__cover"
<p class="box-item-wrap__title"> :src="itemChild.productMainPicture"
{{ itemChild.productName }} />
</p> <div class="goods-box-item__wrap">
<strong class="box-item-wrap__price" <p class="box-item-wrap__title">
>{{ itemChild.activityPrice }}</strong {{ itemChild.productName }}
> </p>
<p>
<strong class="box-item-wrap__price"
>{{ itemChild.activityPrice }}</strong
>
<span class="box-item-wrap__price2"
>{{ itemChild.originalPrice }}</span
>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </el-carousel-item>
</el-carousel-item> </el-carousel>
</el-carousel> </div>
</div> </div>
</div> </main>
</template> </template>
<script> <script>
import _ from "lodash"; import _ from "lodash";
@ -151,6 +163,8 @@ export default {
// //
setTimerInterval({ startTime, endTime }) { setTimerInterval({ startTime, endTime }) {
startTime = startTime .replace(/\-/g, "/");
endTime = endTime .replace(/\-/g, "/");
startTime = new Date(startTime).getTime(); startTime = new Date(startTime).getTime();
endTime = new Date(endTime).getTime(); endTime = new Date(endTime).getTime();
if (this.current > startTime && this.current < endTime) { if (this.current > startTime && this.current < endTime) {
@ -179,57 +193,49 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.home-sckill { .home-sckill-bar {
height: 260px; width: 100%;
cursor: pointer; padding-bottom: 28px;
.home-sckill-bar { .home-sckill-title {
width: 190px; width: 110px;
height: 100%; height: 26px;
padding: 45px 0 28px 0; margin-right: 20px;
text-align: center; }
color: #ffffff; .home-sckill-wrap {
background-size: 100% 100%; .home-sckill-wrap__tip {
border-radius: 4px 0 0 4px; font-size: 18px;
.home-sckill-title { font-family: Microsoft YaHei-Regular, Microsoft YaHei;
display: block; font-weight: 400;
font-size: 28px; color: #999999;
margin-bottom: 90px; margin-right: 10px;
} }
.home-sckill-wrap { }
margin-bottom: 10px;
.home-sckill-wrap__tip { .home-sckill-wrap__countdown {
font-size: 0; .sckill-wrap-countdown__time {
strong { width: 30px;
font-size: 18px; height: 30px;
margin-right: 4px; line-height: 30px;
} text-align: center;
span { color: #ffffff;
font-size: 14px; font-size: 18px;
} font-weight: bold;
} background: #2f3430;
.home-sckill-wrap__countdown { }
margin-top: 10px; .sckill-wrap-countdown--mark {
.sckill-wrap-countdown__time { display: block;
width: 30px; font-size: 20px;
height: 30px; margin: 0 8px;
line-height: 30px;
text-align: center;
color: #ffffff;
font-size: 18px;
font-weight: bold;
background: #2f3430;
}
.sckill-wrap-countdown--mark {
display: block;
font-size: 20px;
margin: 0 8px;
}
}
} }
} }
}
.home-sckill {
height: 300px;
cursor: pointer;
margin-bottom: 60px;
.home-sckill-carousel { .home-sckill-carousel {
/deep/.el-carousel { /deep/.el-carousel {
width: 1010px; width: 1200px;
border-radius: 4px; border-radius: 4px;
.el-carousel__container { .el-carousel__container {
padding: 0 10px; padding: 0 10px;
@ -256,32 +262,45 @@ export default {
} }
.carousel-goods { .carousel-goods {
height: 100%; height: 100%;
background: #f8f8f8;
.carousel-goods-box { .carousel-goods-box {
.carousel-goods-box--line { margin-right: 15px;
height: 160px; width: 228px;
width: 1px; height: 300px;
background: #eeeeee; background: #ffffff;
} border-radius: 4px;
.carousel-goods-box__item { .carousel-goods-box__item {
width: 198px; width: 100%;
padding: 20px 24px; padding: 20px 24px;
transition: all .3s;
&:hover {
transform: translateY(-3px);
}
.goods-box-item__cover { .goods-box-item__cover {
width: 150px; width: 140px;
height: 150px; height: 140px;
object-fit: productMainPicture; object-fit: productMainPicture;
margin-bottom: 14px; margin-bottom: 24px;
} }
.goods-box-item__wrap { .goods-box-item__wrap {
font-size: 14px; font-size: 16px;
color: #333333; color: #333333;
text-align: center; text-align: center;
width: 100%;
.box-item-wrap__title { .box-item-wrap__title {
@include ellipsis; @include ellipsis;
margin-bottom: 8px; margin-bottom: 20px;
} }
.box-item-wrap__price { .box-item-wrap__price {
color: #ff512b; color: #ff512b;
text-align: center; text-align: center;
margin-right: 15px;
}
.box-item-wrap__price2 {
color: #999999;
text-decoration: line-through;
} }
} }
} }

@ -2,12 +2,12 @@
<div <div
v-if="tabBarVisible" v-if="tabBarVisible"
class="home-tabbar-fixed flex" class="home-tabbar-fixed flex"
:class="{ 'home-tabbar-fixed--change': appHover }" :style="tabBarStyle"
> >
<div v-show="appHover" class="home-tabbar-fixed__qrcode"> <!-- <div v-show="appHover" class="home-tabbar-fixed__qrcode">
<img src="~/assets/img/common/app-qrcode.png" /> <img src="~/assets/img/common/app-qrcode.png" />
<p>扫一扫上方二维码 下载APP</p> <p>扫一扫上方二维码 下载APP</p>
</div> </div> -->
<div <div
class="home-tabbar-fixed__box flex flex-column flex-middle" class="home-tabbar-fixed__box flex flex-column flex-middle"
:class="{ 'home-tabbar-fixed__box--height-short': !showToTop }" :class="{ 'home-tabbar-fixed__box--height-short': !showToTop }"
@ -15,20 +15,21 @@
<div <div
@mouseenter="appHover = true" @mouseenter="appHover = true"
@mouseleave="appHover = false" @mouseleave="appHover = false"
@click="$router.push('/down')"
class="tabbar-fixed-box__common flex flex-middle" class="tabbar-fixed-box__common flex flex-middle"
> >
<span v-show="appHover">app</span> <span v-show="appHover">APP</span>
<img v-show="!appHover" src="~/assets/img/home/icon-app.png" /> <img v-show="!appHover" src="~/assets/img/home/icon-app.png" />
</div> </div>
<div class="tabbar-fixed-box__line"></div> <div class="tabbar-fixed-box__line"></div>
<div <div
@mouseenter="customerHover = true" @mouseenter="messageHover = true"
@mouseleave="customerHover = false" @mouseleave="messageHover = false"
@click="onConcatCustomer" @click="onOpenMessagePage"
class="tabbar-fixed-box__common flex flex-middle" class="tabbar-fixed-box__common flex flex-middle"
> >
<span v-show="customerHover"></span> <span v-show="messageHover"></span>
<img v-show="!customerHover" src="~/assets/img/home/icon-message.png" /> <img v-show="!messageHover" src="~/assets/img/home/icon-message.png" />
</div> </div>
<div v-show="showToTop"> <div v-show="showToTop">
<div class="tabbar-fixed-box__line"></div> <div class="tabbar-fixed-box__line"></div>
@ -60,9 +61,10 @@ export default {
data() { data() {
return { return {
appHover: false, appHover: false,
customerHover: false, messageHover: false,
totopHover: false, totopHover: false,
tabBarVisible: false, tabBarVisible: false,
tabBarStyle: null,
}; };
}, },
computed: { computed: {
@ -72,6 +74,7 @@ export default {
}, },
mounted() { mounted() {
this.getTabBarVisible(); this.getTabBarVisible();
this.getTabBarStyle();
}, },
methods: { methods: {
getTabBarVisible() { getTabBarVisible() {
@ -80,10 +83,21 @@ export default {
this.tabBarVisible = true; this.tabBarVisible = true;
} }
}, },
onConcatCustomer() {
//
getTabBarStyle() {
const clientHeight = document.body.clientHeight;
const TOP = 630;
const NORMAL_HEIGHT = 1080;
this.tabBarStyle = {
top: `${(TOP / NORMAL_HEIGHT) * clientHeight}px`,
};
},
onOpenMessagePage() {
if (!this.$isLoginValidate()) { if (!this.$isLoginValidate()) {
return; return;
} }
window.open(`${location.origin}/account/message`);
}, },
toPageTop() { toPageTop() {
document.querySelector("body").scrollIntoView({ behavior: "smooth" }); document.querySelector("body").scrollIntoView({ behavior: "smooth" });
@ -96,8 +110,8 @@ export default {
position: fixed; position: fixed;
z-index: 99; z-index: 99;
left: 50%; left: 50%;
top: 568px;
margin-left: 630px; margin-left: 630px;
border: 1px solid #f8f8f8;
&--change { &--change {
margin-left: 390px; margin-left: 390px;
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-08 01:11:33 * @Date: 2022-05-08 01:11:33
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-10 15:48:51 * @LastEditTime: 2022-05-27 20:01:33
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -14,6 +14,7 @@
<UiButton type="grey" @click="goHome" :radius="true">返回首页</UiButton> <UiButton type="grey" @click="goHome" :radius="true">返回首页</UiButton>
<UiButton type="yellow_gradual" @click="goDetail" :radius="true">查看订单</UiButton> <UiButton type="yellow_gradual" @click="goDetail" :radius="true">查看订单</UiButton>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
@ -24,8 +25,25 @@ export default {
data(){ data(){
return { return {
orderInfo : {}, orderInfo : {},
type : this.$route.query.type,
reuqestNum : 0 reuqestNum : 0
} }
},
mounted(){
// this.getOrderInfo();
if(this.$route.query.type == 2){
this.$confirm("虚拟商品已自动发货,前往消息中心查看?", "提示", {
confirmButtonText: "前往",
cancelButtonText: "取消",
callback: async (e) => {
if (e == `confirm`) {
window.open('https://you.mashibing.com/account/message','_black');
}
}
})
}
}, },
methods:{ methods:{
async getOrderInfo(){ async getOrderInfo(){
@ -48,7 +66,7 @@ export default {
}, },
goDetail(){ goDetail(){
this.$router.replace(`/account/order/detail?id=${this.$route.query.id}`) this.$router.replace(`/account/order/detail?id=${this.$route.query.id}`)
} },
} }
} }
</script> </script>

@ -2,27 +2,35 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-04 17:30:58 * @Date: 2022-05-04 17:30:58
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-17 16:44:30 * @LastEditTime: 2022-06-30 11:19:15
* @Description: file content * @Description: file content
--> -->
<template> <template>
<div class="main"> <div class="main">
<h3 class="title">收货地址</h3> <template v-if="productType == 1">
<BsAddress v-model="address"/> <h3 class="title">收货地址</h3>
<!-- <h3 class="title">支付方式</h3> <BsAddress v-model="address"/>
</template>
<h3 class="title">支付方式</h3>
<div class="pay-type"> <div class="pay-type">
<el-radio label="微信支付" /> <el-radio-group v-model="payType">
<el-radio label="支付宝支付" /> <el-radio label="wx" >
</div> --> <img class="pay-type--wx" src="@/assets/img/order/wx.png"/>
</el-radio>
<el-radio label="ali" >
<img class="pay-type--ali" src="@/assets/img/order/zfb.png"/>
</el-radio>
</el-radio-group>
</div>
<h3 class="title">确认商品信息</h3> <h3 class="title">确认商品信息</h3>
<OrderInfo :products="orderInfo.products" /> <OrderInfo :products="orderInfo.products" />
<Message :orderInfo="orderInfo" :message.sync="userMessage"/> <Message :orderInfo="orderInfo" :message.sync="userMessage"/>
<Amount :amount="orderInfo.productAmount" :address="address"/> <Amount :amount="orderInfo.productAmount" :address="address" :productType="productType" />
<div class="pay"> <div class="pay">
<UiButton radius type="red_panel" @click="submit"></UiButton> <UiButton radius type="red_panel" @click="submit"></UiButton>
</div> </div>
<BsPay :visible.sync="payVisible" :orderId="payOrder.orderId" <BsPay :visible.sync="payVisible" :payType="payType" :orderId="payOrder.orderId"
@cancel="cancelPay" @finish="finishPay" /> @cancel="cancelPay" @finish="finishPay" />
</div> </div>
</template> </template>
@ -43,9 +51,11 @@ export default {
orderInfo : {}, orderInfo : {},
userMessage : '', userMessage : '',
payOrder : {}, payOrder : {},
payType : 'wx',
payVisible : false, payVisible : false,
payTimerTxt : '', payTimerTxt : '',
payTimerStop : null payTimerStop : null,
productType : this.$route.query.productType
} }
}, },
mounted(){ mounted(){
@ -63,6 +73,7 @@ export default {
if(query.mode === 'cart'){ if(query.mode === 'cart'){
res = await ApiGetBeforeCartOrder({ res = await ApiGetBeforeCartOrder({
cartIds: query.ids, cartIds: query.ids,
isVirtual :this.productType == 2 && true,
recipientAddressId : this.address.id recipientAddressId : this.address.id
}) })
} }
@ -73,6 +84,7 @@ export default {
quantity : query.num, quantity : query.num,
activityId : query.activityId, activityId : query.activityId,
activityTimeId : query.activityTimeId, activityTimeId : query.activityTimeId,
isVirtual :this.productType == 2 && true,
// 1 2 // 1 2
activityType : query.activityType, activityType : query.activityType,
recipientAddressId : this.address.id recipientAddressId : this.address.id
@ -92,13 +104,14 @@ export default {
async submit(){ async submit(){
const {query} = this.$route; const {query} = this.$route;
if(!this.address.id){ if(!this.address.id && this.productType === 1){
this.$message.error('请选择收货地址'); this.$message.error('请选择收货地址');
return false; return false;
} }
const {error, result} = await ApiPostSubmitOrder({ const {error, result} = await ApiPostSubmitOrder({
orderSource : 4, orderSource : 6,
recipientAddressId : this.address.id, recipientAddressId : this.address.id,
isVirtual :this.productType == 2 && true,
shoppingCartIds : query.ids ? query.ids.split(',') : [], shoppingCartIds : query.ids ? query.ids.split(',') : [],
products : this.orderInfo.products.map(i => ({ products : this.orderInfo.products.map(i => ({
activityId : query.activityId, activityId : query.activityId,
@ -136,14 +149,14 @@ export default {
}, 5000) }, 5000)
return false; return false;
} }
this.$router.replace(`/order/payResult?id=${this.payOrder.orderId}`) this.$router.replace(`/order/payResult?id=${this.payOrder.orderId}&type=${this.productType}`)
}, },
cancelPay(){ cancelPay(){
this.$router.replace(`/account/order/detail?id=${this.payOrder.orderId}`); this.$router.replace(`/account/order/detail?id=${this.payOrder.orderId}`);
}, },
finishPay(){ finishPay(){
this.$router.replace(`/order/payResult?id=${this.payOrder.orderId}`) this.$router.replace(`/order/payResult?id=${this.payOrder.orderId}&type=${this.productType}`)
} }
} }
} }
@ -159,6 +172,12 @@ export default {
.pay-type{ .pay-type{
border: 1px solid #DDDDDD; border: 1px solid #DDDDDD;
padding: 30px 70px; padding: 30px 70px;
&--wx{
width: 130px;
}
&--ali{
width:92px
}
} }
.pay{ .pay{
text-align: right; text-align: right;

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-08 16:12:18 * @Date: 2022-05-08 16:12:18
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-16 15:41:08 * @LastEditTime: 2022-05-26 20:03:02
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -11,8 +11,10 @@
<span>应付款</span> <span>应付款</span>
<UiMoney class="money" size="20px" preSize="14px" sufSize="14px" :money="amount" float prefix suffix/> <UiMoney class="money" size="20px" preSize="14px" sufSize="14px" :money="amount" float prefix suffix/>
</div> </div>
<p>{{address.province + address.city + address.area + address.detailAddress}}</p> <template v-if="productType == 1">
<p>{{address.name}} {{address.phone}}</p> <p>{{address.province + address.city + address.area + address.detailAddress}}</p>
<p>{{address.name}} {{address.phone}}</p>
</template>
</div> </div>
</template> </template>
<script> <script>
@ -20,6 +22,10 @@ import UiMoney from '../../../../components/UiMoney.vue'
export default { export default {
components: { UiMoney }, components: { UiMoney },
props : { props : {
productType : {
type : String | Number
},
amount : { amount : {
type : Number, type : Number,
default : 0 default : 0
@ -34,7 +40,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.amount{ .amount{
height: 133px; max-height: 133px;
background: #f8f8f8; background: #f8f8f8;
text-align: right; text-align: right;
padding: 20px 40px; padding: 20px 40px;

@ -131,7 +131,6 @@ export default {
length: PAGE_SIZE, length: PAGE_SIZE,
activityTimeId: 0, activityTimeId: 0,
}, },
ticking: false,
isSticky: false, isSticky: false,
timeInterval: null, // timeInterval: null, //
seckillTip: "", // seckillTip: "", //
@ -193,15 +192,7 @@ export default {
}, },
methods: { methods: {
scrollEventMethod() { scrollEventMethod() {
const that = this; this.isSticky = window.scrollY > 400;
//
if (!that.ticking) {
window.requestAnimationFrame(function () {
that.ticking = false;
that.isSticky = window.scrollY > 400;
});
that.ticking = true;
}
}, },
async getSeckillTimes() { async getSeckillTimes() {
const { result } = await ApiGetSeckillTimes(); const { result } = await ApiGetSeckillTimes();
@ -233,7 +224,7 @@ export default {
percentage: percentage:
saleNumber === 0 saleNumber === 0
? 0 ? 0
: (saleNumber / item.number).toFixed(2) * 100, : (saleNumber / item.number).toFixed(3) * 100,
}; };
}); });
} }
@ -387,6 +378,7 @@ export default {
position: relative; position: relative;
width: 100%; width: 100%;
height: 288px; height: 288px;
padding: 20px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;

@ -0,0 +1,22 @@
/*
* @Author: ch
* @Date: 2022-05-31 11:17:38
* @LastEditors: ch
* @LastEditTime: 2022-06-01 15:53:53
* @Description: file content
*/
import {ToAsyncAwait} from '@/plugins/utils';
import { AD_PLATFORM } from '../dicts/ad';
import {axios} from "../axios";
import ENV from '../config/env';
const BASE_URL = `${ENV.base_url}/mall/marketing`;
// 获取广告列表
export const ApiGetAdList = (params) => ToAsyncAwait(axios.get(`${BASE_URL}/app/advertisement`, {
params: {
platform : AD_PLATFORM.PC,
...params
}
}))

@ -0,0 +1,86 @@
/*
* @Author: ch
* @Date: 2022-06-20 11:38:48
* @LastEditors: ch
* @LastEditTime: 2022-06-30 11:48:53
* @Description: file content
*/
import {axiosTk} from "../axiosTk";
import {axios} from "../axios";
import { ToAsyncAwait } from "../utils";
import ENV from '../config/env';
const BASE_URL = `${ENV.base_url}/mall/comment`;
/**
* 根据商品获取评论列表未
* @param {*} param0
*/
export const ApiGetCommentList = (params) =>
ToAsyncAwait(axiosTk.get(`${BASE_URL}/app/comment`, {
params,
headers: {
notVerifyToken : true
}
}));
/**
* 根据商品获取评论总数
* @param {*} param0
*/
export const ApiGetCommentCount = ({productId}) =>
ToAsyncAwait(axiosTk.get(`${BASE_URL}/app/comment/getAllCommentCountByProductId/${productId}`,{
headers: {
notVerifyToken : true
}
}));
/**
* 根据商品获取标签评论总数
* @param {*} param0
*/
export const ApiGetCommentTabCount = ({productId}) =>
ToAsyncAwait(axiosTk.get(`${BASE_URL}/app/comment/listCommentLabel/${productId}`,{
headers: {
notVerifyToken : true
}
}));
/**
* 获取订单评论详情
* @param {*} param0
*/
export const ApiGetOrderCommentDetail = ({orderId}) =>
ToAsyncAwait(axiosTk.get(`${BASE_URL}/app/comment/listOrderCommentByOrderId/${orderId}`));
/**
* 获取商品满意度
* @param {*} param0
*/
export const ApiGetProductSatisfaction = ({productId}) =>
ToAsyncAwait(axios.get(`${BASE_URL}/app/comment/getProductSatisfaction/${productId}`));
/**
* 获取评论详情
* @param {*} param0
*/
export const ApiGetCommentDetail = ({commentId}) =>
ToAsyncAwait(axiosTk.get(`${BASE_URL}/app/comment/getCommentDetail/${commentId}`, {
headers: {
notVerifyToken : true
}
}));
/**
* 新增评论
* @param {*} param0
*/
export const ApiPostComment = (data) =>
ToAsyncAwait(axiosTk.post(`${BASE_URL}/app/comment`, data));
/**
* 更新评论有用数
* @param {*} param0
*/
export const ApiPutCommentUseful = (data) =>
ToAsyncAwait(axiosTk.put(`${BASE_URL}/app/comment/updateUsefulCount`, data));

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save