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
354 changed files with 16567 additions and 27537 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商城系统 ## Lilishop B2B2C商城系统
#### 欢迎交流需求,交流业务,交流技术(基础问题自行解决,其他问题先看文档后提问)
#### 不用削尖脑袋往老群里加,老群活跃度较低,很多潜水党,新群相对而言活跃一些 :tw-1f606: :tw-1f606: :tw-1f606: :tw-1f606: :tw-1f606: :tw-1f606:
#### PS **演示站点所有环境均部署master分支。如果有演示站点问题可以反馈如果演示站点没问题本地运行有问题需自行处理** #### PS **演示站点所有环境均部署master分支。如果有演示站点问题可以反馈如果演示站点没问题本地运行有问题需自行处理**
##### 交流 qq 1群 961316482已满 - **[在线客服](https://work.weixin.qq.com/kfid/kfc4d8dc24a73c15f44)**
##### 交流 qq 2群 875294241(已满) - **微信交流1群(已满)**
##### 交流 qq 3群 263785057已满 - **微信交流2群**:
##### 交流 qq 4群 674617534 (已满) ![微信群](https://lilishop-wechat.oss-cn-beijing.aliyuncs.com/wechat.jpg)
##### 交流 qq 5群 594675235
##### 体验 公众号/小程序/APP 体验,扫描二维码 ##### 体验 公众号/小程序/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) [![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)   ![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部署视频 ## 如何在本地环境运行lilishop-ui部署视频
https://www.bilibili.com/video/BV1B28EeJEnP/ https://www.bilibili.com/video/BV1B28EeJEnP/
@@ -29,8 +60,11 @@ https://www.bilibili.com/video/BV1WD87eoE9F/
## 开发项目 ## 开发项目
#### 安装Node.js #### 安装Node.js
保证`node`版本`14`,推荐 14.17.0 保证`node`版本`14`,推荐 14.17.0
2025-10-10日拉的代码之后不限制于node版本为14这里只是以14版本为例子
可以使用 `yarn` 或者 `npm` 进行安装 可以使用 `yarn` 或者 `npm` 进行安装
#### yarn 安装/启动 #### yarn 安装/启动
@@ -49,17 +83,6 @@ yarn install
yarn dev yarn dev
``` ```
#### npm 安装/启动
```
npm config set registry https://registry.npmmirror.com
// 以buyer项目为例
cd buyer
npm run install
npm run dev
```
#### FAQ #### FAQ
@@ -109,6 +132,13 @@ github 镜像: https://github.com/lilishop?tab=repositories
商城UI 项目下3个文件夹 商城UI 项目下3个文件夹
buyer买家PC端seller商家端manager后台管理端 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 PS手机验证码为 111111
@@ -223,16 +253,6 @@ PS手机验证码为 111111
4.限制商用如果需要商业使用请联系我们。QQ3409056806.或者加入qq群联系群主。 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 - `view-design@^4.3.2`
``` - `vue@^2.6.11`
npm install
```
### 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", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vue-cli-service serve",
"serve": "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": { "dependencies": {
"@amap/amap-jsapi-loader": "0.0.7", "@amap/amap-jsapi-loader": "0.0.7",
@@ -15,11 +18,10 @@
"less": "^2.7.0", "less": "^2.7.0",
"less-loader": "^5.0.0", "less-loader": "^5.0.0",
"mv-count-down": "^0.1.15", "mv-count-down": "^0.1.15",
"node-sass": "^4.14.1", "sass": "^1.63.6",
"postcss-loader": "^7.0.1", "postcss-loader": "^4.3.0",
"psl": "^1.8.0", "psl": "^1.8.0",
"qs": "^6.9.4", "qs": "^6.9.4",
"sass-loader": "^7.3.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"view-design": "^4.3.2", "view-design": "^4.3.2",
"vue": "^2.6.11", "vue": "^2.6.11",
@@ -32,7 +34,7 @@
"devDependencies": { "devDependencies": {
"@vue/cli-service": "~4.5.0", "@vue/cli-service": "~4.5.0",
"compression-webpack-plugin": "^5.0.0", "compression-webpack-plugin": "^5.0.0",
"sass-loader": "^7.3.1", "sass-loader": "^10.4.1",
"uglifyjs-webpack-plugin": "^2.2.0", "uglifyjs-webpack-plugin": "^2.2.0",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"
}, },
@@ -40,5 +42,10 @@
"> 1%", "> 1%",
"last 2 versions", "last 2 versions",
"not dead" "not dead"
] ],
"resolutions": {
"minimatch": "^3.1.2",
"node-sass": "npm:sass@^1.63.6",
"@achrinza/node-ipc": "9.2.2"
}
} }

View File

@@ -10,12 +10,10 @@ import { getBaseSite } from "@/api/common.js";
export default { export default {
name: "App", name: "App",
mounted() { mounted() {
this.init(); this.init();
}, },
methods:{ methods:{
init(){ init(){
if(!storage.getItem("siteName")||!storage.getItem("logoImg")||!storage.getItem("sitelogo_expiration_time")) { if(!storage.getItem("siteName")||!storage.getItem("logoImg")||!storage.getItem("sitelogo_expiration_time")) {
this.getSite(); this.getSite();
}else{ }else{
@@ -35,7 +33,6 @@ export default {
} }
}, },
getSite(){ getSite(){
//获取基本站点信息 //获取基本站点信息
getBaseSite().then((res) => { getBaseSite().then((res) => {

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 way 购物车购买CART/立即购买BUY_NOW / 积分购买POINT
* @param remark 备注 非必填 * @param remark 备注 非必填
*/ */

View File

@@ -10,19 +10,6 @@ export function getVerifyImg (verificationEnums) {
needToken: false needToken: false
}); });
} }
export function getImSetting(params) {
return request({
url: `/buyer/other/setting/get/IM_SETTING`,
method: Method.GET,
needToken: true,
params,
});
}
/** /**
* 验证码校验 * 验证码校验
*/ */

View File

@@ -527,44 +527,3 @@ export function getGoodsDistribution (distributionId) {
needToken: true needToken: true
}); });
} }
/**
* 获取会员发票抬头列表
*/
export function getMemberReceiptList (params) {
return request({
url: `/buyer/wallet/receipt`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 保存会员发票抬头
*/
export function setMemberReceiptList (params) {
return request({
url: `/buyer/wallet/receipt`,
method: Method.POST,
needToken: true,
data:params
});
}
/**
* 保存会员发票抬头
*/
export function delMemberReceipt(id) {
return request({
url: `/buyer/wallet/receipt/${id}`,
method: Method.DELETE,
needToken: true,
params:{id},
headers: {
"Content-Type": "application/x-www-form-urlencoded",
}
});
}

View File

@@ -173,7 +173,7 @@ export default {
border-radius: 18.9px; border-radius: 18.9px;
/deep/ .ivu-input.ivu-input-large { ::v-deep .ivu-input.ivu-input-large {
border: 1.4px solid $theme_color; border: 1.4px solid $theme_color;
box-sizing: border-box; box-sizing: border-box;
border-radius: 19.6px; 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; border-radius: 19.6px !important;
cursor: pointer; cursor: pointer;
box-sizing: border-box; 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; margin-bottom: 20px;
@include white_background_color(); @include white_background_color();
} }
/deep/ .ivu-card-head { ::v-deep .ivu-card-head {
position: relative; position: relative;
padding: 0 14px; padding: 0 14px;
height: 50px; height: 50px;
@@ -140,7 +140,7 @@ export default {
cursor: pointer; cursor: pointer;
} }
/deep/ .ivu-card-body { ::v-deep .ivu-card-body {
padding: 0 !important; padding: 0 !important;
display: none; display: none;
} }

View File

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

View File

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

View File

@@ -81,6 +81,9 @@
</DropdownMenu> </DropdownMenu>
</Dropdown> </Dropdown>
</li> </li>
<li>
<span class="nav-item" @click="shopEntry">店铺入驻</span>
</li>
</ul> </ul>
</div> </div>
@@ -159,6 +162,18 @@ export default {
}); });
} }
}, },
shopEntry() {
// 店铺入驻
if (storage.getItem('accessToken')) {
let routeUrl = this.$router.resolve({
path: '/shopEntry',
query: {id: 1}
});
window.open(routeUrl.href, '_blank');
} else {
this.$router.push('login');
}
},
getCartList() { getCartList() {
// 获取购物车列表 // 获取购物车列表
if (this.userInfo.username) { if (this.userInfo.username) {

View File

@@ -95,7 +95,11 @@ export default {
label: "宝贝收藏", label: "宝贝收藏",
path: "/home/Favorites" path: "/home/Favorites"
}, },
{
icon: "shop",
label: "收藏店铺",
path: "/home/Favorites?type=STORE"
},
{ {
icon: "carts", icon: "carts",
label: "购物车", label: "购物车",

View File

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

View File

@@ -6,11 +6,11 @@
</p> </p>
<!-- 普通发票 --> <!-- 普通发票 -->
<div class="nav-content"> <div class="nav-content">
<Form :model="invoiceForm" ref="form" label-position="left" :label-width="110"> <Form :model="invoiceForm" ref="form" label-position="left" :rules="ruleInline" :label-width="110">
<FormItem label="发票类型"> <FormItem label="发票类型">
<RadioGroup v-model="invoice" type="button" button-style="solid"> <RadioGroup v-model="invoice" type="button" button-style="solid">
<Radio @on-change="changeInvoice" :label="1">电子普通发票</Radio> <Radio @on-change="changeInvoice" :label="1">电子普通发票</Radio>
<Radio :label="2" >增值税专用发票</Radio> <Radio :label="2" :disabled="true">增值税专用发票</Radio>
</RadioGroup> </RadioGroup>
</FormItem> </FormItem>
<FormItem label="发票抬头"> <FormItem label="发票抬头">
@@ -24,46 +24,10 @@
</FormItem> </FormItem>
<FormItem label="单位名称" v-if="type === 2" prop="receiptTitle"> <FormItem label="单位名称" v-if="type === 2" prop="receiptTitle">
<i-input v-model="invoiceForm.receiptTitle"></i-input> <i-input v-model="invoiceForm.receiptTitle"></i-input>
<Poptip ref="poptip" placement="right" width="300">
<div class="global_color">选择其他发票抬头</div>
<div slot="content">
<Spin fix v-if="delReceiptLoad"></Spin>
<div class="receipt-content">
<div class="flex receipt-item" v-for="item in receiptList" :key="item.id" >
<div @click="chooseReceipt(item)">
<div class="receipt-title">{{ item.receiptTitle }}</div>
<div>{{ item.taxpayerId }}</div>
</div>
<div class="global_color" @click="delReceipt(item.id)">
删除
</div>
</div>
</div>
<div style="text-align: right;">
<Page :total="total" @on-change="changePage"
:current="searchParams.pageNumber" :page-size="searchParams.pageSize" size="small" />
</div>
</div>
</Poptip>
</FormItem> </FormItem>
<FormItem label="纳税人识别号" v-if="type === 2" prop="taxpayerId"> <FormItem label="纳税人识别号" v-if="type === 2" prop="taxpayerId">
<i-input v-model="invoiceForm.taxpayerId"></i-input> <i-input v-model="invoiceForm.taxpayerId"></i-input>
</FormItem> </FormItem>
<div v-if="type === 2" class="more" @click="showMore = !showMore">更多选填项</div>
<div v-if="showMore">
<FormItem label="单位地址" v-if="type === 2" prop="address">
<i-input v-model="invoiceForm.address"></i-input>
</FormItem>
<FormItem label="单位电话" v-if="type === 2" prop="mobile">
<i-input v-model="invoiceForm.mobile"></i-input>
</FormItem>
<FormItem label="开户银行" v-if="type === 2" prop="bank">
<i-input v-model="invoiceForm.bank"></i-input>
</FormItem>
<FormItem label="银行账号" v-if="type === 2" prop="bankNumber">
<i-input v-model="invoiceForm.bankNumber"></i-input>
</FormItem>
</div>
<FormItem label="发票内容"> <FormItem label="发票内容">
<RadioGroup v-model="invoiceForm.receiptContent" type="button" button-style="solid"> <RadioGroup v-model="invoiceForm.receiptContent" type="button" button-style="solid">
<Radio label="商品明细">商品明细</Radio> <Radio label="商品明细">商品明细</Radio>
@@ -72,10 +36,8 @@
</FormItem> </FormItem>
</Form> </Form>
<div style="text-align: center"> <div style="text-align: center">
<Button type="primary" :loading="loading" @click="submit">保存发票信息</Button>
<Button type="primary" class="mr_10" :loading="loading" @click="submit">保存发票信息</Button> <Button type="default" @click="invoiceAvailable = false">取消</Button>
<Button type="default" @click="invoiceAvailable = false">取消</Button>
</div> </div>
</div> </div>
</Modal> </Modal>
@@ -83,15 +45,11 @@
</template> </template>
<script> <script>
import { receiptSelect } from '@/api/cart.js'; import { receiptSelect } from '@/api/cart.js';
import { getMemberReceiptList ,setMemberReceiptList,delMemberReceipt } from '@/api/member.js'; import { TINumber } from '@/plugins/RegExp.js';
export default { export default {
name: 'invoiceModal', name: 'invoiceModal',
data () { data () {
return { return {
receiptList:[],
showMore:false,
delReceiptLoad:false,
invoice: 1, // 发票类型 invoice: 1, // 发票类型
invoiceAvailable: false, // 模态框显隐 invoiceAvailable: false, // 模态框显隐
loading: false, // 提交状态 loading: false, // 提交状态
@@ -101,36 +59,17 @@ export default {
taxpayerId: '', // 纳税人识别号 taxpayerId: '', // 纳税人识别号
receiptContent: '商品明细' // 发票内容 receiptContent: '商品明细' // 发票内容
}, },
isDefault:false,
type: 1, // 1 个人 2 单位 type: 1, // 1 个人 2 单位
searchParams:{ ruleInline: {
taxpayerId: [
pageNumber:1, { required: true, message: '请填写纳税人识别号' },
pageSize:5 { pattern: TINumber, message: '请填写正确的纳税人识别号' }
}, ]
total:0, }
}; };
}, },
props: ['invoiceData'], props: ['invoiceData'],
watch: { watch: {
type(val){
if(val === 2 && !this.invoiceForm.receiptTitle){
// 查找默认的发票抬头
const defaultValue = this.receiptList.find(item => item.isDefault === 1)
if(!defaultValue){
this.invoiceForm.receiptTitle = this.receiptList[0].receiptTitle
this.invoiceForm.taxpayerId = this.receiptList[0].taxpayerId
}else{
this.invoiceForm.receiptTitle = defaultValue.receiptTitle
this.invoiceForm.taxpayerId = defaultValue.taxpayerId
}
}
},
invoiceAvailable(val){
if(val){
this.getReceiptList()
}
},
// 回显的发票信息 // 回显的发票信息
invoiceData: { invoiceData: {
handler (val) { handler (val) {
@@ -146,40 +85,7 @@ export default {
immeadite: true immeadite: true
} }
}, },
mounted () {
this.getReceiptList()
},
methods: { methods: {
changePage(v){
this.searchParams.pageNumber = v;
this.getReceiptList();
},
getReceiptList () { // 获取抬头列表
getMemberReceiptList(this.searchParams).then(res => {
if (res.success) {
const list = res.result.records;
this.receiptList = list;
this.total = res.result.total
}
})
},
async delReceipt(id){
try {
this.delReceiptLoad = true
const res = await delMemberReceipt(id)
this.delReceiptLoad = false
if(res.success){
if(this.searchParams.pageNumber !==1 && this.total - 1 < this.searchParams.pageNumber * this.searchParams.pageSize){
this.searchParams.pageNumber = this.searchParams.pageNumber - 1
}
this.$Message.success('删除成功')
this.getReceiptList()
}
} catch (error) {
this.delReceiptLoad = false
}
},
/** /**
* 选择发票抬头 * 选择发票抬头
*/ */
@@ -188,16 +94,12 @@ export default {
this.type = val; this.type = val;
}); });
}, },
chooseReceipt(val){
this.$refs.poptip.visible = false
this.invoiceForm.receiptTitle = val.receiptTitle
this.invoiceForm.taxpayerId = val.taxpayerId
},
/** /**
* 保存判断 * 保存判断
*/ */
save () { save () {
let flag = true; let flage = true;
// 保存分为两种类型,个人以及企业 // 保存分为两种类型,个人以及企业
const { receiptTitle } = JSON.parse( const { receiptTitle } = JSON.parse(
@@ -206,35 +108,31 @@ export default {
// 判断是否填写发票抬头 // 判断是否填写发票抬头
if (!receiptTitle) { if (!receiptTitle) {
this.$Message.error('请填写发票抬头!'); this.$Message.error('请填写发票抬头!');
flag = false; flage = false;
return false; return false;
} }
if (this.type === 2) { if (this.type === 2) {
this.$refs.form.validate((valid) => { this.$refs.form.validate((valid) => {
if (!valid) { if (!valid) {
flag = false; flage = false;
} }
}); });
} else { } else {
delete this.invoiceForm.taxpayerId; delete this.invoiceForm.taxpayerId;
} }
return flag; return flage;
}, },
// 保存发票信息 // 保存发票信息
async submit () { async submit () {
if (this.save()) { if (this.save()) {
this.loading = true;
let submit = { let submit = {
way: this.$route.query.way, way: this.$route.query.way,
...this.invoiceForm ...this.invoiceForm
}; };
// 存储到发票列表中
await setMemberReceiptList({...submit,isDefault:this.isDefault ? 1 : 0})
this.loading = true;
let receipt = await receiptSelect(submit); let receipt = await receiptSelect(submit);
if (receipt.success) { if (receipt.success) {
this.$emit('change', true); this.$emit('change', true);
} }
@@ -258,33 +156,9 @@ export default {
color: $theme_color; color: $theme_color;
} }
} }
.global_color{
cursor: pointer;
}
.receipt-item{
justify-content: space-between;
align-items: center;
padding:8px 16px;
cursor: pointer;
line-height: 1.5;
border-bottom: 1px solid #ededed;
}
.receipt-content{
height: 280px;
}
.nav-content { .nav-content {
width: 500px; width: 500px;
margin: 10px auto; margin: 10px auto;
} }
.more{
text-align: center;
color: $theme_color;
margin-bottom: 20px;
cursor: pointer;
}
/deep/ .ivu-input{
width: 280px !important;
}
</style> </style>

View File

@@ -3,7 +3,7 @@
</template> </template>
<script> <script>
import { getIMDetail ,getImSetting} from "@/api/common"; import { getIMDetail } from "@/api/common";
import Storage from "@/plugins/storage"; import Storage from "@/plugins/storage";
import { getMemberMsg } from "@/api/login"; import { getMemberMsg } from "@/api/login";
export default { export default {
@@ -40,15 +40,9 @@ export default {
}, },
// 获取im信息 // 获取im信息
async getIMDetailMethods() { async getIMDetailMethods() {
// 获取pc im let res = await getIMDetail();
// let res = await getImSetting();
// if (res.success) {
// this.IMLink = res.result.qrCode
// }
let res = await getImSetting();
if (res.success) { if (res.success) {
window.open(res.result.url); this.IMLink = res.result;
// this.IMLink = res.result.qrCode;
} }
}, },
}, },

View File

@@ -57,6 +57,15 @@
:key="index" :key="index"
> >
<div class="shop-name"> <div class="shop-name">
<div>
<Checkbox
v-model="shop.checked"
@on-change="changeChecked(shop.checked, 'shop', shop.storeId)"
></Checkbox>
<span class="go-shop-page" @click="goShopPage(shop.storeId)">{{
shop.storeName
}}</span>
</div>
<span <span
class="shop-coupon" class="shop-coupon"
v-if="shop.couponList.length" v-if="shop.couponList.length"
@@ -537,6 +546,90 @@ export default {
padding-top: 100px; padding-top: 100px;
} }
&-items { &-items {
.shop-name {
height: 50px;
display: flex;
align-items: center;
padding: 0 20px;
position: relative;
@include title_color($light_title_color);
> * {
width: 50%;
}
.go-shop-page:hover {
color: $theme_color;
cursor: pointer;
}
.customer-service {
margin-left: 5px;
color: #fcc217;
cursor: pointer;
&:hover {
color: $theme_color;
}
}
/** 优惠券 */
.shop-coupon {
width: 80px;
height: 24px;
position: relative;
background: url(../assets/images/cart-coupon-icons02.png) 0 0 no-repeat;
> div {
position: absolute;
top: 35px;
left: 0;
width: 300px;
height: 300px;
background-color: #fff;
border: 1px solid $theme_color;
// border-radius: 3px;
z-index: 1;
padding: 10px 20px;
&::before {
content: "";
display: block;
background: url(../assets/images/cart-coupon-icons02.png) 0 -58px no-repeat;
width: 80px;
height: 12px;
position: absolute;
top: -12px;
left: 0;
}
.coupon-item {
margin-bottom: 10px;
span:nth-child(1) {
border: 1px solid #e33937;
display: inline-block;
padding: 3px 10px;
color: $theme_color;
border-radius: 3px;
}
span:nth-child(2) {
font-size: 12px;
margin-left: 5px;
color: #999;
}
.coupon-btn {
height: 26px;
float: right;
font-size: 12px;
}
&::after {
display: block;
content: "";
clear: right;
}
}
}
}
.promotion-notice {
text-align: right;
font-size: 12px;
}
.shop-coupon-show {
background-position-y: -34px;
}
}
.goods-item { .goods-item {
position: relative; position: relative;
@extend .cart-goods-title; @extend .cart-goods-title;

View File

@@ -12,8 +12,15 @@
</Breadcrumb> </Breadcrumb>
<div class="store-collect" v-if="!takeDownSale"> <div class="store-collect" v-if="!takeDownSale">
<span class="mr_10" v-if="goodsMsg.data"> <span class="mr_10" v-if="goodsMsg.data">
<router-link :to="'Merchant?id=' + goodsMsg.data.storeId">{{
goodsMsg.data.storeName
}}</router-link>
</span> </span>
<span class="ml_10" @click="getIMDetailMethods()">联系客服</span> <span @click="collect">
<Icon type="ios-heart" :color="storeCollected ? '#ed3f14' : '#666'" />
{{ storeCollected? "已收藏店铺": "收藏店铺" }}
</span>
<span class="ml_10" @click="IMService(goodsMsg.data.storeId,goodsMsg.data.goodsId,goodsMsg.data.id)">联系客服</span>
</div> </div>
</div> </div>
</div> </div>
@@ -29,12 +36,6 @@
<Button size="small" @click="target('goodsList')">返回商品列表</Button> <Button size="small" @click="target('goodsList')">返回商品列表</Button>
</div> </div>
</empty> </empty>
<Modal title="扫码联系客服" hide-footer v-model="showQrCode">
<div class="img">
<img :src="IMLink" alt="">
</div>
</Modal>
<Spin size="large" fix v-if="isLoading"></Spin> <Spin size="large" fix v-if="isLoading"></Spin>
<BaseFooter></BaseFooter> <BaseFooter></BaseFooter>
</div> </div>
@@ -67,19 +68,16 @@ export default {
mixins: [imTalk], mixins: [imTalk],
data () { data () {
return { return {
showQrCode:false,
goodsMsg: {}, // 商品信息 goodsMsg: {}, // 商品信息
isLoading: false, // 加载状态 isLoading: false, // 加载状态
categoryBar: [], // 分类 categoryBar: [], // 分类
storeCollected: false, // 商品收藏 storeCollected: false, // 商品收藏
storeMsg: {}, // 店铺信息 storeMsg: {}, // 店铺信息
takeDownSale:false, // 是否下架 takeDownSale:false, // 是否下架
IMLink:"",
// qrCode:""
}; };
}, },
methods: { methods: {
// 跳转首页或商品页面 // 跳转首页或商品页面
target(url){ target(url){
this.$router.push({path: url}) this.$router.push({path: url})
@@ -232,11 +230,4 @@ export default {
margin:10px 0 margin:10px 0
} }
.img{
text-align: center;
>img{
width: 200px;
height: 200px;
}
}
</style> </style>

View File

@@ -74,6 +74,12 @@
已有<span>{{ item.commentNum || 0 }}</span 已有<span>{{ item.commentNum || 0 }}</span
>人评价 >人评价
</div> </div>
<div class="goods-show-seller">
<span class="text-bottom" style="color: #e4393c">{{
item.storeName
}}</span>
</div>
<div class="goods-show-right"> <div class="goods-show-right">
<Tag <Tag
class="goods-show-tag" class="goods-show-tag"

View File

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

View File

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

View File

@@ -41,7 +41,7 @@
</tr> </tr>
</table> </table>
<!-- <Alert class="l_title" show-icon type="warning">商家申诉信息</Alert> <Alert class="l_title" show-icon type="warning">商家申诉信息</Alert>
<table cellspacing="0" cellpadding='0' border="1"> <table cellspacing="0" cellpadding='0' border="1">
<tr> <tr>
<td>申诉时间</td> <td>申诉时间</td>
@@ -68,7 +68,7 @@
</div> </div>
</td> </td>
</tr> </tr>
</table> --> </table>
<Alert class="l_title" show-icon type="warning">平台仲裁</Alert> <Alert class="l_title" show-icon type="warning">平台仲裁</Alert>
<table cellspacing="0" cellpadding='0' border="1"> <table cellspacing="0" cellpadding='0' border="1">

View File

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

View File

@@ -16,6 +16,7 @@
{{ item.goodsName }} {{ item.goodsName }}
</div> </div>
<div v-else class="goodsTitle hover-pointer" @click="buynow(item.skuId, item.goodsId,item.id)" > <div v-else class="goodsTitle hover-pointer" @click="buynow(item.skuId, item.goodsId,item.id)" >
{{ item.storeName }}
<Tag color="error" class="operated" v-if="item.selfOperated">商家自营</Tag> <Tag color="error" class="operated" v-if="item.selfOperated">商家自营</Tag>
</div> </div>
<div class="goodsPrice"> <div class="goodsPrice">

View File

@@ -42,8 +42,10 @@
</div> </div>
</div> </div>
</div> </div>
<div>
<div class="btns"> <span @click="shopPage(order.shopId)">{{ order.storeName }}</span>
</div>
<div>
<!-- 订单基础操作 --> <!-- 订单基础操作 -->
<Button @click="goDetail(order.sn)" type="info" size="small">售后详情</Button> <Button @click="goDetail(order.sn)" type="info" size="small">售后详情</Button>
<Button @click="openModal(order)" <Button @click="openModal(order)"
@@ -182,7 +184,14 @@ export default {
}); });
window.open(routeUrl.href, '_blank'); window.open(routeUrl.href, '_blank');
}, },
// 跳转店铺首页
shopPage(id) {
let routeUrl = this.$router.resolve({
path: '/Merchant',
query: {id: id}
});
window.open(routeUrl.href, '_blank');
},
getList() { // 获取售后列表 getList() { // 获取售后列表
this.spinShow = true; this.spinShow = true;
let params = JSON.parse(JSON.stringify(this.params)) let params = JSON.parse(JSON.stringify(this.params))
@@ -354,10 +363,4 @@ export default {
.modal-goods { .modal-goods {
padding: 5px; padding: 5px;
} }
.btns{
>*{
margin: 4px 0;
}
}
</style> </style>

View File

@@ -13,7 +13,15 @@
<p class="global_color fontsize_18">{{ afterSale.orderStatusValue }}</p> <p class="global_color fontsize_18">{{ afterSale.orderStatusValue }}</p>
<p>售后单号:{{ afterSale.sn }} &nbsp;&nbsp;&nbsp;订单号:{{afterSale.orderSn}}</p> <p>售后单号:{{ afterSale.sn }} &nbsp;&nbsp;&nbsp;订单号:{{afterSale.orderSn}}</p>
<div style="color:#999;" class="operation-time">创建时间:{{afterSale.createTime}}</div> <div style="color:#999;" class="operation-time">创建时间:{{afterSale.createTime}}</div>
<div class="service-after">
<div>
本次售后服务由<span>{{afterSale.storeName}}</span>为您提供
</div>
<div>
<img :src="afterSale.goodsImage" alt="" width="60" height="60">
<span>{{afterSale.goodsName}}</span>
</div>
</div>
</div> </div>
<div class="order-card"> <div class="order-card">
<h3>售后进程</h3> <h3>售后进程</h3>

View File

@@ -59,8 +59,10 @@
</div> </div>
</div> </div>
</div> </div>
<div>
<div class="btns"> <span @click="shopPage(order.storeId)">{{ order.storeName }}</span>
</div>
<div>
<!-- 订单基础操作 --> <!-- 订单基础操作 -->
<Button @click="orderDetail(order.sn)" type="info" size="small">订单详情</Button> <Button @click="orderDetail(order.sn)" type="info" size="small">订单详情</Button>
<Button @click="handleCancelOrder(order.sn)" type="error" v-if="order.allowOperationVO.cancel" size="small">取消订单</Button> <Button @click="handleCancelOrder(order.sn)" type="error" v-if="order.allowOperationVO.cancel" size="small">取消订单</Button>
@@ -193,7 +195,14 @@ export default {
} }
this.getList() this.getList()
}, },
// 跳转店铺首页
shopPage (id) {
let routeUrl = this.$router.resolve({
path: '/Merchant',
query: { id: id }
});
window.open(routeUrl.href, '_blank');
},
orderDetail (sn) { orderDetail (sn) {
// 跳转订单详情 // 跳转订单详情
this.$router.push({ name: 'OrderDetail', query: {sn} }); this.$router.push({ name: 'OrderDetail', query: {sn} });
@@ -382,9 +391,4 @@ export default {
} }
} }
} }
.btns{
>*{
margin: 4px 0;
}
}
</style> </style>

View File

@@ -106,7 +106,9 @@
</div> </div>
<!-- 订单商品 --> <!-- 订单商品 -->
<div class="goods"> <div class="goods">
<div class="shop-name">
<span @click="shopPage(order.order.storeId)">{{order.order.storeName}}</span>
</div>
<table> <table>
<thead> <thead>
<tr> <tr>
@@ -486,6 +488,24 @@ export default {
top: 20px; top: 20px;
} }
} }
/** 店铺名称 */
.shop-name {
margin: 15px 0;
span {
color: #438cde;
cursor: pointer;
&:hover {
color: $theme_color;
}
}
.ivu-icon {
color: #ff8f23;
cursor: pointer;
&:hover {
color: $theme_color;
}
}
}
/** 商品列表 */ /** 商品列表 */
table { table {
border: 1px solid #ddd; border: 1px solid #ddd;
@@ -584,22 +604,21 @@ table {
.layui-layer-wrap > .div-express-log { .layui-layer-wrap > .div-express-log {
max-height: 300px; max-height: 300px;
} }
/deep/ .layui-layer-wrap > .div-express-log::-webkit-scrollbar{ ::v-deep .layui-layer-wrap > .div-express-log::-webkit-scrollbar{
width: 1px; width: 1px;
height: 5px; 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; border-radius: 1em;
background-color: rgba(50,50,50,.3); 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; border-radius: 1em;
background-color: rgba(50,50,50,.1); background-color: rgba(50,50,50,.1);
} }
.div-express-log { .div-express-log {
max-height: 300px;
border: solid 1px #e7e7e7; border: solid 1px #e7e7e7;
background: #fafafa; background: #fafafa;
overflow-y: auto; overflow-y: auto;

View File

@@ -115,7 +115,13 @@
</div> </div>
<div class="goods-msg" v-for="(shop, shopIndex) in goodsList" :key="shopIndex"> <div class="goods-msg" v-for="(shop, shopIndex) in goodsList" :key="shopIndex">
<div v-if="shop.checked"> <div v-if="shop.checked">
<div class="shop-name">
<span>
<span class="hover-color" @click="goShopPage(shop.storeId)">{{
shop.storeName
}}</span>&nbsp;&nbsp;
</span>
</div>
<div class="goods-list"> <div class="goods-list">
<div class="goods-item" v-for="(goods, goodsIndex) in shop.checkedSkuList" :key="goodsIndex"> <div class="goods-item" v-for="(goods, goodsIndex) in shop.checkedSkuList" :key="goodsIndex">
<span class="hover-color" @click=" <span class="hover-color" @click="
@@ -884,6 +890,53 @@ export default {
} }
} }
/** 购买商品列表 start */
.shop-name {
display: flex;
justify-content: space-between;
>span:nth-child(1) {
font-weight: bold;
.ivu-icon {
color: #ff8f23;
&:hover {
color: $theme_color;
}
}
}
>span:nth-child(2) {
color: #999;
position: relative;
display: flex;
width: 200px;
}
.delivery-list {
position: absolute;
right: 0;
top: 20px;
background-color: #f3fafe;
box-shadow: 0px 0px 5px #b9b2b2;
display: flex;
flex-wrap: wrap;
width: 200px;
min-height: 100px;
padding: 10px;
li {
width: 90px;
height: 30px;
text-align: center;
&:hover {
cursor: pointer;
}
}
}
}
.goods-list { .goods-list {
width: 1150px; width: 1150px;

View File

@@ -32,7 +32,9 @@
已有<span>{{ item.commentNum || 0 }}</span 已有<span>{{ item.commentNum || 0 }}</span
>人评价 >人评价
</div> </div>
<div class="goods-show-seller">
<span>{{ item.storeName }}</span>
</div>
</div> </div>
</div> </div>
<div class="page-size"> <div class="page-size">

View File

@@ -66,7 +66,9 @@
: 100 : 100
" /> " />
</div> </div>
<div class="goods-show-seller">
<span>{{ item.storeName }}</span>
</div>
</div> </div>
</div> </div>
<BaseFooter /> <BaseFooter />

View File

@@ -9,7 +9,6 @@ Vue.use(Vuex);
export default new Vuex.Store({ export default new Vuex.Store({
state: { state: {
imQrCode: '',
navList: [], // 首页快捷导航 navList: [], // 首页快捷导航
cartNum: storage.getItem('cartNum') || 0, cartNum: storage.getItem('cartNum') || 0,
logoImg: storage.getItem('logoImg') || require('@/assets/images/logo2.png'), logoImg: storage.getItem('logoImg') || require('@/assets/images/logo2.png'),

View File

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

View File

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

View File

@@ -33,6 +33,11 @@ Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[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 // 引入自定义全局css
import '@/assets/css/global.less' import '@/assets/css/global.less'

View File

@@ -65,9 +65,14 @@
> --> > -->
</p> </p>
<!-- 对话列表 --> <!-- 对话列表 -->
<template v-if="loadStatus === 1"> <RecycleScroller
<div v-for="(item, index) in userTalkItem" :key="item.id" class="talk-item pointer" :item-size="64"
:class="{ active: activeIndex == index }" @click="clickTab(item.userId, item, index)"> :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"> <div class="avatar-box">
<face :text="item.face" v-if="item.face"></face> <face :text="item.face" v-if="item.face"></face>
<face-null :text="item.name" v-else></face-null> <face-null :text="item.name" v-else></face-null>
@@ -79,9 +84,7 @@
<div class="title"> <div class="title">
<div class="card-name"> <div class="card-name">
<p class="nickname"> <p class="nickname">
{{ {{ item.remark_name ? item.remark_name : item.name }}
item.remark_name ? item.remark_name : item.name
}}
</p> </p>
<div v-show="item.unread" class="larkc-tag"> <div v-show="item.unread" class="larkc-tag">
{{ item.unread }}条未读 {{ item.unread }}条未读
@@ -89,11 +92,9 @@
<div v-show="item.is_top" class="larkc-tag top"> <div v-show="item.is_top" class="larkc-tag top">
TOP TOP
</div> </div>
<div v-show="item.is_robot" class="larkc-tag top"> <div v-show="item.is_robot" class="larkc-tag top">
BOT BOT
</div> </div>
<div v-show="item.talk_type == 2" class="larkc-tag group"> <div v-show="item.talk_type == 2" class="larkc-tag group">
群组 群组
</div> </div>
@@ -111,9 +112,7 @@
<span v-if="item.lastMessageType === 'ORDER'">[订单链接]</span> <span v-if="item.lastMessageType === 'ORDER'">[订单链接]</span>
</div> </div>
<div class="content"> <div class="content">
<template v-if=" <template v-if="index_name != item.index_name && item.draft_text">
index_name != item.index_name && item.draft_text
">
<span class="draft-color">[草稿]</span> <span class="draft-color">[草稿]</span>
<span>{{ item.draft_text }}</span> <span>{{ item.draft_text }}</span>
</template> </template>
@@ -124,13 +123,12 @@
</span> </span>
<span v-else>[群消息]</span> <span v-else>[群消息]</span>
</template> </template>
<span>{{ item.msg_text }}</span> <span>{{ item.msg_text }}</span>
</template> </template>
</div> </div>
</div> </div>
</div> </div>
</template> </RecycleScroller>
</el-main> </el-main>
</el-scrollbar> </el-scrollbar>
</el-container> </el-container>
@@ -151,6 +149,8 @@
</div> </div>
</template> </template>
<script> <script>
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import { mapGetters, mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
import MainLayout from "@/views/layout/MainLayout"; import MainLayout from "@/views/layout/MainLayout";
import WelcomeModule from "@/components/layout/WelcomeModule"; import WelcomeModule from "@/components/layout/WelcomeModule";
@@ -179,6 +179,7 @@ export default {
UserSearch, UserSearch,
OtherLink, OtherLink,
WelcomeModule, WelcomeModule,
RecycleScroller
}, },
data () { data () {
return { 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 # 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 ### Customize configuration
详情点击 [https://cli.vuejs.org/zn/config/](https://cli.vuejs.org/zn/config/). 详情点击 [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行 #### login.vue页面测试时不走权限直接return 318行
#### Main.vue 页面241行修改避免报错 #### Main.vue 页面241行修改避免报错

View File

@@ -9,6 +9,9 @@
"build": "vue-cli-service build", "build": "vue-cli-service build",
"dev": "vue-cli-service serve" "dev": "vue-cli-service serve"
}, },
"engines": {
"node": ">=14"
},
"dependencies": { "dependencies": {
"@amap/amap-jsapi-loader": "0.0.7", "@amap/amap-jsapi-loader": "0.0.7",
"@antv/g2": "^4.1.12", "@antv/g2": "^4.1.12",
@@ -16,13 +19,16 @@
"core-js": "^3.6.5", "core-js": "^3.6.5",
"dplayer": "^1.26.0", "dplayer": "^1.26.0",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"node-sass": "^4.14.1", "price-color": "1.0.2",
"sass-loader": "^8.0.2", "sass": "^1.63.6",
"sass-loader": "^10.4.1",
"sockjs-client": "^1.4.0", "sockjs-client": "^1.4.0",
"swiper": "^6.3.5", "swiper": "^6.3.5",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"view-design": "^4.7.0", "tdesign-vue": "^1.14.2",
"vue": "^2.6.10", "tdesign-icons-vue": "^0.2.3",
"@vue/composition-api": "^1.7.1",
"vue": "2.6.14",
"vue-awesome-swiper": "^4.1.1", "vue-awesome-swiper": "^4.1.1",
"vue-i18n": "^8.15.1", "vue-i18n": "^8.15.1",
"vue-json-excel": "^0.3.0", "vue-json-excel": "^0.3.0",
@@ -31,8 +37,7 @@
"vue-router": "^3.1.3", "vue-router": "^3.1.3",
"vuedraggable": "^2.23.2", "vuedraggable": "^2.23.2",
"vuex": "^3.4.0", "vuex": "^3.4.0",
"xss": "^1.0.7", "xss": "^1.0.7"
"price-color": "1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^4.4.4", "@vue/cli-plugin-babel": "^4.4.4",
@@ -47,6 +52,11 @@
"style-resources-loader": "^1.3.2", "style-resources-loader": "^1.3.2",
"uglifyjs-webpack-plugin": "^2.2.0", "uglifyjs-webpack-plugin": "^2.2.0",
"vue-cli-plugin-style-resources-loader": "^0.1.4", "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 = () => { export const getBaseSite = () => {
return getRequest(`${commonUrl}/common/common/site`); return getRequestWithNoToken(`${commonUrl}/common/common/site`);
}; };
// 上传文件 // 上传文件

View File

@@ -57,15 +57,5 @@ export const auditDistributionCash = (id,params) => {
return postRequest(`/distribution/cash/audit/${id}`, params) return postRequest(`/distribution/cash/audit/${id}`, params)
} }
// 取消分销商品
export const distributionGoodsCancel = (id) => {
return deleteRequest(`/distribution/goods/cancel/${id}`)
}
// 选择分销商品
export const distributionGoodsCheck = (id,param) => {
return putRequest(`/distribution/goods/checked/${id}`,param)
}

View File

@@ -1,5 +1,5 @@
// 统一请求路径前缀在libs/axios.js中修改 // 统一请求路径前缀在libs/axios.js中修改
import { getRequest, postRequest, putRequest, deleteRequest } from '@/libs/axios'; import { getRequest, postRequest, putRequest, deleteRequest} from '@/libs/axios';
// 获取商品品牌分页列表 // 获取商品品牌分页列表
export const getManagerBrandPage = (params) => { export const getManagerBrandPage = (params) => {
@@ -7,8 +7,8 @@ export const getManagerBrandPage = (params) => {
} }
// 批量删除 // 批量删除
export const delBrand = (ids) => { export const delBrand = (ids) =>{
return deleteRequest(`/goods/brand/delByIds/${ids}`) return deleteRequest(`/goods/brand/delByIds/${ids}`)
} }
@@ -48,12 +48,12 @@ export const getSpecificationList = (params) => {
//获取分类列表数据 //获取分类列表数据
export const getAllCategoryList = (parent_id) => { export const getAllCategoryList = (parent_id) => {
return getRequest(`/goods/category/${parent_id}/all-children`) return getRequest(`/goods/category/${parent_id}/all-children`)
} }
//获取分类列表数据 //获取分类列表数据
export const getCategoryTree = () => { export const getCategoryTree = () => {
return getRequest(`/goods/category/allChildren`) return getRequest(`/goods/category/allChildren`)
} }
// 添加商品分类 // 添加商品分类
@@ -83,7 +83,7 @@ export const insertSpec = (params) => {
return postRequest('/goods/spec', params) return postRequest('/goods/spec', params)
} }
// 添加或修改规格设置 // 添加或修改规格设置
export const updateSpec = (id, params) => { export const updateSpec = (id,params) => {
return putRequest(`/goods/spec/${id}`, params) return putRequest(`/goods/spec/${id}`, params)
} }
//根据分类id获取关联规格 //根据分类id获取关联规格
@@ -101,20 +101,23 @@ export const getGoodsCategory = (parent_id) => {
} }
// 上架商品 // 上架商品
export const upGoods = (id, params) => { export const upGoods = (params) => {
return putRequest(`/goods/goods/${id}/up`, params) return putRequest(`/goods/goods/up`, params)
} }
// 下架商品 // 下架商品
export const lowGoods = (id, params) => { export const lowGoods = (params) => {
return putRequest(`/goods/goods/${id}/under`, params) return putRequest(`/goods/goods/under`, params)
} }
// 获取商品sku分页列表 // 获取商品sku分页列表
export const getGoodsSkuData = (params) => { export const getGoodsSkuData = (params) => {
return getRequest('/goods/goods/sku/list', params) return getRequest('/goods/goods/sku/list', params)
} }
// 获取商品数量
export const getGoodsNumerData = (params) => {
return getRequest('/goods/goods/goodsNumber', params)
}
// 获取商品分页列表 // 获取商品分页列表
export const getGoodsListData = (params) => { export const getGoodsListData = (params) => {
return getRequest('/goods/goods/list', params) return getRequest('/goods/goods/list', params)
@@ -124,8 +127,12 @@ export const getAuthGoodsListData = (params) => {
return getRequest('/goods/goods/auth/list', params) return getRequest('/goods/goods/auth/list', params)
} }
// 审核商品 // 审核商品
export const authGoods = (id, params) => { export const authGoods = (params) => {
return putRequest(`/goods/goods/${id}/auth`, params) return putRequest(`/goods/goods/auth`, params,{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
} }
//查询分类绑定参数信息 //查询分类绑定参数信息
@@ -170,38 +177,38 @@ export const getGoodsSpecInfo = (category_id, params) => {
//获取sku列表 //获取sku列表
export const getSkuPage = (params) => { export const getSkuPage = (params) => {
return getRequest(`/goodsSku/getByPage`, params) return getRequest(`/goodsSku/getByPage`, params)
} }
//查看商品详情 //查看商品详情
export const getGoodsDetail = (id) => { export const getGoodsDetail = (id) => {
return getRequest(`/goods/goods/get/${id}`) return getRequest(`/goods/goods/get/${id}`)
} }
// 获取订单统计图表 // 获取订单统计图表
export const getOrderChart = (params) => { export const getOrderChart = (params) => {
return getRequest(`/statistics/order`, params) return getRequest(`/statistics/order`, params)
} }
// 订单统计概览 // 订单统计概览
export const getOrderOverView = (params) => { export const getOrderOverView = (params) => {
return getRequest(`/statistics/order/overview`, params) return getRequest(`/statistics/order/overview`, params)
} }
// 统计相关订单统计 // 统计相关订单统计
export const statisticsOrderList = (params) => { export const statisticsOrderList = (params) => {
return getRequest(`/statistics/order/order`, params) return getRequest(`/statistics/order/order`, params)
} }
// 统计相关退单统计 // 统计相关退单统计
export const statisticsOrderRefundList = (params) => { export const statisticsOrderRefundList = (params) => {
return getRequest(`/statistics/order/refund`, params) return getRequest(`/statistics/order/refund`, params)
} }
@@ -225,60 +232,3 @@ export const refundStatistics = (params) => {
export const refundPriceStatistics = (params) => { export const refundPriceStatistics = (params) => {
return getRequest(`/statistics/refund/order/getPrice`, params) return getRequest(`/statistics/refund/order/getPrice`, params)
} }
// 获取草稿商品分页列表
export const getDraftGoodsListData = params => {
return getRequest("/goods/draftGoods/page", params);
};
// 获取草稿商品详情
export const getDraftGoodsDetail = id => {
return getRequest(`/goods/draftGoods/${id}`);
};
// 保存草稿商品
export function saveDraftGoods(params) {
return postRequest("/goods/draftGoods/save", params, {
"Content-Type": "application/json"
});
}
// 删除草稿商品
export const deleteDraftGoods = id => {
return deleteRequest(`/goods/draftGoods/${id}`);
};
export function createGoods(params) {
return postRequest("/goods/goods/create", params, {
"Content-Type": "application/json"
});
}
export function editGoods(goodsId, params) {
return putRequest(`/goods/goods/update/${goodsId}`, params, {
"Content-Type": "application/json"
});
}
//根据分类id获取关联品牌
export const getCategoryBrandListDataSeller = (category_id, params) => {
return getRequest(`/goods/category/${category_id}/brands`, params);
};
//查询分类绑定参数信息
export const getCategoryParamsListDataSeller = (id, params) => {
return getRequest(`/goods/categoryParameters/${id}`, params);
};
// 获取商品详情
export const getGoods = id => {
return getRequest(`/goods/goods/get/${id}`);
};
//保存获取关联规格
export const getGoodsSpecInfoSeller = (category_id) => {
return getRequest(`/goods/spec/${category_id}`);
};
// 获取商品单位列表
export const getGoodsUnitList = params => {
return getRequest(`/goods/goodsUnit`,params);
};

View File

@@ -111,7 +111,7 @@ export const changeMobile = (params) => {
}; };
// 获取用户数据 多条件 // 获取用户数据 多条件
export const getUserListData = (params) => { export const getUserListData = (params) => {
return getRequest("/passport/user", params); return getRequest("/passport/user/getByCondition", params);
}; };
// 通过用户名搜索 // 通过用户名搜索
export const searchUserByName = (username, params) => { export const searchUserByName = (username, params) => {
@@ -445,6 +445,21 @@ export const getProgress = () => {
return getRequest(`/other/elasticsearch/progress`); 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) => { export const getCustomWordsPage = (params) => {
return getRequest(`/other/customWords/page`, params); return getRequest(`/other/customWords/page`, params);

View File

@@ -42,11 +42,6 @@ export const afterSaleOrderDetail = (sn) => {
export const afterSaleSellerReview = (sn, params) => { export const afterSaleSellerReview = (sn, params) => {
return putRequest(`/order/afterSale/review/${sn}`, params) return putRequest(`/order/afterSale/review/${sn}`, params)
} }
//查询包裹列表
export const getPackage = (orderSn) => {
return getRequest(`/order/order/getPackage/${orderSn}`);
}
// 商家确认收货 // 商家确认收货
export const afterSaleSellerConfirm = (sn, params) => { export const afterSaleSellerConfirm = (sn, params) => {
@@ -131,7 +126,10 @@ export const getAfterSaleOrderDetail = (sn) => {
export const getAfterSaleTraces = (sn) => { export const getAfterSaleTraces = (sn) => {
return getRequest(`/order/afterSale/getDeliveryTraces/${sn}`) return getRequest(`/order/afterSale/getDeliveryTraces/${sn}`)
} }
// 获取商家选中的物流公司
export const getLogisticsChecked = () => {
return getRequest(`/other/logistics/getChecked`)
}
//查询物流 //查询物流
export const getTraces = (sn, params) => { export const getTraces = (sn, params) => {
@@ -163,18 +161,12 @@ export const storeAddress = (sn) => {
return getRequest(`/order/afterSale/getStoreAfterSaleAddress/${sn}`) return getRequest(`/order/afterSale/getStoreAfterSaleAddress/${sn}`)
} }
// 订单核验 // 获取订单数量统计
export const orderTake = (sn, verificationCode) => { export const getOrderNum = (params) => {
return putRequest(`/order/order/take/${sn}/${verificationCode}`); return getRequest(`/order/order/orderNum`, params)
}; }
//分包裹发货 // 获取售后数量统计
export const partDelivery = (orderSn,params) => { export const getAfterSaleNumVO = (params) => {
return postRequest(`/order/order/${orderSn}/partDelivery`,params,{ return getRequest(`/order/afterSale/afterSaleNumVO`, params)
"Content-type": "application/json"
})
} }
// 修改订单备注
export const modifyOrderRemark = (sn, params) => {
return putRequest(`/order/order/${sn}/sellerRemark`, params);
};

View File

@@ -114,5 +114,5 @@ export const getPrivacy = (type) => {
} }
//修改隐私协议数据 //修改隐私协议数据
export const updatePrivacy = (id,type,params) => { 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

@@ -281,32 +281,3 @@ export const deletePointsGoodsCategoryById = id => {
export const getCouponReceiveList = (params) => { export const getCouponReceiveList = (params) => {
return getRequest("/promotion/coupon/received", params); return getRequest("/promotion/coupon/received", params);
}; };
// 新增满减活动
export const newFullDiscount = (params) => {
return postRequest(`/promotion/fullDiscount`, params, { 'Content-type': 'application/json' })
}
// 编辑满减活动
export const editFullDiscount = (params) => {
return putRequest(`/promotion/fullDiscount`, params, { 'Content-type': 'application/json' })
}
// 新建 拼团
export const savePintuan = (params) => {
return postRequest('/promotion/pintuan', params, { 'Content-type': 'application/json' })
}
// 编辑 拼团
export const editPintuan = (params) => {
return putRequest('/promotion/pintuan', params, { 'Content-type': 'application/json' })
}
// 添加限时抢购 商品
export const setSeckillGoods = (params) => {
return postRequest(`/promotion/seckill/apply/${params.seckillId}`, params.applyVos, { 'Content-type': 'application/json' })
}
// 添加限时抢购 商品
export const removeSeckillGoods = (seckillId, ids) => {
return deleteRequest(`/promotion/seckill/apply/${seckillId}/${ids}`)
}

View File

@@ -1,5 +1,5 @@
// 统一请求路径前缀在libs/axios.js中修改 // 统一请求路径前缀在libs/axios.js中修改
import {getRequest, postRequest, putRequest,deleteRequest} from '@/libs/axios'; import {getRequest, postRequest, putRequest} from '@/libs/axios';
//查询店铺列表 //查询店铺列表
export const getBillPage = (params) => { export const getBillPage = (params) => {
@@ -87,40 +87,3 @@ export const downloadBill = (id) => {
return getRequest(`/order/bill/downLoad/${id}`, {}, 'blob') return getRequest(`/order/bill/downLoad/${id}`, {}, 'blob')
} }
//查询运费模板
export const getShipTemplate = () => {
return getRequest(`/setting/freightTemplate`)
}
export const replyMemberComment = (id, params) => {
return putRequest(`/member/evaluation/reply/${id}`, params)
}
//删除运费模板
export const deleteShipTemplate = (id) => {
return deleteRequest(`/setting/freightTemplate/${id}`)
}
//新增运费模板
export const addShipTemplate = (params, headers) => {
return postRequest(`/setting/freightTemplate`, params, headers)
}
//编辑运费模板
export const editShipTemplate = (id, params, headers) => {
return putRequest(`/setting/freightTemplate/${id}`, params, headers)
}
// 获取商家自提点
export const getShopAddress = (id, params) => {
return getRequest(`/store/member/storeAddress/`, params)
}
export const editShopAddress = (id, params) => {
return putRequest(`/store/member/storeAddress/${id}`, params)
}
export const addShopAddress = (params) => {
return postRequest(`/store/member/storeAddress/`, params)
}
export const deleteShopAddress = (id) => {
return deleteRequest(`/store/member/storeAddress/${id}`)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

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

@@ -10,7 +10,14 @@
{{ item.year + '年' + item.month + '月' }}</Option> {{ item.year + '年' + item.month + '月' }}</Option>
</Select> </Select>
</div> </div>
<div class="shop-list" v-if="!closeShop">
<Select clearable @on-change="changeshop(selectedWay)" v-model="storeId" placeholder="店铺查询"
style="width:200px;margin-left:10px;">
<Scroll :on-reach-bottom="handleReachBottom">
<Option v-for="(item, index) in shopsData" :value="item.id" :key="index">{{ item.storeName }}</Option>
</Scroll>
</Select>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -33,7 +40,7 @@ export default {
params: { params: {
// 请求参数 // 请求参数
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 20,
storeName: "", storeName: "",
}, },
dateList: [ dateList: [

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
<template> <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"> <template v-if="flag">
<goodsDialog <goodsDialog
@selected=" @selected="
@@ -21,7 +21,7 @@
class="linkDialog" class="linkDialog"
/> />
</template> </template>
</Modal> </t-dialog>
</template> </template>
<script> <script>
import goodsDialog from "./goods-dialog"; import goodsDialog from "./goods-dialog";
@@ -86,11 +86,11 @@ export default {
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/deep/ .ivu-modal { ::v-deep .t-dialog {
overflow: hidden; overflow: hidden;
height: 650px !important; height: 650px !important;
} }
/deep/ .ivu-modal-body { ::v-deep .t-dialog__body {
width: 100%; width: 100%;
height: 500px; height: 500px;
overflow: hidden; overflow: hidden;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,12 +4,12 @@
<div class="query-wrapper"> <div class="query-wrapper">
<div class="query-item"> <div class="query-item">
<div>店铺名称</div> <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" /> v-model="params.storeName" />
</div> </div>
<div class="query-item"> <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> </div>
<div> <div>
@@ -25,19 +25,16 @@
<div class="wap-sku" :class="{'theme_color':(item.storeDisable === 'OPEN' ? true : false) }">{{ item.storeDisable === 'OPEN' ? '开启中' : '未开启' }}</div> <div class="wap-sku" :class="{'theme_color':(item.storeDisable === 'OPEN' ? true : false) }">{{ item.storeDisable === 'OPEN' ? '开启中' : '未开启' }}</div>
</div> </div>
</div> </div>
<Spin size="large" fix v-if="loading"></Spin> <t-loading v-if="loading" :loading="true" fullscreen></t-loading>
</div> </div>
<Page <t-pagination
:total="total" :current="params.pageNumber"
class="pageration" :total="Number(total)"
@on-change="changePageSize" :pageSize="params.pageSize"
:page-size="params.pageSize"
size="small" size="small"
show-total :showJumper="true"
show-elevator @change="onPaginationChange"
/>
>
</Page>
</div> </div>
</div> </div>
</div> </div>
@@ -65,8 +62,9 @@ export default {
this.init(); this.init();
}, },
methods: { methods: {
changePageSize(v){ onPaginationChange({ current, pageSize }){
this.params.pageNumber = v; this.params.pageNumber = current;
this.params.pageSize = pageSize;
this.init(); this.init();
}, },
init() { init() {

View File

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

View File

@@ -5,16 +5,7 @@
<h3> <h3>
内容设置 内容设置
</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> </Drawer>
</div> </div>
</template> </template>

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,222 +0,0 @@
<template>
<Modal :mask-closable="false" :value="switched" v-model="switched" title="选择地址" @on-ok="submit" @on-cancel="cancel">
<div class="flex">
<Spin size="large" fix v-if="spinShow"></Spin>
<Tree ref="tree" class="tree" :data="data" expand-node show-checkbox multiple></Tree>
</div>
</Modal>
</template>
<script>
import { getAllCity } from "@/api/index";
export default {
data() {
return {
switched: false, // 控制模态框显隐
spinShow: false, // 加载loading
data: [], // 地区数据
selectedWay: [], // 选择的地区
callBackData: "", // 打开组件的回显数据
};
},
mounted() {
this.init();
},
methods: {
clear() { // 引用该组件的父组件会调用
this.data = [];
this.selectedWay = [];
this.init();
},
/**
* 关闭
*/
cancel() {
this.switched = false;
// 关闭的时候所有数据设置成disabled为true
this.data.forEach((item) => {
this.$set(item, "disabled", false);
item.children.forEach((child) => {
this.$set(child, "disabled", false);
});
});
},
/**
* 打开地图选择器
* @param {val} 回调的数据
* @param {index} 当前操作的运费模板的索引
*/
open(val, index) {
if (val) {
//已选中的地址
let checkedData = this.$store.state.shipTemplate;
let checkData = [];
let disabledData = checkedData.filter((item, i) => {
if (i != index) {
return i != index;
} else {
checkData.push(item);
}
});
// 选中
checkData.forEach((check) => {
// 循环出已经选中的地址id
check.areaId.split(",").forEach((ids) => {
this.data.forEach((item) => {
// 如果当前省份下市区全部选中则选中该省份
if (check.selectedAll) {
check.area.split(",").forEach((area) => {
if (area == item.name) {
this.$set(item, "checked", true);
}
});
}
// 将市区继续循环
item.children.forEach((child, childIndex) => {
// 判断当前市区是否是已选中状态
if (item.checked) {
this.$set(child, "checked", true);
}
if (child.id == ids) {
this.$set(child, "checked", true);
}
});
});
});
});
// 禁用
disabledData.forEach((dis) => {
// 循环出已经选中的地址id
dis.areaId.split(",").forEach((ids) => {
// 循环出省份
this.data.forEach((item) => {
// 如果当前省份下市区全部选中则禁用该省份
if (dis.selectedAll) {
dis.area.split(",").forEach((area) => {
if (area == item.name) {
this.$set(item, "disabled", true);
}
});
}
// 将市区继续循环
item.children.forEach((child, childIndex) => {
// 判断当前市区是否是已禁用状态
if (item.disabled) {
this.$set(child, "disabled", true);
} else {
if (child.id == ids) {
this.$set(child, "disabled", true);
}
}
});
});
});
});
}
this.switched ? (this.switched = true) : (this.switched = true);
},
/**
* 提交并筛选出省市
*/
submit() {
// 筛选出省市
let list = this.$refs.tree.getCheckedAndIndeterminateNodes();
let sort = [];
list.forEach((item, i) => {
item.selectedList = [];
item.selectedAll = false;
// 筛选出当前的省份
if (item.level == "province" && !item.disabled) {
sort.push({
...item,
});
}
// 筛选出当前选中的市
sort.forEach((sortItem, sortIndex) => {
if (
item.level != "province" &&
sortItem.id == item.parentId &&
!item.disabled
) {
sortItem.selectedList.push({
...item,
});
}
});
});
// 判断如果当前省是否全选
this.data.forEach((whether) => {
sort.forEach((item) => {
// 如果当前省匹配
if (
item.id == whether.id &&
item.selectedList.length == whether.children.length
) {
// 给一个全选子级的标识符
item.selectedList.forEach((child) => {
this.$set(child, "selectedAll", true);
});
this.$set(item, "selectedAll", true);
}
});
});
this.$emit("selected", sort);
this.cancel();
},
// 初始化地区数据
init() {
getAllCity().then((res) => {
if (res.result) {
res.result.forEach((item) => {
item.children.forEach((child) => {
child.title = child.name;
});
let data = {
title: item.name,
...item,
};
this.data.push(data);
this.selectedWay.push({ name: data.title, id: data.id });
});
this.$store.state.regions = this.data;
}
});
},
},
};
</script>
<style scoped lang="scss">
.flex {
display: flex;
position: relative;
}
.tree {
flex: 2;
}
.form {
flex: 8;
}
.button-list {
margin-left: 80px;
> * {
margin: 0 4px;
}
}
/deep/ .ivu-modal-body {
height: 400px !important;
overflow: auto;
}
</style>

View File

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

View File

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

View File

@@ -237,6 +237,17 @@ util.initRouterNode = function(routers, data) {
for (let item of data) { for (let item of data) {
let menu = Object.assign({}, item); 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); menu.component = lazyLoading(menu.frontRoute);
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {

View File

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

View File

@@ -1,9 +1,14 @@
// The Vue build version to load with the `import` command // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue' import Vue from 'vue'
import ViewUI from 'view-design'
// import 'view-design/dist/styles/iview.css'
import './styles/theme.less'; 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 "core-js/stable"
// import "regenerator-runtime/runtime" // import "regenerator-runtime/runtime"
@@ -61,11 +66,467 @@ Vue.prototype.wapLinkTo = function (goodsId, skuId) {
import priceColorScheme from 'price-color' import priceColorScheme from 'price-color'
Vue.use(priceColorScheme); Vue.use(priceColorScheme);
const copyViewUi = {...ViewUI} Vue.use(VueCompositionApi)
copyViewUi.Input.props.maxlength.default = inputMaxLength // 挂载最大输入值 Vue.use(TDesign)
Vue.use(copyViewUi, { Vue.component('t-icon', TIcon)
i18n: (key, value) => i18n.t(key, value), 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) Vue.component('liliDialog', liliDialog)
@@ -84,6 +545,7 @@ Vue.prototype.removeStore = removeStore;
Vue.prototype.$mainColor = mainColor; Vue.prototype.$mainColor = mainColor;
Vue.prototype.md5 = md5; Vue.prototype.md5 = md5;
Array.prototype.remove = function (from, to) { Array.prototype.remove = function (from, to) {
var rest = this.slice((to || from) + 1 || this.length); var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from; this.length = from < 0 ? this.length + from : from;

View File

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

View File

@@ -31,20 +31,6 @@ export const otherRouter = {
meta: { title: "个人中心" }, meta: { title: "个人中心" },
component: () => import("@/views/personal-center/personal-center.vue") component: () => import("@/views/personal-center/personal-center.vue")
}, },
{
path: "pickup",
title: "自提点设置",
name: "pickup",
meta: { title: "自提点设置" },
component: () => import("@/views/sys/setting-manage/pickup.vue")
},
{
path: "goods-publish",
title: "商品发布",
name: "goods-publish",
meta: { title: "商品发布" },
component: () => import("@/views/goods/goodsOperation.vue")
},
{ {
path: "change-password", path: "change-password",
title: "修改密码", title: "修改密码",
@@ -69,12 +55,6 @@ export const otherRouter = {
name: "shop", name: "shop",
component: () => import("@/views/seller/shop/shopList.vue") component: () => import("@/views/seller/shop/shopList.vue")
}, },
{
path: "shipTemplate",
title: "自提点设置",
name: "shipTemplate",
component: () => import("@/views/logistics/shipTemplate.vue")
},
{ {
path: "shop-detail", path: "shop-detail",
title: "店铺详细", title: "店铺详细",
@@ -255,12 +235,6 @@ export const otherRouter = {
name: "pintuan-goods", name: "pintuan-goods",
component: () => import("@/views/promotions/pintuan/pintuan-goods.vue") component: () => import("@/views/promotions/pintuan/pintuan-goods.vue")
}, },
{
path: "promotions/pintuan/pintuan-create",
title: "添加拼团活动",
name: "pintuan-create",
component: () => import("@/views/promotions/pintuan/pintuan-create.vue")
},
{ {
path: "promotions/full-discount-detail", path: "promotions/full-discount-detail",
title: "满减满折详情", title: "满减满折详情",

View File

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

View File

@@ -19,10 +19,9 @@
width: 100% !important; width: 100% !important;
display: flex; display: flex;
align-items: center; align-items: center;
background-color: #f0f0f0; // background-color: #f0f0f0;
border-radius: 0.4em; border-radius: 0.4em;
padding: 10px;
margin: 0;
flex-wrap: wrap; flex-wrap: wrap;
> .ivu-form-item { > .ivu-form-item {
margin: 8px 10px !important; margin: 8px 10px !important;
@@ -42,3 +41,8 @@
-webkit-line-clamp: 4; -webkit-line-clamp: 4;
overflow: hidden; 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; @primary-color: #ff5c58;
@info-color: #fa6419; @info-color: #fa6419;
@success-color: #68cabe; @success-color: #68cabe;
@@ -11,9 +8,3 @@
@table-td-highlight-bg: #ededed; @table-td-highlight-bg: #ededed;
@font-size-base: 12px; @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") { } else if (val == "PC") {
return "PC端"; return "PC端";
} else if (val == "WECHAT_MP") { } else if (val == "WECHAT_MP") {
return "小程序"; return "小程序";
} else if (val == "APP") { } else if (val == "APP") {
return "移动应用端"; return "移动应用端";
} else { } else {

View File

@@ -93,12 +93,3 @@ export const REQUIRED = {
required: true, required: true,
message:'请填写参数' message:'请填写参数'
} }
export const WHITE_SPACE = {
whitespace: true,
message: "不可为纯空格",
}
export const VARCHAR60 = {
pattern: /^.{1,60}$/,
message: '长度应该限制在1-60个字符'
}

View File

@@ -12,7 +12,7 @@
<shrinkable-menu></shrinkable-menu> <shrinkable-menu></shrinkable-menu>
</div> </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="main-header">
<div class="header-avator-con"> <div class="header-avator-con">
<!-- 左侧栏 --> <!-- 左侧栏 -->
@@ -37,42 +37,34 @@
</Tooltip> </Tooltip>
</li> </li>
</ul> </ul>
<Dropdown <t-dropdown>
transfer
trigger="hover"
@on-click="handleClickUserDropdown"
>
<div class="dropList"> <div class="dropList">
<span class="main-user-name">{{ userInfo.nickName }}</span> <span class="main-user-name">{{ userInfo.nickName }}</span>
<Avatar <t-avatar
icon="ios-person" :image="avatarPath"
:src="avatarPath"
style="background: #fff; margin-left: 10px" style="background: #fff; margin-left: 10px"
></Avatar> ></t-avatar>
</div> </div>
<DropdownMenu slot="list"> <t-dropdown-menu>
<DropdownItem name="personalCenter">{{ <t-dropdown-item @click="handleClickUserDropdown('personalCenter')">{{
$t("userCenter") $t("userCenter")
}}</DropdownItem> }}</t-dropdown-item>
<DropdownItem name="changePass">{{ <t-dropdown-item @click="handleClickUserDropdown('changePass')">{{
$t("changePass") $t("changePass")
}}</DropdownItem> }}</t-dropdown-item>
<DropdownItem name="loginOut" divided>{{ <t-dropdown-item @click="handleClickUserDropdown('loginOut')">{{
$t("logout") $t("logout")
}}</DropdownItem> }}</t-dropdown-item>
</DropdownMenu> </t-dropdown-menu>
</Dropdown> </t-dropdown>
</Row> </Row>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- 已打开的页面标签 -->
<div class="tags-con" v-if="setting.isUseTabsRouter">
<tags-page-opened :pageTagsList="pageTagsList"></tags-page-opened>
</div>
</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"> <div class="single-page">
<!-- <keep-alive :include="cachePage"> --> <!-- <keep-alive :include="cachePage"> -->
<router-view></router-view> <router-view></router-view>
@@ -88,7 +80,6 @@
<script> <script>
import shrinkableMenu from "./main-parts/shrinkable-menu/shrinkable-menu.vue"; 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 messageTip from "./main-parts/message-tip.vue";
import circleLoading from "@/components/lili/circle-loading.vue"; import circleLoading from "@/components/lili/circle-loading.vue";
import configDrawer from "@/components/lili/config-drawer.vue"; import configDrawer from "@/components/lili/config-drawer.vue";
@@ -102,7 +93,7 @@ const config = require("@/config/index.js");
export default { export default {
components: { components: {
shrinkableMenu, shrinkableMenu,
tagsPageOpened,
messageTip, messageTip,
circleLoading, circleLoading,
configDrawer configDrawer
@@ -125,9 +116,6 @@ export default {
loading() { loading() {
return this.$store.state.app.loading; return this.$store.state.app.loading;
}, },
pageTagsList() {
return this.$store.state.app.pageOpenedList; // 打开的页面的页面对象
},
avatarPath() { avatarPath() {
return localStorage.avatorImgPath; return localStorage.avatorImgPath;
}, },
@@ -145,7 +133,7 @@ export default {
let userInfo = JSON.parse(Cookies.get("userInfoManager")); let userInfo = JSON.parse(Cookies.get("userInfoManager"));
this.userInfo = userInfo; this.userInfo = userInfo;
this.checkTag(this.$route.name);
let currWidth = document.body.clientWidth; let currWidth = document.body.clientWidth;
if (currWidth <= 1200) { if (currWidth <= 1200) {
this.sliceNum = 2; 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() { resize() {
let currWidth = document.body.clientWidth; let currWidth = document.body.clientWidth;
@@ -225,10 +197,6 @@ export default {
}, },
}, },
watch: { watch: {
$route(to, from) {
this.checkTag(to.name);
localStorage.currentPageName = to.name;
},
}, },
mounted() { mounted() {
this.init(); this.init();
@@ -239,8 +207,6 @@ export default {
}); });
}, },
created() { created() {
// 显示打开的页面的列表
this.$store.commit("setOpenedList");
}, },
}; };
</script> </script>

View File

@@ -1,51 +1,25 @@
<template> <template>
<div class="search"> <div class="search">
<Card> <t-card>
<Row class="operation"> <div class="operation">
<Button @click="add" type="primary">添加</Button> <t-button @click="add" theme="primary">添加</t-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
>
</div> </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> </div>
</template> </template>
@@ -58,6 +32,7 @@ import {
} from "@/api/index"; } from "@/api/index";
import { regular } from "@/utils"; import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default { export default {
name: "custom-words", name: "custom-words",
data() { data() {
@@ -69,7 +44,7 @@ export default {
searchForm: { searchForm: {
// 搜索框初始化对象 // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段 sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式 order: "desc", // 默认排序方式
words: "", words: "",
@@ -86,82 +61,16 @@ export default {
], ],
}, },
submitLoading: false, // 添加或编辑提交状态 submitLoading: false, // 添加或编辑提交状态
selectList: [], // 多选数据 selectList: [],
selectCount: 0, // 多选计数 selectCount: 0,
selectedRowKeys: [],
columns: [ columns: [
// 表头 { colKey: "row-select", type: "multiple", width: 60, align: "center" },
{ { title: "自定义分词", colKey: "name", minWidth: 120 },
type: "selection", { title: "创建时间", colKey: "createTime", width: 200 },
width: 60, { title: "更新时间", colKey: "updateTime", width: 200 },
align: "center", { title: "操作人", colKey: "createBy", minWidth: 150 },
}, { title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
{
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);
},
},
},
"删除"
),
]);
},
},
], ],
data: [], // 表单数据 data: [], // 表单数据
total: 0, // 表单数据总数 total: 0, // 表单数据总数
@@ -171,25 +80,25 @@ export default {
init() { init() {
this.getDataList(); this.getDataList();
}, },
changePage(v) { onPaginationChange({ current, pageSize }) {
this.searchForm.pageNumber = v; this.searchForm.pageNumber = current;
this.searchForm.pageSize = pageSize;
this.getDataList(); this.getDataList();
this.clearSelectAll(); this.clearSelectAll();
}, },
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
handleSearch() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.getDataList(); this.getDataList();
}, },
clearSelectAll() { 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.selectList = e;
this.selectCount = e.length; this.selectCount = e.length;
}, },
@@ -218,7 +127,7 @@ export default {
insertCustomWords(this.form).then((res) => { insertCustomWords(this.form).then((res) => {
this.submitLoading = false; this.submitLoading = false;
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.getDataList(); this.getDataList();
this.modalVisible = false; this.modalVisible = false;
} }
@@ -229,7 +138,7 @@ export default {
updateCustomWords(this.form).then((res) => { updateCustomWords(this.form).then((res) => {
this.submitLoading = false; this.submitLoading = false;
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.getDataList(); this.getDataList();
this.modalVisible = false; this.modalVisible = false;
} }
@@ -242,8 +151,8 @@ export default {
add() { add() {
this.modalType = 0; this.modalType = 0;
this.modalTitle = "添加"; this.modalTitle = "添加";
this.form = {} this.form = { name: "" };
this.$refs.form.resetFields(); if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
this.modalVisible = true; this.modalVisible = true;
}, },
@@ -257,17 +166,14 @@ export default {
}, },
// 删除 // 删除
remove(v) { remove(v) {
this.$Modal.confirm({ DialogPlugin.confirm({
title: "确认删除", header: "确认删除",
// 记得确认修改此处
content: "您确认要删除 " + v.name + " ?", content: "您确认要删除 " + v.name + " ?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
// 删除
delCustom(v.id).then((res) => { delCustom(v.id).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.getDataList(); this.getDataList();
} }
}); });
@@ -277,24 +183,20 @@ export default {
// 批量删除 // 批量删除
delAll() { delAll() {
if (this.selectCount <= 0) { if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据"); MessagePlugin.warning("您还未选择要删除的数据");
return; return;
} }
this.$Modal.confirm({ DialogPlugin.confirm({
title: "确认删除", header: "确认删除",
content: "您确认要删除所选的 " + this.selectCount + " 条数据?", content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
let ids = ""; let ids = "";
this.selectList.forEach(function (e) { this.selectList.forEach(function (e) { ids += e.id + ","; });
ids += e.id + ",";
});
ids = ids.substring(0, ids.length - 1); ids = ids.substring(0, ids.length - 1);
// 批量删除
delSensitive(ids).then((res) => { delSensitive(ids).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.clearSelectAll(); this.clearSelectAll();
this.getDataList(); this.getDataList();
} }

View File

@@ -1,435 +1,164 @@
<template> <template>
<div> <div>
<Card> <t-card style="margin-bottom: 12px">
<Row @keydown.enter.native.prevent="handleSearch"> <t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<Form <t-form-item label="会员名称" name="memberName">
ref="searchForm" <t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
:model="searchForm" </t-form-item>
inline
:label-width="70" <t-form-item>
class="search-form" <t-button theme="primary" @click="handleSearch">搜索</t-button>
> </t-form-item>
<Form-item label="会员名称" prop="memberName"> </t-form>
<Input </t-card>
type="text" <t-card>
v-model="searchForm.memberName" <t-tabs :value="activeStatus" @change="onStatusTabChange" class="status-tabs">
placeholder="请输入会员名称" <t-tab-panel label="全部" value="ALL" />
clearable <t-tab-panel v-for="item in distributionStatusList" :key="item.value" :label="item.label" :value="item.value" />
style="width: 200px" </t-tabs>
/> <t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
</Form-item> <div class="mt_10" style="display: flex; justify-content: flex-end">
<Form-item label="状态"> <t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
<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>
</div> </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> </div>
</template> </template>
<script> <script>
import {editDistribution, getDistributionListData, resumeDistribution, retreatDistribution} from "@/api/distribution"; import { editDistribution, getDistributionListData, resumeDistribution, retreatDistribution } from "@/api/distribution";
import {distributionStatusList} from "./dataJson.js"; import { distributionStatusList } from "./dataJson.js";
import {regular} from "@/utils"; import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default { export default {
name: "distribution", name: "distribution",
components: {},
data() { data() {
return { return {
distributionStatusList, // 分销状态 distributionStatusList,
loading: true, // 表单加载状态 loading: true,
modalVisible: false, // 添加或编辑显示 modalVisible: false,
activeStatus: 'ALL',
distributionForm: { distributionForm: {
name: "", name: "",
idNumber: "", idNumber: "",
settlementBankAccountName: "", settlementBankAccountName: "",
settlementBankAccountNum: "", settlementBankAccountNum: "",
settlementBankBranchName: "" settlementBankBranchName: "",
}, },
// 表单验证规则 submitLoading: false,
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, // 编辑提交状态
searchForm: { searchForm: {
// 搜索框初始化对象 pageNumber: 1,
pageNumber: 1, // 当前页数 pageSize: 20,
pageSize: 10, // 页面大小 memberName: "",
distributionStatus: "",
}, },
columns: [ columns: [
{ { title: "会员名称", colKey: "memberName", minWidth: 120, align: "left", tooltip: true },
title: "会员名称", { title: "姓名", colKey: "name", minWidth: 100, align: "left" },
key: "memberName", { title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
minWidth: 120, { title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
tooltip: true, { title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
}, { title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ { title: "推广单数", colKey: "distributionOrderCount", minWidth: 120, width: 150, align: "left" },
title: "姓名", { 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', '-') },
key: "name", { 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', '-') },
minWidth: 100, { 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) => {
title: "身份证号", const s = p.row.distributionStatus;
key: "idNumber", const map = { PASS: { theme: "success", label: "通过" }, APPLY: { theme: "warning", label: "待审核" }, RETREAT: { theme: "warning", label: "清退" }, REFUSE: { theme: "danger", label: "拒绝" } };
minWidth: 120, const cfg = map[s] || { theme: "default", label: s };
}, return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
{ } },
title: "结算银行开户行名称", { title: "操作", colKey: "action", align: "center", fixed: "right", width: 180, cell: (h, p) => {
key: "settlementBankAccountName", return h("div", { class: "ops" }, [
minWidth: 120, 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) } }, ["编辑"]),
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",
},
})
]
);
},
},
], ],
data: [], // 表单数据 data: [],
total: 0, // 表单数据总数 total: 0,
}; };
}, },
methods: { methods: {
// 初始化数据 init() { this.getDataList(); },
init() { changePage(v) { this.searchForm.pageNumber = v; this.getDataList(); },
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(); },
changePage(v) { onStatusTabChange(v) { this.activeStatus = v; this.searchForm.pageNumber = 1; this.getDataList(); },
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();
},
// 获取列表数据
getDataList() { getDataList() {
this.loading = true; this.loading = true;
this.searchForm.status = "PASS"; this.searchForm.distributionStatus = this.activeStatus === 'ALL' ? '' : this.activeStatus;
getDistributionListData(this.searchForm).then((res) => { getDistributionListData(this.searchForm).then((res) => {
this.loading = false; this.loading = false;
if (res.success) { if (res.success) {
this.data = res.result.records; this.data = res.result.records;
this.total = res.result.total; this.total = res.result.total;
} }
}); }).catch(() => { this.loading = false; });
}, },
// 清退分销商
retreat(v) { retreat(v) {
this.$Modal.confirm({ DialogPlugin.confirm({
title: "提示", header: "确认清退",
// 记得确认修改此处
content: "您确认要清退 " + v.memberName + " ?", content: "您确认要清退 " + v.memberName + " ?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
// 删除 retreatDistribution(v.id).then((res) => { if (res.success) { MessagePlugin.success("操作成功"); this.getDataList(); } });
retreatDistribution(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
}
});
}, },
}); });
}, },
// 恢复分销商
resume(v) { resume(v) {
this.$Modal.confirm({ DialogPlugin.confirm({
title: "提示", header: "确认恢复",
// 记得确认修改此处
content: "您确认要恢复 " + v.memberName + " ?", content: "您确认要恢复 " + v.memberName + " ?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
// 删除 resumeDistribution(v.id).then((res) => { if (res.success) { MessagePlugin.success("操作成功"); this.getDataList(); } });
resumeDistribution(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
}
});
}, },
}); });
}, },
// 编辑
edit(v) { edit(v) {
this.$refs.distributionForm.resetFields(); const data = JSON.parse(JSON.stringify(v));
// 转换null为"" for (let attr in data) { if (data[attr] === null) { data[attr] = ""; } }
for (let attr in v) {
if (v[attr] === null) {
v[attr] = "";
}
}
let str = JSON.stringify(v);
let data = JSON.parse(str);
this.distributionForm = data; this.distributionForm = data;
this.modalVisible = true; this.modalVisible = true;
}, },
// 提交表单
handleSubmit() { handleSubmit() {
this.$refs.distributionForm.validate((valid) => { editDistribution(this.distributionForm).then((res) => {
if (valid) { this.submitLoading = false;
// 编辑 if (res.success) { MessagePlugin.success("操作成功"); this.getDataList(); this.modalVisible = false; }
editDistribution(this.distributionForm).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
});
}
}); });
}, },
}, },
mounted() { mounted() { this.init(); },
this.init();
},
}; };
</script> </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> <template>
<div> <div>
<Card> <t-card style="margin-bottom: 12px">
<Row @keydown.enter.native.prevent="handleSearch"> <t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<Form <t-form-item label="会员名称" name="memberName">
ref="searchForm" <t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
:model="searchForm" </t-form-item>
inline <t-form-item>
:label-width="70" <t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
class="search-form" </t-form-item>
> </t-form>
<Form-item label="会员名称" prop="memberName"> </t-card>
<Input <t-card>
type="text" <t-table class="mt_10" :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id"></t-table>
v-model="searchForm.memberName" <div class="mt_10" style="display: flex; justify-content: flex-end">
placeholder="请输入会员名称" <t-pagination
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
:current="searchForm.pageNumber" :current="searchForm.pageNumber"
:total="total" :total="Number(total)"
:page-size="searchForm.pageSize" :pageSize="searchForm.pageSize"
@on-change="changePage" :pageSizeOptions="[20, 50, 100]"
@on-page-size-change="changePageSize"
:page-size-opts="[10, 20, 50]"
size="small" size="small"
show-total :showJumper="true"
show-elevator @change="onPaginationChange"
show-sizer />
></Page> </div>
</Row> </t-card>
</Card>
</div> </div>
</template> </template>
<script> <script>
import { auditDistribution, getDistributionListData } from "@/api/distribution"; import { auditDistribution, getDistributionListData } from "@/api/distribution";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default { export default {
name: "distributionApply", name: "distributionApply",
@@ -63,67 +39,31 @@ export default {
searchForm: { searchForm: {
// 搜索框初始化对象 // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段 sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式 order: "desc", // 默认排序方式
startDate: "", // 起始时间 startDate: "", // 起始时间
endDate: "", // 终止时间 endDate: "", // 终止时间
}, },
columns: [ columns: [
{ { title: "会员名称", colKey: "memberName", minWidth: 100, align: "left", tooltip: true },
title: "会员名称", { title: "姓名", colKey: "name", minWidth: 100, align: "left" },
key: "memberName", { title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
minWidth: 100, { title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
tooltip: true, { title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
}, { title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ { title: "提交时间", colKey: "createTime", minWidth: 120, align: "left" },
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: "操作", title: "操作",
key: "action", colKey: "action",
align: "center", align: "center",
fixed: "right", fixed: "right",
width: 200, width: 200,
render: (h, params) => { cell: (h, params) => {
return h("div", [ return h("div", { class: "ops" }, [
h( h(
"Button", "a",
{ {
props: {
type: "success",
size: "small",
},
style: {
marginRight: "5px",
},
on: { on: {
click: () => { click: () => {
this.audit(params.row, "PASS"); this.audit(params.row, "PASS");
@@ -132,13 +72,10 @@ export default {
}, },
"通过" "通过"
), ),
h("span", {}, "|"),
h( h(
"Button", "a",
{ {
props: {
type: "error",
size: "small",
},
on: { on: {
click: () => { click: () => {
this.audit(params.row, "REFUSE"); this.audit(params.row, "REFUSE");
@@ -160,56 +97,59 @@ export default {
init() { init() {
this.getDataList(); this.getDataList();
}, },
// 分页 改变页码
changePage(v) { changePage(v) {
this.searchForm.pageNumber = v; this.searchForm.pageNumber = v;
this.getDataList(); this.getDataList();
this.clearSelectAll();
}, },
// 分页 改变页数
changePageSize(v) { changePageSize(v) {
this.searchForm.pageSize = v; this.searchForm.pageSize = v;
this.getDataList(); 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() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 20;
this.getDataList(); this.getDataList();
}, },
// 获取列表数据 // 获取列表数据
getDataList() { getDataList() {
this.loading = true; this.loading = true;
this.searchForm.distributionStatus = "APPLY"; this.searchForm.distributionStatus = "APPLY";
getDistributionListData(this.searchForm).then((res) => { getDistributionListData(this.searchForm)
this.loading = false; .then((res) => {
if (res.success) { this.loading = false;
this.data = res.result.records; if (res.success) {
this.total = res.result.total; this.data = res.result.records;
} this.total = res.result.total;
}); }
this.total = this.data.length; })
this.loading = false; .catch(() => {
this.loading = false;
});
}, },
//审核 //审核
audit(v, status) { audit(v, status) {
let test = "拒绝"; let test = "拒绝";
if (status == "PASS") { if (status === "PASS") {
test = "通过"; test = "通过";
} }
let params = { const params = { status };
status: status, DialogPlugin.confirm({
}; header: "确认" + test,
this.$Modal.confirm({
title: "确认" + test,
// 记得确认修改此处
content: "您确认要" + test + " " + v.memberName + " ?", content: "您确认要" + test + " " + v.memberName + " ?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
auditDistribution(v.id, params).then((res) => { auditDistribution(v.id, params).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.getDataList(); this.getDataList();
} }
}); });
@@ -222,3 +162,15 @@ export default {
}, },
}; };
</script> </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> <template>
<div> <div>
<Card> <t-card style="margin-bottom: 12px">
<Form ref="searchForm" @keydown.enter.native.prevent="handleSearch" :model="searchForm" class="search-form"> <t-form :data="searchForm" layout="inline" class="search-form" @submit="handleSearch">
<Form-item label="会员名称" class="flex" prop="memberName"> <t-form-item label="会员名称" name="memberName">
<Input <t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
type="text" placeholder="请输入会员名称" v-model="searchForm.memberName" clearable </t-form-item>
style="width: 200px"></Input> <t-form-item label="编号" name="sn">
</Form-item> <t-input v-model="searchForm.sn" placeholder="请输入编号" clearable style="width: 240px" />
<Form-item label="编号" class="flex"> </t-form-item>
<Input <t-form-item label="状态">
type="text" placeholder="请输入编号" v-model="searchForm.sn" clearable <t-select v-model="searchForm.distributionCashStatus" clearable style="width: 240px">
style="width: 200px"></Input> <t-option v-for="item in cashStatusList" :value="item.value" :key="item.value" :label="item.label" />
</Form-item> </t-select>
<Form-item label="状态" </t-form-item>
style="width: 200px"> <t-form-item>
<Select v-model="searchForm.distributionCashStatus" clearable style="width: 150px"> <t-button theme="primary" @click="handleSearch">搜索</t-button>
<Option v-for="item in cashStatusList" :value="item.value" :key="item.value">{{ item.label }}</Option> </t-form-item>
</Select> </t-form>
</Form-item> </t-card>
<Form-item> <t-card>
<Button @click="handleSearch" type="primary">搜索</Button> <t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
</Form-item> <div class="page padding-row" style="display: flex; justify-content: flex-end">
</Form> <t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
<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>
</div> </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> </div>
</template> </template>
<script> <script>
import { import { auditDistributionCash, getDistributionCash } from "@/api/distribution";
auditDistributionCash, import { cashStatusList } from "./dataJson";
getDistributionCash import { MessagePlugin, DialogPlugin } from "tdesign-vue";
} from "@/api/distribution";
import { cashStatusList } from './dataJson';
export default { export default {
name: "distributionCash", name: "distributionCash",
data() { data() {
@@ -70,7 +87,7 @@ export default {
result: 'FAIL_AUDITING', // 是否通过 result: 'FAIL_AUDITING', // 是否通过
searchForm: { // 搜索框初始化对象 searchForm: { // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段 sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式 order: "desc", // 默认排序方式
}, },
@@ -82,129 +99,65 @@ export default {
}, },
submitLoading: false, // 添加或编辑提交状态 submitLoading: false, // 添加或编辑提交状态
columns: [ columns: [
{ 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: "编号", title: "状态",
key: "sn", colKey: "distributionCashStatus",
minWidth: 200 minWidth: 120,
}, align: "left",
{ cell: (h, p) => {
title: "会员名称", const s = p.row.distributionCashStatus;
key: "distributionName", const map = { APPLY: { theme: "warning", label: "待处理" }, VIA_AUDITING: { theme: "success", label: "通过" }, FAIL_AUDITING: { theme: "danger", label: "审核拒绝" } };
minWidth: 120 const cfg = map[s] || { theme: "default", label: s };
}, return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
{
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: "状态",
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", "审核拒绝");
}
},
},
{ {
title: "操作", title: "操作",
key: "action", colKey: "action",
align: "center", align: "center",
fixed: "right", fixed: "right",
width: 130, width: 130,
render: (h, params) => { cell: (h, params) => {
if(params.row.distributionCashStatus != 'APPLY'){ if (params.row.distributionCashStatus !== "APPLY") {
return h("div", [ return h("div", { class: "ops" }, [
h( h(
"Button", "a",
{ {
props: { on: {
type: "primary", click: () => {
size: "small", this.view(params.row);
}, },
style: {
marginRight: "5px"
},
on: {
click: () => {
this.view(params.row);
}
}
}, },
"查看" },
), "查看"
),
]); ]);
}else {
return h("div", [
h(
"Button",
{
props: {
type: "primary",
size: "small",
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.edit(params.row);
}
}
},
"审核"
),
]);
} }
} return h("div", { class: "ops" }, [
} h(
"a",
{
on: {
click: () => {
this.edit(params.row);
},
},
},
"审核"
),
]);
},
},
], ],
data: [], // 表单数据 data: [], // 表单数据
total: 0 // 表单数据总数 total: 0 // 表单数据总数
@@ -225,59 +178,68 @@ export default {
this.searchForm.pageSize = v; this.searchForm.pageSize = v;
this.getDataList(); 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() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 20;
this.getDataList(); this.getDataList();
}, },
// 获取列表数据
getDataList() { getDataList() {
this.loading = true; this.loading = true;
// 带多条件搜索参数获取表单数据 请自行修改接口 getDistributionCash(this.searchForm)
getDistributionCash(this.searchForm).then(res => { .then((res) => {
this.loading = false; this.loading = false;
if (res.success) { if (res.success) {
this.data = res.result.records; this.data = res.result.records;
this.total = res.result.total; this.total = res.result.total;
} }
}); })
this.total = this.data.length; .catch(() => {
this.loading = false; this.loading = false;
});
}, },
// 通过还是拒绝申请 // 通过还是拒绝申请
handleSubmit() { handleSubmit() {
let result = "拒绝" let result = "拒绝";
if(this.result == 'VIA_AUDITING'){ if (this.result === "VIA_AUDITING") {
result = "通过" result = "通过";
} }
this.$refs.form.validate(valid => { DialogPlugin.confirm({
if (valid) { header: "确认审核",
this.$Modal.confirm({ content: "您确认要审核" + result + "么?",
title: "确认审核", theme: "warning",
content: "您确认要审核"+result+"么?", onConfirm: () => {
loading: true, this.submitLoading = true;
onOk: () => { auditDistributionCash(this.form.id, { result: this.result })
auditDistributionCash(this.form.id,{result:this.result}).then(res => { .then((res) => {
if (res.success) { this.submitLoading = false;
this.$Modal.remove(); if (res.success) {
this.$Message.success("审核成功"); MessagePlugin.success("审核成功");
this.getDataList(); this.getDataList();
this.modalVisible = false; this.modalVisible = false;
} else { } else {
this.modalVisible = false; this.modalVisible = false;
} }
}); })
} .catch(() => {
}) this.submitLoading = false;
} });
},
}); });
}, },
// 弹出modal 审核 // 弹出modal 审核
edit(v) { edit(v) {
this.modalTitle = "审核"; this.modalTitle = "审核";
this.handleStatus = 'edit'; this.handleStatus = 'edit';
this.$refs.form.resetFields(); if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
// 转换null为"" // 转换null为""
for (let attr in v) { for (let attr in v) {
if (v[attr] === null) { if (v[attr] === null) {
@@ -291,7 +253,7 @@ export default {
view(v){ view(v){
this.modalTitle = "查看"; this.modalTitle = "查看";
this.handleStatus = 'view'; this.handleStatus = 'view';
this.$refs.form.resetFields(); if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
// 转换null为"" // 转换null为""
for (let attr in v) { for (let attr in v) {
if (v[attr] === null) { if (v[attr] === null) {
@@ -310,3 +272,15 @@ export default {
} }
}; };
</script> </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,70 +1,45 @@
<template> <template>
<div> <div>
<Card> <t-card style="margin-bottom: 12px">
<Form @keydown.enter.native.prevent="handleSearch" ref="searchForm" :model="searchForm" inline :label-width="70" <t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
class="search-form"> <t-form-item label="商品名称" name="goodsName">
<Form-item label="商品名称" prop="goodsName"> <t-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 200px" /> </t-form-item>
</Form-item> <t-form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button> <t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</Form> </t-form-item>
<Row class="operation" style="margin:10px 0;"> </t-form>
<Button @click="add" type="primary">添加</Button> </t-card>
<t-card>
<Button @click="delAll" type="primary">批量下架</Button> <div class="operation padding-row">
</Row> <t-button theme="primary" @click="delAll">批量下架</t-button>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom" </div>
@on-selection-change="changeSelect"> <t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onSelectChange">
<template slot="goodsName" slot-scope="{row}"> <template #goodsName="{ row }">
<div> <div>
<div class="div-zoom"> <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>
<Poptip trigger="hover" title="扫码在手机中查看" transfer> <t-popup trigger="hover" placement="top" :showArrow="true">
<div slot="content"> <template #content>
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" <vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150" />
:size="150"></vue-qr> </template>
</div> <img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="" />
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt=""> </t-popup>
</Poptip>
</div> </div>
</template> </template>
</Table> </t-table>
<Row type="flex" justify="end" class="mt_10"> <div class="mt_10" style="display: flex; justify-content: flex-end">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" <t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
@on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" size="small" show-total show-elevator
show-sizer></Page>
</Row>
</Card>
<liliDialog
ref="liliDialog"
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
<FormItem label="分销佣金" prop="commission">
<Input v-model="form.commission" clearable style="width: 100%"/>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交
</Button
>
</div> </div>
</Modal> </t-card>
</div> </div>
</template> </template>
<script> <script>
import { delDistributionGoods, getDistributionGoods,distributionGoodsCheck } from "@/api/distribution"; import { delDistributionGoods, getDistributionGoods } from "@/api/distribution";
import vueQr from "vue-qr"; import vueQr from "vue-qr";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default { export default {
components: { components: {
"vue-qr": vueQr, "vue-qr": vueQr,
@@ -72,107 +47,75 @@ export default {
name: "distributionGoods", name: "distributionGoods",
data() { data() {
return { return {
modalVisible: false, // 添加或编辑显示
modalTitle: "", // 添加或编辑标题
form:{
commission : 1 // 分销金额
},
loading: true, // 表单加载状态 loading: true, // 表单加载状态
searchForm: { searchForm: {
// 搜索框初始化对象 // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段 sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式 order: "desc", // 默认排序方式
}, },
selectList: [], // 多选数据 selectList: [],
selectCount: 0, // 多选计数 selectCount: 0,
selectedRowKeys: [],
columns: [ columns: [
// 表头 // 表头
{
type: "selection",
width: 60,
align: "center",
fixed: "left",
},
{ {
title: "商品图片", title: "商品图片",
fixed: "left", fixed: "left",
key: "thumbnail", colKey: "thumbnail",
width: 120, width: 120,
align: "center", align: "center",
render: (h, params) => { cell: (h, p) => h("img", { attrs: { src: p.row.thumbnail || "", alt: "加载图片失败" }, style: { cursor: "pointer", width: "80px", height: "60px", margin: "10px 0", objectFit: "contain" } }),
return h("img", {
attrs: {
src: params.row.thumbnail || '',
alt: "加载图片失败",
},
style: {
cursor: "pointer",
width: "80px",
height: "60px",
margin: "10px 0",
"object-fit": "contain",
},
});
},
}, },
{ {
title: "商品名称", title: "商品名称",
slot: "goodsName", colKey: "goodsName",
minWidth: 200, minWidth: 200,
tooltip: true, tooltip: true,
}, },
{ {
title: "商品价格", title: "商品价格",
key: "price", colKey: "price",
minWidth: 100, minWidth: 100,
render: (h, params) => { cell: (h, p) => h("priceColorScheme", { props: { value: p.row.price, color: this.$mainColor } }),
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
},
}, },
{ {
title: "库存", title: "库存",
key: "quantity", colKey: "quantity",
minWidth: 80, minWidth: 80,
}, },
{ {
title: "添加时间", title: "添加时间",
key: "createTime", colKey: "createTime",
minWidth: 100, minWidth: 100,
}, },
{ {
title: "店铺名称", title: "店铺名称",
key: "storeName", colKey: "storeName",
minWidth: 100, minWidth: 100,
tooltip: true, tooltip: true,
}, },
{ {
title: "佣金金额", title: "佣金金额",
key: "commission", colKey: "commission",
minWidth: 100, minWidth: 100,
sortable: false, sortable: false,
render: (h, params) => { cell: (h, p) => h("priceColorScheme", { props: { value: p.row.commission, color: this.$mainColor } }),
return h("priceColorScheme", {props:{value:params.row.commission,color:this.$mainColor}} );
},
}, },
{ {
title: "操作", title: "操作",
key: "action", colKey: "action",
align: "center", align: "center",
fixed: "right", fixed: "right",
minWidth: 100, minWidth: 100,
render: (h, params) => { cell: (h, params) => {
return h("div", [ return h("div", { class: "ops" }, [
h( h(
"Button", "a",
{ {
props: {
type: "error",
size: "small",
},
on: { on: {
click: () => { click: () => {
this.remove(params.row); this.remove(params.row);
@@ -185,53 +128,15 @@ export default {
}, },
}, },
], ],
submitLoading: false, // 添加或编辑提交状态
data: [], // 表单数据 data: [], // 表单数据
total: 0, // 表单数据总数 total: 0, // 表单数据总数
skuId:0,
formValidate: {
commission: [
{ required: true, message: '请输入大于1小于9999的合法分销金额'},
{
pattern: /^[1-9]\d{0,3}(\.\d{1,2})?$/,
message: "请输入大于1小于9999的合法分销金额",
trigger: "change"
}],
},
}; };
}, },
methods: { methods: {
// 选择商品回调
selectedGoodsData(v){
this.modalVisible = true
this.form.commission = 1
this.modalTitle = "保存分销商品"
this.skuId = v[0].id
},
// 添加商品
handleSubmit(){
this.$refs['form'].validate((valid) => {
if (valid) {
distributionGoodsCheck(this.skuId,this.form).then(res => {
if(res.message === 'success') {
this.$Message.success("添加成功");
}
this.modalVisible = false
this.getDataList()
});
}
})
},
add(){
this.$refs.liliDialog.flag = true;
this.$refs.liliDialog.goodsFlag = true;
this.$refs.liliDialog.singleGoods();
},
// 初始化数据 // 初始化数据
init() { init() {
this.getDataList(); this.getDataList();
}, },
// 分页 改变页码
changePage(v) { changePage(v) {
this.searchForm.pageNumber = v; this.searchForm.pageNumber = v;
this.getDataList(); this.getDataList();
@@ -242,46 +147,55 @@ export default {
this.searchForm.pageSize = v; this.searchForm.pageSize = v;
this.getDataList(); 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() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 20;
this.getDataList(); this.getDataList();
}, },
// 清除选中状态
clearSelectAll() { clearSelectAll() {
this.$refs.table.selectAll(false); this.selectedRowKeys = [];
this.selectList = [];
this.selectCount = 0;
}, },
// 选中后赋值 onSelectChange(keys, { selectedRowData }) {
changeSelect(e) { this.selectedRowKeys = keys;
this.selectList = e; this.selectList = selectedRowData || [];
this.selectCount = e.length; this.selectCount = keys.length;
}, },
// 获取列表数据 // 获取列表数据
getDataList() { getDataList() {
this.loading = true; this.loading = true;
getDistributionGoods(this.searchForm).then((res) => { getDistributionGoods(this.searchForm)
this.loading = false; .then((res) => {
if (res.success) { this.loading = false;
this.data = res.result.records; if (res.success) {
this.total = res.result.total; this.data = res.result.records;
} this.total = res.result.total;
}); }
this.total = this.data.length; })
this.loading = false; .catch(() => {
this.loading = false;
});
}, },
// 下架商品 // 下架商品
remove(v) { remove(v) {
this.$Modal.confirm({ DialogPlugin.confirm({
title: "确认下架", header: "确认下架",
content: "您确认要下架么?", content: "您确认要下架么?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
// 下架
delDistributionGoods(v.id).then((res) => { delDistributionGoods(v.id).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("下架成功"); MessagePlugin.success("下架成功");
this.getDataList(); this.getDataList();
} }
}); });
@@ -291,23 +205,18 @@ export default {
// 批量下架 // 批量下架
delAll() { delAll() {
if (this.selectCount <= 0) { if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要下架的数据"); MessagePlugin.warning("您还未选择要下架的数据");
return; return;
} }
this.$Modal.confirm({ DialogPlugin.confirm({
title: "确认下架", header: "确认下架",
content: "您确认要下架所选的 " + this.selectCount + " 条数据?", content: "您确认要下架所选的 " + this.selectCount + " 条数据?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
let ids = []; const ids = (this.selectList || []).map((item) => item.id);
this.selectList.forEach((item) => {
ids.push(item.id);
});
// 批量下架
delDistributionGoods(ids.toString()).then((res) => { delDistributionGoods(ids.toString()).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("下架成功"); MessagePlugin.success("下架成功");
this.clearSelectAll(); this.clearSelectAll();
this.getDataList(); this.getDataList();
} }
@@ -321,5 +230,17 @@ export default {
}, },
}; };
</script> </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,68 +1,62 @@
<template> <template>
<div> <div>
<Card> <t-card style="margin-bottom: 12px">
<Form ref="searchForm" @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70" class="search-form"> <t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<Form-item label="订单编号" prop="orderSn"> <t-form-item label="订单编号" name="orderSn">
<Input <t-input v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
type="text" </t-form-item>
v-model="searchForm.orderSn" <t-form-item label="分销商" name="distributionName">
placeholder="请输入订单编号" <t-input v-model="searchForm.distributionName" placeholder="请输入分销商名称" clearable style="width: 240px" />
clearable </t-form-item>
style="width: 200px" <t-form-item label="店铺名称">
/> <t-select v-model="searchForm.storeId" placeholder="请选择" :filterable="true" clearable style="width: 240px" @input-change="searchChange">
</Form-item> <t-option v-for="item in shopList" :value="item.id" :key="item.id" :label="item.storeName" />
<Form-item label="分销商" prop="distributionName"> </t-select>
<Input </t-form-item>
type="text" <t-form-item label="订单时间">
v-model="searchForm.distributionName" <t-date-picker v-model="timeRange" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" placeholder="选择时间" style="width: 240px" />
placeholder="请输入分销商名称" </t-form-item>
clearable <t-form-item>
style="width: 200px" <t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
/> </t-form-item>
</Form-item> </t-form>
<Form-item label="订单时间"> </t-card>
<DatePicker type="daterange" v-model="timeRange" format="yyyy-MM-dd" placeholder="选择时间" <t-card>
style="width: 210px"></DatePicker> <t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id">
</Form-item> <template #goodsMsg="{ row }">
<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">
<div class="goods-msg"> <div class="goods-msg">
<img :src="row.image" width="60" height="60" alt=""> <img :src="row.image" width="60" height="60" alt="" />
<div> <div>
<div class="div-zoom"> <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>
<div style="color:#999;font-size:10px">数量x{{row.num}}</div> <div style="color:#999;font-size:10px">数量x{{ row.num }}</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer> <t-popup trigger="hover" placement="top" :showArrow="true">
<div slot="content"> <template #content>
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr> <vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150" />
</div> </template>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt=""> <img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="" />
</Poptip> </t-popup>
</div> </div>
</div> </div>
</template> </template>
<template slot-scope="{row}" slot="distributionOrderStatus"> <template #distributionOrderStatus="{ row }">
<Tag :color="filterStatusColor(row.distributionOrderStatus)">{{filterStatus(row.distributionOrderStatus)}}</Tag> <t-tag :theme="filterStatusColor(row.distributionOrderStatus) === 'green' ? 'success' : (filterStatusColor(row.distributionOrderStatus) === 'orange' ? 'warning' : 'danger')" size="small" variant="light">{{ filterStatus(row.distributionOrderStatus) }}</t-tag>
</template> </template>
</Table> </t-table>
<Row type="flex" justify="end" class="mt_10"> <div class="mt_10" style="display: flex; justify-content: flex-end">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" <t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
@on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" </div>
size="small" show-total show-elevator show-sizer></Page> </t-card>
</Row>
</Card>
</div> </div>
</template> </template>
<script> <script>
import { import { getDistributionOrder } from "@/api/distribution";
getDistributionOrder import { orderStatusList } from "./dataJson";
} from "@/api/distribution"; import { getShopListData } from "@/api/shops";
import {orderStatusList} from './dataJson' import vueQr from "vue-qr";
import vueQr from 'vue-qr' import { MessagePlugin } from "tdesign-vue";
export default { export default {
name: "distributionOrder", name: "distributionOrder",
@@ -71,60 +65,25 @@
}, },
data() { data() {
return { return {
timeRange: [], // 范围时间 timeRange: undefined, // 范围时间
orderStatusList, // 订单状态列表 orderStatusList, // 订单状态列表
shopList: [], // 店铺列表
distributionId: this.$route.query.id, // 分销id distributionId: this.$route.query.id, // 分销id
loading: true, // 表单加载状态 loading: true, // 表单加载状态
searchForm: { // 搜索框初始化对象 searchForm: { // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort:"create_time", sort:"create_time",
order:"desc" order:"desc"
}, },
columns: [ columns: [
{ { title: "订单编号", colKey: "orderSn", minWidth: 180, fixed: "left", tooltip: true },
title: "订单编号", { title: "商品信息", colKey: "goodsMsg", minWidth: 180 },
key: "orderSn", { title: "分销商", colKey: "distributionName", tooltip: true, minWidth: 120 },
minWidth: 180, { title: "店铺名称", colKey: "storeName", minWidth: 120, tooltip: true },
fixed: "left", { title: "状态", colKey: "distributionOrderStatus", minWidth: 120 },
tooltip: true { 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 },
{
title: '商品信息',
slot: 'goodsMsg',
minWidth: 150
},
{
title: "分销商",
key: "distributionName",
tooltip: true,
minWidth:80,
},
{
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,
}
], ],
data: [], // 表单数据 data: [], // 表单数据
total: 0 // 表单数据总数 total: 0 // 表单数据总数
@@ -134,49 +93,78 @@
// 初始化数据 // 初始化数据
init() { init() {
this.getDataList(); this.getDataList();
this.getShopList()
}, },
//分页 改变页码
changePage(v) { changePage(v) {
this.searchForm.pageNumber = v; this.searchForm.pageNumber = v;
this.getDataList(); this.getDataList();
}, },
// 分页 改变页数
changePageSize(v) { changePageSize(v) {
this.searchForm.pageSize = v; this.searchForm.pageSize = v;
this.getDataList(); 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() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 20;
this.getDataList(); this.getDataList();
}, },
// 获取列表数据 // 获取列表数据
getDataList() { getDataList() {
this.searchForm.distributionId = this.distributionId; this.searchForm.distributionId = this.distributionId;
this.loading = true; this.loading = true;
if (this.timeRange && this.timeRange[0]) { if (Array.isArray(this.timeRange) && this.timeRange.length === 2) {
let startTime = this.timeRange[0] const startTime = this.timeRange[0]
let endTime = this.timeRange[1] const endTime = this.timeRange[1]
this.searchForm.startTime = this.$options.filters.unixToDate(startTime / 1000) this.searchForm.startTime = this.$options.filters.unixToDate(startTime / 1000)
this.searchForm.endTime = this.$options.filters.unixToDate(endTime / 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)
this.loading = false; .then((res) => {
if (res.success) { this.loading = false;
this.data = res.result.records; if (res.success) {
this.data = res.result.records;
this.total = res.result.total; this.total = res.result.total;
} }
}); })
this.total = this.data.length; .catch(() => {
this.loading = false; this.loading = false;
});
}, },
getShopList(val) { // 获取店铺列表 搜索用
const params = {
pageNumber: 1,
pageSize: 20,
storeName: ''
}
if (val) {
params.storeName = val;
} else {
params.storeName = ''
}
getShopListData(params).then(res => {
this.shopList = res.result.records
})
},
searchChange(val) { // 店铺搜索,键盘点击回调
this.getShopList(val)
},
filterStatus (status) { // 过滤订单状态 filterStatus (status) { // 过滤订单状态
const arr = [ const arr = [
{status: 'WAIT_BILL', title: '待结算'}, {status: 'NO_COMPLETED', title: '未完成'},
{status: 'COMPLETE', title: '完成'}, {status: 'COMPLETE', title: '完成'},
{status: 'REFUND', title: '退款'}, {status: 'REFUND', title: '退款'},
] ]
@@ -185,21 +173,20 @@
return arr[i].title; return arr[i].title;
} }
} }
return '未完成'; // 默认返回未完成
}, },
filterStatusColor (status) { // 状态tag标签颜色 filterStatusColor (status) { // 状态tag标签颜色
const arr = [ const arr = [
{status: 'WAIT_BILL', color: 'blue'}, {status: 'NO_COMPLETED', color: 'orange'},
{status: 'WAIT_CASH', color: 'orange'}, {status: 'COMPLETE', color: 'green'},
{status: 'COMPLETE_CASH', color: 'green'}, {status: 'REFUND', color: 'red'},
{status: 'CANCEL', color: 'red'},
{status: 'NO_COMPLETED', color: 'red'},
{status: 'REFUND', color: 'magenta'},
] ]
for (let i=0;i<arr.length;i++) { for (let i=0;i<arr.length;i++) {
if (arr[i].status === status) { if (arr[i].status === status) {
return arr[i].color; return arr[i].color;
} }
} }
return 'orange'; // 默认返回橙色
} }
}, },
mounted() { mounted() {

View File

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

View File

@@ -1,53 +1,32 @@
<template> <template>
<div class="search"> <div class="search">
<Card> <t-card>
<Row class="operation"> <div class="operation" style="margin-bottom: 10px;">
<Button @click="add" type="primary">添加</Button> <t-button theme="primary" @click="add">添加</t-button>
<Button @click="refresh">刷新</Button> <t-button variant="outline" @click="delAll" style="margin-left: 8px;">批量删除</t-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
>
</div> </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> </div>
</template> </template>
@@ -59,7 +38,8 @@ import {
delGoodsUnit delGoodsUnit
} from "@/api/index"; } from "@/api/index";
import {regular} from "@/utils"; import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default { export default {
name: "goods-unit", name: "goods-unit",
@@ -68,14 +48,14 @@ export default {
loading: true, // 表单加载状态 loading: true, // 表单加载状态
modalVisible: false, // 添加或编辑显示 modalVisible: false, // 添加或编辑显示
modalTitle: "", // 添加或编辑标题 modalTitle: "", // 添加或编辑标题
searchForm: { searchForm: {
// 搜索框初始化对象 // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort: "createTime", // 默认排序字段 sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式 order: "desc", // 默认排序方式
name: "", name: "",
}, },
form: { form: {
// 添加或编辑表单对象初始化数据 // 添加或编辑表单对象初始化数据
name: "", name: "",
@@ -88,82 +68,16 @@ export default {
] ]
}, },
submitLoading: false, // 添加或编辑提交状态 submitLoading: false, // 添加或编辑提交状态
selectList: [], // 多选数据 selectedRowKeys: [],
selectCount: 0, // 多选计数 selectList: [],
selectCount: 0,
columns: [ columns: [
// 表头 { colKey: "row-select", type: "multiple", width: 60, align: "center" },
{ { title: "计量单位", colKey: "name", minWidth: 120 },
type: "selection", { title: "创建时间", colKey: "createTime", width: 180 },
width: 60, { title: "更新时间", colKey: "updateTime", width: 180 },
align: "center", { title: "操作人", colKey: "createBy", minWidth: 150 },
}, { title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
{
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);
},
},
},
"删除"
),
]);
},
},
], ],
data: [], // 表单数据 data: [], // 表单数据
total: 0, // 表单数据总数 total: 0, // 表单数据总数
@@ -185,20 +99,31 @@ export default {
this.searchForm.pageSize = v; this.searchForm.pageSize = v;
this.getDataList(); 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() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 20;
this.getDataList(); this.getDataList();
}, },
// 清除选中 // 清除选中
clearSelectAll() { clearSelectAll() {
this.$refs.table.selectAll(false); this.selectedRowKeys = [];
this.selectList = [];
this.selectCount = 0;
}, },
// 选中回调 // 选中回调
changeSelect(e) { onSelectChange(keys, { selectedRowData }) {
this.selectList = e; this.selectedRowKeys = keys;
this.selectCount = e.length; this.selectList = selectedRowData || [];
this.selectCount = keys.length;
}, },
// 获取列表数据 // 获取列表数据
getDataList() { getDataList() {
@@ -254,8 +179,10 @@ export default {
// 添加 // 添加
add() { add() {
this.modalTitle = "添加"; this.modalTitle = "添加";
this.form = {}; this.form = { name: "" };
this.$refs.form.resetFields(); if (this.$refs.form && typeof this.$refs.form.reset === "function") {
this.$refs.form.reset();
}
this.modalVisible = true; this.modalVisible = true;
}, },
@@ -268,53 +195,40 @@ export default {
}, },
// 删除 // 删除
remove(v) { remove(v) {
this.$Modal.confirm({ DialogPlugin.confirm({
title: "确认删除", header: "确认删除",
// 记得确认修改此处
content: "您确认要删除 " + v.name + " ?", content: "您确认要删除 " + v.name + " ?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
// 删除
delGoodsUnit(v.id).then((res) => { delGoodsUnit(v.id).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.getDataList(); this.getDataList();
} }
}); });
}, },
}); });
}, },
// 刷新
refresh() {
this.loading = true;
setTimeout(() => {
this.getDataList();
this.loading = false;
this.$Message.success("刷新成功");
}, 500);
},
// 全部删除 // 全部删除
delAll() { delAll() {
if (this.selectCount <= 0) { if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据"); MessagePlugin.warning("您还未选择要删除的数据");
return; return;
} }
this.$Modal.confirm({ DialogPlugin.confirm({
title: "确认删除", header: "确认删除",
content: "您确认要删除所选的 " + this.selectCount + " 条数据?", content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
let ids = ""; let ids = "";
this.selectList.forEach(function (e) { this.selectList.forEach(function (e) {
ids += e.id + ","; ids += e.id + ",";
}); });
ids = ids.substring(0, ids.length - 1); ids = ids.substring(0, ids.length - 1);
// 批量删除
delGoodsUnit(ids).then((res) => { delGoodsUnit(ids).then((res) => {
this.$Modal.remove();
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.clearSelectAll(); this.clearSelectAll();
this.getDataList(); this.getDataList();
} }

View File

@@ -1,528 +0,0 @@
/*选择商品品类*/
.content-goods-publish {
padding: 15px;
margin: 0 auto;
text-align: center;
border-radius: 0.8em;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
background: none repeat 0 0 #fff;
/*商品品类*/
.goods-category {
min-height: 500px;
border-radius: 0.8em;
text-align: left;
padding: 10px;
background: #ededed;
ul {
padding: 12px 8px;
list-style: none;
width: 300px;
background: none repeat 0 0 #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
border-radius: 0.4em;
display: inline-block;
letter-spacing: normal;
margin-right: 15px;
vertical-align: top;
word-spacing: normal;
li {
line-height: 20px;
padding: 10px 5px;
cursor: pointer;
color: #333;
font-size: 12px;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}
}
/** 当前品类被选中的样式 */
.activeClass {
border-radius: 0.4em;
background-color: rgba($color: $theme_color, $alpha: 0.2);
border: 1px solid rgba($color: $theme_color, $alpha: 0.8);
color: #fff;
}
/*!*当前选择的商品品类文字*!*/
.current-goods-category {
text-align: left;
padding: 10px;
width: 100%;
border: 1px solid #fbeed5;
color: #c09853;
background-color: #fcf8e3;
margin: 10px auto;
padding: 8px 35px 8px 14px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
font-size: 12px;
font-weight: bold;
}
}
/*编辑基本信息*/
.el-form {
padding-bottom: 80px;
.el-form-item {
width: 100%;
text-align: left;
}
}
.sku-val {
justify-content: flex-start;
flex-wrap: wrap;
>.ivu-form {
flex-wrap: wrap !important;
}
/deep/ .sku-item-content-val {
margin-right: 20px;
}
}
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;
}
>div {
padding-left: 5%;
}
.form-item-view {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
// padding-left: 80px;
.form-item-view-wholesale {
display: flex;
.form-item-view-wholesale-preview {
padding-left: 5%;
}
}
.layout {
margin-bottom: 20px;
width: 100%;
justify-content: center;
.sku-item-content {
margin: 20px 0;
display: flex;
width: 100% !important;
flex: 1;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
>.ivu-card-body {
width: 100%;
}
.ivu-card-body {
width: 100%;
justify-content: center;
align-items: flex-start;
}
.sku-item-content-name {
display: flex;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
}
}
}
.shop-category-text {
font-size: 12px;
}
}
.form-item-view-bottom {
margin-bottom: 50px;
}
.item-goods-properts-row {
display: flex;
flex-direction: row;
word-break: break-all;
white-space: normal;
width: 300px;
height: 100px;
}
.item-goods-properts {
display: flex;
flex-direction: row;
margin-bottom: 10px;
}
.form-item {
display: flex;
align-items: center;
}
/** 审核信息-拒绝原因 */
.auth-info {
color: red;
}
.el-form-item {
width: 30%;
min-width: 300px;
}
.goods-name-width {
width: 50%;
min-width: 300px;
}
.el-form-item__content {
margin-left: 120px;
text-align: left;
}
p.goods-group-manager {
padding-left: 7.5%;
text-align: left;
color: #999;
font-size: 13px;
}
/*teatarea*/
/deep/ .el-textarea {
width: 150%;
}
.seo-text {
width: 150%;
}
}
/*折叠面板*/
.el-collapse-item {
/deep/ .el-collapse-item__header {
text-align: left;
background-color: #f8f8f8;
padding: 0 10px;
font-weight: bold;
color: #333;
font-size: 14px;
}
.el-form-item {
margin-left: 5%;
width: 25%;
}
/deep/ .el-form-item__content {
margin-left: 120px;
text-align: left;
}
p.goods-group-manager {
padding-left: 12%;
text-align: left;
color: #999;
}
/deep/ .el-collapse-item__content {
padding: 10px 0;
text-align: left;
}
}
.success {
>h1 {
font-size: 28px;
}
>* {
margin: 10px;
}
}
.operation {
>* {
margin: 10px 0;
}
}
/*商品描述*/
.goods-intro {
line-height: 40;
}
/** 底部步骤 */
.footer {
width: 100%;
margin-top: 20px;
padding: 10px;
background-color: #ffc;
position: sticky;
bottom: 0px;
text-align: center;
z-index: 999;
>.ivu-btn {
margin: 0 10px;
}
}
/*图片上传组件第一张图设置封面*/
.goods-images {
/deep/ li.el-upload-list__item:first-child {
position: relative;
}
/deep/ li.el-upload-list__item:first-child:after {
content: "";
color: #fff;
font-weight: bold;
font-size: 12px;
position: absolute;
left: -15px;
top: -6px;
width: 40px;
height: 24px;
padding-top: 6px;
background: #13ce66;
text-align: center;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
}
}
.el-form-item__label {
word-break: break-all;
}
.step-list {
height: 60px;
padding: 10px 30px;
background-color: #fff;
margin-bottom: 20px;
border-radius: 0.8em;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.add-sku-btn {
margin-top: 10px;
}
.sku-item:not(:first-child) {
margin-top: 10px;
}
.sku-upload-list {
text-align: center;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
margin-right: 8px;
}
.preview-picture {
width: 100%;
margin: 0 auto;
display: block;
// text-align: center;
border: 1px solid transparent;
// justify-self: center;
// align-self: center;
}
.preview-picture img {
width: 100%;
height: 100%;
}
.sku-upload-list img {
width: 100%;
height: 100%;
}
.sku-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
.sku-upload-list:hover .sku-upload-list-cover {
display: block;
}
.sku-upload-list-cover i {
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
.required {
/deep/ .ivu-form-item-label::before {
content: "*";
display: inline-block;
margin-right: 4px;
line-height: 1;
font-family: SimSun;
font-size: 14px;
color: #ed4014;
}
}
.demo-upload-list {
width: 150px;
height: 150px;
text-align: center;
border: 1px solid transparent;
border-radius: 4px;
display: inline-block;
background: #fff;
position: relative;
margin-right: 4px;
vertical-align: bottom;
}
.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);
justify-content: space-between;
align-items: center;
flex-direction: column;
}
.demo-upload-list:hover .demo-upload-list-cover {
display: flex;
}
.demo-upload-list-cover div {
margin-top: 50px;
width: 100%;
>i {
width: 50%;
margin-top: 8px;
color: #fff;
font-size: 20px;
cursor: pointer;
}
}
.active-goods-type {
background: #e8e8e8;
}
.goods-type-list {
max-height: 500px;
overflow-y: auto;
}
.template-item {
justify-content: flex-start !important;
}
.tree-bar {
height: auto !important;
max-height: auto !important;
min-height: 240px !important;
}
.goods-type-item {
padding: 20px 0;
width: 100%;
cursor: pointer;
transition: 0.35s;
display: flex;
justify-content: center;
align-items: center;
/deep/ img {
margin-right: 20px;
width: 100px;
margin-left: 10px;
}
/deep/ p {
color: #999;
font-size: 14px;
margin-top: 10px;
}
}
.goods-type-item:hover {
background: #ededed;
}
.goods-list-box {
height: 450px;
overflow: auto;
}
h2 {
cursor: pointer;
font-size: 21px;
color: #333;
}
.form-item-view-wholesale-form-col {
height: 400px;
}
.form-item-view-wholesale-row-del {
display: "flex";
justify-content: "space-between";
align-items: "center";
}
.promise-intro-btn{
margin: 10px 0;
text-align: left;
}

View File

@@ -1,160 +1,140 @@
<template> <template>
<div class="search"> <div class="search">
<Card> <t-card style="margin-bottom: 12px">
<Form <t-form ref="searchForm" :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
ref="searchForm" <t-form-item label="商品名称" name="goodsName">
:model="searchForm" <t-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
inline </t-form-item>
:label-width="70" <t-form-item label="商品ID" name="id">
class="search-form" <t-input v-model="searchForm.id" placeholder="请输入商品ID" clearable style="width: 240px" />
@keydown.enter.native="handleSearch" </t-form-item>
> <t-form-item label="店铺名称" name="storeName">
<Form-item label="商品名称" prop="goodsName"> <t-input v-model="searchForm.storeName" placeholder="请输入店铺名称" clearable style="width: 240px" />
<Input </t-form-item>
type="text" <t-form-item label="销售模式" name="salesModel">
v-model="searchForm.goodsName" <t-select v-model="searchForm.salesModel" placeholder="请选择" clearable style="width: 240px">
placeholder="请输入商品名称" <t-option value="RETAIL" label="零售" />
clearable <t-option value="WHOLESALE" label="批发" />
style="width: 200px" </t-select>
/> </t-form-item>
</Form-item> <t-form-item label="商品类型" name="goodsType">
<Form-item label="商品编号" prop="id"> <t-select v-model="searchForm.goodsType" placeholder="请选择" clearable style="width: 240px">
<Input <t-option value="PHYSICAL_GOODS" label="实物商品" />
type="text" <t-option value="VIRTUAL_GOODS" label="虚拟商品" />
v-model="searchForm.id" </t-select>
placeholder="请输入商品编号" </t-form-item>
clearable <t-form-item>
style="width: 200px" <t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
/> <t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</Form-item> </t-form-item>
</t-form>
</t-card>
<t-card>
<Form-item label="状态" prop="status"> <div class="goods-tab">
<Select <t-tabs v-model="currentStatus" @change="goodsStatusClick">
v-model="searchForm.marketEnable" <t-tab-panel v-for="(item,index) in goodsStatusWithCount" :key="index" :label="item.title" :value="item.value"></t-tab-panel>
placeholder="请选择" </t-tabs>
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>
<div class="mt_10">
<Button type="primary" @click="handleAdd">新增商品</Button>
</div> </div>
<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"
/>
</div>
<div style="margin-left: 13px"> <div class="batch-operations" style="margin: 10px 0;">
<div class="div-zoom"> <t-button theme="success" :disabled="selectedRows.length === 0" @click="batchUpper" style="margin-right: 10px;">批量上架</t-button>
<a @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a> <t-button theme="warning" :disabled="selectedRows.length === 0" @click="batchLower" style="margin-right: 10px;">批量下架</t-button>
</div> <t-button v-if="currentStatus === 'TOBEAUDITED'" theme="primary" :disabled="selectedRows.length === 0" @click="batchAudit">批量审核</t-button>
<Poptip trigger="hover" title="扫码在手机中查看" transfer> </div>
<div slot="content">
<vue-qr <t-table :loading="loading" :columns="columns" :data="data" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onTSelectChange" class="mt_10">
:text="wapLinkTo(row.id, row.skuId)" <template #imageSlot="{ row }">
:margin="0" <div style="margin-top: 5px;">
colorDark="#000" <img :src="row.original" style="height: 50px; width: 50px; object-fit: cover;" />
colorLight="#fff" </div>
:size="150" </template>
></vue-qr> <template #goodsSlot="{ row }">
</div> <div style="margin: 5px 0px; padding: 10px 0px;">
<img <div class="div-zoom">
src="../../../assets/qrcode.svg" <a @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
class="hover-pointer"
width="20"
height="20"
alt=""
/>
</Poptip>
</div> </div>
</div> </div>
</template> </template>
</Table>
<Row type="flex" justify="end" class="mt_10"> <template #action="{ row }">
<Page <template v-if="row.authFlag === 'TOBEAUDITED'">
:current="searchForm.pageNumber" <a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="openAuditModal(row)">审核</a>
:total="total" <span style="margin:0 8px;color:#dcdee2">|</span>
:page-size="searchForm.pageSize" <a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
@on-change="changePage" </template>
@on-page-size-change="changePageSize" <template v-else-if="row.marketEnable == 'DOWN'">
:page-size-opts="[10, 20, 50]" <a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="upper(row)">上架</a>
size="small" <span style="margin:0 8px;color:#dcdee2">|</span>
show-total <a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
show-elevator </template>
show-sizer <template v-else>
></Page> <a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="edit(row)">下架</a>
</Row> <span style="margin:0 8px;color:#dcdee2">|</span>
</Card> <a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
<Modal </template>
title="下架操作" </template>
v-model="modalVisible" </t-table>
:mask-closable="false" <div class="mt_10" style="display: flex; justify-content: flex-end">
:width="500" <t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
>
<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
>
</div> </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> </div>
</template> </template>
<script> <script>
import { getGoodsListData, upGoods, lowGoods } from "@/api/goods"; import { getGoodsListData,getGoodsNumerData, upGoods, lowGoods, authGoods } from "@/api/goods";
import vueQr from "vue-qr"; import vueQr from "vue-qr";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default { export default {
components: { components: {
"vue-qr": vueQr, "vue-qr": vueQr,
@@ -168,184 +148,72 @@ export default {
searchForm: { searchForm: {
// 搜索框初始化对象 // 搜索框初始化对象
pageNumber: 1, // 当前页数 pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小 pageSize: 20, // 页面大小
sort: "create_time", // 默认排序字段 sort: "create_time", // 默认排序字段
order: "desc", // 默认排序方式 order: "desc", // 默认排序方式
goodsName: "",
id: "",
storeName: "",
salesModel: "",
goodsType: "",
goodsStatus: "",
}, },
underForm: { underForm: {
// 下架原因 // 下架原因
reason: "", reason: "",
}, },
goodsAuditForm: {
// 商品审核表单
auth_flag: 1,
},
auditModalVisible: false, // 审核弹框显示状态
currentAuditGoods: null, // 当前审核的商品
submitLoading: false, // 添加或编辑提交状态 submitLoading: false, // 添加或编辑提交状态
selectedRowKeys: [],
columns: [ columns: [
{ { colKey: "row-select", type: "multiple", width: 60, align: "center" },
title: "商品名称", { title: "商品ID", colKey: "id", width: 260 },
key: "goodsName", { title: "商品图片", colKey: "imageSlot", width: 180 },
minWidth: 180, { title: "商品名称", colKey: "goodsSlot", width: 180 },
slot: "goodsSlot", { 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: "商品编号", { title: "店铺名称", colKey: "storeName", width: 180 },
key: "id", { title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
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: "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);
},
},
},
"查看"
),
]);
}
},
},
], ],
data: [], // 表单数据 data: [], // 表单数据
total: 0, // 表单数据总数 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: { methods: {
// 新增商品
handleAdd(){
this.$router.push('/goods-publish')
},
// 初始化数据 // 初始化数据
init() { init() {
this.getDataList(); this.getDataList();
this.getNumberData();
}, },
// 分页 改变页码 // 分页 改变页码
changePage(v) { changePage(v) {
@@ -357,11 +225,42 @@ export default {
this.searchForm.pageSize = v; this.searchForm.pageSize = v;
this.getDataList(); 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() { handleSearch() {
this.searchForm.pageNumber = 1; this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10; this.searchForm.pageSize = 20;
this.getDataList(); 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() { getDataList() {
@@ -374,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) { edit(v) {
this.id = v.id; this.id = v.id;
@@ -386,27 +294,33 @@ export default {
}, },
// 下架 // 下架
lower() { lower() {
lowGoods(this.id, this.underForm).then((res) => { let params = {
this.$Modal.remove(); goodsId: this.id,
reason:this.underForm.reason
};
lowGoods(params).then((res) => {
if (res.success) { if (res.success) {
this.$Message.success("操作成功"); MessagePlugin.success("操作成功");
this.modalVisible = false; this.modalVisible = false;
this.getDataList(); this.getDataList();
this.getNumberData();
} }
}); });
}, },
// 商家 // 上架
upper(v) { upper(v) {
this.$Modal.confirm({ const dlg = DialogPlugin.confirm({
title: "确认上架", header: "确认上架",
content: "您确认要上架 " + v.goodsName + " ?", content: "您确认要上架 " + v.goodsName + " ?",
loading: true, theme: "warning",
onOk: () => { onConfirm: () => {
upGoods(v.id).then((res) => { dlg.hide();
this.$Modal.remove(); const params = { goodsId: v.id };
upGoods(params).then((res) => {
if (res.success) { if (res.success) {
this.$Message.success("上架成功"); MessagePlugin.success("上架成功");
this.getDataList(); this.getDataList();
this.getNumberData();
} }
}); });
}, },
@@ -417,13 +331,229 @@ export default {
showDetail(v) { showDetail(v) {
let id = v.id; let id = v.id;
this.$options.filters.customRouterPush({ this.$options.filters.customRouterPush({
name: "goods-publish", name: "goods-detail",
query: { id: id }, 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() { mounted() {
this.init(); this.init();
}, },
}; };
</script> </script>
<style lang="scss" scoped>
// Tab组件样式
.goods-tab {
::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