完善OSS/CDN,私密OSS,商家入驻,客服
This commit is contained in:
parent
5fc340a47a
commit
fa8d4cc38d
@ -2,6 +2,7 @@ export const apiArr = {
|
||||
getCateList: "/api/v2/wechat/merchant-cate-crud/list", //商家分类列表
|
||||
getMerchantList: "/api/v2/wechat/merchant-info-crud/page", //商家列表
|
||||
getHomeBanner: "/api/v2/wechat/home-banner-region-crud/page", //获取首页banner及其广告
|
||||
getHomeBannerMulti: "/api/v2/wechat/home-banner-region-crud/multi", //按广告位批量获取首页广告(一次返回多个 ad_position)
|
||||
getButtonNum:"/api/v2/wechat/nav-display-crud/info",//获取首页button的行数 数量
|
||||
getHomeButton:"/api/v2/wechat/home-button-region-crud/page", //获取首页button
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ export const apiArr = {
|
||||
getMerchantList:"/api/v2/wechat/merchant-info-crud/page",//商家列表
|
||||
createComment:"/api/v2/wechat/merchant-evaluation-crud/creat",//创建用户评价
|
||||
getMerchantInfo:"/api/v2/wechat/merchant-info-crud/info",//获取商家信息详情
|
||||
getShopActivityList:"/api/v2/wechat/commodity/shop-activity/list",//好店详情页-店铺活动商品列表
|
||||
getMerchantComment:"/api/v2/wechat/merchant-evaluation-crud/page",//获取商家评价
|
||||
merChantCommentLike:"/api/v2/wechat/merchant-evaluation-like-crud/creat",//点赞
|
||||
merChantCommentUnlike:"/api/v2/wechat/merchant-evaluation-like-crud/del",//取消点赞
|
||||
@ -26,4 +27,5 @@ export const apiArr = {
|
||||
|
||||
|
||||
createStore:"/api/v2/wechat/store-info-crud/creat",//门店信息创建
|
||||
ocrRecognize:"/api/v1/wechat/oss/ocr-recognize",//证件 OCR 自动识别
|
||||
};
|
||||
|
||||
84
doc/首页Banner跳转现状梳理.md
Normal file
84
doc/首页Banner跳转现状梳理.md
Normal file
@ -0,0 +1,84 @@
|
||||
# 首页 Banner / 广告位 跳转现状梳理
|
||||
|
||||
> 状态:现状分析(仅梳理,代码未改)。日期:2026-06-03
|
||||
> 范围:小程序 `pages/index/index.vue` 首页各广告位的点击跳转逻辑,对照后端配置。
|
||||
|
||||
---
|
||||
|
||||
## 一、后端是怎么配置跳转的
|
||||
|
||||
每条 banner/广告(表 `home_banner_region`)、金刚位(表 `home_button_region`)都有统一的跳转配置字段,核心是 **`promotion_type`(推广类型)**:
|
||||
|
||||
| promotion_type | 含义 | 配套字段 |
|
||||
|---|---|---|
|
||||
| 1 | 无跳转 | — |
|
||||
| 2 | 选择活动 | 关联 `advertisement_goods`(按 banner id) |
|
||||
| 3 | 跳转本程序页面 | `link_url` |
|
||||
| 4 | 跳转其他小程序 | `appid` + `link_url` |
|
||||
| 5 | 选择商品 | `advertisement_goods[].goods_id` |
|
||||
|
||||
- 后台创建/编辑接口(`api/admin/v2/crud_home_banner_region.go`)用 `promotion_type` + `required-if` 校验对应字段,例如 type=4 必填 appid、type=3/4 必填 link_url。
|
||||
- `home_button_region`(金刚位)字段相同,也有 `promotion_type` / `link_url` / `appid`。
|
||||
- type=2/5 的落地:`/packages/advertising/index/index?id=<banner.id>` 是“广告聚合落地页”,传 banner 自身 id 进去,页面内部拉该 banner 关联的 `advertisement_goods` 商品列表展示,并可进入 `goodsDetail`。
|
||||
|
||||
---
|
||||
|
||||
## 二、前端实际怎么跳的(问题所在)
|
||||
|
||||
首页有 4 个不同的点击处理函数各管一片,**几乎都没读 `promotion_type`**:
|
||||
|
||||
### 1. `headerServerClick`(金刚位 tabList、homeLeftList 用)
|
||||
- 文件:`pages/index/index.vue`(搜 `headerServerClick(e)`)
|
||||
- 只看 `link_url` 和 `appid`,**完全忽略 `promotion_type`**。
|
||||
- 逻辑:无 `link_url` → 弹“此功能暂未开通”;有 `appid` → 跳小程序;否则当本程序路径 `NavgateTo`。
|
||||
- **后果**:type=2(活动)、type=5(商品)的配置它不认 → 落到“没 link_url”分支 → 弹“暂未开通”。
|
||||
|
||||
### 2. `toAdvertisingView`(广告横幅 serverLeft、serverRight[0] 用)
|
||||
- 文件:`pages/index/index.vue:357` 附近
|
||||
- **写死**跳 `/packages/advertising/index/index?id=xxx`,不看 `promotion_type`,一律进广告落地页。
|
||||
|
||||
### 3. `goToPurify`(serverRight 非首个用,模板 `index.vue:101`)
|
||||
- 文件:`pages/index/index.vue:363` 附近
|
||||
- **彻底写死**:固定跳净水小程序 `appId=wx77b22c0a0018e580`,path/appId 全硬编码,传入的 `item` 没用到,与后台配置零关系。
|
||||
- 模板:`@tap="index === 0 ? toAdvertisingView(serverRightList) : goToPurify(item)"` —— serverRight 第一个跳广告页,其余全跳净水小程序。
|
||||
|
||||
### 4. `headerServerClick2`(中部 serverItem / homeRightList1,2 用)
|
||||
- 文件:`pages/index/index.vue`(搜 `headerServerClick2(e)`)
|
||||
- 不跳外链,只按 `title` 匹配商家分类做筛选,或固定跳本地生活页。**注意:这一处可能是“按分类筛选”的有意设计,不一定算 bug。**
|
||||
|
||||
### 5. 顶部轮播 Banner(位置 1,模板 `index.vue:68`)
|
||||
- 点击事件被**注释掉了**(`<!-- <swiper-item ... @click="headerServerClick(item)"> -->`),顶部 banner 现在点击无反应。
|
||||
|
||||
---
|
||||
|
||||
## 三、根因
|
||||
|
||||
后台用统一的 `promotion_type` 模型配跳转,前端却是早期“按位置分别写死”的处理函数拼起来的:既没统一读 `promotion_type`,部分位置还硬编码了目标(广告页、净水小程序)。所以出现“很多跳转和后台配置不符”——不是数据错,是前端没按配置解析。
|
||||
|
||||
---
|
||||
|
||||
## 四、建议修法(未实施,待决策)
|
||||
|
||||
做一个统一跳转函数 `handleAdJump(item)`,严格按 `promotion_type` 分发:
|
||||
|
||||
```
|
||||
switch promotion_type:
|
||||
1: 不跳
|
||||
2: NavgateTo('/packages/advertising/index/index?id=' + item.id) // 活动
|
||||
3: link_url 跳本程序页面(兼容 shopEnter 特例 / H5 / APP webview)
|
||||
4: navigateToMiniProgram(appid, link_url) // 其他小程序
|
||||
5: NavgateTo('/packages/advertising/index/index?id=' + item.id) // 商品(同活动,落地页内展示)
|
||||
其他: 弹“暂未开通”
|
||||
```
|
||||
|
||||
然后把首页所有广告位的 `@click`/`@tap` 都换成 `handleAdJump(item)`:
|
||||
- 顶部轮播 banner:取消注释,改 `handleAdJump`
|
||||
- 金刚位 tabList、homeLeftList:`headerServerClick` → `handleAdJump`
|
||||
- serverLeft、serverRight:`toAdvertisingView` / `goToPurify` → `handleAdJump`
|
||||
|
||||
### 实施前需确认的点
|
||||
1. `headerServerClick2`(中部 serverItem 按 title 筛分类)是否要保留分类筛选语义?还是也改成按 `promotion_type` 跳?
|
||||
2. 净水小程序跳转:是想**保留写死**,还是改由后台某条 banner 配 `type=4 + 该 appid` 来控制(更灵活,去掉硬编码)?
|
||||
3. type=2/5 是否都统一进广告落地页 `/packages/advertising/index/index?id=banner.id`(当前分析结论是“是”)。
|
||||
|
||||
> 相关:`promotion_type` 字段定义见 `huichang-server/internal/model/entity/home_banner_region.go`、`home_button_region.go`;广告落地页 `uniapp-ZHSQ/packages/advertising/index/index.vue`。
|
||||
839
package-lock.json
generated
839
package-lock.json
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "支付键盘、数字键盘、付款键盘、密码键盘",
|
||||
"version": "1.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
@ -1168,5 +1168,842 @@
|
||||
"node": ">=0.4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
|
||||
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.28.4"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
|
||||
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1"
|
||||
}
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
|
||||
},
|
||||
"@vue/compiler-core": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.21.tgz",
|
||||
"integrity": "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==",
|
||||
"requires": {
|
||||
"@babel/parser": "^7.28.3",
|
||||
"@vue/shared": "3.5.21",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-dom": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.21.tgz",
|
||||
"integrity": "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==",
|
||||
"requires": {
|
||||
"@vue/compiler-core": "3.5.21",
|
||||
"@vue/shared": "3.5.21"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-sfc": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.21.tgz",
|
||||
"integrity": "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==",
|
||||
"requires": {
|
||||
"@babel/parser": "^7.28.3",
|
||||
"@vue/compiler-core": "3.5.21",
|
||||
"@vue/compiler-dom": "3.5.21",
|
||||
"@vue/compiler-ssr": "3.5.21",
|
||||
"@vue/shared": "3.5.21",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.18",
|
||||
"postcss": "^8.5.6",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-ssr": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.21.tgz",
|
||||
"integrity": "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==",
|
||||
"requires": {
|
||||
"@vue/compiler-dom": "3.5.21",
|
||||
"@vue/shared": "3.5.21"
|
||||
}
|
||||
},
|
||||
"@vue/reactivity": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.21.tgz",
|
||||
"integrity": "sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA==",
|
||||
"requires": {
|
||||
"@vue/shared": "3.5.21"
|
||||
}
|
||||
},
|
||||
"@vue/runtime-core": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.21.tgz",
|
||||
"integrity": "sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA==",
|
||||
"requires": {
|
||||
"@vue/reactivity": "3.5.21",
|
||||
"@vue/shared": "3.5.21"
|
||||
}
|
||||
},
|
||||
"@vue/runtime-dom": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.21.tgz",
|
||||
"integrity": "sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w==",
|
||||
"requires": {
|
||||
"@vue/reactivity": "3.5.21",
|
||||
"@vue/runtime-core": "3.5.21",
|
||||
"@vue/shared": "3.5.21",
|
||||
"csstype": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"@vue/server-renderer": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.21.tgz",
|
||||
"integrity": "sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA==",
|
||||
"requires": {
|
||||
"@vue/compiler-ssr": "3.5.21",
|
||||
"@vue/shared": "3.5.21"
|
||||
}
|
||||
},
|
||||
"@vue/shared": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.21.tgz",
|
||||
"integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw=="
|
||||
},
|
||||
"abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"requires": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"requires": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"callback-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz",
|
||||
"integrity": "sha512-sAZ9kODla+mGACBZ1IpTCAisKoGnv6PykW7fPk1LrM+mMepE18Yz0515yoVcrZy7dQsTUp3uZLQ/9Sx1RnLoHw==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "> 1.0.0 < 3.0.0"
|
||||
}
|
||||
},
|
||||
"commist": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz",
|
||||
"integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==",
|
||||
"requires": {
|
||||
"leven": "^2.1.0",
|
||||
"minimist": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"d": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
|
||||
"integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
|
||||
"requires": {
|
||||
"es5-ext": "^0.10.64",
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"requires": {
|
||||
"ms": "^2.1.3"
|
||||
}
|
||||
},
|
||||
"duplexify": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
|
||||
"integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
|
||||
"requires": {
|
||||
"end-of-stream": "^1.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^2.0.0",
|
||||
"stream-shift": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
||||
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.64",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
|
||||
"integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
|
||||
"requires": {
|
||||
"es6-iterator": "^2.0.3",
|
||||
"es6-symbol": "^3.1.3",
|
||||
"esniff": "^2.0.1",
|
||||
"next-tick": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"es6-iterator": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
||||
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "^0.10.35",
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"es6-map": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
|
||||
"integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "~0.10.14",
|
||||
"es6-iterator": "~2.0.1",
|
||||
"es6-set": "~0.1.5",
|
||||
"es6-symbol": "~3.1.1",
|
||||
"event-emitter": "~0.3.5"
|
||||
}
|
||||
},
|
||||
"es6-set": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz",
|
||||
"integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
|
||||
"requires": {
|
||||
"d": "^1.0.1",
|
||||
"es5-ext": "^0.10.62",
|
||||
"es6-iterator": "~2.0.3",
|
||||
"es6-symbol": "^3.1.3",
|
||||
"event-emitter": "^0.3.5",
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"es6-symbol": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
|
||||
"integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
|
||||
"requires": {
|
||||
"d": "^1.0.2",
|
||||
"ext": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"esniff": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
|
||||
"integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
|
||||
"requires": {
|
||||
"d": "^1.0.1",
|
||||
"es5-ext": "^0.10.62",
|
||||
"event-emitter": "^0.3.5",
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"event-emitter": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||
"integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "~0.10.14"
|
||||
}
|
||||
},
|
||||
"event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
|
||||
"integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
|
||||
"requires": {
|
||||
"type": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
||||
"integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
|
||||
"requires": {
|
||||
"is-glob": "^3.1.0",
|
||||
"path-dirname": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob-stream": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
|
||||
"integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==",
|
||||
"requires": {
|
||||
"extend": "^3.0.0",
|
||||
"glob": "^7.1.1",
|
||||
"glob-parent": "^3.1.0",
|
||||
"is-negated-glob": "^1.0.0",
|
||||
"ordered-read-streams": "^1.0.0",
|
||||
"pumpify": "^1.3.5",
|
||||
"readable-stream": "^2.1.5",
|
||||
"remove-trailing-separator": "^1.0.1",
|
||||
"to-absolute-glob": "^2.0.0",
|
||||
"unique-stream": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"help-me": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz",
|
||||
"integrity": "sha512-P/IZ8yOMne3SCTHbVY429NZ67B/2bVQlcYGZh2iPPbdLrEQ/qY5aGChn0YTDmt7Sb4IKRI51fypItav+lNl76w==",
|
||||
"requires": {
|
||||
"callback-stream": "^1.0.2",
|
||||
"glob-stream": "^6.1.0",
|
||||
"through2": "^2.0.1",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"is-absolute": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
|
||||
"integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
|
||||
"requires": {
|
||||
"is-relative": "^1.0.0",
|
||||
"is-windows": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
|
||||
"integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"is-negated-glob": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
|
||||
"integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug=="
|
||||
},
|
||||
"is-relative": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
|
||||
"integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
|
||||
"requires": {
|
||||
"is-unc-path": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-unc-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
|
||||
"integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
|
||||
"requires": {
|
||||
"unc-path-regex": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
||||
},
|
||||
"json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
|
||||
},
|
||||
"leven": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
|
||||
"integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA=="
|
||||
},
|
||||
"magic-string": {
|
||||
"version": "0.30.19",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
|
||||
"integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
|
||||
"requires": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
|
||||
},
|
||||
"mqtt": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-3.0.0.tgz",
|
||||
"integrity": "sha512-0nKV6MAc1ibKZwaZQUTb3iIdT4NVpj541BsYrqrGBcQdQ7Jd0MnZD1/6/nj1UFdGTboK9ZEUXvkCu2nPCugHFA==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.0",
|
||||
"commist": "^1.0.0",
|
||||
"concat-stream": "^1.6.2",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"es6-map": "^0.1.5",
|
||||
"help-me": "^1.0.1",
|
||||
"inherits": "^2.0.3",
|
||||
"minimist": "^1.2.0",
|
||||
"mqtt-packet": "^6.0.0",
|
||||
"pump": "^3.0.0",
|
||||
"readable-stream": "^2.3.6",
|
||||
"reinterval": "^1.1.0",
|
||||
"split2": "^3.1.0",
|
||||
"websocket-stream": "^5.1.2",
|
||||
"xtend": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"mqtt-packet": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz",
|
||||
"integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==",
|
||||
"requires": {
|
||||
"bl": "^4.0.2",
|
||||
"debug": "^4.1.1",
|
||||
"process-nextick-args": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="
|
||||
},
|
||||
"next-tick": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
|
||||
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"ordered-read-streams": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
|
||||
"integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==",
|
||||
"requires": {
|
||||
"readable-stream": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
|
||||
"integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q=="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
|
||||
},
|
||||
"picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
||||
"requires": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
|
||||
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"pumpify": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
|
||||
"integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
|
||||
"requires": {
|
||||
"duplexify": "^3.6.0",
|
||||
"inherits": "^2.0.3",
|
||||
"pump": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pump": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
|
||||
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"reinterval": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
|
||||
"integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ=="
|
||||
},
|
||||
"remove-trailing-separator": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
|
||||
},
|
||||
"split2": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
|
||||
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
|
||||
"requires": {
|
||||
"readable-stream": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"stream-shift": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
|
||||
"integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"through2": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||
"requires": {
|
||||
"readable-stream": "~2.3.6",
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
},
|
||||
"through2-filter": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
|
||||
"integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
|
||||
"requires": {
|
||||
"through2": "~2.0.0",
|
||||
"xtend": "~4.0.0"
|
||||
}
|
||||
},
|
||||
"to-absolute-glob": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
|
||||
"integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==",
|
||||
"requires": {
|
||||
"is-absolute": "^1.0.0",
|
||||
"is-negated-glob": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
|
||||
"integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||
},
|
||||
"unc-path-regex": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
|
||||
"integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="
|
||||
},
|
||||
"unique-stream": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
|
||||
"integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
|
||||
"requires": {
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"through2-filter": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"vue": {
|
||||
"version": "3.5.21",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.21.tgz",
|
||||
"integrity": "sha512-xxf9rum9KtOdwdRkiApWL+9hZEMWE90FHh8yS1+KJAiWYh+iGWV1FquPjoO9VUHQ+VIhsCXNNyZ5Sf4++RVZBA==",
|
||||
"requires": {
|
||||
"@vue/compiler-dom": "3.5.21",
|
||||
"@vue/compiler-sfc": "3.5.21",
|
||||
"@vue/runtime-dom": "3.5.21",
|
||||
"@vue/server-renderer": "3.5.21",
|
||||
"@vue/shared": "3.5.21"
|
||||
}
|
||||
},
|
||||
"websocket-stream": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.5.2.tgz",
|
||||
"integrity": "sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ==",
|
||||
"requires": {
|
||||
"duplexify": "^3.5.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^2.3.3",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"ws": "^3.2.0",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"ws": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0",
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,8 +582,10 @@ export default {
|
||||
|
||||
// 使用完整的商品数据对象,而不是itemObj
|
||||
this.currentGG = this.info.commodity_goods_info_list[this.currentGGIndex];
|
||||
// 将promotional_price赋值给sales_price
|
||||
this.currentGG.sales_price = this.promotional_price;
|
||||
// 将promotional_price赋值给sales_price(无活动价时保留商品自身价格,如客服分享场景)
|
||||
if (this.promotional_price !== "" && this.promotional_price != null) {
|
||||
this.currentGG.sales_price = this.promotional_price;
|
||||
}
|
||||
|
||||
// 设置相关属性
|
||||
this.changeImg = this.currentGG.commodity_pic[0];
|
||||
@ -616,8 +618,10 @@ export default {
|
||||
// 切换规格
|
||||
changeGG(item, index) {
|
||||
this.currentGG = item;
|
||||
// 将promotional_price赋值给sales_price
|
||||
this.currentGG.sales_price = this.promotional_price;
|
||||
// 将promotional_price赋值给sales_price(无活动价时保留商品自身价格)
|
||||
if (this.promotional_price !== "" && this.promotional_price != null) {
|
||||
this.currentGG.sales_price = this.promotional_price;
|
||||
}
|
||||
this.currentGGIndex = index;
|
||||
if (this.currentGG.cart_count) {
|
||||
this.currentNum = this.currentGG.cart_count.count;
|
||||
@ -778,7 +782,15 @@ export default {
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.itemObj = JSON.parse(decodeURIComponent(options.item));
|
||||
// 来自客服聊天卡片:优先从本地存储读完整数据(避免 URL 过长)
|
||||
if (options && options.fromChat) {
|
||||
let stashed
|
||||
try { stashed = uni.getStorageSync('chatCardItem') } catch (e) { stashed = null }
|
||||
uni.removeStorageSync('chatCardItem')
|
||||
this.itemObj = stashed || JSON.parse(decodeURIComponent(options.item))
|
||||
} else {
|
||||
this.itemObj = JSON.parse(decodeURIComponent(options.item));
|
||||
}
|
||||
const meun = menuButtonInfo();
|
||||
this.top = meun.top;
|
||||
this.localHeight = meun.height;
|
||||
|
||||
@ -33,9 +33,44 @@
|
||||
}" class="message-item">
|
||||
<image :src="message.isSelf ? userAvatar : getAvatarUrl(message)" class="message-avatar" mode="aspectFill">
|
||||
</image>
|
||||
<view class="message-content">
|
||||
<!-- 文字 -->
|
||||
<view v-if="!message.type || message.type === 1" class="message-content">
|
||||
{{ message.content }}
|
||||
</view>
|
||||
<!-- 图片 -->
|
||||
<view v-else-if="message.type === 2" class="message-media">
|
||||
<image v-if="message.mediaUrl" :src="message.mediaUrl" class="chat-img" mode="aspectFit"
|
||||
@tap="previewImage(message.mediaUrl)" />
|
||||
<view v-else class="media-loading">图片加载中…</view>
|
||||
</view>
|
||||
<!-- 视频 -->
|
||||
<view v-else-if="message.type === 3" class="message-media">
|
||||
<video v-if="message.mediaUrl" :src="message.mediaUrl" class="chat-video" controls></video>
|
||||
<view v-else class="media-loading">视频加载中…</view>
|
||||
</view>
|
||||
<!-- 商品/购物车卡片 -->
|
||||
<view v-else-if="message.type === 4" class="message-card" @tap="openCardLink(message.card)">
|
||||
<image v-if="message.card.pic && !message.card._picErr" :src="message.card.pic" class="card-pic"
|
||||
mode="aspectFill" @error="onCardPicError(message)" />
|
||||
<view v-else class="card-pic card-pic--ph">商品</view>
|
||||
<view class="card-info">
|
||||
<view class="card-name">{{ message.card.name }}</view>
|
||||
<view class="card-price">¥{{ message.card.price }}</view>
|
||||
<view class="card-tag">商品</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 订单卡片 -->
|
||||
<view v-else-if="message.type === 5" class="message-card" @tap="openCardLink(message.card)">
|
||||
<image v-if="message.card.pic && !message.card._picErr" :src="message.card.pic" class="card-pic"
|
||||
mode="aspectFill" @error="onCardPicError(message)" />
|
||||
<view v-else class="card-pic card-pic--ph">订单</view>
|
||||
<view class="card-info">
|
||||
<view class="card-name">订单 {{ message.card.order_no }}</view>
|
||||
<view class="card-price">¥{{ message.card.amount }}</view>
|
||||
<view class="card-tag">订单 · 共{{ message.card.count }}件</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="message-content">{{ message.content }}</view>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
@ -46,18 +81,45 @@
|
||||
<textarea v-model="inputMessage" :adjust-position="true" auto-height class="message-input" cursor-spacing="10"
|
||||
enable-keyboard-accessory-view="true" hold-keyboard="true" maxlength="500" placeholder="请输入消息..."
|
||||
@blur="onInputBlur" @confirm="sendMessage" @focus="onInputFocus" @input="handleInput"></textarea>
|
||||
<view class="plus-btn" @tap="togglePanel">
|
||||
<uni-icons color="#666" size="30" type="plusempty"></uni-icons>
|
||||
</view>
|
||||
<button :disabled="inputMessage.trim() === ''" class="send-btn" @tap="sendMessage">
|
||||
发送
|
||||
</button>
|
||||
</view>
|
||||
<!-- 更多功能面板 -->
|
||||
<view v-if="showPanel" class="more-panel">
|
||||
<view class="panel-item" @tap="chooseMedia('image')">
|
||||
<view class="panel-icon">🖼️</view>
|
||||
<text>相册图片</text>
|
||||
</view>
|
||||
<view class="panel-item" @tap="chooseMedia('camera')">
|
||||
<view class="panel-icon">📷</view>
|
||||
<text>拍摄</text>
|
||||
</view>
|
||||
<view class="panel-item" @tap="chooseMedia('video')">
|
||||
<view class="panel-icon">🎬</view>
|
||||
<text>视频</text>
|
||||
</view>
|
||||
<view class="panel-item" @tap="openGoodsPicker">
|
||||
<view class="panel-icon">🛒</view>
|
||||
<text>商品/购物车</text>
|
||||
</view>
|
||||
<view class="panel-item" @tap="openOrderPicker">
|
||||
<view class="panel-icon">📦</view>
|
||||
<text>订单</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { menuButtonInfo, picUrl, request } from '@/utils'
|
||||
import { menuButtonInfo, picUrl, request, NavgateTo } from '@/utils'
|
||||
import mqttTool from '@/utils/mqtt'
|
||||
import { apiArr } from '../../../api/customerService'
|
||||
import { uploadOSS, signPrivateView } from '@/utils/uploadOSS'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -79,6 +141,8 @@ export default {
|
||||
|
||||
// 输入的消息
|
||||
inputMessage: '',
|
||||
// 更多功能面板
|
||||
showPanel: false,
|
||||
// 是否可以发送消息
|
||||
canSend: false,
|
||||
// 连接状态
|
||||
@ -150,6 +214,13 @@ export default {
|
||||
console.log('用户头像:', this.userAvatar)
|
||||
},
|
||||
onShow() {
|
||||
// 监听 picker 页回传的商品/订单卡片(只注册一次)
|
||||
if (!this._onPickCard) {
|
||||
this._onPickCard = ({ type, card }) => {
|
||||
this.publishMsg(type, JSON.stringify(card))
|
||||
}
|
||||
uni.$on('chat:pickCard', this._onPickCard)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl(record) {
|
||||
@ -193,26 +264,46 @@ export default {
|
||||
let jsMsg = msg // 直接使用已解析的对象,无需再次解析
|
||||
console.log('收到消息', topic, msg)
|
||||
if (jsMsg.send_client === this.selfClientId || jsMsg.receive_client === this.selfClientId) {
|
||||
console.log('接收或发送人是我')
|
||||
if (jsMsg.send_client === this.chatTarget.openId || jsMsg.receive_client === this.chatTarget.openId) {
|
||||
console.log('接收或发送人是我的聊天对象')
|
||||
this.messages.push({
|
||||
content: jsMsg.content,
|
||||
time: Date.now(),
|
||||
isSelf: jsMsg.send_client === this.selfClientId,
|
||||
isLoading: false
|
||||
})
|
||||
console.log('收到我的消息', this.messages)
|
||||
this.scrollToView = 'msg-' + (this.messages.length - 1)
|
||||
this.appendMessage(jsMsg, jsMsg.send_client === this.selfClientId)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 把一条原始消息(含 type/content)转成可渲染的消息对象并追加;图片/视频异步签名 URL
|
||||
async appendMessage(raw, isSelf) {
|
||||
const type = Number(raw.type) || 1
|
||||
const item = {
|
||||
type,
|
||||
content: raw.content,
|
||||
time: Date.now(),
|
||||
isSelf,
|
||||
isLoading: false,
|
||||
mediaUrl: '',
|
||||
card: null
|
||||
}
|
||||
if (type === 4 || type === 5) {
|
||||
try { item.card = typeof raw.content === 'string' ? JSON.parse(raw.content) : raw.content } catch (e) { item.card = {} }
|
||||
}
|
||||
const idx = this.messages.push(item) - 1
|
||||
this.scrollToView = 'msg-' + idx
|
||||
// 图片/视频:content 是私密 object_key,需签名后显示
|
||||
if (type === 2 || type === 3) {
|
||||
try {
|
||||
const r = await signPrivateView(raw.content)
|
||||
this.$set(this.messages[idx], 'mediaUrl', r.url)
|
||||
} catch (e) {
|
||||
console.error('签发聊天媒体URL失败', e)
|
||||
}
|
||||
}
|
||||
},
|
||||
async subscribe() {
|
||||
if (this.isConnected && this.client) {
|
||||
this.client.subscribe('contact/message/receive_msg', { qos: 0 }, (err) => {
|
||||
const topic = 'contact/message/send_msg/' + this.chatTarget.bindId // 按会话精确订阅,天然隔离(沿用 contact/message 授权前缀)
|
||||
this.client.subscribe(topic, { qos: 0 }, (err) => {
|
||||
if (!err) {
|
||||
console.log('订阅成功', 'contact/message/receive_msg', { qos: 0 })
|
||||
console.log('订阅成功', topic, { qos: 0 })
|
||||
this.connectingStatus = ''
|
||||
} else {
|
||||
console.log('订阅失败:', err)
|
||||
@ -348,13 +439,32 @@ export default {
|
||||
}
|
||||
|
||||
// 处理历史消息,转换为需要的格式
|
||||
const formattedMessages = historyMessages.map(msg => ({
|
||||
content: msg.content,
|
||||
time: new Date(msg.create_time).getTime(),
|
||||
times: msg.update_time,
|
||||
isSelf: msg.send_client === this.selfClientId, // 修正判断条件
|
||||
isLoading: false
|
||||
})).reverse(); // 反转消息顺序,确保最早的消息在最前面
|
||||
const formattedMessages = historyMessages.map(msg => {
|
||||
const type = Number(msg.type) || 1
|
||||
const item = {
|
||||
type,
|
||||
content: msg.content,
|
||||
time: new Date(msg.create_time).getTime(),
|
||||
times: msg.update_time,
|
||||
isSelf: msg.send_client === this.selfClientId,
|
||||
isLoading: false,
|
||||
mediaUrl: '',
|
||||
card: null
|
||||
}
|
||||
if (type === 4 || type === 5) {
|
||||
try { item.card = typeof msg.content === 'string' ? JSON.parse(msg.content) : msg.content } catch (e) { item.card = {} }
|
||||
}
|
||||
return item
|
||||
}).reverse(); // 反转消息顺序,确保最早的消息在最前面
|
||||
|
||||
// 图片/视频历史消息:异步签发私密 URL
|
||||
formattedMessages.forEach(item => {
|
||||
if (item.type === 2 || item.type === 3) {
|
||||
signPrivateView(item.content).then(r => {
|
||||
this.$set(item, 'mediaUrl', r.url)
|
||||
}).catch(e => console.error('历史媒体签名失败', e))
|
||||
}
|
||||
})
|
||||
|
||||
console.log('格式化后的历史消息:', formattedMessages)
|
||||
// 将格式化后的历史消息添加到消息列表开头
|
||||
@ -441,7 +551,7 @@ export default {
|
||||
}
|
||||
console.log('发送消息', msgData)
|
||||
this.client.publish(
|
||||
'contact/message/send_msg', // 使用指定的发送消息主题
|
||||
'contact/message/send_msg/' + this.chatTarget.bindId, // 按会话精确主题,双方订阅同一主题
|
||||
JSON.stringify(msgData),
|
||||
{ Qos: 0 },
|
||||
(err) => {
|
||||
@ -458,6 +568,107 @@ export default {
|
||||
this.inputMessage = ''
|
||||
},
|
||||
|
||||
// 切换"+"功能面板
|
||||
togglePanel() {
|
||||
this.showPanel = !this.showPanel
|
||||
},
|
||||
|
||||
// 统一发布消息(type: 1文字 2图片 3视频 4商品 5订单;content 为文本/object_key/JSON字符串)
|
||||
publishMsg(type, content) {
|
||||
if (!this.client || !this.isConnected) {
|
||||
uni.showToast({ title: '连接断开,请重试', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const msgData = {
|
||||
bind_id: this.chatTarget.bindId,
|
||||
send_client: this.selfClientId,
|
||||
receive_client: this.chatTarget.openId,
|
||||
type,
|
||||
content,
|
||||
receive_read_status: 2
|
||||
}
|
||||
this.client.publish('contact/message/send_msg/' + this.chatTarget.bindId, JSON.stringify(msgData), { Qos: 0 }, (err) => {
|
||||
if (err) console.error('发送消息失败', err)
|
||||
})
|
||||
},
|
||||
|
||||
// 选择图片/拍摄/视频并上传(私密,按会话授权)
|
||||
chooseMedia(source) {
|
||||
this.showPanel = false
|
||||
if (source === 'video') {
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album', 'camera'],
|
||||
maxDuration: 60,
|
||||
success: (res) => this.uploadAndSend(res.tempFilePath, 'chat_video', 3)
|
||||
})
|
||||
} else {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: source === 'camera' ? ['camera'] : ['album'],
|
||||
success: (res) => {
|
||||
const fp = res.tempFilePaths && res.tempFilePaths[0]
|
||||
if (fp) this.uploadAndSend(fp, 'chat_image', 2)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 上传到私密 bucket 后,把 object_key 作为消息内容发布
|
||||
async uploadAndSend(filePath, scene, type) {
|
||||
try {
|
||||
const { objectKey } = await uploadOSS({ filePath, scene, bindId: this.chatTarget.bindId })
|
||||
this.publishMsg(type, objectKey)
|
||||
} catch (e) {
|
||||
console.error('上传失败', e)
|
||||
uni.showToast({ title: '上传失败,请重试', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(url) {
|
||||
if (url) uni.previewImage({ urls: [url], current: url })
|
||||
},
|
||||
|
||||
// 点击商品/订单卡片跳转
|
||||
openCardLink(card) {
|
||||
if (!card) return
|
||||
// 兼容老消息:仍带 path 的直接跳
|
||||
if (!card.page && card.path) {
|
||||
NavgateTo(card.path, { isLogin: false })
|
||||
return
|
||||
}
|
||||
if (!card.page) return
|
||||
// 完整 item 经本地存储中转,避免 URL 过长被截断(详情页优先读 storage)
|
||||
const item = card.item || {}
|
||||
try {
|
||||
uni.setStorageSync('chatCardItem', item)
|
||||
} catch (e) {
|
||||
console.error('暂存卡片数据失败', e)
|
||||
}
|
||||
NavgateTo(card.page + '?item=' + encodeURIComponent(JSON.stringify(item)) + '&fromChat=1', { isLogin: false })
|
||||
},
|
||||
|
||||
// 卡片图片加载失败 -> 显示占位(用 $set 保证响应式)
|
||||
onCardPicError(message) {
|
||||
if (message && message.card) {
|
||||
this.$set(message.card, '_picErr', true)
|
||||
}
|
||||
},
|
||||
|
||||
// 选择商品/购物车发送
|
||||
openGoodsPicker() {
|
||||
this.showPanel = false
|
||||
// 跳转到选择页(复用购物车/商品列表),选完回传后 publishMsg(4, JSON)
|
||||
NavgateTo('/packages/customerService/picker/index?type=goods&bindId=' + this.chatTarget.bindId, { isLogin: false })
|
||||
},
|
||||
|
||||
// 选择订单发送
|
||||
openOrderPicker() {
|
||||
this.showPanel = false
|
||||
NavgateTo('/packages/customerService/picker/index?type=order&bindId=' + this.chatTarget.bindId, { isLogin: false })
|
||||
},
|
||||
|
||||
// 处理输入事件
|
||||
handleInput() {
|
||||
this.canSend = this.inputMessage.trim().length > 0
|
||||
@ -580,6 +791,12 @@ export default {
|
||||
clearTimeout(this.reconnectFailedTimer)
|
||||
this.reconnectFailedTimer = null
|
||||
}
|
||||
|
||||
// 移除卡片选择监听
|
||||
if (this._onPickCard) {
|
||||
uni.$off('chat:pickCard', this._onPickCard)
|
||||
this._onPickCard = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -592,4 +809,115 @@ export default {
|
||||
--header-height: 80px; /* 头部高度 */
|
||||
--input-height: 80px; /* 输入区域高度 */
|
||||
}
|
||||
|
||||
/* 图片/视频消息 */
|
||||
.message-media {
|
||||
max-width: 60%;
|
||||
}
|
||||
.chat-img {
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.chat-video {
|
||||
width: 400rpx;
|
||||
height: 300rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.media-loading {
|
||||
padding: 30rpx 40rpx;
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* 商品/订单卡片 */
|
||||
.message-card {
|
||||
display: flex;
|
||||
width: 520rpx;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
.card-pic {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
flex-shrink: 0;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.card-pic--ph {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #bbb;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.card-info {
|
||||
flex: 1;
|
||||
padding: 18rpx 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-width: 0;
|
||||
}
|
||||
.card-name {
|
||||
font-size: 28rpx;
|
||||
color: #222;
|
||||
line-height: 38rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-price {
|
||||
font-size: 32rpx;
|
||||
color: #FF370B;
|
||||
font-weight: 600;
|
||||
}
|
||||
.card-tag {
|
||||
align-self: flex-start;
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
border: 1rpx solid #eee;
|
||||
border-radius: 6rpx;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
/* "+" 按钮与更多面板 */
|
||||
.plus-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
.more-panel {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 24rpx 12rpx;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
.panel-item {
|
||||
width: 20%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
.panel-icon {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 44rpx;
|
||||
}
|
||||
</style>
|
||||
165
packages/customerService/picker/index.vue
Normal file
165
packages/customerService/picker/index.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<view class="picker-page">
|
||||
<!-- 订单:普通/团购 两个 tab -->
|
||||
<view v-if="mode === 'order'" class="tabs">
|
||||
<view class="tab" :class="{ active: orderTab === 'normal' }" @tap="switchTab('normal')">普通订单</view>
|
||||
<view class="tab" :class="{ active: orderTab === 'group' }" @tap="switchTab('group')">团购订单</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="list" scroll-y>
|
||||
<!-- 订单列表 -->
|
||||
<block v-if="mode === 'order'">
|
||||
<view v-for="(item, idx) in orderList" :key="idx" class="order-card" @tap="pickOrder(item)">
|
||||
<view class="order-head">
|
||||
<text class="order-no">订单号:{{ item.order_no }}</text>
|
||||
</view>
|
||||
<view class="order-goods">
|
||||
<image v-for="(g, gi) in (item.commodity_order_item_list || []).slice(0, 4)" :key="gi"
|
||||
:src="g.commodity_pic" class="goods-thumb" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="order-foot">
|
||||
<text>共{{ item.total_count }}件</text>
|
||||
<text class="amount">¥{{ item.total_amount }}</text>
|
||||
<view class="send-btn">发送</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="orderList.length === 0" class="empty">暂无订单</view>
|
||||
</block>
|
||||
|
||||
<!-- 购物车列表 -->
|
||||
<block v-else>
|
||||
<view v-for="(g, idx) in cartGoods" :key="idx" class="goods-row" @tap="pickGoods(g)">
|
||||
<image :src="g.pic" class="goods-thumb-lg" mode="aspectFill" />
|
||||
<view class="goods-info">
|
||||
<view class="goods-name">{{ g.name }}</view>
|
||||
<view class="goods-price">¥{{ g.price }}</view>
|
||||
</view>
|
||||
<view class="send-btn">发送</view>
|
||||
</view>
|
||||
<view v-if="cartGoods.length === 0" class="empty">购物车为空</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, picUrl } from '@/utils'
|
||||
import { apiArr as shopApi } from '@/api/shop'
|
||||
import { apiArr as afterSaleApi } from '@/api/afterSale'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mode: 'order', // order | goods
|
||||
bindId: 0,
|
||||
orderTab: 'normal', // normal | group
|
||||
orderList: [],
|
||||
cartGoods: []
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.mode = options.type === 'goods' ? 'goods' : 'order'
|
||||
this.bindId = Number(options.bindId) || 0
|
||||
uni.setNavigationBarTitle({ title: this.mode === 'goods' ? '选择购物车商品' : '选择订单' })
|
||||
if (this.mode === 'goods') {
|
||||
this.loadCart()
|
||||
} else {
|
||||
this.loadOrders()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
switchTab(t) {
|
||||
this.orderTab = t
|
||||
this.loadOrders()
|
||||
},
|
||||
// 订单列表:order_cate 1普通 2团购(按 tab 过滤)
|
||||
loadOrders() {
|
||||
request(afterSaleApi.orderList, 'POST', {
|
||||
user_id: uni.getStorageSync('userId')
|
||||
}).then(res => {
|
||||
const list = res.order_list || []
|
||||
list.forEach(item => {
|
||||
(item.commodity_order_item_list || []).forEach(g => {
|
||||
g.commodity_pic = (g.commodity_pic && g.commodity_pic.startsWith('http')) ? g.commodity_pic : picUrl + g.commodity_pic
|
||||
})
|
||||
})
|
||||
if (this.orderTab === 'group') {
|
||||
this.orderList = list.filter(i => i.order_cate == 2)
|
||||
} else {
|
||||
this.orderList = list.filter(i => i.order_cate == 1 || i.order_cate == 4)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 购物车(非团购)
|
||||
loadCart() {
|
||||
request(shopApi.getCar, 'POST', { is_group_buy: '' }).then(res => {
|
||||
const groups = [].concat(res.same_day_cart_list || [], res.normal_cart_list || [])
|
||||
const goods = []
|
||||
groups.forEach(sup => {
|
||||
(sup.commodity_cart_and_goods_model || []).forEach(c => {
|
||||
const gi = c.commodity_goods_info || {}
|
||||
goods.push({
|
||||
goods_id: c.goods_id,
|
||||
commodity_id: c.commodity_id,
|
||||
name: gi.commodity_name || gi.goods_name || '商品',
|
||||
pic: (gi.commodity_pic && gi.commodity_pic.startsWith('http')) ? gi.commodity_pic : picUrl + (gi.commodity_pic || ''),
|
||||
price: gi.sales_price || c.price || 0
|
||||
})
|
||||
})
|
||||
})
|
||||
this.cartGoods = goods
|
||||
})
|
||||
},
|
||||
// 选中订单 -> 回传订单卡片(type=5)
|
||||
pickOrder(item) {
|
||||
const firstPic = (item.commodity_order_item_list && item.commodity_order_item_list[0] && item.commodity_order_item_list[0].commodity_pic) || ''
|
||||
const card = {
|
||||
order_id: item.id,
|
||||
order_no: item.order_no,
|
||||
amount: item.total_amount,
|
||||
count: item.total_count,
|
||||
pic: firstPic,
|
||||
page: '/packages/myOrders/orderDetails/index', // 点击跳转目标页(完整 item 经 storage 中转,避免 URL 超长)
|
||||
item // 完整订单对象,详情页直接用
|
||||
}
|
||||
uni.$emit('chat:pickCard', { type: 5, card })
|
||||
uni.navigateBack()
|
||||
},
|
||||
// 选中购物车商品 -> 回传商品卡片(type=4)
|
||||
pickGoods(g) {
|
||||
const card = {
|
||||
goods_id: g.goods_id,
|
||||
commodity_id: g.commodity_id,
|
||||
name: g.name,
|
||||
price: g.price,
|
||||
pic: g.pic,
|
||||
page: '/packages/advertising/goodsDetail/index',
|
||||
item: { commodity_id: g.commodity_id, id: g.goods_id, promotional_price: g.price } // goodsDetail 需 commodity_id 查详情、id 定位规格、promotional_price 作展示价
|
||||
}
|
||||
uni.$emit('chat:pickCard', { type: 4, card })
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.picker-page { display: flex; flex-direction: column; height: 100vh; background: #f5f5f5; }
|
||||
.tabs { display: flex; background: #fff; }
|
||||
.tab { flex: 1; text-align: center; padding: 28rpx 0; font-size: 28rpx; color: #666; }
|
||||
.tab.active { color: #FF370B; font-weight: 600; border-bottom: 4rpx solid #FF370B; }
|
||||
.list { flex: 1; padding: 20rpx; box-sizing: border-box; }
|
||||
.order-card { background: #fff; border-radius: 12rpx; padding: 20rpx; margin-bottom: 20rpx; }
|
||||
.order-head { font-size: 24rpx; color: #999; margin-bottom: 14rpx; }
|
||||
.order-goods { display: flex; gap: 12rpx; }
|
||||
.goods-thumb { width: 120rpx; height: 120rpx; border-radius: 8rpx; background: #f0f0f0; }
|
||||
.order-foot { display: flex; align-items: center; justify-content: flex-end; gap: 20rpx; margin-top: 16rpx; }
|
||||
.order-foot .amount { color: #FF370B; font-weight: 600; }
|
||||
.goods-row { display: flex; align-items: center; background: #fff; border-radius: 12rpx; padding: 16rpx; margin-bottom: 16rpx; }
|
||||
.goods-thumb-lg { width: 140rpx; height: 140rpx; border-radius: 8rpx; background: #f0f0f0; flex-shrink: 0; }
|
||||
.goods-info { flex: 1; margin-left: 20rpx; min-width: 0; }
|
||||
.goods-name { font-size: 28rpx; color: #222; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
||||
.goods-price { font-size: 30rpx; color: #FF370B; font-weight: 600; margin-top: 12rpx; }
|
||||
.send-btn { background: linear-gradient(91deg, #FF7658, #FF370B); color: #fff; font-size: 24rpx; padding: 10rpx 28rpx; border-radius: 30rpx; flex-shrink: 0; }
|
||||
.empty { text-align: center; color: #999; font-size: 26rpx; padding: 80rpx 0; }
|
||||
</style>
|
||||
@ -425,4 +425,84 @@ page {
|
||||
|
||||
.coupon_item_button::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* ============ 店铺活动商品 ============ */
|
||||
.shop-activity {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.shop-activity-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
padding-left: 16rpx;
|
||||
border-left: 6rpx solid #FF370B;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.shop-activity-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.sa-goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border: 1rpx solid #f2f2f2;
|
||||
border-radius: 12rpx;
|
||||
padding: 16rpx;
|
||||
}
|
||||
|
||||
.sa-pic {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 8rpx;
|
||||
flex-shrink: 0;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.sa-info {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sa-name {
|
||||
font-size: 28rpx;
|
||||
color: #222;
|
||||
line-height: 38rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sa-price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 16rpx;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.sa-price {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #FF370B;
|
||||
}
|
||||
|
||||
.sa-unit {
|
||||
font-size: 22rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.sa-origin {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
@ -59,6 +59,27 @@
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 店铺活动商品 -->
|
||||
<view class="white_container shop-activity" v-if="shopActivityList.length > 0">
|
||||
<view class="shop-activity-title">店铺活动</view>
|
||||
<view class="shop-activity-list">
|
||||
<block v-for="(item, index) in shopActivityList" :key="index">
|
||||
<view class="sa-goods" v-for="(sku, sIdx) in item.group_buy_goods_list" :key="sIdx"
|
||||
@click="toShopActivityDetail(sku)">
|
||||
<image class="sa-pic" :src="sku.commodity_pic || item.commodity_pic" mode="aspectFill" />
|
||||
<view class="sa-info">
|
||||
<view class="sa-name">{{ sku.goods_name || item.commodity_name }}</view>
|
||||
<view class="sa-price-row">
|
||||
<view class="sa-price">¥{{ sku.group_buy_price }}<text class="sa-unit" v-if="sku.goods_unit">/{{ sku.goods_unit }}</text></view>
|
||||
<view class="sa-origin" v-if="sku.sales_price">单买价 ¥{{ sku.sales_price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="white_container detail" v-for="(item, index) in commentList" :key="index">
|
||||
<view class="Msg">
|
||||
<view class="Msg_Tit">
|
||||
@ -181,7 +202,8 @@ export default {
|
||||
isDisabled: false,
|
||||
coupons: [],
|
||||
couponDetails: [],
|
||||
showCouponPopup: false
|
||||
showCouponPopup: false,
|
||||
shopActivityList: [] // 店铺活动商品(团购 activity_type=2)
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
@ -213,6 +235,7 @@ export default {
|
||||
this.flag = false
|
||||
this.commentList = []
|
||||
this.getCommentList()
|
||||
this.getShopActivity()
|
||||
});
|
||||
},
|
||||
onShow() {
|
||||
@ -229,6 +252,46 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 店铺活动商品(团购 activity_type=2),小区来源与团购一致(绑定房产小区)
|
||||
getShopActivity() {
|
||||
const userId = uni.getStorageSync('userId')
|
||||
if (!userId) return
|
||||
const params = {
|
||||
user_id: userId,
|
||||
merchant_id: this.info.id,
|
||||
community_id: uni.getStorageSync('changeCommData') ? uni.getStorageSync('changeCommData').id : ''
|
||||
}
|
||||
request(apiArr.getShopActivityList, "POST", params, {}, false).then(res => {
|
||||
const list = (res.list || []).map(item => {
|
||||
const group_buy_goods_list = (item.group_buy_goods_list || []).map(sku => ({
|
||||
...sku,
|
||||
commodity_pic: picUrl + sku.commodity_pic,
|
||||
quantity: 0
|
||||
}))
|
||||
return {
|
||||
...item,
|
||||
commodity_pic: picUrl + item.commodity_pic,
|
||||
group_buy_goods_list
|
||||
}
|
||||
})
|
||||
this.shopActivityList = list
|
||||
}).catch(() => {
|
||||
this.shopActivityList = []
|
||||
})
|
||||
},
|
||||
// 点击店铺活动商品 -> 复用团购详情页
|
||||
toShopActivityDetail(itemObj) {
|
||||
let targetItem = itemObj
|
||||
if (!targetItem.group_buy_activity_info && targetItem.group_buy_goods_list && targetItem.group_buy_goods_list.length > 0) {
|
||||
targetItem = targetItem.group_buy_goods_list[0]
|
||||
}
|
||||
if (!targetItem.group_buy_activity_info) return
|
||||
const item = {
|
||||
...targetItem,
|
||||
groupById: targetItem.group_buy_activity_info.id
|
||||
}
|
||||
NavgateTo(`/packages/shop/groupPurchaseDetail/index?item=${JSON.stringify(item)}`)
|
||||
},
|
||||
getCouponList() {
|
||||
const params = {
|
||||
mch_id: uni.getStorageSync("merchantInfo").id,
|
||||
|
||||
@ -170,7 +170,15 @@ export default {
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
const item = JSON.parse(options?.item);
|
||||
let item
|
||||
// 来自客服聊天卡片:完整订单数据经本地存储中转(避免 URL 过长被截断)
|
||||
if (options && options.fromChat) {
|
||||
try { item = uni.getStorageSync('chatCardItem') } catch (e) { item = null }
|
||||
uni.removeStorageSync('chatCardItem')
|
||||
}
|
||||
if (!item) {
|
||||
item = JSON.parse(options?.item);
|
||||
}
|
||||
this.orderInfo = item;
|
||||
// 启动倒计时
|
||||
item.order_status == "1" ? this.startCountdown() : "";
|
||||
|
||||
@ -1,67 +1,148 @@
|
||||
/* ============================================================
|
||||
* 商家入驻 - 资料审核状态页
|
||||
* 审核中 #FF9F0A 通过 #34C759 失败 #FF3B30 主色 #FF370B
|
||||
* ============================================================ */
|
||||
page {
|
||||
background-color: #F6F7F9;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-top: 100rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 24rpx;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 200rpx;
|
||||
}
|
||||
|
||||
.auditStatus {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto;
|
||||
.audit-card {
|
||||
background: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
padding: 60rpx 40rpx 48rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
margin: 10rpx 0;
|
||||
text-align: center;
|
||||
.audit-icon {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.content{
|
||||
font-size: 26rpx;
|
||||
margin-top: 40rpx;
|
||||
text-align: center;
|
||||
color: #a9a9a9;
|
||||
.audit-icon--ing {
|
||||
background: #FFF4E0;
|
||||
}
|
||||
|
||||
.info{
|
||||
margin-top: 70rpx;
|
||||
width: 500rpx;
|
||||
background-color: #f6f6fa;
|
||||
padding: 20rpx 30rpx;
|
||||
border-radius: 20rpx;
|
||||
.audit-icon--ok {
|
||||
background: #E6F8EA;
|
||||
}
|
||||
|
||||
.info view{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 15rpx 0;
|
||||
.audit-icon--fail {
|
||||
background: #FDECEA;
|
||||
}
|
||||
|
||||
.info_text{
|
||||
color: #999999;
|
||||
.audit-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.info_text2{
|
||||
color: #faba5a;
|
||||
.audit-desc {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
padding: 0 20rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.btn{
|
||||
margin-top: 50rpx;
|
||||
border: none;
|
||||
background-color: #ff4218;
|
||||
color: #ffffff;
|
||||
border-radius: 50rpx;
|
||||
.audit-times {
|
||||
width: 100%;
|
||||
border-top: 1rpx solid #F2F2F2;
|
||||
padding-top: 24rpx;
|
||||
}
|
||||
|
||||
.warning{
|
||||
color: #ff4218;
|
||||
font-size: 27rpx;
|
||||
margin: 50rpx 0;
|
||||
.audit-time-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 44rpx;
|
||||
}
|
||||
|
||||
.warning_title{
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
/* 驳回原因框 */
|
||||
.reject-box {
|
||||
width: 100%;
|
||||
background: #FFF7F4;
|
||||
border: 1rpx solid #FFD9CD;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.reject-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #FF370B;
|
||||
margin-bottom: 14rpx;
|
||||
}
|
||||
|
||||
.reject-text {
|
||||
font-size: 26rpx;
|
||||
color: #FF370B;
|
||||
line-height: 42rpx;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.reject-imgs {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
.reject-imgs-label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.reject-thumbs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.reject-thumb {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid #EEE;
|
||||
}
|
||||
|
||||
/* 底部按钮 */
|
||||
.audit-footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #FFFFFF;
|
||||
padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
height: 88rpx;
|
||||
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
|
||||
border-radius: 44rpx;
|
||||
color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@ -1,128 +1,141 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="auditStatusContainer" v-if="itemObj.status == 1">
|
||||
<view class="header">
|
||||
<view class="statusIcon">
|
||||
<image src="https://static.hshuishang.com/enter_audit1.png" mode="aspectFill" class="auditStatus" />
|
||||
</view>
|
||||
<view class="title">
|
||||
审核中
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view>您的入驻申请正在审核中</view>
|
||||
<view>请耐心等待工作人员处理</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view>
|
||||
<view class="info_text">申请提交时间</view>
|
||||
<view>{{ itemObj.create_time }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="info_text">当前审核环节</view>
|
||||
<view class="info_text2">资质验证中</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="auditStatusContainer" v-if="itemObj.status == 2">
|
||||
<view class="header">
|
||||
<view class="statusIcon">
|
||||
<image src="https://static.hshuishang.com/af_√.png" mode="aspectFill"
|
||||
class="auditStatus" />
|
||||
</view>
|
||||
<view class="title">
|
||||
入驻成功
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view>恭喜您!您的店铺已成功入驻我们平台</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view>
|
||||
<view class="info_text">店铺名称</view>
|
||||
<view>{{ itemObj.merchant_name }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="info_text">入住时间</view>
|
||||
<view>{{ itemObj.handle_time || '' }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="info_text">店铺ID</view>
|
||||
<view>{{ itemObj.merchant_code }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view>
|
||||
<button class="btn" @click="goShopManage">进入店铺管理</button>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="auditStatusContainer" v-if="itemObj.status == 3">
|
||||
<view class="header">
|
||||
<view class="statusIcon">
|
||||
<image src="https://static.hshuishang.com/enter_audit2.png" mode="aspectFill" class="auditStatus" />
|
||||
</view>
|
||||
<view class="title">
|
||||
审核失败
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view>很抱歉,您的入驻申请未通过审核</view>
|
||||
<view>请修改后重新提交</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view>
|
||||
<view class="info_text">申请提交时间</view>
|
||||
<view>{{ itemObj.create_time }}</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="info_text">审核完成时间</view>
|
||||
<view>{{ itemObj.handle_time || '' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="warning" v-if="itemObj.remark">
|
||||
<view class="warning_title">审核未通过原因</view>
|
||||
<view>
|
||||
{{ itemObj.remark || '' }}
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<button class="btn" @click="resubmit">修改并重新提交</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="container">
|
||||
<!-- 审核中 -->
|
||||
<view class="audit-card" v-if="status === 1">
|
||||
<view class="audit-icon audit-icon--ing">
|
||||
<u-icon name="clock" color="#FF9F0A" size="56"></u-icon>
|
||||
</view>
|
||||
<view class="audit-title">正在审核中</view>
|
||||
<view class="audit-desc">您的店铺资料已提交,工作人员将在 1-3 个工作日内完成审核,请耐心等待。</view>
|
||||
<view class="audit-times">
|
||||
<view class="audit-time-row"><text>申请时间:</text><text>{{ itemObj.create_time || '—' }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审核通过 -->
|
||||
<view class="audit-card" v-else-if="status === 2">
|
||||
<view class="audit-icon audit-icon--ok">
|
||||
<u-icon name="checkmark" color="#34C759" size="56"></u-icon>
|
||||
</view>
|
||||
<view class="audit-title">审核通过</view>
|
||||
<view class="audit-desc">恭喜您,您的店铺资料已同意审核</view>
|
||||
<view class="audit-times">
|
||||
<view class="audit-time-row"><text>申请时间:</text><text>{{ itemObj.create_time || '—' }}</text></view>
|
||||
<view class="audit-time-row"><text>审核时间:</text><text>{{ itemObj.handle_time || '—' }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审核失败 -->
|
||||
<view class="audit-card" v-else-if="status === 3">
|
||||
<view class="audit-icon audit-icon--fail">
|
||||
<u-icon name="close" color="#FF3B30" size="56"></u-icon>
|
||||
</view>
|
||||
<view class="audit-title">审核失败</view>
|
||||
<view class="audit-desc">很抱歉,您的资料未通过审核,请修改后重新提交。</view>
|
||||
|
||||
<view class="reject-box" v-if="itemObj.remark || rejectImages.length">
|
||||
<view class="reject-title">
|
||||
<u-icon name="error-circle" color="#FF370B" size="28"></u-icon>
|
||||
<text>驳回原因</text>
|
||||
</view>
|
||||
<view class="reject-text">{{ itemObj.remark || '—' }}</view>
|
||||
<view class="reject-imgs" v-if="rejectImages.length">
|
||||
<view class="reject-imgs-label">问题截图</view>
|
||||
<view class="reject-thumbs">
|
||||
<image v-for="(u, i) in rejectImages" :key="i" :src="u" class="reject-thumb"
|
||||
mode="aspectFill" @click="preview(rejectImages, i)" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="audit-times">
|
||||
<view class="audit-time-row"><text>申请时间:</text><text>{{ itemObj.create_time || '—' }}</text></view>
|
||||
<view class="audit-time-row"><text>审核时间:</text><text>{{ itemObj.handle_time || '—' }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="audit-footer" v-if="status === 3">
|
||||
<view class="btn-primary" @click="resubmit">修改资料并重新提交</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request, NavgateTo } from '../../../utils/index';
|
||||
import { apiArr } from '../../../api/v2Home.js'
|
||||
import { NavgateTo } from '../../../utils/index';
|
||||
import { signPrivateView } from '../../../utils/uploadOSS.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
itemObj: {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.itemObj) {
|
||||
try {
|
||||
const raw = decodeURIComponent(options.itemObj)
|
||||
this.itemObj = JSON.parse(raw)
|
||||
} catch (e) {
|
||||
console.error('解析审核状态参数失败:', e)
|
||||
this.itemObj = {}
|
||||
}
|
||||
} else if (options && options.status) {
|
||||
// 兼容老版本:仅带 status,没有完整对象
|
||||
this.itemObj = { status: Number(options.status) }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goShopManage() {
|
||||
NavgateTo('/packages/storeManagement/index/index');
|
||||
},
|
||||
resubmit() {
|
||||
NavgateTo('/packages/shopEnter/index/index?itemObj=' + JSON.stringify(this.itemObj));
|
||||
}
|
||||
}
|
||||
data() {
|
||||
return {
|
||||
itemObj: {},
|
||||
rejectImages: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
status() {
|
||||
return Number(this.itemObj.status) || 0
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.itemObj) {
|
||||
try {
|
||||
this.itemObj = JSON.parse(decodeURIComponent(options.itemObj))
|
||||
} catch (e) {
|
||||
console.error('解析审核状态参数失败:', e)
|
||||
this.itemObj = {}
|
||||
}
|
||||
} else if (options && options.status) {
|
||||
// 兼容老版本:仅带 status,没有完整对象
|
||||
this.itemObj = { status: Number(options.status) }
|
||||
}
|
||||
// 驳回问题截图:后端 reject_images 字段(逗号分隔的私密 key),有则签名展示
|
||||
if (this.itemObj.reject_images) {
|
||||
this.signRejectImages(this.itemObj.reject_images)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async signRejectImages(paths) {
|
||||
const list = (paths || '').split(',').filter(Boolean)
|
||||
const result = []
|
||||
for (const p of list) {
|
||||
try {
|
||||
const r = await signPrivateView(p)
|
||||
result.push(r.url)
|
||||
} catch (e) {
|
||||
console.error('签发驳回截图 URL 失败:', p, e)
|
||||
}
|
||||
}
|
||||
this.rejectImages = result
|
||||
},
|
||||
preview(urls, current) {
|
||||
if (!urls || !urls.length) return
|
||||
uni.previewImage({ urls, current: urls[current] })
|
||||
},
|
||||
resubmit() {
|
||||
// 编辑数据较大(含多组图片路径),用本地存储中转,避免 URL 过长被截断
|
||||
try {
|
||||
uni.setStorageSync('shopEnterEditData', this.itemObj)
|
||||
} catch (e) {
|
||||
console.error('暂存编辑数据失败:', e)
|
||||
}
|
||||
NavgateTo('/packages/shopEnter/index/index?edit=1');
|
||||
},
|
||||
// 返回首页(审核态为终态,避免回退到表单/确认页造成二次提交)
|
||||
goHome() {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
}
|
||||
},
|
||||
// 拦截物理返回 / 左上角返回:统一回首页,而非弹出上一页
|
||||
onBackPress(e) {
|
||||
// 编辑页发起的二次提交流程(status 3 驳回后点重新提交跳走)不拦截
|
||||
if (e && e.from === 'backbutton') {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url("./index.css");
|
||||
</style>
|
||||
</style>
|
||||
|
||||
235
packages/shopEnter/camera/index.css
Normal file
235
packages/shopEnter/camera/index.css
Normal file
@ -0,0 +1,235 @@
|
||||
/* ============================================================
|
||||
* 商家入驻 - 自定义相机(取景框拍证件)
|
||||
* ============================================================ */
|
||||
page {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.cam-page {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: #000;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.cam-nav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12rpx 24rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.cam-nav-back {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cam-nav-title {
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cam-nav-right {
|
||||
width: 60rpx;
|
||||
}
|
||||
|
||||
/* 相机取景 */
|
||||
.cam-view {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* 取景框遮罩 */
|
||||
.cam-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cam-frame {
|
||||
position: relative;
|
||||
border: 2rpx dashed rgba(255, 255, 255, 0.7);
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.frame-landscape {
|
||||
width: 86vw;
|
||||
height: 54vw;
|
||||
}
|
||||
|
||||
.frame-portrait {
|
||||
width: 64vw;
|
||||
height: 86vw;
|
||||
}
|
||||
|
||||
.cam-corner {
|
||||
position: absolute;
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border-color: #FF370B;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cam-corner.tl {
|
||||
top: -2rpx;
|
||||
left: -2rpx;
|
||||
border-top-width: 6rpx;
|
||||
border-left-width: 6rpx;
|
||||
border-top-left-radius: 16rpx;
|
||||
}
|
||||
|
||||
.cam-corner.tr {
|
||||
top: -2rpx;
|
||||
right: -2rpx;
|
||||
border-top-width: 6rpx;
|
||||
border-right-width: 6rpx;
|
||||
border-top-right-radius: 16rpx;
|
||||
}
|
||||
|
||||
.cam-corner.bl {
|
||||
bottom: -2rpx;
|
||||
left: -2rpx;
|
||||
border-bottom-width: 6rpx;
|
||||
border-left-width: 6rpx;
|
||||
border-bottom-left-radius: 16rpx;
|
||||
}
|
||||
|
||||
.cam-corner.br {
|
||||
bottom: -2rpx;
|
||||
right: -2rpx;
|
||||
border-bottom-width: 6rpx;
|
||||
border-right-width: 6rpx;
|
||||
border-bottom-right-radius: 16rpx;
|
||||
}
|
||||
|
||||
.cam-tip {
|
||||
margin-top: 36rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
/* 横版/竖版切换 */
|
||||
.cam-orient {
|
||||
position: absolute;
|
||||
bottom: 280rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.orient-item {
|
||||
padding: 12rpx 40rpx;
|
||||
border-radius: 40rpx;
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.orient-item.active {
|
||||
background: #FF370B;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作 */
|
||||
.cam-actions {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
height: 240rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.cam-action-side {
|
||||
width: 110rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.cam-action-placeholder {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cam-shutter {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
border: 8rpx solid rgba(255, 255, 255, 0.4);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cam-shutter:active {
|
||||
transform: scale(0.94);
|
||||
}
|
||||
|
||||
/* 预览态 */
|
||||
.cam-preview {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.cam-preview-actions {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
height: 200rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 40rpx;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.prev-btn {
|
||||
width: 240rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.prev-retake {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.prev-submit {
|
||||
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
|
||||
color: #fff;
|
||||
}
|
||||
165
packages/shopEnter/camera/index.vue
Normal file
165
packages/shopEnter/camera/index.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<view class="cam-page">
|
||||
<!-- 顶部自定义导航 -->
|
||||
<view class="cam-nav" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<view class="cam-nav-back" @click="goBack">
|
||||
<u-icon name="arrow-left" color="#fff" size="40"></u-icon>
|
||||
</view>
|
||||
<view class="cam-nav-title">{{ title }}</view>
|
||||
<view class="cam-nav-right"></view>
|
||||
</view>
|
||||
|
||||
<!-- 拍摄态:相机取景 -->
|
||||
<block v-if="!captured">
|
||||
<camera class="cam-view" :device-position="'back'" :flash="'auto'" @error="onCamError"></camera>
|
||||
<!-- 取景框遮罩 -->
|
||||
<view class="cam-overlay">
|
||||
<view class="cam-frame" :class="orientation === 'landscape' ? 'frame-landscape' : 'frame-portrait'">
|
||||
<view class="cam-corner tl"></view>
|
||||
<view class="cam-corner tr"></view>
|
||||
<view class="cam-corner bl"></view>
|
||||
<view class="cam-corner br"></view>
|
||||
</view>
|
||||
<view class="cam-tip">{{ frameTip }}</view>
|
||||
</view>
|
||||
<!-- 横版/竖版切换 -->
|
||||
<view class="cam-orient">
|
||||
<view class="orient-item" :class="{ active: orientation === 'landscape' }" @click="orientation = 'landscape'">横版</view>
|
||||
<view class="orient-item" :class="{ active: orientation === 'portrait' }" @click="orientation = 'portrait'">竖版</view>
|
||||
</view>
|
||||
<!-- 底部操作:相册 / 拍照 -->
|
||||
<view class="cam-actions">
|
||||
<view class="cam-action-side" @click="pickFromAlbum">
|
||||
<u-icon name="photo" color="#fff" size="44"></u-icon>
|
||||
<text>相册</text>
|
||||
</view>
|
||||
<view class="cam-shutter" @click="takePhoto"></view>
|
||||
<view class="cam-action-side cam-action-placeholder"></view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 预览态:重拍 / 提交 -->
|
||||
<block v-else>
|
||||
<image class="cam-preview" :src="tempPath" mode="aspectFit"></image>
|
||||
<view class="cam-preview-actions">
|
||||
<view class="prev-btn prev-retake" @click="retake">重拍</view>
|
||||
<view class="prev-btn prev-submit" @click="confirmUse">提交</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
statusBarHeight: 20,
|
||||
target: 'license', // license / idFront / idBack / industry
|
||||
orientation: 'landscape',
|
||||
captured: false,
|
||||
tempPath: '',
|
||||
cameraCtx: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
const map = {
|
||||
license: '拍摄营业执照',
|
||||
idFront: '拍摄身份证人像面',
|
||||
idBack: '拍摄身份证国徽面',
|
||||
industry: '拍摄行业资质',
|
||||
}
|
||||
return map[this.target] || '拍摄证件'
|
||||
},
|
||||
frameTip() {
|
||||
const map = {
|
||||
license: '请将营业执照完整置于取景框内',
|
||||
idFront: '请将身份证人像面置于取景框内',
|
||||
idBack: '请将身份证国徽面置于取景框内',
|
||||
industry: '请将资质证件完整置于取景框内',
|
||||
}
|
||||
return map[this.target] || '请将证件完整置于取景框内'
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.target) this.target = options.target
|
||||
// 身份证默认横版,营业执照/资质默认竖版
|
||||
this.orientation = (this.target === 'idFront' || this.target === 'idBack') ? 'landscape' : 'portrait'
|
||||
try {
|
||||
const sys = uni.getSystemInfoSync()
|
||||
this.statusBarHeight = sys.statusBarHeight || 20
|
||||
} catch (e) {}
|
||||
},
|
||||
onReady() {
|
||||
// #ifndef H5
|
||||
this.cameraCtx = uni.createCameraContext()
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
onCamError(e) {
|
||||
console.error('相机错误:', e)
|
||||
uni.showModal({
|
||||
title: '无法使用相机',
|
||||
content: '请检查是否已授予相机权限,或改用相册上传。',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
takePhoto() {
|
||||
if (!this.cameraCtx) {
|
||||
// H5 等不支持 camera 组件的环境,回退到系统拍照
|
||||
this.pickFromCamera()
|
||||
return
|
||||
}
|
||||
this.cameraCtx.takePhoto({
|
||||
quality: 'high',
|
||||
success: (res) => {
|
||||
this.tempPath = res.tempImagePath
|
||||
this.captured = true
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '拍照失败,请重试', icon: 'none' })
|
||||
}
|
||||
})
|
||||
},
|
||||
pickFromCamera() {
|
||||
uni.chooseImage({
|
||||
count: 1, sizeType: ['compressed'], sourceType: ['camera'],
|
||||
success: (res) => {
|
||||
const fp = res.tempFilePaths && res.tempFilePaths[0]
|
||||
if (!fp) return
|
||||
this.tempPath = fp
|
||||
this.captured = true
|
||||
}
|
||||
})
|
||||
},
|
||||
pickFromAlbum() {
|
||||
uni.chooseImage({
|
||||
count: 1, sizeType: ['compressed'], sourceType: ['album'],
|
||||
success: (res) => {
|
||||
const fp = res.tempFilePaths && res.tempFilePaths[0]
|
||||
if (!fp) return
|
||||
this.tempPath = fp
|
||||
this.captured = true
|
||||
}
|
||||
})
|
||||
},
|
||||
retake() {
|
||||
this.captured = false
|
||||
this.tempPath = ''
|
||||
},
|
||||
confirmUse() {
|
||||
if (!this.tempPath) return
|
||||
// 把拍摄结果通过事件总线回传给入驻表单页,由其负责上传 + OCR
|
||||
uni.$emit('shopEnter:capture', { target: this.target, filePath: this.tempPath })
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url("./index.css");
|
||||
</style>
|
||||
182
packages/shopEnter/confirm/index.css
Normal file
182
packages/shopEnter/confirm/index.css
Normal file
@ -0,0 +1,182 @@
|
||||
/* ============================================================
|
||||
* 商家入驻 - 确认信息页(预览信息)
|
||||
* 主色 #FF370B 背景 #F6F7F9
|
||||
* ============================================================ */
|
||||
page {
|
||||
background-color: #F6F7F9;
|
||||
min-height: 100vh;
|
||||
padding-bottom: 200rpx;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-bottom: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 顶部进度条(复用主页样式) */
|
||||
.step-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx 30rpx 28rpx;
|
||||
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
|
||||
}
|
||||
|
||||
.step-pill {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
margin: 0 8rpx;
|
||||
border-radius: 30rpx;
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.step-pill.active {
|
||||
background: #FFFFFF;
|
||||
color: #FF370B;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.confirm-head {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
padding: 28rpx 24rpx 8rpx;
|
||||
}
|
||||
|
||||
/* 分组卡片 */
|
||||
.cf-group {
|
||||
background: #FFFFFF;
|
||||
margin: 16rpx 24rpx 0;
|
||||
border-radius: 16rpx;
|
||||
padding: 8rpx 24rpx;
|
||||
}
|
||||
|
||||
.cf-group-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
padding: 20rpx 0 12rpx;
|
||||
border-bottom: 1rpx solid #F2F2F2;
|
||||
}
|
||||
|
||||
.cf-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 22rpx 0;
|
||||
border-bottom: 1rpx solid #F7F7F7;
|
||||
}
|
||||
|
||||
.cf-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.cf-k {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.cf-v {
|
||||
font-size: 26rpx;
|
||||
color: #222;
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* 文件资料行 */
|
||||
.cf-file-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 22rpx 0;
|
||||
border-bottom: 1rpx solid #F7F7F7;
|
||||
}
|
||||
|
||||
.cf-file-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.cf-thumbs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
justify-content: flex-end;
|
||||
flex: 1;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
.cf-thumb {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid #EEE;
|
||||
}
|
||||
|
||||
.cf-empty {
|
||||
font-size: 24rpx;
|
||||
color: #B7B7B7;
|
||||
}
|
||||
|
||||
/* 协议勾选 */
|
||||
.agreement {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 24rpx 0;
|
||||
}
|
||||
|
||||
.agreement-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.agreement-link {
|
||||
color: #FF370B;
|
||||
}
|
||||
|
||||
/* 底部按钮(吸底) */
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #FFFFFF;
|
||||
padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
|
||||
border-radius: 44rpx;
|
||||
color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
background: #FFFFFF;
|
||||
border: 1rpx solid #FF370B;
|
||||
border-radius: 44rpx;
|
||||
color: #FF370B;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
209
packages/shopEnter/confirm/index.vue
Normal file
209
packages/shopEnter/confirm/index.vue
Normal file
@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 顶部进度条 -->
|
||||
<view class="step-bar">
|
||||
<view class="step-pill active">填写信息</view>
|
||||
<view class="step-pill">提交审核</view>
|
||||
<view class="step-pill">入驻成功</view>
|
||||
</view>
|
||||
|
||||
<view class="confirm-head">请确认以下信息</view>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<view class="cf-group">
|
||||
<view class="cf-group-title">基本信息</view>
|
||||
<view class="cf-row"><text class="cf-k">门店名称</text><text class="cf-v">{{ d.merchant_name || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">所在地区</text><text class="cf-v">{{ d._region_label || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">详细地址</text><text class="cf-v">{{ d.address || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">商家类目</text><text class="cf-v">{{ d._cate_name || '—' }}</text></view>
|
||||
<view class="cf-row" v-if="d._biz_status_label"><text class="cf-k">营业状态</text><text class="cf-v">{{ d._biz_status_label }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">负责人姓名</text><text class="cf-v">{{ d.contact_name || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">负责人手机</text><text class="cf-v">{{ d.phone || '—' }}</text></view>
|
||||
</view>
|
||||
|
||||
<!-- 资质信息 -->
|
||||
<view class="cf-group">
|
||||
<view class="cf-group-title">资质信息</view>
|
||||
<view class="cf-row"><text class="cf-k">执照名称</text><text class="cf-v">{{ d.license_name || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">信用代码</text><text class="cf-v">{{ d.credit_code || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">营业执照</text><text class="cf-v">{{ d.license_is_forever === 1 ? '永久有效' : (d.license_valid_until || '—') }}</text></view>
|
||||
<view class="cf-row" v-if="d.industry_name"><text class="cf-k">证书名称</text><text class="cf-v">{{ d.industry_name }}</text></view>
|
||||
<view class="cf-row" v-if="d.industry_cert_no"><text class="cf-k">证书编号</text><text class="cf-v">{{ d.industry_cert_no }}</text></view>
|
||||
<view class="cf-row" v-if="d.industry_name"><text class="cf-k">资质有效期</text><text class="cf-v">{{ d.industry_is_forever === 1 ? '永久有效' : (d.industry_valid_until || '—') }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">法人姓名</text><text class="cf-v">{{ d.legal_person || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">身份证号</text><text class="cf-v">{{ d.id_card_no || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">证件有效期</text><text class="cf-v">{{ d.id_is_forever === 1 ? '永久有效' : (d.id_valid_until || '—') }}</text></view>
|
||||
</view>
|
||||
|
||||
<!-- 结算信息 -->
|
||||
<view class="cf-group">
|
||||
<view class="cf-group-title">结算信息</view>
|
||||
<view class="cf-row"><text class="cf-k">银行开户名</text><text class="cf-v">{{ d.account_name || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">{{ d.account_type === 2 ? '对公账号' : '银行卡号' }}</text><text class="cf-v">{{ d.bank_card || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">开户银行</text><text class="cf-v">{{ d.bank_name || '—' }}</text></view>
|
||||
<view class="cf-row"><text class="cf-k">开户支行</text><text class="cf-v">{{ d.bank_branch || '—' }}</text></view>
|
||||
<view class="cf-row" v-if="d._bank_region_label"><text class="cf-k">银行所在地</text><text class="cf-v">{{ d._bank_region_label }}</text></view>
|
||||
<view class="cf-row" v-if="d.bank_union_no"><text class="cf-k">联行号</text><text class="cf-v">{{ d.bank_union_no }}</text></view>
|
||||
</view>
|
||||
|
||||
<!-- 文件资料 -->
|
||||
<view class="cf-group">
|
||||
<view class="cf-group-title">文件资料</view>
|
||||
<view class="cf-file-row">
|
||||
<text class="cf-k">营业执照</text>
|
||||
<view class="cf-thumbs">
|
||||
<image v-for="(u, i) in licenseUrls" :key="i" :src="u" class="cf-thumb" mode="aspectFill" @click="preview(licenseUrls, i)" />
|
||||
<text v-if="!licenseUrls.length" class="cf-empty">未上传</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cf-file-row">
|
||||
<text class="cf-k">行业资质</text>
|
||||
<view class="cf-thumbs">
|
||||
<image v-for="(u, i) in industryUrls" :key="i" :src="u" class="cf-thumb" mode="aspectFill" @click="preview(industryUrls, i)" />
|
||||
<text v-if="!industryUrls.length" class="cf-empty">未上传</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cf-file-row">
|
||||
<text class="cf-k">法人证件</text>
|
||||
<view class="cf-thumbs">
|
||||
<image v-for="(u, i) in idUrls" :key="i" :src="u" class="cf-thumb" mode="aspectFill" @click="preview(idUrls, i)" />
|
||||
<text v-if="!idUrls.length" class="cf-empty">未上传</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cf-file-row">
|
||||
<text class="cf-k">门头环境</text>
|
||||
<view class="cf-thumbs">
|
||||
<image v-for="(u, i) in facadeUrls" :key="i" :src="u" class="cf-thumb" mode="aspectFill" @click="preview(facadeUrls, i)" />
|
||||
<text v-if="!facadeUrls.length" class="cf-empty">未上传</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cf-file-row">
|
||||
<text class="cf-k">店内环境</text>
|
||||
<view class="cf-thumbs">
|
||||
<image v-for="(u, i) in interiorUrls" :key="i" :src="u" class="cf-thumb" mode="aspectFill" @click="preview(interiorUrls, i)" />
|
||||
<text v-if="!interiorUrls.length" class="cf-empty">未上传</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 协议勾选 -->
|
||||
<view class="agreement">
|
||||
<view class="agreement-check" @click="agreeProtocol = !agreeProtocol">
|
||||
<u-icon :name="agreeProtocol ? 'checkmark-circle-fill' : 'checkmark-circle'" :color="agreeProtocol ? '#FF370B' : '#ccc'" size="36"></u-icon>
|
||||
</view>
|
||||
<view class="agreement-text">
|
||||
我已阅读并同意<text class="agreement-link" @click.stop="viewProtocol">《商家入驻协议》</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-bar">
|
||||
<view class="btn-secondary" @click="goBack">返回修改</view>
|
||||
<view class="btn-primary" @click="submit">提交审核</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { apiArr } from '../../../api/v2local';
|
||||
import { request, picUrl, NavgateTo } from '../../../utils';
|
||||
import { signPrivateView } from '../../../utils/uploadOSS.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
picUrl,
|
||||
d: {},
|
||||
agreeProtocol: false,
|
||||
licenseUrls: [],
|
||||
industryUrls: [],
|
||||
idUrls: [],
|
||||
facadeUrls: [],
|
||||
interiorUrls: [],
|
||||
submitting: false,
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.itemObj) {
|
||||
try {
|
||||
this.d = JSON.parse(decodeURIComponent(options.itemObj))
|
||||
} catch (e) {
|
||||
console.error('解析确认页参数失败:', e)
|
||||
this.d = {}
|
||||
}
|
||||
}
|
||||
// 门头环境 / 店内环境:公开 bucket,直接拼 URL
|
||||
this.facadeUrls = (this.d.facade_photo || '').split(',').filter(Boolean).map(p => this.picUrl + p)
|
||||
this.interiorUrls = (this.d.interior_photo || '').split(',').filter(Boolean).map(p => this.picUrl + p)
|
||||
// 营业执照 / 行业资质 / 身份证:私密 bucket,需要签名
|
||||
this.signList(this.d.license_photo, 'licenseUrls')
|
||||
this.signList(this.d.industry_photo, 'industryUrls')
|
||||
this.signList([this.d.id_card_front, this.d.id_card_back].filter(Boolean).join(','), 'idUrls')
|
||||
},
|
||||
methods: {
|
||||
async signList(paths, key) {
|
||||
const list = (paths || '').split(',').filter(Boolean)
|
||||
const result = []
|
||||
for (const p of list) {
|
||||
try {
|
||||
const r = await signPrivateView(p)
|
||||
result.push(r.url)
|
||||
} catch (e) {
|
||||
console.error('签发私密 URL 失败:', p, e)
|
||||
}
|
||||
}
|
||||
this[key] = result
|
||||
},
|
||||
preview(urls, current) {
|
||||
if (!urls || !urls.length) return
|
||||
uni.previewImage({ urls, current: urls[current] })
|
||||
},
|
||||
viewProtocol() {
|
||||
uni.showModal({
|
||||
title: '商家入驻协议',
|
||||
content: '本协议是您与平台之间关于商家入驻服务的法律协议。入驻后您需遵守平台规则,按时提供商品或服务,保证信息真实有效。平台有权对违规商家进行处罚。',
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
})
|
||||
},
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
submit() {
|
||||
if (!this.agreeProtocol) {
|
||||
uni.showToast({ title: '请先阅读并同意商家入驻协议', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (this.submitting) return
|
||||
this.submitting = true
|
||||
// 剥离仅用于展示的下划线字段,避免传给后端
|
||||
const params = {}
|
||||
Object.keys(this.d).forEach(k => {
|
||||
if (!k.startsWith('_')) params[k] = this.d[k]
|
||||
})
|
||||
request(apiArr.createStore, "POST", params).then(res => {
|
||||
// 审核页仅需少量字段;用 reLaunch 清空页面栈,避免返回到表单/确认页造成二次提交
|
||||
const auditItem = {
|
||||
status: 1,
|
||||
create_time: new Date().toLocaleString('sv-SE').replace('T', ' '),
|
||||
handle_time: '',
|
||||
remark: ''
|
||||
}
|
||||
uni.reLaunch({
|
||||
url: "/packages/shopEnter/auditStatus/index?itemObj=" + encodeURIComponent(JSON.stringify(auditItem))
|
||||
})
|
||||
}).catch(res => {
|
||||
this.submitting = false
|
||||
const msg = res && res.message ? res.message : '提交失败,请稍后重试'
|
||||
if (msg.includes("agent_nil")) {
|
||||
uni.showModal({ title: '提交失败', content: '未找到对应的代理商信息,请联系平台', showCancel: false })
|
||||
return
|
||||
}
|
||||
uni.showModal({ title: '提交失败', content: msg, showCancel: false })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url("./index.css");
|
||||
</style>
|
||||
@ -36,6 +36,19 @@
|
||||
<view class="tips-item">4. 仅支持二代身份证</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="example-section" v-if="type === 'industry'">
|
||||
<view class="title">行业资质示例</view>
|
||||
<view class="example-img">
|
||||
<image src="/static/example/license.jpg" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="tips">
|
||||
<view class="tips-title">拍摄要求:</view>
|
||||
<view class="tips-item">1. 请上传与经营品类对应的资质(如食品经营许可证)</view>
|
||||
<view class="tips-item">2. 照片需清晰完整,四角完整可见</view>
|
||||
<view class="tips-item">3. 不得有遮挡、涂改、反光</view>
|
||||
<view class="tips-item">4. 资质需在有效期内</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -55,7 +68,8 @@ export default {
|
||||
// 设置导航栏标题
|
||||
const titleMap = {
|
||||
license: '营业执照示例',
|
||||
idcard: '身份证示例'
|
||||
idcard: '身份证示例',
|
||||
industry: '行业资质示例'
|
||||
}
|
||||
uni.setNavigationBarTitle({
|
||||
title: titleMap[this.type] || '资质示例'
|
||||
|
||||
@ -418,3 +418,257 @@ page {
|
||||
font-size: 26rpx;
|
||||
color: #B7B7B7;
|
||||
}
|
||||
|
||||
/* ============ Tab2 资质相关 ============ */
|
||||
.qual-thumb {
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
border-radius: 12rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid #EBEBEB;
|
||||
}
|
||||
|
||||
.qual-thumb-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.qual-thumb-del {
|
||||
position: absolute;
|
||||
top: 8rpx;
|
||||
right: 8rpx;
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.id-card-row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.id-card-cell {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.id-card-cell .upload-add {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
.id-card-cell .qual-thumb {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
.id-card-cell-label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.forever-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
margin-top: 12rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.forever-toggle-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* ============ 有效期分段控件(永久有效 / 截止日期) ============ */
|
||||
.validity-seg {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.validity-seg .seg-item {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
border: 1rpx solid #EBEBEB;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
.validity-seg .seg-item.active {
|
||||
color: #FF370B;
|
||||
border-color: #FF370B;
|
||||
background: #FFF1ED;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ============ 结算页:银行账户信息分组标题 ============ */
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
color: #222;
|
||||
font-weight: 600;
|
||||
padding: 28rpx 24rpx 4rpx;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
width: 6rpx;
|
||||
height: 30rpx;
|
||||
background: #FF370B;
|
||||
border-radius: 3rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
/* 结算页行内底部提示 */
|
||||
.row-tip {
|
||||
font-size: 22rpx;
|
||||
color: #86909C;
|
||||
padding: 12rpx 24rpx 0;
|
||||
line-height: 34rpx;
|
||||
}
|
||||
|
||||
/* 结算页可点击选择行右侧布局 */
|
||||
.row_con--select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.row_con .row_value {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.row_con .row_value.placeholder {
|
||||
color: #B7B7B7;
|
||||
}
|
||||
|
||||
/* ============ 结算页 银行账户信息表单 ============ */
|
||||
.Msg {
|
||||
background: #FFFFFF;
|
||||
margin: 12rpx 24rpx 0;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.Msg .row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid #F2F2F2;
|
||||
}
|
||||
|
||||
.Msg .row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.Msg .row_label {
|
||||
font-size: 26rpx;
|
||||
color: #222;
|
||||
margin-bottom: 14rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Msg .row_label .star {
|
||||
color: #FF370B;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
.Msg .row_con {
|
||||
height: 80rpx;
|
||||
border: 1rpx solid #EBEBEB;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
.Msg .row_con input {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #222;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
}
|
||||
|
||||
.Msg .row_con input::placeholder {
|
||||
color: #B7B7B7;
|
||||
}
|
||||
|
||||
/* 结算页底部按钮组 */
|
||||
.btn-group {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
padding: 40rpx 24rpx;
|
||||
}
|
||||
|
||||
.btn-group .prevBtn {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
background: #FFFFFF;
|
||||
border: 1rpx solid #FF370B;
|
||||
border-radius: 44rpx;
|
||||
color: #FF370B;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-group .nextBtn {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
|
||||
border-radius: 44rpx;
|
||||
color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-sheet {
|
||||
width: 100%;
|
||||
background: #F2F2F4;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.action-item {
|
||||
background: #FFFFFF;
|
||||
padding: 32rpx 0;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #222;
|
||||
border-bottom: 1rpx solid #F0F0F0;
|
||||
}
|
||||
|
||||
.action-item:active {
|
||||
background: #F8F8F8;
|
||||
}
|
||||
|
||||
.action-cancel {
|
||||
margin-top: 12rpx;
|
||||
color: #999;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
23
pages.json
23
pages.json
@ -145,6 +145,13 @@
|
||||
"navigationBarBackgroundColor": "#F9F9F9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "picker/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "选择",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "chattingRecords/index",
|
||||
"style": {
|
||||
@ -586,6 +593,20 @@
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "confirm/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "商家入驻",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "camera/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "拍摄证件",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "sucess/index",
|
||||
"style": {
|
||||
@ -597,7 +618,7 @@
|
||||
{
|
||||
"path": "auditStatus/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "审核状态",
|
||||
"navigationBarTitleText": "资料审核",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
},
|
||||
|
||||
@ -489,6 +489,9 @@ export default {
|
||||
uni.setStorageSync('location', preciseLocation);
|
||||
uni.setStorageSync('ad_code', ad_info.adcode);
|
||||
// TODO: 这里需要强依赖 ad_code 去查询,必须保障代码先后执行顺序正确
|
||||
// 先一次性批量拉取首页各广告位(1-11),后续各 getHomeXxx 直接读缓存,
|
||||
// 把原来十几次 banner-region 请求压成一次
|
||||
await this.prefetchBannerGroups();
|
||||
const [bannerList, serverLeft, serverRightList, homeLeftList, homeRightList, bottomList, buttonList, categoryList] = await Promise.all([
|
||||
|
||||
this.getHomeBanner(),// 轮播图查询
|
||||
@ -677,18 +680,45 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
async getHomeBanner() {
|
||||
// 一次性拉取多个广告位,结果缓存到 this._bannerGroups,供各 getHomeXxx 读取,
|
||||
// 把原来十几次 banner-region 请求压成一次。
|
||||
async prefetchBannerGroups(positions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) {
|
||||
try {
|
||||
const res = await request(apiArr2.getHomeBannerMulti, "POST", {
|
||||
ad_code: Number(uni.getStorageSync('ad_code')),
|
||||
ad_positions: positions,
|
||||
longitude: uni.getStorageSync('location').lng,
|
||||
latitude: uni.getStorageSync('location').lat,
|
||||
page_size: 50
|
||||
}, { silent: false });
|
||||
this._bannerGroups = (res && res.groups) ? res.groups : {};
|
||||
} catch (e) {
|
||||
console.warn('批量拉取首页广告失败,回退逐个请求:', e);
|
||||
this._bannerGroups = null; // 标记不可用,各方法回退单查
|
||||
}
|
||||
},
|
||||
|
||||
// 读取某广告位的数据:优先用批量缓存,缓存缺失则回退单个 page 请求(保证方法可独立工作)
|
||||
async getBannerRows(position) {
|
||||
if (this._bannerGroups) {
|
||||
const rows = this._bannerGroups[String(position)] || [];
|
||||
return rows;
|
||||
}
|
||||
const res = await request(apiArr2.getHomeBanner, "POST", {
|
||||
ad_code: uni.getStorageSync('ad_code'),
|
||||
ad_position: 1,
|
||||
ad_position: position,
|
||||
longitude: uni.getStorageSync('location').lng,
|
||||
latitude: uni.getStorageSync('location').lat,
|
||||
page_num: 1,
|
||||
page_size: 10
|
||||
page_size: 50
|
||||
}, { silent: false });
|
||||
return (res && res.rows) ? res.rows : [];
|
||||
},
|
||||
|
||||
if (res.rows && res.rows.length) {
|
||||
let filterRes = this.filterShowList(res.rows, 1);
|
||||
async getHomeBanner() {
|
||||
const rows = await this.getBannerRows(1);
|
||||
if (rows && rows.length) {
|
||||
let filterRes = this.filterShowList(rows, 1);
|
||||
filterRes.forEach(item => {
|
||||
item.pic_src = picUrl + item.pic_src
|
||||
})
|
||||
@ -699,21 +729,14 @@ export default {
|
||||
},
|
||||
|
||||
async getServerLeft() {
|
||||
const res = await request(apiArr2.getHomeBanner, "POST", {
|
||||
ad_code: uni.getStorageSync('ad_code'),
|
||||
ad_position: 2,
|
||||
longitude: uni.getStorageSync('location').lng,
|
||||
latitude: uni.getStorageSync('location').lat,
|
||||
page_num: 1,
|
||||
page_size: 10
|
||||
}, { silent: false });
|
||||
if (!res.rows || !res.rows.length) {
|
||||
const rows = await this.getBannerRows(2);
|
||||
if (!rows || !rows.length) {
|
||||
this.serverLeftList = []
|
||||
}
|
||||
|
||||
if (res.rows && res.rows.length) {
|
||||
this.serverLeftList = res.rows
|
||||
let filterRes = this.filterShowList(res?.rows, 1);
|
||||
if (rows && rows.length) {
|
||||
this.serverLeftList = rows
|
||||
let filterRes = this.filterShowList(rows, 1);
|
||||
filterRes.forEach(item => {
|
||||
item.pic_src = picUrl + item.pic_src
|
||||
})
|
||||
@ -727,19 +750,12 @@ export default {
|
||||
async getServerRight() {
|
||||
const rightList = []
|
||||
for (let i = 3; i < 5; i++) {
|
||||
const res = await request(apiArr2.getHomeBanner, "POST", {
|
||||
ad_code: uni.getStorageSync('ad_code'),
|
||||
ad_position: i,
|
||||
longitude: uni.getStorageSync('location').lng,
|
||||
latitude: uni.getStorageSync('location').lat,
|
||||
page_num: 1,
|
||||
page_size: 10
|
||||
}, { silent: false });
|
||||
if (!res.rows || !res.rows.length) {
|
||||
const rows = await this.getBannerRows(i);
|
||||
if (!rows || !rows.length) {
|
||||
this.serverRightList = []
|
||||
}
|
||||
if (res.rows && res.rows.length) {
|
||||
let filterRes = this.filterShowList(res?.rows, 1);
|
||||
if (rows && rows.length) {
|
||||
let filterRes = this.filterShowList(rows, 1);
|
||||
filterRes.forEach(item => {
|
||||
item.pic_src = picUrl + item.pic_src
|
||||
})
|
||||
@ -750,16 +766,9 @@ export default {
|
||||
},
|
||||
|
||||
async getHomeMidLeft() {
|
||||
const res = await request(apiArr2.getHomeBanner, "POST", {
|
||||
ad_code: uni.getStorageSync('ad_code'),
|
||||
ad_position: 5,
|
||||
longitude: uni.getStorageSync('location').lng,
|
||||
latitude: uni.getStorageSync('location').lat,
|
||||
page_num: 1,
|
||||
page_size: 10
|
||||
}, { silent: false });
|
||||
if (res.rows && res.rows.length) {
|
||||
let filterRes = this.filterShowList(res?.rows, 1);
|
||||
const rows = await this.getBannerRows(5);
|
||||
if (rows && rows.length) {
|
||||
let filterRes = this.filterShowList(rows, 1);
|
||||
filterRes.forEach(item => {
|
||||
item.pic_src = picUrl + item.pic_src
|
||||
})
|
||||
@ -772,19 +781,9 @@ export default {
|
||||
async getHomeMidRight() {
|
||||
const rightList = []
|
||||
for (let i = 6; i < 12; i++) {
|
||||
const res = await request(apiArr2.getHomeBanner, "POST", {
|
||||
ad_code: uni.getStorageSync('ad_code'),
|
||||
ad_position: i,
|
||||
longitude: uni.getStorageSync('location').lng,
|
||||
latitude: uni.getStorageSync('location').lat,
|
||||
page_num: 1,
|
||||
page_size: 10
|
||||
}, { silent: false });
|
||||
if (res.rows && res.rows.length) {
|
||||
// let firstItem = res.rows[0];
|
||||
// firstItem.pic_src = picUrl + firstItem.pic_src;
|
||||
// rightList.push(firstItem);
|
||||
let filterRes = this.filterShowList(res?.rows, 1);
|
||||
const rows = await this.getBannerRows(i);
|
||||
if (rows && rows.length) {
|
||||
let filterRes = this.filterShowList(rows, 1);
|
||||
filterRes.forEach(item => {
|
||||
item.pic_src = picUrl + item.pic_src
|
||||
})
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"appid": "wx1addb25675dd8e70",
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "3.8.3",
|
||||
"libVersion": "3.9.1",
|
||||
"packOptions": {
|
||||
"ignore": [],
|
||||
"include": []
|
||||
@ -19,7 +19,18 @@
|
||||
"disablePlugins": [],
|
||||
"outputPath": ""
|
||||
},
|
||||
"condition": true
|
||||
"condition": true,
|
||||
"compileWorklet": false,
|
||||
"uglifyFileName": false,
|
||||
"uploadWithSourceMap": true,
|
||||
"packNpmManually": false,
|
||||
"minifyWXSS": true,
|
||||
"minifyWXML": true,
|
||||
"localPlugins": false,
|
||||
"disableUseStrict": false,
|
||||
"useCompilerPlugins": false,
|
||||
"swc": false,
|
||||
"disableSWC": true
|
||||
},
|
||||
"condition": {},
|
||||
"editorSetting": {
|
||||
|
||||
@ -2,7 +2,22 @@
|
||||
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
|
||||
"projectname": "uniapp-ZHSQ",
|
||||
"setting": {
|
||||
"compileHotReLoad": true
|
||||
"compileHotReLoad": true,
|
||||
"urlCheck": true,
|
||||
"coverView": true,
|
||||
"lazyloadPlaceholderEnable": false,
|
||||
"skylineRenderEnable": false,
|
||||
"preloadBackgroundData": false,
|
||||
"autoAudits": false,
|
||||
"useApiHook": true,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"useStaticServer": false,
|
||||
"useLanDebug": false,
|
||||
"showES6CompileOption": false,
|
||||
"checkInvalidKey": true,
|
||||
"ignoreDevUnusedFiles": true,
|
||||
"bigPackageSizeSupport": false
|
||||
},
|
||||
"libVersion": "3.9.1"
|
||||
"libVersion": "3.16.0",
|
||||
"condition": {}
|
||||
}
|
||||
@ -19,8 +19,10 @@ const inferExt = (filePath) => {
|
||||
return filePath.substring(idx + 1).toLowerCase();
|
||||
};
|
||||
|
||||
const fetchCredential = (scene, ext) => {
|
||||
const fetchCredential = (scene, ext, bindId) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const data = { scene, ext };
|
||||
if (bindId) data.bind_id = bindId; // 客服聊天场景:按会话分目录
|
||||
uni.request({
|
||||
url: RequsetUrl + "/api/v1/wechat/oss/credential",
|
||||
method: "POST",
|
||||
@ -28,7 +30,7 @@ const fetchCredential = (scene, ext) => {
|
||||
Authorization: uni.getStorageSync("ctoken") || "",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
data: { scene, ext },
|
||||
data,
|
||||
success: (res) => {
|
||||
if (res.statusCode !== 200) return reject(new Error("获取上传凭证失败:" + res.statusCode));
|
||||
const body = res.data || {};
|
||||
@ -78,7 +80,7 @@ const postToOSS = (filePath, cred) => {
|
||||
* @param {boolean} [opts.showLoading=true]
|
||||
* @returns {Promise<{ objectKey: string, url: string }>}
|
||||
*/
|
||||
export const uploadOSS = async ({ filePath, scene, ext, showLoading = true }) => {
|
||||
export const uploadOSS = async ({ filePath, scene, ext, bindId, showLoading = true }) => {
|
||||
if (!filePath) throw new Error("filePath 不能为空");
|
||||
if (!scene) throw new Error("scene 不能为空");
|
||||
|
||||
@ -87,7 +89,7 @@ export const uploadOSS = async ({ filePath, scene, ext, showLoading = true }) =>
|
||||
|
||||
if (showLoading) uni.showLoading({ title: "上传中", mask: true });
|
||||
try {
|
||||
const cred = await fetchCredential(scene, finalExt);
|
||||
const cred = await fetchCredential(scene, finalExt, bindId);
|
||||
await postToOSS(filePath, cred);
|
||||
return {
|
||||
objectKey: cred.object_key,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user