Browse Source

1.1.1

master
zkthink 5 years ago
parent
commit
9fa6006cb6
  1. 116
      src/api/Comment.js
  2. 67
      src/api/Label.js
  3. 76
      src/api/Member.js
  4. 14
      src/components/Management/Container.vue
  5. 27
      src/components/Management/checkDialog.vue
  6. 18
      src/components/Tinymce/components/EditorImage.vue
  7. 5
      src/components/Tinymce/index.vue
  8. 291
      src/lang/en.js
  9. 299
      src/lang/zh.js
  10. 70
      src/router/index.js
  11. 58
      src/store/modules/account.js
  12. 3
      src/utils/commons.js
  13. 8
      src/utils/date.js
  14. 18
      src/utils/permissionDirect.js
  15. 2
      src/views/ceres/auth/role/Index.vue
  16. 6
      src/views/classification/Edit.vue
  17. 41
      src/views/comment/comment-manage/deletes.vue
  18. 178
      src/views/comment/comment-manage/details.vue
  19. 293
      src/views/comment/comment-manage/index.vue
  20. 66
      src/views/comment/keyword/add.vue
  21. 245
      src/views/comment/keyword/index.vue
  22. 66
      src/views/comment/sensitive-word/add.vue
  23. 253
      src/views/comment/sensitive-word/index.vue
  24. 97
      src/views/customer-manage/custom/custom-info/component/address/index.vue
  25. 157
      src/views/customer-manage/custom/custom-info/component/comment/index.vue
  26. 143
      src/views/customer-manage/custom/custom-info/component/label/index.vue
  27. 124
      src/views/customer-manage/custom/custom-info/component/order/index.vue
  28. 272
      src/views/customer-manage/custom/custom-info/index.vue
  29. 340
      src/views/customer-manage/custom/index.vue
  30. 290
      src/views/customer-manage/label/add.vue
  31. 299
      src/views/customer-manage/label/index.vue
  32. 91
      src/views/customer-manage/label/more.vue
  33. 8
      src/views/finance/cash-deposit/index.vue
  34. 6
      src/views/finance/cash/details.vue
  35. 3
      src/views/login/index.vue
  36. 2
      src/views/management/apply/detail.vue
  37. 6
      src/views/management/apply/dialog.vue
  38. 19
      src/views/marketing/add/index.vue
  39. 2
      src/views/marketing/details/info.vue
  40. 4
      src/views/marketing/details/shop.vue
  41. 63
      src/views/menu/empower/index.vue

116
src/api/Comment.js

@ -0,0 +1,116 @@
import axiosApi from './AxiosApi.js'
const apiList = {
getList: `/authority/comment/findCommentList`,
handleComment: `/authority/comment/handleComment`,
getSensitiveKeywordList: `/authority/comment/findSensitiveKeywordList`,
setSensitiveKeyword: `/authority/comment/updateSensitiveKeywordSetting`,
addSensitiveKeyword: `/authority/comment/addSensitiveKeyword`,
editSensitiveKeyword: `/authority/comment/updateSensitiveKeyword`,
deleteSensitiveKeyword: `/authority/comment/deleteSensitiveKeyword`,
getCommentKeywordList: `/authority/comment/findCommentKeywordList`,
setCommentKeywordList: `/authority/comment/updateCommentKeywordSetting`,
addCommentKeyword: `/authority/comment/addCommentKeyword`,
editCommentKeyword: `/authority/comment/updateCommentKeyword`,
deleteCommentKeyword: `/authority/comment/deleteCommentKeyword`
}
export default {
// 敏感词列表
getList(data) {
return axiosApi({
method: 'POST',
url: apiList.getList,
data
})
},
// 操作评论
handleComment(data) {
return axiosApi({
method: 'POST',
url: apiList.handleComment,
data
})
},
// 查询敏感词列表
getSensitiveKeywordList(data) {
return axiosApi({
method: 'POST',
url: apiList.getSensitiveKeywordList,
data
})
},
// 敏感词配置
setSensitiveKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.setSensitiveKeyword,
data
})
},
// 新增敏感词
addSensitiveKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.addSensitiveKeyword,
data
})
},
// 修改敏感词
editSensitiveKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.editSensitiveKeyword,
data
})
},
// 删除敏感词
deleteSensitiveKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.deleteSensitiveKeyword,
data
})
},
// 查询关键词列表
getCommentKeywordList(data) {
return axiosApi({
method: 'POST',
url: apiList.getCommentKeywordList,
data
})
},
// 关键词配置
setCommentKeywordList(data) {
return axiosApi({
method: 'POST',
url: apiList.setCommentKeywordList,
data
})
},
// 新增关键词
addCommentKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.addCommentKeyword,
data
})
},
// 修改关键词
editCommentKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.editCommentKeyword,
data
})
},
// 删除关键词
deleteCommentKeyword(data) {
return axiosApi({
method: 'POST',
url: apiList.deleteCommentKeyword,
data
})
}
}

67
src/api/Label.js

@ -0,0 +1,67 @@
import axiosApi from './AxiosApi.js'
const apiList = {
getLabelList: `/authority/memberTag/page`,
addLabel: `/authority/memberTag`,
queryTag: `/authority/memberTag/queryTag/`,
deleteTag: `/authority/memberTag`,
editTag: `/authority/memberTag`,
exportTag: `/authority/memberTag/export`,
getTagInfo: `/authority/memberTag/`
}
export default {
// 标签列表
getLabelList(data) {
return axiosApi({
method: 'POST',
url: apiList.getLabelList,
data
})
},
// 新建标签
addLabel(data) {
return axiosApi({
method: 'POST',
url: apiList.addLabel,
data
})
},
// 查询客户标签
queryTag(id) {
return axiosApi({
method: 'GET',
url: `${apiList.queryTag}${id}`
})
},
// 删除标签
deleteTag(data) {
return axiosApi({
method: 'DELETE',
url: apiList.deleteTag,
data
})
},
// 修改标签
editTag(data) {
return axiosApi({
method: 'PUT',
url: apiList.editTag,
data
})
},
// 导出标签
exportTag(data) {
return axiosApi({
method: 'POST',
url: apiList.exportTag,
data
})
},
// 查询标签详情
getTagInfo(id) {
return axiosApi({
method: 'GET',
url: `${apiList.getTagInfo}${id}`
})
}
}

76
src/api/Member.js

@ -0,0 +1,76 @@
import axiosApi from './AxiosApi.js'
const apiList = {
getMemberList: `/authority/member/page`,
addTag: `/authority/member/addTag`,
forbiddenMember: `/authority/member/forbidden`,
getMemberInfo: `/authority/member/query/`,
getMemberAddress: `/authority/memberAddress/page`,
getOrderList: `/authority/order/findAdminOrderList`,
getCustomData: `/authority/order/getOrderStatisticsByMid/`,
getCommentList: `/authority/comment/findCommentList`
}
export default {
// 客户管理列表
getMemberList(data) {
return axiosApi({
method: 'POST',
url: apiList.getMemberList,
data
})
},
// 打标签
addTag(data) {
return axiosApi({
method: 'POST',
url: apiList.addTag,
data
})
},
// 加黑名单
forbiddenMember(data) {
return axiosApi({
method: 'POST',
url: apiList.forbiddenMember,
data
})
},
// 客户详情
getMemberInfo(id) {
return axiosApi({
method: 'GET',
url: `${apiList.getMemberInfo}${id}`
})
},
// 客户消费数据
getCustomData(id) {
return axiosApi({
method: 'GET',
url: `${apiList.getCustomData}${id}`
})
},
// 会员订单
getOrderList(data) {
return axiosApi({
method: 'POST',
url: apiList.getOrderList,
data
})
},
// 客户评价列表
getCommentList(data) {
return axiosApi({
method: 'POST',
url: apiList.getCommentList,
data
})
},
// 会员收货地址
getMemberAddress(data) {
return axiosApi({
method: 'POST',
url: apiList.getMemberAddress,
data
})
}
}

14
src/components/Management/Container.vue

@ -16,14 +16,14 @@
<el-button
type="text"
size="small"
@click.native.prevent="checkRow(scope.row)"
@click.native.prevent="checkRow(scope.row, true)"
>
查看
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="checkRow(scope.row)"
@click.native.prevent="checkRow(scope.row, false)"
>
编辑
</el-button>
@ -46,13 +46,14 @@
/>
<Dialog
:center="true"
title="查看商家"
:title="checkData.check ?'查看商家': '修改商家'"
:visible.sync="checkVisible"
:fullscreen="!true"
:before-close="closeCheckDialog"
class="check-dialog"
width="55%"
>
<checkDialog :data-map="checkData" @close="closeCheckDialog" />
<checkDialog v-if="checkVisible" :data-map="checkData" @close="closeCheckDialog" />
</Dialog>
</div>
</template>
@ -103,12 +104,15 @@ export default {
fetch() {
this.$emit('fetch', this.form)
},
checkRow(item) {
checkRow(item, v) {
item.check = v
this.checkVisible = true
this.checkData = item
console.log(this.checkData, 11)
},
closeCheckDialog() {
this.checkVisible = false
this.checkData = {}
},
prohibit(item) {
const code = item.status.code

27
src/components/Management/checkDialog.vue

@ -6,7 +6,7 @@
<form-item label="店铺名称" prop="name">
<Input
v-model="dataMap.name"
readonly
:disabled="dataMap.check"
size="medium"
maxlength="30"
show-word-limit
@ -16,7 +16,7 @@
<form-item label="店铺负责人" prop="duty">
<Input
v-model="dataMap.duty"
readonly
:disabled="dataMap.check"
size="medium"
maxlength="50"
show-word-limit
@ -26,7 +26,7 @@
<form-item label="联系电话">
<Input
v-model="dataMap.contactTel"
readonly
:disabled="dataMap.check"
size="medium"
maxlength="50"
show-word-limit
@ -36,7 +36,7 @@
<form-item label="联系地址">
<Input
v-model="dataMap.address"
readonly
:disabled="dataMap.check"
size="medium"
maxlength="50"
show-word-limit
@ -46,7 +46,7 @@
<form-item label="生效日期" prop="startTime">
<date-picker
v-model="dataMap.startTime"
readonly
:disabled="dataMap.check"
size="medium"
type="date"
value-format="yyyy-MM-dd HH:mm:ss"
@ -55,7 +55,7 @@
<form-item label="生效时限(年)" prop="expireLimitYear">
<Input
v-model="dataMap.expireLimitYear"
readonly
:disabled="dataMap.check"
size="medium"
maxlength="4"
show-word-limit
@ -71,7 +71,7 @@
<form-item label="账号" prop="mobile">
<Input
v-model="dataMap.account"
readonly
:disabled="dataMap.check"
size="medium"
maxlength="11"
show-word-limit
@ -79,7 +79,7 @@
/>
</form-item>
<form-item size="large">
<Button type="primary" @click="close">确定</Button>
<Button v-if="!dataMap.check" type="primary" @click="sumbit">确定</Button>
</form-item>
</tab-pane>
</Tabs>
@ -88,6 +88,7 @@
</template>
<script>
import { Tabs, TabPane, Form, FormItem, Input, Button, Select, Option, DatePicker } from 'element-ui'
import Management from '@/api/Management'
export default {
components: {
Tabs,
@ -117,9 +118,19 @@ export default {
activeName: 'authorize'
}
},
created() {},
methods: {
close() {
this.$emit('close')
},
sumbit() {
const _ = this
Management.editTenant(this.dataMap).then(res => {
if (res.data.code === 0) {
_.$message.success('修改成功')
_.close()
}
})
}
}
}

18
src/components/Tinymce/components/EditorImage.vue

@ -1,7 +1,12 @@
<template>
<div class="upload-container">
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
upload
<el-button
:style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini"
type="primary"
@click=" dialogVisible=true"
>
<!-- upload -->
上传
</el-button>
<el-dialog :visible.sync="dialogVisible">
<el-upload
@ -16,14 +21,17 @@
list-type="picture-card"
>
<el-button size="small" type="primary">
Click upload
<!-- Click upload -->
点击上传
</el-button>
</el-upload>
<el-button @click="dialogVisible = false">
Cancel
<!-- Cancel -->
取消
</el-button>
<el-button type="primary" @click="handleSubmit">
Confirm
<!-- Confirm -->
确认
</el-button>
</el-dialog>
</div>

5
src/components/Tinymce/index.vue

@ -1,6 +1,6 @@
<template>
<div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
<textarea :id="tinymceId" class="tinymce-textarea" />
<textarea :id="tinymceId" class="tinymce-textarea"></textarea>
<div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
</div>
@ -72,7 +72,8 @@ export default {
},
computed: {
language() {
return this.languageTypeList[this.$store.getters.language]
// return this.languageTypeList[this.$store.getters.language]
return this.languageTypeList.zh
},
containerWidth() {
const width = this.width

291
src/lang/en.js

@ -46,71 +46,229 @@ export default {
passwordErrorNum: 'PasswordErrorNum',
passwordErrorLockTime: 'PasswordErrorLockTime'
},
globalUser: {
tenantCode: 'TenantCode',
user: {
account: 'Account',
mobile: 'Mobile',
name: 'Name',
email: 'Email',
password: 'Password',
confirmPassword: 'ConfirmPassword'
},
user: {
username: 'UserName',
password: 'Password',
sex: 'Gender',
orgId: 'Org',
stationId: 'Station',
email: 'Email',
dept: 'Department',
role: 'Role',
mobile: 'Mobile',
sex: 'Gender',
status: 'Status',
createTime: 'CreateTime',
modifyTime: 'ModifyTime',
mobile: 'Mobile',
avatar: 'Avatar',
workDescribe: 'WorkDescribe',
passwordErrorLastTime: 'PasswordErrorLastTime',
passwordErrorNum: 'PasswordErrorNum',
passwordExpireTime: 'PasswordExpireTime',
lastLoginTime: 'LastLoginTime',
desc: 'Personal Description',
nation: 'nation',
education: 'education',
positionStatus: 'positionStatus',
createTime: 'CreateTime',
updateTime: 'ModifyTime',
oldPassword: 'Old Password',
newPassword: 'New Password',
confirmPassword: 'Confirm Again',
social: 'Third Party Account'
},
role: {
roleName: 'RoleName',
remark: 'Description',
code: 'Code',
name: 'Name',
describe: 'Describe',
status: 'Status',
readonly: 'Readonly',
createTime: 'CreateTime',
perms: 'Permissions'
dsType: 'DsType',
orgList: 'Org'
},
menu: {
parentId: 'ParentId',
menuName: 'Name',
id: 'ID',
label: 'Label',
describe: 'Describe',
code: 'Permissions',
isPublic: 'IsPublic',
path: 'Router Uri',
type: 'Type',
icon: 'Icon',
component: 'Component',
path: 'URL',
orderNum: 'Order',
perms: 'Permissions'
isEnable: 'IsEnable',
sortValue: 'Order',
parentId: 'ParentId',
icon: 'Icon',
group: 'Group'
},
resource: {
code: 'Code',
name: 'Name',
describe: 'Describe'
},
dept: {
deptName: 'DeptName',
org: {
label: 'label',
abbreviation: 'Abbreviation',
describe: 'Describe',
parentId: 'ParentId',
orderNum: 'Order'
sortValue: 'SortValue',
status: 'Status'
},
systemLog: {
username: 'UserName',
operation: 'Description',
createTime: 'CreateTime',
time: 'Duration',
method: 'Method',
params: 'parameter',
ip: 'IP',
location: 'Location'
station: {
name: 'Name',
describe: 'Describe',
orgId: 'Org',
status: 'Status'
},
optLog: {
requestIp: 'IP',
type: 'type',
userName: 'userName',
description: 'description',
classPath: 'classPath',
actionMethod: 'actionMethod',
requestUri: 'requestUri',
httpMethod: 'httpMethod',
params: 'params',
result: 'result',
exDesc: 'exDesc',
consumingTime: 'consumingTime',
startTime: 'startTime',
finishTime: 'finishTime',
ua: 'ua'
},
loginLog: {
username: 'UserName',
loginTime: 'LoginTime',
ip: 'IP',
location: 'Location',
system: 'System',
browser: 'Browser'
userName: 'userName',
account: 'account',
requestIp: 'IP',
description: 'description',
loginDate: 'loginDate',
ua: 'ua',
browser: 'browser',
browserVersion: 'browserVersion',
operatingSystem: 'operatingSystem',
location: 'location'
},
attachment: {
bizId: 'bizId',
bizType: 'bizType',
dataType: 'dataType',
submittedFileName: 'submittedFileName',
group: 'group',
path: 'path',
relativePath: 'relativePath',
url: 'url',
fileMd5: 'fileMd5',
contextType: 'contextType',
filename: 'filename',
ext: 'ext',
size: 'size',
orgId: 'orgId',
icon: 'icon'
},
smsTemplate: {
providerType: 'providerType',
appId: 'appId',
appSecret: 'appSecret',
url: 'url',
customCode: 'customCode',
name: 'name',
content: 'content',
templateParams: 'templateParams',
templateCode: 'templateCode',
signName: 'signName',
templateDescribe: 'templateDescribe'
},
smsTask: {
templateId: 'templateId',
status: 'status',
sourceType: 'sourceType',
receiver: 'receiver',
topic: 'topic',
templateParams: 'templateParams',
sendTime: 'sendTime',
content: 'content',
draft: 'isDraft'
},
smsSendStatus: {
taskId: 'task',
sendStatus: 'sendStatus',
receiver: 'receiver',
bizId: 'bizId',
ext: 'ext',
code: 'code',
message: 'message',
fee: 'fee'
},
msgs: {
bizType: 'bizType',
bizId: 'bizId',
msgsCenterType: 'msgsCenterType',
title: 'title',
content: 'content',
author: 'author',
handlerUrl: 'handlerUrl',
handlerParams: 'handlerParams',
isSingleHandle: 'isSingleHandle',
isDelete: 'isDelete',
isRead: 'isRead',
readTime: 'readTime'
},
systemApi: {
code: "code",
name: "name",
describe: "describe",
requestMethod: "requestMethod",
contentType: "contentType",
serviceId: "serviceId",
path: "path",
status: "status",
isPersist: "isPersist",
isAuth: "isAuth",
isOpen: "isOpen",
className: "className",
methodName: "methodName"
},
application: {
clientId: "clientId",
clientSecret: "clientSecret",
website: "website",
name: "name",
icon: "icon",
appType: "appType",
describe: "describe",
status: "status"
},
dictionary: {
type: "type",
name: "name",
describe: "describe",
status: "status"
},
dictionaryItem: {
dictionaryId: "dictionaryId",
dictionaryType: "dictionaryType",
code: "code",
name: "name",
describe: "describe",
status: "status",
sortValue: "sortValue"
},
area: {
code: "code",
label: "label",
fullName: 'fullName',
sortValue: 'sortValue',
longitude: 'longitude',
latitude: 'latitude',
level: "level",
parentCode: 'parentCode',
parentId: 'parent',
source: 'source'
},
parameter: {
key: "key",
name: "name",
value: 'value',
describe: 'describe',
status: 'status',
readonly: 'readonly'
},
gen: {
config: {
@ -139,6 +297,7 @@ export default {
field3: 'Field 3',
createTime: 'Import Time'
},
status: 'Status',
refresh: 'Refresh',
operation: 'Operation',
search: 'Search',
@ -148,13 +307,14 @@ export default {
export: 'Export',
exportPreview: 'exportPreview',
import: 'Import',
upload: 'Upload',
download: 'Download',
templateDownload: 'Template Download',
delete: 'Delete',
resetPassword: 'RestPassword',
openInNewPage: 'New Page',
createTime: 'createTime',
updateTime: 'updateTime',
systemData: 'Is System Data'
updateTime: 'updateTime'
},
tagsView: {
refresh: 'Refresh',
@ -165,12 +325,12 @@ export default {
settings: {
title: 'Page style setting',
theme: 'Theme Color',
tagsView: 'Open Tags-View',
// tagsView: 'Open Tags-View',
fixedHeader: 'Fixed Header',
sidebarLogo: 'Sidebar Logo'
},
system: {
title: 'cereshop-admin-ui System'
title: 'cereshop'
},
tips: {
systemError: 'System maintenance, please try again~',
@ -179,13 +339,13 @@ export default {
switchLanguageSuccess: 'Switch language successfully',
loginSuccess: 'Login successful',
loginFail: 'Login failed',
defaultPassword: 'The user\'s default password is 1234qwer',
defaultPassword: 'The user\'s default password is 123456',
getDataFail: 'Failed to get data',
createSuccess: 'Create successfully',
updateSuccess: 'Update successfully',
deleteSuccess: 'Delete successfully',
systemData: 'System Data, Inoperable',
noDataSelected: 'No data selected yet',
copySelected: 'Copy successfully',
confirmDelete: 'The selected data will be permanently deleted, continue?',
confirmDeleteCache: 'Whether to clear the user permission cache immediately?',
containCurrentUser: 'The operation has been canceled because it contains the currently logged in user',
@ -197,7 +357,7 @@ export default {
onlyChooseOne: 'Only one node can be selected as the parent node',
noNodeSelected: 'Please select a node first',
confirmDeleteNode: 'The selected node and its child nodes will be permanently deleted. Continue?',
iframeGrant: 'Userame: cereshop Password: 123456',
iframeGrant: 'Userame: cereshop Password: cereshop',
notEqual: 'Inconsistent values entered twice',
oldPasswordIncorrect: 'Old password incorrect',
uploadSuccess: 'Upload Successfully',
@ -207,13 +367,14 @@ export default {
updateFailed: 'Update failed',
noPermission: 'No permission',
confirmRestPassword: 'Make sure to reset the selected user password?',
resetPasswordSuccess: 'The selected user password reset has been reset to 1234qwer',
resetPasswordSuccess: 'The selected user password reset has been reset to 123456',
getCodeImageFailed: 'Failed to get image verification code',
tooManyRequest: 'Getting the authentication code is too frequent. Please try again in 1 minute',
clientOriginSecret: 'The original password of the client is: '
},
rules: {
require: 'Can\'t be empty',
range0to255: '0 to 255 characters in length',
range2to10: '2 to 10 characters in length',
range3to10: '3 to 10 characters in length',
range3to20: '3 to 20 characters in length',
@ -221,7 +382,6 @@ export default {
range6to20: '6 to 20 characters in length',
email: 'Email is invalid',
mobile: 'Phone number is invalid',
accountExist: 'The account already exists',
usernameExist: 'The username already exists',
clientIdExist: 'The clientId already exists',
roleNameExist: 'The role name already exists',
@ -234,10 +394,10 @@ export default {
invalidURL: 'URL is invalid'
},
common: {
system: 'Dev&Operate Microservice SaaS System',
system: 'Microservice SaaS System',
desc: {
a: 'Based on SpringBoot 2.2.5 & SpringCloud Hoxton.SR1',
b: 'Use Spring Cloud OAuth2 Unified Authentication',
b: 'Use Jwt Unified Authentication',
c: 'Enterprise design and configuration, deny demo project',
d: 'Front-end separation architecture for increased efficiency',
e: 'Integrate multiple monitoring to escort microservices',
@ -250,6 +410,8 @@ export default {
cancel: 'Cancel',
add: 'Create',
edit: 'Modify',
copy: 'Copy',
upload: 'Upload',
username: 'User Name',
dept: 'Department',
createTime: 'Create Time',
@ -281,20 +443,23 @@ export default {
goodAfternoon: 'Good afternoon',
goodEvening: 'Good evening',
randomMessage: {
a: 'Have a coffee break☕',
b: 'Do you want to play LOL with your friends?',
c: 'How many bugs🐞 did you write today?',
d: 'Have you chatted in the group today?',
e: 'What delicious food did you eat today?',
f: 'Have you smiled today?😊',
g: 'Have you solved the problem for others today?',
h: 'What are you going to eat?',
i: 'Do you want to watch movies on weekends?'
0: '帮我帮我帮我帮我帮我帮我帮我',
1: 'Have a coffee break☕',
2: 'Do you want to play LOL with your friends?',
3: 'How many bugs🐞 did you write today?',
4: 'Have you chatted in the group today?',
5: 'What delicious food did you eat today?',
6: 'Have you smiled today?😊',
7: 'Have you solved the problem for others today?',
8: 'What are you going to eat?',
9: 'Do you want to watch movies on weekends?'
},
docDetails: 'Learn more',
allProject: 'All Projects',
noDept: 'No department',
noRole: 'No role',
noEmail: 'No Email',
noMobile: 'No Mobile',
noWorkDescribe: `This guy's lazy.He didn't leave anything.`,
firstLogin: 'First login',
todayIp: 'Today IP',

299
src/lang/zh.js

@ -14,7 +14,7 @@ export default {
deleteCache: '清除缓存'
},
login: {
title: 'cereshop',
title: '商家登录',
logIn: '立即登录',
tenant: '企业',
username: '账号',
@ -46,71 +46,229 @@ export default {
passwordErrorNum: '密码输错次数',
passwordErrorLockTime: '账号锁定时间'
},
globalUser: {
tenantCode: '企业编码',
user: {
account: '账号',
mobile: '手机',
name: '姓名',
email: '邮箱',
password: '密码',
confirmPassword: '确认密码'
},
user: {
username: '用户名',
password: '密码',
sex: '性别',
orgId: '组织',
stationId: '岗位',
email: '邮箱',
dept: '部门',
role: '角色',
mobile: '电话',
sex: '性别',
status: '状态',
createTime: '创建时间',
modifyTime: '修改时间',
mobile: '电话',
avatar: '头像',
workDescribe: '个人描述',
passwordErrorLastTime: '最后一次输错密码时间',
passwordErrorNum: '密码错误次数',
passwordExpireTime: '密码过期时间',
lastLoginTime: '最后登录时间',
desc: '个人描述',
nation: '民族',
education: '学历',
positionStatus: '职位状态',
createTime: '创建时间',
updateTime: '修改时间',
oldPassword: '旧密码',
newPassword: '新密码',
confirmPassword: '再次确认',
confirmPassword: '确认密码',
social: '第三方账号'
},
role: {
roleName: '角色名称',
remark: '角色描述',
code: '编码',
name: '角色名称',
describe: '角色描述',
status: '状态',
readonly: '是否内置',
createTime: '创建时间',
perms: '角色权限'
dsType: '数据范围',
orgList: '组织'
},
menu: {
parentId: '上级ID',
menuName: '名称',
id: 'ID',
label: '名称',
describe: '描述',
code: '权限编码',
isPublic: '是否公有',
path: '路由URI',
type: '类型',
icon: '图标',
component: '组件',
path: 'URL',
orderNum: '排序',
perms: '权限'
isEnable: '是否启用',
sortValue: '排序',
parentId: '上级ID',
icon: '图标',
group: '分组'
},
resource: {
code: '编码',
name: '名称',
describe: '描述'
},
dept: {
deptName: '部门名称',
org: {
label: '部门名称',
abbreviation: '简称',
describe: '描述',
parentId: '上级ID',
orderNum: '排序'
sortValue: '排序',
status: '状态'
},
systemLog: {
username: '操作人',
operation: '操作描述',
createTime: '操作时间',
time: '耗时',
method: '操作方法',
station: {
name: '岗位名称',
describe: '描述',
orgId: '组织',
status: '状态'
},
optLog: {
requestIp: 'IP',
type: '类型',
userName: '操作人',
description: '操作描述',
classPath: '类路径',
actionMethod: '请求方法',
requestUri: '请求地址',
httpMethod: '请求类型',
params: '方法参数',
ip: 'IP',
location: '操作地点'
result: '返回值',
exDesc: '异常详情信息',
consumingTime: '消耗时间',
startTime: '开始时间',
finishTime: '完成时间',
ua: '浏览器请求头'
},
loginLog: {
username: '用户名',
loginTime: '登录时间',
ip: 'IP',
location: '登录地点',
system: '登录系统',
browser: '浏览器'
userName: '姓名',
account: '账号',
requestIp: 'IP',
description: '描述',
loginDate: '登录时间',
ua: '浏览器请求头',
browser: '浏览器',
browserVersion: '浏览器版本',
operatingSystem: '操作系统',
location: '地区'
},
attachment: {
bizId: '业务ID',
bizType: '业务类型',
dataType: '数据类型',
submittedFileName: '文件名',
group: '组',
path: '路径',
relativePath: '相对路径',
url: '访问链接',
fileMd5: 'md5',
contextType: '类型',
filename: '唯一文件名',
ext: '后缀',
size: '大小',
orgId: '组织',
icon: '图标'
},
smsTemplate: {
providerType: '类型',
appId: '应用ID',
appSecret: '应用密码',
url: 'SMS服务域名',
customCode: '模板编码',
name: '模板名称',
content: '模板内容',
templateParams: '模板参数',
templateCode: '模板CODE',
signName: '模板签名',
templateDescribe: '模板描述'
},
smsTask: {
templateId: '短信模板',
status: '执行状态',
sourceType: '来源类型',
receiver: '接收者',
topic: '主题',
templateParams: '模板参数',
sendTime: '发送时间',
content: '发送内容',
draft: '是否草稿'
},
smsSendStatus: {
taskId: '任务',
sendStatus: '发送状态',
receiver: '接收者手机号',
bizId: '发送回执',
ext: '发送返回',
code: '状态码',
message: '状态码的描述',
fee: '计费条数'
},
msgs: {
bizType: '业务类型',
bizId: '业务ID',
msgsCenterType: '消息类型',
title: '标题',
content: '内容',
author: '作者',
handlerUrl: '处理地址',
handlerParams: '处理参数',
isSingleHandle: '是否单人处理',
isDelete: '是否删除',
isRead: '状态',
readTime: '读消息的时间'
},
systemApi: {
code: "接口编码",
name: "接口名称",
describe: "资源描述",
requestMethod: "请求方式",
contentType: "响应类型",
serviceId: "服务ID",
path: "请求路径",
status: "状态",
isPersist: "保留数据",
isAuth: "是否需要认证",
isOpen: "是否公开",
className: "类名",
methodName: "方法名"
},
application: {
clientId: "clientId",
clientSecret: "clientSecret",
website: "官网",
name: "应用名称",
icon: "应用图标",
appType: "类型",
describe: "备注",
status: "状态"
},
dictionary: {
type: "类型",
name: "名称",
describe: "描述",
status: "状态"
},
dictionaryItem: {
dictionaryId: "字典ID",
dictionaryType: "类型",
code: "编码",
name: "名称",
describe: "描述",
status: "状态",
sortValue: "排序"
},
area: {
code: "编码",
label: "名称",
fullName: '全名',
sortValue: '排序',
longitude: '经度',
latitude: '维度',
level: "行政区级",
parentCode: '父编码',
parentId: '上级地区',
source: '数据来源'
},
parameter: {
key: "参数键",
name: "参数名称",
value: '参数值',
describe: '描述',
status: '状态',
readonly: '只读'
},
gen: {
config: {
@ -139,22 +297,24 @@ export default {
field3: '字段3',
createTime: '导入时间'
},
status: '状态',
refresh: '刷新',
operation: '操作',
search: '搜索',
reset: '重置',
more: '更多操作',
more: '更多',
add: '添加',
export: '导出',
exportPreview: '导出预览',
import: '导入',
upload: '上传',
download: '下载',
templateDownload: '模板下载',
delete: '删除',
resetPassword: '密码重置',
openInNewPage: '新页面打开',
createTime: '创建时间',
updateTime: '修改时间',
systemData: '是否内置'
updateTime: '修改时间'
},
tagsView: {
refresh: '刷新当前',
@ -165,12 +325,12 @@ export default {
settings: {
title: '系统布局配置',
theme: '主题色',
tagsView: '开启 Tags-View',
// tagsView: '开启 Tags-View',
fixedHeader: '固定 Header',
sidebarLogo: '侧边栏 Logo'
},
system: {
title: 'cereshop-admin'
title: 'cereshop商家端'
},
tips: {
systemError: '系统维护中,请稍微再试~',
@ -179,13 +339,13 @@ export default {
switchLanguageSuccess: '切换语言成功',
loginSuccess: '登录成功',
loginFail: '登录失败',
defaultPassword: '用户的默认密码为1234qwer',
defaultPassword: '用户的默认密码为123456',
getDataFail: '获取数据失败',
saveSuccess: '保存成功',
createSuccess: '新增成功',
copySelected: '复制成功',
updateSuccess: '修改成功',
deleteSuccess: '删除成功',
systemData: '系统数据,不能操作',
saveSuccess: '保存成功',
noDataSelected: '请先选择需要操作的数据',
confirmDelete: '选中数据将被永久删除, 是否继续?',
confirmDeleteCache: '是否立即清除用户权限缓存?',
@ -198,7 +358,7 @@ export default {
onlyChooseOne: '只能选择一个节点作为父节点',
noNodeSelected: '请先选择节点',
confirmDeleteNode: '选中节点及其子结点将被永久删除, 是否继续?',
iframeGrant: '用户名:FEBS 密码:123456',
iframeGrant: '用户名:cereshop 密码:123456',
notEqual: '两次输入不一致',
oldPasswordIncorrect: '原密码不正确',
uploadSuccess: '上传成功',
@ -208,13 +368,14 @@ export default {
updateFailed: '修改失败',
noPermission: '无权限',
confirmRestPassword: '确定重置所选用户密码?',
resetPasswordSuccess: '所选用户密码重置已被重置为1234qwer',
resetPasswordSuccess: '所选用户密码重置已被重置为123456',
getCodeImageFailed: '获取图形验证码失败',
tooManyRequest: '获取验证码过于频繁,请1分钟后再试',
clientOriginSecret: '该客户端原始密码为:'
},
rules: {
require: '不能为空',
range0to255: '长度在 0 到 255 个字符',
range2to10: '长度在 2 到 10 个字符',
range3to10: '长度在 3 到 10 个字符',
range3to20: '长度在 3 到 20 个字符',
@ -222,7 +383,6 @@ export default {
range6to20: '长度在 6 到 20 个字符',
email: '请输入正确的邮箱地址',
mobile: '请输入合法的手机号',
accountExist: '该账号已存在',
usernameExist: '该用户名已存在',
clientIdExist: '该Client ID已存在',
roleNameExist: '该角色名称已存在',
@ -235,14 +395,14 @@ export default {
invalidURL: '不是有效的URL'
},
common: {
system: '开发&运营后台',
system: '微服务SaaS脚手架',
desc: {
a: '基于 SpringBoot 2.2.5 & SpringCloud Hoxton.SR1',
a: '基于SpringBoot 2.2.5 & SpringCloud Hoxton.SR1',
b: '使用Jwt自定义统一认证',
c: '企业级设计和配置,拒绝demo项目',
d: '前后端分离架构,提高软件开发效率',
e: '集成多种监控,为微服务保驾护航',
f: '提供详细的文档,手把手教你从零搭建到部署'
f: '提供详细的文档&视频教程,手把手教你从零搭建到部署'
},
view: '查看',
tips: '提示',
@ -251,6 +411,8 @@ export default {
cancel: '取消',
add: '新增',
edit: '修改',
copy: '复制',
upload: '上传',
yes: '是',
no: '否',
sex: {
@ -279,18 +441,21 @@ export default {
goodAfternoon: '下午好',
goodEvening: '晚上好',
randomMessage: {
a: '喝杯咖啡休息下吧☕',
b: '要不要和朋友打局LOL',
c: '今天又写了几个Bug🐞呢',
d: '今天在群里吹水了吗',
e: '今天吃了什么好吃的呢',
f: '今天您微笑了吗😊',
g: '今天帮别人解决问题了吗',
h: '准备吃些什么呢',
i: '周末要不要去看电影?'
0: '帮我帮我帮我帮我帮我帮我帮我',
1: '喝杯咖啡休息下吧☕',
2: '要不要和朋友打局LOL',
3: '今天又写了几个Bug🐞呢',
4: '今天在群里吹水了吗',
5: '今天吃了什么好吃的呢',
6: '今天您微笑了吗😊',
7: '今天帮别人解决问题了吗',
8: '准备吃些什么呢',
9: '周末要不要去看电影?'
},
docDetails: '了解更多',
allProject: '所有项目',
noEmail: '暂无邮箱',
noMobile: '暂无手机',
noDept: '暂无部门',
noRole: '暂无角色',
noWorkDescribe: '这家伙很懒,什么也没留下~',

70
src/router/index.js

@ -184,6 +184,76 @@ const constRouter = [
}
]
},
{
path: '/comment',
component: Layout,
name: "评论",
children: [
{
path: '/comment/comment-manage',
component: () => import('@/views/comment/comment-manage/index'),
meta: {
title: '评论管理',
affix: true
}
},
{
path: '/comment/sensitive-word',
component: () => import('@/views/comment/sensitive-word/index'),
meta: {
title: '敏感词管理',
affix: true
}
},
{
path: '/comment/keyword',
component: () => import('@/views/comment/keyword/index'),
meta: {
title: '关键词管理',
affix: true
}
}
]
},
{
path: '/customer-manage',
component: Layout,
name: '客户管理',
children: [
{
path: '/customer-manage/custom',
component: () => import('@/views/customer-manage/custom/index'),
meta: {
title: '客户管理',
affix: true
}
},
{
path: '/customer-manage/label',
component: () => import('@/views/customer-manage/label/index'),
meta: {
title: '标签管理',
affix: true
}
},
{
path: '/customer-manage/custom-info',
component: () => import('@/views/customer-manage/custom/custom-info/index'),
meta: {
title: '客户详情',
affix: true
}
},
{
path: '/customer-manage/label/add',
component: () => import('@/views/customer-manage/label/add'),
meta: {
title: '创建标签',
affix: true
}
}
]
},
{
path: '/menu',
component: Layout,

58
src/store/modules/account.js

@ -129,6 +129,64 @@ export default {
}
]
},
{
path: '/comment',
meta: {
title: '评论',
icon: 'el-icon-s-comment'
},
children: [
{
path: '/comment/comment-manage',
name: '评论管理',
meta: {
title: '评论管理',
icon: ''
}
},
{
path: '/comment/sensitive-word',
name: '敏感词管理',
meta: {
title: '敏感词管理',
icon: ''
}
},
{
path: '/comment/keyword',
name: '关键词管理',
meta: {
title: '关键词管理',
icon: ''
}
}
]
},
{
path: '/customer-manage',
meta: {
title: '客户管理',
icon: 'el-icon-s-custom'
},
children: [
{
path: '/customer-manage/custom',
name: '客户管理',
meta: {
title: '客户管理',
icon: ''
}
},
{
path: '/customer-manage/label',
name: '标签管理',
meta: {
title: '标签管理',
icon: ''
}
}
]
},
{
"sortValue": 1,
"children": [{

3
src/utils/commons.js

@ -66,9 +66,10 @@ export const initDicts = (codes, dicts = {}) => {
* @param response
*/
export const downloadFile = (response) => {
console.log(response, 12)
const res = response.data
const type = res.type
if (type.includes("application/json")) {
if (type && type.includes("application/json")) {
const reader = new FileReader()
reader.onload = e => {
if (e.target.readyState === 2) {

8
src/utils/date.js

@ -0,0 +1,8 @@
export function getIntervalTime(start, end, flag) {
const temp = new Date(end).getTime() - new Date(start).getTime()
const min = temp / 60000
const hour = min / 60
if (min < 60 && !flag) return `${min}分钟`
if (hour < 24 && !flag) return `${hour}小时`
return `${parseInt(hour / 24)}`
}

18
src/utils/permissionDirect.js

@ -5,8 +5,8 @@ export const hasPermission = {
install (Vue) {
Vue.directive('hasPermission', {
bind (el, binding, vnode) {
const permissions = vnode.context.$store.state.account.permissions
const value = binding.value
// const permissions = vnode.context.$store.state.account.permissions
/* onst value = binding.value
let flag = true
for (const v of value) {
if (!permissions.includes(v)) {
@ -19,7 +19,7 @@ export const hasPermission = {
} else {
el.parentNode.removeChild(el)
}
}
} */
}
})
}
@ -30,8 +30,8 @@ export const hasNoPermission = {
install (Vue) {
Vue.directive('hasNoPermission', {
bind (el, binding, vnode) {
const permissions = vnode.context.$store.state.account.permissions
const value = binding.value
// const permissions = vnode.context.$store.state.account.permissions
/* const value = binding.value
let flag = true
for (const v of value) {
if (permissions.includes(v)) {
@ -44,7 +44,7 @@ export const hasNoPermission = {
} else {
el.parentNode.removeChild(el)
}
}
} */
}
})
}
@ -55,8 +55,8 @@ export const hasAnyPermission = {
install (Vue) {
Vue.directive('hasAnyPermission', {
bind (el, binding, vnode) {
const permissions = vnode.context.$store.state.account.permissions
const value = binding.value
// const permissions = vnode.context.$store.state.account.permissions
/* const value = binding.value
let flag = false
for (const v of value) {
if (permissions.includes(v)) {
@ -69,7 +69,7 @@ export const hasAnyPermission = {
} else {
el.parentNode.removeChild(el)
}
}
} */
}
})
}

2
src/views/ceres/auth/role/Index.vue

@ -478,7 +478,7 @@ export default {
if (res.isSuccess) {
this.tableData = res.data
}
}).finally(() => this.loading = false)
}).finally(() => { this.loading = false })
},
sortChange(val) {
this.queryParams.sort = val.prop

6
src/views/classification/Edit.vue

@ -53,11 +53,11 @@
<img
v-if="data.categoryImgArray&&data.categoryImgArray[0].url"
:src="data.categoryImgArray&&data.categoryImgArray[0].url"
>
/>
<i
v-else
class="el-icon-plus"
/>
></i>
</el-upload>
</div>
<el-input
@ -131,7 +131,7 @@ export default {
depth = depth + ''
const tipsMp = {
'1': '添加二级类别名称',
'2': '添加三级类别称'
'2': '添加三级类别称'
}
return tipsMp[depth]
},

41
src/views/comment/comment-manage/deletes.vue

@ -0,0 +1,41 @@
<template>
<el-dialog
:title="dialogVisible.title"
:visible.sync="dialogVisible.visible"
width="30%"
>
<span>删除后将无法恢复评论</span>
<span slot="footer" class="dialog-footer">
<el-button @click="close"> </el-button>
<el-button type="primary" @click="confirm"> </el-button>
</span>
</el-dialog>
</template>
<script>
export default {
props: {
dialogVisible: {
type: Object,
default: () => {}
}
},
data() {
return {}
},
methods: {
confirm() {
},
close() {
this.$emit('closed')
}
}
}
</script>
<style lang='less' scoped>
/deep/.el-dialog__body {
font-size: 16px;
}
</style>

178
src/views/comment/comment-manage/details.vue

@ -0,0 +1,178 @@
<template>
<div class="detail_page">
<ul>
<li v-if="info.sensitiveFlag">
<p>敏感词</p>
<p>{{ info.sensitiveKeywordList.join() }}</p>
</li>
<li
v-for="(item,index) in list" :key="index" :class="[{'active_li': info.additionalComment && index === 2}]"
:time="time"
>
<p v-if="item.show">{{ item.name }}</p>
<p v-if="item.show">
<span v-if="item.type===1">{{ item.value }}</span>
<span v-else>
<img v-for="(ob, i) in item.imgList" :key="i" :src="ob" alt="" />
</span>
</p>
</li>
</ul>
<div class="btn_list">
<el-button type="primary" @click="confirm">{{ info.hideFlag ? '显示' : '隐藏' }}</el-button>
<el-button class="delete" @click="deletes">删除</el-button>
</div>
</div>
</template>
<script>
import { getIntervalTime } from '@/utils/date'
export default {
props: {
info: {
type: Object,
default: () => {}
}
},
data() {
return {
list: [
{
name: '评论',
value: '商品好看有实用,强烈推荐购买。这台电脑买来不是玩游戏的,没那爱好。主要用来给孩子上网课,大人偶尔会看看电影视频这些,所以配的4K显示器。京东快递很麻利,从山东调货,隔天就到了,非常感谢。',
type: 1,
fields: 'commentText'
},
{
name: '图片',
value: '商品好看有实用,强烈推荐购买。这台电脑买来不是玩游戏的,没那爱好。主要用来给孩子上网课,大人偶尔会看看电影视频这些,所以配的4K显示器。京东快递很麻利,从山东调货,隔天就到了,非常感谢。',
type: 2,
imgList: [
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg'
],
fields: 'commentImgs'
},
{
name: '追评',
value: '机器外观精致小巧,性能也足够家用。',
type: 1,
fields: 'additionalComment',
fieldsItem: 'commentText'
},
{
name: '图片',
value: '机器外观精致小巧,性能也足够家用。',
type: 2,
imgList: [
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg',
'http://cereshop.oss-cn-shenzhen.aliyuncs.com/admin/2020/07/6b0d6d7a-8ec8-4fdd-b75d-8b6590683543.jpg'
],
fields: 'additionalComment',
fieldsItem: 'commentImgs'
}
],
time: ''
}
},
watch: {
info: {
handler() {
this.getList()
},
deep: true
}
},
created() {
this.getList()
},
methods: {
getList() {
const _ = this
_.list.map(item => {
if (_.info[item.fields]) {
item.value = _.info[item.fields]
item.show = true
if (item.fields === 'additionalComment') {
item.value = _.info.additionalComment[item.fieldsItem]
if (item.fieldsItem === 'commentImgs') {
item.imgList = _.info.additionalComment.commentImgsFlag ? _.info.additionalComment.commentImgs.split(',') : []
item.show = _.info.additionalComment.commentImgsFlag
}
}
if (item.fields === 'commentImgs') {
item.imgList = _.info.commentImgsFlag ? _.info.commentImgs.split(',') : []
item.show = _.info.commentImgsFlag
}
}
})
if (_.info.additionalComment) {
_.time = `${getIntervalTime(_.info.createTime, _.info.additionalComment.createTime)}后追加评论`
}
},
deletes() {
this.$emit('deletes')
},
confirm() {
this.$emit('handle')
}
}
}
</script>
<style lang='less' scoped>
.detail_page {
ul {
overflow: hidden;
li {
overflow: hidden;
p {
overflow: hidden;
font-size: 16px;
float: left;
&:nth-child(1) {
font-weight: 600;
width: 70px;
}
&:nth-child(2) {
width: calc(100% - 75px);
img {
float: left;
width: calc(25% - 8px);
height: 135px;
border-radius: 4px;
margin-right: 8px;
margin-bottom: 10px;
}
}
}
}
.active_li {
border-top: 1px solid #E0E5EB;
padding-top: 50px;
position: relative;
&:after {
content: attr(time);
position: absolute;
top: 10px;
left: 0;
display: block;
color: #F18B48;
font-size: 16px;
}
}
}
.btn_list {
text-align: center;
.delete {
margin-left: 20px !important;
}
}
}
</style>

293
src/views/comment/comment-manage/index.vue

@ -0,0 +1,293 @@
<template>
<div class="comment_manage_page">
<div class="content">
<el-tabs
v-model="formParams.type"
@tab-click="selectItem"
>
<el-tab-pane
v-for="(item, index) in tabList"
:key="index"
:label="item.name"
:name="item.id"
/>
</el-tabs>
<div class="toolbar">
<el-form
:inline="true"
:model="formParams"
>
<el-form-item label="商家名称">
<el-input v-model="formParams.storeName" size="mini" />
</el-form-item>
<el-form-item label="商家编码">
<el-input v-model="formParams.tenantCode" size="mini" />
</el-form-item>
<el-form-item label="商品ID">
<el-input v-model="formParams.productId" size="mini" />
</el-form-item>
<el-form-item label="关键词">
<el-input v-model="formParams.keyword" size="mini" />
</el-form-item>
<el-form-item>
<el-button
type="primary"
size="mini"
@click="query"
>
查询
</el-button>
<el-button
plain
size="mini"
@click="reset"
>
重置
</el-button>
</el-form-item>
</el-form>
</div>
<div class="content_table">
<div class="table">
<el-table
:data="tableData.commentDTOList"
border
style="width: 100%"
>
<el-table-column
prop="storeName"
label="商家名称"
/>
<el-table-column
prop="tenantCode"
label="商家编码"
/>
<el-table-column
prop="productId"
label="商品ID"
/>
<el-table-column
prop="memberAccount"
label="评论人"
/>
<el-table-column
prop="createTime"
label="评论日期"
/>
<el-table-column label="操作">
<template
slot-scope="scope"
>
<el-button
type="text"
size="small"
@click.native.prevent="details(scope.row)"
>
查看
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="handle(scope.row)"
>
{{ scope.row.hideFlag? '显示' : '隐藏' }}
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="deletes(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<pagination
v-show="tableData.total > 0"
:limit.sync="formParams.pageSize"
:page.sync="formParams.pageIndex"
:total="Number(tableData.total)"
@pagination="fetch"
/>
</div>
</div>
<Dialog
:title="dialog.title"
:visible.sync="dialog.visible"
:fullscreen="!true"
:before-close="close"
width="55%"
>
<detail v-if="dialog.visible" :info="dialog.info" @deletes="deletes" @handle="handle" />
</Dialog>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import detail from './details'
import { Dialog } from 'element-ui'
import Comment from '@/api/Comment'
export default {
components: {
Pagination,
Dialog,
detail
},
data() {
return {
formParams: {
keyword: '',
storeName: '',
tenantCode: '',
productId: '',
pageSize: 10,
pageIndex: 1,
type: '1'
},
date: [],
tableData: {},
tabList: [
{ name: '全部评论', id: '1' },
{ name: '敏感评论', id: '2' }
],
dialog: {}
}
},
created() {
this.getList()
},
methods: {
async getList() {
const res = await Comment.getList(this.formParams)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
query() {
this.getList()
},
details(info) {
this.dialog = {
title: '评论详情',
visible: true,
info
}
},
handle(item) {
const _ = this
const ob = item || _.dialog.info
const params = {
id: ob.id,
action: ob.hideFlag ? 1 : 2
}
const t = ob.hideFlag ? '显示' : '隐藏'
_.$confirm(`确定要${t}该评论`, `${t}评论`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Comment.handleComment(params).then(res => {
if (res.data.code === 0) {
_.getList()
_.$message.success(`${t}成功`)
}
})
})
},
deletes(id) {
const _ = this
const params = {
id: id || _.dialog.info.id,
action: 3
}
_.$confirm('删除后将无法恢复评论', '删除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Comment.handleComment(params).then(res => {
if (res.data.code === 0) {
_.dialog = {}
_.getList()
_.$message.success('删除成功')
}
})
})
},
reset() {
this.formParams = {
keyword: '',
storeName: '',
tenantCode: '',
productId: '',
pageSize: 10,
pageIndex: 1
}
},
fetch() {
this.getList()
},
selectItem() {
this.getList()
},
close() {
this.dialog = {}
}
}
}
</script>
<style lang='less' scoped>
.comment_manage_page{
padding: 10px 20px;
box-sizing: border-box;
.content {
background-color: #fff;
padding: 20px;
.toolbar {
padding: 10px;
}
}
}
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
text-align: center;
}
td {
font-size: 14px;
text-align: center;
color: #666666;
}
}
/deep/ .el-dialog__wrapper {
.el-dialog__header {
height: 70px;
background-color: #3A68F2;
.el-dialog__title {
font-size:24px;
color: #fff;
}
}
}
/deep/ .el-message-box__btns .el-button {
margin-right: 10px !important;
}
</style>

66
src/views/comment/keyword/add.vue

@ -0,0 +1,66 @@
<template>
<div class="add_page">
<el-form
ref="form" :model="form" :rules="rules"
required
label-width="100px"
>
<el-form-item prop="keyword" label="关键词">
<el-input v-model="form.keyword" />
</el-form-item>
</el-form>
<div class="btn_list">
<el-button type="primary" @click="confirm">确定</el-button>
<el-button class="delete" @click="cancel">取消</el-button>
</div>
</div>
</template>
<script>
export default {
props: {
dialog: {
type: Object,
default: () => {}
}
},
data() {
return {
form: {
keyword: this.dialog.info.keyword || ''
},
rules: {
keyword: [
{ required: true, message: '请输入关键词', trigger: 'blur' }
]
}
}
},
methods: {
confirm() {
const vm = this
vm.$refs.form.validate((valid) => {
if (valid) {
vm.$emit('add', vm.form)
}
})
},
cancel() {
this.$emit('close')
}
}
}
</script>
<style lang='less' scoped>
.add_page {
padding: 0 50px;
.btn_list {
padding-top: 20px;
text-align: center;
}
}
/deep/.el-button {
// margin-right: 30px;
}
</style>

245
src/views/comment/keyword/index.vue

@ -0,0 +1,245 @@
<template>
<div class="keyword_page">
<div class="head">
<el-form ref="formPage" action="" :model="formPage" inline>
<el-form-item label="关键词">
<el-input v-model="formPage.keyword" size="mini" />
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="fetch">查询</el-button>
<el-button size="mini" @click="reset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="setting">
<el-form ref="form" :model="form" inline>
<el-form-item label="状态">
<!-- <el-radio-group v-model="form.enabled" @change="changeItem">
<el-radio :label="1">开启</el-radio>
<el-radio :label="0">关闭</el-radio>
</el-radio-group> -->
<el-switch
v-model="form.enabled"
:active-value="1"
:inactive-value="0"
@change="changeItem"
/>
</el-form-item>
</el-form>
</div>
<div class="content">
<el-button type="primary" size="mini" style="margin-bottom: 20px" @click="addCommentKeyword">新增</el-button>
<el-table
:data="tableData.commentKeywordList"
border
style="width: 100%"
>
<el-table-column
type="index"
width="100"
label="序号"
/>
<el-table-column
prop="keyword"
label="关键词"
/>
<el-table-column
prop="createTime"
label="创建时间"
/>
<el-table-column label="操作">
<template
slot-scope="scope"
>
<el-button
type="text"
size="small"
@click.native.prevent="edit(scope.row)"
>
修改
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="deletes(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.total > 0"
:limit.sync="formPage.pageSize"
:page.sync="formPage.pageIndex"
:total="Number(tableData.total)"
@pagination="fetch"
/>
</div>
<Dialog
:title="dialog.title"
:visible.sync="dialog.visible"
:fullscreen="!true"
:before-close="close"
width="30%"
>
<add v-if="dialog.visible" :dialog="dialog" @add="add" @close="close" />
</Dialog>
</div>
</template>
<script>
import Comment from '@/api/Comment'
import Pagination from '@/components/Pagination'
import { Dialog } from 'element-ui'
import add from './add'
export default {
components: {
Pagination,
Dialog,
add
},
data() {
return {
form: {
enabled: 0
},
formPage: {
keyword: '',
pagesize: 10,
pageSize: 10,
pageIndex: 1
},
tableData: {},
dialog: {
}
}
},
created() {
this.getCommentKeywordList()
},
methods: {
async getCommentKeywordList() {
const res = await Comment.getCommentKeywordList(this.formPage)
const ob = res.data
if (ob.code === 0) {
this.tableData = ob.data
Object.keys(this.form).forEach(item => {
if ( ob.data.commentKeywordList[0] && ob.data.commentKeywordList[0][item] !== undefined) {
this.form[item] = ob.data.commentKeywordList[0][item]
}
})
}
},
changeItem() {
Comment.setCommentKeywordList(this.form).then(res => {
if (res.data.code === 0) {
this.getCommentKeywordList()
}
})
},
addCommentKeyword() {
this.dialog = {
title: '新增',
visible: true,
info: {}
}
},
add(keyword) {
const _ = this
const key = _.dialog.edit ? 'editCommentKeyword' : 'addCommentKeyword'
if (_.dialog.edit) {
keyword.id = _.dialog.info.id
}
Comment[key](Object.assign({}, _.form, keyword )).then(res => {
if (res.data.code === 0) {
_.getCommentKeywordList()
_.$message.success(`${_.dialog.edit ? '修改' : '新增'}成功`)
_.close()
}
})
},
close() {
this.dialog = {}
},
fetch() {
this.getCommentKeywordList()
},
reset() {
this.formPage.keyword = ''
},
edit(item) {
this.dialog = {
title: '修改',
visible: true,
edit: true,
info: item
}
},
deletes(id) {
const _ = this
_.$confirm('确定要删除该条关键词', `删除`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Comment.deleteCommentKeyword({ id }).then(res => {
if (res.data.code === 0) {
_.$message.success('删除成功')
_.getCommentKeywordList()
}
})
})
}
}
}
</script>
<style lang='less' scoped>
.keyword_page {
margin-top: 10px;
background-color: #fff;
height: calc(100% - 10px);
padding: 20px 30px;
.setting {
height: 80px;
}
}
/deep/ .el-form-item__label {
text-align: left !important;
font-weight: 400;
}
/deep/.el-form-item {
margin-right: 50px;
}
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
// text-align: center;
}
td {
font-size: 14px;
// text-align: center;
color: #666666;
}
}
/deep/ .el-dialog__wrapper {
.el-dialog__header {
height: 70px;
background-color: #3A68F2;
.el-dialog__title {
font-size:24px;
color: #fff;
}
}
}
</style>

66
src/views/comment/sensitive-word/add.vue

@ -0,0 +1,66 @@
<template>
<div class="add_page">
<el-form
ref="form" :model="form" :rules="rules"
required
label-width="100px"
>
<el-form-item prop="sensitiveKeyword" label="敏感词">
<el-input v-model="form.sensitiveKeyword" />
</el-form-item>
</el-form>
<div class="btn_list">
<el-button type="primary" @click="confirm">确定</el-button>
<el-button class="delete" @click="cancel">取消</el-button>
</div>
</div>
</template>
<script>
export default {
props: {
dialog: {
type: Object,
default: () => {}
}
},
data() {
return {
form: {
sensitiveKeyword: this.dialog.info.sensitiveKeyword || ''
},
rules: {
sensitiveKeyword: [
{ required: true, message: '请输入敏感词', trigger: 'blur' }
]
}
}
},
methods: {
confirm() {
const vm = this
vm.$refs.form.validate((valid) => {
if (valid) {
vm.$emit('add', vm.form)
}
})
},
cancel() {
this.$emit('close')
}
}
}
</script>
<style lang='less' scoped>
.add_page {
padding: 0 50px;
.btn_list {
padding-top: 20px;
text-align: center;
}
}
/deep/.el-button {
// margin-right: 30px;
}
</style>

253
src/views/comment/sensitive-word/index.vue

@ -0,0 +1,253 @@
<template>
<div class="sensitive_word_page">
<div class="head">
<el-form ref="formPage" action="" :model="formPage" inline>
<el-form-item label="关键词">
<el-input v-model="formPage.keyword" size="mini" />
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="fetch">查询</el-button>
<el-button size="mini" @click="reset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="setting">
<el-form ref="form" :model="form" inline>
<el-form-item label="状态">
<!-- <el-radio-group v-model="form.enabled" @change="changeItem">
<el-radio :label="1">开启</el-radio>
<el-radio :label="0">关闭</el-radio>
</el-radio-group> -->
<el-switch
v-model="form.enabled"
:active-value="1"
:inactive-value="0"
@change="changeItem"
/>
</el-form-item>
<el-form-item label="处理措施">
<el-radio-group v-model="form.action" @change="changeItem">
<el-radio :label="1">禁止发布</el-radio>
<el-radio :label="2">需审核</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</div>
<div class="content">
<el-button type="primary" size="mini" style="margin-bottom: 20px" @click="addSensitiveKeyword">新增</el-button>
<el-table
:data="tableData.sensitiveKeywordList"
border
style="width: 100%"
>
<el-table-column
type="index"
width="100"
label="序号"
/>
<el-table-column
prop="sensitiveKeyword"
label="敏感词"
/>
<el-table-column
prop="createTime"
label="创建时间"
/>
<el-table-column label="操作">
<template
slot-scope="scope"
>
<el-button
type="text"
size="small"
@click.native.prevent="edit(scope.row)"
>
修改
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="deletes(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.total > 0"
:limit.sync="formPage.pageSize"
:page.sync="formPage.pageIndex"
:total="Number(tableData.total)"
@pagination="fetch"
/>
</div>
<Dialog
:title="dialog.title"
:visible.sync="dialog.visible"
:fullscreen="!true"
:before-close="close"
width="30%"
>
<add v-if="dialog.visible" :dialog="dialog" @add="add" @close="close" />
</Dialog>
</div>
</template>
<script>
import Comment from '@/api/Comment'
import Pagination from '@/components/Pagination'
import { Dialog } from 'element-ui'
import add from './add'
export default {
components: {
Pagination,
Dialog,
add
},
data() {
return {
form: {
enabled: 0,
action: 1
},
formPage: {
keyword: '',
pagesize: 10,
pageSize: 10,
pageIndex: 1
},
tableData: {},
dialog: {
}
}
},
created() {
this.getSensitiveKeywordList()
},
methods: {
async getSensitiveKeywordList() {
const res = await Comment.getSensitiveKeywordList(this.formPage)
const ob = res.data
if (ob.code === 0) {
this.tableData = ob.data
Object.keys(this.form).forEach(item => {
if ( ob.data.sensitiveKeywordList[0] && ob.data.sensitiveKeywordList[0][item] !== undefined) {
this.form[item] = ob.data.sensitiveKeywordList[0][item]
}
})
}
},
changeItem() {
Comment.setSensitiveKeyword(this.form).then(res => {
if (res.data.code === 0) {
this.getSensitiveKeywordList()
}
})
},
addSensitiveKeyword() {
this.dialog = {
title: '新增',
visible: true,
info: {}
}
},
add(keyword) {
const _ = this
const key = _.dialog.edit ? 'editSensitiveKeyword' : 'addSensitiveKeyword'
if (_.dialog.edit) {
keyword.id = _.dialog.info.id
}
Comment[key](Object.assign({}, _.form, keyword )).then(res => {
if (res.data.code === 0) {
_.getSensitiveKeywordList()
_.$message.success(`${_.dialog.edit ? '修改' : '新增'}成功`)
_.close()
}
})
},
close() {
this.dialog = {}
},
fetch() {
this.getSensitiveKeywordList()
},
reset() {
this.formPage.keyword = ''
},
edit(item) {
this.dialog = {
title: '修改',
visible: true,
edit: true,
info: item
}
},
deletes(id) {
const _ = this
_.$confirm('确定要删除该条敏感词', `删除`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Comment.deleteSensitiveKeyword({ id }).then(res => {
if (res.data.code === 0) {
_.$message.success('删除成功')
_.getSensitiveKeywordList()
}
})
})
}
}
}
</script>
<style lang='less' scoped>
.sensitive_word_page {
margin-top: 10px;
background-color: #fff;
height: calc(100% - 10px);
padding: 20px 30px;
.setting {
height: 80px;
}
}
/deep/ .el-form-item__label {
text-align: left !important;
font-weight: 400;
}
/deep/.el-form-item {
margin-right: 50px;
}
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
// text-align: center;
}
td {
font-size: 14px;
// text-align: center;
color: #666666;
}
}
/deep/ .el-dialog__wrapper {
.el-dialog__header {
height: 70px;
background-color: #3A68F2;
.el-dialog__title {
font-size:24px;
color: #fff;
}
}
}
</style>

97
src/views/customer-manage/custom/custom-info/component/address/index.vue

@ -0,0 +1,97 @@
<template>
<div class="order_page">
<el-table
:data="tableData.records"
border
style="width: 80%"
>
<el-table-column
prop="username"
label="收货人"
/>
<el-table-column
prop="phone"
label="联系电话"
/><el-table-column
prop="address"
label="地址"
/>
</el-table>
<pagination
v-show="tableData.total > 0"
:limit.sync="form.size"
:page.sync="form.current"
:total="Number(tableData.total)"
@pagination="fetch"
/>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import Member from '@/api/Member'
export default {
components: {
Pagination
},
data() {
return {
form: {
"current": 1,
"map": {},
"model": {
"address": "",
"area": "",
"city": "",
"cityInfo": "",
"id": 0,
"isDefault": true,
"mid": 0,
"phone": "",
"province": "",
"tag": "",
"username": ""
},
"order": "descending",
"size": 10,
"sort": "id"
},
tableData: {}
}
},
created() {
this.getMemberAddress()
},
methods: {
async getMemberAddress() {
this.form.model.mid = this.$route.query.id
const res = await Member.getMemberAddress(this.form)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
fetch() {
this.getMemberAddress()
}
}
}
</script>
<style lang='less' scoped>
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
text-align: center;
}
td {
font-size: 14px;
text-align: center;
color: #666666;
}
}
</style>

157
src/views/customer-manage/custom/custom-info/component/comment/index.vue

@ -0,0 +1,157 @@
<template>
<div class="order_page">
<el-table
:data="tableData.commentDTOList"
border
style="width: 80%"
>
<el-table-column
prop="storeName"
label="店铺名称"
/>
<el-table-column
prop="productName"
label="商品名称"
/>
<el-table-column label="操作">
<template
slot-scope="scope"
>
<el-button
type="text"
size="small"
@click.native.prevent="details(scope.row)"
>
查看
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.total > 0"
:limit.sync="form.pageSize"
:page.sync="form.pageIndex"
:total="Number(tableData.total)"
@pagination="fetch"
/>
<Dialog
:title="dialog.title"
:visible.sync="dialog.visible"
:fullscreen="!true"
:before-close="close"
width="55%"
>
<detail v-if="dialog.visible" :info="dialog.info" @deletes="deletes" @handle="handle" />
</Dialog>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import { Dialog } from 'element-ui'
import detail from '@/views/comment/comment-manage/details'
import Member from '@/api/Member'
import Comment from '@/api/Comment'
export default {
components: {
Pagination,
Dialog,
detail
},
data() {
return {
form: {
pageIndex: 1,
pageSize: 10
},
tableData: {},
dialog: {}
}
},
created() {
this.getCommentList()
},
methods: {
async getCommentList() {
this.form.mid = this.$route.query.id
const res = await Member.getCommentList(this.form)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
details(info) {
this.dialog = {
title: '评论详情',
visible: true,
info
}
},
close() {
this.dialog = {}
},
deletes(id) {
const _ = this
const params = {
id: id || _.dialog.info.id,
action: 3
}
_.$confirm('删除后将无法恢复评论', '删除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Comment.handleComment(params).then(res => {
if (res.data.code === 0) {
_.dialog = {}
_.getList()
_.$message.success('删除成功')
}
})
})
},
handle(item) {
const _ = this
const ob = item || _.dialog.info
const params = {
id: ob.id,
action: ob.hideFlag ? 1 : 2
}
const t = ob.hideFlag ? '显示' : '隐藏'
_.$confirm(`确定要${t}该评论`, `${t}评论`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Comment.handleComment(params).then(res => {
if (res.data.code === 0) {
_.getList()
_.$message.success(`${t}成功`)
}
})
})
},
fetch() {
this.getCommentList()
}
}
}
</script>
<style lang='less' scoped>
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
text-align: center;
}
td {
font-size: 14px;
text-align: center;
color: #666666;
}
}
</style>

143
src/views/customer-manage/custom/custom-info/component/label/index.vue

@ -0,0 +1,143 @@
<template>
<div class="label_page">
<el-dialog
:title="dialog.title"
:visible.sync="dialog.visible"
width="40%"
:before-close="close"
>
<el-form label-width="100px">
<el-form-item label="标签名称">
<el-col :span="12">
<el-input v-model="form.model.name" />
</el-col>
<el-col :span="6" class="el_col_text">
<el-button @click="fetch">查询</el-button>
</el-col>
<el-col :span="6" class="el_col_text">
<span @click="manageTag">管理标签</span>
</el-col>
</el-form-item>
<el-form-item>
<el-row>
<el-checkbox-group v-model="checkList">
<el-row v-for="(item, index) in tableData.records" :key="index">
<el-checkbox :label="item.id">{{ item.name }}</el-checkbox>
</el-row>
</el-checkbox-group>
</el-row>
<el-row>
<pagination
v-show="tableData.total > 0"
:limit.sync="form.size"
:page.sync="form.current"
:total="Number(tableData.total)"
@pagination="fetch"
/>
</el-row>
</el-form-item>
</el-form>
<div style="text-align:center;">
<el-button @click="close"> </el-button>
<el-button type="primary" @click="confirm"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import Label from '@/api/Label'
import Pagination from '@/components/Pagination'
export default {
components: {
Pagination
},
props: {
dialog: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
form: {
"current": 1,
"map": {},
"model": {
"name": "",
"type": ''
},
"order": "descending",
"size": 10,
"sort": "id"
},
checkList: [],
list: [
{ name: '潜在客户', id: '1' },
{ name: '土豪', id: '2' },
{ name: '小气', id: '3' }
],
tableData: {}
}
},
created() {
this.getLabelList()
this.queryTag()
},
methods: {
async getLabelList() {
const res = await Label.getLabelList(this.form)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
async queryTag () {
const res = await Label.queryTag(this.dialog.id)
const resData = res.data
const t = []
if (resData.code === 0) {
if (resData.data.length) {
resData.data.forEach(item => {
t.push(item.tagId)
})
}
this.checkList = t
}
},
fetch() {
this.getLabelList()
},
manageTag() {
this.$router.push({ path: '/customer-manage/label' })
},
close() {
this.$emit('close')
},
confirm() {
this.$emit('confirm', this.checkList)
}
}
}
</script>
<style lang='less' scoped>
.label_page {
.el_col_text {
text-align:center;
font-size: 14px;
color: #3A68F2;
&:hover {
cursor:pointer;
}
}
}
/deep/ .el-dialog__body {
width: 80%;
margin: 0 auto;
}
</style>

124
src/views/customer-manage/custom/custom-info/component/order/index.vue

@ -0,0 +1,124 @@
<template>
<div class="order_page">
<el-form inline>
<el-form-item label="订单ID">
<el-input v-model="form.Keyword" size="mini" />
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini">查询</el-button>
<el-button size="mini" @click="query">查询</el-button>
</el-form-item>
</el-form>
<el-table
:data="tableData.adminOrderDTOList"
border
style="width: 80%"
>
<el-table-column
prop="id"
label="订单ID"
/>
<el-table-column
prop="storeName"
label="店铺名称"
/>
<el-table-column
prop="productCount"
label="商品数量"
/>
<el-table-column
prop="paySum"
:formatter="getPrice"
label="订单金额(元)"
/>
<el-table-column
prop="orderStatus"
:formatter="getStatus"
label="状态"
/>
</el-table>
<pagination
v-show="tableData.total > 0"
:limit.sync="form.pageSize"
:page.sync="form.pageIndex"
:total="Number(tableData.total)"
@pagination="query"
/>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import Member from '@/api/Member'
export default {
components: {
Pagination
},
data() {
return {
form: {
Keyword: '',
pageIndex: 1,
pageSize: 10,
keywordType: 1
},
tableData: {}
}
},
created() {
this.getOrderList()
},
methods: {
async getOrderList() {
this.form.mid = this.$route.query.id
const res = await Member.getOrderList(this.form)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
getStatus(row, item, value) {
const ob = {
1: '待付款',
2: '待发货',
3: '待收货',
4: '已完成',
5: '已取消'
}
return ob[value]
},
getPrice(row, item, value) {
return value / 100
},
query() {
this.getOrderList()
},
reset() {
this.form = {
Keyword: '',
pageIndex: 1,
pageSize: 10,
keywordType: 1
}
}
}
}
</script>
<style lang='less' scoped>
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
text-align: center;
}
td {
font-size: 14px;
text-align: center;
color: #666666;
}
}
</style>

272
src/views/customer-manage/custom/custom-info/index.vue

@ -0,0 +1,272 @@
<template>
<div class="custom_info_page">
<h2>客户信息</h2>
<div class="custom_info">
<div class="info_item">
<img :src="memberBaseInfo.headimg" alt="" />
</div>
<div class="info_item">
<ul>
<li v-for="(item, index) in infoList" :key="index">
<p>
<span>{{ item.name }} : </span>
<span>{{ item.value }}</span>
</p>
</li>
</ul>
</div>
</div>
<div class="custom_tag">
<h2>客户标签</h2>
<p v-for="(item,index) in tagList" :key="index">{{ item.tagName }}</p>
<p @click="addTag">贴标签</p>
</div>
<div class="custom_data">
<h2>消费数据</h2>
<div class="data_list">
<p><span> : <font>{{ customData.orderCount }}</font></span> 支付成功数: <font>{{ customData.payOrderCount }}</font></p>
<p><span>售后次数: <font>{{ customData.returnCount }}</font></span> 售后单数: <font>{{ customData.returnOrderCount }}</font></p>
</div>
<div class="tab_list">
<p v-for="(item,index) in tabList" :key="index" :class="[{'active': componentName === item.componentName}]" @click="changeTab(item)">
{{ item.tabName }}
</p>
</div>
<div class="component_content">
<component :is="componentName" />
</div>
</div>
<labels v-if="dialog.visible" :dialog="dialog" @close="close" @confirm="confirm" />
</div>
</template>
<script>
import order from './component/order/index'
import comment from './component/comment/index'
import addressInfo from './component/address/index'
import Member from '@/api/Member'
import labels from './component/label/index'
export default {
components: {
order,
comment,
addressInfo,
labels
},
data() {
return {
infoList: [
{ name: '用户昵称', value: '', fields: 'nickname' },
{ name: '手 机 号', value: '', fields: 'phone' },
{ name: '性 别', value: '', fields: 'sex' },
{ name: '注册时间', value: '', fields: 'createTime' },
{ name: '生 日', value: '', fields: 'birth' }
],
tagList: [],
tabList: [
{ tabName: 'TA的订单', componentName: 'order' },
{ tabName: 'TA的评论', componentName: 'comment' },
{ tabName: 'TA的收货地址', componentName: 'addressInfo' }
],
componentName: 'order',
customData: {},
memberBaseInfo: {},
dialog: {}
}
},
created() {
this.getMemberInfo()
this.getCustomData()
},
methods: {
async getMemberInfo() {
const res = await Member.getMemberInfo(this.$route.query.id)
const resData = res.data
if (resData.code === 0) {
const t = resData.data
this.tagList = t.memberTagList
this.memberBaseInfo = t.memberBaseInfo
this.getInfoList(t.memberBaseInfo || {})
}
},
async getCustomData() {
const res = await Member.getCustomData(this.$route.query.id)
const resData = res.data
if (resData.code === 0) {
this.customData = resData.data
}
},
//
getInfoList(ob) {
const _ = this
_.infoList.map(item => {
item.value = ob[item.fields] || ''
if (item.fields === 'sex') {
item.value = item.value === '1' ? '男' : '女'
}
})
},
//
addTag() {
this.dialog = {
title: '选择标签',
visible: true,
id: this.$route.query.id
}
},
confirm(ids) {
const params = {
mid: this.$route.query.id,
tagIds: ids
}
const _ = this
Member.addTag(params).then(res => {
if (res.data.code === 0) {
_.$message.success('操作成功')
_.getMemberInfo()
_.close()
}
})
},
close() {
this.dialog = {}
},
changeTab(item) {
this.componentName = item.componentName
}
}
}
</script>
<style lang='less' scoped>
h2 {
font-size: 24px;
font-weight: 500;
position: relative;
&::before {
content: '';
height: 24px;
width: 4px;
background-color: #3A68F2;
position: absolute;
left: -10px;
top: 2px;
display: block;
}
}
.custom_info_page {
margin-top: 20px;
padding: 20px 100px;
background-color: #fff;
min-height: 500px;
.custom_info {
overflow: hidden;
margin-bottom: 30px;
.info_item {
float: left;
&:nth-child(1) {
height: 180px;
width: 100px;
img {
width: 100px;
height: 100px;
border-radius: 50px;
text-align: center;
margin-top: 40px;
}
}
&:nth-child(2) {
width: 50%;
ul {
overflow: hidden;
list-style: none;
li {
float: left;
p {
font-size: 16px;
color: #333;
span:nth-child(2) {
color: #666;
}
}
&:nth-child(odd) {
width: 30%;
}
&:nth-child(even) {
width: 70%;
}
}
}
}
}
}
.custom_tag {
margin-bottom: 30px;
p {
display: inline-block;
background-color: #D8E1FC;
font-size: 16px;
color: #333;
text-align: center;
margin-right: 20px;
border-radius: 4px;
padding: 8px 15px;
&:last-child {
background-color: #fff;
color: #3A68F2;
&:hover {
cursor: pointer;
}
}
}
}
.custom_data {
.data_list {
p {
font-size: 16px;
font{
color:#666;
}
span {
display: inline-block;
width: 200px;
}
}
}
.tab_list {
overflow: hidden;
p {
float: left;
padding: 0 50px;
font-size: 16px;
border: 1px #E0E5EB solid;
box-sizing: border-box;
color: #999999;
height: 48px;
line-height: 48px;
&:nth-child(-n + 2) {
border-right: 0;
}
&:nth-child(1) {
border-radius: 4px 0 0 4px;
}
&:nth-child(3) {
border-radius: 0 4px 4px 0;
}
&:hover {
cursor: pointer;
}
}
.active {
background-color: #3A68F2;
color: #fff;
border: 0;
}
}
}
}
</style>

340
src/views/customer-manage/custom/index.vue

@ -0,0 +1,340 @@
<template>
<div class="custom_page">
<div class="content">
<div class="toolbar">
<el-form
:model="formParams"
label-width="120px"
>
<el-row>
<el-col :span="20">
<el-row>
<el-col :span="5">
<el-form-item label="客户昵称">
<el-input v-model="formParams.model.nickname" size="mini" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="手机号">
<el-input v-model="formParams.tel" size="mini" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="标签">
<el-input v-model="formParams.model.tagId" size="mini" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="最近消费时间">
<el-date-picker
v-model="date"
size="mini"
type="daterange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="yyyy-MM-dd"
@change="handleChange"
/>
</el-form-item>
</el-col>
</el-row>
<el-row v-show="showMore">
<el-col :span="5">
<el-form-item label="累计金额">
<el-col :span="11">
<el-input v-model="formParams.model.totalConsumAmountStart" size="mini" />
</el-col>
<el-col :span="2" style="text-align: center;color: #DCDFE6;">
-
</el-col>
<el-col :span="11">
<el-input v-model="formParams.model.totalConsumAmountEnd" size="mini" />
</el-col>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="购买次数">
<el-col :span="11">
<el-input v-model="formParams.model.buyTimesStart" size="mini" />
</el-col>
<el-col :span="2" style="text-align: center;color: #DCDFE6;">
-
</el-col>
<el-col :span="11">
<el-input v-model="formParams.model.buyTimesEnd" size="mini" />
</el-col>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="4">
<el-form-item label-width="0">
<el-button
type="primary"
size="mini"
@click="query"
>
查询
</el-button>
<el-button
plain
size="mini"
@click="reset"
>
重置
</el-button>
<span style="margin-left: 10px;dispaly:inline-block;font-size: 16px;" @click="dispalyMore">
<i :class="[showMore?'el-icon-arrow-up':'el-icon-arrow-down']"></i>
</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div class="content_table">
<div class="table">
<el-table
:data="tableData.records"
border
style="width: 100%"
>
<el-table-column
prop="nickname"
label="客户昵称"
/>
<el-table-column
prop="phone"
label="手机号"
/>
<el-table-column
prop="expendAmount"
label="消费总额"
:formatter="getPrice"
/>
<el-table-column
prop="buyTimes"
label="购买次数"
/>
<el-table-column
prop="lastBuyTime"
label="最近消费时间"
/>
<el-table-column
prop="registerTime"
label="注册时间"
/>
<el-table-column label="操作">
<template
slot-scope="scope"
>
<el-button
type="text"
size="small"
@click.native.prevent="details(scope.row.id)"
>
详情
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="makeTag(scope.row.id)"
>
打标签
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="addBlackList(scope.row)"
>
{{ scope.row.status ? '取消黑名单' : '加入黑名单' }}
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<pagination
v-show="tableData.total > 0"
:limit.sync="formParams.size"
:page.sync="formParams.current"
:total="Number(tableData.total)"
@pagination="fetch"
/>
</div>
</div>
<labels v-if="dialog.visible" :dialog="dialog" @close="close" @confirm="confirm" />
</div>
</template>
<script>
import Member from '@/api/Member'
import Pagination from '@/components/Pagination'
import labels from './custom-info/component/label/index'
export default {
components: {
Pagination,
labels
},
data() {
return {
showMore: false,
formParams: {
size: 10,
current: 1,
model: {
buyTimesStart: '',
buyTimesEnd: '',
totalConsumAmountStart: '',
totalConsumAmountEnd: '',
nickname: '',
tagId: '',
lastConsumTimeStart: '',
lastConsumTimeEnd: ''
}
},
date: [],
tableData: {},
dialog: {}
}
},
created() {
this.getList()
},
methods: {
async getList() {
const res = await Member.getMemberList(this.formParams)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
getPrice(row, item, value) {
return value / 100
},
query() {
this.getList()
},
details(id) {
this.$router.push({ path: '/customer-manage/custom-info', query: { id }})
},
makeTag(id) {
this.dialog = {
title: '选择标签',
visible: true,
id
}
},
confirm(ids) {
const params = {
mid: this.dialog.id,
tagIds: ids
}
const _ = this
Member.addTag(params).then(res => {
if (res.data.code === 0) {
_.$message.success('操作成功')
_.getList()
_.close()
}
})
},
addBlackList(item) {
const _ = this
_.$confirm(`${item.status ? '确认是否取消黑名单' : '加入黑名单后,对方将无法登录商城'}`, `${item.status ? '取消黑名单' : '加入黑名单'}`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Member.forbiddenMember({ mid: item.id, status: !item.status }).then(res => {
if (res.data.code === 0) {
_.getList()
_.$message.success(`成功${item.status ? '取消' : '加入'}黑名单`)
}
})
})
},
close() {
this.dialog = {}
},
reset() {
this.formParams = {
size: 10,
current: 1,
model: {
buyTimesStart: '',
buyTimesEnd: '',
totalConsumAmountStart: '',
totalConsumAmountEnd: '',
nickname: '',
tagId: '',
lastConsumTimeStart: '',
lastConsumTimeEnd: ''
}
}
},
fetch() {
this.getList()
},
selectItem() {
this.getList()
},
handleChange(value) {
this.formParams.model.lastConsumTimeStart = (value && value[0]) || ''
this.formParams.model.lastConsumTimeEnd = (value && value[1]) || ''
},
dispalyMore() {
this.showMore = !this.showMore
}
}
}
</script>
<style lang='less' scoped>
.custom_page{
padding: 10px 20px;
box-sizing: border-box;
.content {
background-color: #fff;
padding: 20px;
.toolbar {
padding: 10px;
}
}
}
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
text-align: center;
}
td {
font-size: 14px;
text-align: center;
color: #666666;
}
}
/deep/ .el-dialog__wrapper {
.el-dialog__header {
height: 70px;
background-color: #3A68F2;
.el-dialog__title {
font-size:24px;
color: #fff;
}
}
}
/deep/ .el-message-box__btns .el-button {
margin-right: 10px !important;
}
</style>

290
src/views/customer-manage/label/add.vue

@ -0,0 +1,290 @@
<template>
<div class="add_page">
<div class="header">
{{ title }}
<div class="btn_list">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</div>
</div>
<div class="add_content">
<el-form label-width="80px">
<el-form-item label="标签名称">
<el-input v-model="form.name" placeholder="最多输入32个字符" />
</el-form-item>
<el-form-item label="标签类型">
<el-radio-group v-model="form.type">
<el-radio :label="1">手动标签</el-radio>
<el-radio :label="2">自动标签</el-radio>
</el-radio-group>
</el-form-item>
<div v-if="form.type===2" class="auto_label">
<el-form-item label="满足条件">
<el-radio-group v-model="form.meetCondition">
<el-radio :label="1">满足任意选中的条件即可</el-radio>
<el-radio :label="2">必须满足所有选被中的条件</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="交易条件">
<el-checkbox-group v-model="checkBox">
<el-row>
<el-checkbox :label="1" name="config">最后消费时间</el-checkbox>
<el-row>
<el-radio-group v-model="form.config.lastConsumTime.type">
<el-row class="indent">
<el-radio :label="1">最近</el-radio>
<el-select
v-model="form.config.lastConsumTime.value"
style="width:70px"
:disabled="form.config.lastConsumTime.type === 2 || !checkBox.includes(1)"
>
<el-option
v-for="(item, index) in dayList"
:key="index"
:label="item.label"
:value="item.label"
/>
</el-select>
<span style="font-size: 16px;margin-left: 10px;"></span>
</el-row>
<el-row class="indent">
<el-radio :label="2">自定义</el-radio>
<el-date-picker
v-model="date"
:disabled="form.config.lastConsumTime.type === 1 || !checkBox.includes(1)"
type="daterange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="yyyy-MM-dd"
@change="handleChange"
/>
</el-row>
</el-radio-group>
</el-row>
</el-row>
<el-row>
<el-checkbox :label="2" name="config">累计消费次数</el-checkbox>
<el-row class="indent">
<el-col :span="3" class="unit">
<el-input v-model="totalConsumTimes.start" :disabled="!checkBox.includes(2)" />
<span></span>
</el-col>
<el-col :span="1" style="font-size: 16px;text-align: center;">
</el-col>
<el-col :span="3" class="unit">
<el-input v-model="totalConsumTimes.end" :disabled="!checkBox.includes(2)" />
<span></span>
</el-col>
</el-row>
</el-row>
<el-row>
<el-checkbox :label="3" name="config">累计消费金额</el-checkbox>
<el-row class="indent">
<el-col :span="3" class="unit">
<el-input v-model="totalConsumAmount.start" :disabled="!checkBox.includes(3)" />
<span></span>
</el-col>
<el-col :span="1" style="font-size: 16px;text-align: center;">
</el-col>
<el-col :span="3" class="unit">
<el-input v-model="totalConsumAmount.end" :disabled="!checkBox.includes(3)" />
<span></span>
</el-col>
</el-row>
</el-row>
</el-checkbox-group>
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script>
import Label from '@/api/Label'
export default {
data() {
return {
form: {
name: '',
meetCondition: 1,
type: 1,
config: {
totalConsumTimes: '',
lastConsumTime: {
type: 1,
value: 3
},
totalConsumAmount: ''
}
},
checkBox: [],
totalConsumTimes: {
start: '',
end: ''
},
totalConsumAmount: {
start: '',
end: ''
},
num: '',
date: [],
dayList: [
{ label: 3 },
{ label: 7 },
{ label: 15 },
{ label: 30 },
{ label: 45 },
{ label: 60 }
]
}
},
computed: {
title() {
const ob = {
edit: '修改标签',
add: '创建标签'
}
return ob[this.$route.query.type]
}
},
created() {
this.$route.meta.title = this.title
this.getTagInfo()
},
methods: {
async getTagInfo() {
const info = this.$route.query
if (info.type === 'add') return
const res = await Label.getTagInfo(info.id)
const resData = res.data
if (resData.code === 0) {
const ob = resData.data
Object.keys(this.form).forEach(item => {
this.form[item] = ob[item]
if (item === 'config') {
this.totalConsumAmount = this.changeFields(ob.config.totalConsumAmount, true)
this.totalConsumTimes = this.changeFields(ob.config.totalConsumTimes, false)
this.form.config.lastConsumTime.value = this.changeTime(ob.config.lastConsumTime)
}
})
}
},
handleChange(value) {
// this.form.config.lastConsumTime.value = `${(value && value[0]) || ''}${value && value[0] ? '' : ''}${(value && value[1]) || ''}`
},
getDate(obj) {
const value = this.date
if (obj.type === 2) {
obj.value = `${(value && value[0]) || ''}${value && value[0] ? '至' : ''}${(value && value[1]) || ''}`
}
},
save() {
const _ = this
const query = _.$route.query
const ob = {
edit: 'editTag',
add: 'addLabel'
}
if (query.type === 'edit') {
_.form.id = query.id
}
_.form.config.totalConsumTimes = this.assemblyFields(_.totalConsumTimes.start, _.totalConsumTimes.end, false)
_.form.config.totalConsumAmount = this.assemblyFields(_.totalConsumAmount.start, _.totalConsumAmount.end, true)
_.getDate(_.form.config.lastConsumTime)
Label[ob[query.type]](this.form).then(res => {
if (res.data.code === 0) {
_.$message.success('新增成功')
_.cancel()
}
})
},
cancel() {
this.$router.push({ path: '/customer-manage/label' })
},
assemblyFields(val1, val2, boo) {
let t = ''
if (val1 || val2) {
t = boo ? `${val1 * 100}-${val2 * 100}` : `${val1}-${val2}`
}
return t
},
changeFields(obj, flag) {
const ob = {
start: '',
end: ''
}
if (obj) {
const t = obj.split('-')
ob.start = flag ? t[0] / 100 : t[0]
ob.end = flag ? t[1] / 100 : t[1]
flag ? this.checkBox.push(3) : this.checkBox.push(2)
}
return ob
},
changeTime(obj) {
let value = 3
if (obj) {
this.checkBox.push(1)
if (obj.type === 2) {
this.date = obj.value.split('至')
} else {
value = obj.value
}
}
return value
}
}
}
</script>
<style lang='less' scoped>
.add_page {
margin-top: 20px;
padding: 20px;
background-color: #fff;
.header {
height: 80px;
line-height: 80px;
font-size: 24px;
border-bottom: 1px solid #E0E5EB;
.btn_list {
float: right;
}
}
.add_content {
width: 60%;
margin: 20px auto;
.indent {
padding-left: 20px;
margin-bottom: 15px;
box-sizing: border-box;
}
.auto_label {
background-color: #F7F7F7;
border-radius: 4px;
overflow: hidden;
}
}
}
/deep/ .unit {
position: relative;
span {
position: absolute;
right: 0;
font-size: 16px;
border-left: 1px solid #DCDFE6;
padding: 0 8px;
}
.el-input__inner {
padding: 0 40px 0 5px ;
}
}
</style>

299
src/views/customer-manage/label/index.vue

@ -0,0 +1,299 @@
<template>
<div class="label_page">
<el-form inline>
<el-form-item style="margin-right:0;">
<el-select
v-model="form.model.type"
size="mini"
style="width: 130px;"
>
<el-option
v-for="(item, index) in typeList"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-input
v-model="form.model.name"
size="mini"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="fetch">查询</el-button>
<el-button size="mini" @click="reset">重置</el-button>
</el-form-item>
<el-form-item style="float:right;">
<el-button type="primary" size="mini" @click="add">新建标签</el-button>
<el-button size="mini" @click="exportTag">导出标签</el-button>
</el-form-item>
</el-form>
<el-table
ref="multipleTable"
:data="tableData.records"
border
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
/>
<el-table-column
prop="name"
label="标签名"
/>
<el-table-column
prop="tagCount"
label="客户"
/>
<el-table-column
prop="type"
label="标签类型"
:formatter="getType"
/>
<el-table-column
prop="tradeCondition"
label="打标条件"
>
<template slot-scope="scope">
<span v-if="scope.row.type===1">未设置</span>
<p v-else class="condition">
<span>{{ getCondition(scope.row.config) }}</span>
<span @click="moreCondition(scope.row)">查看更多</span>
</p>
</template>
</el-table-column>
<el-table-column label="操作">
<template
slot-scope="scope"
>
<el-button
type="text"
size="small"
@click.native.prevent="edit(scope.row.id)"
>
编辑
</el-button>
<el-button
type="text"
size="small"
@click.native.prevent="deletes(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="batch_btn">
<el-button :disabled="!multipleSelection.length" @click="deletes(false)">批量删除</el-button>
</div>
<pagination
v-show="tableData.total > 0"
:limit.sync="form.size"
:page.sync="form.current"
:total="Number(tableData.total)"
@pagination="fetch"
/>
<Dialog
:title="dialog.title"
:visible.sync="dialog.visible"
:fullscreen="!true"
:before-close="close"
width="35%"
>
<more v-if="dialog.visible" :info="dialog.info" @close="close" />
</Dialog>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import Label from '@/api/Label'
import { Dialog } from 'element-ui'
import more from './more'
import { downloadFile } from '@/utils/commons'
// import {getIntervalTime} from '@/utils/date'
export default {
components: {
Pagination,
Dialog,
more
},
data() {
return {
form: {
"current": 1,
"map": {},
"model": {
"name": "",
"type": ''
},
"order": "descending",
"size": 10,
"sort": "id"
},
typeList: [
{ label: '全部标签类型', value: '' },
{ label: '手动标签', value: 1 },
{ label: '自动标签', value: 2 }
],
tableData: {},
multipleSelection: [],
dialog: {}
}
},
created() {
this.getLabelList()
},
methods: {
async getLabelList() {
const res = await Label.getLabelList(this.form)
const resData = res.data
if (resData.code === 0) {
this.tableData = resData.data
}
},
getType(row, item, value) {
return Number(value) === 1 ? '手动标签' : '自动标签'
},
add() {
this.$router.push({ path: '/customer-manage/label/add', query: { type: 'add' }})
},
handleSelectionChange(val) {
this.multipleSelection = val
},
fetch() {
this.getLabelList()
},
reset() {
this.form = {
"current": 1,
"map": {},
"model": {
"name": "",
"type": ''
},
"order": "descending",
"size": 10,
"sort": "id"
}
},
edit(id) {
this.$router.push({ path: '/customer-manage/label/add', query: { type: 'edit', id }})
},
exportTag() {
Label.exportTag(this.form).then(res => {
downloadFile(res)
})
},
deletes(id) {
const _ = this
let ids = []
if (id) {
ids = [id]
} else {
this.multipleSelection.forEach(item => {
ids.push(item.id)
})
}
_.$confirm( `确认要${id ? '删除本' : '批量删除所选'}标签吗`, `${id ? '删除' : '批量删除'}标签`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
Label.deleteTag({ ids }).then(res => {
if (res.data.code === 0) {
_.getLabelList()
_.$message.success('操作成功')
}
})
})
},
getCondition (obj) {
let t = ''
t += `最后消费时间在${obj.lastConsumTime.value}${obj.lastConsumTime.type === 1 ? '天' : ''}内;`
if (obj.totalConsumTimes) {
const times = obj.totalConsumTimes.split('-')
t += `累计成功交易在${times[0]}-${times[1]}`
}
if (obj.totalConsumAmount) {
const amount = obj.totalConsumAmount.split('-')
t += `累计消费金额在${amount[0] / 100}-${amount[1] / 100}`
}
return t
},
moreCondition(item) {
this.dialog = {
title: '打标详情',
info: item,
visible: true
}
},
close() {
this.dialog = {}
}
}
}
</script>
<style lang='less' scoped>
.label_page {
margin-top: 20px;
background-color:#fff;
padding:20px;
.batch_btn {
padding: 5px 10px;
border: 1px solid #dfe6ec;
border-top: 0;
}
.condition {
span{
display: block;
&:nth-child(1) {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
&:nth-child(2) {
color: #1682e6;
text-align: left;
&:hover {
cursor: pointer;
}
}
}
}
}
/deep/ .el-table {
th {
background: #EEF3FF;
color:#333333;
font-size:16px;
font-weight: 400;
border-color: #E0E5EB;
text-align: center;
}
td {
font-size: 14px;
text-align: center;
color: #666666;
}
}
/deep/ .el-dialog__wrapper {
.el-dialog__header {
height: 70px;
background-color: #3A68F2;
.el-dialog__title {
font-size:24px;
color: #fff;
}
}
}
</style>

91
src/views/customer-manage/label/more.vue

@ -0,0 +1,91 @@
<template>
<div class="more_page">
<h2>{{ getTitle(info.meetCondition) }}</h2>
<div class="condition">
<p>交易条件:</p>
<p>
<span v-for="(item, index) in list" :key="index">{{ item }}</span>
</p>
</div>
<el-button type="primary" @click="close">我知道了</el-button>
</div>
</template>
<script>
export default {
props: {
info: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
list: ['最后消费时间在30天内', '累计成功交易在3-4次', '累计消费金额在100-200元']
}
},
created() {
this.getData()
},
methods: {
getData() {
const arr = []
const obj = this.info.config
arr.push(`最后消费时间在${obj.lastConsumTime.value}${obj.lastConsumTime.type === 1 ? '天' : ''}`)
if (obj.totalConsumTimes) {
const times = obj.totalConsumTimes.split('-')
arr.push(`累计成功交易在${times[0]}-${times[1]}`)
}
if (obj.totalConsumAmount) {
const amount = obj.totalConsumAmount.split('-')
arr.push(`累计消费金额在${amount[0] / 100}-${amount[1] / 100}`)
}
this.list = arr
},
getTitle(v) {
return v === 1 ? '满足以下任意条件即可' : '必须满足以下所有条件'
},
close() {
this.$emit('close')
}
}
}
</script>
<style scoped lang='less'>
.more_page {
width: 80%;
margin: 0 auto;
color: #333;
text-align: center;
h2 {
font-size: 24px;
font-weight: 400;
}
.condition {
overflow: hidden;
p {
font-size: 16px;
float: left;
&:nth-child(1) {
width: 30%;
text-align: right;
padding-right:10px;
box-sizing: border-box;
}
&:nth-child(2) {
text-align: left;
width: 70%;
span {
display: block;
}
}
}
}
}
</style>

8
src/views/finance/cash-deposit/index.vue

@ -78,12 +78,13 @@
label="活动名称"
/>
<el-table-column
prop="orderCode"
prop="transactionId"
label="交易流水号"
/>
<el-table-column
prop="amount"
label="保证金金额"
:formatter="getPrice"
/>
<el-table-column
prop="state"
@ -159,9 +160,12 @@ export default {
const res = await Finance.getDepositSum()
const resData = res.data
if (resData.code === 0) {
vm.total = resData.data.total || 0
vm.total = resData.data.total / 100
}
},
getPrice(row, item, value) {
return value / 100
},
reset() {
this.formParams = {
size: 10,

6
src/views/finance/cash/details.vue

@ -72,12 +72,6 @@ export default {
this.info = d
this.dataList.map(item => {
item.value = d[item.field]
if (item.field === 'cardholderName') {
item.value = `${item.value.slice(0, 1)}**`
}
if (item.field === 'cardNumber') {
item.value = `${item.value.slice(0, 4)}****************`
}
})
Object.keys(this.params).map(item => {
this.params[item] = d[item]

3
src/views/login/index.vue

@ -6,7 +6,8 @@
class="login-form" label-position="left"
>
<div class="title-container">
<h3 class="title">{{ $t('login.title') }}平台登录</h3>
<h3 class="title">平台登录</h3>
<!-- {{ $t('login.title') }} -->
<!-- <lang-select class="set-language" /> -->
</div>
<span v-if="login.type === &quot;up&quot;">

2
src/views/management/apply/detail.vue

@ -226,7 +226,7 @@ export default {
item.value = `${o.companyAddressProvince || ''}${o.companyAddressCity || ''}${o.companyAddressDistrict || ''}${o.companyAddress || ''}`
}
if (item.field === 'businessTimeStart') {
item.value = `${o.businessTimeStart || ''}──${o.businessTimeEnd || ''}`
item.value = o.effectDateType === 1 ? '长期有效' : `${o.businessTimeStart || ''}──${o.businessTimeEnd || ''}`
}
})
},

6
src/views/management/apply/dialog.vue

@ -35,7 +35,7 @@
<el-col :span="18">
<el-input v-model.number="form.effectTimeLimit" placeholder="请输入生效时限" />
</el-col>
<el-col :span="2">
<el-col :span="2" class="unit">
</el-col>
</el-form-item>
@ -124,5 +124,7 @@ export default {
</script>
<style scoped lang='less'>
.unit {
text-indent: 15px;
}
</style>

19
src/views/marketing/add/index.vue

@ -18,29 +18,30 @@
<el-form-item label="活动介绍:">
<el-input v-model="form.description" type="textarea" placeholder="请输入活动介绍" :disabled="unStart" />
</el-form-item>
<!-- :picker-options="pickerOptions" -->
<el-form-item label="活动时间:">
<el-form-item label="报名时间:">
<el-date-picker
v-model="date1"
v-model="date2"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="yyyy-MM-dd HH:mm"
:disabled="applyEnd"
:picker-options="pickerOptions"
:picker-options="pickerOptions1"
/>
</el-form-item>
<el-form-item label="起止时间:">
<el-form-item label="活动时间:">
<el-date-picker
v-model="date2"
v-model="date1"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="yyyy-MM-dd HH:mm"
:picker-options="pickerOptions1"
:disabled="applyEnd"
:picker-options="pickerOptions"
/>
</el-form-item>
@ -76,7 +77,7 @@
<el-form-item v-for="(item,index) in list" :key="index">
<el-col :span="10">
<el-input v-model="item.fullAmount" style="width: 80%;" :disabled="unStart" />
</el-col>
<el-col :span="10">
@ -151,6 +152,7 @@ export default {
if (this.date1[0] !== "" && t && t.status === 2) {
return time.getTime() < new Date(this.date1[0]).getTime()
}
return ''
}
},
pickerOptions1: {
@ -159,6 +161,7 @@ export default {
if (this.date2[0] !== "" && t && (t.status === 3 || t.status === 4)) {
return time.getTime() < new Date(this.date2[0]).getTime()
}
return ''
}
}
}

2
src/views/marketing/details/info.vue

@ -83,7 +83,7 @@ export default {
vm.img = info.image
if (info.promotionDetail && info.promotionDetail.length) {
info.promotionDetail.forEach(item => {
vm.promotionDetail.push(`${item.fullAmount / 100}${item.discountAmount / 100}`)
vm.promotionDetail.push(`${item.fullAmount / 100}${item.discountAmount / 100}`)
})
}
}

4
src/views/marketing/details/shop.vue

@ -15,7 +15,7 @@
<el-form-item label="审核状态">
<el-select
v-model="formParams.status"
v-model="formParams.model.status"
size="mini"
>
<el-option
@ -162,7 +162,7 @@ export default {
model: {
storeName: '',
tenantCode: '',
status: '',
status: 2,
promotionId: this.params.id
},
size: 10,

63
src/views/menu/empower/index.vue

@ -5,47 +5,11 @@
<el-button type="primary" class="save_btn" :loading="loading" @click="save">保存</el-button>
</div>
<div class="empower_content">
<!-- <div class="item">
<div class="top_box">
平台菜单
<el-select v-model="type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="menu_tree">
<el-tree
ref="platFormTree"
:data="platFormMenu"
show-checkbox
default-expand-all
node-key="id"
highlight-current
:props="defaultProps"
/>
</div>
</div> -->
<!-- <div class="item">
<div class="btn_list">
<p @click="empower">
<img :src="right" alt="" />
</p>
<p @click="recycleMenu">
<img :src="left" alt="" />
</p>
</div>
</div> -->
<div class="item">
<div class="top_box">
<el-form inline label-width="100px">
<el-form-item class="select_type">
<el-select v-model="type" placeholder="请选择">
<el-select v-model="type" placeholder="请选择" @change="changeselect">
<el-option
v-for="item in options"
:key="item.value"
@ -54,9 +18,9 @@
/>
</el-select>
</el-form-item>
<el-form-item v-if="type" label="商家编号">
<el-form-item v-if="type" label="号">
<el-col :span="15">
<el-input v-model="form.tenantCode" placeholder="请输入商家编号" />
<el-input v-model="form.account" placeholder="请输入号" />
</el-col>
<el-col :span="6">
<el-button @click="getSpecialMerchantMenu">搜索</el-button>
@ -94,7 +58,7 @@ export default {
{ label: '同步指定商家', value: 1 }
],
type: 0,
tenantCode: '',
account: '',
defaultProps: {
children: 'children',
label: 'label'
@ -104,7 +68,7 @@ export default {
selected: [],
form: {
menuList: [],
tenantCode: null
account: null
},
allKeys: []
@ -119,7 +83,6 @@ export default {
}
},
created() {
// this.getPlatformMenu()
this.getAllMerchanMenu()
},
mounted() {
@ -133,6 +96,11 @@ export default {
this.$refs.merchantTree.setCheckedKeys([])
}
},
changeselect(v) {
if (!v) {
this.getAllMerchanMenu()
}
},
async getPlatformMenu() {
const res = await Menu.getPlatformMenu()
const resData = res.data
@ -164,10 +132,17 @@ export default {
},
//
async getSpecialMerchantMenu() {
const res = await Menu.getSpecialMerchantMenu(this.form.tenantCode)
const res = await Menu.getSpecialMerchantMenu(this.form.account)
const resData = res.data
if (resData.code === 0) {
this.form.menuList = resData.data
// this.form.menuList = resData.data
const t = resData.data
this.changeTreeData(t)
this.form.menuList = t
this.getSelected(t)
this.$nextTick(() => {
this.setCheckedNodes()
})
}
},
save() {

Loading…
Cancel
Save