mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-06-21 09:30:24 +08:00
manager 升级到vue3
This commit is contained in:
59
manager/MIGRATION-VUE3.md
Normal file
59
manager/MIGRATION-VUE3.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# manager Vue 3 + Element Plus 迁移说明
|
||||
|
||||
## 已完成(P1–P3 骨架)
|
||||
|
||||
- 依赖升级:`vue@3`、`vue-router@4`、`vuex@4`、`vue-i18n@9`、`element-plus`
|
||||
- 入口:`src/main.js`(`createApp`)
|
||||
- 路由、动态路由、全局 `$Message` / `$Modal` / `$Notice`、`$filters`、`priceColorScheme`、`vue-qr@5`
|
||||
- TinyMCE:移除已弃用 `template` 插件
|
||||
|
||||
## P5 批量修复(Table / 过滤器)
|
||||
|
||||
列表页 **60+** 已 `el-table`;过滤器已改为 `$filters.*`;全项目已无 `$set` / `$options.filters`。
|
||||
|
||||
## P6 表单 / 弹窗(已完成模块)
|
||||
|
||||
| 模块 | 状态 |
|
||||
|------|------|
|
||||
| 地区、秒杀设置、分销设置、修改密码、编辑器、链接弹窗 | ✅ |
|
||||
| 店铺详情 / 店铺编辑 `shopOperation.vue` | ✅ |
|
||||
| 售后详情 `afterSaleOrderDetail.vue` | ✅ |
|
||||
| **系统设置** `sys/setting-manage/**`(19 个 vue + template.js) | ✅ |
|
||||
| **菜单 / 部门** `sys/menu-manage/`、`sys/department-manage/` | ✅ |
|
||||
| **页面装修** `views/page-decoration/**`(PC + H5 装修、modelList、wap 模板) | ✅ |
|
||||
| **文章管理** `views/page/article-manage/**` | ✅ |
|
||||
| **零散页面** 礼品卡、个人中心、热区、促销编辑、视频号、错误页、短信签名等 | ✅ |
|
||||
|
||||
### 系统设置包含
|
||||
|
||||
- `settingManage.vue`(Tab 壳)
|
||||
- `platformSetting.vue`
|
||||
- `setting/`:基础、商品、订单、积分、提现、物流、OSS、短信、客服
|
||||
- `pay/`:支付开关、支付宝、微信
|
||||
- `authLogin/`:登录、QQ、微信
|
||||
- `smsSettingManage.vue`
|
||||
|
||||
`template.js` 中动态组件已 `markRaw`。
|
||||
|
||||
## 可选后续
|
||||
|
||||
- `components/tree-table`:旧 JSX 表格,当前路由未引用;`Spin` 已改 `v-loading`,`beforeUnmount` 已对齐 Vue 3
|
||||
- 样式文件中残留的 `.ivu-*` 类名可随页面改版逐步清理(不影响运行)
|
||||
|
||||
## 编译告警处理(2026-05)
|
||||
|
||||
- 全项目 `::v-deep` 已改为 Vue 3 推荐的 `:deep(...)`
|
||||
- `common.scss` 合并 `table-common.scss`,去掉全局 `@import` 注入告警
|
||||
- `vue.config.js` 配置 `sassOptions.silenceDeprecations` 抑制 Sass legacy API 提示
|
||||
- `common.scss`:`.search > .el-card + .el-card` 恢复列表页双 Card 间距(原 `.ivu-card` 规则已失效)
|
||||
- `element.scss`:全局 `el-table--border` 去掉列竖线
|
||||
|
||||
## 本地运行
|
||||
|
||||
```bash
|
||||
cd manager
|
||||
yarn install
|
||||
yarn run dev
|
||||
```
|
||||
|
||||
Node **18+**,包管理统一 **yarn**。
|
||||
@@ -1,10 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@vue/app',
|
||||
{
|
||||
useBuiltIns: 'entry'
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
presets: ["@vue/cli-plugin-babel/preset"],
|
||||
};
|
||||
|
||||
@@ -10,51 +10,51 @@
|
||||
"dev": "vue-cli-service serve"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amap/amap-jsapi-loader": "0.0.7",
|
||||
"@antv/g2": "^4.1.12",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js": "^3.36.0",
|
||||
"dplayer": "^1.26.0",
|
||||
"element-plus": "^2.6.3",
|
||||
"js-cookie": "^2.2.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"price-color": "1.0.2",
|
||||
"sass": "^1.63.6",
|
||||
"sass-loader": "^10.4.1",
|
||||
"sockjs-client": "^1.4.0",
|
||||
"swiper": "^6.3.5",
|
||||
"uuid": "^8.3.2",
|
||||
"view-design": "^4.7.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue": "^3.4.21",
|
||||
"vue-awesome-swiper": "^4.1.1",
|
||||
"vue-i18n": "^8.15.1",
|
||||
"vue-i18n": "^9.10.2",
|
||||
"vue-json-excel": "^0.3.0",
|
||||
"vue-print-nb": "^1.7.5",
|
||||
"vue-qr": "^2.3.0",
|
||||
"vue-router": "^3.1.3",
|
||||
"vuedraggable": "^2.23.2",
|
||||
"vuex": "^3.4.0",
|
||||
"vue-qr": "^5.0.3",
|
||||
"vue-router": "^4.3.0",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vuex": "^4.1.0",
|
||||
"xss": "^1.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.4.4",
|
||||
"@vue/cli-plugin-router": "^4.4.4",
|
||||
"@vue/cli-plugin-vuex": "^4.4.4",
|
||||
"@vue/cli-service": "^4.4.4",
|
||||
"compression-webpack-plugin": "^4.0.0",
|
||||
"css-loader": "^5.0.1",
|
||||
"less": "^3.12.2",
|
||||
"less-loader": "^6.2.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"style-resources-loader": "^1.3.2",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"vue-cli-plugin-style-resources-loader": "^0.1.4",
|
||||
"vue-template-compiler": "2.6.14"
|
||||
"webpack": "^5.95.0",
|
||||
"@vue/cli-plugin-babel": "^5.0.8",
|
||||
"@vue/cli-plugin-router": "^5.0.8",
|
||||
"@vue/cli-plugin-vuex": "^5.0.8",
|
||||
"@vue/cli-service": "^5.0.8",
|
||||
"@vue/compiler-sfc": "^3.4.21",
|
||||
"compression-webpack-plugin": "^10.0.0",
|
||||
"css-loader": "^6.10.0",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^11.1.4",
|
||||
"style-loader": "^3.3.4",
|
||||
"style-resources-loader": "^1.5.0",
|
||||
"vue-cli-plugin-style-resources-loader": "^0.1.5"
|
||||
},
|
||||
"resolutions": {
|
||||
"minimatch": "^3.1.2",
|
||||
"node-sass": "npm:sass@^1.63.6",
|
||||
"@achrinza/node-ipc": "9.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name='description' content='在线购物平台'>
|
||||
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> -->
|
||||
<link rel="icon" href="./logo.ico" type="image/x-icon" />
|
||||
<!-- favicon 可选:将 logo.ico 放到 public/ 后取消下行注释 -->
|
||||
<!-- <link rel="icon" href="/logo.ico" type="image/x-icon" /> -->
|
||||
<title>admin</title>
|
||||
<meta name="keywords" content="keywords" />
|
||||
<meta name="description" content="description" />
|
||||
@@ -72,7 +73,7 @@
|
||||
<script src="<%=js%>"></script>
|
||||
<% } %>
|
||||
<script src="/config.js"></script>
|
||||
<script src="./tinymce/tinymce.min.js"></script>
|
||||
<script src="/tinymce/tinymce.min.js"></script>
|
||||
<noscript>
|
||||
<strong
|
||||
>We're sorry but admin doesn't work properly without JavaScript
|
||||
|
||||
@@ -1,32 +1,46 @@
|
||||
<template>
|
||||
<div id="main" class="app-main">
|
||||
<router-view></router-view>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCategoryTree } from '@/api/goods.js'
|
||||
import Cookies from "js-cookie";
|
||||
import { getCategoryTree } from "@/api/goods.js";
|
||||
import util from "@/libs/util";
|
||||
|
||||
export default {
|
||||
updated () {
|
||||
if (!localStorage.getItem('category') && this.$route.path !== '/login') {
|
||||
getCategoryTree(0).then(res => {
|
||||
name: "App",
|
||||
updated() {
|
||||
if (!localStorage.getItem("category") && this.$route.path !== "/login") {
|
||||
getCategoryTree(0).then((res) => {
|
||||
if (res.success) {
|
||||
localStorage.setItem('category', JSON.stringify(res.result))
|
||||
localStorage.setItem("category", JSON.stringify(res.result));
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const loggedIn = this.getStore("accessToken") || Cookies.get("userInfoManager");
|
||||
if (loggedIn) {
|
||||
util.bootstrapDynamicRoutesFromCache();
|
||||
util.initRouter(this);
|
||||
this.$store.commit("setOpenedList");
|
||||
this.$store.commit("initCachePage");
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f0f0f0;
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.app-main {
|
||||
@@ -42,14 +56,6 @@ body {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.ivu-btn-text:focus {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ivu-tag {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tox-notifications-container {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -1,97 +1,85 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="breadcrumb">
|
||||
<span @click="clickBreadcrumb(item, index)" :class="{ 'active': item.selected }" v-for="(item, index) in dateList"
|
||||
:key="index"> {{ item.title }}</span>
|
||||
<span
|
||||
v-for="(item, index) in dateList"
|
||||
:key="index"
|
||||
:class="{ active: item.selected }"
|
||||
@click="clickBreadcrumb(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</span>
|
||||
<div class="date-picker">
|
||||
<Select @on-change="changeSelect($event, selectedWay)" :value="month" placeholder="年月查询" clearable
|
||||
style="width:200px;margin-left:10px;">
|
||||
<Option v-for="(item, i) in dates" :value="item.year + '-' + item.month" :key="i" clearable>
|
||||
{{ item.year + '年' + item.month + '月' }}</Option>
|
||||
</Select>
|
||||
<el-select
|
||||
v-model="month"
|
||||
placeholder="年月查询"
|
||||
clearable
|
||||
style="width: 200px; margin-left: 10px"
|
||||
@change="changeSelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, i) in dates"
|
||||
:key="i"
|
||||
:label="item.year + '年' + item.month + '月'"
|
||||
:value="item.year + '-' + item.month"
|
||||
/>
|
||||
</el-select>
|
||||
</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 v-if="!closeShop" class="shop-list">
|
||||
<el-select
|
||||
v-model="storeId"
|
||||
placeholder="店铺查询"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px; margin-left: 10px"
|
||||
@change="changeshop"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in shopsData"
|
||||
:key="index"
|
||||
:label="item.storeName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getShopListData } from "@/api/shops.js";
|
||||
|
||||
export default {
|
||||
props: ["closeShop"],
|
||||
data() {
|
||||
return {
|
||||
month: "", // 月份
|
||||
|
||||
month: "",
|
||||
selectedWay: {
|
||||
// 可选时间项
|
||||
title: "过去7天",
|
||||
selected: true,
|
||||
searchType: "LAST_SEVEN",
|
||||
},
|
||||
storeId: "", // 店铺id
|
||||
dates: [], // 日期列表
|
||||
storeId: "",
|
||||
dates: [],
|
||||
params: {
|
||||
// 请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
pageSize: 100,
|
||||
storeName: "",
|
||||
},
|
||||
dateList: [
|
||||
// 筛选条件
|
||||
{
|
||||
title: "今天",
|
||||
selected: false,
|
||||
searchType: "TODAY",
|
||||
},
|
||||
{
|
||||
title: "昨天",
|
||||
selected: false,
|
||||
searchType: "YESTERDAY",
|
||||
},
|
||||
{
|
||||
title: "过去7天",
|
||||
selected: true,
|
||||
searchType: "LAST_SEVEN",
|
||||
},
|
||||
{
|
||||
title: "过去30天",
|
||||
selected: false,
|
||||
searchType: "LAST_THIRTY",
|
||||
},
|
||||
{ title: "今天", selected: false, searchType: "TODAY" },
|
||||
{ title: "昨天", selected: false, searchType: "YESTERDAY" },
|
||||
{ title: "过去7天", selected: true, searchType: "LAST_SEVEN" },
|
||||
{ title: "过去30天", selected: false, searchType: "LAST_THIRTY" },
|
||||
],
|
||||
originDateList: [
|
||||
// 筛选条件
|
||||
{
|
||||
title: "今天",
|
||||
selected: false,
|
||||
searchType: "TODAY",
|
||||
},
|
||||
{
|
||||
title: "昨天",
|
||||
selected: false,
|
||||
searchType: "YESTERDAY",
|
||||
},
|
||||
{
|
||||
title: "过去7天",
|
||||
selected: true,
|
||||
searchType: "LAST_SEVEN",
|
||||
},
|
||||
{
|
||||
title: "过去30天",
|
||||
selected: false,
|
||||
searchType: "LAST_THIRTY",
|
||||
},
|
||||
{ title: "今天", selected: false, searchType: "TODAY" },
|
||||
{ title: "昨天", selected: false, searchType: "YESTERDAY" },
|
||||
{ title: "过去7天", selected: true, searchType: "LAST_SEVEN" },
|
||||
{ title: "过去30天", selected: false, searchType: "LAST_THIRTY" },
|
||||
],
|
||||
|
||||
shopTotal: "", // 店铺总数
|
||||
shopsData: [], // 店铺数据
|
||||
shopTotal: 0,
|
||||
shopsData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -99,58 +87,35 @@ export default {
|
||||
this.getShopList();
|
||||
},
|
||||
methods: {
|
||||
// 页面触底
|
||||
handleReachBottom() {
|
||||
setTimeout(() => {
|
||||
if (this.params.pageNumber * this.params.pageSize <= this.shopTotal) {
|
||||
this.params.pageNumber++;
|
||||
this.getShopList();
|
||||
}
|
||||
}, 1500);
|
||||
},
|
||||
// 查询店铺列表
|
||||
getShopList() {
|
||||
getShopListData(this.params).then((res) => {
|
||||
if (res.success) {
|
||||
/**
|
||||
* 解决数据请求中,滚动栏会一直上下跳动
|
||||
*/
|
||||
this.shopTotal = res.result.total;
|
||||
|
||||
this.shopsData.push(...res.result.records);
|
||||
this.shopsData = res.result.records || [];
|
||||
}
|
||||
});
|
||||
},
|
||||
// 变更店铺
|
||||
changeshop(val) {
|
||||
changeshop() {
|
||||
this.selectedWay.storeId = this.storeId;
|
||||
this.$emit("selected", this.selectedWay);
|
||||
},
|
||||
|
||||
// 获取近5年 年月
|
||||
getFiveYears() {
|
||||
let getYear = new Date().getFullYear();
|
||||
|
||||
let lastFiveYear = getYear - 5;
|
||||
let maxMonth = new Date().getMonth() + 1;
|
||||
let dates = [];
|
||||
// 循环出过去5年
|
||||
const getYear = new Date().getFullYear();
|
||||
const lastFiveYear = getYear - 5;
|
||||
const maxMonth = new Date().getMonth() + 1;
|
||||
const dates = [];
|
||||
for (let year = lastFiveYear; year <= getYear; year++) {
|
||||
for (let month = 1; month <= 12; month++) {
|
||||
if (year == getYear && month > maxMonth) {
|
||||
} else {
|
||||
dates.push({
|
||||
year: year,
|
||||
month: month,
|
||||
});
|
||||
if (year === getYear && month > maxMonth) {
|
||||
continue;
|
||||
}
|
||||
dates.push({ year, month });
|
||||
}
|
||||
}
|
||||
this.dates = dates.reverse();
|
||||
},
|
||||
// 改变已选店铺
|
||||
changeSelect(e) {
|
||||
this.month = e
|
||||
this.month = e;
|
||||
if (this.month) {
|
||||
this.dateList.forEach((res) => {
|
||||
res.selected = false;
|
||||
@@ -158,53 +123,44 @@ export default {
|
||||
this.selectedWay.year = this.month.split("-")[0];
|
||||
this.selectedWay.month = this.month.split("-")[1];
|
||||
this.selectedWay.searchType = "";
|
||||
|
||||
this.$emit("selected", this.selectedWay);
|
||||
} else {
|
||||
|
||||
const current = this.dateList.find(item => { return item.selected })
|
||||
this.selectedWay = current
|
||||
this.clickBreadcrumb(current)
|
||||
const current = this.dateList.find((item) => item.selected);
|
||||
this.selectedWay = current;
|
||||
this.clickBreadcrumb(current);
|
||||
this.$emit("selected", this.selectedWay);
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
// 变更时间
|
||||
clickBreadcrumb(item) {
|
||||
|
||||
let currentIndex;
|
||||
this.dateList.forEach((res,index) => {
|
||||
this.dateList.forEach((res, index) => {
|
||||
res.selected = false;
|
||||
if(res.title === item.title){
|
||||
currentIndex = index
|
||||
if (res.title === item.title) {
|
||||
currentIndex = index;
|
||||
}
|
||||
});
|
||||
item.selected = true;
|
||||
item.storeId = this.storeId;
|
||||
this.month = "";
|
||||
if (item.searchType == "") {
|
||||
let currentDate = this.originDateList[currentIndex].searchType
|
||||
if (currentDate) {
|
||||
item.searchType = currentDate
|
||||
} else {
|
||||
item.searchType = "LAST_SEVEN";
|
||||
}
|
||||
if (item.searchType === "") {
|
||||
const currentDate = this.originDateList[currentIndex].searchType;
|
||||
item.searchType = currentDate || "LAST_SEVEN";
|
||||
}
|
||||
this.selectedWay = item;
|
||||
this.selectedWay.year = new Date().getFullYear();
|
||||
this.selectedWay.month = "";
|
||||
|
||||
this.$emit("selected", this.selectedWay);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
>span {
|
||||
|
||||
> span {
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -215,8 +171,6 @@ export default {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.date-picker {}
|
||||
|
||||
.active:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
||||
@@ -122,7 +122,7 @@ export default {
|
||||
deactivated() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const plugins = [
|
||||
'advlist', 'anchor', 'autolink', 'autosave', 'code', 'codesample', 'directionality', 'emoticons', 'fullscreen', 'image', 'importcss', 'insertdatetime', 'link', 'lists', 'media', 'nonbreaking', 'pagebreak', 'preview', 'save', 'searchreplace', 'table', 'template', 'visualblocks', 'visualchars', 'wordcount'
|
||||
'advlist', 'anchor', 'autolink', 'autosave', 'code', 'codesample', 'directionality', 'emoticons', 'fullscreen', 'image', 'importcss', 'insertdatetime', 'link', 'lists', 'media', 'nonbreaking', 'pagebreak', 'preview', 'save', 'searchreplace', 'table', 'visualblocks', 'visualchars', 'wordcount'
|
||||
]
|
||||
export default plugins
|
||||
|
||||
@@ -1,70 +1,90 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<Button @click="handleClickUploadImage">上传图片</Button>
|
||||
<Modal v-model="show" width="850" @on-ok="callback" title="上传图片">
|
||||
<div class="import-oss" @click="importOSS">
|
||||
从资源库中导入
|
||||
</div>
|
||||
<el-button @click="handleClickUploadImage">上传图片</el-button>
|
||||
<el-dialog v-model="show" width="850px" title="上传图片" append-to-body :z-index="3500">
|
||||
<div class="import-oss" @click="importOSS">从资源库中导入</div>
|
||||
<div style="display: flex; flex-wrap: wrap">
|
||||
<vuedraggable
|
||||
:animation="200"
|
||||
:list="images"
|
||||
>
|
||||
<vuedraggable :animation="200" :list="images">
|
||||
<div
|
||||
v-for="(item, __index) in images"
|
||||
:key="__index"
|
||||
class="upload-list"
|
||||
>
|
||||
<template>
|
||||
<img alt="image" :src="item.url"/>
|
||||
<div class="upload-list-cover">
|
||||
<div>
|
||||
<Icon
|
||||
size="30"
|
||||
type="md-search"
|
||||
@click.native="$previewImage(item.url)"
|
||||
></Icon>
|
||||
<Icon
|
||||
size="30"
|
||||
type="md-trash"
|
||||
@click.native="handleRemoveGoodsPicture(__index)"
|
||||
></Icon>
|
||||
</div>
|
||||
<img alt="image" :src="item.url" />
|
||||
<div class="upload-list-cover">
|
||||
<div>
|
||||
<el-icon class="action-icon" :size="30" @click="handleView(item.url)">
|
||||
<ZoomIn />
|
||||
</el-icon>
|
||||
<el-icon
|
||||
class="action-icon"
|
||||
:size="30"
|
||||
@click="handleRemoveGoodsPicture(__index)"
|
||||
>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
<div class="upload-box">
|
||||
<Upload
|
||||
<el-upload
|
||||
ref="upload"
|
||||
:action="uploadFileUrl"
|
||||
:format="['jpg', 'jpeg', 'png']"
|
||||
:headers="{ ...accessToken }"
|
||||
:max-size="10240"
|
||||
:on-exceeded-size="handleMaxSize"
|
||||
:on-format-error="handleFormatError"
|
||||
:on-success="handleSuccessGoodsPicture"
|
||||
:show-upload-list="false"
|
||||
:headers="accessToken"
|
||||
:show-file-list="false"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
drag
|
||||
multiple
|
||||
type="drag"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-success="handleSuccessGoodsPicture"
|
||||
:on-error="handleUploadError"
|
||||
>
|
||||
<div style="width: 148px; height: 148px; line-height: 148px">
|
||||
<Icon size="20" type="md-add"></Icon>
|
||||
<div class="upload-trigger">
|
||||
<el-icon :size="20"><Plus /></el-icon>
|
||||
</div>
|
||||
</Upload>
|
||||
</el-upload>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="show = false">取消</el-button>
|
||||
<el-button type="primary" @click="callback">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal width="1000" v-model="showOssManager" @on-ok="confirmUrls">
|
||||
<OssManage ref="ossManage" :isComponent="true" :initialize="showOssManager" @selected="(list)=>{ selectedImage = list}" @callback="handleCallback" />
|
||||
</Modal>
|
||||
<el-dialog
|
||||
v-model="showOssManager"
|
||||
width="1000px"
|
||||
append-to-body
|
||||
:z-index="3600"
|
||||
destroy-on-close
|
||||
@closed="confirmUrls"
|
||||
>
|
||||
<OssManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="showOssManager"
|
||||
@selected="(list) => { selectedImage = list }"
|
||||
@callback="handleCallback"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="showOssManager = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmUrls">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="viewImage" title="图片预览" width="520px" append-to-body :z-index="3700">
|
||||
<img :src="previewUrl" alt="预览" style="width: 100%; display: block; margin: 0 auto" />
|
||||
<template #footer>
|
||||
<el-button @click="viewImage = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { Delete, Plus, ZoomIn } from "@element-plus/icons-vue";
|
||||
import vuedraggable from "vuedraggable";
|
||||
import {uploadFile} from "@/libs/axios";
|
||||
// import OssManage from "@/views/sys/oss-manage/ossManage";
|
||||
import { uploadFile } from "@/libs/axios";
|
||||
import OssManage from "@/views/sys/oss-manage/ossManage.vue";
|
||||
|
||||
export default {
|
||||
@@ -72,16 +92,21 @@ export default {
|
||||
components: {
|
||||
OssManage,
|
||||
vuedraggable,
|
||||
Delete,
|
||||
Plus,
|
||||
ZoomIn,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false, // 是否显示弹窗
|
||||
uploadFileUrl: uploadFile, // 上传地址
|
||||
accessToken:"",
|
||||
showOssManager:false, // 是否显示oss管理弹窗
|
||||
images:[],
|
||||
selectedImage:[]
|
||||
}
|
||||
show: false,
|
||||
uploadFileUrl: uploadFile,
|
||||
accessToken: {},
|
||||
showOssManager: false,
|
||||
images: [],
|
||||
selectedImage: [],
|
||||
viewImage: false,
|
||||
previewUrl: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.accessToken = {
|
||||
@@ -89,71 +114,73 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClickUploadImage(){
|
||||
handleClickUploadImage() {
|
||||
this.show = true;
|
||||
},
|
||||
// 回调给父级
|
||||
callback() {
|
||||
// 先给数据做一下处理 然后将数据传给父级
|
||||
const formatImages = this.images.map((item) => item.url);
|
||||
this.$emit('callback',formatImages)
|
||||
handleView(url) {
|
||||
this.previewUrl = url;
|
||||
this.viewImage = true;
|
||||
},
|
||||
callback() {
|
||||
const formatImages = this.images.map((item) => item.url);
|
||||
this.$emit("callback", formatImages);
|
||||
this.show = false;
|
||||
},
|
||||
// 移除商品图片
|
||||
handleRemoveGoodsPicture(__index) {
|
||||
this.images.splice(__index, 1);
|
||||
},
|
||||
// 图片大小不正确
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "超过文件大小限制",
|
||||
desc: "图片大小不能超过10MB",
|
||||
});
|
||||
handleBeforeUpload(file) {
|
||||
const okType = ["image/jpeg", "image/png", "image/jpg"].includes(file.type);
|
||||
if (!okType) {
|
||||
this.$Message.warning("文件 " + file.name + " 的格式不正确,请选择 jpg/jpeg/png");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 10) {
|
||||
this.$Message.warning("图片大小不能超过10MB");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 图片格式不正确
|
||||
handleFormatError(file) {
|
||||
this.$Notice.warning({
|
||||
title: "文件格式不正确",
|
||||
desc: "文件 " + file.name + " 的格式不正确",
|
||||
});
|
||||
},
|
||||
// sku图片上传成功
|
||||
handleSuccessGoodsPicture(res, file) {
|
||||
if (file.response) {
|
||||
file.url = file.response.result;
|
||||
this.images.push(file);
|
||||
handleSuccessGoodsPicture(res) {
|
||||
const url = res?.result ?? res?.data?.result;
|
||||
if (url) {
|
||||
this.images.push({ url });
|
||||
} else {
|
||||
this.$Message.error(res?.message || "上传失败");
|
||||
}
|
||||
},
|
||||
confirmUrls(){
|
||||
// this.selectedImage.length ? this.selectedImage.forEach(element => {
|
||||
// this.images.push({ url: element.url })
|
||||
// }):''
|
||||
this.showOssManager = false
|
||||
handleUploadError(err) {
|
||||
this.$Message.error(err?.message || String(err));
|
||||
},
|
||||
handleCallback(val){
|
||||
this.$Message.success("导入成功")
|
||||
this.images.push({url:val.url})
|
||||
confirmUrls() {
|
||||
this.showOssManager = false;
|
||||
},
|
||||
// 从资源库中导入图片
|
||||
importOSS(){
|
||||
handleCallback(val) {
|
||||
this.$Message.success("导入成功");
|
||||
this.images.push({ url: val.url });
|
||||
},
|
||||
importOSS() {
|
||||
this.showOssManager = true;
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.ossManage) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.import-oss{
|
||||
.import-oss {
|
||||
margin-bottom: 10px;
|
||||
text-align: right;
|
||||
color: $theme_color;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
.wrapper{
|
||||
.wrapper {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.upload-list {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
@@ -166,47 +193,48 @@ export default {
|
||||
margin-right: 4px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.upload-box{
|
||||
.upload-box {
|
||||
margin: 10px 0;
|
||||
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.upload-trigger {
|
||||
width: 148px;
|
||||
height: 148px;
|
||||
line-height: 148px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.upload-list img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.upload-list:hover .upload-list-cover {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.upload-list-cover div {
|
||||
margin-top: 50px;
|
||||
width: 100%;
|
||||
|
||||
>i {
|
||||
width: 50%;
|
||||
margin-top: 8px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.action-icon {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -51,49 +51,45 @@
|
||||
<li class="hz-u-square hz-u-square-br" data-pointer="dealBR"></li>
|
||||
</ul>
|
||||
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="showModal"
|
||||
title="编辑热区"
|
||||
draggable
|
||||
scrollable
|
||||
:mask="false"
|
||||
ok-text="保存"
|
||||
@on-ok="saveZone"
|
||||
@on-cancel="cancelZone"
|
||||
:modal="false"
|
||||
append-to-body
|
||||
width="520px"
|
||||
@close="cancelZone"
|
||||
>
|
||||
<div>
|
||||
<div class="hz-edit-img">
|
||||
<img class="show-image" :src="zoneForm.img" alt />
|
||||
</div>
|
||||
|
||||
<Form :model="zoneForm" :label-width="80">
|
||||
<!-- <FormItem label="图片链接:">
|
||||
<Input v-model="zoneForm.img"></Input>
|
||||
<Button size="small" type="primary" @click="handleSelectImg"
|
||||
>选择图片</Button
|
||||
<el-form :model="zoneForm" label-width="80px">
|
||||
<el-form-item label="跳转链接:">
|
||||
<el-input type="textarea" v-if="zoneForm.type === 'other' && zoneForm.title === '外部链接'" v-model="zoneForm.link" />
|
||||
<el-button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</el-button
|
||||
>
|
||||
:v-model="zoneForm.type === 'goods' ? zoneForm.goodsName : zoneForm.link"
|
||||
</FormItem> -->
|
||||
<FormItem label="跳转链接:">
|
||||
<Input type="textarea" v-if="zoneForm.type === 'other' && zoneForm.title === '外部链接'" v-model="zoneForm.link" ></Input>
|
||||
<Button size="small" type="primary" @click="handleSelectLink"
|
||||
>选择链接</Button
|
||||
>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="cancelZone">取消</el-button>
|
||||
<el-button type="primary" @click="saveZone">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 选择商品。链接 -->
|
||||
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
|
||||
<!-- 选择图片 -->
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<el-dialog width="1200px" v-model="picModelFlag" append-to-body destroy-on-close>
|
||||
<ossManage
|
||||
@callback="callbackSelected"
|
||||
:isComponent="true"
|
||||
:initialize="picModelFlag"
|
||||
ref="ossManage"
|
||||
/>
|
||||
</Modal>
|
||||
<template #footer />
|
||||
</el-dialog>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
@@ -179,7 +175,7 @@ export default {
|
||||
},
|
||||
// 已选链接
|
||||
selectedLink(val) {
|
||||
this.zoneForm.link = this.$options.filters.formatLinkType(val);
|
||||
this.zoneForm.link = this.$filters.formatLinkType(val);
|
||||
this.settingZone(val);
|
||||
this.changeInfo(this.zoneForm);
|
||||
},
|
||||
@@ -220,7 +216,10 @@ export default {
|
||||
break;
|
||||
}
|
||||
},
|
||||
saveZone() {},
|
||||
saveZone() {
|
||||
this.showModal = false;
|
||||
this.changeInfo(this.zoneForm);
|
||||
},
|
||||
cancelZone() {
|
||||
this.showModal = false;
|
||||
},
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<template>
|
||||
<Modal
|
||||
:styles="{ top: '120px' }"
|
||||
width="800"
|
||||
@on-cancel="clickClose"
|
||||
@on-ok="clickOK"
|
||||
<el-dialog
|
||||
v-model="flag"
|
||||
:mask-closable="false"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
title="绘制热区"
|
||||
scrollable
|
||||
top="120px"
|
||||
destroy-on-close
|
||||
@close="clickClose"
|
||||
>
|
||||
<template v-if="flag">
|
||||
<hotzone
|
||||
@@ -17,7 +16,11 @@
|
||||
:image="res.img"
|
||||
></hotzone>
|
||||
</template>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="clickClose">取消</el-button>
|
||||
<el-button type="primary" @click="clickOK">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import hotzone from "./components/Hotzone.vue";
|
||||
@@ -57,11 +60,11 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
::v-deep .ivu-modal {
|
||||
:deep(.el-dialog) {
|
||||
overflow: hidden;
|
||||
height: 650px !important;
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
:deep(.el-dialog__body) {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -4,46 +4,26 @@
|
||||
<div class="query-wrapper">
|
||||
<div class="query-item">
|
||||
<div>搜索范围</div>
|
||||
<Input
|
||||
<el-input
|
||||
v-model="goodsParams.goodsName"
|
||||
placeholder="商品名称"
|
||||
@on-clear="
|
||||
goodsData = [];
|
||||
goodsParams.goodsName = '';
|
||||
goodsParams.pageNumber = 1;
|
||||
getQueryGoodsList();
|
||||
"
|
||||
@on-enter="
|
||||
() => {
|
||||
goodsData = [];
|
||||
goodsParams.pageNumber = 1;
|
||||
getQueryGoodsList();
|
||||
}
|
||||
"
|
||||
icon="ios-search"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
v-model="goodsParams.goodsName"
|
||||
@clear="onSearchGoods"
|
||||
@keyup.enter="onSearchGoods"
|
||||
/>
|
||||
</div>
|
||||
<div class="query-item">
|
||||
<Cascader
|
||||
<el-cascader
|
||||
v-model="category"
|
||||
:options="skuList"
|
||||
placeholder="请选择商品分类"
|
||||
style="width: 250px"
|
||||
:data="skuList"
|
||||
></Cascader>
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
<div class="query-item">
|
||||
<Button
|
||||
type="primary"
|
||||
@click="
|
||||
goodsData = [];
|
||||
goodsParams.pageNumber = 1;
|
||||
getQueryGoodsList();
|
||||
"
|
||||
icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
<el-button type="primary" @click="onSearchGoods">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -63,27 +43,33 @@
|
||||
<div class="wap-content-desc">
|
||||
<div class="wap-content-desc-title">{{ item.goodsName }}</div>
|
||||
|
||||
<div class="wap-sku">{{ item.goodsUnit }}<Tag style="margin-left: 10px;" :color="item.salesModel === 'RETAIL' ? 'default' : 'geekblue'">{{item.salesModel === "RETAIL" ? "零售型" : "批发型"}}</Tag></div>
|
||||
<div class="wap-sku">
|
||||
{{ item.goodsUnit }}
|
||||
<el-tag
|
||||
style="margin-left: 10px"
|
||||
:type="item.salesModel === 'RETAIL' ? 'info' : 'primary'"
|
||||
>
|
||||
{{ item.salesModel === "RETAIL" ? "零售型" : "批发型" }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="wap-content-desc-bottom">
|
||||
<div>¥{{ item.price | unitPrice }}</div>
|
||||
<div>¥{{ $filters.unitPrice(item.price) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Spin size="large" fix v-if="loading"></Spin>
|
||||
<div v-if="loading" v-loading="loading" class="loading-mask" />
|
||||
|
||||
<div v-if="empty" class="empty">暂无商品信息</div>
|
||||
</div>
|
||||
<Page
|
||||
:total="total"
|
||||
<el-pagination
|
||||
v-model:current-page="goodsParams.pageNumber"
|
||||
class="pageration"
|
||||
@on-change="changePageSize"
|
||||
:total="total"
|
||||
:page-size="goodsParams.pageSize"
|
||||
layout="total, prev, pager, next"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
|
||||
>
|
||||
</Page>
|
||||
@current-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -145,6 +131,11 @@ export default {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
onSearchGoods() {
|
||||
this.goodsData = [];
|
||||
this.goodsParams.pageNumber = 1;
|
||||
this.getQueryGoodsList();
|
||||
},
|
||||
changePageSize(v){
|
||||
this.goodsParams.pageNumber = v;
|
||||
this.getQueryGoodsList();
|
||||
@@ -201,7 +192,6 @@ export default {
|
||||
arr[index] = {
|
||||
value: grandson.id,
|
||||
label: grandson.name,
|
||||
children: "",
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<Modal :styles="{ top: '120px' }" width="1160" :z-index="10000" @on-cancel="clickClose" @on-ok="clickOK" v-model="flag" :mask-closable="false" scrollable>
|
||||
<el-dialog
|
||||
v-model="flag"
|
||||
width="1160px"
|
||||
top="120px"
|
||||
:z-index="10000"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@close="clickClose"
|
||||
>
|
||||
<template v-if="flag">
|
||||
<goodsDialog
|
||||
@selected="
|
||||
@@ -21,7 +30,11 @@
|
||||
class="linkDialog"
|
||||
/>
|
||||
</template>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="clickClose">取消</el-button>
|
||||
<el-button type="primary" @click="clickOK">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import goodsDialog from "./goods-dialog";
|
||||
@@ -86,11 +99,7 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
::v-deep .ivu-modal {
|
||||
overflow: hidden;
|
||||
height: 650px !important;
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
:deep(.el-dialog__body) {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<Tabs :value="wap[0].title" class="tabs">
|
||||
<TabPane
|
||||
<el-tabs v-model="activeTab" class="tabs">
|
||||
<el-tab-pane
|
||||
:label="item.title"
|
||||
:name="item.title"
|
||||
@click="clickTag(item, i)"
|
||||
v-for="(item, i) in wap"
|
||||
:key="i"
|
||||
>
|
||||
@@ -17,9 +16,8 @@
|
||||
}
|
||||
"
|
||||
/>
|
||||
</TabPane>
|
||||
<!-- </template> -->
|
||||
</Tabs>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -30,13 +28,16 @@ export default {
|
||||
components: {
|
||||
goodsDialog
|
||||
},
|
||||
setup() {
|
||||
return { templateWay };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
templateWay, // 模板数据
|
||||
changed: "", // 变更模板
|
||||
selected: 0, // 已选数据
|
||||
selectedLink: "", //选中的链接
|
||||
wap, // tab标签
|
||||
activeTab: wap[0]?.title || "",
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -122,13 +123,8 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep .ivu-modal {
|
||||
overflow: hidden;
|
||||
height: 650px !important;
|
||||
}
|
||||
::v-deep .ivu-modal-body {
|
||||
width: 100%;
|
||||
:deep(.el-tabs__content) {
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .ivu-scroll-container {
|
||||
:deep(.ivu-scroll-container){
|
||||
width: 100% !important;
|
||||
height: 400px !important;
|
||||
}
|
||||
|
||||
::v-deep .ivu-scroll-content {
|
||||
:deep(.ivu-scroll-content){
|
||||
/* */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -81,7 +81,7 @@
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
|
||||
::v-deep img {
|
||||
:deep(img){
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { markRaw } from "vue";
|
||||
import category from "./category.vue";
|
||||
import shops from "./shops.vue";
|
||||
import marketing from "./marketing.vue";
|
||||
import pages from "./pages.vue";
|
||||
import goods from "../goods-dialog.vue";
|
||||
import other from "./other.vue";
|
||||
import special from "./special.vue";
|
||||
|
||||
import category from './category.vue'
|
||||
import shops from './shops.vue'
|
||||
import marketing from './marketing.vue'
|
||||
import pages from './pages.vue'
|
||||
import goods from '../goods-dialog.vue'
|
||||
import other from './other.vue'
|
||||
import special from './special.vue'
|
||||
export default {
|
||||
pages,
|
||||
marketing,
|
||||
shops,
|
||||
category,
|
||||
goods,
|
||||
other,
|
||||
special
|
||||
}
|
||||
pages: markRaw(pages),
|
||||
marketing: markRaw(marketing),
|
||||
shops: markRaw(shops),
|
||||
category: markRaw(category),
|
||||
goods: markRaw(goods),
|
||||
other: markRaw(other),
|
||||
special: markRaw(special),
|
||||
};
|
||||
|
||||
@@ -2,49 +2,66 @@
|
||||
<div class="wrapper">
|
||||
<div class="list">
|
||||
<div
|
||||
class="list-item"
|
||||
v-for="(item, index) in Object.keys(promotionList)"
|
||||
:key="index"
|
||||
@click="clickPromotion(item, index)"
|
||||
class="list-item"
|
||||
:class="{ active: selectedIndex == index }"
|
||||
@click="clickPromotion(item, index)"
|
||||
>
|
||||
{{ typeOption(item).title }}
|
||||
</div>
|
||||
|
||||
<!-- <div class="list-item" >暂无活动</div> -->
|
||||
</div>
|
||||
<div class="content">
|
||||
<div v-if="showPromotionList">
|
||||
<!-- <div class="search-views">
|
||||
<Input v-model="value11" disabled class="search">
|
||||
<span slot="prepend">店铺名称</span>
|
||||
</Input>
|
||||
<Button type="primary">选择</Button>
|
||||
|
||||
</div> -->
|
||||
|
||||
<div class="tables">
|
||||
<Table
|
||||
height="350"
|
||||
border
|
||||
tooltip
|
||||
:loading="loading"
|
||||
:columns="activeColumns"
|
||||
:data="showPromotionList"
|
||||
></Table>
|
||||
<el-table v-loading="loading" border height="350" :data="showPromotionList" style="width: 100%">
|
||||
<template v-if="isSeckillMode">
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="storeName" label="店铺名称" show-overflow-tooltip />
|
||||
<el-table-column label="活动时间" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.timeLine }}点</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原价" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ $filters.unitPrice(row.originalPrice) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="现价" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ seckillStatusText(row.promotionApplyStatus) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-table-column prop="goodsName" label="商品名称" show-overflow-tooltip />
|
||||
<el-table-column prop="storeName" label="店铺名称" show-overflow-tooltip />
|
||||
<el-table-column prop="startTime" label="开始时间" show-overflow-tooltip />
|
||||
<el-table-column prop="endTime" label="结束时间" show-overflow-tooltip />
|
||||
</template>
|
||||
<el-table-column label="操作" width="100" fixed="right" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<a v-if="row" class="link-text" @click="selectedPromotion({ row, index: $index })">
|
||||
{{ index === $index ? "已选" : "选择" }}
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Page
|
||||
@on-change="
|
||||
(val) => {
|
||||
params.pageNumber = val;
|
||||
}
|
||||
"
|
||||
:current="params.pageNumber"
|
||||
:page-size="params.pageSize"
|
||||
<el-pagination
|
||||
v-model:current-page="params.pageNumber"
|
||||
v-model:page-size="params.pageSize"
|
||||
class="mt_10"
|
||||
:total="Number(totals)"
|
||||
layout="prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-elevator
|
||||
@current-change="(val) => { params.pageNumber = val; }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,225 +69,29 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getAllPromotion,
|
||||
getPromotionSeckill,
|
||||
getPromotionGoods,
|
||||
} from "@/api/promotion";
|
||||
import { getAllPromotion } from "@/api/promotion";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
totals: "", // 总数
|
||||
loading: true, //表格请求数据为true
|
||||
promotionList: "", // 活动列表
|
||||
selectedIndex: 0, //左侧菜单选择
|
||||
promotions: "", //选中的活动key
|
||||
index: 999, // 已选下标
|
||||
totals: "",
|
||||
loading: true,
|
||||
promotionList: "",
|
||||
selectedIndex: 0,
|
||||
promotions: "",
|
||||
index: 999,
|
||||
params: {
|
||||
// 请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
pintuanColumns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "开始时间",
|
||||
key: "startTime",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "结束时间",
|
||||
key: "endTime",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
fixed: "right",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.selectedPromotion(params);
|
||||
},
|
||||
},
|
||||
},
|
||||
this.index == params.index ? "已选" : "选择"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
seckillColumns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
tooltip: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "活动时间",
|
||||
key: "timeLine",
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("div", {}, `${params.row.timeLine}点`);
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "原价",
|
||||
key: "originalPrice",
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
{},
|
||||
this.$options.filters.unitPrice(params.row.originalPrice)
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "现价",
|
||||
key: "price",
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
{
|
||||
style: {},
|
||||
},
|
||||
this.$options.filters.unitPrice(params.row.price, "¥")
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "promotionApplyStatus",
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
{
|
||||
style: {},
|
||||
},
|
||||
params.row.promotionApplyStatus == "APPLY"
|
||||
? "申请"
|
||||
: params.row.promotionApplyStatus == "PASS"
|
||||
? "通过"
|
||||
: "拒绝"
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 100,
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.selectedPromotion(params);
|
||||
},
|
||||
},
|
||||
},
|
||||
this.index == params.index ? "已选" : "选择"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
activeColumns: [], // 活动表头
|
||||
|
||||
columns: [
|
||||
{
|
||||
title: "活动标题",
|
||||
key: "title",
|
||||
tooltip: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "活动开始时间",
|
||||
key: "startTime",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "活动结束时间",
|
||||
key: "endTime",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
fixed: "right",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.selectedPromotion(params);
|
||||
},
|
||||
},
|
||||
},
|
||||
this.index == params.index ? "已选" : "选择"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
promotionData: "", //商品集合
|
||||
|
||||
showPromotionList: [], //显示当前促销的商品
|
||||
showPromotionList: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isSeckillMode() {
|
||||
return this.promotions === "SECKILL";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
@@ -278,97 +99,48 @@ export default {
|
||||
params: {
|
||||
handler() {
|
||||
this.index = 999;
|
||||
this.typeOption(this.promotions) &&
|
||||
this.typeOption(this.promotions).methodsed();
|
||||
this.typeOption(this.promotions) && this.typeOption(this.promotions).methodsed();
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
seckillStatusText(v) {
|
||||
if (v === "APPLY") return "申请";
|
||||
if (v === "PASS") return "通过";
|
||||
return "拒绝";
|
||||
},
|
||||
sortGoods(type) {
|
||||
this.loading = false;
|
||||
this.params.pageNumber - 1;
|
||||
this.showPromotionList = this.promotionList[type];
|
||||
},
|
||||
typeOption(type) {
|
||||
// 活动选项
|
||||
switch (type) {
|
||||
case "FULL_DISCOUNT":
|
||||
return {
|
||||
title: "满减",
|
||||
methodsed: () => {
|
||||
this.showPromotionList = [];
|
||||
this.activeColumns = this.pintuanColumns;
|
||||
|
||||
this.sortGoods("FULL_DISCOUNT");
|
||||
},
|
||||
};
|
||||
return { title: "满减", methodsed: () => { this.showPromotionList = []; this.sortGoods("FULL_DISCOUNT"); } };
|
||||
case "PINTUAN":
|
||||
return {
|
||||
title: "拼团",
|
||||
methodsed: (id) => {
|
||||
this.showPromotionList = [];
|
||||
this.activeColumns = this.pintuanColumns;
|
||||
this.sortGoods("PINTUAN");
|
||||
},
|
||||
};
|
||||
|
||||
return { title: "拼团", methodsed: () => { this.showPromotionList = []; this.sortGoods("PINTUAN"); } };
|
||||
case "KANJIA":
|
||||
return {
|
||||
title: "砍价",
|
||||
methodsed: (id) => {
|
||||
this.showPromotionList = [];
|
||||
this.activeColumns = this.pintuanColumns;
|
||||
this.sortGoods("KANJIA");
|
||||
},
|
||||
};
|
||||
return { title: "砍价", methodsed: () => { this.showPromotionList = []; this.sortGoods("KANJIA"); } };
|
||||
case "SECKILL":
|
||||
return {
|
||||
title: "秒杀",
|
||||
methodsed: () => {
|
||||
this.showPromotionList = [];
|
||||
this.activeColumns = this.seckillColumns;
|
||||
this.sortGoods("SECKILL");
|
||||
},
|
||||
};
|
||||
// case "COUPON":
|
||||
// return {
|
||||
// title: "优惠券",
|
||||
// methodsed: () => {
|
||||
// this.showPromotionList = [];
|
||||
// this.activeColumns = this.pintuanColumns;
|
||||
// this.sortGoods("COUPON");
|
||||
// },
|
||||
// };
|
||||
return { title: "秒杀", methodsed: () => { this.showPromotionList = []; this.sortGoods("SECKILL"); } };
|
||||
case "POINTS_GOODS":
|
||||
return {
|
||||
title: "积分商品",
|
||||
methodsed: () => {
|
||||
this.showPromotionList = [];
|
||||
this.activeColumns = this.pintuanColumns;
|
||||
this.sortGoods("POINTS_GOODS");
|
||||
},
|
||||
};
|
||||
return { title: "积分商品", methodsed: () => { this.showPromotionList = []; this.sortGoods("POINTS_GOODS"); } };
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
},
|
||||
// 选择活动
|
||||
selectedPromotion(val) {
|
||||
val.row.___type = "marketing";
|
||||
val.row.___promotion = this.promotions;
|
||||
this.$emit("selected", [val.row]);
|
||||
|
||||
this.index = val.index;
|
||||
},
|
||||
// 获取所有营销的活动
|
||||
async init() {
|
||||
let res = await getAllPromotion();
|
||||
const res = await getAllPromotion();
|
||||
if (res.success) {
|
||||
this.loading = false;
|
||||
this.getPromotion(res);
|
||||
// this.clickPromotion(this.typeOption[Object.keys(res.result)[0]], 0);
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
@@ -376,43 +148,25 @@ export default {
|
||||
getPromotion(res) {
|
||||
if (res.result) {
|
||||
this.promotionList = res.result;
|
||||
// 去除优惠券
|
||||
delete this.promotionList.COUPON;
|
||||
Object.keys(res.result)[0] && this.typeOption(Object.keys(res.result)[0]).methodsed();
|
||||
this.promotions = Object.keys(res.result)[0];
|
||||
}
|
||||
|
||||
// if (Object.keys(res.result).length) {
|
||||
// this.typeOption[Object.keys(res.result)[0]].methodsed(
|
||||
// this.promotionList[Object.keys(res.result)[0]].id
|
||||
// );
|
||||
// }
|
||||
},
|
||||
|
||||
// 点击某个活动查询活动列表
|
||||
clickPromotion(val, i) {
|
||||
this.promotions = val;
|
||||
this.selectedIndex = i;
|
||||
this.params.pageNumber = 1;
|
||||
this.typeOption(val) &&
|
||||
this.typeOption(val).methodsed(this.promotionList[val].id);
|
||||
this.typeOption(val) && this.typeOption(val).methodsed(this.promotionList[val].id);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.search {
|
||||
width: 300px;
|
||||
}
|
||||
.page {
|
||||
margin-top: 2vh;
|
||||
text-align: right;
|
||||
}
|
||||
.time {
|
||||
font-size: 12px;
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.tables {
|
||||
height: 400px;
|
||||
@@ -420,13 +174,12 @@ img {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
}
|
||||
::v-deep .ivu-table-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
.list {
|
||||
margin: 0 1.5%;
|
||||
height: 400px;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
width: auto;
|
||||
> .list-item {
|
||||
padding: 10px;
|
||||
transition: 0.35s;
|
||||
@@ -436,10 +189,6 @@ img {
|
||||
background: #ededed;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
flex: 1;
|
||||
width: auto;
|
||||
}
|
||||
.content {
|
||||
overflow: hidden;
|
||||
flex: 4;
|
||||
@@ -449,11 +198,6 @@ img {
|
||||
}
|
||||
.wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
.search-views {
|
||||
display: flex;
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,142 +1,103 @@
|
||||
<template>
|
||||
<div>
|
||||
<Row :gutter="30">
|
||||
<Col
|
||||
span="4"
|
||||
v-for="(item, index) in linkList"
|
||||
:key="index"
|
||||
v-if="
|
||||
(item.title !== '拼团频道' && item.title !== '签到') ||
|
||||
$route.name !== 'renovation'
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="card"
|
||||
:class="{ active: selectedIndex == index }"
|
||||
@click="handleLink(item, index)"
|
||||
<el-row :gutter="30">
|
||||
<template v-for="(item, index) in linkList" :key="index">
|
||||
<el-col
|
||||
v-if="showLinkItem(item)"
|
||||
:span="4"
|
||||
>
|
||||
<Icon size="24" :type="item.icon" />
|
||||
<p>{{ item.title }}</p>
|
||||
</div>
|
||||
</Col>
|
||||
<!-- 外部链接,只有pc端跳转 -->
|
||||
<Col span="4">
|
||||
<div
|
||||
class="card"
|
||||
:class="{ active: selectedIndex == index }"
|
||||
@click="handleLink(item, index)"
|
||||
>
|
||||
<el-icon :size="24">
|
||||
<component :is="item.icon" />
|
||||
</el-icon>
|
||||
<p>{{ item.title }}</p>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
<el-col v-if="linkVisible" :span="4">
|
||||
<div
|
||||
v-if="linkVisible"
|
||||
class="card"
|
||||
:class="{ active: selectedIndex == linkList.length }"
|
||||
@click="handleLink(linkItem, linkList.length)"
|
||||
>
|
||||
<Icon size="24" :type="linkItem.icon" />
|
||||
<el-icon :size="24">
|
||||
<component :is="linkItem.icon" />
|
||||
</el-icon>
|
||||
<p>{{ linkItem.title }}</p>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { markRaw } from "vue";
|
||||
import {
|
||||
House,
|
||||
ShoppingCart,
|
||||
Star,
|
||||
Document,
|
||||
User,
|
||||
Promotion,
|
||||
PriceTag,
|
||||
Sunny,
|
||||
VideoCamera,
|
||||
Share,
|
||||
ShoppingBag,
|
||||
Link,
|
||||
} from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
linkList: [
|
||||
// 链接列表
|
||||
{
|
||||
title: "首页",
|
||||
icon: "md-home",
|
||||
___type: "home",
|
||||
},
|
||||
{
|
||||
title: "购物车",
|
||||
icon: "md-cart",
|
||||
___type: "cart",
|
||||
},
|
||||
{
|
||||
title: "收藏商品",
|
||||
icon: "md-heart",
|
||||
___type: "collection",
|
||||
},
|
||||
{
|
||||
title: "我的订单",
|
||||
icon: "md-document",
|
||||
___type: "order",
|
||||
},
|
||||
{
|
||||
title: "个人中心",
|
||||
icon: "md-person",
|
||||
___type: "user",
|
||||
},
|
||||
{
|
||||
title: "拼团频道",
|
||||
icon: "md-flame",
|
||||
___type: "group",
|
||||
},
|
||||
{
|
||||
title: "秒杀频道",
|
||||
icon: "md-flame",
|
||||
___type: "seckill",
|
||||
},
|
||||
{
|
||||
title: "领券中心",
|
||||
icon: "md-pricetag",
|
||||
___type: "coupon",
|
||||
},
|
||||
{
|
||||
title: "签到",
|
||||
icon: "md-happy",
|
||||
___type: "sign",
|
||||
},
|
||||
{
|
||||
title: "小程序直播",
|
||||
icon: "ios-videocam",
|
||||
___type: "live",
|
||||
},
|
||||
{
|
||||
title: "砍价",
|
||||
icon: "md-share-alt",
|
||||
___type: "kanjia",
|
||||
},
|
||||
{
|
||||
title: "积分商城",
|
||||
icon: "ios-basket",
|
||||
___type: "point",
|
||||
},
|
||||
{ title: "首页", icon: markRaw(House), ___type: "home" },
|
||||
{ title: "购物车", icon: markRaw(ShoppingCart), ___type: "cart" },
|
||||
{ title: "收藏商品", icon: markRaw(Star), ___type: "collection" },
|
||||
{ title: "我的订单", icon: markRaw(Document), ___type: "order" },
|
||||
{ title: "个人中心", icon: markRaw(User), ___type: "user" },
|
||||
{ title: "拼团频道", icon: markRaw(Promotion), ___type: "group" },
|
||||
{ title: "秒杀频道", icon: markRaw(Promotion), ___type: "seckill" },
|
||||
{ title: "领券中心", icon: markRaw(PriceTag), ___type: "coupon" },
|
||||
{ title: "签到", icon: markRaw(Sunny), ___type: "sign" },
|
||||
{ title: "小程序直播", icon: markRaw(VideoCamera), ___type: "live" },
|
||||
{ title: "砍价", icon: markRaw(Share), ___type: "kanjia" },
|
||||
{ title: "积分商城", icon: markRaw(ShoppingBag), ___type: "point" },
|
||||
],
|
||||
linkItem: {
|
||||
title: "外部链接",
|
||||
icon: "ios-link",
|
||||
icon: markRaw(Link),
|
||||
___type: "link",
|
||||
url: "",
|
||||
},
|
||||
linkVisible: true, // 是否显示外部链接
|
||||
selectedIndex: 9999999, // 已选index
|
||||
linkVisible: true,
|
||||
selectedIndex: 9999999,
|
||||
};
|
||||
},
|
||||
created(){
|
||||
// console.log(window.location.href)
|
||||
let urls = window.location.href
|
||||
if(urls.indexOf('/floorList/renovation') != -1){
|
||||
this.linkList.forEach((items,indexs)=>{
|
||||
if(items.title == '砍价'){
|
||||
this.linkList.splice(indexs,1)
|
||||
}
|
||||
})
|
||||
this.linkList.forEach((item,index)=>{
|
||||
if(item.title == '小程序直播'){
|
||||
this.linkList.splice(index,1)
|
||||
}
|
||||
})
|
||||
this.linkList.forEach((itemss,indexss)=>{
|
||||
if(itemss.title == '积分商城'){
|
||||
this.linkList.splice(indexss,1)
|
||||
}
|
||||
})
|
||||
this.linkVisible = true
|
||||
}else{
|
||||
this.linkVisible = false
|
||||
created() {
|
||||
const urls = window.location.href;
|
||||
if (urls.indexOf("/floorList/renovation") != -1) {
|
||||
this.linkList = this.linkList.filter(
|
||||
(item) =>
|
||||
item.title !== "砍价" &&
|
||||
item.title !== "小程序直播" &&
|
||||
item.title !== "积分商城"
|
||||
);
|
||||
this.linkVisible = true;
|
||||
} else {
|
||||
this.linkVisible = false;
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
showLinkItem(item) {
|
||||
return (
|
||||
(item.title !== "拼团频道" && item.title !== "签到") ||
|
||||
this.$route.name !== "renovation"
|
||||
);
|
||||
},
|
||||
handleLink(val, index) {
|
||||
val = { ...val, ___type: "other" };
|
||||
this.selectedIndex = index;
|
||||
@@ -157,7 +118,7 @@ export default {
|
||||
text-align: center;
|
||||
transition: 0.35s;
|
||||
cursor: pointer;
|
||||
::v-deep p {
|
||||
:deep(p) {
|
||||
margin: 10px 0;
|
||||
}
|
||||
border: 1px solid #ededed;
|
||||
|
||||
@@ -33,7 +33,7 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-card-body {
|
||||
:deep(.ivu-card-body){
|
||||
height: 414px;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -69,11 +69,11 @@ export default {
|
||||
height: 416px;
|
||||
overflow: hidden;
|
||||
}
|
||||
::v-deep .ivu-table {
|
||||
:deep(.ivu-table){
|
||||
height: 300px !important;
|
||||
overflow: auto;
|
||||
}
|
||||
::v-deep .ivu-card-body {
|
||||
:deep(.ivu-card-body){
|
||||
padding: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -4,40 +4,54 @@
|
||||
<div class="query-wrapper">
|
||||
<div class="query-item">
|
||||
<div>店铺名称</div>
|
||||
<Input placeholder="请输入店铺名称" @on-clear="shopsData=[]; params.storeName=''; params.pageNumber =1; init()" @on-enter="()=>{shopsData=[]; params.pageNumber =1; init();}" icon="ios-search" clearable style="width: 150px"
|
||||
v-model="params.storeName" />
|
||||
<el-input
|
||||
v-model="params.storeName"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
style="width: 150px"
|
||||
@clear="resetSearch"
|
||||
@keyup.enter="resetSearch"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="query-item">
|
||||
<Button type="primary" @click="shopsData=[];params.pageNumber =1; init();" icon="ios-search">搜索</Button>
|
||||
<el-button type="primary" @click="resetSearch">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="wap-content-list" >
|
||||
<div class="wap-content-item" @click="clickShop(item,index)" :class="{ active:selected == index }" v-for="(item, index) in shopsData" :key="index">
|
||||
<div v-loading="loading" class="wap-content-list">
|
||||
<div
|
||||
v-for="(item, index) in shopsData"
|
||||
:key="index"
|
||||
class="wap-content-item"
|
||||
:class="{ active: selected == index }"
|
||||
@click="clickShop(item, index)"
|
||||
>
|
||||
<div>
|
||||
<img class="shop-logo" :src="item.storeLogo" alt="" />
|
||||
</div>
|
||||
<div class="wap-content-desc">
|
||||
<div class="wap-content-desc-title">{{ item.storeName }}</div>
|
||||
|
||||
<div class="self-operated" :class="{'theme_color':item.selfOperated }">{{ item.selfOperated ? '自营' : '非自营' }}</div>
|
||||
<div class="wap-sku" :class="{'theme_color':(item.storeDisable === 'OPEN' ? true : false) }">{{ item.storeDisable === 'OPEN' ? '开启中' : '未开启' }}</div>
|
||||
<div class="self-operated" :class="{ theme_color: item.selfOperated }">
|
||||
{{ item.selfOperated ? "自营" : "非自营" }}
|
||||
</div>
|
||||
<div
|
||||
class="wap-sku"
|
||||
:class="{ theme_color: item.storeDisable === 'OPEN' }"
|
||||
>
|
||||
{{ item.storeDisable === "OPEN" ? "开启中" : "未开启" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Spin size="large" fix v-if="loading"></Spin>
|
||||
</div>
|
||||
<Page
|
||||
:total="total"
|
||||
<el-pagination
|
||||
class="pageration"
|
||||
@on-change="changePageSize"
|
||||
:page-size="params.pageSize"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
|
||||
>
|
||||
</Page>
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="params.pageSize"
|
||||
:current-page="params.pageNumber"
|
||||
@current-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,25 +61,28 @@ import { getShopListData } from "@/api/shops.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false, // 加载状态
|
||||
total: "", // 总数
|
||||
params: { // 请求参数
|
||||
loading: false,
|
||||
total: 0,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 12,
|
||||
storeDisable: "OPEN",
|
||||
storeName: "",
|
||||
},
|
||||
shopsData: [], // 店铺数据
|
||||
selected: 9999999999, //设置一个不可能选中的index
|
||||
shopsData: [],
|
||||
selected: 9999999999,
|
||||
};
|
||||
},
|
||||
watch: {},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
changePageSize(v){
|
||||
resetSearch() {
|
||||
this.shopsData = [];
|
||||
this.params.pageNumber = 1;
|
||||
this.init();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.params.pageNumber = v;
|
||||
this.init();
|
||||
},
|
||||
@@ -73,15 +90,10 @@ export default {
|
||||
this.loading = true;
|
||||
getShopListData(this.params).then((res) => {
|
||||
if (res.success) {
|
||||
/**
|
||||
* 解决数据请求中,滚动栏会一直上下跳动
|
||||
*/
|
||||
this.total = res.result.total;
|
||||
|
||||
this.shopsData = res.result.records;
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
clickShop(val, i) {
|
||||
@@ -105,15 +117,18 @@ export default {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 340px;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.shop-logo {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: url("../../../assets/selected.png") no-repeat;
|
||||
background-position: right;
|
||||
background-size: 10%;
|
||||
}
|
||||
.pageration {
|
||||
margin-top: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,26 +3,31 @@
|
||||
<div class="content">
|
||||
<div>
|
||||
<div class="tables">
|
||||
<Table
|
||||
border
|
||||
height="350"
|
||||
tooltip
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
>
|
||||
</Table>
|
||||
<el-table v-loading="loading" border height="350" :data="data" style="width: 100%">
|
||||
<el-table-column prop="name" label="专题名称" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="100" fixed="right" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<el-button
|
||||
v-if="row"
|
||||
:type="index === $index ? 'primary' : 'default'"
|
||||
size="small"
|
||||
@click="selectRow(row, $index)"
|
||||
>
|
||||
{{ index === $index ? "已选" : "选择" }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Page
|
||||
|
||||
@on-change="changePageNum"
|
||||
@on-page-size-change="changePageSize"
|
||||
:current="params.pageNumber"
|
||||
:page-size="params.pageSize"
|
||||
<el-pagination
|
||||
v-model:current-page="params.pageNumber"
|
||||
v-model:page-size="params.pageSize"
|
||||
class="mt_10"
|
||||
:total="Number(total)"
|
||||
layout="prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-elevator
|
||||
@current-change="changePageNum"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,16 +35,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getHomeList } from "@/api/other.js";
|
||||
import { getHomeList } from "@/api/other.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true, //表格请求数据为true
|
||||
promotionList: "", // 活动列表
|
||||
selectedIndex: 0, //左侧菜单选择
|
||||
promotions: "", //选中的活动key
|
||||
index: 999, // 已选下标
|
||||
data:[],
|
||||
loading: true,
|
||||
index: 999,
|
||||
data: [],
|
||||
params: {
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
@@ -48,68 +50,34 @@ export default {
|
||||
pageSize: 20,
|
||||
pageType: "SPECIAL",
|
||||
},
|
||||
total: 0, // 表单数据总数
|
||||
columns: [
|
||||
{
|
||||
title: "专题名称",
|
||||
key: "name",
|
||||
tooltip: true,
|
||||
// slot: 'name'
|
||||
// width: 200,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
fixed: "right",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: this.index == params.index ? "primary" : "default",
|
||||
size: "small",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.index = params.index;
|
||||
params.row = {...params.row,pageType:'special',___type:'special'}
|
||||
this.$emit("selected", [params.row]);
|
||||
},
|
||||
},
|
||||
},
|
||||
this.index == params.index ? "已选" : "选择"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
methods: {
|
||||
changePageNum (val) { // 修改评论页码
|
||||
selectRow(row, idx) {
|
||||
this.index = idx;
|
||||
const payload = { ...row, pageType: "special", ___type: "special" };
|
||||
this.$emit("selected", [payload]);
|
||||
},
|
||||
changePageNum(val) {
|
||||
this.params.pageNumber = val;
|
||||
this.init();
|
||||
},
|
||||
changePageSize (val) { // 修改评论页数
|
||||
changePageSize(val) {
|
||||
this.params.pageNumber = 1;
|
||||
this.params.pageSize = val;
|
||||
this.init();
|
||||
},
|
||||
// 获取话题的标题
|
||||
async init() {
|
||||
// 根据当前路径判断当前是H5还是PC
|
||||
this.params.pageClientType = this.$route.name === 'renovation' ? 'PC' : 'H5'
|
||||
let res = await getHomeList(this.params);
|
||||
this.params.pageClientType = this.$route.name === "renovation" ? "PC" : "H5";
|
||||
const res = await getHomeList(this.params);
|
||||
if (res.success) {
|
||||
this.loading = false;
|
||||
this.data= res.result.records
|
||||
this.total = res.result.total
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
@@ -128,49 +96,17 @@ img {
|
||||
margin-top: 2vh;
|
||||
text-align: right;
|
||||
}
|
||||
.time {
|
||||
font-size: 12px;
|
||||
}
|
||||
.tables {
|
||||
height: 400px;
|
||||
margin-top: 20px;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
}
|
||||
::v-deep .ivu-table-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
.list {
|
||||
margin: 0 1.5%;
|
||||
height: 400px;
|
||||
overflow: auto;
|
||||
> .list-item {
|
||||
padding: 10px;
|
||||
transition: 0.35s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.list-item:hover {
|
||||
background: #ededed;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
flex: 1;
|
||||
width: auto;
|
||||
}
|
||||
.content {
|
||||
overflow: hidden;
|
||||
flex: 4;
|
||||
}
|
||||
.active {
|
||||
background: #ededed;
|
||||
}
|
||||
.wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
.search-views {
|
||||
display: flex;
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
<template>
|
||||
<div style="display: inline-block;">
|
||||
<Icon type="ios-loading" size="18" color="#2d8cf0" class="spin-icon-load"></Icon>
|
||||
<div style="display: inline-block">
|
||||
<el-icon class="spin-icon-load" :size="18" color="#ff5c58">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Loading } from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
name: "circleLoading"
|
||||
name: "circleLoading",
|
||||
components: { Loading },
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -14,5 +19,12 @@ export default {
|
||||
.spin-icon-load {
|
||||
animation: ani-demo-spin 1s linear infinite;
|
||||
}
|
||||
@keyframes ani-demo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,78 +1,34 @@
|
||||
<template>
|
||||
<div>
|
||||
<Drawer width="300px" title="页面配置" v-model="drawer">
|
||||
<!-- 内容 -->
|
||||
<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>
|
||||
<el-drawer v-model="drawer" title="页面配置" size="300px">
|
||||
<div class="config-empty">暂无可配置项</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: "configDrawer",
|
||||
data() {
|
||||
return {
|
||||
drawer: false,
|
||||
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
setting: state => {
|
||||
return state.setting.setting
|
||||
}
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
setting: {
|
||||
handler(val) {
|
||||
this.setStore('admin-setting', val)
|
||||
this.$store.commit('updateSetting', val);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.drawer = true
|
||||
this.drawer = true;
|
||||
},
|
||||
close() {
|
||||
this.drawer = false
|
||||
this.drawer = false;
|
||||
},
|
||||
toggle() {
|
||||
this.drawer != this.drawer
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
* {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 10px 0 20px 0;
|
||||
}
|
||||
|
||||
.config-item {
|
||||
cursor: pointer;
|
||||
margin-bottom: 20px;
|
||||
justify-content: space-between;
|
||||
<style scoped>
|
||||
.config-empty {
|
||||
color: #909399;
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,72 +1,68 @@
|
||||
<template>
|
||||
<div>
|
||||
<Cascader
|
||||
<el-cascader
|
||||
v-model="selectDep"
|
||||
:data="department"
|
||||
@on-change="handleChangeDep"
|
||||
change-on-select
|
||||
:options="department"
|
||||
:props="cascaderProps"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择"
|
||||
></Cascader>
|
||||
style="width: 100%"
|
||||
@change="handleChangeDep"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { initDepartment } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "departmentChoose",
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectDep: [], // 已选数据
|
||||
department: [] // 列表
|
||||
selectDep: [],
|
||||
department: [],
|
||||
cascaderProps: {
|
||||
value: "value",
|
||||
label: "label",
|
||||
children: "children",
|
||||
checkStrictly: true,
|
||||
emitPath: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取部门数据
|
||||
initDepartmentData() {
|
||||
initDepartment().then(res => {
|
||||
initDepartment().then((res) => {
|
||||
if (res.success) {
|
||||
const arr = res.result;
|
||||
this.filterData(arr)
|
||||
this.department = arr
|
||||
this.filterData(arr);
|
||||
this.department = arr;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleChangeDep(value, selectedData) {
|
||||
handleChangeDep(value) {
|
||||
let departmentId = "";
|
||||
// 获取最后一个值
|
||||
if (value && value.length > 0) {
|
||||
departmentId = value[value.length - 1];
|
||||
}
|
||||
this.$emit("on-change", departmentId);
|
||||
},
|
||||
// 清空已选列表
|
||||
clearSelect() {
|
||||
this.selectDep = [];
|
||||
},
|
||||
// 处理部门数据
|
||||
filterData (data) {
|
||||
data.forEach(e => {
|
||||
filterData(data) {
|
||||
data.forEach((e) => {
|
||||
e.value = e.id;
|
||||
e.label = e.title;
|
||||
if (e.children) {
|
||||
this.filterData(e.children)
|
||||
} else {
|
||||
return
|
||||
this.filterData(e.children);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initDepartmentData();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,106 +1,110 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display:flex;">
|
||||
<Input
|
||||
<div style="display: flex">
|
||||
<el-input
|
||||
v-model="departmentTitle"
|
||||
readonly
|
||||
style="margin-right:10px;"
|
||||
style="margin-right: 10px; flex: 1"
|
||||
:placeholder="placeholder"
|
||||
:clearable="clearable"
|
||||
@on-clear="clearSelect"
|
||||
@clear="clearSelect"
|
||||
/>
|
||||
<Poptip transfer trigger="click" placement="right" title="选择部门" width="250">
|
||||
<Button icon="md-list">选择部门</Button>
|
||||
<div slot="content">
|
||||
<Input
|
||||
v-model="searchKey"
|
||||
suffix="ios-search"
|
||||
@on-change="searchDep"
|
||||
placeholder="输入部门名搜索"
|
||||
clearable
|
||||
<el-popover trigger="click" placement="right" title="选择部门" :width="280">
|
||||
<template #reference>
|
||||
<el-button>选择部门</el-button>
|
||||
</template>
|
||||
<el-input
|
||||
v-model="searchKey"
|
||||
placeholder="输入部门名搜索"
|
||||
clearable
|
||||
style="margin-bottom: 8px"
|
||||
@input="searchDep"
|
||||
/>
|
||||
<div v-loading="depLoading" class="dep-tree-bar">
|
||||
<el-tree
|
||||
:data="dataDep"
|
||||
:props="treeProps"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
default-expand-all
|
||||
@node-click="selectTree"
|
||||
/>
|
||||
<div class="dep-tree-bar">
|
||||
<Tree
|
||||
:data="dataDep"
|
||||
@on-select-change="selectTree"
|
||||
></Tree>
|
||||
<Spin size="large" fix v-if="depLoading"></Spin>
|
||||
</div>
|
||||
</div>
|
||||
</Poptip>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {initDepartment, searchDepartment} from "@/api/index";
|
||||
import { initDepartment } from "@/api/index";
|
||||
|
||||
export default {
|
||||
name: "departmentTreeChoose",
|
||||
props: {
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "点击选择部门"
|
||||
}
|
||||
default: "点击选择部门",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
depLoading: false, // 加载状态
|
||||
departmentTitle: "", // modal标题
|
||||
searchKey: "", // 搜索关键词
|
||||
dataDep: [], // 部门列表
|
||||
cloneDep: [], // 克隆部门列表
|
||||
selectDep: [], // 已选部门
|
||||
departmentId: [] // 部门id
|
||||
depLoading: false,
|
||||
departmentTitle: "",
|
||||
searchKey: "",
|
||||
dataDep: [],
|
||||
cloneDep: [],
|
||||
departmentId: [],
|
||||
treeProps: {
|
||||
label: "title",
|
||||
children: "children",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取部门数据
|
||||
initDepartmentData() {
|
||||
initDepartment().then(res => {
|
||||
if (res.success) {
|
||||
this.dataDep = res.result;
|
||||
|
||||
this.cloneDep = JSON.parse(JSON.stringify(this.dataDep));
|
||||
}
|
||||
});
|
||||
this.depLoading = true;
|
||||
initDepartment()
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.dataDep = res.result;
|
||||
this.cloneDep = JSON.parse(JSON.stringify(this.dataDep));
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.depLoading = false;
|
||||
});
|
||||
},
|
||||
searchDep() {
|
||||
// 搜索部门
|
||||
if (this.searchKey) {
|
||||
this.dataDep = this.cloneDep.filter(item => {
|
||||
return item.title.indexOf(this.searchKey) > -1;
|
||||
});
|
||||
|
||||
this.dataDep = this.cloneDep.filter(
|
||||
(item) => item.title.indexOf(this.searchKey) > -1
|
||||
);
|
||||
} else {
|
||||
this.dataDep = JSON.parse(JSON.stringify(this.cloneDep));
|
||||
}
|
||||
},
|
||||
// 选择回调
|
||||
selectTree(v) {
|
||||
if (v.length === 0) {
|
||||
selectTree(node) {
|
||||
if (!node) {
|
||||
this.$emit("on-change", null);
|
||||
this.departmentId = "";
|
||||
this.departmentTitle = "";
|
||||
return
|
||||
return;
|
||||
}
|
||||
this.departmentId = v[0].id;
|
||||
this.departmentTitle = v[0].title;
|
||||
let department = {
|
||||
this.departmentId = node.id;
|
||||
this.departmentTitle = node.title;
|
||||
this.$emit("on-change", {
|
||||
departmentId: this.departmentId,
|
||||
departmentTitle: this.departmentTitle
|
||||
}
|
||||
this.$emit("on-change", department);
|
||||
departmentTitle: this.departmentTitle,
|
||||
});
|
||||
},
|
||||
// 清除选中方法
|
||||
clearSelect() {
|
||||
this.departmentId = [];
|
||||
this.departmentTitle = "";
|
||||
@@ -112,7 +116,6 @@ export default {
|
||||
}
|
||||
this.$emit("on-clear");
|
||||
},
|
||||
// 设置数据 回显用
|
||||
setData(ids, title) {
|
||||
this.departmentTitle = title;
|
||||
if (this.multiple) {
|
||||
@@ -121,11 +124,11 @@ export default {
|
||||
this.departmentId = [];
|
||||
this.departmentId.push(ids);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initDepartmentData();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -145,9 +148,6 @@ export default {
|
||||
|
||||
.dep-tree-bar::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 0 2px #d1d1d1;
|
||||
background: #e4e4e4;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
<template>
|
||||
<div class="set-password">
|
||||
<Poptip transfer trigger="focus" placement="right" width="250">
|
||||
<Input
|
||||
type="password"
|
||||
password
|
||||
style="width:350px;"
|
||||
:maxlength="maxlength"
|
||||
v-model="currentValue"
|
||||
@on-change="handleChange"
|
||||
:size="size"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
/>
|
||||
<div :class="tipStyle" slot="content">
|
||||
<div class="words">强度 : {{strength}}</div>
|
||||
<Progress
|
||||
:percent="strengthValue"
|
||||
:status="progressStatus"
|
||||
hide-info
|
||||
style="margin: 13px 0;"
|
||||
<el-popover trigger="focus" placement="right" :width="250">
|
||||
<template #reference>
|
||||
<el-input
|
||||
v-model="currentValue"
|
||||
type="password"
|
||||
show-password
|
||||
style="width: 350px"
|
||||
:maxlength="maxlength"
|
||||
:size="size"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
@input="handleChange"
|
||||
/>
|
||||
<br />请至少输入 6 个字符。请不要使
|
||||
<br />用容易被猜到的密码。
|
||||
</template>
|
||||
<div :class="tipStyle">
|
||||
<div class="words">强度 : {{ strength }}</div>
|
||||
<el-progress
|
||||
:percentage="strengthValue"
|
||||
:status="progressStatus"
|
||||
:show-text="false"
|
||||
style="margin: 13px 0"
|
||||
/>
|
||||
<br />请至少输入 6 个字符。请不要使用容易被猜到的密码。
|
||||
</div>
|
||||
</Poptip>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -32,54 +33,53 @@
|
||||
export default {
|
||||
name: "setPassword",
|
||||
props: {
|
||||
modelValue: String,
|
||||
value: String,
|
||||
size: String,
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "请输入密码,长度为6-20个字符"
|
||||
default: "请输入密码,长度为6-20个字符",
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: 20
|
||||
}
|
||||
default: 20,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change"],
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value, // 当前值
|
||||
tipStyle: "password-tip-none", // 强度样式
|
||||
strengthValue: 0, // 强度等级
|
||||
progressStatus: "normal", // 进度条状态
|
||||
strength: "无", // 密码强度描述
|
||||
grade: 0 // 强度等级
|
||||
currentValue: this.modelValue ?? this.value ?? "",
|
||||
tipStyle: "password-tip-none",
|
||||
strengthValue: 0,
|
||||
progressStatus: "",
|
||||
strength: "无",
|
||||
grade: 0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
this.setCurrentValue(val);
|
||||
},
|
||||
value(val) {
|
||||
this.setCurrentValue(val);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
checkStrengthValue(v) {
|
||||
// 评级制判断密码强度 最高5
|
||||
let grade = 0;
|
||||
if (/\d/.test(v)) {
|
||||
grade++; //数字
|
||||
}
|
||||
if (/[a-z]/.test(v)) {
|
||||
grade++; //小写
|
||||
}
|
||||
if (/[A-Z]/.test(v)) {
|
||||
grade++; //大写
|
||||
}
|
||||
if (/\W/.test(v)) {
|
||||
grade++; //特殊字符
|
||||
}
|
||||
if (v.length >= 10) {
|
||||
grade++;
|
||||
}
|
||||
if (/\d/.test(v)) grade++;
|
||||
if (/[a-z]/.test(v)) grade++;
|
||||
if (/[A-Z]/.test(v)) grade++;
|
||||
if (/\W/.test(v)) grade++;
|
||||
if (v.length >= 10) grade++;
|
||||
this.grade = grade;
|
||||
return grade;
|
||||
},
|
||||
@@ -90,14 +90,14 @@ export default {
|
||||
this.strengthValue = 0;
|
||||
return;
|
||||
}
|
||||
let grade = this.checkStrengthValue(this.currentValue);
|
||||
const grade = this.checkStrengthValue(this.currentValue);
|
||||
if (grade <= 1) {
|
||||
this.progressStatus = "wrong";
|
||||
this.progressStatus = "exception";
|
||||
this.tipStyle = "password-tip-weak";
|
||||
this.strength = "弱";
|
||||
this.strengthValue = 33;
|
||||
} else if (grade >= 2 && grade <= 4) {
|
||||
this.progressStatus = "normal";
|
||||
this.progressStatus = "";
|
||||
this.tipStyle = "password-tip-middle";
|
||||
this.strength = "中";
|
||||
this.strengthValue = 66;
|
||||
@@ -108,61 +108,33 @@ export default {
|
||||
this.strengthValue = 100;
|
||||
}
|
||||
},
|
||||
// 密码变动后回调
|
||||
handleChange(v) {
|
||||
handleChange() {
|
||||
this.strengthChange();
|
||||
this.$emit("update:modelValue", this.currentValue);
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue, this.grade, this.strength);
|
||||
},
|
||||
// 监听密码变动,实时回显密码强度
|
||||
setCurrentValue(value) {
|
||||
if (value === this.currentValue) {
|
||||
return;
|
||||
}
|
||||
this.currentValue = value;
|
||||
if (value === this.currentValue) return;
|
||||
this.currentValue = value ?? "";
|
||||
this.strengthChange();
|
||||
this.$emit("on-change", this.currentValue, this.grade, this.strength);
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.setCurrentValue(val);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.set-password .ivu-poptip,
|
||||
.set-password .ivu-poptip-rel {
|
||||
display: block;
|
||||
}
|
||||
.password-tip-none {
|
||||
padding: 1vh 0;
|
||||
}
|
||||
|
||||
.password-tip-weak {
|
||||
padding: 1vh 0;
|
||||
|
||||
.words {
|
||||
color: #ed3f14;
|
||||
}
|
||||
.password-tip-weak .words {
|
||||
color: #ed3f14;
|
||||
}
|
||||
|
||||
.password-tip-middle {
|
||||
padding: 1vh 0;
|
||||
|
||||
.words {
|
||||
color: #2d8cf0;
|
||||
}
|
||||
.password-tip-middle .words {
|
||||
color: #2d8cf0;
|
||||
}
|
||||
|
||||
.password-tip-strong {
|
||||
padding: 1vh 0;
|
||||
|
||||
.words {
|
||||
color: #52c41a;
|
||||
}
|
||||
.password-tip-strong .words {
|
||||
color: #52c41a;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,210 +1,166 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display:flex;">
|
||||
<Input
|
||||
<div style="display: flex; gap: 10px; align-items: center; width: 100%">
|
||||
<el-input
|
||||
v-if="showInput"
|
||||
v-model="currentValue"
|
||||
@on-change="handleChange"
|
||||
v-show="showInput"
|
||||
:placeholder="placeholder"
|
||||
:size="size"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
:maxlength="maxlength"
|
||||
style="flex: 1"
|
||||
@input="handleChange"
|
||||
>
|
||||
<Poptip slot="append" transfer trigger="hover" title="图片预览" placement="right">
|
||||
<Icon type="md-eye" class="see-icon" />
|
||||
<div slot="content">
|
||||
<img :src="currentValue" alt="该资源不存在" style="max-width: 300px;margin: 0 auto;display: block;" />
|
||||
<a @click="viewImage=true" style="margin-top:5px;text-align:right;display:block">查看大图</a>
|
||||
</div>
|
||||
</Poptip>
|
||||
</Input>
|
||||
<Button @click="handleCLickImg('storeLogo')">选择图片</Button>
|
||||
<!--<Upload-->
|
||||
<!--:action="uploadFileUrl"-->
|
||||
<!--:headers="accessToken"-->
|
||||
<!--:on-success="handleSuccess"-->
|
||||
<!--:on-error="handleError"-->
|
||||
<!--:format="['jpg','jpeg','png','gif','bmp']"-->
|
||||
<!--accept=".jpg, .jpeg, .png, .gif, .bmp"-->
|
||||
<!--:max-size="1024"-->
|
||||
<!--:on-format-error="handleFormatError"-->
|
||||
<!--:on-exceeded-size="handleMaxSize"-->
|
||||
<!--:before-upload="beforeUpload"-->
|
||||
<!--:show-upload-list="false"-->
|
||||
<!--ref="up"-->
|
||||
<!--class="upload"-->
|
||||
<!-->-->
|
||||
<!--<Button :loading="loading" :size="size" :disabled="disabled">上传图片</Button>-->
|
||||
<!--</Upload>-->
|
||||
<template #append>
|
||||
<el-popover trigger="hover" placement="right" :width="320" title="图片预览">
|
||||
<template #reference>
|
||||
<el-button class="see-icon">
|
||||
<el-icon><View /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
<img
|
||||
v-if="currentValue"
|
||||
:src="currentValue"
|
||||
alt="该资源不存在"
|
||||
style="max-width: 280px; display: block; margin: 0 auto"
|
||||
/>
|
||||
<el-button
|
||||
v-if="currentValue"
|
||||
type="primary"
|
||||
link
|
||||
style="margin-top: 8px; display: block; text-align: right"
|
||||
@click="viewImage = true"
|
||||
>
|
||||
查看大图
|
||||
</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button @click="handleCLickImg('storeLogo')">选择图片</el-button>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
title="图片预览"
|
||||
v-model="viewImage"
|
||||
:styles="{ top: '30px' }"
|
||||
:z-index="3500"
|
||||
draggable
|
||||
>
|
||||
<img :src="currentValue" alt="该资源不存在" style="max-width: 300px;margin: 0 auto;display: block;" />
|
||||
<div slot="footer">
|
||||
<Button @click="viewImage=false">关闭</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Modal width="1200px" v-model="picModalFlag" :z-index="3500">
|
||||
<ossManage @callback="callbackSelected" ref="ossManage" :isComponent="true" :initialize="picModalFlag" />
|
||||
</Modal>
|
||||
<el-dialog v-model="viewImage" title="图片预览" width="480px" append-to-body :z-index="3500">
|
||||
<img
|
||||
:src="currentValue"
|
||||
alt="该资源不存在"
|
||||
style="max-width: 100%; margin: 0 auto; display: block"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="viewImage = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="picModalFlag" width="1200px" append-to-body :z-index="3500" destroy-on-close>
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="picModalFlag"
|
||||
@callback="callbackSelected"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { View } from "@element-plus/icons-vue";
|
||||
import { uploadFile } from "@/api/index";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
|
||||
export default {
|
||||
name: "uploadPicInput",
|
||||
components: {
|
||||
ossManage,
|
||||
View,
|
||||
},
|
||||
props: {
|
||||
modelValue: String,
|
||||
value: String,
|
||||
size: {
|
||||
default: 'default',
|
||||
type: String
|
||||
default: "default",
|
||||
type: String,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "图片链接"
|
||||
default: "图片链接",
|
||||
},
|
||||
showInput: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
maxlength: Number,
|
||||
icon: {
|
||||
type: String,
|
||||
default: "ios-cloud-upload-outline"
|
||||
}
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change"],
|
||||
data() {
|
||||
return {
|
||||
accessToken: {}, // 验证token
|
||||
currentValue: this.value, // 当前值
|
||||
loading: false, // 加载状态
|
||||
viewImage: false, // 预览图片modal
|
||||
uploadFileUrl: uploadFile, // 上传地址
|
||||
picModalFlag: false, // 图片选择器
|
||||
selectedFormBtnName: "", // 点击图片绑定form
|
||||
picIndex: "", // 存储身份证图片下标,方便赋值
|
||||
accessToken: {},
|
||||
currentValue: this.modelValue ?? this.value ?? "",
|
||||
viewImage: false,
|
||||
uploadFileUrl: uploadFile,
|
||||
picModalFlag: false,
|
||||
selectedFormBtnName: "",
|
||||
picIndex: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 选择图片modal
|
||||
handleCLickImg(val, index) {
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
this.picModalFlag = true;
|
||||
this.selectedFormBtnName = val;
|
||||
this.picIndex = index;
|
||||
},
|
||||
// 图片回显
|
||||
callbackSelected(val) {
|
||||
this.picModalFlag = false;
|
||||
this.currentValue = val.url;
|
||||
this.picIndex = "";
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue);
|
||||
this.emitValue(this.currentValue);
|
||||
},
|
||||
// 初始化
|
||||
init() {
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken")
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
},
|
||||
// 格式校验
|
||||
handleFormatError(file) {
|
||||
this.loading = false;
|
||||
this.$Notice.warning({
|
||||
title: "不支持的文件格式",
|
||||
desc:
|
||||
"所选文件‘ " +
|
||||
file.name +
|
||||
" ’格式不正确, 请选择 .jpg .jpeg .png .gif .bmp格式文件"
|
||||
});
|
||||
emitValue(val) {
|
||||
this.$emit("update:modelValue", val);
|
||||
this.$emit("input", val);
|
||||
this.$emit("on-change", val);
|
||||
},
|
||||
// 大小校验
|
||||
handleMaxSize(file) {
|
||||
this.loading = false;
|
||||
this.$Notice.warning({
|
||||
title: "文件大小过大",
|
||||
desc: "所选文件大小过大, 不得超过1M."
|
||||
});
|
||||
handleChange() {
|
||||
this.emitValue(this.currentValue);
|
||||
this.$attrs.rollback && this.$attrs.rollback();
|
||||
},
|
||||
// 上传前
|
||||
beforeUpload() {
|
||||
this.loading = true;
|
||||
return true;
|
||||
},
|
||||
// 上传成功
|
||||
handleSuccess(res, file) {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.currentValue = res.result;
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue);
|
||||
} else {
|
||||
// this.$Message.error(res.message);
|
||||
}
|
||||
},
|
||||
// 上传失败
|
||||
handleError(error, file, fileList) {
|
||||
this.loading = false;
|
||||
this.$Message.error(error.toString());
|
||||
},
|
||||
// 上传成功回显
|
||||
handleChange(v) {
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue);
|
||||
this.$attrs.rollback && this.$attrs.rollback()
|
||||
},
|
||||
// 初始值
|
||||
setCurrentValue(value) {
|
||||
if (value === this.currentValue) {
|
||||
return;
|
||||
}
|
||||
this.currentValue = value;
|
||||
this.$emit("input", this.currentValue);
|
||||
this.$emit("on-change", this.currentValue);
|
||||
}
|
||||
this.currentValue = value ?? "";
|
||||
this.emitValue(this.currentValue);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
this.setCurrentValue(val);
|
||||
},
|
||||
value(val) {
|
||||
this.setCurrentValue(val);
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.see-icon {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upload {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -3,187 +3,169 @@
|
||||
<div class="upload-pic-thumb">
|
||||
<vuedraggable
|
||||
:list="uploadList"
|
||||
:disabled="!draggable||!multiple"
|
||||
:disabled="!draggable || !multiple"
|
||||
:animation="200"
|
||||
class="list-group"
|
||||
ghost-class="thumb-ghost"
|
||||
@end="onEnd"
|
||||
>
|
||||
<div class="upload-list" v-for="(item, index) in uploadList" :key="index">
|
||||
<div v-if="item.status == 'finished'" style="height:60px;">
|
||||
<img :src="item.url" />
|
||||
<div v-for="(item, index) in uploadList" :key="index" class="upload-list">
|
||||
<div v-if="item.status == 'finished'" style="height: 60px">
|
||||
<img :src="item.url" alt="" />
|
||||
<div class="upload-list-cover">
|
||||
<Icon type="ios-eye-outline" @click="handleView(item.url)"></Icon>
|
||||
<Icon type="ios-trash-outline" @click="handleRemove(item)"></Icon>
|
||||
<el-icon class="action-icon" @click="handleView(item.url)"><View /></el-icon>
|
||||
<el-icon class="action-icon" @click="handleRemove(item)"><Delete /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
|
||||
<el-progress
|
||||
v-if="item.showProgress"
|
||||
:percentage="item.percentage"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
<Upload
|
||||
<el-upload
|
||||
ref="upload"
|
||||
:multiple="multiple"
|
||||
:show-upload-list="false"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
:format="['jpg','jpeg','png','gif']"
|
||||
:max-size="1024"
|
||||
:on-format-error="handleFormatError"
|
||||
:on-exceeded-size="handleMaxSize"
|
||||
:before-upload="handleBeforeUpload"
|
||||
type="drag"
|
||||
:action="uploadFileUrl"
|
||||
:headers="accessToken"
|
||||
style="display: inline-block;width:58px;"
|
||||
:multiple="multiple"
|
||||
:show-file-list="false"
|
||||
accept=".jpg,.jpeg,.png,.gif"
|
||||
drag
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
style="display: inline-block; width: 58px"
|
||||
>
|
||||
<div style="width: 58px;height:58px;line-height: 58px;">
|
||||
<Icon type="md-camera" size="20"></Icon>
|
||||
<div class="upload-trigger">
|
||||
<el-icon :size="20"><Camera /></el-icon>
|
||||
</div>
|
||||
</Upload>
|
||||
</el-upload>
|
||||
</div>
|
||||
<Modal title="图片预览" v-model="viewImage" :styles="{top: '30px'}" draggable>
|
||||
<img :src="imgUrl" alt="无效的图片链接" style="width: 100%;margin: 0 auto;display: block;" />
|
||||
<div slot="footer">
|
||||
<Button @click="viewImage=false">关闭</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<el-dialog v-model="viewImage" title="图片预览" width="520px" append-to-body>
|
||||
<img :src="imgUrl" alt="无效的图片链接" style="width: 100%; display: block; margin: 0 auto" />
|
||||
<template #footer>
|
||||
<el-button @click="viewImage = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Camera, Delete, View } from "@element-plus/icons-vue";
|
||||
import { uploadFile } from "@/api/index";
|
||||
import vuedraggable from "vuedraggable";
|
||||
|
||||
export default {
|
||||
name: "uploadPicThumb",
|
||||
components: {
|
||||
vuedraggable
|
||||
vuedraggable,
|
||||
Camera,
|
||||
Delete,
|
||||
View,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: null
|
||||
},
|
||||
modelValue: { type: null },
|
||||
value: { type: null },
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 10
|
||||
}
|
||||
default: 10,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue", "input", "on-change", "uploadchange"],
|
||||
data() {
|
||||
return {
|
||||
accessToken: {}, // 验证token
|
||||
uploadFileUrl: uploadFile, // 上传地址
|
||||
uploadList: [], // 上传列表
|
||||
viewImage: false, // 预览modal
|
||||
imgUrl: "" // 图片地址
|
||||
accessToken: {},
|
||||
uploadFileUrl: uploadFile,
|
||||
uploadList: [],
|
||||
viewImage: false,
|
||||
imgUrl: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
bindValue() {
|
||||
return this.modelValue !== undefined ? this.modelValue : this.value;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 拖拽结束事件
|
||||
onEnd() {
|
||||
this.returnValue();
|
||||
},
|
||||
// 初始化方法
|
||||
init() {
|
||||
this.setData(this.value, true);
|
||||
this.setData(this.bindValue, true);
|
||||
this.accessToken = {
|
||||
accessToken: this.getStore("accessToken")
|
||||
accessToken: this.getStore("accessToken"),
|
||||
};
|
||||
},
|
||||
// 预览图片
|
||||
handleView(imgUrl) {
|
||||
this.imgUrl = imgUrl;
|
||||
this.viewImage = true;
|
||||
},
|
||||
// 移除图片
|
||||
handleRemove(file) {
|
||||
this.uploadList = this.uploadList.filter(i => i.url !== file.url);
|
||||
this.uploadList = this.uploadList.filter((i) => i.url !== file.url);
|
||||
this.returnValue();
|
||||
},
|
||||
// 上传成功
|
||||
handleSuccess(res, file) {
|
||||
if (res.success) {
|
||||
file.url = res.result;
|
||||
// 单张图片处理
|
||||
if (!this.multiple && this.uploadList.length > 0) {
|
||||
// 删除第一张
|
||||
this.uploadList.splice(0, 1);
|
||||
}
|
||||
this.uploadList.push(file);
|
||||
// 返回组件值
|
||||
this.returnValue();
|
||||
} else {
|
||||
this.$Message.error(res.message);
|
||||
}
|
||||
},
|
||||
// 上传失败
|
||||
handleError(error, file, fileList) {
|
||||
handleError(error) {
|
||||
this.$Message.error(error.toString());
|
||||
},
|
||||
// 格式校验
|
||||
handleFormatError(file) {
|
||||
this.$Notice.warning({
|
||||
title: "不支持的文件格式",
|
||||
desc:
|
||||
"所选文件‘ " +
|
||||
file.name +
|
||||
" ’格式不正确, 请选择 .jpg .jpeg .png .gif图片格式文件"
|
||||
});
|
||||
},
|
||||
// 上传文件大小校验
|
||||
handleMaxSize(file) {
|
||||
this.$Notice.warning({
|
||||
title: "文件大小过大",
|
||||
desc:
|
||||
"所选文件大小过大,不能超过1M."
|
||||
});
|
||||
},
|
||||
// 上传之前钩子
|
||||
handleBeforeUpload() {
|
||||
handleBeforeUpload(file) {
|
||||
const okType = ["image/jpeg", "image/png", "image/gif", "image/jpg"].includes(file.type);
|
||||
if (!okType) {
|
||||
this.$Message.warning("请选择 .jpg .jpeg .png .gif 格式图片");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 > 1024) {
|
||||
this.$Message.warning("所选文件大小过大,不能超过 1M");
|
||||
return false;
|
||||
}
|
||||
if (this.multiple && this.uploadList.length >= this.limit) {
|
||||
this.$Message.warning("最多只能上传" + this.limit + "张图片");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 返回组件值
|
||||
emitValue(val) {
|
||||
this.$emit("update:modelValue", val);
|
||||
this.$emit("input", val);
|
||||
this.$emit("on-change", val);
|
||||
},
|
||||
returnValue() {
|
||||
if (!this.uploadList || this.uploadList.length < 1) {
|
||||
if (!this.multiple) {
|
||||
this.$emit("input", "");
|
||||
this.$emit("on-change", "");
|
||||
} else {
|
||||
this.$emit("input", []);
|
||||
this.$emit("on-change", []);
|
||||
}
|
||||
const empty = this.multiple ? [] : "";
|
||||
this.emitValue(empty);
|
||||
return;
|
||||
}
|
||||
if (!this.multiple) {
|
||||
// 单张
|
||||
let v = this.uploadList[0].url;
|
||||
this.$emit("input", v);
|
||||
this.$emit("on-change", v);
|
||||
this.emitValue(this.uploadList[0].url);
|
||||
} else {
|
||||
let v = [];
|
||||
this.uploadList.forEach(e => {
|
||||
v.push(e.url);
|
||||
});
|
||||
this.$emit("input", v);
|
||||
this.$emit("on-change", v);
|
||||
this.emitValue(this.uploadList.map((e) => e.url));
|
||||
}
|
||||
},
|
||||
// 传入值变化时改变值
|
||||
setData(v, init) {
|
||||
if (typeof v == "string") {
|
||||
// 单张
|
||||
if (this.multiple) {
|
||||
this.$Message.warning("多张上传仅支持数组数据类型");
|
||||
return;
|
||||
@@ -191,60 +173,49 @@ export default {
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
this.uploadList = [];
|
||||
let item = {
|
||||
url: v,
|
||||
status: "finished"
|
||||
};
|
||||
this.uploadList.push(item);
|
||||
this.uploadList = [{ url: v, status: "finished" }];
|
||||
this.$emit("uploadchange", v);
|
||||
this.$emit("on-change", v);
|
||||
} else if (typeof v == "object") {
|
||||
// 多张
|
||||
this.emitValue(v);
|
||||
} else if (typeof v == "object" && v) {
|
||||
if (!this.multiple) {
|
||||
this.$Message.warning("单张上传仅支持字符串数据类型");
|
||||
return;
|
||||
}
|
||||
this.uploadList = [];
|
||||
const list = v.length > this.limit ? v.slice(0, this.limit) : v;
|
||||
if (v.length > this.limit) {
|
||||
for (let i = 0; i < this.limit; i++) {
|
||||
let item = {
|
||||
url: v[i],
|
||||
status: "finished"
|
||||
};
|
||||
this.uploadList.push(item);
|
||||
}
|
||||
this.$emit("on-change", v.slice(0, this.limit));
|
||||
if (init) {
|
||||
this.$emit("input", v.slice(0, this.limit));
|
||||
}
|
||||
this.$Message.warning("最多只能上传" + this.limit + "张图片");
|
||||
} else {
|
||||
v.forEach(e => {
|
||||
let item = {
|
||||
status: "finished",
|
||||
...e
|
||||
};
|
||||
this.uploadList.push(item);
|
||||
}
|
||||
list.forEach((e) => {
|
||||
this.uploadList.push({
|
||||
status: "finished",
|
||||
...(typeof e === "string" ? { url: e } : e),
|
||||
});
|
||||
this.$emit("on-change", v);
|
||||
});
|
||||
if (init) {
|
||||
this.emitValue(list);
|
||||
} else {
|
||||
this.$emit("on-change", list);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
this.setData(val);
|
||||
},
|
||||
value(val) {
|
||||
this.setData(val);
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-pic-thumb{
|
||||
.upload-pic-thumb {
|
||||
display: flex;
|
||||
}
|
||||
.upload-list {
|
||||
@@ -264,7 +235,8 @@ export default {
|
||||
}
|
||||
.upload-list img {
|
||||
width: 100%;
|
||||
height: -webkit-fill-available;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.upload-list-cover {
|
||||
display: none;
|
||||
@@ -274,15 +246,17 @@ export default {
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.upload-list:hover .upload-list-cover {
|
||||
display: block;
|
||||
display: flex;
|
||||
}
|
||||
.upload-list-cover i {
|
||||
.action-icon {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.list-group {
|
||||
display: inline-block;
|
||||
@@ -291,4 +265,12 @@ export default {
|
||||
opacity: 0.5;
|
||||
background: #c8ebfb;
|
||||
}
|
||||
.upload-trigger {
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div id="map-container"></div>
|
||||
|
||||
<div class="search-con">
|
||||
<Input placeholder="输入关键字搜索" id="input-map" v-model="mapSearch" />
|
||||
<el-input id="input-map" v-model="mapSearch" placeholder="输入关键字搜索" clearable />
|
||||
<ul>
|
||||
<li v-for="(tip, index) in tips" :key="index" @click="selectAddr(tip.location)">
|
||||
<p>{{ tip.name }}</p>
|
||||
@@ -13,9 +13,8 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer" class="footer">
|
||||
|
||||
<Button type="primary" :loading="loading" @click="ok">确定</Button>
|
||||
<div class="footer">
|
||||
<el-button type="primary" :loading="loading" @click="ok">确定</el-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,38 +1,50 @@
|
||||
<template>
|
||||
<Modal width="800" footer-hide v-model="enableMap">
|
||||
<RadioGroup @on-change="changeMap" v-model="mapDefault" type="button">
|
||||
<Radio label="select">级联选择</Radio>
|
||||
<Radio label="map" v-if="aMapSwitch">高德地图</Radio>
|
||||
</RadioGroup>
|
||||
<el-dialog v-model="enableMap" width="800px" :show-close="true" destroy-on-close>
|
||||
<el-radio-group v-model="mapDefault" @change="changeMap">
|
||||
<el-radio-button value="select">级联选择</el-radio-button>
|
||||
<el-radio-button v-if="aMapSwitch" value="map">高德地图</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div>
|
||||
<div v-if="mapDefault === 'select'">
|
||||
<div class="selector">
|
||||
<div class="selector-item" v-for="(plant, plantIndex) in Object.keys(data)" :key="plantIndex">
|
||||
<div :class="{ 'active': chiosend[plantIndex].id == item.id }" v-for="(item, index) in data[plant]"
|
||||
<div
|
||||
v-for="(plant, plantIndex) in Object.keys(data)"
|
||||
:key="plantIndex"
|
||||
class="selector-item"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in data[plant]"
|
||||
:key="index"
|
||||
@click="init(item, plantIndex != Object.keys(data).length - 1 ? Object.keys(data)[plantIndex + 1] : 0, plantIndex)"
|
||||
class="map-item">
|
||||
:class="{ active: chiosend[plantIndex]?.id == item.id }"
|
||||
class="map-item"
|
||||
@click="
|
||||
init(
|
||||
item,
|
||||
plantIndex != Object.keys(data).length - 1
|
||||
? Object.keys(data)[plantIndex + 1]
|
||||
: 0,
|
||||
plantIndex
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="footer">
|
||||
<Button type="primary" @click="finished">确定</Button>
|
||||
<el-button type="primary" @click="finished">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<mapping v-if="mapDefault === 'map'" ref="map" @getAddress="getAddress" />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { aMapSwitch } from '@/config/index'
|
||||
import { aMapSwitch } from "@/config/index";
|
||||
import mapping from "@/components/map/index.vue";
|
||||
import * as API_Setup from "@/api/common.js";
|
||||
|
||||
export default {
|
||||
components: { mapping },
|
||||
data() {
|
||||
@@ -41,87 +53,76 @@ export default {
|
||||
enableMap: false,
|
||||
mapDefault: "select",
|
||||
data: {
|
||||
province: [], //省
|
||||
city: [], //市
|
||||
area: [], //区
|
||||
street: [], //街道
|
||||
province: [],
|
||||
city: [],
|
||||
area: [],
|
||||
street: [],
|
||||
},
|
||||
chiosend: [],
|
||||
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.chiosend = new Array(4).fill("");
|
||||
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.enableMap = true
|
||||
this.init({ id: 0 }, 'province');
|
||||
this.enableMap = true;
|
||||
this.init({ id: 0 }, "province");
|
||||
},
|
||||
changeMap(val) {
|
||||
this.mapDefault = val
|
||||
|
||||
|
||||
this.mapDefault = val;
|
||||
},
|
||||
init(val, level = 'province', index) {
|
||||
init(val, level = "province", index) {
|
||||
if (level == 0) {
|
||||
// 说明选择到了街道,将街道id存入数组
|
||||
this.chiosend.splice(3, 1, val);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
API_Setup.getChildRegion(val.id).then((res) => {
|
||||
if (res.result.length && val.id !== 0) {
|
||||
this.chiosend[index] = val
|
||||
}
|
||||
else if(!res.result.length){
|
||||
this.chiosend[index] = val
|
||||
this.chiosend[index] = val;
|
||||
} else if (!res.result.length) {
|
||||
this.chiosend[index] = val;
|
||||
}
|
||||
this.data[level] = res.result;
|
||||
if (level == 'city') {
|
||||
this.data.area = []
|
||||
this.data.street = []
|
||||
this.chiosend.splice(1, 3, "","","");
|
||||
if (level == "city") {
|
||||
this.data.area = [];
|
||||
this.data.street = [];
|
||||
this.chiosend.splice(1, 3, "", "", "");
|
||||
}
|
||||
if (level == 'area') {
|
||||
this.data.street = []
|
||||
this.chiosend.splice(2, 2, "","");
|
||||
if (level == "area") {
|
||||
this.data.street = [];
|
||||
this.chiosend.splice(2, 2, "", "");
|
||||
}
|
||||
if (level == 'street') {
|
||||
if (level == "street") {
|
||||
this.chiosend.splice(3, 1, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
getAddress(center) {
|
||||
this.$emit('callback', {
|
||||
this.$emit("callback", {
|
||||
type: this.mapDefault,
|
||||
data: center
|
||||
})
|
||||
data: center,
|
||||
});
|
||||
this.enableMap = false;
|
||||
},
|
||||
// 选择完成
|
||||
finished() {
|
||||
if(!this.chiosend[0]){
|
||||
this.$Message.error("请选择地址")
|
||||
return
|
||||
if (!this.chiosend[0]) {
|
||||
this.$Message.error("请选择地址");
|
||||
return;
|
||||
}
|
||||
const params = this.chiosend.filter((item) => item!=="" && item.value !== "");
|
||||
const params = this.chiosend.filter((item) => item !== "" && item.value !== "");
|
||||
this.enableMap = false;
|
||||
this.$emit('callback', {
|
||||
this.$emit("callback", {
|
||||
type: this.mapDefault,
|
||||
data: params
|
||||
})
|
||||
data: params,
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.selector {
|
||||
|
||||
|
||||
height: 400px;
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
|
||||
58
manager/src/components/price-color-scheme.vue
Normal file
58
manager/src/components/price-color-scheme.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<span :style="priceStyle">
|
||||
{{ dot }}{{ displayText }}
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { unitPrice } from "@/utils/filters";
|
||||
|
||||
export default {
|
||||
name: "priceColorScheme",
|
||||
props: {
|
||||
value: {
|
||||
default: 0,
|
||||
validator(val) {
|
||||
return (
|
||||
val === null ||
|
||||
val === undefined ||
|
||||
typeof val === "number" ||
|
||||
typeof val === "string"
|
||||
);
|
||||
},
|
||||
},
|
||||
unit: {
|
||||
type: String,
|
||||
default: "¥",
|
||||
},
|
||||
dot: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
customStyle: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
displayText() {
|
||||
const val = this.value;
|
||||
if (val === null || val === undefined || val === "" || val === "null") {
|
||||
return `${this.unit || "¥"}0.00`;
|
||||
}
|
||||
return unitPrice(val, this.unit);
|
||||
},
|
||||
priceStyle() {
|
||||
const resolvedColor = this.color || this.$mainColor || "";
|
||||
return resolvedColor
|
||||
? { color: resolvedColor, ...this.customStyle }
|
||||
: { ...this.customStyle };
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,182 +1,149 @@
|
||||
<template>
|
||||
<div>
|
||||
<Cascader
|
||||
:data="data"
|
||||
:load-data="loadData"
|
||||
<el-cascader
|
||||
v-model="addr"
|
||||
:options="data"
|
||||
:props="cascaderProps"
|
||||
placeholder="请选择地址"
|
||||
@on-change="change"
|
||||
style="width: 350px"
|
||||
></Cascader>
|
||||
@change="change"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {getChildRegion} from '@/api/common.js';
|
||||
import { getChildRegion } from "@/api/common.js";
|
||||
|
||||
export default {
|
||||
data () {
|
||||
props: ["addressId"],
|
||||
data() {
|
||||
return {
|
||||
data: [], // 地区数据
|
||||
addr: [] // 已选数据
|
||||
data: [],
|
||||
addr: [],
|
||||
};
|
||||
},
|
||||
props: ['addressId'],
|
||||
mounted () {},
|
||||
computed: {
|
||||
cascaderProps() {
|
||||
return {
|
||||
value: "value",
|
||||
label: "label",
|
||||
lazy: true,
|
||||
lazyLoad: this.loadData,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
change (val, selectedData) { // 选择地区
|
||||
/**
|
||||
* @returns [regionId,region]
|
||||
*/
|
||||
this.$emit('selected', [
|
||||
val,
|
||||
selectedData[selectedData.length - 1].__label.split('/')
|
||||
]);
|
||||
change(val) {
|
||||
if (!val || !val.length) {
|
||||
this.$emit("selected", [[], []]);
|
||||
return;
|
||||
}
|
||||
const labels = this.resolveLabels(val);
|
||||
this.$emit("selected", [val, labels]);
|
||||
},
|
||||
loadData (item, callback) { // 加载数据
|
||||
item.loading = true;
|
||||
getChildRegion(item.value).then((res) => {
|
||||
if (res.result.length <= 0) {
|
||||
item.loading = false;
|
||||
} else {
|
||||
res.result.forEach((child) => {
|
||||
item.loading = false;
|
||||
resolveLabels(values) {
|
||||
const labels = [];
|
||||
let options = this.data;
|
||||
for (const v of values) {
|
||||
const node = options.find((item) => item.value === v);
|
||||
if (!node) break;
|
||||
labels.push(node.label);
|
||||
options = node.children || [];
|
||||
}
|
||||
return labels;
|
||||
},
|
||||
loadData(node, resolve) {
|
||||
const parentId = node.level === 0 ? 0 : node.value;
|
||||
getChildRegion(parentId).then((res) => {
|
||||
if (!res.result || res.result.length <= 0) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
const nodes = res.result.map((child) => {
|
||||
const isLeaf =
|
||||
child.level === "street" ||
|
||||
node.label === "香港特别行政区" ||
|
||||
child.name === "台湾省";
|
||||
return {
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
leaf: isLeaf,
|
||||
};
|
||||
});
|
||||
resolve(nodes);
|
||||
});
|
||||
},
|
||||
async init() {
|
||||
const data = await getChildRegion(0);
|
||||
this.data = data.result.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
leaf: item.name === "台湾省",
|
||||
}));
|
||||
},
|
||||
async reviewData() {
|
||||
const addr = JSON.parse(JSON.stringify(this.addressId.split(",")));
|
||||
const length = addr.length;
|
||||
const root = await getChildRegion(0);
|
||||
const arr0 = root.result.map((item) => ({
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
leaf: item.name === "台湾省",
|
||||
children: [],
|
||||
}));
|
||||
|
||||
let data = {
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
loading: false,
|
||||
children: []
|
||||
};
|
||||
|
||||
if (child.level === 'street' || item.label === '香港特别行政区') {
|
||||
item.children.push({
|
||||
value: child.id,
|
||||
label: child.name
|
||||
});
|
||||
} else {
|
||||
item.children.push(data);
|
||||
}
|
||||
});
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
async init () { // 初始化地图数据
|
||||
let data = await getChildRegion(0);
|
||||
let arr = [];
|
||||
data.result.forEach((item) => {
|
||||
let obj;
|
||||
// 台湾省做处理
|
||||
if (item.name === '台湾省') {
|
||||
obj = {
|
||||
value: item.id,
|
||||
label: item.name
|
||||
};
|
||||
} else {
|
||||
obj = {
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
loading: false,
|
||||
children: []
|
||||
};
|
||||
}
|
||||
arr.push(obj);
|
||||
});
|
||||
this.data = arr;
|
||||
},
|
||||
async reviewData () {
|
||||
// 数据回显
|
||||
let addr = JSON.parse(JSON.stringify(this.addressId.split(',')));
|
||||
let length = addr.length;
|
||||
let data = await getChildRegion(0);
|
||||
let arr0 = [];
|
||||
let arr1 = [];
|
||||
let arr2 = [];
|
||||
// 第一级数据
|
||||
data.result.forEach((item) => {
|
||||
let obj;
|
||||
// 台湾省做处理
|
||||
if (item.name === '台湾省') {
|
||||
obj = {
|
||||
value: item.id,
|
||||
label: item.name
|
||||
};
|
||||
} else {
|
||||
obj = {
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
loading: false,
|
||||
children: []
|
||||
};
|
||||
}
|
||||
arr0.push(obj);
|
||||
});
|
||||
// 根据选择的数据来加载数据列表
|
||||
if (length > 0) {
|
||||
let children = await getChildRegion(addr[0]);
|
||||
children = this.handleData(children.result);
|
||||
const children = await getChildRegion(addr[0]);
|
||||
const arr1 = this.handleData(children.result);
|
||||
arr0.forEach((e) => {
|
||||
if (e.value === addr[0]) {
|
||||
e.children = arr1 = children;
|
||||
e.children = arr1;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (length > 1) {
|
||||
let children = await getChildRegion(addr[1]);
|
||||
children = this.handleData(children.result);
|
||||
let arr1 = arr0.find((e) => e.value === addr[0])?.children || [];
|
||||
const children = await getChildRegion(addr[1]);
|
||||
const arr2 = this.handleData(children.result);
|
||||
arr1.forEach((e) => {
|
||||
if (e.value === addr[1]) {
|
||||
e.children = arr2 = children;
|
||||
e.children = arr2;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (length > 2) {
|
||||
let children = await getChildRegion(addr[2]);
|
||||
children = this.handleData(children.result);
|
||||
const arr1 = arr0.find((e) => e.value === addr[0])?.children || [];
|
||||
const arr2 = arr1.find((e) => e.value === addr[1])?.children || [];
|
||||
const children = await getChildRegion(addr[2]);
|
||||
const arr3 = this.handleData(children.result);
|
||||
arr2.forEach((e) => {
|
||||
if (e.value === addr[2]) {
|
||||
e.children = children;
|
||||
e.children = arr3;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.data = arr0;
|
||||
this.addr = addr;
|
||||
},
|
||||
handleData (data) {
|
||||
// 处理接口数据
|
||||
let item = [];
|
||||
data.forEach((child) => {
|
||||
let obj = {
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
loading: false,
|
||||
children: []
|
||||
};
|
||||
|
||||
if (child.level === 'street' || item.label === '香港特别行政区') {
|
||||
item.push({
|
||||
value: child.id,
|
||||
label: child.name
|
||||
});
|
||||
} else {
|
||||
item.push(obj);
|
||||
}
|
||||
});
|
||||
return item;
|
||||
}
|
||||
handleData(data) {
|
||||
return data.map((child) => ({
|
||||
value: child.id,
|
||||
label: child.name,
|
||||
leaf: child.level === "street",
|
||||
children: child.level === "street" ? undefined : [],
|
||||
}));
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
addressId: {
|
||||
handler: function (v) {
|
||||
handler(v) {
|
||||
if (v) {
|
||||
this.reviewData();
|
||||
} else {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<div
|
||||
v-if="columns.length > 0"
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:class="[prefixCls, `${prefixCls}-${size}`, tableClass]">
|
||||
<Spin fix v-if="loading"></Spin>
|
||||
<div
|
||||
v-show="showHeader"
|
||||
ref="header-wrapper"
|
||||
@@ -297,6 +297,11 @@ export default {
|
||||
cellStyle: [Object, Function],
|
||||
expandKey: String
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
treeTableRoot: this,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
computedWidth: "",
|
||||
@@ -387,7 +392,7 @@ export default {
|
||||
this.measure();
|
||||
window.addEventListener("resize", this.measure);
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("resize", this.measure);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Checkbox from '../Checkbox/Checkbox'; // eslint-disable-line
|
||||
// import Radio from '../Radio/Radio'; // eslint-disable-line
|
||||
import { mixins } from './utils';
|
||||
import { Radio } from 'view-design'; // eslint-disable-line
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
export default {
|
||||
name: 'TreeTable__body',
|
||||
mixins: [mixins],
|
||||
components: { Radio },
|
||||
inject: {
|
||||
treeTableRoot: { default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
radioSelectedIndex: -1,
|
||||
@@ -15,6 +15,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
table() {
|
||||
if (this.treeTableRoot) return this.treeTableRoot;
|
||||
let parent = this.$parent;
|
||||
while (parent) {
|
||||
if (parent.$options && parent.$options.name === 'TreeTable') return parent;
|
||||
parent = parent.$parent;
|
||||
}
|
||||
return this.$parent;
|
||||
},
|
||||
},
|
||||
@@ -186,8 +192,21 @@ export default {
|
||||
return classList.join(' ');
|
||||
}
|
||||
|
||||
// Vue 3:scoped slot 合并到 $slots
|
||||
function renderTemplateSlot(table, slotName, scope) {
|
||||
if (!table || !slotName) return '';
|
||||
const slots = table.$slots || {};
|
||||
let slot = slots[slotName];
|
||||
if (!slot && table.$scopedSlots && table.$scopedSlots[slotName]) {
|
||||
slot = table.$scopedSlots[slotName];
|
||||
}
|
||||
if (!slot) return '';
|
||||
return slot(scope);
|
||||
}
|
||||
|
||||
// 根据type渲染单元格Cell
|
||||
function renderCell(row, rowIndex, column, columnIndex) {
|
||||
if (!row || !column) return '';
|
||||
// ExpandType
|
||||
if (this.isExpandCell(this.table, columnIndex)) {
|
||||
return <i class='zk-icon zk-icon-angle-right'></i>;
|
||||
@@ -226,7 +245,15 @@ export default {
|
||||
// onOn-change={isChecked => this.handleEvent(null, 'checkbox', { row, rowIndex, column, columnIndex }, { isChecked })}>
|
||||
// </Checkbox>;
|
||||
} else {
|
||||
res = <Radio value={this.radioSelectedIndex === rowIndex} on-on-change={() => this.handleEvent(null, 'radio', { row, rowIndex, column, columnIndex })}></Radio>;
|
||||
res = (
|
||||
<input
|
||||
type="radio"
|
||||
checked={this.radioSelectedIndex === rowIndex}
|
||||
onChange={() =>
|
||||
this.handleEvent(null, 'radio', { row, rowIndex, column, columnIndex })
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -254,9 +281,12 @@ export default {
|
||||
if (column.type === undefined || column.type === 'custom') {
|
||||
return row[column.key];
|
||||
} else if (column.type === 'template') {
|
||||
return this.table.$scopedSlots[column.template]
|
||||
? this.table.$scopedSlots[column.template]({ row, rowIndex, column, columnIndex })
|
||||
: '';
|
||||
return renderTemplateSlot.call(this, this.table, column.template, {
|
||||
row,
|
||||
rowIndex,
|
||||
column,
|
||||
columnIndex,
|
||||
});
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -305,10 +335,7 @@ export default {
|
||||
<td
|
||||
class={`${this.prefixCls}--expand-content`}
|
||||
colspan={this.table.tableColumns.length}>
|
||||
{this.table.$scopedSlots.expand
|
||||
? this.table.$scopedSlots.expand({ row, rowIndex })
|
||||
: ''
|
||||
}
|
||||
{renderTemplateSlot.call(this, this.table, 'expand', { row, rowIndex })}
|
||||
</td>
|
||||
</tr>,
|
||||
])
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
let scrollBarWidth;
|
||||
|
||||
export default function () {
|
||||
if (Vue.prototype.$isServer) return 0;
|
||||
export default function getScrollBarWidth() {
|
||||
if (typeof document === "undefined") return 0;
|
||||
if (scrollBarWidth !== undefined) return scrollBarWidth;
|
||||
|
||||
const outer = document.createElement('div');
|
||||
outer.style.visibility = 'hidden';
|
||||
outer.style.width = '100px';
|
||||
outer.style.position = 'absolute';
|
||||
outer.style.top = '-9999px';
|
||||
const outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.position = "absolute";
|
||||
outer.style.top = "-9999px";
|
||||
document.body.appendChild(outer);
|
||||
|
||||
const widthNoScroll = outer.offsetWidth;
|
||||
outer.style.overflow = 'scroll';
|
||||
outer.style.overflow = "scroll";
|
||||
|
||||
const inner = document.createElement('div');
|
||||
inner.style.width = '100%';
|
||||
const inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
outer.appendChild(inner);
|
||||
|
||||
const widthWithScroll = inner.offsetWidth;
|
||||
|
||||
@@ -1,59 +1,81 @@
|
||||
<template>
|
||||
<div class="verify-content" v-if="show" @mousemove="mouseMove" @mouseup="mouseUp" @click.stop>
|
||||
<div class="imgBox" :style="{width:data.originalWidth+'px',height:data.originalHeight + 'px'}">
|
||||
<img :src="data.backImage" style="width:100%;height:100%" alt="">
|
||||
<img class="slider" :src="data.slidingImage" :style="{left:distance+'px',top:data.randomY+'px'}" :width="data.sliderWidth" :height="data.sliderHeight" alt="">
|
||||
<Icon type="md-refresh" class="refresh" @click="init" />
|
||||
<div
|
||||
class="verify-content"
|
||||
v-if="show"
|
||||
@mousemove="mouseMove"
|
||||
@mouseup="mouseUp"
|
||||
@click.stop
|
||||
>
|
||||
<div
|
||||
class="imgBox"
|
||||
:style="{
|
||||
width: data.originalWidth + 'px',
|
||||
height: data.originalHeight + 'px',
|
||||
}"
|
||||
>
|
||||
<img :src="data.backImage" style="width: 100%; height: 100%" alt="" />
|
||||
<img
|
||||
class="slider"
|
||||
:src="data.slidingImage"
|
||||
:style="{ left: distance + 'px', top: data.randomY + 'px' }"
|
||||
:width="data.sliderWidth"
|
||||
:height="data.sliderHeight"
|
||||
alt=""
|
||||
/>
|
||||
<el-icon class="refresh" @click="init"><Refresh /></el-icon>
|
||||
</div>
|
||||
<div class="handle" :style="{width:data.originalWidth+'px'}">
|
||||
<span class="bgcolor" :style="{width:distance + 'px',background:bgColor}"></span>
|
||||
<span class="swiper" :style="{left:distance + 'px'}" @mousedown="mouseDown">
|
||||
<Icon type="md-arrow-round-forward" />
|
||||
<div class="handle" :style="{ width: data.originalWidth + 'px' }">
|
||||
<span
|
||||
class="bgcolor"
|
||||
:style="{ width: distance + 'px', background: bgColor }"
|
||||
></span>
|
||||
<span class="swiper" :style="{ left: distance + 'px' }" @mousedown="mouseDown">
|
||||
<el-icon><DArrowRight /></el-icon>
|
||||
</span>
|
||||
<span class="text">{{verifyText}}</span>
|
||||
<span class="text">{{ verifyText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getVerifyImg, postVerifyImg } from './verify.js';
|
||||
import { Refresh, DArrowRight } from "@element-plus/icons-vue";
|
||||
import { getVerifyImg, postVerifyImg } from "./verify.js";
|
||||
|
||||
export default {
|
||||
components: { Refresh, DArrowRight },
|
||||
props: {
|
||||
// 传入数据,判断是登录、注册、修改密码
|
||||
verifyType: {
|
||||
defalut: 'LOGIN',
|
||||
type: String
|
||||
}
|
||||
default: "LOGIN",
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
show: false, // 验证码显隐
|
||||
type: 'LOGIN', // 请求类型
|
||||
data: { // 验证码数据
|
||||
backImage: '',
|
||||
slidingImage: '',
|
||||
show: false,
|
||||
type: "LOGIN",
|
||||
data: {
|
||||
backImage: "",
|
||||
slidingImage: "",
|
||||
originalHeight: 150,
|
||||
originalWidth: 300,
|
||||
sliderWidth: 60,
|
||||
sliderHeight: 60
|
||||
sliderHeight: 60,
|
||||
},
|
||||
distance: 0, // 拼图移动距离
|
||||
flag: false, // 判断滑块是否按下
|
||||
downX: 0, // 鼠标按下位置
|
||||
bgColor: '#04ad11', // 滑动背景颜色
|
||||
verifyText: '拖动滑块解锁' // 文字提示
|
||||
distance: 0,
|
||||
flag: false,
|
||||
downX: 0,
|
||||
bgColor: "#04ad11",
|
||||
verifyText: "拖动滑块解锁",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 鼠标按下事件,开始拖动滑块
|
||||
mouseDown (e) {
|
||||
mouseDown(e) {
|
||||
this.downX = e.clientX;
|
||||
this.flag = true;
|
||||
},
|
||||
// 鼠标移动事件,计算距离
|
||||
mouseMove (e) {
|
||||
mouseMove(e) {
|
||||
if (this.flag) {
|
||||
let offset = e.clientX - this.downX;
|
||||
|
||||
const offset = e.clientX - this.downX;
|
||||
if (offset > this.data.originalWidth - 43) {
|
||||
this.distance = this.data.originalWidth - 43;
|
||||
} else if (offset < 0) {
|
||||
@@ -63,65 +85,63 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
// 鼠标抬起事件,验证是否正确
|
||||
mouseUp () {
|
||||
mouseUp() {
|
||||
if (!this.flag) return false;
|
||||
this.flag = false;
|
||||
let params = {
|
||||
const params = {
|
||||
verificationEnums: this.type,
|
||||
xPos: this.distance
|
||||
xPos: this.distance,
|
||||
};
|
||||
postVerifyImg(params).then(res => {
|
||||
if (res.success) {
|
||||
if (res.result) {
|
||||
this.bgColor = 'green';
|
||||
this.verifyText = '解锁成功';
|
||||
this.$emit('change', { status: true, distance: this.distance });
|
||||
postVerifyImg(params)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
if (res.result) {
|
||||
this.bgColor = "green";
|
||||
this.verifyText = "解锁成功";
|
||||
this.$emit("change", { status: true, distance: this.distance });
|
||||
} else {
|
||||
this.bgColor = "red";
|
||||
this.verifyText = "解锁失败";
|
||||
setTimeout(() => this.init(), 1000);
|
||||
this.$emit("change", { status: false, distance: this.distance });
|
||||
}
|
||||
} else {
|
||||
this.bgColor = 'red';
|
||||
this.verifyText = '解锁失败';
|
||||
let that = this;
|
||||
setTimeout(() => {
|
||||
that.init();
|
||||
}, 1000);
|
||||
this.$emit('change', { status: false, distance: this.distance });
|
||||
this.init();
|
||||
}
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
|
||||
}).catch(()=>{
|
||||
this.init()
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
init () { // 初始化数据
|
||||
init() {
|
||||
this.flag = false;
|
||||
this.downX = 0;
|
||||
this.distance = 0;
|
||||
this.bgColor = '#04ad11';
|
||||
this.verifyText = '拖动滑块解锁';
|
||||
getVerifyImg(this.type).then(res => {
|
||||
this.bgColor = "#04ad11";
|
||||
this.verifyText = "拖动滑块解锁";
|
||||
getVerifyImg(this.type).then((res) => {
|
||||
if (res.result) {
|
||||
this.data = res.result;
|
||||
this.show = true;
|
||||
} else {
|
||||
this.$Message.warning('请求失败请重试!')
|
||||
this.$Message.warning("请求失败请重试!");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
verifyType: {
|
||||
immediate: true,
|
||||
handler: function (v) {
|
||||
handler(v) {
|
||||
this.type = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.verify-content{
|
||||
.verify-content {
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
@@ -174,9 +194,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.ivu-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.text {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from "axios";
|
||||
import { getStore, setStore } from "./storage.js";
|
||||
import { router } from "../router/index";
|
||||
import { Message } from "view-design";
|
||||
import { Message } from "@/utils/message";
|
||||
import Cookies from "js-cookie";
|
||||
import { handleRefreshToken } from "../api/index";
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
|
||||
@@ -1,10 +1,130 @@
|
||||
import { getCurrentPermissionList } from "@/api/index";
|
||||
import lazyLoading from "./lazyLoading.js";
|
||||
|
||||
import { router } from "@/router/index";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
let util = {};
|
||||
|
||||
/** 动态菜单路由 name,用于登出或重新注册时清理 */
|
||||
util.dynamicRouteNames = [];
|
||||
|
||||
util.clearDynamicRoutes = function () {
|
||||
util.dynamicRouteNames.forEach((name) => {
|
||||
if (router.hasRoute(name)) {
|
||||
router.removeRoute(name);
|
||||
}
|
||||
});
|
||||
util.dynamicRouteNames = [];
|
||||
};
|
||||
|
||||
util.collectLeafRoutes = function (routes, result = [], parentPath = "") {
|
||||
routes.forEach((route) => {
|
||||
let segment = route.path != null ? String(route.path) : "";
|
||||
segment = segment.replace(/^\//, "");
|
||||
const fullPath = [parentPath, segment].filter(Boolean).join("/");
|
||||
const hasChildren = route.children && route.children.length > 0;
|
||||
|
||||
if (hasChildren) {
|
||||
util.collectLeafRoutes(route.children, result, fullPath);
|
||||
} else if (
|
||||
route.name &&
|
||||
route.component &&
|
||||
!String(route.name).endsWith("__layout")
|
||||
) {
|
||||
result.push({
|
||||
path: fullPath || segment || route.name,
|
||||
name: route.name,
|
||||
component: route.component,
|
||||
meta: route.meta || {},
|
||||
});
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
/** Vue Router 4:动态路由必须挂到 otherRouter 下,且刷新/热更新后需重新注册 */
|
||||
util.registerDynamicRoutes = function (menuData, options = {}) {
|
||||
const { rematch = true } = options;
|
||||
const pendingPath = router.currentRoute.value.fullPath;
|
||||
const pendingUnmatched = router.currentRoute.value.matched.length === 0;
|
||||
|
||||
util.clearDynamicRoutes();
|
||||
const constRoutes = [];
|
||||
util.initAllMenuData(constRoutes, menuData);
|
||||
|
||||
const leaves = [];
|
||||
constRoutes.forEach((top) => {
|
||||
const base = (top.path || "").replace(/^\//, "");
|
||||
if (top.children && top.children.length) {
|
||||
util.collectLeafRoutes(top.children, leaves, base);
|
||||
} else if (
|
||||
top.name &&
|
||||
top.component &&
|
||||
!String(top.name).endsWith("__layout")
|
||||
) {
|
||||
leaves.push({
|
||||
path: base || top.name,
|
||||
name: top.name,
|
||||
component: top.component,
|
||||
meta: top.meta || {},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
leaves.forEach((leaf) => {
|
||||
const path = (leaf.path || leaf.name || "").replace(/^\//, "");
|
||||
if (!router.hasRoute(leaf.name)) {
|
||||
router.addRoute("otherRouter", {
|
||||
path,
|
||||
name: leaf.name,
|
||||
component: leaf.component,
|
||||
meta: leaf.meta,
|
||||
});
|
||||
util.dynamicRouteNames.push(leaf.name);
|
||||
}
|
||||
});
|
||||
|
||||
if (!router.hasRoute("error-404")) {
|
||||
router.addRoute({
|
||||
path: "/:pathMatch(.*)*",
|
||||
name: "error-404",
|
||||
component: lazyLoading("error-page/404"),
|
||||
meta: { title: "404-页面不存在" },
|
||||
});
|
||||
util.dynamicRouteNames.push("error-404");
|
||||
}
|
||||
|
||||
if (
|
||||
rematch &&
|
||||
pendingUnmatched &&
|
||||
pendingPath &&
|
||||
pendingPath !== "/login"
|
||||
) {
|
||||
const resolved = router.resolve(pendingPath);
|
||||
if (resolved.matched.length > 0) {
|
||||
router.replace(pendingPath).catch(() => {});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 从 localStorage 恢复动态路由(刷新深链前必须先注册,避免 /member/xxx 无匹配) */
|
||||
util.bootstrapDynamicRoutesFromCache = function () {
|
||||
if (!Cookies.get("userInfoManager")) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const raw = window.localStorage.getItem("menuData");
|
||||
if (!raw) {
|
||||
return false;
|
||||
}
|
||||
util.registerDynamicRoutes(JSON.parse(raw), { rematch: false });
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn("[router] menuData parse failed", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
util.title = function(title) {
|
||||
title = title || "运营后台";
|
||||
window.document.title = title;
|
||||
@@ -94,7 +214,7 @@ util.initRouter = function(vm) {
|
||||
// 404路由需要和动态路由一起加载
|
||||
const otherRouter = [
|
||||
{
|
||||
path: "/*",
|
||||
path: "/:pathMatch(.*)*",
|
||||
name: "error-404",
|
||||
meta: {
|
||||
title: "404-页面不存在"
|
||||
@@ -132,15 +252,11 @@ util.initRouter = function(vm) {
|
||||
return;
|
||||
}
|
||||
util.initAllMenuData(constRoutes, menuData);
|
||||
util.initRouterNode(otherRoutes, otherRouter);
|
||||
// 添加所有主界面路由
|
||||
util.registerDynamicRoutes(menuData);
|
||||
vm.$store.commit(
|
||||
"updateAppRouter",
|
||||
constRoutes.filter(item => item.children.length > 0)
|
||||
constRoutes.filter((item) => item.children && item.children.length > 0)
|
||||
);
|
||||
// 添加全局路由
|
||||
vm.$store.commit("updateDefaultRouter", otherRoutes);
|
||||
// 添加菜单路由
|
||||
util.initMenuData(vm, menuData);
|
||||
// 缓存数据 修改加载标识
|
||||
window.localStorage.setItem("menuData", JSON.stringify(menuData));
|
||||
@@ -154,7 +270,7 @@ util.initRouter = function(vm) {
|
||||
return;
|
||||
}
|
||||
let menuData = JSON.parse(data);
|
||||
// 添加菜单路由
|
||||
util.registerDynamicRoutes(menuData);
|
||||
util.initMenuData(vm, menuData);
|
||||
}
|
||||
};
|
||||
@@ -235,17 +351,27 @@ util.initRouterNode = function(routers, data) {
|
||||
// data为所有子菜单数据
|
||||
|
||||
for (let item of data) {
|
||||
let menu = Object.assign({}, item);
|
||||
const menu = Object.assign({}, item);
|
||||
const hasChildren = item.children && item.children.length > 0;
|
||||
|
||||
menu.component = lazyLoading(menu.frontRoute);
|
||||
|
||||
if (item.children && item.children.length > 0) {
|
||||
if (hasChildren) {
|
||||
menu.children = [];
|
||||
// Vue Router 4:父子路由 name 必须不同,后端菜单常出现同名父子节点
|
||||
if (menu.name) {
|
||||
menu.name = `${menu.name}__layout`;
|
||||
}
|
||||
util.initRouterNode(menu.children, item.children);
|
||||
// 分组节点通常无页面,仅在有 frontRoute 时挂载组件
|
||||
if (menu.frontRoute) {
|
||||
menu.component = lazyLoading(menu.frontRoute);
|
||||
} else {
|
||||
delete menu.component;
|
||||
}
|
||||
} else if (menu.frontRoute) {
|
||||
menu.component = lazyLoading(menu.frontRoute);
|
||||
}
|
||||
|
||||
let meta = {};
|
||||
// 给页面添加标题、父级菜单name(方便左侧菜单选中)
|
||||
const meta = {};
|
||||
meta.title = menu.title ? menu.title + " - 运营后台" : null;
|
||||
meta.firstRouterName = item.firstRouterName;
|
||||
menu.meta = meta;
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
import Vue from 'vue';
|
||||
import VueI18n from 'vue-i18n';
|
||||
import zhLocale from './lang/zh-CN';
|
||||
import enLocale from './lang/en-US';
|
||||
import zhCnLocale from 'view-design/src/locale/lang/zh-CN';
|
||||
import enUsLocale from 'view-design/src/locale/lang/en-US';
|
||||
import { createI18n } from "vue-i18n";
|
||||
import zhLocale from "./lang/zh-CN";
|
||||
import enLocale from "./lang/en-US";
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
// 根据浏览器信息自动设置语言
|
||||
const navLang = navigator.language;
|
||||
const localLang = (navLang == 'zh-CN' || navLang == 'en-US') ? navLang : false;
|
||||
const lang = window.localStorage.lang || localLang || 'zh-CN';
|
||||
const localLang = navLang === "zh-CN" || navLang === "en-US" ? navLang : false;
|
||||
const lang = window.localStorage.lang || localLang || "zh-CN";
|
||||
|
||||
Vue.config.lang = lang;
|
||||
|
||||
// 多语言配置 vue-i18n 6.x+
|
||||
Vue.locale = () => { };
|
||||
const messages = {
|
||||
'zh-CN': Object.assign(zhCnLocale, zhLocale),
|
||||
'en-US': Object.assign(enUsLocale, enLocale)
|
||||
"zh-CN": zhLocale,
|
||||
"en-US": enLocale,
|
||||
};
|
||||
const i18n = new VueI18n({
|
||||
locale: lang,
|
||||
messages
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: true,
|
||||
globalInjection: true,
|
||||
locale: lang,
|
||||
fallbackLocale: "zh-CN",
|
||||
messages,
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
|
||||
@@ -1,114 +1,88 @@
|
||||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue'
|
||||
import ViewUI from 'view-design'
|
||||
// import 'view-design/dist/styles/iview.css'
|
||||
import './styles/theme.less';
|
||||
import { createApp } from "vue";
|
||||
import "core-js/stable";
|
||||
import "./styles/theme.less";
|
||||
import App from "./App.vue";
|
||||
import { router } from "./router/index";
|
||||
import store from "./store";
|
||||
import i18n from "@/locale";
|
||||
import { setupElementPlus } from "@/plugins/element";
|
||||
import { setupLegacyMessage } from "@/utils/message";
|
||||
import liliDialog from "@/components/lili-dialog";
|
||||
import PriceColorScheme from "@/components/price-color-scheme.vue";
|
||||
import { install as installVueQr } from "vue-qr";
|
||||
import {
|
||||
getRequest,
|
||||
postRequest,
|
||||
putRequest,
|
||||
deleteRequest,
|
||||
importRequest,
|
||||
uploadFileRequest,
|
||||
} from "@/libs/axios";
|
||||
import { setStore, getStore, removeStore } from "@/libs/storage";
|
||||
import util from "@/libs/util";
|
||||
import { md5 } from "@/utils/md5.js";
|
||||
import * as filters from "@/utils/filters";
|
||||
|
||||
import "core-js/stable"
|
||||
// import "regenerator-runtime/runtime"
|
||||
import App from './App'
|
||||
import {router} from './router/index'
|
||||
import store from './store'
|
||||
import i18n from '@/locale'
|
||||
const { aMapSecurityJsCode, mainColor } = require("@/config");
|
||||
|
||||
import {getRequest, postRequest, putRequest, deleteRequest, importRequest, uploadFileRequest} from '@/libs/axios'
|
||||
import {setStore, getStore, removeStore} from '@/libs/storage'
|
||||
import util from '@/libs/util'
|
||||
|
||||
import * as filters from '@/utils/filters' // global filter
|
||||
import liliDialog from '@/components/lili-dialog'
|
||||
|
||||
import {md5} from '@/utils/md5.js';
|
||||
|
||||
// 打印
|
||||
import Print from 'vue-print-nb';
|
||||
|
||||
Vue.use(Print);
|
||||
const {aMapSecurityJsCode, inputMaxLength,mainColor } = require("@/config");
|
||||
// 高德安全密钥
|
||||
if (aMapSecurityJsCode) {
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: aMapSecurityJsCode,
|
||||
};
|
||||
}
|
||||
|
||||
const PC_URL = BASE.PC_URL;
|
||||
const WAP_URL = BASE.WAP_URL;
|
||||
|
||||
Vue.config.devtools = true;
|
||||
Vue.config.productionTip = false
|
||||
const PC_URL = BASE.PC_URL; // 跳转买家端地址 pc端
|
||||
const WAP_URL = BASE.WAP_URL; // 跳转买家端地址 wap端
|
||||
Vue.prototype.linkTo = function (goodsId, skuId) {
|
||||
// 跳转买家端商品
|
||||
// 刷新深链(如 /member/user-manage)前先从缓存注册动态路由
|
||||
util.bootstrapDynamicRoutesFromCache();
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
setupElementPlus(app);
|
||||
setupLegacyMessage(app);
|
||||
installVueQr(app);
|
||||
|
||||
app.use(router);
|
||||
app.use(store);
|
||||
app.use(i18n);
|
||||
|
||||
app.component("liliDialog", liliDialog);
|
||||
app.component("priceColorScheme", PriceColorScheme);
|
||||
|
||||
app.config.globalProperties.getRequest = getRequest;
|
||||
app.config.globalProperties.postRequest = postRequest;
|
||||
app.config.globalProperties.putRequest = putRequest;
|
||||
app.config.globalProperties.deleteRequest = deleteRequest;
|
||||
app.config.globalProperties.importRequest = importRequest;
|
||||
app.config.globalProperties.uploadFileRequest = uploadFileRequest;
|
||||
app.config.globalProperties.setStore = setStore;
|
||||
app.config.globalProperties.getStore = getStore;
|
||||
app.config.globalProperties.removeStore = removeStore;
|
||||
app.config.globalProperties.$mainColor = mainColor;
|
||||
app.config.globalProperties.md5 = md5;
|
||||
app.config.globalProperties.$filters = filters;
|
||||
|
||||
app.config.globalProperties.linkTo = function (goodsId, skuId) {
|
||||
let src;
|
||||
if (skuId) {
|
||||
src = `${PC_URL}/goodsDetail?skuId=${skuId}&goodsId=${goodsId}`;
|
||||
} else {
|
||||
src = `${PC_URL}/goodsDetail?goodsId=${goodsId}`;
|
||||
}
|
||||
|
||||
window.open(src, "_blank");
|
||||
};
|
||||
Vue.prototype.wapLinkTo = function (goodsId, skuId) {
|
||||
// app端二维码
|
||||
|
||||
app.config.globalProperties.wapLinkTo = function (goodsId, skuId) {
|
||||
if (skuId) {
|
||||
return `${WAP_URL}/pages/product/goods?id=${skuId}&goodsId=${goodsId}`;
|
||||
} else {
|
||||
return `${WAP_URL}/pages/product/goods?goodsId=${goodsId}`;
|
||||
}
|
||||
return `${WAP_URL}/pages/product/goods?goodsId=${goodsId}`;
|
||||
};
|
||||
// 引入价格格式化组件
|
||||
import priceColorScheme from 'price-color'
|
||||
Vue.use(priceColorScheme);
|
||||
|
||||
const copyViewUi = {...ViewUI}
|
||||
copyViewUi.Input.props.maxlength.default = inputMaxLength // 挂载最大输入值
|
||||
Vue.use(copyViewUi, {
|
||||
i18n: (key, value) => i18n.t(key, value),
|
||||
router.isReady().then(() => {
|
||||
app.mount("#app");
|
||||
});
|
||||
|
||||
Vue.component('liliDialog', liliDialog)
|
||||
|
||||
|
||||
|
||||
// 挂载全局使用的方法
|
||||
Vue.prototype.getRequest = getRequest;
|
||||
Vue.prototype.postRequest = postRequest;
|
||||
Vue.prototype.putRequest = putRequest;
|
||||
Vue.prototype.deleteRequest = deleteRequest;
|
||||
Vue.prototype.importRequest = importRequest;
|
||||
Vue.prototype.uploadFileRequest = uploadFileRequest;
|
||||
Vue.prototype.setStore = setStore;
|
||||
Vue.prototype.getStore = getStore;
|
||||
Vue.prototype.removeStore = removeStore;
|
||||
Vue.prototype.$mainColor = mainColor;
|
||||
Vue.prototype.md5 = md5;
|
||||
|
||||
Array.prototype.remove = function (from, to) {
|
||||
var rest = this.slice((to || from) + 1 || this.length);
|
||||
this.length = from < 0 ? this.length + from : from;
|
||||
return this.push.apply(this, rest);
|
||||
};
|
||||
|
||||
Object.keys(filters).forEach(key => {
|
||||
Vue.filter(key, filters[key])
|
||||
})
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
render: h => h(App),
|
||||
data: {
|
||||
currentPageName: ''
|
||||
},
|
||||
mounted() {
|
||||
// 初始化菜单
|
||||
util.initRouter(this);
|
||||
this.currentPageName = this.$route.name;
|
||||
// 显示打开的页面的列表
|
||||
this.$store.commit('setOpenedList');
|
||||
this.$store.commit('initCachePage');
|
||||
}
|
||||
})
|
||||
// 登录后由 App.vue 触发 initRouter 拉取/更新菜单
|
||||
export { app, util };
|
||||
|
||||
11
manager/src/plugins/element.js
Normal file
11
manager/src/plugins/element.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import ElementPlus from "element-plus";
|
||||
import zhCn from "element-plus/es/locale/lang/zh-cn";
|
||||
import "element-plus/dist/index.css";
|
||||
import "@/styles/element.scss";
|
||||
|
||||
export function setupElementPlus(app) {
|
||||
app.use(ElementPlus, {
|
||||
locale: zhCn,
|
||||
size: "default",
|
||||
});
|
||||
}
|
||||
@@ -1,56 +1,46 @@
|
||||
import Vue from 'vue';
|
||||
import ViewUI from 'view-design';
|
||||
import Util from '../libs/util';
|
||||
import VueRouter from 'vue-router';
|
||||
import Cookies from 'js-cookie';
|
||||
import {routers} from './router';
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import NProgress from "nprogress";
|
||||
import "nprogress/nprogress.css";
|
||||
import Util from "../libs/util";
|
||||
import Cookies from "js-cookie";
|
||||
import store from "@/store";
|
||||
import { routers } from "./router";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
NProgress.configure({ showSpinner: false });
|
||||
|
||||
// 路由配置
|
||||
const RouterConfig = {
|
||||
mode: 'history',
|
||||
routes: routers
|
||||
};
|
||||
|
||||
/**
|
||||
* 解决重复点击菜单会控制台报错bug
|
||||
*/
|
||||
const routerPush = VueRouter.prototype.push
|
||||
VueRouter.prototype.push = function push(location) {
|
||||
return routerPush.call(this, location).catch(error=> error)
|
||||
}
|
||||
|
||||
export const router = new VueRouter(RouterConfig);
|
||||
export const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: routers,
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
ViewUI.LoadingBar.start();
|
||||
NProgress.start();
|
||||
Util.title(to.meta.title);
|
||||
|
||||
next();
|
||||
|
||||
const name = to.name;
|
||||
const hasToken = Cookies.get("userInfoManager");
|
||||
|
||||
if (!Cookies.get('userInfoManager') && name !== 'login') {
|
||||
// 判断是否已经登录且前往的页面不是登录页
|
||||
next({
|
||||
name: 'login'
|
||||
});
|
||||
} else if (Cookies.get('userInfoManager') && name === 'login') {
|
||||
// 判断是否已经登录且前往的是登录页
|
||||
Util.title();
|
||||
next({
|
||||
name: 'home_index'
|
||||
});
|
||||
} else {
|
||||
Util.toDefaultPage([...routers], name, router, next);
|
||||
if (!hasToken && name !== "login") {
|
||||
next({ name: "login" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasToken && name === "login") {
|
||||
Util.title();
|
||||
next({ name: "home_index" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasToken) {
|
||||
Util.toDefaultPage([...routers], name, router, next);
|
||||
return;
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
router.afterEach((to) => {
|
||||
Util.openNewPage(router.app, to.name, to.params, to.query);
|
||||
ViewUI.LoadingBar.finish();
|
||||
Util.openNewPage({ $store: store }, to.name, to.params, to.query);
|
||||
NProgress.done();
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
|
||||
import { createStore } from "vuex";
|
||||
import app from "./modules/app";
|
||||
import setting from './modules/setting';
|
||||
import setting from "./modules/setting";
|
||||
import user from "./modules/user";
|
||||
import dict from "./modules/dict";
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
const store = createStore({
|
||||
state: {
|
||||
// 状态
|
||||
openStyleStore: "", // 移动端楼层装修中选择风格存储
|
||||
openStoreId:"",
|
||||
notices: "" //通知提示信息
|
||||
},
|
||||
mutations: {
|
||||
// 改变方法
|
||||
openStyleStore: "",
|
||||
openStoreId: "",
|
||||
notices: "",
|
||||
},
|
||||
mutations: {},
|
||||
actions: {},
|
||||
modules: {
|
||||
app,
|
||||
user,
|
||||
setting,
|
||||
dict
|
||||
}
|
||||
dict,
|
||||
},
|
||||
});
|
||||
|
||||
export default store;
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
router
|
||||
} from '@/router/index';
|
||||
import Util from '@/libs/util';
|
||||
import Vue from 'vue';
|
||||
import i18n from '@/locale';
|
||||
|
||||
const app = {
|
||||
state: {
|
||||
@@ -34,11 +34,10 @@ const app = {
|
||||
// 动态添加主界面路由,需要缓存
|
||||
updateAppRouter(state, routes) {
|
||||
state.routers.push(...routes);
|
||||
router.addRoutes(routes);
|
||||
// 实际 addRoute 在 util.registerDynamicRoutes 中完成
|
||||
},
|
||||
// 动态添加全局路由404、500等页面,不需要缓存
|
||||
updateDefaultRouter(state, routes) {
|
||||
router.addRoutes(routes);
|
||||
// 兼容旧调用,404 由 registerDynamicRoutes 注册
|
||||
},
|
||||
setAdded(state, v) {
|
||||
state.added = v;
|
||||
@@ -122,7 +121,7 @@ const app = {
|
||||
switchLang(state, lang) {
|
||||
state.lang = lang;
|
||||
localStorage.lang = lang;
|
||||
Vue.config.lang = lang;
|
||||
i18n.global.locale = lang;
|
||||
},
|
||||
setMessageCount(state, count) {
|
||||
state.messageCount = count;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import Cookies from 'js-cookie';
|
||||
import util from '@/libs/util';
|
||||
|
||||
const user = {
|
||||
state: {},
|
||||
mutations: {
|
||||
logout () {
|
||||
util.clearDynamicRoutes();
|
||||
Cookies.remove('userInfoManager');
|
||||
// 清空打开的页面等数据
|
||||
localStorage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,5 +124,50 @@ $bg_color: #f1f6fa;
|
||||
}
|
||||
|
||||
|
||||
// table-common(原 @import 合并,避免 Sass @import 弃用警告)
|
||||
.search {
|
||||
.operation {
|
||||
margin-bottom: 2vh;
|
||||
}
|
||||
.select-clear {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.search-input {
|
||||
width: 270px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.search-form {
|
||||
width: 100% !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0.4em;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@import "./table-common.scss";
|
||||
> .ivu-form-item,
|
||||
> .el-form-item {
|
||||
margin: 8px 10px !important;
|
||||
}
|
||||
}
|
||||
.padding-row {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.search-btn {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.div-zoom {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
overflow: hidden;
|
||||
}
|
||||
// 列表页「筛选 Card + 列表 Card」间距(Vue3 使用 el-card)
|
||||
.search > .el-card + .el-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
// 兼容遗留 iView 结构
|
||||
.ivu-card + .ivu-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
97
manager/src/styles/element.scss
Normal file
97
manager/src/styles/element.scss
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Element Plus 主题覆盖(对齐原 iView 主色) */
|
||||
:root {
|
||||
--el-color-primary: #ff5c58;
|
||||
--el-color-success: #68cabe;
|
||||
--el-color-warning: #fa6419;
|
||||
--el-color-danger: #ff3c2a;
|
||||
--el-font-size-extra-small: 12px;
|
||||
--el-font-size-small: 13px;
|
||||
--el-font-size-base: 14px;
|
||||
--el-font-size-large: 16px;
|
||||
}
|
||||
|
||||
.el-button--primary {
|
||||
--el-button-bg-color: #ff5c58;
|
||||
--el-button-border-color: #ff5c58;
|
||||
--el-button-hover-bg-color: #ff7875;
|
||||
--el-button-hover-border-color: #ff7875;
|
||||
}
|
||||
|
||||
/* 全局表格:去掉列竖线,保留行横线 */
|
||||
.el-table--border {
|
||||
.el-table__cell {
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
.el-table__border-left-patch {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after,
|
||||
.el-table__inner-wrapper::before,
|
||||
.el-table__inner-wrapper::after {
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
&.el-table--group::before,
|
||||
&.el-table--group::after,
|
||||
&.el-table--group .el-table__inner-wrapper::before,
|
||||
&.el-table--group .el-table__inner-wrapper::after {
|
||||
width: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__fixed-right::before,
|
||||
.el-table__fixed::before {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* 列表操作列统一样式 */
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #c0c4cc;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdfe6;
|
||||
}
|
||||
|
||||
.el-table .ops {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
a:not(.link-text) {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
}
|
||||
|
||||
> span:not(.op-split) {
|
||||
margin: 0 8px;
|
||||
color: #dcdfe6;
|
||||
}
|
||||
}
|
||||
|
||||
.gcc-disabled-action {
|
||||
color: #c0c4cc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@@ -23,7 +23,8 @@
|
||||
border-radius: 0.4em;
|
||||
|
||||
flex-wrap: wrap;
|
||||
> .ivu-form-item {
|
||||
> .ivu-form-item,
|
||||
> .el-form-item {
|
||||
margin: 8px 10px !important;
|
||||
}
|
||||
}
|
||||
@@ -42,7 +43,12 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 为Card组件之间增加间距
|
||||
// 列表页相邻 Card 间距(Element Plus)
|
||||
.search > .el-card + .el-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
// 兼容遗留 iView
|
||||
.ivu-card + .ivu-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
@import "~view-design/src/styles/index.less";
|
||||
// iview 自定义样式
|
||||
|
||||
@primary-color: #ff5c58;
|
||||
@info-color: #fa6419;
|
||||
// Element Plus 主题变量(原 view-design less 已移除)
|
||||
@primary-color: #ff5c58;
|
||||
@info-color: #fa6419;
|
||||
@success-color: #68cabe;
|
||||
@error-color: #ff3c2a;
|
||||
@table-thead-bg: #f8f8f9;
|
||||
@table-td-stripe-bg: #f8f8f9;
|
||||
@table-td-hover-bg: #ededed;
|
||||
@table-td-highlight-bg: #ededed;
|
||||
@font-size-base: 12px;
|
||||
@font-size-base: 14px;
|
||||
|
||||
.ivu-drawer,
|
||||
.drawer,
|
||||
.ivu-drawer-wrap {
|
||||
.el-drawer,
|
||||
.drawer {
|
||||
z-index: 2600 !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
background: #e4e4e4;
|
||||
}
|
||||
|
||||
.block-tool .ivu-tooltip,
|
||||
.block-tool .ivu-tooltip-rel {
|
||||
.block-tool .el-tooltip,
|
||||
.block-tool .el-tooltip__trigger {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
74
manager/src/utils/message.js
Normal file
74
manager/src/utils/message.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
/**
|
||||
* 兼容原 view-design Message API,便于业务页渐进迁移
|
||||
*/
|
||||
export const Message = {
|
||||
success(content) {
|
||||
return ElMessage.success(normalize(content));
|
||||
},
|
||||
error(content) {
|
||||
return ElMessage.error(normalize(content));
|
||||
},
|
||||
warning(content) {
|
||||
return ElMessage.warning(normalize(content));
|
||||
},
|
||||
info(content) {
|
||||
return ElMessage.info(normalize(content));
|
||||
},
|
||||
};
|
||||
|
||||
export const Notice = {
|
||||
open(options = {}) {
|
||||
const fn = Message[options.type] || Message.info;
|
||||
return fn(options.desc || options.title || "");
|
||||
},
|
||||
info(options) {
|
||||
return Message.info(options?.desc || options?.title || "");
|
||||
},
|
||||
success(options) {
|
||||
return Message.success(options?.desc || options?.title || "");
|
||||
},
|
||||
warning(options) {
|
||||
return Message.warning(options?.desc || options?.title || "");
|
||||
},
|
||||
error(options) {
|
||||
return Message.error(options?.desc || options?.title || "");
|
||||
},
|
||||
};
|
||||
|
||||
export const Modal = {
|
||||
confirm(options = {}) {
|
||||
const content = options.content || options.title || "确认操作?";
|
||||
return ElMessageBox.confirm(content, options.title || "提示", {
|
||||
confirmButtonText: options.okText || "确定",
|
||||
cancelButtonText: options.cancelText || "取消",
|
||||
type: options.type || "warning",
|
||||
})
|
||||
.then(() => {
|
||||
if (typeof options.onOk === "function") {
|
||||
return options.onOk();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (typeof options.onCancel === "function") {
|
||||
options.onCancel();
|
||||
}
|
||||
});
|
||||
},
|
||||
remove() {
|
||||
ElMessageBox.close();
|
||||
},
|
||||
};
|
||||
|
||||
function normalize(content) {
|
||||
if (typeof content === "string") return content;
|
||||
if (content && content.content) return content.content;
|
||||
return String(content ?? "");
|
||||
}
|
||||
|
||||
export function setupLegacyMessage(app) {
|
||||
app.config.globalProperties.$Message = Message;
|
||||
app.config.globalProperties.$Modal = Modal;
|
||||
app.config.globalProperties.$Notice = Notice;
|
||||
}
|
||||
@@ -3,155 +3,126 @@
|
||||
</style>
|
||||
<template>
|
||||
<div class="main">
|
||||
<!-- 左侧菜单 -->
|
||||
<div class="sidebar-menu-con menu-bar">
|
||||
<div class="logo-con">
|
||||
<!-- <img src="../assets/logo.png" key="max-logo" /> -->
|
||||
<img :src="domainLogo" key="max-logo" />
|
||||
</div>
|
||||
<shrinkable-menu></shrinkable-menu>
|
||||
<shrinkable-menu />
|
||||
</div>
|
||||
<!-- 顶部标题栏主体 -->
|
||||
<div class="main-header-con" :style="{ height: setting.isUseTabsRouter ? '100px' : '60px' }">
|
||||
<div class="main-header-con" :style="{ height: '60px' }">
|
||||
<div class="main-header">
|
||||
<div class="header-logo-con">
|
||||
<img :src="domainLogo" key="max-logo" />
|
||||
</div>
|
||||
<div class="header-avator-con">
|
||||
<!-- 左侧栏 -->
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div class="flex flex-a-c user-module">
|
||||
<!-- 通知消息 -->
|
||||
<message-tip v-if="tipsMessage" :res="tipsMessage"></message-tip>
|
||||
<!-- 用户头像 -->
|
||||
<div class="user-dropdown-menu-con">
|
||||
<Row
|
||||
<div class="flex flex-a-c user-module" style="height: 100%">
|
||||
<message-tip v-if="tipsMessage" :res="tipsMessage" />
|
||||
<div class="user-dropdown-menu-con" style="margin-left: 24px; display: flex; align-items: center; height: 100%">
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="end"
|
||||
align="middle"
|
||||
class="user-dropdown-innercon"
|
||||
>
|
||||
<ul class="nav-list">
|
||||
<li class="nav-item " @click="handleClickSetting">
|
||||
<Tooltip content="设置">
|
||||
<Icon size="16" type="md-settings" />
|
||||
</Tooltip>
|
||||
</li>
|
||||
</ul>
|
||||
<Dropdown
|
||||
transfer
|
||||
trigger="hover"
|
||||
@on-click="handleClickUserDropdown"
|
||||
>
|
||||
<el-dropdown trigger="hover" @command="handleClickUserDropdown">
|
||||
<div class="dropList">
|
||||
<span class="main-user-name">{{ userInfo.nickName }}</span>
|
||||
<Avatar
|
||||
icon="ios-person"
|
||||
<el-avatar
|
||||
:size="32"
|
||||
:src="avatarPath"
|
||||
style="background: #fff; margin-left: 10px"
|
||||
></Avatar>
|
||||
>
|
||||
<el-icon><UserFilled /></el-icon>
|
||||
</el-avatar>
|
||||
</div>
|
||||
<DropdownMenu slot="list">
|
||||
<DropdownItem name="personalCenter">{{
|
||||
$t("userCenter")
|
||||
}}</DropdownItem>
|
||||
<DropdownItem name="changePass">{{
|
||||
$t("changePass")
|
||||
}}</DropdownItem>
|
||||
<DropdownItem name="loginOut" divided>{{
|
||||
$t("logout")
|
||||
}}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</Row>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="personalCenter">
|
||||
{{ $t("userCenter") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="changePass">
|
||||
{{ $t("changePass") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided command="loginOut">
|
||||
{{ $t("logout") }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 已打开的页面标签 -->
|
||||
<div class="tags-con" v-if="setting.isUseTabsRouter">
|
||||
<tags-page-opened :pageTagsList="pageTagsList"></tags-page-opened>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-page-con" :style="{ 'top': setting.isUseTabsRouter ? '100px' : '60px', height: setting.isUseTabsRouter ? 'calc(100% - 110px)' : 'calc(100% - 70px)' }">
|
||||
<div class="breadcrumb-bar" v-if="setting.isUseTabsRouter">
|
||||
<page-breadcrumb />
|
||||
</div>
|
||||
<div
|
||||
class="single-page-con"
|
||||
:style="{
|
||||
top: setting.isUseTabsRouter ? '104px' : '60px',
|
||||
height: setting.isUseTabsRouter ? 'calc(100% - 114px)' : 'calc(100% - 70px)',
|
||||
}"
|
||||
>
|
||||
<div class="single-page">
|
||||
<!-- <keep-alive :include="cachePage"> -->
|
||||
<router-view></router-view>
|
||||
<!-- </keep-alive> -->
|
||||
<router-view v-slot="{ Component }">
|
||||
<component :is="Component" v-if="Component" :key="$route.fullPath" />
|
||||
</router-view>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 全局加载动画 -->
|
||||
<circleLoading class="loading-position" v-show="loading" />
|
||||
<!-- 右侧抽屉配置 -->
|
||||
<configDrawer ref="config"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { UserFilled } from "@element-plus/icons-vue";
|
||||
import shrinkableMenu from "./main-parts/shrinkable-menu/shrinkable-menu.vue";
|
||||
import tagsPageOpened from "./main-parts/tags-page-opened.vue";
|
||||
import pageBreadcrumb from "./main-parts/page-breadcrumb.vue";
|
||||
import messageTip from "./main-parts/message-tip.vue";
|
||||
import circleLoading from "@/components/lili/circle-loading.vue";
|
||||
import configDrawer from "@/components/lili/config-drawer.vue";
|
||||
import Cookies from "js-cookie";
|
||||
import util from "@/libs/util.js";
|
||||
import { getNoticePage, logout } from "@/api/index";
|
||||
import { getBaseSite } from "@/api/common";
|
||||
|
||||
var client;
|
||||
const config = require("@/config/index.js");
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserFilled,
|
||||
shrinkableMenu,
|
||||
tagsPageOpened,
|
||||
pageBreadcrumb,
|
||||
messageTip,
|
||||
circleLoading,
|
||||
configDrawer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
sliceNum: 5, // 展示nav数量
|
||||
userInfo: "", // 用户信息
|
||||
tipsMessage: "", // 通知消息
|
||||
sliceNum: 5,
|
||||
userInfo: "",
|
||||
tipsMessage: "",
|
||||
defaultLogo: require("@/assets/logo.png"),
|
||||
domainLogo: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
setting(){
|
||||
let data = this.$store.state.setting
|
||||
|
||||
return data.setting
|
||||
setting() {
|
||||
return this.$store.state.setting.setting;
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.app.loading;
|
||||
},
|
||||
pageTagsList() {
|
||||
return this.$store.state.app.pageOpenedList; // 打开的页面的页面对象
|
||||
return this.$store.state.app.pageOpenedList;
|
||||
},
|
||||
avatarPath() {
|
||||
return localStorage.avatorImgPath;
|
||||
},
|
||||
lang() {
|
||||
return this.$store.state.app.lang;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleClickSetting() {
|
||||
this.$refs.config.open();
|
||||
},
|
||||
init() {
|
||||
// 菜单初始化
|
||||
let userInfo = JSON.parse(Cookies.get("userInfoManager"));
|
||||
|
||||
const userInfo = JSON.parse(Cookies.get("userInfoManager"));
|
||||
this.userInfo = userInfo;
|
||||
this.checkTag(this.$route.name);
|
||||
let currWidth = document.body.clientWidth;
|
||||
if (currWidth <= 1200) {
|
||||
this.sliceNum = 2;
|
||||
}
|
||||
this.domainLogo = localStorage.getItem("icon");
|
||||
let link =
|
||||
this.domainLogo = localStorage.getItem("icon") || this.defaultLogo;
|
||||
const link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
@@ -159,35 +130,22 @@ export default {
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
window.document.title = localStorage.getItem("title") + " - 运营后台";
|
||||
// 读取未读消息数
|
||||
getNoticePage({}).then((res) => {
|
||||
if (res.success) {
|
||||
this.tipsMessage = res.result;
|
||||
|
||||
this.$store.state.notices = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//用户头像下方抽屉点击
|
||||
handleClickUserDropdown(name) {
|
||||
//个人中心
|
||||
if (name === "personalCenter") {
|
||||
util.openNewPage(this, "personal-center");
|
||||
this.$router.push({
|
||||
name: "personal-center",
|
||||
});
|
||||
}
|
||||
//修改密码
|
||||
else if (name === "changePass") {
|
||||
this.$router.push({ name: "personal-center" });
|
||||
} else if (name === "changePass") {
|
||||
util.openNewPage(this, "change-password");
|
||||
this.$router.push({
|
||||
name: "change_password",
|
||||
});
|
||||
}
|
||||
// 退出登录
|
||||
else if (name === "loginOut") {
|
||||
logout().then((res) => {
|
||||
this.$router.push({ name: "change_password" });
|
||||
} else if (name === "loginOut") {
|
||||
logout().then(() => {
|
||||
this.$store.commit("logout", this);
|
||||
this.$store.commit("setAdded", false);
|
||||
this.setStore("accessToken", "");
|
||||
@@ -196,15 +154,9 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
//切换标签
|
||||
checkTag(name) {
|
||||
let openpageHasTag = this.pageTagsList.some((item) => {
|
||||
if (item.name == name) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const openpageHasTag = this.pageTagsList.some((item) => item.name == name);
|
||||
if (!openpageHasTag) {
|
||||
// 解决关闭当前标签后再点击回退按钮会退到当前页时没有标签的问题
|
||||
util.openNewPage(
|
||||
this,
|
||||
name,
|
||||
@@ -213,33 +165,33 @@ export default {
|
||||
);
|
||||
}
|
||||
},
|
||||
//宽度动态计算
|
||||
resize() {
|
||||
let currWidth = document.body.clientWidth;
|
||||
let count = currWidth / 300;
|
||||
if (count > 6) {
|
||||
this.sliceNum = 6;
|
||||
} else {
|
||||
this.sliceNum = count;
|
||||
const currWidth = document.body.clientWidth;
|
||||
const count = currWidth / 300;
|
||||
this.sliceNum = count > 6 ? 6 : count;
|
||||
},
|
||||
onLogoError(e) {
|
||||
if (e?.target && e.target.src !== this.defaultLogo) {
|
||||
e.target.src = this.defaultLogo;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route(to, from) {
|
||||
$route(to) {
|
||||
this.checkTag(to.name);
|
||||
localStorage.currentPageName = to.name;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
let that = this;
|
||||
this.resize();
|
||||
window.addEventListener("resize", function () {
|
||||
that.resize();
|
||||
});
|
||||
window.addEventListener("resize", this.resize);
|
||||
this.$store.commit("setOpenedList");
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("resize", this.resize);
|
||||
},
|
||||
created() {
|
||||
// 显示打开的页面的列表
|
||||
this.$store.commit("setOpenedList");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,37 +1,53 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card class="change-pass">
|
||||
<p slot="title">修改密码</p>
|
||||
<div class="mt_10">
|
||||
<Form ref="editPasswordForm" :model="editPasswordForm" :label-width="100" label-position="right" :rules="passwordValidate" style="width:450px">
|
||||
<FormItem label="原密码" prop="oldPass">
|
||||
<Input type="password" v-model="editPasswordForm.oldPassword" placeholder="请输入现在使用的密码"></Input>
|
||||
</FormItem>
|
||||
<FormItem label="新密码" prop="newPass">
|
||||
<SetPassword v-model="editPasswordForm.newPassword" @on-change="changeInputPass" />
|
||||
</FormItem>
|
||||
<FormItem label="确认新密码" prop="rePass">
|
||||
<Input type="password" v-model="editPasswordForm.rePassword" placeholder="请再次输入新密码"></Input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="primary" class="mr_10" :loading="savePassLoading" @click="saveEditPass">保存
|
||||
</Button>
|
||||
<Button @click="cancelEditPass">取消</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</div>
|
||||
</Card>
|
||||
<el-card class="change-pass">
|
||||
<template #header>修改密码</template>
|
||||
<el-form
|
||||
ref="editPasswordForm"
|
||||
:model="editPasswordForm"
|
||||
label-width="100px"
|
||||
label-position="right"
|
||||
:rules="passwordValidate"
|
||||
style="width: 450px"
|
||||
class="mt_10"
|
||||
>
|
||||
<el-form-item label="原密码" prop="oldPassword">
|
||||
<el-input
|
||||
v-model="editPasswordForm.oldPassword"
|
||||
type="password"
|
||||
show-password
|
||||
placeholder="请输入现在使用的密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<SetPassword v-model="editPasswordForm.newPassword" @on-change="changeInputPass" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="rePassword">
|
||||
<el-input
|
||||
v-model="editPasswordForm.rePassword"
|
||||
type="password"
|
||||
show-password
|
||||
placeholder="请再次输入新密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="savePassLoading" @click="saveEditPass">保存</el-button>
|
||||
<el-button @click="cancelEditPass">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SetPassword from "@/components/lili/set-password";
|
||||
import { changePass } from "@/api/index";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
|
||||
export default {
|
||||
name: "change-password",
|
||||
components: {
|
||||
SetPassword
|
||||
SetPassword,
|
||||
},
|
||||
data() {
|
||||
const valideRePassword = (rule, value, callback) => {
|
||||
@@ -42,102 +58,61 @@ export default {
|
||||
}
|
||||
};
|
||||
return {
|
||||
savePassLoading: false, // 保存加载状态
|
||||
editPasswordForm: { // 编辑密码表单
|
||||
savePassLoading: false,
|
||||
editPasswordForm: {
|
||||
oldPassword: "",
|
||||
newPassword: "",
|
||||
rePassword: "",
|
||||
},
|
||||
strength: "", // 密码强度
|
||||
passwordValidate: { // 验证规则
|
||||
oldPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入原密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
strength: "",
|
||||
passwordValidate: {
|
||||
oldPassword: [{ required: true, message: "请输入原密码", trigger: "blur" }],
|
||||
newPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入新密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
message: "请至少输入6个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
max: 32,
|
||||
message: "最多输入32个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
{ required: true, message: "请输入新密码", trigger: "blur" },
|
||||
{ min: 6, message: "请至少输入6个字符", trigger: "blur" },
|
||||
{ max: 32, message: "最多输入32个字符", trigger: "blur" },
|
||||
],
|
||||
rePassword: [
|
||||
{
|
||||
required: true,
|
||||
message: "请再次输入新密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
validator: valideRePassword,
|
||||
trigger: "blur",
|
||||
},
|
||||
{ required: true, message: "请再次输入新密码", trigger: "blur" },
|
||||
{ validator: valideRePassword, trigger: "blur" },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 密码强度
|
||||
changeInputPass(v, grade, strength) {
|
||||
this.strength = strength;
|
||||
},
|
||||
// 确认修改密码
|
||||
saveEditPass() {
|
||||
let params = {
|
||||
const params = {
|
||||
password: this.md5(this.editPasswordForm.oldPassword),
|
||||
newPassword: this.md5(this.editPasswordForm.newPassword),
|
||||
passStrength: this.md5(this.strength),
|
||||
};
|
||||
this.$refs["editPasswordForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
this.savePassLoading = true;
|
||||
changePass(params).then((res) => {
|
||||
this.savePassLoading = false;
|
||||
if (res.success) {
|
||||
this.$Modal.success({
|
||||
title: "修改密码成功",
|
||||
content: "修改密码成功,需重新登录",
|
||||
onOk: () => {
|
||||
this.$store.commit("logout", this);
|
||||
this.$router.push({
|
||||
name: "login",
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.$refs.editPasswordForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.savePassLoading = true;
|
||||
changePass(params).then((res) => {
|
||||
this.savePassLoading = false;
|
||||
if (res.success) {
|
||||
ElMessageBox.alert("修改密码成功,需重新登录", "修改密码成功", {
|
||||
confirmButtonText: "确定",
|
||||
callback: () => {
|
||||
this.$store.commit("logout", this);
|
||||
this.$router.push({ name: "login" });
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
// 取消修改密码
|
||||
cancelEditPass() {
|
||||
this.$store.commit("removeTag", "change_password");
|
||||
localStorage.pageOpenedList = JSON.stringify(
|
||||
this.$store.state.app.pageOpenedList
|
||||
);
|
||||
let lastPageName = "";
|
||||
let length = this.$store.state.app.pageOpenedList.length;
|
||||
if (length > 1) {
|
||||
lastPageName = this.$store.state.app.pageOpenedList[length - 1].name;
|
||||
} else {
|
||||
lastPageName = this.$store.state.app.pageOpenedList[0].name;
|
||||
}
|
||||
this.$router.push({
|
||||
name: lastPageName,
|
||||
});
|
||||
localStorage.pageOpenedList = JSON.stringify(this.$store.state.app.pageOpenedList);
|
||||
const list = this.$store.state.app.pageOpenedList;
|
||||
const lastPageName = list.length > 1 ? list[list.length - 1].name : list[0].name;
|
||||
this.$router.push({ name: lastPageName });
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,51 +1,66 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation">
|
||||
<Button @click="add" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
sortable="custom"
|
||||
@on-selection-change="changeSelect"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="form" :label-width="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
|
||||
>
|
||||
<el-card>
|
||||
<div class="operation">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
style="width: 100%"
|
||||
row-key="id"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<el-table-column type="selection" width="60" align="center" />
|
||||
<el-table-column prop="name" label="自定义分词" min-width="120" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="200" />
|
||||
<el-table-column prop="updateTime" label="更新时间" width="200" />
|
||||
<el-table-column prop="createBy" label="操作人" min-width="150" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="detail(row)">修改</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="自定义分词" prop="name">
|
||||
<el-input v-model="form.name" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -54,118 +69,36 @@ import {
|
||||
getCustomWordsPage,
|
||||
delCustom,
|
||||
insertCustomWords,
|
||||
updateCustomWords
|
||||
updateCustomWords,
|
||||
} from "@/api/index";
|
||||
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "custom-words",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
loading: true,
|
||||
modalType: 0,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
words: "",
|
||||
},
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
name: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
name: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "自定义分词",
|
||||
key: "name",
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
key: "updateTime",
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: "操作人",
|
||||
key: "createBy",
|
||||
minWidth: 150
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"修改"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
submitLoading: false,
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -187,17 +120,14 @@ export default {
|
||||
this.getDataList();
|
||||
},
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
this.$refs.table?.clearSelection();
|
||||
},
|
||||
// 选中状态变更
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
|
||||
getCustomWordsPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
@@ -208,12 +138,10 @@ export default {
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
// 提交数据
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
|
||||
if (this.modalType == 0) {
|
||||
delete this.form.id;
|
||||
insertCustomWords(this.form).then((res) => {
|
||||
@@ -226,7 +154,6 @@ export default {
|
||||
});
|
||||
} else {
|
||||
this.form.id = this.id;
|
||||
// 编辑
|
||||
updateCustomWords(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
@@ -239,16 +166,13 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加
|
||||
add() {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加";
|
||||
this.form = {}
|
||||
this.$refs.form.resetFields();
|
||||
|
||||
this.form = {};
|
||||
this.$refs.form?.resetFields();
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 修改
|
||||
detail(v) {
|
||||
this.modalType = 1;
|
||||
this.id = v.id;
|
||||
@@ -256,15 +180,12 @@ export default {
|
||||
this.modalVisible = true;
|
||||
this.form.name = v.name;
|
||||
},
|
||||
// 删除
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
delCustom(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -275,7 +196,6 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 批量删除
|
||||
delAll() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要删除的数据");
|
||||
@@ -291,8 +211,7 @@ export default {
|
||||
ids += e.id + ",";
|
||||
});
|
||||
ids = ids.substring(0, ids.length - 1);
|
||||
// 批量删除
|
||||
delSensitive(ids).then((res) => {
|
||||
delCustom(ids).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
|
||||
@@ -1,355 +1,198 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Row @keydown.enter.native.prevent="handleSearch">
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.distributionStatus" style="width: 240px">
|
||||
<el-option
|
||||
v-for="item in distributionStatusList"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="状态">
|
||||
<Select
|
||||
v-model="searchForm.distributionStatus"
|
||||
style="width: 240px"
|
||||
>
|
||||
<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>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="idNumber" label="身份证号" min-width="120" />
|
||||
<el-table-column prop="settlementBankAccountName" label="结算银行开户行名称" min-width="120" />
|
||||
<el-table-column prop="settlementBankAccountNum" label="结算银行开户账号" min-width="120" />
|
||||
<el-table-column prop="settlementBankBranchName" label="结算银行开户支行名称" min-width="120" />
|
||||
<el-table-column prop="distributionOrderCount" label="推广单数" width="150" />
|
||||
<el-table-column label="分销订单金额" width="150">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.distributionOrderPrice" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分销金额" width="150">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.rebateTotal" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="待提现金额" width="150">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.canRebate" color="green" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="冻结金额" width="150">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.commissionFrozen" color="#347dda" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="150">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<el-tag v-if="row.distributionStatus == 'PASS'" type="success">通过</el-tag>
|
||||
<el-tag v-else-if="row.distributionStatus == 'APPLY'" type="primary">待审核</el-tag>
|
||||
<el-tag v-else-if="row.distributionStatus == 'RETREAT'" type="warning">清退</el-tag>
|
||||
<el-tag v-else-if="row.distributionStatus == 'REFUSE'" type="danger">拒绝</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a v-if="row.distributionStatus != 'RETREAT'" class="link-text" @click="retreat(row)">清退</a>
|
||||
<a v-if="row.distributionStatus == 'RETREAT'" class="link-text" @click="resume(row)">恢复</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
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>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
title="修改分销员"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
ref="distributionForm"
|
||||
:model="distributionForm"
|
||||
label-width="150px"
|
||||
:rules="distributionFormValidate"
|
||||
>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="distributionForm.name" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号" prop="idNumber">
|
||||
<el-input v-model="distributionForm.idNumber" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结算银行开户行名称" prop="settlementBankAccountName">
|
||||
<el-input v-model="distributionForm.settlementBankAccountName" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结算银行开户账号" prop="settlementBankAccountNum">
|
||||
<el-input v-model="distributionForm.settlementBankAccountNum" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结算银行开户支行名称" prop="settlementBankBranchName">
|
||||
<el-input v-model="distributionForm.settlementBankBranchName" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {editDistribution, getDistributionListData, resumeDistribution, retreatDistribution} from "@/api/distribution";
|
||||
import {distributionStatusList} from "./dataJson.js";
|
||||
import {regular} from "@/utils";
|
||||
import { editDistribution, getDistributionListData, resumeDistribution, retreatDistribution } from "@/api/distribution";
|
||||
import { distributionStatusList } from "./dataJson.js";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "distribution",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
distributionStatusList, // 分销状态
|
||||
loading: true, // 表单加载状态
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
distributionStatusList,
|
||||
loading: true,
|
||||
modalVisible: false,
|
||||
distributionForm: {
|
||||
name: "",
|
||||
idNumber: "",
|
||||
settlementBankAccountName: "",
|
||||
settlementBankAccountNum: "",
|
||||
settlementBankBranchName: ""
|
||||
settlementBankBranchName: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
distributionFormValidate: {
|
||||
name: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
idNumber: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
settlementBankAccountName: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
settlementBankAccountNum: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
settlementBankBranchName: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
idNumber: [regular.REQUIRED, regular.VARCHAR20],
|
||||
settlementBankAccountName: [regular.REQUIRED, regular.VARCHAR20],
|
||||
settlementBankAccountNum: [regular.REQUIRED, regular.VARCHAR20],
|
||||
settlementBankBranchName: [regular.REQUIRED, regular.VARCHAR20],
|
||||
},
|
||||
submitLoading: false, // 编辑提交状态
|
||||
submitLoading: false,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 120,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "姓名",
|
||||
key: "name",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "身份证号",
|
||||
key: "idNumber",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户行名称",
|
||||
key: "settlementBankAccountName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户账号",
|
||||
key: "settlementBankAccountNum",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户支行名称",
|
||||
key: "settlementBankBranchName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "推广单数",
|
||||
key: "distributionOrderCount",
|
||||
minWidth: 120,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: "分销订单金额",
|
||||
key: "distributionOrderPrice",
|
||||
width: 150,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props: {value: params.row.distributionOrderPrice, color: this.$mainColor}});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "分销金额",
|
||||
key: "rebateTotal",
|
||||
width: 150,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props: {value: params.row.rebateTotal, color: this.$mainColor}});
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: "待提现金额",
|
||||
key: "canRebate",
|
||||
width: 150,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props: {value: params.row.canRebate, color: 'green'}});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "冻结金额",
|
||||
key: "commissionFrozen",
|
||||
width: 150,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props: {value: params.row.commissionFrozen, color: '#347dda'}});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "distributionStatus",
|
||||
width: 150,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
if (params.row.distributionStatus == "PASS") {
|
||||
return h("Tag", {props: {color: "green",},}, "通过");
|
||||
} else if (params.row.distributionStatus == "APPLY") {
|
||||
return h("Tag", {props: {color: "geekblue",},}, "待审核");
|
||||
} else if (params.row.distributionStatus == "RETREAT") {
|
||||
return h("Tag", {props: {color: "volcano",},}, "清退");
|
||||
} else if (params.row.distributionStatus == "REFUSE") {
|
||||
return h("Tag", {props: {color: "red",},}, "拒绝");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 140,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
{
|
||||
style: {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
},
|
||||
},
|
||||
[
|
||||
h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "error",
|
||||
size: "small",
|
||||
},
|
||||
style: {
|
||||
marginRight: "5px",
|
||||
display:
|
||||
params.row.distributionStatus != "RETREAT"
|
||||
? "block"
|
||||
: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.retreat(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"清退"
|
||||
),
|
||||
h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "success",
|
||||
size: "small",
|
||||
},
|
||||
style: {
|
||||
marginRight: "5px",
|
||||
display:
|
||||
params.row.distributionStatus == "RETREAT"
|
||||
? "block"
|
||||
: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.resume(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"恢复"
|
||||
),
|
||||
h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "info",
|
||||
size: "small",
|
||||
},
|
||||
style: {
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"编辑"
|
||||
), h(
|
||||
"div",
|
||||
{
|
||||
style: {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
},
|
||||
})
|
||||
]
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
this.searchForm.status = "PASS";
|
||||
@@ -361,15 +204,12 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 清退分销商
|
||||
retreat(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要清退 " + v.memberName + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
retreatDistribution(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -380,15 +220,12 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 恢复分销商
|
||||
resume(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要恢复 " + v.memberName + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
resumeDistribution(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -399,10 +236,8 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 编辑
|
||||
edit(v) {
|
||||
this.$refs.distributionForm.resetFields();
|
||||
// 转换null为""
|
||||
this.$refs.distributionForm?.resetFields();
|
||||
for (let attr in v) {
|
||||
if (v[attr] === null) {
|
||||
v[attr] = "";
|
||||
@@ -413,11 +248,9 @@ export default {
|
||||
this.distributionForm = data;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 提交表单
|
||||
handleSubmit() {
|
||||
this.$refs.distributionForm.validate((valid) => {
|
||||
if (valid) {
|
||||
// 编辑
|
||||
editDistribution(this.distributionForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
|
||||
@@ -1,56 +1,68 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Row @keydown.enter.native.prevent="handleSearch">
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
type="primary"
|
||||
class="search-btn"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
class="mt_10"
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="idNumber" label="身份证号" min-width="120" />
|
||||
<el-table-column prop="settlementBankAccountName" label="结算银行开户行名称" min-width="120" />
|
||||
<el-table-column prop="settlementBankAccountNum" label="结算银行开户账号" min-width="120" />
|
||||
<el-table-column prop="settlementBankBranchName" label="结算银行开户支行名称" min-width="120" />
|
||||
<el-table-column prop="createTime" label="提交时间" min-width="100" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" @click="audit(row, 'PASS')">通过</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="audit(row, 'REFUSE')">拒绝</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -61,115 +73,35 @@ export default {
|
||||
name: "distributionApply",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "姓名",
|
||||
key: "name",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "身份证号",
|
||||
key: "idNumber",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户行名称",
|
||||
key: "settlementBankAccountName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户账号",
|
||||
key: "settlementBankAccountNum",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户支行名称",
|
||||
key: "settlementBankBranchName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "提交时间",
|
||||
key: "createTime",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
on: {
|
||||
click: () => {
|
||||
this.audit(params.row, "PASS");
|
||||
},
|
||||
},
|
||||
},
|
||||
"通过"
|
||||
),
|
||||
h("span", {}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
on: {
|
||||
click: () => {
|
||||
this.audit(params.row, "REFUSE");
|
||||
},
|
||||
},
|
||||
},
|
||||
"拒绝"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
this.searchForm.distributionStatus = "APPLY";
|
||||
@@ -180,10 +112,7 @@ export default {
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
//审核
|
||||
audit(v, status) {
|
||||
let test = "拒绝";
|
||||
if (status == "PASS") {
|
||||
@@ -194,7 +123,6 @@ export default {
|
||||
};
|
||||
this.$Modal.confirm({
|
||||
title: "确认" + test,
|
||||
// 记得确认修改此处
|
||||
content: "您确认要" + test + " " + v.memberName + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
|
||||
@@ -1,270 +1,219 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Form ref="searchForm" @keydown.enter.native.prevent="handleSearch" :model="searchForm" class="search-form">
|
||||
<Form-item label="会员名称" class="flex" prop="memberName">
|
||||
<Input
|
||||
type="text" placeholder="请输入会员名称" v-model="searchForm.memberName" clearable
|
||||
style="width: 240px"></Input>
|
||||
</Form-item>
|
||||
<Form-item label="编号" class="flex">
|
||||
<Input
|
||||
type="text" placeholder="请输入编号" v-model="searchForm.sn" clearable
|
||||
style="width: 240px"></Input>
|
||||
</Form-item>
|
||||
<Form-item label="状态"
|
||||
style="width: 240px">
|
||||
<Select v-model="searchForm.distributionCashStatus" clearable style="width: 150px">
|
||||
<Option v-for="item in cashStatusList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item>
|
||||
<Button @click="handleSearch" type="primary">搜索</Button>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<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="[20,50,100]" size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable='false' :width="500">
|
||||
<Form ref="form" :model="form" :label-width="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 class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" class="flex" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="编号" class="flex">
|
||||
<el-input
|
||||
v-model="searchForm.sn"
|
||||
placeholder="请输入编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" style="width: 240px">
|
||||
<el-select v-model="searchForm.distributionCashStatus" clearable style="width: 150px">
|
||||
<el-option
|
||||
v-for="item in cashStatusList"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sn" label="编号" min-width="200" />
|
||||
<el-table-column prop="distributionName" label="会员名称" min-width="120" />
|
||||
<el-table-column label="申请金额" min-width="90">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.price" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="申请时间" min-width="130" />
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="idNumber" label="身份证号" min-width="120" />
|
||||
<el-table-column prop="settlementBankAccountName" label="结算银行开户行名称" min-width="120" />
|
||||
<el-table-column prop="settlementBankAccountNum" label="结算银行开户账号" min-width="120" />
|
||||
<el-table-column prop="settlementBankBranchName" label="结算银行开户支行名称" min-width="120" />
|
||||
<el-table-column prop="updateTime" label="处理时间" min-width="130" />
|
||||
<el-table-column label="状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">
|
||||
<span v-if="row.distributionCashStatus == 'APPLY'">待处理</span>
|
||||
<span v-else-if="row.distributionCashStatus == 'VIA_AUDITING'">通过</span>
|
||||
<span v-else-if="row.distributionCashStatus == 'FAIL_AUDITING'">审核拒绝</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="130" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" v-if="row.distributionCashStatus != 'APPLY'" @click="view(row)">查看</a>
|
||||
<a class="link-text" v-else @click="edit(row)">审核</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10 page padding-row" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="100px">
|
||||
<el-form-item label="编号">
|
||||
<el-input v-model="form.sn" disabled clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称">
|
||||
<el-input v-model="form.distributionName" disabled clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="金额">
|
||||
<el-input v-model="form.price" disabled clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="handleStatus == 'edit'" label="是否通过" prop="result">
|
||||
<el-radio-group v-model="result">
|
||||
<el-radio-button value="VIA_AUDITING">通过</el-radio-button>
|
||||
<el-radio-button value="FAIL_AUDITING">拒绝</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-if="handleStatus == 'edit'" #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
auditDistributionCash,
|
||||
getDistributionCash
|
||||
} from "@/api/distribution";
|
||||
import { cashStatusList } from './dataJson';
|
||||
import { auditDistributionCash, getDistributionCash } from "@/api/distribution";
|
||||
import { cashStatusList } from "./dataJson";
|
||||
|
||||
export default {
|
||||
name: "distributionCash",
|
||||
data() {
|
||||
return {
|
||||
cashStatusList, // 状态列表
|
||||
loading: true, // 表单加载状态
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
result: 'FAIL_AUDITING', // 是否通过
|
||||
searchForm: { // 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
cashStatusList,
|
||||
loading: true,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
result: "FAIL_AUDITING",
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
handleStatus:'edit',// 判断是编辑还是查看
|
||||
form: { // 添加或编辑表单对象初始化数据
|
||||
handleStatus: "edit",
|
||||
form: {
|
||||
sn: "",
|
||||
memberName: "",
|
||||
price: "",
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
{
|
||||
title: "编号",
|
||||
key: "sn",
|
||||
minWidth: 200
|
||||
},
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "distributionName",
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
title: "申请金额",
|
||||
key: "price",
|
||||
minWidth: 90,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "申请时间",
|
||||
key: "createTime",
|
||||
minWidth: 130
|
||||
},
|
||||
{
|
||||
title: "姓名",
|
||||
key: "name",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "身份证号",
|
||||
key: "idNumber",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户行名称",
|
||||
key: "settlementBankAccountName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户账号",
|
||||
key: "settlementBankAccountNum",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "结算银行开户支行名称",
|
||||
key: "settlementBankBranchName",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "处理时间",
|
||||
key: "updateTime",
|
||||
minWidth: 130
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
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: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
if (params.row.distributionCashStatus != 'APPLY') {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
on: {
|
||||
click: () => {
|
||||
this.view(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
"审核"
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0 // 表单数据总数
|
||||
submitLoading: false,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据 请自行修改接口
|
||||
getDistributionCash(this.searchForm).then(res => {
|
||||
getDistributionCash(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
// 通过还是拒绝申请
|
||||
handleSubmit() {
|
||||
let result = "拒绝"
|
||||
if(this.result == 'VIA_AUDITING'){
|
||||
result = "通过"
|
||||
let result = "拒绝";
|
||||
if (this.result == "VIA_AUDITING") {
|
||||
result = "通过";
|
||||
}
|
||||
this.$refs.form.validate(valid => {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认审核",
|
||||
content: "您确认要审核"+result+"么?",
|
||||
content: "您确认要审核" + result + "么?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
auditDistributionCash(this.form.id,{result:this.result}).then(res => {
|
||||
if (res.success) {
|
||||
this.$Modal.remove();
|
||||
this.$Message.success("审核成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
} else {
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
auditDistributionCash(this.form.id, { result: this.result }).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Modal.remove();
|
||||
this.$Message.success("审核成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
} else {
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 弹出modal 审核
|
||||
edit(v) {
|
||||
this.modalTitle = "审核";
|
||||
this.handleStatus = 'edit';
|
||||
this.$refs.form.resetFields();
|
||||
// 转换null为""
|
||||
this.handleStatus = "edit";
|
||||
this.$refs.form?.resetFields();
|
||||
for (let attr in v) {
|
||||
if (v[attr] === null) {
|
||||
v[attr] = "";
|
||||
@@ -273,12 +222,10 @@ export default {
|
||||
this.form = JSON.parse(JSON.stringify(v));
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 弹出modal 查看
|
||||
view(v){
|
||||
view(v) {
|
||||
this.modalTitle = "查看";
|
||||
this.handleStatus = 'view';
|
||||
this.$refs.form.resetFields();
|
||||
// 转换null为""
|
||||
this.handleStatus = "view";
|
||||
this.$refs.form?.resetFields();
|
||||
for (let attr in v) {
|
||||
if (v[attr] === null) {
|
||||
v[attr] = "";
|
||||
@@ -288,12 +235,11 @@ export default {
|
||||
let data = JSON.parse(str);
|
||||
this.form = data;
|
||||
this.modalVisible = true;
|
||||
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,214 +1,182 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Form @keydown.enter.native.prevent="handleSearch" ref="searchForm" :model="searchForm" inline :label-width="70"
|
||||
class="search-form">
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation" style="margin:10px 0;">
|
||||
<Button @click="delAll" type="primary">批量下架</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom"
|
||||
@on-selection-change="changeSelect">
|
||||
<template slot="goodsName" slot-scope="{row}">
|
||||
<div>
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
|
||||
</div>
|
||||
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
|
||||
<div slot="content">
|
||||
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff"
|
||||
:size="150"></vue-qr>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter.prevent="handleSearch"
|
||||
>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<div class="operation" style="margin: 10px 0">
|
||||
<el-button type="primary" @click="delAll">批量下架</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="商品图片" width="120" align="center" fixed="left">
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="row"
|
||||
:src="row.thumbnail || ''"
|
||||
alt="商品图"
|
||||
style="cursor: pointer; width: 80px; height: 60px; margin: 10px 0; object-fit: contain"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" min-width="220" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<div class="div-zoom">
|
||||
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
|
||||
</Poptip>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[20,50,100]" size="small" show-total show-elevator
|
||||
show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../assets/qrcode.svg"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="库存" min-width="80" />
|
||||
<el-table-column prop="createTime" label="添加时间" min-width="160" />
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="佣金金额" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">{{ $filters.unitPrice(row.commission, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="100" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="remove(row)">下架</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { delDistributionGoods, getDistributionGoods } from "@/api/distribution";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"vue-qr": vueQr,
|
||||
},
|
||||
name: "distributionGoods",
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
},
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
},
|
||||
{
|
||||
title: "商品图片",
|
||||
fixed: "left",
|
||||
key: "thumbnail",
|
||||
width: 120,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h("img", {
|
||||
attrs: {
|
||||
src: params.row.thumbnail || '',
|
||||
alt: "加载图片失败",
|
||||
},
|
||||
style: {
|
||||
cursor: "pointer",
|
||||
width: "80px",
|
||||
height: "60px",
|
||||
margin: "10px 0",
|
||||
"object-fit": "contain",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
slot: "goodsName",
|
||||
minWidth: 200,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品价格",
|
||||
key: "price",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
minWidth: 80,
|
||||
},
|
||||
{
|
||||
title: "添加时间",
|
||||
key: "createTime",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "佣金金额",
|
||||
key: "commission",
|
||||
minWidth: 100,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.commission,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
minWidth: 100,
|
||||
render: (h, params) => {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"下架"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 清除选中状态
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
this.$refs.table?.clearSelection();
|
||||
},
|
||||
// 选中后赋值
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getDistributionGoods(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
getDistributionGoods(this.searchForm)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 下架商品
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认下架",
|
||||
content: "您确认要下架么?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 下架
|
||||
delDistributionGoods(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -219,7 +187,6 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 批量下架
|
||||
delAll() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要下架的数据");
|
||||
@@ -230,11 +197,7 @@ export default {
|
||||
content: "您确认要下架所选的 " + this.selectCount + " 条数据?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
let ids = [];
|
||||
this.selectList.forEach((item) => {
|
||||
ids.push(item.id);
|
||||
});
|
||||
// 批量下架
|
||||
const ids = this.selectList.map((item) => item.id);
|
||||
delDistributionGoods(ids.toString()).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -252,17 +215,24 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops span {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
.div-zoom {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -1,258 +1,281 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Form ref="searchForm" @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="订单编号" prop="orderSn">
|
||||
<Input
|
||||
type="text"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="订单编号" prop="orderSn">
|
||||
<el-input
|
||||
v-model="searchForm.orderSn"
|
||||
placeholder="请输入订单编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="分销商" prop="distributionName">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="分销商" prop="distributionName">
|
||||
<el-input
|
||||
v-model="searchForm.distributionName"
|
||||
placeholder="请输入分销商名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="店铺名称">
|
||||
<Select v-model="searchForm.storeId" placeholder="请选择" @on-query-change="searchChange" filterable
|
||||
clearable style="width: 240px">
|
||||
<Option v-for="item in shopList" :value="item.id" :key="item.id">{{ item.storeName }}</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="订单时间">
|
||||
<DatePicker type="daterange" v-model="timeRange" format="yyyy-MM-dd" placeholder="选择时间"
|
||||
style="width: 240px"></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10">
|
||||
<template slot-scope="{row}" slot="goodsMsg">
|
||||
<div class="goods-msg">
|
||||
<img :src="row.image" width="60" height="60" alt="">
|
||||
<div>
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
|
||||
</div>
|
||||
<div style="color:#999;font-size:10px">数量:x{{row.num}}</div>
|
||||
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
|
||||
<div slot="content">
|
||||
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称">
|
||||
<el-select
|
||||
v-model="searchForm.storeId"
|
||||
placeholder="请选择"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="searchChange"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in shopList"
|
||||
:key="item.id"
|
||||
:label="item.storeName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单时间">
|
||||
<el-date-picker
|
||||
v-model="timeRange"
|
||||
type="daterange"
|
||||
value-format="YYYY-MM-DD"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
placeholder="选择时间"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="orderSn"
|
||||
label="订单编号"
|
||||
min-width="180"
|
||||
fixed="left"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="商品信息" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="goods-msg">
|
||||
<img :src="row.image" width="60" height="60" alt="" />
|
||||
<div>
|
||||
<div class="div-zoom">
|
||||
<a class="link-text" @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
|
||||
</Poptip>
|
||||
<div style="color: #999; font-size: 10px">数量:x{{ row.num }}</div>
|
||||
<el-popover trigger="hover" title="扫码在手机中查看" placement="top" width="180">
|
||||
<template #reference>
|
||||
<img
|
||||
src="../../assets/qrcode.svg"
|
||||
class="hover-pointer"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="qrcode"
|
||||
/>
|
||||
</template>
|
||||
<vue-qr
|
||||
:text="wapLinkTo(row.goodsId, row.skuId)"
|
||||
:margin="0"
|
||||
color-dark="#000"
|
||||
color-light="#fff"
|
||||
:size="150"
|
||||
/>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{row}" slot="distributionOrderStatus">
|
||||
<Tag :color="filterStatusColor(row.distributionOrderStatus)">{{filterStatus(row.distributionOrderStatus)}}</Tag>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize"
|
||||
@on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[20,50,100]"
|
||||
size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="distributionName" label="分销商" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="状态" min-width="90">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="filterStatusTagType(row.distributionOrderStatus)">
|
||||
{{ filterStatus(row.distributionOrderStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="佣金金额" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">
|
||||
{{ $filters.unitPrice(row.rebate, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="160" fixed="right" />
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getDistributionOrder
|
||||
} from "@/api/distribution";
|
||||
import {orderStatusList} from './dataJson'
|
||||
import {getShopListData} from '@/api/shops'
|
||||
import vueQr from 'vue-qr'
|
||||
import { getDistributionOrder } from "@/api/distribution";
|
||||
import { orderStatusList } from "./dataJson";
|
||||
import { getShopListData } from "@/api/shops";
|
||||
import vueQr from "vue-qr";
|
||||
|
||||
export default {
|
||||
name: "distributionOrder",
|
||||
components: {
|
||||
"vue-qr":vueQr
|
||||
export default {
|
||||
name: "distributionOrder",
|
||||
components: { vueQr },
|
||||
data() {
|
||||
return {
|
||||
timeRange: [],
|
||||
orderStatusList,
|
||||
shopList: [],
|
||||
distributionId: this.$route.query.id,
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route(e) {
|
||||
this.distributionId = e.query.id ? e.query.id : undefined;
|
||||
this.getDataList();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timeRange: [], // 范围时间
|
||||
orderStatusList, // 订单状态列表
|
||||
shopList: [], // 店铺列表
|
||||
distributionId: this.$route.query.id, // 分销id
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: { // 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort:"create_time",
|
||||
order:"desc"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "订单编号",
|
||||
key: "orderSn",
|
||||
minWidth: 180,
|
||||
fixed: "left",
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '商品信息',
|
||||
slot: 'goodsMsg',
|
||||
minWidth: 150
|
||||
},
|
||||
|
||||
{
|
||||
title: "分销商",
|
||||
key: "distributionName",
|
||||
tooltip: true,
|
||||
minWidth:80,
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
minWidth:80,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
slot: "distributionOrderStatus",
|
||||
minWidth:80,
|
||||
},
|
||||
{
|
||||
title: "佣金金额",
|
||||
key: "rebate",
|
||||
minWidth:80,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.rebate,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
{
|
||||
fixed: "right",
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
minWidth:100,
|
||||
sortable: false,
|
||||
}
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0 // 表单数据总数
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getShopList();
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getShopList()
|
||||
},
|
||||
//分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.searchForm.distributionId = this.distributionId;
|
||||
this.loading = true;
|
||||
if (this.timeRange && this.timeRange[0]) {
|
||||
let startTime = this.timeRange[0]
|
||||
let endTime = this.timeRange[1]
|
||||
this.searchForm.startTime = this.$options.filters.unixToDate(startTime / 1000)
|
||||
this.searchForm.endTime = this.$options.filters.unixToDate(endTime / 1000)
|
||||
}
|
||||
// 带多条件搜索参数获取表单数据 请自行修改接口
|
||||
getDistributionOrder(this.searchForm).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.searchForm.distributionId = this.distributionId;
|
||||
this.loading = true;
|
||||
if (this.timeRange && this.timeRange[0] && this.timeRange[1]) {
|
||||
const startTime = new Date(this.timeRange[0]).getTime();
|
||||
const endTime = new Date(this.timeRange[1]).getTime();
|
||||
this.searchForm.startTime = this.$filters.unixToDate(startTime / 1000);
|
||||
this.searchForm.endTime = this.$filters.unixToDate(endTime / 1000);
|
||||
} else {
|
||||
this.searchForm.startTime = null;
|
||||
this.searchForm.endTime = null;
|
||||
}
|
||||
getDistributionOrder(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
getShopList(val) { // 获取店铺列表 搜索用
|
||||
const params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
storeName: ''
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
if (val) {
|
||||
params.storeName = val;
|
||||
} else {
|
||||
params.storeName = ''
|
||||
}
|
||||
|
||||
getShopListData(params).then(res => {
|
||||
this.shopList = res.result.records
|
||||
})
|
||||
},
|
||||
searchChange(val) { // 店铺搜索,键盘点击回调
|
||||
this.getShopList(val)
|
||||
},
|
||||
filterStatus (status) { // 过滤订单状态
|
||||
const arr = [
|
||||
{status: 'NO_COMPLETED', title: '未完成'},
|
||||
{status: 'COMPLETE', title: '完成'},
|
||||
{status: 'REFUND', title: '退款'},
|
||||
]
|
||||
for (let i=0;i<arr.length;i++) {
|
||||
if (arr[i].status === status) {
|
||||
return arr[i].title;
|
||||
}
|
||||
}
|
||||
return '未完成'; // 默认返回未完成
|
||||
},
|
||||
filterStatusColor (status) { // 状态tag标签颜色
|
||||
const arr = [
|
||||
{status: 'NO_COMPLETED', color: 'orange'},
|
||||
{status: 'COMPLETE', color: 'green'},
|
||||
{status: 'REFUND', color: 'red'},
|
||||
]
|
||||
for (let i=0;i<arr.length;i++) {
|
||||
if (arr[i].status === status) {
|
||||
return arr[i].color;
|
||||
}
|
||||
}
|
||||
return 'orange'; // 默认返回橙色
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
getShopList(val) {
|
||||
const params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
storeName: val || "",
|
||||
};
|
||||
getShopListData(params).then((res) => {
|
||||
this.shopList = res.result.records;
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
$route(e) { // 监听路由,参数变化调取接口
|
||||
this.distributionId = e.query.id ? e.query.id : undefined;
|
||||
this.getDataList();
|
||||
searchChange(val) {
|
||||
this.getShopList(val);
|
||||
},
|
||||
filterStatus(status) {
|
||||
const arr = [
|
||||
{ status: "NO_COMPLETED", title: "未完成" },
|
||||
{ status: "COMPLETE", title: "完成" },
|
||||
{ status: "REFUND", title: "退款" },
|
||||
];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i].status === status) {
|
||||
return arr[i].title;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return "未完成";
|
||||
},
|
||||
filterStatusTagType(status) {
|
||||
const arr = [
|
||||
{ status: "NO_COMPLETED", type: "warning" },
|
||||
{ status: "COMPLETE", type: "success" },
|
||||
{ status: "REFUND", type: "danger" },
|
||||
];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i].status === status) {
|
||||
return arr[i].type;
|
||||
}
|
||||
}
|
||||
return "warning";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.goods-msg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
>div{
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.goods-msg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hover-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
<template>
|
||||
<div style="background-color: #fff;">
|
||||
|
||||
<Form ref="form" :model="form" :rules="formRule" :label-width="120" style="padding: 10px;">
|
||||
|
||||
<Divider orientation="left">分销设置</Divider>
|
||||
<FormItem label="是否开启分销" prop="isOpen">
|
||||
<i-switch size="large" v-model="form.isOpen" :true-value="true" :false-value="false">
|
||||
<span slot="open">开启</span>
|
||||
<span slot="close">关闭</span>
|
||||
</i-switch>
|
||||
</FormItem>
|
||||
<FormItem label="分销关系绑定天数" prop="distributionDay">
|
||||
<InputNumber :min="1" :max="365" style="width:100px;" v-model="form.distributionDay"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="primary" @click="submit">保存</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div style="background-color: #fff">
|
||||
<el-form ref="form" :model="form" :rules="formRule" label-width="140px" style="padding: 10px">
|
||||
<el-divider content-position="left">分销设置</el-divider>
|
||||
<el-form-item label="是否开启分销" prop="isOpen">
|
||||
<el-switch v-model="form.isOpen" active-text="开启" inactive-text="关闭" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分销关系绑定天数" prop="distributionDay">
|
||||
<el-input-number v-model="form.distributionDay" :min="1" :max="365" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -28,26 +23,22 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
isOpen: true,
|
||||
distributionDay: 0, //分销关系绑定天数
|
||||
distributionDay: 1,
|
||||
},
|
||||
formRule: {
|
||||
isOpen: [
|
||||
regular.REQUIRED
|
||||
],
|
||||
distributionDay: [
|
||||
regular.REQUIRED
|
||||
],
|
||||
}
|
||||
isOpen: [regular.REQUIRED],
|
||||
distributionDay: [regular.REQUIRED],
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取分销设置数据
|
||||
getDataList() {
|
||||
getSetting("DISTRIBUTION_SETTING").then((res) => {
|
||||
if (res.success) {
|
||||
@@ -55,20 +46,17 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 提交api
|
||||
submit() {
|
||||
setSetting("DISTRIBUTION_SETTING", this.form).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) return;
|
||||
setSetting("DISTRIBUTION_SETTING", this.form).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
|
||||
<template>
|
||||
<div class="error403">
|
||||
<div class="error403-body-con">
|
||||
<Card>
|
||||
<div class="error403-body-con-title">4<span class="error403-0-span">
|
||||
<Icon type="android-lock"></Icon>
|
||||
</span><span class="error403-key-span">
|
||||
<Icon size="220" type="ios-bolt"></Icon>
|
||||
</span></div>
|
||||
<el-card>
|
||||
<div class="error403-body-con-title">
|
||||
4<span class="error403-0-span">🔒</span><span class="error403-key-span">⚡</span>
|
||||
</div>
|
||||
<p class="error403-body-con-message">You don't have permission</p>
|
||||
<div class="error403-btn-con">
|
||||
<Button @click="goHome" size="large" style="width: 200px;" type="text">返回首页</Button>
|
||||
<Button @click="backPage" size="large" style="width: 200px;margin-left: 40px;" type="primary">返回上一页</Button>
|
||||
<el-button size="large" style="width: 200px" @click="goHome">返回首页</el-button>
|
||||
<el-button size="large" type="primary" style="width: 200px; margin-left: 40px" @click="backPage">
|
||||
返回上一页
|
||||
</el-button>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,11 +21,9 @@
|
||||
export default {
|
||||
name: "Error403",
|
||||
methods: {
|
||||
// 返回上一页
|
||||
backPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
// 返回首页
|
||||
goHome() {
|
||||
this.$router.push({
|
||||
name: "home_index",
|
||||
@@ -35,6 +32,7 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes error403animation {
|
||||
0% {
|
||||
@@ -84,14 +82,8 @@ export default {
|
||||
border: 20px solid #ed3f14;
|
||||
color: #ed3f14;
|
||||
margin-right: 10px;
|
||||
i {
|
||||
display: inline-block;
|
||||
font-size: 120px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
font-size: 80px;
|
||||
line-height: 130px;
|
||||
}
|
||||
.error403-key-span {
|
||||
display: inline-block;
|
||||
@@ -100,15 +92,8 @@ export default {
|
||||
height: 190px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
i {
|
||||
display: inline-block;
|
||||
font-size: 190px;
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
transform: translate(-50%, -60%);
|
||||
transform-origin: center bottom;
|
||||
animation: error403animation 2.8s ease 0s infinite;
|
||||
}
|
||||
font-size: 80px;
|
||||
animation: error403animation 2.8s ease 0s infinite;
|
||||
}
|
||||
}
|
||||
&-message {
|
||||
@@ -127,4 +112,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
|
||||
<template>
|
||||
<div class="error404">
|
||||
<div class="error404-body-con">
|
||||
<Card>
|
||||
<el-card>
|
||||
<div class="error404-body-con-title">
|
||||
4<span><Icon type="ios-navigate-outline"></Icon></span>4
|
||||
4<span>🧭</span>4
|
||||
</div>
|
||||
<p class="error404-body-con-message">
|
||||
YOU LOOK LOST
|
||||
</p>
|
||||
<p class="error404-body-con-message">YOU LOOK LOST</p>
|
||||
<div class="error404-btn-con">
|
||||
<Button @click="goHome" size="large" style="width: 200px" type="text"
|
||||
>返回首页</Button
|
||||
>
|
||||
<Button
|
||||
@click="backPage"
|
||||
size="large"
|
||||
style="width: 200px; margin-left: 40px"
|
||||
type="primary"
|
||||
>返回上一页</Button
|
||||
>
|
||||
<el-button size="large" style="width: 200px" @click="goHome">返回首页</el-button>
|
||||
<el-button size="large" type="primary" style="width: 200px; margin-left: 40px" @click="backPage">
|
||||
返回上一页
|
||||
</el-button>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,11 +21,9 @@
|
||||
export default {
|
||||
name: "Error404",
|
||||
methods: {
|
||||
// 返回上一页
|
||||
backPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
// 返回首页
|
||||
goHome() {
|
||||
this.$router.push({
|
||||
name: "home_index",
|
||||
@@ -43,6 +32,7 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes error404animation {
|
||||
0% {
|
||||
@@ -83,7 +73,7 @@ export default {
|
||||
span {
|
||||
display: inline-block;
|
||||
color: #19be6b;
|
||||
font-size: 230px;
|
||||
font-size: 120px;
|
||||
animation: error404animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,18 @@
|
||||
|
||||
|
||||
<template>
|
||||
<div class="error500">
|
||||
<div class="error500-body-con">
|
||||
<Card>
|
||||
<el-card>
|
||||
<div class="error500-body-con-title">
|
||||
5<span class="error500-0-span"
|
||||
><Icon type="social-freebsd-devil"></Icon></span
|
||||
><span class="error500-0-span"
|
||||
><Icon type="social-freebsd-devil"></Icon
|
||||
></span>
|
||||
5<span class="error500-0-span">😈</span><span class="error500-0-span">😈</span>
|
||||
</div>
|
||||
<p class="error500-body-con-message">Oops! the server is wrong</p>
|
||||
<div class="error500-btn-con">
|
||||
<Button @click="goHome" size="large" style="width: 200px" type="text"
|
||||
>返回首页</Button
|
||||
>
|
||||
<Button
|
||||
@click="backPage"
|
||||
size="large"
|
||||
style="width: 200px; margin-left: 40px"
|
||||
type="primary"
|
||||
>返回上一页</Button
|
||||
>
|
||||
<el-button size="large" style="width: 200px" @click="goHome">返回首页</el-button>
|
||||
<el-button size="large" type="primary" style="width: 200px; margin-left: 40px" @click="backPage">
|
||||
返回上一页
|
||||
</el-button>
|
||||
</div>
|
||||
</Card>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -33,11 +21,9 @@
|
||||
export default {
|
||||
name: "Error500",
|
||||
methods: {
|
||||
// 返回上一页
|
||||
backPage() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
// 返回首页
|
||||
goHome() {
|
||||
this.$router.push({
|
||||
name: "home_index",
|
||||
@@ -46,6 +32,7 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes error500animation {
|
||||
0% {
|
||||
@@ -86,21 +73,15 @@ export default {
|
||||
.error500-0-span {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 170px;
|
||||
height: 170px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
border: 20px solid #ed3f14;
|
||||
color: #ed3f14;
|
||||
margin-right: 10px;
|
||||
i {
|
||||
display: inline-block;
|
||||
font-size: 120px;
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 10px;
|
||||
transform-origin: center bottom;
|
||||
animation: error500animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
font-size: 60px;
|
||||
line-height: 80px;
|
||||
animation: error500animation 3s ease 0s infinite alternate;
|
||||
}
|
||||
}
|
||||
&-message {
|
||||
|
||||
@@ -1,52 +1,67 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation">
|
||||
<Button @click="add" type="primary">添加</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="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="form" :label-width="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
|
||||
>
|
||||
<el-card>
|
||||
<div class="operation">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
<el-button @click="delAll">批量删除</el-button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
style="width: 100%"
|
||||
row-key="id"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<el-table-column type="selection" width="60" align="center" />
|
||||
<el-table-column prop="name" label="计量单位" min-width="120" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" />
|
||||
<el-table-column prop="createBy" label="操作人" min-width="150" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="edit(row)">修改</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="计量单位" prop="name">
|
||||
<el-input v-model="form.name" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -55,156 +70,64 @@ import {
|
||||
addGoodsUnit,
|
||||
getGoodsUnitPage,
|
||||
updateGoodsUnit,
|
||||
delGoodsUnit
|
||||
delGoodsUnit,
|
||||
} from "@/api/index";
|
||||
|
||||
import {regular} from "@/utils";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "goods-unit",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
loading: true,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
name: "",
|
||||
},
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
name: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
name: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR5
|
||||
]
|
||||
name: [regular.REQUIRED, regular.VARCHAR5],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "计量单位",
|
||||
key: "name",
|
||||
minWidth: 120
|
||||
},
|
||||
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
key: "updateTime",
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: "操作人",
|
||||
key: "createBy",
|
||||
minWidth: 150
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"修改"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
submitLoading: false,
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 清除选中
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
this.$refs.table?.clearSelection();
|
||||
},
|
||||
// 选中回调
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
|
||||
getGoodsUnitPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
@@ -215,20 +138,16 @@ export default {
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
// 修改后提交
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
|
||||
if (this.modalTitle == "添加") {
|
||||
|
||||
if(this.data.find(item=>item.name == this.form.name)){
|
||||
this.$Message.error('请勿添加重复计量单位!')
|
||||
this.submitLoading = false
|
||||
return
|
||||
if (this.data.find((item) => item.name == this.form.name)) {
|
||||
this.$Message.error("请勿添加重复计量单位!");
|
||||
this.submitLoading = false;
|
||||
return;
|
||||
}
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.form.id;
|
||||
addGoodsUnit(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -239,7 +158,6 @@ export default {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
updateGoodsUnit(this.id, this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
@@ -252,30 +170,24 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加
|
||||
add() {
|
||||
this.modalTitle = "添加";
|
||||
this.form = {};
|
||||
this.$refs.form.resetFields();
|
||||
|
||||
this.$refs.form?.resetFields();
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 编辑
|
||||
edit(v) {
|
||||
this.id = v.id;
|
||||
this.modalTitle = "修改";
|
||||
this.modalVisible = true;
|
||||
this.form.name = v.name;
|
||||
},
|
||||
// 删除
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
delGoodsUnit(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -286,8 +198,6 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 全部删除
|
||||
delAll() {
|
||||
if (this.selectCount <= 0) {
|
||||
this.$Message.warning("您还未选择要删除的数据");
|
||||
@@ -303,7 +213,6 @@ export default {
|
||||
ids += e.id + ",";
|
||||
});
|
||||
ids = ids.substring(0, ids.length - 1);
|
||||
// 批量删除
|
||||
delGoodsUnit(ids).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -312,9 +221,9 @@ export default {
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
|
||||
@@ -1,253 +1,289 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keydown.enter.native="handleSearch"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品编号" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编号" prop="id">
|
||||
<el-input
|
||||
v-model="searchForm.id"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="店铺名称" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称" prop="storeName">
|
||||
<el-input
|
||||
v-model="searchForm.storeName"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="销售模式" prop="status">
|
||||
<Select
|
||||
</el-form-item>
|
||||
<el-form-item label="销售模式" prop="salesModel">
|
||||
<el-select
|
||||
v-model="searchForm.salesModel"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="RETAIL">零售</Option>
|
||||
<Option value="WHOLESALE">批发</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="商品类型" prop="status">
|
||||
<Select
|
||||
<el-option label="零售" value="RETAIL" />
|
||||
<el-option label="批发" value="WHOLESALE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型" prop="goodsType">
|
||||
<el-select
|
||||
v-model="searchForm.goodsType"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="PHYSICAL_GOODS">实物商品</Option>
|
||||
<Option value="VIRTUAL_GOODS">虚拟商品</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="商品分组" prop="groupId">
|
||||
<Select
|
||||
<el-option label="实物商品" value="PHYSICAL_GOODS" />
|
||||
<el-option label="虚拟商品" value="VIRTUAL_GOODS" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分组" prop="groupId">
|
||||
<el-select
|
||||
v-model="searchForm.groupId"
|
||||
placeholder="请选择商品分组"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option v-for="item in goodsGroupList" :value="item.id" :key="item.id">{{ item.groupName }}</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
class="search-btn"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<el-option
|
||||
v-for="item in goodsGroupList"
|
||||
:key="item.id"
|
||||
:label="item.groupName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div class="goods-tab">
|
||||
<Tabs v-model="currentStatus" @on-click="goodsStatusClick">
|
||||
<TabPane v-for="(item,index) in goodsStatusWithCount" :key="index" :label="item.title" :name="item.value">
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<el-card>
|
||||
<div class="goods-tab">
|
||||
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in goodsStatusWithCount"
|
||||
:key="index"
|
||||
:label="item.title"
|
||||
:name="item.value"
|
||||
/>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 批量操作按钮 -->
|
||||
<div class="batch-operations" style="margin: 10px 0;">
|
||||
<Button
|
||||
<div class="batch-operations" style="margin: 10px 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
style="margin-right: 10px"
|
||||
@click="openSetGoodsGroup"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
批量设置分组
|
||||
</Button>
|
||||
<Button
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
:disabled="selectedRows.length === 0"
|
||||
style="margin-right: 10px"
|
||||
@click="batchUpper"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
批量上架
|
||||
</Button>
|
||||
<Button
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
:disabled="selectedRows.length === 0"
|
||||
style="margin-right: 10px"
|
||||
@click="batchLower"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
批量下架
|
||||
</Button>
|
||||
<Button
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentStatus === 'TOBEAUDITED'"
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="batchAudit"
|
||||
>
|
||||
批量审核
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
@on-select="onSelect"
|
||||
@on-select-all="onSelectAll"
|
||||
@on-selection-change="onSelectionChange"
|
||||
row-key="id"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<!-- 商品图片格式化 -->
|
||||
<template slot="imageSlot" slot-scope="{ row }">
|
||||
<div style="margin-top: 5px;">
|
||||
<el-table-column type="selection" width="100" align="center" />
|
||||
<el-table-column prop="id" label="商品ID" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="商品图片" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="row && row.original"
|
||||
:src="row.original"
|
||||
style="height: 50px; width: 50px; object-fit: cover;"
|
||||
style="height: 50px; width: 50px; object-fit: cover"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" width="200">
|
||||
<template #default="{ row }">
|
||||
<span :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, '¥') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="buyCount" label="销量" width="150" />
|
||||
<el-table-column prop="quantity" label="库存" width="150" />
|
||||
<el-table-column label="销售模式" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ salesModelText(row.salesModel) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品类型" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ goodsTypeText(row.goodsType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ marketEnableText(row.marketEnable) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ authFlagText(row.authFlag) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeName" label="店铺名称" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.authFlag === 'TOBEAUDITED'">
|
||||
<a class="link-text" @click="openAuditModal(row)">审核</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
<template v-else-if="row.marketEnable === 'DOWN'">
|
||||
<a class="link-text" @click="upper(row)">上架</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a class="link-text" @click="edit(row)">下架</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="{ row }">
|
||||
<div style="margin: 5px 0px; padding: 10px 0px;">
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
title="下架操作"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="underForm" :model="underForm" :label-width="100">
|
||||
<FormItem label="下架原因" prop="reason">
|
||||
<Input v-model="underForm.reason" clearable style="width: 100%" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="lower"
|
||||
>提交</Button
|
||||
>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
title="商品审核"
|
||||
v-model="auditModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="auditForm" :model="goodsAuditForm" :label-width="100">
|
||||
<FormItem label="审核结果" prop="auth_flag">
|
||||
<RadioGroup v-model="goodsAuditForm.auth_flag">
|
||||
<Radio :label="1">审核通过</Radio>
|
||||
<Radio :label="2">审核拒绝</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<!-- <FormItem label="审核备注" prop="reason" v-if="goodsAuditForm.auth_flag === 2">
|
||||
<Input v-model="goodsAuditForm.reason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
||||
</FormItem> -->
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="auditModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="confirmAudit">提交审核</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<!-- 批量审核弹框 -->
|
||||
<Modal
|
||||
title="批量商品审核"
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" title="下架操作" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="underForm" :model="underForm" label-width="100px">
|
||||
<el-form-item label="下架原因" prop="reason">
|
||||
<el-input v-model="underForm.reason" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="lower">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="auditModalVisible" title="商品审核" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="auditForm" :model="goodsAuditForm" label-width="100px">
|
||||
<el-form-item label="审核结果" prop="auth_flag">
|
||||
<el-radio-group v-model="goodsAuditForm.auth_flag">
|
||||
<el-radio :value="1">审核通过</el-radio>
|
||||
<el-radio :value="2">审核拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="auditModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmAudit">提交审核</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="batchAuditModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
title="批量商品审核"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<Form ref="batchAuditForm" :model="batchAuditForm" :label-width="100">
|
||||
<FormItem label="审核结果" prop="auth_flag">
|
||||
<RadioGroup v-model="batchAuditForm.auth_flag">
|
||||
<Radio :label="1">审核通过</Radio>
|
||||
<Radio :label="2">审核拒绝</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="审核备注" prop="reason" v-if="batchAuditForm.auth_flag === 2">
|
||||
<Input v-model="batchAuditForm.reason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
||||
</FormItem>
|
||||
<FormItem label="选中商品">
|
||||
<div style="max-height: 200px; overflow-y: auto;">
|
||||
<Tag v-for="item in selectedRows" :key="item.id" style="margin: 2px;">{{item.goodsName}}</Tag>
|
||||
<el-form ref="batchAuditForm" :model="batchAuditForm" label-width="100px">
|
||||
<el-form-item label="审核结果" prop="auth_flag">
|
||||
<el-radio-group v-model="batchAuditForm.auth_flag">
|
||||
<el-radio :value="1">审核通过</el-radio>
|
||||
<el-radio :value="2">审核拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="batchAuditForm.auth_flag === 2" label="审核备注" prop="reason">
|
||||
<el-input v-model="batchAuditForm.reason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选中商品">
|
||||
<div style="max-height: 200px; overflow-y: auto">
|
||||
<el-tag v-for="item in selectedRows" :key="item.id" style="margin: 2px">{{ item.goodsName }}</el-tag>
|
||||
</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="batchAuditModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="submitBatchAudit">提交审核</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal v-model="goodsGroupFlag" title="批量设置商品分组" width="420">
|
||||
<Form ref="goodsGroupForm" :model="goodsGroupForm" :rules="goodsGroupRule" :label-width="90">
|
||||
<FormItem label="商品分组" prop="groupId">
|
||||
<Select v-model="goodsGroupForm.groupId" clearable filterable style="width: 240px">
|
||||
<Option v-for="item in goodsGroupList" :value="item.id" :key="item.id">{{ item.groupName }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="goodsGroupFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="goodsGroupLoading" @click="submitSetGoodsGroup">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="batchAuditModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitBatchAudit">提交审核</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="goodsGroupFlag" title="批量设置商品分组" width="420px">
|
||||
<el-form ref="goodsGroupForm" :model="goodsGroupForm" :rules="goodsGroupRule" label-width="90px">
|
||||
<el-form-item label="商品分组" prop="groupId">
|
||||
<el-select v-model="goodsGroupForm.groupId" clearable filterable style="width: 240px">
|
||||
<el-option
|
||||
v-for="item in goodsGroupList"
|
||||
:key="item.id"
|
||||
:label="item.groupName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="goodsGroupFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="goodsGroupLoading" @click="submitSetGoodsGroup">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -261,11 +297,7 @@ import {
|
||||
getGoodsGroupByPage,
|
||||
addGoodsGroupItems
|
||||
} from "@/api/goods";
|
||||
import vueQr from "vue-qr";
|
||||
export default {
|
||||
components: {
|
||||
"vue-qr": vueQr,
|
||||
},
|
||||
name: "goods",
|
||||
data() {
|
||||
return {
|
||||
@@ -291,259 +323,10 @@ export default {
|
||||
auditModalVisible: false, // 审核弹框显示状态
|
||||
currentAuditGoods: null, // 当前审核的商品
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
{
|
||||
type: 'selection',
|
||||
width: 60,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: "商品ID",
|
||||
key: "id",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品图片",
|
||||
key: "original",
|
||||
width: 180,
|
||||
slot: "imageSlot",
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 180,
|
||||
slot: "goodsSlot",
|
||||
},
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "销量",
|
||||
key: "buyCount",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("span", params.row.buyCount || 0);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("span", params.row.quantity || 0);
|
||||
},
|
||||
},
|
||||
{
|
||||
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: 120,
|
||||
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: 120,
|
||||
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: 180,
|
||||
render: (h, params) => {
|
||||
if (params.row.authFlag == "TOBEAUDITED") {
|
||||
return h("Tag", { props: { color: "volcano" } }, "待审核");
|
||||
} else if (params.row.authFlag == "PASS") {
|
||||
return h("Tag", { props: { color: "green" } }, "通过");
|
||||
} else if (params.row.authFlag == "REFUSE") {
|
||||
return h("Tag", { props: { color: "red" } }, "拒绝");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
width: 180, // 使用minWidth替代width
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
// 如果是待审核状态,显示审核按钮
|
||||
if (params.row.authFlag === "TOBEAUDITED") {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.openAuditModal(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"审核"
|
||||
),
|
||||
h("span", {
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2"
|
||||
}
|
||||
}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
}
|
||||
// 原有的上架/下架逻辑
|
||||
else if (params.row.marketEnable == "DOWN") {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.upper(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"上架"
|
||||
),
|
||||
h("span", {
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2"
|
||||
}
|
||||
}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"下架"
|
||||
),
|
||||
h("span", {
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2"
|
||||
}
|
||||
}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
currentStatus: '',
|
||||
currentStatus: "ALL",
|
||||
goodsNumerData: {},
|
||||
goodsAuditForm: {
|
||||
// 商品编辑表单
|
||||
auth_flag: 1,
|
||||
},
|
||||
selectedRows: [], // 选中的行数据
|
||||
selectAll: false, // 全选状态
|
||||
batchAuditModalVisible: false, // 批量审核弹框显示状态
|
||||
@@ -565,7 +348,7 @@ export default {
|
||||
computed: {
|
||||
goodsStatusWithCount() {
|
||||
return [
|
||||
{title: '全部', value: ''},
|
||||
{title: '全部', value: 'ALL'},
|
||||
{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'},
|
||||
@@ -574,6 +357,33 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clearTableSelection() {
|
||||
this.$refs.table?.clearSelection?.();
|
||||
},
|
||||
onStatusTabClick(tab) {
|
||||
this.goodsStatusClick(tab.paneName);
|
||||
},
|
||||
salesModelText(v) {
|
||||
if (v === "RETAIL") return "零售";
|
||||
if (v === "WHOLESALE") return "批发";
|
||||
return "其他类型";
|
||||
},
|
||||
goodsTypeText(v) {
|
||||
if (v === "PHYSICAL_GOODS") return "实物商品";
|
||||
if (v === "VIRTUAL_GOODS") return "虚拟商品";
|
||||
return "电子卡券";
|
||||
},
|
||||
marketEnableText(v) {
|
||||
if (v === "DOWN") return "下架";
|
||||
if (v === "UPPER") return "上架";
|
||||
return "";
|
||||
},
|
||||
authFlagText(v) {
|
||||
if (v === "TOBEAUDITED") return "待审核";
|
||||
if (v === "PASS") return "通过";
|
||||
if (v === "REFUSE") return "拒绝";
|
||||
return "";
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
@@ -667,31 +477,23 @@ export default {
|
||||
|
||||
//查看商品详情
|
||||
showDetail(v) {
|
||||
let id = v.id;
|
||||
this.$options.filters.customRouterPush({
|
||||
this.$filters.customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: id },
|
||||
})
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
|
||||
// 商品状态筛选
|
||||
goodsStatusClick(item) {
|
||||
// 根据选择的状态设置搜索条件
|
||||
if (item === 0) {
|
||||
// 全部:清除状态筛选
|
||||
goodsStatusClick(name) {
|
||||
if (name === "ALL" || name === "" || name === undefined || name === null) {
|
||||
delete this.searchForm.goodsStatus;
|
||||
this.currentStatus = "ALL";
|
||||
} else {
|
||||
// 其他状态正常赋值
|
||||
this.searchForm.goodsStatus = item;
|
||||
this.searchForm.goodsStatus = name;
|
||||
this.currentStatus = name;
|
||||
}
|
||||
this.currentStatus = item;
|
||||
|
||||
// tab切换时清除选中内容
|
||||
this.selectedRows = [];
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.selectAll(false);
|
||||
}
|
||||
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
},
|
||||
examine(v, authFlag) {
|
||||
@@ -762,15 +564,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
// 选择框事件处理
|
||||
onSelect(selection, row) {
|
||||
// 单行选择时触发
|
||||
},
|
||||
|
||||
onSelectAll(selection) {
|
||||
// 全选时触发
|
||||
},
|
||||
|
||||
onSelectionChange(selection) {
|
||||
this.selectedRows = selection;
|
||||
},
|
||||
@@ -939,9 +732,7 @@ export default {
|
||||
this.goodsGroupFlag = false;
|
||||
this.selectedRows = [];
|
||||
this.selectAll = false;
|
||||
if (this.$refs.table && this.$refs.table.selectAll) {
|
||||
this.$refs.table.selectAll(false);
|
||||
}
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
} else if (res && res.message) {
|
||||
this.$Message.error(res.message);
|
||||
@@ -961,7 +752,7 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
// Tab组件样式
|
||||
.goods-tab {
|
||||
::v-deep .ivu-tabs-tab {
|
||||
:deep(.el-tabs__item) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +1,93 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
@keydown.enter.native="handleSearch"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品编号" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编号" prop="id">
|
||||
<el-input
|
||||
v-model="searchForm.id"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
>
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="scope">
|
||||
<div style="margin-top: 5px; height: 80px; display: flex">
|
||||
<div style="">
|
||||
<img
|
||||
:src="scope.row.original"
|
||||
style="height: 60px; margin-top: 3px; width: 60px"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div style="margin-left: 13px">
|
||||
<div class="div-zoom">
|
||||
<a>{{ scope.row.goodsName }}</a>
|
||||
<el-card>
|
||||
<el-table v-loading="loading" :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column label="商品名称" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" style="margin-top: 5px; height: 80px; display: flex; align-items: flex-start">
|
||||
<img
|
||||
v-if="row.original"
|
||||
:src="row.original"
|
||||
style="height: 60px; width: 60px; object-fit: cover; margin-top: 3px"
|
||||
alt=""
|
||||
/>
|
||||
<div style="margin-left: 13px">
|
||||
<div class="div-zoom">
|
||||
<a class="link-text">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="商品编号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="价格" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="authFlagTagType(row.authFlag)">{{ authFlagText(row.authFlag) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="examine(row, 1)">通过</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="examine(row, 2)">拒绝</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -81,214 +95,82 @@
|
||||
import { authGoods, getAuthGoodsListData } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "goods",
|
||||
components: {},
|
||||
name: "goodsApply",
|
||||
data() {
|
||||
return {
|
||||
id: "", //要操作的id
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
goodsAuditForm: {
|
||||
// 商品编辑表单
|
||||
auth_flag: 1,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 180,
|
||||
slot: "goodsSlot",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品编号",
|
||||
key: "id",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
minWidth: 130,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "审核状态",
|
||||
key: "authFlag",
|
||||
minWidth: 130,
|
||||
render: (h, params) => {
|
||||
if (params.row.authFlag == "TOBEAUDITED") {
|
||||
return h("div", [
|
||||
h("Badge", {
|
||||
props: {
|
||||
status: "error",
|
||||
text: "待审核",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
} else if (params.row.authFlag == "PASS") {
|
||||
return h("div", [
|
||||
h("Badge", {
|
||||
props: {
|
||||
status: "success",
|
||||
text: "审核通过",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
} else if (params.row.authFlag == "REFUSE") {
|
||||
return h("div", [
|
||||
h("Badge", {
|
||||
props: {
|
||||
status: "error",
|
||||
text: "审核拒绝",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.examine(params.row, 1);
|
||||
},
|
||||
},
|
||||
},
|
||||
"通过"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.examine(params.row, 2);
|
||||
},
|
||||
},
|
||||
},
|
||||
"拒绝"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
authFlagText(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "待审核",
|
||||
PASS: "审核通过",
|
||||
REFUSE: "审核拒绝",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
authFlagTagType(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "warning",
|
||||
PASS: "success",
|
||||
REFUSE: "danger",
|
||||
};
|
||||
return map[v] || "info";
|
||||
},
|
||||
init() {
|
||||
// 初始化数据
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
// 改变页码
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
// 改变每页数量
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
// 搜索
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
// 获取列表数据
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据
|
||||
this.searchForm.authFlag = 0;
|
||||
getAuthGoodsListData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
getAuthGoodsListData(this.searchForm)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
examine(v, authFlag) {
|
||||
// 审核商品
|
||||
let examine = "通过";
|
||||
this.goodsAuditForm.authFlag = "PASS";
|
||||
if (authFlag != 1) {
|
||||
examine = "拒绝";
|
||||
this.goodsAuditForm.authFlag = "REFUSE";
|
||||
}
|
||||
const examine = authFlag === 1 ? "通过" : "拒绝";
|
||||
this.goodsAuditForm.authFlag = authFlag === 1 ? "PASS" : "REFUSE";
|
||||
this.$Modal.confirm({
|
||||
title: "确认审核",
|
||||
content: "您确认要审核" + examine + " " + v.goodsName + " ?",
|
||||
content: `您确认要审核${examine} ${v.goodsName} ?`,
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
let formData = new FormData();
|
||||
formData.append('goodsIds', v.id);
|
||||
formData.append('authFlag', this.goodsAuditForm.authFlag);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("goodsIds", v.id);
|
||||
formData.append("authFlag", this.goodsAuditForm.authFlag);
|
||||
authGoods(formData).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -299,13 +181,11 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
//查看商品详情
|
||||
showDetail(v) {
|
||||
let id = v.id;
|
||||
this.$options.filters.customRouterPush({
|
||||
this.$filters.customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: id },
|
||||
})
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
@@ -313,3 +193,20 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
.div-zoom {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,247 +1,159 @@
|
||||
<template>
|
||||
<div>
|
||||
<Form :label-width="120">
|
||||
<Card>
|
||||
<el-form label-width="120px">
|
||||
<el-card>
|
||||
<div class="base-info-item">
|
||||
<h4>基本信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品分类">
|
||||
<el-form-item label="商品分类">
|
||||
<span v-for="(item, index) in goods.categoryName" :key="index">
|
||||
{{ item }}
|
||||
<i v-if="index !== goods.categoryName.length - 1">></i>
|
||||
</span>
|
||||
</FormItem>
|
||||
<FormItem label="商品名称">
|
||||
{{ goods.goodsName }}
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="商品卖点">
|
||||
{{ goods.sellingPoint }}
|
||||
</FormItem>
|
||||
<FormItem label="商品参数">
|
||||
<div v-if="goods.goodsParamsDTOList && goods.goodsParamsDTOList.length" v-for="(item,index) in goods.goodsParamsDTOList" :key="index">
|
||||
<div style="margin-bottom: 10px; display: flex; align-items: center;" >
|
||||
{{ item.groupName }} : <tag v-for="(child,i) in item.goodsParamsItemDTOList" :key="i">
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称">{{ goods.goodsName }}</el-form-item>
|
||||
<el-form-item label="商品卖点">{{ goods.sellingPoint }}</el-form-item>
|
||||
<el-form-item label="商品参数">
|
||||
<div
|
||||
v-if="goods.goodsParamsDTOList && goods.goodsParamsDTOList.length"
|
||||
v-for="(item, index) in goods.goodsParamsDTOList"
|
||||
:key="index"
|
||||
style="margin-bottom: 10px; display: flex; align-items: center"
|
||||
>
|
||||
{{ item.groupName }} :
|
||||
<el-tag v-for="(child, i) in item.goodsParamsItemDTOList" :key="i" style="margin-left: 4px">
|
||||
{{ child.paramName }} - {{ child.paramValue }}
|
||||
</tag>
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>商品交易信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="计量单位"> {{ goods.goodsUnit }}</FormItem>
|
||||
<FormItem label="销售模式">
|
||||
<el-form-item label="计量单位">{{ goods.goodsUnit }}</el-form-item>
|
||||
<el-form-item label="销售模式">
|
||||
{{ goods.salesModel === "RETAIL" ? "零售型" : "批发型" }}
|
||||
</FormItem>
|
||||
<FormItem label="销售规则" v-if="goods.salesModel !== 'RETAIL'">
|
||||
<Table
|
||||
border
|
||||
:columns="wholesalePreviewColumns"
|
||||
:data="wholesaleData"
|
||||
>
|
||||
</Table>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="goods.salesModel !== 'RETAIL'" label="销售规则">
|
||||
<el-table border :data="wholesaleData" style="width: 100%">
|
||||
<el-table-column label="销售规则" width="300">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">
|
||||
当商品购买数量 ≥{{ row.num }} 时,售价为 ¥{{ row.price }} /{{ goods.goodsUnit }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>商品规格及图片</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品编号"> {{ goods.id }}</FormItem>
|
||||
<FormItem label="商品价格">
|
||||
<priceColorScheme :value="goods.price" :color="$mainColor"></priceColorScheme>
|
||||
|
||||
</FormItem>
|
||||
<FormItem label="商品图片">
|
||||
<el-form-item label="商品编号">{{ goods.id }}</el-form-item>
|
||||
<el-form-item label="商品价格">
|
||||
<priceColorScheme :value="goods.price" :color="$mainColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片">
|
||||
<div
|
||||
class="demo-upload-list"
|
||||
v-for="(item, __index) in goods.goodsGalleryList"
|
||||
:key="__index"
|
||||
class="demo-upload-list"
|
||||
>
|
||||
<img :src="item" />
|
||||
<div class="demo-upload-list-cover">
|
||||
<Icon
|
||||
type="ios-eye-outline"
|
||||
@click.native="handleViewGoodsPicture(item)"
|
||||
></Icon>
|
||||
<el-icon class="preview-icon" @click="handleViewGoodsPicture(item)"><View /></el-icon>
|
||||
</div>
|
||||
<Modal title="View Image" v-model="goodsPictureVisible">
|
||||
<img
|
||||
:src="previewGoodsPicture"
|
||||
v-if="goodsPictureVisible"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="商品视频">
|
||||
<video
|
||||
v-if="goods.goodsVideo"
|
||||
controls
|
||||
class="player"
|
||||
:src="goods.goodsVideo"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="商品规格">
|
||||
<Table :columns="skuColumn" :data="skuData">
|
||||
<template slot="showImage" slot-scope="scope">
|
||||
<div style="margin-top: 5px; display: flex">
|
||||
<div>
|
||||
<el-dialog v-model="goodsPictureVisible" title="View Image" width="600px">
|
||||
<img v-if="goodsPictureVisible" :src="previewGoodsPicture" style="width: 100%" />
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品视频">
|
||||
<video v-if="goods.goodsVideo" controls class="player" :src="goods.goodsVideo" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品规格">
|
||||
<el-table :data="skuData" style="width: 100%">
|
||||
<el-table-column prop="specs" label="规格" />
|
||||
<el-table-column prop="sn" label="编号" />
|
||||
<el-table-column prop="weight" label="重量(kg)" />
|
||||
<el-table-column
|
||||
v-for="(item, index) in wholesaleData"
|
||||
:key="'wp' + index"
|
||||
:label="'购买量 ≥ ' + item.num"
|
||||
>
|
||||
<template #default>
|
||||
<el-input v-if="wholesaleData[index]" v-model="wholesaleData[index].price" disabled>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="goods.salesModel !== 'WHOLESALE'" label="价格">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.price" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="goods.salesModel !== 'WHOLESALE'" prop="quantity" label="库存" />
|
||||
<el-table-column label="图片">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" style="margin-top: 5px; display: flex">
|
||||
<img
|
||||
v-for="(item,index) in scope.row.image"
|
||||
v-for="(item, index) in row.image"
|
||||
:key="index"
|
||||
:src="item"
|
||||
style="height: 60px; margin:10px; width: 60px"
|
||||
style="height: 60px; margin: 10px; width: 60px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="wholePrice0">
|
||||
<Input
|
||||
v-if="wholesaleData[0]"
|
||||
clearable
|
||||
disabled
|
||||
v-model="wholesaleData[0].price"
|
||||
>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="wholePrice1">
|
||||
<Input
|
||||
v-if="wholesaleData[1]"
|
||||
clearable
|
||||
disabled
|
||||
v-model="wholesaleData[1].price"
|
||||
>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="wholePrice2">
|
||||
<Input
|
||||
v-if="wholesaleData[2]"
|
||||
clearable
|
||||
disabled
|
||||
v-model="wholesaleData[2].price"
|
||||
>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
</Table>
|
||||
</FormItem>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>商品详情描述</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品描述">
|
||||
<el-form-item label="商品描述">
|
||||
<div v-html="goods.intro"></div>
|
||||
</FormItem>
|
||||
<FormItem label="移动端描述">
|
||||
</el-form-item>
|
||||
<el-form-item label="移动端描述">
|
||||
<div v-html="goods.mobileIntro"></div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Form>
|
||||
</el-card>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { View } from "@element-plus/icons-vue";
|
||||
import { getGoodsDetail } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "goodsDetail",
|
||||
components: { View },
|
||||
data() {
|
||||
return {
|
||||
goods: {}, // 商品信息
|
||||
previewGoodsPicture: "", // 预览图片
|
||||
goodsPictureVisible: false, // 预览图片模态框
|
||||
wholesalePreviewColumns: [
|
||||
{
|
||||
title: "销售规则",
|
||||
width: 300,
|
||||
render: (h, params) => {
|
||||
let guide =
|
||||
"当商品购买数量 ≥" +
|
||||
params.row.num +
|
||||
" 时,售价为 ¥" +
|
||||
params.row.price +
|
||||
" /" +
|
||||
this.goods.goodsUnit;
|
||||
return h("div", guide);
|
||||
},
|
||||
},
|
||||
],
|
||||
goods: {},
|
||||
previewGoodsPicture: "",
|
||||
goodsPictureVisible: false,
|
||||
wholesaleData: [],
|
||||
skuColumn: [
|
||||
// 规格表头
|
||||
{
|
||||
title: "规格",
|
||||
key: "specs",
|
||||
},
|
||||
{
|
||||
title: "编号",
|
||||
key: "sn",
|
||||
},
|
||||
{
|
||||
title: "重量(kg)",
|
||||
key: "weight",
|
||||
},
|
||||
],
|
||||
skuData: [], // sku数据
|
||||
skuData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.initGoods(this.$route.query.id);
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据,获取商品详情
|
||||
initGoods(id) {
|
||||
getGoodsDetail(id).then((res) => {
|
||||
this.goods = res.result;
|
||||
let that = this;
|
||||
res.result.skuList.forEach(function (sku, index, array) {
|
||||
that.skuData.push({
|
||||
specs: sku.goodsName,
|
||||
sn: sku.sn,
|
||||
weight: sku.weight,
|
||||
cost: sku.cost,
|
||||
price:sku.price,
|
||||
image: sku.goodsGalleryList,
|
||||
quantity:sku.quantity
|
||||
});
|
||||
});
|
||||
if (res.result.salesModel === "WHOLESALE" && res.result.wholesaleList) {
|
||||
res.result.wholesaleList.forEach((item, index) => {
|
||||
this.skuColumn.push({
|
||||
title: "购买量 ≥ " + item.num,
|
||||
slot: "wholePrice" + index,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.skuColumn.push(
|
||||
// {
|
||||
// title: "成本",
|
||||
// key: "cost",
|
||||
// render: (h, params) => {
|
||||
// console.log(params)
|
||||
// return h("priceColorScheme", {props:{value:params.row.cost,color:this.$mainColor}} );
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
}
|
||||
);
|
||||
}
|
||||
this.skuColumn.push({
|
||||
title: "图片",
|
||||
slot: "showImage",
|
||||
});
|
||||
this.wholesaleData = res.result.wholesaleList;
|
||||
this.skuData = res.result.skuList.map((sku) => ({
|
||||
specs: sku.goodsName,
|
||||
sn: sku.sn,
|
||||
weight: sku.weight,
|
||||
cost: sku.cost,
|
||||
price: sku.price,
|
||||
image: sku.goodsGalleryList,
|
||||
quantity: sku.quantity,
|
||||
}));
|
||||
this.wholesaleData = res.result.wholesaleList || [];
|
||||
});
|
||||
},
|
||||
// 预览商品图片
|
||||
handleViewGoodsPicture(url) {
|
||||
this.previewGoodsPicture = url;
|
||||
this.goodsPictureVisible = true;
|
||||
@@ -251,7 +163,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" soped>
|
||||
/*平铺*/
|
||||
div.base-info-item {
|
||||
h4 {
|
||||
margin-bottom: 10px;
|
||||
@@ -300,13 +211,10 @@ div.base-info-item {
|
||||
.demo-upload-list:hover .demo-upload-list-cover {
|
||||
display: block;
|
||||
}
|
||||
.demo-upload-list-cover i {
|
||||
.preview-icon {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.ivu-table table {
|
||||
width: 100% !important;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,74 +1,148 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" @submit.native.prevent @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70"
|
||||
class="search-form">
|
||||
<Form-item label="品牌名称">
|
||||
<Input type="text" v-model="searchForm.name" placeholder="请输入品牌名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="add" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable="false" :width="500">
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="品牌名称" prop="name">
|
||||
<Input v-model="form.name" clearable style="width: 100%"/>
|
||||
</FormItem>
|
||||
<FormItem label="品牌图标" prop="logo">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="品牌名称">
|
||||
<el-input
|
||||
v-model="searchForm.name"
|
||||
placeholder="请输入品牌名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
|
||||
<el-table ref="table" v-loading="loading" border :data="data" style="width: 100%">
|
||||
<el-table-column prop="name" label="品牌名称" width="200" />
|
||||
<el-table-column label="品牌图标" align="left" >
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="row"
|
||||
:src="row.logo || ''"
|
||||
alt="加载图片失败"
|
||||
style="cursor: pointer; width: 80px; height: 60px; margin: 10px 0; object-fit: contain"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="left" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
:model-value="row.deleteFlag == 0"
|
||||
inline-prompt
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
@change="(val) => handleStatusSwitchChange(row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="170" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="230" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="openCategoryModal(row)">关联分类</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="delBrand(row.id)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="品牌名称" prop="name">
|
||||
<el-input v-model="form.name" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌图标" prop="logo">
|
||||
<div style="display: flex; align-items: center; gap: 12px">
|
||||
<img
|
||||
:src="form.logo || defaultPic"
|
||||
alt="品牌图标"
|
||||
style="width: 80px; height: 60px; object-fit: contain; border: 1px solid #dcdee2; border-radius: 4px; background: #fff;"
|
||||
style="width: 80px; height: 60px; object-fit: contain; border: 1px solid #dcdee2; border-radius: 4px; background: #fff"
|
||||
/>
|
||||
<Button type="text" @click="openLogoPicker">修改</Button>
|
||||
<el-button type="primary" link @click="openLogoPicker">修改</el-button>
|
||||
</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" :show-close="true">
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
@callback="callbackSelected"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<Modal
|
||||
:title="categoryModalTitle"
|
||||
<el-dialog
|
||||
v-model="categoryModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="700"
|
||||
:title="categoryModalTitle"
|
||||
width="700px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div style="position: relative; max-height: 520px; overflow: auto;">
|
||||
<Spin size="large" fix v-if="categoryTreeLoading"></Spin>
|
||||
<Tree
|
||||
<div v-loading="categoryTreeLoading" style="position: relative; max-height: 520px; overflow: auto">
|
||||
<el-tree
|
||||
ref="categoryTree"
|
||||
:key="categoryTreeKey"
|
||||
:data="categoryTreeData"
|
||||
:props="{ label: 'title', children: 'children' }"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
@on-check-change="onCategoryTreeCheckChange"
|
||||
></Tree>
|
||||
default-expand-all
|
||||
:default-checked-keys="selectedCategoryIds"
|
||||
@check="onCategoryTreeCheckChange"
|
||||
/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="categoryModalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="categorySubmitLoading" @click="submitBrandCategory"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="categoryModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="categorySubmitLoading" @click="submitBrandCategory">
|
||||
提交
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -84,22 +158,21 @@ import {
|
||||
saveBrandCategory,
|
||||
} from "@/api/goods";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
|
||||
import {regular} from "@/utils";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "brand",
|
||||
components: {
|
||||
ossManage
|
||||
ossManage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultPic: require("@/assets/default.png"),
|
||||
loading: true, // 表单加载状态
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
picModelFlag: false, // 图片选择器
|
||||
loading: true,
|
||||
modalType: 0,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
picModelFlag: false,
|
||||
categoryModalVisible: false,
|
||||
categoryModalTitle: "关联分类",
|
||||
categoryTreeLoading: false,
|
||||
@@ -109,173 +182,23 @@ export default {
|
||||
currentBrandId: "",
|
||||
selectedCategoryIds: [],
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
name: "",
|
||||
logo: "",
|
||||
deleteFlag: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
name: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
logo: [
|
||||
regular.REQUIRED,
|
||||
regular.URL200
|
||||
],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
logo: [regular.REQUIRED, regular.URL200],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
{
|
||||
title: "品牌名称",
|
||||
key: "name",
|
||||
width: 200,
|
||||
resizable: true,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "品牌图标",
|
||||
key: "logo",
|
||||
align: "left",
|
||||
render: (h, params) => {
|
||||
return h("img", {
|
||||
attrs: {
|
||||
src: params.row.logo || '',
|
||||
alt: "加载图片失败",
|
||||
},
|
||||
style: {
|
||||
cursor: "pointer",
|
||||
width: "80px",
|
||||
height: "60px",
|
||||
margin: "10px 0",
|
||||
"object-fit": "contain",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "deleteFlag",
|
||||
align: "left",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"i-switch",
|
||||
{
|
||||
props: {
|
||||
value: params.row.deleteFlag == 0,
|
||||
size: "large",
|
||||
},
|
||||
on: {
|
||||
"on-change": (checked) => {
|
||||
this.handleStatusSwitchChange(params.row, checked);
|
||||
},
|
||||
},
|
||||
},
|
||||
[
|
||||
h("span", { slot: "open" }, "启用"),
|
||||
h("span", { slot: "close" }, "禁用"),
|
||||
]
|
||||
);
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
label: "启用",
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: "禁用",
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
filterMultiple: false,
|
||||
filterMethod(value, row) {
|
||||
if (value == 0) {
|
||||
return row.deleteFlag == 0;
|
||||
} else if (value == 1) {
|
||||
return row.deleteFlag == 1;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 210,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.openCategoryModal(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"关联分类"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.delBrand(params.row.id);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
submitLoading: false,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -287,18 +210,13 @@ export default {
|
||||
this.picModelFlag = false;
|
||||
this.form.logo = val.url;
|
||||
},
|
||||
buildCategoryTreeNodes(list, selectedSet) {
|
||||
buildCategoryTreeNodes(list) {
|
||||
if (!Array.isArray(list) || list.length === 0) return [];
|
||||
return list.map((item) => {
|
||||
const children = this.buildCategoryTreeNodes(item.children || [], selectedSet);
|
||||
return {
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
expand: true,
|
||||
checked: selectedSet.has(item.id),
|
||||
children,
|
||||
};
|
||||
});
|
||||
return list.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
children: this.buildCategoryTreeNodes(item.children || []),
|
||||
}));
|
||||
},
|
||||
async openCategoryModal(row) {
|
||||
this.currentBrandId = row.id;
|
||||
@@ -319,22 +237,16 @@ export default {
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
this.selectedCategoryIds = selectedIds;
|
||||
const selectedSet = new Set(selectedIds);
|
||||
this.categoryTreeData = treeRes && treeRes.success
|
||||
? this.buildCategoryTreeNodes(treeRes.result || [], selectedSet)
|
||||
: [];
|
||||
this.categoryTreeData =
|
||||
treeRes && treeRes.success
|
||||
? this.buildCategoryTreeNodes(treeRes.result || [])
|
||||
: [];
|
||||
} finally {
|
||||
this.categoryTreeLoading = false;
|
||||
}
|
||||
},
|
||||
onCategoryTreeCheckChange(checkedNodes) {
|
||||
if (!Array.isArray(checkedNodes)) {
|
||||
this.selectedCategoryIds = [];
|
||||
return;
|
||||
}
|
||||
this.selectedCategoryIds = checkedNodes
|
||||
.map((node) => node && node.id)
|
||||
.filter(Boolean);
|
||||
onCategoryTreeCheckChange(_data, checkedInfo) {
|
||||
this.selectedCategoryIds = checkedInfo?.checkedKeys || [];
|
||||
},
|
||||
submitBrandCategory() {
|
||||
if (!this.currentBrandId) return;
|
||||
@@ -342,16 +254,17 @@ export default {
|
||||
saveBrandCategory(
|
||||
this.currentBrandId,
|
||||
(this.selectedCategoryIds || []).map((id) => String(id))
|
||||
).then((res) => {
|
||||
this.categorySubmitLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.categoryModalVisible = false;
|
||||
return;
|
||||
}
|
||||
}).catch(() => {
|
||||
this.categorySubmitLoading = false;
|
||||
});
|
||||
)
|
||||
.then((res) => {
|
||||
this.categorySubmitLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.categoryModalVisible = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.categorySubmitLoading = false;
|
||||
});
|
||||
},
|
||||
handleStatusSwitchChange(row, checked) {
|
||||
const disable = !checked;
|
||||
@@ -373,36 +286,29 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 删除品牌
|
||||
async delBrand(id) {
|
||||
let res = await delBrand(id);
|
||||
|
||||
const res = await delBrand(id);
|
||||
if (res.success) {
|
||||
this.$Message.success("品牌删除成功!");
|
||||
this.getDataList();
|
||||
}
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getManagerBrandPage(this.searchForm).then((res) => {
|
||||
@@ -413,13 +319,11 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 提交表单
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.form.id;
|
||||
addBrand(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -430,7 +334,6 @@ export default {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
updateBrand(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
@@ -443,28 +346,24 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加
|
||||
add() {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加";
|
||||
this.$refs.form.resetFields();
|
||||
this.$refs.form?.resetFields();
|
||||
delete this.form.id;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
|
||||
// 编辑
|
||||
edit(v) {
|
||||
this.modalType = 1;
|
||||
this.modalTitle = "编辑";
|
||||
this.$refs.form.resetFields();
|
||||
// 转换null为""
|
||||
for (let attr in v) {
|
||||
this.$refs.form?.resetFields();
|
||||
for (const attr in v) {
|
||||
if (v[attr] === null) {
|
||||
v[attr] = "";
|
||||
}
|
||||
}
|
||||
let str = JSON.stringify(v);
|
||||
let data = JSON.parse(str);
|
||||
const str = JSON.stringify(v);
|
||||
const data = JSON.parse(str);
|
||||
this.form = data;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
@@ -474,3 +373,6 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
@@ -1,165 +1,163 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<el-card>
|
||||
<div class="mb_10">
|
||||
<Button @click="addParent" icon="md-add">添加一级分类</Button>
|
||||
<el-button type="primary" @click="addParent">添加一级分类</el-button>
|
||||
</div>
|
||||
<Table
|
||||
update-show-children
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
class="table"
|
||||
:load-data="handleLoadData"
|
||||
row-key="id"
|
||||
:loading="loading"
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
row-key="id"
|
||||
border
|
||||
:tree-props="{ children: 'children' }"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template slot="action" slot-scope="scope">
|
||||
<div class="ops">
|
||||
<a class="ops-link" @click="edit(scope.row)">编辑</a>
|
||||
<a class="ops-link" @click="remove(scope.row)">删除</a>
|
||||
<a v-show="scope.row.level != 2" class="ops-link" @click="addChildren(scope.row)">添加子分类</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template slot="commissionRate" slot-scope="scope">
|
||||
<priceColorScheme v-if="scope.row.commissionRate > 0" unit="" :color="$mainColor" :value="scope.row.commissionRate">%</priceColorScheme>
|
||||
<priceColorScheme v-else :value="scope.row.commissionRate" unit="" >%</priceColorScheme>
|
||||
<!-- {{ scope.row.commissionRate }}% -->
|
||||
</template>
|
||||
|
||||
<template slot="deleteFlag" slot-scope="{ row }">
|
||||
<i-switch
|
||||
size="large"
|
||||
v-model="row.deleteFlag"
|
||||
:true-value="false"
|
||||
:false-value="true"
|
||||
:loading="row._statusLoading"
|
||||
@on-change="onStatusSwitchChange(row, $event)"
|
||||
>
|
||||
<span slot="open">开启</span>
|
||||
<span slot="close">关闭</span>
|
||||
</i-switch>
|
||||
</template>
|
||||
</Table>
|
||||
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="formAdd" :label-width="100" :rules="formValidate">
|
||||
<div v-if="showParent">
|
||||
<FormItem label="上级分类" prop="parentId">
|
||||
{{ parentTitle }}
|
||||
<Input
|
||||
v-model="formAdd.parentId"
|
||||
clearable
|
||||
style="width: 100%; display: none"
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
<FormItem label="层级" prop="level" style="display: none">
|
||||
<Input v-model="formAdd.level" clearable style="width: 100%" />
|
||||
</FormItem>
|
||||
<FormItem label="分类名称" prop="name">
|
||||
<Input v-model="formAdd.name" clearable style="width: 100%" />
|
||||
</FormItem>
|
||||
<FormItem label="分类图标" prop="image" v-if="formAdd.level !== 1">
|
||||
<upload-pic-input
|
||||
v-model="formAdd.image"
|
||||
style="width: 100%"
|
||||
></upload-pic-input>
|
||||
</FormItem>
|
||||
<FormItem label="排序值" prop="sortOrder" style="width: 345px">
|
||||
<InputNumber v-model="formAdd.sortOrder"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="佣金比例(%)" prop="commissionRate" style="width: 345px">
|
||||
<InputNumber :max="100" :min="0" v-model="formAdd.commissionRate"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="是否启用" prop="deleteFlag">
|
||||
<i-switch
|
||||
size="large"
|
||||
v-model="formAdd.deleteFlag"
|
||||
:true-value="false"
|
||||
:false-value="true"
|
||||
<el-table-column prop="name" label="分类名称" min-width="200" />
|
||||
<el-table-column label="状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.deleteFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
inline-prompt
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
:loading="!!row._statusLoading"
|
||||
@change="(val) => onStatusSwitchChange(row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="佣金" width="120">
|
||||
<template #default="{ row }">
|
||||
<span
|
||||
v-if="row"
|
||||
:style="row.commissionRate > 0 ? { color: $mainColor } : {}"
|
||||
>
|
||||
<span slot="open">启用</span>
|
||||
<span slot="close">禁用</span>
|
||||
</i-switch>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="Submit">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
{{ row.commissionRate }}%
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
<template v-if="row.level != 2">
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="addChildren(row)">添加子分类</a>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Modal
|
||||
:title="modalBrandTitle"
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="formAdd" label-width="100px" :rules="formValidate">
|
||||
<el-form-item v-if="showParent" label="上级分类" prop="parentId">
|
||||
{{ parentTitle }}
|
||||
<el-input v-model="formAdd.parentId" style="display: none" />
|
||||
</el-form-item>
|
||||
<el-form-item label="层级" prop="level" style="display: none">
|
||||
<el-input v-model="formAdd.level" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="formAdd.name" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formAdd.level !== 1" label="分类图标" prop="image">
|
||||
<upload-pic-input v-model="formAdd.image" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序值" prop="sortOrder">
|
||||
<el-input-number v-model="formAdd.sortOrder" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="佣金比例(%)" prop="commissionRate">
|
||||
<el-input-number v-model="formAdd.commissionRate" :min="0" :max="100" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用" prop="deleteFlag">
|
||||
<el-switch
|
||||
v-model="formAdd.deleteFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
inline-prompt
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="Submit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalBrandVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
:title="modalBrandTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<Form ref="brandForm" :model="brandForm" :label-width="100">
|
||||
<Select v-model="brandForm.categoryBrands" filterable multiple>
|
||||
<Option v-for="item in brandWay" :value="item.id" :key="item.id">{{
|
||||
item.name
|
||||
}}</Option>
|
||||
</Select>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalBrandVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="saveCategoryBrand"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-form ref="brandForm" :model="brandForm" label-width="100px">
|
||||
<el-select v-model="brandForm.categoryBrands" filterable multiple style="width: 100%">
|
||||
<el-option v-for="item in brandWay" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalBrandVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="saveCategoryBrand">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal
|
||||
:title="modalSpecTitle"
|
||||
<el-dialog
|
||||
v-model="modalSpecVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
:title="modalSpecTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<Form ref="specForm" :model="specForm" :label-width="100">
|
||||
<Select v-model="specForm.categorySpecs" multiple>
|
||||
<Option
|
||||
<el-form ref="specForm" :model="specForm" label-width="100px">
|
||||
<el-select v-model="specForm.categorySpecs" multiple style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in specifications"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
:label="item.specName"
|
||||
>
|
||||
</Option>
|
||||
</Select>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalSpecVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="saveCategorySpec"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
</Card>
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalSpecVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="saveCategorySpec">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
delCategory,
|
||||
disableCategory,
|
||||
getBrandListData,
|
||||
getCategoryBrandListData,
|
||||
getCategorySpecListData,
|
||||
getCategoryTree,
|
||||
getSpecificationList,
|
||||
insertCategory,
|
||||
saveCategoryBrand,
|
||||
saveCategorySpec,
|
||||
updateCategory,
|
||||
delCategory,
|
||||
disableCategory,
|
||||
getBrandListData,
|
||||
getCategoryBrandListData,
|
||||
getCategorySpecListData,
|
||||
getCategoryTree,
|
||||
getSpecificationList,
|
||||
insertCategory,
|
||||
saveCategoryBrand,
|
||||
saveCategorySpec,
|
||||
updateCategory,
|
||||
} from "@/api/goods";
|
||||
|
||||
import uploadPicInput from "@/components/lili/upload-pic-input";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "goods-category",
|
||||
components: {
|
||||
@@ -167,69 +165,44 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
recordLevel:[], // 记录当前层级
|
||||
submitLoading: false, //加载状态
|
||||
categoryList: [], // 分类列表
|
||||
loading: false, // 加载状态
|
||||
brands: [], //品牌集合
|
||||
specifications: [], //规格集合
|
||||
categoryId: "", // 分类id
|
||||
categorySpecs: [], //已经选择的规格
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalBrandVisible: false, //品牌关联编辑显示
|
||||
modalSpecVisible: false, //品牌关联编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
showParent: false, // 是否展示上级菜单
|
||||
parentTitle: "", // 父级菜单名称
|
||||
modalBrandTitle: "", // 品牌弹窗标题
|
||||
modalSpecTitle: "", // 规格弹窗标题
|
||||
submitLoading: false,
|
||||
categoryList: [],
|
||||
loading: false,
|
||||
brands: [],
|
||||
specifications: [],
|
||||
categoryId: "",
|
||||
categorySpecs: [],
|
||||
modalType: 0,
|
||||
modalVisible: false,
|
||||
modalBrandVisible: false,
|
||||
modalSpecVisible: false,
|
||||
modalTitle: "",
|
||||
showParent: false,
|
||||
parentTitle: "",
|
||||
modalBrandTitle: "",
|
||||
modalSpecTitle: "",
|
||||
formAdd: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
parentId: "",
|
||||
name: "",
|
||||
image: "",
|
||||
sortOrder: 0,
|
||||
deleteFlag: 0,
|
||||
deleteFlag: false,
|
||||
commissionRate: 0,
|
||||
level: 0,
|
||||
},
|
||||
brandForm: {
|
||||
categoryBrands: [],
|
||||
},
|
||||
brandWay: "", //请求绑定品牌的信息
|
||||
specForm: {}, // 规格数据
|
||||
// 表单验证规则
|
||||
brandWay: [],
|
||||
specForm: {
|
||||
categorySpecs: [],
|
||||
},
|
||||
formValidate: {
|
||||
commissionRate: [regular.REQUIRED, regular.INTEGER],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
sortOrder: [regular.REQUIRED, regular.INTEGER],
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "分类名称",
|
||||
key: "name",
|
||||
tree: true,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
slot: "deleteFlag",
|
||||
},
|
||||
{
|
||||
title: "佣金",
|
||||
key: "commissionRate",
|
||||
|
||||
slot: "commissionRate",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
|
||||
slot: "action",
|
||||
},
|
||||
],
|
||||
tableData: [], // 表格数据
|
||||
checkedCategoryChildren: "", //选中的分类子级
|
||||
tableData: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -250,48 +223,38 @@ export default {
|
||||
const isClosing = nextDeleteFlag === true;
|
||||
this.$Modal.confirm({
|
||||
title: isClosing ? "确认关闭" : "确认开启",
|
||||
content:
|
||||
"您是否要" +
|
||||
(isClosing ? "关闭" : "开启") +
|
||||
"当前分类 " +
|
||||
row.name +
|
||||
" 及其子分类?",
|
||||
content: `您是否要${isClosing ? "关闭" : "开启"}当前分类 ${row.name} 及其子分类?`,
|
||||
loading: true,
|
||||
okText: "是",
|
||||
cancelText: "否",
|
||||
onOk: () => {
|
||||
this.$set(row, "_statusLoading", true);
|
||||
disableCategory(row.id, { enableOperations: isClosing ? true : 0 }).then(
|
||||
(res) => {
|
||||
this.$Modal.remove();
|
||||
this.$set(row, "_statusLoading", false);
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
return;
|
||||
}
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
row._statusLoading = true;
|
||||
disableCategory(row.id, { enableOperations: isClosing ? true : 0 }).then((res) => {
|
||||
this.$Modal.remove();
|
||||
row._statusLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList();
|
||||
return;
|
||||
}
|
||||
);
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
},
|
||||
});
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
this.getBrandList();
|
||||
this.getSpecList();
|
||||
},
|
||||
//获取所有品牌
|
||||
getBrandList() {
|
||||
getBrandListData().then((res) => {
|
||||
this.brandWay = res;
|
||||
});
|
||||
},
|
||||
//获取所有规格
|
||||
getSpecList() {
|
||||
getSpecificationList().then((res) => {
|
||||
if (res.length != 0) {
|
||||
@@ -299,7 +262,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//弹出品牌关联框
|
||||
brandOperation(v) {
|
||||
getCategoryBrandListData(v.id).then((res) => {
|
||||
this.categoryId = v.id;
|
||||
@@ -308,7 +270,6 @@ export default {
|
||||
this.modalBrandVisible = true;
|
||||
});
|
||||
},
|
||||
//弹出规格关联框
|
||||
specOperation(v) {
|
||||
getCategorySpecListData(v.id).then((res) => {
|
||||
this.categoryId = v.id;
|
||||
@@ -317,7 +278,6 @@ export default {
|
||||
this.modalSpecVisible = true;
|
||||
});
|
||||
},
|
||||
//保存分类规格绑定
|
||||
saveCategorySpec() {
|
||||
saveCategorySpec(this.categoryId, this.specForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -327,7 +287,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//保存分类品牌绑定
|
||||
saveCategoryBrand() {
|
||||
saveCategoryBrand(this.categoryId, this.brandForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -337,19 +296,17 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加子分类
|
||||
addChildren(v) {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加子分类";
|
||||
this.parentTitle = v.name;
|
||||
this.formAdd.level = eval(v.level + "+1");
|
||||
this.formAdd.level = Number(v.level) + 1;
|
||||
this.formAdd.commissionRate = v.commissionRate;
|
||||
this.showParent = true;
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = v.id;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 编辑分类
|
||||
edit(v) {
|
||||
this.modalType = 1;
|
||||
this.modalTitle = "编辑";
|
||||
@@ -364,57 +321,51 @@ export default {
|
||||
this.showParent = false;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 添加一级分类
|
||||
addParent() {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加一级分类";
|
||||
this.parentTitle = "顶级分类";
|
||||
this.showParent = true;
|
||||
this.$refs.form.resetFields();
|
||||
this.$refs.form?.resetFields();
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = 0;
|
||||
this.formAdd.level = 0;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 提交
|
||||
Submit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.formAdd.id;
|
||||
insertCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
updateCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!valid) return;
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
delete this.formAdd.id;
|
||||
insertCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除分类
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
delCategory(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -425,80 +376,22 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 异步手动加载分类名称
|
||||
handleLoadData(item, callback) {
|
||||
this.recordLevel[item.level] = item.id;
|
||||
if (item.level == 0) {
|
||||
let categoryList = JSON.parse(JSON.stringify(this.categoryList));
|
||||
categoryList.forEach((val) => {
|
||||
if (val.id == item.id) {
|
||||
val.children.map((child) => {
|
||||
child._loading = false;
|
||||
child.children = [];
|
||||
});
|
||||
this.normalizeCategoryTree(val.children);
|
||||
// 模拟加载
|
||||
setTimeout(() => {
|
||||
callback(val.children);
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.deepCategoryChildren(item.id, this.categoryList);
|
||||
this.normalizeCategoryTree(this.checkedCategoryChildren);
|
||||
setTimeout(() => {
|
||||
callback(this.checkedCategoryChildren);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
|
||||
// 通过递归children来实现手动加载数据
|
||||
deepCategoryChildren(id, list) {
|
||||
if (id != "0" && list.length != 0) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i];
|
||||
if (item.id == id) {
|
||||
this.checkedCategoryChildren = item.children;
|
||||
return;
|
||||
} else {
|
||||
this.deepCategoryChildren(id, item.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取分类数据
|
||||
getAllList() {
|
||||
this.loading = true;
|
||||
getCategoryTree().then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
localStorage.setItem("category", JSON.stringify(res.result));
|
||||
this.normalizeCategoryTree(res.result);
|
||||
this.categoryList = JSON.parse(JSON.stringify(res.result));
|
||||
this.tableData = res.result.map((item) => {
|
||||
if(this.recordLevel[0] && item.id === this.recordLevel[0]) {
|
||||
item._showChildren = true
|
||||
// 继续判断第二层
|
||||
if(this.recordLevel[1] && item.children){
|
||||
item.children.map((child)=>{
|
||||
if(this.recordLevel[1] && child.id === this.recordLevel[1]){
|
||||
child._showChildren = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}else{
|
||||
if (item.children.length !== 0) {
|
||||
item.children = [];
|
||||
item._loading = false;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
});
|
||||
getCategoryTree()
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
localStorage.setItem("category", JSON.stringify(res.result));
|
||||
this.normalizeCategoryTree(res.result);
|
||||
this.categoryList = JSON.parse(JSON.stringify(res.result));
|
||||
this.tableData = JSON.parse(JSON.stringify(res.result));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 启用分类
|
||||
enable(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认启用",
|
||||
@@ -511,16 +404,15 @@ export default {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
},
|
||||
});
|
||||
},
|
||||
// 禁用分类
|
||||
disable(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认禁用",
|
||||
@@ -533,12 +425,12 @@ export default {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -548,31 +440,15 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-table-wrapper {
|
||||
:deep(.el-table__body-wrapper) {
|
||||
overflow: auto;
|
||||
}
|
||||
.table {
|
||||
min-height: 100vh;
|
||||
height: auto;
|
||||
min-height: 60vh;
|
||||
}
|
||||
.ops-link {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.ops-link + .ops-link {
|
||||
margin-left: 16px;
|
||||
position: relative;
|
||||
}
|
||||
.ops-link + .ops-link::before {
|
||||
content: "|";
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
color: #dcdee2;
|
||||
.mb_10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,73 +1,92 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="参数名称" prop="paramName">
|
||||
<Input v-model="form.paramName" clearable style="width: 520px" />
|
||||
</FormItem>
|
||||
<FormItem label="是否必填" prop="required">
|
||||
<RadioGroup v-model="form.required">
|
||||
<Radio :label="0">否</Radio>
|
||||
<Radio :label="1">是</Radio>
|
||||
</RadioGroup>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>商品发布时参数是否必填</span
|
||||
>
|
||||
</FormItem>
|
||||
<FormItem label="是否索引" prop="isIndex">
|
||||
<RadioGroup v-model="form.isIndex">
|
||||
<Radio :label="0">否</Radio>
|
||||
<Radio :label="1">是</Radio>
|
||||
</RadioGroup>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>开启索引后,用户将可以通过该参数筛选商品,索引开关不影响商详页的参数展示</span
|
||||
>
|
||||
</FormItem>
|
||||
<FormItem label="排序" prop="sort">
|
||||
<InputNumber :min="0" type="number" v-model="form.sort" style="width: 520px" />
|
||||
</FormItem>
|
||||
<FormItem label="参数值" prop="options">
|
||||
<Table :columns="optionColumns" :data="form.options" border size="small" style="width: 520px" />
|
||||
<el-card>
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="参数名称" prop="paramName">
|
||||
<el-input v-model="form.paramName" clearable style="width: 520px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否必填" prop="required">
|
||||
<el-radio-group v-model="form.required">
|
||||
<el-radio :value="0">否</el-radio>
|
||||
<el-radio :value="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px">商品发布时参数是否必填</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否索引" prop="isIndex">
|
||||
<el-radio-group v-model="form.isIndex">
|
||||
<el-radio :value="0">否</el-radio>
|
||||
<el-radio :value="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px">
|
||||
开启索引后,用户将可以通过该参数筛选商品,索引开关不影响商详页的参数展示
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number :min="0" v-model="form.sort" style="width: 520px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数值" prop="options">
|
||||
<el-table :data="form.options" border size="small" style="width: 520px">
|
||||
<el-table-column label="参数值" min-width="420">
|
||||
<template #default="{ row, $index }">
|
||||
<el-input
|
||||
v-if="row"
|
||||
v-model="form.options[$index].value"
|
||||
clearable
|
||||
@blur="touchOptionsValidate"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<a v-if="row" class="link-text" @click="removeOptionRow($index)">
|
||||
删除
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="margin-top: 10px">
|
||||
<Button type="primary" @click="addOptionRow">新增</Button>
|
||||
<el-button type="primary" @click="addOptionRow">新增</el-button>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="关联分类">
|
||||
<Button type="default" @click="openCategoryModal">选择分类</Button>
|
||||
<span v-if="selectedCategoryNamesText" style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>{{ selectedCategoryNamesText }}</span
|
||||
>
|
||||
<span v-else style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>已选择{{ selectedCategoryIds.length }}个分类</span
|
||||
>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="default" @click="back">返回</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit">保存</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联分类">
|
||||
<el-button @click="openCategoryModal">选择分类</el-button>
|
||||
<span v-if="selectedCategoryNamesText" style="margin-left: 10px; color: #999; font-size: 12px">
|
||||
{{ selectedCategoryNamesText }}</span>
|
||||
<span v-else style="margin-left: 10px; color: #999; font-size: 12px">
|
||||
已选择{{ selectedCategoryIds.length }}个分类
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="back">返回</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Modal
|
||||
:title="categoryModalTitle"
|
||||
<el-dialog
|
||||
v-model="categoryModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="700"
|
||||
:title="categoryModalTitle"
|
||||
width="700px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div style="position: relative; max-height: 520px; overflow: auto;">
|
||||
<Spin size="large" fix v-if="categoryTreeLoading"></Spin>
|
||||
<Tree
|
||||
<div v-loading="categoryTreeLoading" style="position: relative; max-height: 520px; overflow: auto">
|
||||
<el-tree
|
||||
ref="categoryTree"
|
||||
:key="categoryTreeKey"
|
||||
:data="categoryTreeData"
|
||||
:props="{ label: 'title', children: 'children' }"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
@on-check-change="onCategoryTreeCheckChange"
|
||||
></Tree>
|
||||
default-expand-all
|
||||
:default-checked-keys="selectedCategoryIds"
|
||||
@check="onCategoryTreeCheckChange"
|
||||
/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="categoryModalVisible = false">取消</Button>
|
||||
<Button type="primary" style="margin-left: 8px" @click="categoryModalVisible = false">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="categoryModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" style="margin-left: 8px" @click="categoryModalVisible = false">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -190,51 +209,6 @@ export default {
|
||||
isIndex: 0,
|
||||
sort: 0,
|
||||
},
|
||||
optionColumns: [
|
||||
{
|
||||
title: "参数值",
|
||||
key: "value",
|
||||
minWidth: 420,
|
||||
render: (h, params) => {
|
||||
return h("Input", {
|
||||
props: {
|
||||
value: params.row.value,
|
||||
clearable: true,
|
||||
},
|
||||
on: {
|
||||
input: (val) => {
|
||||
if (!Array.isArray(this.form.options)) this.form.options = [];
|
||||
if (!this.form.options[params.index]) return;
|
||||
this.form.options[params.index].value = val;
|
||||
},
|
||||
"on-blur": () => {
|
||||
this.touchOptionsValidate();
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "error",
|
||||
size: "small",
|
||||
},
|
||||
on: {
|
||||
click: () => this.removeOptionRow(params.index),
|
||||
},
|
||||
},
|
||||
"删除",
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
formValidate: {
|
||||
paramName: [regular.REQUIRED, regular.VARCHAR5],
|
||||
options: [{ required: true, validator: validateOptions, trigger: "change" }],
|
||||
@@ -253,8 +227,8 @@ export default {
|
||||
const selectedSet = new Set(toStringArray(this.selectedCategoryIds));
|
||||
const isSelected = (node) => {
|
||||
if (!node) return false;
|
||||
const id = node.id !== undefined && node.id !== null ? String(node.id) : "";
|
||||
if (id && selectedSet.has(id)) return true;
|
||||
const nodeId = node.id !== undefined && node.id !== null ? String(node.id) : "";
|
||||
if (nodeId && selectedSet.has(nodeId)) return true;
|
||||
const children = Array.isArray(node.children) ? node.children : [];
|
||||
if (children.length === 0) return false;
|
||||
return children.every(isSelected);
|
||||
@@ -276,11 +250,11 @@ export default {
|
||||
watch: {
|
||||
"form.required"(val) {
|
||||
const n = normalize01(val, 0);
|
||||
if (val !== n) this.$set(this.form, "required", n);
|
||||
if (val !== n) this.form.required = n;
|
||||
},
|
||||
"form.isIndex"(val) {
|
||||
const n = normalize01(val, 0);
|
||||
if (val !== n) this.$set(this.form, "isIndex", n);
|
||||
if (val !== n) this.form.isIndex = n;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@@ -302,18 +276,13 @@ export default {
|
||||
this.form.options.splice(index, 1);
|
||||
this.touchOptionsValidate();
|
||||
},
|
||||
buildCategoryTreeNodes(list, selectedSet) {
|
||||
buildCategoryTreeNodes(list) {
|
||||
if (!Array.isArray(list) || list.length === 0) return [];
|
||||
return list.map((item) => {
|
||||
const children = this.buildCategoryTreeNodes(item.children || [], selectedSet);
|
||||
return {
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
expand: true,
|
||||
checked: selectedSet.has(String(item.id)),
|
||||
children,
|
||||
};
|
||||
});
|
||||
return list.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
children: this.buildCategoryTreeNodes(item.children || []),
|
||||
}));
|
||||
},
|
||||
async loadDetail(parameterId) {
|
||||
if (!parameterId) return;
|
||||
@@ -337,7 +306,6 @@ export default {
|
||||
this.categoryTreeLoading = true;
|
||||
this.categoryTreeKey += 1;
|
||||
try {
|
||||
const selectedSet = new Set(toStringArray(this.selectedCategoryIds));
|
||||
if (!Array.isArray(this.categoryTreeSource) || this.categoryTreeSource.length === 0) {
|
||||
const treeRes = await getCategoryTree();
|
||||
this.categoryTreeSource = treeRes && treeRes.success ? treeRes.result || [] : [];
|
||||
@@ -345,17 +313,13 @@ export default {
|
||||
buildCategoryIdNameMap(this.categoryTreeSource, map);
|
||||
this.categoryIdNameMap = map;
|
||||
}
|
||||
this.categoryTreeData = this.buildCategoryTreeNodes(this.categoryTreeSource || [], selectedSet);
|
||||
this.categoryTreeData = this.buildCategoryTreeNodes(this.categoryTreeSource || []);
|
||||
} finally {
|
||||
this.categoryTreeLoading = false;
|
||||
}
|
||||
},
|
||||
onCategoryTreeCheckChange(checkedNodes) {
|
||||
if (!Array.isArray(checkedNodes)) {
|
||||
this.selectedCategoryIds = [];
|
||||
return;
|
||||
}
|
||||
this.selectedCategoryIds = toStringArray(checkedNodes.map((node) => node && node.id).filter(Boolean));
|
||||
onCategoryTreeCheckChange(_data, checkedInfo) {
|
||||
this.selectedCategoryIds = toStringArray(checkedInfo?.checkedKeys || []);
|
||||
},
|
||||
initForm() {
|
||||
if (this.id) {
|
||||
|
||||
@@ -1,55 +1,72 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
@submit.native.prevent
|
||||
@keydown.enter.native="handleSearch"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="参数名称">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="参数名称">
|
||||
<el-input
|
||||
v-model="searchForm.paramName"
|
||||
placeholder="请输入参数名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="goAdd" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="goAdd">添加</el-button>
|
||||
</div>
|
||||
<el-table v-loading="loading" border :data="data" ref="table" style="width: 100%">
|
||||
<el-table-column prop="paramName" label="参数名称" width="300" />
|
||||
<el-table-column prop="options" label="参数值" min-width="260" show-overflow-tooltip />
|
||||
<el-table-column label="必填" width="300" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ isTruthyFlag(row.required) ? "是" : "否" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="可索引" width="300" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ isTruthyFlag(row.isIndex) ? "是" : "否" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row">
|
||||
<a class="link-text" @click="goEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>|<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
deleteParams,
|
||||
getGoodsParamsPage,
|
||||
} from "@/api/goods";
|
||||
import { deleteParams, getGoodsParamsPage } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "categoryParams",
|
||||
@@ -66,90 +83,12 @@ export default {
|
||||
paramName: "",
|
||||
},
|
||||
data: [],
|
||||
columns: [
|
||||
{
|
||||
title: "参数名称",
|
||||
key: "paramName",
|
||||
width: 300,
|
||||
resizable: true,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "参数值",
|
||||
key: "options",
|
||||
minWidth: 260,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "必填",
|
||||
key: "required",
|
||||
width: 300,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const val = params.row.required;
|
||||
const on = val === 1 || val === "1" || val === true;
|
||||
return h("span", on ? "是" : "否");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "可索引",
|
||||
key: "isIndex",
|
||||
width: 300,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const val = params.row.isIndex;
|
||||
const on = val === 1 || val === "1" || val === true;
|
||||
return h("span", on ? "是" : "否");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 300,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.goEdit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isTruthyFlag(val) {
|
||||
return val === 1 || val === "1" || val === true;
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
@@ -209,4 +148,10 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss"></style>
|
||||
<style lang="scss">
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,103 +1,171 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Row>
|
||||
<Form ref="searchForm" :model="searchForm" @keydown.enter.native="handleSearch" @submit.native.prevent inline :label-width="70" class="search-form">
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn" icon="ios-search">搜索</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10">
|
||||
<!-- 页面展示 -->
|
||||
<template slot="shopDisableSlot" slot-scope="scope">
|
||||
<i-switch size="large" true-value="OPEN" false-value="CLOSE" v-model="scope.row.status"
|
||||
@on-change="changeSwitch(scope.row)">
|
||||
<span slot="open">展示</span>
|
||||
<span slot="close">隐藏</span>
|
||||
</i-switch>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]"
|
||||
size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<!-- 评价详情 -->
|
||||
<Modal v-model="infoFlag" width="800" :title="infoTitle">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table ref="table" v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="content" label="评论内容" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column label="是否置顶" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.top ? 'danger' : 'info'">
|
||||
{{ row.top ? "已置顶" : "未置顶" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="评价" width="90">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="gradeTagType(row.grade)">{{ gradeText(row.grade) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="评价时间" width="170" />
|
||||
<el-table-column label="页面展示" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.status"
|
||||
active-value="OPEN"
|
||||
inactive-value="CLOSE"
|
||||
inline-prompt
|
||||
active-text="展示"
|
||||
inactive-text="隐藏"
|
||||
@change="changeSwitch(row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" @click="info(row)">查看</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="updateTop(row)">{{ row.top ? "取消置顶" : "置顶评论" }}</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="infoFlag" :title="infoTitle" width="800px">
|
||||
<div class="info-list" style="overflow: hidden">
|
||||
<div class="left-container">
|
||||
<div class="product">
|
||||
<img class="img" :src=infoData.goodsImage>
|
||||
<img class="img" :src="infoData.goodsImage" />
|
||||
</div>
|
||||
<div class="show">
|
||||
<label>页面展示:</label>
|
||||
<i-switch size="large" true-value="OPEN" false-value="CLOSE" v-model="infoData.status"
|
||||
@on-change="changeSwitchView" style="margin-top: 3px">
|
||||
<span slot="open">展示</span>
|
||||
<span slot="close">隐藏</span>
|
||||
</i-switch>
|
||||
<el-switch
|
||||
v-model="infoData.status"
|
||||
active-value="OPEN"
|
||||
inactive-value="CLOSE"
|
||||
inline-prompt
|
||||
active-text="展示"
|
||||
inactive-text="隐藏"
|
||||
style="margin-top: 3px"
|
||||
@change="changeSwitchView"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-container">
|
||||
<div class="border-b">{{ infoData.goodsName }}</div>
|
||||
<div class="border-b">
|
||||
<div class="div-height"> 店铺名称:{{ infoData.storeName }}</div>
|
||||
<div class="div-height"> 订单号:{{ infoData.orderNo }}</div>
|
||||
<div class="div-height">店铺名称:{{ infoData.storeName }}</div>
|
||||
<div class="div-height">订单号:{{ infoData.orderNo }}</div>
|
||||
</div>
|
||||
|
||||
<div class="border-b">
|
||||
<List>
|
||||
|
||||
<ListItem>
|
||||
<ListItemMeta :avatar="infoData.memberProfile" :title="infoData.memberName"
|
||||
:description="infoData.content"/>
|
||||
</ListItem>
|
||||
<div class="score-content">
|
||||
<span>物流评分:{{infoData.deliveryScore}}</span>
|
||||
<span>服务评分:{{infoData.serviceScore}}</span>
|
||||
<span>描述评分:{{infoData.descriptionScore}}</span>
|
||||
<div class="review-item">
|
||||
<el-avatar v-if="infoData.memberProfile" :src="infoData.memberProfile" :size="40" />
|
||||
<div class="review-meta">
|
||||
<div class="review-name">{{ infoData.memberName }}</div>
|
||||
<div class="review-content">{{ infoData.content }}</div>
|
||||
</div>
|
||||
<div class="" v-if="infoData.haveImage">
|
||||
评价图
|
||||
<div style="margin-left: 40px">
|
||||
<template v-if="infoData.images && infoData.images.length">
|
||||
<img style="width: 100px;height: 110px;margin-left: 2px"
|
||||
v-for="(img,index) in infoData.images.split(',')" :src="img"
|
||||
alt="" :key="index"/>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-content">
|
||||
<span>物流评分:{{ infoData.deliveryScore }}</span>
|
||||
<span>服务评分:{{ infoData.serviceScore }}</span>
|
||||
<span>描述评分:{{ infoData.descriptionScore }}</span>
|
||||
</div>
|
||||
<div v-if="infoData.haveImage">
|
||||
评价图
|
||||
<div style="margin-left: 40px">
|
||||
<template v-if="infoData.images && infoData.images.length">
|
||||
<img
|
||||
v-for="(img, index) in infoData.images.split(',')"
|
||||
:key="index"
|
||||
style="width: 100px; height: 110px; margin-left: 2px"
|
||||
:src="img"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-b" v-if="infoData.reply">
|
||||
<div v-if="infoData.reply" class="border-b">
|
||||
<div>
|
||||
<div>
|
||||
<div style="float: left"> 商家回复:</div>
|
||||
<div style="margin-left: 60px">{{ infoData.reply }}</div>
|
||||
</div>
|
||||
<div v-if="infoData.haveReplyImage">
|
||||
<div style="margin-left: 60px">
|
||||
<template v-if="infoData.replyImage && infoData.replyImage.length">
|
||||
<img style="width: 100px;height: 110px" v-for="(img,index) in infoData.replyImage.split(',')" :key="index"
|
||||
:src="img" alt=""/>
|
||||
</template>
|
||||
</div>
|
||||
<div style="float: left">商家回复:</div>
|
||||
<div style="margin-left: 60px">{{ infoData.reply }}</div>
|
||||
</div>
|
||||
<div v-if="infoData.haveReplyImage">
|
||||
<div style="margin-left: 60px">
|
||||
<template v-if="infoData.replyImage && infoData.replyImage.length">
|
||||
<img
|
||||
v-for="(img, index) in infoData.replyImage.split(',')"
|
||||
:key="index"
|
||||
style="width: 100px; height: 110px"
|
||||
:src="img"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,223 +173,66 @@
|
||||
import * as API_Member from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "goods-review", // 会员评价
|
||||
name: "goods-review",
|
||||
data() {
|
||||
return {
|
||||
infoData: {}, // 商品信息
|
||||
infoFlag: false, // 评价展示
|
||||
infoTitle: "", // modal名称
|
||||
loading: true, // 表单加载状态
|
||||
infoData: {},
|
||||
infoFlag: false,
|
||||
infoTitle: "",
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
goodsName: "",
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
},
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 120,
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "评论内容",
|
||||
key: "content",
|
||||
minWidth: 220,
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "是否置顶",
|
||||
key: "top",
|
||||
align: "center",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Tag",
|
||||
{
|
||||
props: {
|
||||
color: params.row.top ? "red" : "default",
|
||||
},
|
||||
},
|
||||
params.row.top ? "已置顶" : "未置顶"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "评价",
|
||||
key: "grade",
|
||||
align: "left",
|
||||
width: 90,
|
||||
render: (h, params) => {
|
||||
if (params.row.grade == "GOOD") {
|
||||
return h("Tag", {props: {color: "green",},}, "好评");
|
||||
} else if (params.row.grade == "MODERATE") {
|
||||
return h("Tag", {props: {color: "orange",},}, "中评");
|
||||
} else {
|
||||
return h("Tag", {props: {color: "red",},}, "差评");
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "评价时间",
|
||||
key: "createTime",
|
||||
align: "left",
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: "页面展示",
|
||||
key: "shopDisable",
|
||||
align: "left",
|
||||
width: 100,
|
||||
slot: "shopDisableSlot",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 220,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.info(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2",
|
||||
},
|
||||
},
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.updateTop(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
params.row.top ? "取消置顶" : "置顶评论"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2",
|
||||
},
|
||||
},
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"Poptip",
|
||||
{
|
||||
props: { confirm: true, title: "确认删除" },
|
||||
on: {
|
||||
"on-ok": () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
[
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 切换查看switch
|
||||
changeSwitchView(val) {
|
||||
let status = val;
|
||||
API_Member.updateMemberReview(this.infoData.id, {status}).then(
|
||||
(res) => {
|
||||
this.$Message.success("修改成功!");
|
||||
this.init();
|
||||
}
|
||||
);
|
||||
gradeTagType(grade) {
|
||||
if (grade === "GOOD") return "success";
|
||||
if (grade === "MODERATE") return "warning";
|
||||
return "danger";
|
||||
},
|
||||
gradeText(grade) {
|
||||
if (grade === "GOOD") return "好评";
|
||||
if (grade === "MODERATE") return "中评";
|
||||
return "差评";
|
||||
},
|
||||
changeSwitchView(val) {
|
||||
const status = val;
|
||||
API_Member.updateMemberReview(this.infoData.id, { status }).then(() => {
|
||||
this.$Message.success("修改成功!");
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
//列表直接选择页面是否展示
|
||||
changeSwitch(v) {
|
||||
let status = v.status;
|
||||
API_Member.updateMemberReview(v.id, {status: status}).then((res) => {
|
||||
const status = v.status;
|
||||
API_Member.updateMemberReview(v.id, { status }).then(() => {
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
// 置顶评论
|
||||
updateTop(v) {
|
||||
const top = !v.top;
|
||||
API_Member.updateMemberReviewTop(v.id, { top }).then((res) => {
|
||||
@@ -340,7 +251,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取列表
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberReview(this.searchForm).then((res) => {
|
||||
@@ -353,7 +263,6 @@ export default {
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
//评价详情
|
||||
info(v) {
|
||||
this.infoFlag = true;
|
||||
this.infoTitle = `用户${v.memberName}的评价详情`;
|
||||
@@ -363,14 +272,13 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除评论
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除会员" + v.memberName + "的评论?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
API_Member.delMemberReview(v.id).then((res) => {
|
||||
API_Member.delMemberReview(v.id).then(() => {
|
||||
this.$Modal.remove();
|
||||
this.$Message.success("修改成功");
|
||||
this.init();
|
||||
@@ -384,6 +292,7 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-container {
|
||||
float: left;
|
||||
@@ -408,8 +317,8 @@ img {
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.show{
|
||||
label{
|
||||
.show {
|
||||
label {
|
||||
font-size: 14px;
|
||||
}
|
||||
margin-top: 15px;
|
||||
@@ -430,12 +339,26 @@ label {
|
||||
position: relative;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.div-height{
|
||||
.div-height {
|
||||
line-height: 25px;
|
||||
}
|
||||
.score-content {
|
||||
margin: 5px 0;
|
||||
span{margin-right: 20px;}
|
||||
span {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.review-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.review-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
.review-content {
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
|
||||
@@ -1,61 +1,70 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button type="primary" @click="openAdd">添加分组</Button>
|
||||
</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"
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="openAdd">添加分组</el-button>
|
||||
</div>
|
||||
|
||||
<el-table ref="table" v-loading="loading" :data="data" border class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="groupName" label="分组名称" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="description" label="分组描述" min-width="240" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops" style="display: flex; justify-content: center">
|
||||
<a class="link-text" @click="openEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal v-model="addFlag" title="添加商品分组">
|
||||
<Form ref="addForm" :model="formAdd" :rules="rulesAdd" :label-width="90">
|
||||
<FormItem label="分组名称" prop="groupName" style="width: 90%;">
|
||||
<Input v-model="formAdd.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</FormItem>
|
||||
<FormItem label="分组描述" prop="description" style="width: 90%;">
|
||||
<Input v-model="formAdd.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="addFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</Button>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal v-model="editFlag" title="编辑商品分组">
|
||||
<Form ref="editForm" :model="formEdit" :rules="rulesEdit" :label-width="90">
|
||||
<Input v-model="formEdit.id" v-show="false" />
|
||||
<FormItem label="分组名称" prop="groupName" style="width: 90%;">
|
||||
<Input v-model="formEdit.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</FormItem>
|
||||
<FormItem label="分组描述" prop="description" style="width: 90%;">
|
||||
<Input v-model="formEdit.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="editFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="addFlag" title="添加商品分组" width="500px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="addForm" :model="formAdd" :rules="rulesAdd" label-width="90px">
|
||||
<el-form-item label="分组名称" prop="groupName" style="width: 90%">
|
||||
<el-input v-model="formAdd.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组描述" prop="description" style="width: 90%">
|
||||
<el-input v-model="formAdd.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="addFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="editFlag" title="编辑商品分组" width="500px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="editForm" :model="formEdit" :rules="rulesEdit" label-width="90px">
|
||||
<el-input v-model="formEdit.id" style="display: none" />
|
||||
<el-form-item label="分组名称" prop="groupName" style="width: 90%">
|
||||
<el-input v-model="formEdit.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组描述" prop="description" style="width: 90%">
|
||||
<el-input v-model="formEdit.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="editFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -71,54 +80,6 @@ export default {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "分组名称",
|
||||
key: "groupName",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "分组描述",
|
||||
key: "description",
|
||||
minWidth: 240,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
key: "updateTime",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
const linkStyle = {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
};
|
||||
const sep = h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
);
|
||||
return h("div", { class: "ops", style: { display: "flex", justifyContent: "center" } }, [
|
||||
h("a", { style: linkStyle, on: { click: () => this.openEdit(params.row) } }, "编辑"),
|
||||
sep,
|
||||
h("a", { style: linkStyle, on: { click: () => this.remove(params.row) } }, "删除"),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
total: 0,
|
||||
addFlag: false,
|
||||
@@ -135,10 +96,10 @@ export default {
|
||||
description: "",
|
||||
},
|
||||
rulesAdd: {
|
||||
groupName: [{ required: true, message: "请输入分组名称" }],
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
rulesEdit: {
|
||||
groupName: [{ required: true, message: "请输入分组名称" }],
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -248,7 +209,7 @@ export default {
|
||||
remove(row) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "<p>确定删除该分组?</p>",
|
||||
content: "确定删除该分组?",
|
||||
onOk: () => {
|
||||
API_Goods.deleteGoodsGroup(row.id)
|
||||
.then((res) => {
|
||||
@@ -271,3 +232,16 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops span {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,120 +1,160 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keydown.enter.native="handleSearch"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品ID" prop="goodsId">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="商品ID" prop="goodsId">
|
||||
<el-input
|
||||
v-model="searchForm.goodsId"
|
||||
placeholder="请输入商品ID"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="SKU货号" prop="sn">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="SKU货号" prop="sn">
|
||||
<el-input
|
||||
v-model="searchForm.sn"
|
||||
placeholder="请输入SKU货号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="店铺名称" prop="storeName">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称" prop="storeName">
|
||||
<el-input
|
||||
v-model="searchForm.storeName"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
class="search-btn"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
<Button @click="handleReset" style="margin-left: 8px">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button style="margin-left: 8px" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Card class="mt_10">
|
||||
<Alert show-icon>
|
||||
支持按规格逐条设置虚拟销量,列表总销量 = 真实销量 + 虚拟销量。
|
||||
</Alert>
|
||||
<el-card class="mt_10">
|
||||
<el-alert
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
title="支持按规格逐条设置虚拟销量,列表总销量 = 真实销量 + 虚拟销量。"
|
||||
style="margin-bottom: 10px"
|
||||
/>
|
||||
|
||||
<div class="batch-operations">
|
||||
<Button
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="openBatchVirtualSalesModal"
|
||||
>
|
||||
批量设置虚拟销量
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
sortable="custom"
|
||||
@on-sort-change="changeSort"
|
||||
@on-selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
@sort-change="changeSort"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<template slot="goodsSlot" slot-scope="{ row }">
|
||||
<div class="goods-info">
|
||||
<img
|
||||
:src="row.thumbnail"
|
||||
class="goods-thumbnail"
|
||||
/>
|
||||
<div class="goods-text">
|
||||
<div class="div-zoom">{{ row.goodsName }}</div>
|
||||
<div class="sub-title" v-if="row.simpleSpecs">
|
||||
规格:{{ row.simpleSpecs.trim() || "-" }}
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="id" label="SKU ID" width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="goodsId" label="商品ID" width="180" show-overflow-tooltip />
|
||||
<el-table-column label="商品信息" min-width="360">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="goods-info">
|
||||
<img
|
||||
v-if="row.thumbnail"
|
||||
:src="row.thumbnail"
|
||||
class="goods-thumbnail"
|
||||
alt=""
|
||||
/>
|
||||
<div class="goods-text">
|
||||
<div class="div-zoom">{{ row.goodsName }}</div>
|
||||
<div v-if="row.simpleSpecs" class="sub-title">
|
||||
规格:{{ row.simpleSpecs.trim() || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="真实销量" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.buyCount || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="虚拟销量" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.virtualSalesInput || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总销量" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ getTotalSales(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.marketEnable === 'UPPER' ? 'success' : 'warning'">
|
||||
{{ row.marketEnable === "UPPER" ? "上架" : "下架" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="{ row, $index }">
|
||||
<a
|
||||
v-if="row"
|
||||
class="link-text"
|
||||
:class="{ disabled: row.saving }"
|
||||
@click="!row.saving && openVirtualSalesModal(row, $index)"
|
||||
>
|
||||
设置
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="editModalVisible"
|
||||
:title="modalMode === 'batch' ? '批量设置虚拟销量' : '设置虚拟销量'"
|
||||
:mask-closable="false"
|
||||
:closable="!modalSubmitting"
|
||||
width="480px"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="!modalSubmitting"
|
||||
:show-close="!modalSubmitting"
|
||||
destroy-on-close
|
||||
>
|
||||
<div v-if="modalMode === 'single' && currentSku" class="virtual-sales-modal">
|
||||
<div class="sku-info-item">
|
||||
@@ -129,50 +169,42 @@
|
||||
<span class="sku-info-label">SKU ID:</span>
|
||||
<span>{{ currentSku.id || "-" }}</span>
|
||||
</div>
|
||||
|
||||
<Form :label-width="90" class="mt_10">
|
||||
<Form-item label="虚拟销量">
|
||||
<InputNumber
|
||||
<el-form label-width="90px" class="mt_10">
|
||||
<el-form-item label="虚拟销量">
|
||||
<el-input-number
|
||||
v-model="editForm.virtualSales"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
:precision="0"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-else-if="modalMode === 'batch'" class="virtual-sales-modal">
|
||||
<div class="sku-info-item">
|
||||
<span class="sku-info-label">已选规格:</span>
|
||||
<span>{{ selectedRows.length }} 个</span>
|
||||
</div>
|
||||
|
||||
<Form :label-width="90" class="mt_10">
|
||||
<Form-item label="虚拟销量">
|
||||
<InputNumber
|
||||
<el-form label-width="90px" class="mt_10">
|
||||
<el-form-item label="虚拟销量">
|
||||
<el-input-number
|
||||
v-model="editForm.virtualSales"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
:precision="0"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button @click="handleCancelVirtualSales" :disabled="modalSubmitting">
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="modalSubmitting"
|
||||
@click="handleSubmitVirtualSales"
|
||||
>
|
||||
<template #footer>
|
||||
<el-button :disabled="modalSubmitting" @click="handleCancelVirtualSales">取消</el-button>
|
||||
<el-button type="primary" :loading="modalSubmitting" @click="handleSubmitVirtualSales">
|
||||
提交
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -216,84 +248,6 @@ export default {
|
||||
sn: "",
|
||||
storeName: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "SKU ID",
|
||||
key: "id",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品ID",
|
||||
key: "goodsId",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品信息",
|
||||
key: "goodsName",
|
||||
minWidth: 360,
|
||||
slot: "goodsSlot",
|
||||
},
|
||||
{
|
||||
title: "真实销量",
|
||||
key: "buyCount",
|
||||
width: 110,
|
||||
render: (h, params) => h("span", params.row.buyCount || 0),
|
||||
},
|
||||
{
|
||||
title: "虚拟销量",
|
||||
key: "virtualSalesInput",
|
||||
width: 110,
|
||||
render: (h, params) => h("span", params.row.virtualSalesInput || 0),
|
||||
},
|
||||
{
|
||||
title: "总销量",
|
||||
key: "totalSalesDisplay",
|
||||
width: 110,
|
||||
render: (h, params) => h("span", this.getTotalSales(params.row)),
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "marketEnable",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
const isUpper = params.row.marketEnable === "UPPER";
|
||||
return h(
|
||||
"Tag",
|
||||
{ props: { color: isUpper ? "green" : "volcano" } },
|
||||
isUpper ? "上架" : "下架"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "primary",
|
||||
size: "small",
|
||||
loading: !!params.row.saving,
|
||||
},
|
||||
on: {
|
||||
click: () => this.openVirtualSalesModal(params.row, params.index),
|
||||
},
|
||||
},
|
||||
"设置"
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
@@ -328,12 +282,13 @@ export default {
|
||||
};
|
||||
this.getDataList();
|
||||
},
|
||||
changeSort(e) {
|
||||
this.searchForm.sort = e.key;
|
||||
this.searchForm.order = e.order;
|
||||
if (e.order === "normal") {
|
||||
changeSort({ prop, order }) {
|
||||
if (!order) {
|
||||
this.searchForm.sort = "create_time";
|
||||
this.searchForm.order = "desc";
|
||||
} else {
|
||||
this.searchForm.sort = prop;
|
||||
this.searchForm.order = order === "ascending" ? "asc" : "desc";
|
||||
}
|
||||
this.getDataList();
|
||||
},
|
||||
@@ -394,9 +349,7 @@ export default {
|
||||
this.editModalVisible = true;
|
||||
},
|
||||
handleCancelVirtualSales() {
|
||||
if (this.modalSubmitting) {
|
||||
return;
|
||||
}
|
||||
if (this.modalSubmitting) return;
|
||||
this.resetVirtualSalesModal();
|
||||
},
|
||||
resetVirtualSalesModal() {
|
||||
@@ -416,18 +369,21 @@ export default {
|
||||
this.handleBatchSubmitVirtualSales(virtualSales);
|
||||
return;
|
||||
}
|
||||
if (!this.currentSku || this.currentIndex < 0) {
|
||||
return;
|
||||
}
|
||||
if (!this.currentSku || this.currentIndex < 0) return;
|
||||
|
||||
const currentIndex = this.currentIndex;
|
||||
const currentSkuId = this.currentSku.id;
|
||||
this.modalSubmitting = true;
|
||||
this.$set(this.data[currentIndex], "saving", true);
|
||||
if (this.data[currentIndex]) {
|
||||
this.data[currentIndex].saving = true;
|
||||
}
|
||||
updateGoodsSkuVirtualSales(currentSkuId, { virtualSales })
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.$set(this.data[currentIndex], "virtualSales", virtualSales);
|
||||
this.$set(this.data[currentIndex], "virtualSalesInput", virtualSales);
|
||||
if (this.data[currentIndex]) {
|
||||
this.data[currentIndex].virtualSales = virtualSales;
|
||||
this.data[currentIndex].virtualSalesInput = virtualSales;
|
||||
}
|
||||
this.$Message.success("虚拟销量设置成功");
|
||||
this.resetVirtualSalesModal();
|
||||
} else {
|
||||
@@ -439,7 +395,7 @@ export default {
|
||||
})
|
||||
.finally(() => {
|
||||
if (this.data[currentIndex]) {
|
||||
this.$set(this.data[currentIndex], "saving", false);
|
||||
this.data[currentIndex].saving = false;
|
||||
}
|
||||
this.modalSubmitting = false;
|
||||
});
|
||||
@@ -455,9 +411,7 @@ export default {
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.data = this.data.map((item) => {
|
||||
if (!skuIds.includes(item.id)) {
|
||||
return item;
|
||||
}
|
||||
if (!skuIds.includes(item.id)) return item;
|
||||
return {
|
||||
...item,
|
||||
virtualSales,
|
||||
@@ -465,9 +419,7 @@ export default {
|
||||
};
|
||||
});
|
||||
this.selectedRows = [];
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.selectAll(false);
|
||||
}
|
||||
this.$refs.table?.clearSelection();
|
||||
this.$Message.success("虚拟销量设置成功");
|
||||
this.resetVirtualSalesModal();
|
||||
} else {
|
||||
@@ -517,6 +469,12 @@ export default {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.div-zoom {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.batch-operations {
|
||||
margin-top: 10px;
|
||||
}
|
||||
@@ -537,4 +495,8 @@ export default {
|
||||
color: #808695;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,7 +10,7 @@ h4 {
|
||||
margin: 20px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
::v-deep .ivu-icon {
|
||||
:deep(.ivu-icon){
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="count-list flex">
|
||||
<div class="count-item" @click="navigateTo('managerGoods')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="md-photos" />
|
||||
<el-icon class="icon" :size="31"><Picture /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.goodsNum || 0 }}</div>
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
<div class="count-item" @click="navigateTo('memberList')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="md-person" />
|
||||
<el-icon class="icon" :size="31"><User /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.memberNum || 0 }}</div>
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="count-item" @click="navigateTo('orderList')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="md-list" />
|
||||
<el-icon class="icon" :size="31"><List /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.orderNum || 0 }}</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
<div class="count-item" @click="navigateTo('shopList')">
|
||||
<div>
|
||||
<Icon class="icon" size="31" type="ios-stats" />
|
||||
<el-icon class="icon" :size="31"><DataLine /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="counts">{{ homeData.storeNum || 0 }}</div>
|
||||
@@ -83,8 +83,7 @@
|
||||
<div class="flow-member">
|
||||
<div>当前在线人数</div>
|
||||
<span>
|
||||
{{ homeData.currentNumberPeopleOnline || 0 }}
|
||||
</span>
|
||||
{{ homeData.currentNumberPeopleOnline || 0 }}</span>
|
||||
</div>
|
||||
<div class="flow-wrapper">
|
||||
<h4>流量概括</h4>
|
||||
@@ -129,7 +128,7 @@
|
||||
<div class="today-item">
|
||||
<div>今日交易额</div>
|
||||
<span v-if="homeData.todayOrderPrice"
|
||||
>¥{{ homeData.todayOrderPrice | unitPrice }}</span
|
||||
>{{ $filters.unitPrice(homeData.todayOrderPrice, '¥') }}</span
|
||||
>
|
||||
<span v-else>¥0.00</span>
|
||||
</div>
|
||||
@@ -176,97 +175,47 @@
|
||||
<!-- top10商品 -->
|
||||
<div class="card transform">
|
||||
<h4>热卖商品TOP10</h4>
|
||||
<Table
|
||||
stripe
|
||||
:columns="tophotGoodsColumns"
|
||||
:data="topHotGoodsData"
|
||||
></Table>
|
||||
<el-table stripe :data="topHotGoodsData" style="width: 100%">
|
||||
<el-table-column type="index" label="排名" width="100" align="center" />
|
||||
<el-table-column prop="goodsName" label="商品名称" />
|
||||
<el-table-column prop="price" label="价格">
|
||||
<template #default="{ row }">
|
||||
<span :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, '¥') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="num" label="销量" width="100" sortable />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- top10店铺 -->
|
||||
<div class="card transform">
|
||||
<h4>热卖店铺TOP10</h4>
|
||||
<Table
|
||||
stripe
|
||||
:columns="tophotShopsColumns"
|
||||
:data="topHotShopsData"
|
||||
></Table>
|
||||
<el-table stripe :data="topHotShopsData" style="width: 100%">
|
||||
<el-table-column type="index" label="排名" width="100" align="center" />
|
||||
<el-table-column prop="storeName" label="店铺名称" />
|
||||
<el-table-column prop="price" label="价格">
|
||||
<template #default="{ row }">
|
||||
<span :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, '¥') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="num" label="销量" width="100" sortable />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Picture, User, List, DataLine } from "@element-plus/icons-vue";
|
||||
import { homeStatistics, hotGoods, hotShops, getNoticePage } from "@/api/index";
|
||||
import * as API_Goods from "@/api/goods";
|
||||
import { Chart } from "@antv/g2";
|
||||
import * as API_Member from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
components: { Picture, User, List, DataLine },
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 测试数据
|
||||
test: {
|
||||
a: "test",
|
||||
languages: [],
|
||||
},
|
||||
// 测试数据结束
|
||||
tophotShopsColumns: [
|
||||
// 表格表头
|
||||
{
|
||||
type: "index",
|
||||
width: 100,
|
||||
title: "排名",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
},
|
||||
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "销量",
|
||||
key: "num",
|
||||
width: 100,
|
||||
sortable: true,
|
||||
},
|
||||
],
|
||||
|
||||
tophotGoodsColumns: [
|
||||
{
|
||||
type: "index",
|
||||
width: 100,
|
||||
title: "排名",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
},
|
||||
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "销量",
|
||||
key: "num",
|
||||
width: 100,
|
||||
sortable: true,
|
||||
},
|
||||
],
|
||||
topHotGoodsData: [], //热卖商品集合
|
||||
topHotShopsData: [], //热卖店铺集合
|
||||
awaitTodoData: "", //今日待办集合
|
||||
|
||||
@@ -1,135 +1,126 @@
|
||||
<template>
|
||||
<div class="login" @click="$refs.verify.show = false">
|
||||
<Row @keydown.enter.native="submitLogin" class="flex">
|
||||
<Col style="width: 368px">
|
||||
<el-row class="flex" @keyup.enter="submitLogin">
|
||||
<el-col style="width: 368px">
|
||||
<Header />
|
||||
<Row style="flex-direction: column">
|
||||
<Form
|
||||
<el-row style="flex-direction: column">
|
||||
<el-form
|
||||
ref="usernameLoginForm"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
class="form"
|
||||
>
|
||||
<FormItem prop="username">
|
||||
<Input
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
prefix="ios-contact"
|
||||
size="large"
|
||||
clearable
|
||||
placeholder="请输入用户名"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem prop="password">
|
||||
<Input
|
||||
type="password"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><User /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
prefix="ios-lock"
|
||||
type="password"
|
||||
size="large"
|
||||
password
|
||||
show-password
|
||||
placeholder="请输入密码"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Lock /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<Row>
|
||||
<Button
|
||||
<el-row>
|
||||
<el-button
|
||||
class="login-btn"
|
||||
type="primary"
|
||||
size="large"
|
||||
:loading="loading"
|
||||
style="width: 100%"
|
||||
@click="submitLogin"
|
||||
long
|
||||
>
|
||||
<span v-if="!loading">{{ $t("login") }}</span>
|
||||
<span v-else>{{ $t("logining") }}</span>
|
||||
</Button>
|
||||
</Row>
|
||||
</Row>
|
||||
<!-- 拼图验证码 -->
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-row>
|
||||
<verify
|
||||
ref="verify"
|
||||
class="verify-con"
|
||||
verifyType="LOGIN"
|
||||
@change="verifyChange"
|
||||
></verify>
|
||||
/>
|
||||
<Footer />
|
||||
</Col>
|
||||
<!-- <LangSwitch /> -->
|
||||
</Row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { User, Lock } from "@element-plus/icons-vue";
|
||||
import { login, userInfo } from "@/api/index";
|
||||
import Cookies from "js-cookie";
|
||||
import Header from "@/views/main-parts/header";
|
||||
import Footer from "@/views/main-parts/footer";
|
||||
import LangSwitch from "@/views/main-parts/lang-switch";
|
||||
import util from "@/libs/util.js";
|
||||
import verify from "@/components/verify";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LangSwitch,
|
||||
Header,
|
||||
Footer,
|
||||
verify,
|
||||
User,
|
||||
Lock,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false, // 加载状态
|
||||
loading: false,
|
||||
form: {
|
||||
// 表单数据
|
||||
username: "",
|
||||
password: "",
|
||||
mobile: "",
|
||||
code: "",
|
||||
},
|
||||
rules: {
|
||||
// 验证规则
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "账号不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
{ required: true, message: "账号不能为空", trigger: "blur" },
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "密码不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
{ required: true, message: "密码不能为空", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
afterLogin(res) {
|
||||
// 登录成功后处理
|
||||
let accessToken = res.result.accessToken;
|
||||
let refreshToken = res.result.refreshToken;
|
||||
const accessToken = res.result.accessToken;
|
||||
const refreshToken = res.result.refreshToken;
|
||||
this.setStore("accessToken", accessToken);
|
||||
this.setStore("refreshToken", refreshToken);
|
||||
// 获取用户信息
|
||||
userInfo().then((res) => {
|
||||
if (res.success) {
|
||||
// 加载菜单
|
||||
Cookies.set("userInfoManager", JSON.stringify(res.result));
|
||||
this.$store.commit("setAvatarPath", res.result.avatar);
|
||||
util.initRouter(this);
|
||||
this.$router.push({
|
||||
name: "home_index",
|
||||
});
|
||||
this.$store.commit("setOpenedList");
|
||||
this.$store.commit("initCachePage");
|
||||
this.$router.push({ name: "home_index" });
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
submitLogin() {
|
||||
// 登录操作
|
||||
this.$refs.usernameLoginForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$refs.verify.init();
|
||||
@@ -137,12 +128,9 @@ export default {
|
||||
});
|
||||
},
|
||||
verifyChange(con) {
|
||||
// 拼图验证码回显
|
||||
if (!con.status) return;
|
||||
|
||||
this.loading = true;
|
||||
|
||||
let fd = new FormData();
|
||||
const fd = new FormData();
|
||||
fd.append("username", this.form.username);
|
||||
fd.append("password", this.md5(this.form.password));
|
||||
login(fd)
|
||||
@@ -185,20 +173,10 @@ export default {
|
||||
.login-btn {
|
||||
background: linear-gradient(135deg, $theme_color 0%, $warning_color 100%);
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
transition: 0.35s;
|
||||
border: none;
|
||||
}
|
||||
.login-btn:hover {
|
||||
opacity: 0.9;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
.flex {
|
||||
|
||||
@@ -1,321 +1,249 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="add" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
>
|
||||
<!-- 页面展示 -->
|
||||
<template slot="disableSlot" slot-scope="{row}">
|
||||
<i-switch size="large" :true-value="true" :false-value="false" :value="row.switch" @on-change="changeSwitch(row)">
|
||||
<span slot="open">开启</span>
|
||||
<span slot="close">禁用</span>
|
||||
</i-switch>
|
||||
</template>
|
||||
</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="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="form" :label-width="120" :rules="formValidate">
|
||||
<FormItem label="物流公司名称" prop="name">
|
||||
<Input v-model="form.name" clearable style="width: 100%"/>
|
||||
</FormItem>
|
||||
<FormItem label="物流公司代码" prop="code">
|
||||
<Input v-model="form.code" clearable style="width: 100%"/>
|
||||
</FormItem>
|
||||
<FormItem label="支持电子面单">
|
||||
<i-switch v-model="form.standBy" size="large">
|
||||
<span slot="open">开</span>
|
||||
<span slot="close">关</span>
|
||||
</i-switch>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="禁用状态" prop="disabled">
|
||||
|
||||
<i-switch true-value="OPEN" false-value="CLOSE" v-model="form.disabled" size="large">
|
||||
<span slot="open">开启</span>
|
||||
<span slot="close">禁用</span>
|
||||
</i-switch>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
|
||||
>提交
|
||||
</Button
|
||||
>
|
||||
<el-card>
|
||||
<div class="operation padding-row" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="name" label="物流公司名称" min-width="120" />
|
||||
<el-table-column prop="code" label="物流公司编码" min-width="120" />
|
||||
<el-table-column label="状态" width="150" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.switch"
|
||||
inline-prompt
|
||||
active-text="开启"
|
||||
inactive-text="禁用"
|
||||
@change="changeSwitch(row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="150" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="detail(row)">修改</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="formValidate" label-width="120px">
|
||||
<el-form-item label="物流公司名称" prop="name">
|
||||
<el-input v-model="form.name" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物流公司代码" prop="code">
|
||||
<el-input v-model="form.code" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="支持电子面单">
|
||||
<el-switch
|
||||
v-model="form.standBy"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="禁用状态" prop="disabled">
|
||||
<el-switch
|
||||
v-model="form.disabled"
|
||||
inline-prompt
|
||||
active-value="OPEN"
|
||||
inactive-value="CLOSE"
|
||||
active-text="开启"
|
||||
inactive-text="禁用"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
|
||||
提交
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getLogisticsPage,
|
||||
updateLogistics,
|
||||
addLogistics,
|
||||
delLogistics,
|
||||
} from "@/api/logistics";
|
||||
import {
|
||||
getLogisticsPage,
|
||||
updateLogistics,
|
||||
addLogistics,
|
||||
delLogistics,
|
||||
} from "@/api/logistics";
|
||||
|
||||
export default {
|
||||
name: "logistics",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
name: "",
|
||||
},
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
name: "",
|
||||
disabled:"CLOSE"
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入物流公司名称",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
const defaultForm = () => ({
|
||||
name: "",
|
||||
code: "",
|
||||
standBy: false,
|
||||
disabled: "CLOSE",
|
||||
});
|
||||
|
||||
export default {
|
||||
name: "logistics",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
name: "",
|
||||
},
|
||||
form: defaultForm(),
|
||||
formValidate: {
|
||||
name: [
|
||||
{
|
||||
title: "物流公司名称",
|
||||
key: "name",
|
||||
minWidth: 120,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "物流公司编码",
|
||||
key: "code",
|
||||
minWidth: 120,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "disabled",
|
||||
width: 150,
|
||||
slot: "disableSlot",
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 180,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 150,
|
||||
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);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
required: true,
|
||||
message: "请输入物流公司名称",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
};
|
||||
},
|
||||
submitLoading: false,
|
||||
data: [],
|
||||
total: 0,
|
||||
id: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取列表
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
|
||||
getLogisticsPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
const data = res.result.records;
|
||||
data.forEach(e => {
|
||||
e.switch = e.disabled === 'OPEN' ? true : false;
|
||||
e.standBy = e.standBy == 'null' || !e.standBy ? false : true;
|
||||
});
|
||||
this.data = data;
|
||||
console.log(data)
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
changePage() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getLogisticsPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
// switch 切换状态
|
||||
changeSwitch (v) {
|
||||
this.form.name = v.name;
|
||||
this.form.code = v.code;
|
||||
this.form.standBy = v.standBy;
|
||||
if (res.success) {
|
||||
const data = res.result.records;
|
||||
data.forEach((e) => {
|
||||
e.switch = e.disabled === "OPEN";
|
||||
e.standBy = e.standBy == "null" || !e.standBy ? false : !!e.standBy;
|
||||
});
|
||||
this.data = data;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
changeSwitch(row) {
|
||||
this.form.name = row.name;
|
||||
this.form.code = row.code;
|
||||
this.form.standBy = row.standBy;
|
||||
this.form.disabled = row.disabled === "CLOSE" ? "OPEN" : "CLOSE";
|
||||
updateLogistics(row.id, this.form).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
} else {
|
||||
row.switch = !row.switch;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) return;
|
||||
this.submitLoading = true;
|
||||
|
||||
this.form.disabled = v.disabled === 'CLOSE' ? 'OPEN' : 'CLOSE';
|
||||
updateLogistics(v.id, this.form).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 确认提交
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
|
||||
if (this.modalTitle == "添加") {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.form.id;
|
||||
|
||||
|
||||
addLogistics(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
updateLogistics(this.id, this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
if (this.modalTitle === "添加") {
|
||||
const payload = { ...this.form };
|
||||
delete payload.id;
|
||||
addLogistics(payload).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加信息
|
||||
add() {
|
||||
this.modalTitle = "添加";
|
||||
this.form = {};
|
||||
this.$refs.form.resetFields();
|
||||
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 编辑
|
||||
detail(v) {
|
||||
this.id = v.id;
|
||||
this.modalTitle = "修改";
|
||||
this.modalVisible = true;
|
||||
|
||||
this.form.name = v.name;
|
||||
this.form.code = v.code;
|
||||
console.log(v)
|
||||
this.form.standBy = v.standBy;
|
||||
|
||||
|
||||
|
||||
|
||||
this.form.disabled = v.disabled
|
||||
},
|
||||
// 删除物流公司
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
// 记得确认修改此处
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
delLogistics(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
updateLogistics(this.id, this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
add() {
|
||||
this.modalTitle = "添加";
|
||||
this.form = defaultForm();
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form?.resetFields();
|
||||
});
|
||||
this.modalVisible = true;
|
||||
},
|
||||
};
|
||||
detail(v) {
|
||||
this.id = v.id;
|
||||
this.modalTitle = "修改";
|
||||
this.form = {
|
||||
name: v.name,
|
||||
code: v.code,
|
||||
standBy: v.standBy == "null" || !v.standBy ? false : !!v.standBy,
|
||||
disabled: v.disabled,
|
||||
};
|
||||
this.modalVisible = true;
|
||||
},
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
onOk: () => {
|
||||
return delLogistics(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
<template>
|
||||
<div class="foot">
|
||||
<Row type="flex" justify="space-around" class="help">
|
||||
<el-row justify="space-around" class="help">
|
||||
<a class="item" :href="config.website" target="_blank">帮助</a>
|
||||
<a class="item" :href="config.website" target="_blank">隐私</a>
|
||||
<a class="item" :href="config.website" target="_blank">条款</a>
|
||||
</Row>
|
||||
<Row type="flex" justify="center" class="copyright">
|
||||
</el-row>
|
||||
<el-row justify="center" class="copyright">
|
||||
Copyright © {{ year }} - Present
|
||||
<a
|
||||
:href="config.website"
|
||||
class="href"
|
||||
target="_blank"
|
||||
style="margin: 0 5px"
|
||||
>{{ config.title }}</a
|
||||
>
|
||||
</Row>
|
||||
<a :href="config.website" class="href" target="_blank" style="margin: 0 5px">{{ config.title }}</a>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const config = require("@/config/index");
|
||||
export default {
|
||||
// name: "footer",
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
year: new Date().getFullYear(), // 年
|
||||
year: new Date().getFullYear(),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<Row class="header">
|
||||
<el-row class="header">
|
||||
<img :src="domainLogo" class="logo" width="220px" />
|
||||
</Row>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getBaseSite } from "@/api/common.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -22,44 +23,35 @@ export default {
|
||||
!localStorage.getItem("icontitle_expiration_time")
|
||||
) {
|
||||
this.getSite();
|
||||
} else if (new Date() > localStorage.getItem("icontitle_expiration_time")) {
|
||||
this.getSite();
|
||||
} else {
|
||||
// 如果缓存过期,则获取最新的信息
|
||||
if (new Date() > localStorage.getItem("icontitle_expiration_time")) {
|
||||
this.getSite();
|
||||
return;
|
||||
} else {
|
||||
this.domainLogo = localStorage.getItem("icon");
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = localStorage.getItem("icon");
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
window.document.title = localStorage.getItem("title") + " - 运营后台";
|
||||
}
|
||||
this.domainLogo = localStorage.getItem("icon");
|
||||
this.applyFavicon(localStorage.getItem("icon"));
|
||||
window.document.title = localStorage.getItem("title") + " - 运营后台";
|
||||
}
|
||||
},
|
||||
applyFavicon(href) {
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = href;
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
},
|
||||
getSite() {
|
||||
//获取domainLogo
|
||||
getBaseSite().then((res) => {
|
||||
const { domainLogo, domainIcon, siteName } = JSON.parse(res.result.settingValue);
|
||||
const { domainLogo, domainIcon, siteName } = JSON.parse(
|
||||
res.result.settingValue
|
||||
);
|
||||
this.domainLogo = domainLogo;
|
||||
// 过期时间
|
||||
var expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||
// 存放过期时间
|
||||
const expirationTime = new Date().setHours(new Date().getHours() + 1);
|
||||
localStorage.setItem("icontitle_expiration_time", expirationTime);
|
||||
// 存放信息
|
||||
localStorage.setItem("icon", domainLogo);
|
||||
localStorage.setItem("domainIcon", domainIcon);
|
||||
localStorage.setItem("title", siteName);
|
||||
let link =
|
||||
document.querySelector("link[rel*='icon']") ||
|
||||
document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.href = domainLogo;
|
||||
link.rel = "shortcut icon";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
this.applyFavicon(domainIcon || domainLogo);
|
||||
window.document.title = siteName + " - 运营后台";
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
<template>
|
||||
<div class="lang-icon">
|
||||
<Dropdown @on-click="langChange">
|
||||
<Icon type="md-globe" size="26"/>
|
||||
<DropdownMenu slot="list">
|
||||
<DropdownItem name="zh-CN">简体中文</DropdownItem>
|
||||
<DropdownItem name="en-US">English</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
<el-dropdown @command="langChange">
|
||||
<el-icon :size="26"><Platform /></el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="zh-CN">简体中文</el-dropdown-item>
|
||||
<el-dropdown-item command="en-US">English</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Platform } from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
name: "langSwitch",
|
||||
components: { Platform },
|
||||
methods: {
|
||||
langChange(v) {
|
||||
this.$i18n.locale = v;
|
||||
this.$store.commit("switchLang", v);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,81 +1,98 @@
|
||||
<template>
|
||||
<div class="message-con">
|
||||
<Dropdown trigger="click">
|
||||
|
||||
<a href="javascript:void(0)">
|
||||
<el-dropdown trigger="click" popper-class="todo-dropdown" @command="navigateTo">
|
||||
<a href="javascript:void(0)" class="message-link">
|
||||
{{ value > 0 ? "有" + value + "条待办事项" : "无待办事项" }}
|
||||
<Icon v-if="value!=0" type="ios-arrow-down"></Icon>
|
||||
<el-icon v-if="value != 0"><ArrowDown /></el-icon>
|
||||
</a>
|
||||
<DropdownMenu v-if="value!=0" slot="list">
|
||||
<DropdownItem v-if="res.balanceCash" @click.native="navigateTo('deposit')">
|
||||
<Badge :count="res.balanceCash">待处理预存款提现申请 </Badge>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="res.complain" @click.native="navigateTo('orderComplaint')">
|
||||
<Badge :count="res.complain">待处理投诉审核 </Badge>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="res.distributionCash" @click.native="navigateTo('distributionCash')">
|
||||
<Badge :count="res.distributionCash">待处理分销商提现申请 </Badge>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="res.goods" @click.native="navigateTo('applyGoods')">
|
||||
<Badge :count="res.goods">待处理商品审核 </Badge>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="res.refund" @click.native="navigateTo('afterSaleOrder')">
|
||||
<Badge :count="res.refund">待处理售后申请 </Badge>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="res.store" @click.native="navigateTo('shopAuth')">
|
||||
<Badge :count="res.store">待处理店铺入驻审核 </Badge>
|
||||
</DropdownItem>
|
||||
<DropdownItem v-if="res.waitPayBill" @click.native="navigateTo('accountStatementBill')">
|
||||
<Badge :count="res.waitPayBill">待与商家对账</Badge>
|
||||
</DropdownItem>
|
||||
<div></div>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu v-if="value != 0">
|
||||
<el-dropdown-item v-if="res.balanceCash" command="deposit">
|
||||
<el-badge :value="res.balanceCash">待处理预存款提现申请</el-badge>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="res.complain" command="orderComplaint">
|
||||
<el-badge :value="res.complain">待处理投诉审核</el-badge>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="res.distributionCash" command="distributionCash">
|
||||
<el-badge :value="res.distributionCash">待处理分销商提现申请</el-badge>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="res.goods" command="applyGoods">
|
||||
<el-badge :value="res.goods">待处理商品审核</el-badge>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="res.refund" command="afterSaleOrder">
|
||||
<el-badge :value="res.refund">待处理售后申请</el-badge>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="res.store" command="shopAuth">
|
||||
<el-badge :value="res.store">待处理店铺入驻审核</el-badge>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="res.waitPayBill" command="accountStatementBill">
|
||||
<el-badge :value="res.waitPayBill">待与商家对账</el-badge>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ArrowDown } from "@element-plus/icons-vue";
|
||||
|
||||
export default {
|
||||
name: "messageTip",
|
||||
data() {
|
||||
return {
|
||||
value: 0, // 消息数量
|
||||
empty: false, // 是否为空
|
||||
};
|
||||
},
|
||||
components: { ArrowDown },
|
||||
props: {
|
||||
res: {
|
||||
type: null,
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
computed: {
|
||||
value() {
|
||||
let count = 0;
|
||||
const r = this.res || {};
|
||||
Object.keys(r).forEach((k) => {
|
||||
if (r[k]) count += r[k];
|
||||
});
|
||||
return count;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
navigateTo(name) {
|
||||
this.$router.push({
|
||||
name,
|
||||
});
|
||||
},
|
||||
init() {
|
||||
Object.keys(this.res).forEach((item) => {
|
||||
this.value = parseInt(this.value) + parseInt(this.res[item]);
|
||||
});
|
||||
this.$router.push({ name });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
::v-deep .ivu-select-dropdown {
|
||||
text-align: left;
|
||||
}
|
||||
.message-con {
|
||||
margin-right: 10px;
|
||||
}
|
||||
::v-deep .ivu-dropdown-item{
|
||||
padding: 7px 20px !important;
|
||||
}
|
||||
::v-deep .ivu-badge-count{
|
||||
right: -10px !important;
|
||||
|
||||
<style scoped>
|
||||
.message-link {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.todo-dropdown .el-dropdown-menu__item {
|
||||
min-width: 150px;
|
||||
padding: 6px 36px 6px 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.todo-dropdown .el-dropdown-menu__item + .el-dropdown-menu__item {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.todo-dropdown .el-badge {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.todo-dropdown .el-badge__content.is-fixed {
|
||||
right: 4px;
|
||||
top: 8px;
|
||||
transform: translateY(-50%) translateX(50%);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
201
manager/src/views/main-parts/page-breadcrumb.vue
Normal file
201
manager/src/views/main-parts/page-breadcrumb.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<el-breadcrumb separator=">" class="page-breadcrumb">
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, idx) in items"
|
||||
:key="idx"
|
||||
>
|
||||
<a
|
||||
v-if="idx < items.length - 1 && item.target"
|
||||
class="bc-link"
|
||||
@click.prevent="go(item.target)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<span v-else :class="{ 'is-current': idx === items.length - 1 }">
|
||||
{{ item.title }}
|
||||
</span>
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { otherRouter } from "@/router/router";
|
||||
|
||||
const stripLayout = (name) => (name || "").replace(/__layout$/, "");
|
||||
|
||||
// 详情/二级页面归属的「列表/父页面」name 映射
|
||||
const PARENT_MAP = {
|
||||
"member-detail": "memberList",
|
||||
"order-detail": "orderList",
|
||||
"after-order-detail": "afterSale",
|
||||
"order-complaint-detail": "orderComplaint",
|
||||
"shop-detail": "shopList",
|
||||
"shop-operation": "shopList",
|
||||
"bill-detail": "bill",
|
||||
"goods-detail": "manager-goods",
|
||||
"goods-parameter-edit": "goods-parameter",
|
||||
"add-points-goods": "manager-points-goods",
|
||||
"edit-points-goods": "manager-points-goods",
|
||||
"coupon-receive": "manager-coupon",
|
||||
"add-platform-coupon": "manager-coupon",
|
||||
"edit-platform-coupon": "manager-coupon",
|
||||
"add-coupon-activity": "manager-coupon-activity",
|
||||
"edit-coupon-activity": "manager-coupon-activity",
|
||||
"coupon-activity-info": "manager-coupon-activity",
|
||||
"pintuan-goods": "manager-pintuan",
|
||||
"full-discount-detail": "manager-full-discount",
|
||||
"manager-seckill-add": "manager-seckill",
|
||||
"add-kanJia-activity-goods": "manager-kanjia",
|
||||
"edit-kanJia-activity-goods": "manager-kanjia",
|
||||
"add-gift-card-cash-activity": "manager-gift-card-cash",
|
||||
"edit-gift-card-cash-activity": "manager-gift-card-cash",
|
||||
"gift-card-cash-records": "manager-gift-card-cash",
|
||||
"gift-card-cash-batch-credentials": "manager-gift-card-cash",
|
||||
};
|
||||
|
||||
const findFirstLeaf = (group) => {
|
||||
if (!group || !Array.isArray(group.children) || !group.children.length) {
|
||||
return null;
|
||||
}
|
||||
const first = group.children.find((c) => c && c.name) || group.children[0];
|
||||
return stripLayout(first?.name) || null;
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "pageBreadcrumb",
|
||||
computed: {
|
||||
items() {
|
||||
const route = this.$route;
|
||||
if (!route || !route.name || route.name === "home_index") {
|
||||
return [{ title: "首页" }];
|
||||
}
|
||||
return this.buildChain(stripLayout(route.name));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
go(target) {
|
||||
if (!target || !target.name) return;
|
||||
if (this.$route.name === target.name) return;
|
||||
this.$router.push(target);
|
||||
},
|
||||
findInMenu(name) {
|
||||
const menuList = this.$store.state.app.menuList || [];
|
||||
for (const grp of menuList) {
|
||||
for (const child of grp.children || []) {
|
||||
if (stripLayout(child.name) === name) {
|
||||
return { group: grp, child };
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
routerEntry(name) {
|
||||
if (Array.isArray(otherRouter.children)) {
|
||||
return otherRouter.children.find((c) => c.name === name);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
topItem() {
|
||||
const navList = this.$store.state.app.navList || [];
|
||||
const menuList = this.$store.state.app.menuList || [];
|
||||
const currNavTitle = this.$store.state.app.currNavTitle;
|
||||
const firstName =
|
||||
this.$route.meta && this.$route.meta.firstRouterName;
|
||||
|
||||
let topTitle = currNavTitle;
|
||||
if (firstName) {
|
||||
const top = navList.find((n) => n.name === firstName);
|
||||
if (top) topTitle = top.title;
|
||||
}
|
||||
if (!topTitle) return null;
|
||||
|
||||
let target = null;
|
||||
if (menuList && menuList.length) {
|
||||
const leafName = findFirstLeaf(menuList[0]);
|
||||
if (leafName) target = { name: leafName };
|
||||
}
|
||||
return { title: topTitle, target };
|
||||
},
|
||||
buildChain(name, depth = 0) {
|
||||
if (depth > 6) return [];
|
||||
|
||||
const inMenu = this.findInMenu(name);
|
||||
if (inMenu) {
|
||||
const list = [];
|
||||
const top = this.topItem();
|
||||
if (top) list.push(top);
|
||||
const groupLeaf = findFirstLeaf(inMenu.group);
|
||||
list.push({
|
||||
title: inMenu.group.title,
|
||||
target: groupLeaf ? { name: groupLeaf } : null,
|
||||
});
|
||||
list.push({ title: inMenu.child.title });
|
||||
return list;
|
||||
}
|
||||
|
||||
const parentName = PARENT_MAP[name];
|
||||
const entry = this.routerEntry(name);
|
||||
const selfTitle = entry?.title
|
||||
? entry.title
|
||||
: (this.$route.meta && this.$route.meta.title
|
||||
? String(this.$route.meta.title).replace(/\s*-\s*.+$/, "")
|
||||
: "");
|
||||
|
||||
if (parentName) {
|
||||
const parentChain = this.buildChain(parentName, depth + 1).map(
|
||||
(it, idx, arr) =>
|
||||
idx === arr.length - 1
|
||||
? { title: it.title, target: { name: parentName } }
|
||||
: it
|
||||
);
|
||||
if (selfTitle) parentChain.push({ title: selfTitle });
|
||||
return parentChain;
|
||||
}
|
||||
|
||||
const list = [];
|
||||
const top = this.topItem();
|
||||
if (top) list.push(top);
|
||||
if (selfTitle) list.push({ title: selfTitle });
|
||||
return list;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-breadcrumb {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
line-height: 44px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
:deep(.el-breadcrumb__item) {
|
||||
.el-breadcrumb__inner {
|
||||
color: #606266;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.bc-link {
|
||||
color: #606266;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.is-current {
|
||||
color: $theme_color;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,27 +1,32 @@
|
||||
<template>
|
||||
<div class="ivu-shrinkable-menu">
|
||||
<!-- 一级菜单 -->
|
||||
<Menu ref="sideMenu" width="80px" theme="dark" :active-name="currNav" @on-select="selectNav">
|
||||
<MenuItem v-for="(item, i) in navList" :key="i" :name="item.name">
|
||||
{{item.title}}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<!-- 二级菜单 -->
|
||||
<Menu
|
||||
ref="childrenMenu"
|
||||
:active-name="$route.name"
|
||||
width="120px"
|
||||
@on-select="changeMenu"
|
||||
<div class="shrinkable-menu">
|
||||
<el-menu
|
||||
class="nav-menu-dark"
|
||||
:default-active="currNav"
|
||||
@select="selectNav"
|
||||
>
|
||||
<template v-for="item in menuList">
|
||||
<MenuGroup :title="item.title" :key="item.id" style="padding-left:0;">
|
||||
<MenuItem :name="menu.name" v-for="menu in item.children" :key="menu.name">
|
||||
{{menu.title}}
|
||||
</MenuItem>
|
||||
</MenuGroup>
|
||||
|
||||
<el-menu-item v-for="(item, i) in navList" :key="i" :index="item.name">
|
||||
{{ item.title }}
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-menu
|
||||
:key="currNav"
|
||||
class="sub-menu"
|
||||
:default-active="$route.name"
|
||||
@select="changeMenu"
|
||||
>
|
||||
<template v-for="item in menuList" :key="item.id">
|
||||
<el-menu-item-group :title="item.title">
|
||||
<el-menu-item
|
||||
v-for="menu in item.children"
|
||||
:key="menu.name"
|
||||
:index="menu.name"
|
||||
>
|
||||
{{ menu.title }}
|
||||
</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</template>
|
||||
</Menu>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -39,60 +44,80 @@ export default {
|
||||
},
|
||||
currNav() {
|
||||
return this.$store.state.app.currNav;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// 监听路由变化
|
||||
$route: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val.meta.firstRouterName && val.meta.firstRouterName !== this.currNav) {
|
||||
this.selectNav(val.meta.firstRouterName)
|
||||
}
|
||||
$route(val) {
|
||||
if (
|
||||
val.meta.firstRouterName &&
|
||||
val.meta.firstRouterName !== this.currNav
|
||||
) {
|
||||
this.selectNav(val.meta.firstRouterName);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
changeMenu(name) { //二级路由点击
|
||||
this.$router.push({
|
||||
name: name
|
||||
changeMenu(name) {
|
||||
if (!name) return;
|
||||
if (this.$router.hasRoute(name)) {
|
||||
this.$router.push({ name });
|
||||
return;
|
||||
}
|
||||
util.initRouter(this);
|
||||
this.$nextTick(() => {
|
||||
if (this.$router.hasRoute(name)) {
|
||||
this.$router.push({ name });
|
||||
} else {
|
||||
this.$Message.warning("菜单路由未就绪,请刷新页面后重试");
|
||||
}
|
||||
});
|
||||
},
|
||||
selectNav(name) { // 一级路由点击事件
|
||||
selectNav(name) {
|
||||
this.$store.commit("setCurrNav", name);
|
||||
this.setStore("currNav", name);
|
||||
util.initRouter(this);
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.childrenMenu.updateActiveName()
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ivu-shrinkable-menu{
|
||||
height: calc(100% - 60px);
|
||||
width: 200px;
|
||||
display: flex;
|
||||
.shrinkable-menu {
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ivu-btn-text:hover {
|
||||
background-color: rgba(255,255,255,.2) !important;
|
||||
.nav-menu-dark {
|
||||
width: 80px;
|
||||
background-color: #191a23;
|
||||
border-right: none;
|
||||
|
||||
:deep(.el-menu-item) {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
justify-content: center;
|
||||
padding: 0 8px !important;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
height: auto;
|
||||
min-height: 56px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
:deep(.el-menu-item.is-active) {
|
||||
background-color: #fff !important;
|
||||
color: $theme_color !important;
|
||||
}
|
||||
}
|
||||
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
|
||||
background-color: #fff;
|
||||
&:hover{
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.ivu-menu-vertical{
|
||||
|
||||
.sub-menu {
|
||||
width: 120px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu), .ivu-menu-dark.ivu-menu-vertical .ivu-menu-submenu-title-active:not(.ivu-menu-submenu){
|
||||
color: $theme_color;
|
||||
}
|
||||
::v-deep.ivu-menu-vertical .ivu-menu-item-group-title {
|
||||
height: 40px;
|
||||
border-right: none;
|
||||
|
||||
:deep(.el-menu-item-group__title) {
|
||||
padding-left: 16px;
|
||||
line-height: 40px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,31 +1,42 @@
|
||||
|
||||
|
||||
<template>
|
||||
|
||||
<div
|
||||
ref="scrollCon"
|
||||
@DOMMouseScroll="handlescroll"
|
||||
@mousewheel="handlescroll"
|
||||
class="tags-outer-scroll-con"
|
||||
>
|
||||
<ul v-show="visible" :style="{left: contextMenuLeft + 'px', top: contextMenuTop + 'px'}" class="contextmenu">
|
||||
<li v-for="(item, key) of actionList" @click="handleTagsOption(key)" :key="key">{{item}}</li>
|
||||
<ul
|
||||
v-show="visible"
|
||||
:style="{ left: contextMenuLeft + 'px', top: contextMenuTop + 'px' }"
|
||||
class="contextmenu"
|
||||
>
|
||||
<li
|
||||
v-for="(item, key) of actionList"
|
||||
:key="key"
|
||||
@click="handleTagsOption(key)"
|
||||
>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
<div ref="scrollBody" class="tags-inner-scroll-body" :style="{left: tagBodyLeft + 'px'}">
|
||||
<transition-group name="taglist-moving-animation">
|
||||
<Tag
|
||||
type="dot"
|
||||
v-for="item in pageTagsList"
|
||||
ref="tagsPageOpened"
|
||||
:key="item.name"
|
||||
:name="item.name"
|
||||
@on-close="closePage"
|
||||
@click.native="linkTo(item)"
|
||||
:closable="item.name=='home_index'?false:true"
|
||||
:color="item.children?(item.children[0].name==currentPageName?'primary':'default'):(item.name==currentPageName?'primary':'default')"
|
||||
@contextmenu.prevent.native="contextMenu(item, $event)"
|
||||
>{{ itemTitle(item) }}</Tag>
|
||||
</transition-group>
|
||||
<div
|
||||
ref="scrollBody"
|
||||
class="tags-inner-scroll-body"
|
||||
:style="{ left: tagBodyLeft + 'px' }"
|
||||
>
|
||||
<el-tag
|
||||
v-for="item in pageTagsList"
|
||||
:key="item.name"
|
||||
:closable="item.name !== 'home_index'"
|
||||
:type="tagType(item)"
|
||||
:effect="isActive(item) ? 'dark' : 'plain'"
|
||||
class="page-tag"
|
||||
size="large"
|
||||
@close="closePage($event, item.name)"
|
||||
@click="linkTo(item)"
|
||||
@contextmenu.prevent="contextMenu(item, $event)"
|
||||
>
|
||||
{{ itemTitle(item) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -33,197 +44,137 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "tagsPageOpened",
|
||||
data() {
|
||||
return {
|
||||
currentPageName: this.$route.name, // 当前路由名称
|
||||
tagBodyLeft: 0, // 标签左偏移量
|
||||
visible: false, // 显示操作按钮
|
||||
contextMenuLeft: 0, // 内容左偏移量
|
||||
contextMenuTop: 0, // 内容上偏移量
|
||||
actionList: {
|
||||
others: '关闭其他',
|
||||
clearAll: '关闭所有'
|
||||
},
|
||||
refsTag: [], // 所有已打开标签
|
||||
tagsCount: 1 // 标签数量
|
||||
};
|
||||
},
|
||||
props: {
|
||||
pageTagsList: Array,
|
||||
beforePush: {
|
||||
type: Function,
|
||||
default: item => {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.$store.state.app.currentTitle;
|
||||
default: () => true,
|
||||
},
|
||||
tagsList() {
|
||||
return this.$store.state.app.pageOpenedList;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentPageName: this.$route.name,
|
||||
tagBodyLeft: 0,
|
||||
visible: false,
|
||||
contextMenuLeft: 0,
|
||||
contextMenuTop: 0,
|
||||
actionList: {
|
||||
others: "关闭其他",
|
||||
clearAll: "关闭所有",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isActive(item) {
|
||||
return item.children
|
||||
? item.children[0].name === this.currentPageName
|
||||
: item.name === this.currentPageName;
|
||||
},
|
||||
tagType(item) {
|
||||
return this.isActive(item) ? "primary" : "info";
|
||||
},
|
||||
itemTitle(item) {
|
||||
if (typeof item.title == "object") {
|
||||
if (typeof item.title === "object") {
|
||||
return this.$t(item.title.i18n);
|
||||
} else {
|
||||
return item.title;
|
||||
}
|
||||
return item.title;
|
||||
},
|
||||
closePage(event, name) {
|
||||
let pageOpenedList = this.$store.state.app.pageOpenedList;
|
||||
let lastPageObj = pageOpenedList[0];
|
||||
if (this.currentPageName == name) {
|
||||
let len = pageOpenedList.length;
|
||||
if (this.currentPageName === name) {
|
||||
const len = pageOpenedList.length;
|
||||
for (let i = 1; i < len; i++) {
|
||||
if (pageOpenedList[i].name == name) {
|
||||
if (i < len - 1) {
|
||||
lastPageObj = pageOpenedList[i + 1];
|
||||
} else {
|
||||
lastPageObj = pageOpenedList[i - 1];
|
||||
}
|
||||
if (pageOpenedList[i].name === name) {
|
||||
lastPageObj =
|
||||
i < len - 1 ? pageOpenedList[i + 1] : pageOpenedList[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let tagWidth = event.target.parentNode.offsetWidth;
|
||||
} else if (event && event.target) {
|
||||
const tagWidth = event.target.parentNode?.offsetWidth || 0;
|
||||
this.tagBodyLeft = Math.min(this.tagBodyLeft + tagWidth, 0);
|
||||
}
|
||||
this.$store.commit("removeTag", name);
|
||||
this.$store.commit("closePage", name);
|
||||
pageOpenedList = this.$store.state.app.pageOpenedList;
|
||||
localStorage.pageOpenedList = JSON.stringify(pageOpenedList);
|
||||
if (this.currentPageName == name) {
|
||||
if (this.currentPageName === name) {
|
||||
this.linkTo(lastPageObj);
|
||||
}
|
||||
},
|
||||
linkTo(item) {
|
||||
if (this.$route.name == item.name) {
|
||||
return;
|
||||
}
|
||||
let routerObj = {};
|
||||
routerObj.name = item.name;
|
||||
if (item.argu) {
|
||||
routerObj.params = item.argu;
|
||||
}
|
||||
if (item.query) {
|
||||
routerObj.query = item.query;
|
||||
}
|
||||
if (this.$route.name === item.name) return;
|
||||
const routerObj = { name: item.name };
|
||||
if (item.argu) routerObj.params = item.argu;
|
||||
if (item.query) routerObj.query = item.query;
|
||||
if (this.beforePush(item)) {
|
||||
this.$router.push(routerObj);
|
||||
}
|
||||
},
|
||||
handlescroll(e) {
|
||||
var type = e.type;
|
||||
const type = e.type;
|
||||
let delta = 0;
|
||||
if (type == "DOMMouseScroll" || type == "mousewheel") {
|
||||
if (type === "DOMMouseScroll" || type === "mousewheel") {
|
||||
delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0) * 40;
|
||||
}
|
||||
let left = 0;
|
||||
if (delta > 0) {
|
||||
left = Math.min(0, this.tagBodyLeft + delta);
|
||||
} else {
|
||||
if ( this.$refs.scrollCon.offsetWidth - 100 < this.$refs.scrollBody.offsetWidth ) {
|
||||
if ( this.tagBodyLeft < -( this.$refs.scrollBody.offsetWidth - this.$refs.scrollCon.offsetWidth + 100 ) ) {
|
||||
left = this.tagBodyLeft;
|
||||
} else {
|
||||
left = Math.max(
|
||||
this.tagBodyLeft + delta,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
this.$refs.scrollBody.offsetWidth -
|
||||
100
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
this.$refs.scrollCon.offsetWidth - 100 <
|
||||
this.$refs.scrollBody.offsetWidth
|
||||
) {
|
||||
if (
|
||||
this.tagBodyLeft <
|
||||
-(this.$refs.scrollBody.offsetWidth - this.$refs.scrollCon.offsetWidth + 100)
|
||||
) {
|
||||
left = this.tagBodyLeft;
|
||||
} else {
|
||||
this.tagBodyLeft = 0;
|
||||
left = Math.max(
|
||||
this.tagBodyLeft + delta,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
this.$refs.scrollBody.offsetWidth -
|
||||
100
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.tagBodyLeft = 0;
|
||||
}
|
||||
this.tagBodyLeft = left;
|
||||
},
|
||||
handleTagsOption(type) {
|
||||
if (type == "clearAll") {
|
||||
if (type === "clearAll") {
|
||||
this.$store.commit("clearAllTags");
|
||||
this.$router.push({
|
||||
name: "home_index"
|
||||
});
|
||||
this.$router.push({ name: "home_index" });
|
||||
} else {
|
||||
this.$store.commit("clearOtherTags", this);
|
||||
}
|
||||
this.tagBodyLeft = 0;
|
||||
},
|
||||
moveToView(tag) {
|
||||
if (tag.offsetLeft < -this.tagBodyLeft) {
|
||||
// 标签在可视区域左侧
|
||||
this.tagBodyLeft = -tag.offsetLeft + 10;
|
||||
} else if (
|
||||
tag.offsetLeft + 10 > -this.tagBodyLeft &&
|
||||
tag.offsetLeft + tag.offsetWidth <
|
||||
-this.tagBodyLeft + this.$refs.scrollCon.offsetWidth - 100
|
||||
) {
|
||||
// 标签在可视区域
|
||||
this.tagBodyLeft = Math.min(
|
||||
0,
|
||||
this.$refs.scrollCon.offsetWidth -
|
||||
100 -
|
||||
tag.offsetWidth -
|
||||
tag.offsetLeft -
|
||||
20
|
||||
);
|
||||
} else {
|
||||
// 标签在可视区域右侧
|
||||
this.tagBodyLeft = -(
|
||||
tag.offsetLeft -
|
||||
(this.$refs.scrollCon.offsetWidth - 100 - tag.offsetWidth) +
|
||||
20
|
||||
);
|
||||
}
|
||||
contextMenu(item, e) {
|
||||
this.visible = true;
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left;
|
||||
this.contextMenuLeft = e.clientX - offsetLeft + 10;
|
||||
this.contextMenuTop = e.clientY - 64;
|
||||
},
|
||||
contextMenu (item, e) {
|
||||
this.visible = true
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left
|
||||
this.contextMenuLeft = e.clientX - offsetLeft + 10
|
||||
this.contextMenuTop = e.clientY - 64
|
||||
closeMenu() {
|
||||
this.visible = false;
|
||||
},
|
||||
closeMenu () {
|
||||
this.visible = false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.refsTag = this.$refs.tagsPageOpened;
|
||||
setTimeout(() => {
|
||||
this.refsTag.forEach((item, index) => {
|
||||
if (this.$route.name == item.name) {
|
||||
let tag = this.refsTag[index].$el;
|
||||
this.moveToView(tag);
|
||||
}
|
||||
});
|
||||
}, 1); // 这里不设定时器就会有偏移bug
|
||||
this.tagsCount = this.tagsList.length;
|
||||
},
|
||||
watch: {
|
||||
$route(to) {
|
||||
this.currentPageName = to.name;
|
||||
this.$nextTick(() => {
|
||||
this.refsTag.forEach((item, index) => {
|
||||
if (to.name == item.name) {
|
||||
let tag = this.refsTag[index].$el;
|
||||
this.moveToView(tag);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.tagsCount = this.tagsList.length;
|
||||
this.tagsCount = this.pageTagsList?.length;
|
||||
},
|
||||
visible (value) {
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.closeMenu)
|
||||
document.body.addEventListener("click", this.closeMenu);
|
||||
} else {
|
||||
document.body.removeEventListener('click', this.closeMenu)
|
||||
document.body.removeEventListener("click", this.closeMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -237,7 +188,7 @@ export default {
|
||||
z-index: 11000;
|
||||
list-style-type: none;
|
||||
border-radius: 4px;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .1);
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.1);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 5px 15px;
|
||||
@@ -247,7 +198,25 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.ivu-tag-primary, .ivu-tag-primary.ivu-tag-dot .ivu-tag-dot-inner{
|
||||
background: $theme_color;
|
||||
.page-tag {
|
||||
margin-right: 8px;
|
||||
cursor: pointer;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
& + .page-tag {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.el-tag__close {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
}
|
||||
|
||||
.sidebar-menu-con {
|
||||
height: 100%;
|
||||
height: calc(100% - 60px);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
z-index: 21;
|
||||
transition: width 0.3s; // background: rgb(73, 80, 96)
|
||||
background: #fff;
|
||||
box-shadow: rgba(0, 21, 41, 0.35) 2px 0px 6px;
|
||||
box-shadow: rgba(0, 21, 41, 0.12) 2px 0 6px;
|
||||
}
|
||||
|
||||
.layout-text {
|
||||
@@ -52,11 +52,11 @@
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
display: block;
|
||||
padding-left: 200px;
|
||||
padding-left: 0;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
z-index: 20;
|
||||
box-shadow: 0 2px 1px 1px rgba(100, 100, 100, 0.1);
|
||||
height: 60px;
|
||||
z-index: 22;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
|
||||
transition: padding 0.3s;
|
||||
}
|
||||
|
||||
@@ -81,22 +81,29 @@
|
||||
}
|
||||
|
||||
.tags-con {
|
||||
height: 40px;
|
||||
height: 44px;
|
||||
z-index: -1;
|
||||
background: #f0f0f0;
|
||||
background: #fff;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
.tags-outer-scroll-con {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding-right: 120px;
|
||||
padding-right: 12px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.tags-inner-scroll-body {
|
||||
position: absolute;
|
||||
padding: 2px 10px;
|
||||
padding: 0 6px;
|
||||
overflow: visible;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
transition: left 0.3s ease;
|
||||
}
|
||||
|
||||
@@ -119,15 +126,34 @@
|
||||
min-width: 740px;
|
||||
height: 60px;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 1px 1px rgba(100, 100, 100, 0.1);
|
||||
position: relative;
|
||||
z-index: 11;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.navicon-con {
|
||||
margin: 6px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header-logo-con {
|
||||
flex-shrink: 0;
|
||||
width: 200px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-left: 12px;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-height: 44px;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.header-middle-con {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
@@ -146,7 +172,8 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 30px;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-end;
|
||||
margin-left: auto;
|
||||
height: 100%;
|
||||
|
||||
|
||||
@@ -162,9 +189,9 @@
|
||||
|
||||
|
||||
.message-con {
|
||||
display: inline-block;
|
||||
|
||||
padding: 18px 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -215,15 +242,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-bar {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 212px;
|
||||
right: 0;
|
||||
height: 44px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
z-index: 19;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.single-page-con {
|
||||
min-width: 740px;
|
||||
position: relative;
|
||||
left: 220px;
|
||||
left: 200px;
|
||||
top: 100px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: calc(100% - 110px);
|
||||
width: calc(100% - 220px);
|
||||
width: calc(100% - 200px);
|
||||
overflow: auto;
|
||||
background-color: #f0f0f0;
|
||||
z-index: 1;
|
||||
@@ -231,7 +272,7 @@
|
||||
|
||||
.single-page {
|
||||
position: relative;
|
||||
margin: 10px;
|
||||
margin: 10px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,15 +288,7 @@
|
||||
}
|
||||
|
||||
.logo-con {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
img {
|
||||
height: 44px;
|
||||
width: auto;
|
||||
}
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-bar {
|
||||
|
||||
@@ -1,208 +1,163 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="充值单号" prop="rechargeSn">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="充值单号" prop="rechargeSn">
|
||||
<el-input
|
||||
v-model="searchForm.rechargeSn"
|
||||
placeholder="请输入充值单号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="支付时间">
|
||||
<DatePicker
|
||||
</el-form-item>
|
||||
<el-form-item label="支付时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
@on-change="selectDateRange"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 240px"
|
||||
></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
style="width: 360px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<el-table
|
||||
v-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"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="rechargeSn" label="订单号" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="充值金额" width="160" sortable>
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.rechargeMoney" :color="$mainColor" unit="+" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="充值方式" width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ rechargeWayText(row.rechargeWay) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.payStatus === 'PAID' ? 'success' : 'danger'">
|
||||
{{ row.payStatus === "PAID" ? "已付款" : "未付款" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="充值时间" width="190" />
|
||||
<el-table-column prop="payTime" label="支付时间" width="190" />
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUserRecharge,
|
||||
} from "@/api/member";
|
||||
export default {
|
||||
name: "recharge",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
memberName:""
|
||||
},
|
||||
selectDate: null, // 选择区间时间
|
||||
columns: [
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 120,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "订单号",
|
||||
key: "rechargeSn",
|
||||
minWidth: 180,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "充值金额",
|
||||
key: "rechargeMoney",
|
||||
width: 160,
|
||||
sortable: true,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.rechargeMoney,color:this.$mainColor,unit:"+"}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "充值方式",
|
||||
key: "rechargeWay",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.rechargeWay === 'ALIPAY') {
|
||||
return h('div', [h('span', {}, '支付宝')]);
|
||||
} else if (params.row.rechargeWay === 'WECHAT') {
|
||||
return h('div', [h('span', {}, '微信')]);
|
||||
} else if (params.row.rechargeWay === 'BANK_TRANSFER') {
|
||||
return h('div', [h('span', {}, '线下转账')]);
|
||||
} else {
|
||||
return h('div', [h('span', {}, '')]);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "支付状态",
|
||||
key: "payStatus",
|
||||
align: "left",
|
||||
width: 120,
|
||||
sortable: false,
|
||||
render: (h, params) => {
|
||||
if (params.row.payStatus == "PAID") {
|
||||
return h("Tag", {props: {color: "green",},}, "已付款");
|
||||
} else {
|
||||
return h("Tag", {props: {color: "red",},}, "未付款");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "充值时间",
|
||||
key: "createTime",
|
||||
align: "left",
|
||||
width: 190,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "支付时间",
|
||||
key: "payTime",
|
||||
align: "left",
|
||||
width: 190,
|
||||
sortable: false,
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
};
|
||||
import { getUserRecharge } from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "recharge",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
},
|
||||
selectDate: null,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
rechargeWayText(way) {
|
||||
if (way === "ALIPAY") return "支付宝";
|
||||
if (way === "WECHAT") return "微信";
|
||||
if (way === "BANK_TRANSFER") return "线下转账";
|
||||
return "";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 时间段赋值
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getUserRecharge(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
selectDateRange(v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getUserRecharge(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,132 +1,148 @@
|
||||
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="支付时间">
|
||||
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd HH:mm:ss" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]"
|
||||
size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 360px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="100" />
|
||||
<el-table-column label="变动金额" width="150">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<priceColorScheme
|
||||
v-if="row.money > 0"
|
||||
:value="row.money"
|
||||
color="green"
|
||||
/>
|
||||
<priceColorScheme
|
||||
v-else-if="row.money < 0"
|
||||
:value="row.money"
|
||||
:color="$mainColor"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="变更时间" width="200" />
|
||||
<el-table-column label="业务类型" width="200">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ serviceTypeText(row.serviceType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="detail" label="详细" min-width="300" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserWallet } from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "walletLog",
|
||||
data() {
|
||||
return {
|
||||
loading: true, // 表单加载状态
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
memberName: "",
|
||||
},
|
||||
selectDate: null, // 选择时间段
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "变动金额",
|
||||
key: "money",
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
if (params.row.money >0) {
|
||||
return h("priceColorScheme", {props:{value:params.row.money,color:'green'}} );
|
||||
} else if (params.row.money < 0) {
|
||||
return h("priceColorScheme", {props:{value:params.row.money,color:this.$mainColor}} );
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "变更时间",
|
||||
key: "createTime",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "业务类型",
|
||||
key: "serviceType",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
if (params.row.serviceType == "WALLET_WITHDRAWAL") {
|
||||
return h("div", [h("span", {}, "余额提现")]);
|
||||
} else if (params.row.serviceType == "WALLET_PAY") {
|
||||
return h("div", [h("span", {}, "余额支付")]);
|
||||
} else if (params.row.serviceType == "WALLET_REFUND") {
|
||||
return h("div", [h("span", {}, "余额退款")]);
|
||||
} else if (params.row.serviceType == "WALLET_RECHARGE") {
|
||||
return h("div", [h("span", {}, "余额充值")]);
|
||||
} else {
|
||||
return h("div", [h("span", {}, "佣金提成")]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "详细",
|
||||
key: "detail",
|
||||
minWidth: 300,
|
||||
tooltip: true,
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
},
|
||||
selectDate: null,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
serviceTypeText(type) {
|
||||
if (type === "WALLET_WITHDRAWAL") return "余额提现";
|
||||
if (type === "WALLET_PAY") return "余额支付";
|
||||
if (type === "WALLET_REFUND") return "余额退款";
|
||||
if (type === "WALLET_RECHARGE") return "余额充值";
|
||||
return "佣金提成";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 时间段赋值
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
// 获取列表数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getUserWallet(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
@@ -134,8 +150,6 @@ export default {
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -1,102 +1,171 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
|
||||
</Form-item>
|
||||
<Form-item label="提现状态" prop="applyStatus">
|
||||
<Select v-model="searchForm.applyStatus" clearable style="width: 240px">
|
||||
<Option value="APPLY">申请中</Option>
|
||||
<Option value="VIA_AUDITING">审核通过</Option>
|
||||
<Option value="WAIT_USER_CONFIRM">用户确认</Option>
|
||||
<Option value="FAIL_AUDITING">审核拒绝</Option>
|
||||
<Option value="SUCCESS">提现成功</Option>
|
||||
<Option value="ERROR">提现失败</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="申请时间">
|
||||
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd HH:mm:ss" clearable @on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
|
||||
</Form-item>
|
||||
<Form-item style="margin-left: -35px" class="br">
|
||||
<Button @click="handleSearch" type="primary" icon="ios-search">搜索
|
||||
</Button>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table class="mt_10" :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom" @on-sort-change="changeSort" @on-selection-change="changeSelect"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal :title="modalTitle" v-model="roleModalVisible" :mask-closable="false" :width="500">
|
||||
<Form :label-width="80">
|
||||
<FormItem label="申请编号">
|
||||
<span>{{showList.sn}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="用户名称">
|
||||
<span>{{showList.memberName}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="申请金额">
|
||||
<priceColorScheme :value="showList.applyMoney" :color="$mainColor"></priceColorScheme>
|
||||
</FormItem>
|
||||
<FormItem label="提现状态">
|
||||
<span>{{showList.applyStatus | paramTypeFilter}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="申请时间">
|
||||
<span>{{showList.createTime}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="审核备注">
|
||||
<Input v-model="audit" type="textarea" />
|
||||
</FormItem>
|
||||
|
||||
</Form>
|
||||
<div slot="footer" v-if="showList.applyStatus == 'APPLY'">
|
||||
<Button type="text" @click="submitRole(false)">拒绝</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="submitRole(true)">通过
|
||||
</Button>
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="提现状态" prop="applyStatus">
|
||||
<el-select v-model="searchForm.applyStatus" clearable style="width: 240px">
|
||||
<el-option label="申请中" value="APPLY" />
|
||||
<el-option label="审核通过" value="VIA_AUDITING" />
|
||||
<el-option label="用户确认" value="WAIT_USER_CONFIRM" />
|
||||
<el-option label="审核拒绝" value="FAIL_AUDITING" />
|
||||
<el-option label="提现成功" value="SUCCESS" />
|
||||
<el-option label="提现失败" value="ERROR" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请时间">
|
||||
<el-date-picker
|
||||
v-model="selectDate"
|
||||
type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placeholder="选择起始时间"
|
||||
style="width: 360px"
|
||||
@change="selectDateRange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
@sort-change="changeSort"
|
||||
@selection-change="changeSelect"
|
||||
>
|
||||
<el-table-column prop="sn" label="申请编号" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="memberName" label="用户名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="申请金额" width="120">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.applyMoney" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提现状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="applyStatusTagType(row.applyStatus)">
|
||||
{{ applyStatusText(row.applyStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="申请时间" width="170" sortable="custom" />
|
||||
<el-table-column prop="inspectTime" label="审核时间" width="170" />
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" v-if="row.applyStatus === 'APPLY'" @click="openAudit(row)">审核</a>
|
||||
<a class="link-text" v-else @click="openQuery(row)">查看</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<Modal :title="modalTitle" v-model="queryModalVisible" :mask-closable="false" :width="500">
|
||||
<Form :label-width="80">
|
||||
<FormItem label="申请编号:">
|
||||
<span>{{showList.sn}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="用户名称:">
|
||||
<span>{{showList.memberName}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="申请金额:">
|
||||
<priceColorScheme :value="showList.applyMoney" :color="$mainColor"></priceColorScheme>
|
||||
<el-dialog
|
||||
v-model="roleModalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form label-width="80px">
|
||||
<el-form-item label="申请编号">
|
||||
<span>{{ showList.sn }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称">
|
||||
<span>{{ showList.memberName }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请金额">
|
||||
<priceColorScheme :value="showList.applyMoney" :color="$mainColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="提现状态">
|
||||
<span>{{ paramTypeFilter(showList.applyStatus) }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请时间">
|
||||
<span>{{ showList.createTime }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核备注">
|
||||
<el-input v-model="audit" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<template v-if="showList.applyStatus === 'APPLY'">
|
||||
<el-button @click="submitRole(false)">拒绝</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitRole(true)">通过</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</FormItem>
|
||||
<FormItem label="提现状态:">
|
||||
<span>{{showList.applyStatus | paramTypeFilter}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="申请时间:">
|
||||
<span>{{showList.createTime}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="审核时间:">
|
||||
<span>{{showList.inspectTime}}</span>
|
||||
</FormItem>
|
||||
<FormItem label="审核备注:">
|
||||
<span>{{showList.inspectRemark || '暂无备注'}}</span>
|
||||
</FormItem>
|
||||
|
||||
</Form>
|
||||
<div slot="footer" v-if="showList.applyStatus == 'APPLY'">
|
||||
<Button type="text" @click="submitRole(false)">拒绝</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="submitRole(true)">通过
|
||||
</Button>
|
||||
</div>
|
||||
<div slot="footer" v-else>
|
||||
<Button type="text" @click="queryModalVisible = false">取消</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-dialog
|
||||
v-model="queryModalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="申请编号:">
|
||||
<span>{{ showList.sn }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称:">
|
||||
<span>{{ showList.memberName }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请金额:">
|
||||
<priceColorScheme :value="showList.applyMoney" :color="$mainColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="提现状态:">
|
||||
<span>{{ paramTypeFilter(showList.applyStatus) }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="申请时间:">
|
||||
<span>{{ showList.createTime }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核时间:">
|
||||
<span>{{ showList.inspectTime }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核备注:">
|
||||
<span>{{ showList.inspectRemark || "暂无备注" }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<template v-if="showList.applyStatus === 'APPLY'">
|
||||
<el-button @click="submitRole(false)">拒绝</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitRole(true)">通过</el-button>
|
||||
</template>
|
||||
<el-button v-else @click="queryModalVisible = false">取消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,169 +174,68 @@ import { getUserWithdrawApply, withdrawApply } from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "withdrawApply",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
modalTitle: "", //弹出框标题
|
||||
openSearch: true, // 显示搜索
|
||||
openTip: true, // 显示提示
|
||||
loading: true, // 表单加载状态
|
||||
audit: "", // 审核备注
|
||||
roleModalVisible: false, // 审核模态框
|
||||
queryModalVisible: false, // 审核模态框
|
||||
modalTitle: "",
|
||||
loading: true,
|
||||
audit: "",
|
||||
roleModalVisible: false,
|
||||
queryModalVisible: false,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
memberName: "",
|
||||
applyStatus: "",
|
||||
},
|
||||
selectDate: null, // 选择时间段
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
selectList: [], // 多选数据
|
||||
selectCount: 0, // 多选计数
|
||||
showList: {}, // 可操作选项
|
||||
columns: [
|
||||
{
|
||||
title: "申请编号",
|
||||
key: "sn",
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "用户名称",
|
||||
key: "memberName",
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "申请金额",
|
||||
key: "applyMoney",
|
||||
align: "left",
|
||||
width: 120,
|
||||
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.applyMoney,color:this.$mainColor}} );
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
{
|
||||
title: "提现状态",
|
||||
align: "left",
|
||||
key: "applyStatus",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.applyStatus == "APPLY") {
|
||||
return h("Tag", { props: { color: "volcano" } }, "申请中");
|
||||
} else if (params.row.applyStatus == "VIA_AUDITING") {
|
||||
return h("Tag", { props: { color: "green" } }, "审核通过");
|
||||
} else if (params.row.applyStatus == "WAIT_USER_CONFIRM") {
|
||||
return h("Tag", { props: { color: "gold" } }, "用户确认");
|
||||
} else if (params.row.applyStatus == "SUCCESS") {
|
||||
return h("Tag", { props: { color: "blue" } }, "提现成功");
|
||||
} else if (params.row.applyStatus == "ERROR") {
|
||||
return h("Tag", { props: { color: "blue" } }, "提现失败");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "red" } }, "审核拒绝");
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "申请时间",
|
||||
key: "createTime",
|
||||
align: "left",
|
||||
width: 170,
|
||||
},
|
||||
{
|
||||
title: "审核时间",
|
||||
key: "inspectTime",
|
||||
align: "left",
|
||||
width: 170,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 120,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
if (params.row.applyStatus == "APPLY") {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showList = {};
|
||||
this.roleModalVisible = true;
|
||||
this.showList = params.row;
|
||||
this.audit = "";
|
||||
},
|
||||
},
|
||||
},
|
||||
"审核"
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showList = {};
|
||||
this.queryModalVisible = true;
|
||||
this.showList = params.row;
|
||||
this.modalTitle = "查看";
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
selectDate: null,
|
||||
submitLoading: false,
|
||||
selectList: [],
|
||||
selectCount: 0,
|
||||
showList: {},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
filters: {
|
||||
paramTypeFilter(val) {
|
||||
if (val === "APPLY") {
|
||||
return "申请中";
|
||||
} else if (val === "VIA_AUDITING") {
|
||||
return "审核通过(提现成功)";
|
||||
} else if (val === "WAIT_USER_CONFIRM") {
|
||||
return "用户确认";
|
||||
} else if (val === "FAIL_AUDITING") {
|
||||
return "审核拒绝";
|
||||
} else if (val === "SUCCESS") {
|
||||
return "提现成功";
|
||||
} else if (val === "ERROR") {
|
||||
return "提现失败";
|
||||
} else {
|
||||
return "未知状态";
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
paramTypeFilter(val) {
|
||||
if (val === "APPLY") return "申请中";
|
||||
if (val === "VIA_AUDITING") return "审核通过(提现成功)";
|
||||
if (val === "WAIT_USER_CONFIRM") return "用户确认";
|
||||
if (val === "FAIL_AUDITING") return "审核拒绝";
|
||||
if (val === "SUCCESS") return "提现成功";
|
||||
if (val === "ERROR") return "提现失败";
|
||||
return "未知状态";
|
||||
},
|
||||
applyStatusText(status) {
|
||||
if (status === "APPLY") return "申请中";
|
||||
if (status === "VIA_AUDITING") return "审核通过";
|
||||
if (status === "WAIT_USER_CONFIRM") return "用户确认";
|
||||
if (status === "SUCCESS") return "提现成功";
|
||||
if (status === "ERROR") return "提现失败";
|
||||
return "审核拒绝";
|
||||
},
|
||||
applyStatusTagType(status) {
|
||||
if (status === "APPLY") return "warning";
|
||||
if (status === "VIA_AUDITING") return "success";
|
||||
if (status === "WAIT_USER_CONFIRM") return "warning";
|
||||
if (status === "SUCCESS") return "primary";
|
||||
if (status === "ERROR") return "primary";
|
||||
return "danger";
|
||||
},
|
||||
openAudit(row) {
|
||||
this.showList = { ...row };
|
||||
this.audit = "";
|
||||
this.roleModalVisible = true;
|
||||
},
|
||||
openQuery(row) {
|
||||
this.showList = { ...row };
|
||||
this.modalTitle = "查看";
|
||||
this.queryModalVisible = true;
|
||||
},
|
||||
submitRole(res) {
|
||||
const params = {};
|
||||
params.applyId = this.showList.id;
|
||||
@@ -319,33 +287,36 @@ export default {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
this.searchForm.memberName = "";
|
||||
// 重新加载数据
|
||||
this.getDataList();
|
||||
},
|
||||
changeSort(e) {
|
||||
this.searchForm.sort = e.key;
|
||||
this.searchForm.order = e.order;
|
||||
if (e.order === "normal") {
|
||||
this.searchForm.sort = e.prop || e.key;
|
||||
this.searchForm.order = e.order === "ascending" ? "asc" : e.order === "descending" ? "desc" : "";
|
||||
if (!e.order) {
|
||||
this.searchForm.order = "";
|
||||
}
|
||||
this.getDataList();
|
||||
},
|
||||
clearSelectAll() {
|
||||
this.$refs.table.selectAll(false);
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.clearSelection();
|
||||
}
|
||||
},
|
||||
changeSelect(e) {
|
||||
this.selectList = e;
|
||||
this.selectCount = e.length;
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
if (v && v.length === 2) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
} else {
|
||||
this.searchForm.startDate = "";
|
||||
this.searchForm.endDate = "";
|
||||
}
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据 请自行修改接口
|
||||
getUserWithdrawApply(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
@@ -353,8 +324,6 @@ export default {
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
@@ -374,4 +343,3 @@ export default {
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,42 +1,90 @@
|
||||
<template>
|
||||
<div class="search member-benefit">
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button type="primary" @click="openAdd">添加权益设置</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="openAdd">添加权益设置</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
stripe
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
no-data-text="暂无数据"
|
||||
empty-text="暂无数据"
|
||||
class="mt_10 benefit-list-table benefit-list-table--no-vertical-borders"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="权益类型" width="132">
|
||||
<template #default="{ row }">
|
||||
<span
|
||||
v-if="row"
|
||||
:title="benefitTypeLabel(row.benefitType)"
|
||||
class="benefit-list-cell-ellipsis benefit-list-cell-ellipsis--type"
|
||||
>
|
||||
{{ benefitTypeLabel(row.benefitType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="权益名称" width="188">
|
||||
<template #default="{ row }">
|
||||
<span
|
||||
v-if="row"
|
||||
:title="row.benefitName || '-'"
|
||||
class="benefit-list-cell-ellipsis benefit-list-cell-ellipsis--name"
|
||||
>
|
||||
{{ row.benefitName || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="权益LOGO" width="116" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row && !row.benefitLogo">-</span>
|
||||
<div v-else-if="row" class="benefit-logo-thumb benefit-logo-thumb--table">
|
||||
<img :src="row.benefitLogo" alt="" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="118" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
:model-value="row.benefitState === 'OPEN'"
|
||||
inline-prompt
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
:loading="!!row._benefitStateLoading"
|
||||
@change="(checked) => onBenefitStateSwitch(row, checked)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="140">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops" style="display: flex; justify-content: center">
|
||||
<a class="link-text" @click="openEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 30, 50]"
|
||||
:page-sizes="[20, 30, 50]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 平台优惠券选择(与「添加优惠券活动」coupon-publish 相同组件) -->
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="couponPickerVisible"
|
||||
title="选择优惠券"
|
||||
width="80%"
|
||||
:z-index="3000"
|
||||
:mask-closable="false"
|
||||
@on-ok="handleCouponPickerClose"
|
||||
@on-cancel="handleCouponPickerClose"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@close="handleCouponPickerClose"
|
||||
>
|
||||
<couponTemplate
|
||||
v-if="couponPickerVisible"
|
||||
@@ -45,38 +93,41 @@
|
||||
promotionStatus="START"
|
||||
@selected="onCouponTemplateSelected"
|
||||
/>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
|
||||
<Drawer
|
||||
<el-drawer
|
||||
v-model="addFlag"
|
||||
title="添加权益设置"
|
||||
width="1120"
|
||||
placement="right"
|
||||
size="1120px"
|
||||
direction="rtl"
|
||||
:z-index="950"
|
||||
:mask-closable="false"
|
||||
:closable="true"
|
||||
scrollable
|
||||
class-name="benefit-form-drawer"
|
||||
:close-on-click-modal="false"
|
||||
class="benefit-form-drawer"
|
||||
>
|
||||
<Form ref="addForm" :model="formAdd" :rules="rulesAdd" :label-width="110">
|
||||
<FormItem label="权益类型" prop="benefitType">
|
||||
<Select
|
||||
<el-form ref="addForm" :model="formAdd" :rules="rulesAdd" label-width="110px">
|
||||
<el-form-item label="权益类型" prop="benefitType">
|
||||
<el-select
|
||||
v-model="formAdd.benefitType"
|
||||
clearable
|
||||
placeholder="请选择权益类型"
|
||||
style="width: 100%"
|
||||
@on-change="onAddBenefitTypeChange"
|
||||
@change="onAddBenefitTypeChange"
|
||||
>
|
||||
<Option v-for="item in benefitTypeOptions" :key="item.value" :value="item.value">{{ item.description }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
<el-option
|
||||
v-for="item in benefitTypeOptions"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.description"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-show="formAdd.benefitType === 'GIFT_POINT'"
|
||||
label="赠送积分"
|
||||
prop="giftPoint"
|
||||
:required="formAdd.benefitType === 'GIFT_POINT'"
|
||||
>
|
||||
<InputNumber
|
||||
<el-input-number
|
||||
v-model="formAdd.giftPoint"
|
||||
:min="0"
|
||||
:max="99999"
|
||||
@@ -84,28 +135,54 @@
|
||||
style="width: 220px"
|
||||
placeholder="必填,范围 0-99999"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-show="formAdd.benefitType === 'COUPON_PACKAGE'"
|
||||
label="赠送优惠券"
|
||||
prop="couponPackageRows"
|
||||
:required="formAdd.benefitType === 'COUPON_PACKAGE'"
|
||||
>
|
||||
<div>
|
||||
<Button type="dashed" icon="ios-add" class="mb_10" @click="openCouponPicker('add')">添加优惠券</Button>
|
||||
<Table
|
||||
<el-button plain class="mb_10" @click="openCouponPicker('add')">添加优惠券</el-button>
|
||||
<el-table
|
||||
border
|
||||
size="small"
|
||||
:columns="couponPackageTableColumns"
|
||||
:data="formAdd.couponPackageRows"
|
||||
no-data-text="请添加优惠券"
|
||||
></Table>
|
||||
empty-text="请添加优惠券"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="couponName" label="优惠券名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="有效期" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" v-html="row.validRange || '-'" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="faceValueLabel" label="面额" min-width="100" />
|
||||
<el-table-column label="赠送张数" width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-input-number
|
||||
v-if="row"
|
||||
:model-value="row.quantity"
|
||||
:min="1"
|
||||
:max="10"
|
||||
:precision="0"
|
||||
style="width: 100px"
|
||||
@change="(val) => onCouponQuantityChange('add', $index, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<a v-if="row" class="link-text" @click="removeCouponRow('add', $index)">删除</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="权益名称" prop="benefitName">
|
||||
<Input v-model="formAdd.benefitName" maxlength="50" placeholder="请输入权益名称" />
|
||||
</FormItem>
|
||||
<FormItem label="权益LOGO" prop="benefitLogo">
|
||||
</el-form-item>
|
||||
<el-form-item label="权益名称" prop="benefitName">
|
||||
<el-input v-model="formAdd.benefitName" maxlength="50" placeholder="请输入权益名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权益LOGO" prop="benefitLogo">
|
||||
<div class="benefit-logo-field">
|
||||
<div v-if="formAdd.benefitLogo" class="benefit-logo-thumb">
|
||||
<img :src="formAdd.benefitLogo" alt="" />
|
||||
@@ -114,57 +191,60 @@
|
||||
<upload-pic-input v-model="formAdd.benefitLogo" placeholder="请上传权益 LOGO 图片地址" style="width: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="权益介绍" prop="benefitDesc">
|
||||
<Input v-model="formAdd.benefitDesc" type="textarea" :rows="4" maxlength="500" placeholder="请输入权益介绍" />
|
||||
</FormItem>
|
||||
<FormItem label="启用状态" prop="benefitState">
|
||||
<RadioGroup v-model="formAdd.benefitState">
|
||||
<Radio label="OPEN">开启</Radio>
|
||||
<Radio label="CLOSE">关闭</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="排序" prop="benefitSort">
|
||||
<InputNumber v-model="formAdd.benefitSort" :min="1" :max="9999" :precision="0" style="width: 220px" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
<el-form-item label="权益介绍" prop="benefitDesc">
|
||||
<el-input v-model="formAdd.benefitDesc" type="textarea" :rows="4" maxlength="500" placeholder="请输入权益介绍" />
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态" prop="benefitState">
|
||||
<el-radio-group v-model="formAdd.benefitState">
|
||||
<el-radio value="OPEN">开启</el-radio>
|
||||
<el-radio value="CLOSE">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="benefitSort">
|
||||
<el-input-number v-model="formAdd.benefitSort" :min="1" :max="9999" :precision="0" style="width: 220px" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="benefit-drawer-footer-btns">
|
||||
<Button @click="addFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitAddLoading" @click="submitAdd">提交</Button>
|
||||
<el-button @click="addFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitAddLoading" @click="submitAdd">提交</el-button>
|
||||
</div>
|
||||
</Drawer>
|
||||
</el-drawer>
|
||||
|
||||
<Drawer
|
||||
<el-drawer
|
||||
v-model="editFlag"
|
||||
title="编辑权益设置"
|
||||
width="1120"
|
||||
placement="right"
|
||||
size="1120px"
|
||||
direction="rtl"
|
||||
:z-index="950"
|
||||
:mask-closable="false"
|
||||
:closable="true"
|
||||
scrollable
|
||||
class-name="benefit-form-drawer"
|
||||
:close-on-click-modal="false"
|
||||
class="benefit-form-drawer"
|
||||
>
|
||||
<Form ref="editForm" :model="formEdit" :rules="rulesEdit" :label-width="110">
|
||||
<Input v-model="formEdit.id" v-show="false" />
|
||||
<FormItem label="权益类型" prop="benefitType">
|
||||
<Select
|
||||
<el-form ref="editForm" :model="formEdit" :rules="rulesEdit" label-width="110px">
|
||||
<el-input v-model="formEdit.id" v-show="false" />
|
||||
<el-form-item label="权益类型" prop="benefitType">
|
||||
<el-select
|
||||
v-model="formEdit.benefitType"
|
||||
clearable
|
||||
placeholder="请选择权益类型"
|
||||
style="width: 100%"
|
||||
@on-change="onEditBenefitTypeChange"
|
||||
@change="onEditBenefitTypeChange"
|
||||
>
|
||||
<Option v-for="item in benefitTypeOptions" :key="item.value" :value="item.value">{{ item.description }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
<el-option
|
||||
v-for="item in benefitTypeOptions"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.description"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-show="formEdit.benefitType === 'GIFT_POINT'"
|
||||
label="赠送积分"
|
||||
prop="giftPoint"
|
||||
:required="formEdit.benefitType === 'GIFT_POINT'"
|
||||
>
|
||||
<InputNumber
|
||||
<el-input-number
|
||||
v-model="formEdit.giftPoint"
|
||||
:min="0"
|
||||
:max="99999"
|
||||
@@ -172,28 +252,54 @@
|
||||
style="width: 220px"
|
||||
placeholder="必填,范围 0-99999"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-show="formEdit.benefitType === 'COUPON_PACKAGE'"
|
||||
label="赠送优惠券"
|
||||
prop="couponPackageRows"
|
||||
:required="formEdit.benefitType === 'COUPON_PACKAGE'"
|
||||
>
|
||||
<div>
|
||||
<Button type="dashed" icon="ios-add" class="mb_10" @click="openCouponPicker('edit')">添加优惠券</Button>
|
||||
<Table
|
||||
<el-button plain class="mb_10" @click="openCouponPicker('edit')">添加优惠券</el-button>
|
||||
<el-table
|
||||
border
|
||||
size="small"
|
||||
:columns="couponPackageTableColumnsEdit"
|
||||
:data="formEdit.couponPackageRows"
|
||||
no-data-text="请添加优惠券"
|
||||
></Table>
|
||||
empty-text="请添加优惠券"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="couponName" label="优惠券名称" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="有效期" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" v-html="row.validRange || '-'" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="faceValueLabel" label="面额" min-width="100" />
|
||||
<el-table-column label="赠送张数" width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-input-number
|
||||
v-if="row"
|
||||
:model-value="row.quantity"
|
||||
:min="1"
|
||||
:max="10"
|
||||
:precision="0"
|
||||
style="width: 100px"
|
||||
@change="(val) => onCouponQuantityChange('edit', $index, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<a v-if="row" class="link-text" @click="removeCouponRow('edit', $index)">删除</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="权益名称" prop="benefitName">
|
||||
<Input v-model="formEdit.benefitName" maxlength="50" placeholder="请输入权益名称" />
|
||||
</FormItem>
|
||||
<FormItem label="权益LOGO" prop="benefitLogo">
|
||||
</el-form-item>
|
||||
<el-form-item label="权益名称" prop="benefitName">
|
||||
<el-input v-model="formEdit.benefitName" maxlength="50" placeholder="请输入权益名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="权益LOGO" prop="benefitLogo">
|
||||
<div class="benefit-logo-field">
|
||||
<div v-if="formEdit.benefitLogo" class="benefit-logo-thumb">
|
||||
<img :src="formEdit.benefitLogo" alt="" />
|
||||
@@ -202,25 +308,25 @@
|
||||
<upload-pic-input v-model="formEdit.benefitLogo" placeholder="请上传权益 LOGO 图片地址" style="width: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="权益介绍" prop="benefitDesc">
|
||||
<Input v-model="formEdit.benefitDesc" type="textarea" :rows="4" maxlength="500" placeholder="请输入权益介绍" />
|
||||
</FormItem>
|
||||
<FormItem label="启用状态" prop="benefitState">
|
||||
<RadioGroup v-model="formEdit.benefitState">
|
||||
<Radio label="OPEN">开启</Radio>
|
||||
<Radio label="CLOSE">关闭</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="排序" prop="benefitSort">
|
||||
<InputNumber v-model="formEdit.benefitSort" :min="1" :max="9999" :precision="0" style="width: 220px" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
<el-form-item label="权益介绍" prop="benefitDesc">
|
||||
<el-input v-model="formEdit.benefitDesc" type="textarea" :rows="4" maxlength="500" placeholder="请输入权益介绍" />
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态" prop="benefitState">
|
||||
<el-radio-group v-model="formEdit.benefitState">
|
||||
<el-radio value="OPEN">开启</el-radio>
|
||||
<el-radio value="CLOSE">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="benefitSort">
|
||||
<el-input-number v-model="formEdit.benefitSort" :min="1" :max="9999" :precision="0" style="width: 220px" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="benefit-drawer-footer-btns">
|
||||
<Button @click="editFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitEditLoading" @click="submitEdit">提交</Button>
|
||||
<el-button @click="editFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitEditLoading" @click="submitEdit">提交</el-button>
|
||||
</div>
|
||||
</Drawer>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -244,9 +350,7 @@ const buildDefaultForm = () => ({
|
||||
benefitSort: 1,
|
||||
benefitState: "OPEN",
|
||||
benefitConfig: "",
|
||||
/** 仅 UI:赠送积分数量;提交时写入 benefitConfig */
|
||||
giftPoint: null,
|
||||
/** 仅 UI:券礼包已选优惠券(含展示字段);提交时写入 benefitConfig.coupons */
|
||||
couponPackageRows: [],
|
||||
});
|
||||
|
||||
@@ -265,109 +369,6 @@ export default {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "权益类型",
|
||||
key: "benefitType",
|
||||
width: 132,
|
||||
render: (h, params) => {
|
||||
const v = params.row.benefitType;
|
||||
let text = "-";
|
||||
if (v) {
|
||||
const opt = this.benefitTypeOptions.find((o) => o.value === v);
|
||||
text = opt ? opt.description : v;
|
||||
}
|
||||
return h(
|
||||
"span",
|
||||
{
|
||||
attrs: { title: text },
|
||||
class: "benefit-list-cell-ellipsis benefit-list-cell-ellipsis--type",
|
||||
},
|
||||
text
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "权益名称",
|
||||
key: "benefitName",
|
||||
width: 188,
|
||||
render: (h, params) => {
|
||||
const text = params.row.benefitName || "-";
|
||||
return h(
|
||||
"span",
|
||||
{
|
||||
attrs: { title: text },
|
||||
class: "benefit-list-cell-ellipsis benefit-list-cell-ellipsis--name",
|
||||
},
|
||||
text
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "权益LOGO",
|
||||
key: "benefitLogo",
|
||||
width: 116,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const src = params.row.benefitLogo;
|
||||
if (!src) return h("span", "-");
|
||||
return h(
|
||||
"div",
|
||||
{
|
||||
class: "benefit-logo-thumb benefit-logo-thumb--table",
|
||||
},
|
||||
[
|
||||
h("img", {
|
||||
attrs: { src, alt: "" },
|
||||
}),
|
||||
]
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "benefitState",
|
||||
width: 118,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const row = params.row;
|
||||
return h("i-switch", {
|
||||
props: {
|
||||
value: row.benefitState === "OPEN",
|
||||
size: "large",
|
||||
loading: !!row._benefitStateLoading,
|
||||
},
|
||||
on: {
|
||||
"on-change": (checked) => {
|
||||
this.onBenefitStateSwitch(row, checked);
|
||||
},
|
||||
},
|
||||
}, [
|
||||
h("span", { slot: "open" }, "开启"),
|
||||
h("span", { slot: "close" }, "关闭"),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 140,
|
||||
render: (h, params) => {
|
||||
const linkStyle = {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
};
|
||||
const sep = h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|");
|
||||
return h("div", { style: { display: "flex", justifyContent: "center" } }, [
|
||||
h("a", { style: linkStyle, on: { click: () => this.openEdit(params.row) } }, "编辑"),
|
||||
sep,
|
||||
h("a", { style: linkStyle, on: { click: () => this.remove(params.row) } }, "删除"),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
addFlag: false,
|
||||
editFlag: false,
|
||||
@@ -386,13 +387,6 @@ export default {
|
||||
rulesEdit() {
|
||||
return this.buildFormRules("edit");
|
||||
},
|
||||
couponPackageTableColumns() {
|
||||
return this.buildCouponPackageTableColumns("add");
|
||||
},
|
||||
couponPackageTableColumnsEdit() {
|
||||
return this.buildCouponPackageTableColumns("edit");
|
||||
},
|
||||
/** 传给优惠券列表组件,用于勾选回显(与 coupon-publish 一致用 id) */
|
||||
couponPickerSelectedList() {
|
||||
const form = this.couponPickerWhich === "add" ? this.formAdd : this.formEdit;
|
||||
return (form.couponPackageRows || []).map((r) => ({
|
||||
@@ -402,6 +396,20 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
benefitTypeLabel(v) {
|
||||
if (!v) return "-";
|
||||
const opt = this.benefitTypeOptions.find((o) => o.value === v);
|
||||
return opt ? opt.description : v;
|
||||
},
|
||||
onCouponQuantityChange(which, index, val) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
const refName = which === "add" ? "addForm" : "editForm";
|
||||
this[formKey].couponPackageRows[index].quantity = val;
|
||||
this.$nextTick(() => {
|
||||
const ref = this.$refs[refName];
|
||||
if (ref) ref.validateField("couponPackageRows");
|
||||
});
|
||||
},
|
||||
buildFormRules(which) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
return {
|
||||
@@ -478,66 +486,6 @@ export default {
|
||||
validRange: this.formatCouponValidity(detail),
|
||||
};
|
||||
},
|
||||
buildCouponPackageTableColumns(which) {
|
||||
const formKey = which === "add" ? "formAdd" : "formEdit";
|
||||
const linkStyle = { color: "#2d8cf0", cursor: "pointer" };
|
||||
return [
|
||||
{ title: "优惠券名称", key: "couponName", minWidth: 100, tooltip: true },
|
||||
{
|
||||
title: "有效期",
|
||||
minWidth: 100,
|
||||
render: (h, p) =>
|
||||
h("span", {
|
||||
domProps: { innerHTML: p.row.validRange || "-" },
|
||||
}),
|
||||
},
|
||||
{ title: "面额", key: "faceValueLabel", minWidth: 100 },
|
||||
{
|
||||
title: "赠送张数",
|
||||
key: "quantity",
|
||||
width: 150,
|
||||
render: (h, params) =>
|
||||
h("InputNumber", {
|
||||
props: {
|
||||
min: 1,
|
||||
max: 10,
|
||||
precision: 0,
|
||||
value: params.row.quantity,
|
||||
},
|
||||
style: { width: "100px" },
|
||||
on: {
|
||||
"on-change": (val) => {
|
||||
this.$set(this[formKey].couponPackageRows[params.index], "quantity", val);
|
||||
this.$nextTick(() => {
|
||||
const ref = which === "add" ? this.$refs.addForm : this.$refs.editForm;
|
||||
if (ref) ref.validateField("couponPackageRows");
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) =>
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: linkStyle,
|
||||
on: {
|
||||
click: () => {
|
||||
this.removeCouponRow(which, params.index);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
},
|
||||
];
|
||||
},
|
||||
/** 构造 benefitConfig JSON 字符串 */
|
||||
buildBenefitConfigString(slice) {
|
||||
const { benefitType, giftPoint, couponPackageRows } = slice;
|
||||
if (benefitType === GIFT_POINT) {
|
||||
@@ -552,7 +500,6 @@ export default {
|
||||
}
|
||||
return "";
|
||||
},
|
||||
/** 从详情 benefitConfig 解析赠送积分,解析失败时返回 null */
|
||||
parseGiftPointFromConfig(benefitType, benefitConfigStr) {
|
||||
if (benefitType !== GIFT_POINT || !benefitConfigStr) return null;
|
||||
try {
|
||||
@@ -613,7 +560,6 @@ export default {
|
||||
}
|
||||
return [];
|
||||
},
|
||||
/** 与添加时 formatCouponFace 一致;仅有 faceValueText 时去掉「减免」前缀 */
|
||||
normalizeCouponFaceFromDetail(item) {
|
||||
let face = this.formatCouponFace(item);
|
||||
if (face !== "-") return face;
|
||||
@@ -624,7 +570,6 @@ export default {
|
||||
.replace(/^减免\s*/, "")
|
||||
.trim() || "-";
|
||||
},
|
||||
/** 管理端详情 couponItems → 表格行(面额展示与添加一致) */
|
||||
mapCouponItemsToPackageRows(items) {
|
||||
if (!Array.isArray(items)) return [];
|
||||
return items.map((item) => {
|
||||
@@ -669,7 +614,7 @@ export default {
|
||||
});
|
||||
}
|
||||
}
|
||||
this.$set(this.formEdit, "couponPackageRows", rows);
|
||||
this.formEdit.couponPackageRows = rows;
|
||||
},
|
||||
handleCouponPickerClose() {
|
||||
this.couponPickerVisible = false;
|
||||
@@ -678,7 +623,6 @@ export default {
|
||||
this.couponPickerWhich = which;
|
||||
this.couponPickerVisible = true;
|
||||
},
|
||||
/** 与 coupon-publish `selectedCoupon`:表格多选变更时同步到券礼包配置 */
|
||||
onCouponTemplateSelected(selectedRows) {
|
||||
const which = this.couponPickerWhich;
|
||||
const form = which === "add" ? this.formAdd : this.formEdit;
|
||||
@@ -689,7 +633,7 @@ export default {
|
||||
const qty = existing ? existing.quantity : 1;
|
||||
return this.buildCouponDisplayRow(row, qty);
|
||||
});
|
||||
this.$set(form, "couponPackageRows", rows);
|
||||
form.couponPackageRows = rows;
|
||||
this.$nextTick(() => {
|
||||
const ref = this.$refs[refName];
|
||||
if (ref) ref.validateField("couponPackageRows");
|
||||
@@ -791,7 +735,6 @@ export default {
|
||||
API_Member.getMemberBenefit(row.id).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
const raw = res.result;
|
||||
/** 新接口:{ benefit, couponItems };旧接口:扁平 MemberBenefit */
|
||||
const detail = raw.benefit != null ? raw.benefit : raw;
|
||||
const couponItems = raw.couponItems;
|
||||
const bt = detail.benefitType || "";
|
||||
@@ -866,19 +809,19 @@ export default {
|
||||
title: "提示",
|
||||
content: `<p>确定${text}该客户权益?</p>`,
|
||||
onOk: () => {
|
||||
this.$set(row, "_benefitStateLoading", true);
|
||||
row._benefitStateLoading = true;
|
||||
return API_Member.updateMemberBenefitState(row.id, nextState)
|
||||
.then((res) => {
|
||||
this.$set(row, "_benefitStateLoading", false);
|
||||
row._benefitStateLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success(`${text}成功`);
|
||||
this.$set(row, "benefitState", nextState);
|
||||
row.benefitState = nextState;
|
||||
} else {
|
||||
this.getData();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$set(row, "_benefitStateLoading", false);
|
||||
row._benefitStateLoading = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -913,17 +856,20 @@ export default {
|
||||
border-top: 1px solid #e8eaec;
|
||||
text-align: right;
|
||||
}
|
||||
.benefit-drawer-footer-btns .ivu-btn + .ivu-btn {
|
||||
.benefit-drawer-footer-btns .el-button + .el-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdfe6;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--
|
||||
权益 LOGO 缩略图:固定 100×100。
|
||||
不使用 .member-benefit 前缀:Modal 默认 transfer 到 body,弹窗内节点不在 .member-benefit 下。
|
||||
Table 列 render 生成的节点在子组件内,同样用非 scoped。
|
||||
-->
|
||||
<style lang="scss">
|
||||
.benefit-logo-thumb {
|
||||
width: 100px;
|
||||
@@ -952,7 +898,6 @@ export default {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 权益列表:固定类型/名称列宽并省略过长文案(悬浮 title 可看全文) */
|
||||
.member-benefit .benefit-list-table table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
@@ -971,9 +916,8 @@ export default {
|
||||
max-width: 172px;
|
||||
}
|
||||
|
||||
/* 列表不出现列与列之间的竖线(保留行间分隔) */
|
||||
.member-benefit .benefit-list-table--no-vertical-borders .ivu-table th,
|
||||
.member-benefit .benefit-list-table--no-vertical-borders .ivu-table td {
|
||||
.member-benefit .benefit-list-table--no-vertical-borders .el-table th,
|
||||
.member-benefit .benefit-list-table--no-vertical-borders .el-table td {
|
||||
border-right: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,57 +1,80 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="90"
|
||||
@keydown.enter.native="handleSearch"
|
||||
@submit.native.prevent
|
||||
label-width="90px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<FormItem label="客户手机号" prop="mobile">
|
||||
<Input
|
||||
<el-form-item label="客户手机号" prop="mobile">
|
||||
<el-input
|
||||
v-model="searchForm.memberMobile"
|
||||
clearable
|
||||
placeholder="请输入客户手机号"
|
||||
style="width: 220px"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="规则" prop="ruleKey">
|
||||
<Select v-model="searchForm.ruleKey" clearable filterable style="width: 220px">
|
||||
<Option v-for="item in ruleOptions" :key="item.value" :value="item.value">
|
||||
{{ item.label }}
|
||||
</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<Button type="primary" icon="ios-search" @click="handleSearch">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item label="规则" prop="ruleKey">
|
||||
<el-select v-model="searchForm.ruleKey" clearable filterable style="width: 220px">
|
||||
<el-option
|
||||
v-for="item in ruleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-card>
|
||||
<el-table v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column label="客户手机号" width="140" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.memberMobile || row.mobile || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规则名称" width="150" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.ruleName || findRuleName(row.ruleKey) || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="变化经验值" width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ formatExperienceValue(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="经验值限额" width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ formatMaxValue(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作说明" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.content || row.remark || row.description || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="170" />
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -86,67 +109,20 @@ export default {
|
||||
memberMobile: "",
|
||||
ruleKey: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "客户手机号",
|
||||
key: "memberMobile",
|
||||
width: 140,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
const v = params.row.memberMobile || params.row.mobile || "-";
|
||||
return h("span", v);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "规则名称",
|
||||
key: "ruleName",
|
||||
width: 150,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
const text = params.row.ruleName || this.findRuleName(params.row.ruleKey) || "-";
|
||||
return h("span", text);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "变化经验值",
|
||||
key: "value",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
const v =
|
||||
params.row.value ??
|
||||
params.row.variableExperience ??
|
||||
params.row.experience ??
|
||||
params.row.variableValue;
|
||||
return h("span", v == null ? "-" : v);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "经验值限额",
|
||||
key: "maxValue",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
const v = params.row.maxValue ?? params.row.maxExperience ?? params.row.limitValue;
|
||||
return h("span", v == null ? "-" : v);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作说明",
|
||||
key: "content",
|
||||
minWidth: 200,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
const text = params.row.content || params.row.remark || params.row.description || "-";
|
||||
return h("span", text);
|
||||
},
|
||||
},
|
||||
{ title: "创建时间", key: "createTime", width: 170 },
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
formatExperienceValue(row) {
|
||||
const v = row.value ?? row.variableExperience ?? row.experience ?? row.variableValue;
|
||||
return v == null ? "-" : v;
|
||||
},
|
||||
formatMaxValue(row) {
|
||||
const v = row.maxValue ?? row.maxExperience ?? row.limitValue;
|
||||
return v == null ? "-" : v;
|
||||
},
|
||||
findRuleName(ruleKey) {
|
||||
const hit = this.ruleOptions.find((item) => item.value === ruleKey);
|
||||
return hit ? hit.label : "";
|
||||
|
||||
@@ -1,10 +1,226 @@
|
||||
<template>
|
||||
<div class="experience-setting">
|
||||
<Card>
|
||||
<Form :label-width="120" label-position="right">
|
||||
<Table :loading="loading" :columns="columns" :data="form.items" class="mt_10 experience-table"></Table>
|
||||
<FormItem label="经验值说明" style="margin-top: 16px" class="desc-item">
|
||||
<Input
|
||||
<el-card>
|
||||
<el-form label-width="120px" label-position="right">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="form.items"
|
||||
class="mt_10 experience-table"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="是否开启" width="90" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
:model-value="!!form.items[$index].enabled"
|
||||
@change="(checked) => updateRuleEnabled($index, checked)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ruleName" label="类型" width="160" />
|
||||
<el-table-column label="经验值(1-100)" min-width="700">
|
||||
<template #default="{ row, $index }">
|
||||
<template v-if="row">
|
||||
<div v-if="row.ruleKey === 'REGISTER'" class="rule-cell">
|
||||
<div class="rule-row">
|
||||
<span class="rule-label">获得经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">会员注册成功后可获得经验值</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'SHARE'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">分享商品详情页获得经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">可获得经验值限额:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].maxValue)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleMaxValue($index, val)"
|
||||
@blur="() => commitRuleMaxValue($index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rule-tip">会员分享商城页面可获得的经验值</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'COMMENT'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<span class="rule-label">对已购买商品完成提交评论获得经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">仅针对评论字数大于30字的评论进行发放</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'FOLLOW_STORE'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">获得经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">可获得经验值限额:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].maxValue)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleMaxValue($index, val)"
|
||||
@blur="() => commitRuleMaxValue($index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rule-tip">关注店铺可获得经验值,每个客户D相同店铺仅第一次关注可进行获得</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'PROFILE'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<span class="rule-label">获得经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">完善个人基本信息可获得经验值,每个会员仅可获得一次</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'BIND_WECHAT'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<span class="rule-label">获取经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">绑定微信成功获得经验值,每个会员仅可获得一次</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'ADD_ADDRESS'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<span class="rule-label">获取经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">添加收货地址后获得经验值,每个会员仅可获得一次</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'SHARE_REGISTER'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">获取的经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">可获得经验值限额:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].maxValue)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleMaxValue($index, val)"
|
||||
@blur="() => commitRuleMaxValue($index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rule-tip">仅被注册成功后才可获得相应奖励经验值</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'SHARE_BUY'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">获取的经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-inline">
|
||||
<span class="rule-label">可获得经验值限额:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].maxValue)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleMaxValue($index, val)"
|
||||
@blur="() => commitRuleMaxValue($index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rule-tip">仅被购买成功后才可获得相应奖励经验值</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'SIGN_IN'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<span class="rule-label">获取的经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">客户每日签到后可获的经验值</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="row.ruleKey === 'CONSUME'" class="rule-cell">
|
||||
<div class="rule-row rule-row-wrap">
|
||||
<span class="rule-label">1元获取经验值:</span>
|
||||
<el-input
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</div>
|
||||
<div class="rule-tip">客户消费1元可获取经验值,向下取整</div>
|
||||
</div>
|
||||
|
||||
<el-input
|
||||
v-else
|
||||
:model-value="formatInputValue(form.items[$index].value)"
|
||||
style="width: 120px"
|
||||
@input="(val) => updateRuleValue($index, val)"
|
||||
@blur="() => commitRuleValue($index)"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-form-item label="经验值说明" style="margin-top: 16px" class="desc-item">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
@@ -12,12 +228,12 @@
|
||||
show-word-limit
|
||||
placeholder="请输入经验值说明"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="primary" :loading="submitLoading" @click="submit">保存</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submit">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -58,340 +274,33 @@ export default {
|
||||
loading: false,
|
||||
submitLoading: false,
|
||||
form: defaultForm(),
|
||||
columns: [
|
||||
{
|
||||
title: "是否开启",
|
||||
key: "enabled",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h("Checkbox", {
|
||||
props: { value: !!this.form.items[params.index].enabled },
|
||||
on: {
|
||||
"on-change": (checked) => {
|
||||
this.updateRuleEnabled(params.index, checked);
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "类型",
|
||||
key: "ruleName",
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: "经验值(1-100)",
|
||||
key: "value",
|
||||
minWidth: 700,
|
||||
render: (h, params) => {
|
||||
const row = this.form.items[params.index] || {};
|
||||
const inputNode = h("Input", {
|
||||
style: { width: "120px" },
|
||||
props: {
|
||||
value: row.value == null ? "" : String(row.value),
|
||||
number: true,
|
||||
},
|
||||
on: {
|
||||
input: (val) => {
|
||||
this.updateRuleValue(params.index, val);
|
||||
},
|
||||
"on-change": (v) => {
|
||||
this.updateRuleValue(params.index, v);
|
||||
},
|
||||
"on-blur": () => {
|
||||
this.commitRuleValue(params.index);
|
||||
},
|
||||
},
|
||||
});
|
||||
const maxInputNode = h("Input", {
|
||||
style: { width: "120px" },
|
||||
props: {
|
||||
value: row.maxValue == null ? "" : String(row.maxValue),
|
||||
number: true,
|
||||
},
|
||||
on: {
|
||||
input: (val) => {
|
||||
this.updateRuleMaxValue(params.index, val);
|
||||
},
|
||||
"on-change": (v) => {
|
||||
this.updateRuleMaxValue(params.index, v);
|
||||
},
|
||||
"on-blur": () => {
|
||||
this.commitRuleMaxValue(params.index);
|
||||
},
|
||||
},
|
||||
});
|
||||
if (params.row.ruleKey === "REGISTER") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获得经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"会员注册成功后可获得经验值"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "SHARE") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", marginRight: "16px" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "分享商品详情页获得经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "可获得经验值限额:"), maxInputNode]
|
||||
),
|
||||
]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"会员分享商城页面可获得的经验值"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "COMMENT") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "对已购买商品完成提交评论获得经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"仅针对评论字数大于30字的评论进行发放"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "FOLLOW_STORE") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", marginRight: "16px" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获得经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "可获得经验值限额:"), maxInputNode]
|
||||
),
|
||||
]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"关注店铺可获得经验值,每个客户D相同店铺仅第一次关注可进行获得"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "PROFILE") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获得经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"完善个人基本信息可获得经验值,每个会员仅可获得一次"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "BIND_WECHAT") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获取经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"绑定微信成功获得经验值,每个会员仅可获得一次"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "ADD_ADDRESS") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获取经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"添加收货地址后获得经验值,每个会员仅可获得一次"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "SHARE_REGISTER") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", marginRight: "16px" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获取的经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "可获得经验值限额:"), maxInputNode]
|
||||
),
|
||||
]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"仅被注册成功后才可获得相应奖励经验值"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "SHARE_BUY") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", marginRight: "16px" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获取的经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "可获得经验值限额:"), maxInputNode]
|
||||
),
|
||||
]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"仅被购买成功后才可获得相应奖励经验值"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "SIGN_IN") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "获取的经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"客户每日签到后可获的经验值"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
if (params.row.ruleKey === "CONSUME") {
|
||||
return h(
|
||||
"div",
|
||||
{ style: { display: "flex", flexDirection: "column", alignItems: "flex-start" } },
|
||||
[
|
||||
h(
|
||||
"div",
|
||||
{ style: { display: "flex", alignItems: "center", flexWrap: "wrap" } },
|
||||
[h("span", { style: { marginRight: "8px" } }, "1元获取经验值:"), inputNode]
|
||||
),
|
||||
h(
|
||||
"div",
|
||||
{ style: { marginTop: "6px", color: "#808695", fontSize: "12px" } },
|
||||
"客户消费1元可获取经验值,向下取整"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
return inputNode;
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
formatInputValue(v) {
|
||||
return v == null ? "" : String(v);
|
||||
},
|
||||
getRawInputValue(v) {
|
||||
return v && v.target ? v.target.value : v;
|
||||
},
|
||||
updateRuleEnabled(index, enabled) {
|
||||
const item = this.form.items[index] || {};
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
enabled: !!enabled,
|
||||
});
|
||||
};
|
||||
},
|
||||
updateRuleValue(index, v) {
|
||||
const raw = this.getRawInputValue(v);
|
||||
const next = Number(raw);
|
||||
const item = this.form.items[index] || {};
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
value: Number.isFinite(next) ? next : null,
|
||||
});
|
||||
};
|
||||
},
|
||||
commitRuleValue(index) {
|
||||
const item = this.form.items[index] || {};
|
||||
@@ -402,41 +311,41 @@ export default {
|
||||
else if (next > 100) value = 100;
|
||||
else value = Math.floor(next);
|
||||
}
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
value,
|
||||
});
|
||||
};
|
||||
},
|
||||
updateRuleMaxValue(index, v) {
|
||||
const raw = this.getRawInputValue(v);
|
||||
const item = this.form.items[index] || {};
|
||||
if (raw == null || raw === "") {
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: null,
|
||||
});
|
||||
};
|
||||
return;
|
||||
}
|
||||
const next = Number(raw);
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: Number.isFinite(next) ? next : null,
|
||||
});
|
||||
};
|
||||
},
|
||||
commitRuleMaxValue(index) {
|
||||
const item = this.form.items[index] || {};
|
||||
if (item.maxValue == null || item.maxValue === "") {
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: null,
|
||||
});
|
||||
};
|
||||
return;
|
||||
}
|
||||
const next = Number(item.maxValue);
|
||||
this.$set(this.form.items, index, {
|
||||
this.form.items[index] = {
|
||||
...item,
|
||||
maxValue: Number.isFinite(next) && next >= 1 ? Math.floor(next) : null,
|
||||
});
|
||||
};
|
||||
},
|
||||
normalizeConfig(val) {
|
||||
if (!val) return {};
|
||||
@@ -535,21 +444,52 @@ export default {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
::v-deep .experience-table .ivu-table th {
|
||||
.rule-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.rule-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.rule-row-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rule-inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.rule-label {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.rule-tip {
|
||||
margin-top: 6px;
|
||||
color: #808695;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
:deep(.experience-table .el-table__header th) {
|
||||
background: #fafbfc;
|
||||
}
|
||||
|
||||
::v-deep .experience-table .ivu-table td {
|
||||
:deep(.experience-table .el-table__body td) {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
::v-deep .experience-table .ivu-table-cell {
|
||||
:deep(.experience-table .cell) {
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
::v-deep .desc-item .ivu-form-item-label {
|
||||
:deep(.desc-item .el-form-item__label) {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -1,120 +1,180 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button type="primary" @click="openAdd">添加客户等级</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
></Table>
|
||||
</Card>
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="openAdd">添加客户等级</el-button>
|
||||
</div>
|
||||
|
||||
<Modal v-model="addFlag" title="添加客户等级" width="720" :z-index="950" :mask-closable="false">
|
||||
<Form ref="addForm" :model="formAdd" :rules="rules" :label-width="110">
|
||||
<FormItem label="等级名称" prop="gradeName">
|
||||
<Input v-model="formAdd.gradeName" maxlength="50" placeholder="请输入等级名称" />
|
||||
</FormItem>
|
||||
<FormItem label="是否默认" prop="isDefault">
|
||||
<RadioGroup v-model="formAdd.isDefault">
|
||||
<Radio :label="true">是</Radio>
|
||||
<Radio :label="false">否</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="等级图标" prop="gradeImage">
|
||||
<upload-pic-input v-model="formAdd.gradeImage"></upload-pic-input>
|
||||
</FormItem>
|
||||
<FormItem label="等级背景图" prop="gradeBackground">
|
||||
<upload-pic-input v-model="formAdd.gradeBackground"></upload-pic-input>
|
||||
</FormItem>
|
||||
<FormItem label="字体颜色" prop="gradeFontColor">
|
||||
<Input v-model="formAdd.gradeFontColor" maxlength="20" placeholder="如:#333333" />
|
||||
</FormItem>
|
||||
<FormItem label="所需经验值" prop="requiredExperience">
|
||||
<InputNumber v-model="formAdd.requiredExperience" :min="1" :precision="0" style="width: 220px"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="等级排序" prop="gradeSort">
|
||||
<InputNumber v-model="formAdd.gradeSort" :min="1" :max="9999" :precision="0" style="width: 220px"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="等级开关" prop="gradeState">
|
||||
<RadioGroup v-model="formAdd.gradeState">
|
||||
<Radio label="OPEN">开启</Radio>
|
||||
<Radio label="CLOSE">关闭</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="关联权益" prop="benefitIds">
|
||||
<Select
|
||||
:value="addBenefitOrder"
|
||||
<el-table v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="gradeName" label="等级名称" width="130" show-overflow-tooltip />
|
||||
<el-table-column label="默认等级" width="95">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.isDefault === true ? 'success' : 'info'">
|
||||
{{ row.isDefault === true ? "是" : "否" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="等级图标" width="100">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row && !row.gradeImage">-</span>
|
||||
<img
|
||||
v-else-if="row"
|
||||
:src="row.gradeImage"
|
||||
alt="等级图标"
|
||||
style="width: 48px; height: 48px; object-fit: contain; border: 1px solid #dcdee2; border-radius: 4px; background: #fff"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="等级背景图" width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row && !row.gradeBackground">-</span>
|
||||
<img
|
||||
v-else-if="row"
|
||||
:src="row.gradeBackground"
|
||||
alt="等级背景图"
|
||||
style="width: 64px; height: 40px; object-fit: cover; border: 1px solid #dcdee2; border-radius: 4px; background: #fff"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="requiredExperience" label="所需经验值" width="110" />
|
||||
<el-table-column prop="gradeSort" label="等级排序" width="95" />
|
||||
<el-table-column label="状态" width="118" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
:model-value="row.gradeState === 'OPEN'"
|
||||
inline-prompt
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
:loading="!!row._gradeStateLoading"
|
||||
@change="(checked) => onGradeStateSwitch(row, checked)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="130" align="center">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops" style="display: flex; justify-content: center">
|
||||
<a class="link-text" @click="openEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="addFlag" title="添加客户等级" width="720px" :z-index="950" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="addForm" :model="formAdd" :rules="rules" label-width="110px">
|
||||
<el-form-item label="等级名称" prop="gradeName">
|
||||
<el-input v-model="formAdd.gradeName" maxlength="50" placeholder="请输入等级名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否默认" prop="isDefault">
|
||||
<el-radio-group v-model="formAdd.isDefault">
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="等级图标" prop="gradeImage">
|
||||
<upload-pic-input v-model="formAdd.gradeImage" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级背景图" prop="gradeBackground">
|
||||
<upload-pic-input v-model="formAdd.gradeBackground" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体颜色" prop="gradeFontColor">
|
||||
<el-input v-model="formAdd.gradeFontColor" maxlength="20" placeholder="如:#333333" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所需经验值" prop="requiredExperience">
|
||||
<el-input-number v-model="formAdd.requiredExperience" :min="1" :precision="0" style="width: 220px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级排序" prop="gradeSort">
|
||||
<el-input-number v-model="formAdd.gradeSort" :min="1" :max="9999" :precision="0" style="width: 220px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级开关" prop="gradeState">
|
||||
<el-radio-group v-model="formAdd.gradeState">
|
||||
<el-radio value="OPEN">开启</el-radio>
|
||||
<el-radio value="CLOSE">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联权益" prop="benefitIds">
|
||||
<el-select
|
||||
:model-value="addBenefitOrder"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择客户权益"
|
||||
style="width: 100%"
|
||||
@on-change="onAddBenefitIdsChange"
|
||||
@change="onAddBenefitIdsChange"
|
||||
>
|
||||
<Option v-for="b in benefitOptions" :key="b.id" :value="String(b.id)">{{ benefitOptionLabel(b) }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="addFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-option
|
||||
v-for="b in benefitOptions"
|
||||
:key="b.id"
|
||||
:value="String(b.id)"
|
||||
:label="benefitOptionLabel(b)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="addFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal v-model="editFlag" title="编辑客户等级" width="720" :z-index="950" :mask-closable="false">
|
||||
<Form ref="editForm" :model="formEdit" :rules="rules" :label-width="110">
|
||||
<Input v-model="formEdit.id" v-show="false" />
|
||||
<FormItem label="等级名称" prop="gradeName">
|
||||
<Input v-model="formEdit.gradeName" maxlength="50" placeholder="请输入等级名称" />
|
||||
</FormItem>
|
||||
<FormItem label="是否默认" prop="isDefault">
|
||||
<RadioGroup v-model="formEdit.isDefault">
|
||||
<Radio :label="true">是</Radio>
|
||||
<Radio :label="false">否</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="等级图标" prop="gradeImage">
|
||||
<upload-pic-input v-model="formEdit.gradeImage"></upload-pic-input>
|
||||
</FormItem>
|
||||
<FormItem label="等级背景图" prop="gradeBackground">
|
||||
<upload-pic-input v-model="formEdit.gradeBackground"></upload-pic-input>
|
||||
</FormItem>
|
||||
<FormItem label="字体颜色" prop="gradeFontColor">
|
||||
<Input v-model="formEdit.gradeFontColor" maxlength="20" placeholder="如:#333333" />
|
||||
</FormItem>
|
||||
<FormItem label="所需经验值" prop="requiredExperience">
|
||||
<InputNumber v-model="formEdit.requiredExperience" :min="1" :precision="0" style="width: 220px"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="等级排序" prop="gradeSort">
|
||||
<InputNumber v-model="formEdit.gradeSort" :min="1" :max="9999" :precision="0" style="width: 220px"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="等级开关" prop="gradeState">
|
||||
<RadioGroup v-model="formEdit.gradeState">
|
||||
<Radio label="OPEN">开启</Radio>
|
||||
<Radio label="CLOSE">关闭</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="关联权益" prop="benefitIds">
|
||||
<Select
|
||||
:value="editBenefitOrder"
|
||||
<el-dialog v-model="editFlag" title="编辑客户等级" width="720px" :z-index="950" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="editForm" :model="formEdit" :rules="rules" label-width="110px">
|
||||
<el-input v-model="formEdit.id" style="display: none" />
|
||||
<el-form-item label="等级名称" prop="gradeName">
|
||||
<el-input v-model="formEdit.gradeName" maxlength="50" placeholder="请输入等级名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否默认" prop="isDefault">
|
||||
<el-radio-group v-model="formEdit.isDefault">
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="等级图标" prop="gradeImage">
|
||||
<upload-pic-input v-model="formEdit.gradeImage" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级背景图" prop="gradeBackground">
|
||||
<upload-pic-input v-model="formEdit.gradeBackground" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体颜色" prop="gradeFontColor">
|
||||
<el-input v-model="formEdit.gradeFontColor" maxlength="20" placeholder="如:#333333" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所需经验值" prop="requiredExperience">
|
||||
<el-input-number v-model="formEdit.requiredExperience" :min="1" :precision="0" style="width: 220px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级排序" prop="gradeSort">
|
||||
<el-input-number v-model="formEdit.gradeSort" :min="1" :max="9999" :precision="0" style="width: 220px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级开关" prop="gradeState">
|
||||
<el-radio-group v-model="formEdit.gradeState">
|
||||
<el-radio value="OPEN">开启</el-radio>
|
||||
<el-radio value="CLOSE">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联权益" prop="benefitIds">
|
||||
<el-select
|
||||
:model-value="editBenefitOrder"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择客户权益"
|
||||
style="width: 100%"
|
||||
@on-change="onEditBenefitIdsChange"
|
||||
@change="onEditBenefitIdsChange"
|
||||
>
|
||||
<Option v-for="b in benefitOptions" :key="b.id" :value="String(b.id)">{{ benefitOptionLabel(b) }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="editFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-option
|
||||
v-for="b in benefitOptions"
|
||||
:key="b.id"
|
||||
:value="String(b.id)"
|
||||
:label="benefitOptionLabel(b)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="editFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -135,7 +195,6 @@ const buildDefaultForm = () => ({
|
||||
benefitIds: "",
|
||||
});
|
||||
|
||||
/** 权益多选:新勾选追加到末尾,取消勾选移除,保持已有顺序 */
|
||||
function syncOrderedBenefitIds(prevOrder, selected) {
|
||||
const sel = Array.isArray(selected) ? selected.map((id) => String(id)) : [];
|
||||
const out = [];
|
||||
@@ -157,144 +216,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
columns: [
|
||||
{
|
||||
title: "等级名称",
|
||||
key: "gradeName",
|
||||
width: 130,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "默认等级",
|
||||
key: "isDefault",
|
||||
width: 95,
|
||||
render: (h, params) => {
|
||||
const yes = params.row.isDefault === true;
|
||||
return h(
|
||||
"Tag",
|
||||
{
|
||||
props: {
|
||||
color: yes ? "success" : "default",
|
||||
},
|
||||
},
|
||||
yes ? "是" : "否"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "等级图标",
|
||||
key: "gradeImage",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (!params.row.gradeImage) return h("span", "-");
|
||||
return h("img", {
|
||||
attrs: {
|
||||
src: params.row.gradeImage,
|
||||
alt: "等级图标",
|
||||
},
|
||||
style: {
|
||||
width: "48px",
|
||||
height: "48px",
|
||||
objectFit: "contain",
|
||||
border: "1px solid #dcdee2",
|
||||
borderRadius: "4px",
|
||||
background: "#fff",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "等级背景图",
|
||||
key: "gradeBackground",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (!params.row.gradeBackground) return h("span", "-");
|
||||
return h("img", {
|
||||
attrs: {
|
||||
src: params.row.gradeBackground,
|
||||
alt: "等级背景图",
|
||||
},
|
||||
style: {
|
||||
width: "64px",
|
||||
height: "40px",
|
||||
objectFit: "cover",
|
||||
border: "1px solid #dcdee2",
|
||||
borderRadius: "4px",
|
||||
background: "#fff",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "所需经验值",
|
||||
key: "requiredExperience",
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
title: "等级排序",
|
||||
key: "gradeSort",
|
||||
width: 95,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "gradeState",
|
||||
width: 118,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const row = params.row;
|
||||
return h("i-switch", {
|
||||
props: {
|
||||
value: row.gradeState === "OPEN",
|
||||
size: "large",
|
||||
loading: !!row._gradeStateLoading,
|
||||
},
|
||||
on: {
|
||||
"on-change": (checked) => {
|
||||
this.onGradeStateSwitch(row, checked);
|
||||
},
|
||||
},
|
||||
}, [
|
||||
h("span", { slot: "open" }, "开启"),
|
||||
h("span", { slot: "close" }, "关闭"),
|
||||
]);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 130,
|
||||
render: (h, params) => {
|
||||
const linkStyle = {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
};
|
||||
const sep = h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
);
|
||||
return h(
|
||||
"div",
|
||||
{ class: "ops", style: { display: "flex", justifyContent: "center" } },
|
||||
[
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.openEdit(params.row) } },
|
||||
"编辑"
|
||||
),
|
||||
sep,
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.remove(params.row) } },
|
||||
"删除"
|
||||
),
|
||||
]
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
addFlag: false,
|
||||
editFlag: false,
|
||||
@@ -302,7 +223,6 @@ export default {
|
||||
submitEditLoading: false,
|
||||
formAdd: buildDefaultForm(),
|
||||
formEdit: buildDefaultForm(),
|
||||
/** 关联权益 id 顺序(与 benefitIds 一致) */
|
||||
addBenefitOrder: [],
|
||||
editBenefitOrder: [],
|
||||
benefitOptions: [],
|
||||
@@ -506,19 +426,19 @@ export default {
|
||||
title: "提示",
|
||||
content: `<p>确定${text}该客户等级?</p>`,
|
||||
onOk: () => {
|
||||
this.$set(row, "_gradeStateLoading", true);
|
||||
row._gradeStateLoading = true;
|
||||
return API_Member.updateMemberGradeState(row.id, nextState)
|
||||
.then((res) => {
|
||||
this.$set(row, "_gradeStateLoading", false);
|
||||
row._gradeStateLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success(`${text}成功`);
|
||||
this.$set(row, "gradeState", nextState);
|
||||
row.gradeState = nextState;
|
||||
} else {
|
||||
this.getData();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$set(row, "_gradeStateLoading", false);
|
||||
row._gradeStateLoading = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -545,3 +465,15 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops span {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,61 +1,72 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button type="primary" @click="openAdd">添加分组</Button>
|
||||
</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"
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="openAdd">添加分组</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table ref="table" v-loading="loading" :data="data" border class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="groupName" label="分组名称" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="description" label="分组描述" min-width="240" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="180" />
|
||||
<el-table-column prop="updateTime" label="更新时间" min-width="180" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops" style="display: flex; justify-content: center">
|
||||
<a class="link-text" @click="openEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal v-model="addFlag" title="添加分组">
|
||||
<Form ref="addForm" :model="formAdd" :rules="rulesAdd" :label-width="90">
|
||||
<FormItem label="分组名称" prop="groupName" style="width: 90%;">
|
||||
<Input v-model="formAdd.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</FormItem>
|
||||
<FormItem label="分组描述" prop="description" style="width: 90%;">
|
||||
<Input v-model="formAdd.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="addFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</Button>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal v-model="editFlag" title="编辑分组">
|
||||
<Form ref="editForm" :model="formEdit" :rules="rulesEdit" :label-width="90">
|
||||
<Input v-model="formEdit.id" v-show="false" />
|
||||
<FormItem label="分组名称" prop="groupName" style="width: 90%;">
|
||||
<Input v-model="formEdit.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</FormItem>
|
||||
<FormItem label="分组描述" prop="description" style="width: 90%;">
|
||||
<Input v-model="formEdit.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="editFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="addFlag" title="添加分组" width="500px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="addForm" :model="formAdd" :rules="rulesAdd" label-width="90px">
|
||||
<el-form-item label="分组名称" prop="groupName" style="width: 90%">
|
||||
<el-input v-model="formAdd.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组描述" prop="description" style="width: 90%">
|
||||
<el-input v-model="formAdd.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="addFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="editFlag" title="编辑分组" width="500px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="editForm" :model="formEdit" :rules="rulesEdit" label-width="90px">
|
||||
<el-input v-model="formEdit.id" style="display: none" />
|
||||
<el-form-item label="分组名称" prop="groupName" style="width: 90%">
|
||||
<el-input v-model="formEdit.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组描述" prop="description" style="width: 90%">
|
||||
<el-input v-model="formEdit.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="editFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -71,67 +82,6 @@ export default {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "分组名称",
|
||||
key: "groupName",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "分组描述",
|
||||
key: "description",
|
||||
minWidth: 240,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
key: "updateTime",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
const linkStyle = {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
};
|
||||
const sep = h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
);
|
||||
const children = [
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.openEdit(params.row) } },
|
||||
"编辑"
|
||||
),
|
||||
sep,
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.remove(params.row) } },
|
||||
"删除"
|
||||
),
|
||||
];
|
||||
return h(
|
||||
"div",
|
||||
{ class: "ops", style: { display: "flex", justifyContent: "center" } },
|
||||
children
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
total: 0,
|
||||
addFlag: false,
|
||||
@@ -148,10 +98,10 @@ export default {
|
||||
description: "",
|
||||
},
|
||||
rulesAdd: {
|
||||
groupName: [{ required: true, message: "请输入分组名称" }],
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
rulesEdit: {
|
||||
groupName: [{ required: true, message: "请输入分组名称" }],
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -236,7 +186,7 @@ export default {
|
||||
remove(row) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "<p>确定删除该分组?</p>",
|
||||
content: "确定删除该分组?",
|
||||
onOk: () => {
|
||||
API_Member.deleteMemberGroup(row.id).then((res) => {
|
||||
if (res && res.success) {
|
||||
@@ -255,3 +205,16 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops span {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,175 +1,173 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Row>
|
||||
<Card>
|
||||
<Row @keydown.enter.native="handleSearch">
|
||||
<Form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="会员名称" prop="username">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.username"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
|
||||
<Form-item label="联系方式" prop="mobile">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.mobile"
|
||||
placeholder="请输入会员联系方式"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
class="search-btn"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
sortable="custom"
|
||||
>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
</Row>
|
||||
|
||||
<!-- 修改模态框 -->
|
||||
<Modal
|
||||
v-model="descFlag"
|
||||
:title="descTitle"
|
||||
@on-ok="handleSubmitModal"
|
||||
width="500"
|
||||
>
|
||||
<Form
|
||||
ref="formValidate"
|
||||
:model="formValidate"
|
||||
:rules="ruleValidate"
|
||||
:label-width="80"
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<FormItem label="头像">
|
||||
<el-form-item label="会员名称" prop="username">
|
||||
<el-input
|
||||
v-model="searchForm.username"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系方式" prop="mobile">
|
||||
<el-input
|
||||
v-model="searchForm.mobile"
|
||||
placeholder="请输入会员联系方式"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="username" label="会员名称" min-width="150" align="left" show-overflow-tooltip />
|
||||
<el-table-column prop="nickName" label="昵称" min-width="120" align="left" show-overflow-tooltip />
|
||||
<el-table-column label="联系方式" min-width="130">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.mobile || "" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="注册时间" min-width="180" />
|
||||
<el-table-column label="积分数量" min-width="120" align="left">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.point == void 0 ? "0" : row.point }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops" style="display: flex; justify-content: center">
|
||||
<template v-if="selectedMember">
|
||||
<a class="link-text" @click="callback(row)">选择</a>
|
||||
<span class="op-split">|</span>
|
||||
</template>
|
||||
<a class="link-text" @click="detail(row)">查看</a>
|
||||
<template v-if="!selectedMember">
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="enable(row)">启用</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="editPerm(row)">编辑</a>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="descFlag" :title="descTitle" width="500px" destroy-on-close>
|
||||
<el-form ref="formValidate" :model="formValidate" :rules="ruleValidate" label-width="80px">
|
||||
<el-form-item label="头像">
|
||||
<img :src="formValidate.face" class="face" />
|
||||
<Button
|
||||
type="text"
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
class="upload"
|
||||
@click="
|
||||
() => {
|
||||
this.picModelFlag = true;
|
||||
this.$refs.ossManage.selectImage = true;
|
||||
picModelFlag = true;
|
||||
$refs.ossManage.selectImage = true;
|
||||
}
|
||||
"
|
||||
>修改
|
||||
</Button>
|
||||
>修改</el-button>
|
||||
<input type="file" style="display: none" id="file" />
|
||||
</FormItem>
|
||||
<FormItem label="会员名称" prop="name">
|
||||
<Input
|
||||
v-model="formValidate.username"
|
||||
style="width: 200px"
|
||||
disabled
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="用户昵称" prop="name">
|
||||
<Input v-model="formValidate.nickName" style="width: 200px" />
|
||||
</FormItem>
|
||||
<FormItem label="性别" prop="sex">
|
||||
<RadioGroup
|
||||
type="button"
|
||||
button-style="solid"
|
||||
v-model="formValidate.sex"
|
||||
>
|
||||
<Radio :label="1">
|
||||
<span>男</span>
|
||||
</Radio>
|
||||
<Radio :label="0">
|
||||
<span>女</span>
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="修改密码" prop="password">
|
||||
<Input
|
||||
type="password"
|
||||
style="width: 220px"
|
||||
password
|
||||
v-model="formValidate.newPassword"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="生日" prop="birthday">
|
||||
<DatePicker
|
||||
type="date"
|
||||
format="yyyy-MM-dd"
|
||||
</el-form-item>
|
||||
<el-form-item label="会员名称" prop="name">
|
||||
<el-input v-model="formValidate.username" style="width: 200px" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="name">
|
||||
<el-input v-model="formValidate.nickName" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-radio-group v-model="formValidate.sex">
|
||||
<el-radio-button :value="1">男</el-radio-button>
|
||||
<el-radio-button :value="0">女</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="修改密码" prop="password">
|
||||
<el-input v-model="formValidate.newPassword" type="password" show-password style="width: 220px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="生日" prop="birthday">
|
||||
<el-date-picker
|
||||
v-model="formValidate.birthday"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 220px"
|
||||
></DatePicker>
|
||||
</FormItem>
|
||||
<FormItem label="所在地" prop="mail">
|
||||
{{ formValidate.region || '暂无地址' }}
|
||||
<Button style="margin-left: 10px;" @click="$refs.map.open()">选择</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
<Modal width="1200px" v-model="picModelFlag">
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="所在地" prop="mail">
|
||||
{{ formValidate.region || "暂无地址" }}
|
||||
<el-button style="margin-left: 10px" @click="$refs.map.open()">选择</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="descFlag = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmitModal">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="picModelFlag" width="1200px">
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
@callback="callbackSelected"
|
||||
:isComponent="true"
|
||||
:initialize="picModelFlag"
|
||||
/>
|
||||
</el-dialog>
|
||||
<multipleMap ref="map" @callback="selectedRegion" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import * as API_Member from "@/api/member.js";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
import multipleMap from "@/components/map/multiple-map";
|
||||
|
||||
export default {
|
||||
name: "memberRecycle",
|
||||
components: {
|
||||
|
||||
ossManage,
|
||||
multipleMap
|
||||
multipleMap,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedMember: false, //是否是其他组件调用
|
||||
descTitle: "", // modal标题
|
||||
descFlag: false, //编辑查看框
|
||||
openSearch: true, // 显示搜索
|
||||
loading: true, // 表单加载状态
|
||||
|
||||
selectedMember: false,
|
||||
descTitle: "",
|
||||
descFlag: false,
|
||||
openSearch: true,
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
order: "desc",
|
||||
@@ -177,198 +175,72 @@ export default {
|
||||
mobile: "",
|
||||
disabled: "CLOSE",
|
||||
},
|
||||
picModelFlag: false, // 选择图片
|
||||
formValidate: {}, // 表单数据
|
||||
ruleValidate: {}, //修改验证
|
||||
columns: [
|
||||
{
|
||||
title: "会员名称",
|
||||
align: "left",
|
||||
key: "username",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "昵称",
|
||||
align: "left",
|
||||
key: "nickName",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "联系方式",
|
||||
width: 130,
|
||||
key: "mobile",
|
||||
render: (h, params) => {
|
||||
if (params.row.mobile == null) {
|
||||
return h("div", [h("span", {}, "")]);
|
||||
} else {
|
||||
return h("div", [h("span", {}, params.row.mobile)]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "注册时间",
|
||||
key: "createTime",
|
||||
width: 180,
|
||||
},
|
||||
|
||||
{
|
||||
title: "积分数量",
|
||||
align: "left",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"div",
|
||||
{},
|
||||
params.row.point == void 0 ? "0" : params.row.point
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
const linkStyle = {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
};
|
||||
const sep = h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
);
|
||||
const children = [];
|
||||
if (this.selectedMember) {
|
||||
children.push(
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.callback(params.row) } },
|
||||
"选择"
|
||||
)
|
||||
);
|
||||
children.push(sep);
|
||||
}
|
||||
children.push(
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.detail(params.row) } },
|
||||
"查看"
|
||||
)
|
||||
);
|
||||
if (!this.selectedMember) {
|
||||
children.push(sep);
|
||||
children.push(
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.enable(params.row) } },
|
||||
"启用"
|
||||
)
|
||||
);
|
||||
children.push(sep);
|
||||
children.push(
|
||||
h(
|
||||
"a",
|
||||
{ style: linkStyle, on: { click: () => this.editPerm(params.row) } },
|
||||
"编辑"
|
||||
)
|
||||
);
|
||||
}
|
||||
return h(
|
||||
"div",
|
||||
{ class: "ops", style: { display: "flex", justifyContent: "center" } },
|
||||
children
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
picModelFlag: false,
|
||||
formValidate: {},
|
||||
ruleValidate: {},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 回调给父级
|
||||
callback(val) {
|
||||
this.$emit("callback", val);
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getData();
|
||||
},
|
||||
// 分页 修改页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
changePage() {
|
||||
this.getData();
|
||||
},
|
||||
// 分页 修改页数
|
||||
changePageSize(v) {
|
||||
changePageSize() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getData();
|
||||
},
|
||||
//查看详情修改
|
||||
editPerm(val) {
|
||||
this.descTitle = `查看用户 ${val.username}`;
|
||||
this.descFlag = true;
|
||||
|
||||
this.getMemberInfo(val.id);
|
||||
},
|
||||
/**
|
||||
* 查询查看会员详情
|
||||
*/
|
||||
getMemberInfo(id) {
|
||||
API_Member.getMemberInfoData(id).then((res) => {
|
||||
if (res.result) {
|
||||
this.$set(this, "formValidate", res.result);
|
||||
this.formValidate = res.result;
|
||||
}
|
||||
});
|
||||
},
|
||||
//查询会员列表
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberListData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.loading = false;
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 选中的图片
|
||||
callbackSelected(val) {
|
||||
this.picModelFlag = false;
|
||||
this.formValidate.face = val.url;
|
||||
},
|
||||
|
||||
// 选中的地址
|
||||
selectedRegion(val) {
|
||||
if(val.type === 'select'){
|
||||
const paths = val.data.map(item => item.name).join(',')
|
||||
const ids = val.data.map(item => item.id).join(',')
|
||||
|
||||
this.$set(this.formValidate,'region',paths)
|
||||
this.$set(this.formValidate,'regionId',ids)
|
||||
|
||||
}
|
||||
else{
|
||||
this.$set(this.formValidate,'region',val.data.addr)
|
||||
this.$set(this.formValidate,'regionId',val.data.addrId)
|
||||
if (val.type === "select") {
|
||||
const paths = val.data.map((item) => item.name).join(",");
|
||||
const ids = val.data.map((item) => item.id).join(",");
|
||||
this.formValidate.region = paths;
|
||||
this.formValidate.regionId = ids;
|
||||
} else {
|
||||
this.formValidate.region = val.data.addr;
|
||||
this.formValidate.regionId = val.data.addrId;
|
||||
}
|
||||
},
|
||||
|
||||
//详细
|
||||
detail(row) {
|
||||
this.$options.filters.customRouterPush({ name: "member-detail", query: { id: row.id } })
|
||||
|
||||
this.$filters.customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
},
|
||||
//启用会员
|
||||
enable(v) {
|
||||
let params = {
|
||||
memberIds: [v.id],
|
||||
@@ -382,26 +254,19 @@ export default {
|
||||
if (res.success) {
|
||||
this.$Message.success("启用成功");
|
||||
this.getData();
|
||||
} else {
|
||||
// this.$Message.error(res.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 提交修改数据
|
||||
handleSubmitModal() {
|
||||
const { nickName, sex, username, face, newPassword, id ,regionId,region} =
|
||||
this.formValidate;
|
||||
const { nickName, sex, username, face, newPassword, id, regionId, region } = this.formValidate;
|
||||
let time = new Date(this.formValidate.birthday);
|
||||
let birthday =
|
||||
time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
|
||||
let birthday = time.getFullYear() + "-" + (time.getMonth() + 1) + "-" + time.getDate();
|
||||
let submit = {
|
||||
regionId:regionId,
|
||||
regionId: regionId,
|
||||
region: region,
|
||||
nickName,
|
||||
|
||||
sex,
|
||||
birthday,
|
||||
face: face || "",
|
||||
@@ -413,6 +278,7 @@ export default {
|
||||
API_Member.updateMember(submit).then((res) => {
|
||||
if (res.result) {
|
||||
this.$Message.success("修改成功!");
|
||||
this.descFlag = false;
|
||||
this.init();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,98 +1,108 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--微信模板-->
|
||||
<Modal v-model="wechatModal" width="530">
|
||||
<p slot="header">
|
||||
<Icon type="edit"></Icon>
|
||||
<span>微信设置</span>
|
||||
</p>
|
||||
<div>
|
||||
<Form ref="wechatFormData" :model="wechatFormData" label-position="left" :label-width="100">
|
||||
<FormItem v-if="tab === 'WECHAT'" label="模板名称">
|
||||
<Input v-model="wechatFormData.name" size="large" maxlength="9" disabled></Input>
|
||||
</FormItem>
|
||||
<FormItem v-if="tab === 'WECHAT'" label="头部信息" prop="first">
|
||||
<Input v-model="wechatFormData.first" size="large" maxlength="50"></Input>
|
||||
</FormItem>
|
||||
<FormItem v-if="tab === 'WECHAT'" label="备注" prop="remark">
|
||||
<Input class='textarea' :rows="5" :autosize="{maxRows:5,minRows: 5}" v-model="wechatFormData.remark"
|
||||
type="textarea" maxlength="150"/>
|
||||
</FormItem>
|
||||
<FormItem label="是否开启" prop="enable">
|
||||
<i-switch v-model="wechatFormData.enable" size="large">
|
||||
<span slot="open">开启</span>
|
||||
<span slot="close">关闭</span>
|
||||
</i-switch>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<el-dialog v-model="wechatModal" title="微信设置" width="530px">
|
||||
<el-form ref="wechatFormData" :model="wechatFormData" label-width="100px">
|
||||
<el-form-item v-if="tab === 'WECHAT'" label="模板名称">
|
||||
<el-input v-model="wechatFormData.name" maxlength="9" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="tab === 'WECHAT'" label="头部信息" prop="first">
|
||||
<el-input v-model="wechatFormData.first" maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="tab === 'WECHAT'" label="备注" prop="remark">
|
||||
<el-input v-model="wechatFormData.remark" type="textarea" :rows="5" maxlength="150" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否开启" prop="enable">
|
||||
<el-switch v-model="wechatFormData.enable" active-text="开启" inactive-text="关闭" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button v-if="tab === 'WECHAT'" type="primary" @click="wechatFormDataEdit">保存</el-button>
|
||||
<el-button v-else type="primary" @click="wechatMPFormDataEdit">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
<div slot="footer" style="text-align: right">
|
||||
<Button v-if="tab === 'WECHAT'" type="primary" @click="wechatFormDataEdit">保存</Button>
|
||||
|
||||
<Button v-else type="primary" @click="wechatMPFormDataEdit">保存</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<Card>
|
||||
<Tabs @on-click="tabPaneChange" v-model="tab">
|
||||
<TabPane label="微信消息" name="WECHAT">
|
||||
<div class="search">
|
||||
<Row class="operation mt_10">
|
||||
<Button @click="weChatSync" type="primary">初始化微信消息</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="weChatColumns"
|
||||
:data="weChatData"
|
||||
ref="weChatTable"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="weChatSearchForm.pageNumber"
|
||||
<el-card>
|
||||
<el-tabs v-model="tab" @tab-click="tabPaneChange">
|
||||
<el-tab-pane label="微信消息" name="WECHAT">
|
||||
<div class="search">
|
||||
<div class="operation mt_10">
|
||||
<el-button type="primary" @click="weChatSync">初始化微信消息</el-button>
|
||||
</div>
|
||||
<el-table v-loading="loading" border :data="weChatData" ref="weChatTable" style="width: 100%">
|
||||
<el-table-column prop="code" label="模板编号" width="500" sortable />
|
||||
<el-table-column label="是否开启" width="150" sortable>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.enable ? "开启" : "关闭" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="模板名称" width="200" sortable />
|
||||
<el-table-column prop="createTime" label="创建时间" sortable />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="wechatSettingAlert(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="delWeChat(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="weChatSearchForm.pageNumber"
|
||||
v-model:page-size="weChatSearchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="weChatTotal"
|
||||
:page-size="weChatSearchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
size="small"
|
||||
></Page>
|
||||
</Row>
|
||||
</div>
|
||||
</TabPane>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<TabPane label="微信小程序订阅消息" name="WECHATMP">
|
||||
<div class="search">
|
||||
<Row class="operation mt_10">
|
||||
<Button @click="weChatSync('mp')" type="primary">初始化微信小程序订阅消息</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="weChatColumns"
|
||||
:data="weChatMPData"
|
||||
sortable="custom"
|
||||
ref="weChatMPTable"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="weChatMPSearchForm.pageNumber"
|
||||
<el-tab-pane label="微信小程序订阅消息" name="WECHATMP">
|
||||
<div class="search">
|
||||
<div class="operation mt_10">
|
||||
<el-button type="primary" @click="weChatSync('mp')">初始化微信小程序订阅消息</el-button>
|
||||
</div>
|
||||
<el-table v-loading="loading" border :data="weChatMPData" ref="weChatMPTable" style="width: 100%">
|
||||
<el-table-column prop="code" label="模板编号" width="500" sortable />
|
||||
<el-table-column label="是否开启" width="150" sortable>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.enable ? "开启" : "关闭" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="模板名称" width="200" sortable />
|
||||
<el-table-column prop="createTime" label="创建时间" sortable />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="wechatSettingAlert(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="delWeChat(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="weChatMPSearchForm.pageNumber"
|
||||
v-model:page-size="weChatMPSearchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="weChatMPTotal"
|
||||
:page-size="weChatMPSearchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
size="small"
|
||||
></Page>
|
||||
</Row>
|
||||
</div>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -101,257 +111,147 @@ import {
|
||||
getWechatMessagePage,
|
||||
editWechatMessageTemplate,
|
||||
delWechatMessageTemplate,
|
||||
|
||||
wechatMPMessageSync,
|
||||
getWechatMPMessagePage,
|
||||
editWechatMPMessageTemplate,
|
||||
delWechatMPMessageTemplate
|
||||
delWechatMPMessageTemplate,
|
||||
} from "@/api/setting";
|
||||
|
||||
export default {
|
||||
title: "wechat-message-manage",
|
||||
data() {
|
||||
return {
|
||||
|
||||
wechatModal: false,// modal展示
|
||||
wechatFormData: {}, // 微信数据
|
||||
wechatMPFormData: {}, // 微信订阅消息
|
||||
tab: "WECHAT", // tab栏分类
|
||||
searchForm: { // 请求参数
|
||||
type: "WECHAT"
|
||||
},
|
||||
loading: true, // 表单加载状态
|
||||
id: '', // 模板id
|
||||
//微信消息查询
|
||||
weChatSearchForm: {
|
||||
// 搜索框对应data对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
},
|
||||
weChatMPSearchForm: {
|
||||
// 搜索框对应data对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
},
|
||||
weChatColumns: [
|
||||
{
|
||||
title: "模板编号",
|
||||
key: "code",
|
||||
width: 500,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
title: "是否开启",
|
||||
key: "enable",
|
||||
sortable: true,
|
||||
width: 150,
|
||||
render: (h, params) => {
|
||||
if (params.row.enable == true) {
|
||||
return h('div', [
|
||||
h('span', {}, '开启'),
|
||||
]);
|
||||
} else {
|
||||
return h('div', [
|
||||
h('span', {}, '关闭'),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "模板名称",
|
||||
key: "name",
|
||||
width: 200,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
sortable: true,
|
||||
sortType: "desc",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.wechatSettingAlert(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.delWeChat(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
"删除"
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
],
|
||||
weChatData: [], // 表单数据
|
||||
weChatMPData: [], // 表单数据
|
||||
weChatTotal: 0, // 表单数据总数
|
||||
weChatMPTotal: 0, // 表单数据总数
|
||||
wechatModal: false,
|
||||
wechatFormData: {},
|
||||
wechatMPFormData: {},
|
||||
tab: "WECHAT",
|
||||
searchForm: { type: "WECHAT" },
|
||||
loading: true,
|
||||
id: "",
|
||||
weChatSearchForm: { pageNumber: 1, pageSize: 20 },
|
||||
weChatMPSearchForm: { pageNumber: 1, pageSize: 20 },
|
||||
weChatData: [],
|
||||
weChatMPData: [],
|
||||
weChatTotal: 0,
|
||||
weChatMPTotal: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.type = this.tab;
|
||||
this.getDataList();
|
||||
if (this.tab === "WECHAT") {
|
||||
this.weChatSearchForm.pageNumber = v;
|
||||
this.getWechatMessagePage();
|
||||
} else {
|
||||
this.weChatMPSearchForm.pageNumber = v;
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.type = this.tab;
|
||||
this.getDataList();
|
||||
if (this.tab === "WECHAT") {
|
||||
this.weChatSearchForm.pageSize = v;
|
||||
this.getWechatMessagePage();
|
||||
} else {
|
||||
this.weChatMPSearchForm.pageSize = v;
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
},
|
||||
//微信弹出框
|
||||
wechatSettingAlert(v) {
|
||||
this.wechatFormData = v
|
||||
this.id = v.id
|
||||
this.wechatModal = true
|
||||
this.wechatFormData = v;
|
||||
this.id = v.id;
|
||||
this.wechatModal = true;
|
||||
},
|
||||
|
||||
//同步微信消息
|
||||
weChatSync(mp) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
// 记得确认修改此处
|
||||
content: "确认要初始化微信小程序消息订阅?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 同步微信消息模板
|
||||
|
||||
if (mp === "mp") {
|
||||
wechatMPMessageSync().then(res => {
|
||||
wechatMPMessageSync().then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success('微信小程序消息订阅初始化');
|
||||
this.$Message.success("微信小程序消息订阅初始化");
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 同步微信消息模板
|
||||
wechatMessageSync().then(res => {
|
||||
wechatMessageSync().then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success('微信消息模板初始化成功');
|
||||
this.$Message.success("微信消息模板初始化成功");
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
wechatFormDataEdit() {
|
||||
this.$refs.wechatFormData.validate((valid) => {
|
||||
if (valid) {
|
||||
if (!this.wechatFormData.updateTime) {
|
||||
this.wechatFormData.updateTime = "";
|
||||
}
|
||||
editWechatMessageTemplate(this.id, this.wechatFormData).then((res) => {
|
||||
if (res.message === "success") {
|
||||
this.$Message.success("微信模板修改成功");
|
||||
this.wechatModal = false;
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//微信设置保存
|
||||
wechatFormDataEdit() {
|
||||
this.$refs['wechatFormData'].validate((valid) => {
|
||||
if (valid) {
|
||||
if(!this.wechatFormData.updateTime){
|
||||
this.wechatFormData.updateTime = ''
|
||||
}
|
||||
editWechatMessageTemplate(this.id, this.wechatFormData).then(res => {
|
||||
if (res.message === 'success') {
|
||||
this.$Message.success('微信模板修改成功');
|
||||
this.wechatModal = false;
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
wechatMPFormDataEdit() {
|
||||
this.$refs['wechatFormData'].validate((valid) => {
|
||||
this.$refs.wechatFormData.validate((valid) => {
|
||||
if (valid) {
|
||||
editWechatMPMessageTemplate(this.id, this.wechatMPFormData).then(res => {
|
||||
if (res.message === 'success') {
|
||||
this.$Message.success('微信消息订阅模板修改成功');
|
||||
editWechatMPMessageTemplate(this.id, this.wechatMPFormData).then((res) => {
|
||||
if (res.message === "success") {
|
||||
this.$Message.success("微信消息订阅模板修改成功");
|
||||
this.wechatModal = false;
|
||||
this.getWechatMessagePage();
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
//删除微信模消息
|
||||
delWeChat(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定删除此模板?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除微信消息模板
|
||||
if (this.tab === "WECHAT") {
|
||||
delWechatMessageTemplate(v.id).then(res => {
|
||||
delWechatMessageTemplate(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Modal.remove();
|
||||
this.$Message.success('微信模板删除成功');
|
||||
this.getWechatMessagePage()
|
||||
this.$Message.success("微信模板删除成功");
|
||||
this.getWechatMessagePage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
delWechatMPMessageTemplate(v.id).then(res => {
|
||||
delWechatMPMessageTemplate(v.id).then((res) => {
|
||||
if (res.success) {
|
||||
this.$Modal.remove();
|
||||
this.$Message.success('微信消息订阅删除成功');
|
||||
this.getWechatMessagePage()
|
||||
this.$Message.success("微信消息订阅删除成功");
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
},
|
||||
selectDateRange(v) {
|
||||
if (v) {
|
||||
this.searchForm.startDate = v[0];
|
||||
this.searchForm.endDate = v[1];
|
||||
}
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getWechatMessagePage(this.searchWe).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.weChatData = res.result.records;
|
||||
this.weChatTotal = res.result.total;
|
||||
}
|
||||
});
|
||||
this.getWechatMessagePage();
|
||||
},
|
||||
//分页获取微信消息
|
||||
getWechatMessagePage() {
|
||||
getWechatMessagePage(this.weChatSearchForm).then(res => {
|
||||
this.loading = true;
|
||||
getWechatMessagePage(this.weChatSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.weChatData = res.result.records;
|
||||
@@ -359,9 +259,9 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//分页获取微信小程序消息订阅
|
||||
getWechatMPMessagePage() {
|
||||
getWechatMPMessagePage(this.weChatMPSearchForm).then(res => {
|
||||
this.loading = true;
|
||||
getWechatMPMessagePage(this.weChatMPSearchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.weChatMPData = res.result.records;
|
||||
@@ -369,20 +269,30 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//tab切换事件
|
||||
tabPaneChange(v) {
|
||||
tabPaneChange(tab) {
|
||||
const v = tab.paneName || this.tab;
|
||||
this.searchForm.type = v;
|
||||
//如果是微信消息则走单独的接口
|
||||
if (v === "WECHAT") {
|
||||
this.getWechatMessagePage();
|
||||
} else if (v === "WECHATMP") {
|
||||
this.getWechatMPMessagePage();
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,518 +1,434 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card class="points-statistics-card">
|
||||
<Row type="flex" justify="space-around" align="middle" class="points-statistics">
|
||||
<Col :xs="24" :sm="12" class="points-statistics-item">
|
||||
<el-card class="points-statistics-card">
|
||||
<el-row type="flex" justify="space-around" align="middle" class="points-statistics">
|
||||
<el-col :xs="24" :sm="12" class="points-statistics-item">
|
||||
<div class="points-statistics-title">已发放积分数</div>
|
||||
<div class="points-statistics-subtitle">历史累计发放积分数</div>
|
||||
<div class="points-statistics-value">{{ formatNumber(pointsStatistics.totalPoint) }}</div>
|
||||
</Col>
|
||||
<Col :xs="24" :sm="12" class="points-statistics-item">
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" class="points-statistics-item">
|
||||
<div class="points-statistics-title">未使用积分数</div>
|
||||
<div class="points-statistics-subtitle">会员账户未使用积分数</div>
|
||||
<div class="points-statistics-value">{{ formatNumber(pointsStatistics.unUsedPoint) }}</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<div class="point-tabs-wrap">
|
||||
<Tabs v-model="activeTab" class="point-tabs">
|
||||
<TabPane label="积分列表" name="pointList">
|
||||
<Card class="point-content-card">
|
||||
<Form
|
||||
@keydown.enter.native="handleMemberSearch"
|
||||
ref="memberSearchForm"
|
||||
:model="memberSearchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
@submit.native.prevent
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="客户名称" prop="nickName">
|
||||
<Input
|
||||
v-model="memberSearchForm.nickName"
|
||||
placeholder="请输入客户名称"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
<el-tabs v-model="activeTab" class="point-tabs">
|
||||
<el-tab-pane label="积分列表" name="pointList">
|
||||
<el-card class="point-content-card">
|
||||
<el-form
|
||||
ref="memberSearchForm"
|
||||
:model="memberSearchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleMemberSearch"
|
||||
>
|
||||
<el-form-item label="客户名称" prop="nickName">
|
||||
<el-input
|
||||
v-model="memberSearchForm.nickName"
|
||||
placeholder="请输入客户名称"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="客户账号" prop="username">
|
||||
<el-input
|
||||
v-model="memberSearchForm.username"
|
||||
placeholder="请输入客户账号"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="账号状态" prop="disabled">
|
||||
<el-select
|
||||
v-model="memberSearchForm.disabled"
|
||||
clearable
|
||||
placeholder="请选择账号状态"
|
||||
style="width: 160px"
|
||||
>
|
||||
<el-option label="启用" value="OPEN" />
|
||||
<el-option label="禁用" value="CLOSE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="积分值">
|
||||
<el-input-number
|
||||
v-model="memberSearchForm.minPoint"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
placeholder="最小积分值"
|
||||
style="width: 140px"
|
||||
/>
|
||||
<span class="point-range-separator">-</span>
|
||||
<el-input-number
|
||||
v-model="memberSearchForm.maxPoint"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
placeholder="最大积分值"
|
||||
style="width: 140px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="search-btn" type="primary" @click="handleMemberSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="point-content-card member-list-card">
|
||||
<template #header>
|
||||
<div class="card-title">用户列表</div>
|
||||
</template>
|
||||
<el-table
|
||||
v-loading="memberLoading"
|
||||
:data="memberData"
|
||||
class="member-table"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="客户名称" width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.nickName || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户账号" width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.username || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="账号状态" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.disabled === true ? 'success' : 'info'">
|
||||
{{ row.disabled === true ? "启用" : "禁用" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="积分余额" width="180">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.point == null ? 0 : row.point }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<a v-if="row" class="link-text" @click="detail(row)">详情</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="memberSearchForm.pageNumber"
|
||||
v-model:page-size="memberSearchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="memberTotal"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changeMemberPage"
|
||||
@size-change="changeMemberPageSize"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="客户账号" prop="username">
|
||||
<Input
|
||||
v-model="memberSearchForm.username"
|
||||
placeholder="请输入客户账号"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
</div>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="积分增减记录" name="pointChangeRecord">
|
||||
<el-card class="point-content-card">
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="username">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="search-btn" type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="point-content-card">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10 point-table"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="content" label="操作内容" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="beforePoint" label="之前积分" width="200" />
|
||||
<el-table-column label="变动积分" width="200">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<priceColorScheme
|
||||
v-if="row.pointType === 'INCREASE'"
|
||||
:value="row.variablePoint"
|
||||
color="green"
|
||||
unit="+"
|
||||
/>
|
||||
<priceColorScheme
|
||||
v-else
|
||||
:value="row.variablePoint"
|
||||
:color="$mainColor"
|
||||
unit="-"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="point" label="当前积分" width="200" />
|
||||
<el-table-column prop="createTime" label="操作时间" width="200" />
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="账号状态" prop="disabled">
|
||||
<Select
|
||||
v-model="memberSearchForm.disabled"
|
||||
clearable
|
||||
placeholder="请选择账号状态"
|
||||
style="width: 160px"
|
||||
>
|
||||
<Option value="OPEN">启用</Option>
|
||||
<Option value="CLOSE">禁用</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="积分值">
|
||||
<InputNumber
|
||||
v-model="memberSearchForm.minPoint"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
placeholder="最小积分值"
|
||||
style="width: 140px"
|
||||
/>
|
||||
<span class="point-range-separator">-</span>
|
||||
<InputNumber
|
||||
v-model="memberSearchForm.maxPoint"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
placeholder="最大积分值"
|
||||
style="width: 140px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleMemberSearch" class="search-btn" type="primary" icon="ios-search">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card class="point-content-card member-list-card">
|
||||
<div slot="title" class="card-title">用户列表</div>
|
||||
<Table
|
||||
:loading="memberLoading"
|
||||
:columns="memberColumns"
|
||||
:data="memberData"
|
||||
class="member-table"
|
||||
>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="memberSearchForm.pageNumber"
|
||||
:total="memberTotal"
|
||||
:page-size="memberSearchForm.pageSize"
|
||||
@on-change="changeMemberPage"
|
||||
@on-page-size-change="changeMemberPageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
</TabPane>
|
||||
<TabPane label="积分增减记录" name="pointChangeRecord">
|
||||
<Card class="point-content-card">
|
||||
<Form
|
||||
@keydown.enter.native="handleSearch"
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
@submit.native.prevent
|
||||
class="search-form"
|
||||
>
|
||||
<Form-item label="会员名称" prop="username">
|
||||
<Input
|
||||
type="text"
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card class="point-content-card">
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10 point-table"
|
||||
>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Member from "@/api/member.js";
|
||||
|
||||
import * as API_Member from "@/api/member.js";
|
||||
|
||||
export default {
|
||||
// 积分历史页面
|
||||
name: "point",
|
||||
data() {
|
||||
return {
|
||||
activeTab: "pointList",
|
||||
loading: true, // 表单加载状态
|
||||
memberLoading: false,
|
||||
pointsStatistics: {
|
||||
totalPoint: 0,
|
||||
unUsedPoint: 0,
|
||||
},
|
||||
searchForm: { // 请求参数
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
memberSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
nickName: "",
|
||||
username: "",
|
||||
disabled: "",
|
||||
minPoint: null,
|
||||
maxPoint: null,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 120,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: "操作内容",
|
||||
key: "content",
|
||||
minWidth: 200,
|
||||
tooltip: true
|
||||
},
|
||||
|
||||
{
|
||||
title: "之前积分",
|
||||
key: "beforePoint",
|
||||
width: 200,
|
||||
},
|
||||
|
||||
{
|
||||
title: "变动积分",
|
||||
key: "variablePoint",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
if (params.row.pointType == 'INCREASE') {
|
||||
return h("priceColorScheme", {props:{value:params.row.variablePoint,color:'green',unit:"+"}} );
|
||||
} else {
|
||||
return h("priceColorScheme", {props:{value:params.row.variablePoint,color:this.$mainColor,unit:"-"}} );
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "当前积分",
|
||||
key: "point",
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "操作时间",
|
||||
key: "createTime",
|
||||
width: 200
|
||||
},
|
||||
|
||||
],
|
||||
memberColumns: [
|
||||
{
|
||||
title: "客户名称",
|
||||
key: "nickName",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("span", params.row.nickName || "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "客户账号",
|
||||
key: "username",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
render: (h, params) => {
|
||||
return h("span", params.row.username || "-");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "账号状态",
|
||||
key: "disabled",
|
||||
width: 180,
|
||||
render: (h, params) => {
|
||||
const enabled = params.row.disabled === true;
|
||||
return h(
|
||||
"Tag",
|
||||
{
|
||||
props: {
|
||||
color: enabled ? "success" : "default",
|
||||
},
|
||||
},
|
||||
enabled ? "启用" : "禁用"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "积分余额",
|
||||
key: "point",
|
||||
width: 180,
|
||||
render: (h, params) => {
|
||||
const point = params.row.point == null ? 0 : params.row.point;
|
||||
return h("span", point);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.detail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"详情"
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
memberData: [],
|
||||
memberTotal: 0,
|
||||
total: 0, // 表单数据总数
|
||||
};
|
||||
export default {
|
||||
name: "point",
|
||||
data() {
|
||||
return {
|
||||
activeTab: "pointList",
|
||||
loading: true,
|
||||
memberLoading: false,
|
||||
pointsStatistics: {
|
||||
totalPoint: 0,
|
||||
unUsedPoint: 0,
|
||||
},
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
memberSearchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
nickName: "",
|
||||
username: "",
|
||||
disabled: "",
|
||||
minPoint: null,
|
||||
maxPoint: null,
|
||||
},
|
||||
data: [],
|
||||
memberData: [],
|
||||
memberTotal: 0,
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
callback(val) {
|
||||
this.$emit("callback", val);
|
||||
},
|
||||
methods: {
|
||||
// 回调给父级
|
||||
callback(val) {
|
||||
this.$emit("callback", val);
|
||||
},
|
||||
// 查看会员详情
|
||||
detail(row) {
|
||||
this.$options.filters.customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getStatistics();
|
||||
this.getMemberList();
|
||||
this.getData();
|
||||
},
|
||||
getStatistics() {
|
||||
API_Member.queryMemberPointsStatistics().then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.pointsStatistics = {
|
||||
totalPoint: res.result.totalPoint || 0,
|
||||
unUsedPoint: res.result.unUsedPoint || 0,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
formatNumber(value) {
|
||||
const numericValue = Number(value || 0);
|
||||
if (!Number.isFinite(numericValue)) return "0";
|
||||
return numericValue.toLocaleString();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getData();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getData();
|
||||
},
|
||||
handleMemberSearch() {
|
||||
this.memberSearchForm.pageNumber = 1;
|
||||
this.getMemberList();
|
||||
},
|
||||
changeMemberPage(v) {
|
||||
this.memberSearchForm.pageNumber = v;
|
||||
this.getMemberList();
|
||||
},
|
||||
changeMemberPageSize(v) {
|
||||
this.memberSearchForm.pageNumber = 1;
|
||||
this.memberSearchForm.pageSize = v;
|
||||
this.getMemberList();
|
||||
},
|
||||
getMemberList() {
|
||||
this.memberLoading = true;
|
||||
const params = {
|
||||
pageNumber: this.memberSearchForm.pageNumber,
|
||||
pageSize: this.memberSearchForm.pageSize,
|
||||
nickName: this.memberSearchForm.nickName || undefined,
|
||||
username: this.memberSearchForm.username || undefined,
|
||||
disabled: this.memberSearchForm.disabled || undefined,
|
||||
minPoint: this.memberSearchForm.minPoint,
|
||||
maxPoint: this.memberSearchForm.maxPoint,
|
||||
};
|
||||
API_Member.getMemberListData(params).then((res) => {
|
||||
detail(row) {
|
||||
this.$filters.customRouterPush({ name: "member-detail", query: { id: row.id } });
|
||||
},
|
||||
init() {
|
||||
this.getStatistics();
|
||||
this.getMemberList();
|
||||
this.getData();
|
||||
},
|
||||
getStatistics() {
|
||||
API_Member.queryMemberPointsStatistics().then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.pointsStatistics = {
|
||||
totalPoint: res.result.totalPoint || 0,
|
||||
unUsedPoint: res.result.unUsedPoint || 0,
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
formatNumber(value) {
|
||||
const numericValue = Number(value || 0);
|
||||
if (!Number.isFinite(numericValue)) return "0";
|
||||
return numericValue.toLocaleString();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getData();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getData();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getData();
|
||||
},
|
||||
handleMemberSearch() {
|
||||
this.memberSearchForm.pageNumber = 1;
|
||||
this.getMemberList();
|
||||
},
|
||||
changeMemberPage(v) {
|
||||
this.memberSearchForm.pageNumber = v;
|
||||
this.getMemberList();
|
||||
},
|
||||
changeMemberPageSize(v) {
|
||||
this.memberSearchForm.pageNumber = 1;
|
||||
this.memberSearchForm.pageSize = v;
|
||||
this.getMemberList();
|
||||
},
|
||||
getMemberList() {
|
||||
this.memberLoading = true;
|
||||
const params = {
|
||||
pageNumber: this.memberSearchForm.pageNumber,
|
||||
pageSize: this.memberSearchForm.pageSize,
|
||||
nickName: this.memberSearchForm.nickName || undefined,
|
||||
username: this.memberSearchForm.username || undefined,
|
||||
disabled: this.memberSearchForm.disabled || undefined,
|
||||
minPoint: this.memberSearchForm.minPoint,
|
||||
maxPoint: this.memberSearchForm.maxPoint,
|
||||
};
|
||||
API_Member.getMemberListData(params)
|
||||
.then((res) => {
|
||||
this.memberLoading = false;
|
||||
if (res && res.success && res.result && res.result.records) {
|
||||
this.memberData = res.result.records;
|
||||
this.memberTotal = res.result.total;
|
||||
}
|
||||
}).catch(() => {
|
||||
})
|
||||
.catch(() => {
|
||||
this.memberLoading = false;
|
||||
});
|
||||
},
|
||||
//查新积分列表
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getHistoryPointData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
API_Member.getHistoryPointData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
},
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.points-statistics-card {
|
||||
margin-bottom: 10px;
|
||||
.points-statistics-card {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.point-tabs-wrap {
|
||||
padding: 12px 16px 16px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(23, 35, 61, 0.04);
|
||||
}
|
||||
|
||||
.point-tabs {
|
||||
:deep(.el-tabs__header) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.point-tabs-wrap {
|
||||
padding: 12px 16px 16px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(23, 35, 61, 0.04);
|
||||
:deep(.el-tabs__item) {
|
||||
padding: 8px 18px;
|
||||
color: #515a6e;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.point-tabs {
|
||||
::v-deep .ivu-tabs-bar {
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
::v-deep .ivu-tabs-nav .ivu-tabs-tab {
|
||||
padding: 8px 18px;
|
||||
color: #515a6e;
|
||||
background: #fff;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
::v-deep .ivu-tabs-nav .ivu-tabs-tab-active {
|
||||
color: #2d8cf0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
::v-deep .ivu-tabs-ink-bar {
|
||||
height: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.points-statistics {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.points-statistics-item {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.points-statistics-title {
|
||||
font-size: 14px;
|
||||
color: #17233d;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.points-statistics-subtitle {
|
||||
font-size: 12px;
|
||||
color: #808695;
|
||||
line-height: 18px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.points-statistics-value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #fa6419;
|
||||
line-height: 26px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.point-table {
|
||||
::v-deep .ivu-table-border th,
|
||||
::v-deep .ivu-table-border td {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.point-content-card {
|
||||
margin-bottom: 12px;
|
||||
|
||||
::v-deep .ivu-card-body {
|
||||
padding: 18px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.member-list-card {
|
||||
::v-deep .ivu-card-head {
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 14px;
|
||||
:deep(.el-tabs__item.is-active) {
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
color: #17233d;
|
||||
}
|
||||
|
||||
.member-table {
|
||||
::v-deep .ivu-table-header th {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
::v-deep .ivu-tag {
|
||||
margin-right: 0;
|
||||
}
|
||||
:deep(.el-tabs__active-bar) {
|
||||
height: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.point-range-separator {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #808695;
|
||||
}
|
||||
.points-statistics {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.face {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
.points-statistics-item {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.points-statistics-title {
|
||||
font-size: 14px;
|
||||
color: #17233d;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.points-statistics-subtitle {
|
||||
font-size: 12px;
|
||||
color: #808695;
|
||||
line-height: 18px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.points-statistics-value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #fa6419;
|
||||
line-height: 26px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.point-content-card {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.member-list-card {
|
||||
:deep(.el-card__header) {
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #17233d;
|
||||
}
|
||||
|
||||
.member-table {
|
||||
:deep(.el-table__header th) {
|
||||
background: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
.point-range-separator {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #808695;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.face {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,351 +1,197 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Tabs value="RETURN_MONEY" @on-click="handleClickType">
|
||||
<TabPane label="退款" name="RETURN_MONEY">
|
||||
<Row class="operation" style="margin-bottom: 10px">
|
||||
<Button @click="add" type="primary" >添加</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</TabPane>
|
||||
<TabPane label="取消" name="CANCEL">
|
||||
<Row class="operation" style="margin-bottom: 10px">
|
||||
<Button @click="add" type="primary" icon="md-add">添加</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</TabPane>
|
||||
<TabPane label="退货" name="RETURN_GOODS">
|
||||
<Row class="operation" style="margin-bottom: 10px">
|
||||
<Button @click="add" type="primary" icon="md-add">添加</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</TabPane>
|
||||
<TabPane label="投诉" name="COMPLAIN">
|
||||
<Row class="operation" style="margin-bottom: 10px">
|
||||
<Button @click="add" type="primary" icon="md-add">添加</Button>
|
||||
<Button @click="getDataList" icon="md-refresh">刷新</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="售后原因" prop="reason">
|
||||
<Input v-model="form.reason" maxlength="20" clearable style="width: 100%"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
|
||||
>提交
|
||||
</Button
|
||||
>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeTab" @tab-click="onTabClick">
|
||||
<el-tab-pane label="退款" name="RETURN_MONEY">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="取消" name="CANCEL">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="退货" name="RETURN_GOODS">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="投诉" name="COMPLAIN">
|
||||
<div class="operation" style="margin-bottom: 10px">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
<el-button @click="getDataList">刷新</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-table v-loading="loading" border :data="data" ref="table" style="width: 100%">
|
||||
<el-table-column prop="createBy" label="创建人" min-width="120" />
|
||||
<el-table-column prop="reason" label="原因" min-width="400" />
|
||||
<el-table-column prop="createTime" label="时间" min-width="100" />
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="售后原因" prop="reason">
|
||||
<el-input v-model="form.reason" maxlength="20" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as API_Order from "@/api/order";
|
||||
import * as API_Order from "@/api/order";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
modalVisible: false,//添加售后原因弹出框
|
||||
modalTitle: "", //添加售后原因弹出框标题
|
||||
loading: true, // 表单加载状态
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
form: {
|
||||
reason: ""
|
||||
},//添加编辑表单
|
||||
formValidate: {
|
||||
reason: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入售后原因",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
serviceType: "RETURN_MONEY"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "创建人",
|
||||
key: "createBy",
|
||||
minWidth: 120,
|
||||
},
|
||||
{
|
||||
title: "原因",
|
||||
key: "reason",
|
||||
minWidth: 400,
|
||||
},
|
||||
{
|
||||
title: "时间",
|
||||
key: "createTime",
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
}
|
||||
}
|
||||
},
|
||||
"删除"
|
||||
)
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0,//条数
|
||||
};
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeTab: "RETURN_MONEY",
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
loading: true,
|
||||
submitLoading: false,
|
||||
form: { reason: "" },
|
||||
formValidate: {
|
||||
reason: [{ required: true, message: "请输入售后原因", trigger: "blur" }],
|
||||
},
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
serviceType: "RETURN_MONEY",
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onTabClick(tab) {
|
||||
this.handleClickType(tab.paneName);
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 分页 修改页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 分页 修改页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
//切换tab
|
||||
handleClickType(v) {
|
||||
this.searchForm.pageNumber = 1 // 当前页数
|
||||
this.searchForm.pageSize = 20 // 页面大小
|
||||
//退款
|
||||
if (v == "RETURN_MONEY") {
|
||||
this.searchForm.serviceType = "RETURN_MONEY"
|
||||
}
|
||||
//退货
|
||||
if (v == "RETURN_GOODS") {
|
||||
this.searchForm.serviceType = "RETURN_GOODS"
|
||||
}
|
||||
//取消
|
||||
if (v == "CANCEL") {
|
||||
this.searchForm.serviceType = "CANCEL"
|
||||
}
|
||||
//取消
|
||||
if (v == "COMPLAIN") {
|
||||
this.searchForm.serviceType = "COMPLAIN"
|
||||
}
|
||||
this.getDataList();
|
||||
},
|
||||
//获取售后原因数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getAfterSaleReasonPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
},
|
||||
//添加售后原因
|
||||
add() {
|
||||
this.form.reason = ""
|
||||
this.modalVisible = true
|
||||
this.modalTitle = "添加售后原因"
|
||||
},
|
||||
//修改售后原因
|
||||
edit(v) {
|
||||
|
||||
this.form.reason = v.reason
|
||||
this.form.id = v.id
|
||||
|
||||
this.modalVisible = true
|
||||
this.modalTitle = "修改售后原因"
|
||||
},
|
||||
//提交表单
|
||||
handleSubmit() {
|
||||
this.form.serviceType = this.searchForm.serviceType
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalTitle == '添加售后原因') {
|
||||
// 添加
|
||||
delete this.form.id;
|
||||
API_Order.addAfterSaleReason(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
API_Order.editAfterSaleReason(this.form.id, this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
//删除售后原因
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
// 记得确认修改此处
|
||||
content: "确认要删除此售后原因?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
API_Order.delAfterSaleReason(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("售后原因已删除");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
};
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleClickType(v) {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.searchForm.serviceType = v;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Order.getAfterSaleReasonPage(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
add() {
|
||||
this.form.reason = "";
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = "添加售后原因";
|
||||
},
|
||||
edit(v) {
|
||||
this.form.reason = v.reason;
|
||||
this.form.id = v.id;
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = "修改售后原因";
|
||||
},
|
||||
handleSubmit() {
|
||||
this.form.serviceType = this.searchForm.serviceType;
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalTitle == "添加售后原因") {
|
||||
delete this.form.id;
|
||||
API_Order.addAfterSaleReason(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
API_Order.editAfterSaleReason(this.form.id, this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getDataList();
|
||||
this.modalVisible = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "确认要删除此售后原因?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
API_Order.delAfterSaleReason(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("售后原因已删除");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getDataList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user