70 Commits

Author SHA1 Message Date
pikachu1995@126.com
43f214b40a refactor(ui): 替换iView为TDesign组件库并优化相关代码
feat(coupon): 新增优惠券详情页面
feat(api): 添加会员评价状态更新和删除接口
perf(pagination): 统一分页大小选项为[20, 50, 100]
style(theme): 移除旧主题文件并更新样式类名
fix(menu): 修复菜单组件兼容性问题
chore(deps): 更新package.json依赖项
docs(modal): 添加全局Modal组件兼容层
2025-12-07 19:08:03 +08:00
pikachu1995@126.com
d701c72928 refactor(page-decoration): 重构移动端页面管理界面,使用Tabs组件替换分类卡片
feat(wap): 为移动端页面列表添加类型标签页功能
fix(dialog): 修复对话框确认后未隐藏的问题
style: 统一移动端页面管理样式,优化表格布局
2025-12-07 13:48:19 +08:00
pikachu1995@126.com
028f32a73c refactor(manager): 替换iView组件为TDesign并优化样式
- 将iView组件统一替换为TDesign组件
- 优化表单、表格、弹窗等交互样式
- 修复路由重复添加问题
- 更新依赖版本
- 调整布局间距与响应式
- 修复表单重置方法兼容性
- 统一消息提示组件
2025-11-30 18:19:19 +08:00
pikachu1995@126.com
e5d98d022e feat(manager): 调整分页组件默认页面大小为20
- 将所有页面的默认页面大小从10调整为20
- 更新分页选项数组,将最小值从10改为20
- 统一所有分页相关组件的pageSize默认值为20
- 修改pageSizeOpts选项为[20, 50, 100]
- 确保所有涉及分页的业务逻辑使用新的默认值
2025-11-24 13:09:11 +08:00
pikachu1995@126.com
799184fd21 style(components): 将按钮组件替换为链接样式
- 统一将页面中的 Button 组件替换为 a 标签,保持样式一致
- 添加统一的链接样式类 ops-link 和分隔符样式类 ops-sep
- 更新操作列中按钮的样式,使用颜色、光标和文本装饰属性替代原有 props 配置
- 在多个文件中调整了操作项之间的分隔符显示逻辑
- 优化表格操作列渲染函数,去除冗余的 Button 属性配置
- 保持功能不变的前提下提升界面视觉一致性
2025-11-24 11:33:54 +08:00
pikachu1995@126.com
756cb28daa fix(api): 修正更新隐私协议的API路径格式
feat(ui): 在顶部导航栏添加客服按钮及样式
添加客服按钮功能,包括获取IM链接和用户信息验证

refactor(order): 重构分销订单状态显示逻辑
统一订单状态显示为"未完成"、"完成"和"退款",并调整对应颜色
2025-11-23 16:30:41 +08:00
lifenlong
5f6eb6a26d feat(积分商品分类): 添加分页功能并支持按排序值排序
在积分商品分类页面添加分页组件,支持分页查询和排序
新增排序值字段展示,并对分类列表按排序值进行递归排序
2025-11-20 15:32:46 +08:00
pikachu1995@126.com
4efbec5741 refactor(分页): 统一调整分页大小选项为[20, 50, 100]并更新默认pageSize
style(售后订单): 优化商品图片样式,添加圆角和固定宽高
docs(售后订单): 更新售后状态显示文本,使其更清晰易懂
2025-10-27 18:34:01 +08:00
Ryan Ran
86dbc0d86e docs(README): 更新安装指导,新增yarn安装和启动步骤,移除npm相关内容以简化用户体验 2025-10-22 15:01:21 +08:00
pikachu1995@126.com
c32d011851 docs(readme): 更新交流方式和联系方式- 移除了旧的QQ群交流信息
- 新增微信交流群二维码
- 添加在线客服链接
- 精简了联系方式展示方式
- 统一了交流渠道描述格式
2025-10-20 14:52:33 +08:00
pikachu1995@126.com
311ca35afc feat(商品设置): 添加ES商品索引管理功能
新增三个API接口用于管理ES商品索引:
1. 删除ES中下架的商品
2. 删除不存在的索引
3. 生成所有商品的缓存
同时在商品设置页面添加对应操作按钮
2025-10-20 13:43:34 +08:00
Ryan Ran
1a3fae6501 fix(README & package.json): 更新 README 文档以反映 Node.js 版本兼容性,移除 NODE_OPTIONS 环境变量的依赖,确保项目在 Node.js 16 及以上版本下正常运行,优化用户安装指导。 2025-10-10 15:23:27 +08:00
Ryan Ran
3432530de7 fix(README.md): 更新文档以兼容更高的 Node.js 版本(20、18、16),并提供安装指导,确保用户能够顺利拉取最新代码和处理依赖问题。 2025-09-30 14:03:43 +08:00
Ryan Ran
af85493863 fix(buyer端升级node版本): 添加 .npmrc 和 .yarnrc 文件以支持引擎配置,更新 package.json 中的 NODE_OPTIONS 环境变量,替换多个组件中的 /deep/ 选择器为 ::v-deep,优化依赖管理,确保兼容性,兼容node16版本 2025-09-30 13:33:22 +08:00
Ryan Ran
ae85f0d612 fix(manager端升级node版本): 更新多个组件的样式,替换 /deep/ 选择器为 ::v-deep,替换 node-sass 为 sass,优化依赖管理和兼容性,兼容node16版本 2025-09-30 11:38:38 +08:00
Ryan Ran
16c4a78e29 fix(兼容性): 更新 seller 项目的 package.json 和 README.md,添加 NODE_OPTIONS 环境变量以支持 Node.js 版本 20 和 18 的运行,详细说明各版本的兼容性和安装要求,优化文档以提升用户体验。 2025-09-30 11:04:12 +08:00
Ryan Ran
8fb87aa64d feat(seller端升级node版本): 添加 .npmrc 和 .yarnrc 文件以支持引擎配置,更新 package.json 中的引擎要求并替换 node-sass 为 sass,优化依赖管理和兼容性,兼容node16版本 2025-09-29 18:26:52 +08:00
Ryan Ran
c5d675b6d2 fix(商品规格): 优化规格值处理逻辑,确保在规格值为空时移除对应行并更新表格数据,增强用户体验 2025-09-23 19:17:24 +08:00
Ryan Ran
f4d06b2d7b fix(商品审核): 更新审核功能,添加请求头以支持表单数据提交,提升接口兼容性 2025-09-23 14:14:43 +08:00
Ryan Ran
bb610a7cd8 fix(商品审核): 优化审核功能,使用FormData处理请求数据,提升代码可读性和维护性 2025-09-23 14:01:53 +08:00
misworga831
bb864e72b3 fix(商品规格): 优化规格值编辑逻辑,避免空值提交并清理错误提示 2025-09-15 21:45:47 +09:00
misworga831
c6c4797d87 fix(商品规格): 修复规格值过滤逻辑,确保移除空值并更新表格数据 2025-09-15 21:03:33 +09:00
misworga831
25fed42395 fix(商品规格): 添加内联错误提示,优化规格值验证逻辑 2025-09-15 16:04:48 +09:00
misworga831
66c4676493 fix(商品规格): 更新规格值提示信息,增加用户操作指导 2025-09-12 22:35:03 +09:00
misworga831
f8747b5d5d fix(商品操作): 优化模板和方法中的代码格式,提升可读性 2025-09-12 22:19:38 +09:00
misworga831
0eb58d4b8a fix(商品规格): 修复规格值编辑逻辑,避免对未定义索引的访问 2025-09-11 19:52:35 +09:00
pikachu1995@126.com
7b30ea343f feat(商品管理): 添加商品复制功能并优化批量操作
- 在商品操作页面添加复制商品功能,通过copyId参数区分复制操作
- 复制商品时自动清除原商品ID确保提交为新商品
- 优化批量操作按钮功能,包括上架、下架、删除和设置物流模板
- 移除未使用的批量规格更新功能
- 调整商品列表操作按钮布局,将复制功能加入操作列
2025-09-09 17:04:58 +08:00
pikachu1995@126.com
7db8484a7c feat(售后订单): 添加售后数量统计功能并显示在标签页
- 在manager和seller端添加获取售后数量统计的API接口
- 修改售后订单页面,显示各状态对应的数量统计
- 新增计算属性serviceStatusWithCount动态生成带数量的标签页
- 在初始化、搜索和状态切换时调用统计接口更新数据
2025-08-29 11:36:45 +08:00
pikachu1995@126.com
78b058009b feat(订单/商品): 添加数量统计功能并优化列表展示
- 在订单和商品管理页面添加数量统计功能
- 优化订单和商品列表的筛选和展示样式
- 统一API接口参数传递方式
- 移除重复代码和无用代码
2025-08-29 09:40:36 +08:00
pikachu1995@126.com
05abad3905 feat(会员管理): 新增会员ID搜索和头像显示功能
refactor(订单管理): 移除表格边框并优化分页选项

feat(售后订单): 添加关键字搜索字段并移除二维码功能

feat(商品管理): 新增批量操作和审核功能,优化商品列表展示

style: 移除多余的margin-top样式
2025-08-27 16:15:11 +08:00
pikachu1995@126.com
ad178b1806 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2025-08-27 10:12:05 +08:00
pikachu1995@126.com
075c20ae41 feat(订单列表): 新增搜索字段和支付方式筛选功能
- 添加关键字、商品名称、收货人和支付方式搜索字段
- 增加支付方式显示列和筛选功能
- 调整默认分页大小为20并增加100条选项
- 优化订单状态筛选逻辑
2025-08-27 10:11:40 +08:00
Ryan Ran
56420bd4d0 feat: 添加pageClientType属性以支持页面类型设置
在`renovation.vue`文件中,新增`pageClientType`属性并设置为'PC',以便于在页面数据中区分客户端类型,提升页面功能的灵活性。
2025-08-26 10:40:19 +08:00
pikachu1995@126.com
a18fc729c0 style(oss-manage): 调整表单元素宽度并优化布局结构
将日期选择器和输入框的宽度从200px统一调整为240px,提升表单元素的一致性
拆分操作区域到单独的Card组件中,改善页面布局结构
2025-08-21 16:41:46 +08:00
pikachu1995@126.com
099941a54e style: 统一输入框和选择器宽度为240px并优化卡片布局
- 将多处输入框和选择器的宽度从200px调整为240px
- 优化卡片布局结构,添加分割卡片提升可读性
- 移除部分冗余的刷新按钮和样式代码
- 调整日期选择器等表单元素的宽度为240px
2025-08-21 16:41:27 +08:00
Ryan Ran
3867d51d92 fix: 移除管理端会员列表,回收站username字段,优化成员列表组件的属性结构 2025-08-13 18:18:41 +08:00
Ryan Ran
f1be18b7e3 添加vue-virtual-scroller依赖并在消息视图中实现虚拟滚动功能,以优化对话列表的渲染性能。同时,为managerseller项目添加minimatch依赖项的解析版本以解决潜在的版本冲突。 2025-07-15 16:16:42 +08:00
Ryan Ran
ef46380f9e 添加minimatch依赖项的解析版本以解决潜在的版本冲突 2025-07-04 17:16:47 +08:00
chc
d711273cf0 商品发布参数项校验无法some问题 2025-03-12 10:28:59 +08:00
chc
5e7cf2d679 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2025-03-11 19:09:39 +08:00
chc
11319ba21f 分类参数必填校验 2025-03-11 19:09:05 +08:00
Chopper711
b4a706820e ### feat: 优化优惠折扣输入组件 (master)
- 将`Input`组件替换为`InputNumber`组件,以确保输入的优惠折扣
  在0.1到9.9之间,并支持一位小数。
- 在`full-discount-add.vue`和`full-discount-detail.vue`文件中,
  更新了`FormItem`组件的`优惠折扣`输入逻辑。
- 在`coupon-publish.vue`文件中,更新了描述文本以强调输入
  范围和格式。
- 在`coupon.vue`文件中,修复了优惠券类型判断逻辑,增加了
  "DISCOUNT"类型和未知类型的处理。
2025-02-21 17:34:58 +08:00
Chopper711
376a3223dc fix: 优化积分商品添加页面和对账单详情页面的功能 (master)
- 移除积分商品添加页面的冗余标题
- 将兑换时间选择器替换为活动时间范围选择器
- 简化验证规则,使用rangeTime替代单独的开始和结束时间
- 调整批量删除按钮和其他按钮的样式格式
- 在对账单详情页面添加删除消息提示框功能
2025-02-21 16:09:14 +08:00
Chopper711
a85ec69549 fix: 消息提示框以及消息点击查看后需要标记已读按钮优化 2025-02-20 15:48:19 +08:00
Chopper711
ebf4d6d3eb Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-ui 2025-02-20 14:57:21 +08:00
Chopper711
2ccd8265b9 fix: 消息提示框以及消息点击查看后需要标记已读按钮优化 2025-02-20 14:52:53 +08:00
chc
fb1671d062 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2025-02-17 13:41:42 +08:00
chc
95e37df2ec 电子面单物流选中错误问题 2025-02-17 13:41:05 +08:00
pikachu1995@126.com
cfde72f1ab Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2025-02-11 15:43:20 +08:00
pikachu1995@126.com
efc778acbc 微信支付配置,添加配置使用公钥还是证书 2025-02-11 15:43:09 +08:00
misworga831
37384ebadd fix: 优化商品编辑 2025-01-21 13:53:07 +08:00
misworga831
9a7aee7e97 fix: 优化商品编辑 2025-01-20 18:43:21 +08:00
chc
1a56534d28 提现设置增加校验 2025-01-20 18:12:41 +08:00
chc
79e7e5f087 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2025-01-17 17:42:58 +08:00
chc
aea03cf975 支付设置选中状态错误问题 2025-01-17 17:42:49 +08:00
pikachu1995@126.com
8ef6f944dc 微信支付配置,添加微信支付公钥 2025-01-08 16:14:14 +08:00
pikachu1995@126.com
e18d243961 优化微信支付配置,不读取密钥文件,改成读配置文件 2024-12-27 11:01:53 +08:00
chc
765b633cea Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2024-12-25 10:35:50 +08:00
chc
9c402a3878 1.查看物流信息
2.直播图片选择器修改
3.管理端隐藏会员详情
2024-12-25 10:35:40 +08:00
Chopper711
86426b087a feat: 使用InputNumber组件替换折扣输入框 (master)
在coupon-publish.vue中,将折扣输入框从Input组件更改为
InputNumber组件,以便更好地控制折扣值的输入范围。
2024-12-23 11:51:05 +08:00
chc
c5aaa2f3e2 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2024-12-02 18:05:51 +08:00
chc
cc59bb6094 售后实际退款金额显示错误问题 2024-12-02 18:05:43 +08:00
Ryan Ran
5662da1210 fix: 修改商家端分销商品列表点击链接商品不展示问题 2024-11-25 10:43:49 +08:00
Ryan Ran
863725d3ba 优化管理端活动楼层装修 2024-11-11 15:23:32 +08:00
Yer11214
b1acfbdd4b !40 修复了行政地区切换验证状态没更新的问题
Merge pull request !40 from 孟锴/feature/mengkai-master-branch
2024-10-14 07:34:03 +00:00
mengkai
001f9c3f30 修复了行政地区切换验证状态没更新的问题 2024-10-14 11:26:26 +08:00
Yer11214
8d4df4b66e Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-ui 2024-10-07 22:26:15 +08:00
Yer11214
604447508a fix: oss选择图片不展示报错bug 2024-10-07 22:26:13 +08:00
misworga831
6f30949620 fix: 移动端楼层装修促销活动移除优惠券.pc端楼层装修快捷导航外部链接无法填写问题 2024-09-23 21:18:27 +08:00
chc
10e8e82fe4 增加部分发货状态 2024-09-18 15:25:04 +08:00
311 changed files with 15890 additions and 21365 deletions

View File

@@ -0,0 +1,38 @@
## 目标
- 增加 Tabs 与内容的间距样式
- 将“查看”弹窗统一为右侧抽屉并用 `t-descriptions` 展示
- 修复自定义分词页面 `resetFields()` 报错为 TDesign 的 `reset()`
## 涉及页面与改动
### 1) 站内信模板
- 文件:`manager/src/views/sys/message/noticeMessageTemplate.vue`
- 改动:
-`t-tabs` 增加类名(如 `notice-tabs`),样式:`::v-deep(.notice-tabs .t-tabs__content){ padding-top:16px }`
- 在每个 `t-tab-panel` 内包裹 `div.tab-content` 并设 `padding-top:16px`
- 将查看详情 `t-dialog` 改为 `t-drawer``placement="right" size="800px"`),内容改为 `t-descriptions` 单列展示(标题、类型、模板内容等),保留编辑/发送交互不变
### 2) 意见反馈
- 文件:`manager/src/views/page/feedback/feedback.vue`
- 改动:
- 将详情 `t-dialog` 改为 `t-drawer`(右侧展开)
- 只读内容用 `t-descriptions` 单列展示(用户名、手机、类型、内容、图片列表),移除禁用表单控件
- 分页区域由 iView `Row/Page` 改为 `t-pagination`(保持现有页码/页大小逻辑)
- 抽屉底部仅保留“返回”按钮(左对齐)
### 3) 自定义分词
- 文件:`manager/src/views/custom-words/index.vue`
- 改动:
-`add()` 等调用中,将 `this.$refs.form.resetFields()` 替换为:
- `if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); } else { this.form = { name: '' } }`
- 初始化 `this.form` 改为显式字段对象,确保校验兼容
- 检查页面是否存在其他 iView API`$Message/$Modal`),若有统一为 `MessagePlugin/DialogPlugin`
## 验证
- 打开对应页面,切换 Tabs间距生效
- 点击“查看”→ 抽屉从右侧展开,信息以 `t-descriptions` 单列展示,底部仅“返回”按钮
- 自定义分词点击“添加”,不再出现 `resetFields` 报错,表单成功清空
- 分页切换正常且无控制台警告
## 注意
- 不改动现有业务接口与数据结构;仅替换 UI 容器与只读展示方式
- 样式值可根据视觉反馈上调(如 20px

1
.vercel/project.json Normal file
View File

@@ -0,0 +1 @@
{"neverMindDeployCard":true}

View File

@@ -1,16 +1,12 @@
## Lilishop B2B2C商城系统
#### 欢迎交流需求,交流业务,交流技术(基础问题自行解决,其他问题先看文档后提问)
#### 不用削尖脑袋往老群里加,老群活跃度较低,很多潜水党,新群相对而言活跃一些 :tw-1f606: :tw-1f606: :tw-1f606: :tw-1f606: :tw-1f606: :tw-1f606:
#### PS **演示站点所有环境均部署master分支。如果有演示站点问题可以反馈如果演示站点没问题本地运行有问题需自行处理**
##### 交流 qq 1群 961316482已满
##### 交流 qq 2群 875294241(已满)
##### 交流 qq 3群 263785057已满
##### 交流 qq 4群 674617534 (已满)
##### 交流 qq 5群 594675235
- **[在线客服](https://work.weixin.qq.com/kfid/kfc4d8dc24a73c15f44)**
- **微信交流1群(已满)**
- **微信交流2群**:
![微信群](https://lilishop-wechat.oss-cn-beijing.aliyuncs.com/wechat.jpg)
##### 体验 公众号/小程序/APP 体验,扫描二维码
@@ -19,6 +15,41 @@
[![star](https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark)](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
  ![github](https://img.shields.io/github/stars/hongyehuicheng/lilishop.svg?style=social&logo=#181717)
## 2025-10-10日更新
兼容更高的node版本16
这里我用的是node版本 v16.20.2
npm版本 8.19.4
使用yarn install 然后执行 yarn dev
yarn 安装/启动
```
// 如果没有 yarn 安装yarn
npm install yarn -g
// 切换源
yarn config set registry https://registry.npmmirror.com
// 以buyer项目为例
cd buyer
yarn install
yarn dev
```
没有二开过的项目直接拉最新代码即可,二开项目可以跟着提交记录一起同步修改 install出现问题检查的话删除 "package-lock.json" 重新install
Q&A 为什么不升级更高的node版本 :因为高node版本 OpenSSL 改动 导致旧版本 Webpack 插件会失效 试了好几次如果兼容的话 需要升级Webpack5以及其他的插件 升级内容较多 为了更稳定的还是尽量少动为主
****
## 如何在本地环境运行lilishop-ui部署视频
https://www.bilibili.com/video/BV1B28EeJEnP/
@@ -29,8 +60,11 @@ https://www.bilibili.com/video/BV1WD87eoE9F/
## 开发项目
#### 安装Node.js
保证`node`版本`14`,推荐 14.17.0
2025-10-10日拉的代码之后不限制于node版本为14这里只是以14版本为例子
可以使用 `yarn` 或者 `npm` 进行安装
#### yarn 安装/启动
@@ -49,17 +83,6 @@ yarn install
yarn dev
```
#### npm 安装/启动
```
npm config set registry https://registry.npmmirror.com
// 以buyer项目为例
cd buyer
npm run install
npm run dev
```
#### FAQ
@@ -109,6 +132,13 @@ github 镜像: https://github.com/lilishop?tab=repositories
商城UI 项目下3个文件夹
buyer买家PC端seller商家端manager后台管理端
### 前端 UI 框架与版本
- manager`tdesign-vue@^1.14.2``tdesign-icons-vue@^0.2.3``view-design@^4.7.0``vue@2.6.14`
- buyer`view-design@^4.3.2``vue@^2.6.11`
- seller`view-design@^4.6.1``vue@^2.6.10`
- im`element-ui@^2.14.1``vue@^2.6.11`
### 演示地址
PS手机验证码为 111111
@@ -223,16 +253,6 @@ PS手机验证码为 111111
4.限制商用如果需要商业使用请联系我们。QQ3409056806.或者加入qq群联系群主。
### 交流群
##### 交流 qq 1群 961316482已满
##### 交流 qq 2群 875294241已满
##### 交流 qq 3群 263785057已满
##### 交流 qq 4群 674617534已满
##### 交流 qq 5群 594675235
### 附录
有人有自己的学习视频、学习记录文档、希望宣传关联开源项目等均可以私聊仓库所有者。

1
buyer/.npmrc Normal file
View File

@@ -0,0 +1 @@
engine-strict=false

1
buyer/.yarnrc Normal file
View File

@@ -0,0 +1 @@
--ignore-engines true

View File

@@ -1,19 +1,5 @@
# new
### UI 框架与版本
## Project setup
```
npm install
```
- `view-design@^4.3.2`
- `vue@^2.6.11`
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -3,9 +3,12 @@
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
"build": "vue-cli-service build",
"dev": "vue-cli-service serve"
},
"engines": {
"node": ">=14"
},
"dependencies": {
"@amap/amap-jsapi-loader": "0.0.7",
@@ -15,11 +18,10 @@
"less": "^2.7.0",
"less-loader": "^5.0.0",
"mv-count-down": "^0.1.15",
"node-sass": "^4.14.1",
"postcss-loader": "^7.0.1",
"sass": "^1.63.6",
"postcss-loader": "^4.3.0",
"psl": "^1.8.0",
"qs": "^6.9.4",
"sass-loader": "^7.3.1",
"uuid": "^8.3.2",
"view-design": "^4.3.2",
"vue": "^2.6.11",
@@ -32,7 +34,7 @@
"devDependencies": {
"@vue/cli-service": "~4.5.0",
"compression-webpack-plugin": "^5.0.0",
"sass-loader": "^7.3.1",
"sass-loader": "^10.4.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-template-compiler": "^2.6.11"
},
@@ -40,5 +42,10 @@
"> 1%",
"last 2 versions",
"not dead"
]
],
"resolutions": {
"minimatch": "^3.1.2",
"node-sass": "npm:sass@^1.63.6",
"@achrinza/node-ipc": "9.2.2"
}
}

View File

@@ -63,7 +63,7 @@ export function addCartGoods (params) {
/**
* 创建交易
* @param client 客户端H5/移动端 PC/PC端,WECHAT_MP/小程序,APP/移动应用端
* @param client 客户端H5/移动端 PC/PC端,WECHAT_MP/小程序,APP/移动应用端
* @param way 购物车购买CART/立即购买BUY_NOW / 积分购买POINT
* @param remark 备注 非必填
*/

View File

@@ -173,7 +173,7 @@ export default {
border-radius: 18.9px;
/deep/ .ivu-input.ivu-input-large {
::v-deep .ivu-input.ivu-input-large {
border: 1.4px solid $theme_color;
box-sizing: border-box;
border-radius: 19.6px;
@@ -188,7 +188,7 @@ export default {
}
}
/deep/ .ivu-input-group-append {
::v-deep .ivu-input-group-append {
border-radius: 19.6px !important;
cursor: pointer;
box-sizing: border-box;

View File

@@ -113,12 +113,12 @@ export default {
}
}
/deep/ .ivu-card, .ivu-card-head, ._Card {
::v-deep .ivu-card, .ivu-card-head, ._Card {
margin-bottom: 20px;
@include white_background_color();
}
/deep/ .ivu-card-head {
::v-deep .ivu-card-head {
position: relative;
padding: 0 14px;
height: 50px;
@@ -140,7 +140,7 @@ export default {
cursor: pointer;
}
/deep/ .ivu-card-body {
::v-deep .ivu-card-body {
padding: 0 !important;
display: none;
}

View File

@@ -147,11 +147,11 @@ export default {
justify-content: center;
flex-direction: column;
}
/deep/.popup .ivu-drawer-body{
::v-deep.popup .ivu-drawer-body{
padding: 0!important;
background-color: #eee;
}
/deep/.popup .ivu-drawer-wrap{
::v-deep.popup .ivu-drawer-wrap{
z-index: 3001;
}
</style>

View File

@@ -326,7 +326,7 @@ export default {
.item-intro-img {
width: 100%;
min-height: 300px;
/deep/ img{
::v-deep img{
margin:0 auto;
}
}
@@ -472,7 +472,7 @@ export default {
.ivu-tabs-ink-bar {
background-color: $theme_color !important;
}
/deep/.ivu-tabs-bar{
::v-deep.ivu-tabs-bar{
border: none;
}
.item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab{

View File

@@ -84,10 +84,10 @@ export default {
border-top: 1.4px solid #e2e2e2;
}
&:hover {
/deep/ .goods-name {
::v-deep .goods-name {
color: $theme_color;
}
/deep/ .goods-desc {
::v-deep .goods-desc {
color: $theme_color;
}
}

View File

@@ -17,6 +17,10 @@ export const orderStatusList = [
name: '待发货',
status: 'UNDELIVERED'
},
{
name: '部分发货',
status: 'PARTS_DELIVERED'
},
{
name: '已发货',
status: 'DELIVERED'

View File

@@ -54,7 +54,7 @@ export default {
</script>
<style scoped lang="scss">
/deep/ .ivu-col-span-2, .ivu-col-span-4 {
::v-deep .ivu-col-span-2, .ivu-col-span-4 {
text-align: center;
color: $theme_color;
}
@@ -71,7 +71,7 @@ export default {
border-bottom: 1px solid $border_color;
padding: 16px 0;
/deep/ .ivu-col {
::v-deep .ivu-col {
padding: 8px 0;
}

View File

@@ -584,7 +584,7 @@ export default {
margin-left: 25px;
margin-top: 5px
}
/deep/ .ivu-alert-message {
::v-deep .ivu-alert-message {
p {
margin: 4px 0;
}

View File

@@ -604,22 +604,21 @@ table {
.layui-layer-wrap > .div-express-log {
max-height: 300px;
}
/deep/ .layui-layer-wrap > .div-express-log::-webkit-scrollbar{
::v-deep .layui-layer-wrap > .div-express-log::-webkit-scrollbar{
width: 1px;
height: 5px;
}
/deep/ .layui-layer-wrap > .div-express-log::-webkit-scrollbar-thumb{
::v-deep .layui-layer-wrap > .div-express-log::-webkit-scrollbar-thumb{
border-radius: 1em;
background-color: rgba(50,50,50,.3);
}
/deep/ .layui-layer-wrap > .div-express-log::-webkit-scrollbar-track{
::v-deep .layui-layer-wrap > .div-express-log::-webkit-scrollbar-track{
border-radius: 1em;
background-color: rgba(50,50,50,.1);
}
.div-express-log {
max-height: 300px;
border: solid 1px #e7e7e7;
background: #fafafa;
overflow-y: auto;

View File

@@ -70,7 +70,7 @@ module.exports = {
loaderOptions: {
sass: {
data: `@import "@/assets/styles/global.scss";` //全局加载scss
additionalData: `@import "@/assets/styles/global.scss";` //全局加载scss
},
// 向 CSS 相关的 loader 传递选项
less: {

View File

@@ -24,6 +24,7 @@
"vue-cropper": "^0.5.5",
"vue-prism-editor": "^0.5.1",
"vue-router": "^3.4.9",
"vue-virtual-scroller": "^1.1.2",
"vuex": "^3.5.1"
},
"devDependencies": {

View File

@@ -33,6 +33,11 @@ Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[key]);
});
import VueVirtualScroller from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
Vue.component('RecycleScroller', VueVirtualScroller.RecycleScroller)
// 引入自定义全局css
import '@/assets/css/global.less'

View File

@@ -65,9 +65,14 @@
> -->
</p>
<!-- 对话列表 -->
<template v-if="loadStatus === 1">
<div v-for="(item, index) in userTalkItem" :key="item.id" class="talk-item pointer"
:class="{ active: activeIndex == index }" @click="clickTab(item.userId, item, index)">
<RecycleScroller
:item-size="64"
:items="userTalkItem"
:prerender="10"
v-slot="{ item, index }"
>
<div v-bind:key="item.id" class="talk-item pointer" :class="{ active: activeIndex == index }" @click="clickTab(item.userId, item, index)">
<div class="avatar-box">
<face :text="item.face" v-if="item.face"></face>
<face-null :text="item.name" v-else></face-null>
@@ -79,9 +84,7 @@
<div class="title">
<div class="card-name">
<p class="nickname">
{{
item.remark_name ? item.remark_name : item.name
}}
{{ item.remark_name ? item.remark_name : item.name }}
</p>
<div v-show="item.unread" class="larkc-tag">
{{ item.unread }}条未读
@@ -89,11 +92,9 @@
<div v-show="item.is_top" class="larkc-tag top">
TOP
</div>
<div v-show="item.is_robot" class="larkc-tag top">
BOT
</div>
<div v-show="item.talk_type == 2" class="larkc-tag group">
群组
</div>
@@ -111,9 +112,7 @@
<span v-if="item.lastMessageType === 'ORDER'">[订单链接]</span>
</div>
<div class="content">
<template v-if="
index_name != item.index_name && item.draft_text
">
<template v-if="index_name != item.index_name && item.draft_text">
<span class="draft-color">[草稿]</span>
<span>{{ item.draft_text }}</span>
</template>
@@ -124,13 +123,12 @@
</span>
<span v-else>[群消息]</span>
</template>
<span>{{ item.msg_text }}</span>
</template>
</div>
</div>
</div>
</template>
</RecycleScroller>
</el-main>
</el-scrollbar>
</el-container>
@@ -151,6 +149,8 @@
</div>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import { mapGetters, mapState } from "vuex";
import MainLayout from "@/views/layout/MainLayout";
import WelcomeModule from "@/components/layout/WelcomeModule";
@@ -179,6 +179,7 @@ export default {
UserSearch,
OtherLink,
WelcomeModule,
RecycleScroller
},
data () {
return {

1
manager/.npmrc Normal file
View File

@@ -0,0 +1 @@
engine-strict=false

1
manager/.yarnrc Normal file
View File

@@ -0,0 +1 @@
--ignore-engines true

View File

@@ -1,33 +1,15 @@
# LILISHOP-UI
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your tests
```
npm run test
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
详情点击 [https://cli.vuejs.org/zn/config/](https://cli.vuejs.org/zn/config/).
### UI 框架与版本
- `tdesign-vue@^1.14.2`
- `tdesign-icons-vue@^0.2.3`
- `vue@2.6.14`
#### login.vue页面测试时不走权限直接return 318行
#### Main.vue 页面241行修改避免报错

View File

@@ -9,6 +9,9 @@
"build": "vue-cli-service build",
"dev": "vue-cli-service serve"
},
"engines": {
"node": ">=14"
},
"dependencies": {
"@amap/amap-jsapi-loader": "0.0.7",
"@antv/g2": "^4.1.12",
@@ -16,13 +19,16 @@
"core-js": "^3.6.5",
"dplayer": "^1.26.0",
"js-cookie": "^2.2.1",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2",
"price-color": "1.0.2",
"sass": "^1.63.6",
"sass-loader": "^10.4.1",
"sockjs-client": "^1.4.0",
"swiper": "^6.3.5",
"uuid": "^8.3.2",
"view-design": "^4.7.0",
"vue": "^2.6.10",
"tdesign-vue": "^1.14.2",
"tdesign-icons-vue": "^0.2.3",
"@vue/composition-api": "^1.7.1",
"vue": "2.6.14",
"vue-awesome-swiper": "^4.1.1",
"vue-i18n": "^8.15.1",
"vue-json-excel": "^0.3.0",
@@ -31,8 +37,7 @@
"vue-router": "^3.1.3",
"vuedraggable": "^2.23.2",
"vuex": "^3.4.0",
"xss": "^1.0.7",
"price-color":"1.0.2"
"xss": "^1.0.7"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.4.4",
@@ -47,6 +52,11 @@
"style-resources-loader": "^1.3.2",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-cli-plugin-style-resources-loader": "^0.1.4",
"vue-template-compiler": "^2.6.10"
"vue-template-compiler": "2.6.14"
},
"resolutions": {
"minimatch": "^3.1.2",
"node-sass": "npm:sass@^1.63.6",
"@achrinza/node-ipc": "9.2.2"
}
}

View File

@@ -23,7 +23,7 @@ export const postVerifyImg = (params) => {
// 获取系统基础信息
export const getBaseSite = () => {
return getRequest(`${commonUrl}/common/common/site`);
return getRequestWithNoToken(`${commonUrl}/common/common/site`);
};
// 上传文件

View File

@@ -101,20 +101,23 @@ export const getGoodsCategory = (parent_id) => {
}
// 上架商品
export const upGoods = (id, params) => {
return putRequest(`/goods/goods/${id}/up`, params)
}
// 下架商品
export const lowGoods = (id, params) => {
return putRequest(`/goods/goods/${id}/under`, params)
}
export const upGoods = (params) => {
return putRequest(`/goods/goods/up`, params)
}
// 下架商品
export const lowGoods = (params) => {
return putRequest(`/goods/goods/under`, params)
}
// 获取商品sku分页列表
export const getGoodsSkuData = (params) => {
return getRequest('/goods/goods/sku/list', params)
}
// 获取商品数量
export const getGoodsNumerData = (params) => {
return getRequest('/goods/goods/goodsNumber', params)
}
// 获取商品分页列表
export const getGoodsListData = (params) => {
return getRequest('/goods/goods/list', params)
@@ -124,8 +127,12 @@ export const getAuthGoodsListData = (params) => {
return getRequest('/goods/goods/auth/list', params)
}
// 审核商品
export const authGoods = (id, params) => {
return putRequest(`/goods/goods/${id}/auth`, params)
export const authGoods = (params) => {
return putRequest(`/goods/goods/auth`, params,{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
}
//查询分类绑定参数信息

View File

@@ -111,7 +111,7 @@ export const changeMobile = (params) => {
};
// 获取用户数据 多条件
export const getUserListData = (params) => {
return getRequest("/passport/user", params);
return getRequest("/passport/user/getByCondition", params);
};
// 通过用户名搜索
export const searchUserByName = (username, params) => {
@@ -445,6 +445,21 @@ export const getProgress = () => {
return getRequest(`/other/elasticsearch/progress`);
};
// 删除ES中下架的商品
export const deleteGoodsDown = () => {
return getRequest(`/other/elasticsearch/deleteGoodsDown`);
};
// 删除不存在的索引
export const delSkuIndex = () => {
return getRequest(`/other/elasticsearch/delSkuIndex`);
};
// 生成所有商品的缓存
export const generateGoodsCache = () => {
return getRequest(`/other/elasticsearch/cache`);
};
// 分页查询自定义分词
export const getCustomWordsPage = (params) => {
return getRequest(`/other/customWords/page`, params);

View File

@@ -160,3 +160,13 @@ export const refundLog = (params) => {
export const storeAddress = (sn) => {
return getRequest(`/order/afterSale/getStoreAfterSaleAddress/${sn}`)
}
// 获取订单数量统计
export const getOrderNum = (params) => {
return getRequest(`/order/order/orderNum`, params)
}
// 获取售后数量统计
export const getAfterSaleNumVO = (params) => {
return getRequest(`/order/afterSale/afterSaleNumVO`, params)
}

View File

@@ -114,5 +114,5 @@ export const getPrivacy = (type) => {
}
//修改隐私协议数据
export const updatePrivacy = (id,type,params) => {
return putRequest(`/other/article/updateArticle/${type}?id=${id}`, params, {"Content-Type": "application/json"})
return putRequest(`/other/article/updateArticle/${type}/${id}`, params, {"Content-Type": "application/json"})
}

View File

@@ -0,0 +1,44 @@
<template>
<t-pagination
:current="current"
:total="Number(total)"
:pageSize="pageSize"
:pageSizeOptions="pageSizeOptionsComputed"
:size="size"
:showJumper="showElevator || showJumper"
@change="onTdChange"
v-bind="$attrs"
/>
</template>
<script>
export default {
name: 'Page',
inheritAttrs: false,
props: {
current: { type: Number, default: 1 },
total: { type: [Number, String], default: 0 },
pageSize: { type: Number, default: 20 },
pageSizeOpts: { type: Array, default: () => [] },
pageSizeOptions: { type: Array, default: () => [] },
size: { type: String, default: 'small' },
showElevator: { type: Boolean, default: false },
showJumper: { type: Boolean, default: false },
showSizer: { type: Boolean, default: false },
showTotal: { type: Boolean, default: false }
},
computed: {
pageSizeOptionsComputed() {
return (this.pageSizeOptions && this.pageSizeOptions.length)
? this.pageSizeOptions
: (this.pageSizeOpts && this.pageSizeOpts.length ? this.pageSizeOpts : undefined)
}
},
methods: {
onTdChange(info) {
if (info && typeof info.current !== 'undefined') this.$emit('on-change', info.current)
if (info && typeof info.pageSize !== 'undefined') this.$emit('on-page-size-change', info.pageSize)
this.$emit('change', info)
}
}
}
</script>

View File

@@ -40,7 +40,7 @@ export default {
params: {
// 请求参数
pageNumber: 1,
pageSize: 10,
pageSize: 20,
storeName: "",
},
dateList: [

View File

@@ -1,7 +1,7 @@
<template>
<div class="wrapper">
<Button @click="handleClickUploadImage">上传图片</Button>
<Modal v-model="show" width="850" @on-ok="callback" title="上传图片">
<t-button @click="handleClickUploadImage">上传图片</t-button>
<t-dialog :visible.sync="show" :width="850" header="上传图片" @confirm="callback" @close="show=false">
<div class="import-oss" @click="importOSS">
从资源库中导入
</div>
@@ -19,51 +19,48 @@
<img alt="image" :src="item.url"/>
<div class="upload-list-cover">
<div>
<Icon
size="30"
type="md-search"
@click.native="$previewImage(item.url)"
></Icon>
<Icon
size="30"
type="md-trash"
@click.native="handleRemoveGoodsPicture(__index)"
></Icon>
<t-icon name="search" size="30" @click="$previewImage(item.url)" />
<t-icon name="delete" size="30" @click="handleRemoveGoodsPicture(__index)" />
</div>
</div>
</template>
</div>
</vuedraggable>
<div class="upload-box">
<Upload
<t-upload
ref="upload"
:action="uploadFileUrl"
:format="['jpg', 'jpeg', 'png']"
:headers="{ ...accessToken }"
:max-size="10240"
:on-exceeded-size="handleMaxSize"
:on-format-error="handleFormatError"
:on-success="handleSuccessGoodsPicture"
:show-upload-list="false"
multiple
type="drag"
accept=".jpg,.jpeg,.png"
:sizeLimit="{ size: 10240, unit: 'KB' }"
@success="handleSuccessGoodsPicture"
@fail="handleFail"
:showUploadFileList="false"
:multiple="true"
theme="dragger"
>
<div style="width: 148px; height: 148px; line-height: 148px">
<Icon size="20" type="md-add"></Icon>
<div style="width: 148px; height: 148px; line-height: 148px; display:flex; align-items:center; justify-content:center;">
<t-icon size="20" name="add" />
</div>
</Upload>
</t-upload>
</div>
</div>
</Modal>
</t-dialog>
<Modal width="1000" v-model="showOssManager" @on-ok="confirmUrls">
<OssManage ref="ossManage" :isComponent="true" :initialize="showOssManager" @selected="handleCallback" />
</Modal>
<t-dialog :width="1000" :visible.sync="showOssManager" header="资源库" @confirm="confirmUrls" @close="showOssManager=false">
<OssManage ref="ossManage" :isComponent="true" :initialize="showOssManager" @selected="(list)=>{ selectedImage = list}" @callback="handleCallback" />
<template #footer>
<t-button variant="text" @click="showOssManager=false">关闭</t-button>
<t-button theme="primary" @click="confirmUrls">确定</t-button>
</template>
</t-dialog>
</div>
</template>
<script>
import vuedraggable from "vuedraggable";
import { uploadFile } from "@/libs/axios";
import {uploadFile} from "@/libs/axios";
import { MessagePlugin } from "tdesign-vue";
// import OssManage from "@/views/sys/oss-manage/ossManage";
import OssManage from "@/views/sys/oss-manage/ossManage.vue";
export default {
@@ -88,11 +85,8 @@ export default {
};
},
methods: {
confirmUrl(){
},
handleClickUploadImage(){
this.show = true
this.show = true;
},
// 回调给父级
callback() {
@@ -105,38 +99,35 @@ export default {
this.images.splice(__index, 1);
},
// 图片大小不正确
handleMaxSize(file) {
this.$Notice.warning({
title: "超过文件大小限制",
desc: "图片大小不能超过10MB",
});
},
// 图片格式不正确
handleFormatError(file) {
this.$Notice.warning({
title: "文件格式不正确",
desc: "文件 " + file.name + " 的格式不正确",
});
handleFail({ error, file }) {
if (error && error.type === 'exceed-size') {
MessagePlugin.warning("图片大小不能超过10MB");
} else if (error && error.type === 'accept') {
MessagePlugin.warning("文件格式不正确(仅支持 .jpg/.jpeg/.png");
} else {
MessagePlugin.error("上传失败");
}
},
// sku图片上传成功
handleSuccessGoodsPicture(res, file) {
if (file.response) {
file.url = file.response.result;
handleSuccessGoodsPicture({ response, file }) {
if (response) {
file.url = response.result;
this.images.push(file);
}
},
confirmUrls(){
this.selectedImage.length ? this.selectedImage.forEach(element => {
this.images.push({ url: element.url })
}):''
// this.selectedImage.length ? this.selectedImage.forEach(element => {
// this.images.push({ url: element.url })
// }):''
this.showOssManager = false
},
handleCallback(val){
this.selectedImage = val
MessagePlugin.success("导入成功")
this.images.push({url:val.url})
},
// 从资源库中导入图片
importOSS(){
this.showOssManager = true
this.showOssManager = true;
this.$refs.ossManage.selectImage = true;
}
}

View File

@@ -51,22 +51,18 @@
<li class="hz-u-square hz-u-square-br" data-pointer="dealBR"></li>
</ul>
<Modal
v-model="showModal"
title="编辑热区"
draggable
scrollable
:mask="false"
ok-text="保存"
@on-ok="saveZone"
@on-cancel="cancelZone"
<t-dialog
:visible.sync="showModal"
header="编辑热区"
:draggable="true"
@close="cancelZone"
>
<div>
<div class="hz-edit-img">
<img class="show-image" :src="zoneForm.img" alt />
</div>
<Form :model="zoneForm" :label-width="80">
<t-form :data="zoneForm" :labelWidth="80">
<!-- <FormItem label="图片链接:">
<Input v-model="zoneForm.img"></Input>
<Button size="small" type="primary" @click="handleSelectImg"
@@ -74,26 +70,31 @@
>
:v-model="zoneForm.type === 'goods' ? zoneForm.goodsName : zoneForm.link"
</FormItem> -->
<FormItem label="跳转链接:">
<Input type="textarea" v-if="zoneForm.type === 'other' && zoneForm.title === '外部链接'" v-model="zoneForm.link" ></Input>
<Button size="small" type="primary" @click="handleSelectLink"
>选择链接</Button
>
</FormItem>
</Form>
<t-form-item label="跳转链接:">
<t-textarea v-if="zoneForm.type === 'other' && zoneForm.title === '外部链接'" v-model="zoneForm.link" />
<t-button size="small" theme="primary" @click="handleSelectLink">选择链接</t-button>
</t-form-item>
</t-form>
</div>
</Modal>
<template #footer>
<t-button variant="text" @click="cancelZone">取消</t-button>
<t-button theme="primary" @click="saveZone">保存</t-button>
</template>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</li>
</template>

View File

@@ -1,13 +1,11 @@
<template>
<Modal
:styles="{ top: '120px' }"
width="800"
@on-cancel="clickClose"
@on-ok="clickOK"
v-model="flag"
:mask-closable="false"
title="绘制热区"
scrollable
<t-dialog
:visible.sync="flag"
:width="800"
header="绘制热区"
:closeOnOverlayClick="false"
@close="clickClose"
@confirm="clickOK"
>
<template v-if="flag">
<hotzone
@@ -17,7 +15,7 @@
:image="res.img"
></hotzone>
</template>
</Modal>
</t-dialog>
</template>
<script>
import hotzone from "./components/Hotzone.vue";
@@ -57,11 +55,11 @@ export default {
};
</script>
<style scoped lang="scss">
/deep/ .ivu-modal {
::v-deep .t-dialog {
overflow: hidden;
height: 650px !important;
}
/deep/ .ivu-modal-body {
::v-deep .t-dialog__body {
width: 100%;
height: 500px;
overflow: hidden;

View File

@@ -19,7 +19,6 @@
getQueryGoodsList();
}
"
icon="ios-search"
clearable
style="width: 150px"
v-model="goodsParams.goodsName"
@@ -41,9 +40,10 @@
goodsParams.pageNumber = 1;
getQueryGoodsList();
"
icon="ios-search"
>搜索</Button
>
<template #icon><t-icon name="search" /></template>
搜索
</Button>
</div>
</div>
<div>

View File

@@ -1,5 +1,5 @@
<template>
<Modal :styles="{ top: '120px' }" width="1160" :z-index="10000" @on-cancel="clickClose" @on-ok="clickOK" v-model="flag" :mask-closable="false" scrollable>
<t-dialog :visible.sync="flag" :width="1160" header="选择" :closeOnOverlayClick="false" @close="clickClose" @confirm="clickOK">
<template v-if="flag">
<goodsDialog
@selected="
@@ -21,7 +21,7 @@
class="linkDialog"
/>
</template>
</Modal>
</t-dialog>
</template>
<script>
import goodsDialog from "./goods-dialog";
@@ -86,11 +86,11 @@ export default {
};
</script>
<style scoped lang="scss">
/deep/ .ivu-modal {
::v-deep .t-dialog {
overflow: hidden;
height: 650px !important;
}
/deep/ .ivu-modal-body {
::v-deep .t-dialog__body {
width: 100%;
height: 500px;
overflow: hidden;

View File

@@ -1,10 +1,9 @@
<template>
<div class="wrapper">
<Tabs :value="wap[0].title" class="tabs">
<TabPane
<t-tabs :value="wap[0].title" class="tabs" @change="onTabChange">
<t-tab-panel
:label="item.title"
:name="item.title"
@click="clickTag(item, i)"
:value="item.title"
v-for="(item, i) in wap"
:key="i"
>
@@ -17,9 +16,8 @@
}
"
/>
</TabPane>
<!-- </template> -->
</Tabs>
</t-tab-panel>
</t-tabs>
</div>
</template>
<script>
@@ -65,11 +63,13 @@ export default {
}
return cur;
}, []);
this.wap.forEach((items,indexs) => {
if(items.title == '活动'){
this.wap.splice(indexs,1)
if (this.$route.path !== '/floorList/main') {
this.wap.forEach((items, indexs) => {
if (items.title == '活动') {
this.wap.splice(indexs, 1)
}
})
}
}else{
this.wap.push( {
title: "活动",
@@ -94,6 +94,8 @@ export default {
});
},
methods: {
onTabChange(val){
}
// isVisible(item) {
// const type = this.$route.query.pagetype;
// if (type == "INDEX" && [ "discover"].includes(item.name)) {
@@ -120,11 +122,11 @@ export default {
width: 100%;
}
/deep/ .ivu-modal {
::v-deep .ivu-modal {
overflow: hidden;
height: 650px !important;
}
/deep/ .ivu-modal-body {
::v-deep .ivu-modal-body {
width: 100%;
height: 500px;
overflow: hidden;

View File

@@ -42,12 +42,12 @@
}
}
/deep/ .ivu-scroll-container {
::v-deep .ivu-scroll-container {
width: 100% !important;
height: 400px !important;
}
/deep/ .ivu-scroll-content {
::v-deep .ivu-scroll-content {
/* */
display: flex;
flex-wrap: wrap;
@@ -81,7 +81,7 @@
align-items: center;
margin: 10px;
/deep/ img {
::v-deep img {
width: 60px;
height: 60px;
text-align: center;

View File

@@ -70,16 +70,9 @@ export default {
params: {
// 请求参数
pageNumber: 1,
pageSize: 10,
pageSize: 20,
},
pintuanColumns: [
// 表头
{
title: "活动标题",
key: "title",
tooltip: true,
width: 250,
},
{
title: "商品名称",
key: "goodsName",
@@ -108,12 +101,12 @@ export default {
render: (h, params) => {
return h("div", [
h(
"Button",
"a",
{
props: {
// type: this.index == params.index ? "primary" : "",
type: 'default',
size: "small",
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
@@ -201,12 +194,12 @@ export default {
render: (h, params) => {
return h("div", [
h(
"Button",
"a",
{
props: {
// type: this.index == params.index ? "primary" : "",
type: 'default',
size: "small",
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
@@ -253,12 +246,12 @@ export default {
render: (h, params) => {
return h("div", [
h(
"Button",
"a",
{
props: {
// type: this.index == params.index ? "primary" : "",
type: 'default',
size: "small",
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
@@ -339,15 +332,15 @@ export default {
this.sortGoods("SECKILL");
},
};
case "COUPON":
return {
title: "优惠券",
methodsed: () => {
this.showPromotionList = [];
this.activeColumns = this.pintuanColumns;
this.sortGoods("COUPON");
},
};
// case "COUPON":
// return {
// title: "优惠券",
// methodsed: () => {
// this.showPromotionList = [];
// this.activeColumns = this.pintuanColumns;
// this.sortGoods("COUPON");
// },
// };
case "POINTS_GOODS":
return {
title: "积分商品",
@@ -383,7 +376,10 @@ export default {
getPromotion(res) {
if (res.result) {
this.promotionList = res.result;
// 去除优惠券
delete this.promotionList.COUPON;
Object.keys(res.result)[0] && this.typeOption(Object.keys(res.result)[0]).methodsed();
this.promotions = Object.keys(res.result)[0];
}
// if (Object.keys(res.result).length) {
@@ -424,7 +420,7 @@ img {
overflow: auto;
width: 100%;
}
/deep/ .ivu-table-wrapper {
::v-deep .ivu-table-wrapper {
width: 100%;
}
.list {

View File

@@ -1,8 +1,8 @@
<template>
<div>
<Row :gutter="30">
<Col
span="4"
<t-row :gutter="30">
<t-col
:span="4"
v-for="(item, index) in linkList"
:key="index"
v-if="
@@ -15,23 +15,23 @@
:class="{ active: selectedIndex == index }"
@click="handleLink(item, index)"
>
<Icon size="24" :type="item.icon" />
<t-icon name="link" size="24" />
<p>{{ item.title }}</p>
</div>
</Col>
</t-col>
<!-- 外部链接只有pc端跳转 -->
<Col span="4">
<t-col :span="4">
<div
v-if="linkVisible"
class="card"
:class="{ active: selectedIndex == linkList.length }"
@click="handleLink(linkItem, linkList.length)"
>
<Icon size="24" :type="linkItem.icon" />
<t-icon name="link" size="24" />
<p>{{ linkItem.title }}</p>
</div>
</Col>
</Row>
</t-col>
</t-row>
</div>
</template>
<script>
@@ -157,7 +157,7 @@ export default {
text-align: center;
transition: 0.35s;
cursor: pointer;
/deep/ p {
::v-deep p {
margin: 10px 0;
}
border: 1px solid #ededed;

View File

@@ -33,7 +33,7 @@ export default {
};
</script>
<style lang="scss" scoped>
/deep/ .ivu-card-body {
::v-deep .ivu-card-body {
height: 414px;
overflow: auto;
}
@@ -69,11 +69,11 @@ export default {
height: 416px;
overflow: hidden;
}
/deep/ .ivu-table {
::v-deep .ivu-table {
height: 300px !important;
overflow: auto;
}
/deep/ .ivu-card-body {
::v-deep .ivu-card-body {
padding: 0;
height: auto;
}

View File

@@ -4,12 +4,12 @@
<div class="query-wrapper">
<div class="query-item">
<div>店铺名称</div>
<Input placeholder="请输入店铺名称" @on-clear="shopsData=[]; params.storeName=''; params.pageNumber =1; init()" @on-enter="()=>{shopsData=[]; params.pageNumber =1; init();}" icon="ios-search" clearable style="width: 150px"
<t-input placeholder="请输入店铺名称" @clear="shopsData=[]; params.storeName=''; params.pageNumber =1; init()" @enter="()=>{shopsData=[]; params.pageNumber =1; init();}" clearable style="width: 150px"
v-model="params.storeName" />
</div>
<div class="query-item">
<Button type="primary" @click="shopsData=[];params.pageNumber =1; init();" icon="ios-search">搜索</Button>
<t-button theme="primary" @click="shopsData=[];params.pageNumber =1; init();">搜索</t-button>
</div>
</div>
<div>
@@ -25,19 +25,16 @@
<div class="wap-sku" :class="{'theme_color':(item.storeDisable === 'OPEN' ? true : false) }">{{ item.storeDisable === 'OPEN' ? '开启中' : '未开启' }}</div>
</div>
</div>
<Spin size="large" fix v-if="loading"></Spin>
<t-loading v-if="loading" :loading="true" fullscreen></t-loading>
</div>
<Page
:total="total"
class="pageration"
@on-change="changePageSize"
:page-size="params.pageSize"
<t-pagination
:current="params.pageNumber"
:total="Number(total)"
:pageSize="params.pageSize"
size="small"
show-total
show-elevator
>
</Page>
:showJumper="true"
@change="onPaginationChange"
/>
</div>
</div>
</div>
@@ -65,8 +62,9 @@ export default {
this.init();
},
methods: {
changePageSize(v){
this.params.pageNumber = v;
onPaginationChange({ current, pageSize }){
this.params.pageNumber = current;
this.params.pageSize = pageSize;
this.init();
},
init() {

View File

@@ -45,7 +45,7 @@ export default {
order: "desc",
pageClientType: "H5",
pageNumber: 1,
pageSize: 10,
pageSize: 20,
pageType: "SPECIAL",
},
total: 0, // 表单数据总数
@@ -137,7 +137,7 @@ img {
overflow: auto;
width: 100%;
}
/deep/ .ivu-table-wrapper {
::v-deep .ivu-table-wrapper {
width: 100%;
}
.list {

View File

@@ -5,16 +5,7 @@
<h3>
内容设置
</h3>
<div class="config-item flex flex-a-c flex-j-sb">
<div>
<Tooltip theme="light" placement="bottom-end" max-width="100" content="关闭之后部分页面点击'查看''详情'等按钮将跳到新页面展示" >
<div>
多标签Tab页内嵌模式
</div>
</Tooltip>
</div>
<i-switch v-model="setting.isUseTabsRouter"></i-switch>
</div>
</Drawer>
</div>
</template>

View File

@@ -10,15 +10,19 @@
@on-clear="clearSelect"
/>
<Poptip transfer trigger="click" placement="right" title="选择部门" width="250">
<Button icon="md-list">选择部门</Button>
<Button>
<template #icon><t-icon name="browse" /></template>
选择部门
</Button>
<div slot="content">
<Input
v-model="searchKey"
suffix="ios-search"
@on-change="searchDep"
placeholder="输入部门名搜索"
clearable
/>
>
<template #suffixIcon><t-icon name="search" /></template>
</Input>
<div class="dep-tree-bar">
<Tree
:data="dataDep"

View File

@@ -1,25 +1,20 @@
<template>
<div>
<div style="display:flex;">
<Input
<t-input
v-model="currentValue"
@on-change="handleChange"
@change="handleChange"
v-show="showInput"
:placeholder="placeholder"
:size="size"
:disabled="disabled"
:readonly="readonly"
:maxlength="maxlength"
>
<Poptip slot="append" transfer trigger="hover" title="图片预览" placement="right">
<Icon type="md-eye" class="see-icon" />
<div slot="content">
<img :src="currentValue" alt="该资源不存在" style="max-width: 300px;margin: 0 auto;display: block;" />
<a @click="viewImage=true" style="margin-top:5px;text-align:right;display:block">查看大图</a>
</div>
</Poptip>
</Input>
<Button @click="handleCLickImg('storeLogo')">选择图片</Button>
<template #suffix>
<a style="margin-left:8px" @click="viewImage=true">预览</a>
</template>
</t-input>
<t-button @click="handleCLickImg('storeLogo')">选择图片</t-button>
<!--<Upload-->
<!--:action="uploadFileUrl"-->
<!--:headers="accessToken"-->
@@ -39,16 +34,19 @@
<!--</Upload>-->
</div>
<Modal title="图片预览" v-model="viewImage" :styles="{top: '30px'}" draggable>
<t-dialog header="图片预览" :visible.sync="viewImage" :width="500" @close="viewImage=false">
<img :src="currentValue" alt="该资源不存在" style="max-width: 300px;margin: 0 auto;display: block;" />
<div slot="footer">
<Button @click="viewImage=false">关闭</Button>
</div>
</Modal>
<template #footer>
<t-button variant="text" @click="viewImage=false">关闭</t-button>
</template>
</t-dialog>
<Modal width="1200px" v-model="picModalFlag">
<t-dialog :width="1200" header="选择图片" :visible.sync="picModalFlag" @close="picModalFlag=false">
<ossManage @callback="callbackSelected" ref="ossManage" :isComponent="true" :initialize="picModalFlag" />
</Modal>
<template #footer>
<t-button variant="text" @click="picModalFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -56,6 +54,7 @@
<script>
import { uploadFile } from "@/api/index";
import ossManage from "@/views/sys/oss-manage/ossManage";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "uploadPicInput",
components: {
@@ -161,7 +160,7 @@ export default {
// 上传失败
handleError(error, file, fileList) {
this.loading = false;
this.$Message.error(error.toString());
MessagePlugin.error(error.toString());
},
// 上传成功回显
handleChange(v) {

View File

@@ -13,48 +13,48 @@
<div v-if="item.status == 'finished'" style="height:60px;">
<img :src="item.url" />
<div class="upload-list-cover">
<Icon type="ios-eye-outline" @click="handleView(item.url)"></Icon>
<Icon type="ios-trash-outline" @click="handleRemove(item)"></Icon>
<t-icon name="browse" @click="handleView(item.url)"></t-icon>
<t-icon name="delete" @click="handleRemove(item)"></t-icon>
</div>
</div>
<div v-else>
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
<t-progress v-if="item.showProgress" :percentage="item.percentage"></t-progress>
</div>
</div>
</vuedraggable>
<Upload
<t-upload
ref="upload"
:multiple="multiple"
:show-upload-list="false"
:on-success="handleSuccess"
:on-error="handleError"
:format="['jpg','jpeg','png','gif']"
:max-size="1024"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
type="drag"
:showUploadFileList="false"
:autoUpload="true"
:action="uploadFileUrl"
:headers="accessToken"
accept=".jpg,.jpeg,.png,.gif"
:sizeLimit="{ size: 1024, unit: 'KB' }"
:beforeUpload="handleBeforeUpload"
theme="dragger"
@success="handleSuccess"
@fail="handleError"
style="display: inline-block;width:58px;"
>
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="md-camera" size="20"></Icon>
<div style="width: 58px;height:58px;line-height: 58px;display:flex;align-items:center;justify-content:center;">
<t-icon name="camera" size="20"></t-icon>
</div>
</Upload>
</t-upload>
</div>
<Modal title="图片预览" v-model="viewImage" :styles="{top: '30px'}" draggable>
<t-dialog header="图片预览" :visible.sync="viewImage" :width="600">
<img :src="imgUrl" alt="无效的图片链接" style="width: 100%;margin: 0 auto;display: block;" />
<div slot="footer">
<Button @click="viewImage=false">关闭</Button>
</div>
</Modal>
<template #footer>
<t-button variant="text" @click="viewImage=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>
<script>
import { uploadFile } from "@/api/index";
import vuedraggable from "vuedraggable";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "uploadPicThumb",
components: {
@@ -109,9 +109,9 @@ export default {
this.returnValue();
},
// 上传成功
handleSuccess(res, file) {
if (res.success) {
file.url = res.result;
handleSuccess({ response, file }) {
if (response && response.success) {
file.url = response.result;
// 单张图片处理
if (!this.multiple && this.uploadList.length > 0) {
// 删除第一张
@@ -121,35 +121,25 @@ export default {
// 返回组件值
this.returnValue();
} else {
this.$Message.error(res.message);
MessagePlugin.error((response && response.message) || '上传失败');
}
},
// 上传失败
handleError(error, file, fileList) {
this.$Message.error(error.toString());
handleError({ error }) {
MessagePlugin.error((error && error.toString()) || '上传失败');
},
// 格式校验
handleFormatError(file) {
this.$Notice.warning({
title: "不支持的文件格式",
desc:
"所选文件‘ " +
file.name +
" ’格式不正确, 请选择 .jpg .jpeg .png .gif图片格式文件"
});
MessagePlugin.warning("所选文件格式不正确, 请选择 .jpg/.jpeg/.png/.gif 文件");
},
// 上传文件大小校验
handleMaxSize(file) {
this.$Notice.warning({
title: "文件大小过大",
desc:
"所选文件大小过大不能超过1M."
});
MessagePlugin.warning("所选文件大小过大不能超过1M");
},
// 上传之前钩子
handleBeforeUpload() {
if (this.multiple && this.uploadList.length >= this.limit) {
this.$Message.warning("最多只能上传" + this.limit + "张图片");
MessagePlugin.warning("最多只能上传" + this.limit + "张图片");
return false;
}
return true;
@@ -185,7 +175,7 @@ export default {
if (typeof v == "string") {
// 单张
if (this.multiple) {
this.$Message.warning("多张上传仅支持数组数据类型");
MessagePlugin.warning("多张上传仅支持数组数据类型");
return;
}
if (!v) {
@@ -202,7 +192,7 @@ export default {
} else if (typeof v == "object") {
// 多张
if (!this.multiple) {
this.$Message.warning("单张上传仅支持字符串数据类型");
MessagePlugin.warning("单张上传仅支持字符串数据类型");
return;
}
this.uploadList = [];
@@ -218,7 +208,7 @@ export default {
if (init) {
this.$emit("input", v.slice(0, this.limit));
}
this.$Message.warning("最多只能上传" + this.limit + "张图片");
MessagePlugin.warning("最多只能上传" + this.limit + "张图片");
} else {
v.forEach(e => {
let item = {

View File

@@ -1,9 +1,9 @@
<template>
<Modal width="800" footer-hide v-model="enableMap">
<RadioGroup @on-change="changeMap" v-model="mapDefault" type="button">
<Radio label="select">级联选择</Radio>
<Radio label="map" v-if="aMapSwitch">高德地图</Radio>
</RadioGroup>
<t-dialog :width="800" :visible.sync="enableMap" header="选择地址" @close="enableMap=false">
<t-radio-group @change="changeMap" v-model="mapDefault">
<t-radio value="select">级联选择</t-radio>
<t-radio value="map" v-if="aMapSwitch">高德地图</t-radio>
</t-radio-group>
<div>
<div v-if="mapDefault === 'select'">
<div class="selector">
@@ -18,21 +18,24 @@
</div>
<div class="footer">
<Button type="primary" @click="finished">确定</Button>
<t-button theme="primary" @click="finished">确定</t-button>
</div>
</div>
<mapping v-if="mapDefault === 'map'" ref="map" @getAddress="getAddress" />
</div>
</Modal>
<template #footer>
<t-button variant="text" @click="enableMap=false">关闭</t-button>
</template>
</t-dialog>
</template>
<script>
import { aMapSwitch } from '@/config/index'
import mapping from "@/components/map/index.vue";
import * as API_Setup from "@/api/common.js";
import { MessagePlugin } from "tdesign-vue";
export default {
components: { mapping },
data() {
@@ -104,7 +107,7 @@ export default {
// 选择完成
finished() {
if(!this.chiosend[0]){
this.$Message.error("请选择地址")
MessagePlugin.error("请选择地址")
return
}
const params = this.chiosend.filter((item) => item!=="" && item.value !== "");

View File

@@ -1,13 +1,12 @@
import Checkbox from '../Checkbox/Checkbox'; // eslint-disable-line
// import Radio from '../Radio/Radio'; // eslint-disable-line
import { mixins } from './utils';
import { Radio } from 'view-design'; // eslint-disable-line
/* eslint-disable no-underscore-dangle */
export default {
name: 'TreeTable__body',
mixins: [mixins],
components: { Radio },
components: {},
data() {
return {
radioSelectedIndex: -1,

View File

@@ -1,7 +1,7 @@
import axios from "axios";
import { getStore, setStore } from "./storage.js";
import { router } from "../router/index";
import { Message } from "view-design";
import { MessagePlugin } from "tdesign-vue";
import Cookies from "js-cookie";
import { handleRefreshToken } from "../api/index";
import {v4 as uuidv4} from 'uuid';
@@ -42,7 +42,7 @@ service.interceptors.request.use(
return config;
},
err => {
Message.error("请求超时");
MessagePlugin.error("请求超时");
return Promise.reject(err);
}
);
@@ -53,14 +53,14 @@ service.interceptors.response.use(
const data = response.data;
// 根据返回的code值来做不同的处理(和后端约定)
if (!data.success && data.message) {
Message.error(data.message);
MessagePlugin.error(data.message);
}
switch (data.code) {
case 400:
if (data.message !== null) {
Message.error(data.message);
MessagePlugin.error(data.message);
} else {
Message.error("系统异常");
MessagePlugin.error("系统异常");
}
break;
case 20004:
@@ -70,9 +70,9 @@ service.interceptors.response.use(
setStore("accessToken", "");
if (router.history.current.name != "login") {
if (data.message !== null) {
Message.error(data.message);
MessagePlugin.error(data.message);
} else {
Message.error("未知错误,请重新登录");
MessagePlugin.error("未知错误,请重新登录");
}
router.push("/login");
}
@@ -81,9 +81,9 @@ service.interceptors.response.use(
case 500:
// 系统异常
if (data.message !== null) {
Message.error(data.message);
MessagePlugin.error(data.message);
} else {
Message.error("系统异常");
MessagePlugin.error("系统异常");
}
break;
default:
@@ -119,7 +119,7 @@ service.interceptors.response.use(
}
} else {
// 其他错误处理
Message.error(error.response.data.message);
MessagePlugin.error(error.response.data.message);
}
}
/* router.push("/login") */

View File

@@ -237,6 +237,17 @@ util.initRouterNode = function(routers, data) {
for (let item of data) {
let menu = Object.assign({}, item);
// 过滤空路径,避免生成 "path:''" 的重复路由
if (!menu.path || String(menu.path).trim() === '') {
continue;
}
// 去重:同名路由不重复添加
const exists = routers.some(r => r && r.name === menu.name);
if (exists) {
continue;
}
menu.component = lazyLoading(menu.frontRoute);
if (item.children && item.children.length > 0) {

View File

@@ -2,8 +2,6 @@ import Vue from 'vue';
import VueI18n from 'vue-i18n';
import zhLocale from './lang/zh-CN';
import enLocale from './lang/en-US';
import zhCnLocale from 'view-design/src/locale/lang/zh-CN';
import enUsLocale from 'view-design/src/locale/lang/en-US';
Vue.use(VueI18n);
@@ -17,8 +15,8 @@ Vue.config.lang = lang;
// 多语言配置 vue-i18n 6.x+
Vue.locale = () => { };
const messages = {
'zh-CN': Object.assign(zhCnLocale, zhLocale),
'en-US': Object.assign(enUsLocale, enLocale)
'zh-CN': zhLocale,
'en-US': enLocale
};
const i18n = new VueI18n({
locale: lang,

View File

@@ -1,9 +1,14 @@
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import ViewUI from 'view-design'
// import 'view-design/dist/styles/iview.css'
import './styles/theme.less';
import TDesign from 'tdesign-vue'
import 'tdesign-vue/es/style/index.css'
import TdPage from '@/components/TdPage.vue'
import VueCompositionApi from '@vue/composition-api'
import { Icon as TIcon } from 'tdesign-icons-vue'
import 'tdesign-icons-vue/lib/style/index.css'
import { MessagePlugin, DialogPlugin, NotificationPlugin, NotifyPlugin } from 'tdesign-vue'
import "core-js/stable"
// import "regenerator-runtime/runtime"
@@ -61,11 +66,467 @@ Vue.prototype.wapLinkTo = function (goodsId, skuId) {
import priceColorScheme from 'price-color'
Vue.use(priceColorScheme);
const copyViewUi = {...ViewUI}
copyViewUi.Input.props.maxlength.default = inputMaxLength // 挂载最大输入值
Vue.use(copyViewUi, {
i18n: (key, value) => i18n.t(key, value),
});
Vue.use(VueCompositionApi)
Vue.use(TDesign)
Vue.component('t-icon', TIcon)
Vue.component('Page', TdPage)
Vue.prototype.$Message = MessagePlugin
let __lastDialog = null
Vue.prototype.$Modal = {
confirm: function (opts) {
const d = DialogPlugin.confirm({
header: opts && (opts.title || opts.header),
content: opts && (opts.content || opts.desc),
theme: opts && opts.theme ? opts.theme : 'default',
onConfirm: opts && opts.onOk,
onCancel: opts && opts.onCancel,
onClose: opts && opts.onClose
})
__lastDialog = d
return d
},
info: function (opts) {
const d = DialogPlugin.alert({
header: opts && (opts.title || '提示'),
content: opts && (opts.content || opts.desc),
theme: 'info',
onClose: opts && (opts.onOk || opts.onClose)
})
__lastDialog = d
return d
},
success: function (opts) {
const d = DialogPlugin.alert({
header: opts && (opts.title || '成功'),
content: opts && (opts.content || opts.desc),
theme: 'success',
onClose: opts && (opts.onOk || opts.onClose)
})
__lastDialog = d
return d
},
warning: function (opts) {
const d = DialogPlugin.alert({
header: opts && (opts.title || '警告'),
content: opts && (opts.content || opts.desc),
theme: 'warning',
onClose: opts && (opts.onOk || opts.onClose)
})
__lastDialog = d
return d
},
error: function (opts) {
const d = DialogPlugin.alert({
header: opts && (opts.title || '错误'),
content: opts && (opts.content || opts.desc),
theme: 'danger',
onClose: opts && (opts.onOk || opts.onClose)
})
__lastDialog = d
return d
},
remove: function () {
if (__lastDialog && typeof __lastDialog.hide === 'function') {
__lastDialog.hide()
} else if (__lastDialog && typeof __lastDialog.destroy === 'function') {
__lastDialog.destroy()
}
__lastDialog = null
}
}
Vue.prototype.$Notice = {
info: function (opts) {
return NotificationPlugin.info({
title: opts && opts.title,
content: opts && (opts.desc || opts.content)
})
},
success: function (opts) {
return NotificationPlugin.success({
title: opts && opts.title,
content: opts && (opts.desc || opts.content)
})
},
warning: function (opts) {
return NotificationPlugin.warning({
title: opts && opts.title,
content: opts && (opts.desc || opts.content)
})
},
error: function (opts) {
return NotificationPlugin.error({
title: opts && opts.title,
content: opts && (opts.desc || opts.content)
})
},
closeAll: function () {
return NotificationPlugin.closeAll()
}
}
Vue.component('Input', {
inheritAttrs: false,
props: ['value'],
model: { prop: 'value', event: 'input' },
render(h){
const attrs = this.$attrs || {}
const props = Object.assign({}, attrs, { value: this.value })
const on = Object.assign({}, this.$listeners, {
change: v => this.$emit('input', v),
enter: e => this.$emit('on-enter', e),
clear: e => this.$emit('on-clear', e),
input: v => this.$emit('input', v)
})
if(attrs.type === 'textarea'){
const taProps = Object.assign({}, props)
delete taProps.type
return h('t-textarea', { props: taProps, on })
}
return h('t-input', { props, on })
}
})
Vue.component('Card', {
inheritAttrs: false,
render(h){
return h('t-card', { props: this.$attrs }, this.$slots.default)
}
})
Vue.component('Button', {
inheritAttrs: false,
render(h){
const attrs = this.$attrs || {}
const type = attrs.type
let theme = attrs.theme
let variant = attrs.variant
if(!theme){
switch(type){
case 'primary': theme = 'primary'; break
case 'default': theme = 'default'; break
case 'success': theme = 'success'; break
case 'warning': theme = 'warning'; break
case 'error': theme = 'danger'; break
case 'info': theme = 'primary'; break
case 'text': theme = theme || 'default'; variant = 'text'; break
default: theme = theme || 'default'
}
}
if(attrs.ghost){ variant = 'outline' }
const props = Object.assign({}, attrs, { theme })
if(variant){ props.variant = variant }
delete props.type
delete props.ghost
return h('t-button', { props, on: this.$listeners }, this.$slots.default)
}
})
Vue.component('Spin', {
props: ['size','fix'],
render(h){
const size = this.size === 'large' ? 'large' : 'small'
return h('t-loading', { props: { loading: true, size, fullscreen: !!this.fix } })
}
})
Vue.component('Tag', {
props: ['color'],
render(h){
let theme = 'default'
if(this.color === 'geekblue') theme = 'primary'
return h('t-tag', { props: { theme } }, this.$slots.default)
}
})
Vue.component('Cascader', {
inheritAttrs: false,
props: ['value','data','placeholder'],
model: { prop: 'value', event: 'input' },
render(h){
const props = { value: this.value, options: this.data, placeholder: this.placeholder }
const on = Object.assign({}, this.$listeners, { change: val => this.$emit('input', val) })
return h('t-cascader', { props, on })
}
})
Vue.component('Tabs', {
inheritAttrs: false,
props: ['value'],
model: { prop: 'value', event: 'change' },
render(h){
const props = Object.assign({}, this.$attrs, { value: this.value })
const on = Object.assign({}, this.$listeners, { change: v => this.$emit('change', v) })
return h('t-tabs', { props, on }, this.$slots.default)
}
})
Vue.component('TabPane', {
props: ['label','name'],
render(h){
const value = this.name
const props = { label: this.label, value }
return h('t-tab-panel', { props }, this.$slots.default)
}
})
Vue.component('Row', {
inheritAttrs: false,
render(h){
return h('t-row', { attrs: this.$attrs }, this.$slots.default)
}
})
Vue.component('Col', {
inheritAttrs: false,
render(h){
const props = Object.assign({}, this.$attrs)
if(typeof props.span !== 'undefined') props.span = Number(props.span)
return h('t-col', { props }, this.$slots.default)
}
})
Vue.component('Modal', {
inheritAttrs: false,
props: ['value','title','footerHide','closable','maskClosable'],
model: { prop: 'value', event: 'input' },
render(h){
const props = {
visible: !!this.value,
header: this.title,
closeOnOverlayClick: this.maskClosable !== false,
closeBtn: this.closable !== false,
}
const on = {
confirm: e => this.$emit('on-ok', e),
cancel: e => this.$emit('on-cancel', e),
close: e => this.$emit('on-close', e),
'update:visible': v => this.$emit('input', v)
}
const slots = Object.assign({}, this.$slots)
if(this.footerHide){
props.footer = null
}
return h('t-dialog', { props, on }, slots.default)
}
})
Vue.component('Drawer', {
inheritAttrs: false,
props: ['value','title','size','closeOnOverlayClick'],
model: { prop: 'value', event: 'input' },
render(h){
const props = {
visible: !!this.value,
header: this.title,
size: String(this.size || 400),
closeOnOverlayClick: this.closeOnOverlayClick !== false
}
const on = {
'update:visible': v => this.$emit('input', v)
}
return h('t-drawer', { props, on }, this.$slots.default)
}
})
Vue.component('Dropdown', {
inheritAttrs: false,
props: ['trigger','placement','disabled','hideOnClick'],
render(h){
const props = Object.assign({}, this.$attrs, {
trigger: this.trigger || this.$attrs.trigger || 'hover',
placement: this.placement || this.$attrs.placement || 'bottom',
disabled: this.disabled || this.$attrs.disabled,
hideOnClick: this.hideOnClick !== undefined ? this.hideOnClick : this.$attrs.hideOnClick
})
return h('t-dropdown', { props, on: this.$listeners }, this.$slots.default)
}
})
Vue.component('DropdownMenu', {
render(h){
return h('t-dropdown-menu', {}, this.$slots.default)
}
})
Vue.component('DropdownItem', {
inheritAttrs: false,
props: ['name','command','disabled','divider'],
render(h){
const value = this.name || this.command
const props = { value, disabled: !!this.disabled, divider: !!this.divider }
const on = Object.assign({}, this.$listeners)
return h('t-dropdown-item', { props, on }, this.$slots.default)
}
})
Vue.component('Alert', {
props: ['type','title'],
render(h){
const theme = this.type || 'info'
return h('t-alert', { props: { theme, message: this.title } })
}
})
Vue.component('Form', {
inheritAttrs: false,
props: ['model','rules','inline','labelWidth'],
methods: {
validate(cb){
const inst = this.$refs && this.$refs.tForm
if(!inst){ if(cb) cb(false); return false }
const r = inst.validate && inst.validate()
if(cb){
Promise.resolve(r).then(res => {
const ok = res === true || res === null || (res && typeof res === 'object' && Object.keys(res).length === 0)
cb(ok)
}).catch(() => cb(false))
}
return r
},
resetFields(){
const inst = this.$refs && this.$refs.tForm
if(inst && inst.reset) inst.reset()
},
reset(){
const inst = this.$refs && this.$refs.tForm
if(inst && inst.reset) inst.reset()
}
},
render(h){
const attrs = this.$attrs || {}
const props = {
data: this.model || attrs.model || {},
rules: this.rules || attrs.rules,
layout: (this.inline || attrs.inline) ? 'inline' : (attrs.layout || 'vertical'),
labelWidth: this.labelWidth || attrs.labelWidth || attrs['label-width']
}
return h('t-form', { props, on: this.$listeners, ref: 'tForm' }, this.$slots.default)
}
})
Vue.component('FormItem', {
inheritAttrs: false,
props: ['prop','label'],
render(h){
const attrs = this.$attrs || {}
const props = {
name: this.prop || attrs.prop || '',
label: this.label || attrs.label || ''
}
return h('t-form-item', { props }, this.$slots.default)
}
})
Vue.component('Table', {
props: ['columns','data','loading','height','border','rowKey','tooltip'],
render(h){
const cols = (this.columns || []).map(c => {
const nc = Object.assign({}, c)
if(c.render && !c.cell){
nc.cell = (h2, { row, col, rowIndex }) => c.render(h2, { row, column: col, index: rowIndex })
delete nc.render
}
if(c.key && !c.colKey){
nc.colKey = c.key
delete nc.key
}
return nc
})
const props = { columns: cols, data: this.data, loading: this.loading, height: this.height, rowKey: this.rowKey || 'id' }
return h('t-table', { props })
}
})
Vue.component('Select', {
inheritAttrs: false,
props: ['value'],
model: { prop: 'value', event: 'change' },
render(h){
const props = Object.assign({}, this.$attrs, { value: this.value })
const on = Object.assign({}, this.$listeners, { change: v => { this.$emit('on-change', v); this.$emit('change', v) } })
return h('t-select', { props, on }, this.$slots.default)
}
})
Vue.component('Option', {
props: ['value','label'],
render(h){
return h('t-option', { props: { value: this.value, label: this.label } }, this.$slots.default)
}
})
Vue.component('InputNumber', {
inheritAttrs: false,
props: ['value','min','max','step','size','disabled'],
model: { prop: 'value', event: 'change' },
render(h){
const props = Object.assign({}, this.$attrs, { value: this.value })
const on = Object.assign({}, this.$listeners, { change: v => { this.$emit('change', v); this.$emit('input', v) } })
return h('t-input-number', { props, on })
}
})
Vue.component('RadioGroup', {
inheritAttrs: false,
props: ['value'],
model: { prop: 'value', event: 'change' },
render(h){
const attrs = this.$attrs || {}
const props = Object.assign({}, attrs, { value: this.value })
delete props.type
delete props['button-style']
const on = Object.assign({}, this.$listeners, { change: v => this.$emit('change', v) })
return h('t-radio-group', { props, on }, this.$slots.default)
}
})
Vue.component('Radio', {
inheritAttrs: false,
props: ['label','disabled'],
render(h){
const value = this.label
const props = Object.assign({}, this.$attrs, { value, disabled: !!this.disabled })
return h('t-radio', { props }, this.$slots.default)
}
})
Vue.component('CheckboxGroup', {
inheritAttrs: false,
props: ['value'],
model: { prop: 'value', event: 'change' },
render(h){
const props = Object.assign({}, this.$attrs, { value: this.value })
const on = Object.assign({}, this.$listeners, { change: v => { this.$emit('change', v); this.$emit('on-change', v) } })
return h('t-checkbox-group', { props, on }, this.$slots.default)
}
})
Vue.component('Checkbox', {
inheritAttrs: false,
props: ['label','disabled'],
render(h){
const props = Object.assign({}, this.$attrs, { value: this.label, disabled: !!this.disabled })
return h('t-checkbox', { props }, this.$slots.default)
}
})
Vue.component('i-switch', {
props: ['value'],
model: { prop: 'value', event: 'change' },
render(h){
return h('t-switch', { props: { value: this.value }, on: { change: v => { this.$emit('on-change', v); this.$emit('change', v) } } })
}
})
Vue.component('Tooltip', {
props: ['content','placement'],
render(h){
return h('t-tooltip', { props: { content: this.content, placement: this.placement || 'top' } }, this.$slots.default)
}
})
Vue.component('Poptip', {
inheritAttrs: false,
props: ['title','placement'],
render(h){
const props = { content: this.title || this.$attrs.content, placement: this.placement || 'top' }
const on = Object.assign({}, this.$listeners, { confirm: e => this.$emit('on-ok', e), cancel: e => this.$emit('on-cancel', e) })
return h('t-popconfirm', { props, on }, this.$slots.default)
}
})
Vue.component('Icon', {
props: ['type','size','color'],
render(h){
const map = {
'md-home': 'home',
'md-cart': 'cart',
'md-heart': 'heart',
'md-document': 'file',
'md-person': 'user',
'ios-link': 'link',
'ios-videocam': 'video',
'md-share-alt': 'share'
}
const name = map[this.type] || this.type || 'link'
const props = { name: name, size: this.size }
const data = {}
if(this.color){ data.style = { color: this.color } }
return h('t-icon', { props, ...data })
}
})
Vue.component('liliDialog', liliDialog)
@@ -84,6 +545,7 @@ Vue.prototype.removeStore = removeStore;
Vue.prototype.$mainColor = mainColor;
Vue.prototype.md5 = md5;
Array.prototype.remove = function (from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;

View File

@@ -1,5 +1,4 @@
import Vue from 'vue';
import ViewUI from 'view-design';
import Util from '../libs/util';
import VueRouter from 'vue-router';
import Cookies from 'js-cookie';
@@ -24,7 +23,6 @@ VueRouter.prototype.push = function push(location) {
export const router = new VueRouter(RouterConfig);
router.beforeEach((to, from, next) => {
ViewUI.LoadingBar.start();
Util.title(to.meta.title);
next();
@@ -49,7 +47,6 @@ router.beforeEach((to, from, next) => {
router.afterEach((to) => {
Util.openNewPage(router.app, to.name, to.params, to.query);
ViewUI.LoadingBar.finish();
window.scrollTo(0, 0);
});

View File

@@ -34,11 +34,21 @@ const app = {
// 动态添加主界面路由,需要缓存
updateAppRouter(state, routes) {
state.routers.push(...routes);
const useAddRoute = typeof router.addRoute === 'function';
if (useAddRoute) {
(routes || []).forEach(r => router.addRoute(r));
} else {
router.addRoutes(routes);
}
},
// 动态添加全局路由404、500等页面不需要缓存
updateDefaultRouter(state, routes) {
const useAddRoute = typeof router.addRoute === 'function';
if (useAddRoute) {
(routes || []).forEach(r => router.addRoute(r));
} else {
router.addRoutes(routes);
}
},
setAdded(state, v) {
state.added = v;

View File

@@ -19,10 +19,9 @@
width: 100% !important;
display: flex;
align-items: center;
background-color: #f0f0f0;
// background-color: #f0f0f0;
border-radius: 0.4em;
padding: 10px;
margin: 0;
flex-wrap: wrap;
> .ivu-form-item {
margin: 8px 10px !important;
@@ -42,3 +41,8 @@
-webkit-line-clamp: 4;
overflow: hidden;
}
// 为Card组件之间增加间距
.ivu-card + .ivu-card {
margin-top: 10px;
}

View File

@@ -1,6 +1,3 @@
@import "~view-design/src/styles/index.less";
// iview 自定义样式
@primary-color: #ff5c58;
@info-color: #fa6419;
@success-color: #68cabe;
@@ -11,9 +8,3 @@
@table-td-highlight-bg: #ededed;
@font-size-base: 12px;
.ivu-drawer,
.drawer,
.ivu-drawer-wrap {
z-index: 2600 !important;
}

View File

@@ -61,7 +61,7 @@ export function clientTypeWay(val) {
} else if (val == "PC") {
return "PC端";
} else if (val == "WECHAT_MP") {
return "小程序";
return "小程序";
} else if (val == "APP") {
return "移动应用端";
} else {

View File

@@ -12,7 +12,7 @@
<shrinkable-menu></shrinkable-menu>
</div>
<!-- 顶部标题栏主体 -->
<div class="main-header-con" :style="{ height: setting.isUseTabsRouter ? '100px' : '60px' }">
<div class="main-header-con" style="height: 60px">
<div class="main-header">
<div class="header-avator-con">
<!-- 左侧栏 -->
@@ -37,42 +37,34 @@
</Tooltip>
</li>
</ul>
<Dropdown
transfer
trigger="hover"
@on-click="handleClickUserDropdown"
>
<t-dropdown>
<div class="dropList">
<span class="main-user-name">{{ userInfo.nickName }}</span>
<Avatar
icon="ios-person"
:src="avatarPath"
<t-avatar
:image="avatarPath"
style="background: #fff; margin-left: 10px"
></Avatar>
></t-avatar>
</div>
<DropdownMenu slot="list">
<DropdownItem name="personalCenter">{{
<t-dropdown-menu>
<t-dropdown-item @click="handleClickUserDropdown('personalCenter')">{{
$t("userCenter")
}}</DropdownItem>
<DropdownItem name="changePass">{{
}}</t-dropdown-item>
<t-dropdown-item @click="handleClickUserDropdown('changePass')">{{
$t("changePass")
}}</DropdownItem>
<DropdownItem name="loginOut" divided>{{
}}</t-dropdown-item>
<t-dropdown-item @click="handleClickUserDropdown('loginOut')">{{
$t("logout")
}}</DropdownItem>
</DropdownMenu>
</Dropdown>
}}</t-dropdown-item>
</t-dropdown-menu>
</t-dropdown>
</Row>
</div>
</div>
</div>
</div>
<!-- 已打开的页面标签 -->
<div class="tags-con" v-if="setting.isUseTabsRouter">
<tags-page-opened :pageTagsList="pageTagsList"></tags-page-opened>
</div>
</div>
<div class="single-page-con" :style="{ 'top': setting.isUseTabsRouter ? '100px' : '60px', height: setting.isUseTabsRouter ? 'calc(100% - 110px)' : 'calc(100% - 70px)' }">
<div class="single-page-con" :style="{ 'top': '60px', height: 'calc(100% - 70px)' }">
<div class="single-page">
<!-- <keep-alive :include="cachePage"> -->
<router-view></router-view>
@@ -88,7 +80,6 @@
<script>
import shrinkableMenu from "./main-parts/shrinkable-menu/shrinkable-menu.vue";
import tagsPageOpened from "./main-parts/tags-page-opened.vue";
import messageTip from "./main-parts/message-tip.vue";
import circleLoading from "@/components/lili/circle-loading.vue";
import configDrawer from "@/components/lili/config-drawer.vue";
@@ -102,7 +93,7 @@ const config = require("@/config/index.js");
export default {
components: {
shrinkableMenu,
tagsPageOpened,
messageTip,
circleLoading,
configDrawer
@@ -125,9 +116,6 @@ export default {
loading() {
return this.$store.state.app.loading;
},
pageTagsList() {
return this.$store.state.app.pageOpenedList; // 打开的页面的页面对象
},
avatarPath() {
return localStorage.avatorImgPath;
},
@@ -145,7 +133,7 @@ export default {
let userInfo = JSON.parse(Cookies.get("userInfoManager"));
this.userInfo = userInfo;
this.checkTag(this.$route.name);
let currWidth = document.body.clientWidth;
if (currWidth <= 1200) {
this.sliceNum = 2;
@@ -196,23 +184,7 @@ export default {
});
}
},
//切换标签
checkTag(name) {
let openpageHasTag = this.pageTagsList.some((item) => {
if (item.name == name) {
return true;
}
});
if (!openpageHasTag) {
// 解决关闭当前标签后再点击回退按钮会退到当前页时没有标签的问题
util.openNewPage(
this,
name,
this.$route.params || {},
this.$route.query || {}
);
}
},
//宽度动态计算
resize() {
let currWidth = document.body.clientWidth;
@@ -225,10 +197,6 @@ export default {
},
},
watch: {
$route(to, from) {
this.checkTag(to.name);
localStorage.currentPageName = to.name;
},
},
mounted() {
this.init();
@@ -239,8 +207,6 @@ export default {
});
},
created() {
// 显示打开的页面的列表
this.$store.commit("setOpenedList");
},
};
</script>

View File

@@ -1,51 +1,25 @@
<template>
<div class="search">
<Card>
<Row class="operation">
<Button @click="add" type="primary">添加</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
sortable="custom"
@on-selection-change="changeSelect"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
<FormItem label="自定义分词" prop="name">
<Input v-model="form.name" clearable style="width: 100%" />
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交</Button
>
<t-card>
<div class="operation">
<t-button @click="add" theme="primary">添加</t-button>
</div>
</Modal>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onSelectChange"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
<t-dialog :visible="modalVisible" :header="modalTitle" :mask-closable="false" :width="500" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100" :rules="formValidate">
<t-form-item label="自定义分词" name="name">
<t-input v-model="form.name" clearable style="width: 100%" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -58,6 +32,7 @@ import {
} from "@/api/index";
import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "custom-words",
data() {
@@ -69,7 +44,7 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
words: "",
@@ -86,82 +61,16 @@ export default {
],
},
submitLoading: false, // 添加或编辑提交状态
selectList: [], // 多选数据
selectCount: 0, // 多选计数
selectList: [],
selectCount: 0,
selectedRowKeys: [],
columns: [
// 表头
{
type: "selection",
width: 60,
align: "center",
},
{
title: "自定义分词",
key: "name",
minWidth: 120
},
{
title: "创建时间",
key: "createTime",
width: 200
},
{
title: "更新时间",
key: "updateTime",
width: 200
},
{
title: "操作人",
key: "createBy",
minWidth: 150
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 200,
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"修改"
),
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.remove(params.row);
},
},
},
"删除"
),
]);
},
},
{ colKey: "row-select", type: "multiple", width: 60, align: "center" },
{ title: "自定义分词", colKey: "name", minWidth: 120 },
{ title: "创建时间", colKey: "createTime", width: 200 },
{ title: "更新时间", colKey: "updateTime", width: 200 },
{ title: "操作人", colKey: "createBy", minWidth: 150 },
{ title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -171,25 +80,25 @@ export default {
init() {
this.getDataList();
},
changePage(v) {
this.searchForm.pageNumber = v;
onPaginationChange({ current, pageSize }) {
this.searchForm.pageNumber = current;
this.searchForm.pageSize = pageSize;
this.getDataList();
this.clearSelectAll();
},
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.getDataList();
},
clearSelectAll() {
this.$refs.table.selectAll(false);
this.selectedRowKeys = [];
this.selectList = [];
this.selectCount = 0;
},
// 选中状态变更
changeSelect(e) {
onSelectChange(selectedRowKeys, { selectedRowData }) {
this.selectedRowKeys = selectedRowKeys;
const e = selectedRowData || [];
this.selectList = e;
this.selectCount = e.length;
},
@@ -218,7 +127,7 @@ export default {
insertCustomWords(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -229,7 +138,7 @@ export default {
updateCustomWords(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -242,8 +151,8 @@ export default {
add() {
this.modalType = 0;
this.modalTitle = "添加";
this.form = {}
this.$refs.form.resetFields();
this.form = { name: "" };
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
this.modalVisible = true;
},
@@ -257,17 +166,14 @@ export default {
},
// 删除
remove(v) {
this.$Modal.confirm({
title: "确认删除",
// 记得确认修改此处
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除 " + v.name + " ?",
loading: true,
onOk: () => {
// 删除
theme: "warning",
onConfirm: () => {
delCustom(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});
@@ -277,24 +183,20 @@ export default {
// 批量删除
delAll() {
if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据");
MessagePlugin.warning("您还未选择要删除的数据");
return;
}
this.$Modal.confirm({
title: "确认删除",
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
loading: true,
onOk: () => {
theme: "warning",
onConfirm: () => {
let ids = "";
this.selectList.forEach(function (e) {
ids += e.id + ",";
});
this.selectList.forEach(function (e) { ids += e.id + ","; });
ids = ids.substring(0, ids.length - 1);
// 批量删除
delSensitive(ids).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.clearSelectAll();
this.getDataList();
}

View File

@@ -1,435 +1,164 @@
<template>
<div>
<Card>
<Row @keydown.enter.native.prevent="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="状态">
<Select
v-model="searchForm.distributionStatus"
style="width: 200px"
>
<Option
v-for="item in distributionStatusList"
:value="item.value"
:key="item.value"
>{{ item.label }}
</Option
>
</Select>
</Form-item>
<Button
@click="handleSearch"
type="primary"
icon="ios-search"
class="search-btn"
>搜索
</Button
>
</Form>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<Modal title="修改分销员" v-model="modalVisible" :mask-closable="false" :width="600">
<Form ref="distributionForm" :model="distributionForm" :label-width="150" :rules="distributionFormValidate">
<FormItem label="姓名" prop="name">
<Input v-model="distributionForm.name" clearable style="width: 100%"/>
</FormItem>
<FormItem label="身份证号" prop="idNumber">
<Input v-model="distributionForm.idNumber" clearable style="width: 100%"/>
</FormItem>
<FormItem label="结算银行开户行名称" prop="settlementBankAccountName">
<Input v-model="distributionForm.settlementBankAccountName" clearable style="width: 100%"/>
</FormItem>
<FormItem label="结算银行开户账号" prop="settlementBankAccountNum">
<Input v-model="distributionForm.settlementBankAccountNum" clearable style="width: 100%"/>
</FormItem>
<FormItem label="结算银行开户支行名称" prop="settlementBankBranchName">
<Input v-model="distributionForm.settlementBankBranchName" clearable style="width: 100%"/>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit">提交</Button>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-tabs :value="activeStatus" @change="onStatusTabChange" class="status-tabs">
<t-tab-panel label="全部" value="ALL" />
<t-tab-panel v-for="item in distributionStatusList" :key="item.value" :label="item.label" :value="item.value" />
</t-tabs>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</Modal>
</t-card>
<t-drawer :visible.sync="modalVisible" :header="'修改分销员'" placement="right" size="500px" @close="modalVisible = false">
<t-form ref="distributionForm" :data="distributionForm" :labelWidth="150">
<t-form-item label="姓名" name="name">
<t-input v-model="distributionForm.name" />
</t-form-item>
<t-form-item label="身份证号" name="idNumber">
<t-input v-model="distributionForm.idNumber" />
</t-form-item>
<t-form-item label="结算银行开户行名称" name="settlementBankAccountName">
<t-input v-model="distributionForm.settlementBankAccountName" />
</t-form-item>
<t-form-item label="结算银行开户账号" name="settlementBankAccountNum">
<t-input v-model="distributionForm.settlementBankAccountNum" />
</t-form-item>
<t-form-item label="结算银行开户支行名称" name="settlementBankBranchName">
<t-input v-model="distributionForm.settlementBankBranchName" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-drawer>
</div>
</template>
<script>
import {editDistribution, getDistributionListData, resumeDistribution, retreatDistribution} from "@/api/distribution";
import {distributionStatusList} from "./dataJson.js";
import {regular} from "@/utils";
import { editDistribution, getDistributionListData, resumeDistribution, retreatDistribution } from "@/api/distribution";
import { distributionStatusList } from "./dataJson.js";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "distribution",
components: {},
data() {
return {
distributionStatusList, // 分销状态
loading: true, // 表单加载状态
modalVisible: false, // 添加或编辑显示
distributionStatusList,
loading: true,
modalVisible: false,
activeStatus: 'ALL',
distributionForm: {
name: "",
idNumber: "",
settlementBankAccountName: "",
settlementBankAccountNum: "",
settlementBankBranchName: ""
settlementBankBranchName: "",
},
// 表单验证规则
distributionFormValidate: {
name: [
regular.REQUIRED,
regular.VARCHAR20
],
idNumber: [
regular.REQUIRED,
regular.VARCHAR20
],
settlementBankAccountName: [
regular.REQUIRED,
regular.VARCHAR20
],
settlementBankAccountNum: [
regular.REQUIRED,
regular.VARCHAR20
],
settlementBankBranchName: [
regular.REQUIRED,
regular.VARCHAR20
],
},
submitLoading: false, // 编辑提交状态
submitLoading: false,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageNumber: 1,
pageSize: 20,
memberName: "",
distributionStatus: "",
},
columns: [
{
title: "会员名称",
key: "memberName",
minWidth: 120,
tooltip: true,
},
{
title: "姓名",
key: "name",
minWidth: 100,
},
{
title: "身份证号",
key: "idNumber",
minWidth: 120,
},
{
title: "结算银行开户行名称",
key: "settlementBankAccountName",
minWidth: 120,
},
{
title: "结算银行开户账号",
key: "settlementBankAccountNum",
minWidth: 120,
},
{
title: "结算银行开户支行名称",
key: "settlementBankBranchName",
minWidth: 120,
},
{
title: "推广单数",
key: "distributionOrderCount",
minWidth: 120,
width: 150,
},
{
title: "分销订单金额",
key: "distributionOrderPrice",
width: 150,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props: {value: params.row.distributionOrderPrice, color: this.$mainColor}});
},
},
{
title: "分销金额",
key: "rebateTotal",
width: 150,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props: {value: params.row.rebateTotal, color: this.$mainColor}});
},
},
{
title: "待提现金额",
key: "canRebate",
width: 150,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props: {value: params.row.canRebate, color: 'green'}});
},
},
{
title: "冻结金额",
key: "commissionFrozen",
width: 150,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props: {value: params.row.commissionFrozen, color: '#347dda'}});
},
},
{
title: "状态",
key: "distributionStatus",
width: 150,
sortable: false,
render: (h, params) => {
if (params.row.distributionStatus == "PASS") {
return h("Tag", {props: {color: "green",},}, "通过");
} else if (params.row.distributionStatus == "APPLY") {
return h("Tag", {props: {color: "geekblue",},}, "待审核");
} else if (params.row.distributionStatus == "RETREAT") {
return h("Tag", {props: {color: "volcano",},}, "清退");
} else if (params.row.distributionStatus == "REFUSE") {
return h("Tag", {props: {color: "red",},}, "拒绝");
}
},
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 140,
render: (h, params) => {
return h(
"div",
{
style: {
display: "flex",
justifyContent: "center",
},
},
[
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
display:
params.row.distributionStatus != "RETREAT"
? "block"
: "none",
},
on: {
click: () => {
this.retreat(params.row);
},
},
},
"清退"
),
h(
"Button",
{
props: {
type: "success",
size: "small",
},
style: {
marginRight: "5px",
display:
params.row.distributionStatus == "RETREAT"
? "block"
: "none",
},
on: {
click: () => {
this.resume(params.row);
},
},
},
"恢复"
),
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.edit(params.row);
},
},
},
"编辑"
), h(
"div",
{
style: {
display: "flex",
justifyContent: "center",
},
})
]
);
},
},
{ title: "会员名称", colKey: "memberName", minWidth: 120, align: "left", tooltip: true },
{ title: "姓名", colKey: "name", minWidth: 100, align: "left" },
{ title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
{ title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
{ title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
{ title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ title: "推广单数", colKey: "distributionOrderCount", minWidth: 120, width: 150, align: "left" },
{ title: "分销订单金额", colKey: "distributionOrderPrice", width: 150, align: "left", cell: (h, p) => p.row.distributionOrderPrice != null ? h("priceColorScheme", { props: { value: p.row.distributionOrderPrice, color: this.$mainColor } }) : h('span', '-') },
{ title: "分销金额", colKey: "rebateTotal", width: 150, align: "left", cell: (h, p) => p.row.rebateTotal != null ? h("priceColorScheme", { props: { value: p.row.rebateTotal, color: this.$mainColor } }) : h('span', '-') },
{ title: "待提现金额", colKey: "canRebate", width: 150, align: "left", cell: (h, p) => p.row.canRebate != null ? h("priceColorScheme", { props: { value: p.row.canRebate, color: "green" } }) : h('span', '-') },
{ title: "冻结金额", colKey: "commissionFrozen", width: 150, align: "left", cell: (h, p) => p.row.commissionFrozen != null ? h("priceColorScheme", { props: { value: p.row.commissionFrozen, color: "#347dda" } }) : h('span', '-') },
{ title: "状态", colKey: "distributionStatus", width: 150, align: "left", cell: (h, p) => {
const s = p.row.distributionStatus;
const map = { PASS: { theme: "success", label: "通过" }, APPLY: { theme: "warning", label: "待审核" }, RETREAT: { theme: "warning", label: "清退" }, REFUSE: { theme: "danger", label: "拒绝" } };
const cfg = map[s] || { theme: "default", label: s };
return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
} },
{ title: "操作", colKey: "action", align: "center", fixed: "right", width: 180, cell: (h, p) => {
return h("div", { class: "ops" }, [
h("t-button", { props: { theme: "danger", size: "small" }, style: { marginRight: "8px", display: p.row.distributionStatus !== "RETREAT" ? "inline-block" : "none" }, on: { click: () => this.retreat(p.row) } }, ["清退"]),
h("t-button", { props: { theme: "success", size: "small" }, style: { marginRight: "8px", display: p.row.distributionStatus === "RETREAT" ? "inline-block" : "none" }, on: { click: () => this.resume(p.row) } }, ["恢复"]),
h("t-button", { props: { theme: "default", size: "small" }, on: { click: () => this.edit(p.row) } }, ["编辑"]),
]);
} },
],
data: [], // 表单数据
total: 0, // 表单数据总数
data: [],
total: 0,
};
},
methods: {
// 初始化数据
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.getDataList();
},
// 获取列表数据
init() { this.getDataList(); },
changePage(v) { this.searchForm.pageNumber = v; this.getDataList(); },
changePageSize(v) { this.searchForm.pageSize = v; this.getDataList(); },
onPaginationChange(info) { if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) { this.changePageSize(info.pageSize); } if (info && typeof info.current !== "undefined") { this.changePage(info.current); } },
handleSearch() { this.searchForm.pageNumber = 1; this.searchForm.pageSize = 20; this.getDataList(); },
onStatusTabChange(v) { this.activeStatus = v; this.searchForm.pageNumber = 1; this.getDataList(); },
getDataList() {
this.loading = true;
this.searchForm.status = "PASS";
this.searchForm.distributionStatus = this.activeStatus === 'ALL' ? '' : this.activeStatus;
getDistributionListData(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
}).catch(() => { this.loading = false; });
},
// 清退分销商
retreat(v) {
this.$Modal.confirm({
title: "提示",
// 记得确认修改此处
DialogPlugin.confirm({
header: "确认清退",
content: "您确认要清退 " + v.memberName + " ?",
loading: true,
onOk: () => {
// 删除
retreatDistribution(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
}
});
theme: "warning",
onConfirm: () => {
retreatDistribution(v.id).then((res) => { if (res.success) { MessagePlugin.success("操作成功"); this.getDataList(); } });
},
});
},
// 恢复分销商
resume(v) {
this.$Modal.confirm({
title: "提示",
// 记得确认修改此处
DialogPlugin.confirm({
header: "确认恢复",
content: "您确认要恢复 " + v.memberName + " ?",
loading: true,
onOk: () => {
// 删除
resumeDistribution(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
}
});
theme: "warning",
onConfirm: () => {
resumeDistribution(v.id).then((res) => { if (res.success) { MessagePlugin.success("操作成功"); this.getDataList(); } });
},
});
},
// 编辑
edit(v) {
this.$refs.distributionForm.resetFields();
// 转换null为""
for (let attr in v) {
if (v[attr] === null) {
v[attr] = "";
}
}
let str = JSON.stringify(v);
let data = JSON.parse(str);
const data = JSON.parse(JSON.stringify(v));
for (let attr in data) { if (data[attr] === null) { data[attr] = ""; } }
this.distributionForm = data;
this.modalVisible = true;
},
// 提交表单
handleSubmit() {
this.$refs.distributionForm.validate((valid) => {
if (valid) {
// 编辑
editDistribution(this.distributionForm).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
});
}
if (res.success) { MessagePlugin.success("操作成功"); this.getDataList(); this.modalVisible = false; }
});
},
},
mounted() {
this.init();
},
mounted() { this.init(); },
};
</script>
<style scoped lang="scss">
.status-tabs { margin: 8px 0; }
::v-deep .status-tabs .t-tabs__content { display: none; }
</style>

View File

@@ -1,59 +1,35 @@
<template>
<div>
<Card>
<Row @keydown.enter.native.prevent="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Button
@click="handleSearch"
type="primary"
class="search-btn"
>搜索</Button
>
</Form>
</Row>
<Table
class="mt_10"
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table class="mt_10" :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
:showJumper="true"
@change="onPaginationChange"
/>
</div>
</t-card>
</div>
</template>
<script>
import { auditDistribution, getDistributionListData } from "@/api/distribution";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "distributionApply",
@@ -63,67 +39,31 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
},
columns: [
{
title: "会员名称",
key: "memberName",
minWidth: 100,
tooltip: true,
},
{
title: "姓名",
key: "name",
minWidth: 100,
},
{
title: "身份证号",
key: "idNumber",
minWidth: 120,
},
{
title: "结算银行开户行名称",
key: "settlementBankAccountName",
minWidth: 120,
},
{
title: "结算银行开户账号",
key: "settlementBankAccountNum",
minWidth: 120,
},
{
title: "结算银行开户支行名称",
key: "settlementBankBranchName",
minWidth: 120,
},
{
title: "提交时间",
key: "createTime",
minWidth: 100,
},
{ title: "会员名称", colKey: "memberName", minWidth: 100, align: "left", tooltip: true },
{ title: "姓名", colKey: "name", minWidth: 100, align: "left" },
{ title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
{ title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
{ title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
{ title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ title: "提交时间", colKey: "createTime", minWidth: 120, align: "left" },
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
fixed: "right",
width: 200,
render: (h, params) => {
return h("div", [
cell: (h, params) => {
return h("div", { class: "ops" }, [
h(
"Button",
"a",
{
props: {
type: "success",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.audit(params.row, "PASS");
@@ -132,13 +72,10 @@ export default {
},
"通过"
),
h("span", {}, "|"),
h(
"Button",
"a",
{
props: {
type: "error",
size: "small",
},
on: {
click: () => {
this.audit(params.row, "REFUSE");
@@ -160,56 +97,59 @@ export default {
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
this.clearSelectAll();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 获取列表数据
getDataList() {
this.loading = true;
this.searchForm.distributionStatus = "APPLY";
getDistributionListData(this.searchForm).then((res) => {
getDistributionListData(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
//审核
audit(v, status) {
let test = "拒绝";
if (status == "PASS") {
if (status === "PASS") {
test = "通过";
}
let params = {
status: status,
};
this.$Modal.confirm({
title: "确认" + test,
// 记得确认修改此处
const params = { status };
DialogPlugin.confirm({
header: "确认" + test,
content: "您确认要" + test + " " + v.memberName + " ?",
loading: true,
onOk: () => {
theme: "warning",
onConfirm: () => {
auditDistribution(v.id, params).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});
@@ -222,3 +162,15 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.ops a {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops span {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
</style>

View File

@@ -1,64 +1,81 @@
<template>
<div>
<Card>
<Form ref="searchForm" @keydown.enter.native.prevent="handleSearch" :model="searchForm" class="search-form">
<Form-item label="会员名称" class="flex" prop="memberName">
<Input
type="text" placeholder="请输入会员名称" v-model="searchForm.memberName" clearable
style="width: 200px"></Input>
</Form-item>
<Form-item label="编号" class="flex">
<Input
type="text" placeholder="请输入编号" v-model="searchForm.sn" clearable
style="width: 200px"></Input>
</Form-item>
<Form-item label="状态"
style="width: 200px">
<Select v-model="searchForm.distributionCashStatus" clearable style="width: 150px">
<Option v-for="item in cashStatusList" :value="item.value" :key="item.value">{{ item.label }}</Option>
</Select>
</Form-item>
<Form-item>
<Button @click="handleSearch" type="primary">搜索</Button>
</Form-item>
</Form>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10"></Table>
<Row type="flex" justify="end" class="page padding-row">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" size="small" show-total show-elevator show-sizer></Page>
</Row>
</Card>
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable='false' :width="500">
<Form ref="form" :model="form" :label-width="100" >
<FormItem label="编号">
<Input disabled v-model="form.sn" clearable style="width:100%"/>
</FormItem>
<FormItem label="会员名称">
<Input disabled v-model="form.distributionName" clearable style="width:100%"/>
</FormItem>
<FormItem label="金额">
<Input disabled v-model="form.price" clearable style="width:100%"/>
</FormItem>
<FormItem label="是否通过" prop="result" v-if="handleStatus =='edit'">
<RadioGroup v-model="result" type="button" button-style="solid">
<Radio label="VIA_AUDITING">通过</Radio>
<Radio label="FAIL_AUDITING">拒绝</Radio>
</RadioGroup>
</FormItem>
</Form>
<div slot="footer" v-if="handleStatus == 'edit'">
<Button type="text" @click="modalVisible=false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit">提交</Button>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="编号" name="sn">
<t-input v-model="searchForm.sn" placeholder="请输入编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="状态">
<t-select v-model="searchForm.distributionCashStatus" clearable style="width: 240px">
<t-option v-for="item in cashStatusList" :value="item.value" :key="item.value" :label="item.label" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<div class="page padding-row" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</Modal>
</t-card>
<t-drawer :visible.sync="modalVisible" :header="modalTitle" placement="right" size="500px" @close="modalVisible = false">
<div v-if="handleStatus === 'view'">
<t-descriptions :column="1" size="medium">
<t-descriptions-item label="编号">{{ form.sn }}</t-descriptions-item>
<t-descriptions-item label="会员名称">{{ form.distributionName }}</t-descriptions-item>
<t-descriptions-item label="申请金额">{{ form.price }}</t-descriptions-item>
<t-descriptions-item label="申请时间">{{ form.createTime }}</t-descriptions-item>
<t-descriptions-item label="姓名">{{ form.name }}</t-descriptions-item>
<t-descriptions-item label="身份证号">{{ form.idNumber }}</t-descriptions-item>
<t-descriptions-item label="结算银行开户行名称">{{ form.settlementBankAccountName }}</t-descriptions-item>
<t-descriptions-item label="结算银行开户账号">{{ form.settlementBankAccountNum }}</t-descriptions-item>
<t-descriptions-item label="结算银行开户支行名称">{{ form.settlementBankBranchName }}</t-descriptions-item>
<t-descriptions-item label="处理时间">{{ form.updateTime }}</t-descriptions-item>
<t-descriptions-item label="状态">{{ { APPLY: '待处理', VIA_AUDITING: '通过', FAIL_AUDITING: '审核拒绝' }[form.distributionCashStatus] || form.distributionCashStatus }}</t-descriptions-item>
</t-descriptions>
</div>
<div v-else>
<t-form ref="form" :data="form" :labelWidth="100">
<t-form-item label="编号">
<t-input v-model="form.sn" disabled style="width: 100%" />
</t-form-item>
<t-form-item label="会员名称">
<t-input v-model="form.distributionName" disabled style="width: 100%" />
</t-form-item>
<t-form-item label="金额">
<t-input v-model="form.price" disabled style="width: 100%" />
</t-form-item>
<t-form-item label="是否通过">
<t-radio-group v-model="result">
<t-radio value="VIA_AUDITING">通过</t-radio>
<t-radio value="FAIL_AUDITING">拒绝</t-radio>
</t-radio-group>
</t-form-item>
</t-form>
</div>
<template #footer>
<div v-if="handleStatus === 'edit'" style="display: flex; justify-content: flex-end">
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" style="margin-left: 8px" @click="handleSubmit">提交</t-button>
</div>
<div v-else style="display: flex; justify-content: flex-start">
<t-button theme="primary" @click="modalVisible = false">返回</t-button>
</div>
</template>
</t-drawer>
</div>
</template>
<script>
import {
auditDistributionCash,
getDistributionCash
} from "@/api/distribution";
import { cashStatusList } from './dataJson';
import { auditDistributionCash, getDistributionCash } from "@/api/distribution";
import { cashStatusList } from "./dataJson";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "distributionCash",
data() {
@@ -70,7 +87,7 @@ export default {
result: 'FAIL_AUDITING', // 是否通过
searchForm: { // 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
},
@@ -82,129 +99,65 @@ export default {
},
submitLoading: false, // 添加或编辑提交状态
columns: [
{
title: "编号",
key: "sn",
minWidth: 200
},
{
title: "会员名称",
key: "distributionName",
minWidth: 120
},
{
title: "申请金额",
key: "price",
minWidth: 90,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
},
},
{
title: "申请时间",
key: "createTime",
minWidth: 130
},
{
title: "姓名",
key: "name",
minWidth: 100,
},
{
title: "身份证号",
key: "idNumber",
minWidth: 120,
},
{
title: "结算银行开户行名称",
key: "settlementBankAccountName",
minWidth: 120,
},
{
title: "结算银行开户账号",
key: "settlementBankAccountNum",
minWidth: 120,
},
{
title: "结算银行开户支行名称",
key: "settlementBankBranchName",
minWidth: 120,
},
{
title: "处理时间",
key: "updateTime",
minWidth: 130
},
{ title: "编号", colKey: "sn", width: 300, align: "left" },
{ title: "会员名称", colKey: "distributionName", minWidth: 120, align: "left" },
{ title: "申请金额", colKey: "price", minWidth: 100, align: "left", cell: (h, p) => h("priceColorScheme", { props: { value: p.row.price, color: this.$mainColor } }) },
{ title: "申请时间", colKey: "createTime", minWidth: 150, align: "left" },
{ title: "姓名", colKey: "name", minWidth: 100, align: "left" },
{ title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
{ title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
{ title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
{ title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ title: "处理时间", colKey: "updateTime", minWidth: 150, align: "left" },
{
title: "状态",
key: "distributionCashStatus",
minWidth: 100,
render: (h, params) => {
if (params.row.distributionCashStatus == 'APPLY') {
return h("div", "待处理");
}
if (params.row.distributionCashStatus == 'VIA_AUDITING') {
return h("div", "通过");
}
if (params.row.distributionCashStatus == 'FAIL_AUDITING') {
return h("div", "审核拒绝");
}
colKey: "distributionCashStatus",
minWidth: 120,
align: "left",
cell: (h, p) => {
const s = p.row.distributionCashStatus;
const map = { APPLY: { theme: "warning", label: "待处理" }, VIA_AUDITING: { theme: "success", label: "通过" }, FAIL_AUDITING: { theme: "danger", label: "审核拒绝" } };
const cfg = map[s] || { theme: "default", label: s };
return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
},
},
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
fixed: "right",
width: 130,
render: (h, params) => {
if(params.row.distributionCashStatus != 'APPLY'){
return h("div", [
cell: (h, params) => {
if (params.row.distributionCashStatus !== "APPLY") {
return h("div", { class: "ops" }, [
h(
"Button",
"a",
{
props: {
type: "primary",
size: "small",
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.view(params.row);
}
}
},
},
},
"查看"
),
]);
}else {
return h("div", [
}
return h("div", { class: "ops" }, [
h(
"Button",
"a",
{
props: {
type: "primary",
size: "small",
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.edit(params.row);
}
}
},
},
},
"审核"
),
]);
}
}
}
},
},
],
data: [], // 表单数据
total: 0 // 表单数据总数
@@ -225,59 +178,68 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== 'undefined' && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== 'undefined') {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 获取列表数据
getDataList() {
this.loading = true;
// 带多条件搜索参数获取表单数据 请自行修改接口
getDistributionCash(this.searchForm).then(res => {
getDistributionCash(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
// 通过还是拒绝申请
handleSubmit() {
let result = "拒绝"
if(this.result == 'VIA_AUDITING'){
result = "通过"
let result = "拒绝";
if (this.result === "VIA_AUDITING") {
result = "通过";
}
this.$refs.form.validate(valid => {
if (valid) {
this.$Modal.confirm({
title: "确认审核",
content: "您确认要审核"+result+"么?",
loading: true,
onOk: () => {
auditDistributionCash(this.form.id,{result:this.result}).then(res => {
DialogPlugin.confirm({
header: "确认审核",
content: "您确认要审核" + result + "么?",
theme: "warning",
onConfirm: () => {
this.submitLoading = true;
auditDistributionCash(this.form.id, { result: this.result })
.then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Modal.remove();
this.$Message.success("审核成功");
MessagePlugin.success("审核成功");
this.getDataList();
this.modalVisible = false;
} else {
this.modalVisible = false;
}
});
}
})
}
.catch(() => {
this.submitLoading = false;
});
},
});
},
// 弹出modal 审核
edit(v) {
this.modalTitle = "审核";
this.handleStatus = 'edit';
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
// 转换null为""
for (let attr in v) {
if (v[attr] === null) {
@@ -291,7 +253,7 @@ export default {
view(v){
this.modalTitle = "查看";
this.handleStatus = 'view';
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
// 转换null为""
for (let attr in v) {
if (v[attr] === null) {
@@ -310,3 +272,15 @@ export default {
}
};
</script>
<style lang="scss" scoped>
.ops a {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops span {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
</style>

View File

@@ -1,45 +1,45 @@
<template>
<div>
<Card>
<Form @keydown.enter.native.prevent="handleSearch" ref="searchForm" :model="searchForm" inline :label-width="70"
class="search-form">
<Form-item label="商品名称" prop="goodsName">
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 200px" />
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
<Row class="operation" style="margin:10px 0;">
<Button @click="delAll" type="primary">批量下架</Button>
</Row>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom"
@on-selection-change="changeSelect">
<template slot="goodsName" slot-scope="{row}">
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="商品名称" name="goodsName">
<t-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="operation padding-row">
<t-button theme="primary" @click="delAll">批量下架</t-button>
</div>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onSelectChange">
<template #goodsName="{ row }">
<div>
<div class="div-zoom">
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<a @click="linkTo(row.goodsId,row.skuId)">{{ row.goodsName }}</a>
</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff"
:size="150"></vue-qr>
</div>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
</Poptip>
<t-popup trigger="hover" placement="top" :showArrow="true">
<template #content>
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150" />
</template>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="" />
</t-popup>
</div>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" size="small" show-total show-elevator
show-sizer></Page>
</Row>
</Card>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
<script>
import { delDistributionGoods, getDistributionGoods } from "@/api/distribution";
import vueQr from "vue-qr";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
components: {
"vue-qr": vueQr,
@@ -51,98 +51,71 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
},
selectList: [], // 多选数据
selectCount: 0, // 多选计数
selectList: [],
selectCount: 0,
selectedRowKeys: [],
columns: [
// 表头
{
type: "selection",
width: 60,
align: "center",
fixed: "left",
},
{
title: "商品图片",
fixed: "left",
key: "thumbnail",
colKey: "thumbnail",
width: 120,
align: "center",
render: (h, params) => {
return h("img", {
attrs: {
src: params.row.thumbnail || '',
alt: "加载图片失败",
},
style: {
cursor: "pointer",
width: "80px",
height: "60px",
margin: "10px 0",
"object-fit": "contain",
},
});
},
cell: (h, p) => h("img", { attrs: { src: p.row.thumbnail || "", alt: "加载图片失败" }, style: { cursor: "pointer", width: "80px", height: "60px", margin: "10px 0", objectFit: "contain" } }),
},
{
title: "商品名称",
slot: "goodsName",
colKey: "goodsName",
minWidth: 200,
tooltip: true,
},
{
title: "商品价格",
key: "price",
colKey: "price",
minWidth: 100,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
cell: (h, p) => h("priceColorScheme", { props: { value: p.row.price, color: this.$mainColor } }),
},
},
{
title: "库存",
key: "quantity",
colKey: "quantity",
minWidth: 80,
},
{
title: "添加时间",
key: "createTime",
colKey: "createTime",
minWidth: 100,
},
{
title: "店铺名称",
key: "storeName",
colKey: "storeName",
minWidth: 100,
tooltip: true,
},
{
title: "佣金金额",
key: "commission",
colKey: "commission",
minWidth: 100,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.commission,color:this.$mainColor}} );
},
cell: (h, p) => h("priceColorScheme", { props: { value: p.row.commission, color: this.$mainColor } }),
},
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
fixed: "right",
minWidth: 100,
render: (h, params) => {
return h("div", [
cell: (h, params) => {
return h("div", { class: "ops" }, [
h(
"Button",
"a",
{
props: {
type: "error",
size: "small",
},
on: {
click: () => {
this.remove(params.row);
@@ -164,7 +137,6 @@ export default {
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
@@ -175,46 +147,55 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 清除选中状态
clearSelectAll() {
this.$refs.table.selectAll(false);
this.selectedRowKeys = [];
this.selectList = [];
this.selectCount = 0;
},
// 选中后赋值
changeSelect(e) {
this.selectList = e;
this.selectCount = e.length;
onSelectChange(keys, { selectedRowData }) {
this.selectedRowKeys = keys;
this.selectList = selectedRowData || [];
this.selectCount = keys.length;
},
// 获取列表数据
getDataList() {
this.loading = true;
getDistributionGoods(this.searchForm).then((res) => {
getDistributionGoods(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
// 下架商品
remove(v) {
this.$Modal.confirm({
title: "确认下架",
DialogPlugin.confirm({
header: "确认下架",
content: "您确认要下架么?",
loading: true,
onOk: () => {
// 下架
theme: "warning",
onConfirm: () => {
delDistributionGoods(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("下架成功");
MessagePlugin.success("下架成功");
this.getDataList();
}
});
@@ -224,23 +205,18 @@ export default {
// 批量下架
delAll() {
if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要下架的数据");
MessagePlugin.warning("您还未选择要下架的数据");
return;
}
this.$Modal.confirm({
title: "确认下架",
DialogPlugin.confirm({
header: "确认下架",
content: "您确认要下架所选的 " + this.selectCount + " 条数据?",
loading: true,
onOk: () => {
let ids = [];
this.selectList.forEach((item) => {
ids.push(item.id);
});
// 批量下架
theme: "warning",
onConfirm: () => {
const ids = (this.selectList || []).map((item) => item.id);
delDistributionGoods(ids.toString()).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("下架成功");
MessagePlugin.success("下架成功");
this.clearSelectAll();
this.getDataList();
}
@@ -254,5 +230,17 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.ops a {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops span {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
</style>

View File

@@ -1,75 +1,62 @@
<template>
<div>
<Card>
<Form ref="searchForm" @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="分销商" prop="distributionName">
<Input
type="text"
v-model="searchForm.distributionName"
placeholder="请输入分销商名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="店铺名称">
<Select v-model="searchForm.storeId" placeholder="请选择" @on-query-change="searchChange" filterable
clearable style="width: 150px">
<Option v-for="item in shopList" :value="item.id" :key="item.id">{{ item.storeName }}</Option>
</Select>
</Form-item>
<Form-item label="订单时间">
<DatePicker type="daterange" v-model="timeRange" format="yyyy-MM-dd" placeholder="选择时间"
style="width: 210px"></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10">
<template slot-scope="{row}" slot="goodsMsg">
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="订单编号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="分销商" name="distributionName">
<t-input v-model="searchForm.distributionName" placeholder="请输入分销商名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="店铺名称">
<t-select v-model="searchForm.storeId" placeholder="请选择" :filterable="true" clearable style="width: 240px" @input-change="searchChange">
<t-option v-for="item in shopList" :value="item.id" :key="item.id" :label="item.storeName" />
</t-select>
</t-form-item>
<t-form-item label="订单时间">
<t-date-picker v-model="timeRange" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" placeholder="选择时间" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id">
<template #goodsMsg="{ row }">
<div class="goods-msg">
<img :src="row.image" width="60" height="60" alt="">
<img :src="row.image" width="60" height="60" alt="" />
<div>
<div class="div-zoom">
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<a @click="linkTo(row.goodsId,row.skuId)">{{ row.goodsName }}</a>
</div>
<div style="color:#999;font-size:10px">数量x{{row.num}}</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
</div>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
</Poptip>
<div style="color:#999;font-size:10px">数量x{{ row.num }}</div>
<t-popup trigger="hover" placement="top" :showArrow="true">
<template #content>
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150" />
</template>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="" />
</t-popup>
</div>
</div>
</template>
<template slot-scope="{row}" slot="distributionOrderStatus">
<Tag :color="filterStatusColor(row.distributionOrderStatus)">{{filterStatus(row.distributionOrderStatus)}}</Tag>
<template #distributionOrderStatus="{ row }">
<t-tag :theme="filterStatusColor(row.distributionOrderStatus) === 'green' ? 'success' : (filterStatusColor(row.distributionOrderStatus) === 'orange' ? 'warning' : 'danger')" size="small" variant="light">{{ filterStatus(row.distributionOrderStatus) }}</t-tag>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize"
@on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10,20,50]"
size="small" show-total show-elevator show-sizer></Page>
</Row>
</Card>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
<script>
import {
getDistributionOrder
} from "@/api/distribution";
import {orderStatusList} from './dataJson'
import {getShopListData} from '@/api/shops'
import vueQr from 'vue-qr'
import { getDistributionOrder } from "@/api/distribution";
import { orderStatusList } from "./dataJson";
import { getShopListData } from "@/api/shops";
import vueQr from "vue-qr";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "distributionOrder",
@@ -78,66 +65,25 @@
},
data() {
return {
timeRange: [], // 范围时间
timeRange: undefined, // 范围时间
orderStatusList, // 订单状态列表
shopList: [], // 店铺列表
distributionId: this.$route.query.id, // 分销id
loading: true, // 表单加载状态
searchForm: { // 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort:"create_time",
order:"desc"
},
columns: [
{
title: "订单编号",
key: "orderSn",
minWidth: 180,
fixed: "left",
tooltip: true
},
{
title: '商品信息',
slot: 'goodsMsg',
minWidth: 150
},
{
title: "分销商",
key: "distributionName",
tooltip: true,
minWidth:80,
},
{
title: "店铺名称",
key: "storeName",
minWidth:80,
tooltip: true
},
{
title: "状态",
slot: "distributionOrderStatus",
minWidth:80,
},
{
title: "佣金金额",
key: "rebate",
minWidth:80,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.rebate,color:this.$mainColor}} );
},
},
{
fixed: "right",
title: "创建时间",
key: "createTime",
minWidth:100,
sortable: false,
}
{ title: "订单编号", colKey: "orderSn", minWidth: 180, fixed: "left", tooltip: true },
{ title: "商品信息", colKey: "goodsMsg", minWidth: 180 },
{ title: "分销商", colKey: "distributionName", tooltip: true, minWidth: 120 },
{ title: "店铺名称", colKey: "storeName", minWidth: 120, tooltip: true },
{ title: "状态", colKey: "distributionOrderStatus", minWidth: 120 },
{ title: "佣金金额", colKey: "rebate", minWidth: 120, cell: (h, p) => h("priceColorScheme", { props: { value: p.row.rebate, color: this.$mainColor } }) },
{ fixed: "right", title: "创建时间", colKey: "createTime", minWidth: 150 },
],
data: [], // 表单数据
total: 0 // 表单数据总数
@@ -149,48 +95,58 @@
this.getDataList();
this.getShopList()
},
//分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 获取列表数据
getDataList() {
this.searchForm.distributionId = this.distributionId;
this.loading = true;
if (this.timeRange && this.timeRange[0]) {
let startTime = this.timeRange[0]
let endTime = this.timeRange[1]
if (Array.isArray(this.timeRange) && this.timeRange.length === 2) {
const startTime = this.timeRange[0]
const endTime = this.timeRange[1]
this.searchForm.startTime = this.$options.filters.unixToDate(startTime / 1000)
this.searchForm.endTime = this.$options.filters.unixToDate(endTime / 1000)
} else {
this.searchForm.startTime = null
this.searchForm.endTime = null
}
// 带多条件搜索参数获取表单数据 请自行修改接口
getDistributionOrder(this.searchForm).then(res => {
getDistributionOrder(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
getShopList(val) { // 获取店铺列表 搜索用
const params = {
pageNumber: 1,
pageSize: 10,
pageSize: 20,
storeName: ''
}
if (val) {
@@ -208,7 +164,7 @@
},
filterStatus (status) { // 过滤订单状态
const arr = [
{status: 'WAIT_BILL', title: '待结算'},
{status: 'NO_COMPLETED', title: '未完成'},
{status: 'COMPLETE', title: '完成'},
{status: 'REFUND', title: '退款'},
]
@@ -217,21 +173,20 @@
return arr[i].title;
}
}
return '未完成'; // 默认返回未完成
},
filterStatusColor (status) { // 状态tag标签颜色
const arr = [
{status: 'WAIT_BILL', color: 'blue'},
{status: 'WAIT_CASH', color: 'orange'},
{status: 'COMPLETE_CASH', color: 'green'},
{status: 'CANCEL', color: 'red'},
{status: 'NO_COMPLETED', color: 'red'},
{status: 'REFUND', color: 'magenta'},
{status: 'NO_COMPLETED', color: 'orange'},
{status: 'COMPLETE', color: 'green'},
{status: 'REFUND', color: 'red'},
]
for (let i=0;i<arr.length;i++) {
if (arr[i].status === status) {
return arr[i].color;
}
}
return 'orange'; // 默认返回橙色
}
},
mounted() {

View File

@@ -1,27 +1,23 @@
<template>
<div style="background-color: #fff;">
<Form ref="form" :model="form" :rules="formRule" :label-width="120" style="padding: 10px;">
<Divider orientation="left">分销设置</Divider>
<FormItem label="是否开启分销" prop="isOpen">
<i-switch size="large" v-model="form.isOpen" :true-value="true" :false-value="false">
<span slot="open">开启</span>
<span slot="close">关闭</span>
</i-switch>
</FormItem>
<FormItem label="分销关系绑定天数" prop="distributionDay">
<InputNumber :min="1" :max="365" style="width:100px;" v-model="form.distributionDay"></InputNumber>
</FormItem>
<FormItem>
<Button type="primary" @click="submit">保存</Button>
</FormItem>
</Form>
</div>
<t-card>
<t-form ref="form" :data="form" :rules="formRule" :labelWidth="120" style="padding: 10px;">
<t-divider align="left">分销设置</t-divider>
<t-form-item label="是否开启分销" name="isOpen">
<t-switch v-model="form.isOpen" />
</t-form-item>
<t-form-item label="分销关系绑定天数" name="distributionDay">
<t-input-number :min="1" :max="365" style="width:100px;" v-model="form.distributionDay" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="submit">保存</t-button>
</t-form-item>
</t-form>
</t-card>
</template>
<script>
import { setSetting, getSetting } from "@/api/index";
import { MessagePlugin } from "tdesign-vue";
import { regular } from "@/utils";
export default {
name: "distributionSetting",
@@ -59,7 +55,7 @@ export default {
submit() {
setSetting("DISTRIBUTION_SETTING", this.form).then((res) => {
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});

View File

@@ -1,53 +1,32 @@
<template>
<div class="search">
<Card>
<Row class="operation">
<Button @click="add" type="primary">添加</Button>
<Button @click="refresh">刷新</Button>
<Button @click="delAll">批量删除</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
sortable="custom"
@on-selection-change="changeSelect"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
<FormItem label="计量单位" prop="name">
<Input v-model="form.name" clearable style="width: 100%" />
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交</Button
>
<t-card>
<div class="operation" style="margin-bottom: 10px;">
<t-button theme="primary" @click="add">添加</t-button>
<t-button variant="outline" @click="delAll" style="margin-left: 8px;">批量删除</t-button>
</div>
</Modal>
<t-table :loading="loading" :columns="columns" :data="data" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onSelectChange">
<template #action="{ row }">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none;margin-right:5px" @click="edit(row)">修改</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="remove(row)">删除</a>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
<t-drawer :visible.sync="modalVisible" :header="modalTitle" placement="right" size="500px" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100" :rules="formValidate">
<t-form-item label="计量单位" name="name">
<t-input v-model="form.name" style="width: 100%" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-drawer>
</div>
</template>
@@ -59,7 +38,8 @@ import {
delGoodsUnit
} from "@/api/index";
import {regular} from "@/utils";
import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "goods-unit",
@@ -71,7 +51,7 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
name: "",
@@ -88,82 +68,16 @@ export default {
]
},
submitLoading: false, // 添加或编辑提交状态
selectList: [], // 多选数据
selectCount: 0, // 多选计数
selectedRowKeys: [],
selectList: [],
selectCount: 0,
columns: [
// 表头
{
type: "selection",
width: 60,
align: "center",
},
{
title: "计量单位",
key: "name",
minWidth: 120
},
{
title: "创建时间",
key: "createTime",
width: 180
},
{
title: "更新时间",
key: "updateTime",
width: 180
},
{
title: "操作人",
key: "createBy",
minWidth: 150
},
{
title: "操作",
key: "action",
align: "center",
width: 200,
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.edit(params.row);
},
},
},
"修改"
),
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.remove(params.row);
},
},
},
"删除"
),
]);
},
},
{ colKey: "row-select", type: "multiple", width: 60, align: "center" },
{ title: "计量单位", colKey: "name", minWidth: 120 },
{ title: "创建时间", colKey: "createTime", width: 180 },
{ title: "更新时间", colKey: "updateTime", width: 180 },
{ title: "操作人", colKey: "createBy", minWidth: 150 },
{ title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -185,20 +99,31 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 清除选中
clearSelectAll() {
this.$refs.table.selectAll(false);
this.selectedRowKeys = [];
this.selectList = [];
this.selectCount = 0;
},
// 选中回调
changeSelect(e) {
this.selectList = e;
this.selectCount = e.length;
onSelectChange(keys, { selectedRowData }) {
this.selectedRowKeys = keys;
this.selectList = selectedRowData || [];
this.selectCount = keys.length;
},
// 获取列表数据
getDataList() {
@@ -254,8 +179,10 @@ export default {
// 添加
add() {
this.modalTitle = "添加";
this.form = {};
this.$refs.form.resetFields();
this.form = { name: "" };
if (this.$refs.form && typeof this.$refs.form.reset === "function") {
this.$refs.form.reset();
}
this.modalVisible = true;
},
@@ -268,53 +195,40 @@ export default {
},
// 删除
remove(v) {
this.$Modal.confirm({
title: "确认删除",
// 记得确认修改此处
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除 " + v.name + " ?",
loading: true,
onOk: () => {
// 删除
theme: "warning",
onConfirm: () => {
delGoodsUnit(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});
},
});
},
// 刷新
refresh() {
this.loading = true;
setTimeout(() => {
this.getDataList();
this.loading = false;
this.$Message.success("刷新成功");
}, 500);
},
// 全部删除
delAll() {
if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据");
MessagePlugin.warning("您还未选择要删除的数据");
return;
}
this.$Modal.confirm({
title: "确认删除",
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
loading: true,
onOk: () => {
theme: "warning",
onConfirm: () => {
let ids = "";
this.selectList.forEach(function (e) {
ids += e.id + ",";
});
ids = ids.substring(0, ids.length - 1);
// 批量删除
delGoodsUnit(ids).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.clearSelectAll();
this.getDataList();
}

View File

@@ -1,165 +1,140 @@
<template>
<div class="search">
<Card>
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
@keydown.enter.native="handleSearch"
>
<Form-item label="商品名称" prop="goodsName">
<Input
type="text"
v-model="searchForm.goodsName"
placeholder="请输入商品名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="商品编号" prop="id">
<Input
type="text"
v-model="searchForm.id"
placeholder="请输入商品编号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="店铺名称" prop="id">
<Input
type="text"
v-model="searchForm.storeName"
placeholder="请输入店铺名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="状态" prop="status">
<Select
v-model="searchForm.marketEnable"
placeholder="请选择"
clearable
style="width: 200px"
>
<Option value="UPPER">上架</Option>
<Option value="DOWN">下架</Option>
</Select>
</Form-item>
<Form-item label="销售模式" prop="status">
<Select
v-model="searchForm.salesModel"
placeholder="请选择"
clearable
style="width: 200px"
>
<Option value="RETAIL">零售</Option>
<Option value="WHOLESALE">批发</Option>
</Select>
</Form-item>
<Form-item label="商品类型" prop="status">
<Select
v-model="searchForm.goodsType"
placeholder="请选择"
clearable
style="width: 200px"
>
<Option value="PHYSICAL_GOODS">实物商品</Option>
<Option value="VIRTUAL_GOODS">虚拟商品</Option>
</Select>
</Form-item>
<Button
@click="handleSearch"
class="search-btn"
type="primary"
icon="ios-search"
>搜索</Button
>
</Form>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
>
<!-- 商品栏目格式化 -->
<template slot="goodsSlot" slot-scope="{ row }">
<div style="margin: 5px 0px; height: 80px; display: flex">
<div style="">
<img
:src="row.original"
style="height: 60px; margin-top: 1px; width: 60px"
/>
<t-card style="margin-bottom: 12px">
<t-form ref="searchForm" :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="商品名称" name="goodsName">
<t-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="商品ID" name="id">
<t-input v-model="searchForm.id" placeholder="请输入商品ID" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="店铺名称" name="storeName">
<t-input v-model="searchForm.storeName" placeholder="请输入店铺名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="销售模式" name="salesModel">
<t-select v-model="searchForm.salesModel" placeholder="请选择" clearable style="width: 240px">
<t-option value="RETAIL" label="零售" />
<t-option value="WHOLESALE" label="批发" />
</t-select>
</t-form-item>
<t-form-item label="商品类型" name="goodsType">
<t-select v-model="searchForm.goodsType" placeholder="请选择" clearable style="width: 240px">
<t-option value="PHYSICAL_GOODS" label="实物商品" />
<t-option value="VIRTUAL_GOODS" label="虚拟商品" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="goods-tab">
<t-tabs v-model="currentStatus" @change="goodsStatusClick">
<t-tab-panel v-for="(item,index) in goodsStatusWithCount" :key="index" :label="item.title" :value="item.value"></t-tab-panel>
</t-tabs>
</div>
<div style="margin-left: 13px">
<div class="batch-operations" style="margin: 10px 0;">
<t-button theme="success" :disabled="selectedRows.length === 0" @click="batchUpper" style="margin-right: 10px;">批量上架</t-button>
<t-button theme="warning" :disabled="selectedRows.length === 0" @click="batchLower" style="margin-right: 10px;">批量下架</t-button>
<t-button v-if="currentStatus === 'TOBEAUDITED'" theme="primary" :disabled="selectedRows.length === 0" @click="batchAudit">批量审核</t-button>
</div>
<t-table :loading="loading" :columns="columns" :data="data" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onTSelectChange" class="mt_10">
<template #imageSlot="{ row }">
<div style="margin-top: 5px;">
<img :src="row.original" style="height: 50px; width: 50px; object-fit: cover;" />
</div>
</template>
<template #goodsSlot="{ row }">
<div style="margin: 5px 0px; padding: 10px 0px;">
<div class="div-zoom">
<a @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr
:text="wapLinkTo(row.id, row.skuId)"
:margin="0"
colorDark="#000"
colorLight="#fff"
:size="150"
></vue-qr>
</div>
<img
src="../../../assets/qrcode.svg"
class="hover-pointer"
width="20"
height="20"
alt=""
/>
</Poptip>
</div>
</div>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<Modal
title="下架操作"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="underForm" :model="underForm" :label-width="100">
<FormItem label="下架原因" prop="reason">
<Input v-model="underForm.reason" clearable style="width: 100%" />
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="lower"
>提交</Button
>
<template #action="{ row }">
<template v-if="row.authFlag === 'TOBEAUDITED'">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="openAuditModal(row)">审核</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
</template>
<template v-else-if="row.marketEnable == 'DOWN'">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="upper(row)">上架</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
</template>
<template v-else>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="edit(row)">下架</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
</template>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</Modal>
</t-card>
<t-dialog :visible.sync="modalVisible" header="下架操作" width="500px" :footer="false" @close="modalVisible = false">
title="下架操作"
>
<t-form ref="underForm" :data="underForm" :labelWidth="100">
<t-form-item label="下架原因" name="reason">
<t-input v-model="underForm.reason" style="width: 100%" />
</t-form-item>
</t-form>
<div style="text-align:right;margin-top: 12px;">
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="lower">提交</t-button>
</div>
</t-dialog>
<t-dialog :visible.sync="auditModalVisible" header="商品审核" width="500px" :footer="false" @close="auditModalVisible = false">
<t-form ref="auditForm" :data="goodsAuditForm" :labelWidth="100">
<t-form-item label="审核结果" name="auth_flag">
<t-radio-group v-model="goodsAuditForm.auth_flag">
<t-radio :value="1">审核通过</t-radio>
<t-radio :value="2">审核拒绝</t-radio>
</t-radio-group>
</t-form-item>
</t-form>
<div style="text-align:right;margin-top: 12px;">
<t-button variant="text" @click="auditModalVisible = false">取消</t-button>
<t-button theme="primary" @click="confirmAudit">提交审核</t-button>
</div>
</t-dialog>
<t-dialog :visible.sync="batchAuditModalVisible" header="批量商品审核" width="500px" :footer="false" @close="batchAuditModalVisible = false">
<t-form ref="batchAuditForm" :data="batchAuditForm" :labelWidth="100">
<t-form-item label="审核结果" name="auth_flag">
<t-radio-group v-model="batchAuditForm.auth_flag">
<t-radio :value="1">审核通过</t-radio>
<t-radio :value="2">审核拒绝</t-radio>
</t-radio-group>
</t-form-item>
<t-form-item label="审核备注" name="reason" v-if="batchAuditForm.auth_flag === 2">
<t-textarea v-model="batchAuditForm.reason" :rows="3" placeholder="请输入拒绝原因" />
</t-form-item>
<t-form-item label="选中商品">
<div style="max-height: 200px; overflow-y: auto;">
<t-tag v-for="item in selectedRows" :key="item.id" style="margin: 2px;">{{item.goodsName}}</t-tag>
</div>
</t-form-item>
</t-form>
<div style="text-align:right;margin-top: 12px;">
<t-button variant="text" @click="batchAuditModalVisible = false">取消</t-button>
<t-button theme="primary" @click="submitBatchAudit">提交审核</t-button>
</div>
</t-dialog>
</div>
</template>
<script>
import { getGoodsListData, upGoods, lowGoods } from "@/api/goods";
import { getGoodsListData,getGoodsNumerData, upGoods, lowGoods, authGoods } from "@/api/goods";
import vueQr from "vue-qr";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
components: {
"vue-qr": vueQr,
@@ -173,185 +148,72 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "create_time", // 默认排序字段
order: "desc", // 默认排序方式
goodsName: "",
id: "",
storeName: "",
salesModel: "",
goodsType: "",
goodsStatus: "",
},
underForm: {
// 下架原因
reason: "",
},
goodsAuditForm: {
// 商品审核表单
auth_flag: 1,
},
auditModalVisible: false, // 审核弹框显示状态
currentAuditGoods: null, // 当前审核的商品
submitLoading: false, // 添加或编辑提交状态
selectedRowKeys: [],
columns: [
{
title: "商品名称",
key: "goodsName",
minWidth: 180,
slot: "goodsSlot",
},
{
title: "商品编号",
key: "id",
minWidth: 150,
tooltip: true,
},
{
title: "价格",
key: "price",
width: 130,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
},
},
{
title: "销售模式",
key: "salesModel",
width: 100,
render: (h, params) => {
if (params.row.salesModel === "RETAIL") {
return h("Tag", { props: { color: "orange" } }, "零售");
} else if (params.row.salesModel === "WHOLESALE") {
return h("Tag", { props: { color: "magenta" } }, "批发");
} else {
return h("Tag", { props: { color: "volcano" } }, "其他类型");
}
},
},
{
title: "商品类型",
key: "goodsType",
width: 130,
render: (h, params) => {
if (params.row.goodsType === "PHYSICAL_GOODS") {
return h("Tag", { props: { color: "green" } }, "实物商品");
} else if (params.row.goodsType === "VIRTUAL_GOODS") {
return h("Tag", { props: { color: "volcano" } }, "虚拟商品");
} else {
return h("Tag", { props: { color: "geekblue" } }, "电子卡券");
}
},
},
{
title: "状态",
key: "marketEnable",
width: 100,
render: (h, params) => {
if (params.row.marketEnable == "DOWN") {
return h("Tag", { props: { color: "volcano" } }, "下架");
} else if (params.row.marketEnable == "UPPER") {
return h("Tag", { props: { color: "green" } }, "上架");
}
},
},
{
title: "审核状态",
key: "authFlag",
width: 130,
render: (h, params) => {
if (params.row.authFlag == "TOBEAUDITED") {
return h("Tag", { props: { color: "volcano" } }, "待审核");
} else if (params.row.authFlag == "PASS") {
return h("Tag", { props: { color: "green" } }, "通过");
} else if (params.row.authFlag == "REFUSE") {
return h("Tag", { props: { color: "red" } }, "拒绝");
}
},
},
{
title: "店铺名称",
key: "storeName",
minWidth: 100,
tooltip: true,
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 150,
render: (h, params) => {
if (params.row.marketEnable == "DOWN") {
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.upper(params.row);
},
},
},
"上架"
),
h(
"Button",
{
props: {
size: "small",
},
on: {
click: () => {
this.showDetail(params.row);
},
},
},
"查看"
),
]);
} else {
return h("div", [
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.edit(params.row);
},
},
},
"下架"
),
h(
"Button",
{
props: {
size: "small",
},
on: {
click: () => {
this.showDetail(params.row);
},
},
},
"查看"
),
]);
}
},
},
{ colKey: "row-select", type: "multiple", width: 60, align: "center" },
{ title: "商品ID", colKey: "id", width: 260 },
{ title: "商品图片", colKey: "imageSlot", width: 180 },
{ title: "商品名称", colKey: "goodsSlot", width: 180 },
{ title: "价格", colKey: "price", width: 100, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }) },
{ title: "销量", colKey: "buyCount", width: 100 },
{ title: "库存", colKey: "quantity", width: 100 },
{ title: "店铺名称", colKey: "storeName", width: 180 },
{ title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
currentStatus: '',
goodsNumerData: {},
goodsAuditForm: {
// 商品编辑表单
auth_flag: 1,
},
selectedRows: [], // 选中的行数据
selectAll: false, // 全选状态
batchAuditModalVisible: false, // 批量审核弹框显示状态
batchAuditForm: {
auth_flag: 1,
reason: ''
},
};
},
computed: {
goodsStatusWithCount() {
return [
{title: '全部', value: ''},
{title: `出售中${this.goodsNumerData.upperGoodsNum ? '(' + this.goodsNumerData.upperGoodsNum + ')' : ''}`, value: 'UPPER'},
{title: `仓库中${this.goodsNumerData.downGoodsNum ? '(' + this.goodsNumerData.downGoodsNum + ')' : ''}`, value: 'DOWN'},
{title: `待审核${this.goodsNumerData.auditGoodsNum ? '(' + this.goodsNumerData.auditGoodsNum + ')' : ''}`, value: 'TOBEAUDITED'},
{title: `审核未通过${this.goodsNumerData.refuseGoodsNum ? '(' + this.goodsNumerData.refuseGoodsNum + ')' : ''}`, value: 'REFUSE'}
];
}
},
methods: {
// 初始化数据
init() {
this.getDataList();
this.getNumberData();
},
// 分页 改变页码
changePage(v) {
@@ -363,11 +225,42 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
this.getNumberData();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "create_time",
order: "desc",
goodsName: "",
id: "",
storeName: "",
salesModel: "",
goodsType: "",
goodsStatus: "",
};
this.currentStatus = '';
this.selectedRows = [];
this.selectedRowKeys = [];
if (this.$refs.table) {
this.$refs.table.selectAll(false);
}
this.getDataList();
this.getNumberData();
},
// 获取数据
getDataList() {
@@ -380,6 +273,15 @@ export default {
}
});
},
getNumberData() {
// 创建一个不包含goodsStatus字段的搜索参数
const { goodsStatus, ...searchParams } = this.searchForm;
getGoodsNumerData(searchParams).then((res) => {
if (res.success) {
this.goodsNumerData = res.result;
}
})
},
// 编辑
edit(v) {
this.id = v.id;
@@ -392,27 +294,33 @@ export default {
},
// 下架
lower() {
lowGoods(this.id, this.underForm).then((res) => {
this.$Modal.remove();
let params = {
goodsId: this.id,
reason:this.underForm.reason
};
lowGoods(params).then((res) => {
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.modalVisible = false;
this.getDataList();
this.getNumberData();
}
});
},
// 商家
// 上架
upper(v) {
this.$Modal.confirm({
title: "确认上架",
const dlg = DialogPlugin.confirm({
header: "确认上架",
content: "您确认要上架 " + v.goodsName + " ?",
loading: true,
onOk: () => {
upGoods(v.id).then((res) => {
this.$Modal.remove();
theme: "warning",
onConfirm: () => {
dlg.hide();
const params = { goodsId: v.id };
upGoods(params).then((res) => {
if (res.success) {
this.$Message.success("上架成功");
MessagePlugin.success("上架成功");
this.getDataList();
this.getNumberData();
}
});
},
@@ -427,9 +335,225 @@ export default {
query: { id: id },
})
},
// 商品状态筛选
goodsStatusClick(item) {
// 根据选择的状态设置搜索条件
if (item === 0) {
// 全部:清除状态筛选
delete this.searchForm.goodsStatus;
} else {
// 其他状态正常赋值
this.searchForm.goodsStatus = item;
}
this.currentStatus = item;
// tab切换时清除选中内容
this.selectedRows = [];
if (this.$refs.table) {
this.$refs.table.selectAll(false);
}
this.getDataList();
},
examine(v, authFlag) {
// 审核商品
let examine = "通过";
this.goodsAuditForm.authFlag = "PASS";
if (authFlag != 1) {
examine = "拒绝";
this.goodsAuditForm.authFlag = "REFUSE";
}
const dlg = DialogPlugin.confirm({
header: "确认审核",
content: "您确认要审核" + examine + " " + v.goodsName + " ?",
theme: "warning",
onConfirm: () => {
dlg.hide();
this.goodsAuditForm.goodsIds = v.id;
const formData = new FormData();
formData.append('goodsIds', v.id);
formData.append('authFlag', this.goodsAuditForm.authFlag);
authGoods(formData).then((res) => {
if (res.success) {
MessagePlugin.success("审核成功");
this.getDataList();
this.getNumberData();
}
});
},
});
},
// 打开审核弹框
openAuditModal(goods) {
this.currentAuditGoods = goods;
this.goodsAuditForm.auth_flag = 1;
this.goodsAuditForm.reason = '';
this.auditModalVisible = true;
},
// 确认审核(二次确认)
confirmAudit() {
const auditText = this.goodsAuditForm.auth_flag === 1 ? '通过' : '拒绝';
const dlg = DialogPlugin.confirm({
header: '确认审核',
content: `您确认要审核${auditText} "${this.currentAuditGoods.goodsName}" 吗?`,
theme: 'warning',
onConfirm: () => {
dlg.hide();
this.submitAudit();
},
});
},
// 提交审核
submitAudit() {
let formData = new FormData();
formData.append('goodsIds', this.currentAuditGoods.id);
formData.append('authFlag', this.goodsAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
authGoods(formData).then((res) => {
if (res.success) {
MessagePlugin.success('审核成功');
this.auditModalVisible = false;
this.getDataList();
this.getNumberData();
}
});
},
// 选择框事件处理
onTSelectChange(keys, { selectedRowData }) {
this.selectedRowKeys = keys;
this.selectedRows = selectedRowData || [];
},
// 批量上架
batchUpper() {
if (this.selectedRows.length === 0) {
this.$Message.warning('请先选择要上架的商品');
return;
}
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
DialogPlugin.confirm({
header: '确认批量上架',
content: `您确认要上架以下商品吗?\n${goodsNames}`,
theme: 'warning',
onConfirm: () => {
const goodsIds = this.selectedRows.map(item => item.id);
const params = { goodsId: goodsIds };
upGoods(params).then((res) => {
if (res.success) {
MessagePlugin.success('批量上架成功');
this.selectedRows = [];
this.selectedRowKeys = [];
this.selectAll = false;
this.getDataList();
this.getNumberData();
}
});
}
});
},
// 批量下架
batchLower() {
if (this.selectedRows.length === 0) {
this.$Message.warning('请先选择要下架的商品');
return;
}
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
DialogPlugin.confirm({
header: '确认批量下架',
content: `您确认要下架以下商品吗?\n${goodsNames}`,
theme: 'warning',
onConfirm: () => {
const goodsIds = this.selectedRows.map(item => item.id);
const params = { goodsId: goodsIds, reason: '批量下架操作' };
lowGoods(params).then((res) => {
if (res.success) {
MessagePlugin.success('批量下架成功');
this.selectedRows = [];
this.selectedRowKeys = [];
this.selectAll = false;
this.getDataList();
this.getNumberData();
}
});
}
});
},
// 批量审核
batchAudit() {
if (this.selectedRows.length === 0) {
MessagePlugin.warning('请先选择要审核的商品');
return;
}
// 重置批量审核表单
this.batchAuditForm = {
auth_flag: 1,
reason: ''
};
this.batchAuditModalVisible = true;
},
// 提交批量审核
submitBatchAudit() {
if (this.selectedRows.length === 0) {
MessagePlugin.warning('请先选择要审核的商品');
return;
}
// 如果是拒绝审核,必须填写原因
if (this.batchAuditForm.auth_flag === 2 && !this.batchAuditForm.reason.trim()) {
MessagePlugin.warning('审核拒绝时必须填写拒绝原因');
return;
}
const actionText = this.batchAuditForm.auth_flag === 1 ? '通过' : '拒绝';
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
const dlg = DialogPlugin.confirm({
header: `确认批量审核${actionText}`,
content: `您确认要${actionText}以下商品的审核吗?\n${goodsNames}`,
theme: 'warning',
onConfirm: () => {
dlg.hide();
const goodsIds = this.selectedRows.map(item => item.id);
const formData = new FormData();
formData.append('goodsId', goodsIds);
formData.append('authFlag', this.batchAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
formData.append('reason', this.batchAuditForm.reason || '');
authGoods(formData).then((res) => {
if (res.success) {
MessagePlugin.success(`批量审核${actionText}成功`);
this.selectedRows = [];
this.selectedRowKeys = [];
this.selectAll = false;
this.batchAuditModalVisible = false;
this.getDataList();
this.getNumberData();
}
});
}
});
}
},
mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
// Tab组件样式
.goods-tab {
::v-deep .ivu-tabs-tab {
font-size: 14px;
}
}
</style>

View File

@@ -1,6 +1,12 @@
<template>
<div class="search">
<Card>
<Tabs v-model="activeStatus" @change="onStatusTabChange" style="margin-bottom: 12px">
<TabPane label="全部" name="ALL" />
<TabPane label="待审核" name="TOBEAUDITED" />
<TabPane label="审核通过" name="PASS" />
<TabPane label="审核拒绝" name="REFUSE" />
</Tabs>
<Form
ref="searchForm"
@keydown.enter.native="handleSearch"
@@ -15,7 +21,7 @@
v-model="searchForm.goodsName"
placeholder="请输入商品名称"
clearable
style="width: 200px"
style="width: 240px"
/>
</Form-item>
<Form-item label="商品编号" prop="id">
@@ -24,13 +30,16 @@
v-model="searchForm.id"
placeholder="请输入商品编号"
clearable
style="width: 200px"
style="width: 240px"
/>
</Form-item>
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search"
>搜索</Button
>
<Button @click="handleSearch" class="search-btn" type="primary">
<template #icon><t-icon name="search" /></template>
搜索
</Button>
</Form>
</Card>
<Card>
<Table
:loading="loading"
border
@@ -64,7 +73,7 @@
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
:page-size-opts="[20, 50, 100]"
size="small"
show-total
show-elevator
@@ -85,10 +94,11 @@ export default {
return {
id: "", //要操作的id
loading: true, // 表单加载状态
activeStatus: 'ALL',
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "create_time", // 默认排序字段
order: "desc", // 默认排序方式
},
@@ -100,7 +110,7 @@ export default {
{
title: "商品名称",
key: "goodsName",
minWidth: 180,
minWidth: 140,
slot: "goodsSlot",
tooltip: true,
},
@@ -169,13 +179,12 @@ export default {
render: (h, params) => {
return h("div", [
h(
"Button",
"a",
{
props: {
type: "success",
size: "small",
},
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
marginRight: "5px",
},
on: {
@@ -187,13 +196,17 @@ export default {
"通过"
),
h(
"Button",
"span",
{ style: { margin: "0 8px", color: "#dcdee2" } },
"|"
),
h(
"a",
{
props: {
type: "error",
size: "small",
},
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
marginRight: "5px",
},
on: {
@@ -205,11 +218,17 @@ export default {
"拒绝"
),
h(
"Button",
"span",
{ style: { margin: "0 8px", color: "#dcdee2" } },
"|"
),
h(
"a",
{
props: {
type: 'default',
size: "small",
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none"
},
on: {
click: () => {
@@ -245,14 +264,19 @@ export default {
handleSearch() {
// 搜索
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
onStatusTabChange(v){
this.activeStatus = v;
this.searchForm.pageNumber = 1;
this.getDataList();
},
getDataList() {
// 获取列表数据
this.loading = true;
// 带多条件搜索参数获取表单数据
this.searchForm.authFlag = 0;
this.searchForm.authFlag = this.activeStatus === 'ALL' ? 0 : this.activeStatus;
getAuthGoodsListData(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
@@ -274,7 +298,11 @@ export default {
content: "您确认要审核" + examine + " " + v.goodsName + " ?",
loading: true,
onOk: () => {
authGoods(v.id, this.goodsAuditForm).then((res) => {
let formData = new FormData();
formData.append('goodsIds', v.id);
formData.append('authFlag', this.goodsAuditForm.authFlag);
authGoods(formData).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("审核成功");

View File

@@ -1,144 +1,117 @@
<template>
<div>
<Form :label-width="120">
<Card>
<div class="base-info-item">
<h4>基本信息</h4>
<div class="form-item-view">
<FormItem label="商品分类">
<div class="search">
<t-card style="margin-bottom: 12px">
<div class="detail-section">
<div class="detail-title">基本信息</div>
<div class="detail-grid">
<div class="detail-row">
<div class="label">商品分类</div>
<div class="value">
<span v-for="(item, index) in goods.categoryName" :key="index">
{{ item }}
<i v-if="index !== goods.categoryName.length - 1">&gt;</i>
{{ item }}<i v-if="index !== goods.categoryName.length - 1"> &gt; </i>
</span>
</FormItem>
<FormItem label="商品名称">
{{ goods.goodsName }}
</FormItem>
</div>
</div>
<div class="detail-row">
<div class="label">商品名称</div>
<div class="value">{{ goods.goodsName }}</div>
</div>
<div class="detail-row">
<div class="label">商品卖点</div>
<div class="value">{{ goods.sellingPoint }}</div>
</div>
<div class="detail-row">
<div class="label">商品参数</div>
<div class="value">
<div v-if="goods.goodsParamsDTOList && goods.goodsParamsDTOList.length" v-for="(item,index) in goods.goodsParamsDTOList" :key="index" class="param-line">
<span class="param-group">{{ item.groupName }}</span>
<t-tag v-for="(child,i) in item.goodsParamsItemDTOList" :key="i" variant="light" style="margin-right: 8px">{{ child.paramName }} - {{ child.paramValue }}</t-tag>
</div>
</div>
</div>
</div>
</div>
</t-card>
<FormItem label="商品卖点">
{{ goods.sellingPoint }}
</FormItem>
<FormItem label="商品参数">
<div v-if="goods.goodsParamsDTOList && goods.goodsParamsDTOList.length" v-for="(item,index) in goods.goodsParamsDTOList" :key="index">
<div style="margin-bottom: 10px; display: flex; align-items: center;" >
{{ item.groupName }} : <tag v-for="(child,i) in item.goodsParamsItemDTOList" :key="i">
{{ child.paramName }} - {{ child.paramValue }}
</tag>
<t-card style="margin-bottom: 12px">
<div class="detail-section">
<div class="detail-title">商品交易信息</div>
<div class="detail-grid">
<div class="detail-row">
<div class="label">计量单位</div>
<div class="value">{{ goods.goodsUnit }}</div>
</div>
<div class="detail-row">
<div class="label">销售模式</div>
<div class="value">{{ goods.salesModel === 'RETAIL' ? '零售型' : '批发型' }}</div>
</div>
<div class="detail-row" v-if="goods.salesModel !== 'RETAIL'">
<div class="label">销售规则</div>
<div class="value full">
<t-table :columns="wholesalePreviewColumns" :data="wholesaleData" :rowKey="(row) => row._rowKey ? row._rowKey : ('wholesale-' + row.num + '-' + row.price)" size="small" bordered></t-table>
</div>
</div>
</FormItem>
</div>
<h4>商品交易信息</h4>
<div class="form-item-view">
<FormItem label="计量单位"> {{ goods.goodsUnit }}</FormItem>
<FormItem label="销售模式">
{{ goods.salesModel === "RETAIL" ? "零售型" : "批发型" }}
</FormItem>
<FormItem label="销售规则" v-if="goods.salesModel !== 'RETAIL'">
<Table
border
:columns="wholesalePreviewColumns"
:data="wholesaleData"
>
</Table>
</FormItem>
</div>
<h4>商品规格及图片</h4>
<div class="form-item-view">
<FormItem label="商品编号"> {{ goods.id }}</FormItem>
<FormItem label="商品价格">
<priceColorScheme :value="goods.price" :color="$mainColor"></priceColorScheme>
</t-card>
</FormItem>
<FormItem label="商品图片">
<div
class="demo-upload-list"
v-for="(item, __index) in goods.goodsGalleryList"
:key="__index"
>
<img :src="item" />
<div class="demo-upload-list-cover">
<Icon
type="ios-eye-outline"
@click.native="handleViewGoodsPicture(item)"
></Icon>
<t-card style="margin-bottom: 12px">
<div class="detail-section">
<div class="detail-title">商品规格及图片</div>
<div class="detail-grid">
<div class="detail-row">
<div class="label">商品编号</div>
<div class="value">{{ goods.id }}</div>
</div>
<Modal title="View Image" v-model="goodsPictureVisible">
<img
:src="previewGoodsPicture"
v-if="goodsPictureVisible"
style="width: 100%"
/>
</Modal>
<div class="detail-row">
<div class="label">商品价格</div>
<div class="value"><priceColorScheme :value="goods.price" :color="$mainColor" /></div>
</div>
</FormItem>
<FormItem label="商品视频">
<video
v-if="goods.goodsVideo"
controls
class="player"
:src="goods.goodsVideo"
/>
</FormItem>
<FormItem label="商品规格">
<Table :columns="skuColumn" :data="skuData">
<template slot="showImage" slot-scope="scope">
<div style="margin-top: 5px; display: flex">
<div>
<img
v-for="(item,index) in scope.row.image"
:key="index"
:src="item"
style="height: 60px; margin:10px; width: 60px"
/>
<div class="detail-row">
<div class="label">商品图片</div>
<div class="value">
<div class="gallery">
<div class="demo-upload-list" v-for="(item, __index) in goods.goodsGalleryList" :key="__index">
<img :src="item" @click="handleViewGoodsPicture(item)" />
</div>
</div>
</template>
<template slot-scope="{ row }" slot="wholePrice0">
<Input
v-if="wholesaleData[0]"
clearable
disabled
v-model="wholesaleData[0].price"
>
<span slot="append"></span>
</Input>
</template>
<template slot-scope="{ row }" slot="wholePrice1">
<Input
v-if="wholesaleData[1]"
clearable
disabled
v-model="wholesaleData[1].price"
>
<span slot="append"></span>
</Input>
</template>
<template slot-scope="{ row }" slot="wholePrice2">
<Input
v-if="wholesaleData[2]"
clearable
disabled
v-model="wholesaleData[2].price"
>
<span slot="append"></span>
</Input>
</template>
</Table>
</FormItem>
</div>
<h4>商品详情描述</h4>
<div class="form-item-view">
<FormItem label="商品描述">
<div v-html="goods.intro"></div>
</FormItem>
<FormItem label="移动端描述">
<div v-html="goods.mobileIntro"></div>
</FormItem>
<t-dialog :visible="goodsPictureVisible" header="预览图片" :width="600" @close="goodsPictureVisible=false">
<img :src="previewGoodsPicture" v-if="goodsPictureVisible" style="width: 100%" />
</t-dialog>
</div>
</div>
</Card>
</Form>
<div class="detail-row" v-if="goods.goodsVideo">
<div class="label">商品视频</div>
<div class="value full">
<video controls class="player" :src="goods.goodsVideo" />
</div>
</div>
<div class="detail-row">
<div class="label">商品规格</div>
<div class="value full">
<t-table :columns="skuColumn" :data="skuData" :rowKey="(row) => row._rowKey ? row._rowKey : ('sku-' + row.sn + '-' + row.specs)" bordered>
</t-table>
</div>
</div>
</div>
</div>
</t-card>
<t-card>
<div class="detail-section">
<div class="detail-title">商品详情描述</div>
<div class="detail-grid">
<div class="detail-row">
<div class="label">商品描述</div>
<div class="value full"><div v-html="goods.intro"></div></div>
</div>
<div class="detail-row">
<div class="label">移动端描述</div>
<div class="value full"><div v-html="goods.mobileIntro"></div></div>
</div>
</div>
</div>
</t-card>
</div>
</template>
<script>
@@ -147,42 +120,23 @@ export default {
name: "goodsDetail",
data() {
return {
goods: {}, // 商品信息
previewGoodsPicture: "", // 预览图片
goodsPictureVisible: false, // 预览图片模态框
goods: {},
previewGoodsPicture: "",
goodsPictureVisible: false,
wholesalePreviewColumns: [
{
title: "销售规则",
width: 300,
render: (h, params) => {
let guide =
"当商品购买数量 ≥" +
params.row.num +
" 时,售价为 ¥" +
params.row.price +
" /" +
this.goods.goodsUnit;
return h("div", guide);
},
cell: (h, { row }) => h("div", "当商品购买数量 ≥" + row.num + " 时,售价为 ¥" + row.price + " /" + this.goods.goodsUnit),
},
],
wholesaleData: [],
skuColumn: [
// 规格表头
{
title: "规格",
key: "specs",
},
{
title: "编号",
key: "sn",
},
{
title: "重量(kg)",
key: "weight",
},
{ title: "规格", colKey: "specs" },
{ title: "编号", colKey: "sn" },
{ title: "重量(kg)", colKey: "weight" },
],
skuData: [], // sku数据
skuData: [],
};
},
mounted() {
@@ -193,52 +147,45 @@ export default {
initGoods(id) {
getGoodsDetail(id).then((res) => {
this.goods = res.result;
let that = this;
res.result.skuList.forEach(function (sku, index, array) {
that.skuData.push({
res.result.skuList.forEach((sku, index) => {
this.skuData.push({
specs: sku.goodsName,
sn: sku.sn,
weight: sku.weight,
cost: sku.cost,
price:sku.price,
price: sku.price,
image: sku.goodsGalleryList,
quantity:sku.quantity
quantity: sku.quantity,
_rowKey: sku.id ? ('sku-' + sku.id) : ('sku-' + sku.sn + '-' + index)
});
});
if (res.result.salesModel === "WHOLESALE" && res.result.wholesaleList) {
res.result.wholesaleList.forEach((item, index) => {
this.skuColumn.push({
title: "购买量 ≥ " + item.num,
slot: "wholePrice" + index,
colKey: "wholePrice" + index,
cell: (h) => h("div", (this.wholesaleData && this.wholesaleData[index] ? this.wholesaleData[index].price : "") + " 元"),
});
});
} else {
this.skuColumn.push(
// {
// title: "成本",
// key: "cost",
// render: (h, params) => {
// console.log(params)
// return h("priceColorScheme", {props:{value:params.row.cost,color:this.$mainColor}} );
// },
// },
{
this.skuColumn.push({
title: "价格",
key: "price",
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
},
},{
title: "库存",
key: "quantity",
}
);
colKey: "price",
cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }),
});
this.skuColumn.push({ title: "库存", colKey: "quantity" });
}
this.skuColumn.push({
title: "图片",
slot: "showImage",
colKey: "image",
cell: (h, { row }) => h("div", { style: { marginTop: "5px", display: "flex" } }, [
h("div", row.image && row.image.map((item, index) => h("img", { attrs: { src: item }, key: index, style: { height: "60px", margin: "10px", width: "60px" } })))
]),
});
this.wholesaleData = res.result.wholesaleList;
this.wholesaleData = (res.result.wholesaleList || []).map((item, idx) => ({
...item,
_rowKey: 'wholesale-' + item.num + '-' + item.price + '-' + idx
}));
});
},
// 预览商品图片
@@ -250,26 +197,40 @@ export default {
};
</script>
<style lang="scss" soped>
/*平铺*/
div.base-info-item {
h4 {
margin-bottom: 10px;
padding: 0 10px;
border: 1px solid #ddd;
background-color: #f8f8f8;
font-weight: bold;
color: #333;
font-size: 14px;
line-height: 40px;
text-align: left;
}
.form-item-view {
padding-left: 80px;
}
<style lang="scss" scoped>
.detail-section {
padding: 10px 0;
}
.detail-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 12px;
}
.detail-grid {
display: grid;
grid-template-columns: 280px 1fr;
grid-row-gap: 8px;
}
.detail-row {
display: contents;
}
.label {
color: #666;
padding-right: 12px;
}
.value {
color: #333;
}
.value.full {
grid-column: 1 / span 2;
}
.param-line {
margin-bottom: 8px;
}
.gallery {
display: flex;
flex-wrap: wrap;
}
.demo-upload-list {
display: inline-block;
width: 60px;
@@ -282,31 +243,16 @@ div.base-info-item {
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
margin-right: 4px;
margin-right: 8px;
margin-bottom: 8px;
}
.demo-upload-list img {
width: 100%;
height: 100%;
}
.demo-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
.demo-upload-list:hover .demo-upload-list-cover {
display: block;
}
.demo-upload-list-cover i {
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
.ivu-table table {
width: 100% !important;
.player {
width: 480px;
max-width: 100%;
}
</style>

View File

@@ -1,38 +1,39 @@
<template>
<div class="search">
<Card>
<Form ref="searchForm" @submit.native.prevent @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70"
class="search-form">
<Form-item label="品牌名称">
<Input type="text" v-model="searchForm.name" placeholder="请输入品牌名称" clearable style="width: 200px"/>
</Form-item>
<Button @click="handleSearch" type="primary">搜索</Button>
</Form>
<Row class="operation padding-row">
<Button @click="add" type="primary">添加</Button>
<Button @click="refresh">刷新</Button>
</Row>
<Table :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small"
show-total show-elevator show-sizer></Page>
</Row>
</Card>
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable="false" :width="500">
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
<FormItem label="品牌名称" prop="name">
<Input v-model="form.name" clearable style="width: 100%"/>
</FormItem>
<FormItem label="品牌图标" prop="logo">
<upload-pic-input v-model="form.logo" style="width: 100%"></upload-pic-input>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit">提交</Button>
<t-card style="margin-bottom: 12px">
<t-form ref="searchForm" :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="品牌名称" name="name">
<t-input v-model="searchForm.name" placeholder="请输入品牌名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="operation padding-row">
<t-button theme="primary" @click="add">添加</t-button>
</div>
</Modal>
<t-table :loading="loading" :columns="columns" :data="data" rowKey="id" size="small" />
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
<t-drawer :visible.sync="modalVisible" :header="modalTitle" placement="right" size="500px" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100" :rules="formValidate">
<t-form-item label="品牌名称" name="name">
<t-input v-model="form.name" style="width: 100%" />
</t-form-item>
<t-form-item label="品牌图标" name="logo">
<upload-pic-input v-model="form.logo" style="width: 100%"></upload-pic-input>
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-drawer>
</div>
</template>
@@ -46,7 +47,8 @@ import {
} from "@/api/goods";
import uploadPicInput from "@/components/lili/upload-pic-input";
import {regular} from "@/utils";
import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "brand",
@@ -62,7 +64,7 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "create_time", // 默认排序字段
order: "desc", // 默认排序方式
},
@@ -85,152 +87,21 @@ export default {
},
submitLoading: false, // 添加或编辑提交状态
columns: [
{
title: "品牌名称",
key: "name",
width: 200,
resizable: true,
sortable: false,
},
{
title: "品牌图标",
key: "logo",
align: "left",
render: (h, params) => {
return h("img", {
attrs: {
src: params.row.logo || '',
alt: "加载图片失败",
},
style: {
cursor: "pointer",
width: "80px",
height: "60px",
margin: "10px 0",
"object-fit": "contain",
},
});
},
},
{
title: "状态",
key: "deleteFlag",
align: "left",
render: (h, params) => {
if (params.row.deleteFlag == 0) {
return h("Tag", {props: {color: "green",},}, "启用");
} else if (params.row.deleteFlag == 1) {
return h("Tag", {props: {color: "volcano",},}, "禁用");
}
},
filters: [
{
label: "启用",
value: 0,
},
{
label: "禁用",
value: 1,
},
],
filterMultiple: false,
filterMethod(value, row) {
if (value == 0) {
return row.deleteFlag == 0;
} else if (value == 1) {
return row.deleteFlag == 1;
}
},
},
{
title: "操作",
key: "action",
width: 180,
align: "center",
fixed: "right",
render: (h, params) => {
let enableOrDisable = "";
if (params.row.deleteFlag == 0) {
enableOrDisable = h(
"Button",
{
props: {
size: "small",
type: "error",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.disable(params.row);
},
},
},
"禁用"
);
} else {
enableOrDisable = h(
"Button",
{
props: {
type: "success",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.enable(params.row);
},
},
},
"启用"
);
}
{ title: "品牌名称", colKey: "name", width: 200 },
{ title: "品牌图标", colKey: "logo", align: "left", cell: (h, { row }) => h("img", { attrs: { src: row.logo || '', alt: "加载图片失败" }, style: { cursor: "pointer", width: "48px", height: "36px", margin: "6px 0", objectFit: "contain" } }) },
{ title: "状态", colKey: "deleteFlag", align: "left", cell: (h, { row }) => row.deleteFlag == 0 ? h("t-tag", { props: { theme: "success", variant: "light" } }, "启用") : h("t-tag", { props: { theme: "warning", variant: "light" } }, "禁用") },
{ title: "操作", colKey: "action", width: 180, align: "center", fixed: "right", cell: (h, { row }) => {
const enableOrDisable = row.deleteFlag == 0
? h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "5px" }, on: { click: () => this.disable(row) } }, "禁用")
: h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "5px" }, on: { click: () => this.enable(row) } }, "启用");
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.edit(params.row);
},
},
},
"编辑"
),
h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "5px" }, on: { click: () => this.edit(row) } }, "编辑"),
h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"),
enableOrDisable,
h(
"Button",
{
props: {
type: 'default',
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.delBrand(params.row.id);
},
},
},
"删除"
),
h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"),
h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.confirmDel(row) } }, "删除"),
]);
},
},
} },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -239,13 +110,22 @@ export default {
methods: {
// 删除品牌
async delBrand(id) {
let res = await delBrand(id);
const res = await delBrand(id);
if (res.success) {
this.$Message.success("品牌删除成功!");
MessagePlugin.success("品牌删除成功!");
this.getDataList();
}
},
confirmDel(row) {
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除品牌 " + row.name + " ?",
theme: "warning",
onConfirm: () => {
this.delBrand(row.id);
},
});
},
// 初始化数据
init() {
this.getDataList();
@@ -260,10 +140,28 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "create_time",
order: "desc",
name: "",
};
this.getDataList();
},
// 获取数据
@@ -288,7 +186,7 @@ export default {
addBrand(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -298,7 +196,7 @@ export default {
updateBrand(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -311,24 +209,16 @@ export default {
add() {
this.modalType = 0;
this.modalTitle = "添加";
this.$refs.form.resetFields();
this.$refs.form.reset();
delete this.form.id;
this.modalVisible = true;
},
// 刷新
refresh() {
this.loading = true;
setTimeout(() => {
this.getDataList();
this.loading = false;
this.$Message.success("刷新成功");
}, 500);
},
// 编辑
edit(v) {
this.modalType = 1;
this.modalTitle = "编辑";
this.$refs.form.resetFields();
this.$refs.form.reset();
// 转换null为""
for (let attr in v) {
if (v[attr] === null) {
@@ -342,15 +232,14 @@ export default {
},
// 启用品牌
enable(v) {
this.$Modal.confirm({
title: "确认启用",
DialogPlugin.confirm({
header: "确认启用",
content: "您确认要启用品牌 " + v.name + " ?",
loading: true,
onOk: () => {
theme: "warning",
onConfirm: () => {
disableBrand(v.id, {disable: false}).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});
@@ -359,15 +248,14 @@ export default {
},
// 禁用
disable(v) {
this.$Modal.confirm({
title: "确认禁用",
DialogPlugin.confirm({
header: "确认禁用",
content: "您确认要禁用品牌 " + v.name + " ?",
loading: true,
onOk: () => {
theme: "warning",
onConfirm: () => {
disableBrand(v.id, {disable: true}).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});

View File

@@ -1,204 +1,84 @@
<template>
<div>
<Card>
<div class="mb_10">
<Button @click="addParent" icon="md-add">添加一级分类</Button>
<div class="search">
<t-card style="margin-bottom: 12px">
<div class="operation padding-row">
<t-button theme="primary" @click="addParent">添加一级分类</t-button>
</div>
<Table
update-show-children
class="table"
:load-data="handleLoadData"
row-key="id"
</t-card>
<t-card>
<t-enhanced-table
ref="tableRef"
:loading="loading"
rowKey="id"
:data="tableData"
:columns="columns"
>
<template slot="action" slot-scope="scope">
<Dropdown v-show="scope.row.level == 2" trigger="click">
<Button size="small">
绑定
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem @click.native="brandOperation(scope.row)"
>编辑绑定品牌</DropdownItem
>
<DropdownItem @click.native="specOperation(scope.row)"
>编辑绑定规格</DropdownItem
>
<DropdownItem @click.native="parameterOperation(scope.row)"
>编辑绑定参数</DropdownItem
>
</DropdownMenu>
</Dropdown>
&nbsp;
<Dropdown trigger="click">
<Button size="small">
操作
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem @click.native="edit(scope.row)">编辑</DropdownItem>
<DropdownItem
v-if="scope.row.deleteFlag == 1"
@click.native="enable(scope.row)"
>启用</DropdownItem
>
<DropdownItem
v-if="scope.row.deleteFlag == 0"
@click.native="disable(scope.row)"
>禁用</DropdownItem
>
<DropdownItem @click.native="remove(scope.row)">删除</DropdownItem>
</DropdownMenu>
</Dropdown>
&nbsp;
<Button
v-show="scope.row.level != 2"
type="primary"
@click="addChildren(scope.row)"
size="small"
icon="md-add"
style="margin-right: 5px"
>添加子分类
</Button>
</template>
<template slot="commissionRate" slot-scope="scope">
<priceColorScheme v-if="scope.row.commissionRate > 0" unit="" :color="$mainColor" :value="scope.row.commissionRate">%</priceColorScheme>
<priceColorScheme v-else :value="scope.row.commissionRate" unit="" >%</priceColorScheme>
<!-- {{ scope.row.commissionRate }}% -->
</template>
<template slot="deleteFlag" slot-scope="{ row }">
<Tag
:class="{ ml_10: row.deleteFlag }"
:color="row.deleteFlag == false ? 'success' : 'error'"
>
{{ row.deleteFlag == false ? "正常启用" : "禁用" }}</Tag
>
</template>
</Table>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="form" :model="formAdd" :label-width="100" :rules="formValidate">
<div v-if="showParent">
<FormItem label="上级分类" prop="parentId">
{{ parentTitle }}
<Input
v-model="formAdd.parentId"
clearable
style="width: 100%; display: none"
:tree="{ childrenKey: 'children', treeNodeColumnIndex: 0, indent: 24, expandTreeNodeOnClick: true }"
/>
</FormItem>
</div>
<FormItem label="层级" prop="level" style="display: none">
<Input v-model="formAdd.level" clearable style="width: 100%" />
</FormItem>
<FormItem label="分类名称" prop="name">
<Input v-model="formAdd.name" clearable style="width: 100%" />
</FormItem>
<FormItem label="分类图标" prop="image" v-if="formAdd.level !== 1">
<upload-pic-input
v-model="formAdd.image"
style="width: 100%"
></upload-pic-input>
</FormItem>
<FormItem label="排序值" prop="sortOrder" style="width: 345px">
<InputNumber v-model="formAdd.sortOrder"></InputNumber>
</FormItem>
<FormItem label="佣金比例(%)" prop="commissionRate" style="width: 345px">
<InputNumber :max="100" :min="0" v-model="formAdd.commissionRate"></InputNumber>
</FormItem>
<FormItem label="是否启用" prop="deleteFlag">
<i-switch
size="large"
v-model="formAdd.deleteFlag"
:true-value="false"
:false-value="true"
>
<span slot="open">启用</span>
<span slot="close">禁用</span>
</i-switch>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="Submit">提交</Button>
</div>
</Modal>
</t-card>
<Modal
:title="modalBrandTitle"
v-model="modalBrandVisible"
:mask-closable="false"
:width="500"
>
<Form ref="brandForm" :model="brandForm" :label-width="100">
<Select v-model="brandForm.categoryBrands" filterable multiple>
<Option v-for="item in brandWay" :value="item.id" :key="item.id">{{
item.name
}}</Option>
</Select>
</Form>
<div slot="footer">
<Button type="text" @click="modalBrandVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="saveCategoryBrand"
>提交</Button
>
<t-dialog :header="modalTitle" :visible="modalVisible" :width="500" :closeOnOverlayClick="false" @close="modalVisible = false">
<t-form ref="form" :data="formAdd" :labelWidth="100" :rules="formValidate">
<div v-if="showParent">
<t-form-item label="上级分类" name="parentId">
<div>{{ parentTitle }}</div>
<t-input v-model="formAdd.parentId" style="width: 100%; display: none" />
</t-form-item>
</div>
</Modal>
<t-form-item label="层级" name="level" style="display: none">
<t-input v-model="formAdd.level" />
</t-form-item>
<t-form-item label="分类名称" name="name">
<t-input v-model="formAdd.name" clearable />
</t-form-item>
<t-form-item label="分类图标" name="image" v-if="formAdd.level !== 1">
<upload-pic-input v-model="formAdd.image" />
</t-form-item>
<t-form-item label="排序值" name="sortOrder">
<t-input-number v-model="formAdd.sortOrder" />
</t-form-item>
<t-form-item label="佣金比例(%)" name="commissionRate">
<t-input-number :max="100" :min="0" v-model="formAdd.commissionRate" />
</t-form-item>
<t-form-item label="是否启用" name="deleteFlag">
<t-switch v-model="formAdd.deleteFlag" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="Submit">提交</t-button>
</template>
</t-dialog>
<t-dialog :header="modalBrandTitle" :visible="modalBrandVisible" :width="500" :closeOnOverlayClick="false" @close="modalBrandVisible = false">
<t-form ref="brandForm" :data="brandForm" :labelWidth="100">
<t-select v-model="brandForm.categoryBrands" filterable multiple>
<t-option v-for="item in brandWay" :value="item.id" :key="item.id" :label="item.name" />
</t-select>
</t-form>
<template #footer>
<t-button variant="text" @click="modalBrandVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="saveCategoryBrand">提交</t-button>
</template>
</t-dialog>
<Modal
:title="modalSpecTitle"
v-model="modalSpecVisible"
:mask-closable="false"
:width="500"
>
<Form ref="specForm" :model="specForm" :label-width="100">
<Select v-model="specForm.categorySpecs" multiple>
<Option
v-for="item in specifications"
:value="item.id"
:key="item.id"
:label="item.specName"
>
</Option>
</Select>
</Form>
<div slot="footer">
<Button type="text" @click="modalSpecVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="saveCategorySpec"
>提交</Button
>
</div>
</Modal>
</Card>
</div>
</template>
<script>
import {
delCategory,
disableCategory,
getBrandListData,
getCategoryBrandListData,
getCategorySpecListData,
getCategoryTree,
getSpecificationList,
insertCategory,
saveCategoryBrand,
saveCategorySpec,
updateCategory,
delCategory,
disableCategory,
getBrandListData,
getCategoryBrandListData,
getCategoryTree,
insertCategory,
saveCategoryBrand,
updateCategory,
} from "@/api/goods";
import uploadPicInput from "@/components/lili/upload-pic-input";
import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "goods-category",
components: {
@@ -206,23 +86,18 @@ export default {
},
data() {
return {
recordLevel:[], // 记录当前层级
submitLoading: false, //加载状态
submitLoading: false,
categoryList: [], // 分类列表
loading: false, // 加载状态
brands: [], //品牌集合
specifications: [], //规格集合
categoryId: "", // 分类id
categorySpecs: [], //已经选择的规格
modalType: 0, // 添加或编辑标识
modalVisible: false, // 添加或编辑显示
modalBrandVisible: false, //品牌关联编辑显示
modalSpecVisible: false, //品牌关联编辑显示
modalTitle: "", // 添加或编辑标题
showParent: false, // 是否展示上级菜单
parentTitle: "", // 父级菜单名称
modalBrandTitle: "", // 品牌弹窗标题
modalSpecTitle: "", // 规格弹窗标题
formAdd: {
// 添加或编辑表单对象初始化数据
parentId: "",
@@ -237,7 +112,6 @@ export default {
categoryBrands: [],
},
brandWay: "", //请求绑定品牌的信息
specForm: {}, // 规格数据
// 表单验证规则
formValidate: {
commissionRate: [regular.REQUIRED, regular.INTEGER],
@@ -245,38 +119,43 @@ export default {
sortOrder: [regular.REQUIRED, regular.INTEGER],
},
columns: [
{
title: "分类名称",
key: "name",
tree: true,
},
{
title: "状态",
slot: "deleteFlag",
},
{
title: "佣金",
key: "commissionRate",
slot: "commissionRate",
},
{
title: "操作",
key: "action",
slot: "action",
},
{ title: "分类名称", colKey: "name", minWidth: 180 },
{ title: "状态", colKey: "deleteFlag", width: 120, cell: (h, { row }) => h("t-tag", { props: { theme: row.deleteFlag ? "danger" : "success", variant: "light" } }, row.deleteFlag ? "禁用" : "正常启用") },
{ title: "佣金", colKey: "commissionRate", width: 120, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.commissionRate, color: this.$mainColor, unit: "" } }, "%") },
{ title: "操作", colKey: "action", align: "left", width: 460, fixed: "right", cell: (h, { row }) => {
const links = [];
if (row.level == 2) {
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.brandOperation(row) } }, "编辑绑定品牌"));
links.push(h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"));
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.parameterOperation(row) } }, "编辑绑定参数"));
links.push(h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"));
}
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.edit(row) } }, "编辑"));
links.push(h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"));
if (row.deleteFlag == 1) {
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.enable(row) } }, "启用"));
} else {
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.disable(row) } }, "禁用"));
}
if (row.level != 2) {
links.push(h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"));
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.addChildren(row) } }, "添加子分类"));
}
links.push(h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"));
links.push(h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => this.remove(row) } }, "删除"));
return h("div", links);
} },
],
tableData: [], // 表格数据
checkedCategoryChildren: "", //选中的分类子级
expandedTreeNodes: [],
};
},
methods: {
// 初始化数据
init() {
this.getAllList(0);
this.getAllList();
this.getBrandList();
this.getSpecList();
},
//获取所有品牌
getBrandList() {
@@ -284,14 +163,6 @@ export default {
this.brandWay = res;
});
},
//获取所有规格
getSpecList() {
getSpecificationList().then((res) => {
if (res.length != 0) {
this.specifications = res.result;
}
});
},
//弹出品牌关联框
brandOperation(v) {
getCategoryBrandListData(v.id).then((res) => {
@@ -301,31 +172,12 @@ export default {
this.modalBrandVisible = true;
});
},
//弹出规格关联框
specOperation(v) {
getCategorySpecListData(v.id).then((res) => {
this.categoryId = v.id;
this.modalSpecTitle = "规格关联";
this.specForm.categorySpecs = res.map((item) => item.id);
this.modalSpecVisible = true;
});
},
//保存分类规格绑定
saveCategorySpec() {
saveCategorySpec(this.categoryId, this.specForm).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.modalSpecVisible = false;
}
});
},
//保存分类品牌绑定
saveCategoryBrand() {
saveCategoryBrand(this.categoryId, this.brandForm).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.modalBrandVisible = false;
}
});
@@ -367,7 +219,7 @@ export default {
this.modalTitle = "添加一级分类";
this.parentTitle = "顶级分类";
this.showParent = true;
this.$refs.form.resetFields();
this.$refs.form.reset();
delete this.formAdd.id;
this.formAdd.parentId = 0;
this.modalVisible = true;
@@ -383,10 +235,10 @@ export default {
insertCategory(this.formAdd).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("添加成功");
MessagePlugin.success("添加成功");
this.getAllList();
this.modalVisible = false;
this.$refs.form.resetFields();
this.$refs.form.reset();
}
});
} else {
@@ -394,10 +246,10 @@ export default {
updateCategory(this.formAdd).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("修改成功");
MessagePlugin.success("修改成功");
this.getAllList();
this.modalVisible = false;
this.$refs.form.resetFields();
this.$refs.form.reset();
}
});
}
@@ -406,16 +258,14 @@ export default {
},
// 删除分类
remove(v) {
this.$Modal.confirm({
title: "确认删除",
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除 " + v.name + " ?",
loading: true,
onOk: () => {
// 删除
theme: "warning",
onConfirm: () => {
delCategory(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getAllList();
}
});
@@ -424,44 +274,7 @@ export default {
},
// 异步手动加载分类名称
handleLoadData(item, callback) {
this.recordLevel[item.level] = item.id;
if (item.level == 0) {
let categoryList = JSON.parse(JSON.stringify(this.categoryList));
categoryList.forEach((val) => {
if (val.id == item.id) {
val.children.map((child) => {
child._loading = false;
child.children = [];
});
// 模拟加载
setTimeout(() => {
callback(val.children);
}, 100);
}
});
} else {
this.deepCategoryChildren(item.id, this.categoryList);
setTimeout(() => {
callback(this.checkedCategoryChildren);
}, 100);
}
},
// 通过递归children来实现手动加载数据
deepCategoryChildren(id, list) {
if (id != "0" && list.length != 0) {
for (let i = 0; i < list.length; i++) {
let item = list[i];
if (item.id == id) {
this.checkedCategoryChildren = item.children;
return;
} else {
this.deepCategoryChildren(id, item.children);
}
}
}
},
// 获取分类数据
getAllList() {
this.loading = true;
@@ -470,72 +283,49 @@ export default {
if (res.success) {
localStorage.setItem("category", JSON.stringify(res.result));
this.categoryList = JSON.parse(JSON.stringify(res.result));
this.tableData = res.result.map((item) => {
if(this.recordLevel[0] && item.id === this.recordLevel[0]) {
item._showChildren = true
// 继续判断第二层
if(this.recordLevel[1] && item.children){
item.children.map((child)=>{
if(this.recordLevel[1] && child.id === this.recordLevel[1]){
child._showChildren = true
}
})
}
}else{
if (item.children.length !== 0) {
item.children = [];
item._loading = false;
}
}
return item;
});
this.tableData = this.categoryList;
}
});
},
// 启用分类
enable(v) {
this.$Modal.confirm({
title: "确认启用",
DialogPlugin.confirm({
header: "确认启用",
content: "您是否要启用当前分类 " + v.name + " 及其子分类?",
loading: true,
okText: "是",
cancelText: "否",
onOk: () => {
theme: "warning",
onConfirm: () => {
disableCategory(v.id, { enableOperations: 0 }).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getAllList(0);
MessagePlugin.success("操作成功");
this.getAllList();
}
});
},
onCancel: () => {
this.getAllList(0);
this.getAllList();
},
});
},
// 禁用分类
disable(v) {
this.$Modal.confirm({
title: "确认禁用",
DialogPlugin.confirm({
header: "确认禁用",
content: "您是否要禁用当前分类 " + v.name + " 及其子分类?",
loading: true,
okText: "是",
cancelText: "否",
onOk: () => {
theme: "warning",
onConfirm: () => {
disableCategory(v.id, { enableOperations: true }).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getAllList(0);
MessagePlugin.success("操作成功");
this.getAllList();
}
});
},
onCancel: () => {
this.getAllList(0);
this.getAllList();
},
});
},
},
mounted() {
this.init();
@@ -543,11 +333,21 @@ export default {
};
</script>
<style lang="scss" scoped>
/deep/ .ivu-table-wrapper {
::v-deep .ivu-table-wrapper {
overflow: auto;
}
.table {
min-height: 100vh;
height: auto;
}
.ops-link {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops-sep {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
</style>

View File

@@ -17,20 +17,16 @@
<Icon type="ios-film-outline"></Icon>&nbsp;{{ group.groupName }}
</p>
<p slot="extra">
<Dropdown slot="extra">
<t-dropdown slot="extra">
<a href="javascript:void(0)">
操作
<Icon type="ios-arrow-down"></Icon>
</a>
<Dropdown-menu slot="list">
<Dropdown-item @click.native="handleEditParamsGroup(group)"
>编辑</Dropdown-item
>
<Dropdown-item @click.native="handleDeleteParamGroup(group)"
>删除</Dropdown-item
>
</Dropdown-menu>
</Dropdown>
<t-dropdown-menu>
<t-dropdown-item @click="handleEditParamsGroup(group)">编辑</t-dropdown-item>
<t-dropdown-item @click="handleDeleteParamGroup(group)">删除</t-dropdown-item>
</t-dropdown-menu>
</t-dropdown>
<Icon type="arrow-down-b"></Icon>
</p>
<template v-if="group.params && group.params.length > 0">

View File

@@ -4,10 +4,12 @@
<Form @submit.native.prevent @keydown.enter.native="handleSearch" ref="searchForm" :model="searchForm" inline :label-width="70"
class="search-form">
<Form-item label="规格名称" prop="specName">
<Input type="text" v-model="searchForm.specName" placeholder="请输入规格名称" clearable style="width: 200px" />
<Input type="text" v-model="searchForm.specName" placeholder="请输入规格名称" clearable style="width: 240px" />
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn">搜索</Button>
</Form>
</Card>
<Card>
<Row class="operation padding-row">
<Button @click="add" type="primary">添加</Button>
<Button @click="delAll">批量删除</Button>
@@ -17,7 +19,7 @@
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total show-elevator
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small" show-total show-elevator
show-sizer></Page>
</Row>
</Card>
@@ -59,7 +61,7 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "asc", // 默认排序方式
},
@@ -108,13 +110,12 @@ export default {
render: (h, params) => {
return h("div", [
h(
"Button",
"a",
{
props: {
type: "info",
size: "small",
},
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
marginRight: "5px",
},
on: {
@@ -126,11 +127,17 @@ export default {
"编辑"
),
h(
"Button",
"span",
{ style: { margin: "0 8px", color: "#dcdee2" } },
"|"
),
h(
"a",
{
props: {
type: "error",
size: "small",
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
@@ -170,14 +177,14 @@ export default {
//搜索参数
handleSearch () {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
//重置搜索参数
handleReset () {
this.$refs.searchForm.resetFields();
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
// 重新加载数据
this.getDataList();
},

View File

@@ -1,32 +1,32 @@
<template>
<div>
<Card>
<Row>
<Form ref="searchForm" :model="searchForm" @keydown.enter.native="handleSearch" @submit.native.prevent inline :label-width="70" class="search-form">
<Form-item label="会员名称" prop="memberName">
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 200px"/>
</Form-item>
<Button @click="handleSearch" type="primary" class="search-btn" icon="ios-search">搜索</Button>
</Form>
</Row>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10">
<!-- 页面展示 -->
<template slot="shopDisableSlot" slot-scope="scope">
<i-switch size="large" true-value="OPEN" false-value="CLOSE" v-model="scope.row.status"
@on-change="changeSwitch(scope.row)">
<span slot="open">展示</span>
<span slot="close">隐藏</span>
</i-switch>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]"
size="small" show-total show-elevator show-sizer></Page>
</Row>
</Card>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination
:current="searchForm.pageNumber"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
:showJumper="true"
@change="onPaginationChange"
/>
</div>
</t-card>
<!-- 评价详情 -->
<Modal v-model="infoFlag" width="800" :title="infoTitle">
<t-drawer :visible="infoFlag" :header="infoTitle" placement="right" size="800px" @close="infoFlag = false">
<div class="info-list" style="overflow: hidden">
<div class="left-container">
@@ -35,11 +35,8 @@
</div>
<div class="show">
<label>页面展示</label>
<i-switch size="large" true-value="OPEN" false-value="CLOSE" v-model="infoData.status"
@on-change="changeSwitchView" style="margin-top: 3px">
<span slot="open">展示</span>
<span slot="close">隐藏</span>
</i-switch>
<t-switch size="large" :customValue="['OPEN','CLOSE']" :label="['展示','隐藏']" v-model="infoData.status"
@change="changeSwitchView" style="margin-top: 3px" />
</div>
</div>
<div class="right-container">
@@ -50,29 +47,34 @@
</div>
<div class="border-b">
<List>
<ListItem>
<ListItemMeta :avatar="infoData.memberProfile" :title="infoData.memberName"
:description="infoData.content"/>
</ListItem>
<t-list>
<t-list-item>
<div style="display: flex; align-items: flex-start">
<t-avatar :image="infoData.memberProfile" size="48px" />
<div style="margin-left: 12px">
<div>{{ infoData.memberName }}</div>
<div style="color: #666">{{ infoData.content }}</div>
</div>
</div>
</t-list-item>
<t-list-item>
<div class="score-content">
<span>物流评分{{infoData.deliveryScore}}</span>
<span>服务评分{{infoData.serviceScore}}</span>
<span>描述评分{{infoData.descriptionScore}}</span>
</div>
<div class="" v-if="infoData.haveImage">
评价图
</t-list-item>
<t-list-item v-if="infoData.haveImage">
<div>评价图</div>
<div style="margin-left: 40px">
<template v-if="infoData.images && infoData.images.length">
<img style="width: 100px;height: 110px;margin-left: 2px"
v-for="(img,index) in infoData.images.split(',')" :src="img"
alt="" :key="index"/>
</template>
</div>
</div>
</List>
</t-list-item>
</t-list>
</div>
<div class="border-b" v-if="infoData.reply">
<div>
@@ -92,113 +94,127 @@
</div>
</div>
</div>
</Modal>
<div slot="footer" style="display: flex; justify-content: flex-start">
<t-button theme="primary" @click="infoFlag = false">返回</t-button>
</div>
</t-drawer>
</div>
</template>
<script>
import * as API_Member from "@/api/member";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "goods-review", // 会员评价
data() {
return {
infoData: {}, // 商品信息
infoData: { status: 'CLOSE' }, // 商品信息
infoFlag: false, // 评价展示
infoTitle: "", // modal名称
loading: true, // 表单加载状态
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
memberName: "",
},
columns: [
// 表头
{
title: "商品名称",
key: "goodsName",
colKey: "goodsName",
minWidth: 120,
align: "left",
tooltip: true,
},
{
title: "会员名称",
key: "memberName",
colKey: "memberName",
minWidth: 120,
align: "left",
tooltip: true,
},
{
title: "评价",
key: "grade",
colKey: "grade",
align: "left",
width: 90,
render: (h, params) => {
if (params.row.grade == "GOOD") {
return h("Tag", {props: {color: "green",},}, "好评");
} else if (params.row.grade == "MODERATE") {
return h("Tag", {props: {color: "orange",},}, "中评");
minWidth: 90,
cell: (h, params) => {
const grade = params.row.grade;
if (grade === "GOOD") {
return h("t-tag", { props: { theme: "success", variant: "light", size: "small" } }, ["好评"]);
} else if (grade === "MODERATE") {
return h("t-tag", { props: { theme: "warning", variant: "light", size: "small" } }, ["中评"]);
} else {
return h("Tag", {props: {color: "red",},}, "差评");
return h("t-tag", { props: { theme: "danger", variant: "light", size: "small" } }, ["差评"]);
}
}
},
{
title: "物流评分",
key: "deliveryScore",
render: (h, params) => {
return h('div',params.row.deliveryScore || 5 + '星')
colKey: "deliveryScore",
minWidth: 100,
cell: (h, params) => {
const val = params.row.deliveryScore || 5;
return h("div", val + "星");
},
},
{
title: "服务评分",
key: "deliveryScore",
render: (h, params) => {
return h('div',params.row.serviceScore || 5 + '星')
colKey: "serviceScore",
minWidth: 100,
cell: (h, params) => {
const val = params.row.serviceScore || 5;
return h("div", val + "星");
},
},
{
title: "描述评分",
key: "deliveryScore",
render: (h, params) => {
return h('div',params.row.descriptionScore || 5 + '星')
colKey: "descriptionScore",
minWidth: 100,
cell: (h, params) => {
const val = params.row.descriptionScore || 5;
return h("div", val + "星");
},
},
{
title: "评价时间",
key: "createTime",
colKey: "createTime",
align: "left",
width: 170
},
{
title: "页面展示",
key: "shopDisable",
colKey: "shopDisable",
align: "left",
width: 100,
slot: "shopDisableSlot",
minWidth: 100,
cell: (h, params) => {
return h("t-switch", {
props: { size: "large", value: params.row.status, customValue: ["OPEN", "CLOSE"], label: ["", ""] },
on: { change: (val) => { params.row.status = val; this.changeSwitch(params.row); } }
});
},
},
{
title: "操作",
key: "action",
colKey: "action",
width: 150,
align: "center",
fixed: "right",
render: (h, params) => {
return h("div", [
cell: (h, params) => {
return h("div", { class: "ops" }, [
h(
"Button",
"a",
{
props: {
size: "small",
type: "info",
},
style: {
marginRight: "5px",
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
@@ -209,23 +225,39 @@ export default {
"查看"
),
h(
"Button",
"span",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
margin: "0 8px",
color: "#dcdee2",
},
},
"|"
),
h(
"t-popconfirm",
{
props: { content: "确认删除" },
on: {
click: () => {
confirm: () => {
this.remove(params.row);
},
},
},
[
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
},
"删除"
),
]
),
]);
},
},
@@ -240,7 +272,7 @@ export default {
let status = val;
API_Member.updateMemberReview(this.infoData.id, {status}).then(
(res) => {
this.$Message.success("修改成功!");
MessagePlugin.success("修改成功!");
this.init();
}
);
@@ -249,21 +281,37 @@ export default {
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
this.clearSelectAll();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== 'undefined' && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize)
}
if (info && typeof info.current !== 'undefined') {
this.changePage(info.current)
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
handleReset() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.memberName = "";
this.searchForm.sort = "createTime";
this.searchForm.order = "desc";
this.searchForm.startDate = "";
this.searchForm.endDate = "";
this.getDataList();
},
//列表直接选择页面是否展示
@@ -279,7 +327,16 @@ export default {
API_Member.getMemberReview(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
const list = Array.isArray(res.result && res.result.records) ? res.result.records : [];
list.forEach((e) => {
const s = e && e.status;
if (s === 'OPEN' || s === 'CLOSE') {
e.status = s;
} else {
e.status = s ? 'OPEN' : 'CLOSE';
}
});
this.data = list;
this.total = res.result.total;
}
});
@@ -292,25 +349,24 @@ export default {
this.infoTitle = `用户${v.memberName}的评价详情`;
API_Member.getMemberInfoReview(v.id).then((res) => {
if (res.result) {
this.infoData = res.result;
const data = res.result || {};
const s = data.status;
data.status = (s === 'OPEN' || s === 'CLOSE') ? s : (s ? 'OPEN' : 'CLOSE');
this.infoData = data;
}
});
},
// 删除评论
remove(v) {
this.$Modal.confirm({
title: "确认删除",
content: "您确认要删除会员" + v.memberName + "的评论?",
loading: true,
onOk: () => {
API_Member.delMemberReview(v.id).then((res) => {
this.$Modal.remove();
this.$Message.success("修改成功");
if (res && res.success) {
MessagePlugin.success("删除成功");
} else {
MessagePlugin.warning("删除失败");
}
this.init();
});
},
});
},
},
mounted() {
this.init();
@@ -370,4 +426,14 @@ label {
margin: 5px 0;
span{margin-right: 20px;}
}
.ops a {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops span {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
</style>

View File

@@ -10,7 +10,7 @@ h4 {
margin: 20px 0;
font-size: 18px;
}
/deep/ .ivu-icon {
::v-deep .ivu-icon {
margin-left: 40px;
margin-right: 40px;
}

View File

@@ -1,8 +1,6 @@
<template>
<div>
<!-- 统计 -->
<div class="card">
<h4>基本信息</h4>
<t-card class="card" title="基本信息">
<div class="count-list flex">
<div class="count-item" @click="navigateTo('managerGoods')">
<div>
@@ -41,11 +39,9 @@
</div>
</div>
</div>
</div>
</t-card>
<!-- 今日待办 -->
<div class="card">
<h4>今日待办</h4>
<t-card class="card" title="今日待办">
<div class="todo-list flex">
<div class="todo-item" @click="navigateTo('applyGoods')">
<div class="counts">{{ $store.state.notices.goods || 0 }}</div>
@@ -64,9 +60,7 @@
<div>待审核售后</div>
</div>
<div class="todo-item">
<div class="counts">
{{ $store.state.notices.distributionCash || 0 }}
</div>
<div class="counts">{{ $store.state.notices.distributionCash || 0 }}</div>
<div>待审核分销提现</div>
</div>
<div class="todo-item" @click="navigateTo('accountStatementBill')">
@@ -74,10 +68,9 @@
<div>待审核分账</div>
</div>
</div>
</div>
</t-card>
<!-- 今日流量概括 -->
<div class="card flow">
<t-card class="card flow" title="流量概括">
<div class="flow-list flex">
<div class="flow-item">
<div class="flow-member">
@@ -128,9 +121,7 @@
</div>
<div class="today-item">
<div>今日交易额</div>
<span v-if="homeData.todayOrderPrice"
>{{ homeData.todayOrderPrice | unitPrice }}</span
>
<span v-if="homeData.todayOrderPrice">{{ homeData.todayOrderPrice | unitPrice }}</span>
<span v-else>0.00</span>
</div>
<div class="today-item">
@@ -152,46 +143,27 @@
</div>
</div>
</div>
</div>
</t-card>
<!-- chart -->
<div class="card transform">
<div>
<h4>最近48小时在线人数整点为准</h4>
<t-card class="card transform" title="最近48小时在线人数整点为准">
<div id="historyMemberChart"></div>
</div>
</div>
<!-- chart -->
</t-card>
<div class="charts flex">
<div class="chart-item">
<h4>流量走势</h4>
<t-card class="chart-item" title="流量走势">
<div id="pvChart"></div>
</div>
<div class="chart-item">
<h4>交易趋势</h4>
</t-card>
<t-card class="chart-item" title="交易趋势">
<div id="orderChart"></div>
</div>
</t-card>
</div>
<!-- top10商品 -->
<div class="card transform">
<h4>热卖商品TOP10</h4>
<Table
stripe
:columns="tophotGoodsColumns"
:data="topHotGoodsData"
></Table>
</div>
<t-card class="card transform" title="热卖商品TOP10">
<t-table stripe :columns="tophotGoodsColumns" :data="topHotGoodsData" rowKey="goodsName" />
</t-card>
<!-- top10店铺 -->
<div class="card transform">
<h4>热卖店铺TOP10</h4>
<Table
stripe
:columns="tophotShopsColumns"
:data="topHotShopsData"
></Table>
</div>
<t-card class="card transform" title="热卖店铺TOP10">
<t-table stripe :columns="tophotShopsColumns" :data="topHotShopsData" rowKey="storeName" />
</t-card>
</div>
</template>
@@ -213,59 +185,17 @@ export default {
},
// 测试数据结束
tophotShopsColumns: [
// 表格表头
{
type: "index",
width: 100,
title: "排名",
align: "center",
},
{
title: "店铺名称",
key: "storeName",
},
{
title: "价格",
key: "price",
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
},
},
{
title: "销量",
key: "num",
width: 100,
sortable: true,
},
{ title: "排名", colKey: "index", width: 90, align: "center", cell: (h, { rowIndex }) => rowIndex + 1 },
{ title: "店铺名称", colKey: "storeName", minWidth: 140, tooltip: true },
{ title: "价格", colKey: "price", width: 120, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }) },
{ title: "销量", colKey: "num", width: 100 },
],
tophotGoodsColumns: [
{
type: "index",
width: 100,
title: "排名",
align: "center",
},
{
title: "商品名称",
key: "goodsName",
},
{
title: "价格",
key: "price",
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
},
},
{
title: "销量",
key: "num",
width: 100,
sortable: true,
},
{ title: "排名", colKey: "index", width: 90, align: "center", cell: (h, { rowIndex }) => rowIndex + 1 },
{ title: "商品名称", colKey: "goodsName", minWidth: 140, tooltip: true },
{ title: "价格", colKey: "price", width: 120, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }) },
{ title: "销量", colKey: "num", width: 100 },
],
topHotGoodsData: [], //热卖商品集合
topHotShopsData: [], //热卖店铺集合

View File

@@ -1,75 +1,58 @@
<template>
<div class="search">
<Card>
<Row class="operation padding-row">
<Button @click="add" type="primary">添加</Button>
</Row>
<Table
<t-card>
<div class="operation padding-row">
<t-button theme="primary" @click="add">添加</t-button>
</div>
<t-table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
rowKey="id"
>
<!-- 页面展示 -->
<template slot="disableSlot" slot-scope="{row}">
<i-switch size="large" :true-value="true" :false-value="false" :value="row.switch" @on-change="changeSwitch(row)">
<span slot="open">开启</span>
<span slot="close">禁用</span>
</i-switch>
<template #disableSlot="{ row }">
<t-switch :value="row.switch" @change="() => changeSwitch(row)" size="large" />
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
</t-table>
<div class="mt_10" style="display:flex;justify-content:flex-end">
<t-pagination
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="form" :model="form" :label-width="120" :rules="formValidate">
<FormItem label="物流公司名称" prop="name">
<Input v-model="form.name" clearable style="width: 100%"/>
</FormItem>
<FormItem label="物流公司代码" prop="code">
<Input v-model="form.code" clearable style="width: 100%"/>
</FormItem>
<FormItem label="支持电子面单">
<i-switch v-model="form.standBy" size="large">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
</FormItem>
<FormItem label="禁用状态" prop="disabled">
<i-switch true-value="OPEN" false-value="CLOSE" v-model="form.disabled" size="large">
<span slot="open">开启</span>
<span slot="close">禁用</span>
</i-switch>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交
</Button
>
showJumper
showPageSize
@change="paginationChange"
/>
</div>
</Modal>
</t-card>
<t-dialog
:header="modalTitle"
:visible="modalVisible"
:width="500"
:closeOnOverlayClick="false"
@close="modalVisible = false"
>
<t-form ref="form" :data="form" :labelWidth="120" :rules="formValidate">
<t-form-item label="物流公司名称" name="name">
<t-input v-model="form.name" clearable style="width: 100%" />
</t-form-item>
<t-form-item label="物流公司代码" name="code">
<t-input v-model="form.code" clearable style="width: 100%" />
</t-form-item>
<t-form-item label="支持电子面单">
<t-switch v-model="form.standBy" size="large" />
</t-form-item>
<t-form-item label="禁用状态" name="disabled">
<t-switch :value="form.disabled === 'OPEN'" @change="val => form.disabled = val ? 'OPEN' : 'CLOSE'" size="large" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -80,6 +63,7 @@
addLogistics,
delLogistics,
} from "@/api/logistics";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "logistics",
@@ -99,6 +83,7 @@
form: {
// 添加或编辑表单对象初始化数据
name: "",
code: "",
disabled:"CLOSE"
},
// 表单验证规则
@@ -110,73 +95,60 @@
trigger: "blur",
},
],
code: [
{
required: true,
message: "请输入物流公司代码",
trigger: "blur",
},
],
},
submitLoading: false, // 添加或编辑提交状态
columns: [
{
title: "物流公司名称",
key: "name",
colKey: "name",
minWidth: 120,
sortable: false,
},
{
title: "物流公司编码",
key: "code",
colKey: "code",
minWidth: 120,
sortable: false,
},
{
title: "状态",
key: "disabled",
colKey: "disabled",
width: 150,
slot: "disableSlot",
},
{
title: "创建时间",
key: "createTime",
colKey: "createTime",
width: 180,
sortable: false,
},
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
width: 150,
render: (h, params) => {
return h("div", [
h(
"Button",
"a",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "8px" },
on: { click: () => { this.detail(params.row); } },
},
"修改"
),
h(
"Button",
"a",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.remove(params.row);
},
},
style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" },
on: { click: () => { this.remove(params.row); } },
},
"删除"
),
@@ -193,14 +165,10 @@
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
// 分页
paginationChange(pageInfo) {
this.searchForm.pageNumber = pageInfo.current;
this.searchForm.pageSize = pageInfo.pageSize;
this.getDataList();
},
// 获取列表
@@ -209,19 +177,20 @@
getLogisticsPage(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
const data = res.result.records;
if (res && res.success) {
const result = res.result || {};
const data = Array.isArray(result.records) ? result.records : [];
data.forEach(e => {
e.switch = e.disabled === 'OPEN' ? true : false;
e.standBy = e.standBy == 'null' || !e.standBy ? false : true;
e.switch = e.disabled === 'OPEN';
e.standBy = e.standBy === 'null' || !e.standBy ? false : true;
});
this.data = data;
console.log(data)
this.total = res.result.total;
this.total = Number(result.total || data.length || 0);
} else {
this.data = [];
this.total = 0;
}
});
this.total = this.data.length;
this.loading = false;
}).catch(() => { this.loading = false; this.data = []; this.total = 0; });
},
// switch 切换状态
changeSwitch (v) {
@@ -232,49 +201,52 @@
this.form.disabled = v.disabled === 'CLOSE' ? 'OPEN' : 'CLOSE';
updateLogistics(v.id, this.form).then((res) => {
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});
},
// 确认提交
handleSubmit() {
this.$refs.form.validate((valid) => {
if (valid) {
const validateFn = this.$refs.form && this.$refs.form.validate;
if (!validateFn) { MessagePlugin.error("表单未初始化,请刷新页面后重试"); return; }
const done = () => {
this.submitLoading = true;
const onFinally = () => { this.submitLoading = false; };
if (this.modalTitle == "添加") {
// 添加 避免编辑后传入id等数据 记得删除
delete this.form.id;
addLogistics(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
onFinally();
if (res && res.success) {
MessagePlugin.success("添加成功");
this.getDataList();
this.modalVisible = false;
}
});
} else {
// 编辑
MessagePlugin.error((res && res.message) ? res.message : "添加失败,请稍后重试");
}
}).catch(() => { onFinally(); MessagePlugin.error("网络异常,请稍后再试"); });
} else {
updateLogistics(this.id, this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
onFinally();
if (res && res.success) {
MessagePlugin.success("修改成功");
this.getDataList();
this.modalVisible = false;
} else {
MessagePlugin.error((res && res.message) ? res.message : "修改失败,请稍后重试");
}
});
}).catch(() => { onFinally(); MessagePlugin.error("网络异常,请稍后再试"); });
}
}
});
};
const p = validateFn();
if (p && typeof p.then === "function") { p.then((valid) => { if (valid === true) { done(); } else { MessagePlugin.warning(valid && valid.firstError ? valid.firstError : "请完善必填信息后再提交"); } }); }
else { validateFn((valid) => { if (valid) { done(); } else { MessagePlugin.warning("请完善必填信息后再提交"); } }); }
},
// 添加信息
add() {
this.modalTitle = "添加";
this.form = {};
this.$refs.form.resetFields();
this.form = { name: "", code: "", standBy: false, disabled: "CLOSE" };
this.$refs.form && this.$refs.form.reset && this.$refs.form.reset();
this.modalVisible = true;
},
@@ -284,29 +256,25 @@
this.modalTitle = "修改";
this.modalVisible = true;
this.form.name = v.name;
this.form.code = v.code;
console.log(v)
this.form.standBy = v.standBy;
this.form.name = v.name || "";
this.form.code = v.code || "";
this.form.standBy = v.standBy === 'null' || !v.standBy ? false : true;
this.form.disabled = v.disabled
this.form.disabled = v.disabled || 'CLOSE'
},
// 删除物流公司
remove(v) {
this.$Modal.confirm({
title: "确认删除",
// 记得确认修改此处
DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除 " + v.name + " ?",
loading: true,
onOk: () => {
// 删除
theme: "warning",
onConfirm: () => {
delLogistics(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});

View File

@@ -24,7 +24,7 @@ export default {
this.getSite();
} else {
// 如果缓存过期,则获取最新的信息
if (new Date() > localStorage.getItem("icontitle_expiration_time")) {
if (Date.now() > Number(localStorage.getItem("icontitle_expiration_time"))) {
this.getSite();
return;
} else {
@@ -43,16 +43,17 @@ export default {
getSite() {
//获取domainLogo
getBaseSite().then((res) => {
const { domainLogo, domainIcon, siteName } = JSON.parse(res.result.settingValue);
if (res && res.success && res.result && res.result.settingValue) {
const parsed = JSON.parse(res.result.settingValue);
const domainLogo = parsed && parsed.domainLogo ? parsed.domainLogo : this.domainLogo;
const domainIcon = parsed && parsed.domainIcon ? parsed.domainIcon : parsed.domainLogo;
const siteName = parsed && parsed.siteName ? parsed.siteName : document.title;
this.domainLogo = domainLogo;
// 过期时间
var expirationTime = new Date().setHours(new Date().getHours() + 1);
// 存放过期时间
localStorage.setItem("icontitle_expiration_time", expirationTime);
// 存放信息
localStorage.setItem("icon", domainLogo);
localStorage.setItem("domainIcon", domainIcon);
localStorage.setItem("title", siteName);
localStorage.setItem("domainIcon", domainIcon || domainLogo);
localStorage.setItem("title", siteName || "运营后台");
let link =
document.querySelector("link[rel*='icon']") ||
document.createElement("link");
@@ -60,8 +61,9 @@ export default {
link.href = domainLogo;
link.rel = "shortcut icon";
document.getElementsByTagName("head")[0].appendChild(link);
window.document.title = siteName + " - 运营后台";
});
window.document.title = (siteName || "运营后台") + " - 运营后台";
}
}).catch(() => {});
},
},
mounted() {

View File

@@ -1,12 +1,12 @@
<template>
<div class="lang-icon">
<Dropdown @on-click="langChange">
<t-dropdown>
<Icon type="md-globe" size="26"/>
<DropdownMenu slot="list">
<DropdownItem name="zh-CN">简体中文</DropdownItem>
<DropdownItem name="en-US">English</DropdownItem>
</DropdownMenu>
</Dropdown>
<t-dropdown-menu>
<t-dropdown-item @click="langChange('zh-CN')">简体中文</t-dropdown-item>
<t-dropdown-item @click="langChange('en-US')">English</t-dropdown-item>
</t-dropdown-menu>
</t-dropdown>
</div>
</template>

View File

@@ -1,36 +1,36 @@
<template>
<div class="message-con">
<Dropdown trigger="click">
<t-dropdown>
<a href="javascript:void(0)">
{{ value > 0 ? "有" + value + "条待办事项" : "无待办事项" }}
<Icon v-if="value!=0" type="ios-arrow-down"></Icon>
</a>
<DropdownMenu v-if="value!=0" slot="list">
<DropdownItem v-if="res.balanceCash" @click.native="navigateTo('deposit')">
<t-dropdown-menu v-if="value!=0">
<t-dropdown-item v-if="res.balanceCash" @click="navigateTo('deposit')">
<Badge :count="res.balanceCash">待处理预存款提现申请 </Badge>
</DropdownItem>
<DropdownItem v-if="res.complain" @click.native="navigateTo('orderComplaint')">
</t-dropdown-item>
<t-dropdown-item v-if="res.complain" @click="navigateTo('orderComplaint')">
<Badge :count="res.complain">待处理投诉审核 </Badge>
</DropdownItem>
<DropdownItem v-if="res.distributionCash" @click.native="navigateTo('distributionCash')">
</t-dropdown-item>
<t-dropdown-item v-if="res.distributionCash" @click="navigateTo('distributionCash')">
<Badge :count="res.distributionCash">待处理分销商提现申请 </Badge>
</DropdownItem>
<DropdownItem v-if="res.goods" @click.native="navigateTo('applyGoods')">
</t-dropdown-item>
<t-dropdown-item v-if="res.goods" @click="navigateTo('applyGoods')">
<Badge :count="res.goods">待处理商品审核 </Badge>
</DropdownItem>
<DropdownItem v-if="res.refund" @click.native="navigateTo('afterSaleOrder')">
</t-dropdown-item>
<t-dropdown-item v-if="res.refund" @click="navigateTo('afterSaleOrder')">
<Badge :count="res.refund">待处理售后申请 </Badge>
</DropdownItem>
<DropdownItem v-if="res.store" @click.native="navigateTo('shopAuth')">
</t-dropdown-item>
<t-dropdown-item v-if="res.store" @click="navigateTo('shopAuth')">
<Badge :count="res.store">待处理店铺入驻审核 </Badge>
</DropdownItem>
<DropdownItem v-if="res.waitPayBill" @click.native="navigateTo('accountStatementBill')">
</t-dropdown-item>
<t-dropdown-item v-if="res.waitPayBill" @click="navigateTo('accountStatementBill')">
<Badge :count="res.waitPayBill">待与商家对账</Badge>
</DropdownItem>
</t-dropdown-item>
<div></div>
</DropdownMenu>
</Dropdown>
</t-dropdown-menu>
</t-dropdown>
</div>
</template>
@@ -66,16 +66,16 @@ export default {
};
</script>
<style scoped lang="scss">
/deep/ .ivu-select-dropdown {
::v-deep .ivu-select-dropdown {
text-align: left;
}
.message-con {
margin-right: 10px;
}
/deep/ .ivu-dropdown-item{
::v-deep .ivu-dropdown-item{
padding: 7px 20px !important;
}
/deep/ .ivu-badge-count{
::v-deep .ivu-badge-count{
right: -10px !important;
}
</style>

View File

@@ -1,27 +1,30 @@
<template>
<div class="ivu-shrinkable-menu">
<!-- 一级菜单 -->
<Menu ref="sideMenu" width="80px" theme="dark" :active-name="currNav" @on-select="selectNav">
<MenuItem v-for="(item, i) in navList" :key="i" :name="item.name">
{{item.title}}
</MenuItem>
</Menu>
<!-- 二级菜单 -->
<Menu
ref="childrenMenu"
:active-name="$route.name"
width="100px"
@on-select="changeMenu"
<div class="td-shrinkable-menu">
<!-- 一级菜单顶级导航 -->
<t-menu :value="currNav" theme="dark" :width="80" @change="selectNav">
<t-menu-item v-for="(item, i) in navList" :key="i" :value="item.name">
{{ item.title }}
</t-menu-item>
</t-menu>
<!-- /三级菜单当前顶级导航下的分组与页面 -->
<t-menu
:value="$route.name"
:defaultExpanded="defaultExpanded"
:expandMutex="true"
:width="232"
@change="changeMenu"
>
<template v-for="item in menuList">
<MenuGroup :title="item.title" :key="item.id" style="padding-left:0;">
<MenuItem :name="menu.name" v-for="menu in item.children" :key="menu.name">
{{menu.title}}
</MenuItem>
</MenuGroup>
</template>
</Menu>
<t-submenu v-for="item in menuList" :key="item.id || item.name" :value="'group-' + (item.name || item.id)">
<template #title>{{ item.title }}</template>
<t-menu-item
v-for="menu in item.children"
:key="menu.name"
:value="menu.name"
>
{{ menu.title }}
</t-menu-item>
</t-submenu>
</t-menu>
</div>
</template>
@@ -39,6 +42,16 @@ export default {
},
currNav() {
return this.$store.state.app.currNav;
},
defaultExpanded() {
const active = this.$route && this.$route.name;
const groups = [];
(this.$store.state.app.menuList || []).forEach(g => {
if ((g.children || []).some(c => c.name === active)) {
groups.push('group-' + (g.name || g.id));
}
});
return groups;
}
},
watch: {
@@ -52,47 +65,27 @@ export default {
}
},
methods: {
changeMenu(name) { //二级路由点击
this.$router.push({
name: name
});
changeMenu(name) {
this.$router.push({ name });
},
selectNav(name) { // 一级路由点击事件
selectNav(name) {
this.$store.commit("setCurrNav", name);
this.setStore("currNav", name);
util.initRouter(this);
this.$nextTick(()=>{
this.$refs.childrenMenu.updateActiveName()
})
},
}
};
</script>
<style lang="scss" scoped>
.ivu-shrinkable-menu{
.td-shrinkable-menu{
height: calc(100% - 60px);
width: 180px;
width: 312px;
display: flex;
}
.ivu-btn-text:hover {
background-color: rgba(255,255,255,.2) !important;
::v-deep .t-default-menu{
border-right: 1px solid #f0f0f0;
}
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
background-color: #fff;
&:hover{
background-color: #fff;
}
}
.ivu-menu-vertical{
::v-deep .t-menu{
overflow-y: auto;
}
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
color: $theme_color;
}
/deep/.ivu-menu-vertical .ivu-menu-item-group-title {
height: 40px;
line-height: 40px;
padding-left: 20px;
}
</style>

View File

@@ -52,7 +52,7 @@
box-sizing: border-box;
position: fixed;
display: block;
padding-left: 180px;
padding-left: 312px;
width: 100%;
height: 100px;
z-index: 20;
@@ -218,12 +218,12 @@
.single-page-con {
min-width: 740px;
position: relative;
left: 180px;
left: 312px;
top: 100px;
right: 0;
bottom: 0;
height: calc(100% - 110px);
width: calc(100% - 180px);
width: calc(100% - 312px);
overflow: auto;
background-color: #f0f0f0;
z-index: 1;

View File

@@ -1,206 +1,178 @@
<template>
<div class="search">
<Card>
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="充值单号" prop="rechargeSn">
<Input
type="text"
v-model="searchForm.rechargeSn"
placeholder="请输入充值单号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="支付时间">
<DatePicker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 200px"
></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
<div>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="充值单号" name="rechargeSn">
<t-input v-model="searchForm.rechargeSn" placeholder="请输入充值单号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="支付时间">
<t-date-picker v-model="selectDate" mode="date" range enableTimePicker clearable format="YYYY-MM-DD HH:mm:ss" @change="selectDateRange" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
:showJumper="true"
@change="onPaginationChange"
/>
</div>
</t-card>
</div>
</template>
<script>
import {
getUserRecharge,
} from "@/api/member";
export default {
import { getUserRecharge } from "@/api/member";
export default {
name: "recharge",
data() {
return {
loading: true, // 表单加载状态
loading: true,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
memberName:""
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
memberName: "",
rechargeSn: "",
},
selectDate: null, // 选择区间时间
selectDate: [],
columns: [
{
title: "会员名称",
key: "memberName",
colKey: "memberName",
minWidth: 120,
tooltip: true
align: "left",
tooltip: true,
},
{
title: "订单号",
key: "rechargeSn",
colKey: "rechargeSn",
minWidth: 180,
tooltip: true
align: "left",
tooltip: true,
},
{
title: "充值金额",
key: "rechargeMoney",
colKey: "rechargeMoney",
width: 160,
sortable: true,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.rechargeMoney,color:this.$mainColor,unit:"+"}} );
align: "left",
cell: (h, params) => {
return h("priceColorScheme", { props: { value: params.row.rechargeMoney, color: this.$mainColor, unit: "+" } });
},
},
{
title: "充值方式",
key: "rechargeWay",
colKey: "rechargeWay",
width: 120,
render: (h, params) => {
if (params.row.rechargeWay === 'ALIPAY') {
return h('div', [h('span', {}, '支付宝')]);
} else if (params.row.rechargeWay === 'WECHAT') {
return h('div', [h('span', {}, '微信')]);
} else if (params.row.rechargeWay === 'BANK_TRANSFER') {
return h('div', [h('span', {}, '线下转账')]);
} else {
return h('div', [h('span', {}, '')]);
}
}
align: "left",
cell: (h, params) => {
const way = params.row.rechargeWay;
const map = { ALIPAY: "支付宝", WECHAT: "微信", BANK_TRANSFER: "线下转账" };
return h("div", [h("span", {}, map[way] || "")]);
},
},
{
title: "支付状态",
key: "payStatus",
colKey: "payStatus",
align: "left",
width: 120,
sortable: false,
render: (h, params) => {
if (params.row.payStatus == "PAID") {
return h("Tag", {props: {color: "green",},}, "已付款");
} else {
return h("Tag", {props: {color: "red",},}, "未付款");
}
cell: (h, params) => {
const paid = params.row.payStatus === "PAID";
return h("t-tag", { props: { theme: paid ? "success" : "danger", variant: "light", size: "small" } }, [paid ? "已付款" : "未付款"]);
},
},
{
title: "充值时间",
key: "createTime",
colKey: "createTime",
align: "left",
width: 190,
sortable: false,
},
{
title: "支付时间",
key: "payTime",
colKey: "payTime",
align: "left",
width: 190,
sortable: false,
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
data: [],
total: 0,
};
},
methods: {
// 初始化数据
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
handleReset() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.memberName = "";
this.searchForm.rechargeSn = "";
this.searchForm.startDate = "";
this.searchForm.endDate = "";
this.selectDate = [];
this.getDataList();
},
// 时间段赋值
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
}
},
// 获取列表数据
getDataList() {
this.loading = true;
getUserRecharge(this.searchForm).then((res) => {
getUserRecharge(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
},
mounted() {
this.init();
},
};
};
</script>

View File

@@ -1,24 +1,26 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="会员名称" prop="memberName">
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 200px" />
</Form-item>
<Form-item label="支付时间">
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd HH:mm:ss" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 200px"></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
</Row>
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]"
size="small" show-total show-elevator show-sizer></Page>
</Row>
</Card>
<div>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="支付时间">
<t-date-picker v-model="selectDate" mode="date" range enableTimePicker clearable format="YYYY-MM-DD HH:mm:ss" @change="selectDateRange" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table class="mt_10" :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
@@ -28,112 +30,123 @@ export default {
name: "walletLog",
data() {
return {
loading: true, // 表单加载状态
loading: true,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
memberName: "",
},
selectDate: null, // 选择时间段
selectDate: [],
columns: [
// 表头
{
title: "会员名称",
key: "memberName",
colKey: "memberName",
minWidth: 100,
align: "left",
},
{
title: "变动金额",
key: "money",
colKey: "money",
width: 150,
render: (h, params) => {
if (params.row.money >0) {
return h("priceColorScheme", {props:{value:params.row.money,color:'green'}} );
align: "left",
cell: (h, params) => {
if (params.row.money > 0) {
return h("priceColorScheme", { props: { value: params.row.money, color: "green" } });
} else if (params.row.money < 0) {
return h("priceColorScheme", {props:{value:params.row.money,color:this.$mainColor}} );
return h("priceColorScheme", { props: { value: params.row.money, color: this.$mainColor } });
}
},
},
{
title: "变更时间",
key: "createTime",
colKey: "createTime",
width: 200,
align: "left",
},
{
title: "业务类型",
key: "serviceType",
colKey: "serviceType",
width: 200,
render: (h, params) => {
if (params.row.serviceType == "WALLET_WITHDRAWAL") {
return h("div", [h("span", {}, "余额提现")]);
} else if (params.row.serviceType == "WALLET_PAY") {
return h("div", [h("span", {}, "余额支付")]);
} else if (params.row.serviceType == "WALLET_REFUND") {
return h("div", [h("span", {}, "余额退款")]);
} else if (params.row.serviceType == "WALLET_RECHARGE") {
return h("div", [h("span", {}, "余额充值")]);
} else {
return h("div", [h("span", {}, "佣金提成")]);
}
align: "left",
cell: (h, params) => {
const map = {
WALLET_WITHDRAWAL: "余额提现",
WALLET_PAY: "余额支付",
WALLET_REFUND: "余额退款",
WALLET_RECHARGE: "余额充值",
};
return h("div", [h("span", {}, map[params.row.serviceType] || "佣金提成")]);
},
},
{
title: "详细",
key: "detail",
colKey: "detail",
minWidth: 300,
tooltip: true,
align: "left",
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
data: [],
total: 0,
};
},
methods: {
// 初始化数据
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
// 搜索
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
handleReset() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.memberName = "";
this.searchForm.startDate = "";
this.searchForm.endDate = "";
this.selectDate = [];
this.getDataList();
},
// 时间段赋值
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
this.searchForm.endDate = v[1];
}
},
// 获取列表数据
getDataList() {
getUserWallet(this.searchForm).then((res) => {
this.loading = true;
getUserWallet(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
},
mounted() {

View File

@@ -1,246 +1,201 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="会员名称" prop="memberName">
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 200px" />
</Form-item>
<Form-item label="审核状态" prop="applyStatus">
<Select v-model="searchForm.applyStatus" clearable style="width: 200px">
<Option value="APPLY">申请中</Option>
<Option value="VIA_AUDITING">审核通过</Option>
<Option value="FAIL_AUDITING">审核拒绝</Option>
<Option value="SUCCESS">提现成功</Option>
<Option value="ERROR">提现失败</Option>
</Select>
</Form-item>
<Form-item label="申请时间">
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd HH:mm:ss" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 200px"></DatePicker>
</Form-item>
<Form-item style="margin-left: -35px" class="br">
<Button @click="handleSearch" type="primary" icon="ios-search">搜索
</Button>
</Form-item>
</Form>
</Row>
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom" @on-sort-change="changeSort" @on-selection-change="changeSelect"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small"
show-total show-elevator show-sizer></Page>
</Row>
</Card>
<Modal :title="modalTitle" v-model="roleModalVisible" :mask-closable="false" :width="500">
<Form :label-width="80">
<FormItem label="申请编号">
<span>{{showList.sn}}</span>
</FormItem>
<FormItem label="用户名称">
<span>{{showList.memberName}}</span>
</FormItem>
<FormItem label="申请金额">
<priceColorScheme :value="showList.applyMoney" :color="$mainColor"></priceColorScheme>
</FormItem>
<FormItem label="提现状态">
<span>{{showList.applyStatus | paramTypeFilter}}</span>
</FormItem>
<FormItem label="申请时间">
<span>{{showList.createTime}}</span>
</FormItem>
<FormItem label="审核备注">
<Input v-model="audit" type="textarea" />
</FormItem>
</Form>
<div slot="footer" v-if="showList.applyStatus == 'APPLY'">
<Button type="text" @click="submitRole(false)">拒绝</Button>
<Button type="primary" :loading="submitLoading" @click="submitRole(true)">通过
</Button>
<div>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="审核状态" name="applyStatus">
<t-select v-model="searchForm.applyStatus" clearable style="width: 240px">
<t-option value="APPLY" label="申请中" />
<t-option value="VIA_AUDITING" label="审核通过" />
<t-option value="FAIL_AUDITING" label="审核拒绝" />
<t-option value="SUCCESS" label="提现成功" />
<t-option value="ERROR" label="提现失败" />
</t-select>
</t-form-item>
<t-form-item label="申请时间">
<t-date-picker v-model="selectDate" mode="date" range enableTimePicker clearable format="YYYY-MM-DD HH:mm:ss" @change="selectDateRange" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table class="mt_10" :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</Modal>
</t-card>
<Modal :title="modalTitle" v-model="queryModalVisible" :mask-closable="false" :width="500">
<Form :label-width="80">
<FormItem label="申请编号:">
<span>{{showList.sn}}</span>
</FormItem>
<FormItem label="用户名称:">
<span>{{showList.memberName}}</span>
</FormItem>
<FormItem label="申请金额:">
<priceColorScheme :value="showList.applyMoney" :color="$mainColor"></priceColorScheme>
</FormItem>
<FormItem label="提现状态:">
<span>{{showList.applyStatus | paramTypeFilter}}</span>
</FormItem>
<FormItem label="申请时间:">
<span>{{showList.createTime}}</span>
</FormItem>
<FormItem label="审核时间:">
<span>{{showList.inspectTime}}</span>
</FormItem>
<FormItem label="审核备注:">
<span>{{showList.inspectRemark || '暂无备注'}}</span>
</FormItem>
</Form>
<div slot="footer" v-if="showList.applyStatus == 'APPLY'">
<Button type="text" @click="submitRole(false)">拒绝</Button>
<Button type="primary" :loading="submitLoading" @click="submitRole(true)">通过
</Button>
<t-drawer :visible="roleModalVisible" :header="modalTitle" placement="right" size="500px" @close="roleModalVisible = false">
<div class="drawer-content">
<div>申请编号{{ showList.sn }}</div>
<div>用户名称{{ showList.memberName }}</div>
<div class="drawer-row"><span>申请金额</span><priceColorScheme :value="showList.applyMoney" :color="$mainColor" /></div>
<div>提现状态{{ showList.applyStatus | paramTypeFilter }}</div>
<div>申请时间{{ showList.createTime }}</div>
<div>
<t-textarea v-model="audit" placeholder="审核备注" />
</div>
<div slot="footer" v-else>
<Button type="text" @click="queryModalVisible = false">取消</Button>
</div>
</Modal>
<template #footer>
<div v-if="showList.applyStatus == 'APPLY'" style="display: flex; justify-content: flex-end">
<t-button variant="text" @click="submitRole(false)">拒绝</t-button>
<t-button theme="primary" :loading="submitLoading" style="margin-left: 8px" @click="submitRole(true)">通过</t-button>
</div>
</template>
</t-drawer>
<t-drawer :visible="queryModalVisible" :header="modalTitle" placement="right" size="500px" @close="queryModalVisible = false">
<div class="drawer-content">
<div>申请编号{{ showList.sn }}</div>
<div>用户名称{{ showList.memberName }}</div>
<div class="drawer-row"><span>申请金额</span><priceColorScheme :value="showList.applyMoney" :color="$mainColor" /></div>
<div>提现状态{{ showList.applyStatus | paramTypeFilter }}</div>
<div>申请时间{{ showList.createTime }}</div>
<div>审核时间{{ showList.inspectTime }}</div>
<div>审核备注{{ showList.inspectRemark || '暂无备注' }}</div>
</div>
<template #footer>
<div style="display: flex; justify-content: flex-end">
<t-button variant="text" @click="queryModalVisible = false">返回</t-button>
</div>
</template>
</t-drawer>
</div>
</template>
<script>
import { getUserWithdrawApply, withdrawApply } from "@/api/member";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "withdrawApply",
components: {},
data() {
return {
modalTitle: "", //弹出框标题
openSearch: true, // 显示搜索
openTip: true, // 显示提示
loading: true, // 表单加载状态
audit: "", // 审核备注
roleModalVisible: false, // 审核模态框
queryModalVisible: false, // 审核模态框
modalTitle: "",
loading: true,
audit: "",
roleModalVisible: false,
queryModalVisible: false,
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
endDate: "", // 终止时间
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
memberName: "",
applyStatus: "",
},
selectDate: null, // 选择时间段
submitLoading: false, // 添加或编辑提交状态
selectList: [], // 多选数据
selectCount: 0, // 多选计数
showList: {}, // 可操作选项
selectDate: [],
submitLoading: false,
showList: {},
columns: [
{
title: "申请编号",
key: "sn",
colKey: "sn",
align: "left",
tooltip: true,
},
{
title: "用户名称",
key: "memberName",
colKey: "memberName",
align: "left",
tooltip: true,
},
{
title: "申请金额",
key: "applyMoney",
colKey: "applyMoney",
align: "left",
width: 120,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.applyMoney,color:this.$mainColor}} );
cell: (h, params) => {
return h("priceColorScheme", { props: { value: params.row.applyMoney, color: this.$mainColor } });
},
},
{
title: "提现状态",
align: "left",
key: "applyStatus",
colKey: "applyStatus",
width: 120,
render: (h, params) => {
if (params.row.applyStatus == "APPLY") {
return h("Tag", { props: { color: "volcano" } }, "申请中");
} else if (params.row.applyStatus == "VIA_AUDITING") {
return h("Tag", { props: { color: "green" } }, "审核通过");
} else if (params.row.applyStatus == "SUCCESS") {
return h("Tag", { props: { color: "blue" } }, "提现成功");
} else if (params.row.applyStatus == "ERROR") {
return h("Tag", { props: { color: "blue" } }, "提现失败");
} else {
return h("Tag", { props: { color: "red" } }, "审核拒绝");
}
}
cell: (h, params) => {
const status = params.row.applyStatus;
const map = {
APPLY: { theme: "warning", label: "申请中" },
VIA_AUDITING: { theme: "success", label: "审核通过" },
SUCCESS: { theme: "primary", label: "提现成功" },
ERROR: { theme: "danger", label: "提现失败" },
FAIL_AUDITING: { theme: "danger", label: "审核拒绝" },
};
const cfg = map[status] || { theme: "default", label: status };
return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
},
},
{
title: "申请时间",
key: "createTime",
colKey: "createTime",
align: "left",
width: 170,
},
{
title: "审核时间",
key: "inspectTime",
colKey: "inspectTime",
align: "left",
width: 170,
},
{
title: "操作",
key: "action",
colKey: "action",
width: 120,
align: "center",
fixed: "right",
render: (h, params) => {
if (params.row.applyStatus == "APPLY") {
return h(
"Button",
cell: (h, params) => {
if (params.row.applyStatus === "APPLY") {
return h("div", { class: "ops" }, [
h(
"a",
{
props: {
type: "primary",
size: "small",
},
style: {
marginRight: "5px",
},
style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" },
on: {
click: () => {
this.showList = {};
this.roleModalVisible = true;
this.modalTitle = "审核";
this.showList = params.row;
this.audit =""
this.audit = "";
},
},
},
"审核"
);
),
]);
} else {
return h(
"Button",
return h("div", { class: "ops" }, [
h(
"a",
{
props: {
type: "default",
size: "small",
},
style: {
marginRight: "5px",
},
style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" },
on: {
click: () => {
this.showList = {};
this.queryModalVisible = true;
this.showList = params.row;
this.modalTitle = "查看";
this.showList = params.row;
},
},
},
"查看"
);
),
]);
}
},
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
data: [],
total: 0,
};
},
filters: {
@@ -253,6 +208,8 @@ export default {
return "审核拒绝";
} else if (val === "ERROR") {
return "提现失败";
} else if (val === "SUCCESS") {
return "提现成功";
} else {
return "未知状态";
}
@@ -260,21 +217,23 @@ export default {
},
methods: {
submitRole(res) {
const params = {};
params.applyId = this.showList.id;
params.result = res;
params.remark = this.audit;
const params = { applyId: this.showList.id, result: res, remark: this.audit };
if (res === false && params.remark === "") {
this.$Message.error("审核备注不能为空");
MessagePlugin.error("审核备注不能为空");
return;
}
withdrawApply(params).then((res) => {
this.loading = false;
if (res == true) {
this.$Message.success("操作成功");
this.submitLoading = true;
withdrawApply(params)
.then((r) => {
this.submitLoading = false;
if (r === true) {
MessagePlugin.success("操作成功");
this.roleModalVisible = false;
this.getDataList();
}
})
.catch(() => {
this.submitLoading = false;
});
},
init() {
@@ -283,43 +242,34 @@ export default {
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
this.clearSelectAll();
},
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
handleReset() {
this.$refs.searchForm.resetFields();
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.selectDate = null;
this.searchForm.pageSize = 20;
this.selectDate = [];
this.searchForm.startDate = "";
this.searchForm.endDate = "";
this.searchForm.memberName = "";
// 重新加载数据
this.searchForm.applyStatus = "";
this.getDataList();
},
changeSort(e) {
this.searchForm.sort = e.key;
this.searchForm.order = e.order;
if (e.order === "normal") {
this.searchForm.order = "";
}
this.getDataList();
},
clearSelectAll() {
this.$refs.table.selectAll(false);
},
changeSelect(e) {
this.selectList = e;
this.selectCount = e.length;
},
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
@@ -328,16 +278,17 @@ export default {
},
getDataList() {
this.loading = true;
// 带多条件搜索参数获取表单数据 请自行修改接口
getUserWithdrawApply(this.searchForm).then((res) => {
getUserWithdrawApply(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
},
mounted() {
@@ -345,4 +296,27 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.ops a {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops span {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
.drawer-content {
display: flex;
flex-direction: column;
}
.drawer-content > div {
margin: 12px 0;
}
.drawer-row {
display: flex;
align-items: center;
}
</style>

View File

@@ -1,101 +1,118 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="会员名称" prop="username">
<Input type="text" v-model="searchForm.username" placeholder="请输入会员名称" clearable style="width: 200px" />
</Form-item>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员ID" name="id">
<t-input v-model="searchForm.id" placeholder="请输入会员ID" clearable style="width: 240px" />
</t-form-item>
<Form-item label="会员称" prop="nickName">
<Input type="text" v-model="searchForm.nickName" placeholder="请输入会员称" clearable style="width: 200px" />
</Form-item>
<t-form-item label="会员称" name="username">
<t-input v-model="searchForm.username" placeholder="请输入会员称" clearable style="width: 240px" />
</t-form-item>
<Form-item label="联系方式" prop="mobile">
<Input type="text" v-model="searchForm.mobile" placeholder="请输入会员联系方式" clearable style="width: 200px" />
</Form-item>
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search">搜索</Button>
</Form>
</Row>
<Row class="operation padding-row" v-if="!selectedMember">
<Button @click="addMember" type="primary">添加会员</Button>
</Row>
<t-form-item label="会员昵称" name="nickName">
<t-input v-model="searchForm.nickName" placeholder="请输入会员昵称" clearable style="width: 240px" />
</t-form-item>
<Table :loading="loading" border :columns="columns" class="mt_10" :data="data" ref="table"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total show-elevator
show-sizer></Page>
</Row>
</Card>
<t-form-item label="联系方式" name="mobile">
<t-input v-model="searchForm.mobile" placeholder="请输入会员联系方式" clearable style="width: 240px" />
</t-form-item>
<!-- 添加用户模态框 -->
<Modal v-model="addFlag" title="添加会员">
<Form ref="addMemberForm" :model="addMemberForm" :rules="addRule" :label-width="100">
<FormItem label="手机号码" prop="mobile" style="width: 90%;">
<Input v-model="addMemberForm.mobile" maxlength="11" placeholder="请输入手机号码" />
</FormItem>
<FormItem label="会员名称" prop="username" style="width: 90%">
<Input v-model="addMemberForm.username" maxlength="15" placeholder="请输入会员名称" />
</FormItem>
<t-form-item label="状态" name="disabled">
<t-select v-model="searchForm.disabled" style="width: 240px">
<t-option label="全部" value="" />
<t-option label="正常" value="OPEN" />
<t-option label="禁用" value="CLOSE" />
</t-select>
</t-form-item>
<FormItem label="会员密码" prop="password" style="width: 90%">
<Input type="password" password v-model="addMemberForm.password" maxlength="20" placeholder="请输入会员密码" />
</FormItem>
</Form>
<div slot="footer">
<Button @click="addFlag = false">取消</Button>
<Button type="primary" @click="addMemberSubmit">确定</Button>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="operation padding-row" v-if="!selectedMember">
<t-button theme="primary" @click="addMember">添加会员</t-button>
</div>
</Modal>
<!-- 修改模态框 -->
<Modal v-model="descFlag" :title="descTitle" @on-ok="handleSubmitModal" width="500">
<Form ref="form" :model="form" :rules="ruleValidate" :label-width="80">
<Input v-model="form.id" v-show="false"/>
<t-table :loading="loading" :columns="columns" class="mt_10" :data="data" ref="table" rowKey="id"></t-table>
<t-row class="mt_10" justify="end">
<t-pagination
:current="searchForm.pageNumber"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
:showJumper="true"
@change="onPaginationChange"
/>
</t-row>
</t-card>
<FormItem label="头像">
<!-- 添加会员右侧抽屉 -->
<t-drawer :visible.sync="addFlag" header="添加会员" placement="right" size="500px" @close="addFlag = false">
<t-form ref="addMemberForm" :data="addMemberForm" :rules="addRule" :labelWidth="100">
<t-form-item label="手机号码" name="mobile">
<t-input v-model="addMemberForm.mobile" maxlength="11" placeholder="请输入手机号码" />
</t-form-item>
<t-form-item label="会员名称" name="username">
<t-input v-model="addMemberForm.username" maxlength="15" placeholder="请输入会员名称" />
</t-form-item>
<t-form-item label="会员密码" name="password">
<t-input type="password" v-model="addMemberForm.password" maxlength="20" placeholder="请输入会员密码" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="addFlag = false">取消</t-button>
<t-button theme="primary" @click="addMemberSubmit">确定</t-button>
</template>
</t-drawer>
<!-- 编辑会员右侧抽屉 -->
<t-drawer :visible.sync="descFlag" :header="descTitle" placement="right" size="600px" @close="descFlag = false">
<t-form ref="form" :data="form" :rules="ruleValidate" :labelWidth="100">
<t-input v-model="form.id" style="display:none" />
<t-form-item label="头像">
<img :src="form.face || defaultPic" class="face" />
<Button type="text" class="upload" @click="() => {
this.picModelFlag = true;
this.$refs.ossManage.selectImage = true;
}">修改</Button>
<t-button variant="text" class="upload" @click="() => { picModelFlag = true; $refs.ossManage.selectImage = true; }">修改</t-button>
<input type="file" style="display: none" id="file" />
</FormItem>
<FormItem label="用户名" prop="name">
<Input v-model="form.username" style="width: 200px" disabled />
</FormItem>
<FormItem label="用户昵称" prop="name">
<Input v-model="form.nickName" style="width: 200px" />
</FormItem>
<FormItem label="性别" prop="sex">
<RadioGroup type="button" button-style="solid" v-model="form.sex">
<Radio :label="1">
<span></span>
</Radio>
<Radio :label="0">
<span></span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="修改密码" prop="password">
<Input type="password" style="width: 220px" password v-model="form.newPassword" />
</FormItem>
<FormItem label="生日" prop="birthday">
<DatePicker type="date" format="yyyy-MM-dd" v-model="form.birthday" style="width: 220px"></DatePicker>
</FormItem>
<FormItem label="所在地" prop="mail">
{{ form.region || '暂无地址' }}
<Button style="margin-left: 10px;" @click="$refs.map.open()">选择</Button>
</FormItem>
</Form>
</Modal>
<Modal width="1200px" v-model="picModelFlag">
</t-form-item>
<t-form-item label="用户名" name="username">
<t-input v-model="form.username" style="width: 200px" disabled />
</t-form-item>
<t-form-item label="用户昵称" name="nickName">
<t-input v-model="form.nickName" style="width: 200px" />
</t-form-item>
<t-form-item label="性别" name="sex">
<t-radio-group v-model="form.sex">
<t-radio :value="1"></t-radio>
<t-radio :value="0"></t-radio>
</t-radio-group>
</t-form-item>
<t-form-item label="修改密码" name="password">
<t-input type="password" style="width: 220px" v-model="form.newPassword" />
</t-form-item>
<t-form-item label="生日" name="birthday">
<t-date-picker mode="date" format="YYYY-MM-DD" valueType="time-stamp" v-model="form.birthday" style="width: 220px" />
</t-form-item>
<t-form-item label="所在地" name="region">
<div>{{ form.region || '暂无地址' }}</div>
<t-button style="margin-left: 10px;" @click="$refs.map.open()">选择</t-button>
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="descFlag = false">取消</t-button>
<t-button theme="primary" @click="handleSubmitModal">保存</t-button>
</template>
</t-drawer>
<t-dialog :visible.sync="picModelFlag" :width="1200" header="选择图片" @close="picModelFlag=false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
<multipleMap ref="map" @callback="selectedRegion"/>
</div>
</template>
@@ -105,6 +122,7 @@ import multipleMap from "@/components/map/multiple-map";
import * as API_Member from "@/api/member.js";
import ossManage from "@/views/sys/oss-manage/ossManage";
import * as RegExp from "@/libs/RegExp.js";
import { DialogPlugin } from "tdesign-vue";
export default {
name: "member",
@@ -129,9 +147,11 @@ export default {
searchForm: {
// 请求参数
pageNumber: 1,
pageSize: 10,
pageSize: 20, // 页面大小
order: "desc",
id: "",
username: "",
nickName: "",
mobile: "",
disabled: "OPEN",
},
@@ -151,21 +171,49 @@ export default {
},
ruleValidate: {}, //修改验证
columns: [
{
title: "会员ID",
colKey: "id",
minWidth: 120, // 减少宽度
ellipsis: true,
},
{
title: "头像",
colKey: "face",
minWidth: 80,
align: "center",
cell: (h, params) => {
return h("img", {
attrs: {
src: params.row.face || require('@/assets/default.png'),
alt: "头像"
},
style: {
width: "30px",
height: "30px",
borderRadius: "50%",
objectFit: "cover"
}
});
}
},
{
title: "会员名称",
key: "username",
tooltip: true,
colKey: "username",
ellipsis: true,
minWidth: 150, // 减少宽度
},
{
title: "会员昵称",
key: "nickName",
tooltip: true,
colKey: "nickName",
ellipsis: true,
minWidth: 150, // 减少宽度
},
{
title: "联系方式",
width: 130,
key: "mobile",
render: (h, params) => {
minWidth: 130,
colKey: "mobile",
cell: (h, params) => {
if (params.row.mobile == null) {
return h("div", [h("span", {}, "")]);
} else {
@@ -175,15 +223,21 @@ export default {
},
{
title: "注册时间",
key: "createTime",
width: 180,
colKey: "createTime",
minWidth: 160, // 减少宽度
},
{
title: "最后登录时间",
colKey: "lastLoginDate",
minWidth: 160, // 减少宽度
},
{
title: "积分数量",
align: "left",
width: 100,
render: (h, params) => {
minWidth: 120, // 增加宽度
colKey: "point",
cell: (h, params) => {
return h(
"div",
{},
@@ -193,11 +247,11 @@ export default {
},
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
width: 200,
minWidth: 160,
fixed: "right",
render: (h, params) => {
cell: (h, params) => {
return h(
"div",
{
@@ -208,15 +262,13 @@ export default {
},
[
h(
"Button",
"a",
{
props: {
size: "small",
type: params.row.___selected ? "primary" : "default",
},
style: {
marginRight: "5px",
display: this.selectedMember ? "block" : "none",
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
display: this.selectedMember ? "inline-block" : "none",
},
on: {
click: () => {
@@ -226,17 +278,25 @@ export default {
},
params.row.___selected ? "已选择" : "选择"
),
h(
"Button",
"span",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
display: this.selectedMember ? "none" : "block",
margin: "0 8px",
color: "#dcdee2",
display: this.selectedMember ? "inline-block" : "none",
},
},
"|"
),
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
display: this.selectedMember ? "none" : "inline-block",
},
on: {
click: () => {
@@ -247,16 +307,24 @@ export default {
"查看"
),
h(
"Button",
"span",
{
props: {
type: "info",
size: "small",
ghost: true,
},
style: {
marginRight: "5px",
display: this.selectedMember ? "none" : "block",
margin: "0 8px",
color: "#dcdee2",
display: this.selectedMember ? "none" : "inline-block",
},
},
"|"
),
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
display: this.selectedMember ? "none" : "inline-block",
},
on: {
click: () => {
@@ -267,15 +335,24 @@ export default {
"编辑"
),
h(
"Button",
"span",
{
props: {
size: "small",
type: "error",
},
style: {
marginRight: "5px",
display: this.selectedMember ? "none" : "block",
margin: "0 8px",
color: "#dcdee2",
display: this.selectedMember ? "none" : "inline-block",
},
},
"|"
),
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
display: this.selectedMember ? "none" : "inline-block",
},
on: {
click: () => {
@@ -370,10 +447,29 @@ export default {
this.searchForm.pageNumber = 1;
this.getData();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== 'undefined' && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize)
}
if (info && typeof info.current !== 'undefined') {
this.changePage(info.current)
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getData();
},
// 重置筛选
handleReset() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.id = "";
this.searchForm.username = "";
this.searchForm.nickName = "";
this.searchForm.mobile = "";
this.searchForm.disabled = "";
this.getData();
},
//查看详情修改
@@ -385,7 +481,11 @@ export default {
},
addMember() {
this.addFlag = true;
this.$refs.addMemberForm.resetFields();
if (this.$refs.addMemberForm && this.$refs.addMemberForm.reset) {
this.$refs.addMemberForm.reset();
} else {
this.addMemberForm = { mobile: "", username: "", password: "" };
}
},
/**
* 查询查看会员详情
@@ -482,7 +582,7 @@ export default {
regionId,
region,
nickName,
username,
sex,
birthday,
face,
@@ -506,15 +606,10 @@ export default {
};
</script>
<style lang="scss" scoped>
/deep/ .ivu-table-wrapper {
width: 100%;
}
/deep/ .ivu-card {
width: 100%;
}
.face {
width: 60px;
height: 60px;
border-radius: 50%;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,156 +1,107 @@
<template>
<div class="search">
<Row>
<Card>
<Row @keydown.enter.native="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="会员名称" prop="username">
<Input
type="text"
v-model="searchForm.username"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="username">
<t-input v-model="searchForm.username" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<Form-item label="联系方式" prop="mobile">
<Input
type="text"
v-model="searchForm.mobile"
placeholder="请输入会员联系方式"
clearable
style="width: 200px"
/>
</Form-item>
<Button
@click="handleSearch"
class="search-btn"
type="primary"
icon="ios-search"
>搜索</Button
>
</Form>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
sortable="custom"
>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
<t-form-item label="联系方式" name="mobile">
<t-input v-model="searchForm.mobile" placeholder="请输入会员联系方式" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<t-row class="mt_10" justify="end">
<t-pagination
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
</Row>
:showJumper="true"
@change="onPaginationChange"
/>
</t-row>
</t-card>
<!-- 修改模态框 -->
<Modal
v-model="descFlag"
:title="descTitle"
@on-ok="handleSubmitModal"
width="500"
>
<Form
<t-dialog :visible.sync="descFlag" :header="descTitle" :width="500" @confirm="handleSubmitModal" @close="descFlag=false">
<t-form
ref="formValidate"
:model="formValidate"
:data="formValidate"
:rules="ruleValidate"
:label-width="80"
:labelWidth="80"
>
<FormItem label="头像">
<t-form-item label="头像">
<img :src="formValidate.face" class="face" />
<Button
type="text"
<t-button
variant="text"
class="upload"
@click="
() => {
this.picModelFlag = true;
this.$refs.ossManage.selectImage = true;
}
"
@click="() => { picModelFlag = true; $refs.ossManage.selectImage = true; }"
>修改
</Button>
</t-button>
<input type="file" style="display: none" id="file" />
</FormItem>
<FormItem label="会员名称" prop="name">
<Input
</t-form-item>
<t-form-item label="会员名称" name="username">
<t-input
v-model="formValidate.username"
style="width: 200px"
disabled
/>
</FormItem>
<FormItem label="用户昵称" prop="name">
<Input v-model="formValidate.nickName" style="width: 200px" />
</FormItem>
<FormItem label="性别" prop="sex">
<RadioGroup
type="button"
button-style="solid"
v-model="formValidate.sex"
>
<Radio :label="1">
<span></span>
</Radio>
<Radio :label="0">
<span></span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="修改密码" prop="password">
<Input
</t-form-item>
<t-form-item label="用户昵称" name="nickName">
<t-input v-model="formValidate.nickName" style="width: 200px" />
</t-form-item>
<t-form-item label="性别" name="sex">
<t-radio-group v-model="formValidate.sex">
<t-radio :value="1"></t-radio>
<t-radio :value="0"></t-radio>
</t-radio-group>
</t-form-item>
<t-form-item label="修改密码" name="password">
<t-input
type="password"
style="width: 220px"
password
v-model="formValidate.newPassword"
/>
</FormItem>
<FormItem label="生日" prop="birthday">
<DatePicker
type="date"
format="yyyy-MM-dd"
</t-form-item>
<t-form-item label="生日" name="birthday">
<t-date-picker
mode="date"
format="YYYY-MM-DD"
valueType="time-stamp"
v-model="formValidate.birthday"
style="width: 220px"
></DatePicker>
</FormItem>
<FormItem label="所在地" prop="mail">
/>
</t-form-item>
<t-form-item label="所在地" name="region">
{{ formValidate.region || '暂无地址' }}
<Button style="margin-left: 10px;" @click="$refs.map.open()">选择</Button>
</FormItem>
</Form>
</Modal>
<Modal width="1200px" v-model="picModelFlag">
<t-button style="margin-left: 10px;" @click="$refs.map.open()">选择</t-button>
</t-form-item>
</t-form>
</t-dialog>
<t-dialog :visible.sync="picModelFlag" :width="1200" header="选择图片" @close="picModelFlag=false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
<multipleMap ref="map" @callback="selectedRegion" />
</div>
</template>
<script>
import * as API_Member from "@/api/member.js";
import ossManage from "@/views/sys/oss-manage/ossManage";
import multipleMap from "@/components/map/multiple-map";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "memberRecycle",
components: {
@@ -169,7 +120,7 @@ export default {
searchForm: {
// 请求参数
pageNumber: 1,
pageSize: 10,
pageSize: 20,
order: "desc",
username: "",
mobile: "",
@@ -182,20 +133,22 @@ export default {
{
title: "会员名称",
align: "left",
key: "username",
tooltip: true,
colKey: "username",
ellipsis: true,
minWidth: 150,
},
{
title: "昵称",
align: "left",
key: "nickName",
tooltip: true,
colKey: "nickName",
ellipsis: true,
minWidth: 150,
},
{
title: "联系方式",
width: 130,
key: "mobile",
render: (h, params) => {
colKey: "mobile",
minWidth: 130,
cell: (h, params) => {
if (params.row.mobile == null) {
return h("div", [h("span", {}, "")]);
} else {
@@ -205,15 +158,16 @@ export default {
},
{
title: "注册时间",
key: "createTime",
width: 180,
colKey: "createTime",
minWidth: 180,
},
{
title: "积分数量",
align: "left",
width: 120,
render: (h, params) => {
colKey: "point",
minWidth: 120,
cell: (h, params) => {
return h(
"div",
{},
@@ -223,97 +177,61 @@ export default {
},
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
width: 200,
minWidth: 200,
fixed: "right",
render: (h, params) => {
cell: (h, params) => {
const linkStyle = {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
};
const sep = h(
"span",
{ style: { margin: "0 8px", color: "#dcdee2" } },
"|"
);
const children = [];
if (this.selectedMember) {
children.push(
h(
"a",
{ style: linkStyle, on: { click: () => this.callback(params.row) } },
"选择"
)
);
children.push(sep);
}
children.push(
h(
"a",
{ style: linkStyle, on: { click: () => this.detail(params.row) } },
"查看"
)
);
if (!this.selectedMember) {
children.push(sep);
children.push(
h(
"a",
{ style: linkStyle, on: { click: () => this.enable(params.row) } },
"启用"
)
);
children.push(sep);
children.push(
h(
"a",
{ style: linkStyle, on: { click: () => this.editPerm(params.row) } },
"编辑"
)
);
}
return h(
"div",
{
style: {
display: "flex",
justifyContent: "center",
},
},
[
h(
"Button",
{
props: {
size: "small",
},
style: {
marginRight: "5px",
display: this.selectedMember ? "block" : "none",
},
on: {
click: () => {
this.callback(params.row);
},
},
},
"选择"
),
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
h(
"Button",
{
props: {
size: "small",
type: "success",
},
style: {
marginRight: "5px",
display: this.selectedMember ? "none" : "block",
},
on: {
click: () => {
this.enable(params.row);
},
},
},
"启用"
),
h(
"Button",
{
props: {
type: "info",
size: "small",
ghost: true,
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.editPerm(params.row);
},
},
},
"编辑"
),
]
{ class: "ops", style: { display: "flex", justifyContent: "center" } },
children
);
},
},
@@ -342,10 +260,27 @@ export default {
this.searchForm.pageSize = v;
this.getData();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== 'undefined' && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize)
}
if (info && typeof info.current !== 'undefined') {
this.changePage(info.current)
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getData();
},
handleReset() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.username = "";
this.searchForm.mobile = "";
this.searchForm.order = "desc";
this.searchForm.disabled = "CLOSE";
this.getData();
},
//查看详情修改
@@ -408,13 +343,14 @@ export default {
memberIds: [v.id],
disabled: true,
};
this.$Modal.confirm({
title: "提示",
content: "<p>确定启用此会员?</p>",
onOk: () => {
DialogPlugin.confirm({
header: "提示",
content: "确定启用此会员?",
theme: "warning",
onConfirm: () => {
API_Member.updateMemberStatus(params).then((res) => {
if (res.success) {
this.$Message.success("启用成功");
MessagePlugin.success("启用成功");
this.getData();
} else {
// this.$Message.error(res.message);
@@ -435,7 +371,7 @@ export default {
regionId:regionId,
region: region,
nickName,
username,
sex,
birthday,
face: face || "",
@@ -446,7 +382,7 @@ export default {
}
API_Member.updateMember(submit).then((res) => {
if (res.result) {
this.$Message.success("修改成功!");
MessagePlugin.success("修改成功!");
this.init();
}
});
@@ -463,4 +399,14 @@ export default {
height: 60px;
border-radius: 50%;
}
.ops a {
color: #2d8cf0;
cursor: pointer;
text-decoration: none;
}
.ops span {
display: inline-block;
margin: 0 8px;
color: #dcdee2;
}
</style>

View File

@@ -1,98 +1,72 @@
<template>
<div>
<!--微信模板-->
<Modal v-model="wechatModal" width="530">
<p slot="header">
<Icon type="edit"></Icon>
<span>微信设置</span>
</p>
<div>
<Form ref="wechatFormData" :model="wechatFormData" label-position="left" :label-width="100">
<FormItem v-if="tab === 'WECHAT'" label="模板名称">
<Input v-model="wechatFormData.name" size="large" maxlength="9" disabled></Input>
</FormItem>
<FormItem v-if="tab === 'WECHAT'" label="头部信息" prop="first">
<Input v-model="wechatFormData.first" size="large" maxlength="50"></Input>
</FormItem>
<FormItem v-if="tab === 'WECHAT'" label="备注" prop="remark">
<Input class='textarea' :rows="5" :autosize="{maxRows:5,minRows: 5}" v-model="wechatFormData.remark"
type="textarea" maxlength="150"/>
</FormItem>
<FormItem label="是否开启" prop="enable">
<i-switch v-model="wechatFormData.enable" size="large">
<span slot="open">开启</span>
<span slot="close">关闭</span>
</i-switch>
</FormItem>
</Form>
<t-dialog :header="'微信设置'" :visible="wechatModal" :width="530" @close="wechatModal=false">
<t-form ref="wechatFormData" :data="currentForm" :labelWidth="100">
<t-form-item v-if="tab === 'WECHAT'" label="模板名称" name="name">
<t-input v-model="wechatFormData.name" maxlength="9" disabled />
</t-form-item>
<t-form-item v-if="tab === 'WECHAT'" label="头部信息" name="first">
<t-input v-model="wechatFormData.first" maxlength="50" />
</t-form-item>
<t-form-item v-if="tab === 'WECHAT'" label="备注" name="remark">
<t-textarea v-model="wechatFormData.remark" :autosize="{maxRows:5,minRows:5}" maxlength="150" />
</t-form-item>
<t-form-item label="是否开启" name="enable">
<t-switch v-model="currentForm.enable" />
</t-form-item>
</t-form>
<template #footer>
<t-button v-if="tab === 'WECHAT'" theme="primary" @click="wechatFormDataEdit">保存</t-button>
<t-button v-else theme="primary" @click="wechatMPFormDataEdit">保存</t-button>
</template>
</t-dialog>
</div>
<div slot="footer" style="text-align: right">
<Button v-if="tab === 'WECHAT'" type="primary" @click="wechatFormDataEdit">保存</Button>
<Button v-else type="primary" @click="wechatMPFormDataEdit">保存</Button>
</div>
</Modal>
<Card>
<Tabs @on-click="tabPaneChange" v-model="tab">
<TabPane label="微信消息" name="WECHAT">
<t-card>
<t-tabs :value="tab" @change="tabPaneChange">
<t-tab-panel label="微信消息" value="WECHAT">
<div class="search">
<Row class="operation mt_10">
<Button @click="weChatSync" type="primary">初始化微信消息</Button>
</Row>
<Table
:loading="loading"
border
:columns="weChatColumns"
:data="weChatData"
ref="weChatTable"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="weChatSearchForm.pageNumber"
:total="weChatTotal"
:page-size="weChatSearchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10,20,50]"
size="small"
></Page>
</Row>
<div class="operation mt_10">
<t-button theme="primary" @click="weChatSync">初始化微信消息</t-button>
</div>
</TabPane>
<t-table :loading="loading" :columns="weChatColumns" :data="weChatData" rowKey="id">
<template #enable="{ row }">
<span>{{ row.enable ? '开启' : '关闭' }}</span>
</template>
<template #action="{ row }">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="wechatSettingAlert(row)">编辑</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="delWeChat(row)">删除</a>
</template>
</t-table>
<div class="mt_10" style="display:flex;justify-content:flex-end">
<t-pagination :current="weChatSearchForm.pageNumber" :total="weChatTotal" :pageSize="weChatSearchForm.pageSize" :pageSizeOptions="[20,50,100]" size="small" showJumper showPageSize @change="weChatPaginationChange" />
</div>
</div>
</t-tab-panel>
<TabPane label="微信小程序订阅消息" name="WECHATMP">
<t-tab-panel label="微信小程序订阅消息" value="WECHATMP">
<div class="search">
<Row class="operation mt_10">
<Button @click="weChatSync('mp')" type="primary">初始化微信小程序订阅消息</Button>
</Row>
<Table
:loading="loading"
border
:columns="weChatColumns"
:data="weChatMPData"
sortable="custom"
ref="weChatMPTable"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="weChatMPSearchForm.pageNumber"
:total="weChatMPTotal"
:page-size="weChatMPSearchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10,20,50]"
size="small"
></Page>
</Row>
<div class="operation mt_10">
<t-button theme="primary" @click="weChatSync('mp')">初始化微信小程序订阅消息</t-button>
</div>
</TabPane>
</Tabs>
</Card>
<t-table :loading="loading" :columns="weChatColumns" :data="weChatMPData" rowKey="id">
<template #enable="{ row }">
<span>{{ row.enable ? '开启' : '关闭' }}</span>
</template>
<template #action="{ row }">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="wechatSettingAlert(row)">编辑</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="delWeChat(row)">删除</a>
</template>
</t-table>
<div class="mt_10" style="display:flex;justify-content:flex-end">
<t-pagination :current="weChatMPSearchForm.pageNumber" :total="weChatMPTotal" :pageSize="weChatMPSearchForm.pageSize" :pageSizeOptions="[20,50,100]" size="small" showJumper showPageSize @change="weChatMPPaginationChange" />
</div>
</div>
</t-tab-panel>
</t-tabs>
</t-card>
</div>
</template>
<script>
@@ -101,12 +75,12 @@ import {
getWechatMessagePage,
editWechatMessageTemplate,
delWechatMessageTemplate,
wechatMPMessageSync,
getWechatMPMessagePage,
editWechatMPMessageTemplate,
delWechatMPMessageTemplate
} from "@/api/setting";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
title: "wechat-message-manage",
@@ -126,96 +100,19 @@ export default {
weChatSearchForm: {
// 搜索框对应data对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
},
weChatMPSearchForm: {
// 搜索框对应data对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
},
weChatColumns: [
{
title: "模板编号",
key: "code",
width: 500,
sortable: true
},
{
title: "是否开启",
key: "enable",
sortable: true,
width: 150,
render: (h, params) => {
if (params.row.enable == true) {
return h('div', [
h('span', {}, '开启'),
]);
} else {
return h('div', [
h('span', {}, '关闭'),
]);
}
},
},
{
title: "模板名称",
key: "name",
width: 200,
sortable: true
},
{
title: "创建时间",
key: "createTime",
sortable: true,
sortType: "desc",
},
{
title: "操作",
key: "action",
width: 200,
align: "center",
fixed: "right",
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "primary",
size: "small"
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.wechatSettingAlert(params.row);
}
}
},
"编辑"
),
h(
"Button",
{
props: {
type: "error",
size: "small"
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.delWeChat(params.row);
}
}
},
"删除"
)
]);
}
}
{ title: "模板编号", colKey: "code", width: 500, sorter: true },
{ title: "是否开启", colKey: "enable", width: 150, align: "left" },
{ title: "模板名称", colKey: "name", width: 200, sorter: true },
{ title: "创建时间", colKey: "createTime", sorter: true },
{ title: "操作", colKey: "action", width: 200, align: "center", fixed: "right" },
],
weChatData: [], // 表单数据
weChatMPData: [], // 表单数据
@@ -223,49 +120,56 @@ export default {
weChatMPTotal: 0, // 表单数据总数
};
},
computed: {
currentForm() {
return this.tab === 'WECHAT' ? this.wechatFormData : this.wechatMPFormData;
}
},
methods: {
// 初始化数据
init() {
this.getDataList();
this.tabPaneChange(this.tab);
},
changePage(v) {
this.searchForm.type = this.tab;
this.getDataList();
weChatPaginationChange(pageInfo) {
this.weChatSearchForm.pageNumber = pageInfo.current;
this.weChatSearchForm.pageSize = pageInfo.pageSize;
this.getWechatMessagePage();
},
changePageSize(v) {
this.searchForm.type = this.tab;
this.getDataList();
weChatMPPaginationChange(pageInfo) {
this.weChatMPSearchForm.pageNumber = pageInfo.current;
this.weChatMPSearchForm.pageSize = pageInfo.pageSize;
this.getWechatMPMessagePage();
},
//微信弹出框
wechatSettingAlert(v) {
if (this.tab === 'WECHAT') {
this.wechatFormData = v
} else {
this.wechatMPFormData = v
}
this.id = v.id
this.wechatModal = true
},
//同步微信消息
weChatSync(mp) {
this.$Modal.confirm({
title: "提示",
// 记得确认修改此处
content: "确认要初始化微信小程序消息订阅?",
loading: true,
onOk: () => {
// 同步微信消息模板
DialogPlugin.confirm({
header: "提示",
content: mp === 'mp' ? "确认要初始化微信小程序消息订阅?" : "确认要初始化微信消息模板?",
theme: "warning",
onConfirm: () => {
if (mp === "mp") {
wechatMPMessageSync().then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success('微信小程序消息订阅初始化');
MessagePlugin.success('微信小程序消息订阅初始化');
this.getWechatMPMessagePage();
}
});
} else {
// 同步微信消息模板
wechatMessageSync().then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success('微信消息模板初始化成功');
MessagePlugin.success('微信消息模板初始化成功');
this.getWechatMessagePage();
}
});
}
@@ -281,7 +185,7 @@ export default {
}
editWechatMessageTemplate(this.id, this.wechatFormData).then(res => {
if (res.message === 'success') {
this.$Message.success('微信模板修改成功');
MessagePlugin.success('微信模板修改成功');
this.wechatModal = false;
this.getWechatMessagePage();
}
@@ -294,9 +198,9 @@ export default {
if (valid) {
editWechatMPMessageTemplate(this.id, this.wechatMPFormData).then(res => {
if (res.message === 'success') {
this.$Message.success('微信消息订阅模板修改成功');
MessagePlugin.success('微信消息订阅模板修改成功');
this.wechatModal = false;
this.getWechatMessagePage();
this.getWechatMPMessagePage();
}
});
}
@@ -305,32 +209,28 @@ export default {
//删除微信模消息
delWeChat(v) {
this.$Modal.confirm({
title: "提示",
DialogPlugin.confirm({
header: "提示",
content: "确定删除此模板?",
loading: true,
onOk: () => {
// 删除微信消息模板
theme: "warning",
onConfirm: () => {
if (this.tab === "WECHAT") {
delWechatMessageTemplate(v.id).then(res => {
if (res.success) {
this.$Modal.remove();
this.$Message.success('微信模板删除成功');
MessagePlugin.success('微信模板删除成功');
this.getWechatMessagePage()
}
});
} else {
delWechatMPMessageTemplate(v.id).then(res => {
if (res.success) {
this.$Modal.remove();
this.$Message.success('微信消息订阅删除成功');
this.getWechatMessagePage()
MessagePlugin.success('微信消息订阅删除成功');
this.getWechatMPMessagePage()
}
});
}
}
});
},
selectDateRange(v) {
if (v) {
@@ -339,14 +239,11 @@ export default {
}
},
getDataList() {
this.loading = true;
getWechatMessagePage(this.searchWe).then(res => {
this.loading = false;
if (res.success) {
this.weChatData = res.result.records;
this.weChatTotal = res.result.total;
if (this.tab === 'WECHAT') {
this.getWechatMessagePage();
} else {
this.getWechatMPMessagePage();
}
});
},
//分页获取微信消息
getWechatMessagePage() {
@@ -370,6 +267,7 @@ export default {
},
//tab切换事件
tabPaneChange(v) {
this.tab = v;
this.searchForm.type = v;
//如果是微信消息则走单独的接口
if (v === "WECHAT") {

View File

@@ -1,169 +1,147 @@
<template>
<div class="search">
<Card style="padding:0 10px 10px 0">
<Form
@keydown.enter.native="handleSearch"
ref="searchForm"
:model="searchForm"
inline
style="margin-top:10px"
:label-width="70"
@submit.native.prevent
class="search-form"
>
<Form-item label="会员名称" prop="username">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search">搜索</Button >
</Form>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
<div>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
:showJumper="true"
@change="onPaginationChange"
/>
</div>
</t-card>
</div>
</template>
<script>
import * as API_Member from "@/api/member";
import * as API_Member from "@/api/member.js";
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
// 积分历史页面
export default {
name: "point",
components: {
ossManage,
},
data() {
return {
loading: true, // 表单加载状态
searchForm: { // 请求参数
loading: true,
searchForm: {
pageNumber: 1,
pageSize: 10,
pageSize: 20,
memberName: "",
},
columns: [
{
title: "会员名称",
key: "memberName",
colKey: "memberName",
minWidth: 120,
tooltip: true
align: "left",
tooltip: true,
},
{
title: "操作内容",
key: "content",
colKey: "content",
minWidth: 180,
tooltip: true
align: "left",
tooltip: true,
},
{
title: "之前积分",
key: "beforePoint",
colKey: "beforePoint",
width: 110,
align: "left",
},
{
title: "变动积分",
key: "variablePoint",
colKey: "variablePoint",
width: 110,
render: (h, params) => {
if (params.row.pointType == 'INCREASE') {
return h("priceColorScheme", {props:{value:params.row.variablePoint,color:'green',unit:"+"}} );
} else {
return h("priceColorScheme", {props:{value:params.row.variablePoint,color:this.$mainColor,unit:"-"}} );
}
}
align: "left",
cell: (h, params) => {
const val = params.row.variablePoint;
const type = params.row.pointType;
const label = (type === "INCREASE" ? "+" : "-") + val;
const theme = type === "INCREASE" ? "success" : "danger";
return h("t-tag", { props: { theme, variant: "light", size: "small" } }, [label]);
},
},
{
title: "当前积分",
key: "point",
colKey: "point",
width: 110,
align: "left",
},
{
title: "操作时间",
key: "createTime",
width: 170
colKey: "createTime",
width: 170,
align: "left",
},
],
data: [], // 表单数据
total: 0, // 表单数据总数
data: [],
total: 0,
};
},
methods: {
// 回调给父级
callback(val) {
this.$emit("callback", val);
},
// 初始化数据
init() {
this.getData();
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getData();
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getData();
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.getData();
this.searchForm.pageSize = 20;
this.getDataList();
},
//查新积分列表
getData() {
handleReset() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.searchForm.memberName = "";
this.getDataList();
},
getDataList() {
this.loading = true;
API_Member.getHistoryPointData(this.searchForm).then((res) => {
API_Member.getHistoryPointData(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
})
.catch(() => {
this.loading = false;
});
},
},
mounted() {
this.init();
},
};
};
</script>
<style lang="scss" scoped>
.face {
width: 60px;
height: 60px;
border-radius: 50%;
}
</style>
<style lang="scss" scoped></style>

View File

@@ -1,137 +1,62 @@
<template>
<div class="search">
<Card>
<Tabs value="RETURN_MONEY" @on-click="handleClickType">
<TabPane label="退款" name="RETURN_MONEY">
<Row class="operation" style="margin-bottom: 10px">
<Button @click="add" type="primary" >添加</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</TabPane>
<TabPane label="取消" name="CANCEL">
<Row class="operation" style="margin-bottom: 10px">
<Button @click="add" type="primary" icon="md-add">添加</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</TabPane>
<TabPane label="退货" name="RETURN_GOODS">
<Row class="operation" style="margin-bottom: 10px">
<Button @click="add" type="primary" icon="md-add">添加</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</TabPane>
<TabPane label="投诉" name="COMPLAIN">
<Row class="operation" style="margin-bottom: 10px">
<Button @click="add" type="primary" icon="md-add">添加</Button>
<Button @click="getDataList" icon="md-refresh">刷新</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</TabPane>
</Tabs>
</Card>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
<FormItem label="售后原因" prop="reason">
<Input v-model="form.reason" maxlength="20" clearable style="width: 100%"/>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交
</Button
>
<t-card>
<t-tabs :value="searchForm.serviceType" @change="handleClickType">
<t-tab-panel label="退款" value="RETURN_MONEY">
<div class="operation" style="margin: 12px 0 10px">
<t-button @click="add" theme="primary">添加</t-button>
</div>
</Modal>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" />
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-tab-panel>
<t-tab-panel label="取消" value="CANCEL">
<div class="operation" style="margin: 12px 0 10px">
<t-button @click="add" theme="primary">添加</t-button>
</div>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" />
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-tab-panel>
<t-tab-panel label="退货" value="RETURN_GOODS">
<div class="operation" style="margin: 12px 0 10px">
<t-button @click="add" theme="primary">添加</t-button>
</div>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" />
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-tab-panel>
<t-tab-panel label="投诉" value="COMPLAIN">
<div class="operation" style="margin: 12px 0 10px">
<t-button @click="add" theme="primary">添加</t-button>
<t-button variant="outline" @click="getDataList">刷新</t-button>
</div>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" />
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-tab-panel>
</t-tabs>
</t-card>
<t-drawer :header="modalTitle" :visible="modalVisible" placement="right" size="500px" :closeOnOverlayClick="false" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100" :rules="formValidate">
<t-form-item label="售后原因" name="reason">
<t-input v-model="form.reason" maxlength="20" clearable style="width: 100%" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="outline" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 8px;">提交</t-button>
</template>
</t-drawer>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
data() {
@@ -155,70 +80,20 @@
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
serviceType: "RETURN_MONEY"
},
columns: [
{
title: "创建人",
key: "createBy",
minWidth: 120,
},
{
title: "原因",
key: "reason",
minWidth: 400,
},
{
title: "时间",
key: "createTime",
minWidth: 100,
},
{
title: "操作",
key: "action",
align: "center",
width: 200,
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.edit(params.row);
}
}
},
"编辑"
),
h(
"Button",
{
props: {
type: "error",
size: "small",
},
on: {
click: () => {
this.remove(params.row);
}
}
},
"删除"
)
]);
},
},
{ title: "创建人", colKey: "createBy", minWidth: 120 },
{ title: "原因", colKey: "reason", minWidth: 400 },
{ title: "时间", colKey: "createTime", minWidth: 100 },
{ title: "操作", colKey: "action", align: "center", width: 200, cell: (h, p) => h("div", [
h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none", marginRight: "5px" }, on: { click: () => { this.edit(p.row); } } }, "编辑"),
h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"),
h("a", { style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" }, on: { click: () => { this.remove(p.row); } } }, "删除")
]) },
],
data: [], // 表单数据
total: 0,//条数
@@ -238,10 +113,18 @@
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
//切换tab
handleClickType(v) {
this.searchForm.pageNumber = 1 // 当前页数
this.searchForm.pageSize = 10 // 页面大小
this.searchForm.pageSize = 20 // 页面大小
//退款
if (v == "RETURN_MONEY") {
this.searchForm.serviceType = "RETURN_MONEY"
@@ -263,14 +146,17 @@
//获取售后原因数据
getDataList() {
this.loading = true;
API_Order.getAfterSaleReasonPage(this.searchForm).then((res) => {
API_Order.getAfterSaleReasonPage(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total
this.total = res.result.total;
}
});
})
.catch(() => {
this.loading = false;
});
},
//添加售后原因
add() {
@@ -290,51 +176,52 @@
//提交表单
handleSubmit() {
this.form.serviceType = this.searchForm.serviceType
this.$refs.form.validate((valid) => {
if (valid) {
this.$refs.form.validate().then((valid) => {
if (valid === true) {
this.submitLoading = true;
if (this.modalTitle == '添加售后原因') {
// 添加
delete this.form.id;
API_Order.addAfterSaleReason(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("添加成功");
MessagePlugin.success("添加成功");
this.getDataList();
this.modalVisible = false;
}
});
}).catch(() => { this.submitLoading = false; });
} else {
// 编辑
API_Order.editAfterSaleReason(this.form.id, this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("修改成功");
MessagePlugin.success("修改成功");
this.getDataList();
this.modalVisible = false;
}
});
}).catch(() => { this.submitLoading = false; });
}
} else {
MessagePlugin.warning(valid && valid.firstError ? valid.firstError : "请完善表单");
}
});
},
//删除售后原因
remove(v) {
this.$Modal.confirm({
title: "确认删除",
// 记得确认修改此处
content: "确认要删除此售后原因?",
loading: true,
onOk: () => {
// 删除
const dialog = DialogPlugin.confirm({
header: "确认删除",
body: "确认要删除此售后原因?",
theme: "danger",
onConfirm: () => {
API_Order.delAfterSaleReason(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("售后原因已删除");
MessagePlugin.success("售后原因已删除");
this.getDataList();
}
dialog.hide();
});
},
onClose: () => {
dialog.hide();
}
});
}

View File

@@ -1,144 +1,81 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="售后单号" prop="sn">
<Input
type="text"
v-model="searchForm.sn"
placeholder="请输入售后单号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="申请时间">
<DatePicker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 200px"
></DatePicker>
</Form-item>
<Form-item label="商家名称" prop="storeName">
<Input
type="text"
v-model="searchForm.storeName"
placeholder="请输入商家名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="售后类型">
<Select
v-model="searchForm.serviceType"
placeholder="全部"
clearable
style="width: 200px"
>
<Option value="RETURN_MONEY">退款</Option>
<Option value="RETURN_GOODS">退货</Option>
</Select>
</Form-item>
<Button
@click="handleSearch"
type="primary"
icon="ios-search"
class="search-btn"
>搜索</Button
>
</Form>
</Row>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="关键字" name="keywords" style="display: block; width: 100%">
<t-input v-model="searchForm.keywords" placeholder="请输入商品名称、订单编号搜索" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="订单编号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="售后单号" name="sn">
<t-input v-model="searchForm.sn" placeholder="请输入售后单号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="申请时间">
<t-date-picker v-model="selectDate" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" clearable @change="selectDateRange" placeholder="选择起始时间" style="width: 240px" />
</t-form-item>
<t-form-item label="商家名称" name="storeName">
<t-input v-model="searchForm.storeName" placeholder="请输入商家名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="售后类型" name="serviceType">
<t-select v-model="searchForm.serviceType" placeholder="全部" clearable style="width: 240px">
<t-option value="RETURN_MONEY" label="退款" />
<t-option value="RETURN_GOODS" label="退货" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="order-tab">
<div v-for="(item,index) in serviceStatus" :key="index" :class="{'current': currentStatus === item.value}" @click="serviceStatusClick(item)">
{{item.title}}
<t-tabs :value="currentStatus" @change="serviceStatusClick">
<t-tab-panel v-for="item in serviceStatusWithCount" :key="item.value" :label="item.title" :value="item.value" />
</t-tabs>
</div>
</div>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
>
<!-- 商品栏目格式化 -->
<template slot="goodsSlot" slot-scope="{ row }">
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="sn">
<template #goodsSlot="{ row }">
<div style="margin-top: 5px; height: 80px; display: flex">
<div style="">
<img :src="row.goodsImage" style="height: 60px; margin-top: 3px" />
<div>
<img :src="row.goodsImage" style="width: 60px; height: 60px; margin-top: 3px; object-fit: cover; border-radius: 4px;" />
</div>
<div style="margin-left: 13px">
<div class="div-zoom">
<a @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr
:text="wapLinkTo(row.goodsId, row.skuId)"
:margin="0"
colorDark="#000"
colorLight="#fff"
:size="150"
></vue-qr>
</div>
<img
src="../../../assets/qrcode.svg"
class="hover-pointer"
width="20"
height="20"
alt=""
/>
</Poptip>
<div style="color: #999; font-size: 12px; margin-top: 5px;">商品ID: {{ row.goodsId }}</div>
</div>
</div>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<template #serviceTypeTag="{ row }">
<t-tag v-if="row.serviceType === 'RETURN_MONEY'" theme="primary" size="small" variant="light">退款</t-tag>
<t-tag v-else-if="row.serviceType === 'RETURN_GOODS'" theme="warning" size="small" variant="light">退货</t-tag>
<t-tag v-else-if="row.serviceType === 'EXCHANGE_GOODS'" theme="success" size="small" variant="light">换货</t-tag>
</template>
<template #serviceStatusTag="{ row }">
<t-tag v-if="row.serviceStatus === 'APPLY'" theme="primary" size="small" variant="light">申请中</t-tag>
<t-tag v-else-if="row.serviceStatus === 'PASS'" theme="success" size="small" variant="light">通过售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'REFUSE'" theme="danger" size="small" variant="light">拒绝售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'BUYER_RETURN'" theme="warning" size="small" variant="light">买家退货待卖家收货</t-tag>
<t-tag v-else-if="row.serviceStatus === 'SELLER_CONFIRM'" theme="primary" size="small" variant="light">卖家确认收货</t-tag>
<t-tag v-else-if="row.serviceStatus === 'SELLER_TERMINATION'" theme="danger" size="small" variant="light">卖家终止售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'BUYER_CANCEL'" size="small" variant="light">买家取消售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'COMPLETE'" theme="success" size="small" variant="light">完成售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'WAIT_REFUND'" theme="warning" size="small" variant="light">待平台退款</t-tag>
</template>
<template #action="{ row }">
<a style="color: #2d8cf0; cursor: pointer; text-decoration: none" @click="detail(row)">查看</a>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
@@ -156,7 +93,7 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
@@ -166,6 +103,7 @@ export default {
serviceStatus: "",
storeName: "",
sn: "",
keywords: "", // 新增关键字搜索字段
},
selectDate: null, // 选择时间段
form: {
@@ -177,121 +115,16 @@ export default {
billPrice: "",
},
columns: [
{
title: "售后服务单号",
key: "sn",
minWidth: 140,
tooltip: true,
},
{
title: "订单编号",
key: "orderSn",
minWidth: 120,
tooltip: true,
},
{
title: "商品",
key: "goodsName",
minWidth: 300,
tooltip: true,
slot: "goodsSlot",
},
{
title: "会员名称",
key: "memberName",
width: 140,
},
{
title: "商家名称",
key: "storeName",
minWidth: 100,
tooltip: true,
},
{
title: "售后金额",
key: "applyRefundPrice",
width: 110,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
},
},
{
title: "售后类型",
key: "serviceType",
width: 100,
render: (h, params) => {
if (params.row.serviceType == "RETURN_MONEY") {
return h("div", [h("tag", { props: { color: "blue" } }, "退款")]);
} else if (params.row.serviceType == "RETURN_GOODS") {
return h("div", [h("tag", { props: { color: "volcano" } }, "退货")]);
} else if (params.row.serviceType == "EXCHANGE_GOODS") {
return h("div", [h("tag", { props: { color: "green" } }, "换货")]);
}
},
},
{
title: "售后状态",
key: "serviceStatus",
width: 150,
render: (h, params) => {
if (params.row.serviceStatus == "APPLY") {
return h("div", [h("tag", { props: { color: "blue" } }, "申请中")]);
} else if (params.row.serviceStatus == "PASS") {
return h("div", [h("tag", { props: { color: "cyan" } }, "通过售后")]);
} else if (params.row.serviceStatus == "REFUSE") {
return h("div", [h("tag", { props: { color: "volcano" } }, "拒绝售后")]);
} else if (params.row.serviceStatus == "BUYER_RETURN") {
return h("div", [
h("tag", { props: { color: "orange" } }, "买家退货,待卖家收货"),
]);
} else if (params.row.serviceStatus == "SELLER_CONFIRM") {
return h("div", [h("tag", { props: { color: "gold" } }, "卖家确认收货")]);
} else if (params.row.serviceStatus == "SELLER_TERMINATION") {
return h("div", [h("tag", { props: { color: "lime" } }, "卖家终止售后")]);
} else if (params.row.serviceStatus == "BUYER_CANCEL") {
return h("div", [h("tag", { props: { color: "purple" } }, "买家取消售后")]);
} else if (params.row.serviceStatus == "COMPLETE") {
return h("div", [h("tag", { props: { color: "green" } }, "完成售后")]);
} else if (params.row.serviceStatus == "WAIT_REFUND") {
return h("div", [h("tag", { props: { color: "geekblue" } }, "待平台退款")]);
}
},
},
{
title: "申请时间",
key: "createTime",
width: 180,
},
{
title: "操作",
key: "action",
fixed: "right",
align: "center",
width: 100,
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]);
},
},
{ title: "商品", colKey: "goodsSlot", minWidth: 300, tooltip: true },
{ title: "售后服务单号", colKey: "sn", minWidth: 140, tooltip: true },
{ title: "订单编号", colKey: "orderSn", minWidth: 120, tooltip: true },
{ title: "会员ID", colKey: "memberId", minWidth: 120, tooltip: true },
{ title: "会员名称", colKey: "memberName", width: 140 },
{ title: "店铺名称", colKey: "storeName", width: 100, tooltip: true },
{ title: "售后金额", colKey: "applyRefundPrice", width: 110, cell: (h, p) => h("priceColorScheme", { props: { value: p.row.applyRefundPrice, color: this.$mainColor } }) },
{ title: "售后类型", colKey: "serviceTypeTag", width: 100 },
{ title: "申请时间", colKey: "createTime", width: 180 },
{ title: "操作", colKey: "action", fixed: "right", align: "center", width: 100 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -306,30 +139,59 @@ export default {
{title: '卖家终止售后', value: 'SELLER_TERMINATION'},
{title: '买家取消售后', value: 'BUYER_CANCEL'}
],
currentStatus: ''
currentStatus: '',
afterSaleNumData: {} // 售后数量统计数据
};
},
methods: {
// 初始化数据
init() {
this.getDataList();
this.getAfterSaleNumData();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
this.getAfterSaleNumData();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderSn: "",
memberName: "",
serviceStatus: "",
storeName: "",
sn: "",
keywords: "",
};
this.selectDate = null;
this.currentStatus = '';
this.getDataList();
this.getAfterSaleNumData();
},
// 开始结束时间分别赋值
selectDateRange(v) {
@@ -338,18 +200,28 @@ export default {
this.searchForm.endDate = v[1];
}
},
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.getAfterSaleOrderPage(this.searchForm).then((res) => {
API_Order.getAfterSaleOrderPage(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
// 获取售后数量统计
getAfterSaleNumData() {
const { serviceStatus, ...searchParams } = this.searchForm;
API_Order.getAfterSaleNumVO(searchParams).then((res) => {
if (res.success) {
this.afterSaleNumData = res.result;
}
});
},
// 跳转售后详情
detail(v) {
@@ -359,39 +231,43 @@ export default {
query: { sn: sn },
})
},
// 售后筛选
serviceStatusClick(item) {
this.currentStatus = item.value;
this.searchForm.serviceStatus = item.value;
serviceStatusClick(value) {
this.currentStatus = value;
if (value === "") {
delete this.searchForm.serviceStatus;
} else {
this.searchForm.serviceStatus = value;
}
this.getDataList();
this.getAfterSaleNumData();
},
},
mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
.order-tab {
width: 950px;
height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #f0f0f0;
padding: 0 10px;
margin: 10px 20px 10px 0;
div {
text-align: center;
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
computed: {
// 带数量的售后状态
serviceStatusWithCount() {
return [
{title: '全部', value: ''},
{title: `申请售后${this.afterSaleNumData.applyNum ? '(' + this.afterSaleNumData.applyNum + ')' : ''}`, value: 'APPLY'},
{title: `通过售后${this.afterSaleNumData.passNum ? '(' + this.afterSaleNumData.passNum + ')' : ''}`, value: 'PASS'},
{title: `拒绝售后${this.afterSaleNumData.refuseNum ? '(' + this.afterSaleNumData.refuseNum + ')' : ''}`, value: 'REFUSE'},
{title: `待收货${this.afterSaleNumData.buyerReturnNum ? '(' + this.afterSaleNumData.buyerReturnNum + ')' : ''}`, value: 'BUYER_RETURN'},
{title: `确认收货${this.afterSaleNumData.sellerConfirmNum ? '(' + this.afterSaleNumData.sellerConfirmNum + ')' : ''}`, value: 'SELLER_CONFIRM'},
{title: `完成售后${this.afterSaleNumData.completeNum ? '(' + this.afterSaleNumData.completeNum + ')' : ''}`, value: 'COMPLETE'},
{title: `卖家终止售后${this.afterSaleNumData.sellerTerminationNum ? '(' + this.afterSaleNumData.sellerTerminationNum + ')' : ''}`, value: 'SELLER_TERMINATION'},
{title: `买家取消售后${this.afterSaleNumData.buyerCancelNum ? '(' + this.afterSaleNumData.buyerCancelNum + ')' : ''}`, value: 'BUYER_CANCEL'},
{title: `等待平台退款${this.afterSaleNumData.waitRefundNum ? '(' + this.afterSaleNumData.waitRefundNum + ')' : ''}`, value: 'WAIT_REFUND'}
];
}
.current {
background-color: #ffffff;
}
}
</script>
<style lang="scss" scoped>
.order-tab {
::v-deep .t-tabs__nav-item {
font-size: 14px;
}
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="search">
<Card>
<t-card>
<div class="main-content">
<div class="div-flow-left">
<div class="div-form-default">
@@ -19,7 +19,7 @@
</dd>
</dl>
<dl>
<dt>退货状态</dt>
<dt>售后状态</dt>
<dd>{{ afterSaleInfo.serviceName }}</dd>
</dl>
<dl>
@@ -39,7 +39,7 @@
<dl v-if="afterSaleInfo.actualRefundPrice">
<dt>实际退款金额</dt>
<dd>
<priceColorScheme :value="afterSaleInfo.applyRefundPrice" :color="$mainColor"></priceColorScheme>
<priceColorScheme :value="afterSaleInfo.actualRefundPrice" :color="$mainColor"></priceColorScheme>
</dd>
</dl>
<dl v-if="afterSaleInfo.refundPoint">
@@ -79,18 +79,10 @@
<dt>是否同意</dt>
<dd>
<div class="div-content">
<RadioGroup
type="button"
button-style="solid"
v-model="params.serviceStatus"
>
<Radio label="PASS">
<span>同意</span>
</Radio>
<Radio label="REFUSE">
<span>拒绝</span>
</Radio>
</RadioGroup>
<t-radio-group v-model="params.serviceStatus">
<t-radio value="PASS">同意</t-radio>
<t-radio value="REFUSE">拒绝</t-radio>
</t-radio-group>
</div>
</dd>
</dl>
@@ -103,18 +95,16 @@
<dl>
<dt>实际退款金额</dt>
<dd>
<InputNumber :min="0" v-model="params.actualRefundPrice" style="width: 260px" />
<t-input-number :min="0" v-model="params.actualRefundPrice" style="width: 260px" />
</dd>
</dl>
<dl>
<dt>备注信息</dt>
<dd>
<Input
<t-textarea
v-model="params.remark"
type="textarea"
maxlength="200"
:maxlength="200"
:rows="4"
clearable
style="width: 260px"
/>
</dd>
@@ -122,14 +112,14 @@
<dl>
<dd>
<div style="text-align: right; width: 45%; margin-top: 10px">
<Button
type="primary"
<t-button
theme="primary"
:loading="submitLoading"
@click="handleSubmit"
style="margin-left: 5px"
>
确定
</Button>
</t-button>
</div>
</dd>
</dl>
@@ -224,12 +214,10 @@
<dl>
<dt>备注信息</dt>
<dd>
<Input
<t-textarea
v-model="refundPriceForm.remark"
type="textarea"
maxlength="200"
:maxlength="200"
:rows="4"
clearable
style="width: 260px"
/>
</dd>
@@ -237,14 +225,14 @@
<dl>
<dt>操作</dt>
<dd>
<Button
type="primary"
<t-button
theme="primary"
:loading="submitLoading"
@click="refundPriceSubmit"
style="margin-left: 5px"
>
退款
</Button>
</t-button>
</dd>
</dl>
</div>
@@ -283,25 +271,22 @@
<dl>
<dt>操作</dt>
<dd>
<Button
type="info"
<t-button
theme="default"
:loading="submitLoading"
@click="logisticsSeller()"
style="margin-left: 5px"
>
查询物流
</Button>
</t-button>
</dd>
</dl>
</div>
</div>
</div>
</Card>
</t-card>
<!-- 查询物流 -->
<Modal v-model="logisticsModal" width="40">
<p slot="header">
<span>查询物流</span>
</p>
<t-dialog :visible="logisticsModal" header="查询物流" width="40%" :confirmBtn="null" @close="logisticsClose" @cancel="logisticsClose">
<div class="layui-layer-wrap">
<dl>
<dt>售后单号:</dt>
@@ -335,10 +320,10 @@
</ul>
</div>
</div>
<div slot="footer" style="text-align: right">
<Button @click="logisticsClose">取消</Button>
</div>
</Modal>
<template #footer>
<t-button variant="outline" @click="logisticsClose">取消</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -376,11 +361,11 @@ export default {
status: "APPLY",
},
{
name: "通过",
name: "通过售后",
status: "PASS",
},
{
name: "拒绝",
name: "拒绝售后",
status: "REFUSE",
},
{
@@ -404,7 +389,7 @@ export default {
status: "COMPLETE",
},
{
name: "待平台退款",
name: "待平台退款",
status: "WAIT_REFUND",
},
],
@@ -511,7 +496,7 @@ export default {
const ob = this.afterSaleStatusList.filter((e) => {
return e.status === status;
});
return ob[0].name;
return ob.length > 0 ? ob[0].name : status;
},
// 根据订单状态判断是否显示物流信息
showDelivery(status) {

View File

@@ -1,72 +1,55 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="状态" prop="status">
<Select v-model="searchForm.status" placeholder="请选择" clearable style="width: 200px">
<Option value="NEW">新投诉</Option>
<Option value="CANCEL">已撤销</Option>
<Option value="WAIT_APPEAL">待申诉</Option>
<Option value="COMMUNICATION">对话中</Option>
<Option value="WAIT_ARBITRATION">等待仲裁</Option>
<Option value="COMPLETE">已完成</Option>
</Select>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
>
<template slot-scope="{row}" slot="goodsName">
<a class="mr_10" @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
</div>
<img src="../../../assets/qrcode.svg" style="vertical-align:bottom;" class="hover-pointer" width="20" height="20" alt="">
</Poptip>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="订单编号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-tabs :value="tabsValue" @change="onTabsChange">
<t-tab-panel value="ALL" label="全部" />
<t-tab-panel value="NEW" label="新投诉" />
<t-tab-panel value="CANCEL" label="已撤销" />
<t-tab-panel value="WAIT_APPEAL" label="待申诉" />
<t-tab-panel value="COMMUNICATION" label="对话中" />
<t-tab-panel value="WAIT_ARBITRATION" label="等待仲裁" />
<t-tab-panel value="COMPLETE" label="已完成" />
</t-tabs>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id">
<template #goodsName="{ row }">
<a class="mr_10" @click="linkTo(row.goodsId,row.skuId)">{{ row.goodsName }}</a>
<t-popup placement="top" trigger="hover">
<template #content>
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150" />
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<img src="../../../assets/qrcode.svg" style="vertical-align:bottom;" class="hover-pointer" width="20" height="20" alt="" />
</t-popup>
</template>
<template #complainStatusTag="{ row }">
<t-tag v-if="row.complainStatus === 'NEW'" size="small" variant="light">新投诉</t-tag>
<t-tag v-else-if="row.complainStatus === 'CANCEL'" theme="primary" size="small" variant="light">已撤销</t-tag>
<t-tag v-else-if="row.complainStatus === 'WAIT_APPEAL'" theme="warning" size="small" variant="light">待申诉</t-tag>
<t-tag v-else-if="row.complainStatus === 'COMMUNICATION'" theme="warning" size="small" variant="light">对话中</t-tag>
<t-tag v-else-if="row.complainStatus === 'WAIT_ARBITRATION'" theme="primary" size="small" variant="light">等待仲裁</t-tag>
<t-tag v-else-if="row.complainStatus === 'COMPLETE'" theme="success" size="small" variant="light">已完成</t-tag>
</template>
<template #action="{ row }">
<a style="color: #2d8cf0; cursor: pointer; text-decoration: none" @click="detail(row)">{{ row.complainStatus === 'COMPLETE' ? '详情' : '处理' }}</a>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
@@ -84,118 +67,22 @@
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
orderSn: "",
memberName: "",
status: "",
},
tabsValue: 'ALL',
columns: [
// 表头
{
title: "会员名称",
key: "memberName",
width: 200,
sortable: false,
},
{
title: "订单编号",
key: "orderSn",
minWidth: 120,
tooltip: true
},
{
title: "商品名称",
slot: "goodsName",
minWidth: 170,
tooltip: true
},
{
title: "投诉主题",
width: 100,
key: "complainTopic",
tooltip: true
},
{
title: "投诉时间",
key: "createTime",
width: 180,
},
{
title: "投诉状态",
key: "complainStatus",
width: 100,
render: (h, params) => {
if (params.row.complainStatus == "NEW") {
return h('div', [h('tag',{props: {color: "purple"}}, '新投诉'),]);
} else if (params.row.complainStatus == "CANCEL") {
return h('div', [h('tag', {props: {color: "cyan"}}, '已撤销'),]);
} else if (params.row.complainStatus == "WAIT_APPEAL") {
return h('div', [h('tag', {props: {color: "volcano"}}, '待申诉'),]);
} else if (params.row.complainStatus == "COMMUNICATION") {
return h('div', [h('tag', {props: {color: "orange"}}, '对话中'),]);
}else if (params.row.complainStatus == "WAIT_ARBITRATION") {
return h('div', [h('tag', {props: {color: "blue"}}, '等待仲裁'),]);
}else if (params.row.complainStatus == "COMPLETE") {
return h('div', [h('tag', {props: {color: "green"}}, '已完成'),]);
}
}
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 150,
render: (h, params) => {
if(params.row.complainStatus === "COMPLETE"){
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"详情"
),
]);
}else{
return h("div", [
h(
"Button",
{
props: {
type: "primary",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"处理"
),
]);
}
},
},
{ title: "会员名称", colKey: "memberName", width: 200 },
{ title: "订单编号", colKey: "orderSn", minWidth: 120, tooltip: true },
{ title: "商品名称", colKey: "goodsName", minWidth: 170, tooltip: true },
{ title: "投诉主题", colKey: "complainTopic", width: 100, tooltip: true },
{ title: "投诉时间", colKey: "createTime", width: 180 },
{ title: "投诉状态", colKey: "complainStatusTag", width: 120 },
{ title: "操作", colKey: "action", align: "center", fixed: "right", width: 150 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -222,24 +109,55 @@
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.searchForm.status = this.tabsValue === 'ALL' ? '' : this.tabsValue;
this.getDataList();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
orderSn: "",
memberName: "",
status: "",
};
this.tabsValue = 'ALL';
this.getDataList();
},
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.getOrderComplain(this.searchForm).then((res) => {
const params = Object.assign({}, this.searchForm, { status: this.tabsValue === 'ALL' ? '' : this.tabsValue });
API_Order.getOrderComplain(params)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
onTabsChange(val) {
this.tabsValue = val;
this.searchForm.pageNumber = 1;
this.searchForm.status = val === 'ALL' ? '' : val;
this.getDataList();
},
//投诉详情
detail(v) {

View File

@@ -1,6 +1,6 @@
<template>
<div class="search">
<Card>
<t-card>
<div class="main-content">
<div class="div-flow-left">
<div class="div-form-default">
@@ -90,12 +90,11 @@
<dl v-if="complaintInfo.complainStatus!='COMPLETE'">
<dt>发送对话</dt>
<dd>
<Input
<t-textarea
v-model="params.content"
type="textarea"
maxlength="200"
:maxlength="200"
:rows="4"
clearable
placeholder="请输入对话内容"
style="width:260px"
/>
</dd>
@@ -104,12 +103,12 @@
<dt></dt>
<dd>
<div style="text-align: right;width: 45%;margin-top: 10px">
<Button type="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 5px">
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit" style="margin-left: 5px">
回复
</Button>
<Button type="primary" :loading="submitLoading" @click="returnDataList" style="margin-left: 5px">
</t-button>
<t-button theme="primary" :loading="submitLoading" @click="returnDataList" style="margin-left: 5px">
返回列表
</Button>
</t-button>
</div>
</dd>
</dl>
@@ -128,21 +127,21 @@
<dl v-if="arbitrationResultShow == true">
<dt>仲裁</dt>
<dd>
<Input v-model="arbitrationParams.arbitrationResult" type="textarea" maxlength="200" :rows="4" clearable style="width:260px" />
<t-textarea v-model="arbitrationParams.arbitrationResult" :maxlength="200" :rows="4" placeholder="请输入仲裁意见" style="width:260px" />
</dd>
</dl>
<dl>
<dt></dt>
<dd style="text-align:right;display:flex; justify-content: space-between;">
<Button type="primary" ghost :loading="submitLoading" v-if="arbitrationResultShow == false" @click="arbitrationHandle">
<t-button theme="default" variant="outline" :loading="submitLoading" v-if="arbitrationResultShow == false" @click="arbitrationHandle">
直接仲裁结束投诉流程
</Button>
<Button :loading="submitLoading" v-if="complaintInfo.complainStatus == 'NEW'" @click="handleStoreComplaint">
</t-button>
<t-button :loading="submitLoading" v-if="complaintInfo.complainStatus == 'NEW'" @click="handleStoreComplaint">
交由商家申诉
</Button>
<Button type="primary" :loading="submitLoading" v-if="arbitrationResultShow == true" @click="arbitrationHandleSubmit">
</t-button>
<t-button theme="primary" :loading="submitLoading" v-if="arbitrationResultShow == true" @click="arbitrationHandleSubmit">
提交仲裁
</Button>
</t-button>
</dd>
</dl>
</div>
@@ -208,7 +207,7 @@
</div>
</div>
</div>
</Card>
</t-card>
</div>
</template>

View File

@@ -1,39 +1,50 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="100" class="search-form">
<Form-item label="订单号" prop="sn">
<Input type="text" v-model="searchForm.sn" placeholder="订单/交易号" clearable style="width: 200px" />
</Form-item>
<Form-item label="付款状态" prop="orderStatus">
<Select v-model="searchForm.payStatus" placeholder="请选择" clearable style="width: 200px">
<Option value="UNPAID">未付款</Option>
<Option value="PAID">已付款</Option>
</Select>
</Form-item>
<Form-item label="支付方式" prop="orderStatus">
<Select v-model="searchForm.paymentMethod" placeholder="请选择" clearable style="width: 200px">
<Option value="">全部</Option>
<Option value="WECHAT">微信</Option>
<Option value="ALIPAY">支付宝</Option>
<Option value="WALLET">余额</Option>
<Option value="BANK_TRANSFER">银行转账</Option>
</Select>
</Form-item>
<Form-item label="订单创建时间">
<DatePicker v-model="times" type="datetimerange" format="yyyy-MM-dd HH:mm" clearable @on-change="changeDate" placeholder="选择支付时间" style="width: 200px"></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
</Row>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small"
show-total show-elevator show-sizer></Page>
</Row>
</Card>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="订单号" name="sn">
<t-input v-model="searchForm.sn" placeholder="订单/交易号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="支付方式" name="paymentMethod">
<t-select v-model="searchForm.paymentMethod" placeholder="请选择" clearable style="width: 240px">
<t-option value="" label="全部" />
<t-option value="WECHAT" label="微信" />
<t-option value="ALIPAY" label="支付宝" />
<t-option value="WALLET" label="余额" />
<t-option value="BANK_TRANSFER" label="银行转账" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="order-tab">
<t-tabs v-model="activeStatus" @change="onStatusTabChange">
<t-tab-panel label="全部" value="ALL" />
<t-tab-panel label="未付款" value="UNPAID" />
<t-tab-panel label="已付款" value="PAID" />
</t-tabs>
</div>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id">
<template #paymentMethodTag="{ row }">
<t-tag v-if="row.paymentMethod === 'WECHAT'" theme="success" size="small" variant="light">微信</t-tag>
<t-tag v-else-if="row.paymentMethod === 'ALIPAY'" theme="primary" size="small" variant="light">支付宝</t-tag>
<t-tag v-else-if="row.paymentMethod === 'WALLET'" theme="warning" size="small" variant="light">余额支付</t-tag>
<t-tag v-else-if="row.paymentMethod === 'BANK_TRANSFER'" theme="warning" size="small" variant="light">银行转账</t-tag>
<t-tag v-else size="small" variant="light">暂未付款</t-tag>
</template>
<template #payStatusTag="{ row }">
<t-tag v-if="row.payStatus === 'PAID'" theme="success" size="small" variant="light">已付款</t-tag>
<t-tag v-else theme="danger" size="small" variant="light">未付款</t-tag>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
@@ -45,122 +56,35 @@ export default {
data() {
return {
loading: true, // 表单加载状态
activeStatus: 'ALL',
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
sn: "",
payStatus: "",
startDate: "", //订单创建时间
endDate: "", //订单结束时间
paymentMethod: "",
},
times: [], //订单创建时间
columns: [
{
title: "订单/交易编号",
key: "sn",
minWidth: 180,
tooltip: true,
},
{
title: "店铺名称",
key: "storeName",
minWidth: 100,
tooltip: true,
},
{
title: "支付方式",
key: "paymentMethod",
width: 120,
align: "center",
render: (h, params) => {
if (params.row.paymentMethod === "WECHAT") {
return h("div", [
h("Tag", { props: { color: "green" } }, "微信"),
]);
} else if (params.row.paymentMethod === "ALIPAY") {
return h("div", [
h("Tag", { props: { color: "blue" } }, "支付宝"),
]);
} else if (params.row.paymentMethod === "WALLET") {
return h("div", [
h("Tag", { props: { color: "geekblue" } }, "余额支付"),
]);
} else if (params.row.paymentMethod === "BANK_TRANSFER") {
return h("div", [
h("Tag", { props: { color: "orange" } }, "银行转帐"),
]);
} else {
return h("div", [h("Tag", {}, "暂未付款")]);
}
},
},
{
title: "第三方流水",
key: "receivableNo",
minWidth: 130,
render: (h, params) => {
return h("div", [
h("span", {}, params.row.receivableNo || "暂无流水号"),
]);
},
},
{
title: "客户端",
key: "clientType",
width: 130,
render: (h, params) => {
if (
params.row.clientType === "WECHAT_MP" ||
params.row.clientType === "小程序"
) {
return h("div", [h("span", {}, "小程序")]);
} else if (params.row.clientType === "APP") {
return h("div", [h("span", {}, "APP")]);
} else if (params.row.clientType === "PC") {
return h("div", [h("span", {}, "PC网页")]);
} else if (
params.row.clientType === "H5" ||
params.row.clientType === "wap"
) {
return h("div", [h("span", {}, "移动端")]);
}
},
},
{
title: "支付时间",
key: "paymentTime",
width: 200,
render: (h, params) => {
return h("div", [
h("span", {}, params.row.paymentTime || "暂无支付时间"),
]);
},
},
{
title: "订单金额",
fixed: "right",
key: "flowPrice",
minWidth: 80,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
},
},
{
title: "支付状态",
key: "payStatus",
width: 95,
fixed: "right",
render: (h, params) => {
if (params.row.payStatus == "PAID") {
return h("div", [h("Tag", {props:{color:'green'}}, "已付款")]);
} else {
return h("div", [h("Tag", {props:{color:'red'}}, "未付款")]);
}
},
},
{ title: "订单/交易编号", colKey: "sn", minWidth: 180, tooltip: true },
{ title: "店铺名称", colKey: "storeName", minWidth: 100, tooltip: true },
{ title: "支付方式", colKey: "paymentMethodTag", width: 120, align: "center" },
{ title: "第三方流水", colKey: "receivableNo", minWidth: 130, cell: (h, p) => h("div", [h("span", {}, p.row.receivableNo || "暂无流水号")]) },
{ title: "客户端", colKey: "clientTypeText", width: 130, cell: (h, p) => {
let text = "";
if (p.row.clientType === "WECHAT_MP" || p.row.clientType === "小程序") text = "小程序";
else if (p.row.clientType === "APP") text = "APP";
else if (p.row.clientType === "PC") text = "PC网页";
else if (p.row.clientType === "H5" || p.row.clientType === "wap") text = "移动端";
return h("span", {}, text);
} },
{ title: "支付时间", colKey: "paymentTime", width: 200, cell: (h, p) => h("span", {}, p.row.paymentTime || "暂无支付时间") },
{ title: "订单金额", colKey: "flowPrice", minWidth: 80, fixed: "right", cell: (h, p) => h("priceColorScheme", { props: { value: p.row.flowPrice, color: this.$mainColor } }) },
{ title: "支付状态", colKey: "payStatusTag", width: 95, fixed: "right" },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -182,29 +106,55 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
changeDate(val) {
// 改变日期格式
this.searchForm.startDate = val[0];
this.searchForm.endDate = val[1];
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
sn: "",
payStatus: "",
startDate: "",
endDate: "",
paymentMethod: "",
};
this.activeStatus = 'ALL';
this.getDataList();
},
onStatusTabChange(v){
this.activeStatus = v;
this.searchForm.payStatus = v === 'ALL' ? '' : v;
this.searchForm.pageNumber = 1;
this.getDataList();
},
// 获取列表
getDataList() {
this.loading = true;
API_Order.paymentLog(this.searchForm).then((res) => {
API_Order.paymentLog(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
})
.catch(() => {
this.loading = false;
});
},
},
mounted() {
@@ -212,4 +162,3 @@ export default {
},
};
</script>

View File

@@ -1,119 +1,65 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="订单号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="订单/交易号"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="退款状态">
<Select
v-model="searchForm.isRefund"
placeholder="请选择"
clearable
style="width: 200px"
>
<Option value="false">未退款</Option>
<Option value="true">已退款</Option>
</Select>
</Form-item>
<Form-item label="退款时间">
<DatePicker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 200px"
></DatePicker>
</Form-item>
<Button
@click="handleSearch"
type="primary"
icon="ios-search"
class="search-btn"
>搜索</Button
>
</Form>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
class="mt_10"
>
<template slot-scope="{ row, index }" slot="actions">
<Tag color="green" v-if="row.isRefund">已退款</Tag>
<div v-if="!row.isRefund">
<Tag v-if="!row.errorMessage" color="red">未退款</Tag>
<Tooltip v-else placement="left">
<Tag color="red">未退款<Icon type="md-help" /></Tag>
<div
slot="content"
style="white-space: normal"
v-if="row.paymentName == 'WECHAT'"
>
{{
row.errorMessage ? JSON.parse(row.errorMessage).message : ""
}}
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="订单号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="订单/交易号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="退款时间">
<t-date-picker v-model="selectDate" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" clearable @change="selectDateRange" placeholder="选择起始时间" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="order-tab">
<t-tabs v-model="activeStatus" @change="onStatusTabChange">
<t-tab-panel label="全部" value="ALL" />
<t-tab-panel label="退款" value="false" />
<t-tab-panel label="已退款" value="true" />
</t-tabs>
</div>
<div
slot="content"
style="white-space: normal"
v-if="row.paymentName == 'ALIPAY'"
>
{{ row.errorMessage || "" }}
</div>
</Tooltip>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id">
<template #actions="{ row }">
<t-tag v-if="row.isRefund" theme="success" size="small" variant="light">已退款</t-tag>
<div v-else>
<t-tag theme="danger" size="small" variant="light">未退款</t-tag>
<t-popup v-if="row.errorMessage" placement="left" trigger="hover">
<template #content>
<div style="white-space: normal">
<span v-if="row.paymentName === 'WECHAT'">{{ row.errorMessage ? JSON.parse(row.errorMessage).message : '' }}</span>
<span v-else-if="row.paymentName === 'ALIPAY'">{{ row.errorMessage || '' }}</span>
</div>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<span style="margin-left: 6px; color: #999">详情</span>
</t-popup>
</div>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "refundLog",
data() {
return {
loading: true, // 表单加载状态
activeStatus: 'ALL',
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
startDate: "", // 起始时间
@@ -124,52 +70,13 @@ export default {
// 退款起止时间
selectDate: null,
columns: [
{
title: "售后单号",
key: "afterSaleNo",
minWidth: 150,
tooltip: true,
},
{
title: "订单号",
key: "orderSn",
minWidth: 150,
tooltip: true,
},
{
title: "第三方付款流水",
key: "paymentReceivableNo",
minWidth: 150,
tooltip: true,
},
{
title: "第三方退款流水",
key: "receivableNo",
minWidth: 130,
tooltip: true,
},
{
title: "退款金额",
key: "totalAmount",
minWidth: 120,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.totalAmount,color:this.$mainColor}} );
},
},
{
title: "申请时间",
key: "createTime",
minWidth: 120,
tooltip: true,
},
{
title: "退款状态",
key: "isRefund",
align:"center",
width: 200,
slot: "actions",
},
{ title: "售后单号", colKey: "afterSaleNo", minWidth: 150, tooltip: true },
{ title: "单号", colKey: "orderSn", minWidth: 150, tooltip: true },
{ title: "第三方付款流水", colKey: "paymentReceivableNo", minWidth: 150, tooltip: true },
{ title: "第三方退款流水", colKey: "receivableNo", minWidth: 130, tooltip: true },
{ title: "退款金额", colKey: "totalAmount", minWidth: 120, cell: (h, p) => h("priceColorScheme", { props: { value: p.row.totalAmount, color: this.$mainColor } }) },
{ title: "申请时间", colKey: "createTime", minWidth: 150, tooltip: true },
{ title: "退款状态", colKey: "actions", align: "center", width: 220 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -180,21 +87,42 @@ export default {
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderSn: "",
isRefund: "",
};
this.selectDate = null;
this.activeStatus = 'ALL';
this.getDataList();
},
// 起止时间从新赋值
@@ -204,17 +132,26 @@ export default {
this.searchForm.endDate = v[1];
}
},
onStatusTabChange(v){
this.activeStatus = v;
this.searchForm.isRefund = v === 'ALL' ? '' : v;
this.searchForm.pageNumber = 1;
this.getDataList();
},
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.refundLog(this.searchForm).then((res) => {
API_Order.refundLog(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
})
.catch(() => {
this.loading = false;
});
},
},
mounted() {

View File

@@ -4,41 +4,36 @@
<Row @keydown.enter.native="handleSearch">
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="订单号" prop="orderSn">
<Input type="text" v-model="searchForm.orderSn" placeholder="请输入订单号" clearable style="width: 200px" />
<Input type="text" v-model="searchForm.orderSn" placeholder="请输入订单号" clearable style="width: 240px" />
</Form-item>
<Form-item label="会员名称" prop="buyerName">
<Input type="text" v-model="searchForm.buyerName" placeholder="请输入会员名称" clearable style="width: 200px" />
<Input type="text" v-model="searchForm.buyerName" placeholder="请输入会员名称" clearable style="width: 240px" />
</Form-item>
<!-- <Form-item label="订单状态" prop="orderStatus">-->
<!-- <Select v-model="searchForm.orderStatus" placeholder="请选择" clearable style="width: 200px">-->
<!-- <Option value="NEW">新订单</Option>-->
<!-- <Option value="CONFIRM">已确认</Option>-->
<!-- <Option value="TAKE">待核验</Option>-->
<!-- <Option value="COMPLETE">已完成</Option>-->
<!-- <Option value="WAIT_PINTUAN">待成团</Option>-->
<!-- <Option value="CANCELLED">已关闭</Option>-->
<!-- </Select>-->
<!-- </Form-item>-->
<Form-item label="下单时间">
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd" clearable
@on-change="selectDateRange" placeholder="选择起始时间" style="width: 200px"></DatePicker>
@on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
<Button @click="handleSearch" type="primary" class="search-btn">
<template #icon><t-icon name="search" /></template>
搜索
</Button>
</Form>
</Row>
</Card>
<Card>
<div class="order-tab">
<div v-for="(item,index) in orderStatus" :key="index" :class="{'current': currentStatus === item.value}" @click="orderStatusClick(item)">
{{item.title}}
</div>
<Tabs v-model="currentStatus" @on-click="orderStatusClick">
<TabPane v-for="(item,index) in orderStatus" :key="index" :label="item.title" :name="item.value">
</TabPane>
</Tabs>
</div>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10" sortable="custom"
@on-sort-change="changeSort"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total show-elevator
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small" show-total show-elevator
show-sizer></Page>
</Row>
</Card>
@@ -56,7 +51,7 @@ export default {
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
pageSize: 20, // 页面大小
sort: "", // 默认排序字段
order: "", // 默认排序方式
startDate: "", // 起始时间
@@ -90,7 +85,7 @@ export default {
} else if (params.row.clientType == "PC") {
return h("div", {}, "PC端");
} else if (params.row.clientType == "WECHAT_MP") {
return h("div", {}, "小程序");
return h("div", {}, "小程序");
} else if (params.row.clientType == "APP") {
return h("div", {}, "移动应用端");
} else {
@@ -215,7 +210,7 @@ export default {
// 搜索
handleSearch () {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 列表排序
@@ -275,8 +270,8 @@ export default {
},
// 订单筛选
orderStatusClick(item) {
this.currentStatus = item.value;
this.searchForm.orderStatus = item.value;
this.currentStatus = item; // 使用参数 item
this.searchForm.orderStatus = item; // 使用参数 item
this.getDataList();
},
},
@@ -288,23 +283,11 @@ export default {
<style lang="scss" scoped>
// Tab组件样式
.order-tab {
margin: 10px 20px 10px 0;
width: 950px;
height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #f0f0f0;
padding: 0 10px;
div {
text-align: center;
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
}
.current {
background-color: #ffffff;
margin-top: 20px;
::v-deep .ivu-tabs-tab {
font-size: 14px;
}
}
</style>

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