548 Commits
Author SHA1 Message Date
lifizer 5f835afd8b Feat(AI):关键词搜索匹配相关模块列表 2025-05-12 15:48:02 +08:00
modendeveloper 8ef14b73c2 Task:是否非遗角标 2025-05-10 15:46:27 +08:00
linxi 25c2290564 Tasl:旅居分享 2025-05-09 15:16:07 +08:00
linxi 94efec7281 Fix:3772 【商城小程序】产品规格大于等于三个时,商品详情页的商品价格和库存显示错误 2025-05-09 14:19:58 +08:00
linxi d49b46c950 Task:3744 【新需求】礼品卡图片自定义/ 隐藏图片上的文字和按钮 2025-05-09 13:45:48 +08:00
linxi d09b0c23e2 Task:3744 【新需求】礼品卡图片自定义 2025-05-09 11:37:50 +08:00
lifizer c8157c144e Fix(AI):[#3663]输入框中语音输入,未识别到有效语音时,增加提示“没有听清您说了什么,请再说一遍” 2025-05-07 17:42:16 +08:00
linxi ec0c003ff7 Fix:3256 【商城小程序】收货地址页面,给当前选择的地址增加一个标识,放在地址右下角 2025-05-06 17:48:46 +08:00
linxi e35ea1d5c2 Fix:3256 【商城小程序】收货地址页面,给当前选择的地址增加一个标识,放在地址右下角 2025-05-06 17:23:30 +08:00
linxi 1ddc425606 Fix:3750 【商城小程序】千县旅居—资讯点赞数未显示 2025-05-06 16:37:29 +08:00
linxi 54a274a70f Fix:3708 【商城小程序】供应商入驻时店铺封面为视频,驳回入驻申请后,再次提交入驻会提示“请上传店铺封面图” 2025-05-06 16:34:46 +08:00
linxi b1fc1e248d Fix:3750 【商城小程序】千县旅居—资讯点赞数未显示 2025-05-06 15:59:14 +08:00
linxi 51b5a77d07 Fix:2787 【商城小程序】点击进入已下架的商品详情页,页面空白并且没有提示信息,增加提示:该产品已下架或删除 2025-05-06 15:47:39 +08:00
linxi d5293f1038 Fix:3709 【商城小程序】特色店铺提交入驻申请后,视频封面不显示 2025-05-06 15:20:52 +08:00
linxi 4b1e5331ef Fix:2787 【商城小程序】点击进入已下架的商品详情页,页面空白并且没有提示信息,增加提示:该产品已下架或删除 2025-05-06 15:13:43 +08:00
linxi 8dc8bcdd59 Fix:3155 【商城小程序】轮播图底部没有渐变效果(测试机型:苹果12)体验版有问题,正式版是正常的 2025-05-06 15:08:34 +08:00
linxi e76d1a2b81 Fix:3711 【商城小程序】商详页选择的商品数量与订单页面的数据没有同步 2025-05-06 14:44:48 +08:00
linxi 6f139778a7 Feat:去除多余的组件,减少打包体积 2025-05-06 14:25:52 +08:00
linxi 6ad2aeef2e Fox:3721 【商城小程序】商品加购数量等于库存数时,继续点击增加数量按钮,页面所有内容点击无效 2025-05-06 14:25:17 +08:00
linxi fdaad4df7e Fix:3729 【商城小程序】旅居无数据时的提示信息修改为“暂无数据” 2025-04-30 11:39:20 +08:00
linxi dcd8413e22 Fix:3731 【商城小程序】千县旅居—文化图片左右边距不一致 2025-04-30 11:38:25 +08:00
linxi c50fa44fd8 Fix:3732 【商城小程序】城市切换,”当前定位“改为”当前城市“ 2025-04-30 11:34:17 +08:00
linxi 7b28b94390 Fix:旅居资讯移除点赞按钮 2025-04-30 11:24:57 +08:00
linxi f6ee332060 Task:小程序旅居接口对接 2025-04-28 16:29:05 +08:00
lifizer 8b8a467431 Fix(购物车):未登录状态点击去登录不能跳转 2025-04-27 16:48:07 +08:00
lifizer 069ef49839 Refactor(购物车&我的):增加未登录或者登录过期显示以便微信审核 2025-04-27 15:22:33 +08:00
modendeveloper 05cdb3ac34 Merge branch 'test' into dev 2025-04-27 00:06:53 +08:00
modendeveloper 491323fc17 Task:旅居列表接口对接 2025-04-27 00:06:13 +08:00
modendeveloper 3c56f3cfb5 Fix:3695 【商城小程序】进入客服页面发送图片后返回,再次进入该页面未显示消息数据 2025-04-26 16:36:08 +08:00
modendeveloper 5efd4c7ed2 Fix:3700 【商城小程序】顶部标题修改为“寻千县万村” 2025-04-26 16:15:54 +08:00
modendeveloper ce58a1577a Fix:3710 【商城小程序】在商详页购买商品时,多规格商品选择的商品数量与订单页面没有同步 2025-04-26 16:14:16 +08:00
modendeveloper c1f5b7260e Fix:3707 【商城小程序】在商详页购买商品时,减少商品数量会变为负数 2025-04-26 16:06:56 +08:00
lifizer 0885a908ea Fix(AI):[#3663]输入框中语音输入,未识别到有效语音时,增加提示“没有听清您说了什么,请再说一遍” 2025-04-24 15:59:32 +08:00
lifizer 1636c77cfd Fix(AI):[#3702]历史对话下方缺少“开启新对话”按钮,增加一个开启新对话按钮 2025-04-24 15:59:17 +08:00
lifizer 74b02ed292 Refactor(AI):支持短时间内多个会话 2025-04-23 17:34:19 +08:00
linxi 58b716c0ec Fix:3692 【商城小程序】展会详情页顶部标题改为”康养旅居“ 2025-04-23 15:00:04 +08:00
linxi 23eaec9688 Fix:3640 【商城小程序】点击切换店铺后,查看特产、文玩、康养、古镇项目、寻趣味轮播店铺,进入的是自己的店铺 2025-04-23 14:43:30 +08:00
lifizer f1d6ac62c1 Fix(AI):[#3681]AI对话点击手机侧边返回按钮,会回到小程序首页 2025-04-23 14:33:25 +08:00
lifizer 0d0b816fad Fix(AI):[#3647]点击输入框,对话记录同步上移 2025-04-22 14:18:05 +08:00
lifizer 39a54efc27 Fix(AI):[#3681]AI对话点击手机侧边返回按钮,会回到小程序首页 2025-04-22 13:34:26 +08:00
lifizer 30bb94130d Fix(AI):[#3663]输入框中语音输入,未识别到有效语音时,增加提示“没有听清您说了什么,请再说一遍” 2025-04-22 11:35:26 +08:00
lifizer 33f9d611b4 Fix(AI):[#3661]今日AI对话记录删除失败 2025-04-22 11:31:26 +08:00
linxi 3c86c4561a Fix:3648 【商城小程序】进入客服会话页面并返回后,再次进入未显示消息数据 2025-04-21 14:32:36 +08:00
linxi 19632a69ad Fix:3363 【商城小程序】农民店铺的视频资讯,视频播放后每次点击视频播放按钮外的区域都会增加浏览量 2025-04-21 14:15:15 +08:00
linxi e4428f3366 Fix:3640 【商城小程序】点击切换店铺后,查看特产、文玩、康养、古镇项目、寻趣味轮播店铺,进入的是自己的店铺 2025-04-21 14:03:23 +08:00
linxi 590c33d4d3 Fix:3638 【商城小程序】热搜榜单商品图尺寸统一为正方形,不根据原图长度自适应 2025-04-21 11:45:39 +08:00
linxi c285c32a4e Fix:2983 【商城小程序】被下架的商品在购物车中消失(改为前端数据保留,点击时提醒商品已下架或被删除) 2025-04-21 11:36:37 +08:00
linxi ed3e1f3dfc Fix:3659 【商城小程序】顶部标题修改为“寻地标好物” 2025-04-21 11:16:04 +08:00
lifizer ef10e8ad97 Merge branch 'dev' into test 2025-04-16 10:19:55 +08:00
lifizer 3ec0c8c29c Refactor(购物车&我的):增加未登录或者登录过期显示以便微信审核 2025-04-16 10:01:38 +08:00
lifizer 2f55b0bfb8 Refactor(购物车&我的):增加未登录或者登录过期显示以便微信审核 2025-04-15 15:33:01 +08:00
lifizer 3d53cc51a9 Merge branch 'dev' into test 2025-04-15 09:50:08 +08:00
lifizer 4fa9c6a594 Feat(AI):增加参数,只有通过点击才能进入,以便微信审核 2025-04-14 14:47:39 +08:00
lifizer 0bf354f8aa Merge branch 'dev' into test 2025-04-14 14:12:58 +08:00
linxi aa58754f1c Fix:客服消息商品展示价格面议 2025-04-14 10:51:42 +08:00
lifizer fdcdfc505f Conf(拦截器):增加白名单,针对后端返回401不跳转到登录界面 2025-04-14 09:09:24 +08:00
lifizer 59fee9df18 Conf(拦截器):增加白名单,针对后端返回401不跳转到登录界面 2025-04-12 09:19:09 +08:00
lifizer 6f244967a5 Merge branch 'dev' into test 2025-04-11 17:55:27 +08:00
linxi 6a3a2e74a0 Fix:3354 【礼品功能】微信支付失败后在礼品卡页面生成的待付款订单,改为跟普通订单一样,限定时间内未支付订单自动取消 2025-04-11 09:38:08 +08:00
linxi c323a28518 Fix:3354 【礼品功能】微信支付失败后在礼品卡页面生成的待付款订单,改为跟普通订单一样,限定时间内未支付订单自动取消 2025-04-11 09:29:48 +08:00
lifizer d68d4c8773 Fix(AI):[#3620]权限申请点击拒绝后,再次点击语音输入就不会再弹出权限申请弹窗 2025-04-10 16:26:54 +08:00
lifizer 4810aa7e33 Fix(AI):[#3595]热门词条轮播方式使用配置 2025-04-09 11:47:40 +08:00
modendeveloper fd4adbf383 Fix:3256 【商城小程序】收货地址页面,给当前选择的地址增加一个标识,放在地址右下角 2025-04-09 00:31:05 +08:00
modendeveloper 3829e896da Fix:3441 【商城小程序】购物车、待评价--再买一单,先结算满足优惠券使用的订单,再结算价格不满足上一个优惠券的订单时,会提示“不满足优惠券使用的条件” 2025-04-09 00:10:02 +08:00
modendeveloper a5d0ce8657 Fix:3601 【商城小程序】加购或送礼,输入数量超过商品库存,页面点击无效 2025-04-08 23:45:38 +08:00
modendeveloper ed81a95cd9 Fix:3592 【商城小程序】顶部标题修改为“非遗文创” 2025-04-08 23:21:15 +08:00
modendeveloper 0ff82a3590 Fix:3608 【商城小程序】当前用户有店铺时,从寻趣味选择任意店铺进入店铺详情,显示的是自己的店铺详情 2025-04-08 23:20:04 +08:00
lifizer ff471b6017 Fix(AI):[#3602]色块是原来的背景图,苹果手机不支持背景图固定不动,故改为渐变背景色 2025-04-08 22:18:42 +08:00
lifizer 52f2c2b003 Fix(AI):[#3607]底部操作区域增加背景颜色 2025-04-08 22:17:34 +08:00
lifizer 16abf0fdb6 Fix(AI):[#3606]苹果手机键盘底部及开启新对话按钮没有留空隙 2025-04-08 12:20:09 +08:00
lifizer f6851bfa77 Fix(AI):[#3612]进入问答页面后,点击左上角返回按钮,会直接返回小程序首页,改为返回到AI首页 2025-04-08 10:48:11 +08:00
lifizer 794e405ed2 Fix(AI):[#3611]一个用户在问答过程中退了,然后又进入重新生成一个会话,需要关闭ws 2025-04-08 10:47:31 +08:00
lifizer 689d949315 Fix(AI):[#3603, #3604]界面细节调整 2025-04-08 10:45:39 +08:00
lifizer e446b9e847 Fix(AI):[#3609]点击热门词条时,需要卡1秒才能进入问答页面,改为点击后马上进入问答页面 2025-04-08 10:18:58 +08:00
lifizer 67c94d814c Fix(AI):[#3600]键盘弹出后,开启新对话,及键盘底部会被遮挡一部分 2025-04-07 22:57:59 +08:00
lifizer 230e163c53 Feat(云灵AI):界面细节调整 2025-04-06 15:11:20 +08:00
lifizer de473eba57 Feat(云灵AI):对话接口对接完成 2025-04-06 12:57:39 +08:00
linxi 16742b3c23 Fix:3583 【商城小程序】店铺主页—有商品的店铺切换至无商品的店铺时,详情页中会显示商品项;无商品的店铺切换至有商品的店铺时,店铺详情页中不显示商品项 2025-04-06 00:06:14 +08:00
linxi b73e9ee36b Fix:3156 【商城小程序】客服消息--点击商品卡片跳转到商品详情页,在商品详情页中点击“客服”,聊天记录显示空白 2025-04-06 00:06:09 +08:00
linxi bc609f0038 Fix:3583 【商城小程序】店铺主页—有商品的店铺切换至无商品的店铺时,详情页中会显示商品项;无商品的店铺切换至有商品的店铺时,店铺详情页中不显示商品项 2025-04-06 00:06:04 +08:00
modendeveloper eb6865299c Fix:3583 【商城小程序】店铺主页—有商品的店铺切换至无商品的店铺时,详情页中会显示商品项;无商品的店铺切换至有商品的店铺时,店铺详情页中不显示商品项 2025-04-06 00:06:00 +08:00
modendeveloper 2e838088db Fix:3581 【商城小程序】开启了价格面议的商品详情页,点击【加入购物车】按钮没有提示信息 2025-04-06 00:05:55 +08:00
modendeveloper 37cd468d44 Fix:3580 【商城小程序】开启了价格面议的商品价格区域需显示为【价格面议】(页面:店铺商品列表页面、商详页的店铺数据区域) 2025-04-06 00:05:50 +08:00
modendeveloper 850f5922e2 Fix:3347 【商城小程序】送礼方买礼品后,现在没送出去就无法退款,要增加一个退款功能,以及24小时后自动退款 2025-04-06 00:05:45 +08:00
lifizer 50ff88e7df Feat(云灵AI):对话接口对接完成 2025-04-06 00:05:03 +08:00
lifizer 30f550ca92 Conf:补充tabbar图片相对地址,否则真机调试报错 2025-04-06 00:04:29 +08:00
linxi 72725d051e Fix:3583 【商城小程序】店铺主页—有商品的店铺切换至无商品的店铺时,详情页中会显示商品项;无商品的店铺切换至有商品的店铺时,店铺详情页中不显示商品项 2025-04-02 11:30:10 +08:00
linxi 8c85c4465e Fix:3156 【商城小程序】客服消息--点击商品卡片跳转到商品详情页,在商品详情页中点击“客服”,聊天记录显示空白 2025-04-02 11:01:01 +08:00
linxi 2a274766a1 Fix:3583 【商城小程序】店铺主页—有商品的店铺切换至无商品的店铺时,详情页中会显示商品项;无商品的店铺切换至有商品的店铺时,店铺详情页中不显示商品项 2025-04-02 10:13:38 +08:00
modendeveloper eb9533fb7d Fix:3583 【商城小程序】店铺主页—有商品的店铺切换至无商品的店铺时,详情页中会显示商品项;无商品的店铺切换至有商品的店铺时,店铺详情页中不显示商品项 2025-04-02 00:33:20 +08:00
modendeveloper 6f2957f514 Fix:3581 【商城小程序】开启了价格面议的商品详情页,点击【加入购物车】按钮没有提示信息 2025-04-02 00:23:18 +08:00
modendeveloper 610ea7ece1 Fix:3580 【商城小程序】开启了价格面议的商品价格区域需显示为【价格面议】(页面:店铺商品列表页面、商详页的店铺数据区域) 2025-04-02 00:21:22 +08:00
modendeveloper 35b57bbccc Fix:3347 【商城小程序】送礼方买礼品后,现在没送出去就无法退款,要增加一个退款功能,以及24小时后自动退款 2025-04-02 00:07:41 +08:00
lifizer d7ccd248b6 Refactor:删除多余的图片,减小打包体积 2025-04-01 14:23:22 +08:00
lifizer 84562cf6f1 Refactor(AI智能):采取分包 2025-04-01 14:13:57 +08:00
modendeveloper 1510d5e9d9 Fix:3416 【礼品功能】送礼页面手动删除数量后,该数量框显示空白,删除数量后,默认为1
(cherry picked from commit 68cfae2893)
2025-04-01 13:30:34 +08:00
modendeveloper f16793a06a Fix:3477 【商城小程序】开启了价格面议的商品价格区域需显示为【价格面议】(页面:搜索结果列表、商详页点击库存后弹出的规格弹窗、店铺详情页商品列表、商品收藏列表、商品足迹、文玩商品列表)
(cherry picked from commit 3bbd796a85)
2025-04-01 13:30:29 +08:00
modendeveloper 5d6ca1f03d Fix:3478 【商城小程序】所有店铺详情页(供应商店铺、特色店铺、农民店铺、 城市详情页)滑动时顶部导航颜色改为透明
(cherry picked from commit f2fba444a0)
2025-04-01 13:30:23 +08:00
modendeveloper 26b0ce03cd Fix:3170 【商城小程序】查看特色店铺详情页后返回该店铺类型列表,下滑刷新过程中会出现店铺重复展示的情况(以昆明的客栈/民宿、乡村游列表为例)
(cherry picked from commit 632886c81c)
2025-04-01 13:30:18 +08:00
modendeveloper 01028a85b0 Fix:3440 【商城小程序】我的订单—查看订单详情后返回未定位到该订单位置
(cherry picked from commit cf0c180efd)
2025-04-01 13:30:12 +08:00
modendeveloper b18b593afa Fix:3347 【商城小程序】送礼方买礼品后,现在没送出去就无法退款,要增加一个退款功能,以及24小时后自动退款
(cherry picked from commit 4333e8e76a)
2025-04-01 13:30:07 +08:00
modendeveloper 26145a1259 Fix:3347 【商城小程序】送礼方买礼品后,现在没送出去就无法退款,要增加一个退款功能,以及24小时后自动退款
(cherry picked from commit da929cfe3b)
2025-04-01 13:30:00 +08:00
modendeveloper 23dc945f43 Fix:3525 【供应链小程序】客服消息—在商城小程序端删除消息记录后,供应链小程序(商家端)的客服消息记录会跟着删除
(cherry picked from commit 4dcfa23a10)
2025-04-01 13:29:55 +08:00
modendeveloper b8ca3b66fb Fix:3531 【商城小程序】店铺选择界面调整,按钮改为红色色值:#BD3124
(cherry picked from commit 426348932f)
2025-04-01 13:29:50 +08:00
modendeveloper 6af66ec5e0 Fix:3537 【商城小程序】商详页输入商品数量超过3位或4位,数量显示效果需要优化
(cherry picked from commit 8728c6e738)
2025-04-01 13:29:45 +08:00
modendeveloper e21c4aa669 Fix:3385 【商城小程序】多份商品礼包显示已领取数量
(cherry picked from commit f2b6bc18e2)
2025-04-01 13:29:40 +08:00
modendeveloper a27c35ba2d Fix:3443 【商城小程序】个人主页--提现申请--提现记录增加暂无记录的提示
(cherry picked from commit 17810ee741)
2025-04-01 13:29:34 +08:00
modendeveloper 68cfae2893 Fix:3416 【礼品功能】送礼页面手动删除数量后,该数量框显示空白,删除数量后,默认为1 2025-04-01 12:55:36 +08:00
modendeveloper 3bbd796a85 Fix:3477 【商城小程序】开启了价格面议的商品价格区域需显示为【价格面议】(页面:搜索结果列表、商详页点击库存后弹出的规格弹窗、店铺详情页商品列表、商品收藏列表、商品足迹、文玩商品列表) 2025-04-01 12:40:53 +08:00
modendeveloper f2fba444a0 Fix:3478 【商城小程序】所有店铺详情页(供应商店铺、特色店铺、农民店铺、 城市详情页)滑动时顶部导航颜色改为透明 2025-04-01 12:05:05 +08:00
modendeveloper 632886c81c Fix:3170 【商城小程序】查看特色店铺详情页后返回该店铺类型列表,下滑刷新过程中会出现店铺重复展示的情况(以昆明的客栈/民宿、乡村游列表为例) 2025-04-01 11:57:48 +08:00
modendeveloper cf0c180efd Fix:3440 【商城小程序】我的订单—查看订单详情后返回未定位到该订单位置 2025-04-01 11:33:13 +08:00
modendeveloper 4333e8e76a Fix:3347 【商城小程序】送礼方买礼品后,现在没送出去就无法退款,要增加一个退款功能,以及24小时后自动退款 2025-04-01 11:27:08 +08:00
modendeveloper da929cfe3b Fix:3347 【商城小程序】送礼方买礼品后,现在没送出去就无法退款,要增加一个退款功能,以及24小时后自动退款 2025-04-01 11:27:01 +08:00
modendeveloper 4dcfa23a10 Fix:3525 【供应链小程序】客服消息—在商城小程序端删除消息记录后,供应链小程序(商家端)的客服消息记录会跟着删除 2025-04-01 11:08:58 +08:00
modendeveloper 426348932f Fix:3531 【商城小程序】店铺选择界面调整,按钮改为红色色值:#BD3124 2025-04-01 11:05:27 +08:00
modendeveloper 8728c6e738 Fix:3537 【商城小程序】商详页输入商品数量超过3位或4位,数量显示效果需要优化 2025-04-01 11:02:52 +08:00
modendeveloper f2b6bc18e2 Fix:3385 【商城小程序】多份商品礼包显示已领取数量 2025-04-01 10:57:47 +08:00
modendeveloper 17810ee741 Fix:3443 【商城小程序】个人主页--提现申请--提现记录增加暂无记录的提示 2025-04-01 10:31:51 +08:00
lifizer d1bc3cc351 Feat(云灵AI):对话接口对接完成 2025-03-28 15:15:14 +08:00
lifizer aaf2e74cbb Feat(云灵AI):对话接口对接完成 2025-03-27 18:26:26 +08:00
linxi d400c2c948 Merge branch 'dev' into test 2025-03-27 18:13:53 +08:00
lifizer 615b89c8a5 Feat(云灵AI):界面初始化 2025-03-27 18:12:48 +08:00
linxi 01c1a44a32 Fix:3131 【商城小程序】发布视频动态,上传视频时弹出“网络错误,请稍后再试”,点击发布可成功发布视频动态(安卓(小米,vivo)) 2025-03-27 17:08:47 +08:00
linxi c93d44a9ba Fix:3417 【商城小程序】订单详情页增加点击商品信息区域跳转商详页 2025-03-27 16:41:58 +08:00
linxi 3c187447c4 Fix:3433 【商城小程序】头像编辑--图片右下方的图片旋转及图片还原按钮图标显示不明确,点住才会有显示。加深图标颜色,使其更清楚。 2025-03-27 16:13:37 +08:00
linxi 6f881377b0 Fix:3442 【商城小程序】全国特产--搜索城市框不输入任何字段,无论当前在哪个城市,点击搜索会显示天津市 2025-03-27 16:05:22 +08:00
linxi f079db8fc0 Fix:3443 【商城小程序】个人主页--提现申请--提现记录增加暂无记录的提示 2025-03-27 16:00:40 +08:00
linxi a3693e6c9a Fix:3461 【商城小程序】接收某一个客服信息,会话页面存在聊天记录的会话均显示新信息的提示红点 2025-03-27 15:41:59 +08:00
linxi a43180b132 Fix:3461 【商城小程序】接收某一个客服信息,会话页面存在聊天记录的会话均显示新信息的提示红点 2025-03-27 15:41:29 +08:00
linxi ef4ce36eb2 Fix:3514 【商城小程序】店铺中商品名称过长,省略号后第三行仍会漏出部分字体 2025-03-27 15:23:02 +08:00
linxi 7c42efeb6b Fix:3529 【商城小程序】购物须知被遮挡 2025-03-27 15:04:17 +08:00
linxi 455b230931 Fix:3531 【商城小程序】店铺选择界面调整,按钮改为红色色值:#BD3124 2025-03-27 14:58:59 +08:00
linxi a267868890 Fix:3532 【商城小程序】店铺主页—切换登录店铺返回,再次进入店铺主页时未固定到选择店铺 2025-03-27 14:57:05 +08:00
linxi 36914c10b0 Task:多店铺选择 2025-03-25 18:32:28 +08:00
linxi a74f94a061 Task:多店铺选择 2025-03-25 11:48:30 +08:00
linxi 85b1a8f0f1 Task:多店铺选择 2025-03-24 18:13:19 +08:00
linxi a1182276a9 Task:热门词条样式控制 2025-03-20 16:32:48 +08:00
linxi a8f3e99d38 Task: 价格面议小程序端 2025-03-20 15:01:03 +08:00
linxi b148b7b869 Fix:3156 【商城小程序】客服消息--点击商品卡片跳转到商品详情页,在商品详情页中点击“客服”,聊天记录显示空白 2025-03-18 11:48:43 +08:00
linxi 89b94a71dc Fix:3343 【礼品】购买礼品数量,增加可以手动输入数字 2025-03-18 11:16:01 +08:00
linxi 4c76fedeb8 Fix:3339 【商城小程序】千县封面为视频时,功能指引文字偏下,往上移一点 2025-03-14 16:42:23 +08:00
linxi 8b3156630a Fix:3384 【商城小程序】“我的”页面从任一订单状态进入订单列表后,点击查看“全部”下的任意订单详情,返回后默认回到进入的状态列表页面 2025-03-14 14:35:45 +08:00
linxi 36fcb30879 Fix:3343 【礼品】购买礼品数量,增加可以手动输入数字 2025-03-14 14:23:08 +08:00
linxi d297245140 Fix:3344 【商城小程序】所有功能指引改为:点击整个屏幕即可下一步,跳过按钮不变 2025-03-14 11:56:11 +08:00
linxi eee5c0ae6f Fix:3346 【礼品】礼包领取状态,“查看订单详情”与“去商城看看”样式调整 2025-03-14 11:17:18 +08:00
linxi abe6d9af98 Fix:3349 【商城小程序】底部“加入购物车”一行样式增高 2025-03-14 11:07:46 +08:00
linxi 426410ffd1 Fix:3356 【礼品功能】礼包订单支付密码填写错误时的提示改为“支付密码不正确” 2025-03-14 10:59:37 +08:00
linxi 26b6c14141 Fix:3358 【商城小程序】商详页优惠券弹窗—无法取消勾选优惠券 2025-03-14 10:57:20 +08:00
modendeveloper 6b1dd27294 Fix:3197 【商城小程序】农民店铺资讯--第一次点击播放视频时浏览量增加2 2025-03-10 23:48:44 +08:00
modendeveloper 77bb949921 Fix:3322 【商城小程序】特产/文玩供应商入驻驳回后,商家资质数据在前端小程序消失 2025-03-10 23:36:16 +08:00
modendeveloper cbc313e8c5 Fix:3207 【商城小程序】供应商入驻页面—修改营业时间后点击【取消】按钮,营业时间也会被更改 2025-03-10 22:51:36 +08:00
modendeveloper b6a7c02e60 Fix:3219 【商城小程序】从商详页选择非最高减免金额优惠券,结算页面显示的优惠券信息是最高优惠券,与已选择的优惠券不对应 2025-03-10 22:45:52 +08:00
modendeveloper f7a8ba44a8 Fix:3349 【商城小程序】底部“加入购物车”一行样式增高 2025-03-10 22:28:26 +08:00
modendeveloper deb0be8eea Fix:3346 【礼品】礼包领取状态,“查看订单详情”与“去商城看看”样式调整 2025-03-10 22:24:11 +08:00
modendeveloper 7ce0c62131 Fix:3348 【商城小程序】首页搜索板块字体偏小,需放大 2025-03-10 22:04:41 +08:00
lifizer f631166047 Merge branch 'dev' into test 2025-03-06 21:30:11 +08:00
lifizer c6cc2758c9 Fix(礼品):领取领取礼品新增地址保存防抖处理 2025-03-06 21:10:17 +08:00
modendeveloper 45b8d065ae Fix:新增地址保存防抖处理 2025-03-06 20:53:58 +08:00
lifizer ed9ae77ead Feat(寻看点):增加逻辑判断,如果不是点击进入则强制跳转至首页 2025-03-06 09:49:24 +08:00
linxi 0fdee74098 Fix:指引按照正式版流程调整 2025-03-04 10:38:00 +08:00
linxi c7ec45b7e2 Fix:礼品价格 2025-03-04 10:24:15 +08:00
linxi 5dc01c9a3e Fix:去选择按钮去掉,箭头改到数字后面 2025-03-03 15:17:36 +08:00
linxi 38fde39aa7 Fix:礼品卡第一个跟最后一个重复显示了 2025-03-03 14:56:23 +08:00
linxi 754713282b Fix:删掉输入框内容后,输入框应该直接是空白的,不要显示浮动关键词 2025-03-03 14:21:58 +08:00
linxi f36bf5ca73 Fix:支付输入密码键被遮挡 2025-03-03 14:14:16 +08:00
linxi a02d6cc198 Fix:3313 【商城小程序】订单进入详情页显示无轨迹信息,点击查看后返回才显示轨迹信息 2025-03-03 13:57:53 +08:00
modendeveloper cb3ad8180d Fix:3155 【商城小程序】轮播图底部没有渐变效果(测试机型:苹果12)体验版有问题,正式版是正常的 2025-03-01 17:32:15 +08:00
modendeveloper d07fc96efc Fix:3292 【商城小程序】搜索页价格未超过5位数的不要换行 2025-03-01 17:16:34 +08:00
modendeveloper f8e83800bb Fix:3304 【商城小程序】特色店铺提交入驻,填写完资料提交后仍然出现入驻须知 2025-03-01 17:02:53 +08:00
modendeveloper 2df4d6f286 Fix:3284 【商城小程序】搜索页面—编辑搜索框内容时,浮动词条没有隐藏 2025-03-01 16:54:33 +08:00
modendeveloper e5e63f3e2f Fix:3284 【商城小程序】搜索页面—编辑搜索框内容时,浮动词条没有隐藏 2025-03-01 16:29:11 +08:00
modendeveloper e71826919c Fix:3320 【商城小程序】待发货订单申请退款,已退款页面无需显示物流信息,上一条bug只修复了退款中的页面 2025-03-01 16:16:58 +08:00
modendeveloper eefe6404e5 Fix:订单取消支付问题 2025-03-01 16:13:23 +08:00
linxi c3d6b25a5e Fix:3315 【礼品功能】待发货订单退款详情页不要显示物流信息 2025-02-28 16:03:30 +08:00
linxi 1baf5de741 Fix:订单不存在 2025-02-28 09:29:16 +08:00
modendeveloper aec2cfc207 Fix:3281 【礼品功能】赠礼商品支付时无法使用优惠券 2025-02-27 23:18:30 +08:00
modendeveloper 4d453fbd41 Fix:3271 【礼品功能】未实现礼品有地标好物,千县名品,康养食材,文玩商品属性时,默认选择专属礼品卡,所有商品默认都是通用礼品卡 2025-02-27 22:20:09 +08:00
modendeveloper 9a7456bdeb Fix:3296 【礼品功能】未登录状态,点击领取礼包,登录前闪过礼包已被领取的页面,登录后显示的是待领取状态 2025-02-27 22:06:08 +08:00
linxi b85a619027 Fix:3306 【礼品功能】礼品封面两边还要再低于中间,左右两边往下移,底部文字平行,顶部低于中间 2025-02-27 19:02:33 +08:00
modendeveloper 44798a564f Fix:收礼相关逻辑补充 2025-02-27 13:17:07 +08:00
modendeveloper 83a698185c Fix:收礼相关逻辑补充 2025-02-27 12:50:31 +08:00
modendeveloper e257419351 Fix:收礼相关逻辑补充 2025-02-27 12:39:36 +08:00
modendeveloper e56dca5b92 Fix:按钮问题 2025-02-26 22:29:14 +08:00
modendeveloper 84acc97e53 Fix:3303 【礼品功能】选择默认寄语,支付后的送礼包页面,赠言未显示默认寄语内容 2025-02-26 22:24:45 +08:00
linxi c964cf3376 Fix:3293 【礼品功能】礼品按钮位置布局按下图调整一下 2025-02-26 10:37:19 +08:00
linxi d3622f4cff Fix:3296 【礼品功能】未登录状态,点击领取礼包,登录前闪过礼包已被领取的页面,登录后显示的是待领取状态 2025-02-26 10:32:03 +08:00
linxi d6bc12d23a Fix:3299 【礼品功能】有转赠按钮,填写地址按钮会挤压变形 2025-02-26 10:05:38 +08:00
linxi cc1ceb2b4f Fix:3300 【礼品功能】填写地址领取礼包后弹窗报错信息 2025-02-26 10:03:51 +08:00
modendeveloper 8148f629de Fix:3282 【礼品功能】送礼包页面-送礼寄语未增加字数限制,页面优化调整 2025-02-25 23:55:37 +08:00
modendeveloper e092fe4d4c Fix:3278 【礼品功能】默认寄语赠送好友后,我的礼品卡页面未显示赠言 2025-02-25 23:41:01 +08:00
modendeveloper 6ac1b9d415 Fix:收礼相关逻辑补充 2025-02-25 23:37:43 +08:00
modendeveloper 12fa155630 Fix:收礼无法点击填写地址按钮 2025-02-24 21:42:50 +08:00
linxi 744e6d98f9 Fix:3246 【商城小程序】点击浮动关键词进入搜索页面,搜索框未固定显示该关键词 2025-02-24 18:06:49 +08:00
linxi 910991ad69 Fix:3255 【商城小程序】地址管理中修改默认地址后购物车默认地址未同步更改,下拉刷新小程序后才会更改 2025-02-24 17:42:24 +08:00
linxi 60e473db8a Fix:3261 【商城小程序】特色店铺资料填写完成后点击提交会再次出现入驻申请须知 2025-02-24 17:29:59 +08:00
linxi 281249830a Fix:3286 【礼品功能】礼包领取页面-调整商品图片,应与图片框贴合效果,圆角弧度需再缩小点 2025-02-24 17:22:14 +08:00
linxi 1319517a41 Fix:3289 【礼品功能】进入礼包商品详情页,礼包赠送区域会先闪烁后正常显示 2025-02-24 17:20:18 +08:00
linxi 6af05e705a Fix:3262 【礼品功能】每次领取礼品时输入新地址,都会把上一次保存的地址覆盖掉,设置新地址也要保留上一次的地址 2025-02-24 17:05:08 +08:00
linxi f9a89a7129 Fix:3262 【礼品功能】每次领取礼品时输入新地址,都会把上一次保存的地址覆盖掉,设置新地址也要保留上一次的地址 2025-02-24 17:01:26 +08:00
linxi 37be03f3ee Fix:3288 【礼品功能】送礼支付页面增加一个图片 2025-02-24 16:51:17 +08:00
linxi 20c50b8a26 Fix:3287 【礼品功能】收取礼品填写地址时输入超过11位手机号码也可领取成功 2025-02-24 16:32:11 +08:00
linxi b0613f3760 Fix:3285 【商城小程序】用户昵称有两行时,部分机型的【设置中心】按钮超出了红色区域(机型:苹果12) 2025-02-24 16:26:37 +08:00
linxi 89dcf74f17 Fix:3257 【商城小程序】搜索热销榜单中商品价格过长时会超出榜单底框显示 2025-02-24 15:48:43 +08:00
linxi 7c7ca84cd0 Fix:3275 【礼品功能】温馨提示的字体再小一号 2025-02-24 11:42:02 +08:00
linxi 7b543719e6 Fix:3282 【礼品功能】送礼包页面-送礼寄语未增加字数限制,页面优化调整 2025-02-24 11:40:51 +08:00
linxi f127123a62 Fix:3279 【礼品功能】选择封面交互形式优化,应该两边低于中间,而不是高于中间 2025-02-24 11:27:29 +08:00
linxi cd1a12ac6a Fix:3266 【礼品功能】已退回,已收货状态应该是灰色 2025-02-24 10:56:45 +08:00
modendeveloper 221de41cf3 Fix:送出礼品列表分享好友封面图字段调整 2025-02-23 23:46:09 +08:00
modendeveloper e20775c198 Task:。收礼逻辑,目前还缺收礼后再次查看,礼品的订单号,是否已经全部领取完字段 2025-02-23 23:39:13 +08:00
modendeveloper 3c0a91adb9 Fix:3266 【礼品功能】已退回,已收货状态应该是灰色 2025-02-23 23:28:31 +08:00
modendeveloper a95b30deaf Fix:3267 【礼品信息】此处赠言后面的文字,应该是送礼时填写的礼品信息 2025-02-23 23:24:58 +08:00
modendeveloper 61e1e2939f Fix:3268 【礼品功能】进入送礼页面,商品价格会变成0 2025-02-23 23:22:33 +08:00
modendeveloper cca0f24cbc Fix:3265 【礼品功能】收货信息整体往左移,左侧与按钮平行 2025-02-23 21:24:44 +08:00
modendeveloper 09ef536a37 Fix:3264 【礼品功能】当前规格库存不足时,点击送给朋友无响应,应提示:商品库存不足 2025-02-23 21:22:24 +08:00
modendeveloper 0f5f19d9a0 Task:礼品赠送/送礼、分享。收礼 2025-02-23 21:16:10 +08:00
modendeveloper aedc2fd768 Task:礼品赠送/送礼、分享。收礼 2025-02-22 19:20:33 +08:00
linxi f0a4a0edf9 Task:收礼相关接口 2025-02-21 18:25:34 +08:00
lifizer 425821ecf7 Feat(我的礼品卡):接口对接 2025-02-21 14:23:49 +08:00
modendeveloper e1328a7825 Task:礼品赠送/送礼、分享。收礼 2025-02-21 01:21:22 +08:00
lifizer 40207f11a1 Feat(我的礼品卡):接口对接 2025-02-20 13:40:17 +08:00
modendeveloper 1fbbbed4f0 Task:礼品赠送/送礼 2025-02-20 08:34:58 +08:00
linxi dbc31c72fb Task:送礼相关接口 2025-02-19 18:31:38 +08:00
modendeveloper 5dc1f5ad92 Task:礼品赠送/送礼 2025-02-17 23:36:27 +08:00
lifizer 044c1a0863 Feat(我的礼品卡):界面初始化 2025-02-17 21:43:48 +08:00
linxi fcab618a7e Task:礼品功能 2025-02-13 18:33:36 +08:00
linxi 9d1a8916fc Fix:3217 【商城小程序】按如下顺序调整一下首页的新手指引提示顺序 2025-02-12 18:26:55 +08:00
linxi f0abc1e87a Fix:3212 【商城小程序】首页千县功能指引“开始探寻”直接修改为“跳过”和“下一步”按钮 2025-02-12 18:25:37 +08:00
linxi 5ba5aff309 Fix:3217 【商城小程序】按如下顺序调整一下首页的新手指引提示顺序 2025-02-12 18:20:22 +08:00
linxi 6a66405a2f Fix:3217 【商城小程序】按如下顺序调整一下首页的新手指引提示顺序 2025-02-12 18:19:59 +08:00
linxi 2c325ad5b1 Fix:3177 【商城小程序】特产,文玩,特色店铺入驻,流程又被改回去了,没有先弹出入驻须知 2025-02-12 17:26:50 +08:00
linxi 2bc586d8b1 Fix:3022 【商城小程序】填写申请资料点击返回后再次进入,填写内容未保留(修复为填写内容仍然保留) 2025-02-12 17:26:12 +08:00
linxi b2388cf6c6 Fix:3192 【商城小程序】特色店铺入驻页面的营业时间点击无效,无法选择时间 2025-02-12 16:15:38 +08:00
linxi e45d9e1afc Fix:3175 【商城小程序】修改店铺页面的营业时间没有获取已经保存过的数据 2025-02-12 15:55:36 +08:00
modendeveloper ff205ec37f Fix:3131 【商城小程序】发布视频动态,上传视频时弹出“网络错误,请稍后再试”,点击发布可成功发布视频动态(安卓(小米,vivo))/ 调整响应超时配置 2025-01-26 20:28:58 +08:00
modendeveloper 7f5b1ad45c Fix:3116 【商城小程序】全国特产,搜索页面,右上角需要增加购物车按钮,右上角红点显示当前购物车商品数,点击进入购物车页面 2025-01-26 20:23:28 +08:00
modendeveloper 3d8bcb56d5 Fix:3181 【商城小程序】调整功能指引批注位置(机型:vivo x60 pro+) 2025-01-26 20:15:38 +08:00
modendeveloper 0802e6349e Fix:3172 【商城小程序】视频评论还是无法播放 2025-01-26 20:02:02 +08:00
modendeveloper 0372209000 Fix:3132 【商城小程序】店铺视频资讯内容无法显示,安卓(小米,vivo) 2025-01-26 17:32:49 +08:00
modendeveloper b0c019f50c Fix:3137 【商城小程序】产品--封面为视频的农民店铺列表页面未显示封面 2025-01-26 17:14:44 +08:00
modendeveloper 8e0caaca24 Fix:3011 【商城小程序】店铺主页发布动态中,简介输入字数超过140字时未弹出”字数超过限制“提示,且下方字数提示变化不正确 2025-01-26 17:08:15 +08:00
modendeveloper 6f3fa44385 Fix:3180 【商城小程序】已完成、已退款订单详情页中物流显示“暂无物流轨迹”,实际存在物流轨迹 2025-01-26 16:56:32 +08:00
modendeveloper 12c6b177bc Fix:3176 【商城小程序】特色店铺入驻页面的营业时间点击无效,无法选择时间 2025-01-26 16:34:20 +08:00
modendeveloper b532a8a675 Fix:3185 【商城小程序】消息输入字数过多会溢出消息框,超过五行的内容未显示 2025-01-26 16:15:19 +08:00
modendeveloper dbb95c9c10 Fix:3185 【商城小程序】消息输入字数过多会溢出消息框,超过五行的内容未显示 2025-01-26 16:10:24 +08:00
modendeveloper a8334b552c Fix::3182 【商城小程序】订单列表页面—待付款订单点击【立即付款】,顶部的订单类型导航栏会浮动在上层 2025-01-26 16:05:08 +08:00
modendeveloper 887206f1a9 Fix:3116 【商城小程序】全国特产,搜索页面,右上角需要增加购物车按钮,右上角红点显示当前购物车商品数,点击进入购物车页面 2025-01-23 02:13:23 +08:00
modendeveloper 0ace784593 Fix:3116 【商城小程序】全国特产,搜索页面,右上角需要增加购物车按钮,右上角红点显示当前购物车商品数,点击进入购物车页面 2025-01-23 02:13:16 +08:00
modendeveloper 37266a4e97 Fix:3144 【商城小程序】修改店铺资料页面没有营业时间 2025-01-23 01:35:40 +08:00
modendeveloper cd0a91fda5 Fix:3150 【商城小程序】特色店铺、采购批发商入驻流程未改变为先弹出入驻须知再填写资料 2025-01-23 01:18:20 +08:00
modendeveloper b27d2c97fb Fix:3150 【商城小程序】特色店铺、采购批发商入驻流程未改变为先弹出入驻须知再填写资料 2025-01-23 01:12:14 +08:00
modendeveloper 3a66811a52 Fix:[#3143]【商城小程序】供应商入驻资料填写页面—未填写营业时间也可以提交 2025-01-23 01:08:05 +08:00
modendeveloper 3f22aa26b7 Fix:3150 【商城小程序】特色店铺、采购批发商入驻流程未改变为先弹出入驻须知再填写资料 2025-01-23 00:23:28 +08:00
modendeveloper c71586fc1d Fix:3149 【商城小程序】店铺营业时间换到店主名称下方,并且店主名称往上移一点,空出的地方放营业时间 2025-01-23 00:15:56 +08:00
modendeveloper d1544978c5 Fix:3154 【商城小程序】搜索页面—搜索框无法手动输入内容(机型:苹果12。现在显示的数据是浮动词条的数据) 2025-01-23 00:04:08 +08:00
modendeveloper ba0312001b Fix:3151 【商城小程序】点击搜索框处的放大镜不会直接跳转浮动词条对应搜索结果页面,并且搜索框及按钮变长了 2025-01-22 23:59:14 +08:00
modendeveloper f0aa415852 Fix:3153 【商城小程序】全部列表中待收货订单和待收货列表含有“查看物流”键,已完成订单详情页中也有“查看物流”键,需要隐藏 2025-01-22 23:55:35 +08:00
modendeveloper 3d3f8309d1 Fix:3157 【商城小程序】已完成,已退款状态订单也需要显示物流信息 2025-01-22 23:53:41 +08:00
modendeveloper b1a1e5aae0 Fix:3152 【商城小程序】消息板块功能指引框选位置调整(苹果12) 2025-01-22 23:37:23 +08:00
modendeveloper 0691844ee9 Fix:3158 【商城小程序】从消息列表中进入对话与从商品详情页中进入对话,商家的名称不一致(统一为商户名称) 2025-01-22 23:09:16 +08:00
modendeveloper edc79a2b42 Fix:3159 【商城小程序】滑动待收货、待评价订单列表,“更多”按钮浮在订单分类名称上 2025-01-22 23:02:14 +08:00
modendeveloper 3dd6d53f90 Fix:3168 【商城小程序】搜索词过长时,历史搜索词条显示不全 2025-01-22 23:00:13 +08:00
modendeveloper 81c89f5076 Fix:2983 【商城小程序】被下架的商品在购物车中消失(改为前端数据保留,点击时提醒商品已下架或被删除) 2025-01-22 01:56:24 +08:00
modendeveloper 15619b00ff Fix:2983 【商城小程序】被下架的商品在购物车中消失(改为前端数据保留,点击时提醒商品已下架或被删除) 2025-01-22 01:55:12 +08:00
modendeveloper 63526f4f06 Fix:3011 【商城小程序】店铺主页发布动态中,简介输入字数超过140字时未弹出”字数超过限制“提示,且下方字数提示变化不正确 2025-01-22 01:48:10 +08:00
modendeveloper cab0577e03 Fix:3105 【商城小程序】特产/文玩供应商、特色店铺、采购批发商入驻,填写错误验证码,点击提交申请确认申请须知后才会提示 2025-01-22 01:43:23 +08:00
modendeveloper b19ba34db2 Fix:3141 【商城小程序】订单多物流情况下,查看物流详情页中只显示一个物流信息,隐藏底部的查看物流按钮 2025-01-22 01:33:20 +08:00
modendeveloper a96c3759b9 Fix:3124 【商城小程序】寻趣味板块新手引导框选位置调整 2025-01-22 01:23:09 +08:00
modendeveloper 2a3ca96fa0 Fix:3118 【商城小程序】新手引导框选范围需要调整 2025-01-22 01:18:41 +08:00
modendeveloper 626e747049 Fix:3114 【商城小程序】首页及搜索页面搜索框没有显示浮动词条 2025-01-22 01:15:10 +08:00
modendeveloper 94536b0876 Fix:3135 【商城小程序】目前有古镇无店铺的城市,仍然显示了暂无店铺 2025-01-22 00:31:56 +08:00
modendeveloper 3d6a2785d5 Fix:3119 【商城小程序】用户点击商品卡片不会跳转到对应的商品详情页 2025-01-22 00:26:39 +08:00
modendeveloper 5177f5881a Task:消息页改版 2025-01-22 00:00:06 +08:00
modendeveloper e53d0e4f4d Fix:3107 【商城小程序】地标好物角标图片换成这张 2025-01-21 01:19:44 +08:00
modendeveloper 32881769ed Fix:3115 【商城小程序】全国特产需要增加购物车按钮,并可以点击加入购物车 2025-01-21 00:54:51 +08:00
modendeveloper 8020afc339 Fix:3123 【商城小程序】店铺没有显示店铺营业时间 2025-01-21 00:29:44 +08:00
modendeveloper 4e28ef3d37 Fix:3122 【商城小程序】填写入驻申请资料页面没有店铺营业时间 2025-01-21 00:15:37 +08:00
modendeveloper a6816e1469 Fix:3133 【商城小程序】没有显示最后一个店铺类型 2025-01-20 23:04:51 +08:00
modendeveloper 1dd7b1e3b1 Fix:3120 【商城小程序】切换城市页面,弹出“无效的guidename” 2025-01-20 23:00:22 +08:00
modendeveloper a3a0d0c833 Task:物流拆分 2025-01-20 22:56:20 +08:00
modendeveloper b07e967e23 Fix:3022 【商城小程序】填写申请资料点击返回后再次进入,填写内容未保留(修复为填写内容仍然保留) 2025-01-19 22:11:27 +08:00
modendeveloper e18a5e5c70 Fix:3023 【商城小程序】店铺名称超过15个字,店铺logo显示会发生不同程度的压缩 2025-01-19 22:00:06 +08:00
modendeveloper f74f6e3b49 Fix:3024 【商城小程序】古镇名称超过13个字的内容会被分享键遮挡(预留分享键的空间进行换行 2025-01-19 21:37:20 +08:00
modendeveloper f80d58ef3d Fix:3024 【商城小程序】古镇名称超过13个字的内容会被分享键遮挡(预留分享键的空间进行换行 2025-01-19 21:36:43 +08:00
modendeveloper 4dea0cd681 Fix:3061 【商城小程序员】商品资质供应商名称中部分字母显示不全 2025-01-19 21:30:20 +08:00
modendeveloper 6685638c54 Fix:3094 【商城小程序】多规格商品点击购物车图标并加购成功后,再次点击购物车图标打开规格选择页面,购买数量会保留上一次的值 2025-01-19 21:24:16 +08:00
modendeveloper bd2338f16a Task:指引功能/状态接口对接 2025-01-19 02:52:58 +08:00
linxi 85854ea2f6 Task:指引页/ 图片定位完成 2025-01-18 16:45:06 +08:00
modendeveloper ec33f6f4c0 Task:指引功能 2025-01-18 12:32:13 +08:00
linxi f3be581278 Task:指引页 2025-01-17 18:17:30 +08:00
lifizer 50dab652e9 Feat(搜索):排行榜和热门配置对接 2025-01-17 16:49:59 +08:00
linxi 30c2d18412 Task:指引页 2025-01-16 18:09:07 +08:00
modendeveloper c6ff84ca5d Task:指引功能 2025-01-16 00:33:42 +08:00
linxi f19ac9ad42 Task:订单提交页面优化/ 提交订单前,若在商品详情页选择了优惠券,则提交订单页面删除该按钮 2025-01-15 18:16:01 +08:00
modendeveloper 46b858b700 Task:点击购物车图标加入购物车 2025-01-14 23:42:33 +08:00
linxi f8b6d72a59 Task:商品足迹增加商品名称 2025-01-14 15:50:04 +08:00
modendeveloper 4bc50aac9c Task:选择城市,搜索按钮颜色调整 2025-01-13 22:43:06 +08:00
modendeveloper 432177604f Task:商城详情优惠券增加关闭按钮 2025-01-13 22:36:58 +08:00
modendeveloper daf0ed691e Fix:2987 【商城小程序】寻趣味分类,古镇应该始终固定在左侧,现在往右滑动会把古镇分类挤掉,详情见视频附件 2025-01-08 22:03:19 +08:00
modendeveloper a24bfb2ff2 Fix:3011 【商城小程序】店铺主页发布动态中,简介输入字数超过140字时未弹出”字数超过限制“提示,且下方字数提示变化不正确 2025-01-08 21:23:47 +08:00
modendeveloper dc8069bca1 Fix:3002 【商城小程序】优化评论列表中多个视频不能同时播放,播放下一个视频自动暂停前一个正在播放的视频 2025-01-08 21:17:56 +08:00
modendeveloper 02627db525 Fix:3010 【商城小程序】申请店铺入驻,填写资料返回或点击撤销店铺申请,再次进入,填写的资料未保留(修复为资料仍然保留) 2025-01-08 21:05:42 +08:00
modendeveloper 4a929f4b32 Fix:2999 【商城小程序】在当前页面增减商品数量,关闭规格选择后再次打开,商品数量显示为1,点击增减,商品数量变为在之前填写的数量基础上增减 2025-01-08 20:49:09 +08:00
modendeveloper ed006c46c5 Fix:2988 【商城小程序】所有县城的租售资讯--增加“全部”分类,首次进入页面时,默认显示“全部”分类,展示所有店铺 2025-01-08 20:05:08 +08:00
modendeveloper 77953ad6fe Fix:2986 【商城小程序】寻趣味暂无店铺标识,之前改为有此标识也开放为可以进入页面,现在还要按如下方式修改一下规则 2025-01-08 19:56:20 +08:00
modendeveloper 09b677d593 Fix:2984 【商城小程序】我的收藏--被下架的商品在商品收藏中消失(改为前端数据保留,点击时提醒商品已下架或被删除) 2025-01-08 19:42:25 +08:00
modendeveloper 3ea76f4081 Fix:2983 【商城小程序】被下架的商品在购物车中消失(改为前端数据保留,点击时提醒商品已下架或被删除) 2025-01-08 19:33:12 +08:00
lifizer b265382c2e Merge branch 'dev' into test 2024-12-30 11:46:59 +08:00
linxi 0bb76095fb Fix:2975 【商城小程序】产业--租售资讯下三级分类标签需要调整放大,参考效果图,把按钮高度再加一点 2024-12-27 18:05:06 +08:00
linxi cd4bef91c2 Fix:2958 【商城小程序】点击“换一换”,浏览店铺列表出现重复店铺数据 2024-12-27 17:24:16 +08:00
linxi cc2664f116 Fix:2959 【商城小程序】先播放古镇活动版块视频,再播放主图视频,活动版块视频不会暂停 2024-12-27 17:06:24 +08:00
linxi 71aa5e5a3c Fix:2975 【商城小程序】产业--租售资讯下三级分类标签需要调整放大,参考效果图,把按钮高度再加一点 2024-12-27 16:54:54 +08:00
lifizer febca80a9b Fix(寻趣味):[#2971]页面标题替换 2024-12-27 11:56:34 +08:00
lifizer 851bcb16d7 Fix(订单/详情):[#2965]订单详情页点击复制快递单号,粘贴以后会变成订单号 2024-12-27 11:55:45 +08:00
lifizer 20a46f10dc Fix(寻趣味):[#2970]图标替换 2024-12-27 11:55:13 +08:00
lifizer 4a449485f7 Fix(全国特产/城市选择):[#2972]全国特产的特别推荐处店铺视频封面图未显示 2024-12-27 11:43:10 +08:00
modendeveloper 8aa2454a1a Task:村屋多加一级分类 2024-12-26 23:30:30 +08:00
modendeveloper 0ceb016e20 Fix:2966 【商城小程序】特色礼品主页中的商品设置低于3个,商品名称过长时,商品名称不会对应图片宽度换行显示 2024-12-26 19:56:19 +08:00
modendeveloper 8b93ab3c18 Fix:2963 【商城小程序】城市切换提示--提示框效果优化 2024-12-26 19:46:36 +08:00
modendeveloper 3c897506d2 Fix:2950 【商城小程序】非遗文化店铺封面为视频时显示空白 2024-12-24 23:35:18 +08:00
modendeveloper c7fc52d5c3 Fix:2949 【商城小程序】优惠详情中无更多可使用券时增加提示“暂无更多可使用券,快去抽奖吧~” 2024-12-24 23:07:00 +08:00
modendeveloper 403e8d1e3f Fix:2943 【商城小程序】项目-店铺列表页面封面视频无需播放,显示封面即可 2024-12-24 22:56:47 +08:00
modendeveloper 7672f8a309 Fix:2946 【商城小程序】古镇主图视频增加播放/暂停按钮 2024-12-24 22:54:04 +08:00
modendeveloper 5994f5dba4 Fix:2947 【商城小程序】活动内容为视频时,优化视频框,参考店铺视频资讯 2024-12-24 22:46:17 +08:00
modendeveloper 3639c2d04f Fix:2951 【商城小程序】之前寻趣味城市无店铺时,无法点击进入详情页,现在解除这个限制,无店铺也可以点进去,不然看不了古镇 2024-12-24 22:27:49 +08:00
modendeveloper 7f459e2b99 Fix:2948 【商城小程序】推荐店铺-页面下滑刷新店铺数据后,点击“换一换”,店铺数据显示不全且再次点击“换一换”无效 2024-12-24 22:27:29 +08:00
linxi 69d866e6ce Fix:2873 【商城小程序】县城详情页,改为一个商品,一个店铺,错开排列,每行固定一个商品,一个店铺 2024-12-24 11:34:27 +08:00
linxi 37117598ea Fix:2874 【商城小程序】农民店铺标识,改为下图所示的框 2024-12-24 11:10:48 +08:00
linxi 34ff7c403a Fix:2909 【商城小程序】商品价格过长时,商品足迹内商品价格信息显示异常 2024-12-24 10:50:10 +08:00
linxi 420a14f6d9 Fix:2826 【商城小程序】农民店铺无法取消收藏,收藏时点取消图标未变更 2024-12-24 10:26:16 +08:00
linxi a9b63ca251 Fix:2922 【地标好物】多个视频资讯改为不能同时播放 2024-12-24 10:18:56 +08:00
linxi 2b12a03703 Fix:2898 【商城小程序】点击1-3次“换一换”后继续点击无效 2024-12-23 09:20:26 +08:00
linxi 81c82aca50 Fix:2901 【商城小程序】“请上传店铺视频方面”改为“请上传店铺视频封面” 2024-12-23 09:18:14 +08:00
modendeveloper 78c83ecaa3 Fix:2903 【商城小程序】农民店铺、村屋租售,寻趣味店铺,视频资讯播放中再点击视频封面播放,两者会出现同时播放情况 2024-12-19 23:59:15 +08:00
modendeveloper b133d0132c Fix:2908 【商城小程序】搜索结果--商品价格过长时商品原价超出商品框 2024-12-19 23:41:46 +08:00
modendeveloper 555d2babde Fix:2905 【非遗文化】非遗标题名称的文字区域再延长一点,延长至红框范围 2024-12-19 23:03:20 +08:00
modendeveloper 0b4cb9696e Fix:2863 【寻趣味】配置活动删除时间插件,活动时间改为纯文本输入框 2024-12-19 23:00:37 +08:00
modendeveloper 104d0ef4e1 Fix:2864 【管理后台】古镇等级设置,后台改为纯文本输入,前端标识根据文本显示 2024-12-19 00:32:33 +08:00
modendeveloper 020bdadcae Fix:2876 【管理后台】地标好物资讯增加上传视频功能,前端地标好物资讯也需要调整为可以显示视频 2024-12-19 00:26:18 +08:00
modendeveloper ffa827c137 Fix:2858 【寻趣味】古镇内容按城市划分配置显示 2024-12-19 00:25:54 +08:00
modendeveloper 6a3445a0cc Fix:2881 【千县名品】千县,县城资讯需要增加上传视频功能 2024-12-19 00:14:12 +08:00
modendeveloper 97c7fda9bb Fix;2883 【寻趣味】活动时间要另起一行,不能跟资讯连在一起 2024-12-18 23:41:43 +08:00
modendeveloper 78e0937fca Fix:多视频只能播放一个 2024-12-18 23:34:57 +08:00
modendeveloper 27c95042d4 Fix:2887 【商城小程序】村屋资讯-多个视频资讯可同时播放(优化为点击下一个视频播放时,上一个视频自动停止) 2024-12-18 23:23:47 +08:00
modendeveloper 40431f03fc Fix:2886 【商城小程序】农民店铺-多个视频资讯可同时播放(优化为点击下一个视频播放时,上一个视频自动停止) 2024-12-18 23:18:33 +08:00
modendeveloper f64f87546e Fix:2889 【商城小程序】优化当寻趣味店铺封面为视频时,视频资讯和视频封面不能同时播放 2024-12-18 23:18:12 +08:00
modendeveloper f174a83ac0 Fix:2889 【商城小程序】优化当寻趣味店铺封面为视频时,视频资讯和视频封面不能同时播放 2024-12-18 22:48:08 +08:00
modendeveloper 01dc1711ca Fix:2882 【非遗文化】非遗主推荐,需要进行自动往右持续轮播 2024-12-18 22:38:35 +08:00
modendeveloper e0dac0207b Fix:2885 【商城小程序】养生食材,轮播推荐触控区域改为整张图片 2024-12-18 22:34:14 +08:00
modendeveloper c2901522ac Fix:2884 【商城小程序】养生圣地,轮播推荐触控区域改为整张图片 2024-12-18 22:34:02 +08:00
modendeveloper 426ca24f51 Fix:2878 【寻趣味】古镇详情页--去除古镇名称下方虚线 2024-12-18 22:29:49 +08:00
modendeveloper b687d3737a Fix:2877 【寻趣味】古镇详情页--项目--店铺封面为视频时,项目列表店铺未显示封面 2024-12-18 22:28:47 +08:00
modendeveloper 0b0abdfad8 Fix:2880 【寻趣味】古镇详情页--分享按钮位置调整,往下移一点 2024-12-18 22:21:47 +08:00
modendeveloper 99676adb48 Fix:2879 【寻趣味】古镇详情页--活动内容为视频时无法显示视频 2024-12-18 22:17:58 +08:00
modendeveloper f2f2528316 Fix:2891 【商城小程序】封面【播放/暂停键】点击范围不明确,响应不灵敏,把播放/暂停触控区域再加大一些 2024-12-18 22:10:26 +08:00
modendeveloper 9d2c99507c Fix:2890 【商城小程序】顶部名称更换“非遗技艺” 2024-12-18 21:17:44 +08:00
modendeveloper 9092d0d73d Fix:2851 【商城小程序】非遗详情页分类1图片名称去除书名号,文字过长时换行显示,最多显示2行文字,超出... 2024-12-17 22:12:14 +08:00
modendeveloper 8e8ca5a261 Fix:2797 【商城小程序】根据运营设计的调整,非遗主页的省名删除,只显示图片 2024-12-17 22:10:14 +08:00
modendeveloper eddb02d2cf Feat:分享接口对接&&换一换接口对接 2024-12-14 21:56:37 +08:00
linxi b535e21e2f Feat: 寻趣味接口对接(缺分享接口,店住名称字段) 2024-12-13 16:04:25 +08:00
linxi 50cbe66332 Feat: 寻趣味改版(新增古镇模块) 2024-12-12 18:06:03 +08:00
linxi 07bccb8b68 Feat:解除店铺入住图片数量限制 2024-12-04 14:39:26 +08:00
lifizer 89f33882b5 Merge branch 'dev' into test 2024-12-04 14:01:51 +08:00
lifizer c5c9c9146b Fix(购物车&订单):修复地址选择之后事件分发错误问题 2024-12-04 12:03:32 +08:00
linxi c0a09ad449 Fix:2742 【商城小程序】购物车页面修改地址后,定位没有相应的修改 2024-12-04 09:32:12 +08:00
linxi 5112f3314b Fix:2743 【地标好物】服务页面的【客服】文字改为【咨询】 2024-12-04 09:32:01 +08:00
lifizer b225e107e5 Eslint code 2024-12-03 09:51:31 +08:00
lifizer 21a80c6434 Fix(千县名品&寻趣味):[#2740]分享图片的头像变形了 2024-12-03 09:22:07 +08:00
modendeveloper 1a0957f4bb Merge branch 'dev' of https://gitee.com/fengyuze178/xdd-uniapp-new into dev 2024-12-02 18:40:10 +08:00
modendeveloper de6cca5bac Style:分享图片css调整 2024-12-02 18:39:45 +08:00
lifizer 10cbf5ef03 Merge branch 'dev' into test 2024-12-02 10:37:54 +08:00
lifizer 5f0f961220 Chore:代码格式化 2024-12-02 10:23:48 +08:00
lifizer 1f1c114eda Conf:关闭调试模式 2024-12-02 10:23:17 +08:00
modendeveloper f65c033bd7 Feat:分享调整 2024-11-30 18:56:59 +08:00
modendeveloper fc47a981f9 Feat:千县城市分享 2024-11-30 12:20:20 +08:00
lifizer 088f3ea370 Conf(拦截器):设置超时时长为2分钟 2024-11-29 15:43:14 +08:00
lifizer e48762c783 Fix(首页):未校验返回数据的合法性导致界面渲染错误 2024-11-29 15:32:14 +08:00
lifizer 5813924548 Conf(拦截器):修正异常捕获返回的局部变量错误导致逻辑执行异常 2024-11-29 15:13:55 +08:00
linxi 8a9862126b Fix:vivo手机兼容 2024-11-29 11:44:42 +08:00
linxi 6c44e3eb53 Feat:新品商品轮播速度调整 2024-11-29 11:44:29 +08:00
linxi ea71e61451 Fix:2734 【商城小程序】千县—农民店铺和商品封面显示优化,店铺图片封面要铺满底板边缘 2024-11-29 11:01:25 +08:00
linxi 9353aad39f Fix:2585 【商城小程序】购物车--商品数量增减超出库存或少于最低拿货数时,增加提示“商品数量超出库存”和“商品数量不能减少了呦~” 2024-11-29 10:13:30 +08:00
linxi 952a332ba1 Fix:2733 【商城小程序】默认物流地址在列表中删除/修改后购物车定位和订单默认地址未同步刷新,应该删除以后直接刷新 2024-11-29 10:01:23 +08:00
linxi b9b1a4aa30 Fix:2734 【商城小程序】千县—农民店铺和商品封面显示优化,店铺图片封面要铺满底板边缘 2024-11-29 09:46:22 +08:00
linxi 52946a4afe Fix:2735 【商城小程序】千县—农民店铺文化图片显示优化 2024-11-29 09:45:59 +08:00
linxi e0588d2ecb Feat: 新品专区商品封面调整 2024-11-28 18:16:28 +08:00
linxi d676a9e496 Fix:2721 【新品专区】商品和背景图增加同时自动轮播效果,自动轮播时是一个整体,5秒轮播一次,轮播效果查看视频 2024-11-28 17:01:32 +08:00
linxi 2d6d6cf90c Fix:2732 【新品专区】轮播图后面的两个商品区域再缩小一点 2024-11-28 16:54:32 +08:00
linxi 329adbd287 Fix:2730 【商城小程序】千县—农民店铺封面角标显示优化 2024-11-28 16:32:28 +08:00
linxi 370e347b93 Fix:2729 【非遗技艺】非遗文化自动轮播不稳定(刚才可以自动轮播,现在又不可以了) 2024-11-28 16:23:51 +08:00
linxi 9fc2579247 Fix:2725 【商城小程序】千县—农民店铺封面为视频应该显示第一帧作为封面图,并且不要显示播放按钮 2024-11-28 16:21:28 +08:00
linxi 972f5ba027 Fix:2723 【非遗技艺】搜索后切换分类,轮播区域数据没有根据搜索词条进行展示,改为搜索以后,切换分类时也保留搜索结果 2024-11-28 16:11:19 +08:00
linxi ac10ea7a4f Fix:2722 【非遗技艺】点击跳转的触控区域,放大到整个图片 2024-11-28 16:08:54 +08:00
linxi 3d2924fbd3 Fix:2721 【新品专区】商品和背景图增加同时自动轮播效果,自动轮播时是一个整体,5秒轮播一次,轮播效果查看视频 2024-11-28 16:04:37 +08:00
linxi 4dbd30aad5 Fix:2717 【地标好物】产品--无商品时不显示“已经到底啦”,改为显示暂无数据 2024-11-28 15:52:59 +08:00
linxi 11eca54e21 Fix:2718 【商城小程序】首页寻看点素材图标需要放大一点,视频可以自动播放 2024-11-28 15:42:33 +08:00
linxi 8c1fdba140 Style:分享/保存图片按钮样式调整 2024-11-28 09:25:05 +08:00
linxi feb314d279 Fix:节日专题位置被占用问题 2024-11-27 16:34:58 +08:00
linxi a104473e86 Fix:2712 【地标好物】地标好物分享图片下方增加一个保存图片按钮,点击后直接保存图片,替换掉长按保存图片功能 2024-11-27 16:19:08 +08:00
linxi d0fd7cb653 Fix:2707 【非遗文化】手机型号:iQOO neo7SE--非遗文化详情页分类2的店铺,一句话介绍超出两行时的显示效果需要优化 2024-11-27 15:54:21 +08:00
linxi 5a7a5831b0 Fix:2709 【商城小程序】千县暂无资讯增加暂无内容图片提示 2024-11-27 15:28:27 +08:00
linxi 7379cbd052 Fix:2708 【地标好物】暂无商品改为暂无内容图片 2024-11-27 15:23:27 +08:00
linxi 3cc41c3c34 Fix:2711 【非遗文化】非遗列表页面搜索功能需要对轮播区域生效 2024-11-27 15:14:10 +08:00
linxi 80ba906630 Fix:2706 【非遗文化】非遗列表页面的非遗名称字体加粗 2024-11-27 15:07:46 +08:00
linxi 53b52d71d3 Fix:2568 【商城小程序】店铺主页-修改资料、商户入驻-店铺图片、管理后台编辑店铺图片,解除上传图片数量限制(原先是限制最多上传9张) 2024-11-27 15:04:44 +08:00
linxi 99ac5f04ed Fix:2563 【商城小程序】千县—农民店铺封面为视频时未显示,需要显示视频第一帧作为封面 2024-11-27 14:59:05 +08:00
linxi 8d29cb777f Fix:2697 【地标好物】扫二维码需要直接进入相应的省份 2024-11-27 10:54:48 +08:00
linxi a302f11b95 Fix:2697 【地标好物】扫二维码需要直接进入相应的省份 2024-11-27 09:26:00 +08:00
linxi b536f2ad68 Fix:2696 【非遗文化】点击未设置链接的顶部海报无需跳转页面,否则会报错 2024-11-27 09:17:04 +08:00
linxi 3944c961d9 Fix:2695 【非遗文化】非遗未显示推荐数据 2024-11-27 09:13:56 +08:00
linxi 338c63d634 Fix:新品专区轮播图不自动播放 2024-11-26 17:47:48 +08:00
linxi 6a58bf6e45 Fix:2702 【商城小程序】千县—农民店铺详情展示效果与设计图不一致,需要调整一下 2024-11-26 17:47:26 +08:00
linxi b7b23ddab4 Fix:2703 【商城小程序】千县—农民店铺详情点击收藏图标提示“店铺已收藏”,但收藏数量和图标颜色无变化 2024-11-26 17:45:50 +08:00
linxi afd678135d Fix:新品专区背景图同步商品 2024-11-26 15:15:18 +08:00
linxi 8c392f1d57 Fix:2688 【地标好物】文化图片查看大图时增加左右滑动查看 2024-11-26 15:03:26 +08:00
linxi f4cfeb37e8 Fix:2562 【商城小程序】千县—点击进入农民店铺链接数据显示混乱 2024-11-26 14:42:40 +08:00
linxi 0ac3babdd2 Fix:2685 【新品专区】新品专区轮播图,改为每个商品对应上传一个背景图片,因为前端左右滑动商品,背景图需要同步切换 2024-11-26 09:45:21 +08:00
linxi faf51f7c6f Fix:2687 【地标好物】分享图片设置为圆角 2024-11-25 17:09:35 +08:00
linxi 78c13fe05c Fix:2683 【商城小程序】团队管理中搜索不存在会员时增加提示 2024-11-25 17:03:47 +08:00
linxi dcf15eeb54 Fix:2693 【非遗文化】【关闭】状态的省份图标及名称不会变灰,与管理后台展示的效果不一致 2024-11-25 16:54:20 +08:00
linxi 6aced33e45 Fix:2694 【非遗文化】【开启】状态的省份点击无反应 2024-11-25 16:47:54 +08:00
linxi f1460485d3 Fix:2499 【商城小程序】寻趣味,查看店铺详情后返回列表后会出现频闪 2024-11-25 16:43:25 +08:00
linxi 141fbaa330 Fix:2568 【商城小程序】店铺主页-修改资料、商户入驻-店铺图片、管理后台编辑店铺图片,解除上传图片数量限制(原先是限制最多上传9张) 2024-11-25 16:32:40 +08:00
linxi 33d8e42c6f Fix:2534 【商城小程序】千县--未登录时点赞或收藏千县店铺会跳出“非法访问”提示,随后跳转登录页面(去除”非法访问“提示) 2024-11-25 16:23:22 +08:00
linxi 7512d21e75 Fix:2629 【商城小程序】商品评价和店铺资讯超过140字时限制输入无提示,再次输入内容,发表结果会显示再次输入内容的最后两个字/ 商品评价 2024-11-25 11:49:16 +08:00
modendeveloper 74dbbd0a90 Fxi:2449 【商城小程序】寻迹千县-店铺,当资讯、攻略无内容时,提示信息改为暂无资讯/暂无攻略 2024-11-24 16:37:22 +08:00
modendeveloper 1a773023c1 Fix:2584 【商城小程序】商家资质--商品详情页中查看商家资质,名称过长时,左侧“”商家名称“”标题不要换行 2024-11-24 16:31:23 +08:00
modendeveloper 33425987f7 Fix:2629 【商城小程序】商品评价和店铺资讯超过140字时限制输入无提示,再次输入内容,发表结果会显示再次输入内容的最后两个字 2024-11-24 16:28:20 +08:00
modendeveloper 862e624913 Fix:2630 【商城小程序】地标好物增加分享按钮,点击后弹出分享图片 2024-11-24 16:10:14 +08:00
modendeveloper a8bdcd5495 Fix:2641 【地标好物】服务--导航和客服按钮无效 2024-11-24 15:27:25 +08:00
modendeveloper 82b8e53aee Fix:2643 【地标好物】切换到无数据的省份,项目-企业推荐和服务内容会同步上一个省份内容 2024-11-24 15:19:00 +08:00
modendeveloper c484d20cb2 Fix:2649 【非遗文化】【推荐】没有根据类目的切换进行联动变更 2024-11-24 14:49:18 +08:00
modendeveloper 909f462aa1 Fix:2682 【非遗文化】非遗列表页面顶部海报无法自动轮播(只有一张时无需轮播,配置两张及以上时需自动轮播) 2024-11-24 14:37:05 +08:00
modendeveloper 989c0be025 Fix:2652 【非遗文化】点击已设置链接的顶部海报,页面未跳转 2024-11-24 14:36:01 +08:00
modendeveloper 2166597ac8 Fix:2660 【非遗文化】非遗详情页此处应显示店铺的一句话介绍 2024-11-24 14:28:36 +08:00
modendeveloper 0398404f4b Fix:2669 【非遗文化】非遗的名称背景半透明范围再扩大一点,覆盖到名称 2024-11-24 14:25:57 +08:00
modendeveloper 9b90323f27 Fix:2670 【地标好物】项目--政策--文件名称过长时改为换行显示,换行时右侧>图标上下居中(不要省略号) 2024-11-24 14:22:27 +08:00
modendeveloper 453bb23186 Fix:2671 【地标好物】产品和资讯底部的“已经到底了”提示未居中(咨询) 2024-11-24 14:19:19 +08:00
modendeveloper 398a8a40a0 Fix:2672 【非遗技艺】查看大图时,增加左右滑动对图片翻页的功能 2024-11-24 14:16:12 +08:00
modendeveloper a900bc4c1b Fix:2675 【非遗文化】非遗详情页顶部视频自动播放后没有暂停按钮,增加点击视频暂停功能,并且暂停时中间放一个播放按钮,再次点击后继续播放 2024-11-24 14:13:05 +08:00
modendeveloper 2c27ec6f8f Fix:2674 【地标好物】产品和资讯底部的“已经到底了”提示未居中 2024-11-24 13:50:09 +08:00
linxi 87027d9d4e Fix:2604 【商城小程序】抽奖--双击“立即抽奖”,获得奖品两个,只弹出一个抽奖结果,应该限制快速多次点击时只抽一次奖,抽奖动画完成之前不管点多少次,都不能快速触发下一次抽奖 2024-11-21 09:28:33 +08:00
linxi 265507014e Fix:2557 【商城小程序】食补推荐列表商品图显示不完整 2024-11-20 17:39:14 +08:00
linxi 3625a45e2c Fix:2621 【商城小程序】订单详情—再买一单,修改收货地址确认框弹出之前地址已修改,点取消修改无法取消 2024-11-20 17:18:12 +08:00
linxi 0bdcae5d00 Fix:2559 【商城小程序】从文玩城市选择界面跳转到展会页面的顶部标题“康养旅居”改为“文玩艺术” 2024-11-20 17:18:03 +08:00
linxi 7f4cefda3b Fix:2578 【商城小程序】寻趣味顶部,改成:探索生活好去处 2024-11-20 17:08:56 +08:00
linxi de308dfa68 Fix:2617 【商城小程序】前端小程序中资讯显示的时间应为发布时间 2024-11-20 17:05:50 +08:00
linxi 3288c71b8a Fix:2608 【商城小程序】商户入驻--店铺图片选项改为必填项 2024-11-20 17:01:00 +08:00
linxi 257445263d Fix:2605 【商城小程序】商品评价--未显示发表时间 2024-11-20 16:48:13 +08:00
linxi 23a02352d7 Fix:2621 【商城小程序】订单详情—再买一单,修改收货地址确认框弹出之前地址已修改,点取消修改无法取消 2024-11-20 16:34:22 +08:00
linxi f5898444ab Fix:2629 【商城小程序】商品评价和店铺资讯超过140字时限制输入无提示,再次输入内容,发表结果会显示再次输入内容的最后两个字 2024-11-20 15:53:41 +08:00
linxi a14931a64e Fix:2581 【商城小程序】历史搜索--退出重新登录后,历史搜索被清空 2024-11-20 15:50:04 +08:00
linxi 5c92359a09 Fix:2657 【非遗文化】非遗文化详情页分类1简介开头输入的空格无法生效 2024-11-20 15:38:10 +08:00
linxi 9519401d75 Fix:2639 【新品专区】轮播商品--首个商品图片,文字都需比后面的商品大一点,严格按照效果图实现效果 2024-11-20 15:12:37 +08:00
linxi 3f1f2689be Fix:2640 【地标好物】产品--商品区域偏左,改为居中 2024-11-20 15:07:00 +08:00
linxi d502a276be Fix:2642 【地标好物】项目--政策--文件名称过长时不会自动换行 2024-11-20 14:57:29 +08:00
linxi 04c0f4a720 Fix:2644 【地标好物】文化--图片点击无法放大查看 2024-11-20 14:52:11 +08:00
linxi 2d1a1cc242 Fix:2648 【地标好物】项目—企业推荐—店铺名称超过15个字“...”显示 2024-11-20 14:49:31 +08:00
linxi 7bb0c67b83 Fix:2645 【地标好物】项目--政策无内容时隐藏查看更多按钮 2024-11-20 14:47:41 +08:00
linxi 18f9021c83 Fix: 2650 【地标好物】资讯--两侧与手机边缘适当留白,与底部留白平行 2024-11-20 14:35:55 +08:00
linxi 2ef47a52c2 Fix:2665 【非遗文化】非遗文化列表页面顶部海报显示不全,需按效果图尺寸设置该尺寸 2024-11-20 14:11:12 +08:00
linxi 1a8d44f1a4 Fix:2651 【地标好物】项目--服务,地图增加显示定位图标 2024-11-20 11:56:35 +08:00
linxi 33070fe21b Fix:2653 【非遗文化】【推荐】处的非遗文化名称及简介区域新增底色 2024-11-20 11:43:28 +08:00
linxi a18d191ebe Fix:2655 【非遗文化】非遗类目下无数据时,没有相关提示信息,应显示暂无内容的图片 2024-11-20 11:28:33 +08:00
linxi 0ef40fa345 Fix:2656 【非遗文化】类目下方轮播区域,数据大于等于3个时需要自动轮播,持续往右轮播,参考抽奖奖品的轮播 2024-11-20 11:19:46 +08:00
linxi 0b0c87245d Fix:2658 【商城小程序】非遗详情页分类1无法查看大图,增加点击查看大图功能 2024-11-20 10:24:34 +08:00
linxi 18190e76e4 Fix:2659 【非遗文化】进入非遗文化详情页,顶部视频未自动播放,增加自动播放功能 2024-11-20 10:19:15 +08:00
linxi 8f403fa204 Fix:2661 【非遗文化】非遗文化页面搜索无数据时,无相关提示信息,无内容时增加暂无内容图片显示 2024-11-20 10:11:01 +08:00
linxi af0efae84b Fix: 2662 【非遗文化】非遗详情页无店铺数据时没有相关提示信息 2024-11-20 10:07:45 +08:00
linxi fb881355d9 Fix:2663 【非遗文化】非遗详情页副标题改为居中显示 2024-11-20 09:55:00 +08:00
modendeveloper bf7035cd2e Feat:地标好物政策搜索页 2024-11-19 00:58:08 +08:00
modendeveloper 0edbbfcdf5 Feat(首页):新品专区(完成) 2024-11-19 00:38:58 +08:00
modendeveloper 655bb7e7e3 Style(非遗文化&地标好物): 图片、图标、背景图调整 2024-11-17 23:32:49 +08:00
linxi 43b81b5430 Feat: 非遗文化封面字段对接 2024-11-15 17:53:13 +08:00
linxi 5f9a6b358d Feat: 地标好物(服务)
(cherry picked from commit d3957be379)
2024-11-15 10:40:22 +08:00
linxi b5c87c1edb Feat: 地标好物(页面&接口)
(cherry picked from commit c18ec66653)
2024-11-15 10:40:13 +08:00
linxi 6983ebeb21 Refactor:非遗文化重构 2024-11-06 18:03:16 +08:00
modendeveloper 0b9c3aa01f Fix:2524 【管理后台。商城小程序】康养旅居--展会轮播图管理未设置展会链接时,点击跳转会出现报错信息,删除该提示 2024-10-28 23:47:12 +08:00
modendeveloper de55d5fc2e Fix:2490 【商城小程序】我的收藏—千县的收藏数据只有一个时,没有靠左排列显示 2024-10-28 23:45:11 +08:00
modendeveloper 5ff8f5f76f Task(千县名品):商铺跳转 2024-10-28 23:35:59 +08:00
linxi c8a7ea63e3 Merge branch 'dev' of https://gitee.com/fengyuze178/xdd-uniapp-new into dev 2024-10-28 11:15:43 +08:00
linxi 440b058d33 Task(千县名品):产品随机列表展示 2024-10-28 11:15:37 +08:00
lifizer 3c7af4fc42 Fix(文玩推荐城市管理):[#2527]增加链接展会功能 2024-10-28 10:40:01 +08:00
linxi f3f47d236f Task(千县名品):产品列表随机算法实现 2024-10-25 17:47:02 +08:00
linxi 1b93ef7909 Fix:2537 【商城小程序】消息列表--删除消息记录会自动引发下一条记录的删除状态 2024-10-25 14:36:47 +08:00
linxi 52dfba61de Fix:2523 【商城小程序】抽奖--在抽奖记录中领取积分,应该跳出查看积分提示,并跳转到积分记录页面 2024-10-25 11:36:42 +08:00
linxi a7aedcc873 Fix:2528 【商城小程序】消息--历史会话界面,店铺名称过长时会挤压时间显示(店铺名称过长用“...”省略,店铺名只显示一行) 2024-10-25 11:10:43 +08:00
linxi 1eac768b76 Fix:2510 【商城小程序】店铺主页-发布动态,一次性上传多张图片时最后几张会显示上传进度为0%,但点击发布后所有图片都能正常在资讯显示 2024-10-22 09:26:21 +08:00
linxi 246c66193b Merge branch 'dev' of https://gitee.com/fengyuze178/xdd-uniapp-new into dev 2024-10-21 15:28:58 +08:00
linxi 831a6d64c0 Fix:2488 【商城小程序】待发货,待收货点击申请退款正常走退款流程,不提示订单已收货 2024-10-21 15:28:51 +08:00
lifizer 00f495a099 Merge branch 'dev' of https://gitee.com/fengyuze178/xdd-uniapp-new into dev 2024-10-21 15:18:17 +08:00
lifizer 918028aa93 Fix(尖货专题页):[#2509, #2512]模板2的轮播图背景图设置 2024-10-21 15:18:05 +08:00
linxi 0c8e9fcd54 Fix:2496 【商城小程序】养生食材--商品入口图显示不全 2024-10-21 15:14:27 +08:00
linxi 5262b93c3f Fix:2497 【商城小程序】商品详情页,自动轮播至最后一张图后会向左快速返回第一张重新轮播,应在最后一张图后向右自动按顺序轮播第一张 2024-10-21 15:08:17 +08:00
linxi 84470b4ec8 Fix:2498 【商城小程序】康养旅居—养生圣地搜索时店铺封面为视频时隐藏播放按钮 2024-10-21 14:59:20 +08:00
linxi ff5dbae3a4 Fix:2490 【商城小程序】我的收藏—千县的收藏数据只有一个时,没有靠左排列显示 2024-10-21 14:21:43 +08:00
linxi 0d0ac8d883 Fix:2511 【商城小程序】申请退款驳回详情页面,显示的应该是驳回原因而不是申请退款的退款原因 2024-10-21 11:51:11 +08:00
linxi cb6545ecd7 Conf:请求库替换,移除之前的flyIo,改用luch-request 2024-10-18 14:48:22 +08:00
lifizer b0ac014816 Refactor(登录):登录按钮去掉判断逻辑,一直显示 2024-10-17 10:05:39 +08:00
lifizer ca11455148 Conf:开发版和体验版打开调试,线上版本关闭调试 2024-10-16 16:59:28 +08:00
lifizer af2699765d Fix(订单):[#2446] 待发货的申请退款应该跳转到未发货退款页面 2024-10-14 15:08:26 +08:00
lifizer 15c427edf7 Fix(订单):[#2488]待发货,待收货点击申请退款正常走退款流程,不提示订单已收货 2024-10-14 14:27:53 +08:00
lifizer f5b3174acc Fix(养生圣地):[#2486]养生圣地第三行文字删掉 2024-10-14 14:16:26 +08:00
lifizer 820cf2dc3f Fix(养生圣地):[#2491]输入关键词后未点击键盘回车键,列表提示“暂无内容”,默认状态下不用显示暂无内容 2024-10-14 11:05:07 +08:00
lifizer ebe18f0240 Fix(养生圣地):[#2486]养生圣地第三行文字删掉 2024-10-14 11:00:20 +08:00
lifizer 447f94ed8d Fix(专题页):[#2450]商品下架或店铺删除的话改为点击不做响应 2024-10-14 10:59:35 +08:00
lifizer 10ef53ecb1 Fix(养生圣地):[#2487]应该显示一句话介绍,而不是地址 2024-10-14 10:26:29 +08:00
lifizer 08c9193475 Fix(养生圣地):[#2491]输入关键词后未点击键盘回车键,列表提示“暂无内容”,默认状态下不用显示暂无内容 2024-10-14 10:20:41 +08:00
lifizer 93d7735aa9 Fix(展会):[#2492]如果没有配置视频则不显示视频播放器 2024-10-14 10:20:01 +08:00
lifizer db13fa3ffa Fix(千县名品):[#2489]导航栏展开方向改为向下 2024-10-14 10:11:41 +08:00
modendeveloper cf868ccebe Fix:2476 【商城小程序】康养旅居页面点击返回按钮的问题 2024-10-11 23:20:30 +08:00
modendeveloper f3e036b9be Fix:2419 【商城小程序】商品详情顶部图片设置为自动轮播,2秒轮播一张图 2024-10-11 22:47:49 +08:00
modendeveloper 194a51ee19 Fix:2467 【商城小程序】全国特产--城市内的特产商品过多时,底部的商品信息显示不全 2024-10-11 22:42:38 +08:00
modendeveloper 2c6c7e82a9 Fix:2451 【商城小程序】寻趣味--点击轮播图或店铺列表图片进入店铺详情页,返回后页面刷新会回到第一个分类页面 2024-10-11 22:42:19 +08:00
modendeveloper 58e29a98c8 Fix:2448 【商城小程序】待付款订单详情页内点击【修改地址】,重复弹出确认修改的弹窗 2024-10-11 22:33:39 +08:00
modendeveloper fb23c8fccf Fix:2446 【商城小程序】待收货、待评价订单详情页—点击【更多】下的【申请退款】按钮,应该跳转待收货订单退款页面,而不是未发货退款页面 2024-10-11 21:54:37 +08:00
modendeveloper 848307944c Fix:2445 【商城小程序】未打开售后的待评价订单,点击订单详情页的【申请退款】按钮仍然可以退款。 2024-10-11 21:50:47 +08:00
modendeveloper d9c696af23 Fix:2445 【商城小程序】未打开售后的待评价订单,点击订单详情页的【申请退款】按钮仍然可以退款。 2024-10-11 21:49:07 +08:00
modendeveloper abd13edb81 Fix:2444 【商城小程序】我的收藏-千县,千县店铺收藏列表底色显示不统一 2024-10-11 21:35:13 +08:00
modendeveloper 8536ad2aca Fix:2424 【商城小程序】千县—文化图片高度存在拉伸(长宽统一改为1:1正方形) 2024-10-11 21:26:30 +08:00
modendeveloper 226a17f420 Fix:2417 【商城小程序】退款失败订单详情增加显示驳回原因 2024-10-11 21:24:02 +08:00
modendeveloper 09941be7b6 Fix:2482 【商城小程序】养生圣地,店铺封面为视频时,隐藏封面入口封面的播放图标 2024-10-11 21:18:51 +08:00
linxi 387fe8d2b8 Fix:2455 【商城小程序】养生圣地店铺搜索需要单独开个页面展示搜索结果,并且搜索结果不根据分类展示,直接展示当前城市下的所有店铺 2024-10-11 17:39:12 +08:00
linxi 37349183f2 Fix:2485 【商城小程序】按效果图上传164*250背景图,会出现背景图显示不完整的情况 2024-10-11 17:27:56 +08:00
linxi da940c7668 Fix:2482 【商城小程序】养生圣地,店铺封面为视频时,隐藏封面入口封面的播放图标 2024-10-11 16:44:45 +08:00
linxi 28ce362a39 Fix:2455 【商城小程序】养生圣地店铺搜索需要单独开个页面展示搜索结果,并且搜索结果不根据分类展示,直接展示当前城市下的所有店铺 2024-10-11 16:19:38 +08:00
linxi e493acec59 Fix:2475 【商城小程序】样式调整,预约旅居与药膳食谱名称背景框透明度设置为70%,文字超出时用省略号显示,不要换行 2024-10-11 15:41:06 +08:00
linxi b3b5f3f6e4 Fix:2472 【商城小程序】点击展会轮播图,没有跳转到展会详情,并且后台设置的轮播图,和前端显示的不是同一张图 2024-10-11 14:57:18 +08:00
linxi 857891c00b Fix:2468 【商城小程序】加入购物食材文字改为:购入同款食材 2024-10-11 14:44:12 +08:00
linxi 35641a8956 Fix:2454 【商城小程序】康养首页--最新展会信息需要做自动轮播效果,3秒轮播一次 2024-10-11 14:41:53 +08:00
linxi f55cb074c8 Fix:2459 【商城小程序】康养首页--城市列表应以三列进行展示 2024-10-11 14:39:34 +08:00
linxi 150d351152 Fix:2463 【商城小程序】康养生活—养生食材,商品名称过长,最多显示2行,超出部分用省略号 2024-10-11 14:37:49 +08:00
linxi d5cdbc4670 Fix:2471 【商城小程序】养生食材配方--食物清单中主料名称过长时会字段会穿过框外,文字超出用省略号 2024-10-11 14:32:35 +08:00
linxi ade5719c00 Fix:2474 【商城小程序】点击展会文字进入详情的触发区域改为点击整个背景色块都可以触发 2024-10-11 14:16:20 +08:00
linxi c8db02282c Fix:2478 【商城小程序】养生食材--养生榜单中榜单名称超过五个字显示... 2024-10-11 14:13:51 +08:00
linxi 179a5f005c Fix:2479 【商城小程序】分类文字间距再加宽大概二分之一,未选中时文字不加粗 2024-10-11 14:12:14 +08:00
lifizer f0e25c2a0d Fix(尖货专题页):[#2469]第二页的背景图及商品店铺,在前端显示成了第三页的内容 2024-10-11 09:59:24 +08:00
modendeveloper 021e94084f Fix:2460 【商城小程序】养生圣地--点击店铺入口图不会跳转到店铺详情页 2024-10-10 19:48:41 +08:00
modendeveloper dce372aca3 Fix:2462 【商城小程序】康养首页—展会信息—其他展会,搜索信息不存在时增加“暂无内容”提示 2024-10-10 19:46:37 +08:00
modendeveloper 12f2e42a16 Fix:2463 【商城小程序】康养生活—养生食材,商品名称过长,最多显示2行,超出部分用省略号 2024-10-10 19:40:28 +08:00
modendeveloper 1aab9ee691 Fix:2457 【商城小程序】圣地分类改为左右滑动,不要换行 2024-10-10 19:32:00 +08:00
modendeveloper eff9db385a Fix:2454 【商城小程序】康养首页--最新展会信息需要做自动轮播效果,3秒轮播一次 2024-10-10 19:25:24 +08:00
modendeveloper b3d8fefaba Fix:2459 【商城小程序】康养首页--城市列表应以三列进行展示 2024-10-10 19:17:12 +08:00
modendeveloper 8c2e785ea0 Feat:康养页面细节调整(已完成) 2024-10-09 23:58:37 +08:00
linxi b397ba232f Feat:康养接口对接,细节调优 2024-10-09 18:07:04 +08:00
modendeveloper 3d3efa89bf Feat:康养页面接口对接 2024-10-09 00:09:59 +08:00
linxi d8cb8ae6cb Feat:康养部分接口对接(圣地,食材为对接) 2024-10-08 18:03:46 +08:00
modendeveloper 566ef9de61 Feat:康养页面 2024-10-08 00:25:03 +08:00
226 changed files with 43993 additions and 3370 deletions
+1
View File
@@ -26,4 +26,5 @@ export default {
@import "./assets/css/reset.less";
@import "./assets/css/style.less";
@import "./assets/css/v12-style.less";
@import "./assets/css/aiChat.less";
</style>
+335
View File
@@ -0,0 +1,335 @@
<template>
<view
:class="{
'focus': inputOnFocus
}"
class="fix-page-bottom"
>
<view v-if="inputModel === 'input'" class="bottom-body flex-center-between">
<view class="history-wrap" @click="historyViewHandle">
历史
</view>
<view class="input-container">
<!-- 输入模式切换 -->
<view
class="input-model"
@click="toggleInputModel"
>
<image
:src="webUrl + '/aiChat/microphone.png'"
class="icon"
mode="widthFix"
/>
</view>
<!-- 输入框 -->
<view class="input-wrap flex-center-between">
<input
v-model.trim="prompt"
:show-confirm-bar="false"
:adjust-position="true"
:disabled="loading"
:maxlength="-1"
class="inp"
@confirm="sendHandle"
@focus="promptInputFocusHandle"
@blur="promptInputBlurHandle"
/>
<view v-if="!prompt && !inputOnFocus" class="placeholder-txt">发消息...</view>
</view>
<view
class="send-btn"
@click="sendHandle"
>
<image
:src="webUrl + '/aiChat/send.png'"
class="icon"
mode="widthFix"
/>
</view>
</view>
</view>
<!-- 语音输入 -->
<view
v-if="inputModel === 'sound'"
class="sound-input-wrap"
>
<view class="toggle-btn">
<image
:src="webUrl + '/aiChat/icon-06.png'"
class="input-icon"
mode="widthFix"
@click="toggleInputModel"
/>
</view>
<view
class="sound-wrap"
@touchstart="startRecord"
@touchend="stopRecord"
>
<view v-if="startTaskFlag" class="music-wrap">
<view class="item one" />
<view class="item two" />
<view class="item three" />
<view class="item four" />
<view class="item five" />
<view class="item six" />
<view class="item seven" />
</view>
<image
:src="webUrl + '/aiChat/microphone-big.png'"
class="icon"
mode="widthFix"
/>
<view v-if="startTaskFlag" class="music-wrap music-wrap2">
<view class="item one" />
<view class="item two" />
<view class="item three" />
<view class="item four" />
<view class="item five" />
<view class="item six" />
<view class="item seven" />
</view>
</view>
</view>
</view>
</template>
<script>
import {
makeFileTransTask,
getFileTransResult
} from '@/api/voiceToText/index'
import { VUE_APP_API_URL } from '@/config'
import cookie from '@/utils/store/cookie'
export default {
name: 'BottomSend',
props: {
loading: {
type: Boolean,
default: false
},
keyboardHeight: {
type: Number,
default: 0
}
},
data() {
return {
token: cookie.get('login_status'),
userInfo: cookie.get('userInfo'),
webUrl: this.$VUE_APP_RESOURCES_URL,
// 输入模式:input-键盘,sound-语音
inputModel: 'input',
/**
* 端午节送礼攻略
* 丽江逛吃攻略
* 云南非遗有哪些?
* 怎么申请地理标志保护产品?
* 想找个像《去有风的地方》那样的治愈县城
* 云南有哪些小众县城适合旅居?
*/
prompt: '',
recordManager: null,
// 录音权限是否开通
recordPermission: false,
taskId: '',
taskTimer: null,
startTaskFlag: false,
// 输入框是否聚焦
inputOnFocus: false
}
},
beforeDestroy() {
this.clearIntervalFn()
},
created() {
uni.getSetting({
success: res => {
if (res.authSetting['scope.record']) {
this.recordPermission = true
}
}
})
},
methods: {
promptInputFocusHandle() {
this.$emit('focus', 1)
setTimeout(() => {
this.inputOnFocus = true
}, 100)
},
promptInputBlurHandle() {
this.$emit('focus', 0)
this.inputOnFocus = false
},
toggleInputModel() {
if (!this.token) {
uni.reLaunch({ url: '/pages/auth/login' })
return
}
if (this.loading) return
if (this.inputModel === 'input') {
uni.getSetting({
success: res => {
if (!res.authSetting['scope.record']) {
uni.authorize({
scope: 'scope.record',
success: () => {
console.log('获取录音权限成功')
this.recordPermission = true
this.inputModel = 'sound'
},
fail: () => {
console.log('获取录音权限失败')
this.recordPermission = false
uni.showModal({
title: '提示',
content: '需要获取麦克风权限',
confirmText: '前往设置',
confirmColor: '#3D4CF1',
success(res2) {
if (res2.confirm) {
wx.openSetting()
}
}
})
}
})
} else {
this.recordPermission = true
this.inputModel = 'sound'
}
}
})
return
}
if (this.inputModel === 'sound') {
this.clearIntervalFn()
this.inputModel = 'input'
return
}
},
startRecord() {
if (this.loading) {
this.$toast('正在检索')
return
}
// 正在识别,不触发相关动作
if (this.startTaskFlag || this.taskTimer) {
return
}
this.recordManager = uni.getRecorderManager()
console.log('启动录音')
this.startTaskFlag = true
this.recordManager.start({
duration: 60 * 1000,
frameSize: 1,
sampleRate: 16000,
format: 'wav'
})
},
stopRecord() {
const _this = this
// 正在识别,不触发相关动作
if (this.taskTimer) {
return
}
if (_this.recordManager) {
_this.recordManager.stop()
console.log('停止录音')
_this.startTaskFlag = false
_this.recordManager.onStop((res) => {
console.log('录音结束------------')
console.log(res)
const { tempFilePath, fileSize, duration } = res
if (tempFilePath && fileSize && duration) {
_this.taskId = ''
_this.clearIntervalFn()
uni.showLoading({ title: '识别中...' })
uni.uploadFile({
url: `${VUE_APP_API_URL}/api/upload`,
filePath: tempFilePath,
header: {
Authorization: 'Bearer ' + (_this.token || '')
},
name: 'file',
success: uploadRes => {
console.log(JSON.parse(uploadRes.data))
_this.renderTransTask(uploadRes)
},
fail: err => {
console.log(err)
uni.hideLoading()
_this.$toast('没有听清您说了什么,请再说一遍')
}
})
} else {
_this.$toast('没有听清您说了什么,请再说一遍')
}
})
}
},
renderTransTask(uploadRes) {
const _this = this
const file = JSON.parse(uploadRes.data).link || ''
if (!file) return
makeFileTransTask({
file
}).then(taskRes => {
_this.taskId = taskRes.data
_this.getTransResultReq()
}).catch(() => {
uni.hideLoading()
_this.$toast('没有听清您说了什么,请再说一遍')
})
},
getTransResultReq() {
const _this = this
_this.taskTimer = setInterval(() => {
getFileTransResult({
taskId: _this.taskId
}).then(res => {
const { success, data = [] } = res
if (success && data) {
uni.hideLoading()
_this.clearIntervalFn()
if (data === '__NULL__') {
_this.$toast('没有听清您说了什么,请再说一遍')
} else {
if (data.length > 0) {
const prompt = data[0].Text
if (prompt) {
_this.$emit('send', { prompt: prompt.replace('。', '') })
}
}
}
}
}).catch(() => {
uni.hideLoading()
_this.$toast('没有听清您说了什么,请再说一遍')
})
}, 1000)
},
clearIntervalFn() {
this.taskTimer && clearInterval(this.taskTimer)
this.taskTimer = null
setTimeout(() => {
this.startTaskFlag = false
}, 300)
},
sendHandle() {
if (this.loading) return
if (!this.prompt) {
this.$toast('请输入您想问的内容')
return
}
this.$emit('send', { prompt: this.prompt })
this.prompt = ''
this.inputOnFocus = false
},
historyViewHandle() {
this.$emit('history')
}
}
}
</script>
+268
View File
@@ -0,0 +1,268 @@
<template>
<view
:class="{
'show': showLayer
}"
class="history-wrap"
>
<view class="layer" @click="closeLayer" />
<view
:style="{
'padding-top': statusBarHeight + 'px'
}"
class="history-container"
>
<view class="history-type">
<view class="title">
<view class="txt">今日</view>
<image
v-if="todayList.length > 0"
:src="webUrl + '/aiChat/delete.png'"
class="icon"
mode="widthFix"
@click="deleteRecords(1)"
/>
</view>
<view v-if="todayList.length > 0" class="list-cont">
<view
v-for="(item, index) in todayList"
:key="index"
class="item"
@click="historyItemClick(item)"
>
<view class="item-txt one-t">
{{ item.title }}
</view>
</view>
</view>
<view v-else class="no-data">
<image
:src="webUrl + '/orderIcon/nodata1.png'"
class="img"
mode="widthFix"
/>
</view>
</view>
<view class="history-type">
<view class="title">
<view class="txt">30天内</view>
<image
v-if="list.length > 0"
:src="webUrl + '/aiChat/delete.png'"
class="icon"
mode="widthFix"
@click="deleteRecords(2)"
/>
</view>
<view v-if="list.length > 0" class="list-cont">
<view
v-for="(item, index) in list"
:key="index"
class="item"
@click="historyItemClick(item)"
>
<view class="item-txt one-t">
{{ item.title }}
</view>
</view>
</view>
<view v-else class="no-data">
<image
:src="webUrl + '/orderIcon/nodata1.png'"
class="img"
mode="widthFix"
/>
</view>
</view>
<view class="history-type">
<view class="title">
<view class="txt">超过30天</view>
<image
v-if="moreList.length > 0"
:src="webUrl + '/aiChat/delete.png'"
class="icon"
mode="widthFix"
@click="deleteRecords(3)"
/>
</view>
<view v-if="moreList.length > 0" class="list-cont">
<view
v-for="(item, index) in moreList"
:key="index"
class="item"
@click="historyItemClick(item)"
>
<view class="item-txt one-t">
{{ item.title }}
</view>
</view>
</view>
<view v-else class="no-data">
<image
:src="webUrl + '/orderIcon/nodata1.png'"
class="img"
mode="widthFix"
/>
</view>
</view>
</view>
</view>
</template>
<script>
import {
getChatList,
deleteChatListByType
} from '@/api/chat/index'
export default {
name: 'AiHistoryList',
props: {
statusBarHeight: {
type: Number,
default: 0
},
// 来源模块:''-首页,'history'-历史记录
formModule: {
type: String,
default: ''
}
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
showLayer: false,
todayList: [],
list: [],
moreList: []
}
},
methods: {
showView() {
this.showLayer = true
this.getChatListReq()
},
getChatListReq() {
getChatList().then(res => {
const { success, data } = res
if (success) {
this.todayList = data['今天'] || []
this.list = data['30天内'] || []
this.moreList = data['超过30天'] || []
}
})
},
deleteRecords(type) {
deleteChatListByType(type).then(res => {
const { success } = res
if (success) {
this.getChatListReq()
}
})
},
historyItemClick(item) {
const paramsStr = `?chatNumber=${item.chatNumber}&title=${item.title}&click=1`
if (!this.formModule) {
uni.navigateTo({
url: '/aiChat/views/history' + paramsStr
})
} else {
uni.redirectTo({
url: '/aiChat/views/history' + paramsStr
})
}
this.closeLayer()
},
closeLayer() {
this.showLayer = false
}
}
}
</script>
<style scoped lang="less">
.history-wrap {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1001;
transform: translateX(-100%);
opacity: 0;
transition: all 0.3s;
.layer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
background-color: rgba(0, 0, 0, 0.5);
}
.history-container {
position: absolute;
left: 0;
top: 0;
bottom: 0;
z-index: 5;
width: 75%;
padding: 40rpx;
box-sizing: border-box;
border-top-right-radius: 60rpx;
border-bottom-right-radius: 60rpx;
overflow-y: auto;
background-color: #fff;
.history-type + .history-type {
padding: 40rpx 0 0 0;
}
.history-type {
.title {
display: flex;
align-items: center;
justify-content: space-between;
.txt {
font-size: 34rpx;
line-height: 50rpx;
}
.icon {
display: block;
width: 40rpx;
height: 40rpx;
}
}
.list-cont {
padding: 24rpx 0 0 0;
.item + .item {
margin: 12rpx 0 0 0;
}
.item {
.item-txt {
display: inline-block;
max-width: 100%;
height: 60rpx;
padding: 0 24rpx;
box-sizing: border-box;
border-radius: 30rpx;
color: #333;
font-size: 28rpx;
line-height: 60rpx;
background-color: #F1F2FF;
}
}
}
.no-data {
.img {
display: block;
width: 300rpx;
height: 300rpx;
margin: 40rpx auto 0 auto;
}
}
}
}
&.show {
opacity: 1;
transform: translateX(0);
}
}
</style>
+404
View File
@@ -0,0 +1,404 @@
import {
getSseConfigV1,
getCompletionsV2,
deleteChatItemByConversationId,
getAnalyzeKeywordsV1,
getAnalyzeKeywordsChangeV1
} from '@/api/chat/index'
import { VUE_APP_API_URL } from '@/config'
import settings from '@/config/baseSetting.js'
import { formatAiMsgContent } from '../utils/aiChat'
import cookie from '@/utils/store/cookie'
import { handleLoginFailure } from '@/utils'
export const chatMixins = {
data() {
return {
token: cookie.get('login_status'),
userInfo: cookie.get('userInfo'),
webUrl: this.$VUE_APP_RESOURCES_URL,
scrollData: {},
scrollTop: 0,
isScrollToBottom: false,
// 状态栏高度
statusBarHeight: 20,
fileHttpStr: Object.freeze(VUE_APP_API_URL + settings.sysPrefix),
keyboardHeight: 0,
optionsFrom: '',
onFocus: false,
loading: false,
chatNumber: '',
infoResData: {},
chatMessageList: [
/*
{
type: -2,
isError: false,
showCursor: false,
conversationId: '',
prompt: '',
nodes: '-------------监听 WebSocket 接受到服务器的消息事件',
content: '-------------监听 WebSocket 接受到服务器的消息事件',
listQuestion: [
'监听 WebSocket 接受到服务器的消息事件',
'监听 WebSocket 接受到服务器的消息事件',
'监听 WebSocket 接受到服务器的消息事件'
]
}
*/
],
errorMsg: Object.freeze('您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!')
}
},
computed: {
chatMessageListLength() {
return this.chatMessageList.length
}
},
onPageScroll(e) {
this.scrollData = e
const scrollTop = e.scrollTop
this.scrollTop = scrollTop
const query = wx.createSelectorQuery().in(this)
query.select('#fixTbabarBody').boundingClientRect(function(rect) {
const contentHeight = rect.height
const windowInfo = wx.getWindowInfo()
const windowHeight = windowInfo.windowHeight
if (scrollTop + windowHeight + 30 >= contentHeight) {
this.isScrollToBottom = true
} else {
this.isScrollToBottom = false
}
}.bind(this)).exec()
},
onUnload() {
this.closeWsFn()
// console.log('在页面卸载时取消监听')
// wx.offKeyboardHeightChange()
},
created() {
const _this = this
uni.getSystemInfo({
success: (e) => {
let statusBar = 0
// #ifdef MP-WEIXIN
statusBar = e.statusBarHeight
const custom = uni.getMenuButtonBoundingClientRect()
_this.rightDistance = e.windowWidth - custom.left + 10
// #endif
// 状态栏高度
_this.statusBarHeight = statusBar
}
})
_this.createdCallbak()
},
methods: {
createdCallbak() {
console.log('页面初始话回调')
},
inputFocusHandle(value) {
this.onFocus = value === 1
this.scrollToBottomHandle()
},
historyViewHandle() {
console.log(this.$refs.historyView)
this.$refs.historyView.showView()
},
copyContentHandle(data) {
uni.setClipboardData({
data,
success: () => {
uni.showToast({
title: '已复制'
})
}
})
},
copyMoreInfoHandle(item) {
uni.setClipboardData({
data: JSON.stringify(item.showMoreInfo),
success: () => {
uni.showToast({
title: '已复制'
})
}
})
},
shareHandle() {
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline'],
success: (res) => {
console.log(res)
},
fail: err => {
console.log(err)
}
})
},
scrollToBottomHandle() {
uni.pageScrollTo({
duration: 100,
selector: '#bottom_postion'
})
this.isScrollToBottom = true
},
// 重新生成
regenerateHandle(item) {
deleteChatItemByConversationId(item.conversationId).then(res => {
const { success } = res
if (success) {
this.chatMessageList.splice(this.chatMessageListLength - 1, 1)
this.streamReq({
prompt: item.prompt,
init: 1
})
}
})
},
// 建议提问
suggestionItemClickHandle(question) {
this.streamReq({
prompt: question,
init: 0
})
},
// 大家都在问
topicItemClickHandle(question) {
this.streamReq({
prompt: question,
init: 0
})
},
streamReq(params) {
const _this = this
// 需要校验登录状态
if (!_this.token) {
handleLoginFailure()
return
}
const prompt = params.prompt
if (params.init !== 1) {
_this.chatMessageList.push({
prompt,
type: -1
})
}
_this.$nextTick(() => {
_this.scrollToBottomHandle()
})
_this.chatMessageList.push({
content: '',
nodes: '',
isError: false,
showCursor: false,
conversationId: '',
prompt,
listQuestion: [],
type: -2,
showMoreInfo: {}
})
_this.loading = true
_this.showCursor = false
getSseConfigV1({
'chatNumber': _this.chatNumber,
prompt
}).then(resConfig => {
const conversationId = resConfig.data.conversationId
_this.chatNumber = resConfig.data.chatNumber || ''
_this.chatMessageList[_this.chatMessageListLength - 1].showCursor = true
_this.chatMessageList[_this.chatMessageListLength - 1].conversationId = conversationId
if (conversationId) {
_this.initWebSocket(conversationId, () => {
getCompletionsV2({
conversationId,
ws: true,
isNoNeedPublicErrorNotification: 1
}).then(sseRes => {
console.log(sseRes)
// _this.closeWsFn()
}).catch(err => {
console.log(err)
_this.chatErrorSetContent()
})
})
getAnalyzeKeywordsV1({
'chatNumber': _this.chatNumber,
conversationId,
prompt
}).then(keywordRes => {
if (keywordRes.success) {
const keywordResData = keywordRes.data
const show = (keywordResData.searchArtworks ||
keywordResData.searchDiscount ||
keywordResData.searchGoods ||
keywordResData.searchLandmark ||
keywordResData.searchTowns ||
keywordResData.searchTravelGuide
) && (keywordResData.resultItems && keywordResData.resultItems.length > 0)
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo = keywordResData
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo.show = show
// 展示类型
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo.showType = ''
if (show && keywordResData.resultItems) {
keywordResData.resultItems.map(resItem => {
_this.chatMessageList[_this.chatMessageListLength - 1].showMoreInfo.showType = resItem.type
})
}
console.log(_this.chatMessageList[_this.chatMessageListLength - 1])
}
})
} else {
_this.chatErrorSetContent()
}
}).catch(err => {
console.log(err)
_this.chatErrorSetContent()
})
},
analyzeKeywordsChangeHandle(conversationId, showMoreInfo) {
getAnalyzeKeywordsChangeV1({
conversationId,
...showMoreInfo
}).then(res => {
const { success, data } = res
if (success) {
let resultItems = []
let idx = -1
this.chatMessageList.map((item, index) => {
if (item.conversationId === conversationId) {
resultItems = data.resultItems || []
idx = index
}
})
if (idx > -1) {
this.$set(this.chatMessageList[idx].showMoreInfo, 'resultItems', resultItems)
this.$forceUpdate()
}
}
})
},
productItemClickHandle(item) {
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.id
}
})
},
hotelItemClickHandle(item) {
this.$yrouter.push({
path: '/pagesInn/inn/innHome',
query: {
id: item.id
}
})
},
ichItemClickHandle(item) {
this.$yrouter.push({
path: '/pkg_product/views/heritage/details',
query: {
id: item.id
}
})
},
qianxianItemClickHandle(item) {
this.$yrouter.push({
path: '/pkg_product/views/famousQianxianShop',
query: {
id: item.id
}
})
},
chatErrorSetContent() {
this.chatMessageList[this.chatMessageListLength - 1].isError = true
this.chatMessageList[this.chatMessageListLength - 1].content = this.errorMsg
this.chatMessageList[this.chatMessageListLength - 1].nodes = this.errorMsg
this.closeWsFn()
},
closeWsFn() {
this.loading = false
if (this.chatMessageListLength) {
this.chatMessageList[this.chatMessageListLength - 1].showCursor = false
}
uni.closeSocket({
success: () => {
console.log('-----关闭连接')
}
})
this.$nextTick(() => {
this.scrollToBottomHandle()
})
},
initWebSocket(conversationId, cb) {
const _this = this
console.log('------------------创建连接')
uni.connectSocket({
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.unionId}-${conversationId}`,
header: {
'content-type': 'application/json'
},
timeout: 10 * 1000,
success: () => {
console.log('------------WebSocket初始化成功')
},
fail: (err) => {
uni.showModal({
showCancel: false,
content: err
})
}
})
uni.onSocketMessage(res => {
_this.websocketOnmessage(res)
})
uni.onSocketOpen(() => {
cb && cb()
_this.websocketOnopen()
})
uni.onSocketError(err => {
_this.websocketOnerror(err)
})
},
websocketOnmessage(res) {
console.log('-------------监听 WebSocket 接受到服务器的消息事件')
const resData = JSON.parse(res.data)
if (resData) {
const message = resData.message
if (message && this.chatMessageListLength > 1) {
const mesContent = message.content
this.chatMessageList[this.chatMessageListLength - 1].nodes = formatAiMsgContent(mesContent)
this.chatMessageList[this.chatMessageListLength - 1].content = mesContent
this.chatMessageList[this.chatMessageListLength - 1].listQuestion = message.listQuestion || []
this.$forceUpdate()
this.$nextTick(() => {
this.scrollToBottomHandle()
if (message.finish) {
this.closeWsFn()
}
})
}
}
},
websocketOnopen() {
console.log('------------------监听 WebSocket 连接打开事件')
// this.websocketSend(JSON.stringify({ msg: '1' }))
},
websocketOnerror(e) {
console.log('-----------------监听 WebSocket 错误事件')
console.log(e)
},
websocketSend(msg) {
// 数据发送
try {
uni.sendSocketMessage({
data: msg,
success: () => {
console.log('-----------发送消息成功了')
}
})
} catch (err) {
console.log('send failed (' + err.code + ')')
}
}
}
}
+90
View File
@@ -0,0 +1,90 @@
// 引入markdown-it库
import MarkdownIt from './/markdown-it.min.js'
// hljs是由 Highlight.js 经兼容性修改后的文件,请勿直接升级。否则会造成uni-app-vue3-Android下有兼容问题
import hljs from './highlight/highlight-uni.min.js'
// 初始化 MarkdownIt库
const markdownIt = MarkdownIt({
// 在源码中启用 HTML 标签
html: true,
// 如果结果以 <pre ... 开头,内部包装器则会跳过。
highlight: function(str, lang) {
// if (lang && hljs.getLanguage(lang)) {
// console.error('lang', lang)
// try {
// return '<pre class="hljs" style="padding: 5px 8px;margin: 5px 0;overflow: auto;display: block;"><code>' +
// hljs.highlight('lang', str, true).value +
// '</code></pre>';
// } catch (__) {}
// }
// 经过highlight.js处理后的html
let preCode = ''
try {
preCode = hljs.highlightAuto(str).value
} catch (err) {
preCode = markdownIt.utils.escapeHtml(str)
}
// 以换行进行分割
const lines = preCode.split(/\n/).slice(0, -1)
// 添加自定义行号
let html = lines.map((item, index) => {
// 去掉空行
if (item === '') {
return ''
}
return '<li><span class="line-num" data-line="' + (index + 1) + '"></span>' + item + '</li>'
}).join('')
html = '<ol style="padding: 0px 30px;">' + html + '</ol>'
let htmlCode = `<div style="background:#0d1117;margin-top: 5px;color: #888;padding:5px 0;border-radius: 5px;">`
htmlCode += `<pre class="hljs" style="padding:0 8px;margin-bottom:5px;overflow: auto;display: block;border-radius: 5px;"><code>${html}</code></pre>`
htmlCode += '</div>'
return htmlCode
}
})
export function formatAiMsgContent(val) {
if (!val) {
return ''
}
let htmlString = ''
// 修改转换结果的htmlString值 用于正确给界面增加鼠标闪烁的效果
// 判断markdown中代码块标识符的数量是否为偶数
if (val.split('```').length % 2) {
let msgContent = val
if (msgContent[msgContent.length - 1] !== '\n') {
msgContent += '\n'
}
msgContent += ' <span class="cursor">|</span>'
htmlString = markdownIt.render(msgContent)
} else {
htmlString = markdownIt.render(val)
htmlString = markdownIt.render(val) + ' \n <span class="cursor">|</span>'
}
// console.log(htmlString)
return htmlString
}
/**
* 简单实现防抖方法
*
* 防抖(debounce)函数在第一次触发给定的函数时,不立即执行函数,而是给出一个期限值(delay),比如100ms。
* 如果100ms内再次执行函数,就重新开始计时,直到计时结束后再真正执行函数。
* 这样做的好处是如果短时间内大量触发同一事件,只会执行一次函数。
*
* @param fn 要防抖的函数
* @param delay 防抖的毫秒数
* @returns {Function}
*/
export function simpleDebounce(fn, delay = 100) {
let timer = null
return function() {
const args = arguments
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(null, args)
}, delay)
}
}
+10
View File
@@ -0,0 +1,10 @@
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: GitHub Dark
Description: Dark theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-dark
Current colors taken from GitHub's CSS
*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+473
View File
@@ -0,0 +1,473 @@
<template>
<view
:class="scrollTop > 0 ? 'page-scroll' : ''"
class="fix-tabbar-page"
>
<hx-navbar
:back="true"
:fixed="true"
:statusBar="true"
:pageScroll.sync="scrollData"
:title="pageTitle"
color="#333"
transparent="auto"
barPlaceholder="hidden"
/>
<view
id="fixTbabarBody"
:style="{
'padding-top': (44 + statusBarHeight) + 'px'
}"
class="fix-tabbar-body"
>
<view class="chat-wrap">
<view v-if="chatMessageListLength > 0" class="chat-list-wrap">
<view
v-for="(item, index) in chatMessageList"
:key="index"
class="chat-message-item"
>
<view v-if="item.type === -1" class="chat-message-body">
<view class="item-right">
<view class="txt">
{{ item.prompt }}
</view>
</view>
</view>
<view v-if="item.type === -2" class="chat-message-body">
<view class="avatar">
<image
:src="webUrl + '/aiChat/avatar.png'"
class="chat-avatar"
mode="widthFix"
/>
</view>
<view class="item-left">
<view class="txt">
<view
ref="rich-text-box"
:class="{
'show-cursor': item.showCursor
}"
class="rich-text-box"
>
<rich-text
v-if="item.nodes && item.nodes.length"
:nodes="item.nodes"
space="nbsp"
/>
<view v-if="!(item.nodes && item.nodes.length) && loading" class="loader-wrap">
<div class="loader" />
</view>
</view>
<view
v-if="!item.showCursor && item.nodes && item.nodes.length && !item.isError"
class="bottom-btns"
>
<!-- <button
open-type="share"
plain="true"
class="item"
@click="shareHandle"
>
<image
:src="webUrl + '/icon-25.png'"
class="icon"
mode="widthFix"
/>
分享
</button> -->
<view class="item" @click="copyContentHandle(item.content)">
<image
:src="webUrl + '/aiChat/icon-02.png'"
class="icon"
mode="widthFix"
/>
复制
</view>
<view
v-if="index === (chatMessageListLength - 1)"
class="item"
@click="regenerateHandle(item)"
>
<image
:src="webUrl + '/aiChat/icon-04.png'"
class="icon"
mode="widthFix"
/>
重新生成
</view>
</view>
</view>
</view>
<!-- 换一换 -->
<view
v-if="item.showMoreInfo.show"
class="change-list-wrap"
>
<view v-if="item.showMoreInfo.showType === '特产商品'" class="list-wrap">
<view
v-for="(productItem, productIndex) in item.showMoreInfo.resultItems"
:key="productIndex"
class="product-item"
@click="productItemClickHandle(productItem)"
>
<image
:src="productItem.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ productItem.name }}
</view>
<view class="price-wrap">
<view class="price">
<text class="txt"></text>{{ productItem.price }}
</view>
<view class="btn">立即查看</view>
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '店铺'" class="list-wrap">
<view
v-for="(hotel, hotelIndex) in item.showMoreInfo.resultItems"
:key="hotelIndex"
class="product-item"
@click="hotelItemClickHandle(hotel)"
>
<view class="hotel-type">
手工体验
</view>
<image
:src="hotel.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ hotel.name }}
</view>
<view class="desc-wrap one-t">
{{ hotel.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '非遗文化'" class="list-wrap">
<view
v-for="(ich, ichIndex) in item.showMoreInfo.resultItems"
:key="ichIndex"
class="product-item"
@click="ichItemClickHandle(ich)"
>
<image
:src="ich.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ ich.name }}
</view>
<view class="desc-wrap one-t">
{{ ich.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '千县名品'" class="list-wrap">
<view
v-for="(qianxian, qianxianIndex) in item.showMoreInfo.resultItems"
:key="qianxianIndex"
class="product-item"
@click="qianxianItemClickHandle(qianxian)"
>
<image
:src="qianxian.img"
class="img"
/>
<view class="product-info">
<view class="name name2 one-t">
{{ qianxian.name }}
</view>
</view>
</view>
</view>
<view class="change-btn">
<image
:src="webUrl + '/aiChat/icon-change.png'"
class="icon"
mode="widthFix"
@click="analyzeKeywordsChangeHandle(item.conversationId, item.showMoreInfo)"
/>
</view>
</view>
<view
v-if="index === (chatMessageListLength - 1) && item.listQuestion.length > 0"
class="suggestion-wrap"
>
<view class="suggestion-list">
<view
v-for="(question, questionIndex) in item.listQuestion"
:key="questionIndex"
class="item"
@click="suggestionItemClickHandle(question)"
>
<view class="item-cont">
<view class="txt">
{{ question }}
</view>
<image
:src="webUrl + '/aiChat/icon-03.png'"
class="pic"
mode="widthFix"
/>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view id="bottom_postion" class="bottom-postion" />
</view>
</view>
<view
:class="{
'focus': onFocus
}"
class="page-to-bottom"
>
<view
class="new-chat"
@click="createNewHandle"
>
<image
:src="webUrl + '/aiChat/icon-05.png'"
class="btn-icon"
mode="widthFix"
/>
开启新对话
</view>
<image
v-if="chatMessageListLength > 0 && !isScrollToBottom && !loading"
:src="webUrl + '/aiChat/down.png'"
class="icon"
mode="widthFix"
@click="scrollToBottomHandle"
/>
</view>
<bottom-send
ref="bottomSend"
:loading="loading"
:keyboard-height="keyboardHeight"
@send="streamReq"
@history="historyViewHandle"
@focus="inputFocusHandle"
/>
<AiHistoryList
ref="historyView"
:status-bar-height="statusBarHeight"
form-module="history"
/>
</view>
</template>
<script>
import { chatMixins } from '../mixins/chatMixins.js'
import AiHistoryList from '../components/historyList'
import BottomSend from '../components/bottomSend.vue'
import {
historyChatMessage
} from '@/api/chat/index'
import { formatAiMsgContent } from '../utils/aiChat'
export default {
name: 'AiChatHistoryPage',
components: {
AiHistoryList,
BottomSend
},
mixins: [chatMixins],
data() {
return {
pageTitle: ''
}
},
onLoad(options) {
this.chatNumber = options.chatNumber
this.pageTitle = options.title
this.pageTitle = this.pageTitle.length > 8 ? (this.pageTitle.substring(0, 8) + '...') : this.pageTitle
this.init()
},
methods: {
init() {
this.loading = true
historyChatMessage({
chatNumber: this.chatNumber
}).then(res => {
const { success, data = [] } = res
if (success) {
this.loading = false
try {
data.map(item => {
if (item.role === 'user') {
this.chatMessageList.push({
type: -1,
prompt: item.content
})
} else {
if (item.contentType === 'text') {
this.chatMessageList.push({
...item,
nodes: formatAiMsgContent(item.content),
prompt: this.getParentPrompt(data, item.parentMessageId),
conversationId: item.messageId,
showCursor: false,
listQuestion: item.listQuestion || [],
type: -2
})
}
}
})
} catch (err) {
uni.showModal({
title: '错误提示',
content: JSON.stringify(err)
})
console.log(err)
}
}
}).catch(() => {
this.loading = false
})
},
getParentPrompt(list = '', parentMessageId) {
let prompt = ''
list.map(item => {
if (item.messageId === parentMessageId) {
prompt = item.content
}
})
return prompt
},
// 创建新会话
createNewHandle() {
uni.setStorageSync('addNewChat', '1')
uni.navigateBack()
}
}
}
</script>
<style lang="scss" scoped>
.chat-wrap {
padding: 0 0 180rpx 0;
.chat-info-wrap {
padding: 24rpx;
.chat-list-wrap2 {
padding: 0;
}
}
}
.loading-wrap {
text-align: center;
color: #666;
line-height: 120rpx;
}
.rich-text-box {
max-width: 100%;
}
.show-cursor .cursor {
display: inline-block;
color: #3D4CF1;
font-weight: bold;
animation: blinking 1s infinite;
}
@keyframes blinking {
from {
opacity: 1.0;
}
to {
opacity: 0.0;
}
}
.focus-guide-wrap {
display: flex;
align-items: center;
justify-content: space-between;
padding: 60rpx 40rpx;
.guide-left {
.avatar {
display: block;
width: 267rpx;
height: 530rpx;
}
}
.guide-right {
padding: 30rpx;
margin: 0 0 0 40rpx;
border-radius: 20rpx;
font-size: 24rpx;
background-color: #fff;
box-shadow: 0rpx 12rpx 30rpx rgba(0,0,0,0.1);
.title {
font-weight: bold;
}
.content {
padding: 30rpx 0 0 0;
color: #999;
}
}
}
.topic-wrap {
width: 100%;
.title {
display: flex;
align-items: center;
justify-content: center;
.txt {
width: 186rpx;
height: 46rpx;
margin: 0 20rpx;
border-radius: 24rpx;
text-align: center;
line-height: 46rpx;
color: #fff;
font-size: 26rpx;
background-color: #3D4CF1;
}
.icon {
display: flex;
width: 40rpx;
}
}
.list-wrap {
width: 100%;
margin: 60rpx 0 0 0;
overflow-x: auto;
.list-cont {
display: flex;
flex-wrap: wrap;
width: 150%;
.list-item {
display: flex;
align-items: center;
height: 40rpx;
padding: 0 12rpx;
margin: 0 30rpx 30rpx 0;
border-radius: 20rpx;
font-size: 24rpx;
color: #666;
background: rgba(255,255,255,0.39);
box-shadow: 0rpx 6rpx 12rpx rgba(0,0,0,0.1);
.icon {
display: block;
width: 24rpx;
height: 24rpx;
margin: 0 8rpx 0 0;
}
}
}
}
}
</style>
+577
View File
@@ -0,0 +1,577 @@
<template>
<view
:class="scrollTop > 0 ? 'page-scroll' : ''"
class="fix-tabbar-page"
>
<hx-navbar
:back="false"
:fixed="true"
:statusBar="true"
:pageScroll.sync="scrollData"
left-icon="arrowleft"
color="#333"
transparent="auto"
barPlaceholder="hidden"
title="云灵AI智能助手"
@click-left="clickBackHandle"
/>
<page-container
:show="true"
:overlay="false"
:z-index="1"
@beforeleave="pageContainerBeforeleave"
>
<view style="opacity: 0;">
遮罩层用于监听实体键返回
</view>
</page-container>
<view
id="fixTbabarBody"
:style="{
'padding-top': (44 + statusBarHeight) + 'px'
}"
class="fix-tabbar-body"
>
<block v-if="chatMessageListLength < 1">
<view class="home-focus-wrap">
<view class="focus-guide-wrap">
<view class="guide-left">
<image
:src="webUrl + '/aiChat/logo-01.gif'"
class="avatar"
mode="widthFix"
/>
</view>
<view class="guide-right">
<view class="trangle" />
<view class="title">{{ settingInfo.helloMessageTitle }}</view>
<view class="content">{{ settingInfo.helloMessageContent }}</view>
</view>
</view>
</view>
<view class="topic-wrap">
<view class="title">
<image
:src="webUrl + '/aiChat/icon-01.png'"
class="icon"
mode="widthFix"
/>
<view class="txt">#大家都在问</view>
<image
:src="webUrl + '/aiChat/icon-01.png'"
class="icon"
mode="widthFix"
/>
</view>
<view class="list-wrap">
<view
:style="{
'width': animationWidth,
'animation': animationStr
}"
class="list-cont"
>
<view
v-for="(item, index) in topicList"
:key="index"
class="list-item"
@click="topicItemClickHandle(item.title)"
>
<image
v-if="item.isHot"
:src="webUrl + '/aiChat/hot.png'"
class="icon"
mode="widthFix"
/>
{{ item.title }}
</view>
</view>
</view>
</view>
</block>
<view class="chat-wrap">
<view v-if="chatMessageListLength > 0" class="chat-list-wrap">
<view
v-for="(item, index) in chatMessageList"
:key="index"
class="chat-message-item"
>
<view v-if="item.type === -1" class="chat-message-body">
<view class="item-right">
<view class="txt">
{{ item.prompt }}
</view>
</view>
</view>
<view v-if="item.type === -2" class="chat-message-body">
<view class="avatar">
<image
:src="webUrl + '/aiChat/avatar.png'"
class="chat-avatar"
mode="widthFix"
/>
</view>
<view class="item-left">
<view class="txt">
<view
ref="rich-text-box"
:class="{
'show-cursor': item.showCursor
}"
class="rich-text-box"
>
<rich-text
v-if="item.nodes && item.nodes.length"
:nodes="item.nodes"
space="nbsp"
/>
<view v-if="!(item.nodes && item.nodes.length) && loading" class="loader-wrap">
<div class="loading2" />
</view>
</view>
<view
v-if="!item.showCursor && item.nodes && item.nodes.length && !item.isError"
class="bottom-btns"
>
<!-- <button
open-type="share"
plain="true"
class="item"
@click="shareHandle"
>
<image
:src="webUrl + '/icon-25.png'"
class="icon"
mode="widthFix"
/>
分享
</button> -->
<view class="item" @click="copyContentHandle(item.content)">
<image
:src="webUrl + '/aiChat/icon-02.png'"
class="icon"
mode="widthFix"
/>
复制
</view>
<view
v-if="index === (chatMessageListLength - 1)"
class="item"
@click="regenerateHandle(item)"
>
<image
:src="webUrl + '/aiChat/icon-04.png'"
class="icon"
mode="widthFix"
/>
重新生成
</view>
<view class="item item2" @click="copyMoreInfoHandle(item)">拷贝</view>
</view>
</view>
</view>
<!-- 换一换 -->
<view
v-if="item.showMoreInfo.show"
class="change-list-wrap"
>
<view v-if="item.showMoreInfo.showType === '特产商品'" class="list-wrap">
<view
v-for="(productItem, productIndex) in item.showMoreInfo.resultItems"
:key="productIndex"
class="product-item"
@click="productItemClickHandle(productItem)"
>
<image
:src="productItem.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ productItem.name }}
</view>
<view class="price-wrap">
<view class="price">
<text class="txt"></text>{{ productItem.price }}
</view>
<view class="btn">立即查看</view>
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '店铺'" class="list-wrap">
<view
v-for="(hotel, hotelIndex) in item.showMoreInfo.resultItems"
:key="hotelIndex"
class="product-item"
@click="hotelItemClickHandle(hotel)"
>
<view class="hotel-type">
手工体验
</view>
<image
:src="hotel.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ hotel.name }}
</view>
<view class="desc-wrap one-t">
{{ hotel.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '非遗文化'" class="list-wrap">
<view
v-for="(ich, ichIndex) in item.showMoreInfo.resultItems"
:key="ichIndex"
class="product-item"
@click="ichItemClickHandle(ich)"
>
<image
:src="ich.img"
class="img"
/>
<view class="product-info">
<view class="name one-t">
{{ ich.name }}
</view>
<view class="desc-wrap one-t">
{{ ich.description || '' }}
</view>
</view>
</view>
</view>
<view v-if="item.showMoreInfo.showType === '千县名品'" class="list-wrap">
<view
v-for="(qianxian, qianxianIndex) in item.showMoreInfo.resultItems"
:key="qianxianIndex"
class="product-item"
@click="qianxianItemClickHandle(qianxian)"
>
<image
:src="qianxian.img"
class="img"
/>
<view class="product-info">
<view class="name name2 one-t">
{{ qianxian.name }}
</view>
</view>
</view>
</view>
<view class="change-btn">
<image
:src="webUrl + '/aiChat/icon-change.png'"
class="icon"
mode="widthFix"
@click="analyzeKeywordsChangeHandle(item.conversationId, item.showMoreInfo)"
/>
</view>
</view>
<view
v-if="index === (chatMessageListLength - 1) && item.listQuestion.length > 0"
class="suggestion-wrap"
>
<view class="suggestion-list">
<view
v-for="(question, questionIndex) in item.listQuestion"
:key="questionIndex"
class="item"
@click="suggestionItemClickHandle(question)"
>
<view class="item-cont">
<view class="txt">
{{ question }}
</view>
<image
:src="webUrl + '/aiChat/icon-03.png'"
class="pic"
mode="widthFix"
/>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view id="bottom_postion" class="bottom-postion" />
</view>
</view>
<view
:class="{
'focus': onFocus
}"
class="page-to-bottom"
>
<view
v-if="chatNumber"
class="new-chat"
@click="createNewHandle"
>
<image
:src="webUrl + '/aiChat/icon-05.png'"
class="btn-icon"
mode="widthFix"
/>
开启新对话
</view>
<image
v-if="chatMessageListLength > 0 && !isScrollToBottom && !loading"
:src="webUrl + '/aiChat/down.png'"
class="icon"
mode="widthFix"
@click="scrollToBottomHandle"
/>
</view>
<bottom-send
ref="bottomSend"
:loading="loading"
:keyboard-height="keyboardHeight"
@send="streamReq"
@add="createNewHandle"
@history="historyViewHandle"
@focus="inputFocusHandle"
/>
<AiHistoryList
ref="historyView"
:status-bar-height="statusBarHeight"
/>
</view>
</template>
<script>
import { chatMixins } from '../mixins/chatMixins.js'
import {
getAiSystemInfoSetting,
getAiSystemInfoTopic
} from '@/api/public'
import AiHistoryList from '../components/historyList'
import BottomSend from '../components/bottomSend.vue'
export default {
name: 'AiChatIndexPage',
components: {
AiHistoryList,
BottomSend
},
mixins: [chatMixins],
data() {
return {
animationWidth: '150%',
animationStr: '',
settingInfo: {},
topicList: []
}
},
onShow() {
const addNewChat = uni.getStorageSync('addNewChat') === '1'
// 从历史界面点击新增对话
if (addNewChat && this.chatNumber) {
console.log(addNewChat)
uni.removeStorageSync('addNewChat')
this.createNewHandle()
}
},
onUnload() {
this.closeWsFn()
},
methods: {
createdCallbak() {
this.$nextTick(() => {
this.scrollToBottomHandle()
getAiSystemInfoSetting().then(res => {
const { success, data } = res
if (success) {
this.settingInfo = data
this.animationWidth = `${data.systemTopicDivMaxWidth * 750}rpx`
this.animationStr = `TranslateXSwiper-${data.systemTopicDivMaxWidth * 10} ${data.systemTopicDivScrollDuration}s infinite linear alternate`
}
})
getAiSystemInfoTopic().then(res => {
const { success, data } = res
if (success) {
this.topicList = data || []
}
})
})
},
// 创建新会话
createNewHandle() {
if (!this.chatNumber) return
this.closeWsFn()
this.chatNumber = ''
this.showCursor = false
this.loading = false
this.getConfigLoading = false
this.chatMessageList = []
},
clickBackHandle() {
if (!this.chatNumber) {
if (getCurrentPages().length > 1) {
uni.navigateBack()
} else {
uni.reLaunch({
url: '/pages/home/index'
})
}
} else {
this.createNewHandle()
}
},
pageContainerBeforeleave() {
if (!this.chatNumber) {
if (getCurrentPages().length > 1) {
uni.navigateBack()
} else {
uni.reLaunch({
url: '/pages/home/index'
})
}
} else {
this.createNewHandle()
}
}
}
}
</script>
<style lang="scss" scoped>
.chat-wrap {
padding: 0 0 180rpx 0;
.chat-info-wrap {
padding: 24rpx;
.chat-list-wrap2 {
padding: 0;
}
}
}
.loading-wrap {
text-align: center;
color: #666;
line-height: 120rpx;
}
.rich-text-box {
max-width: 100%;
}
.show-cursor .cursor {
display: inline-block;
color: #3D4CF1;
font-weight: bold;
animation: blinking 1s infinite;
}
@keyframes blinking {
from {
opacity: 1.0;
}
to {
opacity: 0.0;
}
}
.focus-guide-wrap {
display: flex;
align-items: center;
justify-content: space-between;
padding: 60rpx 40rpx;
.guide-left {
.avatar {
display: block;
width: 267rpx;
height: 530rpx;
}
}
.guide-right {
position: relative;
padding: 30rpx;
margin: 0 0 0 40rpx;
border-radius: 20rpx;
font-size: 28rpx;
background-color: #fff;
box-shadow: 0rpx 12rpx 30rpx rgba(0,0,0,0.1);
.trangle {
position: absolute;
bottom: 120rpx;
left: -15rpx;
width: 30rpx;
height: 30rpx;
background-color: #fff;
box-shadow: -30rpx 12rpx 30rpx rgba(0,0,0,0.1);
transform: rotate(45deg);
}
.title {
width: 110%;
font-weight: bold;
}
.content {
padding: 30rpx 0 0 0;
color: #999;
}
}
}
.topic-wrap {
width: 100%;
.title {
display: flex;
align-items: center;
justify-content: center;
.txt {
width: 186rpx;
height: 46rpx;
margin: 0 20rpx;
border-radius: 24rpx;
text-align: center;
line-height: 46rpx;
color: #fff;
font-size: 28rpx;
background-color: #3D4CF1;
}
.icon {
display: flex;
width: 40rpx;
height: 32rpx;
}
}
.list-wrap {
width: 100%;
margin: 60rpx 0 0 0;
overflow-x: hidden;
.list-cont {
display: flex;
flex-wrap: wrap;
width: 750 * 1.5rpx;
padding: 0 0 0 24rpx;
box-sizing: border-box;
// animation: translateXSwiper 10s infinite linear alternate;
.list-item {
display: flex;
align-items: center;
height: 48rpx;
padding: 0 18rpx;
margin: 0 30rpx 30rpx 0;
border-radius: 24rpx;
font-size: 28rpx;
color: #666;
background: rgba(255,255,255,0.39);
box-shadow: 0rpx 6rpx 12rpx rgba(0,0,0,0.1);
.icon {
display: block;
width: 24rpx;
height: 24rpx;
margin: 0 8rpx 0 0;
}
}
}
}
}
@keyframes translateXSwiper {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
</style>
+10
View File
@@ -151,3 +151,13 @@ export function getBargainUserList(data) {
export function getBargainUserCancel(data) {
return request.post("/bargain/user/cancel", data);
}
/**
* 新品专区
* @param {*} data
* @returns
*/
export function queryNewZone() {
return request.get("/newGoods");
}
+39
View File
@@ -0,0 +1,39 @@
import request from '@/utils/request'
export function getSseConfigV1(data) {
return request.post('/v1/chat/sse/message', data, { login: true })
}
export function getCompletions(params) {
return request.get('/v1/chat/sse/completions', params, { login: true })
}
export function getCompletionsV2(params) {
return request.get('/v1/chat/sse/completions2', params, { login: true })
}
// 通过关键字-搜索列表
export function getAnalyzeKeywordsV1(data) {
return request.post('/v1/chat/analyzeKeywords', data, { login: true })
}
// 通过关键字-搜索列表-换一换
export function getAnalyzeKeywordsChangeV1(data) {
return request.post('/v1/chat/aiSearch', data, { login: true })
}
export function deleteChatItemByConversationId(id) {
return request.delete('/v1/chat/message/' + id, {}, { login: true })
}
export function getChatList(params) {
return request.get('/v1/chat', params, { login: true })
}
export function historyChatMessage(params) {
return request.get('/v1/chat/message', params, { login: true })
}
export function deleteChatListByType(type) {
return request.delete('/v1/chat/type/' + type, {}, { login: true })
}
+27
View File
@@ -0,0 +1,27 @@
import request from "@/utils/request";
export function getFarmerShop(id) {
return request.get("/countyFamous/farmerShop/" + id)
}
export function setFarmerShopZan(data) {
return request.post("/countyFamous/farmerShop/zan", data)
}
export function getFarmerShopNews(data) {
return request.get("/countyFamous/farmerShop/news", data)
}
export function getFarmerShopQualification(data) {
return request.get("/countyFamous/farmerShop/qualification", data)
}
export function setFarmerShopCollection(data) {
return request.post("/collection/farmerShop/add", data)
}
export function removeFarmerShopCollection(data) {
return request.post("/collection/farmerShop/remove", data)
}
+66
View File
@@ -0,0 +1,66 @@
import request from "@/utils/request";
/**
* 礼品卡送礼订单确认
* @param {*} data
*/
export function getGiftCardSendOrderConfirm(data) {
return request.post("/giftCard/confirm", data);
}
/**
* 礼品卡送礼订单创建
* @param {*} data
*/
export function getGiftCardSendOrder(key, data) {
return request.post("/giftCard/create/" + key, data);
}
/**
* 礼品详情
* @param {*} data
*/
export function getGiftCardDetail(data) {
return request.get("/giftCard/info", data);
}
/**
* 领取礼品卡
* @param {*} data
*/
export function getGiftCardReceive(data) {
return request.post("/giftCard/receive", data);
}
/**
* 礼品卡赠礼须知
* @param {*} data
*/
export function getGiftCardSendNotice(data) {
return request.get("/giftCard/giftNotice", data);
}
/**
* 计算订单金额
* @param {*} data
*/
export function getGiftCardSendOrderAmount(key, data) {
return request.post("giftCard/computed/" + key, data);
}
/**
* 再送一份
* @param {*} data
*/
export function getGiftCardResend(data) {
return request.post("/giftCard/makeAgain", data);
}
/**
* 获取背景图
* @param {*} data
*/
export function getGiftCardSendBackground(data) {
return request.get("giftCard/giftCardBackgroundImage", data);
}
+29
View File
@@ -0,0 +1,29 @@
import request from '@/utils/request'
/**
* 收到的礼品卡列表
* */
export function giftCardReceiveList(param) {
return request.get('/giftCard/receiveList', param)
}
/**
* 送出的礼品卡列表
* */
export function giftCardSendList(param) {
return request.get('/giftCard/sendList', param)
}
/**
* 赠礼须知
* */
export function giftNotice(param) {
return request.get('/giftCard/giftNotice', param)
}
/**
* 退款
*/
export function refund(param) {
return request.post('/giftCard/refund', param)
}
+81
View File
@@ -0,0 +1,81 @@
import request from "@/utils/request";
/**
* 康养生活-养生圣地分类列表
* @returns
*/
export function getCategory() {
return request.get("/wellness/place/category")
}
/**
* 康养生活-养生圣地列表
* @param {*} params
* @returns
*/
export function getWellnessPlace(params) {
return request.get("/wellness/place", params)
}
/**
* 康养生活-展会列表
* @param {*} params
* @returns
*/
export function getWellnessExhibition(params) {
return request.get("/wellness/exhibition", params)
}
/**
* 康养生活-展会详情
* @param {*} id
* @returns
*/
export function getWellnessExhibitionDetails(id) {
return request.get("/wellness/exhibition/" + id)
}
/**
* 康养生活-养生榜单
* @param {*} params
* @returns
*/
export function getRank(params) {
return request.get("/wellness/place/ranking", params)
}
/**
* 康养生活-养生食材列表
* @param {*} params
* @returns
*/
export function getFoods(params) {
return request.get("/wellness/place/food", params)
}
/**
* 康养生活-配方详情
* @param {*} id
* @returns
*/
export function getFoodDetails(id) {
return request.get("/wellness/recipe/" + id)
}
/**
* 康养生活-配方列表
* @param {*} params
* @returns
*/
export function getRecipe(params) {
return request.get("/wellness/recipe", params)
}
/**
* 康养生活-展会轮播图
* @returns
*/
export function getBanner() {
return request.get("/wellness/exhibition/banner")
}
+29
View File
@@ -0,0 +1,29 @@
import request from "@/utils/request";
/**
* 省份非遗数据
* @param {*} id
* @returns
*/
export function getIch(id) {
return request.get("/ich/v2/" + id);
}
/**
* 省份非遗专题数据
* @param {*} id
* @returns
*/
export function getIchContent(id) {
return request.get("/ich/v2/content/" + id);
}
/**
* 获取省份非遗推荐数据
* @param {*} params
* @returns
*/
export function getIchRecommend(params) {
return request.get("/ich/v2/recommend", params);
}
+17
View File
@@ -0,0 +1,17 @@
import request from '@/utils/request'
export function getAction(url, params) {
return request.get(url, params)
}
export function postAction(url, data) {
return request.post(url, data)
}
export function putAction(url, data) {
return request.put(url, data)
}
export function deleteAction(url, data) {
return request.delete(url, data)
}
+38
View File
@@ -236,3 +236,41 @@ export function getHotelShareBackgroundImage(id) {
export function hotelNewsView(data) {
return request.post("/api/hotelNews/view", data, {login: true})
}
export function getFarmerShop(id) {
return request.get("/api/countyFamous/farmerShop/" + id)
}
export function getAncientTownIcon() {
return request.get("/ancientTown/icon")
}
export function getAncientTownList(params) {
return request.get("/ancientTown", params)
}
export function getAncientTownInfo(id) {
return request.get("/ancientTown/" + id)
}
export function getAncientTownActive(params) {
return request.get("/ancientTown/activity", params)
}
export function watchTownActive(data) {
return request.post("/ancientTown/activity/view", data, {login: true})
}
export function shareTown(id) {
return request.get("/ancientTown/poster/" + id, {login: true})
}
/**
* 获取用户店铺列表
*/
export function getMerchantApply() {
return request.get("/merchantApply/userHotels", {}, {login: true})
}
+4
View File
@@ -155,4 +155,8 @@ export function hadLike(data) {
export function hadView(data) {
return request.post('/landmarkGoods/news/view', data, {login: false})
}
export function getShareImg(id) {
return request.get('/landmarkGoods/poster/' + id, {}, {login: false})
}
+12 -2
View File
@@ -9,7 +9,7 @@ export function getSplashScreen() {
* @returns {*}
*/
export function getHomeData(params) {
return request.get("index", params, {
return request.get("/index", params, {
login: false
});
}
@@ -211,4 +211,14 @@ export function getXiaoZhi() {
export function pushSystemStatic(data) {
return request.post("/systemStats/push", data, { login: false })
}
}
// 获取AI系统设置
export function getAiSystemInfoSetting() {
return request.get('/ai/systemInfo', {}, { login: false })
}
// 获取AI系统预设话题列表
export function getAiSystemInfoTopic() {
return request.get('/ai/systemTopic', {}, { login: false })
}
+59
View File
@@ -94,3 +94,62 @@ export function getCountyFamousVillageDetail(id) {
export function getCountyFamousVillageNews(param) {
return request.get('/countyFamous/village/news', param, { login: true })
}
// 获取千县分享图
export function getShareImg(id) {
return request.get('/countyFamous/poster/' + id, {login: true})
}
export function getSaleList(params) {
return request.get('/countyFamous/village/category', params, {login: true})
}
// 旅居列表
export function getJiaLouList(params) {
return request.get('/countyFamous/sojourn', params, {login: true})
}
// 旅居详情
export function getJiaLouDetail(id) {
return request.get('/countyFamous/sojourn/' + id, {}, {login: true})
}
// 旅居资讯数据
export function getJiaLouNews(params) {
return request.get('/countyFamous/sojourn/news', params, {login: true})
}
// 收藏旅居
export function postJiaLouCollect(data) {
return request.post('/collection/sojourn/add', data, {login: true})
}
// 取消收藏旅居
export function postJiaLouRemoveCollect(data) {
return request.post('/collection/sojourn/remove', data, {login: true})
}
// 收藏旅居列表
export function getJiaLouCollectList(params) {
return request.get('/collection/sojourn/list', params, {login: true})
}
// 旅居点赞
export function postJiaLouZan(data) {
return request.post('/countyFamous/sojourn/zan', data, {login: true})
}
// 旅居资讯查看
export function postJiaLouNewsView(data) {
return request.post('/countyFamous/news/view', data, {login: true})
}
// 旅居资讯点赞
export function postJiaLouNewsZan(data) {
return request.post('/countyFamous/news/zan', data, {login: true})
}
// 分享旅居
export function postJiaLouShare(id) {
return request.get('/countyFamous/sojourn/poster/' + id, {login: true})
}
+6
View File
@@ -0,0 +1,6 @@
import request from '@/utils/request'
// 文玩店铺列表
export function getSearchPageConfig() {
return request.get('/searchPage', {}, { login: false })
}
+13
View File
@@ -585,4 +585,17 @@ export function getHistory(params) {
*/
export function getUserLike(params) {
return request.get('/cart/guessYouLike',params)
}
/**
* 用户功能指引状态
* @param {*} params
* @returns
*/
export function queryUserGuide(params) {
return request.get('/user/guide/status', params)
}
export function setUserGuide(params) {
return request.post('/user/guide/status', params)
}
+9
View File
@@ -0,0 +1,9 @@
import request from '@/utils/request'
export function makeFileTransTask(data) {
return request.post('/app/voiceToText/makeFileTransTask', data, { login: true })
}
export function getFileTransResult(data) {
return request.post('/app/voiceToText/getFileTransResult', data, { login: true })
}
File diff suppressed because it is too large Load Diff
+4 -5
View File
@@ -17,16 +17,15 @@
}
.search-box {
width: 686rpx;
width: 90%;
height: 60rpx;
margin: 0 auto;
padding: 0 24rpx 0 32rpx;
box-sizing: border-box;
background: #F7F7F7;
border-radius: 30rpx;
input {
width: 560rpx;
width: 540rpx;
font-size: 24rpx;
}
@@ -66,8 +65,8 @@
}
.active {
border-left: 6rpx solid #FD574B;
color: #FD574B;
border-left: 6rpx solid #C52733;
color: #C52733;
font-weight: bold;
}
}
+3 -6
View File
@@ -9,10 +9,9 @@
}
.box-share {
width: 600rpx;
.box-img {
position: relative;
width: 500rpx;
height: 632rpx;
border-radius: 40rpx;
overflow: hidden;
}
@@ -26,14 +25,12 @@
}
.main-img {
width: 500rpx;
height: 632rpx;
width: 100%;
border-radius: 40rpx;
}
.btn {
width: 500rpx;
height: 100rpx;
width: 100%;
margin-top: 20rpx;
}
}
+8 -3
View File
@@ -3,8 +3,8 @@
@dark-color: #333333;
@white-color: #fff;
@colors: #C52733, #333333, #fff, #666, #F0F0F0, #999999, #E92727, #FFC543;
@classnames: primary, dark, white, secondary-dark, grey, dark1, red, yellow;
@colors: #C52733, #333333, #fff, #666, #F0F0F0, #999999, #E92727, #FFC543, #69C573;
@classnames: primary, dark, white, secondary-dark, grey, dark1, red, yellow, success;
/*=====================================*/
each(@colors, {
@@ -169,7 +169,9 @@ each(@colors, {
display: grid;
grid-template-columns: 1fr 1fr;
}
.v12-gap-10{
grid-gap: 20rpx 20rpx;
}
.v12-text-right{
text-align: right;
@@ -192,6 +194,9 @@ each(@colors, {
.v12-full-width{
width: 100%;
}
.v12-nowrap{
white-space: nowrap
}
+3 -2
View File
@@ -87,7 +87,7 @@ export default {
components: {
uniPopup
},
props: ["callback", "items", "defaultValue"],
props: ["callback", "items", "defaultValue", 'disabled'],
data() {
return {
value: "请选择",
@@ -107,7 +107,7 @@ export default {
},
defaultValue(newValue) {
this.value = newValue;
// this.adjustDefaultValue();
this.adjustDefaultValue();
}
},
mounted() {
@@ -147,6 +147,7 @@ export default {
return idx;
},
open() {
if(this.disabled) return;
if (this.$refs.popup.showPopup) {
this.$refs.popup.close();
return;
+32 -1
View File
@@ -1,7 +1,11 @@
<template>
<view class="popup-coupons">
<view class="popup-box">
<view class="popup-title bold tc">优惠详情</view>
<view class="popup-title bold tc v12-justify-between">
<text></text>
<text>优惠详情</text>
<u-icon name="close" color="#666" size="14" @click.stop="close"></u-icon>
</view>
<SubSection
:current="current"
:can-use="canUse"
@@ -75,6 +79,9 @@
@change="selectCoupon"
v-if="index !== maxIndex"
/>
<view v-if="list.length === 1" class="no-quan v12-font-28 v12-dark1-text text-center">
暂无更多可使用优惠券快去抽奖去吧~
</view>
</view>
<view
v-if="list.length === 0"
@@ -118,6 +125,10 @@ export default {
currentPrice: {
default: 0,
type: Number
},
id: {
type: Number,
default: 0
}
},
data() {
@@ -130,6 +141,17 @@ export default {
},
}
},
watch: {
id: {
immediate: true,
handler(value) {
console.log('couponId', value);
if(value) {
this.selectCoupon(value)
}
}
}
},
computed: {
list() {
const temp = this.current === 0 ? this.twoList['usable'] : this.twoList['unusable']
@@ -170,6 +192,9 @@ export default {
this.$emit('max', this.largOne)
},
methods: {
close() {
this.$emit('close')
},
force2Decimal(value) {
return this.$force2Decimal(value);
},
@@ -179,20 +204,26 @@ export default {
selectCoupon(id) {
this.couponId = id
this.selectItem = this.list.find(e => e.id === id) || {}
// this.$emit('select', this.selectItem)
this.list.map(item => {
item.checked = id === item.id
})
},
setCoupon() {
if (this.current === 1) return
console.log(this.current, '====1=======');
uni.setStorageSync('couponId', this.couponId)
this.$emit('change', this.selectItem || {})
this.$emit('ok', this.couponId)
}
}
}
</script>
<style scoped lang="less">
.text-center{
text-align: center;
}
.popup-coupons {
background: #F0F0F0;
.popup-box {
+224
View File
@@ -0,0 +1,224 @@
<template>
<view v-if="show" class="guide-remark white" @touchmove.stop.prevent="" @click="next">
<view class="guid-wrap">
<image
v-for="(img, index) in functionGuideData.imgs"
:key="index"
:style="[img.style]"
:src="img.url"
@click.stop="handleImg(img)"
mode="aspectFit|aspectFill|widthFix"
lazy-load="true" >
</image>
<view class="box" :style="[functionGuideData.position]">
<!-- <view class="tips flex" :style="{top: functionGuideData.tipsPosition || '-110rpx'}">
{{ functionGuideData.tips }}
</view> -->
</view>
<!-- <view class="btn-wrap flex_center" :style="[functionGuideData.btnGroupPosition]">
<view class="btn flex_center" @click="jump">跳过</view>
<view class="next-btn v12-primary flex_center" @click="next">{{ functionGuideData.step==maxStep ? '知道了' : '下一步' }}</view>
</view> -->
</view>
</view>
</template>
<script>
let timer = null
let flag = false
export default {
props: {
maxStep: {
type: Number,
default: 3
},
guideData: {
type: Object,
default: ()=> {
return {
step: 1,
tips: '', // 介绍
tipsPosition: '', // 介绍 显示位置
btnGroupPosition: '', // 按钮组显示位置
position: {}
}
}
}
},
data() {
return {
show: false,
functionGuideData: {}
}
},
watch: {
guideData: {
deep: true,
immediate: false,
handler(data) {
this.functionGuideData = data
}
}
},
methods: {
handleImg(img) {
if(!img.isBtn) return
if(img.isBtn === 'next') {
this.next()
return
}
if(img.isBtn === 'jump') {
this.jump()
return
}
},
init() {
if (this.show) return
setTimeout(() => {
// const show = uni.getStorageSync('showGuide')
const show = false
if (!show) {
this.show = true
this.$parent.setFunctionGuideData({ step: 1 })
}
}, 1000)
},
jump() {
this.$parent.setFunctionGuideData({ step: 'jump' })
this.setFunctionGuideState()
// 标记状态,只有首次访问小程序时显示指引
uni.setStorageSync('showGuide', 1)
},
next() {
this.throttle(() => {
if (this.functionGuideData.step == this.maxStep) {
this.jump()
return
}
let step = this.functionGuideData.step
this.$parent.setFunctionGuideData({ step: step + 1 })
}, 800)
},
setFunctionGuideState() {
this.show = false
this.$emit('hide')
},
/* 节流 */
throttle(fn) {
if (!flag) {
flag = true
typeof fn === 'function' && fn()
timer = setTimeout(() => {
flag = false
}, 800)
}
}
}
}
</script>
<style lang="scss" scoped>
.btn-wrap{
position: absolute;
z-index: 99;
}
.guid-wrap{
position: relative;
height: inherit;
width: inherit;
}
.next-btn {
color: #fff;
padding: 2rpx 10rpx;
}
.plus {
width: 140rpx;
height: 2rpx;
position: relative;
.in-border {
border: 2rpx dashed #fff;
width: 110rpx;
height: 110rpx;
border-radius: 50%;
position: absolute;
left: 10rpx;
top: -55rpx;
}
.plus-icon {
background: #fff;
border-radius: 50%;
overflow: hidden;
width: 92rpx;
height: 92rpx;
}
}
.guide-remark {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20230828;
.box {
position: absolute;
z-index: 10;
width: 686rpx;
border-radius: 24rpx;
left: 32rpx;
box-shadow: 0 0 0 120vh rgba(0, 0, 0, .6);
transition: all 0.3s ease;
.tips {
width: 100%;
background: #bee9ff;
border-radius: 24rpx;
padding: 20rpx 50rpx;
box-sizing: border-box;
position: absolute;
left: 0;
top: -110rpx;
z-index: 2;
font-size: 28rpx;
transition: top 0.3s ease;
}
.btn-group {
width: 100%;
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 32rpx;
z-index: 2;
transition: bottom 0.3s ease;
.btn {
width: 240rpx;
height: 84rpx;
border-radius: 52rpx;
border: 2rpx solid #FFFFFF;
background: #fff;
margin: 0 30rpx;
white-space: nowrap;
}
}
}
}
.flex {
display: flex;
align-items: center;
}
.flex_center {
@extend .flex;
justify-content: center;
}
</style>
+3 -3
View File
@@ -1,10 +1,10 @@
<template>
<view class="slider-banner product-bg">
<swiper class="swiper-wrapper" @change="handleChange" v-if="imgUrls.length > 0" :indicator-dots='true' indicator-color="rgba(255, 255, 255, .3)" indicator-active-color="#ffffff">
<swiper autoplay circular interval="2000" class="swiper-wrapper" @change="handleChange" v-if="imgUrls.length > 0" :indicator-dots='true' indicator-color="rgba(255, 255, 255, .3)" indicator-active-color="#ffffff">
<block v-for="(item, imgUrlsIndex) in imgUrls" :key="imgUrlsIndex">
<swiper-item>
<image v-if="!checkIfVideo(item)" :src="item" class="slide-image" />
<video v-else class="slide-image" @play="storePlayObj" :show-fullscreen-btn="false" :src="item" :id="buildId(imgUrlsIndex)" autoplay controls></video>
<video v-else class="slide-image" @play="storePlayObj" :show-fullscreen-btn="false" :src="item" :id="buildId(imgUrlsIndex)" autoplay controls></video>
</swiper-item>
</block>
</swiper>
@@ -38,7 +38,7 @@ export default {
currentVideo:null,
ProductConSwiper: {
autoplay: {
disableOnInteraction: false,
disableOnInteraction: true,
delay: 2000
},
loop: true,
+78 -6
View File
@@ -1,12 +1,12 @@
<template>
<view>
<view class="product-window" :class="attr.cartAttr === true ? 'on' : ''">
<view class="product-window" :class="attr.cartAttr === true ? 'on' : ''" :style="{paddingBottom: paddingBottom}">
<view class="textpic acea-row row-between-wrapper">
<view class="pictrue" @click="previewImg(attrObj.productSelect.image)">
<image :src="attrObj.productSelect.image" class="image" />
</view>
<view class="text">
<view class="money font-color-lightred v12-font-">
<view v-if="!isNegotiable" class="money font-color-lightred v12-font-">
<text class="num v12-font-40">{{ attrObj.productSelect.price }}</text>
<text class="v12-ml-2 v12-font-weight-300 v12-font-22" style="color: #BBBBBB; text-decoration: line-through;"></text>
@@ -14,6 +14,7 @@
<text class="v12-white-text v12-red v12-font-22 v12-radius-40 v12-px-1 v12-font-weight-400">会员价</text>
<!-- <text class="stock">库存: {{ attrObj.productSelect.stock }}</text> -->
</view>
<view class="v12-primary-text" v-else>价格面议</view>
<view class="more-t">{{ attrObj.productSelect.store_name }}</view>
</view>
<view class="iconfont icon-guanbi" @click="closeAttr"></view>
@@ -46,7 +47,14 @@
<view class="titlev12-dark-text f12-font-32">购买数量</view>
<view class="carnum acea-row row-left">
<view style="border-radius: 40rpx 0rpx 0rpx 40rpx" class="cart-btn item reduce v12-font-36 v12-font-bold v12-white-text v12-dark1 v12-dark1-border" :class="cartNum <= 1 ? 'on' : ''" @click="CartNumDes">-</view>
<view class="item v12-font-36 v12-font-bold v12-dark-text cart-btn">{{ cartNum }}</view>
<input
type="number"
:min="1"
:max="attrObj.productSelect.stock"
@blur="inputNumer(cartNumber)"
v-model="cartNumber"
style="height: 55rpx !important; width:80rpx !important"
class="item v12-font-36 v12-font-bold v12-dark-text cart-btn" />
<view
style="border-radius:0 40rpx 40rpx 0"
class="item plus v12-font-bold v12-white-text v12-primary v12-primary-border v12-font-36 cart-btn"
@@ -59,6 +67,22 @@
>+</view>
</view>
</view>
<view class="v12-px-2 v12-mt-3" v-if="showOk">
<u-button
shape="circle"
color="#C52733"
@click="$emit('ok')"
:disabled="(attr.productSelect.stock === 0 && attr.cartAttr)"
>加入购物车</u-button>
</view>
<view class="v12-px-2 v12-mt-3" v-if="isGift">
<u-button
shape="circle"
color="#C52733"
@click="$emit('gift')"
:disabled="(attr.productSelect.stock === 0 && attr.cartAttr)"
>送给朋友</u-button>
</view>
</view>
<view class="mask" @touchmove.prevent :hidden="attr.cartAttr === false" @click="closeAttr"></view>
</view>
@@ -67,6 +91,22 @@
export default {
name: "ProductWindow",
props: {
isNegotiable: {
type: Boolean,
default: false
},
isGift: {
type: Boolean,
default: false
},
paddingBottom: {
type: String,
default: '160rpx'
},
showOk: {
type: Boolean,
default: false
},
attr: {
type: Object,
default: () => {
@@ -82,17 +122,43 @@ export default {
},
data() {
return {
cartNumber: this.cartNum,
attrObj: {
productSelect: {},
productAttr: []
}
}
},
watch: {
cartNum: {
handler(val) {
console.log(val, 'cardNum');
this.cartNumber = val || 1
},
deep: true
},
cartNumber(val) {
if (val > this.attrObj.productSelect.stock) {
val = this.attrObj.productSelect.stock
}
this.$emit('input', +val)
this.$emit("changeFun", { action: "ChangeCartNum", value: +val })
}
},
created() {
this.$set(this, 'attrObj', JSON.parse(JSON.stringify(this.attr)))
console.log(this.attrObj)
},
methods: {
inputNumer(e) {
if(e === '') {
this.cartNumber = 1
this.$forceUpdate()
}
if(+e > this.attrObj.productSelect.stock) {
this.cartNumber = this.attrObj.productSelect.stock
this.$forceUpdate()
}
},
reRender(data) {
this.$set(this, 'attrObj', JSON.parse(JSON.stringify(data)))
// console.log(this.attrObj.productAttr)
@@ -107,10 +173,15 @@ export default {
this.$emit("changeFun", { action: "changeattr", value: false })
},
CartNumDes() {
this.$emit("changeFun", { action: "ChangeCartNum", value: false })
if(this.cartNumber === 1) return
console.log(this.cartNumber, 'cartNumber');
this.cartNumber--
this.$emit("changeFun", { action: "ChangeCartNum", value: this.cartNumber })
},
CartNumAdd() {
this.$emit("changeFun", { action: "ChangeCartNum", value: 1 })
if(this.cartNumber >= this.attrObj.productSelect.stock) return
this.cartNumber++
this.$emit("changeFun", { action: "ChangeCartNum", value: this.cartNumber })
},
tapAttr(index, subIndex, subItem) {
// 缺货的点击了没效果
@@ -124,6 +195,7 @@ export default {
}
})
const value = this.getCheckedValue().sort().join(",")
this.cartNumber = 1
this.$emit("changeFun", {
action: "ChangeAttr",
value: {
+1 -1
View File
@@ -80,7 +80,7 @@ export default {
overscroll-behavior: contain;
}
.poster-pop {
width: 4.5 * 100rpx;
width: 6 * 100rpx;
height: 8 * 100rpx;
position: fixed;
left: 50%;
+60 -8
View File
@@ -11,22 +11,41 @@
</view>
<view class="acea-row row-middle">
<view class="name line1">{{ item.nickname }}</view>
<view class="time">{{ item.createTime }} </view>
</view>
</view>
<view class="v12-px-4">
<view class="v12-secondary-dark-text v12-font-24 attr-bg"> {{ item.sku }}</view>
<view class="start" :class="'star' + item.star"></view>
</view>
<!-- <view class="time">{{ item.createTime }} {{ item.sku||'' }}</view> -->
<view class="evaluate-infor v12-font-24">{{ item.comment }}</view>
<view class="imgList acea-row">
<view v-if="item.video" class="pictrue">
<view
@click="pauseOtherVideo('video' + evaluateWtapperIndex)"
v-if="activeVideo !== 'video' + evaluateWtapperIndex"
class="play-icon"
>
<u-icon name="play-right-fill" color="#fff" size="48"></u-icon>
</view>
<image
v-if="activeVideo !== 'video' + evaluateWtapperIndex"
:src="item.video + '?vframe/jpg/offset/1'"
class="image"
@click="pauseOtherVideo('video' + evaluateWtapperIndex)"
>
</image>
<video
v-else
:src="item.video"
:poster="item.video + '?vframe/jpg/offset/1'"
controls
autoplay
play-btn-position="center"
:id="'video' + evaluateWtapperIndex"
class="image"
@play="pauseOtherVideo('video' + evaluateWtapperIndex)"
/>
</view>
<view
@@ -56,17 +75,33 @@ export default {
}
},
data: function() {
return {};
return {
videoPlayers: [],
activeVideo: null,
};
},
mounted: function() {},
methods: {
dataFormat,
previewImage(imgs,index){
uni.previewImage({
current:imgs[index],
urls:imgs
})
}
previewImage(imgs,index){
uni.previewImage({
current:imgs[index],
urls:imgs
})
},
// 播放视频时暂停其他视频
pauseOtherVideo(video) {
this.activeVideo = video;
if(this.videoPlayers.includes(video)) {
this.videoPlayers.forEach((item) => {
if(item !== video) {
uni.createVideoContext(item, this).pause();
}
})
} else {
this.videoPlayers.push(video);
}
}
}
};
</script>
@@ -77,4 +112,21 @@ export default {
width: fit-content;
border-radius: 12rpx;
}
.time{
padding: 0 !important;
}
.evaluateWtapper .evaluateItem .imgList .pictrue{
position: relative;
width: 300rpx;
.play-icon {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 80rpx;
height: 80rpx;
}
}
</style>
+57
View File
@@ -0,0 +1,57 @@
<template>
<view v-if="showImg" class="ai-entrance">
<image
:src="settingInfo.mainImage"
mode="widthFix"
class="img"
@click="enterAiChat()"
/>
</view>
</template>
<script>
import {
getAiSystemInfoSetting
} from '@/api/public'
export default {
name: 'AiEntrance',
data() {
return {
showImg: false,
settingInfo: {}
}
},
created() {
this.init()
},
methods: {
init() {
getAiSystemInfoSetting().then(res => {
const { success, data } = res
if (success) {
this.settingInfo = data
this.showImg = data.showOnAppIndex === 1
}
})
},
enterAiChat() {
uni.navigateTo({
url: '/aiChat/views/index?click=1'
})
}
}
}
</script>
<style scoped lang="less">
.ai-entrance {
position: fixed;
right: 0;
top: 50%;
z-index: 5;
transform: translateY(-50%);
.img {
width: 88rpx;
}
}
</style>
+87
View File
@@ -0,0 +1,87 @@
### 使用组件
```html
<time-picker-popup ref="TimePickerPopupRef" :value="value" @confirm="confirm"></time-picker-popup>
```
### 引入组件
```javascript
import TimePickerPopup from '@/components/time-picker-popup/time-picker-popup.vue';
```
### 注册组件
```javascript
export default {
components: { TimePickerPopup },
data() {
return {
value: ['00', '00', '00', '00']
}
},
onReady() {
this.open();
},
methods: {
confirm(data) {
uni.showToast({
title: `${data[0]}:${data[1]}-${data[2]}:${data[3]}`
})
},
open() {
this.$refs.TimePickerPopupRef.open();
}
}
}
```
### 参数
```javascript
// 当前选中的值
value: {
type: Array,
default: () => (['00', '00', '00', '00'])
},
// 标题
title: {
type: String,
default: '时间'
},
// 取消按钮文字
cancelText: {
type: String,
default: '取消'
},
// 取消按钮颜色
canceColor: {
type: String,
default: '#666666'
},
// 确定按钮文字
confirmText: {
type: String,
default: '确定'
},
// 确定按钮颜色
confirmColor: {
type: String,
default: '#2bb781'
},
// 分割符
segmentation: {
type: String,
default: '-'
},
// 设置选择器中间选中框的类名 注意页面或组件的style中写了scoped时,需要在类名前写/deep/
indicatorClass: {
type: String,
default: 'picker-view__indicator'
},
// 设置选择器中间选中框的样式
indicatorStyle: {
type: String,
default: ''
},
```
@@ -0,0 +1,159 @@
<template>
<!-- 时间选择器弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="custom-picker">
<view class="custom-picker__header">
<view class="cancel" :style="{ color: canceColor }" @tap="onCancel">{{ cancelText }}</view>
<view class="title">{{ title }}</view>
<view class="confirm" :style="{ color: confirmColor }" @tap="onConfirm">{{ confirmText }}</view>
</view>
<picker-view :indicator-class="indicatorClass" :indicator-style="indicatorStyle" class="picker-view"
:value="value" @change="bindChange" @pickstart="pickstart" @pickend="pickend">
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[0]" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[1]" :key="index">{{item}}</view>
</picker-view-column>
<view class="picker-view__segmentation">{{ segmentation }}</view>
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[2]" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[3]" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
</template>
<script>
import utils, {
props,
range
} from './utils.js';
export default {
name: 'TimePickerPopup',
props: props,
data() {
return {
rangeList: utils.range,
pickerValue: [0, 0, 0, 0],
isScoll: false, // 是否正在滚动
}
},
methods: {
/**
* 开启弹窗
*/
open() {
// 判断是否传入props -> value
if (Array.isArray(this.value) && this.value.length) {
this.pickerValue = this.value.map((item, index) => this.rangeList[index].findIndex(child =>
child == this.value[index]));
} else {
this.pickerValue = [0, 0, 0, 0];
}
this.$refs.popup.open();
},
/**
* 关闭弹窗
*/
close() {
this.$refs.popup.close();
// 重置选中数据
this.pickerValue = [0, 0, 0, 0];
},
/**
* 点击确定
*/
onConfirm() {
if (!this.isScoll) {
let data = this.value || ['00', '00', '00', '00'];
if (this.pickerValue && this.pickerValue.length) {
data = this.pickerValue.map((item, index) => String(this.rangeList[index][item]));
}
this.$emit('confirm', data);
this.close();
}
},
/**
* 点击取消
*/
onCancel() {
this.close();
},
/**
* 滚动开始
*/
pickstart() {
this.isScoll = true;
},
/**
* 滚动结束
*/
pickend() {
this.isScoll = false;
},
/**
* 选择器改变
* @param {Object} e
*/
bindChange(e) {
this.pickerValue = e.detail.value;
},
}
}
</script>
<style lang="scss" scoped>
.custom-picker {
width: 100%;
height: 620rpx;
background-color: #fff;
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
&__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 40rpx;
.cancel {
color: #666;
}
.title {
font-size: 32rpx;
color: #333;
}
.confirm {
color: #2bb781;
}
}
}
.picker-view {
width: 100%;
height: 100%;
margin-top: 20rpx;
&__item {
line-height: 100rpx;
text-align: center;
}
/deep/ &__indicator {
height: 100rpx;
color: #2bb781;
}
&__segmentation {
display: flex;
align-items: center;
}
}
</style>
+69
View File
@@ -0,0 +1,69 @@
// 组件props
const props = {
// 当前选中的值
value: {
type: Array,
default: () => (['00', '00', '00', '00'])
},
// 标题
title: {
type: String,
default: '时间'
},
// 取消按钮文字
cancelText: {
type: String,
default: '取消'
},
// 取消按钮颜色
canceColor: {
type: String,
default: '#666666'
},
// 确定按钮文字
confirmText: {
type: String,
default: '确定'
},
// 确定按钮颜色
confirmColor: {
type: String,
default: '#2bb781'
},
// 分割符
segmentation: {
type: String,
default: '-'
},
// 设置选择器中间选中框的类名 注意页面或组件的style中写了scoped时,需要在类名前写/deep/
indicatorClass: {
type: String,
default: 'picker-view__indicator'
},
// 设置选择器中间选中框的样式
indicatorStyle: {
type: String,
default: ''
},
}
// 滚动数据
let range = [
[],
[],
[],
[]
];
for (let i = 0; i < 24; i++) {
range[0].push(i >= 10 ? String(i) : `0${i}`);
range[2].push(i >= 10 ? String(i) : `0${i}`);
}
for (let i = 0; i < 60; i++) {
range[1].push(i >= 10 ? String(i) : `0${i}`);
range[3].push(i >= 10 ? String(i) : `0${i}`);
}
export default {
props,
range
}
+15 -7
View File
@@ -7,11 +7,11 @@
class="sunui-uploader-file"
/>
<block v-for="(item, index) in upload_before_list" :key="index">
<view class="sunui-uploader-file" :class="[item.upload_percent < 100 ? 'sunui-uploader-file-status' : '']" :style="'width:' + upload_img_wh + 'rpx; height:' + upload_img_wh + 'rpx;'">
<view class="sunui-uploader-file" :class="[item.upload_percent < 100 ? '' : '']" :style="'width:' + upload_img_wh + 'rpx; height:' + upload_img_wh + 'rpx;'">
<image class="sunui-uploader-img" :style="'width:' + upload_img_wh + 'rpx; height:' + upload_img_wh + 'rpx;'" :src="item.path" mode="aspectFill" @tap="preview(index)" v-if="type === 'image'" />
<video :id="`myVideo_${index}`" :src="item.path" :data-index="index" @play="videoPlay" @error="videoError" controls :enable-play-gesture="true" objectFit="contain" :style="'width:' + upload_img_wh + 'rpx; height:' + upload_img_wh + 'rpx;'" v-if="type === 'video'"></video>
<view class="sunui-img-removeicon right" @tap.stop="remove(index)" v-show="upimg_move">x</view>
<view class="sunui-loader-filecontent" v-if="item.upload_percent < 100">{{item.upload_percent}}%</view>
<!-- <view class="sunui-loader-filecontent" v-if="item.upload_percent < 100">{{item.upload_percent}}%</view> -->
</view>
</block>
<view v-show="upload_before_list.length < upload_count" hover-class="sunui-uploader-hover" class="sunui-uploader-inputbox" @tap="choose" :style="'width:' + upload_img_wh + 'rpx; height:' + upload_img_wh + 'rpx;'">
@@ -139,10 +139,10 @@ export default {
}
},
videoError(e) {
uni.showModal({
content: '网络错误,请稍后重试!',
showCancel: false
});
// uni.showModal({
// content: '网络错误,请稍后重试!',
// showCancel: false
// });
},
uploadFile(paths) {
const promises = paths.map((path) => {
@@ -185,6 +185,7 @@ export default {
if (Math.ceil(res.size / 1024) < this.upload_video_max * 1024) {
await this.upload_img_size.push(Math.ceil(res.size / 1024));
await this.upload_before_list.push(res);
this.$forceUpdate()
} else {
this.upload_exceeded_list.push(1);
@@ -219,6 +220,7 @@ export default {
if (Math.ceil(res.tempFiles[i].size / 1024) < this.upload_max * 1024) {
await this.upload_img_size.push(Math.ceil(res.tempFiles[i].size / 1024));
await this.upload_before_list.push(res.tempFiles[i]);
this.$forceUpdate()
// TODO v3.1增加图片格式限制
} else {
res.tempFilePaths.splice(i, 1);
@@ -239,6 +241,7 @@ export default {
}
this.upload_cache = await res.tempFilePaths;
this.upload(this.upload_auto);
this.$forceUpdate()
},
fail: (err) => {
console.log(err);
@@ -338,7 +341,12 @@ export default {
uploadTask.onProgressUpdate(async (res) => {
// this.upload_before_list[this.upload_before_list.length-1].upload_percent = await res.progress;
for(let i in this.upload_before_list) { if(this.upload_before_list[i].upload_percent != 100) { this.upload_before_list[i].upload_percent = await res.progress; break; } };
for (let i in this.upload_before_list) {
if (this.upload_before_list[i].upload_percent != 100) {
console.log(res.progress, '-----------res.progress-----------');
this.upload_before_list[i].upload_percent = await res.progress
}
};
});
}
}
@@ -0,0 +1,320 @@
<template>
<uni-popup ref="popup" type="bottom">
<view class="tpf-time-range-section">
<view class="tpf-time-range-title-section flex flex-align-center flex-pack-justify">
<text class="tpf-time-range-title-txt tpf-time-range-cancel" @tap="closePopup('cancel')">取消</text>
<text class="tpf-time-range-title-txt tpf-time-range-title">营业时间</text>
<text class="tpf-time-range-title-txt tpf-time-range-sure" @tap="closePopup('sure')">确定</text>
</view>
<view class="tpf-time-range-main flex flex-l flex-align-center flex-pack-justify">
<view class="tpf-time-range-item flex flex-v flex-align-center">
<picker-view class="flex-1 tpf-picker-view" :value="startDefaultTimeArr" indicator-style="height: 50px;" @change="startTimeChange">
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.hours" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.startMinutes" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
<text class="tpf-time-divide"> - </text>
<view class="tpf-time-range-item flex flex-v flex-align-center">
<picker-view class="flex-1 tpf-picker-view" :value="endDefaultTimeArr" indicator-style="height: 50px;" @change="endTimeChange">
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.hours" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.endMinutes" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</uni-popup>
</template>
<script>
/**
* TimeRange 时间范围选择
* @description 对时间(时、分)区间进行选择,限制选择范围
* @property {string} startTime 定义开始时间
* @property {string} startDefaultTime 定义开始默认时间
* @property {string} endTime 定义结束时间
* @property {string} endDefaultTime 定义结束默认时间
* @event {Function()} name
*/
export default{
name:"TpfTimeRange",
props:{
// 开始时间
startTime:{
type:String,
default:"00:00",
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
},
// 开始默认时间
startDefaultTime:{
type:String,
// #ifdef MP-WEIXIN
default:"00:00",
// #endif
// #ifndef MP-WEIXIN
default(){
return this.startTime;
},
// #endif
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
},
// 结束时间
endTime:{
type:String,
default:"23:59",
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
},
// 结束默认时间
endDefaultTime:{
type:String,
// #ifdef MP-WEIXIN
default:"23:59",
// #endif
// #ifndef MP-WEIXIN
default(){
return this.endTime;
},
// #endif
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
}
},
data(){
return {
startDefaultTimeArr:[0,0],
endDefaultTimeArr:[0,0],
}
},
methods:{
startTimeChange(e){
this.startDefaultTimeArr = e.detail.value;
if(this.compareTwoTimeRange(e.detail.value,this.endDefaultTimeArr)) this.endDefaultTimeArr = e.detail.value;
},
endTimeChange(e){
this.endDefaultTimeArr = e.detail.value;
if(this.compareTwoTimeRange(this.startDefaultTimeArr,e.detail.value)) this.startDefaultTimeArr = e.detail.value;
},
open(){
this.$refs.popup.open();
},
closePopup(action=""){
if(action == "cancel"){
this.$refs.popup.close();
return false;
}
if(this.compareTwoTimeRange(this.startDefaultTimeArr , this.endDefaultTimeArr)){
uni.showToast({
title:"开始时间不能大于结束时间",
icon:'none'
});
return false;
}
let startTime = this.createTimeRange.hours[this.startDefaultTimeArr[0]]+":"+this.createTimeRange.startMinutes[this.startDefaultTimeArr[1]];
let endTime = this.createTimeRange.hours[this.endDefaultTimeArr[0]]+":"+this.createTimeRange.endMinutes[this.endDefaultTimeArr[1]];
this.$emit('timeRange',[
startTime,endTime
]);
this.$refs.popup.close();
},
compareTwoTimeRange(arr1=[],arr2=[]){
if(arr1[0]>arr2[0] || (arr1[0] == arr2[0] && arr1[1] > arr2[1])) return true;
return false;
},
},
beforeCreate(){
// 初始化小时
let hour = [],minute=[];
for(let h=0;h<=24;h++){
hour.push(h<10?'0'+h:h+'');
}
for(let m=0;m<60;m++){
minute.push(m<10?'0'+m:m+'');
}
this.timeRange = {hour,minute};
},
created() {
},
computed:{
createTimeRange(){
let {startTime,startDefaultTime,endTime,endDefaultTime} = this.timeRangeDateChange;
let startTimeArr = startTime.split(":"),endTimeArr = endTime.split(":");
let hours = this.timeRange.hour.slice(
this.timeRange.hour.findIndex(item=>item == startTimeArr[0]),
this.timeRange.hour.findIndex(item=>item == endTimeArr[0])+1,
);
let startMinutes = null;
if(startTimeArr[0] == endTimeArr[0]){
startMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}else{
if(this.startDefaultTimeArr[0] == 0){
startMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1])
);
}
else if(this.startDefaultTimeArr[0] == hours.length-1){
startMinutes = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1
);
}else{
startMinutes = this.timeRange.minute; // 完整数据
}
}
let endMinutes = null;
if(startTimeArr[0] == endTimeArr[0]){
endMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}
else{
if(this.endDefaultTimeArr[0] == 0){
endMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1])
);
}
else if(this.endDefaultTimeArr[0] == hours.length-1){
endMinutes = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1
);
}else{
endMinutes = this.timeRange.minute; // 完整数据
}
}
return {
hours,
startMinutes,
endMinutes,
}
},
// 用于监听属性的变化
timeRangeDateChange(){
let {startTime,startDefaultTime,endTime,endDefaultTime} = this;
startTime = startTime<endTime?startTime:endTime;
startDefaultTime = startDefaultTime>=startTime && startDefaultTime<=endTime?startDefaultTime:startTime;
endDefaultTime = endDefaultTime>=startTime && endDefaultTime<=endTime && endDefaultTime>=startDefaultTime?endDefaultTime:startDefaultTime;
return {
startTime,
startDefaultTime,
endTime,
endDefaultTime
}
}
},
watch:{
timeRangeDateChange:{
handler(newVal,oldVal){
let {startTime,startDefaultTime,endTime,endDefaultTime} = newVal;
let startTimeArr = startTime.split(":"),endTimeArr = endTime.split(":");
let startDefaultTimeArr = startDefaultTime.split(":"),endDefaultTimeArr = endDefaultTime.split(":");
let hours = this.timeRange.hour.slice(
this.timeRange.hour.findIndex(item=>item == startTimeArr[0]),
this.timeRange.hour.findIndex(item=>item == endTimeArr[0])+1,
);
this.$set(this.startDefaultTimeArr,0, hours.includes(startDefaultTimeArr[0])?hours.findIndex(item=>item == startDefaultTimeArr[0]):0);
this.$set(this.endDefaultTimeArr,0, hours.includes(endDefaultTimeArr[0])?hours.findIndex(item=>item == endDefaultTimeArr[0]):this.startDefaultTimeArr[0]);
let startMinute = null,endMinute = null;
if(startTimeArr[0] == endTimeArr[0]){
startMinute = endMinute = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}
else{
if(startDefaultTime.split(":")[0] == startTimeArr[0]){
startMinute = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
);
}
else if(startDefaultTime.split(":")[0] == endTimeArr[0]){
startMinute = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}else{
startMinute = this.timeRange.minute;
}
if(endDefaultTime.split(":")[0] == startTimeArr[0]){
endMinute = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
);
}else if(endDefaultTime.split(":")[0] == endTimeArr[0]){
endMinute = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}else{
endMinute = this.timeRange.minute;
}
}
this.$set(this.startDefaultTimeArr,1, startMinute.includes(startDefaultTimeArr[1])?startMinute.findIndex(item=>item == startDefaultTimeArr[1]):0);
this.$set(this.endDefaultTimeArr,1, endMinute.includes(endDefaultTimeArr[1])?endMinute.findIndex(item=>item == endDefaultTimeArr[1]):this.startDefaultTimeArr[1]);
},
deep:true, // 深度监听
immediate:true, // 初始化立即执行
}
}
}
</script>
<style lang="scss">
.flex{display:flex;}
.flex-v{flex-direction:column;}
.flex-wrap{flex-wrap:wrap;}
.flex-row-wrap{flex-flow:row wrap;}
.flex-1{flex:1;}
.flex-align-center{align-items:center;}
.flex-pack-center{justify-content:center;}
.flex-pack-justify{justify-content:space-between;}
.flex-pack-around{justify-content:space-around;}
.tpf-time-range-section{
background-color: #FFF;
}
.tpf-time-range-title-section{
padding: 20rpx;
border-bottom: 1px #f2f2f2 solid;
}
.tpf-time-range-title-txt{
font-size: 28rpx;
}
.tpf-time-range-title{
font-size:32rpx;
}
.tpf-time-range-main{
padding: 0 20rpx 20rpx;
}
.tpf-time-range-item{
height: 400rpx;
width: 300rpx;
}
.tpf-start-time{
padding: 20rpx 0;
}
.tpf-picker-view{
width:280rpx;
}
</style>
+56 -2
View File
@@ -2,9 +2,27 @@
<view class="xdd-product-item" @click="viewHandle(item)">
<view class="focus-img">
<image
v-if="!item.isFarmerShop"
:src="item[imageKey]"
class="img"
/>
<image
:src="item.farmerShopCover"
v-if="item.farmerShopCoverType === 1 && item.isFarmerShop"
class="img"
mode="heightFix|widthFix">
</image>
<image
:src="item.farmerShopCover + '?vframe/jpg/offset/1'"
mode="heightFix|widthFix"
v-if="item.farmerShopCoverType !== 1 && item.isFarmerShop"
:show-center-play-btn="false"
:show-fullscreen-btn="false"
:show-play-btn="false"
class="img"
:poster="item.farmerShopCover + '?vframe/jpg/offset/1'">
</image>
<image
v-if="item.isOldBrand"
:src="webUrl + '/home/old-mark.png'"
@@ -14,14 +32,27 @@
v-if="item.isLandmarkGoods"
:src="webUrl + '/home/mark-land.png'"
class="mark-img"
style="right: 20rpx"
/>
<image
v-if="item.isCountyFamous"
:src="webUrl + '/home/qixian-mark.png'"
class="mark-img"
/>
<image
v-if="item.isIch"
:src="webUrl + '/home/ich-mark.png'"
class="mark-img"
style="right: 20rpx; width: 70rpx"
/>
<image
v-if="item.isFarmerShop"
:src="webUrl + '/orderIcon/nm.png'"
class="mark-img-nm"
/>
</view>
<view class="info-wrap">
<view v-if="item.isFarmerShop" class="more-t v12-pt-2 v12-font-bold v12-font-28 v12-px-2" >{{ item.farmerShopContent }}</view>
<view class="info-wrap" v-if="!item.isFarmerShop">
<view class="name more-t">
{{ item[nameKey] }}
</view>
@@ -36,7 +67,7 @@
<view class="price">
<text class="price-txt price-red">{{ item[priceKey] }}</text>
</view>
<view class="btn">
<view class="btn" @click.stop="$emit('add', item)">
<image
:src="webUrl + '/home/icon-cart.png'"
class="img"
@@ -44,6 +75,14 @@
</view>
</view>
</view>
<view
v-if="item.isFarmerShop"
class="v12-justify-start v12-align-center v12-pt-2 v12-px-2 v12-pb-2">
<view class="btn v12-mr-2">
<image :src="item.farmerShopLogo" class="nm-img-logo v12-radius-100"></image>
</view>
<view class="one-t v12-font-24 v12-dark1-text" style="width:230rpx">{{ item.farmerShopName }}/{{ item.farmerShopCityName || '-' }}</view>
</view>
</view>
</template>
@@ -89,6 +128,21 @@ export default {
</script>
<style lang="less">
.nm-img-logo {
display: block;
width: 48rpx;
height: 48rpx;
}
.mark-img-nm{
position: absolute;
top: 0;
right: 0;
z-index: 3;
display: block;
width: 100%;
height: 100%;
border-radius: 0 25rpx 0 0;
}
.xdd-product-item {
border-radius: 20rpx;
background-color: #fff;
+22 -1
View File
@@ -5,7 +5,7 @@
}"
class="xdd-tabbar-wrap"
>
<view class="center-img" @click="switchTabFn('/pages/cloud/haveFun')">
<view class="center-img" id="quweiIcon" @click="switchTabFn('/pages/cloud/haveFun')">
<image
:src="webUrl + '/home/tabbar-center.png'"
class="img"
@@ -25,6 +25,7 @@
v-for="(item, index) in tabbarItem"
:key="index"
:class="currIndex === item.index ? 'curr' : ''"
:id="'icon' + index"
class="item"
@click="gotoPage(item.url, item.type, item.index)"
>
@@ -95,7 +96,27 @@ export default {
]]
}
},
mounted() {
this.getElementData('#quweiIcon')
this.getIconData('#icon1')
},
methods: {
getElementData(el) {
const query = uni.createSelectorQuery().in(this)
query.select(el).boundingClientRect().exec((res)=> {
if(res[0]) {
this.$emit('getElementData', res[0])
}
})
},
getIconData(el) {
const query = uni.createSelectorQuery().in(this)
query.select(el).boundingClientRect().exec((res)=> {
if(res[0]) {
this.$emit('getIcon', res[0])
}
})
},
/**
* 跳转至目标页面
* type: 1-tabbar页面,2-非tabbar页面
@@ -248,7 +248,7 @@
background: #EBEBEB;
display: flex;
justify-content: center;
z-index: 2;
z-index: 999;
flex-wrap: wrap;
transition:all 0.2s ease-in 0.2s;
}
+18
View File
@@ -0,0 +1,18 @@
const baseStr = 'edc_epro_prod:'
const settings = {
storage: {
systemInfo: `${baseStr}systemInfo`,
firstLaunch: `${baseStr}firstLaunch`,
token: `${baseStr}token`,
userInfo: `${baseStr}userInfo`,
webInfo: `${baseStr}webInfo`
},
/* 拦截器超时时长 */
timeout: 120 * 1000,
/* 系统接口前缀,没有统一的填空字符串 */
sysPrefix: '/',
/* 是否收集错误日志 */
collectRequestError: false
}
export default settings
+6
View File
@@ -6,11 +6,17 @@ if (NODE_ENV === 'development' || NODE_ENV === 'test') {
BASE_URL = 'https://shop.xdd618.com/api'
SERVICE_URL = 'https://service-test.xdd618.com/api'
SERVICE_WS_URL = 'wss://service-test.xdd618.com/ws'
wx.setEnableDebug({
enableDebug: false
})
}
if (NODE_ENV === 'prod') {
BASE_URL = 'https://wxapp.xdd618.com/api'
SERVICE_URL = 'https://service.xdd618.com/api'
SERVICE_WS_URL = 'wss://service.xdd618.com/ws'
wx.setEnableDebug({
enableDebug: false
})
}
export const VUE_APP_API_URL = BASE_URL
+14 -1
View File
@@ -75,13 +75,26 @@ const force2Decimal = function change2Decimal(value) {
return forceToDecimal(value, 2)
}
const toast = (title = '', position = 'center', success = function() {}) => {
uni.showToast({
title,
mask: false,
icon: 'none',
duration: 2500,
position,
success
})
}
Vue.prototype.$force2Decimal = force2Decimal
Vue.prototype.$forceToDecimal = forceToDecimal
Vue.config.productionTip = false
App.mpType = 'app'
Vue.prototype.$store = store
Vue.prototype.$dialog = dialog;
Vue.prototype.$dialog = dialog
Vue.prototype.$toast = toast
const app = new Vue(App)
+80
View File
@@ -0,0 +1,80 @@
import { queryUserGuide, setUserGuide } from '@/api/user'
export default {
data() {
return {
scrollView: '',
functionGuideData: {
step: 0,
tips: '',
tipsPosition: '',
btnGroupPosition: '',
position: {}
},
screenWidth: 0,
scrollLeft: 0,
totalWidth: 0,
scrollViewWidth: 0,
imgs: [],
_step: 0
}
},
onLoad() {
// this.setGuide('countyFamousIndex', 0)
// this.setGuide('landmarkGoodsIndex', 0)
// this.setGuide('findFunIndex', 0)
// this.setGuide('wellnessFoodIndex', 0)
// this.setGuide('ichIndex', 0)
// this.setGuide('wenwanIndex', 0)
// this.setGuide('goodsIndex', 0)
// this.setGuide('index', 0)
},
methods: {
setGuide(type, status = 1) {
const params = {
guideName: type,
guideStatus: status
}
setUserGuide(params).then(res => {
if(type === 'index') {
this.queryGuide(type)
}
})
},
queryGuide(type) {
const params = {
guideName: type
}
queryUserGuide(params).then(res => {
const { data, success } = res
if(success && data.guideStatus === 0) {
this.$refs.FunctionGuide.init()
}
if(type === 'index' && data.guideStatus === 1) {
this.isOldUser = true
}
if(type === 'index' && data.guideStatus === 0) {
this.isOldUser = false
}
})
},
setFunctionGuideData(data) {
this.functionGuideData = {
...this.functionGuideData,
...data
}
this.showFunctionGuide()
},
getElementData(el, cb) {
const query = uni.createSelectorQuery().in(this)
query.select(el).boundingClientRect().exec((res)=> {
console.log(res, 'getElementData');
if(res[0]) {
cb(res[0])
} else {
this.$refs.FunctionGuide.show = false
}
})
},
}
}
+385
View File
@@ -0,0 +1,385 @@
import {
getCartCount,
getProductCode,
getProductDetail,
postCartAdd,
getProductSkuBySelected
} from '@/api/store'
export default {
data() {
return {
isWenwan: 0,
qualifications: [],
source: '',
isOpen: false,
attrTxt: '',
attrValue: '',
id: null,
productValueArr: [],
attr: {
cartAttr: false,
cart_num: 1,
defaultSku: [],
defaultSkuIndex: [],
productAttr: [],
productSelect: {
cart_num: 1,
earnPoints: 0,
image: '',
otPrice: 0,
price: 0,
stock: 0,
store_name: '',
unique: ''
}
},
cart_num: 1
}
},
methods: {
getSkuActiveStatus(selectedSku) {
getProductSkuBySelected({ id: this.id, selectedSku }).then(res => {
const { success, data } = res
if (success) {
for (const key in data) {
if (data[key]) {
this.attr.productAttr.map(item => {
if (item.attrName === key) {
item.attrValue.map(subItem => {
data[key].map(dataItem => {
if (dataItem.sku === subItem.attr) {
subItem.canUsed = dataItem.canUsed
}
})
})
}
})
}
}
console.log(this.$refs);
this.$refs.attrWindow.reRender(this.attr)
}
})
},
productCon() {
getProductDetail(this.id).then(res => {
const { data } = res
this.storeInfo = {...data.storeInfo}
if(data.storeInfo.stock === 0) {
uni.showToast({
title: "产品库存不足,请选择其他商品",
icon: "none",
duration: 5000
})
return
}
this.isWenwan = data.isWenwan
this.qualifications = data.qualifications || []
// 给 attr 赋值,将请求回来的规格赋值给 attr
if (this.source !== 'pre' && this.source !== 'day' && this.source !== 'kill' && this.source !== 'spe') {
// this.$set(this.attr, 'productAttr', data.productAttr)
this.attr.productAttr = data.productAttr || []
this.productValueArr = []
for (const key in data.productValue) {
this.productValueArr.push({
attrItemkey: key,
...data.productValue[key]
})
}
// 初始化认为所有的规格都是可以选的
this.attr.productAttr.map(item => {
item.attrValue.map(subItem => {
subItem.canUsed = true
})
})
}
this.attr.defaultSku = data.defaultSku
this.attr.defaultSkuIndex = data.defaultSkuIndex
this.DefaultSelect()
// 是否单一规格
const onlyOne = Object.keys(data.productValue).length === 1
if(onlyOne) {
this.handleOk()
return
}
this.attr.cartAttr = !this.isOpen ? true : false
})
},
getAttrItemData(attr) {
let result = {}
this.productValueArr.map(item => {
if (item.attrItemkey === attr) {
result = item
}
})
return result
},
// 默认选中属性
DefaultSelect() {
const productAttr = this.attr.productAttr
const productAttrLength = productAttr.length
this.attr.productAttr.map((item, index) => {
item.attrValue.map((subItem, subIndex) => {
if (this.attr.defaultSkuIndex[index] === subIndex) {
subItem.check = true
} else {
subItem.check = false
}
})
})
const skuKey = (this.attr.defaultSku || []).join(',')
if (!skuKey) {
return
}
const productSelect = this.getAttrItemData(skuKey)
this.attrValue = skuKey
this.attrTxt = '已选择'
if (productSelect && productAttrLength) {
// this.$set(
// this.attr.productSelect,
// 'store_name',
// this.storeInfo.storeName
// )
// this.$set(this.attr.productSelect, 'image', productSelect.image)
// this.$set(this.attr.productSelect, 'price', productSelect.price)
// this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice)
// this.$set(this.attr.productSelect, 'stock', productSelect.stock)
// this.$set(this.attr.productSelect, 'unique', productSelect.unique)
// this.$set(this.attr.productSelect, 'earnPoints', productSelect.earnPoints)
// this.$set(this.attr.productSelect, 'cart_num', 1)
// this.$set(this, 'attrValue', value.sort().join(',')) // 作废
// this.$set(this, 'attrValue', skuKey)
// this.$set(this, 'attrTxt', '已选择')
this.attr.productSelect = {
image: productSelect.image,
price: productSelect.price,
otPrice: productSelect.otPrice,
stock: productSelect.stock,
earnPoints: productSelect.earnPoints,
unique: productSelect.unique,
store_name: this.storeInfo.storeName,
cart_num: 1
}
this.getSkuActiveStatus(skuKey)
} else if (!productSelect && productAttrLength) {
// this.$set(
// this.attr.productSelect,
// 'store_name',
// this.storeInfo.storeName
// )
// this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
// this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
// this.$set(this.attr.productSelect, 'otPrice', this.storeInfo.otPrice)
// this.$set(this.attr.productSelect, 'stock', 0)
// this.$set(this.attr.productSelect, 'earnPoints', 0)
// this.$set(this.attr.productSelect, 'unique', '')
// this.$set(this.attr.productSelect, 'cart_num', 0)
// this.$set(this, 'attrValue', '')
// this.$set(this, 'attrTxt', '请选择')
this.attr.productSelect = {
image: this.storeInfo.image,
price: this.storeInfo.price,
otPrice: this.storeInfo.otPrice,
stock: 0,
earnPoints: 0,
unique: '',
store_name: this.storeInfo.storeName,
cart_num: 1
}
} else if (!productSelect && !productAttrLength) {
// this.$set(
// this.attr.productSelect,
// 'store_name',
// this.storeInfo.storeName
// )
// this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
// this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
// this.$set(this.attr.productSelect, 'otPrice', this.storeInfo.otPrice)
// this.$set(this.attr.productSelect, 'stock', this.storeInfo.stock)
// this.$set(this.attr.productSelect, 'earnPoints', 0)
// this.$set(
// this.attr.productSelect,
// 'unique',
// this.storeInfo.unique || ''
// )
// this.$set(this.attr.productSelect, 'cart_num', 1)
this.attr.productSelect = {
image: this.storeInfo.image,
price: this.storeInfo.price,
otPrice: this.storeInfo.otPrice,
stock: this.storeInfo.stock,
earnPoints: 0,
unique: this.storeInfo.unique || '',
store_name: this.storeInfo.storeName,
cart_num: 1
}
// this.$set(this, 'attrValue', '')
// this.$set(this, 'attrTxt', '请选择')
}
},
// 点击加入购物车按钮
addToCart(item, id = 'id') {
console.log(item, 'addToCart --------- item');
this.id = item[id]
this.$nextTick(() => {
this.productCon()
})// if(this.attr.cartAttr && !this.isOpen){
// return this.isOpen = true
// }
console.log(this.$refs.attrWindow, '--222--');
},
handleOk() {
const productSelect = this.getAttrItemData(this.attrValue)
// 如果有属性,没有选择,提示用户选择
const hasNo = (this.attr.productAttr.length && productSelect === undefined && this.isOpen) || productSelect.stock === 0
if (hasNo) {
uni.showToast({
title: "产品库存不足,请选择其他商品",
icon: "none",
duration: 5000
})
return
}
const q = {
productId: this.id,
cartNum: this.attr.productSelect.cart_num,
new: 0,
uniqueId: this.attr.productSelect !== undefined ? this.attr.productSelect.unique : ''
}
postCartAdd(q).then(res => {
this.isOpen = false
this.attr.cartAttr = false
this.$set(this.attr.productSelect, 'cart_num', 1)
this.cart_num = 1
uni.showToast({
title: "添加购物车成功",
icon: "none",
duration: 2000
})
})
},
ChangeCartNum(changeValue) {
// changeValue:是否 加|减
// 获取当前变动属性
const productSelect = this.getAttrItemData(this.attrValue)
// 如果没有属性,赋值给商品默认库存
if (productSelect === undefined && !this.attr.productAttr.length) {
productSelect = this.attr.productSelect
}
// 无属性值即库存为0;不存在加减
if (productSelect === undefined) return
let stock = productSelect.stock || 0
let num = this.attr.productSelect
if (changeValue) {
if(changeValue > 1) {
num.cart_num = changeValue
} else {
num.cart_num++
}
if (num.cart_num > stock) {
if(stock < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', stock)
this.$set(this, 'cart_num', stock)
}
} else {
if (num.cart_num < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
// this.$set(this, 'cart_num', num.cart_num)
}
}
} else {
num.cart_num--
if (num.cart_num < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
this.$set(this, 'cart_num', num.cart_num)
}
}
},
// 关闭属性
changeattr(msg) {
// 修改了规格
this.attr.cartAttr = msg
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$forceUpdate()
this.isOpen = false
},
// 打开属性插件
selecAttrTap() {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.attr.cartAttr = true
this.isOpen = true
this.$forceUpdate()
},
ChangeAttr(res) {
const { index, subIndex, value } = res
// 修改了规格
const productSelect = this.getAttrItemData(value)
if (productSelect) {
this.attr.productAttr[index].attrValue.map((subItem, subIdx) => {
subItem.check= false
if (subIndex === subIdx) {
subItem.check = true
}
})
this.$set(this.attr.productSelect, 'image', productSelect.image)
this.$set(this.attr.productSelect, 'price', productSelect.price)
this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice)
this.$set(this.attr.productSelect, 'stock', productSelect.stock)
this.$set(this.attr.productSelect, 'unique', productSelect.unique)
this.$set(this.attr.productSelect, 'earnPoints', productSelect.earnPoints)
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'attrValue', value)
this.$set(this, 'attrTxt', '已选择')
this.getSkuActiveStatus(value)
} else {
this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
this.$set(this.attr.productSelect, 'otPrice', this.storeInfo.otPrice)
this.$set(this.attr.productSelect, 'stock', 0)
this.$set(this.attr.productSelect, 'unique', '')
this.$set(this.attr.productSelect, 'earnPoints', 0)
this.$set(this.attr.productSelect, 'cart_num', 0)
this.$set(this, 'attrValue', '')
this.$set(this, 'attrTxt', '请选择')
}
},
changeFun(opt) {
if (typeof opt !== 'object') opt = {}
let action = opt.action || ''
let value = opt.value === undefined ? '' : opt.value
this.cart_num = 1
this[action] && this[action](value)
},
// queryCartCount (isAnima) {
// const isLogin = this.isLogin
// if (isLogin) {
// getCartCount({
// numType: 0
// }).then(res => {
// this.CartCount = res.data.count
// //加入购物车后重置属性
// if (isAnima) {
// this.animated = true
// setTimeout(function () {
// this.animated = false
// }, 500)
// }
// })
// }
// },
}
}
+2
View File
@@ -13,6 +13,8 @@ export const pageListenMixins = {
onShow() {
this.pageViewDateTime = getCurrDateTime()
this.pageToWatchShowCount(this.pageKeyId)
this.videoContext = uni.createVideoContext('indexVideo', this);
},
onUnload() {
this.pageToHideHandle()
+17700
View File
File diff suppressed because it is too large Load Diff
+145 -145
View File
@@ -1,148 +1,148 @@
{
"name": "xdd_mp",
"version": "0.1.0",
"private": true,
"name": "xdd_mp",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "npm run dev:h5",
"build": "npm run build:h5",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
"build:mp-jd": "cross-env NODE_ENV=production UNI_PLATFORM=mp-jd vue-cli-service uni-build",
"build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-xhs": "cross-env NODE_ENV=production UNI_PLATFORM=mp-xhs vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
"dev:mp-jd": "cross-env NODE_ENV=development UNI_PLATFORM=mp-jd vue-cli-service uni-build --watch",
"dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
"dev:mp-lark": "cross-env NODE_ENV=development UNI_PLATFORM=mp-lark vue-cli-service uni-build --watch",
"dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
"dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"dev:mp-xhs": "cross-env NODE_ENV=development UNI_PLATFORM=mp-xhs vue-cli-service uni-build --watch",
"dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
"dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
"dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
"dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
"info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
"serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
"test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
"test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
"test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
"test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
"test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i"
},
"dependencies": {
"@dcloudio/uni-app": "^2.0.2-3090920231225001",
"@dcloudio/uni-app-plus": "^2.0.1-35320220729002",
"@dcloudio/uni-h5": "^2.0.1-35320220729002",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-360": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-alipay": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-baidu": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-jd": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-kuaishou": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-lark": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-qq": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-toutiao": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-vue": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-weixin": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-xhs": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-native": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-webview": "^2.0.1-35320220729002",
"@dcloudio/uni-stacktracey": "^2.0.1-35320220729002",
"@dcloudio/uni-stat": "^2.0.1-35320220729002",
"@vue/composition-api": "^1.7.2",
"@vue/shared": "^3.0.0",
"animate.css": "^3.7.2",
"async-validator": "^3.2.4",
"core-js": "^3.6.5",
"dayjs": "^1.11.2",
"flyio": "^0.6.2",
"jweixin-module": "^1.6.0",
"miniapp-color-thief": "^1.0.5",
"number-precision": "^1.5.2",
"regenerator-runtime": "^0.12.1",
"uview-ui": "2.0.36",
"vconsole": "^3.14.6",
"vue": "^2.6.11",
"vue-ydui": "^1.2.6",
"vuex": "^3.2.0",
"wechat-jssdk": "^5.0.4"
},
"devDependencies": {
"@babel/runtime": "~7.17.9",
"@dcloudio/types": "^3.0.4",
"@dcloudio/uni-automator": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-shared": "^2.0.1-35320220729002",
"@dcloudio/uni-migration": "^2.0.1-35320220729002",
"@dcloudio/uni-template-compiler": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-mp-loader": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-pages-loader": "^2.0.1-35320220729002",
"@vue/cli-plugin-babel": "~4.5.19",
"@vue/cli-service": "~4.5.19",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"less": "^4.1.0",
"less-loader": "^4.1.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0",
"sass": "^1.5.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"resolutions": {
"@babel/runtime": "~7.17.9"
},
"uni-app": {
"scripts": {
"serve": "npm run dev:h5",
"build": "npm run build:h5",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
"build:mp-jd": "cross-env NODE_ENV=production UNI_PLATFORM=mp-jd vue-cli-service uni-build",
"build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-xhs": "cross-env NODE_ENV=production UNI_PLATFORM=mp-xhs vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
"dev:mp-jd": "cross-env NODE_ENV=development UNI_PLATFORM=mp-jd vue-cli-service uni-build --watch",
"dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
"dev:mp-lark": "cross-env NODE_ENV=development UNI_PLATFORM=mp-lark vue-cli-service uni-build --watch",
"dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
"dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"dev:mp-xhs": "cross-env NODE_ENV=development UNI_PLATFORM=mp-xhs vue-cli-service uni-build --watch",
"dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
"dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
"dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
"dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
"info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
"serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
"test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
"test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
"test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
"test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
"test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i"
},
"dependencies": {
"@dcloudio/uni-app": "^2.0.2-3090920231225001",
"@dcloudio/uni-app-plus": "^2.0.1-35320220729002",
"@dcloudio/uni-h5": "^2.0.1-35320220729002",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-360": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-alipay": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-baidu": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-jd": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-kuaishou": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-lark": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-qq": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-toutiao": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-vue": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-weixin": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-xhs": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-native": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-webview": "^2.0.1-35320220729002",
"@dcloudio/uni-stacktracey": "^2.0.1-35320220729002",
"@dcloudio/uni-stat": "^2.0.1-35320220729002",
"@vue/composition-api": "^1.7.2",
"@vue/shared": "^3.0.0",
"animate.css": "^3.7.2",
"async-validator": "^3.2.4",
"core-js": "^3.6.5",
"dayjs": "^1.11.2",
"flyio": "^0.6.2",
"jweixin-module": "^1.6.0",
"miniapp-color-thief": "^1.0.5",
"number-precision": "^1.5.2",
"regenerator-runtime": "^0.12.1",
"uview-ui": "2.0.36",
"vconsole": "^3.14.6",
"vue": "^2.6.11",
"vue-ydui": "^1.2.6",
"vuex": "^3.2.0",
"wechat-jssdk": "^5.0.4"
},
"devDependencies": {
"@babel/runtime": "~7.17.9",
"@dcloudio/types": "^3.0.4",
"@dcloudio/uni-automator": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-shared": "^2.0.1-35320220729002",
"@dcloudio/uni-migration": "^2.0.1-35320220729002",
"@dcloudio/uni-template-compiler": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-mp-loader": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-pages-loader": "^2.0.1-35320220729002",
"@vue/cli-plugin-babel": "~4.5.19",
"@vue/cli-service": "~4.5.19",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"less": "^4.1.0",
"less-loader": "^4.1.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0",
"sass": "^1.5.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"resolutions": {
"@babel/runtime": "~7.17.9"
},
"uni-app": {
"scripts": {
"mp-weixin-test": {
"title": "微信小程序(Test环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "test",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
},
"mp-weixin": {
"title": "微信小程序(生产环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "prod",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
}
}
}
"mp-weixin-test": {
"title": "微信小程序(Test环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "test",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
},
"mp-weixin": {
"title": "微信小程序(生产环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "prod",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
}
}
}
}
+150 -19
View File
@@ -39,7 +39,20 @@
{
"path": "pages/home/landMark",
"style": {
"navigationBarTitleText": "地标好物"
"navigationBarTitleText": "地标好物"
}
},
{
"path": "pages/home/searchPage",
"style": {
"navigationBarTitleText": "搜索"
}
},
{
"path": "pages/home/newZone",
"style": {
"navigationBarTitleText": "新品专区",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
@@ -90,7 +103,15 @@
{
"path": "pages/cloud/haveFun",
"style": {
"navigationBarTitleText": "寻趣味"
"navigationBarTitleText": "趣游生活"
}
},
{
"path": "pages/town/index",
"style": {
"navigationBarTextStyle": "white",
"navigationStyle": "custom",
"navigationBarTitleText": "趣游生活"
}
},
{
@@ -392,6 +413,13 @@
"navigationStyle": "custom"
}
},
{
"path": "inn/farmerStore",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "inn/innGoodList",
"style": {
@@ -540,13 +568,56 @@
{
"path": "views/healthList",
"style": {
"navigationBarTitleText": "康养 · 食材"
"navigationBarTitleText": "选择城市",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "views/expoList",
"style": {
"navigationBarTitleText": "康养旅居",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "views/expoDetails",
"style": {
"navigationBarTitleText": "文化艺术",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "views/healthSanctum",
"style": {
"navigationBarTitleText": "康养旅居",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "views/healthFoods",
"style": {
"navigationBarTitleText": "康养旅居",
"navigationBarBackgroundColor": "#FAEED8"
}
},
{
"path": "views/healthFoodDetails",
"style": {
"navigationBarTitleText": "康养旅居",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "views/healthSearch",
"style": {
"navigationBarTitleText": "搜索",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "views/heritage",
"style": {
"navigationBarTitleText": "非遗文"
"navigationBarTitleText": "非遗文"
}
},
{
@@ -555,6 +626,20 @@
"navigationBarTitleText": ""
}
},
{
"path": "views/heritage/index",
"style": {
"navigationBarTitleText": "非遗文创",
"navigationBarBackgroundColor": "#FAEED8"
}
},
{
"path": "views/heritage/details",
"style": {
"navigationBarTitleText": "非遗文创",
"navigationBarBackgroundColor": "#FAEED8"
}
},
{
"path": "views/heritageVideo",
"style": {
@@ -589,33 +674,40 @@
{
"path": "views/famousList",
"style": {
"navigationBarTitleText": "寻千县"
"navigationBarTitleText": "寻千县万村"
}
},
{
"path": "views/famousQianxian",
"style": {
"navigationBarTitleText": "寻千县"
"navigationBarTitleText": "寻千县万村"
}
},
{
"path": "views/famousQianxianShop",
"style": {
"navigationBarTitleText": "寻千县",
"navigationBarTitleText": "寻千县万村",
"navigationStyle": "custom"
}
},
{
"path": "views/famousQianxianTheme",
"style": {
"navigationBarTitleText": "寻千县",
"navigationBarTitleText": "寻千县万村",
"navigationStyle": "custom"
}
},
{
"path": "views/famousQianxianVillageShop",
"style": {
"navigationBarTitleText": "寻千县",
"navigationBarTitleText": "寻千县万村",
"navigationStyle": "custom"
}
},
{
"path": "views/sojoumStore",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
@@ -659,8 +751,8 @@
"path": "views/nativeList",
"style": {
"navigationBarTitleText": "特产",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#FF564A"
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#fff"
}
},
{
@@ -680,6 +772,24 @@
{
"root": "pkg_user",
"pages": [
{
"path": "views/giftList",
"style": {
"navigationBarTitleText": "我的礼品卡"
}
},
{
"path": "views/gift/gift",
"style": {
"navigationBarTitleText": "送礼包"
}
},
{
"path": "views/gift/receive",
"style": {
"navigationBarTitleText": "好友赠送的礼包"
}
},
{
"path": "views/myFavorite",
"style": {
@@ -739,6 +849,27 @@
}
]
},
{
"root": "aiChat",
"pages": [
{
"path": "views/index",
"style": {
"navigationBarTitleText": "云灵AI智能助手",
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
},
{
"path": "views/history",
"style": {
"navigationBarTitleText": "云灵AI智能助手",
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
}
]
},
{
"root": "v4",
"pages": [
@@ -858,26 +989,26 @@
"list": [
{
"pagePath": "pages/home/index",
"iconPath": "static/tabbar/icon-home.png",
"selectedIconPath": "static/tabbar/icon-home-hot.png",
"iconPath": "/static/images/tabbar/tabbar-01-on.png",
"selectedIconPath": "/static/images/tabbar/tabbar-01-on.png",
"text": "首页"
},
{
"pagePath": "pages/cloud/haveFun",
"iconPath": "static/tabbar/icon-land.png",
"selectedIconPath": "static/tabbar/icon-land-hot.png",
"iconPath": "/static/images/tabbar/tabbar-01-on.png",
"selectedIconPath": "/static/images/tabbar/tabbar-01-on.png",
"text": "寻趣味"
},
{
"pagePath": "pages/cart",
"iconPath": "static/tabbar/icon-cart.png",
"selectedIconPath": "static/tabbar/icon-cart-hot.png",
"iconPath": "/static/images/tabbar/tabbar-01-on.png",
"selectedIconPath": "/static/images/tabbar/tabbar-01-on.png",
"text": "购物车"
},
{
"pagePath": "pages/user/User/index",
"iconPath": "static/tabbar/icon-user.png",
"selectedIconPath": "static/tabbar/icon-user-hot.png",
"iconPath": "/static/images/tabbar/tabbar-01-on.png",
"selectedIconPath": "/static/images/tabbar/tabbar-01-on.png",
"text": "我的"
}
]
@@ -18,12 +18,16 @@ export default {
pageKeyId: ''
}
},
onReady: function(res) {
onReady(res) {
this.videoContext = uni.createVideoContext('myVideo');
this.videoContext.requestFullScreen();
},
onLoad:function(e){
this.curPlayVideoUrl = e.videoUrl
onLoad(options) {
if (!options.click) {
uni.switchTab({ url: '/pages/home/index' })
return
}
this.curPlayVideoUrl = options.videoUrl
const id = options.id
this.pageKeyId = `findVideo_videoId_${id}`
},
@@ -51,7 +51,11 @@ export default {
pageKeyId: Object.freeze('findVideoList')
}
},
onLoad() {
onLoad(options) {
if (!options.click) {
uni.switchTab({ url: '/pages/home/index' })
return
}
this.getType()
this.fetchList()
},
@@ -94,7 +98,7 @@ export default {
})
},
goDetail(item) {
this.$yrouter.push("/pages/VideoPlayBackList/VideoPlayBackDetail?videoUrl=" + item.video + '&id=' + item.id)
this.$yrouter.push("/pages/VideoPlayBackList/VideoPlayBackDetail?videoUrl=" + item.video + '&id=' + item.id + '&click=1')
}
}
}
+29 -32
View File
@@ -131,7 +131,7 @@
<view class="v12-mt-3 v12-font-32 v12-dark-text v12-font-weight-600">发现家乡好物</view>
</view>
<view class="btn-box">
<button class="btn-yes v12-primary" type="mini" v-if="canIUseGetUserProfile" @tap="getUserInfoProfile">快捷登录</button>
<button class="btn-yes v12-primary" type="mini" @tap="getUserInfoProfile">快捷登录</button>
<!-- <button class="btn-no" type="default" @tap="back">拒绝</button> -->
</view>
<view class="agree-box v12-align-center">
@@ -171,7 +171,6 @@ export default {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
authorize: false,
canIUseGetUserProfile: false,
agreeInfo: {},
isAgree: [],
show: false,
@@ -188,9 +187,6 @@ export default {
...mapState(['isAuthorization', '$deviceType', 'token']),
},
onLoad() {
if (wx.getUserProfile) {
this.canIUseGetUserProfile = true
}
// 先校验用户是否授权,如果没有授权,显示授权按钮
getAgree().then(({data}) => this.agreeInfo = data);
},
@@ -227,18 +223,19 @@ export default {
})
},
doneRedirect() {
let redirectUrl = cookie.get('redirect') || "";
redirectUrl = redirectUrl.replace(/\ /g, '');
//如果已经是授权页,跳转主页
let redirectUrl = cookie.get('redirect') || ''
redirectUrl = redirectUrl.replace(/\ /g, '')
// 如果已经是授权页,跳转主页
if (redirectUrl == '/pages/authorization/index' || redirectUrl.length === 0) {
redirectUrl = '/pages/home/index';
redirectUrl = '/pages/home/index'
}
this.$yrouter.reLaunch({
path: redirectUrl,
path: redirectUrl
})
},
getUserInfoProfile() {
if (!this.isAgree[0]) {
const _this = this
if (!_this.isAgree[0]) {
uni.showToast({
title: "请先阅读并同意《用户服务协议及隐私政策》",
icon: "none",
@@ -246,33 +243,33 @@ export default {
})
return
}
wx.getUserProfile({
lang: 'zh_CN',
desc: '需要获取您的信息用来展示',
success: res => {
uni.showLoading({
title: '登录中',
})
login(res).then(e => {
let db_nickname = e.data.nickname;
if (db_nickname === null || db_nickname === undefined || db_nickname === "" || db_nickname === "微信用户") {
this.showFillOut = true;
} else {
this.doneRedirect();
}
}).catch(error => {
uni.showToast({
title: error,
icon: 'none',
duration: 2000,
})
})
},
_this.loginReq(res)
}
})
},
loginReq(res) {
uni.showLoading({
title: '登录中'
})
login(res).then(e => {
const db_nickname = e.data.nickname
if (db_nickname === null || db_nickname === undefined || db_nickname === '' || db_nickname === '微信用户') {
this.showFillOut = true
} else {
this.doneRedirect()
}
}).catch(error => {
uni.showToast({
title: error,
icon: 'none',
duration: 2000
})
})
},
onChooseAvatar(e) {
const {avatarUrl} = e.detail;
this.avatarUrl = avatarUrl;
+399 -281
View File
@@ -10,292 +10,317 @@
title="购物车"
fixed
/>
<view v-if="isLoad" :style="{paddingBottom: list.length > 0 ? '120rpx;' : ''}" class="list-wrap">
<view class="v12-justify-between v12-px-2">
<view class="v12-font-28 v12-dark-text v12-align-center" @click="show = true">
<image :src="webUrl+'/orderIcon/map.png'" style="width: 30rpx;height: 30rpx" class="v12-mr-1"/>
<text>{{ addressInfo.city }}</text>
<view class="v12-ml-1" style="margin-top: 2px;">
<u-icon name="arrow-down"></u-icon>
<view
v-if="isLoad"
:style="{paddingBottom: list.length > 0 ? '120rpx;' : ''}"
class="list-wrap"
>
<view v-if="isNoLogin" class="no-login-wrap">
<image
:src="webUrl + '/page/my/nologin.png'"
class="img"
/>
<view class="txt">您还未登录</view>
<view class="desc">请注册/登录账户后重试</view>
<view class="btn" @click="toLoginHandle">去登录</view>
</view>
<view v-else>
<view class="v12-justify-between v12-px-2">
<view class="v12-font-28 v12-dark-text v12-align-center" @click="show = true">
<image :src="webUrl+'/orderIcon/map.png'" style="width: 30rpx;height: 30rpx" class="v12-mr-1"/>
<text>{{ addressInfo.city }}</text>
<view class="v12-ml-1" style="margin-top: 2px;">
<u-icon name="arrow-down"></u-icon>
</view>
</view>
<view
v-if="list.length > 0"
class="v12-font-28 v12-font-bold v12-dark-text"
@click="editCart"
>{{ isEdit ? '完成' : '管理' }}</view>
</view>
<view
v-if="list.length === 0"
class="tc v12-my-6"
>
<image
:src="$VUE_APP_RESOURCES_URL + '/orderIcon/购物车2.png'"
style="width: 294rpx;height: 354rpx"
mode="scaleToFill"
/>
</view>
<view v-if="list.length === 0">
<view class="v12-px-14">
<u-divider
text=" · 猜你喜欢 · "
textColor="#333"
lineColor="#333"
textPosition="center"
></u-divider>
</view>
<view class="userlike-wrap">
<view
v-for="(item, index) in userLikeList"
:key="index"
@click="goGoodsCon(item)"
class="v12-radius-20 v12-white v12-mb-3 like-card"
>
<view class="img-wrap">
<image :src="item.image" class="img"></image>
<image
v-if="item.isOldBrand"
:src="webUrl + '/home/old-mark.png'"
class="mark-img"
/>
<image
v-if="item.isLandmarkGoods"
:src="webUrl + '/home/mark-land.png'"
class="mark-img"
/>
<image
v-if="item.isIch"
:src="webUrl + '/home/ich-mark.png'"
class="mark-img"
style="right: 20rpx; width: 70rpx"
/>
<image
v-if="item.isCountyFamous"
:src="webUrl + '/home/qixian-mark.png'"
class="mark-img"
/>
</view>
<view class="info-wrap v12-pa-2">
<view class="more-t v12-font-28 v12-dark-text v12-mb-2">
{{ item.storeName }}
</view>
<view v-if="item.bestContent" class="more-t v12-mb-2 v12-font-24 v12-yellow-text v12-font-weight-300">
{{ item.bestContent }}
</view>
<view class="v12-align-center v12-primary-text v12-font-24 v12-mb-2" v-if="item.couponName">
<view class="v12-primary-border v12-radius-8 v12-px-1">券</view>
<view class="v12-primary-border v12-radius-8 v12-px-1">{{ item.couponName }}</view>
</view>
<view class="v12-justify-between v12-align-center">
<view class="v12-font-40 v12-font-bold v12-primary-text">
<text class="">¥</text>
<text class="price-txt price-red">{{ item.price }}</text>
</view>
<view class="btn">
<image
:src="webUrl + '/home/icon-cart.png'"
class="img-icon"
/>
</view>
</view>
</view>
</view>
</view>
</view>
<view
v-if="list.length > 0"
class="v12-font-28 v12-font-bold v12-dark-text"
@click="editCart"
>{{ isEdit ? '完成' : '管理' }}</view>
</view>
<view
v-if="list.length === 0"
class="tc v12-my-6"
>
<image
:src="$VUE_APP_RESOURCES_URL + '/orderIcon/购物车2.png'"
style="width: 294rpx;height: 354rpx"
mode="scaleToFill"
/>
</view>
<view v-if="list.length === 0">
<view class="v12-px-14">
<u-divider
text=" · 猜你喜欢 · "
textColor="#333"
lineColor="#333"
textPosition="center"
></u-divider>
</view>
<view class="userlike-wrap">
<view
v-for="(item, index) in userLikeList"
:key="index"
@click="goGoodsCon(item)"
class="v12-radius-20 v12-white v12-mb-3 like-card"
>
<view class="img-wrap">
<image :src="item.image" class="img"></image>
<image
v-if="item.isOldBrand"
:src="webUrl + '/home/old-mark.png'"
class="mark-img"
/>
<image
v-if="item.isLandmarkGoods"
:src="webUrl + '/home/mark-land.png'"
class="mark-img"
/>
<image
v-if="item.isCountyFamous"
:src="webUrl + '/home/qixian-mark.png'"
class="mark-img"
/>
</view>
<view class="info-wrap v12-pa-2">
<view class="more-t v12-font-28 v12-dark-text v12-mb-2">
{{ item.storeName }}
</view>
<view v-if="item.bestContent" class="more-t v12-mb-2 v12-font-24 v12-yellow-text v12-font-weight-300">
{{ item.bestContent }}
</view>
<view class="v12-align-center v12-primary-text v12-font-24 v12-mb-2" v-if="item.couponName">
<view class="v12-primary-border v12-radius-8 v12-px-1">券</view>
<view class="v12-primary-border v12-radius-8 v12-px-1">{{ item.couponName }}</view>
</view>
<view class="v12-justify-between v12-align-center">
<view class="v12-font-40 v12-font-bold v12-primary-text">
<text class="">¥</text>
<text class="price-txt price-red">{{ item.price }}</text>
</view>
<view class="btn">
<image
:src="webUrl + '/home/icon-cart.png'"
class="img-icon"
/>
</view>
</view>
</view>
</view>
</view>
</view>
<view
v-for="(item, index) in list"
:key="index"
class="group-item"
>
<view class="flex jc-between">
<view class="flex ai-center mer-left">
<!-- <CheckboxIcon
:default-state="item['state']"
:mark="[index]"
style="margin-right: 24rpx;"
@change="onChange"
/> -->
<image
:src="item['merAvatar']"
class="store-cover"
mode="scaleToFill"
/>
<view class="mer-name v12-font-24 v12-font-bold">{{ item['merName'] }}</view>
</view>
<view
class="flex ai-center hotle-btn v12-primary-text"
@click="navToStore(item['hotelId'])"
>
进店逛逛>
<!-- <image
:src="$VUE_APP_RESOURCES_URL + '/20240109234706982937.png'"
style="width: 24rpx;height: 24rpx"
mode="scaleToFill"
/> -->
</view>
</view>
<view class="good-box">
<view
v-for="(good, gIndex) in item['carts']"
:key="gIndex"
class="good flex v12-align-start"
>
<view class="v12-align-center">
<CheckboxIcon
:default-state="good['state']"
:mark="[index, gIndex]"
v-for="(item, index) in list"
:key="index"
class="group-item"
>
<view class="flex jc-between">
<view class="flex ai-center mer-left">
<!-- <CheckboxIcon
:default-state="item['state']"
:mark="[index]"
style="margin-right: 24rpx;"
@change="onChange"
/>
/> -->
<image
v-if="good['productInfo']['attrInfo']['image']"
:src="good['productInfo']['attrInfo']['image']"
class="good-cover flex-0 v12-radius-16"
:src="item['merAvatar']"
class="store-cover"
mode="scaleToFill"
@click="navToGood(good)"
/>
<image
v-else
:src="good['productInfo']['image']"
<view class="mer-name v12-font-24 v12-font-bold">{{ item['merName'] }}</view>
</view>
<view
class="flex ai-center hotle-btn v12-primary-text"
@click="navToStore(item['hotelId'])"
>
进店逛逛>
<!-- <image
:src="$VUE_APP_RESOURCES_URL + '/20240109234706982937.png'"
style="width: 24rpx;height: 24rpx"
mode="scaleToFill"
class="good-cover flex-0"
@click="navToGood(good)"
/>
</view>
<view style="width: 100%">
<view
class="one-t v12-font-28"
@click="navToGood(good)"
>{{ good['productInfo']['storeName'] }}</view>
<view
class="sku ai-center"
@click="changeGoodAttrHandle(good)"
>
规格:{{ good['productInfo']['attrInfo']['sku'] }}
</view>
<!-- <view class="v12-mt-1 v12-align-center">
<view class="v12-primary-text v12-primary-border v12-radius-8 v12-font-24 v12-px-1">
<text>券</text>
</view>
<view class="v12-primary-text v12-primary-border v12-radius-8 v12-font-24 v12-px-1">
<text>满100-30</text>
</view>
</view> -->
<view
class="flex jc-between ai-center"
style="width: 100%;margin-top: 4rpx;"
>
<view
class="v12-font-bold v12-primary-text"
@click="navToGood(good)"
>
<text class="bold v12-font-22">¥</text>
<text class="v12-font-36">{{ good['truePrice'] }}</text>
</view>
<u-number-box
:value="good.cartNum"
:max="good['productInfo']['attrInfo']['stock']"
integer
disabledInput
iconStyle="color: #fff"
class="num-step"
@change="e => changeNumHandle(index, gIndex, good, e)"
>
<template v-slot:minus>
<view class="v12-minus-btn v12-font-bold flex jc-center ai-center">
<u-icon name="minus" size="12" color="#FFFFFF"/>
</view>
</template>
<template v-slot:input>
<view class="num-input tc v12-num-input">{{ good['cartNum'] }}</view>
</template>
<template v-slot:plus>
<view class="v12-plus-btn v12-font-bold flex jc-center ai-center v12-primary">
<u-icon name="plus" size="12" color="#FFFFFF"/>
</view>
</template>
</u-number-box>
</view>
/> -->
</view>
</view>
</view>
</view>
<view class="footer-fixed flex jc-between ai-center" v-if="list.length > 0">
<view style="margin-left: 32rpx;">
<CheckboxIcon
style="margin-right: 24rpx;"
:default-state="isAll"
:mark="[-1]"
@change="onChange"
/>
<text class="v12-dark-text v12-font-32 v12-font-bold">全选({{ selectCount }})</text>
</view>
<view class="flex ai-center" v-if="!isEdit">
<view >
<text class="v12-font-24 v12-dark-text v12-font-weight-550"> 合计:</text>
<text class="v12-font-22 v12-primary-text v12-font-bold">¥</text>
<text class="v12-font-26 v12-primary-text v12-font-bold">{{ total }}</text>
</view>
<view class="btn-submit v12-mx-3 flex jc-center ai-center v12-radius-80 v12-primary" @click="submit">结算</view>
</view>
<view class="flex ai-center" v-else>
<view @click="clearCart" class="v12-justify-between v12-align-center">
<view style="margin-top: 1px"><u-icon name="trash"></u-icon> </view>
<view>清空</view>
</view>
<view @click="remove" class="btn-submit v12-mx-3 flex jc-center ai-center v12-radius-80 v12-primary">删除</view>
</view>
</view>
<view
v-show="showAttr"
class="good-attr-wrap"
>
<view class="layer" @click="closeAttr" />
<view class="content">
<view class="close">
<text class="iconfont icon-guanbi" @click="closeAttr"></text>
</view>
<view class="good-info">
<view class="name-img">
<image :src="currGoodAttr.image" class="img" />
<view class="name">
<view class="more-t">
{{ currGood.productInfo.storeName }}
</view>
<view class="price">
<text class="txt">¥</text>{{ currGoodAttr.price }}
</view>
</view>
</view>
</view>
<view class="attr-wrap">
<view class="good-box">
<view
v-for="(item, index) in goodAttr.productAttr"
:key="index"
class="item"
v-for="(good, gIndex) in item['carts']"
:key="gIndex"
class="good flex v12-align-start"
>
<view class="title">{{ item.attrName }}</view>
<view class="acea-row row-middle">
<view class="v12-align-center">
<CheckboxIcon
:default-state="good['state']"
:mark="[index, gIndex]"
style="margin-right: 24rpx;"
@change="onChange"
/>
<image
v-if="good['productInfo']['attrInfo']['image']"
:src="good['productInfo']['attrInfo']['image']"
class="good-cover flex-0 v12-radius-16"
mode="scaleToFill"
@click="navToGood(good, item)"
/>
<image
v-else
:src="good['productInfo']['image']"
mode="scaleToFill"
class="good-cover flex-0"
@click="navToGood(good, item)"
/>
</view>
<view style="width: 100%">
<view
v-for="(attr, attrIndex) in item.attrValue"
:key="attr"
:class="{
'on': attr.check,
'disabled': getAttrItemData(attr.attr).stock === 0
}"
class="attr"
@click="attrItemClick(attr, attrIndex, index)"
class="one-t v12-font-28"
@click="navToGood(good, item)"
>{{ good['productInfo']['storeName'] }}</view>
<view
class="sku ai-center"
@click="changeGoodAttrHandle(good)"
>
{{ attr.attr }}
<text
v-if="getAttrItemData(attr.attr).stock === 0"
class="tag"
>缺货</text>
规格:{{ good['productInfo']['attrInfo']['sku'] ? good['productInfo']['attrInfo']['sku'] : '' }}
</view>
<!-- <view class="v12-mt-1 v12-align-center">
<view class="v12-primary-text v12-primary-border v12-radius-8 v12-font-24 v12-px-1">
<text>券</text>
</view>
<view class="v12-primary-text v12-primary-border v12-radius-8 v12-font-24 v12-px-1">
<text>满100-30</text>
</view>
</view> -->
<view
class="flex jc-between ai-center"
style="width: 100%;margin-top: 4rpx;"
v-if="good['truePrice'] !== null"
>
<view
class="v12-font-bold v12-primary-text"
@click="navToGood(good, item)"
>
<text class="bold v12-font-22">¥</text>
<text class="v12-font-36">{{ good['truePrice'] }}</text>
</view>
<u-number-box
:value="good.cartNum"
:max="good['productInfo']['attrInfo']['stock']"
integer
disabledInput
iconStyle="color: #fff"
class="num-step"
@change="e => changeNumHandle(index, gIndex, good, e)"
@overlimit="overlimit"
>
<template v-slot:minus>
<view class="v12-minus-btn v12-font-bold flex jc-center ai-center">
<u-icon name="minus" size="12" color="#FFFFFF"/>
</view>
</template>
<template v-slot:input>
<view class="num-input tc v12-num-input">{{ good['cartNum'] }}</view>
</template>
<template v-slot:plus>
<view class="v12-plus-btn v12-font-bold flex jc-center ai-center v12-primary">
<u-icon name="plus" size="12" color="#FFFFFF"/>
</view>
</template>
</u-number-box>
</view>
<view v-else class="v12-secondary-dark-text v12-font-24" style="padding: 0 10rpx">商品已下架</view>
</view>
</view>
</view>
<view class="bottom">
<view
:class="currGoodAttr.stock === 0 ? 'disabled' : ''"
class="btn"
@click="changeAttrConfirm"
>
确认
</view>
<view class="footer-fixed flex jc-between ai-center" v-if="list.length > 0">
<view style="margin-left: 32rpx;">
<CheckboxIcon
style="margin-right: 24rpx;"
:default-state="isAll"
:mark="[-1]"
@change="onChange"
/>
<text class="v12-dark-text v12-font-32 v12-font-bold">全选({{ selectCount }})</text>
</view>
<view class="flex ai-center" v-if="!isEdit">
<view >
<text class="v12-font-24 v12-dark-text v12-font-weight-550"> 合计:</text>
<text class="v12-font-22 v12-primary-text v12-font-bold">¥</text>
<text class="v12-font-26 v12-primary-text v12-font-bold">{{ total }}</text>
</view>
<view class="btn-submit v12-mx-3 flex jc-center ai-center v12-radius-80 v12-primary" @click="submit">结算</view>
</view>
<view class="flex ai-center" v-else>
<view @click="clearCart" class="v12-justify-between v12-align-center">
<view style="margin-top: 1px"><u-icon name="trash"></u-icon> </view>
<view>清空</view>
</view>
<view @click="remove" class="btn-submit v12-mx-3 flex jc-center ai-center v12-radius-80 v12-primary">删除</view>
</view>
</view>
<view
v-show="showAttr"
class="good-attr-wrap"
>
<view class="layer" @click="closeAttr" />
<view class="content">
<view class="close">
<text class="iconfont icon-guanbi" @click="closeAttr"></text>
</view>
<view class="good-info">
<view class="name-img">
<image :src="currGoodAttr.image" class="img" />
<view class="name">
<view class="more-t">
{{ currGood.productInfo.storeName }}
</view>
<view class="price">
<text class="txt">¥</text>{{ currGoodAttr.price }}
</view>
</view>
</view>
</view>
<view class="attr-wrap">
<view
v-for="(item, index) in goodAttr.productAttr"
:key="index"
class="item"
>
<view class="title">{{ item.attrName }}</view>
<view class="acea-row row-middle">
<view
v-for="(attr, attrIndex) in item.attrValue"
:key="attr"
:class="{
'on': attr.check,
'disabled': getAttrItemData(attr.attr).stock === 0
}"
class="attr"
@click="attrItemClick(attr, attrIndex, index)"
>
{{ attr.attr }}
<text
v-if="getAttrItemData(attr.attr).stock === 0"
class="tag"
>缺货</text>
</view>
</view>
</view>
</view>
<view class="bottom">
<view
:class="currGoodAttr.stock === 0 ? 'disabled' : ''"
class="btn"
@click="changeAttrConfirm"
>
确认
</view>
</view>
</view>
</view>
@@ -348,6 +373,7 @@ import {
} from '@/api/store'
import CheckboxIcon from '@/components/CheckboxIcon.vue'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import cookie from "@/utils/store/cookie"
export default {
components: {
CheckboxIcon,
@@ -373,7 +399,9 @@ export default {
isEdit: false,
addressList:[],
addressInfo: {},
userLikeList: []
userLikeList: [],
// 是否已登录
isNoLogin: false
}
},
computed: {
@@ -398,26 +426,34 @@ export default {
},
created() {
this.getCart()
},
onLoad() {
this.getAddress()
},
onShow() {
this.isEdit = false
uni.$on('chooseAddress', (res) => {
this.addressInfo = res;
this.$forceUpdate()
})
if (!this.isLoad) {
return
}
this.closeAttr()
this.getCart()
// 选择地址
const cartChooseAddress = uni.getStorageSync('cartChooseAddress') || {}
if (cartChooseAddress.id) {
this.addressInfo = cartChooseAddress
// uni.setStorageSync('cartChooseAddress', {})
return
}
this.getAddress()
},
onHide() {
this.pageToHideHandle()
},
methods: {
toLoginHandle() {
cookie.set('redirect', '/pages/cart')
uni.reLaunch({
url: '/pages/authorization/index'
})
},
goGoodsCon(item) {
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
@@ -433,7 +469,7 @@ export default {
this.$yrouter.push({
path: "/pages/user/address/AddressManagement/index",
query: {
choosMode: 1
choosMode: 2
}
});
},
@@ -441,15 +477,35 @@ export default {
this.$yrouter.push({
path: "/pages/user/address/AddAddress/index",
query: {
choosMode: 1
choosMode: 2
}
});
},
getAddress() {
getAddressList({page: 1, limit: 9999}).then(res => {
this.addressList = res.data
this.addressInfo = res.data.find(e => e.isDefault == 1) || res.data[0] && res.data[0] || null
});
if (res.isNoLogin) {
this.isNoLogin = true
return
} else {
const { data = [] } = res
this.addressList = data
this.addressInfo = data.find(e => e.isDefault == 1) || uni.getStorageSync('cartChooseAddress') || (data && data[0]) || null
if (!this.addressInfo.id) {
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
} else {
let isExist = false
data.map(item => {
if (item.id === this.addressInfo.id) {
isExist = true
}
})
console.log(2, isExist);
if (!isExist) {
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
}
}
}
})
},
clearCart() {
const ids = this.list.map(l => {
@@ -482,9 +538,20 @@ export default {
},
async getCart() {
const res = await getCartGroup()
if (res.isNoLogin) {
this.isNoLogin = true
this.isLoad = true
return
}
if (res.success) {
this.isLoad = true
this.list = res.data['valid']
const invalid = res.data['invalid'].map(e => {
return {
...e,
isInvalid: true
}
})
this.list = res.data['valid'].concat(invalid)
this.handleAll(false)
const _res = await getUserLike()
this.userLikeList = _res.data
@@ -548,6 +615,7 @@ export default {
changeNumHandle(index, gIndex, good, e) {
const { type } = e
const value = good.cartNum + (type === 'plus' ? 1 : -1)
console.log('index', value);
const id = good.id
// uni.showLoading()
changeCartNum(id, value).then(res => {
@@ -562,6 +630,16 @@ export default {
}, 3000)
})
},
overlimit(e) {
const tip = {
'plus': '商品数量超出库存',
'minus': '商品数量不能减少了呦~'
}
uni.showToast({
title: tip[e],
icon: 'none'
})
},
handleIds() {
if (this.selectCount === 0) {
uni.showToast({
@@ -724,7 +802,15 @@ export default {
this.currGood = {}
this.showAttr = false
},
navToGood(good) {
navToGood(good, item) {
if(item.isInvalid) {
uni.showToast({
title: '商品已下架或被删除',
icon: 'none',
duration: 3000
})
return
}
const query = {
id: good.productId
}
@@ -1050,4 +1136,36 @@ view {
overflow: hidden;
border-radius: 20rpx;
}
.no-login-wrap {
position: relative;
top: 50%;
text-align: center;
transform: translateY(-50%);
.img {
display: block;
width: 478rpx;
height: 398rpx;
margin: 0 auto;
}
.txt {
font-size: 36rpx;
line-height: 56rpx;
color: #666;
}
.desc {
font-size: 28rpx;
line-height: 56rpx;
color: #999;
}
.btn {
width: 320rpx;
height: 80rpx;
margin: 40rpx auto 0 auto;
border-radius: 40rpx;
line-height: 80rpx;
color: #fff;
font-size: 30rpx;
background-color: #C52733;
}
}
</style>
+112 -11
View File
@@ -10,14 +10,14 @@
@confirm="search"
>
<image
:src="webUrl + '/20220903142935869059.png'"
:src="webUrl + '/orderIcon/search.png'"
class="icon"
mode="scaleToFill"
@click="search"
/>
</view>
</view>
<view class="aside">
<view class="aside" id="aside">
<view
v-for="(item, index) in listGroup"
:key="index"
@@ -44,7 +44,7 @@
<view class="fixed-box">
<view class="line-location flex ai-center">
<image :src="webUrl + '/20220903142929759087.png'" mode="scaleToFill"></image>
<text class="bold" v-if="location">当前定位{{ location }}</text>
<text class="bold" v-if="location">当前城市{{ location }}</text>
<view style="color:#f66" @click="reload()" v-else>定位失败
<image :src="webUrl + '/20231215213824297278.png'" mode="scaleToFill" />
</view>
@@ -90,7 +90,11 @@
class="item flex-0 flex flex-col jc-between ai-center"
@click="goToStore(item.hotelId || '')"
>
<image class="cover" :src="item.hotelImage" mode="scaleToFill" />
<image
:src="item.hotelImage + (item.hotelImage.indexOf('.mp4') > -1 ? '?vframe/jpg/offset/1' : '')"
class="cover"
mode="scaleToFill"
/>
<image class="logo" :src="item.hotelLogo" mode="scaleToFill" />
<view style="width: 100%;box-sizing: border-box;padding:0 8rpx">
<view class="name tc one-t">{{ item.hotelName }}</view>
@@ -125,7 +129,7 @@
@click="select(item)"
>
<view class="has-goods" v-if="type === 0 && item.hasData === 0">暂无特产</view>
<view class="has-goods" v-if="type > 0 && type < 6 && item.hasShop === 0">暂无店铺</view>
<view class="has-goods" v-if="type > 0 && type < 6 && item.hasShop === 0 && item.hasAncientTown === 0">暂无店铺</view>
<view class="has-goods" v-if="type === 6 && item.hasData === 0">暂无景点</view>
<image :src="item.icon" mode="scaleToFill"></image>
<view class="one-t">{{ item.cityName }}</view>
@@ -133,6 +137,7 @@
</view>
</mescroll-body>
</view>
<FunctionGuide :maxStep="maxStep" @hide="setGuide(pageKeyId)" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -142,11 +147,14 @@ import {fetchCity} from '@/api/wenwan'
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
import {getCurAddress, getLocation} from '@/utils/common.js'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'ChoseCity',
components: {
MescrollBody
MescrollBody,
FunctionGuide
},
mixins: [
MescrollMixins({
@@ -154,7 +162,8 @@ export default {
mescroll.endSuccess(10)
}
}),
pageListenMixins
pageListenMixins,
GuideMixins
],
data() {
return {
@@ -184,6 +193,15 @@ export default {
pageKeyId: ''
}
},
computed: {
maxStep() {
const stepsMap = {
0: 1,
1: 2,
}
return stepsMap[this.type] || 1
}
},
onLoad(options) {
const type = Number(options.type)
this.type = type
@@ -212,8 +230,79 @@ export default {
this.getMapData()
}
this.init()
if([0,1] .includes(type)) {
this.queryGuide(this.pageKeyId)
}
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
const imgs = [
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '357rpx',
top: '100rpx',
left: '-110rpx',
right: 0,
margin: 'auto',
height: '382rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 125*2+'rpx',
left: -120*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 125*2+'rpx',
left: 170*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.getElementData('#aside', res=>{
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top*2 + 'rpx',
left: res.left*2 + 'rpx',
width: `${res.width*2}rpx`,
height: `${res.height*2}rpx`,
}
})
})
return
} else {
if(this.type === 1) {
this.$refs.FunctionGuide.show = false
}
return
}
},
reload() {
uni.getSetting({
success(res) {
@@ -294,6 +383,7 @@ export default {
this.mescroll && this.mescroll.triggerDownScroll()
},
search() {
if(this.keyword === '') return
this.listGroup.findIndex((group, index) => {
let result
group.city.forEach(item => {
@@ -310,7 +400,7 @@ export default {
},
select(item) {
if (this.type === 0 && item.hasData === 0) return
if ((this.type === 1 || this.type === 2) && item.hasShop === 0) return
if ((this.type === 1 || this.type === 2) && item.hasShop === 0 && item.hasAncientTown === 0) return
uni.setStorageSync("cityName", item.cityName)
switch (this.type) {
@@ -350,6 +440,14 @@ export default {
url: `/pages/shop/GoodsCon/index?id=${productId}&from=${this.getOptionsParams()}`
})
},
goToExhibition(linkExhibitionId) {
if (!linkExhibitionId) {
return
}
uni.navigateTo({
url: `/pkg_product/views/expoDetails?id=${linkExhibitionId}&from=${this.getOptionsParams()}`
})
},
getOptionsParams() {
// 0、特产;1、文玩;2、七彩云上;3、特色礼品;4、康养食材;5、千县名品;6、景点门票
let from = ''
@@ -392,6 +490,9 @@ export default {
case 2:
this.goToGoods(banner.linkProductId)
break
case 3:
this.goToExhibition(banner.linkExhibitionId)
break
default:
break
}
@@ -492,10 +593,10 @@ export default {
}
.item.on {
border-left: 6rpx solid #FD574B;
border-left: 6rpx solid #C52733;
.name {
color: #FD574B;
color: #C52733;
font-weight: bold;
}
}
@@ -515,7 +616,7 @@ export default {
box-sizing: border-box;
margin: 18rpx 0;
padding: 8rpx 0 0 8rpx;
border-left: 6rpx solid #FD574B;
border-left: 6rpx solid #C52733;
color: #262626;
font-size: 30rpx;
line-height: 30rpx;
+315 -307
View File
@@ -1,9 +1,19 @@
<template>
<view class="cloud-page">
<view class="search-box">
<uni-search-bar placeholder="输入搜索关键词" @confirm="search" @clear="clearName"></uni-search-bar>
<view class="search-box flex">
<view class="city-box" @click="goCity('cloud')">
<image
:src="webUrl+'/20220903142929759087.png'"
mode="scaleToFill"
/>
<text>{{ cityName }}</text>
</view>
<uni-search-bar
placeholder="输入搜索关键词"
@confirm="search"
@clear="clearName"
/>
</view>
<view class="nav-box">
<view
v-for="(item, index) in typeList"
@@ -12,370 +22,368 @@
@click="changeType(index)"
>
<image :src="item.icon" mode="scaleToFill"></image>
<view class="nav">{{item.name}}</view>
<view class="nav">{{ item.name }}</view>
</view>
</view>
<view class="list-box">
<text class="type-name">{{typeList[type]['name']}}</text>
<view class="city-box" @click="goCity('cloud')">
<image :src="webUrl+'/20220903142929759087.png'" mode="scaleToFill"></image>
<text>{{cityName}}</text>
</view>
<view class="list" v-if="hotelList.length">
<view
v-if="hotelList.length"
class="list"
>
<custom-waterfalls-flow :value="hotelList" imageKey="cover">
<view class="item" v-for="(item,index) in hotelList" :key="index" slot="slot{{index}}"
@click="goInnDetail(item)">
<view
v-for="(item,index) in hotelList"
:key="index"
slot="slot{{index}}"
class="item"
@click="goInnDetail(item)"
>
<view class="cover-box">
<image class="cover" :src="item.cover" mode="scaleToFill"></image>
<image
:src="item.cover"
mode="scaleToFill"
class="cover"
/>
<view class="my-mask">
<image class="icon" :src="webUrl+'/20220510142728577618.png'" mode="scaleToFill"></image>
<text>{{item.cityName}}</text>
<image
class="icon"
:src="webUrl+'/20220510142728577618.png'"
mode="scaleToFill"
/>
<text>{{ item.cityName }}</text>
</view>
</view>
<view class="more-t">{{item.content}}</view>
<view class="more-t">{{ item.content }}</view>
<view class="flex ai-center" style="margin-bottom: 18rpx;">
<image class="logo" :src="item.logo" mode="scaleToFill"></image>
<text class="one-t">{{item.name}}</text>
<image
class="logo"
:src="item.logo"
mode="scaleToFill"
/>
<text class="one-t">{{ item.name }}</text>
</view>
</view>
</custom-waterfalls-flow>
</view>
<view class="v4-nodata" v-else>
<image src="@/static/images/img_nodata.png" mode="scaleToFill" />
<view class="text">暂无数据</view>
</view>
</view>
</view>
</template>
<script>
import config from '@/utils/mapConfig';
import {
getHotelTypeList,
getHotelList
} from "@/api/inn.js";
export default {
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
typeList: [],
name: "",
page: 1,
type: 0,
tabName: "", // 跳转初始分类名
hotelList: [],
cityName: "丽江市",
paramCity: ""
}
import config from '@/utils/mapConfig'
import {
getHotelTypeList,
getHotelList
} from '@/api/inn.js'
export default {
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
typeList: [],
name: '',
page: 1,
type: 0,
// 跳转初始分类名
tabName: '',
hotelList: [],
cityName: '丽江市',
paramCity: ''
}
},
onLoad(){
this.fetchTypeList()
},
onShow() {
const name = uni.getStorageSync('name')
if (name) {
this.tabName = name
uni.removeStorageSync('name')
}
const memCityName = uni.getStorageSync('cityName')
if (memCityName.length) {
this.cityName = memCityName
this.paramCity = memCityName
this.page = 1
this.hotelList = []
this.fetchList()
uni.removeStorageSync('cityName')
}
},
onReachBottom() {
this.page++
this.fetchList()
},
methods: {
goCity() {
uni.navigateTo({
url:`/pages/chose-city/chose-city?type=2&city=${this.cityName}`
})
},
onLoad(){
this.fetchTypeList()
},
onShow() {
let name = uni.getStorageSync("name");
if (name) {
this.tabName = name;
uni.removeStorageSync("name");
}
//获取当前定位地址
getCurAddress() {
const that = this
//定位
uni.showLoading({
title: '定位中...'
})
uni.getLocation({
type: 'wgs84',
success: function(res) {
let latitude = res.latitude
let longitude = res.longitude
// #ifdef H5
Vue.jsonp(
'https://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude + '&key=' +
config.key, {
output: 'jsonp',
}).then(json => {
// Success.
uni.hideLoading();
that.cityName = json.result.ad_info.city
that.paramCity = json.result.ad_info.city
//定位成功刷新数据
that.fetchList()
}).catch(err => {
uni.hideLoading()
})
// #endif
let memCityName = uni.getStorageSync("cityName")
if (memCityName.length) {
this.cityName = memCityName;
this.paramCity = memCityName;
this.page = 1;
this.hotelList = [];
this.fetchList();
uni.removeStorageSync("cityName")
}
},
onReachBottom() {
this.page++;
this.fetchList();
},
methods: {
goCity() {
uni.navigateTo({
url:`/pages/chose-city/chose-city?type=2&city=${this.cityName}`
})
},
//获取当前定位地址
getCurAddress() {
var that = this;
//定位
uni.showLoading({
title: '定位中...'
});
uni.getLocation({
type: 'wgs84',
success: function(res) {
let latitude = res.latitude;
let longitude = res.longitude;
// #ifdef H5
Vue.jsonp(
'https://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude + '&key=' +
config.key, {
output: 'jsonp',
}).then(json => {
// Success.
// #ifndef H5
uni.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude +
'&key=' + config.key,
success: function(res) {
uni.hideLoading();
that.cityName = json.result.ad_info.city;
that.paramCity = json.result.ad_info.city;
that.cityName = res.data.result.ad_info.city
that.paramCity = res.data.result.ad_info.city
//定位成功刷新数据
that.fetchList()
}).catch(err => {
uni.hideLoading();
})
// #endif
// #ifndef H5
uni.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude +
'&key=' + config.key,
success: function(res) {
uni.hideLoading();
that.cityName = res.data.result.ad_info.city;
that.paramCity = res.data.result.ad_info.city;
//定位成功刷新数据
that.fetchList()
},
fail: function(res) {
uni.hideLoading();
},
complete: function() {}
});
// #endif
},
fail: function(res) {
uni.hideLoading();
}
});
},
fetchTypeList() {
this.hotelList = []
getHotelTypeList().then(res => {
if (res.status === 200) {
for (let i = 0; i < res.data.length; i++) {
if (this.tabName == res.data[i].name) this.type = i;
},
fail: function(res) {
uni.hideLoading()
}
this.typeList = res.data
let memCityName = uni.getStorageSync("cityName")
if (memCityName.length) {
this.cityName = memCityName;
this.paramCity = memCityName;
this.page = 1;
this.list = [];
this.fetchList();
uni.removeStorageSync("cityName")
} else {
this.getCurAddress();
})
// #endif
},
fail: function(res) {
uni.hideLoading()
}
})
},
fetchTypeList() {
this.hotelList = []
getHotelTypeList().then(res => {
const { status, data } = res
if (status === 200) {
for (let i = 0; i < data.length; i++) {
if (this.tabName == data[i].name) {
this.type = i
}
}
})
},
search(e) {
this.name = e.value;
this.page = 1;
this.hotelList = [];
this.fetchList();
},
clearName() {
this.name = "";
this.page = 1;
this.hotelList = [];
this.fetchList();
},
changeType(index) {
this.type = index;
this.page = 1;
this.hotelList = [];
this.fetchList();
},
fetchList() {
getHotelList({
name: this.name,
page: this.page,
type: this.typeList[this.type].id,
cityName: this.paramCity
}).then(res => {
if (res.status === 200) {
this.paramCity = this.cityName;
for (let i = 0; i < res.data.length; i++) {
res.data[i].hide = true;
this.hotelList.push(res.data[i])
}
this.typeList = data
const memCityName = uni.getStorageSync('cityName')
if (memCityName.length) {
this.cityName = memCityName
this.paramCity = memCityName
this.page = 1
this.list = []
this.fetchList()
uni.removeStorageSync('cityName')
} else {
this.getCurAddress()
}
})
},
goInnDetail: function(item) {
//跳转到客栈详情
this.$yrouter.push({
path: "/pagesInn/inn/innHome",
query: {
id: item.id
}
})
},
search(e) {
this.name = e.value
this.page = 1
this.hotelList = []
this.fetchList()
},
clearName() {
this.name = ''
this.page = 1
this.hotelList = []
this.fetchList()
},
changeType(index) {
this.type = index
this.page = 1
this.hotelList = []
this.fetchList()
},
fetchList() {
getHotelList({
name: this.name,
page: this.page,
type: this.typeList[this.type].id,
cityName: this.paramCity
}).then(res => {
if (res.status === 200) {
this.paramCity = this.cityName
for (let i = 0; i < res.data.length; i++) {
res.data[i].hide = true
this.hotelList.push(res.data[i])
}
});
},
}
})
},
goInnDetail(item) {
//跳转到客栈详情
this.$yrouter.push({
path: '/pagesInn/inn/innHome',
query: {
id: item.id
}
})
}
}
}
</script>
<style scoped lang="less">
.cloud-page {
.search-box {
padding: 0 12rpx;
background: #fff;
.cloud-page {
.search-box {
padding: 0 12rpx;
background: #fff;
/deep/.uni-searchbar__box {
border-radius: 44rpx !important;
}
/deep/.uni-searchbar__box {
border-radius: 44rpx !important;
}
}
.city-box {
position: absolute;
right: 30rpx;
display: inline-flex;
align-items: center;
margin-left: 32rpx;
padding: 8rpx 18rpx 8rpx 16rpx;
border-radius: 30px;
background: #fff;
image {
width: 32rpx;
height: 32rpx;
margin-right: 4rpx;
}
.city-box {
position: absolute;
right: 30rpx;
display: inline-flex;
text {
color: #333;
font-size: 28rpx;
}
}
.nav-box {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 36rpx 24rpx;
background: #fff;
overflow-x: auto;
.item {
display: flex;
flex-direction: column;
align-items: center;
margin-left: 32rpx;
padding: 8rpx 18rpx 8rpx 16rpx;
border-radius: 30px;
background: #fff;
margin-left: 70rpx;
image {
width: 32rpx;
height: 32rpx;
margin-right: 4rpx;
width: 64rpx;
height: 64rpx;
}
text {
color: #333;
font-size: 28rpx;
.nav {
color: #666;
font-size: 24rpx;
line-height: 34rpx;
font-weight: bold;
}
}
.nav-box {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 36rpx 24rpx;
background: #fff;
overflow-x: auto;
.item:first-child {
margin-left: 0;
}
}
.item {
display: flex;
flex-direction: column;
align-items: center;
margin-left: 70rpx;
::-webkit-scrollbar {
display: none;
}
image {
width: 64rpx;
height: 64rpx;
}
.list-box {
padding: 20rpx 32rpx;
.nav {
color: #666;
font-size: 24rpx;
line-height: 34rpx;
font-weight: bold;
}
}
.item:first-child {
margin-left: 0;
}
.type-name {
position: relative;
font-size: 28rpx;
line-height: 40rpx;
color: #080F1A;
}
::-webkit-scrollbar {
display: none;
.type-name::before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 10rpx;
background: rgba(253, 104, 93, 0.39);
z-index: -1;
}
.list-box {
padding: 20rpx 32rpx;
.list {
margin-top: 20rpx;
.type-name {
.cover {
width: 332rpx;
height: 332rpx;
vertical-align: middle;
}
.icon {
width: 22rpx;
height: 22rpx;
margin-right: 10rpx;
vertical-align: middle;
}
.logo {
width: 36rpx;
height: 36rpx;
vertical-align: middle;
margin: 0 8rpx;
border-radius: 50%;
}
.cover-box {
position: relative;
font-size: 28rpx;
line-height: 40rpx;
color: #080F1A;
height: auto;
.my-mask {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 56rpx;
line-height: 56rpx;
box-sizing: border-box;
padding: 0 24rpx;
background: linear-gradient(rgba(51, 51, 51, 0), rgba(0, 0, 0, 1));
color: #fff;
font-size: 22rpx;
}
}
.type-name::before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 10rpx;
background: rgba(253, 104, 93, 0.39);
z-index: -1;
}
.list {
margin-top: 20rpx;
.cover {
width: 332rpx;
height: 332rpx;
vertical-align: middle;
}
.icon {
width: 22rpx;
height: 22rpx;
margin-right: 10rpx;
vertical-align: middle;
}
.logo {
width: 36rpx;
height: 36rpx;
vertical-align: middle;
margin: 0 8rpx;
border-radius: 50%;
}
.cover-box {
position: relative;
height: auto;
.my-mask {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 56rpx;
line-height: 56rpx;
box-sizing: border-box;
padding: 0 24rpx;
background: linear-gradient(rgba(51, 51, 51, 0), rgba(0, 0, 0, 1));
color: #fff;
font-size: 22rpx;
}
}
.more-t {
margin: 10rpx;
}
.more-t {
margin: 10rpx;
}
}
}
}
</style>
+20 -9
View File
@@ -17,18 +17,22 @@
</view>
<view class="more-t">{{ item.content }}</view>
<view class="flex ai-center bottom">
<image
v-if="item.logo"
:src="item.logo"
<view
class="logo"
mode="scaleToFill"
></image>
<image
>
<image
v-if="item.logo"
:src="item.logo"
class="logo"
mode="scaleToFill"
></image>
<image
v-else
:src="webUrl + '/20230609145651814148.png'"
class="logo"
/>
<text class="one-t">{{ item.name }}</text>
</view>
<text class="one-t v12-ml-1">{{ item.name }}</text>
</view>
</view>
</template>
@@ -51,6 +55,12 @@ export default {
}
</script>
<style scoped lang="less">
.logo {
width: 46rpx;
height: 46rpx;
vertical-align: middle;
border-radius: 50%;
}
.cover-box-wrap {
margin: 20rpx 0 0 0;
.cover-box {
@@ -73,8 +83,8 @@ export default {
vertical-align: middle;
}
.logo {
width: 36rpx;
height: 36rpx;
width: 46rpx;
height: 46rpx;
vertical-align: middle;
margin: 0 8rpx;
border-radius: 50%;
@@ -105,6 +115,7 @@ export default {
}
.bottom {
margin: 0 0 20rpx 0;
align-content: center;
}
}
</style>
+402 -38
View File
@@ -3,11 +3,12 @@
<view class="top-box">
<view class="v12-justify-start v12-align-center">
<view class="flex jc-end">
<view class="city-box" @click="goCity('cloud')">
<view class="city-box" @click="goCity('cloud')" id="city-box">
<text style="white-space:nowrap; width: 90rpx" class="v12-primary-text one-t">{{ cityName }}</text>
<image :src="webUrl+'/orderIcon/map.png'" mode="scaleToFill"></image>
<image :src="webUrl+'/icon/fun-city-change.png'" mode="scaleToFill"></image>
</view>
</view>
<view class="search-box v12-primary-border flex jc-between ai-center">
<input
v-model="name"
@@ -26,20 +27,54 @@
</view>
</view>
</view>
<scroll-view class="type-box flex" scroll-x enable-flex>
<view
v-for="(item, index) in typeList"
:key="index"
:class="{
'active': typeIndex === index
}"
class="item flex-0 flex flex-col jc-center ai-center"
@click="tapType(index)"
>
<image :src="item.icon" mode="scaleToFill"/>
<view class="name">{{ item.name }}</view>
<view class="v12-pa-2" style="position: relative">
<view class="v12-radius-20 v12-px-2 v12-py-1 tip-wrap v12-align-center v12-justify-between">
<view class="v12-align-center">
<image
class="map-icon"
mode="scaleToFill"
:src="webUrl + '/orderIcon/map_white.png'"
></image>
<text style="width: 95%" class="v12-font-24 v12-white-text">定位显示你在 {{ cityName }} 点击可切换其他城市</text>
</view>
<view @click="goCity('cloud')" class="qh-btn v12-white v12-radius-10 v12-font-24 v12-font-bold v12-dark-text v12-px-2">点击切换</view>
</view>
</scroll-view>
</view>
<view>
<view class="type-box flex" id="type-box">
<view class="first-box">
<view class="first-box__inner">
<view
:class="{
'active': typeIndex === -1
}"
class="item flex-0 flex flex-col jc-center ai-center"
@click="tapType(-1)"
>
<image :src="townConfig.icon" mode="scaleToFill"/>
<view class="name">{{ townConfig.label }}</view>
</view>
</view>
</view>
<!-- <view style="padding-left: 0" class="type-box flex " >
</view> -->
<view class="scroll-box">
<view
v-for="(item, index) in typeList"
:key="index"
:class="{
'active': typeIndex === index
}"
class="item flex-0 flex flex-col jc-center ai-center"
@click="tapType(index)"
>
<image :src="item.icon" mode="scaleToFill"/>
<view class="name">{{ item.name }}</view>
</view>
</view>
</view>
</view>
</view>
<view class="type-banner-wrap">
<view v-if="currType.titleImage" class="title">
@@ -71,9 +106,26 @@
</swiper>
</view>
</view>
<view class="body">
<view>
<view class="body" v-if="typeIndex === -1" id="body1">
<view class="town-card" v-for="(town, i) in townList" :key="i" @click="toTown(town)">
<!-- <view class="town-title">{{ town.name }}</view> -->
<image :src="town.frontImage" mode="scaleToFill"/>
<view class="v12-primary enter-btn">点击进入
<view class="icon-box"><u-icon name="arrow-rightward" color="#fff" size="8"></u-icon></view>
</view>
</view>
<view class="v4-nodata" v-if="townList.length === 0">
<image src="@/static/images/img_nodata.png" mode="scaleToFill"/>
<view class="text">暂无数据</view>
</view>
</view>
<view class="body" v-else>
<view class="v12-justify-between v12-align-center">
<text class="v12-font-bold" v-if="currType.carousel">推荐</text>
<view class="v12-dark1-text v12-font-28 v12-align-center" @click="handleRefresh">
<u-icon name="reload"></u-icon>
换一换
</view>
</view>
<view v-if="isLoad">
<view v-if="hotelList.length > 0">
@@ -110,35 +162,42 @@
:show-avatar="false"
/>
</view>
<FunctionGuide @hide="setGuide('findFunIndex')" :maxStep="3" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
<xdd-tabbar :curr-index="4" />
</view>
</template>
<script>
import { getHotelList, getHotelTypeList } from "@/api/inn.js"
import { getHotelList, getHotelTypeList, getAncientTownIcon, getAncientTownList } from "@/api/inn.js"
import { getCurAddress, getLocation } from "@/utils/common"
import FunHotelItem from './components/HotelItem'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import XddTabbar from '@/components/xdd-tabbar'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
components: {
FunHotelItem,
XddTabbar
XddTabbar,
FunctionGuide
},
mixins: [pageListenMixins],
mixins: [pageListenMixins, GuideMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
name: '',
page: 1,
typeList: [],
typeIndex: 0,
typeIndex: -1,
// 当前选中的类型
currType: {},
cityName: '',
hotelList: [],
isLoad: false,
pageKeyId: Object.freeze('findFunIndex'),
isNext: false
isNext: false,
townConfig: {},
townList: [],
randomSeed: null
}
},
computed: {
@@ -155,23 +214,24 @@ export default {
// 后端接口结构需要调整下,需要补充总页数,前端可判断当前页数大于等于总页数则不发送网络请求
if(this.isNext) {
this.page++
this.fetchList()
const random = this.randomSeed ? 1 : 0
this.fetchList(random, this.randomSeed)
}
},
onLoad() {
this.currType = {}
getHotelTypeList().then(({data}) => {
this.typeList = data
this.currType = this.typeIndex === -1 ? {} : data[this.typeIndex]
this.getMapData()
})
this.getIcon()
this.queryGuide('findFunIndex')
},
onShow() {
const memCityName = uni.getStorageSync('cityName')
this.page = 1
this.currType = {}
this.typeIndex = 0
// this.typeIndex = 0
this.name = ''
getHotelTypeList().then(({data}) => {
this.typeList = data
this.currType = data[this.typeIndex]
this.getMapData()
})
if (memCityName.length) {
this.cityName = memCityName
uni.removeStorageSync('cityName')
@@ -190,6 +250,196 @@ export default {
}
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.getElementData('#city-box', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/寻趣味/Group 1/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '390rpx',
top: 0*2+'rpx',
left: res.width*2+'rpx',
height: '162rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 1/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 80*2+'rpx',
left: -60*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 1/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 80*2+'rpx',
left: 200*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
if(this.functionGuideData.step == 2) {
this._step = this.functionGuideData.step
this.getElementData('#type-box', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/寻趣味/Group 2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '504rpx',
top: 170*2+'rpx',
left: 0+'rpx',
right: 0,
margin: 'auto',
height: '191rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 270*2+'rpx',
left: -160*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 270*2+'rpx',
left: 160*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${(res.height-20)}px`,
}
})
})
return
}
if(this.functionGuideData.step == 3) {
this._step = this.functionGuideData.step
this.getElementData('#body1', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/寻趣味/Group 3/Group 3-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '290rpx',
top: 90*2+'rpx',
left: 0,
right: 0,
margin: 'auto',
height: '165rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 3/Group 3-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '97rpx',
top: 60*2+'rpx',
left: 60*2+'rpx',
right: 0,
margin: 'auto',
height: '55rpx',
},
isBtn: 'jump'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: (res.top) + 'px',
left: res.left+10 + 'px',
width: `${res.width-20}px`,
height: `${res.height-20}px`,
}
})
})
return
}
return
}
},
handleRefresh() {
uni.showLoading()
this.page = 1
this.hotelList = []
this.fetchList(1, this.randomSeed)
},
toTown(town) {
uni.navigateTo({
url: `/pages/town/index?id=${town.id}`
})
},
getIcon() {
getAncientTownIcon().then(res => {
this.townConfig = res.data
})
},
goCity() {
uni.navigateTo({
url: `/pages/chose-city/chose-city?type=2&city=${this.cityName}`
@@ -212,9 +462,11 @@ export default {
}
},
tapType(index) {
if (this.typeIndex === index) return
this.typeIndex = index
this.currType = this.typeList[index]
this.randomSeed = null
this.currType = index === -1 ? {} : this.typeList[index]
this.name = ''
this.search()
},
@@ -224,19 +476,35 @@ export default {
this.hotelList = []
this.fetchList()
},
fetchList() {
fetchList(random = 0, randomSeed) {
if(this.typeIndex === -1) {
const params = {
cityName: this.cityName,
page: 1,
limit: 999
}
getAncientTownList(params).then(res => {
this.townList = res.data.records
})
return
}
const param = {
page: this.page,
type: this.typeList[this.typeIndex].id,
cityName: this.cityName
cityName: this.cityName,
random: random,
randomSeed: this.page > 1 ? randomSeed : null
}
const name = this.name.trim()
if (name.length > 0) {
param.name = name
}
getHotelList(param).then(res => {
const { success, data } = res
const { success, data, msg } = res
if (success) {
if(random === 1) {
this.randomSeed = msg
}
for (let i = 0; i < data.length; i++) {
const cover = data[i].cover
data[i].hide = true
@@ -257,6 +525,7 @@ export default {
}
}).finally(() => {
this.isLoad = true
uni.hideLoading()
})
},
typeBannerItemClick(item) {
@@ -267,6 +536,101 @@ export default {
}
</script>
<style scoped lang="less">
.map-icon{
width: 30rpx;
height: 30rpx;
margin-right: 5rpx;
}
.qh-btn{
padding-top: 4rpx;
padding-bottom: 4rpx;
// border: thin dashed #999;
white-space: nowrap;
}
.tip-wrap{
background: #AAAEB3;
position: relative;
align-items: self-start !important;
&::before{
position: absolute;
content: '';
border-left: 15rpx solid transparent;
border-right: 15rpx solid transparent;
border-top: 20rpx solid transparent;
border-bottom: 20rpx solid #AAAEB3;
top: -30rpx;
left: 10%;
}
}
.icon-box{
border: 1rpx solid #fff;
border-radius: 100%;
width: 16rpx;
height: 16rpx;
margin-left: 5rpx;
padding: 2rpx;
}
.enter-btn{
color: #fff;
width: fit-content;
display: flex;
align-items: center;
padding: 10rpx 16rpx;
position: absolute;
right: 0;
bottom: 0;
border-radius: 30rpx 0;
font-size: 24rpx;
}
.town-title{
border-radius: 100rpx;
/* border-color: #333; */
// mix-blend-mode: difference;
width: fit-content;
padding: 5rpx 20rpx;
border: 1rpx solid #fff;
color: #fff;
position: absolute;
margin: auto;
top: 20rpx;
left: 0;
right: 0;
}
.town-card{
width: 100%;
height: 400rpx;
background: #fff;
border-radius: 30rpx;
position: relative;
overflow: hidden;
margin-bottom: 30rpx;
image{
width: -webkit-fit-content;
width: inherit;
height: -webkit-fit-content;
height: inherit;
}
}
.first-box{
padding-right: 15rpx;
position: sticky;
left: 0;
background-color: #f5f5f5;
z-index: 9;
}
.first-box__inner{
padding: 10rpx;
background: #fff;
border-radius: 30rpx;
}
.scroll-box{
display: flex;
height: fit-content;
background: #fff;
overflow-x: scroll;
padding: 10rpx;
border-radius: 30rpx;
}
.search-btn{
position: absolute;
top: 2rpx;
@@ -308,7 +672,7 @@ export default {
height: 200rpx;
box-sizing: border-box;
white-space: nowrap;
padding: 20rpx 20rpx 0 20rpx;
padding: 0rpx 20rpx 0 20rpx;
.item {
width: 154rpx;
@@ -340,7 +704,7 @@ export default {
}
.body {
padding: 20rpx 20rpx;
padding: 0 20rpx 20rpx;
background: #f5f5f5;
}
+9 -3
View File
@@ -1,13 +1,13 @@
<template>
<view>
<view class="culture v12-d-grid-columns-2">
<view class="img-item " v-for="(item, index) in list" :key="index">
<view class="img-item " v-for="(item, index) in list" :key="index" @click="viewImg(item)">
<image class="img-item" :src="item" mode="widthFix|heightFix" lazy-load="false"></image>
</view>
</view>
<image
v-if="list.length === 0"
:src="webUrl + '/20231023131208675588.png'"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
@@ -39,9 +39,15 @@ export default {
this.getData()
},
methods: {
viewImg(item) {
uni.previewImage({
current: item, // 当前显示图片的http链接
urls: this.list || [] // 需要预览的图片http链接列表
})
},
getData() {
getCulture({landmarkDataId: this.landmarkDataId}).then(res => {
this.list = res.data.cultureImages
this.list = res.data.cultureImages || []
})
}
}
+2
View File
@@ -21,6 +21,7 @@
<view class="flex jc-between ai-center">
<text class="price">{{ item.price }}</text>
<image
@click.stop="$emit('add', item)"
:src="webUrl + '/home/icon-cart.png'"
class="btn"
/>
@@ -70,6 +71,7 @@ export default {
}
.list-box {
margin-top: 24rpx;
padding: 0 20rpx;
.item {
position: relative;
width: 344rpx;
+47 -4
View File
@@ -20,13 +20,25 @@
</view>
</view>
<view class="info-item-body">
<video
v-if="item.type === 2"
@play="infoItemViewClick(item, index)"
play-btn-position="center"
:show-fullscreen-btn="false"
class="video-item v12-mt-0"
:src="item.video"
controls
:id="'video-item' + index"
:poster="item.video + '?vframe/jpg/offset/1'"></video>
<img-box
v-else
:imgList="item.images"
:num="item.images.length"
:img-radius="10"
style="width: 100%"
@click="infoItemViewClick(item)"
/>
</view>
<view class="info-item-bottom">
<view class="time">
@@ -72,11 +84,12 @@
:src="webUrl + '/home/no-data-bg.png'"
mode="widthFix"
class="no-data-loadend"
style="width: 100%;"
/>
</view>
<image
v-if="infoArray.length === 0"
:src="webUrl + '/20231023131208675588.png'"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
@@ -100,7 +113,8 @@ export default {
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
infoArray: []
infoArray: [],
videoPlayers:[]
}
},
watch: {
@@ -121,7 +135,7 @@ export default {
limit: 9999
}
getNews(params).then(res => {
this.infoArray = res.data.records
this.infoArray = res.data.records || []
})
},
likeInfoItemHandle(item, index, value, voValue) {
@@ -136,7 +150,27 @@ export default {
}
})
},
infoItemViewClick(item) {
infoItemViewClick(item, index) {
if(item.type === 2) {
// const coverCtx = uni.createVideoContext('coverVideo', this)
// coverCtx.pause()
const playerId = 'video-item' + index
if(this.videoPlayers.includes(playerId)) {
this.videoPlayers.forEach(player => {
if(player === playerId) return
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
} {
this.videoPlayers.push(playerId)
this.videoPlayers.forEach(player => {
if(player === playerId) return
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
}
this.$emit('video')
}
uni.$u.debounce(() => {
hadView({ landmarkNewsId: item.id }).finally(() => {
this.infoArray.map(info => {
@@ -151,6 +185,15 @@ export default {
};
</script>
<style lang="scss" scoped>
.video-item {
width: 100%;
height: 400rpx;
border-radius: 10rpx;
}
.info-wrapper{
padding: 20px 10px;
}
.info-item + .info-item {
margin: 22rpx 0 0 0;
}
+15 -12
View File
@@ -3,19 +3,19 @@
<view class="list-item" v-for="(item, index) in currentList" :key="index" @click="fileItemClick(item)">
<view class="v12-justify-start v12-align-center">
<view class="v12-font-bold v12-font-28">·</view>
<view class="item-title one-t">{{ item.title }}</view>
<view class="item-title">{{ item.title }}</view>
</view>
<view class="item-action v12-dark"><u-icon name="arrow-right" color="#fff" size="8"></u-icon></view>
</view>
<view class="more-wrap" v-if="isMore ? isMore : list.length > 3">
<view class="more-btn v12-primary v12-align-center" @click="showMore">
{{ isMore ? '收起' : '查看更多' }}
<view class="more-wrap">
<view class="more-btn v12-primary v12-align-center" @click="showMore" v-if="list.length > 0">
{{ isMore ? '查看更多' : '查看更多' }}
<view class="item-action v12-white"><u-icon name="arrow-right" color="#C52733 " size="12"></u-icon></view>
</view>
</view>
<image
v-if="list.length === 0"
:src="webUrl + '/20231023131208675588.png'"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
@@ -56,7 +56,7 @@ export default {
limit: 99999
}
getPorjectPolicyFiles(params).then(res => {
this.list = res.data.records
this.list = res.data.records || []
if(this.isMore) {
this.currentList = this.list
} else {
@@ -65,12 +65,14 @@ export default {
})
},
showMore() {
this.isMore = !this.isMore
if(this.isMore) {
this.currentList = this.list
} else {
this.currentList = this.list.filter((item, index) => index < 3)
}
// this.isMore = !this.isMore
// if(this.isMore) {
// this.currentList = this.list
// } else {
// this.currentList = this.list.filter((item, index) => index < 3)
// }
uni.navigateTo({ url: `/pages/home/searchPage?id=${this.landmarkDataId}&type=2` })
},
fileItemClick(file) {
const url = file.attachment || ''
@@ -130,6 +132,7 @@ export default {
font-size: 24rpx;
color: #333;
margin-left: 10rpx;
max-width: 520rpx;
}
.log-img{
width: 68rpx;
+19 -4
View File
@@ -17,7 +17,13 @@
'no-actived-3': actived === 3 && item.value === 2,
'no-actived-4': actived === 2 && item.value === 3,
}"
>{{ item.name }}</view>
>
<image class="tab-icon" :src="webUrl + '/orderIcon/' + item.icon" mode="aspectFit|aspectFill|widthFix"></image>
{{ item.name }}
<!-- <view>
<view>{{ item.name }}</view>
</view> -->
</view>
</view>
</view>
<view
@@ -53,11 +59,12 @@ export default {
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
actived: 1,
tabs: [
{name: '企业推荐', value: 1},
{name: '政策', value: 2},
{name: '服务', value: 3},
{name: '企业推荐', value: 1, icon: 'qytj.png'},
{name: '政策', value: 2, icon: 'zc.png'},
{name: '服务', value: 3, icon: 'fw.png'},
]
}
},
@@ -70,6 +77,11 @@ export default {
</script>
<style lang="scss" scoped>
.tab-icon{
height: 30rpx;
width: 30rpx;
margin-right: 10rpx;
}
.fit-box-inner{
background: #f0f0f0;
width: initial;
@@ -106,6 +118,9 @@ export default {
background: #f0f0f0;
width: inherit;
height: inherit;
display: flex;
justify-content: center;
align-items: center
}
}
.no-actived-1{
+3 -2
View File
@@ -20,7 +20,7 @@
</view>
<image
v-if="list.length === 0"
:src="webUrl + '/20231023131208675588.png'"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
@@ -57,7 +57,7 @@ export default {
methods: {
getData() {
getPorjectRecommend({landmarkDataId: this.landmarkDataId}).then(res => {
this.list = res.data
this.list = res.data || []
if(this.isMore) {
this.currentList = this.list
} else {
@@ -132,6 +132,7 @@ export default {
font-size: 26rpx;
color: #333;
margin-left: 20rpx;
max-width: 180rpx;
}
.log-img{
width: 68rpx;
+34 -10
View File
@@ -4,27 +4,28 @@
<map
:longitude="info.longitude"
:latitude="info.latitude"
style="width: 100%;height: 400rpx; border-radius: 20rpx;"
:markers="[{latitude: info.latitude,longitude: info.longitude,width: 20, height: 25, iconPath: webUrl + '/page/qianxian/icon-location.png'}]"
style="width: 100%;height: 100%; border-radius: 20rpx;"
/>
</view>
<view class="v12-mt-3 info-wrap">
<view>
<view class="v12-font-32 v12-font-bold v12-mb-2">{{ info.name }}</view>
<view class="v12-font-24 v12-mb-1 v12-dark1-text">办公时间:{{ info.officeTime }}</view>
<view class="v12-font-24 v12-mb-1 v12-dark1-text">{{ info.address }}</view>
<view class="v12-font-32 v12-font-bold v12-mb-2">{{ info.name || '' }}</view>
<view class="v12-font-24 v12-mb-1 v12-dark1-text">办公时间:{{ info.officeTime || '' }}</view>
<view class="v12-font-24 v12-mb-1 v12-dark1-text">{{ info.address || '' }}</view>
</view>
<view class="action-wrap">
<view>
<view @click="showLocation">
<view>
<image :src="webUrl + '/page/qianxian/icon-addr.png'" class="img" />
</view>
<view class="text-center">导航</view>
</view>
<view>
<view @click="call">
<view>
<image :src="webUrl + '/page/qianxian/icon-phone.png'" class="img" />
</view>
<view class="text-center">客服</view>
<view class="text-center">咨询</view>
</view>
</view>
</view>
@@ -34,7 +35,7 @@
简介
</view>
<view class="intro-text">
{{ info.intro }}
{{ info.intro || '' }}
</view>
</view>
</view>
@@ -55,6 +56,29 @@ export default {
mounted() {
console.log(this.info);
},
methods: {
showLocation() {
console.log(this.info);
if (!this.info.latitude || !this.info.longitude) {
this.$dialog.error('暂无位置信息')
} else {
uni.openLocation({
latitude: this.info.latitude,
longitude: this.info.longitude
})
}
},
call() {
if (this.info.tel) {
uni.makePhoneCall({
phoneNumber: this.info.tel
})
} else {
this.$dialog.error('电话为空')
}
},
}
}
</script>
@@ -78,8 +102,8 @@ export default {
}
.info-wrap{
display: flex;
justify-content: space-around;
padding: 40rpx 0 0;
justify-content: space-between;
padding: 40rpx 20rpx 0;
}
.service{
position: relative;
+147
View File
@@ -0,0 +1,147 @@
<template>
<view v-if="posterImageStatus" class="poster-first">
<view class="poster-pop">
<img
src="@/static/images/poster-close.png"
mode="widthFix"
class="close"
@click="posterImageClose"
/>
<image
:src="posterImage"
alt="tp"
class="poster-image"
:show-menu-by-longpress="false"
mode="widthFix"
/>
<view class="v12-white-text v12-radius-20 share-btn" @click="saveImg(posterImage)">保存图片</view>
</view>
<view class="mask"></view>
</view>
</template>
<script>
import { getShareImg } from "@/api/product";
export default {
name: "LandMarkShareImg",
data: function () {
return {
posterImage: "",
posterImageStatus: false,
};
},
methods: {
saveImg(url) {
uni.showLoading({
mask:true,
})
uni.downloadFile({
url: url, // 文件的下载地址
success(res) {
if (res.statusCode === 200) {
let tempFilePath = res.tempFilePath; // 临时文件路径
uni.saveImageToPhotosAlbum({
filePath: tempFilePath,
success:(success)=> {
uni.showToast({
title: "保存成功",
icon: "none",
mask: true,
});
},
fail(err) {
uni.showToast({
title: "保存失败,请重新尝试",
icon: "none",
mask: true,
});
},
})
}
},
});
},
posterImageClose() {
this.posterImageStatus = false;
this.$emit("setPosterImageStatus");
},
savePosterPath(id) {
uni.showLoading({ title: "海报生成中", mask: true });
getShareImg(id)
.then((res) => {
this.posterImage = res.data;
this.posterImageStatus = true;
})
.finally(() => {
uni.hideLoading();
});
},
},
};
</script>
<style scoped lang="less" lang="less">
.share-btn{
text-align: center;
padding: 20rpx 0;
font-size: 28rpx;
background: #ff564a;
}
.poster-first {
overscroll-behavior: contain;
}
.poster-pop {
width: 6 * 100rpx;
height: 8 * 100rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
z-index: 99;
top: 50%;
margin-top: -4.6 * 100rpx;
}
.poster-pop .canvas {
background-color: #ffffff;
height: 8 * 100rpx;
}
.poster-pop .poster-image {
width: 100%;
height: auto;
border-radius: 20rpx;
}
.poster-pop .close {
width: 0.46 * 100rpx;
height: 0.75 * 100rpx;
position: fixed;
right: 0;
top: -0.73 * 100rpx;
display: block;
}
.poster-pop .save-poster {
background-color: #df2d0a;
font-size: 0.22 * 100rpx;
color: #fff;
text-align: center;
height: 0.76 * 100rpx;
line-height: 0.76 * 100rpx;
width: 100%;
margin-top: -0.04 * 100rpx;
}
.poster-pop .keep {
color: #fff;
text-align: center;
font-size: 0.25 * 100rpx;
margin-top: 0.1 * 100rpx;
}
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 9;
}
</style>
+1169 -79
View File
File diff suppressed because it is too large Load Diff
+194 -9
View File
@@ -3,7 +3,7 @@
<view v-if="isLoad">
<view class="top-wrap">
<view class="top-box">
<view class="nav flex">
<view class="nav flex" id="nav-dibiao">
<view
v-for="(item,index) in navList"
:key="index"
@@ -28,6 +28,7 @@
class="img-map"
/>
</view>
<view class="share-btn" @click="toShare"><u-icon name="share-square" color="#C52733"></u-icon>分享给好友</view>
</view>
</view>
</view>
@@ -44,7 +45,7 @@
<view @click="handleTab(item.value)" :class="{ 'tab-actived' : item.value === actived }" class="tab-item" v-for="(item, index) in tabs" :key="index">{{ item.name }}</view>
</view>
</view>
<view class="list-wrap">
<view class="list-wrap" id="list-wrap">
<view v-if="actived === 1">
<projects :landmarkDataId="landmarkDataId" :info="mapData.serviceInfo"></projects>
</view>
@@ -55,13 +56,16 @@
<information :landmarkDataId="landmarkDataId"></information>
</view>
<view v-if="actived === 4">
<goods :goods="goods" v-if="goods.length > 0"></goods>
<image
<goods :goods="goods" v-if="goods.length > 0" @add='addToCart($event, "productId")'></goods>
<!-- <image
v-if="isCompleteLoadGood"
:src="webUrl + '/home/no-data-bg.png'"
mode="widthFix"
class="loadend"
/>
/> -->
<view class="v12-px-6" >
<u-divider :text="goods.length === 0 ? ' · 暂无数据 · ' : ' · 已经到底啦 · '" textPosition="center"></u-divider>
</view>
</view>
</view>
@@ -71,6 +75,16 @@
v-else
:show-avatar="false"
/>
<shareImg ref="shareImg"></shareImg>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
/>
<FunctionGuide @hide="setGuide('landmarkGoodsIndex')" :maxStep="2" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -82,18 +96,26 @@ import {
} from "@/api/product"
import goods from "./components/goods.vue"
import { pageListenMixins } from '@/mixins/pageListenMixins'
import goCartMixin from '@/mixins/goCartMixins'
import projects from './components/projects.vue'
import culture from "./components/culture.vue"
import information from "./components/information.vue"
import shareImg from "./components/shareImg.vue"
import ProductWindow from '@/components/ProductWindow'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'LandMarkPage',
components: {
goods,
projects,
culture,
information
information,
shareImg,
ProductWindow,
FunctionGuide
},
mixins: [pageListenMixins],
mixins: [pageListenMixins, goCartMixin, GuideMixins],
data() {
return {
actived: 1,
@@ -112,7 +134,9 @@ export default {
mapData: null,
goods: [],
isCompleteLoadGood: false,
pageKeyId: Object.freeze('landmarkGoodsIndex')
pageKeyId: Object.freeze('landmarkGoodsIndex'),
posterImageStatus: false,
sceneId: null
}
},
computed: {
@@ -120,8 +144,15 @@ export default {
return this.navList[this.navIndex] ? this.navList[this.navIndex]['id'] : null
}
},
onLoad() {
onLoad(opts) {
console.log('进入地标页');
console.log(opts, '地标opts');
if(opts && opts.scene) {
console.log(opts.scene, 'opts.scene');
this.sceneId = decodeURIComponent(opts.scene).split('&')[0].split('=')[1]
}
this.getNavList()
this.queryGuide('landmarkGoodsIndex')
},
onHide() {
this.pageToHideHandle()
@@ -134,12 +165,149 @@ export default {
this.fetchGoods()
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.getElementData('#nav-dibiao', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/地标好物/Group1/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '495rpx',
top: 50*2+'rpx',
left: 0,
right: 0,
margin: 'auto',
height: '194rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/地标好物/Group1/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 160*2+'rpx',
left: -160*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/地标好物/Group1/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 160*2+'rpx',
left: 160*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
if(this.functionGuideData.step == 2) {
this._step = this.functionGuideData.step
this.getElementData('#list-wrap', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/地标好物/Group2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '450rpx',
top: 300*2+'rpx',
left: 0,
right: 0,
margin: 'auto',
height: '174rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/地标好物/Group2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 280*2+'rpx',
left: -120*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/地标好物/Group2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 280*2+'rpx',
left: 180*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
uni.pageScrollTo({
scrollTop: res.top,
duration: 300
})
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
bottom: 0,
left: res.left + 'px',
width: `${res.width}px`,
height: `${(res.height) + 41}px`,
}
})
})
return
}
return
}
},
toShare() {
this.$refs.shareImg.savePosterPath(this.landmarkDataId)
},
handleTab(value) {
this.actived = value
},
getNavList() {
getProvinceList().then(({data}) => {
this.navList = data
if(this.sceneId) {
this.navIndex = this.navList.map(e => +e.id).indexOf(+this.sceneId)
console.log(this.navIndex, 'navIndex');
}
this.changeNav(this.navIndex)
})
},
@@ -181,6 +349,19 @@ export default {
</script>
<style scoped lang="less">
.share-btn{
color: #C52733;
background: rgba(211,92,101,0.5);
font-size: 24rpx;
width: fit-content;
padding: 8rpx 10rpx;
border-radius: 20rpx 0 0 20rpx;
position: absolute;
right: 0;
top: 80%;
display: flex;
align-items: center;
}
.tabs-wrap{
display: flex;
justify-content: space-around;
@@ -204,6 +385,7 @@ export default {
}
.pkg-product-land-mark {
background: #f0f0f0;
min-height: 100vh;
.top-box {
border-radius: 20rpx;
background-color: #fff;
@@ -267,4 +449,7 @@ export default {
margin-bottom: 60rpx;
}
}
.loadend {
width: 100%;
}
</style>
+172
View File
@@ -0,0 +1,172 @@
<template>
<view class="new-zone-page">
<view class="zone-title">
<rich-text :nodes="details.title"></rich-text>
</view>
<view class="banner-zone v12-mt-2">
<image class="banner-zone" :src="bannerImage" ></image>
<!-- <swiper :current="current" interval="3000" circular style="height:760rpx">
<swiper-item v-for="(item, index) in details.newProducts" :key="index">
</swiper-item>
</swiper> -->
<view class="swiper-wrap">
<swiper @change="handleChange" style="height: 100%;" autoplay circular next-margin="460rpx" interval="4000">
<swiper-item v-for="(item, index) in details.newProducts" :key="index" @click="toGoods(item)">
<view class="new-card" :class="{'is-actived': current == index}">
<image :src="item.productCover" class="new-card-img" mode="heightFix|widthFix"></image>
<view class="box-emp"></view>
<view class="new-info">
<view class="v12-font-26 one-t" style="width: 100px;text-align:center">{{ item.productTitle }}</view>
<view class="v12-font-bold">
<text></text>
<text class=" v12-font-36">{{ item.productPrice }}</text>
</view>
<view class="buy-btn">即刻选购</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
<view class="v12-mt-2 v12-align-center">
<view class="primary-title" v-if="details.contentTitle">
{{ details.contentTitle }}
<view class="title-line"></view>
</view>
<view class="secondary-title v12-ml-2" v-if="details.contentSubTitle">
{{ details.contentSubTitle }}
</view>
</view>
<view class="cover-img v12-mt-2" v-for="(item, index) in details.contents" :key="index" @click="toGoods(item)">
<image :src="item.contentImage" class="cover-img" mode="heightFix|widthFix"></image>
</view>
</view>
</template>
<script>
import { queryNewZone } from '@/api/activity'
export default{
data() {
return {
details: {},
current: 0,
}
},
onLoad() {
queryNewZone().then(res => {
this.details = res.data
})
},
computed: {
bannerImage() {
return this.details.newProducts && this.details.newProducts[this.current] && this.details.newProducts[this.current].bannerImage
}
},
methods: {
handleChange(e) {
this.current = e.detail.current
},
toGoods(item) {
uni.navigateTo({
url: `/pages/shop/GoodsCon/index?id=${item.productId}`
})
}
}
}
</script>
<style lang="scss" scoped>
.new-info{
display: flex;
align-items: center;
flex-direction: column;
}
.box-emp{
width: 100%;
height: 85rpx;
}
.buy-btn{
border-radius: 100px;
width: fit-content;
color: #fff;
background: #C52733;
font-size: 28rpx;
padding: 4rpx 20rpx;
}
.swiper-wrap{
position: absolute;
width: 100%;
height: 400rpx;
left: 20rpx;
bottom: 40rpx;
}
.new-card{
width: 220rpx;
height: 240rpx;
background: #fff;
border-radius: 20rpx;
position: absolute;
bottom: -17rpx;
transition: all ease-in-out 0.3s;
scale: 0.85;
left: 15rpx;
}
.is-actived{
// width: 225rpx;
// height: 260rpx;
bottom: 0;
scale: 1;
left: 0;
}
.cover-img{
width: 706rpx;
height: 400rpx;
border-radius: 20rpx;
}
.new-card-img{
position: absolute;
width: 150rpx;
height: 150rpx;
top: -75rpx;
left: 0;
right: 0;
margin: auto;
border-radius: 50%;
}
.primary-title{
width: fit-content;
position: relative;
font-size: 34rpx;
color: #333333;
font-weight: 800;
}
.secondary-title{
font-family: Source Han Sans SC;
font-weight: 500;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
}
.title-line{
width: 100%;
height: 6rpx;
background: linear-gradient(to right, #C52733 0%, rgba(202,56,67,0.92) 51%, rgba(255,255,255,0) 100%);
border-radius: 6rpx;
position: absolute;
bottom: 3rpx;
}
.new-zone-page{
min-height: 100vh;
background-color: #fff;
padding: 20rpx;
}
.banner-zone{
width: 706rpx !important;
height: 760rpx !important;
border-radius: 20rpx !important;
position: relative !important;
}
</style>
+135
View File
@@ -0,0 +1,135 @@
<template>
<view class="list-page">
<view class="v12-mb-3">
<u-search
placeholder="请输入关键词查询"
v-model="keyword"
shape="round"
:show-action="false"
height="72rpx"
@search="handleSearch"
bg-color="#fff">
</u-search>
</view>
<view v-if="isLoad" class="file-list">
<view
v-for="(file, fileIndex) in currentList"
:key="fileIndex"
class="file-item"
@click="fileItemClick(file)"
>
<view class="name more-t">
·&nbsp;&nbsp;{{ file.title }}
</view>
<image
:src="webUrl + '/page/qianxian/icon-05.png'"
class="icon"
/>
</view>
<view v-if="currentList.length === 0" class="no-data-txt">
暂无数据~
</view>
</view>
<goo-skeleton v-else />
</view>
</template>
<script>
import {
getPorjectPolicyFiles,
} from "@/api/product"
import { pageListenMixins } from '@/mixins/pageListenMixins'
export default {
name: 'searchPage',
mixins: [pageListenMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
isLoad: false,
pageKeyId: '',
list: [],
keyword: '',
currentList: []
}
},
onLoad(options) {
const id = options.id
this.getListReq(id)
},
methods: {
handleSearch() {
this.currentList = this.list.filter(item => item.title.indexOf(this.keyword) > -1)
},
getListReq(id) {
const params = {
landmarkDataId : id,
page: 1,
limit: 9999
}
getPorjectPolicyFiles(params).then(res => {
const { success, data } = res
if (success) {
this.isLoad = true
this.list = data.records || []
this.currentList = [...this.list]
}
})
},
fileItemClick(file) {
const url = file.attachment || ''
if (!url) return
uni.downloadFile({
url,
success: res => {
const filePath = res.tempFilePath
wx.openDocument({
filePath,
fail: (err) => {
console.log(err)
}
})
}
})
}
}
}
</script>
<style scoped lang="less">
.list-page {
min-height: 100vh;
padding: 30rpx;
box-sizing: border-box;
background-color: #f0f0f0;
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
height: 100rpx;
width: 100%;
padding: 0 20rpx;
margin: 0 0 20rpx 0;
border-radius: 20rpx;
box-sizing: border-box;
line-height: 36rpx;
background-color: #fff;
.name {
width: calc(100% - 40rpx);
font-size: 28rpx;
}
.icon {
display: block;
width: 26rpx;
height: 26rpx;
}
}
.loadend {
width: 100%;
}
.no-data-txt {
text-align: center;
line-height: 200rpx;
color: #999;
font-size: 36rpx;
}
}
</style>
+14 -9
View File
@@ -112,6 +112,7 @@ export default {
return {
webUrl:this.$VUE_APP_RESOURCES_URL,
id: "",
index: null,
cartInfo: [],
orderInfo: {},
expressList: [],
@@ -124,6 +125,9 @@ export default {
]
};
},
onLoad(opts) {
this.index = opts.index || 0;
},
watch: {
$yroute(n) {
if (n.name === NAME && this.$yroute.query.id !== this.id) {
@@ -151,16 +155,18 @@ export default {
.catch(err => {
uni.showToast({
title:
err.msg || err.response.data.msg || err.response.data.message,
err.msg ,
icon: "none",
duration: 2000
});
});
},
getExpress() {
console.log(this.id, "this.id");
if (!this.id) {
uni.showToast({
title: err.msg || err.response.data.msg || err.response.data.message,
title: '订单信息错误',
icon: "none",
duration: 2000
});
@@ -169,11 +175,11 @@ export default {
this.loaded = false;
orderDetail(this.id)
.then(res => {
this.orderInfo = {
deliveryId: res.data.deliveryId,
deliveryName: res.data.deliveryName,
deliverySn: res.data.deliverySn
};
console.log(this.index, "this.orderInfo");
const { data } = res;
const current = data.deliveryInfo[+this.index ];
console.log(current, "current");
this.orderInfo = current;
this.getExpressInfo();
// const result = res.data.express.result || {};
// this.cartInfo = res.data.order.cartInfo;
@@ -182,8 +188,7 @@ export default {
})
.catch(err => {
uni.showToast({
title:
err.msg || err.response.data.msg || err.response.data.message,
title: err.msg ,
icon: "none",
duration: 2000
});
+46 -54
View File
@@ -145,7 +145,7 @@
<view class="bnt default" v-if="order.isExtendedDelivery==0"
@click="toDelay(order.orderId)">延长收货
</view>
<view class="bnt default v12-radius-40" @click="goLogistics(order)">查看物流</view>
<!-- <view class="bnt default v12-radius-40" @click="goLogistics(order)">查看物流</view> -->
<view class="bnt bg-color-lightred v12-white v12-primary-text v12-primary-border v12-radius-40" @click="takeOrder(order)">确认收货</view>
</template>
<template v-if="order._status._type == 3">
@@ -246,8 +246,7 @@ export default {
delayId: null,
pageKeyId: Object.freeze('userOrderIndex'),
keyword: '',
_orderId: '',
addressId: '',
_orderId: ''
};
},
components: {
@@ -257,56 +256,49 @@ export default {
},
computed: mapGetters(["userInfo"]),
onShow() {
const _this = this
const chooseAddress = uni.getStorageSync('chooseAddress') || {}
const addressId = chooseAddress.id || ''
//
if (addressId) {
uni.setStorageSync('chooseAddress', {})
uni.showModal({
title:'确定修改地址吗?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success:(success)=>{
if(success.confirm) {
uni.showLoading()
editAddress({
addressId,
orderId: _this._orderId
}).then(res => {
uni.showToast({
icon: 'success',
title: '修改成功!'
})
_this.changeType()
}).finally(() => {
uni.hideLoading()
})
}
},
cancel: () => {
_this.changeType()
},
complete:(complete)=>{
_this._orderId = ''
}
})
} else {
}
},
onLoad() {
this.type = this.type || parseInt(this.$yroute.query.type) || 0;
this.changeType(this.type);
this.getOrderData();
this.getOrderListReq();
uni.$on('chooseAddress', (res) => {
this.addressId = res.id
})
},
onHide() {
this.orderList = [];
this.page = 1;
this.limit = 20;
this.loaded = false;
this.loading = false;
},
watch: {
addressId(val) {
if(val) {
const params = {
addressId: this.addressId,
orderId: this._orderId
}
setTimeout(() => {
uni.showModal({
title:'确定修改地址吗?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success:(success)=>{
if(success.confirm) {
uni.showLoading()
editAddress(params).then(res => {
uni.showToast({
icon: 'success',
title: '修改成功!'
})
}).finally(() => {
uni.hideLoading()
})
}
},
complete:(complete)=>{
this.addressId = ''
this._orderId = ''
},
})
}, 1000)
}
}
},
methods: {
handleBody() {
@@ -487,9 +479,8 @@ export default {
this.changeType(this.type);
},
tabChange(item) {
this.type = item.index
this.$yroute.query.type = this.type
this.changeType();
},
changeType() {
@@ -665,6 +656,7 @@ page {
position: sticky;
top: 0;
background-color: #f5f5f5;
z-index: 54;
}
/deep/ .u-tabs {
position: fixed;
@@ -696,7 +688,7 @@ page {
.address {
margin-left: 4rpx;
color: #FD574B;
color: #C52733;
font-size: 22rpx;
line-height: 36rpx;
}
+126 -82
View File
@@ -8,7 +8,10 @@
<view :class="refundOrder ? 'on' : ''">
<view class="state v12-primary-text v12-font-32 v12-font-bold" v-if="orderInfo.isTickets===1 && orderInfo._status._type == 2">待核销</view>
<view class="state v12-primary-text v12-font-32 v12-font-bold" v-else>{{ getStatus(orderInfo) }}</view>
<view v-if="getStatus(orderInfo)!=='待付款'" class="v12-mt-2 v12-font-24 v12-secondary-dark-text" :class="{'fails-bg': orderInfo._status._type == -3}">{{ orderInfo._status._msg }}</view>
<view v-if="getStatus(orderInfo)!=='待付款'" class="v12-mt-2 v12-font-24 v12-secondary-dark-text" :class="{'fails-bg': orderInfo._status._type == -3}">
<view>{{ orderInfo._status._msg }}</view>
<view v-if="orderInfo._status._type == -3">驳回原因: {{ orderInfo.refundRejectReason }}</view>
</view>
<view class="pending-payments flex ai-center v12-mt-2 v12-font-24 v12-secondary-dark-text" v-else>
<text>需支付{{ orderInfo.payPrice }}</text>
<!-- {{ orderInfo.paymentTimeout }} -->
@@ -25,28 +28,32 @@
</div>
</view>
</view>
<!-- <view class="reject-reason" v-if="orderInfo._status._type==-3 && orderInfo.refundRejectReason">驳回原因{{ orderInfo.refundRejectReason }}</view> -->
<view @click="goLogistics(orderInfo)" class="v12-radius-20 v12-white v12-pa-3 v12-mt-4" v-if="orderInfo._status._type == 3 || (orderInfo._status._type == 2 && orderInfo.isTickets!==1)">
<view >
<text class="v12-secondary-dark-text v12-font-28">{{ orderInfo.deliveryName }}{{ orderInfo.deliveryId }}</text>
<text class="v12-font-22 v12-px-2 v12-py-1 v12-ml-1 v12-primary-text v12-primary-border v12-radius-40" @click="copyClipboard(orderInfo.orderId)">
复制
</text>
</view>
<view class="v12-mt-2 v12-justify-between">
<view class="v12-align-center">
<view class="v12-align-center v12-mr-2">
<image class="logo" :src="webUrl+'/orderIcon/car.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
</view>
<view class="v12-font-28 v12-secondary-dark-text">{{ logistics.Traces && logistics.Traces.length > 0 ? logistics.Traces[logistics.Traces.length - 1].acceptStation : '暂无轨迹信息'}}</view>
</view>
<view v-if="orderInfo.deliveryId !== null && (orderInfo._status._type == -1 || orderInfo._status._type == -2 || orderInfo._status._type == 4 || orderInfo._status._type == 3 || (orderInfo._status._type == 2 && orderInfo.isTickets!==1))">
<view v-if="index < 2 || showMoreDeliver" v-for="(delivery, index) in orderInfo.deliveryInfo" :key="index" class="v12-radius-20 v12-white v12-pa-3 v12-mt-4">
<view>
<uni-icons type="right" size="20" color="#707070"></uni-icons>
<text class="v12-secondary-dark-text v12-font-28">{{ delivery.deliveryName }}{{ delivery.deliveryId }}</text>
<text class="v12-font-22 v12-px-2 v12-py-1 v12-ml-1 v12-primary-text v12-primary-border v12-radius-40" @click="copyClipboard(delivery.deliveryId)">
复制
</text>
</view>
<view class="v12-mt-2 v12-justify-between" @click="goLogistics(orderInfo, index)">
<view class="v12-align-center">
<view class="v12-align-center v12-mr-2">
<image class="logo" :src="webUrl+'/orderIcon/car.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
</view>
<view class="v12-font-28 v12-secondary-dark-text">{{ logistics[index] && logistics[index].Traces && logistics[index].Traces.length > 0 ? logistics[index] && logistics[index].Traces[logistics[index].Traces.length - 1].acceptStation : '暂无轨迹信息'}}</view>
</view>
<view>
<uni-icons type="right" size="20" color="#707070"></uni-icons>
</view>
</view>
<view class="v12-mt-2">
<text class="v12-dark-text v12-font-24">{{ logistics[index] && logistics[index].Traces && logistics[index].Traces.length > 0 ? logistics[index] && logistics[index].Traces[logistics[index].Traces.length - 1].acceptTime : '' }}</text>
</view>
</view>
<view class="v12-mt-2">
<text class="v12-dark-text v12-font-24">{{ logistics.Traces && logistics.Traces.length > 0 ? logistics.Traces[logistics.Traces.length - 1].acceptTime : '' }}</text>
<view class="v12-justify-center v12-mt-3" v-if="orderInfo.deliveryInfo.length > 2">
<u-icon :name="showMoreDeliver ? 'arrow-up' : 'arrow-down'" @click="handleShowMore"></u-icon>
</view>
</view>
<template v-if="!refundOrder">
@@ -104,7 +111,7 @@
<view style="margin-top: 30rpx;border-radius:20rpx;overflow: hidden;" class="v12-white">
<!-- <OrderGoods :evaluate="status.type || 0" :cartInfo="orderInfo.cartInfo || []" title="商品信息"></OrderGoods> -->
<view class="v12-radius-20 v12-pa-3" v-for="(cart, d) in orderInfo.cartInfo" :key="d">
<view class="v12-radius-20 v12-pa-3" v-for="(cart, d) in orderInfo.cartInfo" :key="d" @click="goGoodsCon(cart)">
<view class="v12-justify-between">
<view class="">
<image style="width: 120rpx; height: 120rpx" class="v12-radius-8" :src="cart.productInfo.image"></image>
@@ -129,7 +136,7 @@
</view>
</view>
</view>
<view class="" v-if="orderInfo.cartInfo &&( d === orderInfo.cartInfo.length - 1)">
<view class="" v-if="orderInfo.cartInfo &&( d === orderInfo.cartInfo.length - 1)">
<view class="v12-justify-between v12-mt-3 v12-dark-text">
<view class="v12-font-24 v12-dark-text">
商品总价
@@ -336,24 +343,24 @@
<template v-if="status.type == 1" >
<view class="v12-justify-between " style="width: 100%">
<view class="bnt v12-dark-text v12-dark-border cancel" @click="goRoom(orderInfo)">联系商家</view>
<view class="bnt v12-primary-text v12-primary-border cancel" @click="goGoodsReturn(orderInfo)">申请退款</view>
<view class="bnt v12-primary-text v12-primary-border cancel" @click="goGoodsReturn2(orderInfo)">申请退款</view>
</view>
</template>
<template v-if="status.type == 2">
<view class="v12-justify-between " style="width: 100%">
<view class="bnt v12-dark-text v12-dark-border cancel" @click="goRoom(orderInfo)">联系商家</view>
<view class="v12-justify-between">
<view class="" style="position: relative">
<text class="btn-more v12-font-24 v12-mr-2" @click.stop="showMore = !showMore">更多</text>
<view class="btn-more" style="position: relative">
<view class=" v12-font-24 v12-mr-2" @click.stop="showMore = !showMore">更多</view>
<view class="group-float" v-show="showMore" :style="{top: orderInfo.isExtendedDelivery==0 ? '-60px' : '-32px'}">
<view v-if="orderInfo.isExtendedDelivery==0" class="btn flex jc-center ai-center v12-font-24" @click="toDelay(orderInfo.orderId)">延长收货</view>
<view class="btn flex jc-center ai-center v12-font-24" @click="goGoodsReturn(orderInfo)">申请退款</view>
</view>
</view>
<view class="bnt v12-dark-text v12-dark-border default"
<!-- <view class="bnt v12-dark-text v12-dark-border default"
@click="$yrouter.push({ path: '/pages/order/Logistics/index' ,query:{id:orderInfo.orderId }})"
v-if="orderInfo.isTickets!==1">查看物流
</view>
</view> -->
<view class="bnt v12-primary-text v12-primary-border" @click="takeOrder">确认收货</view>
</view>
</view>
@@ -362,8 +369,8 @@
<view class="v12-justify-between " style="width: 100%">
<view class="bnt v12-dark-text v12-dark-border cancel" @click="goRoom(orderInfo)">联系商家</view>
<view class="v12-justify-between">
<view class="" style="position: relative">
<text class="btn-more v12-font-24 v12-mr-2" @click="showMore = !showMore">更多</text>
<view class="btn-more" style="position: relative">
<text class=" v12-font-24 v12-mr-2" @click.stop="showMore = !showMore">更多</text>
<view class="group-float" v-show="showMore" :style="{top: '-32px'}">
<view class="btn flex jc-center ai-center v12-font-24" @click="goGoodsReturn(orderInfo)">申请退款</view>
</view>
@@ -400,12 +407,12 @@
</template>
<template v-if="status.type == 4">
<view class="bnt v12-dark-text v12-dark-border cancel" @click="delOrder">删除订单</view>
<view
<!-- <view
v-if="orderInfo.isTickets !== 1"
class="bnt v12-dark-text v12-dark-border default"
@click="$yrouter.push({ path: '/pages/order/Logistics/index' ,query:{id:orderInfo.orderId }})"
>查看物流
</view>
</view> -->
</template>
<template v-if="status.type == 6">
<view class="bnt v12-primary-text v12-primary-border" @click="goGroupRule(orderInfo)">查看拼团</view>
@@ -462,7 +469,7 @@ export default {
mixins: [pageListenMixins],
data: function () {
return {
addressId: null,
showMoreDeliver: false,
showExtend: false,
delayId: '',
showMore: false,
@@ -495,47 +502,42 @@ export default {
...mapGetters(["userInfo"])
},
onShow() {
this.id = this.$yroute.query.id;
this.getDetail();
uni.$on('chooseAddress', (res) => {
this.addressId = res.id
})
},
watch: {
addressId(val) {
if(val) {
const params = {
addressId: this.addressId,
orderId: this.orderInfo.orderId
}
setTimeout(() => {
uni.showModal({
title:'确定修改地址吗?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success:(success)=>{
if(success.confirm) {
uni.showLoading()
editAddress(params).then(res => {
uni.showToast({
icon: 'success',
title: '修改成功!'
})
this.getDetail();
}).finally(() => {
uni.hideLoading()
})
}
},
complete:(complete)=>{
const _this = this
const chooseAddress = uni.getStorageSync('chooseAddress') || {}
const addressId = chooseAddress.id || ''
//
if (addressId) {
uni.setStorageSync('chooseAddress', {})
uni.showModal({
title:'确定修改地址吗?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success:(success)=>{
if(success.confirm) {
uni.showLoading()
editAddress({
addressId,
orderId: _this.orderInfo.orderId
}).then(res => {
uni.showToast({
icon: 'success',
title: '修改成功!'
})
_this.getDetail()
}).finally(() => {
uni.hideLoading()
this.addressId = ''
},
})
}, 1000)
}
})
}
},
complete:(complete)=>{
uni.hideLoading()
}
})
} else {
_this.id = _this.$yroute.query.id;
_this.getDetail();
}
},
// inject: ["app"],
@@ -544,21 +546,34 @@ export default {
},
methods: {
copyClipboard,
goGoodsCon(item) {
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.productId
}
})
},
handleShowMore() {
this.showMoreDeliver = !this.showMoreDeliver;
},
handleBody() {
this.showMore = false
this.$forceUpdate()
// this.$forceUpdate()
},
getExpressInfo() {
getExpressInfo(delivery, i) {
if(delivery.deliveryId === null) return
let params = {
orderCode: this.orderInfo.id,
shipperCode: this.orderInfo.deliverySn,
logisticCode: this.orderInfo.deliveryId
shipperCode: delivery.deliverySn,
logisticCode: delivery.deliveryId
};
express(params)
.then(res => {
const {success, data} = res
if(success) {
this.logistics = data || {}
this.logistics[i] = data || {}
this.$forceUpdate()
}
})
@@ -571,11 +586,12 @@ export default {
// });
});
},
goLogistics(order) {
goLogistics(order, index) {
this.$yrouter.push({
path: "/pages/order/Logistics/index",
query: {
id: order.orderId
id: order.orderId,
index: index
}
});
},
@@ -587,7 +603,7 @@ export default {
const ids = res.data.cartInfo.map(e => e.id)
const addressInfo = res.data.addressInfo
if (ids.length === 0) return
uni.navigateTo({
uni.redirectTo({
url: '/pages/order/OrderSubmission/index?id=' + ids.join(',') + '&address=' + JSON.stringify(addressInfo)
})
})
@@ -726,12 +742,33 @@ export default {
})
},
goGoodsReturn(orderInfo) {
// fix bug#1631 bug#2488
if (parseInt(orderInfo._status._type) === 3) {
if(orderInfo.refundSystemStatus === 0) {
uni.showToast({
title: '订单已收货,如需退款请联系商家',
mask: false,
icon: 'none',
duration: 3000
})
} else {
uni.navigateTo({
url: `/pkg_orders/views/refund?id=${orderInfo.orderId}`
})
}
} else {
uni.navigateTo({
url: `/pkg_orders/views/refund?id=${orderInfo.orderId}`
})
}
},
goGoodsReturn2(orderInfo) {
this.$yrouter.push({
path: "/pages/order/GoodsReturn/index",
query: {
id: orderInfo.orderId
}
});
})
},
goGroupRule(orderInfo) {
this.$yrouter.push({
@@ -886,8 +923,11 @@ export default {
this.system_store = res.data.systemStore || {};
this.mapKey = res.data.mapKay;
this.setOfflinePayStatus(this.orderInfo.offlinePayStatus);
if(this.orderInfo._status._type == 3 || (this.orderInfo._status._type == 2 && this.orderInfo.isTickets!==1)) {
this.getExpressInfo()
const orderInfo = this.orderInfo
if(orderInfo._status._type == -1 || orderInfo._status._type == -2 || orderInfo._status._type == 4 || orderInfo._status._type == 3 || (orderInfo._status._type == 2 && orderInfo.isTickets!==1)) {
for(let i = 0; i < orderInfo.deliveryInfo.length; i++) {
this.getExpressInfo(orderInfo.deliveryInfo[i], i)
}
}
})
.catch(err => {
@@ -917,6 +957,10 @@ export default {
};
</script>
<style scoped lang="less">
.btn-more{
display: flex;
align-items: center;
}
.u-count-down__text{
color: #999 !important;
}
+55 -31
View File
@@ -109,13 +109,14 @@
</view>
</view>
<view class="v12-justify-between v12-align-center">
<view class="v12-mr-2" @click="changeCoupons" v-if="couponList.usable.length !== 0">
<!-- <view class="v12-mr-2" @click="changeCoupons" v-if="couponList.usable.length !== 0 && !hasCoupon">
<text class="v12-dark-text v12-font-24" >{{ couponList.usable.length === 0 ? '无' : '去选择' }}</text>
<text class="iconfont icon-jiantou v12-font-24 v12-dark-text"></text>
</view>
<view class="v12-secondary-dark-text">
</view> -->
<view class="v12-secondary-dark-text v12-align-center" @click="changeCoupons">
<text class="v12-font-22 ">-</text>
<text class="v12-font-28">{{ force2Decimal(orderPrice.couponPrice) }}</text>
<text class="iconfont icon-jiantou v12-font-24 v12-dark-text"></text>
</view>
</view>
</view>
@@ -251,7 +252,9 @@
v-if="couponList.usable.length > 0"
:two-list="couponList"
@change="changeCoupons"
@close="close"
:currentPrice="force2Decimal(orderPrice.totalPrice)"
:id="couponId"
@max="couponMax"
:show-tab="false"
/>
@@ -372,7 +375,8 @@ export default {
maxPoints: 0,
pageKeyId: Object.freeze('orderConfirm'),
total: 0,
couponTitle: ''
couponTitle: '',
hasCoupon: false,
};
},
computed: mapGetters(["userInfo", "storeItems"]),
@@ -383,44 +387,39 @@ export default {
shipping_type() {
this.computedPrice('shipping_type');
},
couponId() {
this.couponIndex = this.couponList['usable']?.findIndex(item => item.id === this.couponId)
this.computedPrice('couponId')
async couponId(value) {
this.couponIndex = this.couponList['usable']?.findIndex(item => item.id === +value)
this.couponTitle = this.couponList['usable']?.[this.couponIndex]?.couponTitle
await this.computedPrice('couponId')
}
},
onLoad: function () {
let that = this;
uni.$on('chooseAddress', (res) => {
console.log('监听到选择收货地址:' + JSON.stringify(res));
that.addressInfo = res;
//
that.computedPrice('onLoad chooseAddress');
})
onLoad(opts) {
console.log(opts);
const that = this
if (that.$yroute.query.pinkid !== undefined) {
that.pinkId = that.$yroute.query.pinkid;
that.pinkId = that.$yroute.query.pinkid
}
if (that.$yroute.query.id !== undefined) {
that.cartid = that.$yroute.query.id;
that.cartid = that.$yroute.query.id
console.log(that.cartid)
}
if (that.$yroute.query.lotteryRecordId !== undefined) {
that.lotteryRecordId = that.$yroute.query.lotteryRecordId;
that.lotteryRecordId = that.$yroute.query.lotteryRecordId
}
that.getCartInfo();
that.hasCoupon = opts.couponId !== ''
},
onUnload: function () {
console.log('关闭监听选择收货地址');
uni.$off('chooseAddress');
},
onShow: function () {
onShow() {
const _this = this
_this.getCartInfo()
//
this.$store.dispatch("getUser", true);
_this.$store.dispatch("getUser", true)
},
methods: {
isNullOrEmpty,
couponMax(e) {
this.couponTitle = e.couponTitle
this.couponId = uni.getStorageSync('couponId') || 0
this.couponId = this.$yroute.query.couponId || uni.getStorageSync('couponId') || 0
},
showStoreList() {
this.$store.commit("get_to", "orders");
@@ -440,7 +439,7 @@ export default {
postOrderComputed(this.orderGroupInfo.orderKey, {
addressId: this.addressInfo.id,
useIntegral: this.useIntegral ? 1 : 0,
couponId: this.couponId || 0,
couponId: this.couponList.usable.length === 0 ? 0 : this.couponId || 0,
usePoints: this.usePointsCheck ? 1 : 0,
shipping_type: parseInt(shipping_type) + 1
}).then(res => {
@@ -505,10 +504,32 @@ export default {
if(_this.$yroute.query.address !== undefined ) {
_this.addressInfo = JSON.parse(_this.$yroute.query.address) || {}
} else {
_this.addressInfo = data.addressInfo || {}
_this.addressInfo = uni.getStorageSync('chooseAddress') ? uni.getStorageSync('chooseAddress') : data.addressInfo || {}
}
const chooseAddress = uni.getStorageSync('chooseAddress') || {}
const sourceAddress = uni.getStorageSync('sourceAddress') || data.addressInfo || uni.getStorageSync('chooseAddress')
//
if (chooseAddress.id && (chooseAddress.id !== sourceAddress.id)) {
uni.showModal({
title:'确定修改地址吗?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success: (res) => {
if(res.confirm) {
_this.addressInfo = chooseAddress
//
uni.setStorageSync('sourceAddress', _this.addressInfo || '')
_this.computedPrice('onLoad chooseAddress')
}
},
complete: () => {
uni.hideLoading()
// uni.setStorageSync('chooseAddress', {})
}
})
}
_this.systemStore = data.systemStore || {}
_this.storeSelfMention = data.storeSelfMention
_this.computedPrice()
@@ -649,7 +670,7 @@ export default {
phone: this.contactsTel,
addressId: this.addressInfo.id,
useIntegral: this.useIntegral ? 1 : 0,
couponId: this.couponId || 0,
couponId: this.couponList.usable.length === 0 ? 0 : this.couponId || 0,
usePoints: this.usePointsNumber || 0,
payType: this.active,
pinkId: this.pinkId,
@@ -772,6 +793,9 @@ export default {
that.$refs.payPwdPop.close();//
});
},
close() {
this.show = !this.show
},
// v9-2
changeCoupons(item) {
if(!item) return
+303 -26
View File
@@ -5,13 +5,34 @@
<input
v-model.trim="search"
type="text"
placeholder="请输入"
:placeholder="showkey ? '' : '请输入'"
placeholder-style="color:#999"
@confirm="submit"
@blur="showHistory"
@focus="hideHistory"
@input="hideHistory"
@change="hideHistory"
@compositionstart="hideHistory"
/>
<view class="btn flex-0 flex jc-center ai-center" @click="submit">
<button class="btn flex-0 flex jc-center ai-center" @click.stop="submit">
<text class="iconfont icon-sousuo2"></text>
<text>搜索</text>
</button>
<view class="swpier-bar" v-if="showkey">
<u-notice-bar
duration="4000"
@change="change"
:text="recommendKeyword"
:icon="' '"
color="#999"
fontSize="14"
bgColor="transparent"
direction="column"></u-notice-bar>
</view>
</view>
<view @click="goShoppingCart()" class="item animated bounceIn">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount > 99 ? '99+' : CartCount }}</text>
</view>
</view>
</view>
@@ -31,7 +52,7 @@
<view
v-for="item of historyKey"
:key="item.id"
class="item"
class="item one-t v12-font-28"
@click="toSearch(item.word)"
>
{{ item.word }}
@@ -42,54 +63,186 @@
<view class="title">热门搜索</view>
<view class="list acea-row">
<view
v-for="keywordsKey of keywords"
:key="keywordsKey"
class="item"
@click="toSearch(keywordsKey)"
v-for="(hot, key) in keywords"
:key="key"
class="item v12-font-28 v12-align-center"
:style="{paddingRight: hot.isNew === 1 ? '0 !important' : '24rpx !important'}"
@click="toSearch(hot.keyword)"
>
{{ keywordsKey }}
<view v-if="hot.isNew === 2">
<image :src="webUrl + '/icon/fire.png'" class="fire-icon"></image>
</view>
{{ hot.keyword }}
<view class="new-icon-box" v-if="hot.isNew === 1" >
<image class="new-icon" :src="webUrl + '/icon/new.png'"></image>
</view>
</view>
</view>
</view>
<view class="ranking-wrap">
<view
v-for="(rankingItem, rankingIndex) in rankingArr"
:key="rankingIndex"
:style="{
'background': `linear-gradient(180deg, ${rankingItem.color} 0%, #FFFFFF 35%, #FFFFFF 100%)`
}"
class="ranking-item"
>
<view class="ranking-header">
<image
:src="rankingItem.backgroundImage"
mode="widthFix"
class="icon"
/>
<view class="name">{{ rankingItem.rankingName }}</view>
</view>
<view class="ranking-body">
<view
v-for="(good, goodIndex) in rankingItem.products"
:key="goodIndex"
class="item"
@click="goodItemClick(good)"
>
<view class="img">
<image
:src="good.productImage"
mode="widthFix|heightFix"
class="pic"
/>
</view>
<view class="info">
<view class="name more-t">
{{ good.productName }}
</view>
<view class="price-wrap " :class="{'v12-align-center' : ('' + good.price).length < 5 && ('' + good.otPrice).length < 5}">
<view class="price">
{{ good.price }}
</view>
<view class="ot-price" :class="{'v12-ml-1' : ('' + good.price).length < 5 && ('' + good.otPrice).length < 5}">
{{ good.otPrice }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="line"></view>
</view>
</template>
<script>
import {getSearchKeyword} from '@/api/store'
import {
getSearchPageConfig
} from '@/api/search'
import {
getCartCount,
} from '@/api/store'
import { mapGetters } from 'vuex'
import {trim} from '@/utils'
export default {
name: 'GoodSearch',
props: {},
data: function () {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
showkey: true,
currentSearch: '',
keywords: [],
search: '',
historyKey: []
historyKey: [],
rankingArr: [],
recommendKeyword: [],
CartCount: 0,
keywords1: ''
}
},
computed: mapGetters(['isLogin', 'location', 'userInfo']),
mounted: function () {
this.getData()
this.getCartCount()
},
onLoad(opts){
this.search = opts.keywords
},
onShow() {
this.getHistory()
},
watch: {
search(val) {
if(val) {
this.showkey = false
} else {
// this.showkey = true
// this.currentSearch = this.recommendKeyword[0]
}
}
},
methods: {
//
getCartCount () {
const isLogin = this.isLogin
if (isLogin) {
getCartCount({
numType: 0
}).then(res => {
this.CartCount = res.data.count
})
}
},
goShoppingCart() {
this.$yrouter.switchTab('/pages/cart')
},
showHistory() {
this.currentSearch = this.recommendKeyword[0]
if(this.showkey) return
if(this.search) {
this.showkey = false
return
}
this.showkey = true
},
hideHistory() {
// if(!this.search) {
// this.showkey = true
// return
// }
this.showkey = false
},
change(e) {
this.currentSearch = this.recommendKeyword[e]
},
submit() {
const search = trim(this.search) || ''
if (!search) return
this.setHistory(search)
this.search = ''
this.toSearch(search)
if (this.showkey) {
const search = trim(this.currentSearch) || ''
if (!search) return
this.setHistory(search)
// this.search = ''
this.toSearch(search)
} else {
const search = trim(this.search) || ''
if (!search) return
this.setHistory(search)
// this.search = ''
this.toSearch(search)
}
},
toSearch(s) {
this.setHistory(s)
this.$yrouter.push({path: '/pages/shop/GoodsList/index', query: {s}})
},
getData() {
getSearchKeyword().then(res => {
this.keywords = res.data
getSearchPageConfig().then(res => {
const { success, data } = res
if (success) {
this.keywords = data.searchKeywords
this.rankingArr.push(data.ranking1)
this.rankingArr.push(data.ranking2)
this.recommendKeyword = data.recommendKeyword.split(',')
// const index = this.recommendKeyword.indexOf(this.keywords1)
// [this.recommendKeyword[0], this.recommendKeyword[index]] = [this.recommendKeyword[index], this.recommendKeyword[0]];
}
})
},
getHistory() {
@@ -119,12 +272,53 @@ export default {
}
}
})
},
goodItemClick(good) {
const id = good.productId
if (!id) return
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: { id }
})
}
}
}
</script>
<style lang="less">
.new-icon-box{
position: relative;
width: 50rpx;
height: 100%;
}
.fire-icon{
width: 24rpx;
height: 24rpx;
margin-right: 5rpx;
}
.new-icon{
width: 40rpx;
height: 26rpx;
left: 10rpx;
top: -5rpx;
position: absolute;
}
.iconfont{
position: relative;
}
.item .iconfont.icon-gouwuche1 .num {
right: -15rpx !important;
top: -15rpx!important;
font-size: 20rpx;
position: absolute;
width: 30rpx;
height: 30rpx;
background: #C52733 !important;
color: #fff;
border-radius: 50%;
text-align: center;
padding: 2rpx;
}
.good-search {
min-height: 100vh;
background: #fff !important;
@@ -132,7 +326,8 @@ export default {
.header {
padding: 40rpx 32rpx 32rpx;
background: #F9F9F9;
display: flex;
align-items: center;
.search-box {
width: 686rpx;
height: 72rpx;
@@ -141,19 +336,27 @@ export default {
border-radius: 36rpx;
background: #fff;
font-size: 24rpx;
position: relative;
.swpier-bar{
position: absolute;
width: calc(100% - 128rpx);
top: 0;
}
input {
width: 100%;
position: relative;
z-index: 9;
}
.btn {
width: 128rpx;
height: 54rpx;
background: #FD574B;
background: #C52733;
border-radius: 28rpx;
color: #fff;
font-weight: bold;
padding: 0;
font-size: 26rpx;
.icon-sousuo2 {
margin-right: 4rpx;
font-size: 28rpx;
@@ -182,11 +385,12 @@ export default {
box-sizing: border-box;
margin: 0 24rpx 20rpx 0;
padding: 0 24rpx;
border-radius: 28rpx;
background: #F1F0EE;
color: #666;
border-radius: 12rpx;
background: #F2F2F2;
color: #333;
font-size: 24rpx;
line-height: 48rpx;
position: relative;
}
}
@@ -196,4 +400,77 @@ export default {
}
}
}
.ranking-wrap {
display: flex;
justify-content: space-between;
padding: 24rpx;
background-color: #F2F2F2;
.ranking-item {
width: 344rpx;
padding: 20rpx 12rpx;
box-sizing: border-box;
border-radius: 20rpx;
background-color: #fff;
.ranking-header {
display: flex;
align-items: center;
.icon {
display: block;
width: 40rpx;
height: 40rpx;
}
.name {
margin: 0 0 0 12rpx;
font-weight: bold;
font-size: 30rpx;
color: #333;
line-height: 42rpx;
}
}
.ranking-body {
padding: 24rpx 0 0 0;
.item {
display: flex;
align-items: center;
justify-content: space-around;
margin: 0 0 12rpx 0;
.img {
width: 100rpx;
height: 100rpx;
.pic {
display: block;
width: 100rpx;
height: 100rpx;
border-radius: 8rpx;
}
}
.info {
width: calc(100% - 112rpx);
margin: 0 0 0 12rpx;
.name {
height: 64rpx;
font-size: 26rpx;
color: #333;
line-height: 32rpx;
}
.price-wrap {
// display: flex;
margin: 6rpx 0 0 0;
line-height: 30rpx;
.price {
color: #E92727;
font-size: 24rpx;
}
.ot-price {
// margin: 0 0 0 20rpx;
color: #BFBFBF;
font-size: 20rpx;
text-decoration: line-through;
}
}
}
}
}
}
}
</style>
+156 -42
View File
@@ -17,19 +17,22 @@
<view>
<view class="share acea-row row-between row-middle" style="flex-wrap: nowrap;margin-top: 0;">
<view class="money font-color-lightred acea-row v12-align-center">
<view>
<view v-if="!storeInfo.isNegotiable">
<text class="v12-font-22 v12-red-text"></text>
<text class=" v12-primary-text v12-font-44 v12-red-text">{{ attr.productSelect.price }}</text>
<text class="v12-ml-2 v12-font-weight-300 v12-font-22" style="color: #BBBBBB; text-decoration: line-through;"></text>
<text class="v12-mr-2 v12-font-weight-300 v12-font-22" style="color: #BBBBBB; text-decoration: line-through;">{{ attr.productSelect.otPrice }}</text>
<text v-if="storeInfo.vipPrice && storeInfo.vipPrice > 0" class="v12-white-text v12-red v12-font-22 v12-radius-40 v12-px-1 v12-font-weight-400">会员价</text>
</view>
<view v-if="storeInfo.isNegotiable === 1" class="v12-primary-text v12-font-32 v12-font-weight" @click="goRoom">
价格面议
</view>
</view>
<view style="flex-shrink:0;" class="acea-row row-middle share-btn" @click="listenerActionSheet">
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
<view v-if="couponListLimit2ToShow.length > 0 || attr.productSelect.earnPoints" class="v12-mt-1 v12-mb-3">
<view v-if="couponListLimit2ToShow.length > 0 || attr.productSelect.earnPoints" class="v12-mt-1 v12-mb-1">
<view class="cell flex jc-between ai-center">
<view v-if="couponListLimit2ToShow.length > 0" class="v12-justify-start">
<view
@@ -43,13 +46,7 @@
</view>
</view>
</view>
<view
v-if="attr.productSelect.earnPoints"
:class="couponListLimit2ToShow.length > 0 ? 'earn-points' : ''"
class="value value2 v12-font-24 v12-primary-text"
>
预计获得{{ attr.productSelect.earnPoints }}积分
</view>
<view
v-if="couponListLimit2ToShow.length > 0"
class="value value2 v12-font-24 v12-primary-text"
@@ -60,8 +57,30 @@
</view>
</view>
</view>
<view
v-if="attr.productSelect.earnPoints"
:class="couponListLimit2ToShow.length > 0 ? 'earn-points' : ''"
class="value value2 v12-font-24 v12-primary-text v12-mb-2"
>
预计获得{{ attr.productSelect.earnPoints }}积分
</view>
</view>
<view class="introduce bold">{{ storeInfo.storeName }}</view>
<!-- :style="giftBg ? `background: url('${giftBg}') no-repeat center/cover` : ''" -->
<view v-if="storeInfo.isGiftCard === 1"
@click="toGift"
class=" v12-white-text v12-px-2 v12-py-1 v12-mt-2 v12-radius-20 v12-font-bold v12-justify-between v12-align-center gift-wrap"
:style="giftBg ? 'background: url(' + giftBg + ') no-repeat center/cover' : ''"
:class="giftBg ? '' : 'v12-primary'"
>
<view class="v12-font-28 v12-align-center" style="height: 74rpx; opacity: 0;">
<image class="gift-img" :src="webUrl + '/orderIcon/gift.png'" mode="widthFix" ></image>
支持礼包赠送
</view>
<view @click="toGift" class="v12-white v12-dark-text v12-radius-20 v12-font-28 gift-btn" style="opacity: 0;">
送给朋友
</view>
</view>
<rich-text class="subInfo" :nodes="storeInfo.storeInfo" v-if="storeInfo.storeInfo"/>
</view>
@@ -182,7 +201,13 @@
<!-- v9 优惠券开始 -->
<u-popup :show="show" :round="10" mode="bottom" closeOnClickOverlay @close="changeCoupons()">
<CouponsPopup :two-list="couponList" @change="changeCoupons" :showTab="false" :currentPrice="storeInfo.price" />
<CouponsPopup
:two-list="couponList"
@ok="setCoupon"
@change="changeCoupons"
@close="changeCoupons()"
:showTab="false"
:currentPrice="storeInfo.price" />
</u-popup>
<!-- v9 优惠券结束 -->
@@ -211,7 +236,7 @@
<image class="logo" :src="webUrl+'/orderIcon/资质认证.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
<text class="v12-ml-1 v12-font-28">资质</text>
</view>
<view class="title v12-secondary-dark-text">{{ storeInfo.merName }}</view>
<view class="store-title title more-t v12-secondary-dark-text">{{ storeInfo.merName }}</view>
</view>
<view class="value v12-justify-end v12-align-center">
<!-- <text class=" v12-dark1-text v12-font-24">库存{{ attr.productSelect.stock }}</text> -->
@@ -309,7 +334,8 @@
<view class="more-t bold">{{ item.storeName }}</view>
</view>
<view class="v12-justify-between">
<view class="price bold">{{ item.price }}</view>
<view class="price bold" v-if="!item.isNegotiable">{{ item.price }}</view>
<view class="price bold" v-else>价格面议</view>
<view class="">
<image class="logo" :src="webUrl+'/orderIcon/组 355.png'" mode="" style="margin-right:0; width: 28rpx; height:28rpx"/>
</view>
@@ -392,7 +418,7 @@
<!-- 商品详情结束 -->
<!-- 购买须知开始 -->
<view class="acea-row row-column bg-white" style="padding: 20rpx;border-width: 2px;border-color: #939390;">
<view class="acea-row row-column bg-white" style="padding: 20rpx;border-width: 2px;border-color: #939390;padding-bottom: 60rpx;">
<view class="conter">
<rich-text :nodes="buyNotice" />
</view>
@@ -439,7 +465,7 @@
<view
class="btn-car v12-primary-text v12-primary-border"
:class="{
'btn-car-disabled': (attr.productSelect.stock === 0 && attr.cartAttr) || storeInfo.stock === 0
'btn-car-disabled': (attr.productSelect.stock === 0 && attr.cartAttr) || storeInfo.stock === 0 || storeInfo.isNegotiable === 1
}"
@click="joinCart"
>
@@ -448,7 +474,7 @@
<view
class="btn-buy"
:class="{
'btn-buy-disabled': (attr.productSelect.stock === 0 && attr.cartAttr) || storeInfo.stock === 0
'btn-buy-disabled': (attr.productSelect.stock === 0 && attr.cartAttr) || storeInfo.stock === 0 || storeInfo.isNegotiable === 1
}"
@click="tapBuy"
>
@@ -463,6 +489,9 @@
:attr="attr"
:cartNum="cart_num"
@changeFun="changeFun"
:isNegotiable="storeInfo.isNegotiable === 1"
@gift="gift"
:isGift="isGift"
/>
<ServiceWin ref="serviceWin" :info="storeInfo.guarantee" />
<StorePoster v-on:setPosterImageStatus="setPosterImageStatus" :posterImageStatus="posterImageStatus"
@@ -481,9 +510,9 @@
</view>
</view>
<view class="mask" @touchmove.prevent @click="listenerActionClose" v-show="posters"></view>
<view class="posterCanvasWarp">
<!-- <view class="posterCanvasWarp">
<canvas class="posterCanvas" canvas-id="myCanvas"></canvas>
</view>
</view> -->
</view>
</view>
</view>
@@ -528,7 +557,7 @@ import {
removeProduct
} from '@/api/favorite'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import {getGiftCardSendBackground} from "@/api/gift"
export default {
name: 'GoodsCon',
components: {
@@ -544,6 +573,8 @@ export default {
mixins: [pageListenMixins],
data: function () {
return {
isGift: false,
giftBg: '',
//
isProductInfoExpand: true,
shareInfoStatus: false,
@@ -617,7 +648,8 @@ export default {
isFavorite: false,
pageKeyId: '',
couponListLimit2ToShow: [],
qualifications: []
qualifications: [],
couponId: null
}
},
computed: mapGetters(['isLogin', 'location', 'userInfo']),
@@ -743,6 +775,11 @@ export default {
},
onShow() {
this.getMapData()
getGiftCardSendBackground().then(res => {
if (res.status === 200) {
this.giftBg = res.data || ''
}
})
},
watch: {
posterImageStatus(status) {
@@ -761,6 +798,24 @@ export default {
}
},
methods: {
gift() {
this.goCat(2)
},
toGift() {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0) {
uni.showToast({
title: '商品库存不足',
icon: 'none'
})
return
}
this.isGift = true
// 2=
this.goCat(2)
// uni.navigateTo({
// url: '/pkg_user/views/gift/gift'
// })
},
showService() {
this.$refs.serviceWin.show = true
},
@@ -774,18 +829,21 @@ export default {
})
},
goRoom() {
console.log(this.storeInfo);
const params = {
goodsId: this.productId,
goodsId: this.id,
goodsName: this.attr.productSelect.store_name,
skuStr: this.attrValue,
price: this.attr.productSelect.price,
seckillId: this.activityId,
cover: this.attr.productSelect.image,
goodsData: '',
seckillData: ''
seckillData: '',
isNegotiable: this.storeInfo.isNegotiable
}
const name = this.storeInfo.merName
uni.navigateTo({
url: `/pkg_common/views/room?id=${this.storeInfo.merId}&name=${this.storeInfo.merName}&params=${JSON.stringify(params)}`
url: `/pkg_common/views/room?id=${this.storeInfo.merId}&name=${name}&params=${JSON.stringify(params)}`
})
},
goodsDetail(item) {
@@ -1009,6 +1067,7 @@ export default {
//
productCon() {
const from = this.location
if (this.$deviceType == 'app') {
from.from = 'app'
}
@@ -1021,6 +1080,7 @@ export default {
})
getProductDetail(this.id, from).then(res => {
const { data } = res
uni.hideLoading()
this.$set(this, 'storeInfo', data.storeInfo)
this.isWenwan = data.isWenwan
this.qualifications = data.qualifications || []
@@ -1108,7 +1168,7 @@ export default {
duration: 2000
})
}).finally(() => {
uni.hideLoading()
// uni.hideLoading()
})
},
getAttrItemData(attr) {
@@ -1133,7 +1193,7 @@ export default {
}
})
})
const skuKey = (this.attr.defaultSku || []).join(',')
const skuKey = (this.attr.defaultSku || []).sort().join(',')
if (!skuKey) {
return
}
@@ -1205,7 +1265,12 @@ export default {
let stock = productSelect.stock || 0
let num = this.attr.productSelect
if (changeValue) {
num.cart_num++
console.log(num.cart_num);
if(changeValue >= 1) {
num.cart_num = changeValue
} else {
num.cart_num++
}
if (num.cart_num > stock) {
if(stock < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
@@ -1220,7 +1285,7 @@ export default {
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
this.$set(this, 'cart_num', num.cart_num)
// this.$set(this, 'cart_num', num.cart_num)
}
}
} else {
@@ -1251,6 +1316,7 @@ export default {
changeattr(msg) {
//
this.attr.cartAttr = msg
this.$set(this.attr.productSelect, 'cart_num', 1)
this.isOpen = false
},
//
@@ -1313,24 +1379,32 @@ export default {
},
//
joinCart() {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0) {
if(this.storeInfo.isNegotiable === 1) {
this.$u.toast('该商品为面议商品,无法加入购物车')
return
}
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0 || this.storeInfo.isNegotiable === 1) {
return
}
// 0=
this.isGift = false
this.goCat(0)
},
//
tapBuy() {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0) {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0 || this.storeInfo.isNegotiable === 1) {
return
}
// 1=
this.isGift = false
this.goCat(1)
},
//
goCat(news) {
const that = this
const productSelect = this.getAttrItemData(this.attrValue)
console.log(this.attr);
//
if (that.attrValue) {
//
@@ -1359,7 +1433,7 @@ export default {
const q = {
productId: that.id,
cartNum: that.attr.productSelect.cart_num,
new: news,
new: news === 2 ? 1 : news,
uniqueId: that.attr.productSelect !== undefined ?
that.attr.productSelect.unique : ""
}
@@ -1378,14 +1452,23 @@ export default {
postCartAdd(q).then(function (res) {
that.isOpen = false
that.attr.cartAttr = false
if (news) {
if (news === 1) {
that.$yrouter.push({
path: "/pages/order/OrderSubmission/index",
query: {
id: res.data.cartId
id: res.data.cartId,
couponId: that.couponId // ID
}
})
} else {
return
}
if(news === 2) {
const coupId = that.couponId ? that.couponId : (that.couponList.usable[0] && that.couponList.usable[0].id || '')
uni.navigateTo({
url: '/pkg_user/views/gift/gift?cartId=' + res.data.cartId + '&couponId=' + coupId
})
}
if(news === 0) {
uni.showToast({
title: "添加购物车成功",
icon: "success",
@@ -1394,6 +1477,7 @@ export default {
that.getCartCount(true)
}
})
return
}
}).catch(error => {
that.isOpen = false;
@@ -1433,9 +1517,12 @@ export default {
this.posters = false
},
// v9-2
changeCoupons() {
changeCoupons(e) {
this.show = !this.show
},
setCoupon(couponId) {
this.couponId = couponId
},
async checkFavorite() {
const res = await checkProduct(this.id, this.uniqueId)
if (res.success) this.isFavorite = res.data.hasFavorite
@@ -1715,12 +1802,12 @@ export default {
.btn-car {
width: 200rpx;
height: 60rpx;
line-height: 60rpx;
height: 70rpx;
line-height: 70rpx;
box-sizing: border-box;
margin-right: 20rpx;
border: 2rpx solid #FF564A;
border-radius: 30rpx;
border-radius:100rpx;
color: #FF564A;
}
@@ -1731,9 +1818,9 @@ export default {
.btn-buy {
width: 200rpx;
height: 60rpx;
line-height: 60rpx;
border-radius: 30rpx;
height: 70rpx;
line-height: 70rpx;
border-radius: 70rpx;
background: #C52733;
color: #FFFFFF;
}
@@ -1873,7 +1960,14 @@ export default {
font-size: 0.28 * 100rpx;
color: #808080;
}
.after-title{
white-space: nowrap;
}
.store-title{
width: 400rpx;
height: 40rpx;
line-height: 40rpx;
}
.product-con .store-info .praise .iconfont {
font-size: 0.28 * 100rpx;
}
@@ -1957,7 +2051,10 @@ export default {
.footer .icon-shoucang1 {
color: #eb3729;
}
.product-con .footer{
height: 140rpx !important;
padding-bottom: 20rpx;
}
.product-con .product-intro .conter view {
width: 100% !important;
}
@@ -2064,7 +2161,24 @@ export default {
}
.earn-points {
flex: 1;
padding: 0 0 0 12rpx;
// padding: 0 0 0 12rpx;
margin-bottom: 10rpx;
box-sizing: border-box;
}
.gift-btn{
padding: 10rpx;
}
.gift-img{
width: 34rpx;
height: 34rpx;
margin-right: 10rpx;
}
.gift-wrap{
position: relative;
}
.gift-bg{
position: absolute;
left: 0;
width: 100%;
}
</style>
+5 -1
View File
@@ -2,7 +2,7 @@
<view class="v12-px-3 v12-py-5 qua-card ">
<view class="v12-white v12-radius-16">
<view class="v12-justify-between v12-pa-3">
<text class="v12-font-32 v12-dark-text">
<text class="v12-font-32 v12-dark-text name-wrap">
商家名称
</text>
<text class="v12-font-32 v12-dark-text v12-font-bold">
@@ -48,6 +48,10 @@ export default {
</script>
<style lang="less">
.name-wrap{
white-space: nowrap;
margin-right: 10rpx;
}
.qua-card {
}
.img{
+3 -1
View File
@@ -37,7 +37,9 @@
<textarea
v-model="expect"
placeholder="商品满足你的期待么?说说你的想法,分享给想买的他们吧~"
:maxlength="140"
/>
<view class="v12-px-4 v12-font-24 v12-dark1-text v12-mb-3">{{ expect.length || 0 }} / 140</view>
<view class="upload-title">
添加视频/图片
<text class="txt">
@@ -141,7 +143,7 @@ export default {
this.picArr = uploadList
},
async submit() {
const expect = trim(this.expect)
const expect = trim(this.expect).substring(0, 140)
const product_score = this.scoreList[0].index + 1 === 0 ? "" : this.scoreList[0].index + 1
const service_score = this.scoreList[1].index + 1 === 0 ? "" : this.scoreList[1].index + 1
try {
+60 -6
View File
@@ -16,6 +16,11 @@
/>
<text class="iconfont icon-sousuo" @click="submitForm"></text>
</view>
<view @click="goShoppingCart()" class="item animated bounceIn">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount > 99 ? '99+' : CartCount }}</text>
</view>
</view>
</view>
</form>
<view v-if="showSearchTypeLayer" class="search-type-layer">
@@ -68,7 +73,7 @@
<view class="text">
<view class="name more-t">{{ item.storeName }}</view>
<view class="vip acea-row row-between-wrapper">
<view class="flex ai-end">
<view v-if="!item.isNegotiable" class="ai-end" :class="{'flex': force2Decimal(item.price).length < 6}">
<view class="money">
<text class="num" v-if="item.vipPrice && item.vipPrice > 0">{{ force2Decimal(item.vipPrice) }}</text>
@@ -76,7 +81,11 @@
</view>
<view class="vip-money">{{ force2Decimal(item.otPrice) }}</view>
</view>
<view class="sale">已售{{ item.sales }}</view>
<view v-else class="money">价格面议</view>
<view class="" @click.stop="addToCart(item)">
<image class="logo" :src="webUrl+'/orderIcon/组 355.png'" mode="" style="margin-right:0; width: 34rpx; height:34rpx"/>
</view>
<!-- <view class="sale">已售{{ item.sales }}</view> -->
</view>
</view>
</view>
@@ -160,26 +169,40 @@
v-if="searchType === 'good' && loadend && list.length === 0"
/>
</view>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
/>
</view>
</template>
<script>
import { getProducts, getHotels } from '@/api/store'
import ProductWindow from '@/components/ProductWindow'
import { mapGetters } from 'vuex'
import NP from 'number-precision'
import NoGoodData from '@/components/good/NoData'
import Recommend from '@/components/Recommend'
import goCartMixin from '@/mixins/goCartMixins'
import {
getCartCount,
} from '@/api/store'
export default {
name: 'GoodsList',
components: {
NoGoodData,
ProductWindow,
Recommend
},
data: function () {
mixins: [goCartMixin],
data () {
return {
CartCount: 0,
webUrl: this.$VUE_APP_RESOURCES_URL,
list: [],
query: {
page: 1,
@@ -198,16 +221,31 @@ export default {
showSearchTypeLayer: false
}
},
computed: mapGetters(['userInfo']),
computed: mapGetters(['isLogin', 'location', 'userInfo']),
onLoad(e) {
const { s = '' } = this.$yroute.query
this.query.keyword = s
this.getList()
this.getCartCount()
},
onReachBottom() {
!this.loading && this.getList()
},
methods: {
//
getCartCount () {
const isLogin = this.isLogin
if (isLogin) {
getCartCount({
numType: 0
}).then(res => {
this.CartCount = res.data.count
})
}
},
goShoppingCart() {
this.$yrouter.switchTab('/pages/cart')
},
toggleSearchType(value) {
this.showSearchTypeLayer = value
},
@@ -298,6 +336,22 @@ export default {
</script>
<style scoped lang="less">
.iconfont{
position: relative;
}
.iconfont.icon-gouwuche1 .num {
right: -15rpx !important;
top: -15rpx!important;
font-size: 20rpx;
position: absolute;
width: 30rpx;
height: 30rpx;
background: #C52733 !important;
color: #fff;
border-radius: 50%;
text-align: center;
padding: 2rpx;
}
.productList {
min-height: 100vh;
background-color: #f7f7f7;
+70
View File
@@ -0,0 +1,70 @@
<template>
<view class="v12-pa-2">
<view class="culture v12-d-grid-columns-2" v-if="list.length > 0">
<view class="img-item " v-for="(item, index) in list" :key="index" @click="viewImg(item)">
<image class="img-item" :src="item" mode="widthFix|heightFix" lazy-load="false"></image>
</view>
</view>
<image
v-if="list.length === 0"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
</view>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => []
}
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
}
},
watch: {
landmarkDataId(value) {
if(value) {
this.getData()
}
}
},
methods: {
viewImg(item) {
uni.previewImage({
current: item, // http
urls: this.list || [] // http
})
}
}
}
</script>
<style lang="scss" scoped>
.culture{
grid-gap: 20rpx 20rpx;
padding: 20rpx 10rpx;
background: #fff;
border-radius: 30rpx;
margin-top: 20rpx;
}
.img-item{
width: 340rpx;
height: 340rpx;
border-radius: 30rpx;
}
.img-nodata {
position: relative;
top: 0;
left: 50%;
transform: translate(-50%, 0);
width: 352rpx;
height: 338rpx;
margin-bottom: 60rpx;
}
</style>
+294
View File
@@ -0,0 +1,294 @@
<template>
<view>
<view v-if="actives.length > 0" class="info-wrapper">
<view class="info-list">
<view v-for="(item, index) in actives" :key="index" class="info-item">
<view
:class="item.isTop === 1 ? 'info-item-top' : ''"
:style="{
'background-image': item.isTop
? 'url(' + webUrl + '/page/hotel/info-top-bg.png)'
: 'none',
}"
class="info-item-header"
>
<view class="name">
{{ item.name }}
</view>
<view class="intro">
{{ item.intro }}
</view>
<view class="intro v12-dark-text">活动时间: {{ item.activityTime }}</view>
</view>
<view class="info-item-body" v-if="item.contentType === 1">
<img-box
:imgList="item.images"
:num="item.images.length"
:img-radius="10"
style="width: 100%"
@click="infoItemViewClick(item)"
/>
</view>
<view class="info-item-body" v-if="item.contentType === 2">
<video
@play="infoItemViewClick(item, index)"
play-btn-position="center"
:show-fullscreen-btn="false"
class="video-item v12-mt-0"
:src="item.images[0]"
controls
:id="'video-item' + index"
:poster="item.images[0] + '?vframe/jpg/offset/1'"></video>
</view>
<view class="info-item-bottom">
<view class="time">
{{
item.createTime
? item.createTime.replace(/-/g, ".").substr(0, 10)
: ""
}}
</view>
<view class="btns">
<view class="flex">
<image
:src="webUrl + '/20230803152147141807.png'"
class="icon"
/>
<text class="seeNum-txt v12-font-28">{{ item.pv }}</text>
</view>
</view>
</view>
</view>
</view>
<image
:src="webUrl + '/home/no-data-bg.png'"
mode="widthFix"
class="no-data-loadend"
style="width: 100%;"
/>
</view>
<image
v-if="actives.length === 0"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
</view>
</template>
<script>
import { watchTownActive } from "@/api/inn.js"
import imgBox from '@/components/imageTypeSet/imagebox.vue'
export default {
props: {
infoArray: {
type: Array,
default: () => []
}
},
components: {
imgBox
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
actives: this.infoArray,
videoPlayers: []
}
},
watch: {
infoArray(val) {
this.actives = val
}
},
methods: {
coverPlay(){
this.videoPlayers.forEach(player => {
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
},
handlePlayer() {
this.videoPlayers.forEach(player => {
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
},
infoItemViewClick(item, index) {
if(item.contentType === 2) {
// const coverCtx = uni.createVideoContext('coverVideo', this)
// coverCtx.pause()
const playerId = 'video-item' + index
if(this.videoPlayers.includes(playerId)) {
this.videoPlayers.forEach(player => {
if(player === playerId) return
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
} {
this.videoPlayers.push(playerId)
this.videoPlayers.forEach(player => {
if(player === playerId) return
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
}
this.$emit('video')
}
uni.$u.debounce(() => {
watchTownActive({ id: item.id }).finally(() => {
this.actives.forEach(info => {
if (info.id === item.id) {
info.pv += 1
}
})
})
}, 500)
},
}
};
</script>
<style lang="scss" scoped>
.video-item {
width: 100%;
height: 400rpx;
border-radius: 10rpx;
}
.info-wrapper{
padding: 20px 10px;
}
.info-item + .info-item {
margin: 22rpx 0 0 0;
}
.info-item {
border-radius: 10rpx;
background-color: #fff;
.info-item-header {
position: relative;
padding: 20rpx 20rpx 0 20rpx;
&.info-item-top {
padding-top: 60rpx;
background-size: 100% 80rpx;
background-repeat: no-repeat;
background-image: url();
}
.name {
font-size: 16px;
color: #333;
font-weight: bold;
}
.intro {
margin: 10rpx 0 0 0;
color: #666;
font-size: 14px;
}
}
.info-item-body {
padding: 0 20rpx 20rpx 20rpx;
.video {
padding: 20rpx 0 0 0;
.video-item {
width: 100%;
height: 400rpx;
border-radius: 10rpx;
}
}
}
.info-item-bottom {
display: flex;
align-items: center;
padding: 20rpx;
border-top: 1px solid #f1f1f1;
font-size: 16px;
.time {
flex: 1;
color: #999999;
font-size: 28rpx;
}
.btns {
display: flex;
color: #999;
.flex + .flex {
margin: 0 0 0 32rpx;
}
.flex {
align-items: center;
}
.icon {
width: 32rpx;
height: 32rpx;
margin: 0 8rpx 0 0;
}
.zan-off-icon {
width: 32rpx;
height: 32rpx;
}
.zan-on-icon {
width: 32rpx;
height: 32rpx;
}
.seeNum-txt {
&.on {
color: #D81E06;
}
}
.more-btn {
position: relative;
.more-wrapper {
position: absolute;
right: -20rpx;
top: -150rpx;
z-index: 5;
width: 200rpx;
border-radius: 12rpx;
background-color: #fff;
box-shadow: 0px 1px 6px rgba(0,0,0,0.16);
.more-item + .more-item {
border-top: 1px solid #d5d5d5;
}
.more-item {
display: flex;
align-items: center;
justify-content: center;
height: 70rpx;
font-size: 14px;
color: #333;
.more-icon {
width: 36rpx;
height: 36rpx;
margin: 0 10rpx 0 0;
}
}
}
}
}
}
}
.info-item-top {
padding-top: 60rpx;
background-size: 100% 80rpx;
background-repeat: no-repeat;
background-image: url();
}
.name {
font-size: 16px;
color: #333;
font-weight: bold;
}
.intro {
margin: 10rpx 0 0 0;
color: #666;
font-size: 14px;
}
.img-nodata {
position: relative;
top: 0;
left: 50%;
transform: translate(-50%, 0);
width: 352rpx;
height: 338rpx;
margin-bottom: 60rpx;
}
</style>
+287
View File
@@ -0,0 +1,287 @@
<template>
<view class="projects">
<view class="tabs-wrap">
<view
@click="handleTab(item.value)"
class="tab-item"
:class="{
'tab-isActived': actived === item.value
}"
v-for="(item, index) in tabs"
:key="index">
<view
:class="{
'tab-isActived': actived === item.value,
'no-actived-1': actived === 2 && item.value === 1,
'no-actived-2': actived === 1 && item.value === 2,
'no-actived-3': actived === 3 && item.value === 2,
'no-actived-4': actived === 2 && item.value === 3,
}"
>
{{ item.name }}
</view>
</view>
</view>
<view
v-if="tabs.length > 0"
class="content v12-justify-center"
:class="{
'first-one': actived === 1,
'last-one': actived === 3
}"
>
<view v-if="items.length > 0" class="v12-d-grid-columns-2 v12-gap-10">
<view v-for="(item, index) in items" :key="index" class="store-card" @click="toStore(item.hotelId)">
<view class="cover-box">
<image
v-if="item.coverType === 1"
class="town-cover"
:src="item.cover"
mode="aspectFit|aspectFill|widthFix"></image>
<video
v-if="item.coverType === 2"
play-btn-position="center"
:show-fullscreen-btn="false"
class="town-cover"
:src="item.cover"
:show-play-btn="false"
:show-center-play-btn="false"
controls
:poster="item.cover + '?vframe/jpg/offset/1'"></video>
<view class="name-box">
<image
:src="webUrl + '/home/icon-location.png'"
class="icon"
/>
<view class="one-t">
{{ item.cityName }}
</view>
</view>
</view>
<view class="v12-pa-2 card-bottom">
<view class="v12-dark-text v12-font-bold v12-font-30 more-t v12-pb-1 v12-mb-2">{{ item.content }}</view>
<view class="v12-align-center">
<view class="avtor">
<image class="avtor" :src="item.logo" mode="scaleToFill"></image>
</view>
<view class="v12-secondary-dark-text v12-font-28 v12-ml-3 one-t">{{ item.hotelName }}</view>
</view>
</view>
</view>
</view>
<image
v-if="items.length === 0"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
style="left: 25%;"
mode="scaleToFill"
/>
</view>
<image
v-if="tabs.length === 0"
:src="webUrl + '/orderIcon/wu.png'"
class="img-nodata"
mode="scaleToFill"
/>
</view>
</template>
<script>
export default {
props: {
info: {
default:() => {}
}
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
actived: 1,
items: [],
itemsMap: {
1: 'project1Hotels',
2: 'project2Hotels',
3: 'project3Hotels'
}
}
},
watch: {
info(value) {
this.items = value && value[this.itemsMap[this.actived]]
},
actived: {
handler(value) {
this.items = this.info && this.info[this.itemsMap[value]]
},
deep: true,
immediate: true
}
},
computed: {
tabs() {
return this.info && [
{name: this.info.project1Name, value: 1},
{name: this.info.project2Name, value: 2},
{name: this.info.project3Name, value: 3},
] || []
}
},
methods: {
handleTab(value) {
this.actived = value
},
toStore(id) {
if (!id) {
return
}
uni.navigateTo({
url: '/pagesInn/inn/innHome?id=' + id
})
},
}
}
</script>
<style lang="scss" scoped>
.icon {
display: block;
width: 28rpx;
height: 28rpx;
margin: 0 10rpx 0 0;
}
.name-box{
color: #fff;
position: absolute;
left: 20rpx;
bottom: 20rpx;
font-size: 28rpx;
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 5;
display: flex;
align-items: flex-end;
height: 60rpx;
padding: 0 16rpx 16rpx 16rpx;
border-radius: 0rpx 0rpx 16rpx 16rpx;
box-sizing: border-box;
font-size: 24rpx;
line-height: 28rpx;
color: #fff;
background: linear-gradient(180deg, rgba(0,0,0,0) 0%, #000000 100%);
.icon {
display: block;
width: 28rpx;
height: 28rpx;
margin: 0 10rpx 0 0;
}
.one-t{
width: 240rpx !important;
}
}
.cover-box{
position: relative;
height: 316rpx;
}
.img-nodata {
position: relative;
top: 0;
left: 50%;
transform: translate(-50%, 0);
width: 352rpx;
height: 338rpx;
margin-bottom: 60rpx;
}
.card-bottom{
display: flex;
flex-direction: column;
justify-content: space-between;
height: calc(100% - 356rpx);
}
.avtor{
width: 52rpx;
height: 52rpx;
background: #eee;
border-radius: 50%;
}
.town-cover{
height: 316rpx;
width: 316rpx;
border-radius: 30rpx;
background: rgba(77,39,39,0.1);
}
.store-card{
width: 316rpx;
border-radius: 30rpx;
}
.tab-icon{
height: 30rpx;
width: 30rpx;
margin-right: 10rpx;
}
.fit-box-inner{
background: #f0f0f0;
width: initial;
height: inherit;
width: 40rpx;
}
.first-one{
border-radius: 0 24rpx 24rpx 24rpx !important;
}
.last-one{
border-radius: 24rpx 0 24rpx 24rpx !important;
}
.fit-box{
width: 40rpx;
height: initial;
background: #fff;
display: flex;
}
.projects{
padding: 20rpx;
}
.tabs-wrap{
display: flex;
justify-content: space-between;
}
.tab-item{
text-align: center;
flex: 1;
font-size: 32rpx;
font-weight: bold;
background: #fff;
view{
padding: 20rpx 0;
background: #f0f0f0;
width: inherit;
height: inherit;
display: flex;
justify-content: center;
align-items: center
}
}
.no-actived-1{
border-radius: 0 0 24rpx 0 !important;
}
.no-actived-2{
border-radius: 0 0 0 24rpx !important;
}
.no-actived-3{
border-radius: 0 0 24rpx 0 !important;
}
.no-actived-4{
border-radius: 0 0 0 24rpx !important;
}
.tab-isActived{
background: #fff !important;
border-radius: 24rpx 24rpx 0 0 !important;
position: relative;
}
.content{
background: #fff;
padding: 20rpx 10rpx;
border-radius: 24rpx;
}
</style>
+131
View File
@@ -0,0 +1,131 @@
<template>
<view class="service">
<view class="map-cont">
<map
:longitude="info.longitude"
:latitude="info.latitude"
:markers="[{id:1, latitude: info.latitude,longitude: info.longitude,width: 20, height: 25, iconPath: webUrl + '/page/qianxian/icon-location.png'}]"
style="width: 100%;height: 100%; border-radius: 20rpx;"
/>
</view>
<view class="v12-px-3 v12-font-32 v12-font-bold">{{ info.name || '' }}</view>
<view class="info-wrap">
<view>
<view class="v12-font-28 v12-mb-1 v12-dark1-text">{{ info.openTime || '' }}</view>
<view class="v12-font-28 v12-mb-1 v12-dark1-text">{{ info.address || '' }}</view>
<view class="v12-font-28 v12-mb-1 v12-dark1-text v12-d-flex">
<u-icon size="16" :name="webUrl + '/orderIcon/laba.png'"></u-icon>
{{ info.announcement || '' }}
</view>
</view>
<view class="action-wrap">
<view @click="showLocation">
<view>
<image :src="webUrl + '/page/qianxian/icon-addr.png'" class="img" />
</view>
<view class="text-center">导航</view>
</view>
<view @click="call">
<view>
<image :src="webUrl + '/page/qianxian/icon-phone.png'" class="img" />
</view>
<view class="text-center">咨询</view>
</view>
</view>
</view>
<view style="padding: 0 20rpx;"><u-divider></u-divider></view>
<view class="intro-wrap">
<view class="v12-dark-text v12-font-bold">
简介
</view>
<view class="intro-text">
<rich-text class="" :nodes="info.desc"></rich-text>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
info: {
default: () => {}
}
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
}
},
methods: {
showLocation() {
if (!this.info.latitude || !this.info.longitude) {
this.$dialog.error('暂无位置信息')
} else {
uni.openLocation({
latitude: this.info.latitude,
longitude: this.info.longitude
})
}
},
call() {
if (this.info.tel) {
uni.makePhoneCall({
phoneNumber: this.info.tel
})
} else {
this.$dialog.error('电话为空')
}
},
}
}
</script>
<style lang="scss" scoped>
.service {
background: #fff;
margin-top: 20rpx;
border-radius: 30rpx;
padding: 20rpx;
}
.intro-text{
color: #999;
font-size: 24rpx;
margin-top: 20rpx;
}
.intro-wrap{
padding: 0 20rpx 20rpx;
}
.action-wrap{
display: flex;
align-items: center;
.text-center{
text-align: center;
font-size: 24rpx;
color: #666;
}
}
.info-wrap{
display: flex;
justify-content: space-between;
padding: 20rpx 20rpx 0;
}
.service{
position: relative;
}
.map-cont {
height: 400rpx;
border-radius: 20rpx;
background: #fff;
padding: 20rpx;
box-sizing: border-box;
overflow: hidden;
}
.img{
display: block;
width: 64rpx;
height: 64rpx;
margin: 0 0 16rpx 16rpx;
}
</style>
+314
View File
@@ -0,0 +1,314 @@
<template>
<view class="town">
<hx-navbar :back="true" :fixed="true" color="#fff" :statusBar="true" transparent="hidden" barPlaceholder="hidden" />
<view class="top-img">
<image v-if="townInfo.coverType === 1" :src="townInfo.cover" mode="scaleToFill" class="img"></image>
<video
v-if="townInfo.coverType === 2"
id="videoCover"
class="img"
:src="townInfo.cover"
autoplay
play-btn-position="center"
:show-fullscreen-btn="false"
@play="handlePlay"
> </video>
</view>
<view class="top-intro">
<view class="intro-title v12-pa-3" style="width: 68%">
<text class="v12-font-bold v12-font-40" >{{ townInfo.name }}</text>
<text class="aaaa" v-if="townInfo.qualityRating">
{{ townInfo.qualityRating }}
</text>
</view>
<view class="shareBtn" @click="shareImg"><u-icon name="share-square" color="#C52733"></u-icon>分享给好友</view>
<!-- <u-line dashed></u-line> -->
<view v-if="townInfo.intro" class="v12-pa-3 intro-content">
<u-read-more :toggle="true" showHeight="200">
{{ townInfo.intro }}
</u-read-more>
</view>
</view>
<view class="tabs-wrap">
<view @click="handleTab(item.value)" :class="{ 'tab-actived' : item.value === actived }" class="tab-item" v-for="(item, index) in tabs" :key="index">{{ item.name }}</view>
</view>
<view class="list-wrap">
<view v-if="actived === 1">
<projects :info="townInfo.projectInfo"></projects>
</view>
<view v-if="actived === 2">
<culture :list="townInfo.cultureInfo.cultureImages"></culture>
</view>
<view v-if="actived === 3">
<information ref="information" :infoArray="activeties" @video="handleVideo"></information>
</view>
<view v-if="actived === 4">
<service :info="{...townInfo.serviceInfo, name: townInfo.name}"></service>
</view>
</view>
<!-- 分享 -->
<u-popup
:show="showShare"
mode="center"
bgColor="transparent"
>
<view class="box-share">
<view class="box-img">
<image
:src="webUrl + '/20230608112219219303.png'"
class="icon"
@click="closeShare"
/>
<image :src="posterUrl" class="main-img" mode="widthFix" />
</view>
<image
:src="webUrl + '/20230608112210135038.png'"
mode="widthFix"
class="btn"
@click="saveImg"
/>
</view>
</u-popup>
</view>
</template>
<script>
import { getAncientTownInfo, getAncientTownActive, shareTown } from "@/api/inn.js"
import {getUrlParam} from '@/utils/common.js'
import culture from './components/culture.vue'
import information from './components/information.vue'
import service from './components/service.vue'
import projects from './components/projects.vue'
export default {
components: {
culture,
information,
service,
projects
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
showShare: false,
townInfo: {},
posterUrl: '',
activeties: [],
id: '',
actived: 1,
tabs: [
{name: '项目', value: 1},
{name: '文化', value: 2},
{name: '活动', value: 3},
{name: '服务', value: 4},
],
}
},
onLoad(opts) {
this.id = opts.id
const obj = uni.getEnterOptionsSync()
if(opts.scene || obj.query.scene) {
const query = opts ? decodeURIComponent(opts.scene) : decodeURIComponent(obj.query.scene)
this.id = getUrlParam(query, 'id') || null
}
this.getInfo()
this.getActive()
},
methods: {
handlePlay() {
this.$refs.information.handlePlayer()
},
handleVideo() {
const videoCtx = uni.createVideoContext('videoCover', this)
videoCtx.pause()
},
shareImg() {
uni.showLoading()
shareTown(this.id).then(res => {
this.posterUrl = res.data
this.showShare = !this.showShare
}).finally(() => {
uni.hideLoading()
})
},
closeShare() {
this.showShare = false
},
saveImg() {
const _this = this
uni.getSetting({
success: getRes => {
if (getRes.authSetting["scope.writePhotosAlbum"]) {
_this.downloadImage()
} else {
uni.authorize({
scope: "scope.writePhotosAlbum",
success: () => {
_this.downloadImage()
},
fail: () => {
uni.openSetting({
success: openRes => {
console.log(typeof openRes, openRes)
},
fail: () => {
uni.showToast({
title: "请在设置中打开对应权限",
icon: "none"
})
}
})
}
})
}
},
fail: (err) => {
console.log(err, 2)
}
})
},
downloadImage() {
const _this = this
const randomID = () => Math.random().toString(36).substring(2)
uni.downloadFile({
url: this.posterUrl, //
filePath: wx.env.USER_DATA_PATH + "/share_" + randomID() + ".png", //
success: downRes => {
uni.saveImageToPhotosAlbum({
filePath: downRes.filePath, //
success: function () {
uni.showToast({
title: "保存成功",
icon: "success",
success() {
_this.showShare = false
}
})
},
fail: function (err) {
uni.showToast({
title: err,
icon: "none"
})
}
})
},
fail: function (err) {
uni.showToast({
title: err.errMsg,
icon: "error"
})
}
})
},
getInfo() {
uni.showLoading()
getAncientTownInfo(this.id).then(res => {
this.townInfo = res.data
}).finally(() => {
uni.hideLoading()
})
},
getActive() {
const params = {
ancientTownId: this.id
}
getAncientTownActive(params).then(res => {
this.activeties = res.data.records || []
})
},
handleTab(value) {
this.actived = value
},
}
}
</script>
<style lang="less" scoped>
@import "@/assets/css/store.less";
.shareBtn{
width: fit-content;
padding: 5rpx 15rpx;
background: #edbfc2;
box-shadow: 0rpx 4rpx 4rpx rgba(0,0,0,0.16);
border-radius: 24rpx 0rpx 0rpx 24rpx;
color: #C52733;
font-weight: bold;
font-size: 28rpx;
position: absolute;
right: 0;
top: 24rpx;
display: flex;
align-items: center;
}
.town{
min-height: 100vh;
background: #f0f0f0;
}
.tab-actived{
color: #fff;
font-weight: bold;
background: linear-gradient(to right, #C52733 0%, rgba(211,92,101,0.91) 54%, rgba(255,255,255,0.62) 100%);
border-radius: 38rpx 0rpx 0 38rpx;
padding: 0 20rpx;
}
.tabs-wrap{
display: flex;
justify-content: space-around;
padding: 20rpx 20rpx 0;
color: #333;
font-weight: bold;
font-size: 36rpx;
}
.intro-content{
letter-spacing: 2.5px;
line-height: 40rpx;
font-size: 28rpx;
color: #666;
}
.aaaa{
background: #F1B61A;
color: #fff;
border-radius: 100px;
padding: 0 10rpx;
font-size: 24rpx;
margin-left: 10rpx;
white-space: nowrap;
}
.top-intro{
width: 100%;
min-height: 360rpx;
background: #fff;
box-shadow: 0rpx 0rpx 12rpx rgba(0,0,0,0.13);
border-radius: 30rpx;
margin-top: -30rpx;
position: relative;
z-index: 11;
}
.top-img{
width: 100%;
background: #fff;
height: 560rpx;
position: relative;
.img{
height: inherit;
width: 100%;
}
.img1{
z-index: 10;
position: absolute;
top: 0;
left: 0;
border-radius: 30rpx;
}
.bg{
height: 100%;
width: 50%;
background: #fff;
position: absolute;
top: -30rpx;
right: 0;
z-index: 9;
}
}
</style>
+8 -4
View File
@@ -34,6 +34,7 @@
/>
<view class="good-info">
<view
v-if="historyItem.couponName"
:style="{
opacity: !historyItem.couponName ? 0 : 1
}"
@@ -42,16 +43,18 @@
<view class="v12-primary-text v12-primary-border v12-radius-6 v12-font-18 v12-px-1"></view>
<view class="v12-primary-text v12-primary-border v12-radius-6 v12-font-18 v12-px-1">{{ historyItem.couponName }}</view>
</view>
<view class="more-t v12-font-20 v12-mt-2">{{ historyItem.storeName }}</view>
<view class="v12-justify-between v12-mt-2 price">
<view class="v12-font-bold v12-primary-text v12-align-center">
<view v-if="!historyItem.isNegotiable" class="v12-font-bold v12-primary-text" :class="{'v12-align-center': (historyItem.price).toString().length < 5 && (historyItem.otPrice).toString().length < 5 }">
<text class="v12-font-16"></text>
<text class="v12-font-24">{{ historyItem.price }}</text>
<text class="v12-font-24 v12-mr-1">{{ historyItem.price }}</text>
<view class="ot-price v12-font-weight-400">
<text class="v12-font-22"></text>
<text class="v12-font-22">{{ historyItem.otPrice }}</text>
<view class="under-line"></view>
</view>
</view>
<view v-else class="v12-font-26 v12-primary-text v12-font-bold">价格面议</view>
<image
:src="webUrl+'/orderIcon/组 355.png'"
class="icon"
@@ -63,7 +66,7 @@
</view>
</view>
<view class="v12-px-6" v-if="items.length > 0">
<u-divider text=" · 已经到底啦 · " textPosition="center"></u-divider>
<u-divider text=" · 已经到底啦 · " textPosition="center"></u-divider>
</view>
<image
v-if="items.length === 0"
@@ -254,8 +257,9 @@ export default {
padding: 12rpx 12rpx 20rpx 12rpx;
.price {
line-height: 34rpx;
align-items: flex-end;
.ot-price {
margin: 0 0 0 10rpx;
// margin: 0 0 0 10rpx;
color: #CBCBCB;
position: relative;
}
+115 -24
View File
@@ -1,9 +1,6 @@
<template>
<view class="user user-page tabbar-page">
<view
v-if="$store.getters.token || userInfo.uid"
class="acea-row row-column"
>
<view class="acea-row row-column">
<view class="my-hearder">
<view class="my-header-bg">
<image
@@ -28,7 +25,10 @@
>
地标文化特产
</view>
<view class="info">
<view
v-if="$store.getters.token || userInfo.uid"
class="info"
>
<view class="name-cont">
<view class="txt flex">
<view class="txt-cont">
@@ -39,30 +39,72 @@
class="vip"
/>
</view>
<view class="qrcode" @click="getSpreadPoster">
<image :src="webUrl + '/icon/icon-qrcode.png'" class="code" />
<text class="code-txt">会员码</text>
<view :class="{'v12-align-center': !nowrap}">
<view class="qrcode" @click="getSpreadPoster">
<image :src="webUrl + '/icon/icon-qrcode.png'" class="code" />
<text class="code-txt">会员码</text>
</view>
<view class="v12-align-center" :class="{'v12-ml-2': !nowrap, 'v12-mt-2' : nowrap}" @click="linkTo('/pkg_user/views/personalData')">
<image
:src="webUrl + '/icon/icon-setting.png'"
class="settings-img v12-mr-1"
/>
<text class="v12-font-30">
设置中心
</text>
</view>
</view>
</view>
<view class="avatar-cont" @click="goPersonalData()">
<image :src="userInfo.avatar" class="img" />
</view>
</view>
<view
v-else
class="info"
>
<view class="name-cont">
<view class="txt flex">
<view class="txt-cont">
您还未登录
</view>
</view>
<view>
<view class="qrcode qrcode2" @click="toLoginHandle">
<text class="v12-font-30">
去登录
</text>
</view>
</view>
</view>
<view class="avatar-cont">
<image
:src="webUrl + '/page/my/avatar.jpg'"
class="img"
/>
</view>
</view>
</view>
<view class="my-hdeader-bottom">
<view class="item" @click="linkTo('/pages/user/UserBill/index')">
<view class="number">
<view v-if="!isNoLogin" class="number">
{{ userInfo.nowMoney ? force2Decimal(userInfo.nowMoney) : 0.00 }}
</view>
<view v-else class="number">
--
</view>
<view class="txt">
<image :src="webUrl + '/icon/icon-yue.png'" class="img" />
余额
</view>
</view>
<view class="item" @click="linkTo('/pages/user/Points/index')">
<view class="number">
<view v-if="!isNoLogin" class="number">
{{ userInfo.integral || 0 }}
</view>
<view v-else class="number">
--
</view>
<view class="txt">
<image :src="webUrl + '/icon/icon-jifen.png'" class="img" />
积分
@@ -290,6 +332,12 @@ export default {
},
spreadPoster: {},
toolList: [
{
text: '我的礼包卡',
url: '/pkg_user/views/giftList',
icon: '/icon/gift.png',
allowEnter: true
},
{
text: '我的优惠券',
url: '/pkg_user/views/myCoupons',
@@ -337,17 +385,14 @@ export default {
url: '/pages/user/History/index',
icon: '/icon/icon-help.png',
allowEnter: true
},
{
text: '设置中心',
url: '/pkg_user/views/personalData',
icon: '/icon/icon-setting.png',
allowEnter: true
}
],
bannerBgUrl: '',
userCenterBannerUrl: '',
pageKeyId: Object.freeze('userIndex')
pageKeyId: Object.freeze('userIndex'),
nowrap: true,
//
isNoLogin: false
}
},
computed: mapGetters(['userInfo']),
@@ -358,19 +403,23 @@ export default {
},
onShow() {
if (this.$store.getters.token) {
this.isNoLogin = false
uni.showLoading({
title: '加载中'
})
this.$store.dispatch('getUser', true)
//
this.getUserLevelInfo()
this.getUserLevelInfoReq()
this.isWeixin = isWeixin()
this.getUnreadMsgList()
// this.getUnreadMsgList()
} else {
this.isNoLogin = true
/*
cookie.set('redirect', '/pages/user/User/index')
uni.reLaunch({
url: '/pages/authorization/index'
})
*/
}
},
onHide() {
@@ -379,6 +428,19 @@ export default {
},
methods: {
...mapMutations(['updateAuthorizationPage']),
//
getTextWidth() {
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.select('.txt-cont').boundingClientRect(data => {
console.log(data, 'data');
if (data) {
this.nowrap = data.width < 200;
return data.width;
}
}).exec();
})
},
handleSwiper(e) {
const url = this.userCenterCarousel[e].url
this.linkTo(url)
@@ -426,6 +488,9 @@ export default {
this.$yrouter.push('/pages/order/ReturnList/index')
},
goMyOrder(type) {
if (this.isNoLogin) {
return
}
const types = {
0: 0,
1: 1,
@@ -450,13 +515,18 @@ export default {
this.$yrouter.push('/pkg_user/views/personalData')
},
//
getUserLevelInfo: function () {
getUserLevelInfoReq() {
const _this = this
getUserLevelInfo().then((res) => {
if (res.data) {
_this.userLevelInfo = res.data
if (res.isNoLogin) {
this.isNoLogin = true
return
} else {
if (res.data) {
_this.getTextWidth()
_this.userLevelInfo = res.data
}
}
uni.hideLoading()
}).catch(err => {
uni.hideLoading()
if (err.toLogin) {
@@ -508,6 +578,9 @@ export default {
})
},
toolItemClickHandle(item) {
if (this.isNoLogin) {
return
}
const url = item.url
if (item.showTip) {
this.$dialog.toast({
@@ -524,6 +597,9 @@ export default {
if (!url) {
return
}
if (this.isNoLogin) {
return
}
uni.navigateTo({ url })
},
bannerClickHandle() {
@@ -531,6 +607,12 @@ export default {
return
}
this.linkTo(this.userCenterBannerUrl)
},
toLoginHandle() {
cookie.set('redirect', '/pages/user/User/index')
uni.reLaunch({
url: '/pages/authorization/index'
})
}
}
}
@@ -591,6 +673,11 @@ export default {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.settings-img{
width: 38rpx;
height: 38rpx;
filter: invert(100%) brightness(200%);
}
.my-wrapper {
padding: 30upx;
&.wrapper {
@@ -609,7 +696,7 @@ export default {
width: 33.3333%;
margin: 0 0 42rpx 0;
align-items: center;
justify-content: center;
justify-content: flex-start;
.img {
width: 28px;
height: 28px;
@@ -646,6 +733,7 @@ export default {
z-index: 2;
.bg {
width: 100%;
height: 335px !important;
}
}
.my-header-body {
@@ -704,6 +792,9 @@ export default {
font-size: 13px;
}
}
.qrcode2 {
width: 92rpx;
}
}
.avatar-cont {
.img {
+21 -2
View File
@@ -91,6 +91,8 @@ export default {
return {
district: [],
id: 0,
// 0-1-2-
choosMode: 0,
userAddress: {
realName: '',
phone: '',
@@ -104,6 +106,15 @@ export default {
addressInput: ''
};
},
onLoad(e) {
//
const choosMode = this.$yroute.query.choosMode || 0
if (choosMode) {
this.choosMode = parseInt(choosMode)
} else {
this.choosMode = 0
}
},
mounted: function () {
const id = this.$yroute.query.id
this.id = id
@@ -382,7 +393,7 @@ export default {
duration: 2000
});
}
if(that.$yroute.query.choosMode == 1) {
if (that.choosMode) {
const item = {
id: res.data.id,
realName: name,
@@ -394,7 +405,15 @@ export default {
is_default: isDefault ? true : false,
post_code: ""
}
uni.$emit('chooseAddress', item)
if(that.choosMode === 1) {
uni.setStorageSync('chooseAddress', item)
}
if(that.choosMode === 2) {
uni.setStorageSync('cartChooseAddress', item)
}
if(that.choosMode === 3) {
uni.setStorageSync('giftChooseAddress', item)
}
}
that.$yrouter.back();
});
+110 -123
View File
@@ -1,9 +1,8 @@
<template>
<view
class="address-management"
:class="addressList.length < 1 && page > 1 ? 'on' : ''"
ref="container"
ref="container"
:class="addressList.length < 1 && page > 1 ? 'on' : ''"
class="address-management"
>
<view style="margin-bottom: 12rpx;" class="line" v-if="addressList.length > 0">
<!-- <image :src="webUrl+'/20230304135025917856.png'"/> -->
@@ -24,8 +23,11 @@
item.district
}}{{ item.detail }}
</view>
<view v-if="currentId === item.id && choosMode" class="tip-icon">
<u-icon name="checkbox-mark" color="#C52733" size="20"></u-icon>
</view>
</view>
<view v-if="!chooseMode" class="operation acea-row row-between-wrapper">
<view v-if="!choosMode" class="operation acea-row row-between-wrapper">
<view class="select-btn">
<view class="checkbox-wrapper">
<checkbox-group @change.stop="radioChange(item.id)">
@@ -65,22 +67,13 @@
<text class="iconfont icon-tianjiadizhi"></text>
添加新地址
</view>
<!--<view class="addressBnt wxbnt" v-if="isWechat" @click="getAddress">-->
<!--<text class="iconfont icon-weixin2"></text>导入微信地址-->
<!--</view>-->
</view>
</view>
</template>
<style scoped lang="less">
.address-management.on {
background-color: #fff;
height: 100vh;
}
</style>
<script type="text/babel">
import {getAddressDefaultSet, getAddressList, getAddressRemove} from "@/api/user";
import Loading from "@/components/Loading";
import {isWeixin} from "@/utils";
import {getAddressDefaultSet, getAddressList, getAddressRemove} from "@/api/user"
import Loading from "@/components/Loading"
import {isWeixin} from "@/utils"
import { pageListenMixins } from '@/mixins/pageListenMixins'
export default {
@@ -93,85 +86,120 @@ export default {
webUrl: this.$VUE_APP_RESOURCES_URL,
page: 1,
limit: 20,
chooseMode: false,//
// 0-1-2-
choosMode: 0,
addressList: [],
loadTitle: "",
loading: false,
loadend: false,
isWechat: isWeixin(),
pageKeyId: Object.freeze('userAddressIndex')
};
pageKeyId: Object.freeze('userAddressIndex'),
currentId: null
}
},
mounted: function () {
this.AddressList();
// computed: {
// // id
// currentId: {
// set(val) {
// },
// get() {
// const current = uni.getStorageSync('cartChooseAddress') || {}
// return current.id || null
// }
// }
// },
mounted() {
this.AddressList()
},
onReachBottom() {
!this.loading && this.AddressList();
!this.loading && this.AddressList()
},
onLoad: function (e) {
//
if (this.$yroute.query.choosMode != undefined) {
this.chooseMode = true;
onLoad(e) {
//
const choosMode = this.$yroute.query.choosMode || 0
if (choosMode) {
this.choosMode = parseInt(choosMode)
uni.setNavigationBarTitle({
title: '选择收货地址'
})
} else {
this.chooseMode = false;
this.choosMode = 0
}
},
onShow: function () {
this.refresh();
onShow() {
this.refresh()
},
methods: {
tapAddress: function (item) {
if (this.chooseMode) {
//
uni.$emit('chooseAddress', item)
//
this.$yrouter.back();
tapAddress(item) {
//
if (this.choosMode === 1) {
uni.setStorageSync('chooseAddress', item)
this.$yrouter.back()
}
//
if (this.choosMode === 2) {
uni.setStorageSync('cartChooseAddress', item)
this.$yrouter.back()
}
//
if (this.choosMode === 3) {
uni.setStorageSync('giftChooseAddress', item)
this.$yrouter.back()
}
},
refresh: function () {
this.addressList = [];
this.page = 1;
this.loadend = false;
this.AddressList();
refresh() {
this.addressList = []
this.page = 1
this.loadend = false
this.AddressList()
},
/**
* 获取地址列表
*
*/
AddressList: function () {
let that = this;
if (that.loading) return; //false
if (that.loadend) return; //false
that.loading = true;
getAddressList({page: that.page, limit: that.limit}).then(res => {
that.loading = false;
//apply();js;
that.addressList.push.apply(that.addressList, res.data);
that.loadend = res.data.length < that.limit; //
that.page = that.page + 1;
});
AddressList() {
// false
if (this.loading) return
// false
if (this.loadend) return
this.loading = true
getAddressList({page: this.page, limit: this.limit}).then(res => {
this.loading = false
// apply();js
this.addressList.push.apply(this.addressList, res.data)
//
this.loadend = res.data.length < this.limit
this.page = this.page + 1
if (this.choosMode === 1) {
this.currentId = uni.getStorageSync('chooseAddress') ? uni.getStorageSync('chooseAddress').id : this.addressList.find(e => e.isDefault === 1) ? this.addressList.find(e => e.isDefault === 1).id : null
}
//
if (this.choosMode === 2) {
this.currentId = uni.getStorageSync('cartChooseAddress') ? uni.getStorageSync('cartChooseAddress').id : this.addressList.find(e => e.isDefault === 1) ? this.addressList.find(e => e.isDefault === 1).id : null
}
//
if (this.choosMode === 3) {
this.currentId = uni.getStorageSync('giftChooseAddress') ? uni.getStorageSync('giftChooseAddress').id : this.addressList.find(e => e.isDefault === 1) ? this.addressList.find(e => e.isDefault === 1).id : null
}
})
},
/**
* 编辑地址
*/
editAddress: function (index) {
editAddress(index) {
this.$yrouter.push({
path: "/pages/user/address/AddAddress/index",
query: {id: this.addressList[index].id}
});
})
},
/**
* 删除地址
*/
delAddress: function (index) {
let that = this;
let address = this.addressList[index];
let id = address.id;
delAddress(index) {
const that = this
const address = this.addressList[index]
const id = address.id
uni.showModal({
title: '确认删除此收货地址?',
content: '',
@@ -179,7 +207,6 @@ export default {
cancelText: '取消',
confirmText: '确认',
success: res => {
if (res.confirm) {
getAddressRemove(id).then(function () {
uni.showToast({
@@ -187,84 +214,40 @@ export default {
icon: "success",
duration: 2000,
complete: () => {
that.addressList.splice(index, 1);
that.$set(that, "addressList", that.addressList);
that.addressList.splice(index, 1)
that.$set(that, "addressList", that.addressList)
}
});
});
})
})
}
},
fail: () => {
},
complete: () => {
}
});
})
},
/**
* 设置默认地址
*/
radioChange: function (id) {
radioChange(id) {
getAddressDefaultSet(id).then(res => {
this.refresh();
uni.showToast({title: res.msg, icon: "none", duration: 2000});
});
this.refresh()
uni.showToast({title: res.msg, icon: "none", duration: 2000})
})
},
/**
* 新增地址
*/
addAddress: function () {
addAddress() {
this.$yrouter.push({
path: "/pages/user/address/AddAddress/index"
});
},
getAddress() {
// openAddress().then(userInfo => {
// uni.showLoading({ title: "" });
// postAddress({
// real_name: userInfo.userName,
// phone: userInfo.telNumber,
// address: {
// province: userInfo.provinceName,
// city: userInfo.cityName,
// district: userInfo.countryName
// },
// detail: userInfo.detailInfo,
// post_code: userInfo.postalCode,
// wx_export: 1
// })
// .then(() => {
// this.page = 1;
// this.loading = false;
// this.loadend = false;
// this.addressList = [];
// this.AddressList();
// uni.hideLoading();
// uni.showToast({
// title: "",
// icon: 'success',
// duration: 2000
// });
// })
// .catch(err => {
// uni.hideLoading();
// uni.showToast({
// title: err.msg || err.response.data.msg|| err.response.data.message,
// icon: 'none',
// duration: 2000
// });
// });
// });
})
}
}
};
}
</script>
<style scoped lang="less">
.address-management.on {
background-color: #fff;
height: 100vh;
}
.address-management .item {
box-shadow: 0px 6rpx 6rpx rgba(0, 0, 0, 0.1);
opacity: 1;
@@ -272,5 +255,9 @@ export default {
margin-left: 32rpx;
margin-right: 32rpx;
}
.tip-icon{
position: absolute;
right: 10rpx;
bottom: 10rpx;
}
</style>
@@ -117,6 +117,9 @@
</view>
</view>
</view>
<view class="v12-px-6" v-if="spreadList.length === 0">
<u-divider :text=" ' · 此级别未找到会员 · ' " textPosition="center"></u-divider>
</view>
</view>
<Loading :loaded="loaded" :loading="loading"></Loading>
</view>
+92
View File
@@ -0,0 +1,92 @@
<template>
<u-popup
:show="show"
@close="close"
@open="open"
mode="center"
closeable
round="10"
>
<view class="v12-pa-3 pop-content">
<view class="v12-dark-text v12-font-bold pop-title">请选择登录的店铺</view>
<view v-for="(item, index) in list" :key="index" class="home-wrap">
<view>
<u-avatar :src="item.logo"></u-avatar>
</view>
<view class="name-wrap one-t">{{ item.name }}</view>
<view class="enter-btn" @click="queryHome(index)">
点击进入
</view>
</view>
</view>
</u-popup>
</template>
<script>
export default {
data() {
return {
list: [],
show: false,
}
},
methods: {
queryHome(e) {
this.$nextTick(() => {
this.$emit('enter', this.list[e])
uni.setStorageSync('homeId', this.list[e].id)
this.show = false
})
},
open(records) {
if(!records) return;
this.show = true;
this.list = records && [...records] || []
},
close() {
this.show = false;
}
}
}
</script>
<style lang="less" scoped>
.home-wrap{
display: flex;
align-items: center;
justify-content: space-between;
background: #F6F6F6;
padding: 10rpx 20rpx;
border-radius: 20rpx;
margin-bottom: 10rpx;
}
.name-wrap{
width: 280rpx;
font-size: 30rpx;
font-weight: bold;
}
.enter-btn{
width: 118rpx;
height: 42rpx;
background: #BD3124;
border-radius: 22rpx;
padding: 2rpx 10rpx;
text-align: center;
line-height: 42rpx;
color: #fff;
font-size: 24rpx;
}
.pop-content{
width: 568rpx;
max-height: 860rpx;
background: rgba(255,255,255,0.39);
border-radius: 12rpx;
}
.pop-title{
position: relative;
width: fit-content;
margin-bottom: 20rpx;
}
</style>
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -14,7 +14,7 @@
/>
<view class="">
<view class="name more-t">{{ item.storeName }}</view>
<view class="price-line flex ai-center">
<view class="price-line flex ai-center" v-if="!item.isNegotiable">
<image
:src="webUrl + '/20221118104357701129.png'"
class="label"
@@ -22,6 +22,7 @@
/>
<text>{{ item.price }}</text>
</view>
<view v-else class="price-line">价格面议</view>
</view>
<view class="sales-line flex ai-center">
<image
+113 -21
View File
@@ -3,7 +3,7 @@
<!-- title="店铺主页" -->
<hx-navbar
:fixed="true"
:background-color="[[13,197,197],[13,197,197]]"
:background-color="[0,[0,0,0,0],[0,0,0,0]]"
:pageScroll.sync="scrollData"
statusBarFontColor="#ffffff"
barPlaceholder="hidden"
@@ -31,9 +31,11 @@
:autoplay="true"
:controls="true"
:loop="false"
id="coverVideo"
object-fit="contain"
play-btn-position="center"
class="video"
@play="coverPlay"
/>
</view>
</view>
@@ -59,7 +61,13 @@
<image :src="webUrl + '/20230609145651814148.png'" v-else/>
</view>
<view class="a3 flex jc-between ai-end" style="width: 100%">
<view class="inn-owner" style="flex-grow: 1;">{{ inn.ownerName }}/店主</view>
<view >
<view class="inn-owner" style="flex-grow: 1;">{{ inn.ownerName }}/店主</view>
<view style=" color: #8B8F99; margin-top: 2px" class="v12-font-24 v12-justify-start v12-align-center">
营业时间:
<text v-if="inn.serviceTime">{{ inn.serviceTime }}</text> - <text v-if="inn.serviceEndTime">{{ inn.serviceEndTime }}</text>
</view>
</view>
<view v-if="inn.guaranteeValue" class="guarantee flex jc-center ai-center">
保证金{{ inn.guaranteeValue }}
</view>
@@ -93,7 +101,9 @@
</view>
</view>
</view>
</view>
</view>
<view class="inn-signature-wrap">
<view class="triangle"></view>
@@ -114,11 +124,16 @@
</view>
<view class="bg"></view>
<view class="map-info">
<view class="map-info-hd">
<image :src="webUrl + '/page/hotel/icon-location.png'" class="icon" />
</view>
<view class="map-info-bd more-t">
{{ inn.address }}
<view >
<view class="v12-justify-between v12-align-start">
<view class="map-info-hd">
<image :src="webUrl + '/page/hotel/icon-location.png'" class="icon" />
</view>
<view class="map-info-bd more-t">
{{ inn.address }}
</view>
</view>
</view>
<view class="map-info-ft flex">
<view class="item" @click="showLocation">
@@ -164,7 +179,7 @@
/>
<view class="">
<view class="name more-t">{{ item.storeName }}</view>
<view class="price-line flex ai-center">
<view class="price-line flex ai-center" v-if="!item.isNegotiable">
<image
:src="webUrl + '/20221118104357701129.png'"
class="label"
@@ -172,6 +187,7 @@
/>
<text>{{ item.price }}</text>
</view>
<view class="v12-primary-text v12-font-26" v-else>价格面议</view>
</view>
<view class="sales-line flex ai-center">
<image
@@ -232,7 +248,8 @@
controls
play-btn-position="center"
class="video-item"
@play="infoItemViewClick(item)"
:id="'video-item' + index"
@play="infoItemViewClick(item, index)"
/>
</view>
<view v-else>
@@ -247,7 +264,7 @@
</view>
<view class="info-item-bottom">
<view class="time">
{{ item.createdTime ? item.createdTime.replace(/-/g, '.').substr(0, 10) : '' }}
{{ item.publishTime ? item.publishTime.replace(/-/g, '.').substr(0, 10) : '' }}
</view>
<view class="btns">
<view class="flex">
@@ -385,6 +402,10 @@
<image :src="webUrl + '/page/hotel/edit.png'" class="img" />
修改资料
</view>
<view class="bottom-btn" @click="changeHome">
<image :src="webUrl + '/icon/qiehuan.png'" class="img" />
切换店铺
</view>
</view>
</view>
<goo-skeleton v-else />
@@ -401,15 +422,21 @@
class="icon"
@click="changeShare"
/>
<image :src="posterUrl" class="main-img" />
<image
:src="posterUrl"
mode="widthFix"
class="main-img"
/>
</view>
<image
:src="webUrl + '/20230608112210135038.png'"
mode="widthFix"
class="btn"
@click="saveImg"
/>
</view>
</u-popup>
<homeList ref="homeList" @enter="goHome"></homeList>
</view>
</template>
@@ -425,7 +452,8 @@ import {
setTopHotelNew,
getHotelNewsZan,
getHotelShareBackgroundImage,
hotelNewsView
hotelNewsView,
getMerchantApply
} from "@/api/inn.js"
import {formatDateTime} from "@/utils"
import {getUrlParam} from "@/utils/common.js"
@@ -433,14 +461,16 @@ import imgBox from '@/components/imageTypeSet/imagebox.vue'
import cookie from "@/utils/store/cookie"
import {addStore, removeStore} from "@/api/favorite"
import { pageListenMixins } from '@/mixins/pageListenMixins'
import homeList from "../components/jin-edit/homeList.vue"
export default {
components: {
imgBox
imgBox,
homeList
},
mixins: [pageListenMixins],
data() {
return {
homeList: [],
webUrl: this.$VUE_APP_RESOURCES_URL,
isLoad: false,
activeIndex: 0,
@@ -477,7 +507,8 @@ export default {
isLoadGoodListoSuccess: false,
isLoadInfoListSuccess: false,
pageKeyId: '',
shareImg: ''
shareImg: '',
videoPlayers: []
}
},
// onPageScroll(e){}
@@ -487,6 +518,8 @@ export default {
onLoad(options) {
const id = options.id || ''
const from = options.from
console.log(from);
switch (from) {
//
case 'techan':
@@ -521,7 +554,7 @@ export default {
break
}
if (id) {
this.id = id || null
this.id = this.$yroute.query.isMyInn ? uni.getStorageSync('homeId') || id : id || id
this.partnerId = options.partnerId || null
} else {
let obj = uni.getEnterOptionsSync()
@@ -565,7 +598,38 @@ export default {
}
this.fetchInnDetail()
},
watch: {
activeIndex: {
handler(val) {
console.log(val);
if (val === 1) {
this.fetchInnInfoList()
}
},
deep: true,
immediate: true
}
},
methods: {
goHome(e) {
this.id = e.id
this.isLoad = false
if(this.activeIndex !==1) {
this.activeInde = 1
} else {
this.fetchInnInfoList()
}
this.fetchInnDetail()
// this.fetchGoods(this.id)
},
changeHome() {
uni.showLoading()
getMerchantApply().then(res => {
this.$refs.homeList.open(res.data || [])
}).finally(() => {
uni.hideLoading()
})
},
changeShare() {
this.showShare = !this.showShare
},
@@ -660,7 +724,32 @@ export default {
infoClick: function (info) {
// this.$yrouter.push('/pagesInn/inn/innInfoDetail?id=' + info.id)
},
infoItemViewClick(item) {
coverPlay(){
this.videoPlayers.forEach(player => {
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
},
infoItemViewClick(item, index) {
if(item.type === 'NT_VIDEO') {
const coverCtx = uni.createVideoContext('coverVideo', this)
coverCtx.pause()
const playerId = 'video-item' + index
if(this.videoPlayers.includes(playerId)) {
this.videoPlayers.forEach(player => {
if(player === playerId) return
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
} {
this.videoPlayers.push(playerId)
this.videoPlayers.forEach(player => {
if(player === playerId) return
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
})
}
}
uni.$u.debounce(() => {
hotelNewsView({ id: item.id }).finally(() => {
this.infoArray.map(info => {
@@ -766,6 +855,8 @@ export default {
_this.activeIndex = 1
_this.tabList[0].isShow = false
} else {
_this.activeIndex = 0
this.tabList[0].isShow = true
_this.fetchGoods()
}
}
@@ -846,11 +937,11 @@ export default {
break
}
},
fetchGoods() {
fetchGoods(id) {
this.isLoadGoodListoSuccess = false
this.goodsList = []
getHotelGoodList({
id: this.inn.id,
id: id || this.inn.id,
page: 1,
limit: 12
}).then(res => {
@@ -1018,9 +1109,8 @@ export default {
background: #fff;
.name {
padding: 8rpx 6rpx;
padding: 0 6rpx;
font-size: 26rpx;
line-height: 36rpx;
color: #333333;
}
@@ -1276,6 +1366,7 @@ export default {
padding: 40rpx 10rpx 40rpx 32rpx;
color: #333;
font-size: 14px;
justify-content: space-between;
.map-info-hd {
.icon {
display: block;
@@ -1326,6 +1417,7 @@ export default {
padding: 32rpx;
}
.info-section {
word-break: break-all;
.info-item + .info-item {
margin: 32rpx 0 0 0;
}
+12 -1
View File
@@ -26,9 +26,12 @@
<textarea
v-model="form.intro"
placeholder="请输入简介..."
maxlength="140"
placeholder-style="font-size:24rpx;color:#C2C5CC;"
class="content-style inp"
@input="inputIntro"
/>
<text class="v12-font-24 v12-dark1-text">{{ form.intro.length > 140 ? 140 : form.intro.length }} / 140</text>
</view>
<view class="form-item" v-if="showUpload">
<view v-if="uploadType === 'image'" class="title">图片(最多9张):</view>
@@ -115,6 +118,14 @@
this.hotelId = option.hotelId
},
methods: {
inputIntro() {
if(this.form.intro.length > 140) {
uni.showToast({
title: '字数超过限制',
icon: 'none'
})
}
},
changeTab(index) {
this.tabIndex = index
this.showUpload = false
@@ -152,7 +163,7 @@
postHotelNewsAdd({
hotelId: this.hotelId,
name: this.form.title,
intro: this.form.intro,
intro: this.form.intro.substring(0, 140),
content: this.form.content.replace(/\<img src/g, '<img style="display: block;max-width: 100%;" src'),
type: this.uploadType === 'image' ? 'NT_TEXT' : 'NT_VIDEO',
resources: this.uploadType === 'image' ? this.uploadedFilesArray : [],
+39 -5
View File
@@ -97,6 +97,24 @@
</view>
<text class="iconfont icon-jiantou"></text>
</view>
<view class="item" @click="showTimePicker">
<view class="cell acea-row row-between row-middle">
<view class="cell-title">营业时间</view>
<view class="cell-value">
<u--text :text="innApplyInfo.serviceTime + ' - ' + innApplyInfo.serviceEndTime"></u--text>
<tpf-time-range
startTime="00:00"
endTime="23:59"
:startDefaultTime="innApplyInfo.serviceTime"
:endDefaultTime="innApplyInfo.serviceEndTime"
ref="TimePickerPopupRef"
@timeRange="timeRange"
>
</tpf-time-range>
</view>
</view>
<text class="iconfont icon-jiantou"></text>
</view>
<view class="item is_required">
<view class="cell acea-row row-between row-middle">
<view class="cell-title">店主名字</view>
@@ -140,7 +158,7 @@
<view class="cell acea-row row-between row-middle">
<view class="cell-title">
店铺图片
<text class="txt">最多上传9张图片</text>
<!-- <text class="txt">最多上传9张图片</text> -->
</view>
</view>
</view>
@@ -149,7 +167,8 @@
<tm-upload
:dataList="picsArray"
:upload_img_wh="(750 - 3 * 16 - 2 * 32) / 3.0"
:upload_max="10"
:upload_max="99999"
:upload_count="9999"
:url="uploadUrl"
:header="uploadHeader"
@change="uploadedImgChange"
@@ -170,6 +189,7 @@
:dataList="qualificationsArray"
:upload_img_wh="(750 - 3 * 16 - 2 * 32) / 3.0"
:upload_max="10"
:url="uploadUrl"
:header="uploadHeader"
@change="uploadedImg2Change"
@@ -182,6 +202,7 @@
</template>
<script>
import TimePickerPopup from '@/components/timePickerPopup/time-picker-popup.vue';
import CitySelect from '@/components/CitySelect'
import tmUpload from '@/components/tm-upload/tm-upload.vue'
import {
@@ -193,6 +214,7 @@ import {getHotelTypeList, postHotelInfoEdit} from '@/api/inn.js'
export default {
components: {
CitySelect,
TimePickerPopup,
tmUpload
},
data() {
@@ -228,7 +250,9 @@ export default {
'tel': '',
'qrcode': '',
'tips': '',
'type': ''
'type': '',
serviceTime: '00:00',
serviceEndTime: '23:59'
},
loading: false
}
@@ -241,8 +265,10 @@ export default {
if (id) {
//
const hotel = JSON.parse(uni.getStorageSync('MY_HOTEL_INFO'))
console.log(hotel)
this.innHistory = hotel
this.innHistory = {
...hotel
}
console.log(hotel,'hotel');
this.fillData(this.innApplyInfo, this.innHistory)
if (hotel.coverType === 2) {
this.innApplyInfo.coverVideo = hotel.cover
@@ -271,6 +297,14 @@ export default {
}
},
methods: {
showTimePicker() {
this.$refs.TimePickerPopupRef.open()
},
timeRange(e) {
this.innApplyInfo.serviceTime = e[0]
this.innApplyInfo.serviceEndTime = e[1]
this.$forceUpdate()
},
typePickerChange: function (e) {
this.typeIndex = e.target.value
// type
+6 -3
View File
@@ -93,23 +93,26 @@ export default {
}
const res = await takePrize(item.id)
if (res.success) {
console.log('success', '+++++++++++++');
this.$set(this.list[index], 'status', 2)
uni.showModal({
title: '领取成功',
content: '您的奖品已经领取成功,请前往我的订单查看奖品发货信息',
content: '您的奖品已经领取成功,请前往积分记录查看奖品发货信息',
cancelText: '下次再说',
confirmText: '查看订单',
confirmText: '积分记录',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定')
uni.navigateTo({
url: '/pages/order/MyOrder/index'
url: '/pages/user/Points/index'
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
} else {
console.log('err', '==========');
}
}
}

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