113 Commits
Author SHA1 Message Date
lifizer c8119933af Fix(送礼):[#6162, #6163]图片展示效果调整-2 2026-09-17 16:58:26 +08:00
lifizer c9c048e1ed Fix(送礼):[#6162, #6163]图片展示效果调整 2026-09-17 14:31:49 +08:00
lifizer d363547bf7 Fix(云灵AI):[#5917]我要送礼选择送礼条件后直接点击【跳过】,会直接生成携带该送礼条件的对话 2026-09-15 17:54:42 +08:00
lifizer bc5a59c104 Feat(送礼):支持AI的文生图-5 2026-09-15 16:39:32 +08:00
lifizer 46d8fe8b70 Fix(送礼):[#6046]输入框限制修改为300字 2026-09-15 09:13:10 +08:00
lifizer 108f204f03 Fix(送礼):[#6106]送礼完成后点击【再送一份】按钮,屏幕会变成白屏 2026-09-14 10:54:43 +08:00
linxi 77fee4ea46 Fix:5967 【商城小程序】已发过消息的聊天页面,进行图片相关操作后页面出现白屏 2026-09-11 16:22:35 +08:00
linxi 0e04c560bc Fix:6018 【礼品集采中心小程序】我的订单-集采中心,隐藏自建订单详情页的实付款 2026-09-11 16:01:27 +08:00
lifizer e6d8bff772 Fix(送礼):[#6073]在页面超时后,点击付款并赠送,界面显示“订单已过期,请刷新当前界面”,需自动刷新该页面 2026-09-11 10:11:41 +08:00
lifizer 44093a5893 Fix(送礼):[#6046]输入框限制修改为500字 2026-09-11 09:55:08 +08:00
lifizer 7f058ec10b Fix(送礼):[#6064]收礼方查看的AI礼包封面图不需要显示商品图片 2026-09-11 09:45:02 +08:00
lifizer c226263289 Fix(送礼):[#6075]1、预览图底部增加红色文字;2、点击生成礼包封面后,按钮文字变为:礼包封面生成中... 2026-09-11 09:27:00 +08:00
lifizer a59d10e7dc Feat(送礼):支持AI的文生图-4 2026-09-09 14:32:51 +08:00
lifizer 3523ce5599 Feat(送礼):支持AI的文生图-3 2026-09-09 11:42:47 +08:00
lifizer 41d9da4c7e Feat(送礼):支持AI的文生图-2 2026-09-08 16:06:25 +08:00
lifizer 733048e2c9 Feat(送礼):支持AI的文生图 2026-09-08 15:23:29 +08:00
lifizer 8c00c82e3f Feat(商品详情):店铺资料通过配置控制是否显示 2026-09-08 10:09:47 +08:00
linxi 452f3e3327 Fix:5926 【商城小程序】多规格商品默认组合无库存时,组成该组合的两个规格属性因各自均无可售组合,导致全部规格按钮置灰。 2026-09-04 15:04:28 +08:00
linxi 61cecbe8e5 Fix:5955 【商城小程序】特产供应商/文玩供应商/特色店铺,入驻申请被驳回后页面不显示驳回原因 。 2026-09-04 14:38:55 +08:00
linxi 88147f3783 Fix:5956 【商城小程序】进入招商项目页面,连续点击多次招商项目文件,阅读文件左滑返回后有报错 2026-09-04 11:39:18 +08:00
linxi 069f0fa413 Fix:5954 【商城小程序】进入趣游页面时会短暂出现“暂无数据”后才加载出内容 2026-09-04 11:33:13 +08:00
linxi 6e14b8dd69 Fix:5953 【商城小程序】使用指南页面切换分类类型时页面刷新,短暂展示“暂无数据”,需优化页面切换刷新效果 2026-09-04 11:27:06 +08:00
linxi ed5792b860 Fix:5950 【商城小程序】文玩页面当前城市标识显示的是“当前定位”,参考图2进行文字调整 2026-09-04 11:20:30 +08:00
linxi 98a142dba1 Fix:5948 【商城小程序】旅居团购提交订单取消支付后,错误跳转到【购物‑待付款】页面 2026-09-04 11:14:17 +08:00
linxi b3ae93633c Fix:5921 【商城小程序】划动店铺列表区域无法加载出全部店铺 2026-09-04 10:41:26 +08:00
linxi cb5449eaac Fix:取消体现金额最低限制(界面) 2026-08-31 09:11:45 +08:00
LinCyJang 37c1277a83 Feat:增加提现规则 2026-08-29 15:07:51 +08:00
linxi 36585188c4 Fix:5453 【商城小程序】苹果手机视频列表布局方向从右到左,应该从左到右排列,与安卓同步 2026-08-26 16:25:21 +08:00
linxi 2ee9876f01 Fix:5453 【商城小程序】苹果手机视频列表布局方向从右到左,应该从左到右排列,与安卓同步 2026-08-26 15:54:51 +08:00
linxi 1687f417d7 Fix:5882 【商城小程序】【商户入驻-特产供应商/文玩供应商】填写特产供应商的基本信息资料,文玩供应商的基本信息会被自动同步填写成一模一样的(测试用户ID:5838 配) 2026-08-26 09:37:02 +08:00
linxi 59dec5c11c Fix:5873 【商城小程序】开屏广告持续时间改成5秒 2026-08-25 12:20:08 +08:00
linxi d5d85d2cd2 Fix:5863 【商城小程序】【商户入驻-体验店入驻】当体验店入驻申请被驳回后,入驻申请详情页不显示【提交申请】按钮 2026-08-25 11:57:57 +08:00
linxi 708aa88914 Fix:5872 【商城小程序】【商户入驻-礼品集采中心】礼品集采中心入驻详情页面中,中心名称错误显示为“请填写批发商名称” 2026-08-25 11:34:26 +08:00
linxi dfb92b7332 Fix:5874 【商城小程序】【商户入驻-礼品集采中心】入驻详情页中,“中心名称”“营业执照名称”“联系人姓名”“联系方式”“省市区”“详细地址”与输入框文案间距过大,且“省市区”与“详细地址”输入框文案未对齐 2026-08-25 11:33:23 +08:00
linxi df47b96e87 Fix:5857 【商城小程序】我的订单-集采中心,商城小程序订单详情页商品总价和礼品价值的金额与文字不在一行 2026-08-25 11:24:03 +08:00
linxi 5d8ea0cbd5 Fix:5565 【商城小程序】千县攻略简介和定位的文字字体大小调整 2026-08-24 12:41:24 +08:00
linxi f38ba76ac0 Fix:5851 【商城小程序】【商户入驻-店铺入驻】提交店铺申请后点击“撤销申请”按钮,店铺入驻详情页验证码输入框无法输入内容并且缺失【获取验证码】按钮 2026-08-24 12:25:59 +08:00
linxi 1845171a1e Fix:5852 【商城小程序】验证码输入框旁的“验证码”文案显示位置错位 2026-08-24 12:14:18 +08:00
linxi 007e80bebb Fix:5850 【礼品集采中心小程序】我的订单-集采中心,商城小程序自建礼品订单详情页,自建礼品关闭礼品价值时隐藏礼品价值 2026-08-24 11:54:01 +08:00
linxi a427cfbb92 Fix:5844 【商城小程序】【礼品集采中心入驻】商户入驻申请被驳回后页面未显示驳回原因 2026-08-22 11:58:00 +08:00
linxi f1e063aab9 Fix:5527 【管理后台】媒体管理-弹窗海报,在填写使用指南板块链接时每次从其他板块切换至首页均重复弹出弹窗 2026-08-22 11:05:27 +08:00
linxi 876e15b655 Merge branch 'dev' of gitee.com:fengyuze178/xdd-uniapp-new into dev 2026-08-21 10:20:38 +08:00
linxi b0d8d3163e Fix:5835 【商城小程序】【商户入驻-礼品集采中心】扫码入驻审核通过后,再次进入入驻详情页仍显示“未提交申请”(状态未同步) 2026-08-21 10:20:31 +08:00
lifizer 1e58a29d9b Merge branch 'dev' of https://gitee.com/fengyuze178/xdd-uniapp-new into dev 2026-08-21 10:02:21 +08:00
lifizer e6ff7fafce Fix(云灵AI):[#5831]上滑时背景图相对底部固定 2026-08-21 10:02:03 +08:00
linxi 640d61fd49 Fix:5832 【商城小程序】【商户入驻】各接口入驻详情页,点击“撤销申请”,页面会自动返回至商户入驻列表页 2026-08-21 10:01:56 +08:00
lifizer 6843be82cb Fix(云灵AI):[#5796]预设礼品条件选择界面,苹果16以后出的手机,页面无法往下滑动 2026-08-20 17:05:48 +08:00
linxi c58f785304 Fix:5819 【礼品集采中心小程序】我的订单-集采中心,把自建礼品订单详情页的支付状态和支付方式都删掉 2026-08-20 16:04:13 +08:00
linxi 2062046901 Fix:5824 【商城小程序】【商户入驻】进入任意接口入驻页面时,先闪现未填写资料界面,过几秒才会显示已填写的资料页面 2026-08-20 15:59:59 +08:00
linxi 1adef8d00b Fix:5798 【礼品集采中心小程序】【商户入驻-礼品集采中心入驻】礼品集采中心入驻详情页,商家资质上传位置仅支持上传单张图片 2026-08-20 12:31:56 +08:00
linxi 62b227034f Merge branch 'dev' of gitee.com:fengyuze178/xdd-uniapp-new into dev 2026-08-20 11:57:25 +08:00
linxi 60c3e0f572 Fix: 语法错误 2026-08-20 11:57:18 +08:00
lifizer 0f76d54e27 Feat(云灵AI):增加引导内容配置 2026-08-20 11:53:04 +08:00
linxi 0369f0f1d3 Fix:5808 【商城小程序】【商户入驻-文玩供应商】入驻详情页填写资料后返回商户入驻列表页,再次进入时已填写的店铺资料未自动保存 2026-08-20 11:52:35 +08:00
linxi 085730bb9c Fix:5808 【商城小程序】【商户入驻-文玩供应商】入驻详情页填写资料后返回商户入驻列表页,再次进入时已填写的店铺资料未自动保存 2026-08-20 10:57:01 +08:00
linxi d68f734f95 Fix:5801 【商城小程序】从(体验版)香道滇小程序【商户入驻】点击礼品集采中心入驻接口会跳转到(正式版)香道滇产业供应链 2026-08-20 10:43:29 +08:00
linxi 41d99e95f9 Fix:5805 【商城小程序】【商户入驻-入驻申请须知】用户未勾选“我已仔细阅读并同意”时,点击弹窗空白区域即可关闭弹窗,不符合逻辑 2026-08-20 10:39:11 +08:00
linxi ae72fc0a8f Fix:5809 【商城小程序】【商户入驻】商户入驻详情页视频上传位置缺少删除键 2026-08-20 10:33:31 +08:00
linxi 8e00a1e477 Fix:5812 【商城小程序】【商户入驻-店铺入驻】商户入驻详情页店铺图片封面及店铺logo上传位置缺少删除键 2026-08-20 10:30:01 +08:00
linxi 75d4b43e5e Fix:5793 【商城小程序】我的订单-集采中心,在采购批发订单详情页点击商品信息卡片,改为无法进入批发商品详情页 2026-08-18 18:22:45 +08:00
linxi 62d8cfd13b Fix:5785 【商城小程序】【商户入驻-礼品集采中心入驻】入驻详情页,省市区填写栏错误显示为null 2026-08-18 14:19:09 +08:00
linxi 96b175a562 Fix:5785 【商城小程序】【商户入驻-礼品集采中心入驻】入驻详情页,省市区填写栏错误显示为null 2026-08-18 14:15:49 +08:00
linxi 230fe66e82 Fix:5689 【礼品集采中心小程序】【我的订单-联系商家】向商家发送图片时,页面图片显示为纯白色 2026-08-18 14:11:47 +08:00
linxi 20c53f245c Fix:5680 【商城小程序】购物类订单:收礼方确认收货后订单变为待评价状态,点击【去评价】跳转页面错误,应跳转到图2的页面 2026-08-18 14:00:43 +08:00
linxi ac741f9339 Fix:5701 【商城小程序】【我的订单-集采中心】订单列表采购批发商品卡片未显示商品名称信息 2026-08-18 13:44:00 +08:00
linxi f0284d1b06 Fix:5693 【商城小程序】【我的订单-订单列表】删除已完成订单后,页面跳转至“购物”Tab 2026-08-18 13:31:09 +08:00
linxi 3ac6fa4e14 Fix:5785 【商城小程序】【商户入驻-礼品集采中心入驻】入驻详情页,省市区填写栏错误显示为null 2026-08-18 10:26:04 +08:00
linxi 691f8eabd0 Fix:5695 【商城小程序】已发货订单申请退款被驳回后,订单详情页面没有物流一栏 2026-08-18 10:19:08 +08:00
linxi b0e7628f65 Fix:5728 【商城小程序】我的礼品卡-收到的,商品名称长会被标识遮挡 2026-08-17 18:32:40 +08:00
linxi 920e7cc1dc Fix:5730 【管理后台】我的订单-集采中心,自建礼品订单详情页“商品总价”改成“礼品价值”,支付方式未显示余额支付/微信支付 2026-08-17 16:21:44 +08:00
linxi f4539ccf4a Fix:5778 【商城小程序】【商户入驻-入驻申请须知】香道滇小程序展示的“入驻申请须知”段落格式,与香道滇后台管理系统中配置的内容格式不一致 2026-08-17 16:18:47 +08:00
linxi f20e73e859 Fix:5777 【礼品集采中心小程序】【商户入驻-礼品集采中心】入驻详情页增加“营业执照名称”填写栏,必填项 2026-08-17 16:08:23 +08:00
linxi 57fc90b030 Fix:5759 【礼品集采中心小程序】我的订单-集采中心,领取采购批发礼品的盲盒,订单列表和订单详情页效果显示错误 2026-08-17 15:36:56 +08:00
linxi 6b09cf8a90 Fix:5761 【礼品集采中心PC端】【商户入驻-礼品集采中心】头像、资质内容,点击图片可重新上传,无删除按键。 2026-08-17 14:39:29 +08:00
linxi 4670b51a5a Feat:开屏页调整至5s 2026-08-17 14:39:22 +08:00
linxi e729fb3c94 Merge branch 'dev' of gitee.com:fengyuze178/xdd-uniapp-new into dev 2026-08-12 10:50:17 +08:00
linxi c6ef03434e Fix:5689 【礼品集采中心小程序】【我的订单-联系商家】向商家发送图片时,页面图片显示为纯白色 2026-08-12 10:50:10 +08:00
lifizer f7a3bdc3fe Refactor(云灵AI):ws连接使用uid拼接,兼容APP登录没有获取到unionId 2026-08-12 10:42:57 +08:00
linxi b636cd905b Fix:5707 【礼品集采中心小程序】【我的订单-集采中心】订单详情有【再买一单】按钮,需要删除 2026-08-12 10:28:07 +08:00
linxi 9102c47804 Fix:查看订单详情后返回订单列表,应停留在用户进入详情页前的位置 2026-08-12 10:23:43 +08:00
linxi 238f56ab11 Fix:5716 【商城小程序】【我的订单-集采中心】删除已完成订单后,页面自动刷新跳转至【我的订单-购物】页面 2026-08-12 10:18:44 +08:00
LinCyJang e92027d74e Fix:5593 【商城小程序】自建礼品设置了商品价值,但是收礼人领取后,商城小程序端未显示礼品价值 2026-08-10 22:13:39 +08:00
LinCyJang 90d908a959 Fix:5686 【商城小程序】小程序【我的订单-集采中心】的礼品订单中未显示礼品价值 2026-08-10 21:32:00 +08:00
LinCyJang 3f0ca5e55e Feat:开放采购批发商入驻 2026-08-03 11:56:55 +08:00
LinCyJang 63bebfdb94 Fix:5564 【商城小程序】【旅居团购-退款】退款被驳回后再次进入退款页面,金额仅显示“¥”且“确认退款”按钮可点击显示“加载中” 2026-08-02 11:23:29 +08:00
LinCyJang 35f7127134 Fix:5590 【商城小程序】进入订单详情页时,应默认为全部分类,现在默认进入订单详情页是待支付分类,3个商品订单分类都是同样的问题 2026-08-02 11:17:59 +08:00
LinCyJang 50fe0e78c8 Feat:礼包列表增加角标 2026-08-02 11:12:53 +08:00
LinCyJang 9f843f3bba Merge branch 'dev' of https://gitee.com/fengyuze178/xdd-uniapp-new into dev 2026-08-02 11:02:16 +08:00
LinCyJang eb3db99cb8 Fix:5595 【商城小程序】礼品集采中心收到礼品,在商城小程序-我的礼品卡-收到的,未显示商品信息 2026-08-02 11:02:10 +08:00
linxi d7aecbe755 Feat:集采中心采购订单 2026-07-31 10:59:56 +08:00
lifizer 23f3d8b994 Refactor(千县):图片增加懒加载,优化渲染速度 2026-07-29 14:39:21 +08:00
lifizer 663d8f06fb Conf:增加Fix环境的配置 2026-07-24 16:55:13 +08:00
linxi 37ba270104 Fix:5550 【商城小程序】千县图文攻略, 管理后台上传的图片在香道滇小程序端图片显示调整 2026-07-21 17:26:32 +08:00
linxi 3cd6f29e32 Fix:5536 【商城小程序】订单详情点击商品图片区域之前是可以进入商品详情的,现在点击无法进入商品详情页 2026-07-21 17:19:33 +08:00
linxi 51e9d8b966 Fix:5535 【商城小程序】全国特产、文玩艺术板块的省级导航页面搜索栏,在搜索有效名称时提示“未找到该城市,请重新输入城市名称” 2026-07-21 17:14:13 +08:00
linxi 50363edc6e Fix:5498 【商城小程序】将抽奖商品加入购物车,从购物车进商品详情页,点击【送给朋友】仍可使用优惠券,改为不可使用 2026-07-21 17:09:35 +08:00
linxi 2bc47e46f1 Fix:5485 【商城小程序】简介和定位的文字调大一点,加大1号 2026-07-21 17:01:25 +08:00
linxi 6c851d4f29 Fix:5484 【供应链小程序】扫描县域代理商的推广码,入驻页面接口显示不全,应显示所有入驻接口(通过县域代理商入驻,均存在上下级绑定关系) 2026-07-21 16:56:39 +08:00
linxi 76a877f2c2 Fix: 订单列表所有按钮点击都没反应了 2026-07-14 17:19:39 +08:00
linxi 55ed80acbc Fix:5174 【商城小程序】游客身份直接点击页面底部【客服】按钮并发送文字后,页面显示空白,且未弹出登录引导提示 2026-07-14 14:36:03 +08:00
linxi 956d7bf70b Fix:5176 【商城小程序】省级导航在搜索无效名称时无反馈 2026-07-14 14:28:00 +08:00
linxi 62e7776b64 Fix:5349 【商城小程序】顶部标题“特色礼品”修改为“全国礼品” 2026-07-14 14:21:38 +08:00
linxi 8f7ff49641 Fix:5371 【商城小程序】甄选好礼对应分类下无商品不会提示 2026-07-14 14:17:31 +08:00
linxi 6d963a5bc0 Fix:5397 【商城小程序】商品链接,连续快速点击“送给朋友”,重复弹出多个送礼页面 2026-07-14 14:06:41 +08:00
linxi b4c1ea20ac Fix:5420 【商城小程序】抽奖活动已开奖后取消退款,在个人主页查看我的抽奖码,“失效原因:订单取消”改为“活动已结束,抽奖码无法恢复” 2026-07-14 11:52:36 +08:00
linxi ffadc6c501 Fix:5448 【商城小程序】在详情图区域上传多张图片,详情图现在是一列显示,改为一行显示,可左右滑动查看图片,不自动轮播 2026-07-14 11:12:22 +08:00
linxi 47ac886d5d Fix:5451 【商城小程序】店铺查看资讯详情返回列表页时,列表自动滑动至顶部 2026-07-14 10:54:55 +08:00
linxi f72a68ccc3 Fix:5452 【商城小程序】收礼方申请退款被商家拒绝后,礼包订单详情显示“立即评价”按钮 2026-07-14 10:51:07 +08:00
linxi 73fa5e35d4 Fix:5453 【商城小程序】苹果手机视频列表布局方向从右到左,应该从左到右排列,与安卓同步 2026-07-14 10:41:37 +08:00
linxi 93c9445008 Fix:5463 【商城小程序】千县攻略的简介和定位的文字加粗 2026-07-14 10:28:48 +08:00
linxi ea44413ac1 Fix:5454 【商城小程序】购买商品,微信支付下单后未支付,待付款列表显示两条相同订单记录 2026-07-14 10:01:13 +08:00
linxi 13a9b7a2f6 Feat:千县图文攻略 2026-07-07 15:09:58 +08:00
linxi 80078cae78 Fix:抽奖送礼还能选择优惠券 2026-07-07 09:56:07 +08:00
51 changed files with 3826 additions and 893 deletions
+1 -1
View File
@@ -372,7 +372,7 @@ export const chatMixins = {
const _this = this
console.log('------------------创建连接')
uni.connectSocket({
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.unionId}-${conversationId}`,
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.uid}-${conversationId}`,
header: {
'content-type': 'application/json'
},
+29 -1
View File
@@ -51,6 +51,7 @@ export const chatMixinsV2 = {
audioPlayId: '',
showGiftBtn: false,
buyLoading: false,
buyActionLock: false,
exceptionConfig: {
model_exception: '您提的问题未能理解,云灵思想跑偏啦,重新整理一下问题或者重新提问,让云灵再试试!',
voice_exception: ''
@@ -333,7 +334,7 @@ export const chatMixinsV2 = {
const _this = this
console.log('------------------创建连接')
uni.connectSocket({
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.unionId}-${conversationId}`,
url: VUE_APP_API_URL.replace('https', 'wss') + settings.sysPrefix + `v1/chat/websocket/${_this.userInfo.uid}-${conversationId}`,
header: {
'content-type': 'application/json'
},
@@ -533,6 +534,10 @@ export const chatMixinsV2 = {
this.productItemBuyNowOrGiftBuy(item, 2)
},
productItemBuyNowOrGiftBuy(item, BuyNowOrGiftBuyType) {
if (this.buyActionLock) {
return
}
this.buyActionLock = true
this.audioStopHandle()
this.cart_num = 1
this.m_id = item.id
@@ -540,6 +545,7 @@ export const chatMixinsV2 = {
const { data } = res
this.storeInfo = {...data.storeInfo}
if(data.storeInfo.stock === 0) {
this.buyActionLock = false
uni.showToast({
title: "产品库存不足,请选择其他商品",
icon: "none",
@@ -577,6 +583,14 @@ export const chatMixinsV2 = {
return
}
this.attr.cartAttr = !this.isOpen ? true : false
this.buyActionLock = false
}).catch(error => {
this.buyActionLock = false
uni.showToast({
title: error.msg || '操作失败,请稍后重试',
icon: "none",
duration: 3000
})
})
},
buyNowOrGiftBuyReq(type) {
@@ -617,6 +631,7 @@ export const chatMixinsV2 = {
})
}).finally(() => {
_this.buyLoading = false
_this.buyActionLock = false
})
},
closeAttrWindow() {
@@ -870,6 +885,18 @@ export const chatMixinsV2 = {
this.currentGiftStepIndex--
}
},
clearCurrentGiftStepData() {
const currentStep = this.giftBuyOptions[this.currentGiftStepIndex]
if (!currentStep) return
if (currentStep.type === 'option_card') {
const nextSelections = { ...this.giftSelections }
delete nextSelections[currentStep.id]
this.giftSelections = nextSelections
} else if (currentStep.type === 'price_input') {
this.giftBudget = ''
}
},
nextGiftStep() {
const currentStep = this.giftBuyOptions[this.currentGiftStepIndex]
let hasSelection = false
@@ -897,6 +924,7 @@ export const chatMixinsV2 = {
}
},
skipGiftStep() {
this.clearCurrentGiftStepData()
if (this.currentGiftStepIndex < this.giftBuyOptions.length - 1) {
this.currentGiftStepIndex++
} else {
+16 -3
View File
@@ -184,7 +184,12 @@
<view v-if="item.type === 'price_input'" class="gift-price-input">
<view class="input-wrap">
<text class="label">价格预算</text>
<input v-model="giftBudget" placeholder="例如100以内/300~500元" class="input-budget" placeholder-style="color: #ccc;" />
<input
v-model="giftBudget"
:placeholder="item.guideContent || '例如100以内/300~500元'"
class="input-budget"
placeholder-style="color: #ccc;"
/>
</view>
</view>
</view>
@@ -857,10 +862,18 @@ export default {
display: flex;
flex-direction: column;
justify-content: space-between;
height: calc(100vh - 240rpx);
min-height: calc(100vh - 240rpx);
height: auto;
padding: 0 0 240rpx 0;
padding-bottom: calc(240rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(240rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
overflow-y: auto;
overflow: visible;
}
.gift-steps-wrap {
padding-bottom: 40rpx;
padding-bottom: calc(40rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
}
.focus-guide-wrap {
display: flex;
+36
View File
@@ -124,3 +124,39 @@ export function computedSojoumGroupBuyGiftOrderPrice(params) {
login: true
})
}
/**
* 文生图发起生成
* @param {*} data
* @returns
*/
export function aiGiftImageGenerate(data) {
return request.post("/aiGiftImage/generate", data, {
login: true
})
}
/**
* 文生图状态查询
* @param {*} params
* @returns
*/
export function aiGiftImageStatus(params) {
return request.get("/aiGiftImage/" + params.productId, {
login: true
})
}
/**
* 获取商品以前使用过的AI礼品卡图片
* @param {*} params
* @returns
*/
export function aiGiftImageHistory(params) {
return request.get("/giftCard/aiGiftImages/history?productId=" + params.productId, {
login: true
})
}
+32 -2
View File
@@ -17,8 +17,8 @@ export function getShopData(params) {
// 查看商户申请
// 1-特产供应商 2-店铺 3-文玩供应商
export function getShopInfo() {
return request.get("/merchantApply/info", {}, {login: true})
export function getShopInfo(params) {
return request.get("/merchantApply/info", params, {login: true})
}
// 4-采购批发商
@@ -38,6 +38,18 @@ export function saveShop(hotelInfo, partnerId = '', promoterUid = '') {
return request.post("/merchantApply/hotel/submit", param, {login: true})
}
// 保存店铺入驻草稿
export function saveHotelDraft(hotelInfo, partnerId = '', promoterUid = '') {
let param = {hotelInfo, captcha: hotelInfo.captcha};
if (partnerId && partnerId.length > 0) {
param.partnerId = partnerId;
}
if (promoterUid && promoterUid.length > 0) {
param.promoterUid = promoterUid;
}
return request.post("/merchantApply/hotel/saveDraft", param, {login: true})
}
// 提交特产供应商入驻申请
export function saveSupplier(hotelInfo, supplierInfo, partnerId = '', promoterUid = '') {
let param = {hotelInfo, supplierInfo, captcha: supplierInfo.captcha};
@@ -62,12 +74,30 @@ export function saveWenwanSupplier(hotelInfo, supplierInfo, partnerId = '', prom
return request.post("/merchantApply/wenwanSupplier/submit", param, {login: true})
}
// 保存供应商入驻草稿(特产/文玩共用)
export function saveSupplierDraft(hotelInfo, supplierInfo, partnerId = '', promoterUid = '') {
let param = {hotelInfo, supplierInfo, captcha: supplierInfo.captcha};
if (partnerId && partnerId.length > 0) {
param.partnerId = partnerId;
}
if (promoterUid && promoterUid.length > 0) {
param.promoterUid = promoterUid;
}
return request.post("/merchantApply/supplier/saveDraft", param, {login: true})
}
// 提交采购批发商入驻申请
export function saveWholesaler(wholesalerInfo) {
let param = {wholesalerInfo, captcha: wholesalerInfo.captcha};
return request.post("/merchantApply/wholesaler/submit", param, {login: true})
}
// 保存采购批发商入驻草稿
export function saveWholesalerDraft(wholesalerInfo) {
let param = {wholesalerInfo, captcha: wholesalerInfo.captcha};
return request.post("/merchantApply/wholesaler/saveDraft", param, {login: true})
}
export function saveExperienceStore(params) {
return request.post("/merchantApply/experienceStore/submit", params, {login: true})
}
+5
View File
@@ -60,6 +60,11 @@ export function getCountyFamousCityGuideContent(param) {
return request.get('/countyFamous/guide/content', param, { login: true })
}
// 获取千县名品县城图文攻略详情
export function getCountyFamousGraphicGuideContent(param) {
return request.get('/countyFamous/guide/graphic/content', param, { login: true })
}
// 获取千县名品县城重点产业列表
export function getCountyFamousIndustry(param) {
return request.get('/countyFamous/industry', param, { login: true })
+8
View File
@@ -603,3 +603,11 @@ export function queryUserGuide(params) {
export function setUserGuide(params) {
return request.post('/user/guide/status', params)
}
/**
* 提现规则
*/
export function getWithdrawalRules() {
return request.get('/extract/rule')
}
+16 -12
View File
@@ -8,18 +8,22 @@ page {
justify-content: space-between;
}
.fix-tabbar-page {
position: relative;
min-height: 100vh;
background: linear-gradient(155deg, rgba(61, 76, 241, 0.15) 0%, rgba(255,255,255,1) 25%, rgba(255,255,255,1) 75%, rgba(61, 76, 241, 0.15) 100%);
// background-color: #fff;
// background-size: 100% calc(100vh - 160rpx);
// background-image: url(https://wxapp.xdd618.com/api/file/pic/aiChat/bg.png);
// background-repeat: no-repeat;
// background-attachment: fixed;
&.new-chat {
background-size: 100% calc(100vh - 160rpx);
background-repeat: no-repeat;
}
position: relative;
z-index: 0;
min-height: 100vh;
background: transparent;
isolation: isolate;
&::before {
content: '';
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
pointer-events: none;
background: linear-gradient(155deg, rgba(61, 76, 241, 0.15) 0%, rgba(255,255,255,1) 25%, rgba(255,255,255,1) 75%, rgba(61, 76, 241, 0.15) 100%);
}
.fix-tabbar-header {
position: fixed;
top: 0;
+19
View File
@@ -127,6 +127,25 @@
height: 52vh;
overflow-y: auto;
margin: 30rpx 0;
// 小程序rich-text内块级标签无默认段间距,补充与后台富文本编辑器一致的段落格式
rich-text {
display: block;
width: 100%;
p, div, ul, ol {
display: block;
margin: 0 0 16rpx;
&:last-child {
margin-bottom: 0;
}
}
li {
margin: 0 0 8rpx;
}
}
}
.agree-box {
+11
View File
@@ -42,9 +42,20 @@ export default {
},
goSupplierMini() {
// 区分当前小程序环境:正式版跳正式版,体验版/开发版跳体验版
let envVersion = 'release'
try {
const accountInfo = uni.getAccountInfoSync()
if (accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.envVersion !== 'release') {
envVersion = 'trial'
}
} catch (e) {
envVersion = 'release'
}
uni.navigateToMiniProgram({
appId: "wx9ca93d1f2a9c8156",
path: "pages/auth/login",
envVersion,
success(msg) {
console.log("success", msg)
},
+4 -5
View File
@@ -35,8 +35,7 @@
v-for="(subItem, subIndex) in item.attrValue"
:key="subIndex"
:class="{
'actived': subItem.check,
'disabled': !subItem.canUsed
'actived': subItem.check
}"
class="itemn v12-radius-40"
@click="tapAttr(index, subIndex, subItem)"
@@ -218,9 +217,9 @@ export default {
},
tapAttr(index, subIndex, subItem) {
// 缺货的点击了没效果
if (!subItem.canUsed || subItem.check) {
return
}
// if (!subItem.canUsed || subItem.check) {
// return
// }
this.attrObj.productAttr[index].attrValue.map((subItem, subIdx) => {
subItem.check= false
if (subIndex === subIdx) {
+8
View File
@@ -10,6 +10,14 @@ if (NODE_ENV === 'development' || NODE_ENV === 'test') {
enableDebug: false
})
}
if (NODE_ENV === 'fix') {
BASE_URL = 'https://shop-pre.xdd618.com/api'
SERVICE_URL = 'https://service-pre.xdd618.com/api'
SERVICE_WS_URL = 'wss://service-pre.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'
+11
View File
@@ -133,6 +133,17 @@
"CUSTOM-CONST": true
}
},
"mp-weixin-fix": {
"title": "微信小程序(Fix环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "fix",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
},
"mp-weixin": {
"title": "微信小程序(生产环境)",
"env": {
+9 -2
View File
@@ -355,7 +355,7 @@
{
"path": "views/wholesaler",
"style": {
"navigationBarTitleText": "采购批发商入驻"
"navigationBarTitleText": "礼品集采中心入驻"
}
},
{
@@ -490,7 +490,7 @@
{
"path": "views/giftList",
"style": {
"navigationBarTitleText": "特色礼品"
"navigationBarTitleText": "全国礼品"
}
},
{
@@ -532,6 +532,13 @@
"navigationStyle": "custom"
}
},
{
"path": "views/famousQianxianGraphicGuide",
"style": {
"navigationBarTitleText": "攻略详情",
"navigationStyle": "custom"
}
},
{
"path": "views/famousQianxianVillageShop",
"style": {
+9 -16
View File
@@ -49,21 +49,18 @@ export default {
// 注释下面一行,会停留在启动页
setTimeout(() => {
this.toLaunch();
}, 2000)
}, 5000)
return;
}
// 未登录:静默处理登录,5秒后跳转业务页面
cookie.get("spread");
// this.toLaunch();
if (this.$deviceType == "app") {
// this.toLaunch();
this.$yrouter.switchTab({
path: "/pages/home/index"
});
return;
if (this.$deviceType != "app") {
//检查授权信息
this.checkUserInfo();
}
//检查授权信息
this.checkUserInfo();
setTimeout(() => {
this.toLaunch();
}, 5000);
},
methods: {
...mapActions(["changeAuthorization", "setUserInfo"]),
@@ -89,11 +86,7 @@ export default {
}
}
login(loginInfo).finally(() => {
this.$yrouter.switchTab({
path: "/pages/home/index"
});
});
login(loginInfo);
}
+122 -22
View File
@@ -6,25 +6,44 @@
</view>
</view>
<view class="list" v-if="list.length">
<custom-waterfalls-flow :value="list" imageKey="cover">
<view class="item" v-for="(item,index) in list" :key="index" slot="slot{{index}}" @click="goDetail(item)">
<image class="cover" :src="item.cover" mode="widthFix"></image>
<view class="content">
<view class="title more-t">{{ item.title }}</view>
<view class="footer flex jc-between ai-center">
<view class="visit flex ai-center">
<image class="icon" style="margin-right: 8rpx" :src="item.storeLogo" mode="scaleToFill"></image>
{{ item.storeName }}
<view class="list" v-show="hasList">
<view class="video-waterfalls-wrap">
<view class="waterfalls-column">
<view class="item" v-for="(lItem,lIndex) in leftList" :key="lIndex" @click="goDetail(lItem)">
<image class="cover" :src="lItem.cover" mode="widthFix" lazy-load></image>
<view class="content">
<view class="title more-t">{{ lItem.title }}</view>
<view class="footer flex jc-between ai-center">
<view class="visit flex ai-center">
<image class="icon" style="margin-right: 8rpx" :src="lItem.storeLogo" mode="scaleToFill"></image>
{{ lItem.storeName }}
</view>
<image class="icon flex-0" :src="webUrl+'/20210806121203835373.png'" mode="scaleToFill"></image>
</view>
<image class="icon flex-0" :src="webUrl+'/20210806121203835373.png'" mode="scaleToFill"></image>
</view>
</view>
</view>
</custom-waterfalls-flow>
<view class="waterfalls-column">
<view class="item" v-for="(rItem,rIndex) in rightList" :key="rIndex" @click="goDetail(rItem)">
<image class="cover" :src="rItem.cover" mode="widthFix" lazy-load></image>
<view class="content">
<view class="title more-t">{{ rItem.title }}</view>
<view class="footer flex jc-between ai-center">
<view class="visit flex ai-center">
<image class="icon" style="margin-right: 8rpx" :src="rItem.storeLogo" mode="scaleToFill"></image>
{{ rItem.storeName }}
</view>
<image class="icon flex-0" :src="webUrl+'/20210806121203835373.png'" mode="scaleToFill"></image>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="v4-nodata" v-else>
<view class="loading-more" v-show="isWait">加载中...</view>
<view class="v4-nodata" v-show="showEmpty">
<image src="@/static/images/img_nodata.png" mode="scaleToFill"/>
<view class="text">暂无数据</view>
</view>
@@ -36,6 +55,11 @@ import {getStoreVideoType, getArticleList} from '@/api/public'
import {getVideoList} from '@/api/user'
import { pageListenMixins } from '@/mixins/pageListenMixins'
// 封面固定宽度(rpx
const COVER_WIDTH = 332
// 每项除封面外的文字内容预估高度(rpx)
const TEXT_HEIGHT = 120
export default {
mixins: [pageListenMixins],
data() {
@@ -46,11 +70,23 @@ export default {
page: 1,
limit: 10,
keyword: '',
list: [],
leftList: [],
rightList: [],
leftHeight: 0,
rightHeight: 0,
isWait: false,
requestId: 0,
pageKeyId: Object.freeze('findVideoList')
}
},
computed: {
hasList() {
return this.leftList.length + this.rightList.length > 0
},
showEmpty() {
return !this.isWait && !this.hasList
}
},
onLoad(options) {
if (!options.click) {
uni.switchTab({ url: '/pages/home/index' })
@@ -76,27 +112,73 @@ export default {
changeType(item) {
this.type = item.value
this.page = 1
this.list = []
// 使进行中的请求失效并解锁,避免切换时被上一次请求阻塞
this.requestId++
this.isWait = false
this.fetchList()
},
fetchList() {
resetList() {
this.leftList = []
this.rightList = []
this.leftHeight = 0
this.rightHeight = 0
},
async fetchList() {
if (this.isWait) return
const requestId = ++this.requestId
this.isWait = true
const params = {
type: this.type,
page: this.page,
limit: this.limit
}
getVideoList(params).then(res => {
try {
const res = await getVideoList(params)
// 请求已被更新的请求(如切换分类)取代,丢弃本次结果
if (requestId !== this.requestId) return
if (res.status === 200) {
for (let i = 0; i < res.data.length; i++) {
res.data[i].hide = true
this.list.push(res.data[i])
const items = res.data
for (let i = 0; i < items.length; i++) {
items[i].hide = true
}
// 并行获取所有封面高度,完成后一次性替换列表,避免闪现空列表
const heights = await Promise.all(items.map(item => this.getImageHeight(item.cover)))
if (requestId !== this.requestId) return
if (this.page === 1) this.resetList()
items.forEach((item, i) => {
this.pushToColumn(item, heights[i] + TEXT_HEIGHT)
})
}
this.isWait = false
} catch (e) {
// 忽略请求或图片尺寸获取失败
} finally {
if (requestId === this.requestId) {
this.isWait = false
}
}
},
getImageHeight(src) {
return new Promise(resolve => {
uni.getImageInfo({
src,
success: res => {
resolve(res.height / res.width * COVER_WIDTH)
},
fail: () => {
resolve(COVER_WIDTH)
}
})
})
},
pushToColumn(item, height) {
if (this.leftHeight <= this.rightHeight) {
this.leftList.push(item)
this.leftHeight += height
} else {
this.rightList.push(item)
this.rightHeight += height
}
},
goDetail(item) {
this.$yrouter.push("/pages/VideoPlayBackList/VideoPlayBackDetail?videoUrl=" + item.video + '&id=' + item.id + '&click=1')
}
@@ -114,6 +196,7 @@ export default {
border-radius: 20rpx;
background: #fff;
font-size: 26rpx;
white-space: nowrap;
}
.active {
@@ -125,13 +208,23 @@ export default {
.list {
margin: 28rpx 32rpx;
.video-waterfalls-wrap {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.waterfalls-column {
width: 332rpx;
}
.item {
margin-bottom: 20rpx;
border-radius: 4rpx;
background: #fff;
.cover {
width: 332rpx;
//height: 200rpx;
vertical-align: middle;
}
@@ -174,4 +267,11 @@ export default {
}
}
}
.loading-more {
padding: 24rpx 0;
text-align: center;
font-size: 24rpx;
color: #999;
}
</style>
+16 -13
View File
@@ -384,20 +384,23 @@ export default {
this.mescroll && this.mescroll.triggerDownScroll()
},
search() {
if(this.keyword === '') return
this.listGroup.findIndex((group, index) => {
let result
group.city.forEach(item => {
result = item.cityName.indexOf(this.keyword, 0)
if (result !== -1) {
this.asideTap(index);
return null;
}
})
if (result !== -1) {
return result
}
const keyword = (this.keyword || '').trim()
if (!keyword) return
const matchIndex = this.listGroup.findIndex(group => {
const cityList = Array.isArray(group.city) ? group.city : []
return cityList.some(item => item && item.cityName && item.cityName.indexOf(keyword) !== -1)
})
if (matchIndex !== -1) {
this.keyword = keyword
this.asideTap(matchIndex)
return
}
if (matchIndex === -1) {
uni.showToast({
title: '未找到该城市,请重新输入城市名称',
icon: 'none'
})
}
},
select(item) {
if (this.type === 0 && item.hasData === 0) return
+5 -1
View File
@@ -114,7 +114,8 @@
<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">
<goo-skeleton v-if="!townLoaded" :show-avatar="false"/>
<view class="v4-nodata" v-else-if="townList.length === 0">
<image src="@/static/images/img_nodata.png" mode="scaleToFill"/>
<view class="text">暂无数据</view>
</view>
@@ -203,6 +204,7 @@ export default {
isNext: false,
townConfig: {},
townList: [],
townLoaded: false,
randomSeed: null,
hotelBanner: [],
goodCityId: '',
@@ -519,6 +521,8 @@ export default {
}
getAncientTownList(params).then(res => {
this.townList = res.data.records
}).finally(() => {
this.townLoaded = true
})
return
}
+23 -2
View File
@@ -916,6 +916,18 @@ export default {
}
app.globalData.homeDrawPosterShownInSession = true
},
hasShownOldUserPopupInSession() {
const app = getApp && getApp()
return Boolean(app && app.globalData && app.globalData.homeOldUserPopupShownInSession)
},
markOldUserPopupShownInSession() {
const app = getApp && getApp()
if (!app) return
if (!app.globalData) {
app.globalData = {}
}
app.globalData.homeOldUserPopupShownInSession = true
},
initPosterPopupState(data = {}) {
const drawEntranceConfig = data.drawEntranceConfig || {}
this.$set(this, 'drawEntranceConfig', drawEntranceConfig)
@@ -932,10 +944,19 @@ export default {
(data.lotteryCanDraw || false)
)
this.isDrawPosterVisible = shouldShowDrawPoster
this.isOldUser = !shouldShowDrawPoster && !hasShownDrawPosterInSession && this.canShowOldPoster
const shouldShowOldUserPopup =
!shouldShowDrawPoster &&
!hasShownDrawPosterInSession &&
this.canShowOldPoster &&
!this.hasShownOldUserPopupInSession()
if (shouldShowOldUserPopup) {
this.markOldUserPopupShownInSession()
}
this.isOldUser = shouldShowOldUserPopup
},
showNextPoster() {
if (!this.isDrawPosterVisible && this.canShowOldPoster) {
if (!this.isDrawPosterVisible && this.canShowOldPoster && !this.hasShownOldUserPopupInSession()) {
this.markOldUserPopupShownInSession()
this.isOldUser = true
}
},
+22 -4
View File
@@ -36,7 +36,7 @@
</view>
</view>
<view class="product-wrap v12-mt-3">
<view v-if="products.length > 0" class="product-wrap v12-mt-3">
<view class="product-card" v-for="(item, index) in products" :key="index" @click="toGoods(item)">
<image :src="item.productImage" class="product-card-img" mode="heightFix|widthFix"></image>
<view class="new-info">
@@ -53,6 +53,9 @@
</view>
</view>
</view>
<view v-else class="empty-wrap">
<view class="empty-text">暂无数据</view>
</view>
<ProductWindow
ref="attrWindow"
:attr="attr"
@@ -99,8 +102,12 @@ export default{
onLoad() {
queryNewZone().then(res => {
this.details = res.data
this.tabs = res.data.categories
this.handleClick(0, this.tabs[0])
this.tabs = Array.isArray(res.data.categories) ? res.data.categories : []
if (this.tabs.length > 0) {
this.handleClick(0, this.tabs[0])
} else {
this.products = []
}
})
},
computed: {
@@ -112,7 +119,7 @@ export default{
methods: {
handleClick(index, tab) {
this.activeIndex = index
this.products = tab.products
this.products = Array.isArray(tab && tab.products) ? tab.products : []
},
handleChange(e) {
this.current = e.detail.current
@@ -144,6 +151,17 @@ export default{
justify-content: space-between;
flex-wrap: wrap;
}
.empty-wrap{
min-height: 260rpx;
display: flex;
align-items: center;
justify-content: center;
}
.empty-text{
font-size: 28rpx;
color: #999999;
text-align: center;
}
.tab-line{
position: absolute;
bottom: 0;
File diff suppressed because it is too large Load Diff
+26 -12
View File
@@ -398,7 +398,8 @@ export default {
pageKeyId: Object.freeze('orderConfirm'),
total: 0,
couponTitle: '',
hasCoupon: false
hasCoupon: false,
pageQuery: {}
}
},
computed: mapGetters(["userInfo", "storeItems"]),
@@ -417,17 +418,18 @@ export default {
},
onLoad(opts) {
const that = this
if (that.$yroute.query.pinkid !== undefined) {
that.pinkId = that.$yroute.query.pinkid
that.pageQuery = Object.assign({}, that.resolvePageQuery(), opts || {})
if (that.pageQuery.pinkid !== undefined) {
that.pinkId = that.pageQuery.pinkid
}
if (that.$yroute.query.id !== undefined) {
that.cartid = that.$yroute.query.id
if (that.pageQuery.id !== undefined) {
that.cartid = that.pageQuery.id
console.log(that.cartid)
}
if (that.$yroute.query.lotteryRecordId !== undefined) {
that.lotteryRecordId = that.$yroute.query.lotteryRecordId
if (that.pageQuery.lotteryRecordId !== undefined) {
that.lotteryRecordId = that.pageQuery.lotteryRecordId
}
that.hasCoupon = opts.couponId !== ''
that.hasCoupon = !!(opts && opts.couponId !== '')
that.getCartInfo()
},
onShow() {
@@ -452,14 +454,26 @@ export default {
},
methods: {
isNullOrEmpty,
resolvePageQuery() {
if (this.$yroute && this.$yroute.query) {
return this.$yroute.query
}
if (this.$route && this.$route.query) {
return this.$route.query
}
if (this._route && this._route.query) {
return this._route.query
}
return {}
},
isLotteryOrder() {
const cartInfo = Array.isArray(this.orderGroupInfo && this.orderGroupInfo.cartInfo)
? this.orderGroupInfo.cartInfo
: []
return Boolean(
this.lotteryRecordId ||
this.$yroute.query.from === 'countyLottery' ||
Number(this.$yroute.query.drawActivityId || 0) > 0 ||
this.pageQuery.from === 'countyLottery' ||
Number(this.pageQuery.drawActivityId || 0) > 0 ||
cartInfo.some(item => Number(
item.drawActivityId ||
(item.productInfo && item.productInfo.drawActivityId) ||
@@ -567,8 +581,8 @@ export default {
}
_this.systemStore = data.systemStore || {}
_this.storeSelfMention = data.storeSelfMention
if(_this.$yroute.query.address !== undefined ) {
_this.addressInfo = JSON.parse(_this.$yroute.query.address) || {}
if(_this.pageQuery.address !== undefined ) {
_this.addressInfo = JSON.parse(_this.pageQuery.address) || {}
_this.computedPrice()
} else {
// _this.addressInfo = uni.getStorageSync('sourceAddress') || data.addressInfo || {}
+67 -59
View File
@@ -32,9 +32,9 @@
<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-1">
<view v-if="(!isCountyLotteryGoodsDetail() && 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 v-if="!isCountyLotteryGoodsDetail() && couponListLimit2ToShow.length > 0" class="v12-justify-start">
<view
v-for="(item, index) in couponListLimit2ToShow"
:key="index"
@@ -48,7 +48,7 @@
</view>
<view
v-if="couponListLimit2ToShow.length > 0"
v-if="!isCountyLotteryGoodsDetail() && couponListLimit2ToShow.length > 0"
class="value value2 v12-font-24 v12-primary-text"
@click="changeCoupons()"
>
@@ -201,7 +201,7 @@
</view>
<!-- v9 优惠券开始 -->
<u-popup :show="show" :round="10" mode="bottom" closeOnClickOverlay @close="changeCoupons()">
<u-popup v-if="!isCountyLotteryGoodsDetail()" :show="show" :round="10" mode="bottom" closeOnClickOverlay @close="changeCoupons()">
<CouponsPopup
:two-list="couponList"
@ok="setCoupon"
@@ -309,7 +309,7 @@
</view>
</view>
<!-- v6服务项目结束 -->
<view class="store-section goods-section" v-if="systemStore">
<view class="store-section goods-section" v-if="systemStore && appProductHideMerchant !== '1'">
<view class="flex jc-between ai-center">
<view class="title bold flex ai-center">
<view>
@@ -540,7 +540,7 @@ import {
getProductSkuBySelected
} from '@/api/store'
import { userBindParent } from '@/api/user'
import { handleQrCode, isWeixin } from '@/utils'
import { handleLoginFailure, handleQrCode, isWeixin } from '@/utils'
import { getHomeData } from '@/api/public'
import {
getDailyGoods,
@@ -579,6 +579,7 @@ export default {
mixins: [pageListenMixins],
data: function () {
return {
appProductHideMerchant: '0',
isGift: false,
giftBg: '',
// 商品信息是否展开
@@ -655,7 +656,8 @@ export default {
pageKeyId: '',
couponListLimit2ToShow: [],
qualifications: [],
couponId: null
couponId: null,
submitActionLock: false
}
},
computed: mapGetters(['isLogin', 'location', 'userInfo']),
@@ -731,6 +733,7 @@ export default {
console.log("getLaunchOptionsSync", uni.getLaunchOptionsSync())
console.log("getEnterOptionsSync", uni.getEnterOptionsSync())
uni.removeStorageSync('couponId')
const pageQuery = Object.assign({}, this.resolvePageQuery(), options || {})
const from = options.from
const id = options.id
switch (from) {
@@ -778,10 +781,10 @@ export default {
if (url && url.productId) {
this.id = url.productId
} else if (options.id) {
this.id = options.id || null
this.partnerId = options.partnerId || null
this.activityId = this._route.query.activityId
this.source = this._route.query.from || ''
this.id = pageQuery.id || options.id || null
this.partnerId = pageQuery.partnerId || options.partnerId || null
this.activityId = Number(pageQuery.activityId || pageQuery.drawActivityId || 0)
this.source = pageQuery.from || ''
} else {
const obj = uni.getEnterOptionsSync()
if (options.scene != null || obj.query.scene != null) {
@@ -821,6 +824,7 @@ export default {
}
},
onShow() {
this.submitActionLock = false
this.getMapData()
getGiftCardSendBackground().then(res => {
if (res.status === 200) {
@@ -845,6 +849,18 @@ export default {
}
},
methods: {
resolvePageQuery() {
if (this.$yroute && this.$yroute.query) {
return this.$yroute.query
}
if (this.$route && this.$route.query) {
return this.$route.query
}
if (this._route && this._route.query) {
return this._route.query
}
return {}
},
gift() {
this.goCat(2)
},
@@ -876,14 +892,23 @@ export default {
})
},
goRoom() {
console.log(this.storeInfo);
if (!this.isLogin) {
uni.showToast({
title: '请先登录后联系客服',
icon: 'none',
duration: 2000
})
handleLoginFailure()
return
}
console.log(this.attr);
const params = {
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,
cover: this.attr.productSelect.image || this.storeInfo.image,
goodsData: '',
seckillData: '',
isNegotiable: this.storeInfo.isNegotiable
@@ -1186,6 +1211,7 @@ export default {
this.posterData.price = this.storeInfo.price
this.posterData.code = this.storeInfo.codeBase
this.systemStore = data.systemStore
this.appProductHideMerchant = data.appProductHideMerchant
const good_list = data.goodList || []
const goodArray = []
const count = Math.ceil(good_list.length / 6)
@@ -1252,7 +1278,7 @@ export default {
'store_name',
this.storeInfo.storeName
)
this.$set(this.attr.productSelect, 'image', productSelect.image)
this.$set(this.attr.productSelect, 'image', productSelect.image || this.storeInfo.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)
@@ -1379,7 +1405,7 @@ export default {
subItem.check = true
}
})
this.$set(this.attr.productSelect, 'image', productSelect.image)
this.$set(this.attr.productSelect, 'image', productSelect.image || this.storeInfo.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)
@@ -1500,17 +1526,29 @@ export default {
q.drawActivityId = Number(this.activityId || 0)
break
}
if (that.submitActionLock) {
return
}
that.submitActionLock = true
postCartAdd(q).then(function (res) {
that.isOpen = false
that.attr.cartAttr = false
if (news === 1) {
const orderQuery = {
id: res.data.cartId,
discount: that.storeInfo.discount,
}
if (that.source === 'countyLottery') {
orderQuery.from = 'countyLottery'
orderQuery.drawActivityId = Number(that.activityId || 0)
}
that.$yrouter.push({
path: "/pages/order/OrderSubmission/index",
query: {
id: res.data.cartId,
discount: that.storeInfo.discount,
}
query: orderQuery
})
setTimeout(() => {
that.submitActionLock = false
}, 1500)
return
}
if(news === 2) {
@@ -1527,8 +1565,12 @@ export default {
// + '&couponId=' + coupId
url: giftUrl
})
setTimeout(() => {
that.submitActionLock = false
}, 1500)
}
if(news === 0) {
that.submitActionLock = false
uni.showToast({
title: "添加购物车成功",
icon: "success",
@@ -1541,6 +1583,7 @@ export default {
}
}).catch(error => {
that.isOpen = false;
that.submitActionLock = false
uni.showToast({
title: error.msg,
icon: "none",
@@ -1576,11 +1619,16 @@ export default {
listenerActionClose() {
this.posters = false
},
isCountyLotteryGoodsDetail() {
return this.source === 'countyLottery' && Number(this.activityId || 0) > 0
},
// v9-2
changeCoupons(e) {
if (this.isCountyLotteryGoodsDetail()) return
this.show = !this.show
},
setCoupon(couponId) {
if (this.isCountyLotteryGoodsDetail()) return
this.couponId = couponId
},
async checkFavorite() {
@@ -2248,43 +2296,3 @@ export default {
word-break: keep-all;
}
</style>
}
.gift-wrap{
position: relative;
}
.gift-bg{
position: absolute;
left: 0;
width: 100%;
}
.ll-text{
margin-left: 250rpx;
word-break: keep-all;
}
</style>
.gift-img{
width: 34rpx;
height: 34rpx;
margin-right: 10rpx;
}
.gift-wrap{
position: relative;
}
.gift-bg{
position: absolute;
left: 0;
width: 100%;
}
.ll-text{
margin-left: 250rpx;
word-break: keep-all;
}
</style>
left: 0;
width: 100%;
}
.ll-text{
margin-left: 250rpx;
word-break: keep-all;
}
</style>
+1 -76
View File
@@ -219,7 +219,6 @@ import CitySelect from "@/components/CitySelect";
import tmUpload from '@/components/tm-upload/tm-upload.vue';
import {getCity} from "@/api/user";
import {chooseImage, isWeixin} from "@/utils";
import {getHomeData} from "@/api/public";
import {VUE_APP_API_URL} from "@/config"
import {getHotelTypeList, postHotelApply, postHotelReApply} from "@/api/inn.js";
@@ -440,81 +439,7 @@ export default {
}
});
},
getIndex(value, arr) {
var idx = -1;
for (var i = 0; i < arr.length; i++) {
if (arr[i].n == value) {
idx = i;
break;
}
}
return idx;
},
getCityList: function () {
let that = this;
getCity()
.then(res => {
that.district = res.data;
// that.ready = true;
// if(this.id){
// //设置city_id
// var pIdx = that.getIndex(that.address.province,that.district);
// if(pIdx>-1){
// var citys = that.district[pIdx].c;
// var cIdx = that.getIndex(that.address.city,citys);
// if(cIdx>-1){
// var city = citys[cIdx];
// that.address.city_id = city.v;
// console.log('city_id:'+city.v);
// }
// }
// }
})
.catch(err => {
that.$dialog.error(err.msg);
});
},
chooseQrcodeImg: function () {
chooseImage(img => {
console.log(img)
that.$set(that.innApplyInfo, 'qrcode', img);
});
},
chooseLogoImg: function () {
chooseImage(img => {
console.log(img)
that.innApplyInfo.logo = img;
});
},
chooseCoverImg: function () {
chooseImage(img => {
console.log(img)
that.innApplyInfo.cover = img;
});
},
//文件上传结果
uploadedImgChange: function (uploadedFilesList) {
this.uploadedFilesArray = uploadedFilesList;
},
submit: function () {
if (this.innApplyInfo.name.length == 0) {
this.$dialog.error("请输入店铺名称");
return;
}
if (this.innApplyInfo.type.length == 0) {
this.$dialog.error("请选择店铺类型");
return;
}
submit() {
if (this.addressText.length == 0) {
this.$dialog.error("请选择店铺所在省市区");
return;
+7 -1
View File
@@ -588,7 +588,8 @@ export default {
pageKeyId: '',
shareImg: '',
videoPlayers: [],
isView: false
isView: false,
skipRefreshOnShow: false
}
},
// 必须在页面加 onPageScroll(e){} ,才能滑动显示背景
@@ -679,6 +680,10 @@ export default {
if (!this.isLoad) {
return
}
if (this.skipRefreshOnShow) {
this.skipRefreshOnShow = false
return
}
this.fetchInnDetail()
if(this.isView) return
if(this.activeIndex === 1) {
@@ -834,6 +839,7 @@ export default {
})
},
infoClick: function (info) {
this.skipRefreshOnShow = true
this.$yrouter.push('/pagesInn/inn/innInfoDetail?id=' + info.id)
},
coverPlay(){
+172 -47
View File
@@ -93,7 +93,7 @@
</view>
</view>
</view>
<view v-if="orderInfo.deliveryId !== null && ([-1, -2, 3, 4].includes(orderInfo._status._type) || (orderInfo._status._type == 2 && orderInfo.isTickets !== 1))">
<view v-if="orderInfo.deliveryId !== null && ([-1, -2, -3, 3, 4].includes(orderInfo._status._type) || (orderInfo._status._type == 2 && orderInfo.isTickets !== 1))">
<view
v-for="(delivery, index) in orderInfo.deliveryInfo"
:key="index"
@@ -203,31 +203,31 @@
<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" @click="goGoodsCon(cart, orderInfo.isGiftCardReceiveBlind, orderInfo.isDrawOrder)">
<view class="v12-justify-between" v-if="orderInfo.isGiftCardReceiveBlind === 0">
<view class="v12-radius-20 v12-pa-3" v-for="(cart, d) in getOrderDetailDisplayItems(orderInfo)" :key="d" @click="goGoodsCon(cart, orderInfo.isGiftCardReceiveBlind, orderInfo.isDrawOrder, orderInfo.scenarioCode)">
<view class="v12-justify-between" v-if="!isBlindBoxOrder(orderInfo)">
<view class="">
<image style="width: 120rpx; height: 120rpx" class="v12-radius-8" :src="cart.productInfo.image"></image>
<image style="width: 120rpx; height: 120rpx" class="v12-radius-8" :src="cart.image"></image>
</view>
<view class="v12-justify-between v12-flex-column v12-ml-2" style="flex: 2">
<view class="v12-font-28 v12-dark-text v12-font-bold more-t">
{{ cart.productInfo.storeName }}
{{ cart.name }}
</view>
<view v-if="cart.productInfo.attrInfo && orderInfo.isDrawOrder !== 1" class="more-t v12-secondary-dark-text v12-font-24">
{{ cart.productInfo.attrInfo.sku || '' }}
<view v-if="cart.sku && orderInfo.isDrawOrder !== 1" class="more-t v12-secondary-dark-text v12-font-24">
{{ cart.sku }}
</view>
<view v-if="orderInfo.isDrawOrder === 1" class="more-t v12-secondary-dark-text v12-font-24">
{{ orderInfo.drawOrderInfo.prizeAttrName || '' }}
</view>
</view>
<view class="v12-justify-between v12-flex-column v12-dark-text v12-text-right">
<view class=" " v-if="orderInfo.isDrawOrder === 0">
<view class=" " v-if="orderInfo.isDrawOrder === 0 && cart.showPrice">
<text class="v12-font-22">
</text>
<text class="v12-font-28">{{ cart.truePrice }}</text>
<text class="v12-font-28">{{ force2Decimal(cart.price) }}</text>
</view>
<view class="v12-font-22">
<text>x{{ cart.cartNum }}</text>
<text>x{{ cart.qty }}</text>
</view>
</view>
</view>
@@ -244,16 +244,29 @@
</view>
</view>
</view>
<view class="" v-if="orderInfo.cartInfo &&( d === orderInfo.cartInfo.length - 1) && orderInfo.isDrawOrder === 0">
<view class="v12-justify-between v12-align-center v12-mt-3 v12-dark-text" v-if="orderInfo.isGiftCardReceiveBlind === 0">
<view class="v12-font-24 v12-dark-text">
商品总价
<view class="" v-if="getOrderDetailDisplayItems(orderInfo).length && (d === getOrderDetailDisplayItems(orderInfo).length - 1) && orderInfo.isDrawOrder === 0">
<view v-if="orderInfo.isGiftCardReceiveBlind === 0">
<view class="v12-justify-between v12-align-center v12-mt-3 v12-dark-text" v-if="isCustomGiftOrder(orderInfo)">
<view class="v12-font-24 v12-dark-text" v-if="orderInfo.customGiftInfo.isShowValue">
{{ '礼品价值' }}
</view>
<view class="v12-text-right" v-if="orderInfo.customGiftInfo.isShowValue">
<text class="v12-font-22"></text>
<text class="v12-font-28" v-if="orderInfo.customGiftInfo && orderInfo.customGiftInfo.isShowValue">
{{ force2Decimal(orderInfo.customGiftInfo.giftValue) }}
</text>
</view>
</view>
<view class="v12-text-right">
<text class="v12-font-22"></text>
<text class="v12-font-28">
{{ force2Decimal(orderInfo.totalPrice) }}
</text>
<view class="v12-justify-between v12-align-center v12-mt-3 v12-dark-text" v-else>
<view class="v12-font-24 v12-dark-text">
{{ '商品总价' }}
</view>
<view class="v12-text-right">
<text class="v12-font-22"></text>
<text class="v12-font-28">
{{ force2Decimal(orderInfo.totalPrice) }}
</text>
</view>
</view>
</view>
<view class="v12-justify-between v12-align-center v12-mt-3" v-if="orderInfo.payPostage > 0">
@@ -304,7 +317,7 @@
</view>
</view>
<u-divider></u-divider>
<view class="v12-justify-between v12-align-center v12-mt-3" v-if="orderInfo.isGiftCardReceiveBlind === 0">
<view class="v12-justify-between v12-align-center v12-mt-3" v-if="orderInfo.isGiftCardReceiveBlind === 0 && !isCustomGiftOrder(orderInfo)">
<view class="v12-font-28 v12-font-bold v12-dark-text">
实付款
</view>
@@ -354,11 +367,11 @@
<view class="flex-0">订单类型</view>
<view class="v12-text-right">{{ orderTypeName }}</view>
</view>
<view v-if="orderInfo.isDrawOrder !== 1" class="item acea-row row-between v12-font-24 v12-dark-text ">
<view v-if="orderInfo.isDrawOrder !== 1 && !isCustomGiftOrder(orderInfo)" class="item acea-row row-between v12-font-24 v12-dark-text ">
<view class="flex-0">支付状态</view>
<view class="v12-text-right">{{ orderInfo.paid ? "已支付" : "未支付" }}</view>
</view>
<view v-if="orderInfo.isDrawOrder !== 1" class="item acea-row row-between v12-font-24 v12-dark-text ">
<view v-if="orderInfo.isDrawOrder !== 1 && !isCustomGiftOrder(orderInfo)" class="item acea-row row-between v12-font-24 v12-dark-text ">
<view class="flex-0">支付方式</view>
<view class="v12-text-right">{{ orderInfo._status._payType }}</view>
</view>
@@ -485,22 +498,31 @@
<text class="v12-font-22 v12-dark1-text">
{{ orderInfo.totalNum }}件商品
</text>
<text class="v12-font-bold v12-dark-text v12-font-28 v12-mx-2">
实付款
</text>
<text class="v12-font-bold v12-primary-text v12-font-22">
</text>
<text class="v12-font-bold v12-primary-text v12-font-28">
{{ force2Decimal(orderInfo.payPrice) }}
</text>
<template v-if="!isCustomGiftOrder(orderInfo)">
<text class="v12-font-bold v12-dark-text v12-font-28 v12-mx-2">
实付款
</text>
<text class="v12-font-bold v12-primary-text v12-font-22">
</text>
<text class="v12-font-bold v12-primary-text v12-font-28">
{{ force2Decimal(orderInfo.payPrice) }}
</text>
</template>
</view>
<view class="bnt v12-primary-text v12-primary-border v12-ml-1" @click="subscribePay">立即付款</view>
</view>
</view>
</template>
<template v-if="status.type == 1" >
<view class="v12-justify-between " style="width: 100%">
<view v-if="isCustomGiftOrder(orderInfo)" class="v12-justify-end" style="width: 100%">
<view
v-if="canShowModifyAddress(orderInfo) && orderInfo.isDrawOrder === 0"
class="bnt v12-dark-text v12-dark-border cancel"
@click="goAddress"
>修改地址</view>
</view>
<view v-else class="v12-justify-between " style="width: 100%">
<view class="v12-justify-between ">
<view v-if="orderInfo.isDrawOrder > 0" class="bnt v12-dark-text v12-dark-border cancel" @click.stop="callMerPhone">联系客服</view>
<view v-if="orderInfo.isGiftCardReceiveBlind === 0 && orderInfo.isDrawOrder === 0" class="bnt v12-dark-text v12-dark-border cancel" @click="goRoom(orderInfo)">联系商家</view>
@@ -515,7 +537,10 @@
</view>
</template>
<template v-if="status.type == 2">
<view class="v12-justify-between " style="width: 100%">
<view v-if="isCustomGiftOrder(orderInfo)" class="v12-justify-end" style="width: 100%">
<view class="bnt v12-primary-text v12-primary-border" @click="takeOrder">确认收货</view>
</view>
<view v-else class="v12-justify-between " style="width: 100%">
<view v-if="orderInfo.isGiftCardReceiveBlind === 0" class="bnt v12-dark-text v12-dark-border cancel" @click.stop="callMerPhone">联系客服</view>
<view class="" v-else></view>
<view class="v12-justify-between">
@@ -548,8 +573,12 @@
<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 cancel" @click="buyAgin">再买一单</view>
<view class="bnt v12-primary-text v12-primary-border" @click="routerGo(orderInfo.cartInfo[0])">立即评价</view>
<view v-if="!isCollectiveOrder(orderInfo)" class="bnt v12-dark-text v12-dark-border cancel" @click="buyAgin">再买一单</view>
<view
v-if="canShowOrderEvaluate(orderInfo)"
class="bnt v12-primary-text v12-primary-border"
@click="routerGo(orderInfo.cartInfo[0])"
>立即评价</view>
</view>
</view>
</template>
@@ -562,7 +591,7 @@
<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="bnt v12-dark-text v12-dark-border cancel" @click="buyAgin">再买一单</view>
<view v-if="!isCollectiveOrder(orderInfo)" class="bnt v12-dark-text v12-dark-border cancel" @click="buyAgin">再买一单</view>
</view>
</template>
<template v-if="status.type == -3">
@@ -570,8 +599,12 @@
<view class="bnt v12-dark-text v12-dark-border cancel" @click="goRoom(orderInfo)">联系商家</view>
<view class="v12-justify-between ">
<view class="bnt v12-dark-text v12-dark-border cancel" @click="buyAgin">再买一单</view>
<view class="bnt v12-primary-text v12-primary-border" @click="routerGo(orderInfo.cartInfo[0])">立即评价</view>
<view v-if="!isCollectiveOrder(orderInfo)" class="bnt v12-dark-text v12-dark-border cancel" @click="buyAgin">再买一单</view>
<view
v-if="canShowOrderEvaluate(orderInfo)"
class="bnt v12-primary-text v12-primary-border"
@click="routerGo(orderInfo.cartInfo[0])"
>立即评价</view>
</view>
</view>
</template>
@@ -846,9 +879,12 @@ export default {
}
})
},
goGoodsCon(item, isGiftCardReceiveBlind, isDrawOrder) {
goGoodsCon(item, isGiftCardReceiveBlind, isDrawOrder, scenarioCode) {
if(isGiftCardReceiveBlind) return
if(isDrawOrder) return
// 采购批发订单(集采中心)商品卡片不跳转批发商品详情页
if (Number(scenarioCode) === 22) return
if (Number(scenarioCode) === 24) return
const activityId = Number(
item.drawActivityId ||
(item.productInfo && item.productInfo.drawActivityId) ||
@@ -1025,6 +1061,83 @@ export default {
}
return status;
},
getOrderScenarioCode(order = this.orderInfo) {
return Number(order && order.scenarioCode)
},
isWholesalerOrder(order = this.orderInfo) {
return this.getOrderScenarioCode(order) === 22
},
isCustomGiftOrder(order = this.orderInfo) {
return this.getOrderScenarioCode(order) === 24
},
isBlindBoxOrder(order = this.orderInfo) {
return Number(order && order.isGiftCardReceiveBlind) === 1
},
isCollectiveOrder(order = this.orderInfo) {
return this.isWholesalerOrder(order) || this.isCustomGiftOrder(order)
},
canShowOrderEvaluate(order = this.orderInfo) {
// 仅排除送礼方订单(送礼人未收货不可评价);收礼方订单确认收货后可评价,与订单列表【去评价】逻辑保持一致
return Number(order.isGiftCardSend || 0) !== 1 && !this.isCollectiveOrder(order)
},
formatOrderDetailImage(image) {
const imageUrl = String(image || '').trim()
if (!imageUrl) {
return ''
}
if (/^https?:\/\//i.test(imageUrl)) {
return imageUrl
}
if (imageUrl.startsWith('//')) {
return `https:${imageUrl}`
}
if (imageUrl.startsWith('/')) {
const apiBaseUrl = String(this.$VUE_APP_API_URL || '').replace(/\/api\/?$/, '')
return `${apiBaseUrl}${imageUrl}`
}
return imageUrl
},
normalizeOrderDetailItem(item = {}, isCustomGift = false) {
if (isCustomGift) {
return {
image: this.formatOrderDetailImage(item.giftImage),
name: item.giftName || '商品信息',
sku: item.specName || '',
qty: Number(item.giftNum) || 1,
price: 0,
showPrice: false,
productId: '',
productInfo: {}
}
}
const productInfo = item.productInfo || {}
const attrInfo = productInfo.attrInfo || {}
return {
...item,
image: this.formatOrderDetailImage(item.image || productInfo.image || attrInfo.image || ''),
name: productInfo.storeName || item.storeName || item.productName || '商品信息',
sku: attrInfo.sku || item.sku || item.specName || '',
qty: Number(item.cartNum || item.num || item.quantity || 1) || 1,
price: Number(item.truePrice || item.price || attrInfo.price || productInfo.price || 0) || 0,
showPrice: true,
productId: item.productId || productInfo.id || ''
}
},
getOrderDetailDisplayItems(order = this.orderInfo) {
if (this.isCustomGiftOrder(order)) {
const customGiftInfo = order && order.customGiftInfo
if (!customGiftInfo || typeof customGiftInfo !== 'object' || Array.isArray(customGiftInfo)) {
return []
}
return [this.normalizeOrderDetailItem(customGiftInfo, true)]
}
const cartList = Array.isArray(order && order.cartInfo) ? order.cartInfo : []
// 盲盒订单隐藏商品信息,固定展示一个盲盒礼包行(cartInfo 为空时也要展示)
if (this.isBlindBoxOrder(order)) {
return [this.normalizeOrderDetailItem(cartList[0] || {})]
}
return cartList.map(item => this.normalizeOrderDetailItem(item))
},
getStatusImg(order) {
const type = parseInt(order._status._type);
let imgUrl = "";
@@ -1147,16 +1260,17 @@ export default {
});
},
goBack() {
if (this.name === "MyOrder") {
// 从订单列表进入时直接返回原页面,保留列表页主/子tab及滚动位置
const pages = getCurrentPages()
const prevPage = pages && pages[pages.length - 2]
const prevRoute = prevPage && prevPage.route
if (prevRoute && prevRoute.indexOf('order/MyOrder') > -1) {
this.$yrouter.back();
return;
} else {
console.log(this);
this.$yrouter.replace({
path: "/pages/order/MyOrder/index"
});
return;
}
this.$yrouter.replace({
path: "/pages/order/MyOrder/index"
});
},
cancelOrder() {
cancelOrderHandle(this.orderInfo.orderId)
@@ -1272,8 +1386,19 @@ export default {
orderDetail(id).then(res => {
this.orderInfo = res.data
this.orderInfo._status._type = parseInt(this.orderInfo._status._type)
// 盲盒订单确认收货后(待评价 3 / 已完成 4)展示真实商品信息,
// 后端 isGiftCardReceiveBlind 未随收货状态更新,按订单状态兜底修正
if (Number(this.orderInfo.isGiftCardReceiveBlind) === 1 && [3, 4].includes(this.orderInfo._status._type)) {
this.orderInfo.isGiftCardReceiveBlind = 0
}
this.getOrderStatus()
if (this.orderInfo.combinationId > 0) {
if (this.isWholesalerOrder(this.orderInfo)) {
this.orderTypeName = "采购批发订单"
this.orderTypeNameStatus = false
} else if (this.isCustomGiftOrder(this.orderInfo)) {
this.orderTypeName = "自建礼品订单"
this.orderTypeNameStatus = false
} else if (this.orderInfo.combinationId > 0) {
this.orderTypeName = "拼团订单"
this.orderTypeNameStatus = false
} else if (this.orderInfo.bargainId > 0) {
+2 -2
View File
@@ -23,7 +23,7 @@
<view class="item acea-row row-between-wrapper">
<view class="name">提现</view>
<view class="input">
<input :placeholder="'最低提现金额' + minPrice" v-model="post.money" />
<input v-model="post.money" />
</view>
</view>
<view class="tip">当前可提现金额: {{ commissionCount }}</view>
@@ -45,7 +45,7 @@
<view class="item acea-row row-between-wrapper">
<view class="name">提现</view>
<view class="input">
<input :placeholder="'最低提现金额' + minPrice" v-model="post.money" />
<input placeholder="请输入提现金额" v-model="post.money" />
</view>
</view>
<view class="tip">当前可提现金额: {{ commissionCount }}</view>
+1 -2
View File
@@ -284,8 +284,7 @@ export default {
return [1, 2, -1].includes(Number(item.status)) && !!item.prizeName
},
getInvalidReason(item) {
if (Number(item.claimStatus) === -1) return '奖品过期未领取'
return '订单取消'
return item.invalidReason || ''
},
formatPrizeText(item = {}) {
const prizeName = item.prizeName || '神秘奖品'
+98 -39
View File
@@ -11,7 +11,7 @@
<view class="name one-t">{{ item.username }}</view>
<text class="msg" v-if="item.msg_type===0">{{ item.msg_content }}</text>
<view class="msg" v-if="item.msg_type===1">
<image class="img" :src="item.msg_content" @click="preview(item.msg_content)"></image>
<image class="img" :src="imgUrl(item.msg_content)" @click="preview(imgUrl(item.msg_content))"></image>
</view>
</view>
@@ -22,7 +22,7 @@
<view class="name one-t">{{ item.username }}</view>
<text class="msg" v-if="item.msg_type===0">{{ item.msg_content }}</text>
<view class="msg" v-if="item.msg_type===1">
<image class="img" :src="item.msg_content" @click="preview(item.msg_content)"></image>
<image class="img" :src="imgUrl(item.msg_content)" @click="preview(imgUrl(item.msg_content))"></image>
</view>
<view class="msg v12-d-flex" style="box-sizing: content-box" v-if="item.msg_type===2" @click="toGoods(item)">
<view class="goods-logo">
@@ -108,8 +108,11 @@ export default {
uploadToken: null, //上传token
socketOpen: false,
socketConnecting: false, // 是否正在建连
socketTask: null,
socketMsgQueue: [],
hasConnected: false, // 是否成功建过连接
reconnectHistory: false, // 重连后用服务端历史整体替换本地列表,防止消息重复
roomId: null, //房间ID
content: "", //消息内容
@@ -136,30 +139,22 @@ export default {
},
onShow() {
this.content = uni.getStorageSync(this.merName+this.uid+this.storeId)
this.connectSocketInit();
this.list = []
// 已连接/连接中不重复建连;清空 list 会导致图片操作(触发 onHide/onShow)后页面白屏
if (!this.socketOpen && !this.socketConnecting) {
this.connectSocketInit();
}
},
onUnload() {
if (this.socketOpen) {
this.socketTask.close();
}
uni.onSocketClose(res => {
console.log('WebSocket 已关闭!', res);
});
this.closeSocket();
uni.setStorageSync(this.merName+this.uid+this.storeId, this.content)
},
onHide() {
if (this.socketOpen) {
this.socketTask.close();
}
uni.onSocketClose(res => {
console.log('WebSocket 已关闭!', res);
});
this.closeSocket();
uni.setStorageSync(this.merName+this.uid+this.storeId, this.content)
},
methods: {
toGoods(item) {
const itemJson = JSON.parse(item.msg_content)
const itemJson = this.wsJson(item.msg_content)
if(!itemJson.goodsId) {
// 提示数据错误
// uni.showToast({
@@ -177,7 +172,18 @@ export default {
})
},
wsJson(json) {
return JSON.parse(json)
// 兼容脏数据,避免渲染时报错导致白屏
try {
return JSON.parse(json) || {}
} catch (e) {
return {}
}
},
// 拼接图片完整地址:七牛上传后消息里只存 key,需要补上资源域名;http 统一转 https
imgUrl(content) {
if (!content) return ''
if (/^https?:\/\//i.test(content)) return content.replace(/^http:\/\//i, 'https://')
return this.webUrl + '/' + content
},
getUploadToken() {
let that = this;
@@ -249,33 +255,68 @@ export default {
});
},
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
// 进入页面时创建websocket连接【整个页面随时使用】
connectSocketInit() {
if (this.socketOpen || this.socketConnecting) return;
this.socketConnecting = true;
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
this.socketTask = uni.connectSocket({
const task = uni.connectSocket({
url: this.$SOCKET_URL,
success: () => {
}
})
if (!task) {
this.socketConnecting = false;
return;
}
this.socketTask = task;
uni.onSocketOpen(res => {
console.log('WebSocket连接已打开!', res);
// 任务级回调:全局 uni.onSocket* 每次进页面都会重复注册,导致消息重复处理、连接串台
const isCurrent = () => this.socketTask === task;
task.onOpen(() => {
if (!isCurrent()) return;
this.socketOpen = true;
this.socketConnecting = false;
// 断线重连后重新加入房间;本地已有历史时用服务端历史整体替换,避免重复
this.reconnectHistory = this.hasConnected && this.list.length > 0;
this.hasConnected = true;
this.createRoom();
// 补发连接未就绪期间排队的消息(如发图片时连接被隐藏页关闭)
if (this.socketMsgQueue.length) {
const queue = this.socketMsgQueue.splice(0);
queue.forEach(msg => this.sendSocketMessage(msg));
}
});
uni.onSocketError(err => {
console.log('WebSocket连接打开失败,请检查!', err);
});
uni.onSocketMessage(res => {
console.log('收到服务器内容:', res.data);
task.onMessage(res => {
if (!isCurrent()) return;
this.handleMessage(res.data);
});
uni.onSocketClose(res => {
console.log('WebSocket 已关闭', res);
task.onError(err => {
console.log('WebSocket连接打开失败,请检查', err);
if (!isCurrent()) return;
this.socketOpen = false;
this.socketConnecting = false;
});
task.onClose(() => {
if (!isCurrent()) return;
this.socketOpen = false;
this.socketConnecting = false;
});
},
closeSocket() {
this.socketOpen = false;
this.socketConnecting = false;
if (this.socketTask) {
try {
this.socketTask.close({});
} catch (e) {}
}
},
userInput(event) {
@@ -315,11 +356,14 @@ export default {
},
sendSocketMessage(msg) {
if (this.socketOpen) {
uni.sendSocketMessage({
if (this.socketOpen && this.socketTask) {
this.socketTask.send({
data: msg,
success(res) {
console.log("消息发送成功", res,msg);
fail: () => {
// 发送失败说明连接可能已断开,重新排队并尝试重连后补发
this.socketMsgQueue.push(msg);
this.closeSocket();
this.connectSocketInit();
}
});
} else {
@@ -328,7 +372,12 @@ export default {
},
handleMessage(str) {
let data = JSON.parse(str);
let data;
try {
data = JSON.parse(str);
} catch (e) {
return;
}
switch (data.type) {
case "room_id":
this.roomId = data.msg_content;
@@ -338,13 +387,23 @@ export default {
case "leave":
break;
case "msg":
this.list.push(data.msg_content);
this.scrollLast();
if (data.msg_content) {
this.list.push(data.msg_content);
this.scrollLast();
}
break;
case "msg_history":
this.list = data.msg_content.concat(this.list);
case "msg_history": {
const history = data.msg_content || [];
if (this.reconnectHistory) {
// 重连后服务端重发历史:整体替换,避免消息重复
this.reconnectHistory = false;
this.list = history;
} else {
this.list = history.concat(this.list);
}
this.scrollLast();
break;
}
default:
break;
}
+47 -7
View File
@@ -396,7 +396,7 @@
/>
</view>
</view>
<view v-if="form.isDraft === 0 && form.reviewStatus !== 1">
<view v-if="form.reviewStatus !== 1">
<view
class="v12-primary v12-white-text submit-btn"
:style="{'background': form.reviewStatus === 0 ? '#FA979F !important' : '#4A97FC'}"
@@ -405,19 +405,19 @@
{{ form.reviewStatus === 0 ? '撤销申请' : form.reviewStatus === 2 ? '重新提交' : '提交审核' }}
</view>
</view>
<view v-if="form.reviewStatus === null || (form.isDraft === 1 && form.reviewStatus === 0)">
<!-- <view v-if="form.reviewStatus === null || (form.isDraft === 1 && form.reviewStatus === 0)">
<view
class="v12-primary v12-white-text submit-btn"
@click="submitForm"
>
提交审核
</view>
</view>
</view> -->
<u-popup
:show="show"
mode="center"
round="10"
@close="show=false"
@close="handlePopupClose"
>
<view class="popup-body">
<view class="tc bold">
@@ -440,7 +440,6 @@
<u-button
type="error"
text="确定"
:disabled="!isAgree"
@click="savePopup"
/>
</view>
@@ -451,7 +450,7 @@
<script>
import CitySelect from '@/components/CitySelect'
import { getCity, registerVerify } from '@/api/user'
import { uploadVideo, uploadImage } from '@/utils'
import { uploadVideo, uploadImage, formatRichText } from '@/utils'
import {
getShopData,
saveExperienceStore,
@@ -521,9 +520,10 @@ export default {
onLoad(opts) {
this.partnerId = opts.partnerId || ''
this.promoterUid = opts.promoterUid || ''
uni.showLoading({ title: '加载中...', mask: true })
this.queryCity()
getShopData({partnerId: this.partnerId, promoterUid: this.promoterUid}).then(({ data }) => {
this.notice = data.merchantApplyNotice
this.notice = formatRichText(data.merchantApplyNotice)
})
getExperienceStoreCategoryList().then(({ data }) => {
this.experienceStoreCategoryList = data || []
@@ -531,6 +531,8 @@ export default {
this.experienceStoreCategoryIndex = 0
}
this.initInfo()
}).catch(() => {
uni.hideLoading()
})
},
onUnload() {
@@ -577,12 +579,31 @@ export default {
}).catch(() => {
this.form.isDraft = 1
this.show = true
}).finally(() => {
uni.hideLoading()
})
},
changeAgree(e) {
this.isAgree = e.detail.value.includes('yes')
},
savePopup() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
handlePopupClose() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
stringToMapArr(str, split = ',') {
@@ -865,6 +886,25 @@ export default {
height: 52vh;
overflow-y: auto;
margin: 30rpx 0;
// 小程序rich-text内块级标签无默认段间距,补充与后台富文本编辑器一致的段落格式
::v-deep rich-text {
display: block;
width: 100%;
p, div, ul, ol {
display: block;
margin: 0 0 16rpx;
&:last-child {
margin-bottom: 0;
}
}
li {
margin: 0 0 8rpx;
}
}
}
.popup-body .agree-box {
margin: 60rpx 0;
+8 -5
View File
@@ -6,32 +6,32 @@
mode="scaleToFill"
/>
<image
v-show="partnerType === 'province_partner' || partnerType === ''"
v-show="partnerType === 'province_partner' || partnerType === '' || partnerType === 'county_agent'"
:src="images.goodSupplierImage"
class="img-item"
mode="widthFix"
@click="goto('goods_supplier')"
/>
<image
v-show="partnerType === 'pioneer' || partnerType === ''"
v-show="partnerType === 'pioneer' || partnerType === '' || partnerType === 'county_agent'"
:src="images.wenwanSupplierImage"
class="img-item"
mode="widthFix"
@click="goto('wenwan_supplier')"
/>
<image
v-show="partnerType === 'pioneer' || partnerType === ''"
v-show="partnerType === 'pioneer' || partnerType === '' || partnerType === 'county_agent'"
:src="images.hotelImage"
class="img-item"
mode="widthFix"
@click="goto('shop')"
/>
<!-- <image
<image
:src="images.wholesalerImage"
class="img-item"
mode="widthFix"
@click="goto('wholesaler')"
/> -->
/>
<image
:src="images.travelImage"
class="img-item"
@@ -74,6 +74,9 @@ export default {
this.partnerId = options.partnerId || ''
this.promoterUid = options.promoterUid || ''
getImages().then(({data}) => this.images = data)
},
onShow() {
getShopData({partnerId: this.partnerId, promoterUid: this.promoterUid}).then(({data}) => {
this.partnerType = data.partnerType
this.hotelId = data.hotelId
+130 -73
View File
@@ -6,7 +6,7 @@
labelWidth="216rpx"
>
<view
v-if="stateTitle && isDraft !== 1"
v-if="stateTitle"
class="box-state"
>
<u-alert
@@ -77,11 +77,19 @@
v-if="!form.cover"
class="btn-upload"
>上传图片</view>
<image
v-else
:src="form.cover"
class="img-preview"
/>
<view v-else class="img-wrap">
<image
:src="form.cover"
class="img-preview"
/>
<view
v-if="!reviewing"
class="delete-badge"
@click.stop="deleteImg('cover')"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -102,14 +110,23 @@
v-if="!form.coverVideo"
class="btn-upload"
>上传视频</view>
<video
v-else
:src="form.coverVideo"
:poster="form.coverVideo + '?vframe/jpg/offset/1'"
:controls="false"
play-btn-position="center"
class="video-item"
/>
<view v-else class="img-wrap">
<video
:src="form.coverVideo"
:poster="form.coverVideo + '?vframe/jpg/offset/1'"
:controls="false"
play-btn-position="center"
class="video-item"
/>
<view
v-if="!reviewing"
style="position: absolute; top: 0; right: 0;"
class="delete-badge"
@click.stop="deleteVideo"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -143,11 +160,19 @@
v-if="!form.logo"
class="btn-upload"
>上传图片</view>
<image
v-else
:src="form.logo"
class="img-preview"
/>
<view v-else class="img-wrap">
<image
:src="form.logo"
class="img-preview"
/>
<view
v-if="!reviewing"
class="delete-badge"
@click.stop="deleteImg('logo')"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -415,7 +440,7 @@
:show="show"
mode="center"
round="10"
@close="show=false"
@close="handlePopupClose"
>
<view class="popup-body">
<view class="tc bold">入驻申请须知</view>
@@ -433,7 +458,6 @@
<u-button
type="error"
text="确定"
:disabled="!isAgree"
@click="handleAgree"
/>
</view>
@@ -450,6 +474,7 @@ import {
getShopInfo,
removeApply,
saveShop,
saveHotelDraft,
getHotelInfo,
getCountyFamousHotelType
} from '@/api/join'
@@ -461,7 +486,8 @@ import {
chooseImage,
moreImage,
uploadImage,
chooseVideoToUpload
chooseVideoToUpload,
formatRichText
} from '@/utils'
export default {
@@ -606,45 +632,33 @@ export default {
onLoad(options) {
this.partnerId = options.partnerId || ''
this.promoterUid = options.promoterUid || ''
const local_form = uni.getStorageSync('merchantApplyHotel' + '_form') || {}
this.quaPics = uni.getStorageSync('merchantApplyHotel' + '_quaPics') || []
if(!local_form.serviceTime) {
local_form.serviceTime = '00:00'
}
if(!local_form.serviceEndTime) {
local_form.serviceEndTime = '23:59'
}
this.form = !this.reviewing ? local_form : {
name: '',
cover: '',
coverVideo: '',
coverType: 1, // coverType: 1-图片,2-视频
logo: '',
qualification: '',
type: 0,
typeText: '',
isCountyFamous: 0,
countyFamousHotelType: null,
phone: '',
captcha: '',
area: '',
address: '',
position: '',
content: '',
serviceTime: '00:00',
serviceEndTime: '23:59'
}
this.init()
},
onUnload() {
uni.setStorageSync('merchantApplyHotel'+'_quaPics', this.quaPics)
uni.setStorageSync('merchantApplyHotel' + '_form', this.form)
this.saveDraft()
},
onReady() {
this.$refs.shopForm.setRules(this.rules)
},
methods: {
handleAgree(){
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
handlePopupClose() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
timeRange(e) {
@@ -693,13 +707,14 @@ export default {
}
},
init() {
uni.showLoading({ title: '加载中...', mask: true })
getCity().then(({data}) => {
this.district = data
})
getShopData({partnerId: this.partnerId, promoterUid: this.promoterUid}).then(({data}) => {
this.hotelTypeList = data.hotelTypeList || []
this.columnsType = this.hotelTypeList
this.notice = data.merchantApplyNotice
this.notice = formatRichText(data.merchantApplyNotice)
getCountyFamousHotelType({
page: 1,
limit: 9999
@@ -712,6 +727,8 @@ export default {
}).catch(() => {
this.initInfo()
})
}).catch(() => {
uni.hideLoading()
})
},
@@ -727,22 +744,20 @@ export default {
this.show = true
}
}
if (data.isDraft !== 1) {
switch (data.reviewStatus) {
case 0:
this.stateTitle = '审核中'
this.stateType = 'primary'
this.reviewing = true
break
case 1:
this.reviewing = false
break
case 2:
this.stateTitle = '审核驳回:' + data.reviewMsg
this.stateType = 'error'
this.reviewing = false
break
}
switch (data.reviewStatus) {
case 0:
this.stateTitle = '审核中'
this.stateType = 'primary'
this.reviewing = true
break
case 1:
this.reviewing = false
break
case 2:
this.stateTitle = '审核驳回:' + data.reviewMsg
this.stateType = 'error'
this.reviewing = false
break
}
if (data.hotelInfo) {
// 店铺图片
@@ -787,6 +802,8 @@ export default {
this.form.position = this.$forceToDecimal(this.form.longitude, 6) + ',' + this.$forceToDecimal(this.form.latitude, 6)
this.form.area = `${this.form.provinceName} ${this.form.cityName} ${this.form.areaName}`
}
}).finally(() => {
uni.hideLoading()
})
},
chooseLogoImg(target) {
@@ -795,6 +812,15 @@ export default {
this.form[target] = img
})
},
// 删除单张图片(店铺图片封面 / 店铺logo)
deleteImg(target) {
if (this.reviewing) return
if (target === 'cover') {
this.form.cover = ''
} else if (target === 'logo') {
this.form.logo = ''
}
},
chooseLogoVideo() {
if (this.reviewing) return
chooseVideoToUpload(path => {
@@ -802,6 +828,12 @@ export default {
this.$forceUpdate()
})
},
// 删除视频封面
deleteVideo() {
if (this.reviewing) return
this.form.coverVideo = ''
this.$forceUpdate()
},
chooseShopImg() {
if (this.reviewing) return
const _this = this
@@ -938,17 +970,16 @@ export default {
duration: 3000,
success: () => {
this.showRemove = false
setTimeout(() => {
uni.navigateBack()
}, 3000)
this.reviewing = false
}
})
this.initInfo()
})
},
changeAgree(event) {
this.isAgree = event.detail.value.length > 0
},
save() {
buildPostData() {
this.form.pics = ''
const picsLength = this.pics.length
if (picsLength > 0) {
@@ -971,6 +1002,10 @@ export default {
if (postData.coverType === 2) {
postData.cover = postData.coverVideo
}
return postData
},
save() {
const postData = this.buildPostData()
saveShop(postData, this.partnerId, this.promoterUid).then(res => {
if (res.status === 200) {
uni.showToast({
@@ -991,6 +1026,11 @@ export default {
}
})
})
},
saveDraft() {
if (this.reviewing) return
const postData = this.buildPostData()
saveHotelDraft(postData, this.partnerId, this.promoterUid)
}
}
}
@@ -1020,6 +1060,23 @@ export default {
.font-color-red {
font-size: 22rpx;
}
.img-wrap {
position: relative;
display: inline-block;
.delete-badge {
position: absolute;
top: 0;
right: 20rpx;
background: #000;
color: #fff;
padding: 2rpx 8rpx;
border-radius: 0 0 0 200rpx;
font-size: 22rpx;
z-index: 10;
text-align: center;
}
}
.video-item {
width: 80px;
height: 80px;
+182 -120
View File
@@ -7,7 +7,7 @@
labelWidth="216rpx"
>
<view
v-if="stateTitle && isDraft !== 1"
v-if="stateTitle"
class="box-state"
>
<u-alert
@@ -59,11 +59,19 @@
v-if="!formSupplier.avatar"
class="btn-upload"
>上传图片</view>
<image
v-else
:src="formSupplier.avatar"
class="img-preview"
/>
<view v-else class="img-wrap">
<image
:src="formSupplier.avatar"
class="img-preview"
/>
<view
v-if="!reviewing"
class="delete-badge"
@click.stop="deleteImg('supplier')"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -271,11 +279,19 @@
v-if="!form.cover"
class="btn-upload"
>上传图片</view>
<image
v-else
:src="form.cover"
class="img-preview"
/>
<view v-else class="img-wrap">
<image
:src="form.cover"
class="img-preview"
/>
<view
v-if="!reviewing"
class="delete-badge"
@click.stop="deleteImg('cover')"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -293,14 +309,23 @@
v-if="!form.coverVideo"
class="btn-upload"
>上传视频</view>
<video
v-else
:src="form.coverVideo"
:poster="form.coverVideo + '?vframe/jpg/offset/1'"
:controls="false"
play-btn-position="center"
class="video-item"
/>
<view v-else class="img-wrap">
<video
:src="form.coverVideo"
:poster="form.coverVideo + '?vframe/jpg/offset/1'"
:controls="false"
play-btn-position="center"
class="video-item"
/>
<view
v-if="!reviewing"
style="position: absolute; top: 0; right: 0;"
class="delete-badge"
@click.stop="deleteVideo"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -339,11 +364,19 @@
v-if="!form.logo"
class="btn-upload"
>上传图片</view>
<image
v-else
:src="form.logo"
class="img-preview"
/>
<view v-else class="img-wrap">
<image
:src="form.logo"
class="img-preview"
/>
<view
v-if="!reviewing"
class="delete-badge"
@click.stop="deleteImg('logo')"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -513,7 +546,7 @@
@cancel="changeRemove(false)"
@confirm="onRemove"
/>
<u-popup :show="show" mode="center" round="10" @close="show=false">
<u-popup :show="show" mode="center" round="10" @close="handlePopupClose">
<view class="popup-body">
<view class="tc bold">入驻申请须知</view>
<view class="content">
@@ -530,7 +563,6 @@
<u-button
type="error"
text="确定"
:disabled="!isAgree"
@click="handlAgree"
/>
</view>
@@ -546,14 +578,16 @@ import {
getShopInfo,
removeApply,
saveSupplier,
saveWenwanSupplier
saveWenwanSupplier,
saveSupplierDraft
} from '@/api/join'
import {getCity, registerVerify} from '@/api/user'
import {
chooseImage,
moreImage,
uploadImage,
chooseVideoToUpload
chooseVideoToUpload,
formatRichText
} from '@/utils'
import { pageListenMixins } from '@/mixins/pageListenMixins'
@@ -681,7 +715,8 @@ export default {
// 是否为审核中
reviewing: false,
pageKeyId: '',
showUpload: false
showUpload: false,
pageType: ''
}
},
computed: {
@@ -766,49 +801,8 @@ export default {
this.partnerId = options.partnerId || ''
this.promoterUid = options.promoterUid || ''
const type = options.type
const local = uni.getStorageSync(type) || {}
const local_form = uni.getStorageSync(type + '_form') || {}
this.quaPics = uni.getStorageSync(type + '_quaPics') || []
console.log(this.quaPics, 'this.quaPics');
if(!local_form.serviceTime) {
local_form.serviceTime = '00:00'
}
if(!local_form.serviceEndTime) {
local_form.serviceEndTime = '23:59'
}
this.form = !this.reviewing && local_form || {
name: '',
cover: '',
coverVideo: '',
// coverType: 1-图片,2-视频
coverType: 1,
logo: '',
type: 0,
typeText: '',
phone: '',
area: '',
address: '',
position: '',
content: '',
serviceTime: '00:00',
serviceEndTime: '23:59'
}
this.formSupplier = !this.reviewing && local || {
name: '',
businessLicense: '',
avatar: '',
contact: '',
phone: '',
captcha: '',
qualification: '',
subType: '',
area: '',
address: '',
position: ''
}
this.pageType = type
this.formSupplier.subType = type
if (type === 'goods_supplier') {
this.infoTitle = '特产'
this.pageKeyId = 'merchantApplyGoodsSupplier'
@@ -822,9 +816,7 @@ export default {
this.init()
},
onUnload() {
uni.setStorageSync(this.formSupplier.subType, this.formSupplier)
uni.setStorageSync(this.formSupplier.subType+'_quaPics', this.quaPics)
uni.setStorageSync(this.formSupplier.subType + '_form', this.form)
this.saveDraft()
},
onReady() {
this.$refs.shopForm.setRules(this.rules)
@@ -832,6 +824,23 @@ export default {
},
methods: {
handlAgree() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
handlePopupClose() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
timeRange(e) {
@@ -880,19 +889,26 @@ export default {
}
},
init() {
uni.showLoading({ title: '加载中...', mask: true })
getCity().then(({data}) => {
this.district = data
})
getShopData({partnerId: this.partnerId, promoterUid: this.promoterUid}).then(({data}) => {
this.columnsType = data.hotelTypeList
this.columnsSupplierType = data.supplierTypeList
this.notice = data.merchantApplyNotice
this.notice = formatRichText(data.merchantApplyNotice)
this.initInfo()
}).catch(() => {
uni.hideLoading()
})
},
initInfo() {
// 是否缺少参数区分文玩和特产?
getShopInfo().then((res) => {
// 2026-08-25 BUG 5882 确实需要区分参数
const params = {
subType: this.pageType
}
getShopInfo(params).then((res) => {
this.showUpload = true
const {data} = res
// console.log(res, 'initInfo--------');
@@ -905,28 +921,26 @@ export default {
if(data.isDraft === null || data.isDraft === 1) {
this.show = true
}
if (data.isDraft !== 1) {
switch (data.reviewStatus) {
case 0:
this.stateTitle = '审核中'
this.stateType = 'primary'
this.reviewing = true
break
case 1:
this.reviewing = false
break
case 2:
this.stateTitle = '审核驳回:' + data.reviewMsg
this.stateType = 'error'
this.reviewing = false
break
}
switch (data.reviewStatus) {
case 0:
this.stateTitle = '审核中'
this.stateType = 'primary'
this.reviewing = true
break
case 1:
this.reviewing = false
break
case 2:
this.stateTitle = '审核驳回:' + data.reviewMsg
this.stateType = 'error'
this.reviewing = false
break
}
if (data.hotelInfo) {
// 店铺图片
this.pics = []
this.form = data.hotelInfo
const picsTemp = this.form.pics.split(',')
const picsTemp = (this.form.pics || '').split(',')
if (picsTemp.length > 0) {
picsTemp.map(item => {
if (item) {
@@ -934,39 +948,43 @@ export default {
}
})
}
this.indexType = this.columnsType.findIndex(item => item.id === this.form.type)
this.form.typeText = this.indexType > -1 ? this.columnsType[this.indexType].name : ''
this.form.position = this.$forceToDecimal(this.form.longitude, 6) + ',' + this.$forceToDecimal(this.form.latitude, 6)
this.form.area = `${this.form.provinceName || ''} ${this.form.cityName || ''} ${this.form.areaName || ''}`
if (data.hotelInfo.coverType === 2) {
this.form.coverVideo = data.hotelInfo.cover
this.form.cover = ''
}
}
if (data.supplierInfo) {
// 仅在已提交且申请类型明确不匹配时跳过,草稿状态下正常回显
if (data.isDraft !== 1 && data.applyType != null) {
if (this.infoTitle === "特产" && data.applyType !== 1) return
if (this.infoTitle === "文玩" && data.applyType !== 3) return
}
this.formSupplier = data.supplierInfo
// 后端草稿可能未回传 subType,用当前页面类型补齐
if (!this.formSupplier.subType) {
this.formSupplier.subType = this.pageType
}
// 商家资质
const quaPicsTemp = this.form.qualification && this.form.qualification.split(',') || []
this.quaPics = []
const quaPicsTemp = (this.formSupplier.qualification || '').split(',')
if (quaPicsTemp.length > 0) {
console.log(quaPicsTemp, 'quaPicsTemp--------');
this.quaPics = []
quaPicsTemp.map(item => {
if (item) {
this.quaPics.push({url: item})
}
})
}
this.indexType = this.columnsType.findIndex(item => item.id === this.form.type)
this.form.typeText = this.columnsType[this.indexType].name
this.form.position = this.$forceToDecimal(this.form.longitude, 6) + ',' + this.$forceToDecimal(this.form.latitude, 6)
this.form.area = `${this.form.provinceName || ''} ${this.form.cityName || ''} ${this.form.areaName || ''}`
console.log(this.form, 'form--------');
if (data.hotelInfo.coverType === 2) {
this.form.coverVideo = data.hotelInfo.cover
this.form.cover = ''
}
}
// console.log(data.supplierInfo, 'supplierInfo--------');
if (data.supplierInfo) {
if (this.infoTitle === "特产" && data.applyType !== 1) return
if (this.infoTitle === "文玩" && data.applyType !== 3) return
this.formSupplier = data.supplierInfo
this.formSupplier.typeText = this.columnsSupplierType[this.indexSupplierType].value
this.formSupplier.position = this.$forceToDecimal(this.formSupplier.longitude, 6) + ',' + this.$forceToDecimal(this.formSupplier.latitude, 6)
this.formSupplier.area = `${this.formSupplier.provinceName || ''} ${this.formSupplier.cityName || ''} ${this.formSupplier.areaName || ''}` || ''
this.indexSupplierType = this.columnsSupplierType.findIndex(item => item.key === this.formSupplier.subType)
console.log(this.formSupplier);
this.formSupplier.typeText = this.indexSupplierType > -1 ? this.columnsSupplierType[this.indexSupplierType].value : ''
this.formSupplier.position = this.$forceToDecimal(this.formSupplier.longitude, 6) + ',' + this.$forceToDecimal(this.formSupplier.latitude, 6)
this.formSupplier.area = `${this.formSupplier.provinceName || ''} ${this.formSupplier.cityName || ''} ${this.formSupplier.areaName || ''}`
}
}).finally(() => {
uni.hideLoading()
})
},
chooseLogoImg(target) {
@@ -988,6 +1006,17 @@ export default {
}
})
},
// 删除单张图片(供应商头像 / 店铺封面图 / 店铺logo)
deleteImg(target) {
if (this.reviewing) return
if (target === 'supplier') {
this.formSupplier.avatar = ''
} else if (target === 'cover') {
this.form.cover = ''
} else if (target === 'logo') {
this.form.logo = ''
}
},
chooseLogoVideo() {
if (this.reviewing) return
chooseVideoToUpload(path => {
@@ -995,6 +1024,12 @@ export default {
this.$forceUpdate()
})
},
// 删除视频封面
deleteVideo() {
if (this.reviewing) return
this.form.coverVideo = ''
this.$forceUpdate()
},
chooseShopImg() {
if (this.reviewing) return
const _this = this
@@ -1129,17 +1164,16 @@ export default {
duration: 3000,
success: () => {
this.showRemove = false
setTimeout(() => {
uni.navigateBack()
}, 3000)
this.reviewing = false
}
})
this.initInfo()
})
},
changeAgree(event) {
this.isAgree = event.detail.value.length > 0
},
save() {
buildPostData() {
this.form.pics = ''
const picsLength = this.pics.length
if (picsLength > 0) {
@@ -1162,6 +1196,10 @@ export default {
if (postData.coverType === 2) {
postData.cover = postData.coverVideo
}
return postData
},
save() {
const postData = this.buildPostData()
if (this.infoTitle === '特产') {
saveSupplier(postData, this.formSupplier, this.partnerId, this.promoterUid).then(res => {
if (res.status === 200) {
@@ -1205,6 +1243,13 @@ export default {
})
})
}
},
saveDraft() {
if (this.reviewing) return
// 确保按当前入驻类型(特产/文玩)区分保存,避免共用同一份草稿
this.formSupplier.subType = this.pageType
const postData = this.buildPostData()
saveSupplierDraft(postData, this.formSupplier, this.partnerId, this.promoterUid)
}
}
}
@@ -1244,6 +1289,23 @@ export default {
.font-color-red {
font-size: 22rpx;
}
.img-wrap {
position: relative;
display: inline-block;
.delete-badge {
position: absolute;
top: 0;
right: 20rpx;
background: #000;
color: #fff;
padding: 2rpx 8rpx;
border-radius: 0 0 0 200rpx;
font-size: 22rpx;
z-index: 10;
text-align: center;
}
}
.captcha-wrap {
display: flex;
align-items: center;
+45 -4
View File
@@ -344,7 +344,7 @@
{{ '提交审核' }}
</view>
</view>
<u-popup :show="show" mode="center" round="10" @close="show=false"
<u-popup :show="show" mode="center" round="10" @close="handlePopupClose"
>
<view class="popup-body">
<view class="tc bold">入驻申请须知</view>
@@ -362,7 +362,6 @@
<u-button
type="error"
text="确定"
:disabled="!isAgree"
@click="save"
/>
</view>
@@ -376,7 +375,8 @@ import {getCity, registerVerify} from '@/api/user'
import {
chooseImage,
uploadVideo,
uploadImage
uploadImage,
formatRichText
} from '@/utils'
import {
getShopData,
@@ -469,10 +469,13 @@ export default {
onLoad(opts) {
this.partnerId = opts.partnerId || ''
this.promoterUid = opts.promoterUid || ''
uni.showLoading({ title: '加载中...', mask: true })
this.queryCity()
getShopData({partnerId: this.partnerId, promoterUid: this.promoterUid}).then(({data}) => {
this.notice = data.merchantApplyNotice
this.notice = formatRichText(data.merchantApplyNotice)
this.initInfo()
}).catch(() => {
uni.hideLoading()
})
},
// onShow() {
@@ -492,6 +495,23 @@ export default {
this.isAgree = e.detail.value.includes('yes')
},
save() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
handlePopupClose() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
/**
@@ -554,6 +574,8 @@ export default {
}
}).catch(err => {
// uni.$u.toast(err.msg)
}).finally(() => {
uni.hideLoading()
})
},
/**
@@ -860,6 +882,25 @@ export default {
height: 52vh;
overflow-y: auto;
margin: 30rpx 0;
// 小程序rich-text内块级标签无默认段间距,补充与后台富文本编辑器一致的段落格式
::v-deep rich-text {
display: block;
width: 100%;
p, div, ul, ol {
display: block;
margin: 0 0 16rpx;
&:last-child {
margin-bottom: 0;
}
}
li {
margin: 0 0 8rpx;
}
}
}
.popup-body .agree-box {
margin: 60rpx 0;
+175 -75
View File
@@ -6,8 +6,7 @@
labelWidth="216rpx"
>
<view
v-if="stateTitle && isDraft!==1 && applyType === 4"
class="box-state"
v-if="stateTitle"
>
<u-alert
:center="stateType === 'primary'"
@@ -17,11 +16,11 @@
</view>
<u-cell-group
:border="false"
:customStyle="{'fontSize':'40rpx'}"
title="采购批发商基本信息"
:customStyle="{'fontSize':'40rpx', 'backgroundColor':'#fff'}"
title="礼品集采中心基本信息"
>
<u-form-item prop="name">
<u-cell title="批发商名称" :border="false">
<u-cell title="中心名称" :border="false">
<template #icon>
<text class="required">*</text>
</template>
@@ -30,7 +29,22 @@
v-model="form.name"
:disabled="reviewing"
border="none"
placeholder="请填写批发商名称"
placeholder="请填写礼品集采中心名称"
/>
</template>
</u-cell>
</u-form-item>
<u-form-item prop="businessLicense">
<u-cell title="营业执照名称" :border="false">
<template #icon>
<text class="required">*</text>
</template>
<template #value>
<u-input
v-model="form.businessLicense"
:disabled="reviewing"
border="none"
placeholder="请填写营业执照名称"
/>
</template>
</u-cell>
@@ -44,11 +58,19 @@
v-if="!form.avatar"
class="btn-upload"
>上传图片</view>
<image
v-else
:src="form.avatar"
class="img-preview"
/>
<view v-else class="img-wrap">
<image
:src="form.avatar"
class="img-preview"
/>
<view
v-if="!reviewing"
class="delete-badge"
@click.stop="deleteImg('avatar')"
>
x
</view>
</view>
</view>
</template>
</u-cell>
@@ -100,7 +122,7 @@
placeholder="请填写验证码"
/>
</view>
<view class="captcha-wrap-ft">
<view class="captcha-wrap-ft" v-if="!reviewing">
<u-code
ref="uCode"
seconds="30"
@@ -119,7 +141,7 @@
</u-cell>
</u-form-item>
<u-form-item prop="qualification">
<view class="licence-section">
<view class="full-title">
<u-cell :border="false">
<template #icon>
<text class="required">*</text>
@@ -132,22 +154,16 @@
<view class="licence-image">
<u-cell :border="false">
<template #title>
<view class="box-upload" @click="chooseLogoImg('licence')">
<view
v-if="!form.qualification"
class="btn-upload"
>上传图片</view>
<view v-else>
<view v-if="qualificationArr.length > 0" class="flex">
<image
v-for="(item, index) in qualificationArr"
:key="index"
:src="item"
class="img-preview"
/>
</view>
</view>
</view>
<u-upload
:maxCount="9"
:fileList="quaPics"
:disabled="reviewing"
:deletable="!reviewing"
name="quaPics"
multiple
@afterRead="quaAfterRead"
@delete="quaDeletePic"
/>
</template>
</u-cell>
</view>
@@ -194,7 +210,7 @@
撤销申请
</view>
<view
v-else
v-else-if="reviewStatus !== 1"
class="btn-submit"
@click="onSubmit"
>
@@ -207,7 +223,7 @@
@cancel="changeRemove(false)"
@confirm="onRemove"
/>
<u-popup :show="show" mode="center" round="10" @close="show=false">
<u-popup :show="show" mode="center" round="10" @close="handlePopupClose">
<view class="popup-body">
<view class="tc bold">入驻申请须知</view>
<view class="content">
@@ -224,7 +240,6 @@
<u-button
type="error"
text="确定"
:disabled="!isAgree"
@click="save"
/>
</view>
@@ -234,9 +249,9 @@
<script>
import CitySelect from '@/components/CitySelect'
import {getShopData, getWholesaler, removeApply, saveWholesaler} from '@/api/join'
import {getShopData, getWholesaler, removeApply, saveWholesaler, saveWholesalerDraft} from '@/api/join'
import {getCity, registerVerify} from '@/api/user'
import {chooseImage} from '@/utils'
import {chooseImage, uploadImage, formatRichText} from '@/utils'
import { pageListenMixins } from '@/mixins/pageListenMixins'
export default {
@@ -250,6 +265,7 @@ export default {
tips: '获取验证码',
form: {
name: '',
businessLicense: '',
avatar: '',
contact: '',
phone: '',
@@ -310,7 +326,7 @@ export default {
},
district: [],
address: {},
qualificationArr: [],
quaPics: [],
isAgree: false,
show: false,
notice: '',
@@ -332,6 +348,9 @@ export default {
this.promoterUid = options.promoterUid || ''
this.init()
},
onUnload() {
this.saveDraft()
},
onReady() {
this.$refs.wholesalerForm.setRules(this.rules)
},
@@ -374,65 +393,90 @@ export default {
}
},
init() {
uni.showLoading({ title: '加载中...', mask: true })
getCity().then(({data}) => {
this.district = data
})
getShopData({partnerId: this.partnerId, promoterUid: this.promoterUid}).then(({data}) => {
this.notice = data.merchantApplyNotice
this.notice = formatRichText(data.merchantApplyNotice)
this.initInfo()
}).catch(() => {
uni.hideLoading()
})
},
initInfo() {
getWholesaler().then(({data}) => {
this.applyType = data.applyType
if (data.applyType === 4) {
this.isDraft = data.isDraft
this.reviewStatus = data.reviewStatus
}
this.isDraft = data.isDraft
this.reviewStatus = data.reviewStatus
if(data.isDraft === null || data.isDraft === 1) {
this.show = true
}
if (data.isDraft !== 1) {
switch (data.reviewStatus) {
case 0:
this.stateTitle = '审核中'
this.stateType = 'primary'
this.reviewing = true
break;
case 1:
this.reviewing = false
break;
case 2:
this.stateTitle = '审核驳回:' + data.reviewMsg
this.stateType = 'error'
this.reviewing = false
break;
}
console.log(data.reviewStatus);
switch (data.reviewStatus) {
case 0:
this.stateTitle = '审核中'
this.stateType = 'primary'
this.reviewing = true
break;
case 1:
this.stateTitle = '审核通过'
this.stateType = 'success'
this.reviewing = false
break;
case 2:
this.stateTitle = '审核驳回:' + data.reviewMsg
this.stateType = 'error'
this.reviewing = false
break;
}
if (data.wholesalerInfo) {
this.form = data.wholesalerInfo
this.quaPics = []
if (this.form.qualification) {
this.qualificationArr = this.form.qualification.split(',')
this.form.qualification.split(',').map(item => {
if (item) {
this.quaPics.push({url: item})
}
})
}
this.form.position = this.$forceToDecimal(this.form.longitude, 6) + ',' + this.$forceToDecimal(this.form.latitude, 6)
this.form.area = `${this.form.provinceName} ${this.form.cityName} ${this.form.areaName}`
this.form.area = [this.form.provinceName, this.form.cityName, this.form.areaName].filter(Boolean).join(' ')
}
}).finally(() => {
uni.hideLoading()
})
},
chooseLogoImg(target) {
if (this.reviewing) return
chooseImage(img => {
switch (target) {
case 'avatar':
this.form.avatar = img
break
case 'licence':
this.form.qualification = img
this.qualificationArr = [img]
break
if (target === 'avatar') {
this.form.avatar = img
}
})
},
// 删除头像
deleteImg(target) {
if (target === 'avatar') {
this.form.avatar = ''
}
},
// 删除商家资质图片
quaDeletePic(event) {
this[`${event.name}`].splice(event.index, 1)
},
// 商家资质批量上传
quaAfterRead(event) {
const that = this
if (event.file.length > 0) {
event.file.map(item => {
uploadImage(item.url, img => {
that.quaPics.push({url: img})
})
})
}
},
// 省市区
result(values) {
this.address = {
@@ -449,7 +493,7 @@ export default {
this.form.areaId = values.district.id
},
onSubmit() {
this.buildQualification()
this.$refs.wholesalerForm.validate().then(res => {
// 校验通过
saveWholesaler(this.form).then(res => {
@@ -485,11 +529,10 @@ export default {
duration: 3000,
success: () => {
this.showRemove = false
setTimeout(() => {
uni.navigateBack()
}, 3000)
this.reviewing = false
}
})
this.initInfo()
})
},
@@ -497,7 +540,37 @@ export default {
this.isAgree = event.detail.value.length > 0
},
save() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
handlePopupClose() {
if (!this.isAgree) {
uni.showToast({
title: '请先阅读并同意入驻申请须知',
icon: 'none'
})
return
}
this.show = false
},
saveDraft() {
if (this.reviewing) return
this.buildQualification()
saveWholesalerDraft(this.form)
},
buildQualification() {
this.form.qualification = ''
const tempArr = []
this.quaPics.map(item => {
item.url && tempArr.push(item.url)
})
this.form.qualification = tempArr.join(',')
}
}
}
@@ -505,6 +578,18 @@ export default {
<style lang="less">
@import "@/assets/css/pkg_join.less";
/deep/ .u-cell__title-text {
white-space: nowrap !important;
}
/deep/ .full-title {
.u-cell__title {
width: 100% !important;
white-space: nowrap !important;
}
}
</style>
<style lang="less" scoped>
/deep/ .cityselect-nav {
.item {
@@ -518,14 +603,26 @@ export default {
}
}
/deep/ .licence-section{
.u-cell__title{
width: 650rpx!important;
}
}
.font-color-red{
font-size: 24rpx;
}
.img-wrap {
position: relative;
display: inline-block;
.delete-badge {
position: absolute;
top: 0;
right: 20rpx;
background: #000;
color: #fff;
padding: 2rpx 8rpx;
border-radius: 0 0 0 200rpx;
font-size: 22rpx;
z-index: 10;
text-align: center;
}
}
.captcha-wrap {
display: flex;
align-items: center;
@@ -533,4 +630,7 @@ export default {
flex: 1;
}
}
.btn-submit{
position: sticky !important;
}
</style>
+11
View File
@@ -24,6 +24,7 @@
:src="countyFamousTopImage"
class="img"
mode="widthFix"
:lazy-load="true"
/>
<view v-if="list.length > 0" class="province-wrap" id="province-wrap">
<view
@@ -39,6 +40,7 @@
<image
:src="item.icon"
class="img"
:lazy-load="true"
/>
<view class="name one-t">
{{ item.provinceName }}
@@ -61,6 +63,7 @@
<image
:src="webUrl + '/page/qianxian/icon-06.png'"
class="icon"
:lazy-load="true"
/>
</view>
</view>
@@ -95,11 +98,13 @@
<image
:src="county.logo"
class="county-img"
:lazy-load="true"
/>
<view class="county-name">
<image
:src="webUrl + '/home/icon-location.png'"
class="icon"
:lazy-load="true"
/>
<view class="county-txt one-t">
{{ county.countyName }}
@@ -118,11 +123,13 @@
<image
:src="county.logo"
class="county-img"
:lazy-load="true"
/>
<view class="county-name">
<image
:src="webUrl + '/home/icon-location.png'"
class="icon"
:lazy-load="true"
/>
<view class="county-txt one-t">
{{ county.countyName }}
@@ -140,11 +147,13 @@
<image
:src="county.logo"
class="county-img"
:lazy-load="true"
/>
<view class="county-name">
<image
:src="webUrl + '/home/icon-location.png'"
class="icon"
:lazy-load="true"
/>
<view class="county-txt one-t">
{{ county.countyName }}
@@ -160,6 +169,7 @@
:src="webUrl + '/home/no-data-bg.png'"
mode="widthFix"
class="loadend"
:lazy-load="true"
/>
</view>
<image
@@ -167,6 +177,7 @@
:src="webUrl + '/orderIcon/nodata.png'"
class="img-nodata v12-mt-16"
mode="scaleToFill"
:lazy-load="true"
/>
</view>
<goo-skeleton
@@ -0,0 +1,374 @@
<template>
<view class="graphic-guide-page">
<hx-navbar
:fixed="true"
:background-color="[0,[0,0,0,0],[0,0,0,0]]"
statusBarFontColor="#ffffff"
barPlaceholder="hidden"
transparent="auto"
color="#ffffff"
/>
<view v-if="isLoad">
<swiper
v-if="bannerImages.length"
class="banner-swiper"
circular
autoplay
:interval="5000"
>
<swiper-item
v-for="(item, index) in bannerImages"
:key="index"
>
<image
:src="item"
class="banner-image"
mode="aspectFill"
/>
</swiper-item>
</swiper>
<image
v-else-if="detail.image"
:src="detail.image"
class="banner-fallback"
mode="aspectFill"
/>
<view class="article-card">
<view class="article-title">{{ detail.title || '' }}</view>
<view v-if="detail.intro" class="article-intro">
{{ detail.intro }}
</view>
</view>
<view
v-for="(item, index) in detailList"
:key="index"
class="detail-card"
>
<view v-if="item.placeName" class="section-title">
{{ item.placeName }}
</view>
<view v-if="item.content" class="rich-content">
<u-parse :content="item.content" />
</view>
<view
v-if="item.hotelId"
class="shop-card"
@click="goShop(item)"
>
<image
:src="item.hotelLogo || detail.image"
class="shop-logo"
mode="aspectFill"
/>
<view class="shop-main">
<view class="shop-name">{{ item.hotelName || '关联店铺' }}</view>
<view v-if="getServiceTime(item)" class="shop-time-pill">
经营时间{{ getServiceTime(item) }}
</view>
<view v-if="item.hotelAddress" class="shop-address">
{{ item.hotelAddress }}
</view>
</view>
<view class="shop-btn">点击进入</view>
</view>
<view v-if="item.address" class="section-address">
<text>定位{{ item.address }}</text>
</view>
<scroll-view
v-if="item.images && item.images.length"
class="image-scroll"
scroll-x
show-scrollbar="false"
>
<view class="image-list">
<image
v-for="(img, imgIndex) in item.images"
:key="imgIndex"
:src="img"
class="detail-image"
mode="aspectFill"
@click="previewImage(item.images, imgIndex)"
/>
</view>
</scroll-view>
</view>
<view v-if="!detailList.length" class="empty-text">暂无图文内容</view>
</view>
<goo-skeleton v-else />
</view>
</template>
<script>
import { getCountyFamousGraphicGuideContent } from '@/api/qianxian'
export default {
name: 'FamousQianxianGraphicGuide',
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
isLoad: false,
detail: {}
}
},
computed: {
bannerImages() {
return this.detail.bannerImages || []
},
detailList() {
return this.detail.graphicDetails || []
}
},
onLoad(options) {
const id = options.id
if (!id) {
uni.showToast({
title: '缺少攻略ID',
icon: 'none'
})
return
}
this.getDetailReq(id)
},
methods: {
getDetailReq(id) {
getCountyFamousGraphicGuideContent({
guideId: id
}).then(res => {
const { success, data } = res
if (success) {
this.detail = data || {}
uni.setNavigationBarTitle({
title: this.detail.title || '攻略详情'
})
}
}).finally(() => {
this.isLoad = true
})
},
formatDate(time) {
if (!time) return ''
return time.replace(/-/g, '.').slice(0, 10)
},
previewImage(images = [], index = 0) {
if (!images.length) return
uni.previewImage({
urls: images,
current: index
})
},
getServiceTime(item) {
const start = item.serviceTime || ''
const end = item.serviceEndTime || ''
if (start && end) return `${start}-${end}`
return start || end || ''
},
goShop(item) {
if (!item || !item.hotelId) return
this.$yrouter.push({
path: '/pagesInn/inn/innHome',
query: {
id: item.hotelId
}
})
}
}
}
</script>
<style scoped lang="less">
.graphic-guide-page {
min-height: 100vh;
background: #f6f6f6;
}
.banner-swiper,
.banner-fallback {
width: 100%;
height: 750rpx;
}
.banner-image {
display: block;
width: 100%;
height: 100%;
}
.article-card {
padding: 28rpx 24rpx 32rpx;
position: relative;
z-index: 2;
border-radius: 24rpx;
background: #fff;
}
.article-title {
font-size: 40rpx;
line-height: 56rpx;
color: #333;
font-weight: bold;
}
.article-meta {
margin-top: 12rpx;
font-size: 24rpx;
color: #333;
}
.article-intro {
margin-top: 20rpx;
padding: 20rpx 0rpx;
border-radius: 16rpx;
font-size: 36rpx;
line-height: 44rpx;
color: #333;
// font-weight: bold;
}
.detail-card {
padding: 28rpx 24rpx;
border-radius: 24rpx;
background: #fff;
}
.section-title {
font-size: 36rpx;
line-height: 50rpx;
color: #333;
font-weight: bold;
}
.section-address {
display: flex;
align-items: center;
margin-top: 16rpx;
font-size: 36rpx;
line-height: 40rpx;
color: #333;
font-weight: bold;
}
.address-icon {
width: 28rpx;
height: 28rpx;
margin-right: 8rpx;
flex-shrink: 0;
}
.image-list {
display: inline-flex;
flex-wrap: nowrap;
}
.image-scroll {
width: 100%;
margin-top: 24rpx;
white-space: nowrap;
}
.detail-image {
width: 280rpx;
height: 280rpx;
margin-right: 16rpx;
border-radius: 16rpx;
display: block;
}
.detail-image:last-child {
margin-right: 0;
}
.rich-content {
margin-top: 12rpx;
font-size: 28rpx;
line-height: 46rpx;
color: #333;
word-break: break-word;
}
.shop-card {
display: flex;
align-items: center;
margin-top: 12rpx;
padding: 16rpx;
border-radius: 16rpx;
background: #f4f4f4;
}
.shop-logo {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
flex-shrink: 0;
}
.shop-main {
flex: 1;
min-width: 0;
margin-left: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
}
.shop-head {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.shop-name {
font-size: 32rpx;
color: #333;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.shop-time-pill {
display: inline-flex;
align-items: center;
margin-top: 10rpx;
padding: 4rpx 16rpx;
border: 2rpx solid #c52733;
border-radius: 100rpx;
color: #c52733;
font-size: 22rpx;
width: fit-content;
background: transparent;
}
.shop-time-label {
margin-right: 8rpx;
font-weight: bold;
}
.shop-address {
margin-top: 12rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #666;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.shop-btn {
margin-left: 20rpx;
padding: 12rpx 24rpx;
border-radius: 100rpx;
background: #c52733;
color: #fff;
font-size: 26rpx;
font-weight: 500;
flex-shrink: 0;
}
.empty-text {
padding: 120rpx 0;
text-align: center;
font-size: 28rpx;
color: #999;
}
</style>
+32 -6
View File
@@ -224,7 +224,7 @@
@click.stop="handleInfoHotelClick(item)"
>
<view class="info-shop-logo">
<image :src="item.linkHotelLogo" mode="aspectFill" />
<image :src="item.linkHotelLogo" mode="aspectFill" :lazy-load="true" />
</view>
<view class="info-shop-main">
<view class="info-shop-name">
@@ -245,6 +245,7 @@
<image
:src="webUrl + '/20230803152147141807.png'"
class="icon"
:lazy-load="true"
/>
<text class="seeNum-txt">{{ $formatCount(item.pv) }}</text>
</view>
@@ -253,12 +254,14 @@
v-if="!item.hasZan"
:src="webUrl + '/page/hotel/zan-off-2.png'"
class="zan-off-icon"
:lazy-load="true"
@click="likeInfoItemHandle(item, index, item.zan + 1, true)"
/>
<image
v-else
:src="webUrl + '/page/hotel/zan-on-2.png'"
class="zan-on-icon"
:lazy-load="true"
@click="likeInfoItemHandle(item, index, item.zan - 1, false)"
/>
<text
@@ -390,6 +393,7 @@
<image
:src="item"
class="img"
:lazy-load="true"
@click="showPic(index)"
/>
</view>
@@ -413,6 +417,7 @@
:src="item.image"
mode="widthFix"
class="img"
:lazy-load="true"
/>
<view class="info-wrap">
<view class="time">
@@ -470,6 +475,7 @@
<image
:src="webUrl + '/page/qianxian/icon-02.png'"
class="icon"
:lazy-load="true"
/>
重点项目
</view>
@@ -486,6 +492,7 @@
<image
:src="webUrl + '/page/qianxian/icon-05.png'"
class="icon"
:lazy-load="true"
/>
</view>
</view>
@@ -503,6 +510,7 @@
<image
:src="webUrl + '/page/qianxian/icon-02.png'"
class="icon"
:lazy-load="true"
/>
招商政策
</view>
@@ -525,6 +533,7 @@
<image
:src="webUrl + '/page/qianxian/icon-05.png'"
class="icon"
:lazy-load="true"
/>
</view>
</view>
@@ -583,7 +592,11 @@
{{ tab.name }}
</view>
</view>
<view class="village-wrap v12-pt-3">
<scroll-view
class="village-wrap v12-pt-3"
scroll-y
@scrolltolower="getShopList()"
>
<view class="v12-pa-2 sale-wrap">
<view
v-for="(type, typeIndex) in shopTypeList"
@@ -605,11 +618,13 @@
<image
:src="shop.cover + (shop.coverType === 2 ? '?vframe/jpg/offset/1' : '')"
class="img"
:lazy-load="true"
/>
<view class="location">
<image
:src="webUrl + '/page/qianxian/icon-08.png'"
class="icon"
:lazy-load="true"
/>
<view class="addr one-t">
{{ shop.address }}
@@ -624,6 +639,7 @@
<image
:src="shop.logo"
class="logo"
:lazy-load="true"
/>
<view class="name one-t">
{{ shop.name }}
@@ -633,7 +649,7 @@
</view>
</view>
<view v-else class="no-data">暂无店铺</view>
</view>
</scroll-view>
</view>
</view>
<view v-if="shopList.length > 0" class="load-more-status">
@@ -658,7 +674,11 @@
{{ tab.name }}
</view>
</view>
<view class="village-wrap">
<scroll-view
class="village-wrap"
scroll-y
@scrolltolower="getJiaLouListReq()"
>
<view class="v12-pa-2 sale-wrap">
</view>
@@ -701,7 +721,7 @@
</view>
</view>
<view v-else class="no-data">暂无数据</view>
</view>
</scroll-view>
</view>
</view>
<view v-if="jiaLouList.length > 0" class="load-more-status">
@@ -1820,7 +1840,13 @@ export default {
this.hotelItemClick({ id: linkHotelId })
},
guideItemClickHandle(item) {
// 如果没有开启专题页,则不进入
if (!item || !item.id) return
const guideType = item.guideType || 'topic'
if (guideType === 'graphic') {
uni.navigateTo({ url: `/pkg_product/views/famousQianxianGraphicGuide?id=${item.id}` })
return
}
// topic 类型保持原逻辑
if (!item.isContentPage) return
uni.navigateTo({ url: `/pkg_product/views/famousQianxianTheme?id=${item.id}` })
},
+4
View File
@@ -309,6 +309,10 @@ export default {
// console.log(searchMap);
const filterMap = searchMap.filter(el => el.cityName.includes(this.keyword))
if(filterMap.length === 0) {
uni.showToast({
title: '未找到该城市,请重新输入城市名称',
icon: 'none'
})
return
} else {
this.asideIndex = filterMap[0].index
+97 -36
View File
@@ -7,16 +7,16 @@
<view class="v12-font-28 v12-font-bold">退款金额</view>
<view class="return-method">退回原支付方</view>
</view>
<view class="v12-font-32 v12-primary-text v12-font-bold">¥{{refundAmount}}</view>
<view class="v12-font-32 v12-primary-text v12-font-bold">¥{{ displayRefundAmount }}</view>
</view>
<u-divider></u-divider>
<view class="order-amount">
<text class="v12-font-28 v12-font-bold">订单支付金额</text>
<text class="v12-font-32 v12-font-bold">¥{{orderAmount}}</text>
<text class="v12-font-32 v12-font-bold">¥{{ displayOrderAmount }}</text>
</view>
<view class="deduction-amount v12-mt-2">
<text class="v12-font-24 v12-primary-text">退款违约金</text>
<text class="v12-primary-text">¥{{deductionAmount}}</text>
<text class="v12-primary-text">¥{{ displayDeductionAmount }}</text>
</view>
</view>
@@ -49,19 +49,26 @@
<!-- 提交按钮 -->
<view class="v12-mt-3">
<button class="submit-btn v12-primary v12-white-text v12-radius-100 v12-font-32" block @click="submitRefund">点击确认退款</button>
<button
class="submit-btn v12-primary v12-white-text v12-radius-100 v12-font-32"
:class="{ 'submit-btn-disabled': isSubmitDisabled }"
:disabled="isSubmitDisabled"
block
@click="submitRefund"
>点击确认退款</button>
</view>
</view>
</template>
<script>
import { sojoumOrderRefundInfo, sojoumOrderRefund } from '@/api/sojoumOrder.js'
import { fetchSojoumOrderDetail, sojoumOrderRefundInfo, sojoumOrderRefund } from '@/api/sojoumOrder.js'
export default {
data() {
return {
refundAmount: '',
orderAmount: '',
deductionAmount: '',
refundStatus: 0,
refundReasons: [
'行程变更',
'定错时间/地址',
@@ -72,7 +79,22 @@ export default {
],
selectedReason: '',
otherReason: '',
key: ''
key: '',
submitting: false
}
},
computed: {
displayRefundAmount() {
return this.formatMoney(this.refundAmount)
},
displayOrderAmount() {
return this.formatMoney(this.orderAmount)
},
displayDeductionAmount() {
return this.formatMoney(this.deductionAmount)
},
isSubmitDisabled() {
return this.submitting || Number(this.refundStatus) === 3
}
},
onLoad(opts) {
@@ -80,21 +102,63 @@ export default {
this.getRefundInfo(opts.id)
},
methods: {
getRefundInfo(id) {
sojoumOrderRefundInfo({
orderId: id
}).then(res => {
if (res.status === 200) {
this.refundAmount = res.data.refundPrice
this.orderAmount = res.data.payPrice
this.deductionAmount = res.data.penalty
}
})
async getRefundInfo(id) {
try {
const [refundRes, orderRes] = await Promise.all([
sojoumOrderRefundInfo({
orderId: id
}),
fetchSojoumOrderDetail({
key: id
})
])
const refundData = refundRes && refundRes.status === 200 ? (refundRes.data || {}) : {}
const orderData = orderRes && orderRes.status === 200 ? (orderRes.data || {}) : {}
const orderAmount = this.pickFirstValidValue(refundData.payPrice, orderData.payPrice, 0)
const deductionAmount = this.pickFirstValidValue(refundData.penalty, orderData.penalty, 0)
this.refundAmount = this.resolveRefundAmount(refundData.refundPrice, orderAmount, deductionAmount)
this.orderAmount = orderAmount
this.deductionAmount = deductionAmount
this.refundStatus = Number(this.pickFirstValidValue(orderData.refundStatus, refundData.refundStatus, 0))
} catch (e) {
}
},
selectReason(reason) {
if (this.isSubmitDisabled) {
return
}
this.selectedReason = reason
},
hasValidValue(value) {
return value !== '' && value !== null && value !== undefined
},
pickFirstValidValue(...values) {
for (let index = 0; index < values.length; index += 1) {
if (this.hasValidValue(values[index])) {
return values[index]
}
}
return ''
},
formatMoney(value) {
return this.$force2Decimal(Number(value || 0))
},
resolveRefundAmount(refundPrice, orderAmount, deductionAmount) {
if (this.hasValidValue(refundPrice)) {
return refundPrice
}
const orderPriceNumber = Number(orderAmount || 0)
const deductionNumber = Number(deductionAmount || 0)
return Math.max(orderPriceNumber - deductionNumber, 0)
},
submitRefund() {
if (this.isSubmitDisabled) {
uni.showToast({
title: '退款申请已被驳回',
icon: 'none'
})
return
}
// TODO: 实现退款提交逻辑
// orderId string 订单号
// refundReasonWap string 选择的退款原因
@@ -122,6 +186,7 @@ export default {
title: '加载中...',
mask: true,
})
this.submitting = true
sojoumOrderRefund(refundData).then(res => {
if (res.status === 200) {
uni.showToast({
@@ -133,6 +198,7 @@ export default {
})
}
}).finally(() => {
this.submitting = false
uni.hideLoading();
})
}
@@ -229,27 +295,22 @@ export default {
}
}
.submit-section {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx;
background-color: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
.submit-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
border-radius: 40rpx;
border: none;
letter-spacing: 4rpx;
font-weight: 500;
}
.submit-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
border-radius: 40rpx;
border: none;
letter-spacing: 4rpx;
font-weight: 500;
}
.submit-btn-disabled {
background-color: #c0c4cc !important;
color: #ffffff !important;
}
}
</style>
+8 -4
View File
@@ -333,7 +333,8 @@ export default {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
type: 1,
tabIndex: 1
}
});
break;
@@ -355,7 +356,8 @@ export default {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
type: 1,
tabIndex: 1
}
})
break;
@@ -365,7 +367,8 @@ export default {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
type: 1,
tabIndex: 1
}
})
})
@@ -376,7 +379,8 @@ export default {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
type: 1,
tabIndex: 1
}
});
})
@@ -0,0 +1,164 @@
<template>
<u-popup
:show="show"
mode="bottom"
round="40rpx"
:customStyle="{height: '600rpx'}"
@close="close"
>
<view class="cover-picker v12-pt-4">
<swiper
:current="currentIndex"
:autoplay="false"
:circular="true"
:indicator-dots="false"
@change="onChange"
previous-margin="180rpx"
next-margin="180rpx"
class="cover-swiper"
>
<swiper-item v-for="(item, i) in list" :key="i" class="cover-swiper-item" :class="{'n-actived' : currentIndex !== i}">
<view class="cover-item" :class="{'ios-cover': isIOS}">
<view class="img-wrap">
<image :src="item.cover" class="cover-image" mode="widthFix" />
</view>
</view>
</swiper-item>
</swiper>
<view class="v12-justify-center">
<view class="cover-confirm" @click="confirm">
确定
</view>
</view>
<view class="tips">礼包封面在对方领取时展示</view>
<view class="tips tips2">*图片由云灵AI生成仅供参考</view>
</view>
</u-popup>
</template>
<script>
export default {
props: {
index: {
type: Number,
default: 0
},
show: {
type: Boolean,
default: true
},
list: {
type: Array,
default: () => []
}
},
data() {
return {
currentIndex: this.index
}
},
computed: {
isIOS() {
return uni.getSystemInfoSync().osName === 'ios'
}
},
watch: {
index(val) {
this.currentIndex = val
},
show(val) {
if (val) {
this.currentIndex = this.index
}
}
},
methods: {
close() {
this.currentIndex = 0
this.$emit('update:show', false)
},
onChange(e) {
this.currentIndex = e.detail.current
this.$forceUpdate()
},
confirm() {
this.$emit('confirm', this.list[this.currentIndex])
this.$emit('update:show', false)
}
}
}
</script>
<style lang="less" scoped>
.n-actived{
.cover-item{
transform: scale(0.8);
margin-bottom: -70rpx !important;
}
}
.cover-swiper-item{
height: fit-content !important;
bottom: 0;
overflow: visible;
}
.img-wrap{
position: relative;
overflow: visible;
}
.tips{
font-size: 24rpx;
color: #999;
text-align: center;
margin-top: 20rpx;
}
.tips2{
color: #C52733;
}
.cover-swiper{
height: 800rpx;
}
.cover-picker {
.cover-title {
padding: 30rpx;
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.cover-item {
display: flex;
flex-direction: column;
align-items: center;
overflow: visible;
transition: all .3s ease-in-out;
margin-bottom: 30rpx;
.cover-image {
width: 420rpx;
// height: 580rpx;
border-radius: 16rpx;
transition: all .2s ease-in-out;
}
.cover-name {
margin-top: 20rpx;
font-size: 28rpx;
color: #333;
}
}
.cover-confirm {
margin-top: 40rpx;
width: 240rpx;
height: 80rpx;
border-radius: 16rpx;
font-size: 32rpx;
background-color: #C52733 !important;
color: #fff !important;
text-align: center;
line-height: 80rpx;
}
}
.ios-cover{
zoom: 1.01
}
</style>
@@ -0,0 +1,164 @@
<template>
<u-popup
:show="show"
mode="bottom"
round="40rpx"
:customStyle="{height: '600rpx'}"
@close="close"
>
<view class="cover-picker v12-pt-4">
<swiper
:current="currentIndex"
:autoplay="false"
:circular="true"
:indicator-dots="false"
@change="onChange"
previous-margin="180rpx"
next-margin="180rpx"
class="cover-swiper"
>
<swiper-item v-for="(item, i) in list" :key="i" class="cover-swiper-item" :class="{'n-actived' : currentIndex !== i}">
<view class="cover-item" :class="{'ios-cover': isIOS}">
<view class="img-wrap">
<image :src="item.cover" class="cover-image" mode="widthFix" />
</view>
</view>
</swiper-item>
</swiper>
<view class="v12-justify-center">
<view class="cover-confirm" @click="confirm">
确定
</view>
</view>
<view class="tips">礼包封面在对方领取时展示</view>
<view class="tips tips2">*图片由云灵AI生成仅供参考</view>
</view>
</u-popup>
</template>
<script>
export default {
props: {
index: {
type: Number,
default: 0
},
show: {
type: Boolean,
default: true
},
list: {
type: Array,
default: () => []
}
},
data() {
return {
currentIndex: this.index
}
},
computed: {
isIOS() {
return uni.getSystemInfoSync().osName === 'ios'
}
},
watch: {
index(val) {
this.currentIndex = val
},
show(val) {
if (val) {
this.currentIndex = this.index
}
}
},
methods: {
close() {
this.currentIndex = 0
this.$emit('update:show', false)
},
onChange(e) {
this.currentIndex = e.detail.current
this.$forceUpdate()
},
confirm() {
this.$emit('confirm', this.list[this.currentIndex])
this.$emit('update:show', false)
}
}
}
</script>
<style lang="less" scoped>
.n-actived{
.cover-item{
transform: scale(0.8);
margin-bottom: -70rpx !important;
}
}
.cover-swiper-item{
height: fit-content !important;
bottom: 0;
overflow: visible;
}
.img-wrap{
position: relative;
overflow: visible;
}
.tips{
font-size: 24rpx;
color: #999;
text-align: center;
margin-top: 20rpx;
}
.tips2{
color: #C52733;
}
.cover-swiper{
height: 800rpx;
}
.cover-picker {
.cover-title {
padding: 30rpx;
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.cover-item {
display: flex;
flex-direction: column;
align-items: center;
overflow: visible;
transition: all .3s ease-in-out;
margin-bottom: 30rpx;
.cover-image {
width: 420rpx;
// height: 580rpx;
border-radius: 16rpx;
transition: all .2s ease-in-out;
}
.cover-name {
margin-top: 20rpx;
font-size: 28rpx;
color: #333;
}
}
.cover-confirm {
margin-top: 40rpx;
width: 240rpx;
height: 80rpx;
border-radius: 16rpx;
font-size: 32rpx;
background-color: #C52733 !important;
color: #fff !important;
text-align: center;
line-height: 80rpx;
}
}
.ios-cover{
zoom: 1.01
}
</style>
+30 -13
View File
@@ -1,25 +1,42 @@
<template>
<view class="dialog-conent" v-show="isLogin">
<view class="gift-card-modal" :class="{'ios-cover': isIOS}">
<image class="bg-image" :src="!card.isBlind ? card.cover : card.blindBoxImage" mode="widthFix" lazy-load="false"></image>
<view v-if="card.isBlind !== 1" class="image-wrap" :style="{
top: card.productImageY*2 + 'rpx',
left: card.productImageX*2+ 'rpx'
}">
<image v-if="!isTravelGroup" class="pro-image" :src="card.giftProducts[0].productImage" mode="aspectFit|aspectFill|widthFix" lazy-load="false">
</image>
<image v-if="isTravelGroup" class="pro-image" :src="card.travelGroupProduct.mainImage" mode="aspectFit|aspectFill|widthFix" lazy-load="false">
</image>
<image
class="bg-image"
:src="!card.isBlind ? card.cover : card.blindBoxImage"
mode="widthFix"
lazy-load="false"
/>
<view
v-if="card.isBlind !== 1 && !card.isUseAiCoverImg"
:style="{
top: card.productImageY*2 + 'rpx',
left: card.productImageX*2+ 'rpx'
}"
class="image-wrap"
>
<image
v-if="!isTravelGroup"
:src="card.giftProducts[0].productImage"
mode="aspectFit|aspectFill|widthFix"
lazy-load="false"
class="pro-image"
/>
<image
v-if="isTravelGroup"
:src="card.travelGroupProduct.mainImage"
mode="aspectFit|aspectFill|widthFix"
lazy-load="false"
class="pro-image"
/>
</view>
<view
class="good-story"
v-if="card.isBlind !== 1 && card.giftProducts && card.giftProducts[0].productStory && card.isShowProductStory"
v-if="card.isBlind !== 1 && card.giftProducts && card.giftProducts[0].productStory && card.isShowProductStory && !card.isUseAiCoverImg"
:style="{
right: (card.productStoryX*2 || 0) + 'rpx',
top: (card.productStoryY*2 || 0) + 'rpx'
}"
class="good-story"
>
<view v-for="(line, j) in card.giftProducts[0].productStory.split('/n')" :key="j">{{ line }}</view>
</view>
+657 -45
View File
@@ -1,9 +1,134 @@
<template>
<view class="gift-page" v-if="(goodsInfo.productInfo && goodsInfo.productInfo.storeName) || isGroupBuy">
<view class="top-card" v-if="!isPayOk ">
<view class="v12-justify-between" @click="handleShowCover">
<view
v-if="isLoad && ((goodsInfo.productInfo && goodsInfo.productInfo.storeName) || isGroupBuy)"
class="gift-page"
>
<view class="top-card" v-if="!isPayOk">
<view class="top-tab-nav-wrap">
<view
:class="{'active': selectCoverType === 'default'}"
class="item item1"
@click="toggleSelectCoverType('default')"
>
<view class="txt">选择礼包封面</view>
<image :src="webUrl + '/page/gift/gift-tab01.png'" class="tab-img"></image>
</view>
<view
:class="{'active': selectCoverType === 'ai'}"
class="item item2"
@click="toggleSelectCoverType('ai')"
>
<view class="txt">AI生成礼包封面</view>
<image :src="webUrl + '/page/gift/gift-tab02.png'" class="tab-img"></image>
</view>
</view>
<view
v-if="selectCoverType === 'default'"
class="v12-justify-between"
style="margin-top: -1px;"
@click="handleShowCover"
>
<image class="popCover" :src="popupCover" mode="widthFix" lazy-load="false"></image>
</view>
<view
v-if="selectCoverType === 'ai'"
class="ai-cover-wrap"
>
<view class="ai-cover-body">
<view class="ai-cover-container">
<view v-if="!showAiImgHistoryListSelect">
<view v-if="showGenerateBtn" class="prompt">
<textarea
v-model.trim="aiCoverDesc"
:maxlength="300"
placeholder="请描述你想生成的图片"
class="prompt-textarea"
/>
<p class="prompt-tips">{{ aiCoverDesc.length }}/300</p>
</view>
<view v-else class="imgs-list-wrap ai-img-list-wrap">
<view
v-for="(item, index) in aiCoverImgsList"
:key="index"
class="img-item"
>
<image
:src="item.cover"
:class="{
'active': item.id === selectedAiCoverImage.id
}"
mode="heightFix"
class="img-image"
@click="handleSelectAiCover(item)"
/>
</view>
</view>
</view>
<view v-else>
<view
:class="{'scrollable': aiHistoryCoverImgsList.length > 3}"
class="imgs-list-wrap"
>
<view
v-for="(item, index) in aiHistoryCoverImgsList"
:key="index"
class="img-item"
>
<image
:src="item.cover"
:class="{
'active': item.id === selectedAiCoverImage.id
}"
mode="heightFix"
class="img-image"
@click="handleSelectAiHistoryCover(item)"
/>
</view>
</view>
</view>
</view>
<view class="ai-cover-bottom">
<block v-if="!showAiImgHistoryListSelect">
<view v-if="showGenerateBtn" class="btn-wrap">
<view
v-if="!aiCoverGenerateLoading && aiHistoryCoverImgsList.length > 0"
class="btn btn2"
@click="toggleShowAiImgHistoryListSelect(true)"
>
历史图片
</view>
<view class="btn" @click="handleGenerateAiCover">
{{ aiCoverGenerateLoading ? '礼包封面生成中...' : 'AI生成礼包封面' }}
<image v-if="!aiCoverGenerateLoading" :src="webUrl + '/page/gift/gift-tab-icon01.png'" class="icon"></image>
</view>
<image
v-if="aiCoverGenerateLoading && settingInfo.giftCardT2ILoadingGif"
:src="settingInfo.giftCardT2ILoadingGif"
class="loading-img"
/>
</view>
<view v-else class="btn-wrap">
<view class="btn" @click="handleShowAiCover">
预览
</view>
<view class="btn btn2" @click="handleGenerateAgain">
重新生成
</view>
</view>
</block>
<block v-else>
<view class="btn-wrap">
<view class="btn" @click="handleShowAiHistoryCoverPicker">
预览
</view>
<view class="btn btn2" @click="toggleShowAiImgHistoryListSelect(false)">
使用AI生成
</view>
</view>
</block>
</view>
</view>
</view>
</view>
<view class="gift-good-card">
<view class="v12-align-center v12-justify-start">
@@ -95,7 +220,7 @@
<text class="v12-dark-text v12-font-30">{{ computedResult.discountPrice }}</text>
</view>
</view>
<view class="v12-justify-between v12-align-center v12-font-28 v12-mt-1">
<view v-if="!isCountyLotteryGift" class="v12-justify-between v12-align-center v12-font-28 v12-mt-1">
<view class="v12-font-24 v12-dark-text v12-align-center">
<view class="">
优惠券
@@ -130,7 +255,7 @@
</view>
</button>
<view class="btn-wrap v12-mt-12 v12-justify-center" v-if="!isPayOk">
<view class="gift-submit" @click="showPayPicker = true">付款并赠送</view>
<view class="gift-submit" @click="payNowToSendGift">付款并赠送</view>
</view>
<view class="btn-wrap v12-mt-14 v12-justify-center" v-if="isPayOk && !isGroupBuy">
<view class="gift-submit" @click="makeAgain">再送一份</view>
@@ -148,6 +273,18 @@
:index="defaultIndex"
:message="message"
/>
<AiCoverPicker
:show.sync="showAiCoverPicker"
:list="aiCoverImgsList"
:index="aiDefaultIndex"
@confirm="onAiCoverConfirm"
/>
<AiHistoryCoverPicker
:show.sync="showAiHistoryCoverPicker"
:list="aiHistoryCoverImgsList"
:index="aiHistoryDefaultIndex"
@confirm="onAiHistoryCoverConfirm"
/>
<passkeyborad
ref='payPwdPop'
showMoney
@@ -163,6 +300,7 @@
@confirm="onPayConfirm"
/>
<u-popup
v-if="!isCountyLotteryGift"
:show="showPopup"
:round="10"
mode="bottom"
@@ -215,18 +353,28 @@ import {
createGroupBuyGift,
createSojoumGroupBuyGift,
fetchSojoumGroupBuyGiftCarousel,
computedSojoumGroupBuyGiftOrderPrice
computedSojoumGroupBuyGiftOrderPrice,
aiGiftImageGenerate,
aiGiftImageStatus,
aiGiftImageHistory
} from '@/api/gift'
import {
getAiSystemInfoSetting
} from '@/api/public'
import { weappPay } from "@/libs/wechat";
import {mapGetters} from "vuex";
import giftTips from './components/giftTips.vue'
import CoverPicker from './components/CoverPicker.vue'
import AiCoverPicker from './components/AiCoverPicker.vue'
import AiHistoryCoverPicker from './components/AiHistoryCoverPicker.vue'
import PayPicker from './components/PayPicker.vue';
import CouponsPopup from "@/components/CouponsPopup.vue"
export default {
components: {
giftTips,
CoverPicker,
AiCoverPicker,
AiHistoryCoverPicker,
PayPicker,
passkeyborad,
CouponsPopup
@@ -234,9 +382,13 @@ export default {
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
isLoad: false,
loading: true,
// 盲盒礼包
isBlind: false,
// 一人领取所有礼品
isOneRecipient: false,
// 是否支持好友转赠
canTransfer: false,
message: '',
cartId: '',
@@ -257,6 +409,7 @@ export default {
isShowPayPwdPop: false,
payPassword: '',
payType: '',
// 是否支付成功
isPayOk: false,
giftKey: '',
payPrice: 0,
@@ -264,23 +417,72 @@ export default {
defaultIndex:0,
discount: null,
computedResult: {},
skipCouponIdWatch: false,
couponList: {
unusable: [],
usable: []
},
couponTitle: '',
showPopup: false,
// 盲盒礼包图片
blindImage: '',
// 是否为旅居团购礼品
isGroupBuy: false,
popupCover: '',
showInput: true,
// 是否为县区抽奖礼品
isCountyLotteryGift: false,
// 县域抽奖弹窗
showLotteryGiftPopup: false,
isEligibleForDraw: false
isEligibleForDraw: false,
// 封面切换: default/ai
selectCoverType: 'default',
aiCoverImgsList: [
/*
{
id: 15,
cover: 'https://resource.xdd618.com/1/20251202/1764661118796_中秋 2礼品卡1202.png',
image: 'https://resource.xdd618.com/1/20251202/1764661118797_中秋2 对话框封面.png'
},
{
id: 23,
cover: 'https://resource.xdd618.com/1/20251202/1764661193306_中秋 3礼品卡1202.png',
image: 'https://resource.xdd618.com/1/20251202/1764661193306_中秋3 对话框封面.png'
},
{
id: 41,
cover: 'https://resource.xdd618.com/1/20251202/1764661506015_特色好礼礼品卡1202.png',
image: 'https://resource.xdd618.com/1/20250902/1756781423380_特色好礼对话框封面定稿.png'
}
*/
],
showGenerateBtn: true,
aiCoverGenerateLoading: false,
settingInfo: {},
aiCoverDesc: '',
selectedAiCoverImage: {},
showAiCoverPicker: false,
pollInterval: null,
aiDefaultIndex: 0,
aiHistoryDefaultIndex: 0,
showAiHistoryCoverPicker: false,
aiHistoryCoverImgsList: [],
showAiImgHistoryListSelect: false
}
},
watch: {
async couponId(value) {
if (this.skipCouponIdWatch) {
this.skipCouponIdWatch = false
return
}
if (this.isCountyLotteryGift) {
this.couponTitle = ''
if (Number(value || 0) !== 0) {
this.couponId = 0
return
}
}
this.couponIndex = this.couponList['usable']?.findIndex(item => item.id === +value)
this.couponTitle = this.couponList['usable']?.[this.couponIndex]?.couponTitle
if(this.isGroupBuy) {
@@ -291,11 +493,12 @@ export default {
}
},
onLoad(opts) {
this.cartId = opts.cartId
this.isGroupBuy = opts.isGroupBuy === '1'
this.isCountyLotteryGift = opts.from === 'countyLottery' || opts.isCountyLotteryGift === '1' || !!opts.drawActivityId
const pageQuery = Object.assign({}, this.resolvePageQuery(), opts || {})
this.cartId = pageQuery.cartId
this.isGroupBuy = pageQuery.isGroupBuy === '1'
this.isCountyLotteryGift = pageQuery.from === 'countyLottery' || pageQuery.isCountyLotteryGift === '1' || !!pageQuery.drawActivityId
// this.couponId = opts.couponId || 0
this.discount = opts.discount
this.discount = pageQuery.discount
if(this.isGroupBuy) {
this.getGroupBuyInfo()
} else {
@@ -304,6 +507,16 @@ export default {
fetchSojoumGroupBuyGiftCarousel().then(res => {
this.popupCover = res.data[0]
})
getAiSystemInfoSetting().then(res => {
const { success, data } = res
if (success) {
this.settingInfo = data
this.aiCoverDesc = data.giftCardT2IPromptTemplate || ''
}
})
},
onUnload() {
this.clearIntervalPoll()
},
computed: {
...mapGetters(["userInfo"]),
@@ -324,6 +537,149 @@ export default {
}
},
methods: {
// 封面类型切换
toggleSelectCoverType(type) {
if (this.selectCoverType === type) return
this.selectCoverType = type
},
// 获取商品以前使用过的AI礼品卡图片
aiGiftImageHistoryReq() {
aiGiftImageHistory({
productId: this.goodsInfo.productId
}).then(res => {
const { success, data } = res
if (success && data) {
this.aiHistoryCoverImgsList = data || []
this.aiHistoryCoverImgsList.map(historyItem => {
historyItem.cover = historyItem.coverUrl,
historyItem.image = historyItem.shareUrl,
historyItem.name = historyItem.name || ''
})
}
})
},
handleGenerateAiCover() {
if (!this.aiCoverDesc || !this.aiCoverDesc.trim()) {
uni.showToast({
title: '请先配置文生图提示词',
icon: 'none'
})
return
}
if (this.aiCoverGenerateLoading) return
if (this.pollInterval) return
// 点击生成后,禁用按钮,防止重复点击
this.aiCoverGenerateLoading = true
aiGiftImageGenerate({
prompt: this.aiCoverDesc,
productId: this.goodsInfo.productId
}).then(res => {
const { success, data } = res
if (success) {
this.aiDefaultIndex = 0
this.selectedAiCoverImage = {}
this.aiCoverImgsList = []
// 轮询查询状态
this.pollAiImageGenerateStatus()
}
}).catch(() => {
this.aiCoverGenerateLoading = false
})
},
pollAiImageGenerateStatus() {
const _this = this
this.pollInterval = setInterval(() => {
aiGiftImageStatus({
productId: _this.goodsInfo.productId
}).then(res => {
const { success, data } = res
if (success && data) {
// status: 0=生成中 / 1=成功 / 2=失败(无任何记录时为 null)
if (data.status === 1 || data.status === 2) {
_this.clearIntervalPoll()
}
if (data.status === 1 && data.groups && data.groups.length) {
_this.selectedAiCoverImage = data.groups[0]
_this.aiCoverImgsList = []
data.groups.map(item => {
_this.aiCoverImgsList.push({
id: item.id,
cover: item.coverUrl,
image: item.shareUrl,
name: item.name || ''
})
})
_this.selectedAiCoverImage = _this.aiCoverImgsList[0]
// 封面图片
_this.selectedCover = _this.selectedAiCoverImage.cover
// 分享对话图片
_this.giftImage = _this.selectedAiCoverImage.image
console.log(_this.selectedCover)
console.log(_this.giftImage)
_this.showGenerateBtn = false
_this.aiCoverGenerateLoading = false
}
} else {
_this.aiCoverGenerateLoading = false
_this.showGenerateBtn = true
}
}).catch(() => {
_this.aiCoverGenerateLoading = false
_this.showGenerateBtn = true
})
}, 2000)
},
clearIntervalPoll() {
if (this.pollInterval) {
clearInterval(this.pollInterval)
this.pollInterval = null
}
},
handleGenerateAgain() {
this.aiDefaultIndex = 0
this.selectedAiCoverImage = {}
this.aiCoverImgsList = []
this.showGenerateBtn = true
this.aiCoverGenerateLoading = false
},
resolvePageQuery() {
if (this.$yroute && this.$yroute.query) {
return this.$yroute.query
}
if (this.$route && this.$route.query) {
return this.$route.query
}
if (this._route && this._route.query) {
return this._route.query
}
return {}
},
getCouponId() {
if (this.isCountyLotteryGift) return 0
return this.couponId || 0
},
setCouponIdSilently(value) {
if (this.couponId === value) return
this.skipCouponIdWatch = true
this.couponId = value
},
isCountyLotteryCartItem(item) {
return Number(
(item && item.drawActivityId) ||
(item && item.productInfo && item.productInfo.drawActivityId) ||
0
) > 0
},
syncCountyLotteryGiftFlag(item) {
if (!this.isCountyLotteryGift && this.isCountyLotteryCartItem(item)) {
this.isCountyLotteryGift = true
}
if (!this.isCountyLotteryGift) return
this.couponTitle = ''
if (Number(this.couponId || 0) !== 0) {
this.setCouponIdSilently(0)
}
},
adjustCoverListForProductStory(coverList, productInfo, defaultTemplate) {
if (!productInfo || !productInfo.productStory) {
return {
@@ -356,22 +712,52 @@ export default {
computedTravelGroupPrice(useDefaultCouponId) {
const params = {
key: this.orderKey,
couponId: this.couponId
couponId: this.getCouponId()
}
computedSojoumGroupBuyGiftOrderPrice(params).then(res => {
this.computedResult = res.data.result
this.couponList = res.data.result.couponList
this.payPrice = res.data.result.payPrice
this.$forceUpdate()
if(useDefaultCouponId) {
this.couponId = res.data.result.defaultCouponId || 0
if (this.isCountyLotteryGift) {
this.couponTitle = ''
if (this.couponId !== 0) {
this.setCouponIdSilently(0)
}
} else if(useDefaultCouponId) {
this.setCouponIdSilently(res.data.result.defaultCouponId || 0)
}
})
},
handleShowCover() {
this.showCoverPicker = true
},
handleShowAiCover() {
this.showAiCoverPicker = true
},
handleShowAiHistoryCoverPicker() {
this.showAiHistoryCoverPicker = true
},
toggleShowAiImgHistoryListSelect(show) {
this.showAiImgHistoryListSelect = show
this.selectedAiCoverImage = {}
this.selectedCover = ''
this.giftImage = ''
this.templateId = ''
this.aiHistoryDefaultIndex = 0
this.aiDefaultIndex = 0
if (show) {
if (this.aiHistoryCoverImgsList.length > 0 && this.aiHistoryDefaultIndex === 0) {
const index = this.aiHistoryCoverImgsList.findIndex(item => item.isLastSelected)
if (index !== -1) {
this.aiHistoryDefaultIndex = index
}
this.handleSelectAiHistoryCover(this.aiHistoryCoverImgsList[this.aiHistoryDefaultIndex])
}
}
},
showCouponsPopup() {
if (this.isCountyLotteryGift) return
if (this.couponList.usable && this.couponList.usable.length === 0) return
if(this.isPayOk) return
this.showPopup = !this.showPopup
@@ -380,11 +766,12 @@ export default {
this.showPopup = !this.showPopup
},
changeCoupons(item) {
if (this.isCountyLotteryGift) return
if(!item) return
if (this.couponList.usable && this.couponList.usable.length === 0) return
this.showPopup = !this.showPopup
if(!item.id) {
this.couponId = 0
this.setCouponIdSilently(0)
this.couponTitle = ''
if(this.isGroupBuy) {
this.computedTravelGroupPrice(false)
@@ -393,7 +780,7 @@ export default {
}
return
}
this.couponId = item.id
this.setCouponIdSilently(item.id)
this.couponTitle = item.couponTitle
if(this.isGroupBuy) {
this.computedTravelGroupPrice(false)
@@ -417,12 +804,18 @@ export default {
this.giftNotice = res.data.giftCardGiftNotice
this.orderKey = res.data.orderKey
this.goodsInfo = goodsInfo
this.syncCountyLotteryGiftFlag(goodsInfo)
this.templateId = template.id
this.defaultIndex = this.coverList.findIndex(item => item.id === this.templateId)
console.log(this.defaultIndex, 'defaultIndex');
this.selectedCover = template.cover
this.giftImage = template.image
this.couponId = ''
if (this.selectCoverType === 'ai') {
this.selectedCover = this.selectedAiCoverImage.cover
this.giftImage = this.selectedAiCoverImage.image
this.templateId = this.selectedAiCoverImage.id
}
this.setCouponIdSilently('')
this.computedPrice(this.goodsInfo.cartNum)
})
},
@@ -448,7 +841,7 @@ export default {
computedPrice(num, f) {
const params = {
cartId: this.cartId,
couponId: this.couponId,
couponId: this.getCouponId(),
cartNum : num
}
if(this.discount) {
@@ -456,8 +849,13 @@ export default {
}
getGiftCardSendOrderAmount(this.orderKey, params).then(res => {
this.couponList = res.data.result.couponList
if(!f) {
this.couponId = res.data.result.defaultCouponId || 0
if (this.isCountyLotteryGift) {
this.couponTitle = ''
if (this.couponId !== 0) {
this.setCouponIdSilently(0)
}
} else if(!f) {
this.setCouponIdSilently(res.data.result.defaultCouponId || 0)
this.$forceUpdate()
}
this.payPrice = res.data.result.payPrice
@@ -465,6 +863,24 @@ export default {
this.$forceUpdate()
})
},
payNowToSendGift() {
if (this.selectCoverType === 'default') {
this.showPayPicker = true
return
}
if (this.selectCoverType === 'ai') {
if (!this.selectedAiCoverImage.id) {
uni.showToast({
title: '请生成礼包封面再操作',
icon: 'none'
})
return
} else {
this.showPayPicker = true
}
return
}
},
pwdPopFinish(payPwd) {
this.payPassword = payPwd;
this.confirmGift(true);
@@ -476,8 +892,44 @@ export default {
onCoverConfirm(cover) {
this.cover = cover.name
this.templateId = cover.id
// 封面图片
this.selectedCover = cover.cover
// 分享对话图片
this.giftImage = cover.image
},
onAiCoverConfirm(cover) {
// 封面图片
this.selectedCover = cover.cover
// 分享对话图片
this.giftImage = cover.image
if (this.selectCoverType === 'ai') {
this.selectedAiCoverImage = cover
this.aiDefaultIndex = this.aiCoverImgsList.findIndex(item => item.id === cover.id)
}
},
onAiHistoryCoverConfirm(cover) {
// 封面图片
this.selectedCover = cover.cover
// 分享对话图片
this.giftImage = cover.image
if (this.selectCoverType === 'ai') {
this.selectedAiCoverImage = cover
this.aiHistoryDefaultIndex = this.aiHistoryCoverImgsList.findIndex(item => item.id === cover.id)
}
},
handleSelectAiCover(cover) {
this.selectedAiCoverImage = cover
this.aiDefaultIndex = this.aiCoverImgsList.findIndex(item => item.id === cover.id)
this.selectedCover = cover.cover
this.giftImage = cover.image
this.templateId = cover.id
},
handleSelectAiHistoryCover(cover) {
this.selectedAiCoverImage = cover
this.aiHistoryDefaultIndex = this.aiHistoryCoverImgsList.findIndex(item => item.id === cover.id)
this.selectedCover = cover.cover
this.giftImage = cover.image
this.templateId = cover.id
},
showTips() {
this.$refs.giftTips.showTips = true
@@ -489,24 +941,28 @@ export default {
}
this.loading = true
getGiftCardSendOrderConfirm(params).then(res => {
const temp = this.isGroupBuy ? res.data.giftCardTemplates : res.data.giftCardTemplates.filter(e => e.isTravelGroup === 0)
const hasSpecial = res.data.giftCardTemplates.map(e => e.id).includes(res.data.specialGiftCardTemplate.id)
const initialCoverList = hasSpecial ? [...temp] : [...temp, res.data.specialGiftCardTemplate]
const goodsInfo = res.data.cartInfo[0]
const { coverList, template } = this.adjustCoverListForProductStory(initialCoverList, goodsInfo && goodsInfo.productInfo, res.data.specialGiftCardTemplate)
const data = res.data
const temp = this.isGroupBuy ? data.giftCardTemplates : data.giftCardTemplates.filter(e => e.isTravelGroup === 0)
const hasSpecial = data.giftCardTemplates.map(e => e.id).includes(data.specialGiftCardTemplate.id)
const initialCoverList = hasSpecial ? [...temp] : [...temp, data.specialGiftCardTemplate]
const goodsInfo = data.cartInfo[0]
const { coverList, template } = this.adjustCoverListForProductStory(initialCoverList, goodsInfo && goodsInfo.productInfo, data.specialGiftCardTemplate)
this.coverList = coverList
this.giftNotice = res.data.giftCardGiftNotice
this.orderKey = res.data.orderKey
this.giftNotice = data.giftCardGiftNotice
this.orderKey = data.orderKey
this.goodsInfo = goodsInfo
this.syncCountyLotteryGiftFlag(goodsInfo)
this.templateId = template.id
this.selectedCover = template.cover
this.giftImage = template.image
this.blindImage = res.data.giftCardBlindBoxShareImage
this.blindImage = data.giftCardBlindBoxShareImage
this.defaultIndex = this.coverList.findIndex(item => item.id === this.templateId)
// if(!this.couponId) {
// this.couponId = res.data.couponList.usable[0] && res.data.couponList.usable[0].id || ''
// this.couponId = data.couponList.usable[0] && data.couponList.usable[0].id || ''
// }
this.computedPrice(this.goodsInfo.cartNum)
this.aiGiftImageHistoryReq()
this.isLoad = true
}).finally(() => {
this.loading = false
})
@@ -514,12 +970,17 @@ export default {
isDrawEligible(flag) {
return flag === true || flag === 1 || flag === '1' || flag === 'true'
},
handleGiftPaySuccess(isEligibleForDraw = false) {
handleGiftPaySuccess(data) {
if (data.giftCard) {
this.selectedCover = data.giftCard.cover || this.selectedCover
this.giftImage = data.giftCard.giftCardImage || this.giftImage
}
this.isPayOk = true
this.isEligibleForDraw = this.isDrawEligible(isEligibleForDraw)
this.isEligibleForDraw = this.isDrawEligible(data.isEligibleForDraw)
if (this.isCountyLotteryGift && this.isEligibleForDraw) {
this.showLotteryGiftPopup = true
}
this.aiGiftImageHistoryReq()
},
closeLotteryGiftPopup() {
this.showLotteryGiftPopup = false
@@ -560,19 +1021,22 @@ export default {
key: this.orderKey,
from: 'routine',
cartId: this.cartId,
templateId: this.templateId,
templateId: this.selectCoverType === 'default' ? this.templateId : '',
aiGiftImageId: this.selectCoverType === 'default' ? '' : this.selectedAiCoverImage.id,
cover: this.selectedCover,
message : this.message || '礼笺轻启,礼藏心意',
canTransfer: this.canTransfer ? 1 : 0,
passwordPay: this.payPassword || '',
couponId: this.couponId,
couponId: this.getCouponId(),
payType: this.payType,
} : {
orderKey: this.orderKey,
from: 'routine',
cartId: this.cartId,
couponId: this.couponId,
couponId: this.getCouponId(),
recipientsNum: this.goodsInfo.cartNum,
templateId: this.templateId,
templateId: this.selectCoverType === 'default' ? this.templateId : '',
aiGiftImageId: this.selectCoverType === 'default' ? '' : this.selectedAiCoverImage.id,
message : this.message || '礼笺轻启,礼藏心意',
cover: this.selectedCover,
canTransfer: this.canTransfer ? 1 : 0,
@@ -620,7 +1084,7 @@ export default {
icon: "none",
duration: 2000
});
this.handleGiftPaySuccess(data.isEligibleForDraw);
this.handleGiftPaySuccess(data);
break;
case "WECHAT_H5_PAY":
// H5支付
@@ -637,7 +1101,7 @@ export default {
icon: "none",
duration: 2000
});
this.handleGiftPaySuccess(data.isEligibleForDraw);
this.handleGiftPaySuccess(data);
}).catch(err => {
// this.makeAgain()
@@ -658,7 +1122,7 @@ export default {
});
break;
}
}) .catch(err => {
}).catch(err => {
console.log(err);
uni.hideLoading();
uni.showToast({
@@ -666,6 +1130,14 @@ export default {
icon: "none",
duration: 2000
});
// Fix bug#6073-订单超时后需自动刷新该页面
if (err.res.statusCode === 5113) {
if(this.isGroupBuy) {
this.getGroupBuyInfo()
} else {
this.getGift()
}
}
}).finally(() => {
this.isShowPayPwdPop = false;
this.$refs.payPwdPop.clear();//清空支付密码
@@ -676,6 +1148,7 @@ export default {
const params = {
travelGroupProductId: this.cartId
}
this.isLoad = false
createGroupBuyGift(params).then(res => {
if (res.status === 200) {
this.coverList = res.data.giftCardTemplates || []
@@ -691,6 +1164,7 @@ export default {
}
this.giftNotice = res.data.giftCardGiftNotice
this.computedTravelGroupPrice(true)
this.isLoad = true
}
})
}
@@ -758,11 +1232,7 @@ export default {
border-radius: 16rpx;
}
.tip-wrap{
position: absolute;
bottom: 50rpx;
left: 0;
margin: auto;
right: 0;
margin: 32rpx auto 68rpx auto;
align-items: center;
}
.tip-text{
@@ -788,7 +1258,6 @@ export default {
}
.top-card{
// height: 280rpx;
background: #fff;
border-radius: 16rpx;
}
.line{
@@ -841,7 +1310,6 @@ export default {
}
.popCover{
width: 100%;
border-radius: 16rpx;
}
.lottery-gift-popup{
background: #fff;
@@ -917,4 +1385,148 @@ export default {
.lottery-gift-btn.send::after{
border: none;
}
.top-tab-nav-wrap {
display: flex;
justify-content: space-between;
align-items: center;
.item1 {
.txt {
left: -24rpx;
}
}
.item2 {
.txt {
padding-left: 32rpx;
}
}
.item {
position: relative;
flex: 1;
text-align: center;
font-size: 32rpx;
color: #333;
line-height: 80rpx;
&.active {
color: #fff;
.tab-img {
display: block;
}
}
.txt {
position: relative;
z-index: 5;
}
.tab-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 80rpx;
display: none;
}
}
}
.ai-cover-wrap {
padding: 20rpx;
margin-top: -1px;
box-sizing: border-box;
border-radius: 40rpx 0 40rpx 40rpx;
background-color: #C52932;
.ai-cover-body {
padding: 20rpx;
box-sizing: border-box;
border-radius: 40rpx;
background-color: #fff;
}
.ai-cover-container {
.prompt {
.prompt-textarea {
width: 100%;
height: 200rpx;
background: #fff;
border-radius: 16rpx;
padding: 0 20rpx 12rpx 20rpx;
box-sizing: border-box;
overflow-y: auto;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
}
.prompt-tips {
font-size: 24rpx;
color: #999;
text-align: right;
}
}
.imgs-list-wrap {
display: flex;
justify-content: center;
align-items: baseline;
gap: 40rpx;
padding: 20rpx 0;
box-sizing: border-box;
&.scrollable {
justify-content: flex-start;
flex-wrap: nowrap;
overflow-x: auto;
}
}
.img-image {
display: block;
height: 176rpx;
flex-shrink: 0;
&.active {
transform: scale(1.2) translateY(-16rpx);
}
}
.ai-img-list-wrap {
padding: 28rpx 0 20rpx 0;
}
}
.ai-cover-bottom {
margin-top: 12rpx;
.btn-wrap {
display: flex;
justify-content: center;
align-items: center;
.loading-img {
display: block;
width: 58rpx;
height: 58rpx;
margin-left: 20rpx;
}
}
.btn + .btn {
margin-left: 20rpx;
}
.btn {
display: flex;
justify-content: center;
align-items: center;
height: 54rpx;
line-height: 54rpx;
border-radius: 40rpx;
text-align: center;
font-size: 32rpx;
font-weight: 500;
box-sizing: border-box;
margin: 0;
padding: 0 32rpx;
border: 2rpx solid #c52733;
color: #fff;
background: #c52733;
.icon {
display: block;
width: 28rpx;
height: 28rpx;
margin-left: 16rpx;
}
}
.btn2 {
background: #fff;
color: #c52733;
border: 2rpx solid #c52733;
}
}
}
</style>
+2 -1
View File
@@ -5,7 +5,8 @@
:card="giftCard"
:isTravelGroup="isTravelGroup"
:addr="giftChooseAddress"
@receive="onReceive($event)" />
@receive="onReceive($event)"
/>
<view v-else>
<view class="no-img-wrap" v-if="isExpire">
<view class="wrap-box" >
+98 -11
View File
@@ -18,11 +18,16 @@
<view v-if="cateIndex === 0" class="list-body">
<block v-if="sendList.length > 0">
<view
v-for="(item, index) in sendList"
:key="index"
class="gift-item"
:class="['gift-item', item.badgeText ? 'has-badge' : '']"
>
<view
v-if="item.badgeText"
:class="['gift-badge',['wholesalerCustom', 'wholesalerPurchase'].includes(item.sceneType) ? 'gift-badge-blue' : 'gift-badge-orange']"
>
{{ item.badgeText }}
</view>
<view
v-for="(cart, cartIndex) in item.giftInfo"
:key="cartIndex"
@@ -135,10 +140,16 @@
<view
v-for="(item, index) in receiveList"
:key="index"
class="gift-item"
:class="['gift-item', item.badgeText ? 'has-badge' : '']"
>
<view
v-for="(cart, cartIndex) in item.giftInfos"
v-if="item.badgeText"
:class="['gift-badge', ['wholesalerCustom', 'wholesalerPurchase'].includes(item.sceneType) ? 'gift-badge-blue' : 'gift-badge-orange']"
>
{{ item.badgeText }}
</view>
<view
v-for="(cart, cartIndex) in item._renderGiftInfos"
:key="cartIndex"
class="gift-body"
@click="giftItemClickHanlde(item)"
@@ -146,20 +157,20 @@
>
<view class="gift-img">
<image
:src="cart.productInfo.image"
:src="cart._displayImage"
class="img"
/>
</view>
<view class="gift-good-info">
<view class="name more-t">
{{ cart.productInfo.storeName }}
{{ cart._displayName }}
</view>
<view v-if="cart.productInfo.attrInfo" class="attr-txt">
<view class="txt">{{ cart.productInfo.attrInfo.sku }}</view>
<view v-if="cart._displaySku" class="attr-txt">
<view class="txt">{{ cart._displaySku }}</view>
</view>
<view class="price-wrap">
<view v-if="cart._showPrice" class="price-wrap">
<view class="price">
<text class="prefix"></text>{{ cart.productInfo.attrInfo.price }}
<text class="prefix"></text>{{ cart._displayPrice }}
</view>
</view>
</view>
@@ -442,7 +453,8 @@ export default {
const { success, data } = res
if (success) {
const { list, hasMore } = this.getListResult(data, page)
this.receiveList = page === 1 ? list : this.receiveList.concat(list)
const formatList = list.map(item => this.normalizeReceiveGiftItem(item))
this.receiveList = page === 1 ? formatList : this.receiveList.concat(formatList)
this.receiveHasMore = hasMore
this.receivePage = page + 1
this.receiveInited = true
@@ -526,6 +538,51 @@ export default {
}
return status
},
normalizeReceiveGiftItem(item = {}) {
return {
...item,
_renderGiftInfos: this.getReceiveGiftInfos(item)
}
},
getReceiveGiftInfos(item = {}) {
if (item.customGiftInfo && typeof item.customGiftInfo === 'object') {
const customGift = this.formatCustomGiftInfo(item.customGiftInfo)
if (customGift) {
return [customGift]
}
}
const giftInfos = Array.isArray(item.giftInfos) ? item.giftInfos : []
return giftInfos.map(gift => this.formatDefaultGiftInfo(gift))
},
formatCustomGiftInfo(customGiftInfo = {}) {
const giftImage = typeof customGiftInfo.giftImage === 'string'
? customGiftInfo.giftImage.trim()
: ''
const giftValue = customGiftInfo.giftValue
const hasGiftValue = giftValue !== '' && giftValue !== null && giftValue !== undefined
return {
...customGiftInfo,
_isCustomGift: true,
_displayImage: giftImage,
_displayName: customGiftInfo.giftName || '',
_displaySku: customGiftInfo.specName || '',
_displayPrice: hasGiftValue ? giftValue : '',
_showPrice: Number(customGiftInfo.isShowValue) === 1 && hasGiftValue
}
},
formatDefaultGiftInfo(gift = {}) {
const productInfo = gift.productInfo || {}
const attrInfo = productInfo.attrInfo || {}
const price = attrInfo.price
return {
...gift,
_displayImage: productInfo.image || '',
_displayName: productInfo.storeName || '',
_displaySku: attrInfo.sku || '',
_displayPrice: price,
_showPrice: price !== '' && price !== null && price !== undefined
}
},
showTips() {
this.$refs.giftTips.showTips = true
},
@@ -596,10 +653,40 @@ export default {
z-index: 2;
padding: 84rpx 0 80rpx 0;
.gift-item {
position: relative;
padding: 16rpx;
margin: 0 0 24rpx;
border-radius: 16rpx;
background-color: #ffff;
.gift-badge {
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
width: fit-content;
height: 48rpx;
border-radius: 0rpx 16rpx 0rpx 24rpx;
font-size: 26rpx;
color: #fff;
padding: 0 12rpx;
line-height: 1;
}
.gift-badge-blue {
background: #28AAF4;
}
.gift-badge-orange {
background: #FF9644;
}
&.has-badge {
.gift-good-info {
.name {
padding-right: 160rpx;
}
}
}
.gift-body {
display: flex;
align-items: center;
+50 -5
View File
@@ -17,13 +17,16 @@
</view>
<view class="amount-box">
<view class="title bold">提现金额</view>
<view class="v12-justify-between">
<view class="title bold">提现金额</view>
<view class="title" @click="showRules">提现规则</view>
</view>
<view class="item acea-row row-middle">
<view class="dollar bold"></view>
<view class="input">
<u--input
v-model="amout"
:placeholder="'最低提现金额' + minPrice"
placeholder="请输入提现金额"
:maxlength="-1"
:customStyle="{
'border': 0
@@ -68,18 +71,25 @@
</block>
</blPaymentPasswordInput>
</uni-popup>
<uni-popup ref="rulesPopup" class="rules-popup" safe-area background-color="#fff" type="bottom">
<view class="rules-content">
<view class="rules-title">提现规则</view>
<rich-text v-if="withdrawalRules" class="rules-text" :nodes="withdrawalRules" />
<view v-else class="rules-text">暂无提现规则</view>
</view>
</uni-popup>
</view>
</template>
<script>
import {mapGetters} from "vuex";
import { getBank, bankCardList, postCashInfo } from "@/api/user";
import { getBank, bankCardList, postCashInfo, getWithdrawalRules } from "@/api/user";
import NP from "number-precision";
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import blPaymentPasswordInput from '@/components/blPaymentPasswordInput.vue';
import { pageListenMixins } from '@/mixins/pageListenMixins'
import { formatRichText } from '@/utils'
export default {
mixins: [pageListenMixins],
@@ -97,7 +107,8 @@ export default {
gdLimit: 0, //最低固定费率额度
feeRate: 0, //手续费费率
remark: "", //提现说明
pageKeyId: Object.freeze('userExtractIndex')
pageKeyId: Object.freeze('userExtractIndex'),
withdrawalRules: '',
}
},
components: {
@@ -135,6 +146,12 @@ export default {
}
},
methods: {
showRules() {
getWithdrawalRules().then(res => {
this.withdrawalRules = formatRichText(res.data);
this.$refs.rulesPopup.open();
})
},
calculateSxf: function (amout) {
var sxf = 0;
if (amout == 0) {
@@ -477,4 +494,32 @@ export default {
line-height: 40rpx;
text-decoration: underline;
}
.rules-popup /deep/ .uni-popup__wrapper-box {
background: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
}
.rules-content {
padding: 32rpx;
padding-bottom: calc(32rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
}
.rules-title {
margin-bottom: 24rpx;
color: #333333;
font-size: 32rpx;
font-weight: bold;
line-height: 44rpx;
text-align: center;
}
.rules-text {
color: #666666;
font-size: 26rpx;
line-height: 40rpx;
word-break: break-all;
}
</style>
+9
View File
@@ -9,6 +9,15 @@ import stringify from "@/utils/querystring";
import {VUE_APP_API_URL} from "@/config";
import {auth} from '@/libs/wechat'
// 富文本内容预处理:
// 纯文本内容(不含HTML标签)中的换行符\n在rich-text中会被折叠为空格,需转为<br/>以保留换行格式
export function formatRichText(content) {
if (!content) return ''
// 含HTML标签的富文本内容不做处理,避免破坏原有结构
if (/<[a-zA-Z][^>]*>/.test(content)) return content
return content.replace(/\r\n/g, '\n').replace(/\n/g, '<br/>')
}
export function dataFormat(time, option) {
time = +time * 1000;
const d = new Date(time);
+12
View File
@@ -34,6 +34,7 @@ export default {
pages: 0, // 总页数
list: [],
os: '',
isClick: false, // 防止连续点击重复请求/跳转
pageKeyId: Object.freeze('investmentList')
}
},
@@ -41,6 +42,10 @@ export default {
this.getOS()
this.getData()
},
onShow() {
// 从文件阅读页返回时解锁,允许再次点击
this.isClick = false
},
onReachBottom() {
if (this.pages >= this.page) this.getData()
},
@@ -67,6 +72,8 @@ export default {
})
},
getDetail(id) {
if (this.isClick) return
this.isClick = true
investmentInfo(id).then(({data}) => {
const file = data.contents[0];
if (file.suffix === 'pdf' && this.os === 'android') {
@@ -77,6 +84,8 @@ export default {
url: '/pkg_common/views/pdf?path=' + encodeURI(path) + '&id=' + id
})
}
}).catch(() => {
this.isClick = false
})
},
viewPdf(url) {
@@ -89,8 +98,10 @@ export default {
fileType: 'pdf',
success: result => {
//成功
this.isClick = false
},
fail: err => {
this.isClick = false
uni.showModal({
title: 'openDocument fail',
content: JSON.stringify(err)
@@ -99,6 +110,7 @@ export default {
})
},
fail: err => {
this.isClick = false
uni.showModal({
title: 'downloadFile fail',
content: JSON.stringify(err)
+2 -2
View File
@@ -9,8 +9,8 @@
<view class="location-box flex ai-center">
<!-- @click="goCity"-->
<image :src="webUrl+'/20220903142929759087.png'" mode="scaleToFill"></image>
<text class="city-name">{{ cityName }}</text>
<text>当前定位</text>
<text class="city-name">当前城市{{ cityName }}</text>
<text></text>
</view>
<view class="more-box flex ai-center">
<text @click="goClass">全部商品列表</text>