Compare commits

..

1 Commits

Author SHA1 Message Date
ch db61f1f9d9 pref:补充文档
3 years ago

@ -1,3 +0,0 @@
VUE_APP_BASE_URL = https://k8s-horse-gateway.mashibing.cn
VUE_APP_STATIC_URL = https://k8s-shop-app.mashibing.cn
VUE_APP_IM_URL = wss://k8s-horse-gateway.mashibing.cn

@ -1,3 +0,0 @@
VUE_APP_BASE_URL = https://you-gateway.mashibing.com
VUE_APP_STATIC_URL = https://you-app.mashibing.com
VUE_APP_IM_URL = wss://you-gateway.mashibing.com

@ -1,3 +0,0 @@
VUE_APP_BASE_URL = https://you-gateway.mashibing.com
VUE_APP_STATIC_URL = https://you-app.mashibing.com
VUE_APP_IM_URL = wss://you-gateway.mashibing.com

@ -1,3 +0,0 @@
VUE_APP_BASE_URL = https://k8s-horse-gateway.mashibing.com
VUE_APP_STATIC_URL = https://k8s-shop-app.mashibing.com
VUE_APP_IM_URL = wss://k8s-horse-gateway.mashibing.cn

1
.gitignore vendored

@ -4,7 +4,6 @@ node_modules/
unpackage/ unpackage/
dist/ dist/
.history/ .history/
.hbuilderx/
env.js env.js
yarn.lock yarn.lock

@ -0,0 +1,16 @@
module.exports = {
printWidth: 120,
tabWidth: 4,
useTabs: false,
semi: true,
singleQuote: true,
quoteProps: 'as-needed',
jsxSingleQuote: false,
trailingComma: 'es5',
bracketSpacing: true,
bracketSameLine: false,
arrowParens: 'always',
htmlWhitespaceSensitivity: 'ignore',
vueIndentScriptAndStyle: true,
endOfLine: 'auto',
};

@ -2,31 +2,72 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-17 11:30:06 * @Date: 2022-03-17 11:30:06
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-23 21:18:34 * @LastEditTime: 2022-05-30 17:19:59
* @Description: file content * @Description: file content
--> -->
# shopping-app # shopping-app
严选移动端 严选移动端
## 前置环境
由于项目依赖问题,开发 `node` 版本必须是 `14` or `16` ## 技术架构
- uniapp
- vue2
- unicli
>打包构建工具
- vuex
>状态管理
- uni-simple-router
>路由管理更加的贴近vue-router的路由管理器
- uview-ui
>基础UI库
- js-util-all
>基础工具类
- webscoket
>IM通信
## 规范约束
- 使用 VS Code 进行开发,并安装项目推荐的插件
- 不允许修改 src 目录以外的(项目配置)文件
- 有需要优化解决的问题记录到 TODO.md 文件中,包括技术方面的踩坑记录和业务方面的 BUG 记录
- 按照当前项目结构进行功能开发,不允许随意改变项目文件结构
如果想安装多个版本,可以通过使用 `nvm` 进行版本管理。然具体安装可以参考下面教程 ## 项目结构
[window install nvm](https://juejin.cn/post/7074108351524634655) | SRC 目录 | 用途描述 |
[mac install nvm](https://juejin.cn/post/7206882855200047161) | ---------- | ---------------------------- |
| common | 所有JS文件 |
| --api | API 接口定义 |
| --config | 项目内配置文件 |
| --dicts | 项目中的静态字典表 |
| --plugins | 全局插件 |
| --store | 数据状态模块 |
| --utils | 工具类库模块 |
| components | 自定义通用组件 |
| pages | 页面文件 |
| static | 存放应用的本地静态资源的目录 |
## 公共方法 utils
- 公共方法统一放置 utils 文件夹内,可以按分类建方法文件 如:验证类 verify.js 请求类 request.js
## 开发须知
### 路由页面
- 页面代码尽量做业务模块拆分,禁止出现大几百行上千行的页面文件
- 页面业务模块应就在当前页面目录下创建module 不要放到src/components下
### 工具类utils
- 项目集成js-util-all基础组件不需要重复造轮子
- 公共方法统一放置utils文件夹内可以按分类建方法文件 如验证类verify.js 请求类request.js
- 所有公共方法采用大驼峰命名法 - 所有公共方法采用大驼峰命名法
- 所有的方法都从 index.js 输出,引入时统一引入 index不允许直接引入方法文件 - 所有的方法都从index.js输出引入时统一引入index不允许直接引入方法文件
- 所有方法文件如果导出的是多个方法,不允许在定义方法时导出,必须在文件底部一一导出,并附上方法简单的注释 - 所有方法文件如果导出的是多个方法,不允许在定义方法时导出,必须在文件底部一一导出,并附上方法简单的注释
- 方法头部必须有使用注释
```js ``` js
// 正确 // 正确
import {Req, IsPhone} from '@/common/utils'; import {Req, IsPhone} from '@/common/utils';
@ -35,7 +76,17 @@ import {Req} from '@/common/utils/request';
import {IsPhone} from '@/common/utils/utils'; import {IsPhone} from '@/common/utils/utils';
// 正确 // 正确
/**
* 判断是否为手机号
* @param {String | Number} str 手机号
* @return {Boolean}
*/
const IsPhone = (str) => {....} const IsPhone = (str) => {....}
/**
* 判断是否为邮箱
* @param {String} str 邮箱号
* @return {Boolean}
*/
const IsEmail = (str) => {....} const IsEmail = (str) => {....}
export { export {
// 判断手机号 // 判断手机号
@ -49,20 +100,27 @@ export const IsPhone = (str) => {....}
export const IsEmail = (str) => {....} export const IsEmail = (str) => {....}
``` ```
### 组件
- 请务必使用easycom模式引入第三方组件
- 所有的自定义组件文件名以大驼峰命名且在templet中使用也用大驼峰形式使用
- 组件分两种类型业务类型、UI功能类型命名区分(Bsxxx:业务组件、Uixxx:UI功能组件)
- 页头写好使用注释props slot methods events
## 组件
- 请务必使用 easycom 模式引入第三方组件 ### 状态管理以及存储
- 根目录的 components 只放置真正的组件,某个页面的业务模块应该在 pages 的相应目录下新建 components 目录放置
- 所有的自定义组件文件名以大驼峰命名,且在 templet 中使用也用大驼峰形式使用
## 请求 - 每个功能模块都要对应一个数据状态管理模块
- 必须通过 mutations 修改 state 中的数据
- 接口调用及后续数据逻辑处理应在 actions 中进行,保证多处调用时行为统一
- 使用本存储时必须与 vuex 结合使用,不允许直接在页面中操作本地存储;
- 所有存储 key 必须在 config 中 sotrageKey.js 中定义;
- 所有请求方法命名以Api+请求类型+具体方) 法命名
- 所有请求使用 ToAsyncAwait 包裹
- 不允许使用 try catch 和 then 处理返回结果
```js ### 请求
- 所有请求方法命名以Api+请求类型+具体方法) 法命名
- 所有请求使用ToAsyncAwait 包裹
- 不允许使用try catch 和 then 处理返回结果
``` js
// 使用示例 // 使用示例
// xxapi.js // xxapi.js
import {ToAsyncAwait, ReqestTk} from '@/common/utils' import {ToAsyncAwait, ReqestTk} from '@/common/utils'
@ -84,8 +142,47 @@ export const IsEmail = (str) => {....}
} }
``` ```
### 图片
- 按pages目录结果放置图片
- 有公共使用的图片请放到static/common文件夹内
### 样式相关
- 样式命名方式采取BEM命名优先法则
- 参考 src/styles/gobalVariables.module.less颜色、字号、边距、圆角尽可能复用已有的变量
- 没有特殊需求不允许写全局样式stlye 标签必须加 scoped
- 没有特殊需求不允许定义或使用 ID 选择器、属性选择器
## 代码库
### 分支管理
- 分支命名:特性/任务-日期-创建人例如fix/213-0505-ch
- 所有新开发功能或修复BUG应基于 prod 分支创建未上线以提测的Bug则在原有开发分支上继续开发即可
- 提测则将开发分支合并到功能分支,再将功能分支合并到 test 分支,严禁将 test 分支合并进其他任何分支
- 测试通过后先将 beta 分支合并到功能分支解决冲突,再通过提 push request 通知负责人进行代码审查,审查通过后由负责人合并代码
- 预发通过后先将 特性分支 分支合并到 beta 分支解决冲突,再将 beta 分支合并到 dev 分支,此操作只能由负责人进行
- 解决冲突时如涉及其他开发者代码,应跟当事人确认无误后再合并;
### 提交代码
- 提交前确认项目能正常运行,改动部分功能正常
- 严格遵循 eslint、prettier 代码规范
- 严禁使用 git commit --no-verify -m "xxx" 强制提交代码
- 规范提交信息
| 前缀 | 使用场景 | 示例 |
| -------- | ------------------------------ | -------------------------- |
| feat | 新增功能点、模块 | feat: 用户管理 |
| fix | 修复 BUG | fix: 用户管理分页异常 |
| doc | 文档、注释更新 | doc: README |
| style | 样式、不影响逻辑的代码格式更新 | style: 用户管理标题字号 |
| refactor | 重构功能点、模块 | refactor: 路由模块逻辑重构 |
| test | 测试 | test: 测试工具类 |
| revert | 撤回提交 | revert: 有文件漏提交 |
| build | 编译打包 | build: 编译用户管理 |
| merge | 合并分支 | merge: beta into dev |
| perf | 性能、体验、逻辑优化 | pref: 路由模块解析性能 |
| conf | 配置更新 | conf: 项目 base 路径 |
| chore | 其他 | chore: 其他 |
## 图片
- 按 pages 目录结果放置图片
- 有公共使用的图片请放到 static/common 文件夹内

@ -0,0 +1,14 @@
<!--
* @Author: ch
* @Date: 2022-05-30 17:20:49
* @LastEditors: ch
* @LastEditTime: 2022-05-30 17:29:43
* @Description: file content
-->
# uni提供的请求方式使用不方便
# HBuild 打包繁琐
使用unicli改进自动化部署
# 从不同页面进入购物车要展示1级或2级页面样式的购物车
# flex布局对齐方式的兼容问题

@ -0,0 +1,46 @@
/*
* @Author: ch
* @Date: 2022-05-05 14:40:00
* @LastEditors: ch
* @LastEditTime: 2022-05-26 19:04:26
* @Description: 根据git分支生成对应环境的环境变量
* 开发时如果环境变量换了可以不用重启服务直接运行node env.config.js即可
*/
const fs = require('fs');
const path = require('path');
const envConfig = {
dev : {
baseUrl: 'https://k8s-horse-gateway.mashibing.cn',
staticUrl : 'https://k8s-shop-app.mashibing.cn',
imUrl : 'wss://k8s-horse-gateway.mashibing.cn'
},
test : {
baseUrl: 'https://k8s-horse-gateway.mashibing.cn',
staticUrl : 'https://k8s-shop-app.mashibing.cn',
imUrl : 'wss://k8s-horse-gateway.mashibing.cn'
},
beta : {
baseUrl: 'https://you-gateway.mashibing.com',
staticUrl : 'https://you-app.mashibing.com',
imUrl : 'wss://you-gateway.mashibing.com'
},
prod : {
baseUrl: 'https://you-gateway.mashibing.com',
staticUrl : 'https://you-app.mashibing.com',
imUrl : 'wss://you-gateway.mashibing.com'
}
}
let curEnvConfig = null;
const argv = global.process.argv;
for(key in envConfig){
if(argv.includes(`--ENV:${key}`)){
curEnvConfig = envConfig[key];
break;
}
}
if(!curEnvConfig){
curEnvConfig = envConfig.dev;
}
fs.writeFileSync(`${path.resolve(__dirname, './src/common/config')}/env.js`,
`const ENV = ${JSON.stringify(curEnvConfig)}; export default ENV;`);

23183
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -3,18 +3,15 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"server": "npm run dev:h5", "serve": "node env.config.js & npm run dev:h5",
"server:test": "npm run dev:h5-test", "serve:bate": "node env.config.js --ENV:beta & npm run dev:h5",
"server:bate": "npm run dev:h5-bate", "serve:prod": "node env.config.js --ENV:prod & npm run dev:h5",
"server:prod": "npm run dev:h5-prod", "build": "npm run build:h5",
"build:test": "npm run build:h5-test",
"build:bate": "npm run build:h5-bate",
"build:prod": "npm run build:h5-prod",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build", "build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom", "build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5-test": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build --mode test", "build:h5": "node env.config.js --ENV:test & cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:h5-bate": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build --mode bate", "build:h5:bate": "node env.config.js --ENV:beta & cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:h5-prod": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build --mode prod", "build:h5:prod": "node env.config.js --ENV:prod & cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build", "build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build", "build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build", "build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
@ -32,9 +29,6 @@
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch", "dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom", "dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve", "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:h5-test": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve --mode test",
"dev:h5-bate": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve --mode bate",
"dev:h5-prod": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve --mode prod",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch", "dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch", "dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch", "dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
@ -77,36 +71,35 @@
"@dcloudio/uni-quickapp-webview": "^2.0.1-34720220422002", "@dcloudio/uni-quickapp-webview": "^2.0.1-34720220422002",
"@dcloudio/uni-stat": "^2.0.1-34720220422002", "@dcloudio/uni-stat": "^2.0.1-34720220422002",
"@vue/shared": "^3.0.0", "@vue/shared": "^3.0.0",
"caniuse-lite": "^1.0.30001640",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"flyio": "^0.6.2", "flyio": "^0.6.2",
"regenerator-runtime": "^0.12.1",
"vue": "^2.6.11",
"vuex": "^3.2.0",
"js-util-all": "^1.0.6", "js-util-all": "^1.0.6",
"mp-html": "^2.2.2", "mp-html": "^2.2.2",
"regenerator-runtime": "^0.12.1",
"uni-read-pages": "^1.0.5", "uni-read-pages": "^1.0.5",
"uni-simple-router": "^2.0.7", "uni-simple-router": "^2.0.7",
"uview-ui": "^2.0.29", "uview-ui": "^2.0.29"
"vue": "^2.6.11",
"vuex": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/runtime": "~7.12.0", "@babel/runtime": "~7.12.0",
"@dcloudio/types": "^2.6.7", "@dcloudio/types": "^2.6.7",
"@dcloudio/uni-automator": "2.0.2-4010520240507001", "@dcloudio/uni-automator": "^2.0.1-34720220422002",
"@dcloudio/uni-cli-i18n": "2.0.2-4010520240507001", "@dcloudio/uni-cli-i18n": "^2.0.1-34720220422002",
"@dcloudio/uni-cli-shared": "2.0.2-4010520240507001", "@dcloudio/uni-cli-shared": "^2.0.1-34720220422002",
"@dcloudio/uni-migration": "2.0.2-4010520240507001", "@dcloudio/uni-migration": "^2.0.1-34720220422002",
"@dcloudio/uni-template-compiler": "2.0.2-4010520240507001", "@dcloudio/uni-template-compiler": "^2.0.1-34720220422002",
"@dcloudio/vue-cli-plugin-hbuilderx": "2.0.2-4010520240507001", "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.1-34720220422002",
"@dcloudio/vue-cli-plugin-uni": "2.0.2-4010520240507001", "@dcloudio/vue-cli-plugin-uni": "^2.0.1-34720220422002",
"@dcloudio/vue-cli-plugin-uni-optimize": "2.0.2-4010520240507001", "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.1-34720220422002",
"@dcloudio/webpack-uni-mp-loader": "2.0.2-4010520240507001", "@dcloudio/webpack-uni-mp-loader": "^2.0.1-34720220422002",
"@dcloudio/webpack-uni-pages-loader": "2.0.2-4010520240507001", "@dcloudio/webpack-uni-pages-loader": "^2.0.1-34720220422002",
"@vue/cli-plugin-babel": "~4.5.15", "@vue/cli-plugin-babel": "~4.5.15",
"@vue/cli-service": "~4.5.15", "@vue/cli-service": "~4.5.15",
"babel-plugin-import": "1.13.8", "babel-plugin-import": "^1.11.0",
"cross-env": "7.0.3", "cross-env": "^7.0.2",
"jest": "25.5.4", "jest": "^25.4.0",
"mini-types": "*", "mini-types": "*",
"miniprogram-api-typings": "*", "miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0", "postcss-comment": "^2.0.0",

@ -1,10 +1,3 @@
<!--
* @Author: ch
* @Date: 2022-05-27 17:44:36
* @LastEditors: ch
* @LastEditTime: 2022-06-29 21:37:10
* @Description: file content
-->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-CN"> <html lang="zh-CN">
@ -21,7 +14,7 @@
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" /> <link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head> </head>
<body class="page"> <body>
<noscript> <noscript>
<strong>Please enable JavaScript to continue.</strong> <strong>Please enable JavaScript to continue.</strong>
</noscript> </noscript>

@ -1,18 +0,0 @@
/*
* @Author: ch
* @Date: 2022-05-31 11:17:38
* @LastEditors: ch
* @LastEditTime: 2022-05-31 11:35:10
* @Description: file content
*/
import {ToAsyncAwait, MsbRequest} from '@/common/utils';
import { AD_PLATFORM } from '../dicts/ad';
const BASE_URL = '/mall/marketing';
// 获取广告列表
export const ApiGetAdList = (params) => ToAsyncAwait(MsbRequest.get(`${BASE_URL}/app/advertisement`, {
platform : AD_PLATFORM.MOBILE,
...params
}))

@ -2,34 +2,13 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-06 17:29:13 * @Date: 2022-04-06 17:29:13
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-31 11:18:44 * @LastEditTime: 2022-04-15 14:17:14
* @Description: file content * @Description: file content
*/ */
import {ToAsyncAwait, MsbRequest, MsbRequestTk} from '@/common/utils'; import {ToAsyncAwait, MsbRequestTk} from '@/common/utils';
const BASE_URL = '/mall/base'; const BASE_URL = '/mall/base';
const BASE_URL_UC = '/uc';
/**
* 登录
* @param {*} data
*/
export const ApiPostLogin = (data) => ToAsyncAwait(MsbRequest.post(`${BASE_URL_UC}/user/login`, data));
/**
* 退出登录
* @param {*} data
*/
export const ApiGetLogout= () => ToAsyncAwait(MsbRequest.get(`${BASE_URL_UC}/user/logout`));
/**
* 获取手机验证码
* @param {*} params
*/
export const ApiGetCode = (params) => ToAsyncAwait(MsbRequest.get(`${BASE_URL_UC}/user/login/verificationCode`, params));
/** /**
* 获取收货地址 * 获取收货地址
*/ */

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

@ -1,16 +1,48 @@
/* // /*
* @Author: ch // * @Author: ch
* @Date: 2022-05-27 17:44:36 // * @Date: 2022-05-18 15:21:10
* @LastEditors: ch // * @LastEditors: ch
* @LastEditTime: 2022-06-09 11:34:36 // * @LastEditTime: 2022-05-18 17:24:37
* @Description: file content // * @Description: file content
*/ // */
import {ToAsyncAwait, MsbRequestTk} from '@/common/utils'; // import { MsbSkt } from "../utils/webSkt";
const BASE_URL = '/mall/im'; // import { CreateUUID } from '@/common/utils';
/** // /**
* 获取soket登录秘钥 // * 系统消息心跳
*/ // */
export const ApiGetSoketTicket = () => ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/ticket`, { // export const ApiSktSysHeart = () => MsbSkt.send({
ticketType: 'CONNECT_TICKET' // traceId: CreateUUID(),
})); // traceType: '0',
// content: { text: "ping" }
// });
// /**
// * 获取系统通知会话
// * @param {*} content
// */
// export const ApiSktSysGetSession = (content) => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '1',
// content
// });
// /**
// * 获取系统消息历史消息
// * @param {*} content
// */
// export const ApiSktSysGetHistory = (content) => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '2',
// content
// });
// /**
// * 系统消息已读
// * @param {*} content
// */
// export const ApiSktSysGetHistory = (content) => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '6',
// content
// });

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-29 17:38:17 * @Date: 2022-03-29 17:38:17
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-23 16:21:32 * @LastEditTime: 2022-05-10 16:14:53
* @Description: file content * @Description: file content
*/ */
import {ToAsyncAwait, MsbRequestTk} from '@/common/utils'; import {ToAsyncAwait, MsbRequestTk} from '@/common/utils';
@ -84,11 +84,8 @@ export const ApiPutCancelOrder = (data) =>
export const ApiGetOrderStatistics = () => export const ApiGetOrderStatistics = () =>
ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/app/tradeOrder/statistics`)); ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/app/tradeOrder/statistics`));
/**
* 获取待评价订单详请列表
*/
export const ApiGetCommentOrderDetailList = (params) =>
ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/app/tradeOrder/listOrderProductWaitComment`,params))
/** /**

@ -1,51 +0,0 @@
/*
* @Author: ch
* @Date: 2022-04-28 16:30:54
* @LastEditors: ch
* @LastEditTime: 2022-07-09 10:16:00
* @Description: file content
*/
import {ToAsyncAwait, MsbRequest, MsbRequestTk} from '@/common/utils';
const BASE_URL = '/mall/trade';
export const ApiPostCashierPrepay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/payCenter/cashierPrepay`, data));
/**
* 微信h5支付获取支付URL
* @param {*} data
*/
export const ApiPostWxH5Pay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/payCenter/wxPay/h5`, data));
/**
* 微信JSAPI支付获取支付参数
* @param {*} data
*/
export const ApiPostWxJsApiPay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/payCenter/wxPay/jsapi`, data));
/**
* 微信APP支付
* @param {*} data
*/
export const ApiPostWxAppPay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/payCenter/wxPay/app`, data));
/**
* 支付宝APP支付
* @param {*} data
*/
export const ApiPostAliAppPay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/payCenter/aliPay/app`, data));
/**
* 支付宝h5支付获取支付URL
* @param {*} data
*/
export const ApiPostAliH5Pay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/payCenter/aliPay/wap`, data));

@ -2,12 +2,13 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-28 16:30:54 * @Date: 2022-04-28 16:30:54
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-29 17:16:50 * @LastEditTime: 2022-05-17 20:07:26
* @Description: file content * @Description: file content
*/ */
import {ToAsyncAwait, MsbRequest, MsbRequestTk} from '@/common/utils'; import {ToAsyncAwait, MsbRequest, MsbRequestTk} from '@/common/utils';
const BASE_URL = '/mall/trade';
// 第三方鉴权服务 // 第三方鉴权服务
const AUTH_URL = '/third'; const AUTH_URL = '/third';
const APPID = 'wxd2015f0c56defa02'; const APPID = 'wxd2015f0c56defa02';
@ -32,3 +33,24 @@ export const ApiGetOpenId = ({code}) =>
*/ */
export const ApiPostThirdInfo = (data) => export const ApiPostThirdInfo = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${AUTH_URL}/third/saveThirdInfo`, {...data, appId:APPID})); ToAsyncAwait(MsbRequestTk.post(`${AUTH_URL}/third/saveThirdInfo`, {...data, appId:APPID}));
/**
* 微信h5支付获取支付URL
* @param {*} data
*/
export const ApiPostWxH5Pay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/pay/wxPay/h5`, data));
/**
* 微信JSAPI支付获取支付参数
* @param {*} data
*/
export const ApiPostWxJsApiPay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/pay/wxPay/jsapi`, data));
/**
* 微信APP支付
* @param {*} data
*/
export const ApiPostWxAppPay = (data) =>
ToAsyncAwait(MsbRequestTk.post(`${BASE_URL}/pay/wxPay/app`, data));

@ -1,42 +0,0 @@
/*
* @Author: ch
* @Date: 2022-05-31 11:05:08
* @LastEditors: ch
* @LastEditTime: 2022-05-31 17:23:02
* @Description: file content
*/
const AD_PLATFORM = {
PC: 2,
MOBILE : 1
}
const AD_LOCATION = {
// 首页轮播图
HOME_BANNER: 1,
// 首页精装区
HOME_HARDCOVER: 2,
// 分类banner
CATEGORY_BANNER : 3
}
const AD_JUMP_TYPE = {
// 商品详情
GOODS: 1,
// 分类
CATEGORY: 2,
// 链接
LINK: 3,
// 不跳转
NO_JUMP : 4
}
export {
// 广告所属平台
AD_PLATFORM,
// 广告位置
AD_LOCATION,
// 广告跳转类型
AD_JUMP_TYPE
}

@ -1,33 +0,0 @@
/*
* @Author: ch
* @Date: 2022-06-20 11:10:23
* @LastEditors: ch
* @LastEditTime: 2022-06-28 16:33:25
* @Description: file content
*/
export default {
TYPE : {
// 评价
COMMENT: 1,
// 追评
FOLLOW_COMMENT: 2,
// 回复
ANSWER: 3,
},
// 是否显示
DISPLAY: {
SHOW: 1,
HIDE : 0
},
// 用户类型
USER_TYPE: {
STORE : 1,
USER : 2
},
// 是否默认评价
IS_DEFAULT_COMMENT: {
YES: 1,
NOT : 0
},
RATE_LABEL : ['非常不满意','不满意','一般','满意','非常满意']
}

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-26 11:49:16 * @Date: 2022-05-26 11:49:16
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 11:23:02 * @LastEditTime: 2022-05-26 17:00:06
* @Description: file content * @Description: file content
*/ */
@ -11,25 +11,13 @@ export const ORDER_STATUS = {
// 待支付 // 待支付
AWAIT_PAY: 1 AWAIT_PAY: 1
} }
export default { export const ORDER_TYPE = {
TYPE : { //(1, "普通订单"),
//(1, "普通订单"), NORMAL: 1,
NORMAL: 1, //(2, "免费订单"),
//(2, "免费订单"), FREE: 2,
FREE: 2, //(3, "秒杀订单"),
//(3, "秒杀订单"), SECKILL: 3,
SECKILL: 3, //(4, "虚拟商品订单"),
//(4, "虚拟商品订单"), VIRTUAL : 4
VIRTUAL : 4
},
// 订单状态 1待支付2已关闭3已支付4已发货5已收货6已完成7已追评
STATUS: {
AWAIT_PAY: 1,
CLOSE: 2,
FINISH_PAY: 3,
FINISH_SEND_GOODS: 4,
FINISH_TAKE_GOODS: 5,
FINISH: 6,
FINISH_FOLLOW_COMMENT : 7
}
} }

@ -2,482 +2,362 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-18 14:54:47 * @Date: 2022-05-18 14:54:47
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-14 17:24:14 * @LastEditTime: 2022-05-24 22:51:47
* @Description: file content * @Description: file content
*/ */
import { CreateUUID, FormatDate, ToAsyncAwait } from "@/common/utils"; import { CreateUUID, FormatDate, ToAsyncAwait } from "@/common/utils";
import './potoReq'; const connect = Symbol('connect'),
import './protoRsp' send = Symbol('send'),
const connect = Symbol('connect'); onResponse = Symbol('onResponse'),
const send = Symbol('send'); onMessage = Symbol('onMessage'),
const onMessage = Symbol('onMessage'); updateData = Symbol('updateData')
const fromatPotoReq = (traceId, traceType, content) => { ;
let messageModel = new proto.ReqModel(); export default class MsbIm {
messageModel.setTraceid(traceId); option = {
messageModel.setTracetype(traceType); ioKey : 'traceId',
content && messageModel.setContent(JSON.stringify(content)); reconnect: true,
return messageModel.serializeBinary(); logout : false
}, }
fromatPotoRsp = (data) => { socket = null;
const res = proto.RspModel.deserializeBinary(new Uint8Array(data)); queue = {};
let ctx = res.getContent(); interceptors = {
ctx = ctx ? JSON.parse(ctx) : {}; dataChangeBefore: null,
if (ctx.payload) { dataChangeAfter: null,
ctx.payload = JSON.parse(ctx.payload); onLogout : null,
} onMessage: null
return {
content: ctx,
traceId: res.getTraceid(),
traceType: res.getTracetype(),
code: res.getCode(),
message: res.getMessage(),
};
};
};
sessionData = [];
curSessionId = null;
class MsbIm { constructor(option) {
defaultOption = { this.option = {
ioKey: 'traceId', ...this.option,
reconnect: true, ...option
}; }
socket = null; }
isOpen = false; /**
queue = {}; * 创建连接返回一个Promise 创建成功并成功打开连接算连接成功
interceptors = { * @param {*} option
dataChangeBefore: null, */
dataChangeAfter: null,
onClose: null,
onMessage: null,
};
sessionData = [];
curSessionId = null;
constructor(option) {
this.option = {
...this.defaultOption,
...option,
};
}
/** [connect](option) {
* 创建连接返回一个Promise 创建成功并成功打开连接算连接成功 return new Promise((resolve, reject) => {
* @param {*} option this.socket = uni.connectSocket({
*/ ...option,
[connect](option) { fail(e){
return new Promise((resolve, reject) => { reject(e);
const open = () => { }
console.log('[im] open'); });
this.isOpen = true; this.socket.onOpen(() => {
resolve(this.socket); this.socket.onMessage(async (res) => {
}; const result = JSON.parse(res.data);
const message = async (res) => { if (result.content?.payload) {
const result = fromatPotoRsp(res.data); result.content.payload = JSON.parse(result.content.payload);
this.interceptors.onMessage && this.interceptors.onMessage(result); }
// 处理服务端主动推送的消息 // 401主动退出
this[onMessage](result); if (result.code === 401) {
this.logout();
return false;
}
this.interceptors.onMessage && this.interceptors.onMessage(result);
// 处理服务端主动推送的消息
this[onMessage](result);
// 如果再消息堆里有此消息回调,则执行回调,并删除 // 如果再消息堆里有此消息回调,则执行回调,并删除
const cbk = this.queue[result[this.option.ioKey]]; const cbk = this.queue[result[this.option.ioKey]];
if (cbk) {
cbk(result.code !== 200 ? {error:result} : {result:result});
delete this.queue[result[this.option.ioKey]];
}
})
resolve(this.socket);
});
this.socket.onClose(() => {
if (this.option.reconnect && !this.option.logout) {
this[connect]();
}
this.option.logout = false;
});
});
}
/**
* 向服务端发送消息||请求返回一个Promise对象收到ioKey对应的消息会算一个同步完成
* @param {*} data
*/
[send](data) {
return new Promise((resolve, reject) => {
this.queue[data[this.option.ioKey]] = ({result, error}) => {
if (result) {
resolve(result);
} else {
reject(error);
}
};
this.socket.send({
data : JSON.stringify(data),
fail(e) {
reject({error : e});
}
});
})
}
/**
* 服务端推送消息只处理服务端主动推送的消息
* @param {*} data
*/
[onMessage](data) {
// 判断非服务端主动推送消息不做处理
if (data[this.option.ioKey] || data.code !== 200) {
return false;
}
let ctx = data.content;
let historyData = [...this.sessionData],
newData = [];
const hisIndex = historyData.findIndex(i => i.id === ctx.sessionId);
if(hisIndex >= 0){
// 存在会话往现有会话增加一条消息,并修改最后一条消息为当前消息
const curHisData = historyData[hisIndex];
curHisData.messageList.push(ctx);
curHisData.lastMessage = ctx;
// 不在当前会话窗口则向会话消息加1条未读
if(ctx.sessionId !== this.curSessionId){
curHisData.unreadCount++;
}
newData = historyData;
}else{
// 会话列表不存在,则创建一个会话
newData = [...historyData, {
fromAvatar : ctx.fromAvatar,
fromId : ctx.fromId,
fromNickname : ctx.fromNickname,
id : ctx.id,
lastMessage : ctx,
messageList : [ctx],
unreadCount : 1
}]
}
this.setSessionData(newData)
if (cbk) { }
cbk(result.code !== 200 ? { error: result } : { result: result }); init (config) {
delete this.queue[result[this.option.ioKey]]; return new Promise((resolve, reject) => {
} const heart = () => {
}; setTimeout(async () => {
const close = () => { await this[send]({
console.log('[im] close'); traceId: CreateUUID(),
this.interceptors.onClose && this.interceptors.onClose(); traceType: '0',
}; content: { text: "ping" }
let isUni = false; }).catch((e)=>{});
try { heart();
isUni = uni; },5000)
} catch (e) { }
isUni = false; this[connect]({
} ...config,
if (isUni) { }).then(() => {
this.socket = uni.connectSocket({ heart();
...this.option, resolve(this);
fail(e) { }).catch((e)=>{});
reject(e); })
},
});
this.socket.onOpen(() => {
open();
this.socket.onMessage((res) => {
message(res);
});
});
this.socket.onClose(() => {
close();
});
} else if (WebSocket) {
try {
this.socket = new WebSocket(this.option.url);
this.socket.binaryType = 'arraybuffer';
this.socket.onopen = () => {
open();
};
this.socket.onmessage = (res) => {
message(res);
};
this.socket.onclose = () => {
close();
};
} catch (e) {
reject(e);
}
}
});
}
/**
* 向服务端发送消息||请求返回一个Promise对象收到ioKey对应的消息会算一个同步完成
* @param {*} data
*/
[send](data) {
return new Promise((resolve, reject) => {
if (!this.isOpen) {
return reject('连接未打开');
}
this.queue[data[this.option.ioKey]] = ({ result, error }) => {
if (result) {
resolve(result);
} else {
reject(error);
}
};
const par = fromatPotoReq(data.traceId, data.traceType, data.content); }
logout() {
this.option.logout = true;
this.socket.close();
this.interceptors.onLogout && this.interceptors.onLogout();
}
/**
* 设置数据
*/
setSessionData(data) {
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(data, this.sessionData);
this.sessionData = data;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
}
/**
* 设置当前聊天窗口
* Data为Session数据
* @param {*} data
*/
setCurSessionId(id) {
this.curSessionId = id;
}
/**
* 获取会话列表
* @param {*} params
*/
async getSessionList(params) {
let isUni = false; let {error, result} = await ToAsyncAwait(this[send]({
try { traceId: CreateUUID(),
isUni = uni; traceType : 1,
} catch (e) { ...params
isUni = false; }));
} if (error) {
if (isUni) { return Promise.reject(error);
this.socket.send({ }
data: par, const { content } = result;
fail(e) { content.sessionVOS.forEach(item => {
reject({ error: e }); if (item.lastMessage) {
}, item.lastMessage.payload = JSON.parse(item.lastMessage.payload || {});
}); }
} else if (WebSocket) { let historyData = this.sessionData;
this.socket.send(par); let hisIndex = historyData.findIndex(i => i.id === item.id);
} if(hisIndex >= 0){
}); historyData[hisIndex].lastMessage = item.lastMessage;
} historyData[hisIndex].unreadCount++;
/** this.setSessionData(historyData)
* 服务端推送消息只处理服务端主动推送的消息 }else{
* @param {*} data item.messageList = [];
*/ const newData = [...historyData, item]
[onMessage](data) { this.setSessionData(newData);
// 判断非服务端主动推送消息不做处理 }
if (data[this.option.ioKey] || data.code !== 200) { });
return false; return Promise.resolve(result);
} }
console.log('[im] 主动接收的消息', data); /**
let ctx = data.content; * 获取会话的历史消息记录
let historyData = [...this.sessionData], * @param {*} params
newData = []; */
const hisIndex = historyData.findIndex((i) => i.id === ctx.sessionId); async getHistoryMsg(params) {
if (hisIndex >= 0) { const {error, result} = await ToAsyncAwait(this[send]({
// 存在会话往现有会话增加一条消息,并修改最后一条消息为当前消息 traceId: CreateUUID(),
const curHisData = historyData[hisIndex]; traceType: 23,
curHisData.messageList.push(ctx); ...params
curHisData.lastMessage = ctx; }));
// 不在当前会话窗口则向会话消息加1条未读 if (error) {
if (ctx.sessionId !== this.curSessionId) { return Promise.reject(error);
curHisData.unreadCount++; }
} else { const { content } = result;
this.setRead({ if (content.length) {
content: { let newData = this.sessionData;
sessionId: this.curSessionId, const hisIdx = newData.findIndex(i => i.id === content[0].sessionId);
}, content.forEach(item => {
}); item.payload = JSON.parse(item.payload)
} })
newData = historyData; newData[hisIdx].messageList = newData[hisIdx].messageList.concat(content);
} else { this.setSessionData(newData);
// 会话列表不存在,则创建一个会话 }
newData = [ return Promise.resolve(result);
...historyData,
{
fromAvatar: ctx.session.fromAvatar,
fromId: ctx.session.fromId,
fromNickname: ctx.session.fromNickname,
id: ctx.sessionId,
lastMessage: ctx,
messageList: [ctx],
updateTimeStamp: ctx.createTimeStamp,
unreadCount: 1,
},
];
}
this.setSessionData(newData);
}
init(config) {
return new Promise((resolve, reject) => {
const heart = () => {
// 要优化 心跳没回复需要重连
setTimeout(async () => {
if (this.isOpen) {
await this[send]({
traceId: CreateUUID(),
traceType: 0,
content: { text: 'ping' },
});
}
heart();
}, 1000);
};
this.option = {
...this.option,
...config,
};
this[connect]()
.then((res) => {
resolve(res);
heart();
})
.catch((e) => {
console.log('eeeee', e);
});
});
}
/**
* 设置数据
*/
setSessionData(data) {
let newData = JSON.parse(JSON.stringify(data));
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
this.sessionData = newData;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
}
/**
* 设置当前聊天窗口
* Data为Session数据
* @param {*} data
*/
setCurSessionId(id) {
this.curSessionId = id;
}
/**
* 获取会话列表
* @param {*} params
*/
async getSessionList(params) {
const par = {
traceId: CreateUUID(),
traceType: 1,
...params,
};
console.log('[im] 获取会话列表--start', par); }
let { error, result } = await ToAsyncAwait(this[send](par)); /**
console.log('[im] 获取会话列表--end', result, error); * 会话已读
if (error) { * @param {*} params
return Promise.reject(error); */
} async setRead (params){
const { content } = result; await this[send]({
// let newData = []; traceId : CreateUUID(),
traceType : "6",
...params
});
let newData = this.sessionData.map(item => {
if (item.id == params.content.sessionId) {
item.unreadCount = 0;
}
return item;
});
content.sessionVOS.forEach((item) => { this.setSessionData(newData);
if (item.lastMessage) { }
item.lastMessage.payload = JSON.parse(item.lastMessage.payload || {}); /**
} * 发送消息
let historyData = this.sessionData; * @param {*} params
let hisIndex = historyData.findIndex((i) => i.id === item.id); */
if (hisIndex < 0) { async sendMsg(params) {
item.messageList = []; const index = this.sessionData.findIndex(i => i.id === this.curSessionId)
} let curSession = this.sessionData[index];
// let historyData = this.sessionData; // 临时消息体
// let hisIndex = historyData.findIndex((i) => i.id === item.id); let par = {
// if (hisIndex >= 0) { ...params,
// historyData[hisIndex].lastMessage = item.lastMessage; traceId: CreateUUID(),
// historyData[hisIndex].unreadCount++; traceType: 20,
// newData.push(historyData[hisIndex]); }
// } else { let msgCtx = {
// item.messageList = []; ...params.content,
// newData = [...newData, item]; ...par,
// } fromId: params.fromId,
}); createTimeStamp : (new Date()).getTime(),
this.setSessionData(content.sessionVOS); sendStatus : 'loading'
return Promise.resolve(result); }
} // 点发送,立即把消息加入消息列表,标记为发送中状态
/** curSession.messageList.push(msgCtx);
* 获取会话的历史消息记录 // 超过时间未返回视为发送失败
* @param {*} params this.timerStatus(msgCtx);
*/ const { error, result } = await ToAsyncAwait(this[send](par));
async getHistoryMsg() { // 接到通知,标记消息是否发送成功
const curSessionIdx = this.sessionData.findIndex((i) => i.id === this.curSessionId); for (let i = curSession.messageList.length; i--;) {
const curSession = this.sessionData[curSessionIdx]; const item = curSession.messageList[i];
console.log(curSession, this.curSessionId, 'this.curSessionId'); if (item[this.option.ioKey] === par[this.option.ioKey]) {
const msgList = curSession.messageList || []; curSession.messageList[i].sendStatus = msgCtx.sendStatus = error ? 'fail' : 'success';
const par = { break;
traceId: CreateUUID(), }
traceType: 2, }
content: { let newData = [...this.sessionData];
sessionId: this.curSessionId, newData[index] = curSession;
topMessageId: msgList.length ? msgList[0].id : null, this.setSessionData(newData);
}, if (error) {
}; return Promise.reject(error);
console.log('[im] 获取会话历史消息--start', par); }
const { error, result } = await ToAsyncAwait(this[send](par));
console.log('[im] 获取会话历史消息--end', result, error);
if (error) {
return Promise.reject(error);
}
const { content } = result;
if (content.length) {
let newData = this.sessionData;
content.forEach((item) => {
item.payload = JSON.parse(item.payload);
});
newData[curSessionIdx].messageList = content.concat(newData[curSessionIdx].messageList);
this.setSessionData(newData);
}
return Promise.resolve(result);
}
/**
* 会话已读
* @param {*} params
*/
async setRead(params) {
const par = {
traceId: CreateUUID(),
traceType: '6',
...params,
};
console.log('[im] 会话已读--start', par);
const { error, result } = await this[send](par);
console.log('[im] 会话已读--end', result, error);
let newData = this.sessionData.map((item) => { return Promise.resolve(result);
if (item.id == params.content.sessionId) { }
item.unreadCount = 0; /**
} * 发送失败时重新发送
return item; * @param {*} params
}); */
async resend(params) {
params.sendStatus = 'loading';
this.timerStatus(params)
const { error, result } = await ToAsyncAwait(this[send]({
traceId: params.traceId,
traceType: params.traceType,
content : params.content
}));
params.createTimeStamp = result.createTimeStamp;
if (error) {
params.sendStatus = 'fail';
return Promise.reject(error);
}
params.sendStatus = 'success';
return Promise.resolve(result);
}
timerStatus(msg) {
this.setSessionData(newData); setTimeout(() => {
} if (msg.sendStatus === 'loading') {
/** msg.sendStatus = 'fail';
* 发送消息 delete this.queue[msg.traceId];
* @param {*} params }
*/ }, 3000);
async sendMsg(params) { }
const index = this.sessionData.findIndex((i) => i.id === this.curSessionId); /**
let curSession = this.sessionData[index]; * 主动创建会话
// 临时消息体 * @param {*} params
let par = { */
...params, async createSession (params){
traceId: CreateUUID(), const { result, error } = await ToAsyncAwait(this[send]({
traceType: 3, traceId : CreateUUID(),
}; traceType : 21,
let msgCtx = { ...params
...params.content, }));
...par, if (error) {
createTimeStamp: new Date().getTime(), return Promise.reject(error);
sendStatus: 'loading', }
}; const { content } = result;
if (typeof msgCtx.payload === 'string') { let historyData = this.sessionData;
msgCtx.payload = JSON.parse(msgCtx.payload); let curSession = historyData.find(i => i.id === content.id);
} if (!curSession) {
// 点发送,立即把消息加入消息列表,标记为发送中状态 curSession = {
curSession.lastMessage = msgCtx; ...content,
curSession.messageList.push(msgCtx); unreadCount: 0,
this.setSessionData(this.sessionData); messageList : []
}
const newData = [...historyData, curSession];
this.setSessionData(newData);
}
return Promise.resolve(result);
}
// 超过时间未返回视为发送失败
this.timerStatus(msgCtx);
console.log('[im] 发送消息--start', par);
const { error, result } = await ToAsyncAwait(this[send](par));
console.log('[im] 发送消息--end', result, error);
// 接到通知,标记消息是否发送成功
for (let i = curSession.messageList.length; i--; ) {
const item = curSession.messageList[i];
if (item[this.option.ioKey] === par[this.option.ioKey]) {
curSession.messageList[i].sendStatus = msgCtx.sendStatus = error ? 'fail' : 'success';
break;
}
}
let newData = [...this.sessionData];
curSession.lastMessage = msgCtx;
newData[index] = curSession;
this.setSessionData(newData);
if (error) {
return Promise.reject(error);
}
return Promise.resolve(result);
}
/**
* 发送失败时重新发送
* @param {*} params
*/
async resend(params) {
params.sendStatus = 'loading';
this.timerStatus(params);
console.log('[im] 重新发送消息--start', params);
const { error, result } = await ToAsyncAwait(
this[send]({
traceId: params.traceId,
traceType: params.traceType,
content: params.content,
})
);
console.log('[im] 重新发送消息--end', result, error);
params.createTimeStamp = result.createTimeStamp;
if (error) {
params.sendStatus = 'fail';
return Promise.reject(error);
}
params.sendStatus = 'success';
return Promise.resolve(result);
}
timerStatus(msg) {
setTimeout(() => {
if (msg.sendStatus === 'loading') {
msg.sendStatus = 'fail';
delete this.queue[msg.traceId];
}
}, 3000);
}
/**
* 主动创建会话
* @param {*} params
*/
async createSession(params) {
const par = {
traceId: CreateUUID(),
traceType: 9,
...params,
};
console.log('[im] 主动创建会话--start', par);
const { result, error } = await ToAsyncAwait(this[send](par));
console.log('[im] 主动创建会话--end', result, error);
if (error) {
return Promise.reject(error);
}
const { content } = result;
let historyData = this.sessionData;
let curSession = historyData.find((i) => i.id === content.id);
if (!curSession) {
curSession = {
...content,
unreadCount: 0,
messageList: [],
};
const newData = [...historyData, curSession];
this.setSessionData(newData);
}
return Promise.resolve(result);
}
close() {
this.socket.close();
this.socket = null;
this.isOpen = false;
this.setSessionData([]);
}
} }
export default MsbIm;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-18 11:11:05 * @Date: 2022-03-18 11:11:05
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-12 18:31:15 * @LastEditTime: 2022-03-18 11:11:05
* @Description: file content * @Description: file content
*/ */
import {RouterMount,createRouter} from 'uni-simple-router'; import {RouterMount,createRouter} from 'uni-simple-router';
@ -13,11 +13,6 @@ const router = createRouter({
}); });
//全局路由前置守卫 //全局路由前置守卫
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
// 兼容页面刷新body样式丢失问题
// console.log(document);
if (document) {
document.body.setAttribute('class', `uni-body ${to.path.replace('/', '').replace(/\//g, '-')}`)
}
next(); next();
}); });
// 全局路由后置守卫 // 全局路由后置守卫

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-22 18:28:52 * @Date: 2022-03-22 18:28:52
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 15:31:09 * @LastEditTime: 2022-05-21 11:38:51
* @Description: file content * @Description: file content
*/ */
import Vue from 'vue' import Vue from 'vue'
@ -17,22 +17,16 @@ const
// 地址列表 // 地址列表
ADDRESS = 'ads', ADDRESS = 'ads',
// oppenId // oppenId
OPPED_ID = 'oi', OPPED_ID = 'oi';
// 每个浏览器创建一个UUID作为同一个用户的标识
UUID = 'uid',
// 评价图片预览数据
COMMENT_PREVIEW = 'comment_preview';
export default new Vuex.Store({ export default new Vuex.Store({
state: { state : {
token: uni.getStorageSync(TOKEN) || '', token : uni.getStorageSync(TOKEN) || '',
userInfo: JSON.parse(uni.getStorageSync(USER_INFO) || '{}'), userInfo : JSON.parse(uni.getStorageSync(USER_INFO) || '{}'),
address: JSON.parse(uni.getStorageSync(ADDRESS) || '[]'), address : JSON.parse(uni.getStorageSync(ADDRESS) || '[]'),
openId: uni.getStorageSync(OPPED_ID) || '',
uuid: uni.getStorageSync(UUID) || '',
comment_preview: JSON.parse(uni.getStorageSync(COMMENT_PREVIEW) || '{}'),
imData : [], imData : [],
imMsgCount : 0 imMsgCount : 0,
openId : uni.getStorageSync(OPPED_ID) || ''
}, },
mutations:{ mutations:{
SET_TOKEN (state, token = ''){ SET_TOKEN (state, token = ''){
@ -47,23 +41,15 @@ export default new Vuex.Store({
state.address = address; state.address = address;
uni.setStorageSync(ADDRESS, JSON.stringify(address)); uni.setStorageSync(ADDRESS, JSON.stringify(address));
}, },
SET_UUID (state, uid){
state.uuid = uid;
uni.setStorageSync(UUID, uid);
},
SET_OPEN_ID (state, data){
state.openId = data;
uni.setStorageSync(OPPED_ID, data);
},
SET_COMMENT_PREVIEW(state, data) {
state.comment_preview = data;
uni.setStorageSync(COMMENT_PREVIEW, JSON.stringify(data));
},
SET_IM_DATA (state, data){ SET_IM_DATA (state, data){
state.imData = data ; state.imData = data ;
}, },
SET_IM_MSG_COUNT (state, data){ SET_IM_MSG_COUNT (state, data){
state.imMsgCount = data; state.imMsgCount = data;
},
SET_OPEN_ID (state, data){
state.openId = data;
uni.setStorageSync(OPPED_ID, data);
} }
}, },
actions : { actions : {

@ -1,50 +0,0 @@
/*
* @Author: ch
* @Date: 2022-04-29 14:26:10
* @LastEditors: ch
* @LastEditTime: 2022-07-13 10:37:21
* @Description: file content
*/
import { ApiPostAliH5Pay, ApiPostAliAppPay } from '@/common/api/pay';
const ENV = process.env;
export const Alipay = async ({orderId})=>{
// #ifdef APP-PLUS
const {error, result} = await ApiPostAliAppPay({orderId});
if(error){
uni.$u.toast(error.message);
return false;
}
const par = result.payDataInfo;
uni.requestPayment({
provider: 'alipay',
orderInfo :par.payData,
success(res) {
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=appWx`
});
},
fail(e) {
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=appWx`
});
}
}).then(res => {
console.log('res',res);
})
// #endif
// #ifdef H5
const { error, result } = await ApiPostAliH5Pay({
orderId,
returnUrl : decodeURIComponent(`${ENV.VUE_APP_STATIC_URL}/payResult?orderId=${orderId}&payType=alih5`)
});
if(error){
uni.$u.toast(error.message);
return false;
}
window.location.href = result.payDataInfo.payUrl;
// #endif
}

@ -2,36 +2,27 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-20 11:00:07 * @Date: 2022-05-20 11:00:07
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 10:37:52 * @LastEditTime: 2022-05-23 14:54:50
* @Description: file content * @Description: file content
*/ */
import MsbIm from '@/common/plugins/msbIm' ; import MsbIm from '@/common/plugins/msbIm' ;
import { ToAsyncAwait, FormatJsonSearch } from '@/common/utils'; import { ToAsyncAwait } from '@/common/utils';
import { ApiGetCurrentUser } from '@/common/api/account'; import { ApiGetCurrentUser } from '@/common/api/account';
import { ApiGetSoketTicket } from '@/common/api/im';
import $store from '@/common/store'; import $store from '@/common/store';
const ENV = process.env; import ENV from '@/common/config/env';
const Im = new MsbIm({ const Im = new MsbIm({
reconnect: true, reconnect: true,
}); });
const ImInit = async () => { const ImInit = async () => {
const { error, result } = await ApiGetSoketTicket(); const { error } = await ApiGetCurrentUser();
if (error) { if (error) {
return false; return false;
} }
const par = FormatJsonSearch({
client: result.client,
ticket: result.ticket,
// 1普通用户 2客服链接
connect: 1,
user: $store.state.userInfo.id,
nickname: $store.state.userInfo.nickname,
avatar : $store.state.userInfo.avatar
})
await ToAsyncAwait(Im.init({ await ToAsyncAwait(Im.init({
url: `${ENV.VUE_APP_IM_URL}/ws${par}` // url: `wss://k8s-horse-gateway.mashibing.cn/ws?client=${$store.state.token}&type=1`
url: `${ENV.imUrl}/ws?client=${$store.state.token}&type=1`
})) }))
}; };
@ -41,10 +32,11 @@ Im.interceptors.dataChangeAfter = () => {
Im.sessionData.forEach(i => { Im.sessionData.forEach(i => {
msgCount += i.unreadCount; msgCount += i.unreadCount;
}) })
console.log(Im.sessionData)
$store.commit('SET_IM_MSG_COUNT', msgCount); $store.commit('SET_IM_MSG_COUNT', msgCount);
} }
Im.interceptors.onClose = () => { Im.interceptors.onLogout = () => {
Im.setSessionData([]); Im.setSessionData([]);
Im.setCurSessionId(null); Im.setCurSessionId(null);
$store.commit('SET_IM_DATA', []); $store.commit('SET_IM_DATA', []);

@ -2,22 +2,17 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-22 16:52:28 * @Date: 2022-03-22 16:52:28
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-29 17:28:39 * @LastEditTime: 2022-05-20 11:42:33
* @LastEditTime: 2022-06-29 17:22:32
* @Description: 所有工具类统一在这输出 * @Description: 所有工具类统一在这输出
*/ */
import * as util from './utils'; import * as util from './utils';
import * as requset from './requset'; import * as requset from './requset';
import * as im from './im'; import * as im from './im';
import * as wxpay from './wxpay'; import * as wxpay from './wxpay';
import * as uploadFileOss from './uploadFileOss';
import * as alipay from './alipay';
export * from './utils'; export * from './utils';
export * from './requset'; export * from './requset';
export * from './im'; export * from './im';
export * from './wxpay'; export * from './wxpay';
export * from './uploadFileOss';
export * from './alipay';
export default { ...util, ...requset, ...im, ...wxpay, ...uploadFileOss, ...alipay} export default { ...util, ...requset, ...im, ...wxpay}

@ -2,12 +2,57 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-06 15:33:55 * @Date: 2022-05-06 15:33:55
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 10:38:34 * @LastEditTime: 2022-05-26 19:04:50
* @Description: file content * @Description: file content
*/ */
import { ApiPostWxH5Pay, ApiPostWxJsApiPay } from '@/common/api/wx';
import ENV from '@/common/config/env';
import { Wxpay } from './wxpay'; import { Wxpay } from './wxpay';
export const pay = ({orderId, openId, payType})=>{ export const pay = ({orderId, openId, payType})=>{
if(payType === 'wxpay'){ if(payType === 'wxpay'){
Wxpay({orderId, openId}); Wxpay({orderId, openId});
} }
// #ifdef H5
if(openId) {
// 微信JSAPI
const {error, result} = await ApiPostWxJsApiPay({orderId,openId});
if(error){
uni.$u.toast(error.message);
return false;
}
/*
* 公众号id appId String(16) wx8888888888888888
时间戳 timeStamp String(32) 1414561699 当前的时间
随机字符串 nonceStr String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串不长于32位推荐随机数生成算法
订单详情扩展字符串 package String(128) prepay_id=123456789 统一下单接口返回的prepay_id参数值提交格式如prepay_id=***
签名方式 signType String(32) MD5 签名类型默认为MD5支持HMAC-SHA256和MD5注意此处需与统一下单的签名类型一致
签名 paySign String(64) C380BEC2BFD727A4B6845133519F3AD6 签名
*/
const par = result.dataInfo;
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId : par.appId,
timeStamp : par.timeStamp,
nonceStr : par.nonceStr,
package : par.packageValue,
signType : par.signType,
paySign : par.paySign
}, res => {
if(res.err_msg !== 'get_brand_wcpay_request:cancel'){
uni.navigateTo({
url : `/payResult?orderId=${orderId}&payType=wxjsapi`
});
}
})
}else{
// h5支付
const {error, result} = await ApiPostWxH5Pay({orderId});
if(error){
uni.$u.toast(error.message);
return false;
}
const redirect_url = decodeURIComponent(`${ENV.staticUrl}/payResult?orderId=${orderId}&payType=wxh5`);
window.location.href = `${result.dataInfo.payUrl}&redirect_url=${redirect_url}`;
}
// #ednif
} }

@ -2,21 +2,14 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-17 17:42:32 * @Date: 2022-03-17 17:42:32
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 10:39:07 * @LastEditTime: 2022-05-23 15:19:36
* @Description: 项目接口请求统一处理器返回一个需要token和不需要token的请求封装方法 * @Description: 项目接口请求统一处理器返回一个需要token和不需要token的请求封装方法
*/ */
import MsbUniRequest from '@/common/plugins/msbUniRequest'; import MsbUniRequest from '@/common/plugins/msbUniRequest';
import $store from '@/common/store'; import $store from '@/common/store';
import { CreateUUID } from '@/common/utils'; import ENV from '@/common/config/env';
const ENV = process.env;
// 获取已有的UUID没则创建一个并保存到locaStorage中下次使用
let uuid = $store.state.uuid
if (!uuid) {
uuid = CreateUUID(16, 2);
$store.commit('SET_UUID', uuid);
}
/** /**
* 接口返回成功结果统一处理 * 接口返回成功结果统一处理
* @param {*} response * @param {*} response
@ -82,7 +75,7 @@ const clearRepeat = (option) =>{
// 不需要token的接口封装 // 不需要token的接口封装
const MsbRequest = new MsbUniRequest(); const MsbRequest = new MsbUniRequest();
MsbRequest.baseUrl = ENV.VUE_APP_BASE_URL; MsbRequest.baseUrl = ENV.baseUrl;
MsbRequest.use('request', (option) => { MsbRequest.use('request', (option) => {
if(option.header.repeat){ if(option.header.repeat){
@ -92,7 +85,6 @@ MsbRequest.use('request', (option) => {
return isRepeatVerify; return isRepeatVerify;
} }
} }
option.header.uid = uuid;
return option; return option;
}) })
MsbRequest.use('success', successIntercept); MsbRequest.use('success', successIntercept);
@ -102,29 +94,28 @@ MsbRequest.use('error', errorIntercept);
// 需要token的接口封装 // 需要token的接口封装
const MsbRequestTk = new MsbUniRequest(); const MsbRequestTk = new MsbUniRequest();
MsbRequestTk.baseUrl = ENV.VUE_APP_BASE_URL; MsbRequestTk.baseUrl = ENV.baseUrl;
MsbRequestTk.use('request', (option) => { MsbRequestTk.use('request', (option) => {
const token = $store.state.token; const token = $store.state.token;
option.header.uid = uuid; if(!token){
if(!token && !option.header.notVerifyToken){
// 登录状态处理没有token直接跳转至登录 // 登录状态处理没有token直接跳转至登录
uni.redirectTo({ uni.redirectTo({
url: '/login' url: '/login'
}); });
return Promise.reject({message:'要先登录才能操作哦~'}); return Promise.reject({message:'要先登录才能操作哦~'});
} }else{
delete option.header.notVerifyToken option.header = {...option.header, Authorization:token};
option.header = {...option.header, Authorization:token};
if(option.header.repeat){ if(option.header.repeat){
// 如果当前请求不允许重复调用,则检查重复请求,当前接口有正在请求则不发起请求 // 如果当前请求不允许重复调用,则检查重复请求,当前接口有正在请求则不发起请求
const isRepeatVerify = repeatVerify(option); const isRepeatVerify = repeatVerify(option);
if(isRepeatVerify){ if(isRepeatVerify){
return isRepeatVerify; return isRepeatVerify;
}
} }
return option;
} }
return option;
}) })
MsbRequestTk.use('success', successIntercept); MsbRequestTk.use('success', successIntercept);
MsbRequestTk.use('error', errorIntercept); MsbRequestTk.use('error', errorIntercept);

@ -1,46 +0,0 @@
/*
* @Author: ch
* @Date: 2022-06-21 15:03:11
* @LastEditors: ch
* @LastEditTime: 2022-06-22 14:49:20
* @Description: file content
*/
import { ApiPostGetOssConfig } from '@/common/api/oss';
import {ToAsyncAwait} from '@/common/utils'
/**
*
* @param {*} file 文件
* @param {*} param1 获取OSS鉴权信息参数参考ApiPostGetOssConfig接口
* @returns {Promise}
*/
export const uploadFileOss = (file, {configId, serviceName}) =>{
return ToAsyncAwait(new Promise(async (resolve, reject) => {
const urlArr = file.url.split('/');
const fileName = file.name || urlArr[urlArr.length - 1];
const { error, result:oss } = await ApiPostGetOssConfig({ configId : `${configId}/`, serviceName });
if (error) {
reject(error);
return false
}
uni.uploadFile({
name : 'file',
filePath : file.url,
url : oss.host,
formData : {
name : fileName,
key : `${oss.dir}${'${filename}'}`,
policy : oss.policy,
OSSAccessKeyId : oss.accessId,
success_action_status : 200,
signature : oss.signature
},
success : async (res)=>{
resolve(`${oss.host}/${oss.dir}${fileName}`);
},
fail(e) {
reject(e);
}
})
}
))
}

@ -2,20 +2,18 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-17 19:15:10 * @Date: 2022-03-17 19:15:10
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 10:39:35 * @LastEditTime: 2022-05-23 11:40:29
* @Description: 一些无法归类的公共方法容器 * @Description: 一些无法归类的公共方法容器
*/ */
import { import {
toAsyncAwait as ToAsyncAwait, toAsyncAwait as ToAsyncAwait,
isPhone as IsPhone, isPhone as IsPhone,
formatDate as FormatDate, formatDate as FormatDate,
creatUuid as CreateUUID, creatUuid as CreateUUID,
formatSearchJson as FormatSearchJson, formatSearchJson as FormatSearchJson
formatJsonSearch as FormatJsonSearch
} from "js-util-all"; } from "js-util-all";
import {AD_JUMP_TYPE} from '@/common/dicts/ad';
/** /**
* 首次运行时把定时器赋值给一个变量 第二次执行时 * 首次运行时把定时器赋值给一个变量 第二次执行时
@ -24,76 +22,28 @@ import {AD_JUMP_TYPE} from '@/common/dicts/ad';
* 没有执行清除定时器 超过一定时间后触发回调函数 * 没有执行清除定时器 超过一定时间后触发回调函数
*/ */
const Debounce = (fn, delay) => { const Debounce = (fn, delay) => {
let timer let timer
return function () { return function() {
const that = this const that = this
const _args = arguments // 存一下传入的参数 const _args = arguments // 存一下传入的参数
if (timer) { if (timer) {
clearTimeout(timer) clearTimeout(timer)
} }
timer = setTimeout(function () { timer = setTimeout(function() {
fn.apply(that, _args) fn.apply(that, _args)
}, delay) }, delay)
} }
}
/**
* 广告跳转
* 兼容APP根据域名判断站内跳转还是站外跳转
* @param {*} link
*/
const AdJump = (item) => {
switch (item.jumpType) {
case AD_JUMP_TYPE.GOODS:
uni.navigateTo({
url: `/goodsDetail?id=${item.jumpUrl}`
});
break;
case AD_JUMP_TYPE.CATEGORY:
uni.navigateTo({
url: `/goodsList?categoryId=${item.jumpUrl}`
});
break;
case AD_JUMP_TYPE.LINK:
// #ifdef H5
window.location.href = item.jumpUrl;
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(item.jumpUrl);
// #endif
break;
default:
break
}
}
/**
* api接口错误处理
* @param {*} error 错误体
* @param {*} name 接口名 非必传如操作时错误提示不需要提示接口名时可不传
* @return Boolean true 存在错误并处理 false无错误
*/
const HandleApiError = (error, name) => {
let result = false
if (error) {
const tip = name ? `${name}错误:` : ``;
uni.$u.toast(`${tip}${error.message}`);
result = true;
}
return result;
} }
// 工具类的文件需要把文件提供的工具类统一放最下方做一个统一输出 // 工具类的文件需要把文件提供的工具类统一放最下方做一个统一输出
export { export {
// async await 标识结果处理 // async await 标识结果处理
ToAsyncAwait, ToAsyncAwait,
// 判断是否为手机号 // 判断是否为手机号
IsPhone, IsPhone,
// 时间格式化 // 时间格式化
FormatDate, FormatDate,
FormatSearchJson, FormatSearchJson,
FormatJsonSearch, CreateUUID,
CreateUUID, // 防抖函数
// 防抖函数 Debounce
Debounce,
// 广告跳转
AdJump,
HandleApiError
} }

@ -2,12 +2,12 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-29 14:26:10 * @Date: 2022-04-29 14:26:10
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 10:40:10 * @LastEditTime: 2022-05-26 20:28:48
* @Description: file content * @Description: file content
*/ */
import { ApiPostWxH5Pay, ApiPostWxJsApiPay, ApiPostWxAppPay } from '@/common/api/pay'; import { ApiPostWxH5Pay, ApiPostWxJsApiPay, ApiPostWxAppPay } from '@/common/api/wx';
const ENV = process.env; import ENV from '@/common/config/env';
export const Wxpay = async ({orderId,openId})=>{ export const Wxpay = async ({orderId,openId})=>{
// #ifdef APP-PLUS // #ifdef APP-PLUS
@ -16,7 +16,7 @@ export const Wxpay = async ({orderId,openId})=>{
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
const par = result.payDataInfo; const par = result.dataInfo;
uni.requestPayment({ uni.requestPayment({
provider: 'wxpay', provider: 'wxpay',
orderInfo :{ orderInfo :{
@ -52,12 +52,12 @@ export const Wxpay = async ({orderId,openId})=>{
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
const par = result.payDataInfo; const par = result.dataInfo;
WeixinJSBridge.invoke('getBrandWCPayRequest', { WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId : par.appId, appId : par.appId,
timeStamp : par.timeStamp, timeStamp : par.timeStamp,
nonceStr : par.nonceStr, nonceStr : par.nonceStr,
package: par.packageValue, package : par.packageValue,
signType : par.signType, signType : par.signType,
paySign : par.paySign paySign : par.paySign
}, res => { }, res => {
@ -74,8 +74,8 @@ export const Wxpay = async ({orderId,openId})=>{
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
const redirect_url = decodeURIComponent(`${ENV.VUE_APP_STATIC_URL}/payResult?orderId=${orderId}&payType=wxh5`); const redirect_url = decodeURIComponent(`${ENV.staticUrl}/payResult?orderId=${orderId}&payType=wxh5`);
window.location.href = `${result.payDataInfo.h5Url}&redirect_url=${redirect_url}`; window.location.href = `${result.dataInfo.payUrl}&redirect_url=${redirect_url}`;
} }
// #endif // #endif

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-20 16:45:27 * @Date: 2022-03-20 16:45:27
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 19:34:13 * @LastEditTime: 2022-05-06 14:26:57
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -38,10 +38,10 @@ export default {
...this.params ...this.params
}); });
const res = result.records.map(item => { const res = result.records.map(item => {
// item.labelList[{text:'x',code : 'recommended'},{text:'x',code : 'second_kill'}]
// //
item.seckill = false; item.seckill = false;
item.tagList = []; item.tagList = [];
item.labelList = item.labelList || [];
item.labelList.forEach(i => { item.labelList.forEach(i => {
if(i.code === 'second_kill'){ if(i.code === 'second_kill'){
item.seckill = true; item.seckill = true;

@ -1,85 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-23 10:40:04
* @LastEditors: ch
* @LastEditTime: 2022-06-30 18:01:46
* @Description: file content
-->
<template>
<view class="follow">
<view class="follow--title">{{day}}追评:</view>
<view class="follow--ctx">{{followComment.commentContent}}</view>
<view class="follow--img" v-if="imgs.length">
<image class="follow--img-item" v-for="(item, idx) in imgs" :src="item" :key="idx" @click="preview(idx)" mode="aspectFit"/>
</view>
</view>
</template>
<script>
export default {
props : {
commentDetail : {
type : Object,
default : () => ({})
}
},
computed:{
followComment(){
return this.commentDetail.followComment || {}
},
day(){
const followTime = (new Date(this.followComment.createTime)).getTime();
const commentTime = (new Date(this.commentDetail.createTime)).getTime();
const day = Math.floor((followTime - commentTime) / (24 * 60 * 60 * 1000));
return day > 0 ? `${day}天后` : `当天`;
},
imgs (){
let urls = this.followComment.pictureUrl || '';
return urls ? urls.split(',') : [];
}
},
methods:{
preview(idx){
this.$store.commit('SET_COMMENT_PREVIEW', {
...this.commentDetail,
commentContent : this.followComment.commentContent,
pictureUrl : this.followComment.pictureUrl
});
this.$Router.push({
path : '/goodsCommentPreview',
query : {
idx
}
});
}
}
}
</script>
<style lang="scss" scoped>
.follow{
margin-top: 40rpx;
&--title{
color: $color-yellow3;
font-size: 28rpx;
}
&--ctx{
margin-top: 20rpx;
font-size: 30rpx;
line-height: 46rpx;
word-break: break-all;
}
&--img{
margin-top: 30rpx;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
&-item{
width: 210rpx;
height: 210rpx;
margin:20rpx 0;
}
}
}
</style>

@ -1,66 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-20 14:30:45
* @LastEditors: ch
* @LastEditTime: 2022-06-28 21:14:46
* @Description: file content
-->
<template>
<view class="goods" @click="$Router.push(`/goodsDetail?id=${goods.productId}`)">
<image class="goods--img" :src="goods.productPicture" mode="aspectFit" ></image>
<view class="goods--ctx">
<view class="goods--title">{{ goods.productName }}</view>
<view class="goods--footer">
<view class="goods--sku">{{ goods.skuName }}</view>
<view><slot name="btns"></slot></view>
</view>
</view>
</view>
</template>
<script>
export default {
props : {
goods : {
type : Object,
default : ()=>({})
}
}
}
</script>
<style lang="scss" scoped>
.goods {
display: flex;
&--img {
width: 130rpx;
height: 130rpx;
margin-right: 30rpx;
}
&--ctx{
flex: 1;
overflow: hidden;
padding: 20rpx 0;
}
&--title{
font-size: 28rpx;
overflow:hidden;
text-overflow:ellipsis;
white-space: nowrap;
padding-right: 30rpx;
}
&--footer{
display: flex;
justify-content: space-between;
padding-right: 30rpx;
}
&--sku{
font-size: 24rpx;
color: #999;
margin-top: 20rpx;
}
}
</style>

@ -1,93 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 15:50:01
* @LastEditors: ch
* @LastEditTime: 2022-06-30 18:00:16
* @Description: file content
-->
<template>
<view>
<view class="top">
<u-rate count="5" size="30rpx" :value="commentDetail.commentScore" activeColor="#FFA35B" readonly inactiveColor="#DDD"></u-rate>
<text class="top--time">{{ FormatDate(commentDetail.createTime, 'yyyy-mm-dd hh:ii') }}</text>
</view>
<view class="ctx">{{ commentDetail.commentContent }}</view>
<view class="img" v-if="imgs.length">
<image class="img--item" mode="aspectFit"
v-for="(item, idx) in imgs" :src="item" :key="idx" @click="preview(idx)"/>
</view>
</view>
</template>
<script>
import {FormatDate} from '@/common/utils';
export default {
props : {
commentDetail : {
type : Object,
default : () => ({})
},
imgPreview : {
type: Boolean,
default : true,
require : true
}
},
data(){
return {
curPreview : -1
}
},
computed : {
imgs (){
let urls = this.commentDetail.pictureUrl || '';
return urls ? urls.split(',') : [];
}
},
methods:{
FormatDate,
preview(idx){
if(!this.imgPreview){
return false
}
this.$store.commit('SET_COMMENT_PREVIEW', this.commentDetail);
this.$Router.push({
path : '/goodsCommentPreview',
query : {
idx
}
});
}
}
}
</script>
<style lang="scss" scoped>
.top{
display: flex;
justify-content: space-between;
margin: 20rpx 0;
&--time{
font-size: 24rpx;
color: #999;
}
}
.ctx{
font-size: 30rpx;
line-height: 46rpx;
word-break: break-all;
}
.img{
margin-top: 30rpx;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
&--item{
width: 210rpx;
height: 210rpx;
margin:20rpx 0;
}
}
</style>

@ -1,56 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 15:59:23
* @LastEditors: ch
* @LastEditTime: 2022-06-30 17:57:25
* @Description: file content
-->
<template>
<view class="merchant">
<view class="merchant--title">
<text class="merchant--name">{{merchantComment.userName}}</text>
<text class="merchant--time">{{ FormatDate(merchantComment.createTime, 'yyyy-mm-dd hh:ii') }}
</text>
</view>
<view class="merchant--ctx">{{merchantComment.commentContent}}</view>
</view>
</template>
<script>
import {FormatDate} from '@/common/utils';
export default {
props : {
merchantComment : {
type : Object,
default : () => ({})
}
},
data(){
return {
}
},
methods : {
FormatDate
}
}
</script>
<style lang="scss" scoped>
.merchant{
margin-top: 40rpx;
padding: 30rpx;
background: #F5F5F5;
&--title{
display: flex;
justify-content: space-between;
margin-bottom: 24rpx;
}
&--time{
color: #999;
font-size: 24rpx;
}
&--ctx,&--name{
font-size: 26rpx;
color: #666;
}
}
</style>

@ -1,138 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-20 16:36:14
* @LastEditors: ch
* @LastEditTime: 2022-06-30 21:06:31
* @Description: file content
-->
<template>
<view>
<view class="rate" v-if="type === COMMENT.TYPE.COMMENT">
<text class="rate--title">满意度评分</text>
<u-rate :count="5" v-model="rate" size="47rpx" activeColor="#FFA35B" inactiveColor="#DDD"></u-rate>
<text class="rate--desc">{{rateDesc}}</text>
</view>
<textarea class="textarea" placeholder="从多个维度评价,可以帮助更多想买的人哦~"
:maxlength="500" v-model="commentContent"></textarea>
<u-upload class="upload"
@afterRead="handleUpdateImg" @delete="handleDelImg"
:fileList="fileList" :maxCount="6" :previewFullImage="true">
</u-upload>
<view class="footer">
<UiButton type="solid" :disable="isVerify" @click="handleSubmit">
{{type === COMMENT.TYPE.COMMENT ? '发表评价' : '发表追评'}}
</UiButton>
</view>
</view>
</template>
<script>
import UiButton from '@/components/UiButton.vue';
import {ApiPostComment} from '@/common/api/comment';
import COMMENT from '@/common/dicts/comment';
import {uploadFileOss, HandleApiError} from '@/common/utils';
export default {
components: { UiButton },
props:{
type : {
type : String | Number,
default : COMMENT.TYPE.COMMENT
},
commentDetail : {
type : Object,
default : ()=> ({})
}
},
data(){
return {
COMMENT,
rate : 5,
commentContent : '',
fileList : []
}
},
computed:{
isVerify(){
if(this.type === COMMENT.TYPE.COMMENT){
return !this.rate || !this.commentContent.trim();
}else{
return !this.commentContent.trim();
}
},
isEdit (){
return ( this.commentContent || this.fileList.length > 0) ? true : false
},
rateDesc(){
return COMMENT.RATE_LABEL[this.rate-1];
}
},
watch:{
isEdit(){
this.$emit('editChang',this.isEdit)
}
},
methods:{
async handleSubmit(){
let data = {
commentContent : this.commentContent,
commentType : this.type,
orderProductId : this.commentDetail.orderProductId,
pictureUrl : this.fileList.map(i => i.url).join(',')
}
if(this.type === COMMENT.TYPE.COMMENT){
data.productId = this.commentDetail.productId;
data.commentScore = this.rate;
}else if(this.type === COMMENT.TYPE.FOLLOW_COMMENT){
data.originId = data.parentId = this.commentDetail.id;
}
const {error, result} = await ApiPostComment(data);
if(!HandleApiError(error)){
this.commentContent = '';
this.fileList = [];
this.$nextTick(()=>{
this.$emit('submit',result);
})
}
},
async handleUpdateImg(val){
const {error, result} = await uploadFileOss(val.file, {
configId : 'account-comment',
serviceName : 'comment'
})
if(error){
uni.$u.toast(error);
}
this.fileList.push({url : result});
},
handleDelImg(target){
this.fileList.splice(target.index, 1)
}
}
}
</script>
<style lang="scss" scoped>
.rate{
display: flex;
margin: 50rpx 0;
align-items: center;
&--title{
font-size: 28rpx;
margin-right: 30rpx;
}
&--desc{
font-size: 30rpx;
color: #999;
margin-left: 40rpx;
}
}
.textarea{
height: 200rpx;
margin-bottom: 40rpx;
}
.footer{
width: 100%;
text-align: right;
margin-top: 50rpx;
}
</style>

@ -1,96 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 16:01:19
* @LastEditors: ch
* @LastEditTime: 2022-07-01 17:55:01
* @Description: file content
-->
<template>
<view class="thumb">
<view class="thumb--item" @click="handleUseful">
<u-icon name="thumb-up-fill" v-if="isLike"></u-icon>
<u-icon name="thumb-up" v-else></u-icon>
<text>{{usefulCount}}</text>
</view>
<view class="thumb--item" @click="$Router.push(`/goodsCommentDetail?id=${commentDetail.id}`)">
<u-icon name="chat"></u-icon>
<text>{{commentDetail.replyCount}}</text>
</view>
</view>
</template>
<script>
import {Debounce, HandleApiError} from '@/common/utils';
import {ApiPutCommentUseful} from '@/common/api/comment'
export default {
props : {
commentDetail : {
type : Object,
default : ()=>({})
}
},
data(){
return {
debounce : null,
isLike : false,
usefulCount : 0
}
},
watch :{
commentDetail :{
handler(){
this.isLike = this.commentDetail.isLike;
this.usefulCount = this.commentDetail.usefulCount;
},
deep:true
}
},
mounted(){
this.isLike = this.commentDetail.isLike;
// console.log('---',this.isLike,this.commentDetail.usefulCount);
this.usefulCount = this.commentDetail.usefulCount;
},
methods:{
handleUseful(){
this.isLike = !this.isLike
if(this.isLike){
this.usefulCount++;
}else{
this.usefulCount--;
}
if(!this.debounce){
this.debounce = Debounce(this.updateUseFul, 500);
}
this.debounce();
},
async updateUseFul(){
if(this.isLike === this.commentDetail.isLike){
return false
}
const {error, result} = await ApiPutCommentUseful({
commentId : this.commentDetail.id,
isLike : this.isLike
});
HandleApiError(error);
}
}
}
</script>
<style lang="scss" scoped>
.thumb{
display: flex;
justify-content: flex-end;
margin-top: 40rpx;
&--item{
display: flex;
align-items: center;
margin-left: 50rpx;
text{
font-size: 24rpx;
margin-left: 10rpx;
}
}
}
</style>

@ -1,47 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 22:27:52
* @LastEditors: ch
* @LastEditTime: 2022-07-01 17:14:36
* @Description: file content
-->
<template>
<view class="comment-user">
<image class="comment-user--avatr" :src="userData.userAvatar" shape="circle"/>
<view>
<view class="comment-user--name">{{userData.userName}}</view>
<text class="comment-user--sku" v-if="userData.skuName">{{userData.skuName}}</text>
</view>
</view>
</template>
<script>
export default {
props : {
userData : {
type : Object,
default : ()=> ({})
}
}
}
</script>
<style lang="scss" scoped>
.comment-user{
display: flex;
justify-content: flex-start;
&--avatr{
width: 71rpx;
height: 71rpx;
margin-right: 17rpx;
}
&--name{
margin-top: 5rpx;
}
&--sku{
margin-top: 10rpx;
font-size: 24rpx;
color: #999;
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-19 11:37:50 * @Date: 2022-04-19 11:37:50
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-29 17:27:12 * @LastEditTime: 2022-05-05 11:08:44
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -12,7 +12,7 @@
<script> <script>
import UiRadioPicker from './UiRadioPicker.vue' import UiRadioPicker from './UiRadioPicker.vue'
import { ApiPostWxPay } from '@/common/api/order'; import { ApiPostWxPay } from '@/common/api/order';
import { Wxpay, Alipay } from '@/common/utils'; import { Wxpay } from '@/common/utils';
export default { export default {
components: { UiRadioPicker }, components: { UiRadioPicker },
props : { props : {
@ -32,19 +32,13 @@ export default {
label : '微信支付', label : '微信支付',
value : 'wxpay' value : 'wxpay'
}, },
// {
// label : '',
// value : 'alipay'
// }
] ]
} }
}, },
mounted(){
// APP
if(!this.$store.state.openId){
this.options.push({
label : '支付宝支付',
value : 'alipay'
})
}
},
methods:{ methods:{
confirm(val){ confirm(val){
const orderId = this.order.orderId; const orderId = this.order.orderId;
@ -52,8 +46,7 @@ export default {
Wxpay({orderId, openId: this.$store.state.openId}); Wxpay({orderId, openId: this.$store.state.openId});
this.close(); this.close();
}else{ }else{
// uni.$u.toast(''); uni.$u.toast('暂不支持支付宝支付');
Alipay({orderId})
} }
}, },
close(){ close(){

@ -2,11 +2,11 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-31 15:42:55 * @Date: 2022-03-31 15:42:55
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 14:12:46 * @LastEditTime: 2022-04-19 13:57:30
* @Description: file content * @Description: file content
--> -->
<template> <template>
<view class="ui-white-box" @click="$emit('click')"> <view class="ui-white-box">
<slot></slot> <slot></slot>
</view> </view>
</template> </template>
@ -14,6 +14,6 @@
.ui-white-box{ .ui-white-box{
margin: 20rpx 30rpx; margin: 20rpx 30rpx;
background: $color-grey0; background: $color-grey0;
border-radius: 8rpx; border-radius: 20rpx;
} }
</style> </style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2021-07-26 23:22:16 * @Date: 2021-07-26 23:22:16
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-20 17:38:48 * @LastEditTime: 2022-05-23 20:55:47
* @Description: file content * @Description: file content
*/ */
import Vue from 'vue'; import Vue from 'vue';
@ -13,40 +13,19 @@ import uView from 'uview-ui';
import store from '@/common/store'; import store from '@/common/store';
import {FormatSearchJson} from '@/common/utils'; import {FormatSearchJson} from '@/common/utils';
import {ApiGetOpenId, ApiGetAuthUrl} from '@/common/api/wx'; import {ApiGetOpenId, ApiGetAuthUrl} from '@/common/api/wx';
import {ApiGetCurrentUser} from '@/common/api/account';
import {Im, ImInit} from '@/common/utils'; import {Im, ImInit} from '@/common/utils';
import { ApiSktSysGetSession, ApiSktSysHeart } from './common/api/im'; import { ApiSktSysGetSession, ApiSktSysHeart } from './common/api/im';
const socketInit = () => { if (store.state.token) {
if (!store.state.userInfo.id) {
setTimeout(() => {
socketInit();
},10000)
return false;
}
// 初始化IM // 初始化IM
ImInit().then(() => { ImInit().then(() => {
// 获取到会话列表 // 获取到会话列表
Im.getSessionList(); Im.getSessionList({
content: { sysId : 1 }
});
}); });
} }
const getUserInfo = async () => {
const { error, result } = await ApiGetCurrentUser();
if (error) {
uni.$u.toast(error.message);
return false;
}
store.commit('SET_USER_INFO', result);
};
if (store.state.token) {
socketInit();
getUserInfo();
}
// 微信打开需要授权 // 微信打开需要授权
const ua = navigator ? navigator.userAgent.toLowerCase() : ''; const ua = navigator ? navigator.userAgent.toLowerCase() : '';

@ -1,6 +1,6 @@
{ {
"name" : "马士兵严选", "name" : "马士兵严选",
"appid" : "__UNI__5FEB250", "appid" : "__UNI__3FB31B6",
"description" : "", "description" : "",
"versionName" : "1.0.1", "versionName" : "1.0.1",
"versionCode" : "100", "versionCode" : "100",
@ -40,14 +40,10 @@
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
], ]
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
"minSdkVersion" : 21
}, },
/* ios */ /* ios */
"ios" : { "ios" : {},
"dSYMs" : false
},
/* SDK */ /* SDK */
"sdkConfigs" : { "sdkConfigs" : {
"ad" : {}, "ad" : {},
@ -56,18 +52,39 @@
"__platform__" : [ "android" ], "__platform__" : [ "android" ],
"appid" : "wx17b34a4a90ef18f7", "appid" : "wx17b34a4a90ef18f7",
"UniversalLinks" : "" "UniversalLinks" : ""
},
"alipay" : {
"__platform__" : [ "android" ]
} }
} }
}, },
"icons" : { "icons" : {
"android" : { "android" : {
"hdpi" : "src/static/app-icon/72.png", "hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "src/static/app-icon/96.png", "xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "src/static/app-icon/144.png", "xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "src/static/app-icon/192.png" "xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
} }
} }
} }
@ -101,7 +118,20 @@
"base" : "" "base" : ""
}, },
"devServer" : { "devServer" : {
"port" : 8080 "proxy" : {
"/uc/" : {
"target" : "https://k8s-horse-gateway.mashibing.cn"
},
"/mall/" : {
"target" : "https://k8s-horse-gateway.mashibing.cn"
},
"/pay/" : {
"target" : "https://k8s-horse-gateway.mashibing.cn"
},
"/oss/" : {
"target" : "https://k8s-horse-gateway.mashibing.cn"
}
}
}, },
"optimization" : { "optimization" : {
"treeShaking" : { "treeShaking" : {

@ -10,13 +10,6 @@
"backgroundColor" : "#69ADE5" "backgroundColor" : "#69ADE5"
} }
}, },
{
"path": "pages/webView",
"aliasPath" : "/webView",
"style": {
"navigationBarTitleText": "收银台"
}
},
{ {
"path": "pages/login", "path": "pages/login",
"aliasPath" : "/login", "aliasPath" : "/login",
@ -65,42 +58,6 @@
"navigationBarTitleText": "马士兵严选" "navigationBarTitleText": "马士兵严选"
} }
}, },
{
"path": "pages/goods/enable",
"aliasPath" : "/enable",
"style": {
"navigationBarTitleText": "商品详情"
}
},
{
"path": "pages/goods/comment/list",
"aliasPath" : "/goodsCommentList",
"style": {
"navigationBarTitleText": "全部评价"
}
},
{
"path": "pages/goods/comment/otherList",
"aliasPath" : "/goodsCommentOtherList",
"style": {
"navigationBarTitleText": "全部评价"
}
},
{
"path": "pages/goods/comment/preview",
"aliasPath" : "/goodsCommentPreview",
"style": {
"navigationStyle" : "custom",
"navigationBarTitleText": "马士兵严选"
}
},
{
"path": "pages/goods/comment/detail",
"aliasPath" : "/goodsCommentDetail",
"style": {
"navigationBarTitleText": "全部评价"
}
},
{ {
"path": "pages/account/index", "path": "pages/account/index",
"aliasPath" : "/account", "aliasPath" : "/account",
@ -220,20 +177,6 @@
"navigationBarTitleText": "支付中" "navigationBarTitleText": "支付中"
} }
}, },
{
"path": "pages/order/comment/index/index",
"aliasPath" : "/comment",
"style": {
"navigationBarTitleText": "发表评价"
}
},
{
"path": "pages/order/comment/success",
"aliasPath" : "/commentSuccess",
"style": {
"navigationBarTitleText": "评价成功"
}
},
{ {
"path": "pages/order/saleAfter/saleAfterList", "path": "pages/order/saleAfter/saleAfterList",
"aliasPath" : "/saleAfterList", "aliasPath" : "/saleAfterList",

@ -3,7 +3,7 @@
components: { UiCell },: ch components: { UiCell },: ch
* @Date: 2019-08-22 19:41:20 * @Date: 2019-08-22 19:41:20
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-28 16:38:33 * @LastEditTime: 2022-05-24 09:57:07
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -38,11 +38,6 @@
<image class="item-icon" src="@/static/account/sh.png"/> <image class="item-icon" src="@/static/account/sh.png"/>
<view>待收货</view> <view>待收货</view>
</view> </view>
<view class="order-tabs--item" @click="$Router.push('/orderList?tab=5')">
<u-badge class="item-badge" max="99" :value="statistic.waitComment"></u-badge>
<image class="item-icon" src="@/static/account/pj.png"/>
<view>待评价</view>
</view>
</view> </view>
</view> </view>
<view class="cell"> <view class="cell">
@ -140,10 +135,6 @@ page {
top: 10rpx; top: 10rpx;
z-index: 99; z-index: 99;
border: 1px solid #fff; border: 1px solid #fff;
/* #ifndef H5 */
top: 90rpx;
/* #endif */
} }
&--cell{ &--cell{
border: 0; border: 0;

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-05-11 11:45:08 * @Date: 2022-05-11 11:45:08
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-14 12:55:27 * @LastEditTime: 2022-05-24 22:54:29
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -158,11 +158,11 @@ export default {
this.msgCtx += str; this.msgCtx += str;
}, },
sendGoods(){ sendGoods(){
this.send({...this.simpleGoods, customType:'goodsInfo'}, MSG_TYPE.CUSTOM); this.send(this.simpleGoods, MSG_TYPE.CUSTOM);
this.goodsShow = false; this.goodsShow = false;
}, },
sendOrder(){ sendOrder(){
this.send({...this.simpleOrder, customType : 'orderInfo'}, MSG_TYPE.CUSTOM); this.send(this.simpleOrder, MSG_TYPE.CUSTOM);
this.orderShow = false; this.orderShow = false;
}, },
uploadImg(val){ uploadImg(val){

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-26 14:32:03 * @Date: 2022-03-26 14:32:03
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-14 20:48:40 * @LastEditTime: 2022-05-24 22:42:35
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -11,7 +11,6 @@
<view class="send" :key="item.id" v-if="item.fromId == $store.state.userInfo.id"> <view class="send" :key="item.id" v-if="item.fromId == $store.state.userInfo.id">
<text class="send--status" v-if="item.sendStatus === 'loading'"></text> <text class="send--status" v-if="item.sendStatus === 'loading'"></text>
<text class="send--status send--status__fail" v-if="item.sendStatus === 'fail'" @click="resend(item)"></text> <text class="send--status send--status__fail" v-if="item.sendStatus === 'fail'" @click="resend(item)"></text>
<template v-if="item.type == MSG_TYPE.CUSTOM"> <template v-if="item.type == MSG_TYPE.CUSTOM">
<GoodsInfo class="send--box" position="msg" v-if="item.payload.id" :goodsInfo="item.payload"/> <GoodsInfo class="send--box" position="msg" v-if="item.payload.id" :goodsInfo="item.payload"/>
<OrderInfo class="send--box" position="msg" v-if="item.payload.orderId" :orderInfo="item.payload"/> <OrderInfo class="send--box" position="msg" v-if="item.payload.orderId" :orderInfo="item.payload"/>
@ -27,9 +26,6 @@
<view class="tips" :key="item.id" v-else-if="item.type == MSG_TYPE.TIP"> <view class="tips" :key="item.id" v-else-if="item.type == MSG_TYPE.TIP">
<view class="tips--box">{{item.payload.text}}</view> <view class="tips--box">{{item.payload.text}}</view>
</view> </view>
<view class="tips" :key="item.id" v-else-if="item.type === MSG_TYPE.CUSTOM && item.payload.customType == 'transferWaiterSession'">
<view class="tips--box">现在由客服{{item.payload.toNickname}}为您服务</view>
</view>
<view class="receive" :key="item.id" v-else> <view class="receive" :key="item.id" v-else>
<image class="avatar" :src="item.fromAvatar || require('@/static/message/xt.png')" mode="widthFix"/> <image class="avatar" :src="item.fromAvatar || require('@/static/message/xt.png')" mode="widthFix"/>
<view> <view>
@ -57,9 +53,9 @@ import {Im, ToAsyncAwait} from '@/common/utils';
import {ApiGetOrderDetail} from '@/common/api/order'; import {ApiGetOrderDetail} from '@/common/api/order';
import {ApiGetGoodsDetail} from '@/common/api/goods'; import {ApiGetGoodsDetail} from '@/common/api/goods';
import UiButton from '@/components/UiButton.vue'; import UiButton from '@/components/UiButton.vue';
import Footer from './modules/Footer.vue'; import Footer from './components/Footer.vue';
import GoodsInfo from './modules/GoodsInfo.vue'; import GoodsInfo from './components/GoodsInfo.vue';
import OrderInfo from './modules/OrderInfo.vue'; import OrderInfo from './components/OrderInfo.vue';
export default { export default {
components: { UiButton, Footer, GoodsInfo, OrderInfo }, components: { UiButton, Footer, GoodsInfo, OrderInfo },
data(){ data(){
@ -84,9 +80,6 @@ export default {
return this.curSessionData ? this.curSessionData.messageList : []; return this.curSessionData ? this.curSessionData.messageList : [];
} }
}, },
destroyed(){
Im.setCurSessionId(null);
},
watch:{ watch:{
msgData(){ msgData(){
this.$nextTick(()=>{ this.$nextTick(()=>{
@ -115,7 +108,12 @@ export default {
this.orderId = this.$Route.query.orderId; this.orderId = this.$Route.query.orderId;
this.sessionId = this.$Route.query.sessionId; this.sessionId = this.$Route.query.sessionId;
this.socketInit(); if(this.sessionId){
this.getHistoryMsg();
this.readMsg();
}else{
this.createSessionMain();
}
if(this.goodsId){ if(this.goodsId){
this.getGoodsInfo(); this.getGoodsInfo();
} }
@ -131,35 +129,14 @@ export default {
}, },
methods:{ methods:{
socketInit(){
if(!Im.isOpen){
setTimeout(()=>{
this.socketInit();
}, 100)
return false;
}
if(this.sessionId){
if(!this.msgData?.length){
this.getHistoryMsg();
}
this.readMsg();
}else{
this.createSessionMain();
}
},
/** /**
* 创建会话主体 * 创建会话主体
* 如果是从商品或订单进来需要创建会话 * 如果是从商品或订单进来需要创建会话
*/ */
async createSessionMain(){ async createSessionMain(){
if(!Im.isOpen){
setTimeout(()=>this.createSessionMain(),1000);
return false;
}
const {error, result} = await ToAsyncAwait(Im.createSession({ const {error, result} = await ToAsyncAwait(Im.createSession({
content : { content : {
sessionType : 3 storeId : 1
} }
})); }));
@ -167,24 +144,23 @@ export default {
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
this.sessionId = result.content.id; this.sessionId = result.content.id
Im.setCurSessionId(this.sessionId);
this.getHistoryMsg(); this.getHistoryMsg();
// this.readMsg(); this.readMsg();
}, },
/** /**
* 获取历史消息 * 获取历史消息
*/ */
async getHistoryMsg(){ async getHistoryMsg(){
if(!this.curSessionData.id){
setTimeout(()=>{
this.getHistoryMsg();
}, 500)
return false;
}
this.loading = true; this.loading = true;
const {error, result} = await ToAsyncAwait(Im.getHistoryMsg()); const lastMsg = this.msgData?.length ? this.msgData[0] : {};
const {error, result} = await ToAsyncAwait(Im.getHistoryMsg({
content : {
sessionId : this.sessionId,
topMessageId : lastMsg.id || null
}
}));
if(error){ if(error){
uni.$u.toast(error.errMsg || error.message); uni.$u.toast(error.errMsg || error.message);
return false return false
@ -202,7 +178,6 @@ export default {
})); }));
if(error){ if(error){
uni.$u.toast(error.errMsg || error.message); uni.$u.toast(error.errMsg || error.message);
console.log(error);
return false return false
} }
@ -277,7 +252,6 @@ page{
color: #333; color: #333;
font-size: 32rpx; font-size: 32rpx;
line-height: 40rpx; line-height: 40rpx;
word-break: break-all;
} }
&__img{ &__img{
height: 140rpx; height: 140rpx;
@ -309,7 +283,6 @@ page{
color: #fff; color: #fff;
font-size: 32rpx; font-size: 32rpx;
line-height: 46rpx; line-height: 46rpx;
word-break: break-all;
} }
&__img{ &__img{
height: 140rpx; height: 140rpx;

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-22 16:13:00 * @Date: 2022-03-22 16:13:00
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-17 16:31:20 * @LastEditTime: 2022-05-27 15:32:18
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -18,14 +18,11 @@
<text class="msgItem--text" v-if="item.lastMessage"> <text class="msgItem--text" v-if="item.lastMessage">
<template v-if="item.lastMessage.type == msgType.TXT">{{item.lastMessage.payload.content || item.lastMessage.payload.text}}</template> <template v-if="item.lastMessage.type == msgType.TXT">{{item.lastMessage.payload.content || item.lastMessage.payload.text}}</template>
<template v-if="item.lastMessage.type == msgType.CUSTOM"> <template v-if="item.lastMessage.type == msgType.CUSTOM">
<template v-if="item.lastMessage.payload.customType === 'app_push'"> <template v-if="item.lastMessage.payload.customType === 'orderAutoDelivery'">
{{item.lastMessage.payload.link ? '[链接]' : item.lastMessage.payload.content}} {{item.lastMessage.payload.content}}
</template>
<template v-if="item.lastMessage.payload.customType === 'transferWaiterSession'">
[客服转移]
</template> </template>
<template v-else> <template v-else>
{{item.lastMessage.payload.content || '[未知消息]'}} [链接]
</template> </template>
</template> </template>
<template v-if="item.lastMessage.type == msgType.IMG">[]</template> <template v-if="item.lastMessage.type == msgType.IMG">[]</template>
@ -43,7 +40,7 @@
<script> <script>
import BsEmpty from '../../../components/BsEmpty.vue'; import BsEmpty from '../../../components/BsEmpty.vue';
import {MSG_TYPE} from '@/common/dicts/im'; import {MSG_TYPE} from '@/common/dicts/im';
import {FormatDate, Im} from '@/common/utils'; import {FormatDate} from '@/common/utils';
export default { export default {
components: { BsEmpty }, components: { BsEmpty },
data (){ data (){
@ -59,20 +56,18 @@ export default {
}, },
computed:{ computed:{
sessionData (){ sessionData (){
return this.$store.state.imData.sort((a,b) => b.updateTimeStamp - a.updateTimeStamp); return this.$store.state.imData;
} }
}, },
methods:{ methods:{
FormatDate, FormatDate,
openMsg(item){ openMsg(item){
Im.setCurSessionId(item.id); if(item.type === 3){
if(item.type === 4){ this.$Router.push(`/messageChat?sessionId=${item.id}`);
if(JSON.parse(item.payload).type === 'system'){ }else{
this.$Router.push(`/messageSystem?sessionId=${item.id}`); this.$Router.push(`/messageSystem?sessionId=${item.id}`);
return false;
}
} }
this.$Router.push(`/messageChat?sessionId=${item.id}`);
} }
} }
} }
@ -112,8 +107,6 @@ export default {
display:-webkit-box; display:-webkit-box;
-webkit-box-orient:vertical; -webkit-box-orient:vertical;
-webkit-line-clamp:2; -webkit-line-clamp:2;
word-break: break-all;
} }
&--right{ &--right{
text-align: right; text-align: right;

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-26 14:32:03 * @Date: 2022-03-26 14:32:03
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-02 18:07:09 * @LastEditTime: 2022-05-27 17:02:59
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -21,6 +21,7 @@
<text class="msg-item--desc-link" v-if="i.shipType === 1" @click="openLink(i)" :key="i.shipContent">[]</text> <text class="msg-item--desc-link" v-if="i.shipType === 1" @click="openLink(i)" :key="i.shipContent">[]</text>
<text v-else :key="i.shipContent">{{i.shipContent}}</text> <text v-else :key="i.shipContent">{{i.shipContent}}</text>
</template> </template>
</template> </template>
</view> </view>
</view> </view>
@ -77,7 +78,13 @@ export default {
}, },
async getHistoryMsg(){ async getHistoryMsg(){
this.loading = true; this.loading = true;
await ToAsyncAwait(Im.getHistoryMsg()); const lastMsg = this.msgData?.length ? this.msgData[this.msgData.length - 1] : {};
await ToAsyncAwait(Im.getHistoryMsg({
content : {
sessionId : this.$route.query.sessionId,
topMessageId : lastMsg.id || null
}
}));
}, },
/** /**
* 把当前会话消息置为已读 * 把当前会话消息置为已读

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-22 15:09:06 * @Date: 2022-03-22 15:09:06
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-23 17:45:29 * @LastEditTime: 2022-05-24 17:24:35
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -28,7 +28,6 @@ export default {
return this.$store.state.userInfo return this.$store.state.userInfo
} }
}, },
methods:{ methods:{
logout(){ logout(){
uni.showModal({ uni.showModal({
@ -44,7 +43,7 @@ export default {
return false; return false;
} }
this.$store.commit('SET_TOKEN'); this.$store.commit('SET_TOKEN');
Im.close(); Im.logout();
this.$Router.replace('/login'); this.$Router.replace('/login');
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-28 15:38:23 * @Date: 2022-03-28 15:38:23
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-13 20:49:32 * @LastEditTime: 2022-05-17 11:44:50
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -38,7 +38,7 @@ export default {
nickname : this.userInfo.nickname nickname : this.userInfo.nickname
}); });
if(error){ if(error){
uni.$u.toast(error.message); ui.$u.totas(error.message);
return false; return false;
} }
this.$store.commit('SET_USER_INFO', {...this.userInfo}); this.$store.commit('SET_USER_INFO', {...this.userInfo});

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-28 15:38:23 * @Date: 2022-03-28 15:38:23
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-13 20:59:54 * @LastEditTime: 2022-05-24 09:57:14
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -106,7 +106,7 @@ export default {
const avatar = `${oss.host}/${oss.dir}${fileName}`; const avatar = `${oss.host}/${oss.dir}${fileName}`;
const {error, result} = await ApiPutUser({avatar}); const {error, result} = await ApiPutUser({avatar});
if(error){ if(error){
uni.$u.toast(error.message); ui.$u.totas(error.message);
return false return false
} }
this.$store.commit('SET_USER_INFO', {...this.userInfo, avatar}); this.$store.commit('SET_USER_INFO', {...this.userInfo, avatar});

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2019-08-22 19:41:20 * @Date: 2019-08-22 19:41:20
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-30 17:44:51 * @LastEditTime: 2022-05-17 11:29:38
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -10,7 +10,7 @@
</template> </template>
<script> <script>
import PageCtx from './modules/PageCtx'; import PageCtx from './components/PageCtx';
export default { export default {
components : {PageCtx}, components : {PageCtx},
onShow(){ onShow(){

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-08 18:36:14 * @Date: 2022-04-08 18:36:14
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-30 17:44:55 * @LastEditTime: 2022-05-17 11:29:41
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -10,7 +10,7 @@
</template> </template>
<script> <script>
import PageCtx from './modules/PageCtx'; import PageCtx from './components/PageCtx';
import {ApiGetCartList} from '@/common/api/cart'; import {ApiGetCartList} from '@/common/api/cart';
export default { export default {
components : {PageCtx}, components : {PageCtx},

@ -17,11 +17,10 @@
<!-- 右侧 二级分类 --> <!-- 右侧 二级分类 -->
<scroll-view class="cate-right" @scrolltolower="reachBottom" :scroll-top="scrollTop" :scroll-y="true"> <scroll-view class="cate-right" @scrolltolower="reachBottom" :scroll-top="scrollTop" :scroll-y="true">
<image class="cate-tow-img" v-if="curTwoCategory.adPictureUrl" :src="curTwoCategory.adPictureUrl" <image class="cate-tow-img" :src="`https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/category${categoryData[curIndex].id}.jpg`"></image>
@click="handleAdJump(curTwoCategory)"></image>
<!-- <view @click="onTargetGoodsList(item.id)"> --> <!-- <view @click="onTargetGoodsList(item.id)"> -->
<view class="cate-tow-group" :class="idx === curTwoCategory.children.length - 1 ? 'cate-tow-group__last' :''" <view class="cate-tow-group" :class="idx === categoryData[curIndex].children.length - 1 ? 'cate-tow-group__last' :''"
v-for="(item, idx) in curTwoCategory.children" :key="idx"> v-for="(item, idx) in categoryData[curIndex].children" :key="idx">
<text class="cate-tow-group--title">{{item.name}}</text> <text class="cate-tow-group--title">{{item.name}}</text>
<view class="cate-tow-group--item" v-for="i in item.productList" :key="i.id" <view class="cate-tow-group--item" v-for="i in item.productList" :key="i.id"
@click="$Router.push(`/goodsDetail?id=${i.id}`)"> @click="$Router.push(`/goodsDetail?id=${i.id}`)">
@ -31,9 +30,9 @@
</view> </view>
</view> </view>
<!-- </view> --> <!-- </view> -->
<BsEmpty class="empty" v-if="!curTwoCategory.children.length && !curTwoCategory.isLoading" <BsEmpty class="empty" v-if="!categoryData[curIndex].children.length && !categoryData[curIndex].isLoading"
:icon="require('@/static/common/empty_goods.png')" /> :icon="require('@/static/common/empty_goods.png')" />
<u-loadmore status="loading" v-if="curTwoCategory.isLoading" /> <u-loadmore status="loading" v-if="categoryData[curIndex].isLoading" />
</scroll-view> </scroll-view>
</view> </view>
<BsEmpty v-if="!categoryData.length && !isLoading" /> <BsEmpty v-if="!categoryData.length && !isLoading" />
@ -46,9 +45,6 @@
import {ApiGetCategoryOneList, ApiGetCategoryTwoAndGoods} from '@/common/api/goods'; import {ApiGetCategoryOneList, ApiGetCategoryTwoAndGoods} from '@/common/api/goods';
import BsEmpty from "@/components/BsEmpty"; import BsEmpty from "@/components/BsEmpty";
import UiPageHeader from '../../components/UiPageHeader.vue'; import UiPageHeader from '../../components/UiPageHeader.vue';
import { AD_LOCATION } from '@/common/dicts/ad';
import { ApiGetAdList } from '@/common/api/ad';
import { AdJump } from '@/common/utils';
export default { export default {
components: { BsEmpty, UiPageHeader }, components: { BsEmpty, UiPageHeader },
data() { data() {
@ -63,11 +59,6 @@ export default {
isLoading: true, isLoading: true,
}; };
}, },
computed:{
curTwoCategory(){
return this.categoryData[this.curIndex];
}
},
onLoad() { onLoad() {
// //
this.getCategoryData(); this.getCategoryData();
@ -103,7 +94,6 @@ export default {
item.children = []; item.children = [];
item.isLoading = true; item.isLoading = true;
this.getTwoCategoryData(item); this.getTwoCategoryData(item);
this.getTwoCategoryAd(item);
return item; return item;
}); });
this.isLoading = false; this.isLoading = false;
@ -117,24 +107,6 @@ export default {
const {error, result} = await ApiGetCategoryTwoAndGoods({categoryId : item.id}); const {error, result} = await ApiGetCategoryTwoAndGoods({categoryId : item.id});
this.$set(item, 'children', result); this.$set(item, 'children', result);
this.$set(item, 'isLoading', false); this.$set(item, 'isLoading', false);
},
async getTwoCategoryAd(item){
const {error, result} = await ApiGetAdList({
loacation : AD_LOCATION.CATEGORY_BANNER,
productCategoryId : item.id
});
if(result.length){
this.$set(item, 'adPictureUrl', result[0].pictureUrl);
this.$set(item, 'adJumpUrl', result[0].jumpUrl);
this.$set(item, 'adJumpType', result[0].jumpType);
}
},
handleAdJump(item){
console.log(item);
AdJump({
jumpUrl: item.adJumpUrl,
jumpType:item.adJumpType
});
} }
}, },
}; };

@ -1,268 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 18:19:13
* @LastEditors: ch
* @LastEditTime: 2022-07-01 17:12:16
* @Description: file content
-->
<template>
<view>
<view class="box">
<BsCommentUserInfo :userData="detail"/>
<BsCommentInfo :commentDetail="detail"/>
<BsCommentFollowInfo v-if="detail.followComment" :commentDetail="detail"/>
<BsCommentGoodsInfo class="goods-info" :goods="detail" />
</view>
<view class="reply-title">全部评论( {{detail.replyCount}})</view>
<view class="reply">
<template v-if="detail.replyCount">
<view class="reply--item" v-if="detail.merchantComment">
<view class="reply--title">
<text>
{{detail.merchantComment.userName}}
</text>
<text>{{FormatDate(detail.merchantComment.createTime, 'yyyy-mm-dd hh:ii')}}</text>
</view>
<view class="reply--ctx">{{detail.merchantComment.commentContent}}</view>
</view>
<view class="reply--item" v-for="item in detail.answerCommentList" :key="item.id" @click="handleAnswer(item)">
<view class="reply--title">
<text>
{{item.userName}} {{item.parentId !== detail.id ? ` 回复 ${item.parentUserName}` : ''}}
</text>
<text>{{FormatDate(item.createTime, 'yyyy-mm-dd hh:ii')}}</text>
</view>
<view class="reply--ctx">{{item.commentContent}}</view>
</view>
</template>
<BsEmpty v-else tips="还没有人评论哦,快来抢沙发~"/>
</view>
<view class="footer">
<view class="footer--item" v-if="!detail.followComment && detail.userId === $store.state.userInfo.id"
@click="$Router.push(`/comment?commentId=${commentId}&follow=true`)">
<u-icon name="chat" size="28rpx"></u-icon>
追评
</view>
<view class="footer--item" @click="isShowAnswer = true">
<u-icon name="chat" size="28rpx"></u-icon>
评论
</view>
<view class="footer--item" :class="{'footer--item__active' : isLike}" @click="handleUseful">
<u-icon name="thumb-up" size="28rpx" :color="isLike ? '#FF875B' : ''"></u-icon>
有用<template v-if="detail.usefulCount">({{detail.usefulCount}})</template>
</view>
</view>
<template v-if="isShowAnswer" >
<view class="reply-comment--bg" @click="handleHideAnswer"></view>
<view class="reply-comment">
<view class="reply-comment--box">
<input class="reply-comment--input" maxlength="500" v-model="commentContent" :placeholder="placeholder" />
<UiButton type="gradual" :disable="!commentContent.trim()" @click="handleSubmit"></UiButton>
</view>
</view>
</template>
</view>
</template>
<script>
import BsCommentGoodsInfo from '../../../components/BsCommentGoodsInfo.vue'
import BsCommentInfo from '../../../components/BsCommentInfo.vue'
import BsCommentUserInfo from '../../../components/BsCommentUserInfo.vue'
import UiButton from '../../../components/UiButton.vue'
import {ApiGetCommentDetail, ApiPostComment, ApiPutCommentUseful} from '@/common/api/comment'
import {HandleApiError, Debounce, FormatDate} from '@/common/utils'
import COMMENT from '@/common/dicts/comment'
import BsEmpty from '../../../components/BsEmpty.vue'
import BsCommentFollowInfo from '../../../components/BsCommentFollowInfo.vue'
export default {
components: { BsCommentGoodsInfo, BsCommentInfo, UiButton, BsCommentUserInfo, BsEmpty, BsCommentFollowInfo },
data(){
return {
isShowAnswer : false,
answer : null,
commentId : this.$Route.query.id,
detail : {},
commentContent : '',
isLike : false
}
},
computed:{
placeholder(){
return this.answer ? `回复:${this.answer.userName}` : '说点什么吧?'
},
replyCount(){
}
},
onShow(){
this.getDetail();
},
methods:{
FormatDate,
async getDetail(){
const {error, result} = await ApiGetCommentDetail({
commentId : this.commentId
});
if(!HandleApiError(error,'getDetail')){
this.detail = result;
this.isLike = result.isLike || false;
this.detail.usefulCount = this.detail.usefulCount || 0;
this.detail.replyCount = this.detail.replyCount || 0;
// if(result.merchantComment){
// this.detail.answerCommentList.unshift({
// ...result.merchantComment,
// parentId : result.id
// })
// }
}
},
async handleSubmit(){
let data = {
commentContent : this.commentContent,
commentType : COMMENT.TYPE.ANSWER,
originId : this.detail.id,
parentId : this.answer ? this.answer.id : this.detail.id
}
const {error, result} = await ApiPostComment(data);
if(!HandleApiError(error)){
this.detail.answerCommentList.unshift({
...result,
userName : this.$store.state.userInfo.nickname,
parentUserName: this.answer ? this.answer.userName : ''
});
this.commentContent = '';
this.detail.replyCount++;
uni.$u.toast('评论成功!');
}
},
handleAnswer(item){
this.isShowAnswer = true;
this.answer = item;
},
handleHideAnswer(...e){
this.isShowAnswer = false;
this.answer = null;
},
handleUseful(){
this.isLike = !this.isLike
if(this.isLike){
this.detail.usefulCount++;
}else{
this.detail.usefulCount--;
}
if(!this.debounce){
this.debounce = Debounce(this.updateUseFul, 500);
}
this.debounce();
},
async updateUseFul(){
if(this.isLike === this.detail.isLike){
return false
}
const {error, result} = await ApiPutCommentUseful({
commentId : this.detail.id,
isLike : this.isLike
});
HandleApiError(error);
}
}
}
</script>
<style lang="scss">
page{
background: $color-grey1;
padding-bottom: 140rpx;
}
</style>
<style lang="scss" scoped>
.box{
background: $color-grey0;
padding: 40rpx;
}
.goods-info{
margin-top: 30rpx;
border: 1px solid #f8f8f8;
}
.reply-title{
height: 70rpx;
line-height: 70rpx;
margin-bottom:1rpx;
margin-top: 20rpx;
background: #fff;
padding: 0 40rpx;
}
.reply{
background: #fff;
padding: 0 40rpx;
overflow: hidden;
&--item{
border-bottom: 1px solid $color-grey1;
padding-top: 40rpx;
}
&--title{
display: flex;
justify-content: space-between;
text{
color: #999;
}
}
&--ctx{
margin: 26rpx 0;
line-height: 36rpx;
word-break: break-all;
}
}
.footer{
height: 124rpx;
position: fixed;
bottom: var(--window-bottom);
left: 0;
right: 0;
display: flex;
justify-content: space-around;
align-items: center;
background: #fff;
border-top: 1px solid #f8f8f8;
&--item{
display: flex;
align-items: center;
&__active{
color: $color-yellow3;
}
}
}
.reply-comment--bg{
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
z-index: 1;
}
.reply-comment{
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 2;
background: #fff;
height: 124rpx;
padding: 24rpx 40rpx;
border-top: 1px solid #f8f8f8;
&--box{
display: flex;
background: #F5F5F5;
border-radius: 38rpx;
}
&--input{
flex: 1;
padding:0 20rpx 0 40rpx;
height: 76rpx;
line-height: 76rpx;
}
}
</style>

@ -1,203 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 16:51:03
* @LastEditors: ch
* @LastEditTime: 2022-06-30 22:40:31
* @Description: file content
-->
<template>
<view>
<view class="header">
<view class="tab">
<view class="tab--item" :class="{'tab--item__active' : tabActive == i.labelType}"
v-for="i in tabs" :key="i.labelType" @click="handleChangeTab(i)">
{{i.labelName}}({{i.commentCount}})
</view>
</view>
<view @click="sortChange">
<image v-if="timeSortType" class="header--sort" src="@/static/comment/sort_active.png"/>
<image v-else class="header--sort" src="@/static/comment/sort.png"/>
</view>
</view>
<view class="comment" v-for="item in list" :key="item.id" >
<view>
<BsCommentUserInfo :userData="item"/>
<BsCommentInfo :commentDetail="item"/>
<BsCommentFollowInfo v-if="item.followComment" :commentDetail="item"/>
<BsCommentMerchant v-if="item.merchantComment" :merchantComment="item.merchantComment"/>
</view>
<BsCommentThumbup :commentDetail="item"/>
</view>
<u-loadmore :status="loadingStatus" v-if="loadingStatus === 'loading'"/>
<view class="other" v-if="otherCount" @click="$Router.push(`/goodsCommentOtherList?id=${productId}`)">
已折叠{{otherCount}}条帮助不大的评价
<u-icon name="arrow-right" color="#999" size="15"></u-icon>
</view>
</view>
</template>
<script>
import BsCommentInfo from '../../../components/BsCommentInfo.vue'
import BsCommentUserInfo from '../../../components/BsCommentUserInfo.vue'
import {ApiGetCommentList, ApiGetCommentCount, ApiGetCommentTabCount} from '@/common/api/comment';
import {HandleApiError} from '@/common/utils'
import BsCommentFollowInfo from '../../../components/BsCommentFollowInfo.vue';
import BsCommentThumbup from '../../../components/BsCommentThumbup.vue';
import BsCommentMerchant from '../../../components/BsCommentMerchant.vue';
export default {
components: { BsCommentInfo, BsCommentUserInfo, BsCommentFollowInfo, BsCommentThumbup, BsCommentMerchant },
data (){
return {
list : [],
pageIndex : 1,
pageSize : 10,
productId : this.$Route.query.id,
loadingStatus : 'loading',
otherCount : 0,
timeSortType : false,
tabActive : -1,
tabs : [
{
labelName : '全部',
labelType : -1,
commentCount : 0
}
]
}
},
onLoad(){
this.getList();
this.getTabCount();
this.getCount()
},
onReachBottom(){
this.next();
},
methods:{
async getList(){
this.loadingStatus = 'loading';
const {error, result} = await ApiGetCommentList({
pageIndex : this.pageIndex,
length : this.pageSize,
productId : this.productId,
commentLabel : this.tabActive == -1 ? null : this.tabActive,
sortType : this.timeSortType ? 2 : 1,
isContent : true
});
if(!HandleApiError(error, 'getList')){
this.list = this.list.concat(result.records);
//
if(result.records.length == 0 && this.pageIndex < result.pages){
this.next();
return false;
}
//
// if(result.records.length < this.pageSize){
if(result.pages == this.pageIndex){
this.loadingStatus = 'nomore';
}
}
},
async getTabCount (){
const {error, result} = await ApiGetCommentTabCount({
productId : this.productId
});
if(!HandleApiError(error, 'getTabCount')){
this.tabs = this.tabs.concat(result.filter(i => i.commentCount > 0));
}
},
async getCount(){
const {error, result} = await ApiGetCommentCount({
productId : this.productId
});
if(!HandleApiError(error, 'getCount')){
this.otherCount = result.defaultCommentCount;
this.$set(this.tabs[0],'commentCount', result.allCommentCount)
}
},
calcDay(item, createTime){
const followTime = (new Date(item.createTime)).getTime();
const commentTime = (new Date(createTime)).getTime();
const day = Math.floor((followTime - commentTime) / (24 * 60 * 60 * 1000));
return day > 0 ? `${day}天后` : `当天`;
},
sortChange(){
this.timeSortType = !this.timeSortType;
this.list = [];
this.pageIndex = 1;
this.getList();
},
handleChangeTab(item){
this.tabActive = item.labelType;
this.pageIndex = 1;
this.list = [];
this.getList();
},
next(){
if(this.loadingStatus === 'nomore'){
return false
}
this.pageIndex++;
this.getList();
}
}
}
</script>
<style lang="scss">
page{
background: $color-grey1;
}
</style>
<style lang="scss" scoped>
.header{
background: $color-grey0;
height: 79rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 40rpx;
.tab{
display: flex;
justify-content: flex-start;
&--item{
font-size: 28rpx;
line-height: 75rpx;
margin-right: 64rpx;
&__active{
border-bottom: 4rpx solid $color-yellow3;
}
}
}
&--sort{
width: 30rpx;
height: 30rpx;
}
}
.comment{
margin-top:20rpx ;
background: $color-grey0;
padding: 40rpx;
}
.follow{
margin-top: 40rpx;
&--title{
color: $color-yellow3;
font-size: 28rpx;
}
&--ctx{
margin-top: 20rpx;
font-size: 30rpx;
line-height: 46rpx;
}
}
.other{
display: flex;
align-items: center;
color: #999;
width: 360rpx;
margin: 20rpx auto;
height: 100rpx;
}
</style>

@ -1,109 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 16:51:03
* @LastEditors: ch
* @LastEditTime: 2022-06-28 20:44:13
* @Description: file content
-->
<template>
<view>
<view class="comment" v-for="item in list" :key="item.id">
<BsCommentUserInfo :userData="item"/>
<BsCommentInfo :commentDetail="item"/>
<BsCommentThumbup :commentDetail="item"/>
</view>
<u-loadmore :status="loadingStatus" v-if="loadingStatus === 'loading'"/>
</view>
</template>
<script>
import BsCommentInfo from '../../../components/BsCommentInfo.vue'
import BsCommentUserInfo from '../../../components/BsCommentUserInfo.vue'
import {ApiGetCommentList, ApiGetCommentCount, ApiGetCommentTabCount} from '@/common/api/comment';
import {HandleApiError} from '@/common/utils'
import BsCommentThumbup from '../../../components/BsCommentThumbup.vue';
export default {
components: { BsCommentInfo, BsCommentUserInfo, BsCommentThumbup },
data (){
return {
list : [],
pageIndex : 1,
pageSize : 10,
productId : this.$Route.query.id,
loadingStatus : ''
}
},
onLoad(){
this.getList();
},
onReachBottom(){
this.next();
},
methods:{
async getList(){
if(this.loadingStatus === 'loading'){
return false
}
this.loadingStatus = 'loading';
const {error, result} = await ApiGetCommentList({
pageIndex : 1,
length : this.pageSize,
productId : this.productId,
sortType : 1,
isContent : false
});
if(!HandleApiError(error, 'getList')){
this.list = result.records;
//
if(result.records.length < this.pageSize){
this.loadingStatus = 'nomore';
}
}
},
next(){
if(this.loadingStatus === 'nomore'){
return false
}
this.pageIndex++;
this.getList();
}
}
}
</script>
<style lang="scss">
page{
background: $color-grey1;
}
</style>
<style lang="scss" scoped>
.header{
background: $color-grey0;
height: 79rpx;
display: flex;
justify-content: space-between;
padding: 0 40rpx;
.tab{
display: flex;
justify-content: flex-start;
&--item{
font-size: 28rpx;
line-height: 75rpx;
margin-right: 64rpx;
&__active{
border-bottom: 4rpx solid $color-yellow3;
}
}
}
}
.comment{
margin-top:20rpx ;
background: $color-grey0;
padding: 40rpx;
}
.other{
text-align: center;
color: #999;
margin: 40rpx 0 20rpx;
}
</style>

@ -1,187 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-22 15:15:22
* @LastEditors: ch
* @LastEditTime: 2022-07-01 17:14:16
* @Description: file content
-->
<template>
<view class="preview">
<view class="preview--top">
<image class="preview--back" src="@/static/common/back_white.png" @click="$Router.back()"></image>
<view class="preview--title">{{current + 1}}/{{imgs.length}}</view>
</view>
<u-swiper height="calc(100vh - 420rpx)" :list="imgs" :current="current"
@change="handleChange" :autoplay="false" imgMode="aspectFit" radius="0"/>
<view class="preview--footer">
<view class="preview--user">
<image class="preview--avatar" :src="data.userAvatar"></image>
<view>
<view>{{data.userName}}</view>
<view v-if="data.skuName">{{data.skuName}}</view>
</view>
</view>
<view>
<view class="preview--rate">
<u-rate count="5" size="30rpx" :value="data.commentScore" activeColor="#FFA35B" readonly inactiveColor="#DDD"></u-rate>
<text class="preview--time">{{FormatDate(data.createTime, 'yyyy-mm-dd hh:ii')}}</text>
</view>
<view class="preview--ctx">{{ data.commentContent }}</view>
</view>
<view class="thumb">
<view class="thumb--item" @click="handleUseful">
<u-icon color="#fff" :name="isLike ? 'thumb-up-fill' : 'thumb-up'"></u-icon>
<text>{{data.usefulCount || 0}}</text>
</view>
<view class="thumb--item" @click="$Router.replace(`/goodsCommentDetail?id=${data.id}`)">
<u-icon color="#fff" name="chat"></u-icon>
<text>{{data.replyCount}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
import BsCommentUserInfo from '@/components/BsCommentUserInfo.vue';
import BsCommentThumbup from '../../../components/BsCommentThumbup.vue';
import {ApiPutCommentUseful} from '@/common/api/comment'
import { Debounce,FormatDate, HandleApiError} from '@/common/utils'
export default {
components: { BsCommentUserInfo,BsCommentThumbup },
data (){
return {
data : this.$store.state.comment_preview,
current : Number(this.$Route.query.idx),
isLike : false
}
},
computed : {
imgs(){
const arr = this.data.pictureUrl || [];
return arr.split(',')
}
},
onShow(){
if(!this.data.id){
this.$Router.back();
};
this.isLike = this.data.isLike
},
methods:{
FormatDate,
handleChange(idx){
this.current = idx.current
},
handleUseful(){
this.isLike = !this.isLike
if(this.isLike){
this.data.usefulCount++;
}else{
this.data.usefulCount--;
}
if(!this.debounce){
this.debounce = Debounce(this.updateUseFul, 500);
}
this.debounce();
},
async updateUseFul(){
if(this.isLike === this.data.isLike){
return false
}
const {error, result} = await ApiPutCommentUseful({
commentId : this.data.id,
isLike : this.isLike
});
HandleApiError(error);
}
}
}
</script>
<style lang="scss">
page{
background: #000;
}
</style>
<style lang="scss" scoped>
.preview{
&--top{
height: 44px;
padding: 0 20px;
display: flex;
justify-content: space-between;
align-items: center;
position: -webkit-sticky;
position: sticky;
top: var(--window-top);
z-index: 999;
}
&--back{
width: 14rpx;
height: 28rpx;
}
&--title{
flex: 1;
text-align: center;
color: #fff;
font-size: 32rpx;
}
&--footer{
padding: 40rpx;
}
&--user{
display: flex;
view{
color: #fff;
}
}
&--avatar{
width: 70rpx;
height: 70rpx;
background: #ccc;
margin-right: 20rpx;
border-radius: 50%;
}
&--rate{
display: flex;
align-items: center;
justify-content: space-between;
margin: 20rpx 0 ;
}
&--time{
color: #fff;
font-size: 24rpx;
}
&--ctx{
color: #fff;
@include ellipses(2);
line-height: 32rpx;
height: 60rpx;
}
}
.thumb{
display: flex;
justify-content: flex-end;
margin-top: 20rpx;
&--item{
display: flex;
align-items: center;
margin-left: 50rpx;
text{
font-size: 24rpx;
margin-left: 10rpx;
color: #fff;
}
}
&--icon{
font-size: 24rpx;
margin-left: 10rpx;
color: #fff;
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-23 17:27:21 * @Date: 2022-03-23 17:27:21
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-04 16:26:33 * @LastEditTime: 2022-05-19 11:24:09
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -22,16 +22,14 @@
</view> </view>
<view class="goods-info--title">{{goods.name}}</view> <view class="goods-info--title">{{goods.name}}</view>
</view> </view>
<view class="box"> <view class="select">
<Service></Service> <Service></Service>
<u-cell v-if="stock > 0" label="选择" :value="curSku.name || '请选择规格'" :border="false" isLink @click="onShowSkuPopup(1)"></u-cell> <u-cell v-if="stock > 0" label="选择" :value="curSku.name || '请选择规格'" :border="false" isLink @click="onShowSkuPopup(1)"></u-cell>
<SkuPopup v-model="curSku" :visible.sync="showSkuPopup" :mode="skuMode" <SkuPopup v-model="curSku" :visible.sync="showSkuPopup" :mode="skuMode"
:goodsInfo="goods" :skuInfo="skuInfoData" :activityStatus="activityStatus"> :goodsInfo="goods" :skuInfo="skuInfoData" :activityStatus="activityStatus">
</SkuPopup> </SkuPopup>
</view> </view>
<view class="goods-desc">
<Comment v-if="commentCount" :commentList="commentList" :count="commentCount" :productId="goodsId"/>
<view class="box goods-desc">
<mp-html :content="goods.detail"/> <mp-html :content="goods.detail"/>
</view> </view>
<view class="footer--not-stock" v-if="stock === 0">~</view> <view class="footer--not-stock" v-if="stock === 0">~</view>
@ -49,23 +47,20 @@
</template> </template>
<script> <script>
import {FormatDate, HandleApiError} from '@/common/utils'; import {FormatDate} from '@/common/utils';
import {ApiGetGoodsDetail, ApiGetGoodsSkus} from '@/common/api/goods'; import {ApiGetGoodsDetail, ApiGetGoodsSkus} from '@/common/api/goods';
import {ApiGetCommentList, ApiGetCommentCount} from '@/common/api/comment'; import SlideImage from './components/SlideImage.vue';
import SlideImage from './modules/SlideImage.vue'; import Service from './components/Service.vue';
import Service from './modules/Service.vue'; import SkuPopup from './components/SkuPopup.vue';
import SkuPopup from './modules/SkuPopup.vue';
import SeckillPrice from './modules/SeckillPrice.vue';
import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html'; import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html';
import UiButton from '../../../components/UiButton.vue'; import UiButton from '../../../components/UiButton.vue';
import Comment from './modules/Comment.vue'; import SeckillPrice from './components/SeckillPrice.vue';
export default { export default {
components: { SlideImage, mpHtml, Service, SkuPopup, UiButton, SeckillPrice, Comment}, components: { SlideImage, mpHtml, Service, SkuPopup, UiButton, SeckillPrice},
data(){ data(){
return { return {
// 1 // 1
stock : 1, stock : 1,
goodsId : this.$Route.query.id,
goods : { goods : {
pictureList : [] pictureList : []
}, },
@ -78,10 +73,7 @@ export default {
sku : '', sku : '',
num : 1 num : 1
}, },
productActivityVO : {}, productActivityVO : {}
commentList : [],
commentCount : 0
} }
}, },
computed:{ computed:{
@ -104,11 +96,8 @@ export default {
async getGoodsDetail(){ async getGoodsDetail(){
const {query} = this.$Route; const {query} = this.$Route;
const {error, result} = await ApiGetGoodsDetail({id : query.id}); const {error, result} = await ApiGetGoodsDetail({id : query.id});
if(HandleApiError(error, 'getGoodsDetail')){ if(error){
return false; uni.$u.toast(error.message);
}
if(!result.isEnable){
this.$Router.replace('/enable')
return false; return false;
} }
this.goods = {...result, this.goods = {...result,
@ -130,42 +119,22 @@ export default {
originalPrice:result.startingPrice originalPrice:result.startingPrice
}; };
this.getGoodsSkus(); this.getGoodsSkus();
this.getComment();
this.getCommentCount();
}, },
async getGoodsSkus(){ async getGoodsSkus(){
const {error, result} = await ApiGetGoodsSkus({productId : this.goodsId}); const {query} = this.$Route;
if(!HandleApiError(error, 'getGoodsSkus')){ const {error, result} = await ApiGetGoodsSkus({productId : query.id});
// if(error) {
this.stock = 0; uni.$u.toast(error.message);
this.skuInfoData = result.map(i => { return false;
this.stock += i.stock;
// i.attributeSymbolList = i.attributeSymbolList.split(',')
return i;
});
}
},
async getCommentCount (){
const {error, result} = await ApiGetCommentCount({
productId : this.goods.id
});
if(!HandleApiError(error, 'getCommentCount')){
this.commentCount = result.allCommentCount;
} }
}, //
async getComment(){ this.stock = 0;
const {error, result} = await ApiGetCommentList({ this.skuInfoData = result.map(i => {
pageIndex : 1, this.stock += i.stock;
length : 2, // i.attributeSymbolList = i.attributeSymbolList.split(',')
productId : this.goods.id, return i;
isContent : true,
sortType : 1
}); });
if(!HandleApiError(error, 'getComment')){
this.commentList = result.records;
}
}, },
/** /**
* 显示/隐藏SKU弹窗 * 显示/隐藏SKU弹窗
@ -200,7 +169,10 @@ page {
width: 50rpx; width: 50rpx;
height: 50rpx; height: 50rpx;
left: 40rpx; left: 40rpx;
/* #ifdef H5 */
top: 40rpx; top: 40rpx;
/* #endif */
/* #ifndef H5 */ /* #ifndef H5 */
top: 128rpx; top: 128rpx;
/* #endif */ /* #endif */
@ -237,12 +209,15 @@ page {
} }
.box{ .select{
margin: 20rpx 30rpx; margin: 20rpx 30rpx;
background: $color-grey0; background: $color-grey0;
border-radius: 16rpx; border-radius: 16rpx;
} }
.goods-desc{ .goods-desc{
margin: 20rpx 30rpx;
background: $color-grey0;
border-radius: 16rpx;
padding: 20rpx; padding: 20rpx;
} }
.footer{ .footer{

@ -1,90 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 16:23:27
* @LastEditors: ch
* @LastEditTime: 2022-06-28 11:31:02
* @Description: file content
-->
<template>
<UiWhiteBox @click="handleJumpCmment">
<view class="comment-title">
<text class="comment-title--left">用户评价({{count}})</text>
<text class="comment-title--right">查看全部</text>
</view>
<view class="comment-ctx" v-if="commentList && commentList.length">
<view v-for="item in commentList" :key="item.id">
<BsCommentUserInfo :userData="item"/>
<BsCommentInfo class="comment-ctx--item" :commentDetail="item" :imgPreview="false"/>
</view>
</view>
</UiWhiteBox>
</template>
<script>
import BsCommentInfo from '../../../../components/BsCommentInfo.vue'
import BsCommentUserInfo from '../../../../components/BsCommentUserInfo.vue'
import UiCell from '../../../../components/UiCell.vue'
import UiWhiteBox from '../../../../components/UiWhiteBox.vue'
export default {
components: { BsCommentInfo, UiCell, UiWhiteBox, BsCommentUserInfo },
props : {
count : {
type : Number,
default : 0
},
productId : {
type : Number | String,
default : 0
},
commentList : {
type : Array,
default : () => ([])
}
},
data(){
return {
}
},
methods:{
handleJumpCmment(){
let url = '/goodsCommentOtherList'
if(this.commentList.length){
url = '/goodsCommentList'
}
this.$Router.push({
path : url,
query : {
id : this.productId
}
})
}
}
}
</script>
<style lang="scss" scoped>
.comment-title{
display: flex;
justify-content: space-between;
padding:30rpx;
align-items: center;
&--left{
font-size: 30rpx;
font-weight: bold;
}
&--right{
font-size: 24rpx;
color: #999;
background: url('@/static/common/arrow.png') no-repeat right center;
background-size: 10rpx;
padding-right: 32rpx;
}
}
.comment-ctx{
padding: 0 30rpx;
&--item{
padding: 20rpx 0;
}
}
</style>

@ -1,83 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-03-28 17:16:44
* @LastEditors: ch
* @LastEditTime: 2022-07-13 20:05:42
* @Description: file content
-->
<template>
<view>
<UiWhiteBox class="main">
<image class="icon" src="@/static/goods/cart.png"/>
<view class="title">商品已下架</view>
<view class="btns">
<UiButton class="btn" @click="$Router.pushTab('/')"></UiButton>
</view>
</UiWhiteBox>
<view class="recommend-title">为您推荐</view>
<BsChoiceGoods/>
</view>
</template>
<script>
import UiButton from '@/components/UiButton.vue'
import BsChoiceGoods from '../../components/BsChoiceGoods.vue'
import UiWhiteBox from '../../components/UiWhiteBox.vue'
export default {
components: { UiButton, BsChoiceGoods, UiWhiteBox }
}
</script>
<style lang="scss">
page {
background: $color-grey1;
text-align: center;
}
</style>
<style lang="scss" scoped>
.main{
padding-bottom: 40rpx;
}
.icon{
width: 400rpx;
height: 256rpx;
margin: 169rpx auto 42rpx;
}
.title{
font-size: $font-size-lg;
line-height: 44rpx;
color: $color-grey6;
}
.desc{
font-size: $font-size-sm;
line-height: 34rpx;
color: $color-grey4;
}
.btns{
margin: 74rpx 105rpx 0;
display: flex;
justify-content: space-between;
}
.recommend-title{
font-size: $font-size-lg;
text-align: center;
margin: 51rpx auto 30rpx auto;
display: flex;
align-items: center;
justify-content: space-between;
width: 500rpx;
&::after,&::before{
display: inline-block;
content: '';
width: 160rpx;
height: 2rpx;
background: linear-gradient(90deg, $color-grey3 0%, rgba(204, 204, 204, 0) 100%);
}
&::before{
background: linear-gradient(270deg, $color-grey3 0%, rgba(204, 204, 204, 0) 100%);
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-21 10:31:54 * @Date: 2022-03-21 10:31:54
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-30 17:43:22 * @LastEditTime: 2022-05-05 16:06:41
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -33,7 +33,7 @@
<script> <script>
import {ApiGetGoodsList} from '@/common/api/goods'; import {ApiGetGoodsList} from '@/common/api/goods';
import BsChoiceGoods from "@/components/BsChoiceGoods.vue"; import BsChoiceGoods from "@/components/BsChoiceGoods.vue";
import Sort from "./modules/Sort.vue"; import Sort from "./components/Sort.vue";
import UiPageHeader from '@/components/UiPageHeader.vue'; import UiPageHeader from '@/components/UiPageHeader.vue';
import UiGoodsGroup from '../../../components/UiGoodsGroup.vue'; import UiGoodsGroup from '../../../components/UiGoodsGroup.vue';
import BsEmpty from '../../../components/BsEmpty.vue'; import BsEmpty from '../../../components/BsEmpty.vue';

@ -2,13 +2,12 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-23 10:31:12 * @Date: 2022-03-23 10:31:12
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 19:38:00 * @LastEditTime: 2022-05-21 20:09:18
* @Description: file content * @Description: file content
--> -->
<template> <template>
<view class="banner"> <view class="banner">
<u-swiper bgColor="none" radius="18rpx" height="240rpx" keyName="pictureUrl" indicatorMode="dot" <u-swiper bgColor="none" @click="goDetail" radius="18rpx" keyName="url" :list="data" height="240rpx" circular indicator indicatorMode="dot"></u-swiper>
@click="goDetail" :list="data" circular indicator></u-swiper>
<view class="desc"> <view class="desc">
<view class="desc--item"> <view class="desc--item">
<image class="desc--icon" src='@/static/index/bz.png'></image> <image class="desc--icon" src='@/static/index/bz.png'></image>
@ -30,7 +29,6 @@
</view> </view>
</template> </template>
<script> <script>
import {AdJump} from '@/common/utils';
export default { export default {
data(){ data(){
return { return {
@ -40,13 +38,24 @@ export default {
props:{ props:{
data : { data : {
type : Array, type : Array,
default : ()=>([]) default : []
} }
}, },
methods:{ methods:{
goDetail(idx){ goDetail(idx){
let item = this.data[idx]; let item = this.data[idx];
AdJump(item); if(item.link){
// #ifdef H5
window.location.href = item.link;
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(item.link);
// #endif
}else{
this.$Router.push(`/goodsDetail?id=${this.data[idx].id}`)
}
} }
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2019-08-22 19:41:20 * @Date: 2019-08-22 19:41:20
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 19:39:05 * @LastEditTime: 2022-05-21 16:30:22
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -24,9 +24,9 @@
<view class="category"> <view class="category">
<view class="category--item" v-for="item in categoryList" :key="item.id" <view class="category--item" v-for="item in categoryList" :key="item.id"
@click="AdJump(item)"> @click="$Router.push(`/goodsList?categoryId=${item.id}`)">
<view class="category--image-box"> <view class="category--image-box">
<image class="category--image" :src="item.pictureUrl"></image> <image class="category--image" :src="item.picture"></image>
</view> </view>
<text class="category--title">{{item.name}}</text> <text class="category--title">{{item.name}}</text>
</view> </view>
@ -44,22 +44,39 @@
</template> </template>
<script> <script>
import BsChoiceGoods from '@/components/BsChoiceGoods'; import BsChoiceGoods from '@/components/BsChoiceGoods';
import Seckill from './modules/Seckill'; import Seckill from './components/Seckill';
import Pick from './modules/Pick'; import Pick from './components/Pick';
import Banner from './modules/Banner'; import Banner from './components/Banner';
import {ApiGetBannerData} from '@/common/api/index.js'; import {ApiGetBannerData} from '@/common/api/index.js';
import {ApiGetHomeSeckill} from '@/common/api/seckill.js'; import {ApiGetHomeSeckill} from '@/common/api/seckill.js';
import {ApiGetCategoryNav, ApiGetRecommendedGoodsList} from '@/common/api/goods.js'; import {ApiGetCategoryNav, ApiGetRecommendedGoodsList} from '@/common/api/goods.js';
import {ApiGetAdList} from '@/common/api/ad.js';
import {AD_LOCATION} from '@/common/dicts/ad.js';
import {AdJump} from '@/common/utils';
export default { export default {
components : {BsChoiceGoods, Pick, Banner, Seckill}, components : {BsChoiceGoods, Pick, Banner, Seckill},
data(){ data(){
return { return {
scrollTop : 0, scrollTop : 0,
bannerList: [], bannerList: [
categoryList : [], { url : 'https://msb-edu-prod.oss-cn-beijing.aliyuncs.com/uc/account-avatar/banner6.jpg',
link : 'https://m.mashibing.com/live/1530'
},
{ url : 'https://msb-edu-prod.oss-cn-beijing.aliyuncs.com/uc/account-avatar/banner5.jpg',
link : 'https://m.mashibing.com/course/1373/1/'
},
{ url : 'https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/banner4.jpg',
id : 13
},
{ url : 'https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/1.png',
id : 30
},
{ url : 'https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/2banner.png',
id : 15
},
{ url : 'https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/3banner.png',
id : 40
}
],
categoryList : [
],
recommendedGoodsList : [], recommendedGoodsList : [],
seckillData : {activityTimeVO:{}} seckillData : {activityTimeVO:{}}
@ -69,7 +86,6 @@ export default {
this.getCategoryList(); this.getCategoryList();
this.getRecommendedGoodsList(); this.getRecommendedGoodsList();
this.getSeckillList(); this.getSeckillList();
this.getBannerData();
}, },
onReachBottom(){ onReachBottom(){
this.$refs.goodsGroup.next(); this.$refs.goodsGroup.next();
@ -90,11 +106,10 @@ export default {
}, },
methods : { methods : {
async getCategoryList(){ async getCategoryList(){
const {error, result} = await ApiGetCategoryNav();
const {error, result} = await ApiGetAdList({ if(result){
location : AD_LOCATION.HOME_HARDCOVER this.categoryList = result;
}); }
this.categoryList = result;
}, },
async getRecommendedGoodsList(){ async getRecommendedGoodsList(){
@ -104,19 +119,12 @@ export default {
} }
}, },
async getBannerData(){
const {error, result} = await ApiGetAdList({
location : AD_LOCATION.HOME_BANNER
});
this.bannerList = result || [];
},
async getSeckillList(){ async getSeckillList(){
const {error, result} = await ApiGetHomeSeckill(); const {error, result} = await ApiGetHomeSeckill();
if(result){ if(result){
this.seckillData = result; this.seckillData = result
} }
}, }
AdJump
} }
} }
</script> </script>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-22 15:36:46 * @Date: 2022-03-22 15:36:46
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-13 10:20:21 * @LastEditTime: 2022-05-24 09:57:06
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -119,7 +119,9 @@ export default {
// IM // IM
ImInit().then(() => { ImInit().then(() => {
// //
Im.getSessionList(); Im.getSessionList({
content: { sysId : 1 }
});
}); });
this.goBack(); this.goBack();

@ -1,155 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-20 14:55:54
* @LastEditors: ch
* @LastEditTime: 2022-06-30 23:43:00
* @Description: file content
-->
<template>
<view>
<view class="box" v-for="(item, idx) in list" :key="item.productId">
<BsCommentGoodsInfo :goods="item" />
<BsCommentSubmit v-if="!item.id" :commentDetail="item" :type="COMMENT.TYPE.COMMENT"
@submit="submitComment($event,idx)" @editChang="editChange($event, idx)"/>
<!-- 已评价过显示详情 -->
<template v-else>
<BsCommentInfo :commentDetail="item" v-if="!isFollow"/>
<SubmitFollowComment :commentDetail="item"
@submit="submitFollowComment($event, idx)"
@editChange="editChange($event, idx)" :isFollow="isFollow"/>
<BsCommentMerchant v-if="item.merchantComment && !isFollow" :merchantComment="item.merchantComment"/>
<BsCommentThumbup :commentDetail="item" v-if="!isFollow"/>
</template>
</view>
</view>
</template>
<script>
import { ApiGetOrderCommentDetail,ApiGetCommentDetail } from "@/common/api/comment";
import UiWhiteBox from "@/components/UiWhiteBox.vue";
import UiButton from "@/components/UiButton.vue";
import BsCommentSubmit from "@/components/BsCommentSubmit.vue";
import BsCommentGoodsInfo from '@/components/BsCommentGoodsInfo.vue';
import BsCommentInfo from '@/components/BsCommentInfo.vue';
import BsCommentMerchant from '@/components/BsCommentMerchant.vue';
import BsCommentThumbup from '@/components/BsCommentThumbup.vue';
import SubmitFollowComment from './modules/SubmitFollowComment.vue';
import COMMENT from '@/common/dicts/comment';
const SOURCE = ['goodsComment','orderList','orderDetail','comment']
export default {
components: {
UiWhiteBox,
UiButton,
BsCommentSubmit,
BsCommentGoodsInfo,
BsCommentInfo,
BsCommentMerchant,
BsCommentThumbup,
SubmitFollowComment,
},
data() {
const query = this.$Route.query;
return {
COMMENT,
list: [],
isFollow : query.follow == 'true' ? true : false,
orderId: query.orderId,
commentId : query.commentId
};
},
onLoad() {
if(this.orderId){
this.getOrderCommentDetail();
}else if(this.commentId){
this.getCommentDetail()
}
uni.setNavigationBarTitle({
title : this.isFollow ? '发表追评' : '发表评价'
});
},
beforeRouteLeave(to, from, next) {
if(this.list.findIndex(i => i.isEdit) > -1 &&
!(to.aliasPath == '/goodsCommentPreview' || to.fullPath == '/preview-image')){
uni.showModal({
content : '你正在进行商品评价,退出后评价的内容将不保存!',
cancelColor : '#999',
confirmColor : '#3A83FB',
success: async ({confirm}) => {
if(confirm){
next()
}
}
});
}else{
next();
}
},
methods: {
async getOrderCommentDetail() {
const { error, result } = await ApiGetOrderCommentDetail({
orderId: this.orderId,
});
if (error) {
uni.$u.toast(error.message);
return false;
}
this.list = result;
},
/**
* 按评论查询追评时用
*/
async getCommentDetail(){
const {error, result} = await ApiGetCommentDetail({
commentId : this.commentId
});
if (error) {
uni.$u.toast(error.message);
return false;
}
this.list = [result];
},
getFollowType(item){
let type= 'info'
//
if(this.isFollow){
type = 'form'
}
return type;
},
submitComment(result, idx){
this.$set(this.list, idx, {...this.list[idx],...result});
if(this.list.findIndex(i => !i.id) > -1){
uni.$u.toast('评论成功~');
}else{
this.$Router.replace('/commentSuccess');
}
},
editChange(isEdit, idx){
this.$set(this.list[idx], 'isEdit', isEdit);
},
submitFollowComment(result, idx){
this.$set(this.list[idx],'followComment',{
...this.list[idx].followComment,
...result
});
}
},
};
</script>
<style lang="scss">
page {
background: $color-grey1;
}
</style>
<style lang="scss" scoped>
.box{
background: $color-grey0;
margin-bottom: 20rpx;
padding:40rpx;
}
</style>

@ -1,74 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-20 16:36:41
* @LastEditors: ch
* @LastEditTime: 2022-06-29 20:32:02
* @Description: file content
-->
<template>
<view class="follow">
<BsCommentFollowInfo v-if="commentDetail.followComment"
:commentDetail="commentDetail" />
<template v-else>
<UiButton type="primaryLine" @click="showInput = true" v-if="!showInput"></UiButton>
<template v-else>
<BsCommentSubmit :commentDetail="commentDetail" :type="COMMENT.TYPE.FOLLOW_COMMENT"
@submit="handleSubmit" @editChang="handleEditChange"/>
</template>
</template>
</view>
</template>
<script>
import UiButton from '@/components/UiButton.vue'
import BsCommentFollowInfo from '@/components/BsCommentFollowInfo.vue';
import BsCommentSubmit from '@/components/BsCommentSubmit.vue';
import COMMENT from '@/common/dicts/comment';
export default {
components: { UiButton, BsCommentFollowInfo, BsCommentSubmit },
props : {
commentDetail : {
type : Object,
default : () => ({})
},
isFollow : {
type : Boolean,
default : false
}
},
data(){
return {
showInput : this.isFollow,
COMMENT,
}
},
computed:{
},
methods:{
async handleSubmit(data){
this.$emit('submit',data);
},
handleEditChange(data){
this.$emit('editChange',data);
}
}
}
</script>
<style lang="scss" scoped>
.follow{
margin-top: 40rpx;
&--title{
color: $color-yellow3;
font-size: 28rpx;
}
&--ctx{
margin-top: 20rpx;
font-size: 30rpx;
line-height: 46rpx;
}
}
.footer{
text-align: right;
}
</style>

@ -1,137 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-06-21 15:32:28
* @LastEditors: ch
* @LastEditTime: 2022-06-30 17:23:32
* @Description: file content
-->
<template>
<view class="main">
<view class="ctx">
<image class="icon" src="@/static/order/paySuccess.png"/>
<view class="title">评价成功</view>
<view class="btns">
<UiButton class="btn" @click="$Router.back()"></UiButton>
</view>
</view>
<view class="await" v-if="goodsList.length">
<view class="await--title">这些宝贝还在等你的评价哦~</view>
<BsCommentGoodsInfo class="await--goods" :goods="item" v-for="item in goodsList" :key="item.productId">
<UiButton slot="btns" size="small" type="primaryLine"
@click="$Router.push(`/comment?commentId=${item.orderId}`)">
{{item.commentStatus == 1 ? '评价' : '追评'}}
</UiButton>
</BsCommentGoodsInfo>
</view>
<view class="recommend-title">为您推荐</view>
<BsChoiceGoods></BsChoiceGoods>
</view>
</template>
<script>
import UiButton from '@/components/UiButton.vue'
import BsChoiceGoods from '../../../components/BsChoiceGoods.vue';
import {ApiGetCommentOrderDetailList} from '@/common/api/order';
import {HandleApiError} from '@/common/utils'
import BsCommentGoodsInfo from '../../../components/BsCommentGoodsInfo.vue';
export default {
components: { UiButton, BsChoiceGoods, BsCommentGoodsInfo },
data(){
return {
goodsList : []
}
},
onLoad(){
this.getAwaitGoodsList();
},
methods:{
async getAwaitGoodsList (){
const {error, result} = await ApiGetCommentOrderDetailList({
length:2,
pageIndex : 1
});
if(!HandleApiError(error, 'getAwaitGoodsList')){
this.goodsList = result.records.map(item => {
return {
productPicture : item.productImageUrl,
productName : item.productName,
skuName : item.skuDescribe,
commentStatus : item.commentStatus,
orderId : item.orderId
}
});
}
}
}
}
</script>
<style lang="scss">
page{
background: $color-grey1;
}
</style>
<style lang="scss" scoped>
.main {
text-align: center;
}
.ctx{
background: $color-grey0;
padding-bottom: 40rpx;
.icon{
width: 400rpx;
height: 256rpx;
margin: 169rpx auto 42rpx;
}
.title{
font-size: $font-size-lg;
line-height: 44rpx;
color: $color-grey6;
}
.desc{
font-size: $font-size-sm;
line-height: 34rpx;
color: $color-grey4;
}
.btns{
margin: 74rpx 105rpx 0;
display: flex;
justify-content: space-between;
}
}
.await{
margin-top: 20rpx;
background: $color-grey0;
&--title{
text-align: left;
padding: 40rpx;
border-bottom: 1px solid #f8f8f8;
}
&--goods{
padding: 20rpx 40rpx;
text-align: left;
}
}
.recommend-title{
font-size: $font-size-lg;
text-align: center;
margin: 51rpx auto 30rpx auto;
display: flex;
align-items: center;
justify-content: space-between;
width: 500rpx;
&::after,&::before{
display: inline-block;
content: '';
width: 160rpx;
height: 2rpx;
background: linear-gradient(90deg, $color-grey3 0%, rgba(204, 204, 204, 0) 100%);
}
&::before{
background: linear-gradient(270deg, $color-grey3 0%, rgba(204, 204, 204, 0) 100%);
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-15 17:46:10 * @Date: 2022-04-15 17:46:10
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 18:20:38 * @LastEditTime: 2022-05-27 11:13:24
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -13,17 +13,10 @@
<UiButton class="footer--btn" v-if="orderInfo.orderStatus === 2" @click="service"></UiButton> <UiButton class="footer--btn" v-if="orderInfo.orderStatus === 2" @click="service"></UiButton>
<!-- 已发货可以确认收货 --> <!-- 已发货可以确认收货 -->
<UiButton class="footer--btn" v-if="orderInfo.orderStatus === 4" type="gradual" @click="receive"></UiButton> <UiButton class="footer--btn" v-if="orderInfo.orderStatus === 4" type="gradual" @click="receive"></UiButton>
<UiButton class="footer--btn" type="primaryLine" v-if="orderInfo.orderStatus === ORDER.STATUS.FINISH_TAKE_GOODS"
@click="$Router.push(`/comment?orderId=${orderInfo.orderId}`)">去评价</UiButton>
<UiButton size="min" type="primaryLine" v-if="orderInfo.orderStatus === ORDER.STATUS.FINISH"
@click="$Router.push(`/comment?orderId=${orderInfo.orderId}&follow=true`)">去追评</UiButton>
<!-- 待支付可以取消支付订单 --> <!-- 待支付可以取消支付订单 -->
<template v-if="orderInfo.orderStatus === 1"> <template v-if="orderInfo.orderStatus === 1">
<UiButton class="footer--btn" @click="cancelShow = true">取消订单</UiButton> <UiButton class="footer--btn" @click="cancelShow = true">取消订单</UiButton>
<UiButton class="footer--btn" type="gradual" @click="handlePay"></UiButton> <UiButton class="footer--btn" type="gradual" @click="payShow = true">去支付</UiButton>
</template> </template>
<u-popup class="cancel" :show="cancelShow" @close="closeCancel" round="16rpx" closeable> <u-popup class="cancel" :show="cancelShow" @close="closeCancel" round="16rpx" closeable>
<view class="cancel--title">取消订单原因</view> <view class="cancel--title">取消订单原因</view>
@ -49,17 +42,14 @@
<UiButton type="gradual" :disabed="cancelValue == 0" @click="cancelOrder"></UiButton> <UiButton type="gradual" :disabed="cancelValue == 0" @click="cancelOrder"></UiButton>
</view> </view>
</u-popup> </u-popup>
<!-- <BsPay class="modal" :show.sync="payShow" :order="orderInfo"></BsPay> --> <BsPay class="modal" :show.sync="payShow" :order="orderInfo"></BsPay>
</view> </view>
</template> </template>
<script> <script>
import UiButton from '@/components/UiButton.vue' import UiButton from '@/components/UiButton.vue'
import UiCell from '@/components/UiCell.vue' import UiCell from '@/components/UiCell.vue'
import {ApiPutCancelOrder,ApiPutOrderReceive} from '@/common/api/order'; import {ApiPutCancelOrder,ApiPutOrderReceive} from '@/common/api/order'
import {ApiPostCashierPrepay} from '@/common/api/pay'; import BsPay from '../../../../components/BsPay.vue'
import BsPay from '../../../../components/BsPay.vue';
import ORDER from '@/common/dicts/order';
const ENV = process.env;
export default { export default {
components: { UiButton, UiCell, BsPay }, components: { UiButton, UiCell, BsPay },
props : { props : {
@ -70,10 +60,11 @@ export default {
}, },
data(){ data(){
return { return {
ORDER,
// //
cancelShow : false, cancelShow : false,
cancelValue : 0, cancelValue : 0,
//
payShow : false
} }
}, },
methods : { methods : {
@ -86,16 +77,16 @@ export default {
this.cancelValue = val; this.cancelValue = val;
}, },
async cancelOrder(){ async cancelOrder(){
const orderId = this.orderInfo.orderId; const ooderId = this.$Route.query.id;
const {error, result} = await ApiPutCancelOrder({ const {error, result} = await ApiPutCancelOrder({
cancelReasonType : this.cancelValue, cancelReasonType : this.cancelValue,
orderId : orderId orderId : ooderId
}); });
if(error){ if(error){
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
this.$Router.replace(`/orderDetail?id=${orderId}`); this.$Router.replace(`/orderDetail?id=${ooderId}`);
// //
}, },
/** /**
@ -109,49 +100,39 @@ export default {
success: async ({confirm}) => { success: async ({confirm}) => {
if(confirm){ if(confirm){
const {error} = await ApiPutOrderReceive({ const {error} = await ApiPutOrderReceive({
orderId : this.orderInfo.orderId orderId : this.$Route.query.id
}); });
if(error){ if(error){
uni.$toast(error.message); uni.$toast(error.message);
return false; return false;
} }
this.$Router.push(`/orderSuccess?orderId=${this.orderInfo.orderId}`); this.$Router.push('/orderSuccess');
} }
} }
}) })
// this.$msb.confirm({
// content : '',
// confirm : async ()=>{
// const {error} = await ApiPutOrderReceive({
// orderId : this.$Route.query.id
// });
// if(error){
// uni.$toast(error.message);
// return false;
// }
// this.$Router.push('/orderSuccess');
// }
// })
}, },
service(){ service(){
// uni.$u.toast('')
this.$Router.push({ this.$Router.push({
path : '/messageChat', path : '/messageChat',
query : { query : {
orderId : this.orderInfo.orderId orderId : this.orderInfo.orderId
} }
}) })
},
async handlePay(){
let payType = 'wxjsapi'
if(!this.$store.state.openId){
payType = 'h5'
}
const {error, result} = await ApiPostCashierPrepay({
orderId:this.orderInfo.orderId,
returnUrl : `${ENV.VUE_APP_STATIC_URL}/payResult?orderId=${this.orderInfo.orderId}&payType=${payType}`
});
if(error){
uni.$u.toast(error.message);
return false;
}
// #ifdef H5
window.location.href = result.wapCashierUrl;
// #endif
// #ifndef H5
this.$Router.push(`/webView?url=${encodeURIComponent(result.wapCashierUrl)}`);
// #endif
} }
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-31 17:53:43 * @Date: 2022-03-31 17:53:43
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-28 16:24:52 * @LastEditTime: 2022-05-05 20:43:19
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -35,8 +35,6 @@ export default {
'5' : {name:'已收货', icon: require('@/static/order/fh.png')}, '5' : {name:'已收货', icon: require('@/static/order/fh.png')},
// //
'6' : {name:'交易成功', icon: require('@/static/order/cg.png')}, '6' : {name:'交易成功', icon: require('@/static/order/cg.png')},
//
'7' : {name:'交易成功', icon: require('@/static/order/cg.png')},
}, },
ctxCon : {}, ctxCon : {},
startSecondNum : 0, startSecondNum : 0,

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-31 14:26:09 * @Date: 2022-03-31 14:26:09
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 11:22:41 * @LastEditTime: 2022-05-26 17:13:33
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -29,7 +29,7 @@
</template> </template>
</UiGoodsInfo> </UiGoodsInfo>
</UiWhiteBox> </UiWhiteBox>
<LogisitcsInfo v-if="orderInfo.orderType !== ORDER.TYPE.VIRTUAL" <LogisitcsInfo v-if="orderInfo.orderType !== ORDER_TYPE.VIRTUAL"
:logisitcsInfo="orderInfo.logistics" :orderId="orderInfo.orderId"/> :logisitcsInfo="orderInfo.logistics" :orderId="orderInfo.orderId"/>
<OrderInfo :orderInfo="orderInfo" /> <OrderInfo :orderInfo="orderInfo" />
<Operation :orderInfo="orderInfo" v-if="orderInfo.orderStatus !== 3"></Operation> <Operation :orderInfo="orderInfo" v-if="orderInfo.orderStatus !== 3"></Operation>
@ -40,16 +40,16 @@ import UiGoodsInfo from '@/components/UiGoodsInfo.vue';
import UiWhiteBox from '@/components/UiWhiteBox.vue'; import UiWhiteBox from '@/components/UiWhiteBox.vue';
import UiButton from '@/components/UiButton.vue'; import UiButton from '@/components/UiButton.vue';
import {ApiGetOrderDetail, ApiPutCancelOrder} from '@/common/api/order'; import {ApiGetOrderDetail, ApiPutCancelOrder} from '@/common/api/order';
import StatusTips from './modules/StatusTips.vue'; import StatusTips from './components/StatusTips.vue';
import OrderInfo from './modules/OrderInfo.vue'; import OrderInfo from './components/OrderInfo.vue';
import LogisitcsInfo from './modules/LogisitcsInfo.vue'; import LogisitcsInfo from './components/LogisitcsInfo.vue';
import Operation from './modules/Operation.vue'; import Operation from './components/Operation.vue';
import ORDER from '@/common/dicts/order' import {ORDER_TYPE} from '@/common/dicts/order'
export default { export default {
components: { UiGoodsInfo, UiWhiteBox, UiButton, StatusTips, OrderInfo, LogisitcsInfo, Operation }, components: { UiGoodsInfo, UiWhiteBox, UiButton, StatusTips, OrderInfo, LogisitcsInfo, Operation },
data(){ data(){
return { return {
ORDER, ORDER_TYPE,
orderInfo : { orderInfo : {
products:[], products:[],
logistics:{} logistics:{}
@ -79,7 +79,7 @@ export default {
this.getOrderInfo(); this.getOrderInfo();
}, },
handleSaleAfter(item){ handleSaleAfter(item){
if(this.orderInfo.orderType === ORDER.TYPE.VIRTUAL){ if(this.orderInfo.orderType === ORDER_TYPE.VIRTUAL){
uni.$u.toast('虚拟商品的订单不满足退款要求,不支持申请售后,如有问题请联系客服。'); uni.$u.toast('虚拟商品的订单不满足退款要求,不支持申请售后,如有问题请联系客服。');
}else{ }else{
this.$Router.push(`/saleAfterSelect?id=${item.orderProductId}`) this.$Router.push(`/saleAfterSelect?id=${item.orderProductId}`)

@ -2,13 +2,13 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-22 10:58:24 * @Date: 2022-03-22 10:58:24
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 18:21:13 * @LastEditTime: 2022-05-24 09:57:16
* @Description: file content * @Description: file content
--> -->
<template> <template>
<view> <view>
<view class="tabs"> <view class="tabs">
<text :class="item.key == currentTabKey && 'tabs__active'" <text :class="item.key === currentTabKey && 'tabs__active'"
v-for="item in tabListData" :key="item.key" @click="changeTab(item.key)"> v-for="item in tabListData" :key="item.key" @click="changeTab(item.key)">
{{item.name}}</text> {{item.name}}</text>
</view> </view>
@ -19,7 +19,7 @@
<view class="orders" v-for="item in orderListData" :key="item.orderId"> <view class="orders" v-for="item in orderListData" :key="item.orderId">
<view class="orders--title"> <view class="orders--title">
<text class="orders--name">官方自营</text> <text class="orders--name">官方自营</text>
<text class="orders--status" :class="[ORDER.STATUS.AWAIT_PAY,ORDER.STATUS.FINISH_PAY].includes(item.orderStatus) && 'orders--status__warn'">{{item.orderStatusDesc}}</text> <text class="orders--status" :class="[1,3].includes(item.orderStatus) && 'orders--status__warn'">{{item.orderStatusDesc}}</text>
</view> </view>
<UiGoodsInfoMax v-for="item in item.products" :key="item.orderProductId" <UiGoodsInfoMax v-for="item in item.products" :key="item.orderProductId"
:data="item" @click="$Router.push(`/orderDetail?id=${item.orderId}`)" /> :data="item" @click="$Router.push(`/orderDetail?id=${item.orderId}`)" />
@ -32,49 +32,39 @@
<view class="orders--footer"> <view class="orders--footer">
<UiButton size="min" type="gradual" <UiButton size="min" type="gradual"
v-if="item.orderStatus === ORDER.STATUS.AWAIT_PAY" @click="handlePay(item)">去支付</UiButton> v-if="item.orderStatus === 1" @click="pay(item)">去支付</UiButton>
<UiButton size="min" v-if="[ORDER.STATUS.CLOSE,ORDER.STATUS.AWAIT_PAY].includes(item.orderStatus)" <UiButton size="min" v-if="[2,3].includes(item.orderStatus)"
@click="$Router.push(`/orderDetail?id=${item.orderId}`)">查看详情</UiButton> @click="$Router.push(`/orderDetail?id=${item.orderId}`)">查看详情</UiButton>
<UiButton size="min" v-if="item.orderStatus >= ORDER.STATUS.FINISH_SEND_GOODS" <UiButton size="min" v-if="item.orderStatus >= 4"
@click="$Router.push(`/logisitcsInfo?orderId=${item.orderId}`)">查看物流</UiButton> @click="$Router.push(`/logisitcsInfo?orderId=${item.orderId}`)">查看物流</UiButton>
<UiButton size="min" type="primaryLine" <UiButton size="min" type="gradual" v-if="item.orderStatus === 4" @click="receive(item)"></UiButton>
v-if="item.orderStatus === ORDER.STATUS.FINISH_TAKE_GOODS"
@click="$Router.push(`/comment?orderId=${item.orderId}`)">去评价</UiButton>
<UiButton size="min" type="primaryLine"
v-if="item.orderStatus === ORDER.STATUS.FINISH"
@click="$Router.push(`/comment?orderId=${item.orderId}&follow=true`)">去追评</UiButton>
<UiButton size="min" type="gradual" v-if="item.orderStatus === ORDER.STATUS.FINISH_SEND_GOODS" @click="receive(item)"></UiButton>
</view> </view>
</view> </view>
<u-loadmore :status="loadingStatus" v-if="loadingStatus !== 'nomore'"/> <u-loadmore :status="loadingStatus" v-if="loadingStatus === 'loading'"/>
<!-- <BsPay :show.sync="payShow" :order="payOrder"></BsPay> --> <BsPay :show.sync="payShow" :order="payOrder"></BsPay>
</view> </view>
</template> </template>
<script> <script>
import BsEmpty from '@/components/BsEmpty.vue'; import BsEmpty from '@/components/BsEmpty.vue';
import UiButton from '@/components/UiButton.vue'; import UiButton from '@/components/UiButton.vue';
import { ApiGetOrderList, ApiPutOrderReceive } from '@/common/api/order'; import { ApiGetOrderList, ApiPutOrderReceive } from '@/common/api/order';
import {ApiPostCashierPrepay} from '@/common/api/pay';
import BsPay from '../../components/BsPay.vue'; import BsPay from '../../components/BsPay.vue';
import UiGoodsInfo from '../../components/UiGoodsInfo.vue'; import UiGoodsInfo from '../../components/UiGoodsInfo.vue';
import UiGoodsInfoMax from '../../components/UiGoodsInfoMax.vue'; import UiGoodsInfoMax from '../../components/UiGoodsInfoMax.vue';
import UiMoney from '../../components/UiMoney.vue'; import UiMoney from '../../components/UiMoney.vue';
import ORDER from '@/common/dicts/order';
const ENV = process.env;
export default { export default {
components: { BsEmpty, UiButton, BsPay, UiGoodsInfo, UiGoodsInfoMax, UiMoney }, components: { BsEmpty, UiButton, BsPay, UiGoodsInfo, UiGoodsInfoMax, UiMoney },
data () { data () {
return { return {
ORDER,
tabListData : [ tabListData : [
{key : '-1', name : '全部'}, {key : '-1', name : '全部'},
{key : ORDER.STATUS.AWAIT_PAY, name : '待付款'}, {key : '1', name : '待付款'},
{key : ORDER.STATUS.FINISH_PAY, name : '待发货'}, {key : '3', name : '待发货'},
{key : ORDER.STATUS.FINISH_SEND_GOODS, name : '待收货'}, {key : '4', name : '待收货'}
{key : ORDER.STATUS.FINISH_TAKE_GOODS, name : '待评价'} // {key : '6', name : ''}
], ],
currentTabKey : this.$Route.query.tab || '-1', currentTabKey : this.$Route.query.tab || '-1',
orderListData : [], orderListData : [],
@ -82,11 +72,12 @@ export default {
pageIndex : 1, pageIndex : 1,
pageSize : 10, pageSize : 10,
payShow : false,
payOrder : null payOrder : null
} }
}, },
onLoad(){ onLoad(){
this.getOrderList(); this.getOrderList()
}, },
onReachBottom(){ onReachBottom(){
this.next(); this.next();
@ -96,9 +87,6 @@ export default {
* 切换tab 拉取当前分类第一页数据 * 切换tab 拉取当前分类第一页数据
*/ */
changeTab(key){ changeTab(key){
if(this.loadingStatus == 'loading' || this.currentTabKey == key){
return false;
}
this.currentTabKey = key; this.currentTabKey = key;
this.pageIndex = 1; this.pageIndex = 1;
this.orderListData = []; this.orderListData = [];
@ -115,7 +103,6 @@ export default {
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
this.loadingStatus = 'finish';
// //
if(result.records.length < this.pageSize){ if(result.records.length < this.pageSize){
this.loadingStatus = 'nomore'; this.loadingStatus = 'nomore';
@ -135,25 +122,9 @@ export default {
/** /**
* 立即支付 * 立即支付
*/ */
async handlePay(item){ pay(item){
this.payShow = true;
let payType = 'wxjsapi' this.payOrder = item;
if(!this.$store.state.openId){
payType = 'h5'
}
const {error, result} = await ApiPostCashierPrepay({
orderId:item.orderId,
returnUrl : `${ENV.VUE_APP_STATIC_URL}/payResult?orderId=${item.orderId}&payType=${payType}`
});
// #ifdef H5
window.location.href = result.wapCashierUrl
// #endif
// #ifndef H5
this.$Router.push(`/webView?url=${encodeURIComponent(result.wapCashierUrl)}`);
// #endif
}, },
/** /**
@ -173,7 +144,7 @@ export default {
uni.$toast(error.message); uni.$toast(error.message);
return false; return false;
} }
this.$Router.push(`/orderSuccess?orderId=${item.orderId}`) this.$Router.push('/orderSuccess')
} }
} }
}) })

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-18 15:28:14 * @Date: 2022-04-18 15:28:14
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-22 11:22:21 * @LastEditTime: 2022-05-17 17:55:56
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -11,7 +11,7 @@
<UiGoodsInfo :class="idx === orderInfo.products.length-1 ? 'goods-info__last' : ''" :key="item.orderProductId" <UiGoodsInfo :class="idx === orderInfo.products.length-1 ? 'goods-info__last' : ''" :key="item.orderProductId"
v-for="(item, idx) in orderInfo.products" :data="item"></UiGoodsInfo> v-for="(item, idx) in orderInfo.products" :data="item"></UiGoodsInfo>
</UiWhiteBox> </UiWhiteBox>
<UiWhiteBox class="company" v-if="orderInfo.orderType !== ORDER.TYPE.VIRTUAL"> <UiWhiteBox class="company">
<text class="company--name">{{orderInfo.companyName}}</text> <text class="company--name">{{orderInfo.companyName}}</text>
<view class="company--no"> <view class="company--no">
<text>{{orderInfo.trackingNo}}</text> <text>{{orderInfo.trackingNo}}</text>
@ -38,12 +38,10 @@ import UiGoodsInfo from '@/components/UiGoodsInfo.vue'
import UiWhiteBox from '@/components/UiWhiteBox.vue' import UiWhiteBox from '@/components/UiWhiteBox.vue'
import {ApiGetOrderLogistics} from '@/common/api/order'; import {ApiGetOrderLogistics} from '@/common/api/order';
import UiCopy from '../../components/UiCopy.vue'; import UiCopy from '../../components/UiCopy.vue';
import ORDER from '@/common/dicts/order';
export default { export default {
components: { UiWhiteBox, UiGoodsInfo, UiCopy }, components: { UiWhiteBox, UiGoodsInfo, UiCopy },
data(){ data(){
return { return {
ORDER,
orderInfo : {} orderInfo : {}
} }
}, },

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-28 17:16:44 * @Date: 2022-03-28 17:16:44
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-28 16:46:43 * @LastEditTime: 2022-04-29 23:03:47
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -10,8 +10,7 @@
<image class="icon" src="@/static/order/paySuccess.png"/> <image class="icon" src="@/static/order/paySuccess.png"/>
<view class="title">交易成功</view> <view class="title">交易成功</view>
<view class="btns"> <view class="btns">
<UiButton class="btn" @click="$Router.replaceAll('/')"></UiButton> <UiButton class="btn" type="primaryLine" @click="$Router.replaceAll('/')"></UiButton>
<UiButton class="btn" type="primaryLine" @click="$Router.replace(`/comment?orderId=${orderId}`)"></UiButton>
</view> </view>
</view> </view>
</template> </template>
@ -19,11 +18,6 @@
import UiButton from '@/components/UiButton.vue' import UiButton from '@/components/UiButton.vue'
export default { export default {
components: { UiButton }, components: { UiButton },
data(){
return {
orderId : this.$Route.query.orderId
}
}
} }
</script> </script>

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-04-28 15:01:41 * @Date: 2022-04-28 15:01:41
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 18:41:57 * @LastEditTime: 2022-05-06 10:49:00
* @Description: file content * @Description: file content
--> -->
@ -55,10 +55,10 @@ export default {
this.reuqestNum++; this.reuqestNum++;
const {error, result} = await ApiGetOrderPaySatus({orderId : this.$Route.query.orderId}); const {error, result} = await ApiGetOrderPaySatus({orderId : this.$Route.query.orderId});
if(error){ if(error){
uni.$u.toast(error.message); uin.$u.toast(error.message);
return false return false
} }
if(!result.isSuccess && this.reuqestNum < 10){ if(!result.isSuccess && this.reuqestNum < 5){
setTimeout(()=>{ setTimeout(()=>{
this.getOrderInfo(); this.getOrderInfo();
}, 1000) }, 1000)
@ -69,11 +69,9 @@ export default {
}, },
back(){ back(){
const payType = this.$Route.query.payType; const payType = this.$Route.query.payType;
if(payType === 'wxjsapi'){ if(payType !== 'wxjsapi'){
this.$Router.back(); this.$Router.back(2);
}else if(payType === 'h5'){ }else{
history.back(2);
}else if(payType === 'appWx'){
this.$Router.back(); this.$Router.back();
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-31 14:26:09 * @Date: 2022-03-31 14:26:09
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-05-30 17:47:54 * @LastEditTime: 2022-04-29 23:06:54
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -29,12 +29,12 @@ import UiPageHeader from '@/components/UiPageHeader.vue'
import UiGoodsInfo from '@/components/UiGoodsInfo.vue' import UiGoodsInfo from '@/components/UiGoodsInfo.vue'
import UiWhiteBox from '@/components/UiWhiteBox.vue' import UiWhiteBox from '@/components/UiWhiteBox.vue'
import UiButton from '@/components/UiButton.vue' import UiButton from '@/components/UiButton.vue'
import StatusTips from './modules/StatusTips.vue' import StatusTips from './components/StatusTips.vue'
import UiCell from '@/components/UiCell.vue' import UiCell from '@/components/UiCell.vue'
import GoodsInfo from './modules/GoodsInfo.vue' import GoodsInfo from './components/GoodsInfo.vue'
import AwaitExamine from './modules/AwaitExamine.vue' import AwaitExamine from './components/AwaitExamine.vue'
import SubmitLogistics from './modules/SubmitLogistics.vue' import SubmitLogistics from './components/SubmitLogistics.vue'
import LogisticsInfo from './modules/LogisticsInfo.vue' import LogisticsInfo from './components/LogisticsInfo.vue'
export default { export default {
components: { UiPageHeader, UiGoodsInfo, UiWhiteBox, UiButton, StatusTips, UiCell, GoodsInfo, AwaitExamine, SubmitLogistics, LogisticsInfo }, components: { UiPageHeader, UiGoodsInfo, UiWhiteBox, UiButton, StatusTips, UiCell, GoodsInfo, AwaitExamine, SubmitLogistics, LogisticsInfo },
data(){ data(){

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-20 14:14:53 * @Date: 2022-03-20 14:14:53
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-07-13 18:18:18 * @LastEditTime: 2022-05-26 16:33:14
* @Description: file content * @Description: file content
--> -->
<template> <template>
@ -34,6 +34,21 @@
maxlength="50" placeholder="填写您想要备注的信息50字以内" /> maxlength="50" placeholder="填写您想要备注的信息50字以内" />
</UiCell> </UiCell>
</UiWhiteBox> </UiWhiteBox>
<UiWhiteBox>
<text class="play--title">支付方式</text>
<radio-group>
<u-cell title="微信支付" :border="false" @click="payType = 'wxpay'">
<image class="play--icon" slot="icon" src="@/static/order/wx.png"/>
<radio class="play--radio" slot="right-icon" color="#FF875B"
:checked="payType == 'wxpay'" ></radio>
</u-cell>
<!-- <u-cell title="支付宝支付" :border="false" @click="payType = 'alipay'">
<image class="play--icon" slot="icon" src="@/static/order/zfb.png"/>
<radio class="play--radio" slot="right-icon" color="#FF875B"
:checked="payType == 'alipay'"></radio>
</u-cell> -->
</radio-group>
</UiWhiteBox>
<UiWhiteBox class="amount"> <UiWhiteBox class="amount">
<u-cell title="商品总额" :value="`¥${orderInfo.productAmount}`" :border="false"></u-cell> <u-cell title="商品总额" :value="`¥${orderInfo.productAmount}`" :border="false"></u-cell>
@ -56,13 +71,11 @@
import {GOODS_TYPE} from '@/common/dicts/goods'; import {GOODS_TYPE} from '@/common/dicts/goods';
import UiCell from '@/components/UiCell'; import UiCell from '@/components/UiCell';
import {ApiPostSubmitOrder, ApiGetBeforeOrder, ApiGetBeforeCartOrder} from '@/common/api/order'; import {ApiPostSubmitOrder, ApiGetBeforeOrder, ApiGetBeforeCartOrder} from '@/common/api/order';
import {ApiPostCashierPrepay} from '@/common/api/pay';
import {ApiGetAddress } from '@/common/api/base'; import {ApiGetAddress } from '@/common/api/base';
import {Wxpay, Alipay} from '@/common/utils'; import {Wxpay} from '@/common/utils';
import UiButton from '@/components/UiButton.vue'; import UiButton from '@/components/UiButton.vue';
import UiWhiteBox from '../../components/UiWhiteBox.vue'; import UiWhiteBox from '../../components/UiWhiteBox.vue';
import UiGoodsInfo from '../../components/UiGoodsInfo.vue'; import UiGoodsInfo from '../../components/UiGoodsInfo.vue';
const ENV = process.env;
export default { export default {
components : {UiCell, UiButton, UiWhiteBox, UiGoodsInfo }, components : {UiCell, UiButton, UiWhiteBox, UiGoodsInfo },
data(){ data(){
@ -71,6 +84,7 @@ export default {
address : {}, address : {},
userMessage : '', userMessage : '',
orderInfo : {}, orderInfo : {},
payType : 'wxpay',
productType : this.$Route.query.productType, productType : this.$Route.query.productType,
} }
}, },
@ -175,28 +189,11 @@ export default {
uni.$u.toast(error.message); uni.$u.toast(error.message);
return false; return false;
} }
let payType = 'wxjsapi' if(this.payType === 'wxpay'){
if(!this.$store.state.openId){ Wxpay({orderId : result.orderId, openId : this.$store.state.openId});
payType = 'h5' }else{
} uni.$u.toast('暂不支持支付宝支付');
const {error:er, result:res} = await ApiPostCashierPrepay({
orderId:result.orderId,
returnUrl : `${ENV.VUE_APP_STATIC_URL}/payResult?orderId=${result.orderId}&payType=${payType}`
});
if(er){
uni.$u.toast(er.message);
return false;
} }
// #ifdef H5
window.location.replace(res.wapCashierUrl)
// #endif
// #ifndef H5
this.$Router.push(`/webView?url=${encodeURIComponent(res.wapCashierUrl)}`);
// #endif
} }
} }
} }

@ -2,7 +2,7 @@
* @Author: ch * @Author: ch
* @Date: 2022-03-21 18:08:07 * @Date: 2022-03-21 18:08:07
* @LastEditors: ch * @LastEditors: ch
* @LastEditTime: 2022-06-13 14:25:12 * @LastEditTime: 2022-05-05 10:52:27
* @Description: file content * @Description: file content
--> -->
<template> <template>

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

Loading…
Cancel
Save