refactor(manager): 替换iView组件为TDesign并优化样式

- 将iView组件统一替换为TDesign组件
- 优化表单、表格、弹窗等交互样式
- 修复路由重复添加问题
- 更新依赖版本
- 调整布局间距与响应式
- 修复表单重置方法兼容性
- 统一消息提示组件
This commit is contained in:
pikachu1995@126.com
2025-11-30 18:19:19 +08:00
parent e5d98d022e
commit 028f32a73c
180 changed files with 10701 additions and 17865 deletions

View File

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

1
.vercel/project.json Normal file
View File

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

View File

@@ -132,6 +132,13 @@ github 镜像: https://github.com/lilishop?tab=repositories
商城UI 项目下3个文件夹
buyer买家PC端seller商家端manager后台管理端
### 前端 UI 框架与版本
- manager`tdesign-vue@^1.14.2``tdesign-icons-vue@^0.2.3``view-design@^4.7.0``vue@2.6.14`
- buyer`view-design@^4.3.2``vue@^2.6.11`
- seller`view-design@^4.6.1``vue@^2.6.10`
- im`element-ui@^2.14.1``vue@^2.6.11`
### 演示地址
PS手机验证码为 111111

View File

@@ -0,0 +1,5 @@
### UI 框架与版本
- `view-design@^4.3.2`
- `vue@^2.6.11`

View File

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

View File

@@ -4,6 +4,12 @@
### Customize configuration
详情点击 [https://cli.vuejs.org/zn/config/](https://cli.vuejs.org/zn/config/).
### UI 框架与版本
- `tdesign-vue@^1.14.2`
- `tdesign-icons-vue@^0.2.3`
- `vue@2.6.14`
#### login.vue页面测试时不走权限直接return 318行
#### Main.vue 页面241行修改避免报错

View File

@@ -25,8 +25,10 @@
"sockjs-client": "^1.4.0",
"swiper": "^6.3.5",
"uuid": "^8.3.2",
"view-design": "^4.7.0",
"vue": "^2.6.10",
"tdesign-vue": "^1.14.2",
"tdesign-icons-vue": "^0.2.3",
"@vue/composition-api": "^1.7.1",
"vue": "2.6.14",
"vue-awesome-swiper": "^4.1.1",
"vue-i18n": "^8.15.1",
"vue-json-excel": "^0.3.0",
@@ -50,7 +52,7 @@
"style-resources-loader": "^1.3.2",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-cli-plugin-style-resources-loader": "^0.1.4",
"vue-template-compiler": "^2.6.10"
"vue-template-compiler": "2.6.14"
},
"resolutions": {
"minimatch": "^3.1.2",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,10 +1,9 @@
<template>
<div class="wrapper">
<Tabs :value="wap[0].title" class="tabs">
<TabPane
<t-tabs :value="wap[0].title" class="tabs" @change="onTabChange">
<t-tab-panel
:label="item.title"
:name="item.title"
@click="clickTag(item, i)"
:value="item.title"
v-for="(item, i) in wap"
:key="i"
>
@@ -17,9 +16,8 @@
}
"
/>
</TabPane>
<!-- </template> -->
</Tabs>
</t-tab-panel>
</t-tabs>
</div>
</template>
<script>
@@ -96,6 +94,8 @@ export default {
});
},
methods: {
onTabChange(val){
}
// isVisible(item) {
// const type = this.$route.query.pagetype;
// if (type == "INDEX" && [ "discover"].includes(item.name)) {

View File

@@ -1,8 +1,8 @@
<template>
<div>
<Row :gutter="30">
<Col
span="4"
<t-row :gutter="30">
<t-col
:span="4"
v-for="(item, index) in linkList"
:key="index"
v-if="
@@ -15,23 +15,23 @@
:class="{ active: selectedIndex == index }"
@click="handleLink(item, index)"
>
<Icon size="24" :type="item.icon" />
<t-icon name="link" size="24" />
<p>{{ item.title }}</p>
</div>
</Col>
</t-col>
<!-- 外部链接只有pc端跳转 -->
<Col span="4">
<t-col :span="4">
<div
v-if="linkVisible"
class="card"
:class="{ active: selectedIndex == linkList.length }"
@click="handleLink(linkItem, linkList.length)"
>
<Icon size="24" :type="linkItem.icon" />
<t-icon name="link" size="24" />
<p>{{ linkItem.title }}</p>
</div>
</Col>
</Row>
</t-col>
</t-row>
</div>
</template>
<script>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,61 +1,35 @@
<template>
<div>
<Card>
<Row @keydown.enter.native.prevent="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 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"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table class="mt_10" :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id"></t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[20, 50, 100]"
:total="Number(total)"
:pageSize="searchForm.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
:showJumper="true"
@change="onPaginationChange"
/>
</div>
</t-card>
</div>
</template>
<script>
import { auditDistribution, getDistributionListData } from "@/api/distribution";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "distributionApply",
@@ -72,49 +46,20 @@ export default {
endDate: "", // 终止时间
},
columns: [
{
title: "会员名称",
key: "memberName",
minWidth: 100,
tooltip: true,
},
{
title: "姓名",
key: "name",
minWidth: 100,
},
{
title: "身份证号",
key: "idNumber",
minWidth: 120,
},
{
title: "结算银行开户行名称",
key: "settlementBankAccountName",
minWidth: 120,
},
{
title: "结算银行开户账号",
key: "settlementBankAccountNum",
minWidth: 120,
},
{
title: "结算银行开户支行名称",
key: "settlementBankBranchName",
minWidth: 120,
},
{
title: "提交时间",
key: "createTime",
minWidth: 100,
},
{ title: "会员名称", colKey: "memberName", minWidth: 100, align: "left", tooltip: true },
{ title: "姓名", colKey: "name", minWidth: 100, align: "left" },
{ title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
{ title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
{ title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
{ title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ title: "提交时间", colKey: "createTime", minWidth: 120, align: "left" },
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
fixed: "right",
width: 200,
render: (h, params) => {
cell: (h, params) => {
return h("div", { class: "ops" }, [
h(
"a",
@@ -152,17 +97,22 @@ export default {
init() {
this.getDataList();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
this.clearSelectAll();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
@@ -173,35 +123,33 @@ export default {
getDataList() {
this.loading = true;
this.searchForm.distributionStatus = "APPLY";
getDistributionListData(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
this.loading = false;
getDistributionListData(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.catch(() => {
this.loading = false;
});
},
//审核
audit(v, status) {
let test = "拒绝";
if (status == "PASS") {
if (status === "PASS") {
test = "通过";
}
let params = {
status: status,
};
this.$Modal.confirm({
title: "确认" + test,
// 记得确认修改此处
const params = { status };
DialogPlugin.confirm({
header: "确认" + test,
content: "您确认要" + test + " " + v.memberName + " ?",
loading: true,
onOk: () => {
theme: "warning",
onConfirm: () => {
auditDistribution(v.id, params).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
}
});

View File

@@ -1,66 +1,81 @@
<template>
<div>
<Card>
<Form ref="searchForm" @keydown.enter.native.prevent="handleSearch" :model="searchForm" class="search-form">
<Form-item label="会员名称" class="flex" prop="memberName">
<Input
type="text" placeholder="请输入会员名称" v-model="searchForm.memberName" clearable
style="width: 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>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" class="search-form" @submit="handleSearch">
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="编号" name="sn">
<t-input v-model="searchForm.sn" placeholder="请输入编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="状态">
<t-select v-model="searchForm.distributionCashStatus" clearable style="width: 240px">
<t-option v-for="item in cashStatusList" :value="item.value" :key="item.value" :label="item.label" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id"></t-table>
<div class="page padding-row" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</Modal>
</t-card>
<t-drawer :visible.sync="modalVisible" :header="modalTitle" placement="right" size="500px" @close="modalVisible = false">
<div v-if="handleStatus === 'view'">
<t-descriptions :column="1" size="medium">
<t-descriptions-item label="编号">{{ form.sn }}</t-descriptions-item>
<t-descriptions-item label="会员名称">{{ form.distributionName }}</t-descriptions-item>
<t-descriptions-item label="申请金额">{{ form.price }}</t-descriptions-item>
<t-descriptions-item label="申请时间">{{ form.createTime }}</t-descriptions-item>
<t-descriptions-item label="姓名">{{ form.name }}</t-descriptions-item>
<t-descriptions-item label="身份证号">{{ form.idNumber }}</t-descriptions-item>
<t-descriptions-item label="结算银行开户行名称">{{ form.settlementBankAccountName }}</t-descriptions-item>
<t-descriptions-item label="结算银行开户账号">{{ form.settlementBankAccountNum }}</t-descriptions-item>
<t-descriptions-item label="结算银行开户支行名称">{{ form.settlementBankBranchName }}</t-descriptions-item>
<t-descriptions-item label="处理时间">{{ form.updateTime }}</t-descriptions-item>
<t-descriptions-item label="状态">{{ { APPLY: '待处理', VIA_AUDITING: '通过', FAIL_AUDITING: '审核拒绝' }[form.distributionCashStatus] || form.distributionCashStatus }}</t-descriptions-item>
</t-descriptions>
</div>
<div v-else>
<t-form ref="form" :data="form" :labelWidth="100">
<t-form-item label="编号">
<t-input v-model="form.sn" disabled style="width: 100%" />
</t-form-item>
<t-form-item label="会员名称">
<t-input v-model="form.distributionName" disabled style="width: 100%" />
</t-form-item>
<t-form-item label="金额">
<t-input v-model="form.price" disabled style="width: 100%" />
</t-form-item>
<t-form-item label="是否通过">
<t-radio-group v-model="result">
<t-radio value="VIA_AUDITING">通过</t-radio>
<t-radio value="FAIL_AUDITING">拒绝</t-radio>
</t-radio-group>
</t-form-item>
</t-form>
</div>
<template #footer>
<div v-if="handleStatus === 'edit'" style="display: flex; justify-content: flex-end">
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" style="margin-left: 8px" @click="handleSubmit">提交</t-button>
</div>
<div v-else style="display: flex; justify-content: flex-start">
<t-button theme="primary" @click="modalVisible = false">返回</t-button>
</div>
</template>
</t-drawer>
</div>
</template>
<script>
import {
auditDistributionCash,
getDistributionCash
} from "@/api/distribution";
import { cashStatusList } from './dataJson';
import { auditDistributionCash, getDistributionCash } from "@/api/distribution";
import { cashStatusList } from "./dataJson";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "distributionCash",
data() {
@@ -84,83 +99,36 @@ export default {
},
submitLoading: false, // 添加或编辑提交状态
columns: [
{ title: "编号", colKey: "sn", width: 300, align: "left" },
{ title: "会员名称", colKey: "distributionName", minWidth: 120, align: "left" },
{ title: "申请金额", colKey: "price", minWidth: 100, align: "left", cell: (h, p) => h("priceColorScheme", { props: { value: p.row.price, color: this.$mainColor } }) },
{ title: "申请时间", colKey: "createTime", minWidth: 150, align: "left" },
{ title: "姓名", colKey: "name", minWidth: 100, align: "left" },
{ title: "身份证号", colKey: "idNumber", minWidth: 120, align: "left" },
{ title: "结算银行开户行名称", colKey: "settlementBankAccountName", minWidth: 120, align: "left" },
{ title: "结算银行开户账号", colKey: "settlementBankAccountNum", minWidth: 120, align: "left" },
{ title: "结算银行开户支行名称", colKey: "settlementBankBranchName", minWidth: 120, align: "left" },
{ title: "处理时间", colKey: "updateTime", minWidth: 150, align: "left" },
{
title: "编号",
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: "状态",
colKey: "distributionCashStatus",
minWidth: 120,
align: "left",
cell: (h, p) => {
const s = p.row.distributionCashStatus;
const map = { APPLY: { theme: "warning", label: "待处理" }, VIA_AUDITING: { theme: "success", label: "通过" }, FAIL_AUDITING: { theme: "danger", label: "审核拒绝" } };
const cfg = map[s] || { theme: "default", label: s };
return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
},
},
{
title: "申请时间",
key: "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",
colKey: "action",
align: "center",
fixed: "right",
width: 130,
render: (h, params) => {
if (params.row.distributionCashStatus != 'APPLY') {
cell: (h, params) => {
if (params.row.distributionCashStatus !== "APPLY") {
return h("div", { class: "ops" }, [
h(
"a",
@@ -168,29 +136,28 @@ export default {
on: {
click: () => {
this.view(params.row);
}
}
},
},
},
"查看"
),
]);
} else {
return h("div", { class: "ops" }, [
h(
"a",
{
on: {
click: () => {
this.edit(params.row);
}
}
},
"审核"
),
]);
}
}
}
return h("div", { class: "ops" }, [
h(
"a",
{
on: {
click: () => {
this.edit(params.row);
},
},
},
"审核"
),
]);
},
},
],
data: [], // 表单数据
total: 0 // 表单数据总数
@@ -211,59 +178,68 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== 'undefined' && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== 'undefined') {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.getDataList();
},
// 获取列表数据
getDataList() {
this.loading = true;
// 带多条件搜索参数获取表单数据 请自行修改接口
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;
getDistributionCash(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.catch(() => {
this.loading = false;
});
},
// 通过还是拒绝申请
handleSubmit() {
let result = "拒绝"
if(this.result == 'VIA_AUDITING'){
result = "通过"
let result = "拒绝";
if (this.result === "VIA_AUDITING") {
result = "通过";
}
this.$refs.form.validate(valid => {
if (valid) {
this.$Modal.confirm({
title: "确认审核",
content: "您确认要审核"+result+"么?",
loading: true,
onOk: () => {
auditDistributionCash(this.form.id,{result:this.result}).then(res => {
if (res.success) {
this.$Modal.remove();
this.$Message.success("审核成功");
this.getDataList();
this.modalVisible = false;
} else {
this.modalVisible = false;
}
});
}
})
}
DialogPlugin.confirm({
header: "确认审核",
content: "您确认要审核" + result + "么?",
theme: "warning",
onConfirm: () => {
this.submitLoading = true;
auditDistributionCash(this.form.id, { result: this.result })
.then((res) => {
this.submitLoading = false;
if (res.success) {
MessagePlugin.success("审核成功");
this.getDataList();
this.modalVisible = false;
} else {
this.modalVisible = false;
}
})
.catch(() => {
this.submitLoading = false;
});
},
});
},
// 弹出modal 审核
edit(v) {
this.modalTitle = "审核";
this.handleStatus = 'edit';
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
// 转换null为""
for (let attr in v) {
if (v[attr] === null) {
@@ -277,7 +253,7 @@ export default {
view(v){
this.modalTitle = "查看";
this.handleStatus = 'view';
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
// 转换null为""
for (let attr in v) {
if (v[attr] === null) {

View File

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

View File

@@ -1,77 +1,62 @@
<template>
<div>
<Card>
<Form ref="searchForm" @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="分销商" prop="distributionName">
<Input
type="text"
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">
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="订单编号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="分销商" name="distributionName">
<t-input v-model="searchForm.distributionName" placeholder="请输入分销商名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="店铺名称">
<t-select v-model="searchForm.storeId" placeholder="请选择" :filterable="true" clearable style="width: 240px" @input-change="searchChange">
<t-option v-for="item in shopList" :value="item.id" :key="item.id" :label="item.storeName" />
</t-select>
</t-form-item>
<t-form-item label="订单时间">
<t-date-picker v-model="timeRange" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" placeholder="选择时间" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="id">
<template #goodsMsg="{ row }">
<div class="goods-msg">
<img :src="row.image" width="60" height="60" alt="">
<img :src="row.image" width="60" height="60" alt="" />
<div>
<div class="div-zoom">
<a @click="linkTo(row.goodsId,row.skuId)">{{row.goodsName}}</a>
<a @click="linkTo(row.goodsId,row.skuId)">{{ row.goodsName }}</a>
</div>
<div style="color:#999;font-size:10px">数量x{{row.num}}</div>
<Poptip trigger="hover" title="扫码在手机中查看" transfer>
<div slot="content">
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150"></vue-qr>
</div>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="">
</Poptip>
<div style="color:#999;font-size:10px">数量x{{ row.num }}</div>
<t-popup trigger="hover" placement="top" :showArrow="true">
<template #content>
<vue-qr :text="wapLinkTo(row.goodsId,row.skuId)" :margin="0" colorDark="#000" colorLight="#fff" :size="150" />
</template>
<img src="../../assets/qrcode.svg" class="hover-pointer" width="20" height="20" alt="" />
</t-popup>
</div>
</div>
</template>
<template slot-scope="{row}" slot="distributionOrderStatus">
<Tag :color="filterStatusColor(row.distributionOrderStatus)">{{filterStatus(row.distributionOrderStatus)}}</Tag>
<template #distributionOrderStatus="{ row }">
<t-tag :theme="filterStatusColor(row.distributionOrderStatus) === 'green' ? 'success' : (filterStatusColor(row.distributionOrderStatus) === 'orange' ? 'warning' : 'danger')" size="small" variant="light">{{ filterStatus(row.distributionOrderStatus) }}</t-tag>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize"
@on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[20,50,100]"
size="small" show-total show-elevator show-sizer></Page>
</Row>
</Card>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
<script>
import {
getDistributionOrder
} from "@/api/distribution";
import {orderStatusList} from './dataJson'
import {getShopListData} from '@/api/shops'
import vueQr from 'vue-qr'
import { getDistributionOrder } from "@/api/distribution";
import { orderStatusList } from "./dataJson";
import { getShopListData } from "@/api/shops";
import vueQr from "vue-qr";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "distributionOrder",
@@ -80,7 +65,7 @@
},
data() {
return {
timeRange: [], // 范围时间
timeRange: undefined, // 范围时间
orderStatusList, // 订单状态列表
shopList: [], // 店铺列表
distributionId: this.$route.query.id, // 分销id
@@ -92,54 +77,13 @@
order:"desc"
},
columns: [
{
title: "订单编号",
key: "orderSn",
minWidth: 180,
fixed: "left",
tooltip: true
},
{
title: '商品信息',
slot: 'goodsMsg',
minWidth: 150
},
{
title: "分销商",
key: "distributionName",
tooltip: true,
minWidth:80,
},
{
title: "店铺名称",
key: "storeName",
minWidth:80,
tooltip: true
},
{
title: "状态",
slot: "distributionOrderStatus",
minWidth:80,
},
{
title: "佣金金额",
key: "rebate",
minWidth:80,
sortable: false,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.rebate,color:this.$mainColor}} );
},
},
{
fixed: "right",
title: "创建时间",
key: "createTime",
minWidth:100,
sortable: false,
}
{ title: "订单编号", colKey: "orderSn", minWidth: 180, fixed: "left", tooltip: true },
{ title: "商品信息", colKey: "goodsMsg", minWidth: 180 },
{ title: "分销商", colKey: "distributionName", tooltip: true, minWidth: 120 },
{ title: "店铺名称", colKey: "storeName", minWidth: 120, tooltip: true },
{ title: "状态", colKey: "distributionOrderStatus", minWidth: 120 },
{ title: "佣金金额", colKey: "rebate", minWidth: 120, cell: (h, p) => h("priceColorScheme", { props: { value: p.row.rebate, color: this.$mainColor } }) },
{ fixed: "right", title: "创建时间", colKey: "createTime", minWidth: 150 },
],
data: [], // 表单数据
total: 0 // 表单数据总数
@@ -151,16 +95,22 @@
this.getDataList();
this.getShopList()
},
//分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
@@ -171,23 +121,27 @@
getDataList() {
this.searchForm.distributionId = this.distributionId;
this.loading = true;
if (this.timeRange && this.timeRange[0]) {
let startTime = this.timeRange[0]
let endTime = this.timeRange[1]
if (Array.isArray(this.timeRange) && this.timeRange.length === 2) {
const startTime = this.timeRange[0]
const endTime = this.timeRange[1]
this.searchForm.startTime = this.$options.filters.unixToDate(startTime / 1000)
this.searchForm.endTime = this.$options.filters.unixToDate(endTime / 1000)
} else {
this.searchForm.startTime = null
this.searchForm.endTime = null
}
// 带多条件搜索参数获取表单数据 请自行修改接口
getDistributionOrder(this.searchForm).then(res => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
this.total = this.data.length;
this.loading = false;
getDistributionOrder(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.catch(() => {
this.loading = false;
});
},
getShopList(val) { // 获取店铺列表 搜索用
const params = {

View File

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

View File

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

View File

@@ -1,227 +1,140 @@
<template>
<div class="search">
<Card>
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
@keydown.enter.native="handleSearch"
>
<Form-item label="商品名称" prop="goodsName">
<Input
type="text"
v-model="searchForm.goodsName"
placeholder="请输入商品名称"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="商品编号" prop="id">
<Input
type="text"
v-model="searchForm.id"
placeholder="请输入商品编号"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="店铺名称" prop="id">
<Input
type="text"
v-model="searchForm.storeName"
placeholder="请输入店铺名称"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="销售模式" prop="status">
<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
v-model="searchForm.goodsType"
placeholder="请选择"
clearable
style="width: 240px"
>
<Option value="PHYSICAL_GOODS">实物商品</Option>
<Option value="VIRTUAL_GOODS">虚拟商品</Option>
</Select>
</Form-item>
<Button
@click="handleSearch"
class="search-btn"
type="primary"
icon="ios-search"
>搜索</Button
>
</Form>
</Card>
<Card>
<t-card style="margin-bottom: 12px">
<t-form ref="searchForm" :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="商品名称" name="goodsName">
<t-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="商品ID" name="id">
<t-input v-model="searchForm.id" placeholder="请输入商品ID" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="店铺名称" name="storeName">
<t-input v-model="searchForm.storeName" placeholder="请输入店铺名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="销售模式" name="salesModel">
<t-select v-model="searchForm.salesModel" placeholder="请选择" clearable style="width: 240px">
<t-option value="RETAIL" label="零售" />
<t-option value="WHOLESALE" label="批发" />
</t-select>
</t-form-item>
<t-form-item label="商品类型" name="goodsType">
<t-select v-model="searchForm.goodsType" placeholder="请选择" clearable style="width: 240px">
<t-option value="PHYSICAL_GOODS" label="实物商品" />
<t-option value="VIRTUAL_GOODS" label="虚拟商品" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="goods-tab">
<Tabs v-model="currentStatus" @on-click="goodsStatusClick">
<TabPane v-for="(item,index) in goodsStatusWithCount" :key="index" :label="item.title" :name="item.value">
</TabPane>
</Tabs>
<div class="goods-tab">
<t-tabs v-model="currentStatus" @change="goodsStatusClick">
<t-tab-panel v-for="(item,index) in goodsStatusWithCount" :key="index" :label="item.title" :value="item.value"></t-tab-panel>
</t-tabs>
</div>
<!-- 批量操作按钮 -->
<div class="batch-operations" style="margin: 10px 0;">
<Button
type="success"
:disabled="selectedRows.length === 0"
@click="batchUpper"
style="margin-right: 10px;"
>
批量上架
</Button>
<Button
type="warning"
:disabled="selectedRows.length === 0"
@click="batchLower"
style="margin-right: 10px;"
>
批量下架
</Button>
<Button
v-if="currentStatus === 'TOBEAUDITED'"
type="primary"
:disabled="selectedRows.length === 0"
@click="batchAudit"
>
批量审核
</Button>
<t-button theme="success" :disabled="selectedRows.length === 0" @click="batchUpper" style="margin-right: 10px;">批量上架</t-button>
<t-button theme="warning" :disabled="selectedRows.length === 0" @click="batchLower" style="margin-right: 10px;">批量下架</t-button>
<t-button v-if="currentStatus === 'TOBEAUDITED'" theme="primary" :disabled="selectedRows.length === 0" @click="batchAudit">批量审核</t-button>
</div>
<Table
:loading="loading"
:columns="columns"
:data="data"
ref="table"
class="mt_10"
@on-select="onSelect"
@on-select-all="onSelectAll"
@on-selection-change="onSelectionChange"
>
<!-- 商品图片格式化 -->
<template slot="imageSlot" slot-scope="{ row }">
<t-table :loading="loading" :columns="columns" :data="data" rowKey="id" :rowSelection="{ type: 'multiple', selectedRowKeys }" @select-change="onTSelectChange" class="mt_10">
<template #imageSlot="{ row }">
<div style="margin-top: 5px;">
<img
:src="row.original"
style="height: 50px; width: 50px; object-fit: cover;"
/>
<img :src="row.original" style="height: 50px; width: 50px; object-fit: cover;" />
</div>
</template>
<!-- 商品栏目格式化 -->
<template slot="goodsSlot" slot-scope="{ row }">
<template #goodsSlot="{ row }">
<div style="margin: 5px 0px; padding: 10px 0px;">
<div class="div-zoom">
<a @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
</div>
</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>
<Modal
<template #action="{ row }">
<template v-if="row.authFlag === 'TOBEAUDITED'">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="openAuditModal(row)">审核</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
</template>
<template v-else-if="row.marketEnable == 'DOWN'">
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="upper(row)">上架</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
</template>
<template v-else>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="edit(row)">下架</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="showDetail(row)">查看</a>
</template>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
<t-dialog :visible.sync="modalVisible" header="下架操作" width="500px" :footer="false" @close="modalVisible = false">
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
>
<t-form ref="underForm" :data="underForm" :labelWidth="100">
<t-form-item label="下架原因" name="reason">
<t-input v-model="underForm.reason" style="width: 100%" />
</t-form-item>
</t-form>
<div style="text-align:right;margin-top: 12px;">
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="lower">提交</t-button>
</div>
</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>
</t-dialog>
<t-dialog :visible.sync="auditModalVisible" header="商品审核" width="500px" :footer="false" @close="auditModalVisible = false">
<t-form ref="auditForm" :data="goodsAuditForm" :labelWidth="100">
<t-form-item label="审核结果" name="auth_flag">
<t-radio-group v-model="goodsAuditForm.auth_flag">
<t-radio :value="1">审核通过</t-radio>
<t-radio :value="2">审核拒绝</t-radio>
</t-radio-group>
</t-form-item>
</t-form>
<div style="text-align:right;margin-top: 12px;">
<t-button variant="text" @click="auditModalVisible = false">取消</t-button>
<t-button theme="primary" @click="confirmAudit">提交审核</t-button>
</div>
</Modal>
<!-- 批量审核弹框 -->
<Modal
title="批量商品审核"
v-model="batchAuditModalVisible"
:mask-closable="false"
:width="500"
>
<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="选中商品">
</t-dialog>
<t-dialog :visible.sync="batchAuditModalVisible" header="批量商品审核" width="500px" :footer="false" @close="batchAuditModalVisible = false">
<t-form ref="batchAuditForm" :data="batchAuditForm" :labelWidth="100">
<t-form-item label="审核结果" name="auth_flag">
<t-radio-group v-model="batchAuditForm.auth_flag">
<t-radio :value="1">审核通过</t-radio>
<t-radio :value="2">审核拒绝</t-radio>
</t-radio-group>
</t-form-item>
<t-form-item label="审核备注" name="reason" v-if="batchAuditForm.auth_flag === 2">
<t-textarea v-model="batchAuditForm.reason" :rows="3" placeholder="请输入拒绝原因" />
</t-form-item>
<t-form-item label="选中商品">
<div style="max-height: 200px; overflow-y: auto;">
<Tag v-for="item in selectedRows" :key="item.id" style="margin: 2px;">{{item.goodsName}}</Tag>
<t-tag v-for="item in selectedRows" :key="item.id" style="margin: 2px;">{{item.goodsName}}</t-tag>
</div>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="batchAuditModalVisible = false">取消</Button>
<Button type="primary" @click="submitBatchAudit">提交审核</Button>
</t-form-item>
</t-form>
<div style="text-align:right;margin-top: 12px;">
<t-button variant="text" @click="batchAuditModalVisible = false">取消</t-button>
<t-button theme="primary" @click="submitBatchAudit">提交审核</t-button>
</div>
</Modal>
</t-dialog>
</div>
</template>
<script>
import { getGoodsListData,getGoodsNumerData, upGoods, lowGoods, authGoods } from "@/api/goods";
import vueQr from "vue-qr";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
components: {
"vue-qr": vueQr,
@@ -238,6 +151,12 @@ export default {
pageSize: 20, // 页面大小
sort: "create_time", // 默认排序字段
order: "desc", // 默认排序方式
goodsName: "",
id: "",
storeName: "",
salesModel: "",
goodsType: "",
goodsStatus: "",
},
underForm: {
// 下架原因
@@ -250,250 +169,17 @@ export default {
auditModalVisible: false, // 审核弹框显示状态
currentAuditGoods: null, // 当前审核的商品
submitLoading: false, // 添加或编辑提交状态
selectedRowKeys: [],
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);
},
},
},
"查看"
),
]);
}
},
},
{ colKey: "row-select", type: "multiple", width: 60, align: "center" },
{ title: "商品ID", colKey: "id", width: 260 },
{ title: "商品图片", colKey: "imageSlot", width: 180 },
{ title: "商品名称", colKey: "goodsSlot", width: 180 },
{ title: "价格", colKey: "price", width: 100, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }) },
{ title: "销量", colKey: "buyCount", width: 100 },
{ title: "库存", colKey: "quantity", width: 100 },
{ title: "店铺名称", colKey: "storeName", width: 180 },
{ title: "操作", colKey: "action", align: "center", fixed: "right", width: 200 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -539,6 +225,14 @@ export default {
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
@@ -546,6 +240,28 @@ export default {
this.getDataList();
this.getNumberData();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "create_time",
order: "desc",
goodsName: "",
id: "",
storeName: "",
salesModel: "",
goodsType: "",
goodsStatus: "",
};
this.currentStatus = '';
this.selectedRows = [];
this.selectedRowKeys = [];
if (this.$refs.table) {
this.$refs.table.selectAll(false);
}
this.getDataList();
this.getNumberData();
},
// 获取数据
getDataList() {
this.loading = true;
@@ -583,31 +299,27 @@ export default {
reason:this.underForm.reason
};
lowGoods(params).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.modalVisible = false;
this.getDataList();
this.getNumberData(); // 添加这行
this.getNumberData();
}
});
},
// 上架
upper(v) {
this.$Modal.confirm({
title: "确认上架",
DialogPlugin.confirm({
header: "确认上架",
content: "您确认要上架 " + v.goodsName + " ?",
loading: true,
onOk: () => {
let params = {
goodsId: v.id
};
theme: "warning",
onConfirm: () => {
const params = { goodsId: v.id };
upGoods(params).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("上架成功");
MessagePlugin.success("上架成功");
this.getDataList();
this.getNumberData(); // 添加这行
this.getNumberData();
}
});
},
@@ -652,20 +364,18 @@ export default {
this.goodsAuditForm.authFlag = "REFUSE";
}
this.$Modal.confirm({
title: "确认审核",
DialogPlugin.confirm({
header: "确认审核",
content: "您确认要审核" + examine + " " + v.goodsName + " ?",
loading: true,
onOk: () => {
this.goodsAuditForm.goodsIds=v.id;
let formData = new FormData();
theme: "warning",
onConfirm: () => {
this.goodsAuditForm.goodsIds = v.id;
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) {
this.$Message.success("审核成功");
MessagePlugin.success("审核成功");
this.getDataList();
this.getNumberData();
}
@@ -685,11 +395,11 @@ export default {
// 确认审核(二次确认)
confirmAudit() {
const auditText = this.goodsAuditForm.auth_flag === 1 ? '通过' : '拒绝';
this.$Modal.confirm({
title: '确认审核',
DialogPlugin.confirm({
header: '确认审核',
content: `您确认要审核${auditText} "${this.currentAuditGoods.goodsName}" 吗?`,
loading: true,
onOk: () => {
theme: 'warning',
onConfirm: () => {
this.submitAudit();
},
});
@@ -701,9 +411,8 @@ export default {
formData.append('goodsIds', this.currentAuditGoods.id);
formData.append('authFlag', this.goodsAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
authGoods(formData).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success('审核成功');
MessagePlugin.success('审核成功');
this.auditModalVisible = false;
this.getDataList();
this.getNumberData();
@@ -712,16 +421,9 @@ export default {
},
// 选择框事件处理
onSelect(selection, row) {
// 单行选择时触发
},
onSelectAll(selection) {
// 全选时触发
},
onSelectionChange(selection) {
this.selectedRows = selection;
onTSelectChange(keys, { selectedRowData }) {
this.selectedRowKeys = keys;
this.selectedRows = selectedRowData || [];
},
// 批量上架
@@ -732,28 +434,22 @@ export default {
}
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
this.$Modal.confirm({
title: '确认批量上架',
DialogPlugin.confirm({
header: '确认批量上架',
content: `您确认要上架以下商品吗?\n${goodsNames}`,
loading: true,
onOk: () => {
// 提取所有选中商品的ID
theme: 'warning',
onConfirm: () => {
const goodsIds = this.selectedRows.map(item => item.id);
const params = {
goodsId: goodsIds // 传递ID数组
};
const params = { goodsId: goodsIds };
upGoods(params).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success('批量上架成功');
MessagePlugin.success('批量上架成功');
this.selectedRows = [];
this.selectedRowKeys = [];
this.selectAll = false;
this.getDataList();
this.getNumberData();
}
}).catch(() => {
this.$Modal.remove();
});
}
});
@@ -767,29 +463,22 @@ export default {
}
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
this.$Modal.confirm({
title: '确认批量下架',
DialogPlugin.confirm({
header: '确认批量下架',
content: `您确认要下架以下商品吗?\n${goodsNames}`,
loading: true,
onOk: () => {
// 提取所有选中商品的ID
theme: 'warning',
onConfirm: () => {
const goodsIds = this.selectedRows.map(item => item.id);
const params = {
goodsId: goodsIds, // 传递ID数组
reason: '批量下架操作' // 可以设置默认下架原因
};
const params = { goodsId: goodsIds, reason: '批量下架操作' };
lowGoods(params).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success('批量下架成功');
MessagePlugin.success('批量下架成功');
this.selectedRows = [];
this.selectedRowKeys = [];
this.selectAll = false;
this.getDataList();
this.getNumberData();
}
}).catch(() => {
this.$Modal.remove();
});
}
});
@@ -798,7 +487,7 @@ export default {
// 批量审核
batchAudit() {
if (this.selectedRows.length === 0) {
this.$Message.warning('请先选择要审核的商品');
MessagePlugin.warning('请先选择要审核的商品');
return;
}
@@ -813,45 +502,39 @@ export default {
// 提交批量审核
submitBatchAudit() {
if (this.selectedRows.length === 0) {
this.$Message.warning('请先选择要审核的商品');
MessagePlugin.warning('请先选择要审核的商品');
return;
}
// 如果是拒绝审核,必须填写原因
if (this.batchAuditForm.auth_flag === 2 && !this.batchAuditForm.reason.trim()) {
this.$Message.warning('审核拒绝时必须填写拒绝原因');
MessagePlugin.warning('审核拒绝时必须填写拒绝原因');
return;
}
const actionText = this.batchAuditForm.auth_flag === 1 ? '通过' : '拒绝';
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
this.$Modal.confirm({
title: `确认批量审核${actionText}`,
DialogPlugin.confirm({
header: `确认批量审核${actionText}`,
content: `您确认要${actionText}以下商品的审核吗?\n${goodsNames}`,
loading: true,
onOk: () => {
// 提取所有选中商品的ID
theme: 'warning',
onConfirm: () => {
const goodsIds = this.selectedRows.map(item => item.id);
let formData = new FormData();
const formData = new FormData();
formData.append('goodsId', goodsIds);
formData.append('authFlag', this.batchAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
formData.append('reason', this.batchAuditForm.reason || '');
// 修正直接调用authGoods不传递'batch'参数
authGoods(formData).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success(`批量审核${actionText}成功`);
MessagePlugin.success(`批量审核${actionText}成功`);
this.selectedRows = [];
this.selectedRowKeys = [];
this.selectAll = false;
this.batchAuditModalVisible = false;
this.getDataList();
this.getNumberData();
}
}).catch(() => {
this.$Modal.remove();
});
}
});

View File

@@ -1,6 +1,12 @@
<template>
<div class="search">
<Card>
<Tabs v-model="activeStatus" @change="onStatusTabChange" style="margin-bottom: 12px">
<TabPane label="全部" name="ALL" />
<TabPane label="待审核" name="TOBEAUDITED" />
<TabPane label="审核通过" name="PASS" />
<TabPane label="审核拒绝" name="REFUSE" />
</Tabs>
<Form
ref="searchForm"
@keydown.enter.native="handleSearch"
@@ -27,9 +33,10 @@
style="width: 240px"
/>
</Form-item>
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search"
>搜索</Button
>
<Button @click="handleSearch" class="search-btn" type="primary">
<template #icon><t-icon name="search" /></template>
搜索
</Button>
</Form>
</Card>
<Card>
@@ -87,6 +94,7 @@ export default {
return {
id: "", //要操作的id
loading: true, // 表单加载状态
activeStatus: 'ALL',
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
@@ -102,7 +110,7 @@ export default {
{
title: "商品名称",
key: "goodsName",
minWidth: 180,
minWidth: 140,
slot: "goodsSlot",
tooltip: true,
},
@@ -259,11 +267,16 @@ export default {
this.searchForm.pageSize = 20;
this.getDataList();
},
onStatusTabChange(v){
this.activeStatus = v;
this.searchForm.pageNumber = 1;
this.getDataList();
},
getDataList() {
// 获取列表数据
this.loading = true;
// 带多条件搜索参数获取表单数据
this.searchForm.authFlag = 0;
this.searchForm.authFlag = this.activeStatus === 'ALL' ? 0 : this.activeStatus;
getAuthGoodsListData(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,7 +24,7 @@ export default {
this.getSite();
} else {
// 如果缓存过期,则获取最新的信息
if (new Date() > localStorage.getItem("icontitle_expiration_time")) {
if (Date.now() > Number(localStorage.getItem("icontitle_expiration_time"))) {
this.getSite();
return;
} else {
@@ -43,25 +43,27 @@ export default {
getSite() {
//获取domainLogo
getBaseSite().then((res) => {
const { domainLogo, domainIcon, siteName } = JSON.parse(res.result.settingValue);
this.domainLogo = domainLogo;
// 过期时间
var expirationTime = new Date().setHours(new Date().getHours() + 1);
// 存放过期时间
localStorage.setItem("icontitle_expiration_time", expirationTime);
// 存放信息
localStorage.setItem("icon", domainLogo);
localStorage.setItem("domainIcon", domainIcon);
localStorage.setItem("title", siteName);
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);
window.document.title = siteName + " - 运营后台";
});
if (res && res.success && res.result && res.result.settingValue) {
const parsed = JSON.parse(res.result.settingValue);
const domainLogo = parsed && parsed.domainLogo ? parsed.domainLogo : this.domainLogo;
const domainIcon = parsed && parsed.domainIcon ? parsed.domainIcon : parsed.domainLogo;
const siteName = parsed && parsed.siteName ? parsed.siteName : document.title;
this.domainLogo = domainLogo;
var expirationTime = new Date().setHours(new Date().getHours() + 1);
localStorage.setItem("icontitle_expiration_time", expirationTime);
localStorage.setItem("icon", domainLogo);
localStorage.setItem("domainIcon", domainIcon || domainLogo);
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);
window.document.title = (siteName || "运营后台") + " - 运营后台";
}
}).catch(() => {});
},
},
mounted() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,140 +1,81 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="关键字" prop="keywords" style="display: block; width: 100%;">
<Input
type="text"
v-model="searchForm.keywords"
placeholder="请输入商品名称、订单编号搜索"
clearable
style="width: 240px"
/>
</Form-item>
<br>
<Form-item label="订单编号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="请输入订单编号"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="售后单号" prop="sn">
<Input
type="text"
v-model="searchForm.sn"
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>
<Form-item label="商家名称" prop="storeName">
<Input
type="text"
v-model="searchForm.storeName"
placeholder="请输入商家名称"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="会员名称" prop="memberName">
<Input
type="text"
v-model="searchForm.memberName"
placeholder="请输入会员名称"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="售后类型">
<Select
v-model="searchForm.serviceType"
placeholder="全部"
clearable
style="width: 240px"
>
<Option value="RETURN_MONEY">退款</Option>
<Option value="RETURN_GOODS">退货</Option>
</Select>
</Form-item>
<Button
@click="handleSearch"
type="primary"
icon="ios-search"
class="search-btn"
>搜索</Button
>
</Form>
</Row>
</Card>
<Card>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="关键字" name="keywords" style="display: block; width: 100%">
<t-input v-model="searchForm.keywords" placeholder="请输入商品名称、订单编号搜索" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="订单编号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="请输入订单编号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="售后单号" name="sn">
<t-input v-model="searchForm.sn" placeholder="请输入售后单号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="申请时间">
<t-date-picker v-model="selectDate" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" clearable @change="selectDateRange" placeholder="选择起始时间" style="width: 240px" />
</t-form-item>
<t-form-item label="商家名称" name="storeName">
<t-input v-model="searchForm.storeName" placeholder="请输入商家名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="会员名称" name="memberName">
<t-input v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="售后类型" name="serviceType">
<t-select v-model="searchForm.serviceType" placeholder="全部" clearable style="width: 240px">
<t-option value="RETURN_MONEY" label="退款" />
<t-option value="RETURN_GOODS" label="退货" />
</t-select>
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="order-tab">
<Tabs v-model="currentStatus" @on-click="serviceStatusClick">
<TabPane v-for="item in serviceStatusWithCount" :key="item.value" :label="item.title" :name="item.value">
</TabPane>
</Tabs>
<t-tabs :value="currentStatus" @change="serviceStatusClick">
<t-tab-panel v-for="item in serviceStatusWithCount" :key="item.value" :label="item.title" :value="item.value" />
</t-tabs>
</div>
<Table
:loading="loading"
:columns="columns"
:data="data"
ref="table"
class="mt_10"
>
<!-- 商品栏目格式化 -->
<template slot="goodsSlot" slot-scope="{ row }">
<t-table :loading="loading" :columns="columns" :data="data" ref="table" class="mt_10" rowKey="sn">
<template #goodsSlot="{ row }">
<div style="margin-top: 5px; height: 80px; display: flex">
<div style="">
<div>
<img :src="row.goodsImage" style="width: 60px; height: 60px; margin-top: 3px; object-fit: cover; border-radius: 4px;" />
</div>
<div style="margin-left: 13px">
<div class="div-zoom">
<a @click="linkTo(row.goodsId, row.skuId)">{{ row.goodsName }}</a>
</div>
<div style="color: #999; font-size: 12px; margin-top: 5px;">
商品ID: {{ row.goodsId }}
</div>
<div style="color: #999; font-size: 12px; margin-top: 5px;">商品ID: {{ row.goodsId }}</div>
</div>
</div>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[20, 50, 100]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<template #serviceTypeTag="{ row }">
<t-tag v-if="row.serviceType === 'RETURN_MONEY'" theme="primary" size="small" variant="light">退款</t-tag>
<t-tag v-else-if="row.serviceType === 'RETURN_GOODS'" theme="warning" size="small" variant="light">退货</t-tag>
<t-tag v-else-if="row.serviceType === 'EXCHANGE_GOODS'" theme="success" size="small" variant="light">换货</t-tag>
</template>
<template #serviceStatusTag="{ row }">
<t-tag v-if="row.serviceStatus === 'APPLY'" theme="primary" size="small" variant="light">申请中</t-tag>
<t-tag v-else-if="row.serviceStatus === 'PASS'" theme="success" size="small" variant="light">通过售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'REFUSE'" theme="danger" size="small" variant="light">拒绝售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'BUYER_RETURN'" theme="warning" size="small" variant="light">买家退货待卖家收货</t-tag>
<t-tag v-else-if="row.serviceStatus === 'SELLER_CONFIRM'" theme="primary" size="small" variant="light">卖家确认收货</t-tag>
<t-tag v-else-if="row.serviceStatus === 'SELLER_TERMINATION'" theme="danger" size="small" variant="light">卖家终止售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'BUYER_CANCEL'" size="small" variant="light">买家取消售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'COMPLETE'" theme="success" size="small" variant="light">完成售后</t-tag>
<t-tag v-else-if="row.serviceStatus === 'WAIT_REFUND'" theme="warning" size="small" variant="light">待平台退款</t-tag>
</template>
<template #action="{ row }">
<a style="color: #2d8cf0; cursor: pointer; text-decoration: none" @click="detail(row)">查看</a>
</template>
</t-table>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
@@ -174,132 +115,16 @@ export default {
billPrice: "",
},
columns: [
{
title: "售后服务单号",
key: "sn",
minWidth: 140,
tooltip: true,
},
{
title: "订单编号",
key: "orderSn",
minWidth: 120,
tooltip: true,
},
// 移除这个独立的商品ID列
// {
// title: "商品ID",
// key: "goodsId",
// minWidth: 120,
// tooltip: true,
// },
{
title: "商品",
key: "goodsName",
minWidth: 300,
tooltip: true,
slot: "goodsSlot",
},
{
title: "会员ID",
key: "memberId",
minWidth: 120,
tooltip: true,
},
{
title: "会员名称",
key: "memberName",
width: 140,
},
{
title: "店铺名称",
key: "storeName",
width: 100,
tooltip: true,
},
{
title: "售后金额",
key: "applyRefundPrice",
width: 110,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
},
},
{
title: "售后类型",
key: "serviceType",
width: 100,
render: (h, params) => {
if (params.row.serviceType == "RETURN_MONEY") {
return h("div", [h("tag", { props: { color: "blue" } }, "退款")]);
} else if (params.row.serviceType == "RETURN_GOODS") {
return h("div", [h("tag", { props: { color: "volcano" } }, "退货")]);
} else if (params.row.serviceType == "EXCHANGE_GOODS") {
return h("div", [h("tag", { props: { color: "green" } }, "换货")]);
}
},
},
{
title: "售后状态",
key: "serviceStatus",
width: 180,
render: (h, params) => {
if (params.row.serviceStatus == "APPLY") {
return h("div", [h("tag", { props: { color: "blue" } }, "申请中")]);
} else if (params.row.serviceStatus == "PASS") {
return h("div", [h("tag", { props: { color: "cyan" } }, "通过售后")]);
} else if (params.row.serviceStatus == "REFUSE") {
return h("div", [h("tag", { props: { color: "volcano" } }, "拒绝售后")]);
} else if (params.row.serviceStatus == "BUYER_RETURN") {
return h("div", [
h("tag", { props: { color: "orange" } }, "买家退货,待卖家收货"),
]);
} else if (params.row.serviceStatus == "SELLER_CONFIRM") {
return h("div", [h("tag", { props: { color: "gold" } }, "卖家确认收货")]);
} else if (params.row.serviceStatus == "SELLER_TERMINATION") {
return h("div", [h("tag", { props: { color: "lime" } }, "卖家终止售后")]);
} else if (params.row.serviceStatus == "BUYER_CANCEL") {
return h("div", [h("tag", { props: { color: "purple" } }, "买家取消售后")]);
} else if (params.row.serviceStatus == "COMPLETE") {
return h("div", [h("tag", { props: { color: "green" } }, "完成售后")]);
} else if (params.row.serviceStatus == "WAIT_REFUND") {
return h("div", [h("tag", { props: { color: "geekblue" } }, "待平台退款")]);
}
},
},
{
title: "申请时间",
key: "createTime",
width: 180,
},
{
title: "操作",
key: "action",
fixed: "right",
align: "center",
width: 100,
render: (h, params) => {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none"
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]);
},
},
{ title: "商品", colKey: "goodsSlot", minWidth: 300, tooltip: true },
{ title: "售后服务单号", colKey: "sn", minWidth: 140, tooltip: true },
{ title: "订单编号", colKey: "orderSn", minWidth: 120, tooltip: true },
{ title: "会员ID", colKey: "memberId", minWidth: 120, tooltip: true },
{ title: "会员名称", colKey: "memberName", width: 140 },
{ title: "店铺名称", colKey: "storeName", width: 100, tooltip: true },
{ title: "售后金额", colKey: "applyRefundPrice", width: 110, cell: (h, p) => h("priceColorScheme", { props: { value: p.row.applyRefundPrice, color: this.$mainColor } }) },
{ title: "售后类型", colKey: "serviceTypeTag", width: 100 },
{ title: "申请时间", colKey: "createTime", width: 180 },
{ title: "操作", colKey: "action", fixed: "right", align: "center", width: 100 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -324,17 +149,23 @@ export default {
this.getDataList();
this.getAfterSaleNumData();
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
@@ -342,6 +173,26 @@ export default {
this.getDataList();
this.getAfterSaleNumData();
},
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderSn: "",
memberName: "",
serviceStatus: "",
storeName: "",
sn: "",
keywords: "",
};
this.selectDate = null;
this.currentStatus = '';
this.getDataList();
this.getAfterSaleNumData();
},
// 开始结束时间分别赋值
selectDateRange(v) {
if (v) {
@@ -349,19 +200,19 @@ export default {
this.searchForm.endDate = v[1];
}
},
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.getAfterSaleOrderPage(this.searchForm).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
// 获取售后状态数量
this.total = this.data.length;
this.loading = false;
API_Order.getAfterSaleOrderPage(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.catch(() => {
this.loading = false;
});
},
// 获取售后数量统计
getAfterSaleNumData() {
@@ -380,14 +231,12 @@ export default {
query: { sn: sn },
})
},
// 售后筛选
serviceStatusClick(item) {
this.currentStatus = item;
// 如果是全部空字符串则删除serviceStatus字段
if (item === 0) {
serviceStatusClick(value) {
this.currentStatus = value;
if (value === "") {
delete this.searchForm.serviceStatus;
} else {
this.searchForm.serviceStatus = item;
this.searchForm.serviceStatus = value;
}
this.getDataList();
this.getAfterSaleNumData();
@@ -416,9 +265,8 @@ export default {
}
</script>
<style lang="scss" scoped>
// Tab组件样式
.order-tab {
::v-deep .ivu-tabs-tab {
::v-deep .t-tabs__nav-item {
font-size: 14px;
}
}

View File

@@ -1,6 +1,6 @@
<template>
<div class="search">
<Card>
<t-card>
<div class="main-content">
<div class="div-flow-left">
<div class="div-form-default">
@@ -79,18 +79,10 @@
<dt>是否同意</dt>
<dd>
<div class="div-content">
<RadioGroup
type="button"
button-style="solid"
v-model="params.serviceStatus"
>
<Radio label="PASS">
<span>同意</span>
</Radio>
<Radio label="REFUSE">
<span>拒绝</span>
</Radio>
</RadioGroup>
<t-radio-group v-model="params.serviceStatus">
<t-radio value="PASS">同意</t-radio>
<t-radio value="REFUSE">拒绝</t-radio>
</t-radio-group>
</div>
</dd>
</dl>
@@ -103,18 +95,16 @@
<dl>
<dt>实际退款金额</dt>
<dd>
<InputNumber :min="0" v-model="params.actualRefundPrice" style="width: 260px" />
<t-input-number :min="0" v-model="params.actualRefundPrice" style="width: 260px" />
</dd>
</dl>
<dl>
<dt>备注信息</dt>
<dd>
<Input
<t-textarea
v-model="params.remark"
type="textarea"
maxlength="200"
:maxlength="200"
:rows="4"
clearable
style="width: 260px"
/>
</dd>
@@ -122,14 +112,14 @@
<dl>
<dd>
<div style="text-align: right; width: 45%; margin-top: 10px">
<Button
type="primary"
<t-button
theme="primary"
:loading="submitLoading"
@click="handleSubmit"
style="margin-left: 5px"
>
确定
</Button>
</t-button>
</div>
</dd>
</dl>
@@ -224,12 +214,10 @@
<dl>
<dt>备注信息</dt>
<dd>
<Input
<t-textarea
v-model="refundPriceForm.remark"
type="textarea"
maxlength="200"
:maxlength="200"
:rows="4"
clearable
style="width: 260px"
/>
</dd>
@@ -237,14 +225,14 @@
<dl>
<dt>操作</dt>
<dd>
<Button
type="primary"
<t-button
theme="primary"
:loading="submitLoading"
@click="refundPriceSubmit"
style="margin-left: 5px"
>
退款
</Button>
</t-button>
</dd>
</dl>
</div>
@@ -283,25 +271,22 @@
<dl>
<dt>操作</dt>
<dd>
<Button
type="info"
<t-button
theme="default"
:loading="submitLoading"
@click="logisticsSeller()"
style="margin-left: 5px"
>
查询物流
</Button>
</t-button>
</dd>
</dl>
</div>
</div>
</div>
</Card>
</t-card>
<!-- 查询物流 -->
<Modal v-model="logisticsModal" width="40">
<p slot="header">
<span>查询物流</span>
</p>
<t-dialog :visible="logisticsModal" header="查询物流" width="40%" :confirmBtn="null" @close="logisticsClose" @cancel="logisticsClose">
<div class="layui-layer-wrap">
<dl>
<dt>售后单号:</dt>
@@ -335,10 +320,10 @@
</ul>
</div>
</div>
<div slot="footer" style="text-align: right">
<Button @click="logisticsClose">取消</Button>
</div>
</Modal>
<template #footer>
<t-button variant="outline" @click="logisticsClose">取消</t-button>
</template>
</t-dialog>
</div>
</template>

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,10 @@
<DatePicker v-model="selectDate" type="datetimerange" format="yyyy-MM-dd" clearable
@on-change="selectDateRange" placeholder="选择起始时间" style="width: 240px"></DatePicker>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
<Button @click="handleSearch" type="primary" class="search-btn">
<template #icon><t-icon name="search" /></template>
搜索
</Button>
</Form>
</Row>
@@ -82,7 +85,7 @@ export default {
} else if (params.row.clientType == "PC") {
return h("div", {}, "PC端");
} else if (params.row.clientType == "WECHAT_MP") {
return h("div", {}, "小程序");
return h("div", {}, "小程序");
} else if (params.row.clientType == "APP") {
return h("div", {}, "移动应用端");
} else {

View File

@@ -291,7 +291,7 @@
</Card>
</div>
<Modal v-model="modal" width="530">
<Modal v-model="modal" width="530" title="修改金额" @on-ok="modifyPriceSubmit" @on-cancel="modal = false">
<p slot="header">
<Icon type="edit"></Icon>
<span>修改金额</span>
@@ -311,7 +311,7 @@
</div>
</Modal>
<!-- 订单取消模态框 -->
<Modal v-model="orderCancelModal" width="530">
<Modal v-model="orderCancelModal" width="530" title="订单取消" @on-ok="orderCancelSubmit" @on-cancel="orderCancelModal = false">
<p slot="header">
<Icon type="edit"></Icon>
<span>订单取消</span>
@@ -327,11 +327,11 @@
</div>
<div slot="footer" style="text-align: right">
<Button @click="orderCancelModal = false">关闭</Button>
<Button type="primary" @click="orderCancelSubmit">确认</Button>
<Button type="primary" :loading="orderCancelLoading" @click="orderCancelSubmit">确认</Button>
</div>
</Modal>
<!--收件地址弹出框-->
<Modal v-model="addressModal" width="530">
<Modal v-model="addressModal" width="530" title="修改收件信息" @on-ok="editAddressSubmit" @on-cancel="addressModal = false">
<p slot="header">
<Icon type="edit"></Icon>
<span>修改收件信息</span>
@@ -358,20 +358,14 @@
<Button type="primary" @click="editAddressSubmit">修改</Button>
</div>
</Modal>
<!-- 订单日志 -->
<Modal v-model="orderLogModal" width="60">
<p slot="header">
<span>订单日志</span>
</p>
<t-drawer :visible.sync="orderLogModal" header="订单日志" placement="right" size="500px" @close="orderLogModal = false">
<div class="order-log-div">
<Table :loading="loading" border :columns="orderLogColumns" :data="orderInfo.orderLogs" ref="table"
sortable="custom"></Table>
<Table :loading="loading" border :columns="orderLogColumns" :data="orderInfo.orderLogs" ref="table" sortable="custom"></Table>
</div>
<div slot="footer" style="text-align: right">
<Button @click="handelCancel">取消</Button>
</div>
</Modal>
<template #footer>
<t-button variant="text" @click="orderLogModal = false">关闭</t-button>
</template>
</t-drawer>
<Modal v-model="printModal" width="530" @on-cancel="printCancel">
<p slot="header" style="line-height:26px;height:26px;">
<span style="float: left;">打印发货单</span>
@@ -490,6 +484,8 @@ export default {
},
//弹出订单取消框
orderCancelModal: false,
//订单取消提交状态
orderCancelLoading: false,
//订单发货
orderDeliveryForm: {
logisticsNo: "", //发货单号
@@ -551,7 +547,7 @@ export default {
},
{
title: "优惠",
key: "num",
key: "promotionTag",
minWidth: 100,
render: (h, params) => {
let resultText = "";
@@ -740,17 +736,28 @@ export default {
},
//订单取消提交
orderCancelSubmit () {
this.$refs.orderCancelForm.validate((valid) => {
if (valid) {
API_Order.orderCancel(this.sn, this.orderCancelForm).then((res) => {
if (res.success) {
this.$Message.success("取消成功");
this.getDataList();
}
const formRef = this.$refs.orderCancelForm;
const doSubmit = () => {
this.orderCancelLoading = true;
API_Order.orderCancel(this.sn, this.orderCancelForm).then((res) => {
if (res && res.success) {
this.$Message.success("取消成功");
this.getDataList();
this.orderCancelModal = false;
});
}
});
} else {
this.$Message.error((res && res.message) ? res.message : "取消失败,请稍后重试");
}
this.orderCancelLoading = false;
}).catch(() => {
this.$Message.error("网络异常,请稍后再试");
this.orderCancelLoading = false;
});
};
if (!this.orderCancelForm.reason || this.orderCancelForm.reason.trim() === '') {
this.$Message.warning("请填写取消原因");
return;
}
doSubmit();
},
//订单日志
orderLog () {

View File

@@ -1,145 +1,120 @@
<template>
<div>
<Card>
<Form
ref="searchForm"
@keydown.enter.native="handleSearch"
:model="searchForm"
inline
:label-width="70"
class="search-form"
>
<Form-item label="关键字" prop="keywords" style="display: block; width: 100%;">
<Input
type="text"
v-model="searchForm.keywords"
placeholder="请输入商品名称/收货人/收货人手机号/店铺名称"
clearable
style="width: 500px"
/>
</Form-item>
<Form-item label="订单号" prop="orderSn">
<Input
type="text"
v-model="searchForm.orderSn"
placeholder="请输入订单"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="会员名称" prop="buyerName">
<Input
type="text"
v-model="searchForm.buyerName"
placeholder="请输入会员名称"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="商品名称" prop="goodsName">
<Input
type="text"
v-model="searchForm.goodsName"
placeholder="请输入商品名称"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="收货人" prop="shipName">
<Input
type="text"
v-model="searchForm.shipName"
placeholder="请输入收货人姓名"
clearable
style="width: 240px"
/>
</Form-item>
<Form-item label="订单类型" prop="orderType">
<Select
v-model="searchForm.orderPromotionType"
placeholder="请选择"
clearable
style="width: 240px"
>
<Option value="NORMAL">普通订单</Option>
<Option value="PINTUAN">拼团订单</Option>
<Option value="GIFT">赠品订单</Option>
<Option value="POINTS">积分订单</Option>
<Option value="KANJIA">砍价订单</Option>
</Select>
</Form-item>
<Form-item label="支付方式" prop="paymentMethod">
<Select
v-model="searchForm.paymentMethod"
placeholder="请选择支付方式"
clearable
style="width: 240px"
>
<Option value="WECHAT">微信支付</Option>
<Option value="ALIPAY">支付宝</Option>
<Option value="WALLET">余额支付</Option>
<Option value="BANK_TRANSFER">线下转账</Option>
</Select>
</Form-item>
<Form-item label="下单时间">
<DatePicker
v-model="selectDate"
type="datetimerange"
format="yyyy-MM-dd"
clearable
@on-change="selectDateRange"
placeholder="选择起始时间"
style="width: 240px"
></DatePicker>
</Form-item>
<Button
@click="handleSearch"
type="primary"
icon="ios-search"
class="search-btn"
>搜索</Button
>
</Form>
</Card>
<Card>
<t-card style="margin-bottom: 12px">
<t-form :data="searchForm" layout="inline" :labelWidth="70" class="search-form" @submit="handleSearch">
<t-form-item label="关键字" name="keywords" style="display: block; width: 100%">
<t-input v-model="searchForm.keywords" placeholder="请输入商品名称/收货人/收货人手机号/店铺名称" clearable style="width: 500px" />
</t-form-item>
<t-form-item label="订单号" name="orderSn">
<t-input v-model="searchForm.orderSn" placeholder="请输入订单号" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="会员名称" name="buyerName">
<t-input v-model="searchForm.buyerName" placeholder="请输入会员名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="商品名称" name="goodsName">
<t-input v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="收货人" name="shipName">
<t-input v-model="searchForm.shipName" placeholder="请输入收货人姓名" clearable style="width: 240px" />
</t-form-item>
<t-form-item label="订单类型" name="orderPromotionType">
<t-select v-model="searchForm.orderPromotionType" placeholder="请选择" clearable style="width: 240px">
<t-option value="NORMAL" label="普通订单" />
<t-option value="PINTUAN" label="拼团订单" />
<t-option value="GIFT" label="赠品订单" />
<t-option value="POINTS" label="积分订单" />
<t-option value="KANJIA" label="砍价订单" />
</t-select>
</t-form-item>
<t-form-item label="支付方式" name="paymentMethod">
<t-select v-model="searchForm.paymentMethod" placeholder="请选择支付方式" clearable style="width: 240px">
<t-option value="WECHAT" label="微信支付" />
<t-option value="ALIPAY" label="支付宝" />
<t-option value="WALLET" label="余额支付" />
<t-option value="BANK_TRANSFER" label="线下转账" />
</t-select>
</t-form-item>
<t-form-item label="下单时间">
<t-date-picker v-model="selectDate" mode="date" range format="YYYY-MM-DD" valueType="time-stamp" clearable @change="selectDateRange" placeholder="选择起始时间" style="width: 240px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
<t-button variant="outline" style="margin-left: 8px" @click="handleReset">重置</t-button>
</t-form-item>
</t-form>
</t-card>
<t-card>
<div class="order-tab">
<Tabs v-model="currentStatus" @on-click="orderStatusClick">
<TabPane v-for="(item,index) in orderStatusWithCount" :key="index" :label="item.title" :name="item.value">
</TabPane>
</Tabs>
<t-tabs v-model="currentStatus" @change="orderStatusClick">
<t-tab-panel v-for="(item, index) in orderStatusWithCount" :key="index" :label="item.title" :value="item.value" />
</t-tabs>
</div>
<div>
<Button @click="exportOrder" type="info" class="export">导出订单</Button>
<t-button variant="outline" class="export" @click="exportOrder">导出订单</t-button>
</div>
<Table
:loading="loading"
:columns="columns"
:data="data"
ref="table"
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>
<div class="order-table">
<div class="order-table-header">
<div>商品信息</div>
<div>价格</div>
<div>订单状态</div>
<div>订单来源</div>
<div>订单类型</div>
<div>会员ID</div>
<div>店铺名称</div>
<div>操作</div>
</div>
<div v-for="(order, oIndex) in data" :key="oIndex" class="order-block">
<div class="order-block-head">
<div class="order-head-left">
<span class="order-sn">订单编号 {{ order.sn }}</span>
<t-tooltip content="复制">
<t-icon name="copy" size="16" class="copy-icon" @click="copySn(order.sn)" />
</t-tooltip>
<span class="order-time">下单时间 {{ order.createTime }}</span>
</div>
</div>
<div class="order-block-body">
<div class="order-grid">
<div class="order-grid-left">
<div class="order-item" v-for="(item, gIndex) in order.orderItems || []" :key="gIndex">
<div class="goods-info">
<img :src="item.image" class="goods-thumb" />
<div class="goods-text">
<div class="goods-title">{{ item.name || item.goodsName }}</div>
<div class="goods-meta">商品ID{{ item.goodsId }}</div>
</div>
</div>
</div>
</div>
<div class="col-price">
{{ $options.filters.unitPrice(order.flowPrice || 0, "¥") }}
</div>
<div class="col-status">
{{ orderStatusLabel(order.orderStatus) }}
</div>
<div class="meta-origin">{{ clientTypeLabel(order.clientType) }}</div>
<div class="meta-type">{{ orderPromotionTypeLabel(order.orderPromotionType) }}</div>
<div class="meta-member">{{ order.memberId }}</div>
<div class="meta-store">{{ order.storeName }}</div>
<div class="meta-actions">
<a class="link" @click="detail(order)">订单详情</a>
</div>
</div>
</div>
</div>
</div>
<div class="mt_10" style="display: flex; justify-content: flex-end">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</template>
<script>
import * as API_Order from "@/api/order";
import JsonExcel from "vue-json-excel";
import { MessagePlugin } from "tdesign-vue";
export default {
name: "orderList",
components: {
@@ -160,7 +135,7 @@ export default {
} else if (value == "PC") {
return "PC端";
} else if (value == "WECHAT_MP") {
return "小程序";
return "小程序";
} else if (value == "APP") {
return "移动应用端";
} else {
@@ -201,183 +176,84 @@ export default {
},
selectDate: null,
columns: [
{
title: "订单号",
key: "sn",
minWidth: 240,
tooltip: true,
},
{ title: "订单号", colKey: "sn", minWidth: 240, tooltip: true },
{
title: "订单来源",
key: "clientType",
colKey: "clientType",
width: 120,
render: (h, params) => {
if (params.row.clientType == "H5") {
return h("div", {}, "移动端");
} else if (params.row.clientType == "PC") {
return h("div", {}, "PC端");
} else if (params.row.clientType == "WECHAT_MP") {
return h("div", {}, "小程序端");
} else if (params.row.clientType == "APP") {
return h("div", {}, "移动应用端");
} else {
return h("div", {}, params.row.clientType);
}
cell: (h, p) => {
const m = { H5: "移动端", PC: "PC端", WECHAT_MP: "小程序", APP: "移动应用端" };
return h("div", [m[p.row.clientType] || p.row.clientType]);
},
},
{
title: "订单类型",
key: "orderPromotionType",
colKey: "orderPromotionType",
width: 120,
render: (h, params) => {
if (params.row.orderPromotionType == "NORMAL") {
return h("div", [
h("tag", { props: { color: "blue" } }, "普通订单"),
]);
} else if (params.row.orderPromotionType == "PINTUAN") {
return h("div", [
h("tag", { props: { color: "volcano" } }, "拼团订单"),
]);
} else if (params.row.orderPromotionType == "GIFT") {
return h("div", [
h("tag", { props: { color: "green" } }, "赠品订单"),
]);
} else if (params.row.orderPromotionType == "POINTS") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "积分订单"),
]);
} else if (params.row.orderPromotionType == "KANJIA") {
return h("div", [
h("tag", { props: { color: "pink" } }, "砍价订单"),
]);
}
cell: (h, p) => {
const map = {
NORMAL: { theme: "primary", label: "普通订单" },
PINTUAN: { theme: "warning", label: "拼团订单" },
GIFT: { theme: "success", label: "赠品订单" },
POINTS: { theme: "default", label: "积分订单" },
KANJIA: { theme: "pink", label: "砍价订单" },
};
const cfg = map[p.row.orderPromotionType];
if (!cfg) return h("div", [p.row.orderPromotionType || "-"]);
return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
},
},
{
title: "买家名称",
key: "memberName",
minWidth: 130,
tooltip: true,
},
{
title: "会员ID",
key: "memberId",
minWidth: 120,
tooltip: true,
},
{
title: "店铺名称",
key: "storeName",
minWidth: 150,
tooltip: true,
},
{
title: "订单金额",
key: "flowPrice",
minWidth: 100,
tooltip: true,
render: (h, params) => {
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
},
},
{ title: "买家名称", colKey: "memberName", minWidth: 130, tooltip: true },
{ title: "会员ID", colKey: "memberId", minWidth: 120, tooltip: true },
{ title: "店铺名称", colKey: "storeName", minWidth: 150, tooltip: true },
{ title: "订单金额", colKey: "flowPrice", minWidth: 120, cell: (h, p) => h("priceColorScheme", { props: { value: p.row.flowPrice, color: this.$mainColor } }) },
{
title: "支付方式",
key: "paymentMethod",
colKey: "paymentMethod",
width: 120,
render: (h, params) => {
if (params.row.paymentMethod == "WECHAT") {
return h("div", {}, "微信支付");
} else if (params.row.paymentMethod == "ALIPAY") {
return h("div", {}, "支付宝");
} else if (params.row.paymentMethod == "WALLET") {
return h("div", {}, "余额支付");
} else if (params.row.paymentMethod == "BANK_TRANSFER") {
return h("div", {}, "线下转账");
} else {
return h("div", {}, params.row.paymentMethod || "-");
}
cell: (h, p) => {
const m = { WECHAT: "微信支付", ALIPAY: "支付宝", WALLET: "余额支付", BANK_TRANSFER: "线下转账" };
return h("div", [m[p.row.paymentMethod] || p.row.paymentMethod || "-"]);
},
},
{
title: "订单状态",
key: "orderStatus",
minWidth: 100,
render: (h, params) => {
if (params.row.orderStatus == "UNPAID") {
return h("div", [
h("tag", { props: { color: "magenta" } }, "付款"),
]);
} else if (params.row.orderStatus == "PAID") {
return h("div", [
h("tag", { props: { color: "blue" } }, "已付款"),
]);
} else if (params.row.orderStatus == "UNDELIVERED") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "待发货"),
]);
} else if (params.row.orderStatus == "STAY_PICKED_UP") {
return h("div", [
h("tag", { props: { color: "geekblue" } }, "待自提"),
]);
} else if (params.row.orderStatus == "PARTS_DELIVERED") {
return h("div", [
h("tag", { props: { color: "cyan" } }, "部分发货"),
]);
} else if (params.row.orderStatus == "DELIVERED") {
return h("div", [
h("tag", { props: { color: "cyan" } }, "已发货"),
]);
} else if (params.row.orderStatus == "COMPLETED") {
return h("div", [
h("tag", { props: { color: "green" } }, "已完成"),
]);
} else if (params.row.orderStatus == "TAKE") {
return h("div", [
h("tag", { props: { color: "volcano" } }, "待核验"),
]);
} else if (params.row.orderStatus == "CANCELLED") {
return h("div", [
h("tag", { props: { color: "red" } }, "已关闭"),
]);
}
colKey: "orderStatus",
minWidth: 120,
cell: (h, p) => {
const map = {
UNPAID: { theme: "danger", label: "未付款" },
PAID: { theme: "primary", label: "付款" },
UNDELIVERED: { theme: "warning", label: "待发货" },
STAY_PICKED_UP: { theme: "warning", label: "待自提" },
PARTS_DELIVERED: { theme: "cyan", label: "部分发货" },
DELIVERED: { theme: "cyan", label: "已发货" },
COMPLETED: { theme: "success", label: "已完成" },
TAKE: { theme: "warning", label: "待核验" },
CANCELLED: { theme: "danger", label: "已关闭" },
};
const cfg = map[p.row.orderStatus];
if (!cfg) return h("div", [p.row.orderStatus || "-"]);
return h("t-tag", { props: { theme: cfg.theme, variant: "light", size: "small" } }, [cfg.label]);
},
},
{
title: "下单时间",
key: "createTime",
width: 170,
},
{ title: "下单时间", colKey: "createTime", width: 170 },
{
title: "操作",
key: "action",
colKey: "action",
align: "center",
width: 100,
render: (h, params) => {
return h(
"div",
{ class: "ops" },
[
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
},
on: {
click: () => {
this.detail(params.row);
},
},
},
"查看"
),
]
);
cell: (h, p) => {
return h("div", { class: "ops" }, [
h(
"a",
{
style: { color: "#2d8cf0", cursor: "pointer", textDecoration: "none" },
on: { click: () => { this.detail(p.row); } },
},
"查看"
),
]);
},
},
],
@@ -417,22 +293,64 @@ export default {
}
},
methods: {
orderStatusLabel(status) {
const map = {
UNPAID: "未付款",
PAID: "已付款",
UNDELIVERED: "待发货",
STAY_PICKED_UP: "待自提",
PARTS_DELIVERED: "部分发货",
DELIVERED: "已发货",
COMPLETED: "已完成",
TAKE: "待核验",
CANCELLED: "已关闭",
};
return map[status] || status || "-";
},
clientTypeLabel(ct) {
const m = { H5: "移动端", PC: "PC端", WECHAT_MP: "小程序", APP: "移动应用端" };
return m[ct] || ct || "-";
},
orderPromotionTypeLabel(tp) {
const m = { NORMAL: "普通订单", PINTUAN: "拼团订单", GIFT: "赠品订单", POINTS: "积分订单", KANJIA: "砍价订单" };
return m[tp] || tp || "-";
},
copySn(text) {
const doOk = () => MessagePlugin.success("复制成功");
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(String(text)).then(doOk);
} else {
const input = document.createElement("input");
input.value = String(text);
document.body.appendChild(input);
input.select();
document.execCommand("copy");
document.body.removeChild(input);
doOk();
}
},
// 初始化数据
init() {
this.getDataList();
this.getOrderNumData(); // 新增:获取订单数量统计
},
// 分页 改变页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 分页 改变页数
changePageSize(v) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = v;
this.getDataList();
},
onPaginationChange(info) {
if (info && typeof info.pageSize !== "undefined" && info.pageSize !== this.searchForm.pageSize) {
this.changePageSize(info.pageSize);
}
if (info && typeof info.current !== "undefined") {
this.changePage(info.current);
}
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
@@ -440,7 +358,28 @@ export default {
this.getDataList();
this.getOrderNumData(); // 新增:搜索时也更新数量统计
},
// 起止时间从新赋值
handleReset() {
this.searchForm = {
pageNumber: 1,
pageSize: 20,
sort: "createTime",
order: "desc",
startDate: "",
endDate: "",
orderType: "",
orderSn: "",
keywords: "",
buyerName: "",
goodsName: "",
shipName: "",
orderStatus: "",
paymentMethod: "",
};
this.selectDate = null;
this.currentStatus = '';
this.getDataList();
this.getOrderNumData();
},
selectDateRange(v) {
if (v) {
this.searchForm.startDate = v[0];
@@ -450,15 +389,17 @@ export default {
// 获取列表数据
getDataList() {
this.loading = true;
API_Order.getOrderList(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;
API_Order.getOrderList(this.searchForm)
.then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
})
.catch(() => {
this.loading = false;
});
},
// 跳转详情页面
detail(v) {
@@ -471,8 +412,8 @@ export default {
},
// 导出订单
async exportOrder() {
if(this.searchForm.startDate==""||this.searchForm.endDate==""){
this.$Message.error("必须选择时间范围,搜索后进行导出!");
if (this.searchForm.startDate === "" || this.searchForm.endDate === "") {
MessagePlugin.error("必须选择时间范围,搜索后进行导出!");
}else{
API_Order.exportOrder(this.searchForm)
.then((res) => {
@@ -502,16 +443,9 @@ export default {
},
// 订单筛选
orderStatusClick(name) {
if (name === 0) {
// 点击"全部"时设置为空字符串在getDataList中会被过滤掉
this.searchForm.orderStatus = '';
} else {
// 其他状态正常赋值
this.searchForm.orderStatus = name;
}
this.currentStatus = name;
orderStatusClick(value) {
this.searchForm.orderStatus = value || '';
this.currentStatus = value;
this.getDataList();
},
getOrderNumData() {
@@ -555,4 +489,44 @@ export default {
margin: 0 8px;
color: #dcdee2;
}
.order-table-header {
display: grid;
grid-template-columns: 2.5fr 1fr 1fr 1fr 1fr 1.2fr 1fr 0.8fr;
gap: 12px;
padding: 12px 16px;
background: #f5f5f5;
color: #666;
font-size: inherit;
}
.order-table-header > div { white-space: nowrap; }
.order-block { border: 1px solid #eee; margin: 12px 0; background: #fff; }
.order-block-head { padding: 10px 16px; border-bottom: 1px solid #f0f0f0; display:flex; justify-content:space-between; background: #fafafa; }
.order-head-left { color: #333; }
.order-head-left .order-time { margin-left: 16px; }
.copy-icon { margin-left: 6px; cursor: pointer; vertical-align: middle; }
.order-head-right { display:flex; gap: 16px; color:#666; font-size: inherit; }
.order-block-body { padding: 8px 0; }
.order-grid { display: grid; grid-template-columns: 2.5fr 1fr 1fr 1fr 1fr 1.2fr 1fr 0.8fr; }
.order-grid-left { grid-column: 1 / 2; padding: 8px 0; }
.col-price { grid-column: 2 / 3; color:#333; display:flex; align-items:center; }
.col-price-item { padding: 12px 0; }
.col-status { grid-column: 3 / 4; display:flex; align-items:center; }
.col-status-item { padding: 12px 0; }
.meta-origin { grid-column: 4 / 5; color:#333; display:flex; align-items:center; }
.meta-type { grid-column: 5 / 6; color:#333; display:flex; align-items:center; }
.meta-member { grid-column: 6 / 7; color:#333; display:flex; align-items:center; }
.meta-store { grid-column: 7 / 8; color:#333; display:flex; align-items:center; }
.meta-actions { grid-column: 8 / 9; display:flex; align-items:center; white-space:nowrap; min-width: 100px; }
.meta-actions .link { color: #2d8cf0; cursor: pointer; text-decoration: none; }
.order-item { display: block; padding: 12px 16px; }
.goods-info { display: flex; align-items: center; }
.goods-thumb { width: 60px; height: 60px; object-fit: cover; border-radius: 4px; margin-right: 12px; }
.goods-text { display: flex; flex-direction: column; }
.goods-title { color: #333; font-size: 14px; }
.goods-meta { margin-top: 6px; color: #999; }
.goods-price { color: #333; }
.goods-num { margin-left: 6px; color: #999; }
.goods-status { color: #666; }
.goods-actions { text-align: center; }
.goods-actions .link { color: #2d8cf0; cursor: pointer; text-decoration: none; }
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="wrapper">
<Card class="category">
<t-card class="category">
<div
:class="{ active: i == selectedIndex }"
class="category-item"
@@ -9,11 +9,11 @@
>
<div @click="clickType(typeItem.type, i)">{{ typeItem.title }}</div>
</div>
</Card>
<Card class="content">
<Button type="primary" @click="createTemp">添加页面</Button>
</t-card>
<t-card class="content">
<t-button theme="primary" @click="createTemp">添加页面</t-button>
<div class="list">
<Spin size="large" fix v-if="loading"></Spin>
<t-loading v-if="loading" fullscreen></t-loading>
<div class="item item-title">
<div>页面名称</div>
<div class="item-config">
@@ -28,73 +28,55 @@
<div>{{ item.name || "暂无模板昵称" }}</div>
<div class="item-config">
<div>
<i-switch
<t-switch
v-if="searchForm.pageType !== 'SPECIAL'"
v-model="item.pageShow"
@on-change="releaseTemplate(item.id)"
@change="releaseTemplate(item.id)"
>
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
</t-switch>
</div>
<div class="action">
<Button
type="info"
placement="right"
@click="Template(item)"
size="small"
>编辑</Button
>
<Button
type="success"
placement="right"
@click="decorate(item)"
size="small"
>装修</Button
>
<Poptip confirm title="删除此模板?" @on-ok="delTemplate(item.id)">
<Button type="error" size="small">删除</Button>
</Poptip>
<t-button theme="default" @click="Template(item)" size="small">编辑</t-button>
<t-button theme="success" @click="decorate(item)" size="small">装修</t-button>
<t-button theme="danger" size="small" @click="confirmDelTemplate(item.id)">删除</t-button>
</div>
</div>
</div>
<div class="no-more" v-if="list.length == 0">暂无更多模板</div>
</div>
<Page
show-total
<t-pagination
:total="total"
show-sizer
size="small"
:page-size-opts="[20, 50, 100]"
show-elevator
:pageSizeOptions="[20, 50, 100]"
showJumper
style="float: right; overflow: hidden"
@on-change="changePageNum"
@on-page-size-change="changePageSize"
:page-size="searchForm.pageSize"
:pageSize="searchForm.pageSize"
@change="({ current }) => changePageNum(current)"
@page-size-change="(size) => changePageSize(size)"
/>
</Card>
<Modal
v-model="showModal"
title="模板设置"
draggable
width="600"
:z-index="100"
:loading="loading"
:mask-closable="false"
@on-ok="newTemplate"
@on-cancel="showModal = false"
</t-card>
<t-dialog
:visible.sync="showModal"
header="模板设置"
:width="600"
:closeOnOverlayClick="false"
@confirm="newTemplate"
@close="showModal = false"
>
<Form ref="form" :model="formData" :label-width="80">
<FormItem label="模板名称" prop="name">
<Input v-model="formData.name" placeholder="请输入模板名称" />
</FormItem>
</Form>
</Modal>
<t-form ref="form" :data="formData" :labelWidth="80">
<t-form-item label="模板名称" name="name">
<t-input v-model="formData.name" placeholder="请输入模板名称" />
</t-form-item>
</t-form>
</t-dialog>
</div>
</template>
<script>
import * as API_floor from "@/api/other.js";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "floorList",
data() {
@@ -161,13 +143,13 @@ export default {
(data.pageClientType = "PC");
if (data.id) {
API_floor.updateHome(data.id, data).then((res) => {
this.$Message.success("编辑模板成功");
MessagePlugin.success("编辑模板成功");
this.showModal = false;
this.getTemplateList();
});
} else {
API_floor.setHomeSetup(data).then((res) => {
this.$Message.success("新建模板成功");
MessagePlugin.success("新建模板成功");
this.showModal = false;
this.getTemplateList();
});
@@ -249,7 +231,7 @@ export default {
//发布模板
API_floor.releasePageHome(id).then((res) => {
if (res.success) {
this.$Message.success("发布模板成功");
MessagePlugin.success("发布模板成功");
this.getTemplateList();
}
});
@@ -258,11 +240,19 @@ export default {
delTemplate(id) {
API_floor.removePageHome(id).then((res) => {
if (res.success) {
this.$Message.success("删除模板成功");
MessagePlugin.success("删除模板成功");
this.getTemplateList();
}
});
},
confirmDelTemplate(id) {
DialogPlugin.confirm({
header: "删除此模板",
content: "确认删除后不可恢复",
theme: "warning",
onConfirm: () => this.delTemplate(id)
})
},
},
};
</script>

View File

@@ -8,8 +8,8 @@
>
<img :src="topAdvert.img" width="1200" height="80" alt="" />
<div class="setup-box">
<Button size="small" @click.stop="handleModel('topAdvert')"
>编辑</Button
<t-button size="small" @click.stop="handleModel('topAdvert')"
>编辑</t-button
>
</div>
</div>
@@ -20,16 +20,15 @@
<li>请登录</li>
<li>我的订单</li>
<li>我的足迹</li>
<li><Icon size="18" type="ios-cart-outline"></Icon>购物车</li>
<li><t-icon size="18" name="shopping-cart"></t-icon>购物车</li>
<li>店铺入驻</li>
</ul>
</div>
<div class="search-con">
<img :src="require('@/assets/logo.png')" class="logo" alt="" />
<div class="search">
<i-input size="large" placeholder="输入你想查找的商品">
<Button slot="append">搜索</Button>
</i-input>
<t-input size="large" placeholder="输入你想查找的商品" style="width: 260px" />
<t-button size="small" style="margin-left:8px">搜索</t-button>
</div>
</div>
<div class="nav-con" v-if="$route.query.pageType !== 'SPECIAL'">
@@ -40,8 +39,8 @@
</li>
</ul>
<div class="setup-box">
<Button size="small" @click.stop="handleModel('quickNav')"
>编辑</Button
<t-button size="small" @click.stop="handleModel('quickNav')"
>编辑</t-button
>
</div>
</div>
@@ -66,13 +65,11 @@
</draggable>
</div>
</div>
<Modal
v-model="showModal"
title="顶部广告"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="顶部广告"
:width="800"
:closeOnOverlayClick="false"
>
<!-- 顶部广告 -->
<div class="modal-top-advert">
@@ -89,35 +86,34 @@
建议尺寸<span>{{ topAdvert.size }}</span>
</div>
<div>
图片链接<Input
图片链接<t-input
class="outsideUrl"
v-model="topAdvert.url"
:disabled="!!topAdvert.type && topAdvert.type !== 'link'"
placeholder="https://"
/><Button size="small" type="primary" @click="handleSelectLink"
>选择链接</Button
/>
<t-button size="small" theme="primary" @click="handleSelectLink"
>选择链接</t-button
>
</div>
<div>
选择图片<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
选择图片<t-button size="small" theme="primary" @click="handleSelectImg"
>选择图片</t-button
>&nbsp;
</div>
<div>选择背景色<ColorPicker v-model="topAdvert.bgColor" /></div>
<div>选择背景色<t-color-picker v-model="topAdvert.bgColor" /></div>
</div>
</Modal>
<Modal
v-model="showModalNav"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
</t-dialog>
<t-dialog
:visible.sync="showModalNav"
header="快捷导航"
:width="800"
:closeOnOverlayClick="false"
>
<!-- 分类tab栏 -->
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAddNav"
>添加分类</Button
<t-button theme="primary" size="small" @click="handleAddNav"
>添加分类</t-button
>
<table cellspacing="0">
<thead>
@@ -130,41 +126,41 @@
</thead>
<tbody>
<tr v-for="(item, index) in navList.list" :key="index">
<td><Input v-model="item.name" /></td>
<td><t-input v-model="item.name" /></td>
<td>
<Input
<t-input
v-model="item.url"
:disabled="!item.title || item.title !== '外部链接'"
/>
</td>
<!-- <td><Input v-model="item.sort"/></td> -->
<td>
<Button
<t-button
type="primary"
size="small"
@click="handleSelectLink(item, index)"
>选择链接</Button
>选择链接</t-button
>&nbsp;
<Button type="error" size="small" @click="handleDelNav(index)"
>删除</Button
<t-button theme="danger" size="small" @click="handleDelNav(index)"
>删除</t-button
>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" header="选择图片" :visible.sync="picModelFlag" :footer="false">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
</t-dialog>
</div>
</template>
<script>

View File

@@ -43,9 +43,7 @@
<img :src="item.img" width="230" height="190" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
<t-button size="small" @click.stop="handleSelectModel(item)">编辑</t-button>
</div>
</div>
</li>
@@ -78,9 +76,7 @@
<img :src="item.img" width="190" height="210" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
<t-button size="small" @click.stop="handleSelectModel(item)">编辑</t-button>
</div>
</div>
</div>
@@ -150,11 +146,7 @@
</div>
<div class="setup-box">
<div>
<Button
size="small"
@click.stop="handleSelectModel(element.options)"
>编辑</Button
>
<t-button size="small" @click.stop="handleSelectModel(element.options)">编辑</t-button>
</div>
</div>
</div>
@@ -163,15 +155,13 @@
<not-enough :data="element"></not-enough>
</template>
<div class="del-btn">
<Button size="small" type="error" @click="handleModelDelete">删除</Button>
<t-button size="small" theme="danger" @click="handleModelDelete">删除</t-button>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-top-advert">
<div>
@@ -222,34 +212,33 @@
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<Input
图片链接<t-input
class="outsideUrl"
v-model="selected.url"
:disabled="!!selected.type && selected.type !== 'link'"
placeholder="https://"
/>
<Button size="small" type="primary" @click="handleSelectLink"
>选择链接</Button
>
<t-button size="small" theme="primary" @click="handleSelectLink">选择链接</t-button>
</div>
<div>
选择图片<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
>&nbsp;
选择图片<t-button size="small" theme="primary" @click="handleSelectImg">选择图片</t-button>&nbsp;
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -271,6 +260,7 @@ import onlyGoodsModel from "./modelList/onlyGoodsModel.vue";
import oneRowThreeColumns from "./modelList/oneRowThreeColumns.vue";
import seckillOnlyAlbum from "./modelList/seckill-only-album.vue";
import { DialogPlugin } from "tdesign-vue";
export default {
name: "modelFormItem",
props: ["element", "select", "index", "data"],
@@ -306,10 +296,11 @@ export default {
},
// 删除模块
handleModelDelete() {
this.$Modal.confirm({
title: "提示",
content: "<p>确定删除当前模块吗?</p>",
onOk: () => {
DialogPlugin.confirm({
header: "提示",
content: "确定删除当前模块吗?",
theme: "warning",
onConfirm: () => {
this.$nextTick(() => {
this.data.list.splice(this.index, 1);
});

View File

@@ -21,7 +21,9 @@
<div class="nav-right">
<div class="person-msg">
<img :src="userInfo.face" v-if="userInfo.face" alt />
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
<t-avatar class="mb_10" v-else size="80px">
<t-icon name="user" />
</t-avatar>
<div>
Hi{{ userInfo.nickName || "欢迎来到管理后台" | secrecyMobile }}
</div>

View File

@@ -14,21 +14,19 @@
</Carousel>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
<t-button size="small" @click.stop="handleSelectModel">编辑</t-button>
</div>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="快捷导航"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
<t-button theme="primary" size="small" @click="handleAdd">添加轮播</t-button>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<span style="color: red" class="fz_12 ml_10"
@@ -55,37 +53,32 @@
/>
</td>
<td>
<Input
<t-input
class="outsideUrl"
v-model="item.url"
:disabled="!!item.type && item.type !== 'link'"
/>
</td>
<td>
<Button type="info" size="small" @click="handleSelectLink(item)"
>选择链接</Button
>&nbsp;
<t-button theme="default" size="small" @click="handleSelectLink(item)">选择链接</t-button>&nbsp;
<ColorPicker size="small" v-model="item.bgColor" />
&nbsp;
<Button
type="error"
ghost
size="small"
@click="handleDel(index)"
>删除</Button
>
<t-button theme="danger" size="small" @click="handleDel(index)">删除</t-button>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>

View File

@@ -5,13 +5,13 @@
<div class="nav-side">分类占位区</div>
<div class="nav-content setup-content">
<!-- 轮播图 -->
<Carousel autoplay>
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
<t-swiper autoplay>
<t-swiper-item v-for="(item, index) in data.options.list" :key="index">
<div style="overflow: hidden">
<img :src="item.img" width="590" height="470" />
</div>
</CarouselItem>
</Carousel>
</t-swiper-item>
</t-swiper>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
@@ -20,8 +20,8 @@
</div>
<div class="nav-content1 setup-content">
<!-- 轮播图 -->
<Carousel autoplay :autoplay-speed="5000">
<CarouselItem
<t-swiper autoplay :interval="5000">
<t-swiper-item
v-for="(item, index) in data.options.listRight"
:key="index"
>
@@ -34,8 +34,8 @@
<div>
<img :src="item[2].img" width="190" height="150" />
</div>
</CarouselItem>
</Carousel>
</t-swiper-item>
</t-swiper>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
@@ -45,15 +45,15 @@
<div class="nav-right">
<div class="person-msg">
<img :src="userInfo.face" v-if="userInfo.face" alt />
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
<t-avatar class="mb_10" v-else size="80"><t-icon name="user"/></t-avatar>
<div>
Hi{{ userInfo.nickName || "欢迎来到管理后台" | secrecyMobile }}
</div>
<div v-if="userInfo.id">
<Button type="error" shape="circle">会员中心</Button>
<t-button theme="danger" shape="round">会员中心</t-button>
</div>
<div v-else>
<Button type="error" shape="circle">请登录</Button>
<t-button theme="danger" shape="round">请登录</t-button>
</div>
</div>
<div class="shop-msg">
@@ -74,16 +74,14 @@
</div>
</div>
<!-- 左侧轮播装修 -->
<Modal
v-model="showModal"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="快捷导航"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
<t-button theme="primary" size="small" @click="handleAdd">添加轮播</t-button>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片</span>
@@ -108,56 +106,46 @@
/>
</td>
<td>
<Input
<t-input
class="outsideUrl"
v-model="item.url"
:disabled="!!item.type && item.type !== 'link'"
/>
</td>
<td>
<Button type="info" size="small" @click="handleSelectLink(item)"
>选择链接</Button
<t-button theme="primary" size="small" @click="handleSelectLink(item)"
>选择链接</t-button
>&nbsp;
<Button
type="error"
ghost
<t-button
theme="danger"
variant="outline"
size="small"
@click="handleDel(index)"
>删除</Button
>删除</t-button
>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
</t-dialog>
<!-- 右侧轮播装修 -->
<Modal
v-model="showModal"
title="右侧装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="右侧装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAddGroup"
>添加组</Button
<t-button theme="primary" size="small" @click="handleAddGroup"
>添加组</t-button
>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片</span>
<Tabs
type="card"
closable
@on-tab-remove="handleTabRemove"
class="mt_10"
>
<TabPane
:label="'图片组' + (gIndex + 1)"
v-for="(group, gIndex) in data.options.listRight"
:key="gIndex"
>
<div class="mt_10">
<div v-for="(group, gIndex) in data.options.listRight" :key="gIndex">
<div class="ml_10">图片组 {{ gIndex + 1 }}</div>
<table cellspacing="0">
<thead>
<tr>
@@ -179,33 +167,33 @@
/>
</td>
<td>
<Input
<t-input
class="outsideUrl"
v-model="item.url"
:disabled="!!item.type && item.type !== 'link'"
/>
</td>
<td>
<Button
type="info"
<t-button
theme="primary"
size="small"
@click="handleSelectLink(item)"
>选择链接</Button
>选择链接</t-button
>
</td>
</tr>
</tbody>
</table>
</TabPane>
</Tabs>
</div>
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink"></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" :footer="false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
</t-dialog>
</div>
</template>

View File

@@ -41,24 +41,22 @@
</div>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel()">编辑 </Button>
<t-button size="small" @click.stop="handleSelectModel()">编辑</t-button>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div>
<div class="modal-tab-bar">
<div>
主标题:
<Input style="width: 200px" v-model="data.options.title"></Input>
<t-input style="width: 200px" v-model="data.options.title"></t-input>
</div>
<Divider>左侧商品部分</Divider>
<div class="flex">
@@ -69,25 +67,14 @@
<div>推荐尺寸{{ data.options.data.image.size }}</div>
<div class="link-src">
链接地址
<Input
<t-input
style="width: 200px"
v-model="data.options.data.image.url"
disabled
/>
</div>
<Button
size="small"
type="primary"
@click="handleSelectImg('image')"
>选择图片
</Button>
<Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink('image')"
>选择链接
</Button>
<t-button size="small" theme="primary" @click="handleSelectImg('image')">选择图片</t-button>
<t-button size="small" class="ml_10" theme="primary" @click="handleSelectLink('image')">选择链接</t-button>
</div>
</div>
</div>
@@ -102,35 +89,20 @@
<div class="flex">
<img :src="item.img" class="column-img" />
<div class="column-goods-list">
<div><Input v-model="item.title"></Input></div>
<div><Input v-model="item.desc"></Input></div>
<div><Input disabled v-model="item.url"></Input></div>
<div><t-input v-model="item.title"></t-input></div>
<div><t-input v-model="item.desc"></t-input></div>
<div><t-input disabled v-model="item.url"></t-input></div>
<div>{{ item.size }}</div>
<Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink('list', index)"
>选择链接
</Button>
<Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectImg('list', index)"
>选择图片
</Button>
<t-button size="small" class="ml_10" theme="primary" @click="handleSelectLink('list', index)">选择链接</t-button>
<t-button size="small" class="ml_10" theme="primary" @click="handleSelectImg('list', index)">选择图片</t-button>
</div>
</div>
</div>
</div>
<Divider>右侧商品部分</Divider>
<div class="flex">
<div class="flex">
<div>右侧标题 :</div>
<Input
style="width: 200px"
v-model="data.options.data.hot.title"
></Input>
<t-input style="width: 200px" v-model="data.options.data.hot.title"></t-input>
</div>
<div class="flex column-list">
<div
@@ -154,7 +126,7 @@
</div>
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog
@@ -164,14 +136,17 @@
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>

View File

@@ -5,9 +5,7 @@
<left :data="data" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel('left')"
>编辑
</Button>
<t-button size="small" @click.stop="handleSelectModel('left')">编辑</t-button>
</div>
</div>
</div>
@@ -16,32 +14,24 @@
<right :data="data" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel('right')"
>编辑
</Button>
<t-button size="small" @click.stop="handleSelectModel('right')">编辑</t-button>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div v-if="current">
<div class="modal-tab-bar">
<div>
当前模块 :
<ButtonGroup>
<Button :type="current.model == 'goods' ? 'primary' : 'default'"
>商品</Button
>
<Button :type="current.model == 'brand' ? 'primary' : 'default'"
>品牌</Button
>
</ButtonGroup>
<div>
<t-button :theme="current.model == 'goods' ? 'primary' : 'default'">商品</t-button>
<t-button :theme="current.model == 'brand' ? 'primary' : 'default'">品牌</t-button>
</div>
</div>
<div class="flex">
@@ -52,48 +42,31 @@
<div>推荐尺寸{{ current.data.image.size }}</div>
<div class="link-src">
链接地址
<Input
<t-input
style="width: 200px"
v-model="current.data.image.url"
disabled
/>
</div>
<Button
size="small"
type="primary"
@click="handleSelectImg('default')"
>选择图片
</Button>
<Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink('image')"
>选择链接
</Button>
<t-button size="small" theme="primary" @click="handleSelectImg('default')">选择图片</t-button>
<t-button size="small" class="ml_10" theme="primary" @click="handleSelectLink('image')">选择链接</t-button>
</div>
</div>
</div>
<div class="flex" v-if="current.model == 'goods'">
<div>标签 :</div>
<Input
<t-input
style="width: 200px"
type="text"
v-model="current.data.badge.label"
/>
<Input
<t-input
style="width: 100px; margin-left: 10px"
disabled
type="text"
v-model="current.data.badge.url"
/>
<Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink('badge')"
>选择链接
</Button>
<t-button size="small" class="ml_10" theme="primary" @click="handleSelectLink('badge')">选择链接</t-button>
</div>
<div class="flex column-list">
<div
@@ -103,42 +76,20 @@
>
<div class="flex">
<img :src="item.img" class="column-img" />
<Button
size="small"
class="ml_10"
type="primary"
v-if="current.model == 'goods'"
@click="handleSelectGoods('list', index)"
>选择商品
</Button>
<t-button size="small" class="ml_10" theme="primary" v-if="current.model == 'goods'" @click="handleSelectGoods('list', index)">选择商品</t-button>
<div>
<div v-if="current.model == 'brand'" style="margin-bottom: 10px">
<Input disabled v-model="item.url" />
<t-input disabled v-model="item.url" />
</div>
<Button
size="small"
class="ml_10"
type="primary"
v-if="current.model == 'brand'"
@click="handleSelectLink('list', index)"
>
选择链接
</Button>
<Button
size="small"
class="ml_10"
type="primary"
v-if="current.model == 'brand'"
@click="handleSelectImg('list', index)"
>选择图片
</Button>
<t-button size="small" class="ml_10" theme="primary" v-if="current.model == 'brand'" @click="handleSelectLink('list', index)">选择链接</t-button>
<t-button size="small" class="ml_10" theme="primary" v-if="current.model == 'brand'" @click="handleSelectImg('list', index)">选择图片</t-button>
</div>
</div>
</div>
</div>
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog
@@ -148,14 +99,17 @@
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>

View File

@@ -9,10 +9,10 @@
<span>{{ options.left.secondTitle }} &gt;</span>
<div class="setup-box">
<div>
<Button
<t-button
size="small"
@click.stop="handleSelectModel(options.left, true)"
>编辑</Button
>编辑</t-button
>
</div>
</div>
@@ -30,8 +30,8 @@
<img :src="item.img" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectModel(item)"
>编辑</t-button
>
</div>
</div>
@@ -48,10 +48,10 @@
<span>{{ options.middle.secondTitle }} &gt;</span>
<div class="setup-box">
<div>
<Button
<t-button
size="small"
@click.stop="handleSelectModel(options.middle, true)"
>编辑</Button
>编辑</t-button
>
</div>
</div>
@@ -69,8 +69,8 @@
<img :src="item.img" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectModel(item)"
>编辑</t-button
>
</div>
</div>
@@ -87,10 +87,10 @@
<span>{{ options.right.secondTitle }} &gt;</span>
<div class="setup-box">
<div>
<Button
<t-button
size="small"
@click.stop="handleSelectModel(options.right, true)"
>编辑</Button
>编辑</t-button
>
</div>
</div>
@@ -109,8 +109,8 @@
</div>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectGoods(item)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectGoods(item)"
>编辑</t-button
>
</div>
</div>
@@ -118,13 +118,11 @@
</div>
</div>
<!-- 装修内容 -->
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-top-advert">
<div>
@@ -145,66 +143,64 @@
alt
/>
</div>
<div><span>图片主标题</span><Input v-model="selected.name" /></div>
<div><span>图片描述</span><Input v-model="selected.describe" /></div>
<div><span>图片主标题</span><t-input v-model="selected.name" /></div>
<div><span>图片描述</span><t-input v-model="selected.describe" /></div>
<div class="tips">
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<Input
图片链接<t-input
class="outsideUrl"
v-model="selected.url"
:disabled="!!selected.type && selected.type !== 'link'"
placeholder="https://"
/>
<Button size="small" type="primary" @click="handleSelectLink"
>选择链接</Button
<t-button size="small" theme="primary" @click="handleSelectLink"
>选择链接</t-button
>
</div>
<div>
<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
<t-button size="small" theme="primary" @click="handleSelectImg"
>选择图片</t-button
>&nbsp;
<Button size="small" type="primary" @click="handleSelectGoods('')"
>选择商品</Button
<t-button size="small" theme="primary" @click="handleSelectGoods('')"
>选择商品</t-button
>
</div>
</div>
</Modal>
</t-dialog>
<!-- 装修标题 -->
<Modal
v-model="showModal1"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal1"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-top-advert">
<div><span>主标题</span><Input v-model="selected.title" /></div>
<div><span>副标题</span><Input v-model="selected.secondTitle" /></div>
<div><span>主标题</span><t-input v-model="selected.title" /></div>
<div><span>副标题</span><t-input v-model="selected.secondTitle" /></div>
<div>
<span
>副标题链接<Input
>副标题链接<t-input
class="outsideUrl"
v-model="selected.url"
:disabled="!!selected.type && selected.type !== 'link'"
placeholder="https://" /></span
><Button
><t-button
size="small"
class="ml_10"
type="primary"
theme="primary"
@click="handleSelectLink"
>选择链接</Button
>选择链接</t-button
>
</div>
<div>
<span>背景色</span
><ColorPicker v-if="selected.bgColor" v-model="selected.bgColor" />
><t-color-picker v-if="selected.bgColor" v-model="selected.bgColor" />
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@@ -212,14 +208,17 @@
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>
<script>

View File

@@ -17,28 +17,25 @@
</div>
<div class="setup-box">
<div>
<Button
<t-button
size="small"
@click.stop="handleSelectModel(data.options.list)"
>编辑</Button
>
>编辑</t-button>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-tab-bar">
<div class="flex flex-a-c">
<Button class="add-goods" @click="addCurrentGoods">
<t-button class="add-goods" @click="addCurrentGoods">
添加商品
</Button>
</t-button>
</div>
<div
@@ -52,20 +49,20 @@
<div class="column-config">
<div>
标题
<Input v-model="item.title"></Input>
<t-input v-model="item.title"></t-input>
</div>
<div>
描述
<Input v-model="item.desc"></Input>
<t-input v-model="item.desc"></t-input>
</div>
</div>
<Button @click="delGoods(item,index)">删除</Button>
<t-button theme="danger" @click="delGoods(item,index)">删除</t-button>
</div>
</div>
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog

View File

@@ -9,8 +9,8 @@
<span>{{ msgLeft.secondTitle }}&gt;</span>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(msgLeft, true)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectModel(msgLeft, true)"
>编辑</t-button
>
</div>
</div>
@@ -20,11 +20,11 @@
<img :src="msgLeft.list[0].img" width="160" height="160" alt="" />
<div class="margin-left">{{ msgLeft.list[0].name }}</div>
<div class="margin-left">{{ msgLeft.list[0].describe }}</div>
<Button
<t-button
size="small"
:style="{ background: msgLeft.bgColor }"
class="fz_12 view-btn"
>点击查看</Button
>点击查看</t-button
>
<div class="setup-box">
<div>
@@ -46,8 +46,8 @@
</div>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectModel(item)"
>编辑</t-button
>
</div>
</div>
@@ -65,8 +65,8 @@
<span>{{ msgRight.secondTitle }}&gt;</span>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(msgRight, true)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectModel(msgRight, true)"
>编辑</t-button
>
</div>
</div>
@@ -93,21 +93,19 @@
</div>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
<t-button size="small" @click.stop="handleSelectModel(item)"
>编辑</t-button
>
</div>
</div>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
<t-dialog
:visible.sync="showModal"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-top-advert">
<div>
@@ -136,68 +134,66 @@
alt
/>
</div>
<div><span>图片主标题</span><Input v-model="selected.name" /></div>
<div><span>图片描述</span><Input v-model="selected.describe" /></div>
<div><span>图片主标题</span><t-input v-model="selected.name" /></div>
<div><span>图片描述</span><t-input v-model="selected.describe" /></div>
<div class="tips">
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<Input
图片链接<t-input
class="outsideUrl"
v-model="selected.url"
:disabled="!!selected.type && selected.type !== 'link'"
placeholder="https://"
/>
<Button
<t-button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink"
>选择链接</Button
>选择链接</t-button
>
</div>
<div>
<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
<t-button size="small" theme="primary" @click="handleSelectImg"
>选择图片</t-button
>&nbsp;
<Button size="small" type="primary" @click="handleSelectGoods"
>选择商品</Button
<t-button size="small" theme="primary" @click="handleSelectGoods"
>选择商品</t-button
>
</div>
</div>
</Modal>
<Modal
v-model="showModal1"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
</t-dialog>
<t-dialog
:visible.sync="showModal1"
header="装修"
:width="800"
:closeOnOverlayClick="false"
>
<div class="modal-top-advert">
<div><span>主标题</span><Input v-model="selected.title" /></div>
<div><span>副标题</span><Input v-model="selected.secondTitle" /></div>
<div><span>主标题</span><t-input v-model="selected.title" /></div>
<div><span>副标题</span><t-input v-model="selected.secondTitle" /></div>
<div>
<span
>副标题链接<Input
>副标题链接<t-input
class="outsideUrl"
v-model="selected.url"
:disabled="!!selected.type && selected.type !== 'link'"
placeholder="https://" /></span
><Button
><t-button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink"
>选择链接</Button
>选择链接</t-button
>
</div>
<div>
<span>背景色</span><Input v-model="selected.bgColor" />
<ColorPicker v-if="selected.bgColor" v-model="selected.bgColor" />
<span>背景色</span><t-input v-model="selected.bgColor" />
<t-color-picker v-if="selected.bgColor" v-model="selected.bgColor" />
</div>
</div>
</Modal>
</t-dialog>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@@ -205,14 +201,17 @@
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage
@callback="callbackSelected"
:isComponent="true"
:initialize="picModelFlag"
ref="ossManage"
/>
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>
<script>

View File

@@ -5,7 +5,7 @@
<div class="classification-title">基础模块</div>
<draggable tag="ul" :list="modelData" v-bind="{group:{ name:'model', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" >
<li v-for="(model, index) in modelData" :key="index" class="model-item">
<Icon :type="model.icon" />
<t-icon name="image" />
<span>{{model.name}}</span>
</li>
</draggable>
@@ -16,11 +16,11 @@
</div>
<!-- 操作按钮 -->
<div class="btn-bar" :class="{'top':isHiddenBar}">
<Button type="primary" :loading="submitLoading" @click="saveTemplate">保存模板</Button>
<Button class="ml_10" @click="resetTemplate">还原模板</Button>
<Button class="ml_10" @click="witeLocalStore">将装修内容写入到本地</Button>
<t-button theme="primary" :loading="submitLoading" @click="saveTemplate">保存模板</t-button>
<t-button class="ml_10" @click="resetTemplate">还原模板</t-button>
<t-button class="ml_10" @click="witeLocalStore">将装修内容写入到本地</t-button>
<Button class="ml_10" v-if="hasCache" @click="clearCache">清空本地装修缓存</Button>
<t-button class="ml_10" v-if="hasCache" @click="clearCache">清空本地装修缓存</t-button>
</div>
</div>
</template>
@@ -29,6 +29,7 @@ import { modelData } from "./modelConfig";
import Draggable from "vuedraggable";
import ModelForm from "./modelForm.vue";
import * as API_floor from "@/api/other.js";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
components: {
Draggable,
@@ -41,12 +42,12 @@ export default {
const cache = this.getStore('managerPCPageCache')
this.hasCache = !!cache;
if(cache){
this.$Modal.confirm({
title: '提示',
DialogPlugin.confirm({
header: '提示',
content: '获取到本地有缓存数据,是否使用缓存数据?',
okText: '使用',
cancelText: '取消',
onOk: () => {
confirmBtn: '使用',
cancelBtn: '取消',
onConfirm: () => {
let pageData = cache;
if (pageData) {
pageData = JSON.parse(pageData);
@@ -79,7 +80,7 @@ export default {
methods: {
clearCache(){
this.setStore('managerPCPageCache', '')
this.$Message.success('清除成功')
MessagePlugin.success('清除成功')
},
// 将楼层装修的内容写入到本地缓存中
witeLocalStore(){
@@ -87,7 +88,7 @@ export default {
data.list.unshift(this.$refs.modelForm.navList);
data.list.unshift(this.$refs.modelForm.topAdvert);
this.setStore('managerPCPageCache', data)
this.$Message.success('写入成功')
MessagePlugin.success('写入成功')
},
saveTemplate() {
// 保存模板
@@ -109,7 +110,7 @@ export default {
API_floor.updateHome(this.$route.query.id, data).then((res) => {
this.submitLoading = false
if (res.success) {
this.$Message.success("保存模板成功");
MessagePlugin.success("保存模板成功");
}
});
},

View File

@@ -43,13 +43,12 @@
</div>
</div>
<div class="selectBtn">
<Button
<t-button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
theme="primary"
variant="outline"
>选择照片</t-button>
</div>
</div>
@@ -57,20 +56,19 @@
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<Button
ghost
type="primary"
<t-button
theme="primary"
variant="outline"
size="small"
@click="clickLink(item)"
>选择链接</Button
>
>选择链接</t-button>
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">当前页面状态</div>
<div>
<Tag :type="result.pageShow === 'OPEN' ? 'green' : 'red'">{{result.pageShow === 'OPEN' ? '开启' : '关闭'}}</Tag>
<t-tag :theme="result.pageShow === 'OPEN' ? 'success' : 'danger'">{{result.pageShow === 'OPEN' ? '开启' : '关闭'}}</t-tag>
</div>
</div>
</div>
@@ -79,9 +77,12 @@
<!-- <Button type="primary" @click="addDecorate()" ghost>添加</Button> -->
<liliDialog ref="liliDialog" @selectedLink="selectedLink" :types="linkType"></liliDialog>
</div>
<Modal width="1200px" v-model="picModelFlag">
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</div>
</template>

View File

@@ -43,13 +43,12 @@
</div>
</div>
<div class="selectBtn">
<Button
<t-button
size="small"
theme="primary"
variant="outline"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择链接</Button
>
>选择链接</t-button>
</div>
</div>
@@ -57,20 +56,19 @@
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<Button
ghost
type="primary"
<t-button
theme="primary"
variant="outline"
size="small"
@click="clickLink(item)"
>选择链接</Button
>
>选择链接</t-button>
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">当前页面状态</div>
<div>
<Tag :type="result.pageShow === 'OPEN' ? 'green' : 'red'">{{result.pageShow === 'OPEN' ? '开启' : '关闭'}}</Tag>
<t-tag :theme="result.pageShow === 'OPEN' ? 'success' : 'danger'">{{result.pageShow === 'OPEN' ? '开启' : '关闭'}}</t-tag>
</div>
</div>
</div>
@@ -82,9 +80,12 @@
:types="linkType"
></liliDialog>
</div>
<Modal width="1200px" v-model="picModelFlag">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</div>
</template>

View File

@@ -3,46 +3,44 @@
<div class="decorate-title">
{{ res.name }}
<Button
<t-button
style="margin-left: 20px"
size="small"
ghost
variant="outline"
v-if="
res.type == 'tpl_ad_list' ||
res.type == 'tpl_activity_list' ||
res.drawer
"
type="primary"
theme="primary"
@click="selectStyle()"
>选择风格</Button
>选择风格</t-button
>
<Button
<t-button
style="margin-left: 20px"
size="small"
ghost
variant="outline"
v-if="res.type == 'promotions' || res.drawerPromotions"
type="primary"
theme="primary"
@click="selectPromotions()"
>选择促销活动</Button
>选择促销活动</t-button
>
</div>
<Alert type="warning" v-if="res.name == '商品分类'"
>装修提示
<template slot="desc">
<div style="color: red">
如果当前装修模块不是最后一项模块且模块内容绑定为分类则会默认展示绑定分类的100条商品信息。
</div>
<div style="color: red">
如果当前装修模块是最后一项模块且模块内容绑定为分类,则会默认会根据绑定分类触底加载商品信息。
</div>
<div style="color: red">
如果当前装修内容不为分类,则会展示当前商品的静态信息。
</div>
</template>
</Alert>
<t-alert theme="warning" v-if="res.name == '商品分类'">
装修提示
<div style="color: red">
如果当前装修模块不是最后一项模块且模块内容绑定为分类则会默认展示绑定分类的100条商品信息。
</div>
<div style="color: red">
如果当前装修模块是最后一项模块且模块内容绑定为分类,则会默认会根据绑定分类触底加载商品信息。
</div>
<div style="color: red">
如果当前装修内容不为分类,则会展示当前商品的静态信息。
</div>
</t-alert>
<!-- 右侧显示抽屉 -->
<Drawer title="选择风格" :closable="false" width="400" v-model="styleFlag">
<t-drawer header="选择风格" :closeOnOverlayClick="false" size="400px" :visible.sync="styleFlag">
<div class="drawer">
<div
class="drawer-item"
@@ -55,14 +53,14 @@
<span>{{ item.name }}</span>
</div>
</div>
</Drawer>
</t-drawer>
<!-- 右侧显示抽屉 -->
<Drawer
title="选择促销活动(最多只能展示两个活动)"
:closable="false"
width="400"
v-model="promotionsFlag"
<t-drawer
header="选择促销活动(最多只能展示两个活动)"
:closeOnOverlayClick="false"
size="400px"
:visible.sync="promotionsFlag"
>
<div class="drawer">
<div
@@ -76,7 +74,7 @@
<span>{{ item.name }}</span>
</div>
</div>
</Drawer>
</t-drawer>
<!-- 卡片集合 -->
<div
@@ -96,12 +94,12 @@
>
<div class="decorate-item-title">
<div>卡片</div>
<Icon
<t-icon
@click="closeDecorate(index)"
v-if="res.close || res.type == 'promotionDetail'"
size="20"
color="#e1251b"
type="md-close-circle"
name="close-circle"
style="color:#e1251b"
/>
</div>
@@ -115,13 +113,13 @@
<div class="decorate-view">
<div class="decorate-view-title">标题{{ title_index + 1 }}</div>
<div>
<Input v-model="title_item.title" />
<t-input v-model="title_item.title" />
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">描述</div>
<div>
<Input v-model="title_item.desc" />
<t-input v-model="title_item.desc" />
</div>
</div>
<div class="decorate-view">
@@ -140,16 +138,18 @@
:key="bindGoodsIndex"
class="title-item wes-2"
>
<Tooltip max-width="200" placement="left">
<div slot="content" class="title-tooltip">
{{ bindGoods.title }}
</div>
<t-popup placement="left" trigger="hover">
<template #content>
<div class="title-tooltip">
{{ bindGoods.title }}
</div>
</template>
<div class="title-goodsName">
{{ bindGoods.title }}
</div>
</Tooltip>
</t-popup>
<div class="title-btn">
<Button
<t-button
@click="
slotGoods(
res.options.list[0].listWay,
@@ -160,7 +160,7 @@
"
style="margin-right: 10px"
size="small"
>上移</Button
>上移</t-button
>
</div>
</div>
@@ -172,31 +172,31 @@
</div>
<div class="decorate-view-btn">
<Button
<t-button
@click="bindGoodsId(title_item, title_index)"
size="small"
>选择商品</Button
>选择商品</t-button
>
<Button
<t-button
@click="bindGoodsCategory(title_index)"
size="small"
style="margin-top: 20px"
>选择分类</Button
>选择分类</t-button
>
</div>
</div>
</div>
<div class="decorate-view" v-if="res.type == 'carousel'">
<div class="decorate-view-title">
<Button
<t-button
@click="slotBanner(res, item, index, 'up')"
style="margin-right: 10px"
size="small"
>上移</Button
><Button
>上移</t-button
><t-button
@click="slotBanner(res, item, index, 'down')"
size="small"
>下移</Button
>下移</t-button
>
</div>
</div>
@@ -212,12 +212,12 @@
</div>
</div>
<div class="selectBtn">
<Button
<t-button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
variant="outline"
theme="primary"
>选择照片</t-button
>
</div>
</div>
@@ -274,8 +274,8 @@
>
<div class="decorate-view-title">背景颜色</div>
<div class="decorate-view">
<ColorPicker v-model="item.bk_color" />
<Input v-model="item.bk_color" />
<t-color-picker v-model="item.bk_color" />
<t-input v-model="item.bk_color" />
</div>
</div>
<div
@@ -284,15 +284,15 @@
>
<div class="decorate-view-title">方向</div>
<div class="decorate-view">
<Select
<t-select
style="width: 200px"
@on-change="changeDirection($event, item)"
@change="changeDirection($event, item)"
v-model="item.direction"
>
{{ item.direction }}
<Option label="横向" value="horizontal"></Option>
<Option label="纵向" value="vertical"></Option>
</Select>
<t-option label="横向" value="horizontal"></t-option>
<t-option label="纵向" value="vertical"></t-option>
</t-select>
</div>
</div>
@@ -303,7 +303,7 @@
>
<div class="decorate-view-title">菜单标题</div>
<div>
<Input v-model="item.title" style="width: 200px" />
<t-input v-model="item.title" style="width: 200px" />
</div>
</div>
<div
@@ -316,8 +316,8 @@
>
<div class="decorate-view-title">标题颜色</div>
<div class="decorate-view">
<ColorPicker v-model="item.color" />
<Input v-model="item.color" />
<t-color-picker v-model="item.color" />
<t-input v-model="item.color" />
</div>
</div>
<!-- 填写小标题 -->
@@ -327,7 +327,7 @@
>
<div class="decorate-view-title">小标题</div>
<div>
<Input v-model="item.title1" style="width: 200px" />
<t-input v-model="item.title1" style="width: 200px" />
</div>
</div>
<div
@@ -336,8 +336,8 @@
>
<div class="decorate-view-title">小标题颜色</div>
<div class="decorate-view">
<ColorPicker v-model="item.color1" />
<Input v-model="item.color1" />
<t-color-picker v-model="item.color1" />
<t-input v-model="item.color1" />
</div>
</div>
<div
@@ -351,11 +351,11 @@
:key="tindex"
class="decorate-notice"
>
<Input v-model="t.context" style="width: 200px" />
<Icon
<t-input v-model="t.context" style="width: 200px" />
<t-icon
@click="removeNotice(tindex)"
size="16"
type="md-close-circle"
name="close-circle"
/>
</div>
</div>
@@ -367,10 +367,10 @@
<div class="decorate-view-title">选择模式</div>
<div>
<RadioGroup v-model="item.model" type="button">
<Radio value="link" label="link">链接</Radio>
<Radio value="hotzone" label="hotzone">热区</Radio>
</RadioGroup>
<t-radio-group v-model="item.model">
<t-radio value="link">链接</t-radio>
<t-radio value="hotzone">热区</t-radio>
</t-radio-group>
</div>
</div>
@@ -430,13 +430,13 @@
</span>
</div>
<div>
<Button
ghost
<t-button
variant="outline"
size="small"
type="primary"
theme="primary"
@click="clickLink(item, index, res)"
>
{{ item.model === "hotzone" ? "绘制热区" : "选择链接" }}</Button
{{ item.model === "hotzone" ? "绘制热区" : "选择链接" }}</t-button
>
</div>
</div>
@@ -451,7 +451,7 @@
>
<div class="decorate-view-title">外部链接</div>
<div>
<Input v-model="item.url.url" style="width: 200px" />
<t-input v-model="item.url.url" style="width: 200px" />
</div>
</div>
@@ -468,17 +468,17 @@
</div>
</div>
<Button
<t-button
v-if="
res.type != 'tpl_ad_list' &&
res.type != 'tpl_activity_list' &&
!res.notAdd &&
res.direction != 'horizontal'
"
type="primary"
theme="primary"
@click="addDecorate(res.type, res)"
ghost
>添加</Button
variant="outline"
>添加</t-button
>
<liliDialog
@@ -487,18 +487,21 @@
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<Modal width="800px" title="选择分类" v-model="enableSelectCategory">
<t-dialog :width="800" header="选择分类" :visible.sync="enableSelectCategory" @close="enableSelectCategory=false">
<categoryTemplate
v-if="enableSelectCategory"
@selected="confirmCategory"
/>
</Modal>
</t-dialog>
<hotzone ref="hotzone" @changeZone="changeZone"></hotzone>
<Modal width="1200px" v-model="picModelFlag">
<t-dialog :width="1200" :visible.sync="picModelFlag" header="选择图片" @close="picModelFlag=false">
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
</Modal>
<template #footer>
<t-button variant="text" @click="picModelFlag=false">关闭</t-button>
</template>
</t-dialog>
</div>
</template>
<script>

View File

@@ -48,13 +48,13 @@
:is="templates[element.type]"
:res="element.options"
></component>
<Icon
<t-icon
v-if="selected == index"
@click="closeComponent(index)"
color="#e1251b"
style="color:#e1251b"
size="25"
class="close"
type="ios-close-circle"
name="close-circle"
/>
</div>
</draggable>
@@ -79,6 +79,7 @@ import { modelData } from "./config";
import decorate from "./decorate";
import * as API_Other from "@/api/other";
import * as API_Promotions from "@/api/promotion";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
components: {
Draggable,
@@ -115,19 +116,19 @@ export default {
init() {
// 先读缓存,如果缓存有值则读缓存。
const cache = this.getStore('managerMobilePageCache')
if(cache){
this.$Modal.confirm({
title: '提示',
if (cache) {
DialogPlugin.confirm({
header: '提示',
content: '获取到本地有缓存数据,是否使用缓存数据?',
okText: '使用',
cancelText: '取消',
onOk: () => {
theme: 'warning',
confirmBtn: '使用',
cancelBtn: '取消',
onConfirm: () => {
const data = JSON.parse(cache);
this.contentData = data;
}
});
}
}
if (!this.$route.query.id) return false;
API_Other.getHomeData(this.$route.query.id).then((res) => {
@@ -176,7 +177,7 @@ export default {
let newIndex = this.selected;
if (val.promotionsType) {
if (this.contentData.list[newIndex].options.list.length >= 2) {
this.$Message.error("最多只能展示两个活动");
MessagePlugin.error("最多只能展示两个活动");
return;
}
if (val.promotionsType === "LIVE") {

View File

@@ -3,13 +3,13 @@
<div class="model-title">
<div>店铺装修</div>
<div class="btns">
<Button
<t-button
@click="clickBtn(item)"
size="small"
v-for="(item, index) in way"
:key="index"
:type="item.selected ? 'primary' : ''"
>{{ item.title }}</Button>
:theme="item.selected ? 'primary' : 'default'"
>{{ item.title }}</t-button>
</div>
<div class="model-title-view-btn">
<!-- TODO 后期会补全 目前版本暂无 -->
@@ -20,42 +20,39 @@
<div ref="qrCodeUrl"></div>
</div>
</Poptip>-->
<Button size="default" type="default" v-if="hasCache" @click="clearCache">清空本地缓存</Button>
<Button size="default" type="primary" @click="handleSpinShow">保存模板</Button>
<t-button size="medium" variant="outline" v-if="hasCache" @click="clearCache">清空本地缓存</t-button>
<t-button size="medium" theme="primary" @click="handleSpinShow">保存模板</t-button>
<Modal
title="保存中"
v-model="saveDialog"
:closable="true"
:mask-closable="false"
:footer-hide="true"
<t-dialog
header="保存中"
:visible.sync="saveDialog"
:closeOnOverlayClick="false"
:footer="false"
>
<div v-if="progress">
<div class="model-item">
模板名称
<Input style="width: 200px" v-model="submitWay.name"/>
<t-input style="width: 200px" v-model="submitWay.name"/>
</div>
<div class="model-item">
是否立即发布
<i-switch v-model="submitWay.pageShow">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
<t-switch v-model="submitWay.pageShow"/>
</div>
<div class="model-item">
将当前装修内容写入到本地缓存中下次进入页面时可继续使用
<Button type="small" @click="witeLocalStore">写入</Button>
<t-button size="small" @click="witeLocalStore">写入</t-button>
</div>
<Button type="primary" @click="save()">保存</Button>
<t-button theme="primary" @click="save()">保存</t-button>
</div>
<Progress v-else :percent="num" status="active"/>
</Modal>
<t-progress v-else :percentage="num"/>
</t-dialog>
</div>
</div>
</template>
<script>
import * as API_Other from "@/api/other.js";
import { MessagePlugin } from "tdesign-vue";
export default {
props: ["pagetype"],
@@ -115,12 +112,12 @@ export default {
methods: {
clearCache(){
this.setStore('managerMobilePageCache','');
this.$Message.success('清空成功')
MessagePlugin.success('清空成功')
},
// 将楼层装修的内容写入到本地缓存中
witeLocalStore(){
this.setStore('managerMobilePageCache', this.$store.state.styleStore)
this.$Message.success('写入成功')
MessagePlugin.success('写入成功')
},
clickBtn(val) {
@@ -144,7 +141,7 @@ export default {
this.$store.state.styleStore == void 0 &&
(this.$route.query.pagetype && this.$route.query.pagetype != 'ALERT' && this.$route.query.pagetype != 'OPEN_SCREEN_ANIMATION')
) {
this.$Message.error("请装修楼层");
MessagePlugin.error("请装修楼层");
return false;
}
@@ -183,12 +180,12 @@ export default {
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("修改成功");
MessagePlugin.success("修改成功");
this.goBack();
}, 1000);
} else {
this.saveDialog = false;
this.$Message.error("修改失败,请稍后重试");
MessagePlugin.error("修改失败,请稍后重试");
}
console.log(res);
})
@@ -200,7 +197,7 @@ export default {
update(submitWay) {
console.log(this.$store.state.openStyleStore[0], "123123123");
if (this.$store.state.openStyleStore == void 0) {
this.$Message.error("请装修楼层!");
MessagePlugin.error("请装修楼层!");
return false;
}
this.progress = false;
@@ -230,12 +227,12 @@ export default {
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("修改成功");
MessagePlugin.success("修改成功");
this.goBack();
}, 1000);
} else {
this.saveDialog = false;
this.$Message.error("修改失败,请稍后重试");
MessagePlugin.error("修改失败,请稍后重试");
}
console.log(res);
})
@@ -260,13 +257,13 @@ export default {
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("保存成功");
MessagePlugin.success("保存成功");
this.goBack();
}, 1000);
} else {
this.progress = true;
this.saveDialog = false;
this.$Message.error("保存失败,请稍后重试");
MessagePlugin.error("保存失败,请稍后重试");
}
console.log(res);
})

View File

@@ -1,12 +1,12 @@
<template>
<div class="layout">
<Carousel class="carousel" v-if="res" autoplay :autoplay-speed="5000">
<CarouselItem v-for="(item, index) in res.list" :key="index">
<t-swiper class="carousel" v-if="res" autoplay :interval="5000">
<t-swiper-item v-for="(item, index) in res.list" :key="index">
<div>
<img class="image-mode" :src="item.img" />
</div>
</CarouselItem>
</Carousel>
</t-swiper-item>
</t-swiper>
</div>
</template>
<script>
@@ -29,4 +29,4 @@ export default {
.image-mode {
height: 150px;
}
</style>
</style>

View File

@@ -24,12 +24,12 @@
:key="item_index"
>
<div class="goods-img">
<Icon
<t-icon
size="20"
color="#e1251b"
name="close-circle"
style="color:#e1251b"
@click="closeGoods(item, item_index)"
class="goods-icon"
type="ios-close-circle"
/>
<img :src="item.img" alt />
</div>

View File

@@ -1,7 +1,7 @@
<template>
<div class="layout">
<div class="search">
<Icon type="ios-search" />{{res.list[0].title}}
<t-icon name="search" />{{res.list[0].title}}
</div>
</div>
</template>
@@ -23,4 +23,4 @@ export default {
.layout{
background: #fff;
}
</style>
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="wrapper">
<Card class="category">
<t-card class="category">
<div
:class="{ active: i == selectedIndex }"
class="category-item"
@@ -9,11 +9,11 @@
>
<div @click="clickType(typeItem.type, i)">{{ typeItem.title }}</div>
</div>
</Card>
<Card class="content">
<Button type="primary" @click="handleAdd()">添加页面</Button>
</t-card>
<t-card class="content">
<t-button theme="primary" @click="handleAdd()">添加页面</t-button>
<div class="list">
<Spin size="large" fix v-if="loading"></Spin>
<t-loading size="large" v-if="loading"></t-loading>
<div class="item item-title">
<div>页面名称</div>
<div class="item-config">
@@ -25,29 +25,26 @@
<div class="item" v-for="(item, index) in list" :key="index">
<div>{{ item.name || "暂无模板昵称" }}</div>
<div class="item-config">
<i-switch v-model="item.pageShow" @on-change="changeSwitch(item)">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
<Button type="info" placement="right" @click="handleEdit(item)" size="small">修改</Button>
<Poptip confirm title="删除此模板?" @on-ok="handleDel(item)">
<Button type="error" size="small">删除</Button>
</Poptip>
<t-switch v-model="item.pageShow" @change="changeSwitch(item)"></t-switch>
<t-button theme="primary" variant="outline" @click="handleEdit(item)" size="small">修改</t-button>
<t-popconfirm content="删除此模板?" @confirm="handleDel(item)">
<t-button theme="danger" size="small">删除</t-button>
</t-popconfirm>
</div>
</div>
<div class="no-more" v-if="list.length ==0">暂无更多模板</div>
</div>
<Page
<t-pagination
:total="total"
size="small"
@on-change="changePageNum"
:current="params.pageNumber"
:page-size="params.pageSize"
show-sizer
:page-size-opts="[20, 50, 100]"
@on-page-size-change="changePageSize"
:pageSize="params.pageSize"
:pageSizeOptions="[20, 50, 100]"
size="small"
showJumper
showPageSize
@change="onPaginationChange"
/>
</Card>
</t-card>
</div>
</template>
<script>
@@ -202,6 +199,13 @@ export default {
this.params.pageSize = v;
this.init();
},
onPaginationChange(p) {
if (p && typeof p === 'object') {
this.params.pageNumber = p.current;
this.params.pageSize = p.pageSize;
}
this.init();
},
// 删除模板
handleDel(val) {
this.loading = true;

View File

@@ -1,10 +1,8 @@
<template>
<div>
<Card>
<t-card>
<div class="operation mb_10">
<Button @click="addParent" type="primary" icon="md-add"
>添加一级分类</Button
>
<t-button theme="primary" @click="addParent">添加一级分类</t-button>
</div>
<tree-table
ref="treeTable"
@@ -19,64 +17,34 @@
primary-key="id"
>
<template slot="action" slot-scope="scope">
<a
style="color:#2d8cf0;cursor:pointer;text-decoration:none;margin-right:5px"
@click="edit(scope.row)"
>编辑</a>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none;margin-right:5px" @click="edit(scope.row)">编辑</a>
<span style="margin:0 8px;color:#dcdee2">|</span>
<a
style="color:#2d8cf0;cursor:pointer;text-decoration:none;margin-right:5px"
@click="remove(scope.row)"
>删除</a>
<a style="color:#2d8cf0;cursor:pointer;text-decoration:none;margin-right:5px" @click="remove(scope.row)">删除</a>
<span v-show="scope.row.level != 1" style="margin:0 8px;color:#dcdee2">|</span>
<a
v-show="scope.row.level != 1"
style="color:#2d8cf0;cursor:pointer;text-decoration:none"
@click="addChildren(scope.row)"
>添加子分类</a>
<a v-show="scope.row.level != 1" style="color:#2d8cf0;cursor:pointer;text-decoration:none" @click="addChildren(scope.row)">添加子分类</a>
</template>
</tree-table>
</Card>
<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">
</t-card>
<t-drawer :visible.sync="modalVisible" :header="modalTitle" placement="right" size="500px" @close="modalVisible = false">
<t-form ref="form" :data="formAdd" :labelWidth="100" :rules="formValidate">
<div v-if="showParent" class="parent-field">
<t-form-item label="上级分类" name="parentId">
{{ parentTitle }}
<Input
v-model="formAdd.parentId"
clearable
style="width: 100%; display: none"
/>
</FormItem>
<t-input v-model="formAdd.parentId" clearable style="width: 100%; display: none" />
</t-form-item>
</div>
<FormItem label="分类名称" prop="articleCategoryName">
<Input
v-model="formAdd.articleCategoryName"
clearable
style="width: 100%"
/>
</FormItem>
<FormItem label="排序值" prop="sort">
<InputNumber v-model="formAdd.sort"></InputNumber>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="Submit"
>提交</Button
>
</div>
</Modal>
<t-form-item label="分类名称" name="articleCategoryName">
<t-input v-model="formAdd.articleCategoryName" clearable style="width: 100%" />
</t-form-item>
<t-form-item label="排序值" name="sort">
<t-input-number v-model="formAdd.sort" :min="0" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="Submit">提交</t-button>
</template>
</t-drawer>
</div>
</template>
<script>
@@ -89,6 +57,7 @@ import {
import TreeTable from "@/components/tree-table/Table/Table";
import uploadPicInput from "@/components/lili/upload-pic-input";
import { regular } from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "lili-components",
components: {
@@ -176,7 +145,7 @@ export default {
this.modalTitle = "添加一级分类";
this.parentTitle = "顶级分类";
this.showParent = true;
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
delete this.formAdd.id;
this.formAdd.parentId = 0;
this.modalVisible = true;
@@ -192,7 +161,7 @@ export default {
saveArticleCategory(this.formAdd).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("添加成功");
MessagePlugin.success("添加成功");
this.formAdd = {
// 添加或编辑表单对象初始化数据
@@ -202,7 +171,7 @@ export default {
articleCategoryName: "",
};
} else {
// this.$Message.error(res.message);
}
this.getAllList();
this.modalVisible = false;
@@ -212,13 +181,13 @@ export default {
updateArticleCategory(this.formAdd, this.formAdd.id).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("修改成功");
MessagePlugin.success("修改成功");
} else {
// this.$Message.error(res.message);
}
this.getAllList();
this.modalVisible = false;
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
});
}
}
@@ -226,16 +195,15 @@ export default {
},
// 删除分类
remove(v) {
this.$Modal.confirm({
title: "确认删除",
const dlg = DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除 " + v.articleCategoryName + " ?",
loading: true,
onOk: () => {
// 删除
theme: "warning",
onConfirm: () => {
delArticleCategory(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
dlg.hide();
this.getAllList();
}
});
@@ -323,4 +291,7 @@ export default {
font-weight: 400;
margin: 12px 0;
}
.parent-field {
margin-bottom: 16px;
}
</style>

View File

@@ -1,47 +1,39 @@
<template>
<div class="search">
<Card>
<Row class="operation">
<Button @click="add()" type="primary">设置今日热词</Button>
</Row>
<Row>
<t-card>
<div class="operation">
<t-button @click="add()" theme="primary">设置今日热词</t-button>
</div>
<div>
<p>
<Alert type="success">
<t-alert theme="success">
这里展示今日系统中搜索前一百的搜索热词分数为热词在排序系统中的分数分数越高可以在用户获取热词时进行优先展示首页商品搜索栏下方推荐位分数可以填写负数会降低推荐度
</Alert>
</t-alert>
</p>
</Row>
</div>
<div class="card-list">
<Card v-for="words in data" class="card-item" :key="words" onclick="">
<p>
<a href="#" slot="extra" @click.prevent="add(words)">{{ words }}</a>
</p>
<p slot="extra">
<a @click="deleteWords(words)">
<Icon type="md-close"/>
</a>
</p>
</Card>
<t-card v-for="words in data" class="card-item" :key="words">
<div style="display:flex;justify-content:space-between;align-items:center">
<a href="#" @click.prevent="add(words)">{{ words }}</a>
<a @click="deleteWords(words)">删除</a>
</div>
</t-card>
</div>
</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="keywords">
<Input v-model="form.keywords" clearable style="width: 100%"/>
</FormItem>
<FormItem label="分数" prop="point">
<Input v-model="form.point" clearable style="width: 100%"/>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交
</Button
>
</div>
</Modal>
</t-card>
<t-dialog :visible="modalVisible" :header="modalTitle" :mask-closable="false" :width="500" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100" :rules="formValidate">
<t-form-item label="热词" name="keywords">
<t-input v-model="form.keywords" clearable style="width: 100%" />
</t-form-item>
<t-form-item label="分数" name="point">
<t-input v-model="form.point" clearable style="width: 100%" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -49,6 +41,7 @@
import {getHotWords, setHotWords, deleteHotWords} from "@/api/index";
import {regular} from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "hotWords",
@@ -93,7 +86,7 @@ export default {
setHotWords(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -114,16 +107,16 @@ export default {
this.modalVisible = true;
},
deleteWords(words) {
this.$Modal.confirm({
title: "是否确定删除热词",
content: "<p>您确定要删除此热词吗?</p>",
okText: "确实",
cancelText: "取消",
onOk: () => {
const dlg = DialogPlugin.confirm({
header: "是否确定删除热词",
content: "您确定要删除此热词吗?",
theme: "warning",
onConfirm: () => {
let params = {words: words}
deleteHotWords(params).then((res) => {
if (res.success) {
this.$Message.success("删除成功");
MessagePlugin.success("删除成功");
dlg.hide();
this.getDataList();
}
});

View File

@@ -1,47 +1,39 @@
<template>
<div class="search">
<Card>
<Row class="operation">
<Button @click="add()" type="primary">设置今日热词</Button>
</Row>
<Row>
<t-card>
<div class="operation">
<t-button @click="add()" theme="primary">设置今日热词</t-button>
</div>
<div>
<p>
<Alert type="success">
<t-alert theme="success">
这里展示今日系统中搜索前一百的搜索热词分数为热词在排序系统中的分数分数越高可以在用户获取热词时进行优先展示首页商品搜索栏下方推荐位分数可以填写负数会降低推荐度
</Alert>
</t-alert>
</p>
</Row>
</div>
<div class="card-list">
<Card v-for="words in data" class="card-item" :key="words" onclick="">
<p>
<a href="#" slot="extra" @click.prevent="add(words)">{{ words }}</a>
</p>
<p slot="extra">
<a @click="deleteWords(words)">
<Icon type="md-close"/>
</a>
</p>
</Card>
<t-card v-for="words in data" class="card-item" :key="words">
<div style="display:flex;justify-content:space-between;align-items:center">
<a href="#" @click.prevent="add(words)">{{ words }}</a>
<a @click="deleteWords(words)">删除</a>
</div>
</t-card>
</div>
</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="keywords">
<Input v-model="form.keywords" clearable style="width: 100%"/>
</FormItem>
<FormItem label="分数" prop="point">
<Input v-model="form.point" clearable style="width: 100%"/>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="modalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="handleSubmit"
>提交
</Button
>
</div>
</Modal>
</t-card>
<t-dialog :visible="modalVisible" :header="modalTitle" :mask-closable="false" :width="500" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100" :rules="formValidate">
<t-form-item label="热词" name="keywords">
<t-input v-model="form.keywords" clearable style="width: 100%" />
</t-form-item>
<t-form-item label="分数" name="point">
<t-input v-model="form.point" clearable style="width: 100%" />
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-dialog>
</div>
</template>
@@ -49,6 +41,7 @@
import {getHotWords, setHotWords, deleteHotWords} from "@/api/index";
import {regular} from "@/utils";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
name: "hotWords",
@@ -93,7 +86,7 @@ export default {
setHotWords(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -114,16 +107,16 @@ export default {
this.modalVisible = true;
},
deleteWords(words) {
this.$Modal.confirm({
title: "是否确定删除热词",
content: "<p>您确定要删除此热词吗?</p>",
okText: "确实",
cancelText: "取消",
onOk: () => {
const dlg = DialogPlugin.confirm({
header: "是否确定删除热词",
content: "您确定要删除此热词吗?",
theme: "warning",
onConfirm: () => {
let params = {words: words}
deleteHotWords(params).then((res) => {
if (res.success) {
this.$Message.success("删除成功");
MessagePlugin.success("删除成功");
dlg.hide();
this.getDataList();
}
});

View File

@@ -1,33 +1,27 @@
<template>
<div class="layout">
<Form ref="formValidate" :label-width="150" label-position="right" :model="formValidate" :rules="ruleValidate">
<FormItem class="label-item" v-for="(point,index) in formValidate.pointSettingItems" :key="index"
:label="'签到设置'+(index+1)">
<t-form ref="formValidate" :labelWidth="150" layout="vertical" :data="formValidate" :rules="ruleValidate">
<t-form-item class="label-item" v-for="(point,index) in formValidate.pointSettingItems" :key="index" :label="'签到设置'+(index+1)">
<div class="label-item">
<InputNumber :min="1" v-model="point.day"></InputNumber>
<InputNumber :min="0" v-model="point.point"></InputNumber>
<Button ghost type="error" @click="delSign(point,index)">删除</Button>
<span class="ml_10">签到<span class="theme_color">{{ point.day }}</span>赠送<span
class="theme_color">{{ point.point }}</span>积分</span>
<t-input-number :min="1" v-model="point.day" style="width: 100px; margin-right: 5px" />
<t-input-number :min="0" v-model="point.point" style="width: 150px; margin-right: 5px" />
<t-button variant="outline" theme="danger" @click="delSign(point,index)">删除</t-button>
<span class="ml_10">签到<span class="theme_color">{{ point.day }}</span>赠送<span class="theme_color">{{ point.point }}</span>积分</span>
</div>
</FormItem>
<FormItem label="操作:">
<Button @click="addSign">新增签到</Button>
</FormItem>
</t-form-item>
<t-form-item label="操作:">
<t-button @click="addSign">新增签到</t-button>
</t-form-item>
<div class="label-btns">
<Button type="primary" @click="submit('formValidate')">保存</Button>
<t-button theme="primary" @click="submit('formValidate')">保存</t-button>
</div>
</Form>
</t-form>
</div>
</template>
<script>
import {setSetting} from "@/api/index";
import { MessagePlugin } from "tdesign-vue";
export default {
data() {
@@ -49,9 +43,9 @@ export default {
setupSetting() {
setSetting(this.type, this.formValidate).then((res) => {
if (res.success) {
this.$Message.success("保存成功!");
MessagePlugin.success("保存成功!");
} else {
this.$Message.error("保存失败!");
MessagePlugin.error("保存失败!");
}
});
},
@@ -60,9 +54,7 @@ export default {
},
addSign() {
if (this.formValidate.pointSettingItems.length >= 5) {
this.$Message.error({
content: "最多设置5项签到设置",
});
MessagePlugin.error("最多设置5项签到设置");
return false;
}
this.formValidate.pointSettingItems.push({

View File

@@ -1,137 +1,68 @@
<template>
<div class="wrapper">
<Row>
<Col style="height: 100%" span="4">
<Card class="article-category mr_10">
<Tree :data="treeData" @on-select-change="handleCateChange"></Tree>
</Card>
</Col>
<Col span="20">
<Card class="article-detail">
<Row @keydown.enter.native="handleSearch">
<Form
ref="searchForm"
:model="searchForm"
inline
:label-width="70"
style="width: 100%"
class="search-form"
>
<Form-item label="文章标题" prop="title">
<Input
type="text"
v-model="searchForm.title"
placeholder="请输入文章标题"
clearable
style="width: 200px"
/>
</Form-item>
<Button
@click="handleSearch"
type="primary"
icon="ios-search"
class="search-btn"
>搜索</Button
>
</Form>
</Row>
<Row class="operation padding-row">
<Button @click="add" v-if="!selected" type="primary">添加</Button>
</Row>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
ref="table"
>
<!-- 页面展示 -->
<template slot="openStatusSlot" slot-scope="scope">
<div></div>
<i-switch
size="large"
v-model="scope.row.openStatus"
@on-change="changeSwitch(scope.row)"
>
<span slot="open">展示</span>
<span slot="close">隐藏</span>
</i-switch>
<div style="display:flex;gap:12px">
<div style="width: 25%;height: 100%">
<t-card class="article-category mr_10">
<t-tree :data="treeData" hover @click="handleCateChange"></t-tree>
</t-card>
</div>
<div style="flex:1">
<t-card class="article-detail">
<div @keydown.enter="handleSearch">
<t-form ref="searchForm" :data="searchForm" layout="inline" :labelWidth="70" style="width: 100%" class="search-form" @submit="handleSearch">
<t-form-item label="文章标题" name="title">
<t-input v-model="searchForm.title" placeholder="请输入文章标题" clearable style="width: 200px" />
</t-form-item>
<t-form-item>
<t-button theme="primary" class="search-btn" @click="handleSearch">搜索</t-button>
</t-form-item>
</t-form>
</div>
<div class="operation padding-row">
<t-button @click="add" v-if="!selected" theme="primary">添加</t-button>
</div>
<t-table :loading="loading" :columns="columns" :data="data" ref="table" rowKey="id">
<template #openStatusSlot="{ row }">
<t-switch v-model="row.openStatus" @change="changeSwitch(row)"></t-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
>
</Page>
</Row>
</Card>
</Col>
</Row>
<template #action="{ row, rowIndex }">
<a :style="{ color: '#2d8cf0', cursor: 'pointer', textDecoration: 'none', marginRight: '5px', display: selected ? '' : 'none' }" @click="selectedIndex = rowIndex; $emit('callbacked', row)">{{ selectedIndex == rowIndex ? '已选' : '选择' }}</a>
<span style="margin: 0 8px; color: #dcdee2">|</span>
<a :style="{ color: '#2d8cf0', cursor: 'pointer', textDecoration: 'none', marginRight: '5px' }" @click="edit(row)">编辑</a>
<span style="margin: 0 8px; color: #dcdee2">|</span>
<a :style="{ color: '#2d8cf0', cursor: 'pointer', textDecoration: 'none' }" @click="remove(row)">删除</a>
</template>
</t-table>
<div class="mt_10" style="display:flex;justify-content:flex-end;width:100%">
<t-pagination :current="searchForm.pageNumber" :total="Number(total)" :pageSize="searchForm.pageSize" :pageSizeOptions="[20, 50, 100]" size="small" :showJumper="true" @change="onPaginationChange" />
</div>
</t-card>
</div>
</div>
<template v-if="!selected">
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="1100"
>
<Form ref="form" :model="form" :label-width="100">
<FormItem label="文章标题" prop="title">
<Input v-model="form.title" clearable style="width: 40%" />
</FormItem>
<FormItem label="文章分类" prop="categoryId">
<Select
v-model="treeValue"
placeholder="请选择"
clearable
style="width: 180px"
>
<Option v-if="treeValue" :value="treeValue" style="display: none"
>{{ treeValue }}
</Option>
<Tree
:data="treeDataDefault"
@on-select-change="handleCheckChange"
></Tree>
</Select>
</FormItem>
<FormItem label="文章排序" prop="sort">
<Input
type="number"
v-model="form.sort"
clearable
style="width: 10%"
/>
</FormItem>
<FormItem class="form-item-view-el" label="文章内容" prop="content">
<tinymec
ref="editor"
openXss
v-model="form.content"
v-if="modalVisible"
></tinymec>
</FormItem>
<FormItem label="是否展示" prop="openStatus">
<i-switch size="large" v-model="form.openStatus">
<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
>
</div>
</Modal>
<t-drawer :visible.sync="modalVisible" :header="modalTitle" placement="right" size="900px" @close="modalVisible = false">
<t-form ref="form" :data="form" :labelWidth="100">
<t-form-item label="文章标题" name="title">
<t-input v-model="form.title" clearable style="width: 40%" />
</t-form-item>
<t-form-item label="文章分类" name="categoryId">
<t-tree-select v-model="form.categoryId" :data="treeDataDefault" style="width: 240px" />
</t-form-item>
<t-form-item label="文章排序" name="sort">
<t-input-number v-model="form.sort" :min="0" style="width: 120px" />
</t-form-item>
<t-form-item class="form-item-view-el" label="文章内容" name="content">
<tinymec ref="editor" openXss v-model="form.content" v-if="modalVisible"></tinymec>
</t-form-item>
<t-form-item label="是否展示" name="openStatus">
<t-switch v-model="form.openStatus"></t-switch>
</t-form-item>
</t-form>
<template #footer>
<t-button variant="text" @click="modalVisible = false">取消</t-button>
<t-button theme="primary" :loading="submitLoading" @click="handleSubmit">提交</t-button>
</template>
</t-drawer>
</template>
</div>
</template>
@@ -147,6 +78,7 @@ import {
updateArticleStatus,
} from "@/api/pages";
import tinymec from "@/components/editor/index.vue";
import { MessagePlugin, DialogPlugin } from "tdesign-vue";
export default {
components: {
tinymec: tinymec,
@@ -189,102 +121,11 @@ export default {
treeData: [],
submitLoading: false, // 添加或编辑提交状态
columns: [
// 表头
{
title: "分类名称",
key: "articleCategoryName",
width: 150,
},
{
title: "文章标题",
key: "title",
minWidth: 200,
tooltip: true,
},
{
title: "是否显示",
key: "openStatus",
width: 100,
slot: "openStatusSlot",
},
{
title: "排序",
key: "sort",
width: 100,
},
{
title: "操作",
key: "action",
align: "center",
width: 230,
render: (h, params) => {
return h("div", [
h(
"a",
{
style: {
color: "#2d8cf0",
cursor: "pointer",
textDecoration: "none",
marginRight: "5px",
display: this.selected ? "" : "none",
},
on: {
click: () => {
this.selectedIndex = params.index;
this.$emit("callbacked", params.row);
},
},
},
this.selectedIndex == params.index ? "已选" : "选择"
),
h(
"span",
{ style: { margin: "0 8px", color: "#dcdee2" } },
"|"
),
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);
},
},
},
"删除"
),
]);
},
},
{ title: "分类名称", colKey: "articleCategoryName", width: 150 },
{ title: "文章标题", colKey: "title", minWidth: 200, ellipsis: true },
{ title: "是否显示", colKey: "openStatus", width: 100 },
{ title: "排序", colKey: "sort", width: 100 },
{ title: "操作", colKey: "action", align: "center", width: 230 },
],
data: [], // 表单数据
total: 0, // 表单数据总数
@@ -311,14 +152,15 @@ export default {
this.getAllList(0);
},
// 选择分类回调
handleCateChange(data) {
let { value, title } = data[0];
this.list.push({
value,
title,
});
this.searchForm.categoryId = value;
this.searchTreeValue = title;
handleCateChange(ctx) {
const node = ctx && ctx.node ? ctx.node : ctx;
const value = node && (node.value || node.id);
const title = node && (node.label || node.title);
if (value !== undefined) {
this.list.push({ value, title });
this.searchForm.categoryId = value;
this.searchTreeValue = title;
}
},
//是否展示文章
changeSwitch(v) {
@@ -350,14 +192,9 @@ export default {
this.treeValue = title;
},
// 改变页数
changePage(v) {
this.searchForm.pageNumber = v;
this.getDataList();
},
// 改变页码
changePageSize(v) {
this.selected.pageNumber = 1;
this.searchForm.pageSize = v;
onPaginationChange({ current, pageSize }) {
this.searchForm.pageNumber = current;
this.searchForm.pageSize = pageSize;
this.getDataList();
},
// 搜索列表
@@ -376,6 +213,7 @@ export default {
this.treeDataDefault = this.getTree(res.result);
this.treeData.unshift({
title: "全部",
label: "全部",
level: 0,
children: [],
id: "0",
@@ -391,11 +229,12 @@ export default {
tree.forEach((item) => {
let obj = {};
obj.title = item.articleCategoryName;
obj.label = item.articleCategoryName;
obj.value = item.id;
obj.attr = item.articleCategoryName; // 其他你想要添加的属性
obj.attr = item.articleCategoryName;
obj.expand = false;
obj.selected = false;
obj.children = this.getTree(item.children); // 递归调用
obj.children = this.getTree(item.children);
arr.push(obj);
});
}
@@ -430,7 +269,7 @@ export default {
saveArticle(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -440,7 +279,7 @@ export default {
updateArticle(this.form).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
this.getDataList();
this.modalVisible = false;
}
@@ -459,7 +298,7 @@ export default {
sort: 1,
content: "",
};
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
delete this.form.id;
this.modalVisible = true;
},
@@ -471,7 +310,7 @@ export default {
this.form = {
content: "",
};
this.$refs.form.resetFields();
if (this.$refs.form && typeof this.$refs.form.reset === 'function') { this.$refs.form.reset(); }
seeArticle(data.id).then((res) => {
if (res.result) {
@@ -488,16 +327,15 @@ export default {
},
// 删除文章
remove(v) {
this.$Modal.confirm({
title: "确认删除",
const dlg = DialogPlugin.confirm({
header: "确认删除",
content: "您确认要删除么?",
loading: true,
onOk: () => {
// 删除
theme: "warning",
onConfirm: () => {
delArticle(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
MessagePlugin.success("操作成功");
dlg.hide();
this.getDataList();
}
});

View File

@@ -1,17 +1,14 @@
<template>
<div class="search">
<Card>
<Tabs @on-click="handleClickTab">
<TabPane
v-for="(item, index) in templatesWay"
:key="index"
:name="item.template"
:label="item.label"
>
<components v-if="item.template == currentTemplate" :is="currentTemplate"></components>
</TabPane>
</Tabs>
</Card>
<t-card>
<t-tabs class="hotwords-tabs" :value="currentTemplate" @change="handleClickTab">
<t-tab-panel v-for="(item, index) in templatesWay" :key="index" :value="item.template" :label="item.label">
<div class="tab-content">
<component v-if="item.template == currentTemplate" :is="currentTemplate"></component>
</div>
</t-tab-panel>
</t-tabs>
</t-card>
</div>
</template>
@@ -68,4 +65,7 @@ export default {
};
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
::v-deep(.hotwords-tabs .t-tabs__content) { padding-top: 16px; }
.tab-content { padding-top: 16px; }
</style>

View File

@@ -1,25 +1,11 @@
<template>
<div class="box">
<Row class="operation">
<Col span="12">
<DatePicker
:options="options"
@on-change="search"
type="date"
placement="bottom-end"
placeholder="选择查看日期"
style="width: 200px"
v-model="yestDate"
></DatePicker>
</Col>
</Row>
<Row>
<p>
<Alert type="success">
这里展示历史某一天的热词数据统计可根据需求配置每日持久化多少条数据
</Alert>
</p>
</Row>
<div class="operation" style="margin-bottom:12px">
<t-date-picker v-model="yestDate" mode="date" placeholder="选择查看日期" style="width: 240px" @change="search" :disableDate="options.disabledDate" />
</div>
<div style="margin-bottom:12px">
<t-alert theme="success" message="这里展示历史某一天的热词数据统计,可根据需求配置每日持久化多少条数据。" />
</div>
<div id="container"></div>
</div>
@@ -29,7 +15,7 @@
import { Chart } from "@antv/g2";
import { getHotWordsHistory } from "@/api/index";
import affixTime from "@/components/affix-time";
import { Message } from "view-design";
import { MessagePlugin } from 'tdesign-vue';
export default {
components: {
@@ -78,7 +64,7 @@ export default {
this.hotWordsChart.data(this.hotWordsData);
this.hotWordsChart.render();
if (!this.hotWordsData) {
Message.error("暂无数据");
MessagePlugin.error('暂无数据');
}
}
},

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