Commit 5989cf86 by 曾经

Merge branch 'master' into feature/停复机1

* master: (255 commits)
  update: dist
  fix: 欢迎语文案修改
  update: dist
  update: 升级simple-transfer
  update: 调整vue-template-compiler版本号
  update: dist
  update: 文案
  Revert "update: dist"
  Revert "update: dist"
  update: dist
  update: dist
  update: dist
  update: dist
  update: dist
  update: dist
  update: 预览标题样式
  update: 活码图表单天时
  update: 下载文件名称
  update: dist
  update: dist
  ...

# Conflicts:
#	dist/index.html
#	dist/static/css/index.less
#	dist/static/css/public.css
#	dist/static/js/49.807401f5792ada71e97a.js
#	dist/static/js/50.6e0ff0963e754df4d083.js
#	dist/static/js/50.a1015b29c62714ed4720.js
#	dist/static/js/51.3d27cc017de523b3681b.js
#	dist/static/js/52.4e303a459cce381b78f2.js
#	dist/static/js/52.6787e341b6db605d59cb.js
#	dist/static/js/53.2054052aba70bb38ed8b.js
#	dist/static/js/54.bd74a8552e242d23a2a3.js
#	dist/static/js/55.32d0cfad0434efe88df4.js
#	dist/static/js/55.8e5a59b31576b8166215.js
#	dist/static/js/6.8ce178bff02820b743a4.js
#	dist/static/js/60.af2565e8989c037b9353.js
#	dist/static/js/64.8f931ae5c230a8078f56.js
#	dist/static/js/83.dd23d1e732f2559371c1.js
#	dist/static/js/84.9235b0acae13a0283193.js
#	dist/static/js/84.c38cae3e613a1118eead.js
#	dist/static/js/85.074b79f8ca7fec6cf035.js
#	dist/static/js/86.ef1bb7b695c60c7f8800.js
#	dist/static/js/94.9dd6925c4492cc34c03f.js
#	dist/static/js/96.0358ce4b94a445e60b6b.js
#	dist/static/js/97.b09d8bd34179f669239d.js
#	dist/static/js/app.a955176c1d2a2acb1da9.js
#	dist/static/js/manifest.094659dcdca9738443aa.js
#	index.html
#	package.json
#	src/api/actCode.js
#	src/api/api.js
#	src/assets/QRcode.png
#	src/assets/font/demo_index.html
#	src/assets/font/iconfont.css
#	src/assets/font/iconfont.js
#	src/assets/font/iconfont.json
#	src/assets/font/iconfont.ttf
#	src/assets/font/iconfont.woff
#	src/assets/font/iconfont.woff2
#	src/assets/iphone-head.png
#	src/components/common/links.vue
#	src/components/common/selectShop.vue
#	src/components/layout/index.vue
#	src/components/preview-page.vue
#	src/components/single-upload.vue
#	src/components/utils/directives.js
#	src/router/actCodeManageRouter/attractFlowLinkRouter.js
#	src/router/actCodeManageRouter/staffActCodeRouter.js
#	src/router/index.js
#	src/views/enterprise/salutatory.vue
#	src/views/enterprise/salutatoryIndex.vue
#	src/views/enterprise/salutatorySet.vue
#	src/views/salesleads/actCodeManage/attractFlowLink/detail.vue
#	src/views/salesleads/actCodeManage/attractFlowLink/index.vue
#	src/views/salesleads/actCodeManage/attractFlowLink/landingPage/cardView.vue
#	src/views/salesleads/actCodeManage/attractFlowLink/landingPage/detail.vue
#	src/views/salesleads/actCodeManage/attractFlowLink/landingPage/list.vue
#	src/views/salesleads/actCodeManage/attractFlowLink/landingPage/relationDialog.vue
#	src/views/salesleads/actCodeManage/components/select-clerk/index.vue
#	src/views/salesleads/actCodeManage/components/select-clerk/select-clerk.vue
#	src/views/salesleads/actCodeManage/components/select-clerk/selected-clerk-item.vue
#	src/views/salesleads/actCodeManage/staffActCode/actCodeDetail.vue
#	src/views/salesleads/actCodeManage/staffActCode/actCodeDetailStatistics.vue
#	src/views/salesleads/actCodeManage/staffActCode/actCodeRecord.vue
#	src/views/salesleads/actCodeManage/staffActCode/index.vue
#	src/views/salesleads/actCodeManage/staffActCode/newAddChart.vue
#	src/views/salesleads/actCodeManage/staffActCode/views/act-code-table.vue
#	src/views/salesleads/actCodeManage/staffActCode/views/batchAddCode.vue
#	src/views/salesleads/actCodeManage/staffActCode/views/group-list.vue
#	src/views/salesleads/actCodeManage/staffActCode/views/setActCode.vue
#	src/views/salesleads/components/actCodeDetailInfo.vue
#	src/views/salesleads/components/dataDetail.vue
#	src/views/salesleads/components/welcomesItem.vue
#	static/css/public.css
parents 2afbd796 7cf6242b
...@@ -18,7 +18,7 @@ module.exports = { ...@@ -18,7 +18,7 @@ module.exports = {
// Paths // Paths
assetsSubDirectory: 'static', assetsSubDirectory: 'static',
assetsPublicPath: '/haoban-3/', assetsPublicPath: '/haoban-3/',
proxyTable: proxyConfig.proxyList, // proxyTable: proxyConfig.proxyList,
// Various Dev Server settings // Various Dev Server settings
// host: '0.0.0.0', // can be overwritten by process.env.HOST // host: '0.0.0.0', // can be overwritten by process.env.HOST
......
...@@ -63,13 +63,6 @@ module.exports = { ...@@ -63,13 +63,6 @@ module.exports = {
pathRewrite: { pathRewrite: {
'^/haoban-task-manage-web': '' '^/haoban-task-manage-web': ''
} }
}, }
'/haoban-app-aggregation-web/':{
target: 'https://www.gicdev.com/haoban-app-aggregation-web/',
changeOrigin: true,
pathRewrite: {
'^/haoban-app-aggregation-web/': ''
}
},
} }
} }
...@@ -13,8 +13,9 @@ ...@@ -13,8 +13,9 @@
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="shortcut icon" href="./favicon.ico" /> <link rel="shortcut icon" href="./favicon.ico" />
<title>好办管理平台</title> <title>好办管理平台</title>
<link rel="stylesheet" type="text/css" href="//web-1251519181.file.myqcloud.com/custom-element/custom-element.1.0.69.css" /> <link rel="stylesheet" type="text/css" href="//web-1251519181.file.myqcloud.com/custom-element/custom-element.1.0.76.css" />
<link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_1628375_vcg1gtmx7lb.css" /> <!--好办后台3.0--> <!--好办后台3.0-->
<!-- <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_1628375_vcg1gtmx7lb.css" /> -->
<script src="//at.alicdn.com/t/font_1628375_vcg1gtmx7lb.js"></script> <script src="//at.alicdn.com/t/font_1628375_vcg1gtmx7lb.js"></script>
<!-- 3.0组件库图标 --> <!-- 3.0组件库图标 -->
<link rel="stylesheet" href="//at.alicdn.com/t/font_2859043_udehp133w1.css"> <link rel="stylesheet" href="//at.alicdn.com/t/font_2859043_udehp133w1.css">
...@@ -28,7 +29,7 @@ ...@@ -28,7 +29,7 @@
(function() { (function() {
var src = '/component/static/import-component.js?timestrap='+ new Date().getTime(); var src = '/component/static/import-component.js?timestrap='+ new Date().getTime();
var host = window.location.host; var host = window.location.host;
host = host.indexOf('localhost') > -1 || host.indexOf('192.168') > -1 ? 'gicdev.demogic.com' : host; host = host.indexOf('localhost') > -1 || host.indexOf('192.168') > -1 ? 'www.gicdev.com' : host;
document.write('<script src="//'+ host + src +'"><\/script>') document.write('<script src="//'+ host + src +'"><\/script>')
})() })()
</script> </script>
......
...@@ -322,6 +322,25 @@ module.exports = { ...@@ -322,6 +322,25 @@ module.exports = {
adminList: { adminList: {
// 1.刷新(按钮) // 1.刷新(按钮)
refreshAdminList: ['刷新', 1, 2] refreshAdminList: ['刷新', 1, 2]
} },
// 按钮名称、是否受权限控制0否1是、是否增删改0:跳转 1:增删改 2:其他、按钮跳转路径 // 按钮名称、是否受权限控制0否1是、是否增删改0:跳转 1:增删改 2:其他、按钮跳转路径
actCode: {
addActCode: ['新建活码', 1, 0],
batchActCode: ['批量创建活码', 1, 0],
batchGroup: ['批量分组', 1, 1],
dataActCode: ['数据', 1, 0],
infoActCode: ['详情', 1, 0],
editActCode: ['编辑', 1, 1],
downActCode: ['下载活码', 1, 1],
delActCode: ['作废', 1, 1],
recordCode: ['查看记录', 1, 0]
},
linkCode: {
addLink: ['新建链接', 1, 0],
dataLink: ['数据', 1, 0],
infoLink: ['详情', 1, 0],
editLink: ['编辑', 1, 0],
downLink: ['链接', 1, 1],
recordLink: ['查看记录', 1, 0]
}
} }
{"multipleAssign":"multipleAssign","assign":"assign","willSyncTag":"willSyncTag","breakSyncTag":"breakSyncTag","addShowRules":"addShowRules","editShowRules":"editShowRules","delShowRules":"delShowRules","groupExpire":"groupExpire","syncGroup":"syncGroup","addGroupTemp":"addGroupTemp","editGroupTemp":"editGroupTemp","setStoreArea":"setStoreArea","delGroupTemp":"delGroupTemp","searchSetSave":"searchSetSave","saveTrafficTaskSet":"saveTrafficTaskSet","addCard":"addCard","editCard":"editCard","delCard":"delCard","sendCardLog":"sendCardLog","getCardLog":"getCardLog","saveEvaluateSet":"saveEvaluateSet","addMaterialGroup":"addMaterialGroup","editMaterialGroup":"editMaterialGroup","delMaterialGroup":"delMaterialGroup","multipleDelAssets":"multipleDelAssets","multipleMoveAssets":"multipleMoveAssets","addText":"addText","editText":"editText","delText":"delText","textAssignStore":"textAssignStore","addImage":"addImage","editImage":"editImage","delImage":"delImage","imageAssignStore":"imageAssignStore","addWeb":"addWeb","editWeb":"editWeb","delWeb":"delWeb","webAssignStore":"webAssignStore","addVideo":"addVideo","editVideo":"editVideo","delVideo":"delVideo","videoAssignStore":"videoAssignStore","addFile":"addFile","editFile":"editFile","delFile":"delFile","fileAssignStore":"fileAssignStore","addApps":"addApps","editApps":"editApps","delApps":"delApps","appsAssignStore":"appsAssignStore","saveGoodsSet":"saveGoodsSet","exportActiveUser":"exportActiveUser","exportLoginUser":"exportLoginUser","exportAreaLoginUser":"exportAreaLoginUser","multipleDelReport":"multipleDelReport","exportReport":"exportReport","reportDetail":"reportDetail","multipleDelReportDetail":"multipleDelReportDetail","delReportDetail":"delReportDetail","showReportDetail":"showReportDetail","multipleExportReport":"multipleExportReport","saveTaskSet":"saveTaskSet","settingSystemReport":"settingSystemReport","saveSystemReport":"saveSystemReport","addCustomReport":"addCustomReport","copyCustomReport":"copyCustomReport","editCustomReport":"editCustomReport","delCustomReport":"delCustomReport","monthTarget":"monthTarget","dayTarget":"dayTarget","exportMonthTask":"exportMonthTask","checkMonthTask":"checkMonthTask","multipleDelTask":"multipleDelTask","delTask":"delTask","exportStoreList":"exportStoreList","checkStoreList":"checkStoreList","exportStoreDetail":"exportStoreDetail","checkStoreDetail":"checkStoreDetail","exportStoreDetailPop":"exportStoreDetailPop","previewStoreDetail":"previewStoreDetail","exportGrTaskList":"exportGrTaskList","checkGrTaskList":"checkGrTaskList","exportTaskRecord":"exportTaskRecord","multipleDelTaskRecord":"multipleDelTaskRecord","checkTaskRecord":"checkTaskRecord","exportTaskDetail":"exportTaskDetail","multipleDelTaskDetail":"multipleDelTaskDetail","delTaskDetail":"delTaskDetail","resolveTaskDetail":"resolveTaskDetail","previewTaskDetail":"previewTaskDetail","exportTaskView":"exportTaskView","multipleDelTaskView":"multipleDelTaskView","checkTaskView":"checkTaskView","exportTaskViewDetail":"exportTaskViewDetail","multipleDelTaskViewDetail":"multipleDelTaskViewDetail","checkTaskDetail":"checkTaskDetail","addSalutatory":"addSalutatory","editSalutatory":"editSalutatory","delSalutatory":"delSalutatory","multipleResolve":"multipleResolve","singleResolve":"singleResolve","singleReject":"singleReject","saveApplySetting":"saveApplySetting","refreshStoreMember":"refreshStoreMember","exportContact":"exportContact","checkContactDetail":"checkContactDetail","checkContactMemberDetail":"checkContactMemberDetail","checkLog":"checkLog","saveGuideSetting":"saveGuideSetting","saveAppsVisible":"saveAppsVisible","refreshStoreInfo":"refreshStoreInfo","saveMemberSecret":"saveMemberSecret","addMemberAppsSecret":"addMemberAppsSecret","editMemberAppsSecret":"editMemberAppsSecret","delMemberAppsSecret":"delMemberAppsSecret","addAppsSecret":"addAppsSecret","getAppsSecret":"getAppsSecret","editAppsSecret":"editAppsSecret","delAppsSecret":"delAppsSecret","checkAuth":"checkAuth","bindStoreList":"bindStoreList","refreshStore":"refreshStore","refreshAdminList":"refreshAdminList"} {"multipleAssign":"multipleAssign","assign":"assign","willSyncTag":"willSyncTag","breakSyncTag":"breakSyncTag","addShowRules":"addShowRules","editShowRules":"editShowRules","delShowRules":"delShowRules","groupExpire":"groupExpire","syncGroup":"syncGroup","addGroupTemp":"addGroupTemp","editGroupTemp":"editGroupTemp","setStoreArea":"setStoreArea","delGroupTemp":"delGroupTemp","searchSetSave":"searchSetSave","saveTrafficTaskSet":"saveTrafficTaskSet","addCard":"addCard","editCard":"editCard","delCard":"delCard","sendCardLog":"sendCardLog","getCardLog":"getCardLog","saveEvaluateSet":"saveEvaluateSet","addMaterialGroup":"addMaterialGroup","editMaterialGroup":"editMaterialGroup","delMaterialGroup":"delMaterialGroup","multipleDelAssets":"multipleDelAssets","multipleMoveAssets":"multipleMoveAssets","addText":"addText","editText":"editText","delText":"delText","textAssignStore":"textAssignStore","addImage":"addImage","editImage":"editImage","delImage":"delImage","imageAssignStore":"imageAssignStore","addWeb":"addWeb","editWeb":"editWeb","delWeb":"delWeb","webAssignStore":"webAssignStore","addVideo":"addVideo","editVideo":"editVideo","delVideo":"delVideo","videoAssignStore":"videoAssignStore","addFile":"addFile","editFile":"editFile","delFile":"delFile","fileAssignStore":"fileAssignStore","addApps":"addApps","editApps":"editApps","delApps":"delApps","appsAssignStore":"appsAssignStore","saveGoodsSet":"saveGoodsSet","exportActiveUser":"exportActiveUser","exportLoginUser":"exportLoginUser","exportAreaLoginUser":"exportAreaLoginUser","multipleDelReport":"multipleDelReport","exportReport":"exportReport","reportDetail":"reportDetail","multipleDelReportDetail":"multipleDelReportDetail","delReportDetail":"delReportDetail","showReportDetail":"showReportDetail","multipleExportReport":"multipleExportReport","saveTaskSet":"saveTaskSet","settingSystemReport":"settingSystemReport","saveSystemReport":"saveSystemReport","addCustomReport":"addCustomReport","copyCustomReport":"copyCustomReport","editCustomReport":"editCustomReport","delCustomReport":"delCustomReport","monthTarget":"monthTarget","dayTarget":"dayTarget","exportMonthTask":"exportMonthTask","checkMonthTask":"checkMonthTask","multipleDelTask":"multipleDelTask","delTask":"delTask","exportStoreList":"exportStoreList","checkStoreList":"checkStoreList","exportStoreDetail":"exportStoreDetail","checkStoreDetail":"checkStoreDetail","exportStoreDetailPop":"exportStoreDetailPop","previewStoreDetail":"previewStoreDetail","exportGrTaskList":"exportGrTaskList","checkGrTaskList":"checkGrTaskList","exportTaskRecord":"exportTaskRecord","multipleDelTaskRecord":"multipleDelTaskRecord","checkTaskRecord":"checkTaskRecord","exportTaskDetail":"exportTaskDetail","multipleDelTaskDetail":"multipleDelTaskDetail","delTaskDetail":"delTaskDetail","resolveTaskDetail":"resolveTaskDetail","previewTaskDetail":"previewTaskDetail","exportTaskView":"exportTaskView","multipleDelTaskView":"multipleDelTaskView","checkTaskView":"checkTaskView","exportTaskViewDetail":"exportTaskViewDetail","multipleDelTaskViewDetail":"multipleDelTaskViewDetail","checkTaskDetail":"checkTaskDetail","addSalutatory":"addSalutatory","editSalutatory":"editSalutatory","delSalutatory":"delSalutatory","multipleResolve":"multipleResolve","singleResolve":"singleResolve","singleReject":"singleReject","saveApplySetting":"saveApplySetting","refreshStoreMember":"refreshStoreMember","exportContact":"exportContact","checkContactDetail":"checkContactDetail","checkContactMemberDetail":"checkContactMemberDetail","checkLog":"checkLog","saveGuideSetting":"saveGuideSetting","saveAppsVisible":"saveAppsVisible","refreshStoreInfo":"refreshStoreInfo","saveMemberSecret":"saveMemberSecret","addMemberAppsSecret":"addMemberAppsSecret","editMemberAppsSecret":"editMemberAppsSecret","delMemberAppsSecret":"delMemberAppsSecret","addAppsSecret":"addAppsSecret","getAppsSecret":"getAppsSecret","editAppsSecret":"editAppsSecret","delAppsSecret":"delAppsSecret","checkAuth":"checkAuth","bindStoreList":"bindStoreList","refreshStore":"refreshStore","refreshAdminList":"refreshAdminList","addActCode":"addActCode","batchActCode":"batchActCode","batchGroup":"batchGroup","dataActCode":"dataActCode","infoActCode":"infoActCode","editActCode":"editActCode","downActCode":"downActCode","delActCode":"delActCode","recordCode":"recordCode","addLink":"addLink","dataLink":"dataLink","infoLink":"infoLink","editLink":"editLink","downLink":"downLink","recordLink":"recordLink"}
\ No newline at end of file \ No newline at end of file
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
"vue-amap": "^0.5.10", "vue-amap": "^0.5.10",
"vue-awesome-swiper": "^3.1.3", "vue-awesome-swiper": "^3.1.3",
"vue-clipboard2": "^0.2.0", "vue-clipboard2": "^0.2.0",
"vue-qr": "^1.5.3",
"vue-runtime-helpers": "^1.1.2", "vue-runtime-helpers": "^1.1.2",
"xlsx": "^0.13.5" "xlsx": "^0.13.5"
}, },
......
import { postRequest, getRequest, postJsonRequest } from '@/api/api';
// 新增活码分组
export const addActCodeGroupApi = params => postRequest('/haoban-manage3-web/hm/group/save', params);
// 编辑活码分组
export const editActCodeGroupApi = params => postRequest('/haoban-manage3-web/hm/group/edit', params);
// 删除分组
export const delActCodeGroupApi = params => postRequest('/haoban-manage3-web/hm/group/delete', params);
// 活码列表
export const actCodeListApi = params => postJsonRequest('/haoban-manage3-web/hm/qrcode/list', params);
// 落地页模板列表
export const guidePageList = params => getRequest('/haoban-manage3-web/hm/guide/page/list', params);
// 落地页模板删除
export const guidePageDel = params => postRequest('/haoban-manage3-web/hm/guide/page/delete', params);
// 落地页模板关联详情
export const guidePageRelation = params => getRequest('/haoban-manage3-web/hm/guide/page/relation', params);
// 落地页模板详情
export const guidePageDetail = params => getRequest('/haoban-manage3-web/hm/guide/page/detail', params);
// 落地页 获取当前企业电话、logo
export const wxEnterpriseList = params => postRequest('/haoban-manage3-web/wx-enterprise-list?filteRight=1&requestProject=haoban-manage-web', params);
// 落地页模板编辑详情
export const guidePageEdit = params => postRequest('/haoban-manage3-web/hm/guide/page/edit', params);
// 落地页模板新增详情
export const guidePageSave = params => postRequest('/haoban-manage3-web/hm/guide/page/save', params);
// 【活码链接】 -- 列表
export const linkPage = params => postRequest('/haoban-manage3-web/hm/link/page', params);
//【活码】详情-查看明细列表
export const detailClerkList = params => postJsonRequest('/haoban-manage3-web/hm/qrcode/detail-clerk-list-page', params);
//【欢迎语】-- 特殊欢迎语关联详情列表
export const welcomeRelationList = params => getRequest('/haoban-manage3-web/welcome/relation/list', params);
// 【活码链接】-- 新增
export const linkAdd = params => postJsonRequest('/haoban-manage3-web/hm/link/add', params);
// 【活码链接】-- 编辑
export const linkUpdate = params => postJsonRequest('/haoban-manage3-web/hm/link/update', params);
// 【活码链接】-- 详情 actCode
export const linkDetail = params => getRequest('/haoban-manage3-web/hm/link/detail', params);
// 【活码链接】 -- 统计-总计
export const statisticsTotal = params => postJsonRequest('/haoban-manage3-web/hm/link/statistics/total', params);
// 【活码链接】 -- 统计-图表
export const statisticsChart = params => postJsonRequest('/haoban-manage3-web/hm/link/statistics/chart', params);
// 【活码链接】 -- 统计--查看明细
export const statisticsClerk = params => postJsonRequest('/haoban-manage3-web/hm/link/statistics/clerk', params);
// 【活码链接】-- 门店列表
export const storeListApi = params => getRequest('/haoban-manage3-web/hm/store-list', params);
// 日志查询列表
export const logList = params => getRequest('/haoban-manage3-web/log-record/list', params);
// 获取 业务模块
export const businessType = params => getRequest('/haoban-manage3-web/log-record/business-types', params);
// 获取 操作类型
export const optTypes = params => getRequest('/haoban-manage3-web/log-record/opt-types', params);
// 获取 操作人姓名/手机号
export const listUserBySearchName = params => getRequest('/haoban-manage3-web/list-user-by-search-name', params);
...@@ -18,13 +18,15 @@ Vue.axios.defaults.withCredentials = true; // cookie访问 ...@@ -18,13 +18,15 @@ Vue.axios.defaults.withCredentials = true; // cookie访问
Vue.axios.defaults.headers.common['platform'] = 'haoban'; Vue.axios.defaults.headers.common['platform'] = 'haoban';
Vue.axios.defaults.timeout = 500000; Vue.axios.defaults.timeout = 500000;
let local = window.location.origin; let local = window.location.origin;
const userInfos = JSON.parse(sessionStorage.getItem('userInfos') || '{}'); const userInfos = JSON.parse(sessionStorage.getItem('userInfos') || '{}');
let gicHost = typeof userInfos.gicHost == 'string' ? userInfos.gicHost.replace(/\/$/, '') : ''; let gicHost = typeof userInfos.gicHost == 'string' ? userInfos.gicHost.replace(/\/$/, '') : '';
console.log(gicHost);
if (local.indexOf('localhost') >= 0) { if (local.indexOf('localhost') >= 0) {
gicHost = local; gicHost = local;
} }
gicHost = local; // gicHost = local;
// let local = process.env.NODE_ENV == 'development' ? 'https://www.gicdev.com' : ''; // let local = process.env.NODE_ENV == 'development' ? 'https://www.gicdev.com' : '';
...@@ -56,6 +58,13 @@ Vue.axios.interceptors.request.use( ...@@ -56,6 +58,13 @@ Vue.axios.interceptors.request.use(
cancel cancel
}); });
}); });
/**
* 获取好办 企业 id
*/
if (!!sessionStorage.getItem('userInfoBrandId')) {
let haobanSign = sessionStorage.getItem('userInfoBrandId');
haobanSign ? (config.headers.enterpriseId = haobanSign) : '';
}
return config; return config;
}, },
err => { err => {
...@@ -67,19 +76,25 @@ Vue.axios.interceptors.request.use( ...@@ -67,19 +76,25 @@ Vue.axios.interceptors.request.use(
Vue.axios.interceptors.response.use( Vue.axios.interceptors.response.use(
data => { data => {
removePending(data.config); //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除 removePending(data.config); //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
if (data.status && data.status == 200 && data.data.errorCode != 1) { // if (data.data.hasOwnProperty('errorCode') && data.data.errorCode != 1 && data.data.errorCode != 0) {
// Message.error({ message: `${data.data.message}` });
// }
// if (data.data.hasOwnProperty('code') && data.data.code != 0) {
// Message.error({ message: `${data.data.message}` });
// }
if (data.status && data.status == 200 && data.data.errorCode != 1 && data.data.code != 0) {
if (data.data.errorCode == 4) { if (data.data.errorCode == 4) {
if (window.location.href.indexOf('gic-error') != -1) { if (window.location.href.indexOf('gic-error') != -1) {
return false; return false;
} }
window.location.href = gicHost + '/gic-web/#/login?ishb=1'; window.location.href = gicHost + '/gic-web/#/login?ishb=1';
} }
if (data.data.errorCode == 10 || data.data.errorCode == 7) { if (data.data.errorCode == 10 || data.data.errorCode == 7) {
window.location.href = gicHost + '/haoban-3/#/index'; window.location.href = gicHost + '/haoban-3/#/index';
} }
return data; return data;
} }
return data; return data;
}, },
err => { err => {
...@@ -116,6 +131,26 @@ export const getRequest = (url, params) => { ...@@ -116,6 +131,26 @@ export const getRequest = (url, params) => {
}); });
}; };
/*
*
* 统一 delete 请求方法
* @url: 请求的 url
* @params: 请求带的参数
* @header: 带 token
*
*/
export const deleteRequest = (url, params) => {
params.requestProject = 'haoban-manage-web';
return Vue.axios({
method: 'delete',
url: `${local}${url}`,
data: {},
params: params,
headers: {
'Content-type': 'application/x-www-form-urlencoded'
} // "token": token
});
};
/** /**
* *
* 统一 post 请求方法 * 统一 post 请求方法
......
This source diff could not be displayed because it is too large. You can view the blob instead.
@font-face {
font-family: "iconfont-hb3"; /* Project id 1628375 */
src: url('iconfont.woff2?t=1659429607578') format('woff2'),
url('iconfont.woff?t=1659429607578') format('woff'),
url('iconfont.ttf?t=1659429607578') format('truetype');
}
.iconfont-hb3 {
font-family: "iconfont-hb3" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iconclose-circle-fill:before {
content: "\ecaf";
}
.iconxiazai:before {
content: "\eb83";
}
.iconcaozuorizhi:before {
content: "\ee14";
}
.iconno-data:before {
content: "\ec64";
}
.iconuser-default:before {
content: "\ebcc";
}
.icondianhua:before {
content: "\ebeb";
}
.iconzhibiaoshuoming:before {
content: "\eb57";
}
.iconmore:before {
content: "\ec97";
}
.icongengduo3:before {
content: "\ec98";
}
.iconclose1:before {
content: "\e62c";
}
.iconliushihuiyuan:before {
content: "\e6ca";
}
.iconxinzengyonghu:before {
content: "\e636";
}
.iconPlusOutlined:before {
content: "\e61f";
}
.iconbiaoge-erweima:before {
content: "\e614";
}
.iconguanliyuanka:before {
content: "\e6d9";
}
.iconxiajiantou:before {
content: "\e9e9";
}
.iconshangjiantou:before {
content: "\ea62";
}
.iconno-permission:before {
content: "\ec9c";
}
.iconqiweikehu:before {
content: "\e64f";
}
.iconcheck:before {
content: "\e7fc";
}
.iconshouquanshanghu:before {
content: "\ec95";
}
.iconyingyongjieru:before {
content: "\ec94";
}
.icondaogoushezhi:before {
content: "\ec93";
}
.iconshangpinzhongxin:before {
content: "\ec92";
}
.icontongxunlu1:before {
content: "\ec91";
}
.iconshenhezhongxin1:before {
content: "\ec90";
}
.iconhuanyingyu-o:before {
content: "\ec8f";
}
.iconhuihuarenwujilu:before {
content: "\ec8e";
}
.iconqunfarenwujilu:before {
content: "\ec8d";
}
.iconyuezhibiao:before {
content: "\ec8c";
}
.iconyunribao:before {
content: "\ec8b";
}
.icondenglushuju:before {
content: "\ec8a";
}
.iconsucaiku1:before {
content: "\ec88";
}
.iconpingjiahuifang:before {
content: "\ec87";
}
.iconkaquanhuodong:before {
content: "\ec86";
}
.iconrenwuchuda:before {
content: "\ec85";
}
.iconkehushezhi:before {
content: "\e697";
}
.iconkehubiaoqian:before {
content: "\ec84";
}
.iconwodekehu:before {
content: "\ec83";
}
.icongongzhonghao:before {
content: "\e60f";
}
.icongongzhonghao1:before {
content: "\e691";
}
.iconshurumima-mingma:before {
content: "\ec6d";
}
.iconshurumima-anma:before {
content: "\ec6c";
}
.iconreload-outlined:before {
content: "\e61e";
}
.iconerweima:before {
content: "\e620";
}
.iconxianshiping:before {
content: "\e62e";
}
.iconclose:before {
content: "\e992";
}
.iconchaolianjiebeifen:before {
content: "\e6e1";
}
.iconwenjianleixing-xiaochengxu:before {
content: "\ec29";
}
.iconwenjianleixing-lianjie:before {
content: "\ec28";
}
.iconwenjianleixing-wenjian:before {
content: "\ec26";
}
.iconwenjianleixingshipin:before {
content: "\ec24";
}
.iconwenjianleixingtupian:before {
content: "\e643";
}
.iconxiangyou:before {
content: "\e60c";
}
.iconlianjie:before {
content: "\e62b";
}
.iconduankailianjie:before {
content: "\e674";
}
.iconshezhi:before {
content: "\e688";
}
.iconshenhezhongxin:before {
content: "\e627";
}
.iconkongbiaoqian:before {
content: "\e64c";
}
.icondingdan_pingjia:before {
content: "\e654";
}
.iconxiaochengxu:before {
content: "\e625";
}
.iconpre:before {
content: "\e641";
}
.iconnext:before {
content: "\e640";
}
.iconhuanyingci:before {
content: "\e60d";
}
.iconnew:before {
content: "\e61d";
}
.iconmingxibeifen:before {
content: "\eae0";
}
.iconshangpinshezhi:before {
content: "\e60b";
}
.icongukeguanliicon:before {
content: "\e60a";
}
.iconshuaxin1:before {
content: "\e613";
}
.icongou:before {
content: "\e606";
}
.iconshouquanyanzheng:before {
content: "\e687";
}
.iconhuaban:before {
content: "\e62a";
}
.iconsucaiku:before {
content: "\eab6";
}
.iconwenjian1:before {
content: "\eaae";
}
.iconbofang1:before {
content: "\eaad";
}
.iconbiaoqing:before {
content: "\e612";
}
.iconwenzi:before {
content: "\e611";
}
.icondaima:before {
content: "\e6bc";
}
.icontupian:before {
content: "\e73a";
}
.iconwenjian:before {
content: "\e62d";
}
.iconshipin:before {
content: "\e605";
}
.icontuozhuaiopen:before {
content: "\e61c";
}
.icontoufang2:before {
content: "\e845";
}
.iconcelve:before {
content: "\eaa9";
}
.iconmoban:before {
content: "\e619";
}
.icontongxunlu:before {
content: "\e64e";
}
.iconwodeqiaquan-:before {
content: "\e6bb";
}
.iconhuihuajinglingicon-:before {
content: "\e678";
}
.iconshibai:before {
content: "\e60e";
}
.iconchenggong:before {
content: "\e63c";
}
.iconqiyeweixin:before {
content: "\e628";
}
.iconnan:before {
content: "\e629";
}
.iconxingbienv:before {
content: "\e66b";
}
.iconrenwuzhipai:before {
content: "\e7a5";
}
.iconwanchengrenwu:before {
content: "\ea6c";
}
.iconziyuan1:before {
content: "\e6a4";
}
.icondingwei:before {
content: "\e918";
}
.icongengduo2:before {
content: "\ea5b";
}
.iconqiyexinxi:before {
content: "\ea7a";
}
.iconjia:before {
content: "\ea79";
}
.icondaishenhe_orange:before {
content: "\e604";
}
.iconrenwu1:before {
content: "\e607";
}
.iconshenhe:before {
content: "\e772";
}
.icongengduo1:before {
content: "\e68c";
}
.iconjian:before {
content: "\e634";
}
.iconguanliyuanliebiao:before {
content: "\e609";
}
.iconbumen:before {
content: "\ea78";
}
.iconxiafa:before {
content: "\e64a";
}
.icongengduo:before {
content: "\e603";
}
.iconxitongguanlitubiao_mobanshezhi:before {
content: "\e618";
}
.iconribao:before {
content: "\e750";
}
.iconribaoshezhi:before {
content: "\e7f4";
}
.iconrenwu:before {
content: "\e77a";
}
.iconzhibiao:before {
content: "\e610";
}
.iconhuawujinengzupeizhi:before {
content: "\e601";
}
.iconbuliangpingjiashezhi:before {
content: "\e7f6";
}
.iconhuawushuju:before {
content: "\e600";
}
.iconshuaxin:before {
content: "\e61b";
}
.iconqiaquan:before {
content: "\e6b6";
}
.iconjichushezhi:before {
content: "\e65e";
}
.icontianjiajiahaowubiankuang:before {
content: "\e81a";
}
.iconchengyuan:before {
content: "\e61a";
}
.iconnavigate_next:before {
content: "\e62f";
}
.iconchangyongicon-:before {
content: "\e617";
}
.iconqiye-tianchong:before {
content: "\e730";
}
.iconzuzhijiagouguanli:before {
content: "\e635";
}
.icondianpu-kuai:before {
content: "\e602";
}
.iconxiala:before {
content: "\e608";
}
.iconrizhifuwu:before {
content: "\e65a";
}
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1658109499599" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4660" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
</style></defs><path d="M882.688 680.448l-164.864-202.752c-7.68-9.728-19.456-15.36-31.744-15.36H332.288c-12.288 0-24.064 5.632-31.744 15.36l-164.864 202.752v105.984h746.496v-105.984h0.512z" fill="#2F54EB" p-id="4661"></path><path d="M332.288 459.264H686.08c13.312 0 25.6 6.144 34.304 16.384l165.376 203.776v110.08H132.608v-110.08L297.984 476.16l2.56 2.048m31.744-12.288c-11.264 0-22.016 5.12-29.184 14.336l-163.84 201.728V783.36h739.84v-101.376l-163.84-201.728c-7.168-8.704-17.92-13.824-29.184-14.336H332.288z" fill="#2B2E36" p-id="4662"></path><path d="M245.76 229.376c0-13.824 10.752-24.576 24.576-24.576h475.136c13.824 0 24.576 10.752 24.576 24.576v647.168c0 13.824-10.752 24.576-24.576 24.576H270.336c-13.824 0-24.576-10.752-24.576-24.576V229.376z" fill="#FFFFFF" p-id="4663"></path><path d="M242.688 229.376c0-15.36 12.288-27.648 27.648-27.648h475.136c15.36 0 27.648 12.288 27.648 27.648v647.168c0 15.36-12.288 27.648-27.648 27.648H270.336c-15.36 0-27.648-12.288-27.648-27.648V229.376z m27.648-21.504c-11.776 0-21.504 9.728-21.504 21.504v647.168c0 11.776 9.728 21.504 21.504 21.504h475.136c11.776 0 21.504-9.728 21.504-21.504V229.376c0-11.776-9.728-21.504-21.504-21.504H270.336z" fill="#2B2E36" p-id="4664"></path><path d="M681.984 269.824H336.384c-7.68 0-13.824 6.144-13.824 13.824v171.52c0 7.68 6.144 13.824 13.824 13.824h345.6c7.68 0 13.824-6.144 13.824-13.824V283.136c0-7.168-6.144-13.312-13.824-13.312z" fill="#E8ECFD" p-id="4665"></path><path d="M336.384 272.896c-5.632 0-10.24 4.608-10.24 10.24v171.52c0 5.632 4.608 10.24 10.24 10.24h345.6c5.632 0 10.24-4.608 10.24-10.24V283.136c0-5.632-4.608-10.24-10.24-10.24H336.384z m-12.288-1.536c3.072-3.072 7.68-5.12 12.288-5.12h345.6c9.216 0 16.896 7.68 16.896 16.896v172.032c0 9.216-7.68 16.896-16.896 16.896H336.384c-9.216 0-16.896-7.68-16.896-16.896V283.136c-0.512-4.096 1.536-8.704 4.608-11.776z" fill="#2B2E36" p-id="4666"></path><path d="M881.152 924.16c-5.12 21.504-24.064 36.864-46.592 36.864H183.808c-22.016 0-40.96-15.36-46.592-36.864-1.024-4.096-1.536-8.192-1.536-12.288V680.96h181.248c20.48 0.512 36.352 16.896 36.352 37.376v0.512c0 20.48 15.872 36.864 36.352 36.864h239.616c20.48 0 36.352-16.896 36.352-36.864-0.512-20.48 15.872-36.864 36.352-37.376h181.248v230.912c-0.512 3.584-1.024 7.68-2.048 11.776z" fill="#FFFFFF" p-id="4667"></path><path d="M132.608 677.376h184.32c22.016 0.512 39.424 18.432 39.424 40.448v0.512c0 18.432 14.848 33.28 33.28 33.792h239.616c18.432 0 33.28-15.36 33.28-33.792-0.512-22.016 17.408-40.448 39.424-40.448h184.32v234.496c0 4.608-0.512 8.704-1.536 13.312-5.632 23.04-26.112 38.912-49.664 39.424H183.808c-23.552-0.512-44.032-16.384-49.664-39.424-1.024-4.096-1.536-8.704-1.536-13.312v-235.008z m744.96 245.76c1.024-3.584 1.536-7.68 1.536-11.776v-227.84H701.44c-18.432 0.512-33.28 15.36-32.768 33.792 0 22.016-17.408 39.936-39.424 40.448H389.12c-22.016 0-39.936-18.432-39.424-40.448v-0.512c0.512-18.432-14.336-33.792-32.768-33.792H139.264v227.84c0 4.096 0.512 7.68 1.536 11.776 4.608 19.968 22.528 34.304 43.008 34.304H834.56c20.48 0.512 38.4-13.824 43.008-33.792z" fill="#2B2E36" p-id="4668"></path><path d="M680.448 543.744H337.92c-8.704 0-15.36 7.168-15.36 15.36 0 8.704 7.168 15.36 15.36 15.36h342.016c8.704 0 15.36-7.168 15.36-15.36 0.512-8.704-6.656-15.36-14.848-15.36z m0 80.896H337.92c-8.704 0-15.36 7.168-15.36 15.872 0 8.192 6.656 14.848 15.36 15.36h342.016c8.704 0 15.36-7.168 15.36-15.36s-6.656-15.872-14.848-15.872z" fill="#D1D9FC" p-id="4669"></path><path d="M860.672 107.52l18.944 18.944-67.072 67.072-18.944-18.944L860.672 107.52z m-162.816-52.224h26.624v95.232h-26.624V55.296z m133.12 202.24h95.232v26.624h-95.232v-26.624z" fill="#2F54EB" p-id="4670"></path></svg>
\ No newline at end of file
...@@ -14,25 +14,24 @@ ...@@ -14,25 +14,24 @@
export default { export default {
/* /*
* var storeBusinessTime="10:00-22:00" to * var storeBusinessTime="10:00-22:00" to
*/ */
timeToDate: function(val) { timeToDate: function(val) {
var date = new Date() var date = new Date();
var y = date.getFullYear(); var y = date.getFullYear();
var m = date.getMonth() +1; var m = date.getMonth() + 1;
var day = date.getDate(); var day = date.getDate();
var d = [],newArr = []; var d = [],
newArr = [];
var dArr = val.split('-'); var dArr = val.split('-');
dArr.forEach(function(ele,index){ dArr.forEach(function(ele, index) {
newArr.push(ele.split(':')) newArr.push(ele.split(':'));
}) });
d = [new Date(y,m,day,newArr[0][0],newArr[0][1]),new Date(y,m,day,newArr[1][0],newArr[1][1])] d = [new Date(y, m, day, newArr[0][0], newArr[0][1]), new Date(y, m, day, newArr[1][0], newArr[1][1])];
return d; return d;
}, },
dateToTime(val) { dateToTime(val) {
// console.log(val) // console.log(val)
// (0-9)年月数字的显示 // (0-9)年月数字的显示
...@@ -40,9 +39,9 @@ export default { ...@@ -40,9 +39,9 @@ export default {
return num > 9 ? '' + num : '0' + num; return num > 9 ? '' + num : '0' + num;
} }
var t; var t;
var t1 = formatDig(new Date(val[0]).getHours())+':'+formatDig(new Date(val[0]).getMinutes()) var t1 = formatDig(new Date(val[0]).getHours()) + ':' + formatDig(new Date(val[0]).getMinutes());
var t2 = formatDig(new Date(val[1]).getHours())+':'+formatDig(new Date(val[1]).getMinutes()) var t2 = formatDig(new Date(val[1]).getHours()) + ':' + formatDig(new Date(val[1]).getMinutes());
t= t1+'-'+t2 t = t1 + '-' + t2;
return t; return t;
} }
} };
var SIGN_REGEXP = /([yMdhsm])(\1*)/g; var SIGN_REGEXP = /([yMdhsm])(\1*)/g;
var DEFAULT_PATTERN = 'yyyy-MM-dd'; var DEFAULT_PATTERN = 'yyyy-MM-dd';
function padding(s, len) { function padding(s, len) {
var len = len - (s + '').length; var len = len - (s + '').length;
for (var i = 0; i < len; i++) { s = '0' + s; } for (var i = 0; i < len; i++) {
return s; s = '0' + s;
}; }
return s;
}
export default { export default {
getQueryStringByName: function (name) { getQueryStringByName: function(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = window.location.search.substr(1).match(reg); var r = window.location.search.substr(1).match(reg);
var context = ""; var context = '';
if (r != null) if (r != null) context = r[2];
context = r[2]; reg = null;
reg = null; r = null;
r = null; return context == null || context == '' || context == 'undefined' ? '' : context;
return context == null || context == "" || context == "undefined" ? "" : context; },
formatDate: {
format: function(date, pattern) {
pattern = pattern || DEFAULT_PATTERN;
return pattern.replace(SIGN_REGEXP, function($0) {
switch ($0.charAt(0)) {
case 'y':
return padding(date.getFullYear(), $0.length);
case 'M':
return padding(date.getMonth() + 1, $0.length);
case 'd':
return padding(date.getDate(), $0.length);
case 'w':
return date.getDay() + 1;
case 'h':
return padding(date.getHours(), $0.length);
case 'm':
return padding(date.getMinutes(), $0.length);
case 's':
return padding(date.getSeconds(), $0.length);
}
});
}, },
formatDate: { parse: function(dateString, pattern) {
var matchs1 = pattern.match(SIGN_REGEXP);
format: function (date, pattern) { var matchs2 = dateString.match(/(\d)+/g);
pattern = pattern || DEFAULT_PATTERN; if (matchs1.length == matchs2.length) {
return pattern.replace(SIGN_REGEXP, function ($0) { var _date = new Date(1970, 0, 1);
switch ($0.charAt(0)) { for (var i = 0; i < matchs1.length; i++) {
case 'y': return padding(date.getFullYear(), $0.length); var _int = parseInt(matchs2[i]);
case 'M': return padding(date.getMonth() + 1, $0.length); var sign = matchs1[i];
case 'd': return padding(date.getDate(), $0.length); switch (sign.charAt(0)) {
case 'w': return date.getDay() + 1; case 'y':
case 'h': return padding(date.getHours(), $0.length); _date.setFullYear(_int);
case 'm': return padding(date.getMinutes(), $0.length); break;
case 's': return padding(date.getSeconds(), $0.length); case 'M':
} _date.setMonth(_int - 1);
}); break;
}, case 'd':
parse: function (dateString, pattern) { _date.setDate(_int);
var matchs1 = pattern.match(SIGN_REGEXP); break;
var matchs2 = dateString.match(/(\d)+/g); case 'h':
if (matchs1.length == matchs2.length) { _date.setHours(_int);
var _date = new Date(1970, 0, 1); break;
for (var i = 0; i < matchs1.length; i++) { case 'm':
var _int = parseInt(matchs2[i]); _date.setMinutes(_int);
var sign = matchs1[i]; break;
switch (sign.charAt(0)) { case 's':
case 'y': _date.setFullYear(_int); break; _date.setSeconds(_int);
case 'M': _date.setMonth(_int - 1); break; break;
case 'd': _date.setDate(_int); break; }
case 'h': _date.setHours(_int); break;
case 'm': _date.setMinutes(_int); break;
case 's': _date.setSeconds(_int); break;
}
}
return _date;
}
return null;
} }
return _date;
}
return null;
} }
}
}; };
<template>
<el-dialog title="链接信息" :visible.sync="show" width="600px" :before-close="close">
<div v-loading="loading" class="links-block">
<div class="links__body">
<div class="links__body--url">{{ src }}</div>
<div class="links__body--btn">
<el-button v-clipboard:text="src" v-show="src" type="text" icon="iconfont icon-lianjie font-14">复制链接</el-button>
</div>
</div>
<div class="link__divider"></div>
<div class="links__qr">
<div style="text-align:center">
<vue-qr v-if="sourceType" id="qrImg" :text="src" :size="102" :margin="5"></vue-qr>
<img v-else :src="src" class="imgs" />
</div>
<el-button v-show="src" type="text" icon="iconfont-hb3 iconxiazai font-14 m-r-5" @click="download">二维码下载</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import VueQr from 'vue-qr';
export default {
name: 'links',
components: {
VueQr
},
props: {
show: {
type: Boolean,
default: false
},
src: {
type: String,
default: ''
},
imageName: {
type: String,
default: ''
},
sourceType: {
type: Boolean,
default: true
}
},
data() {
return {
loading: false,
miniprogram: {
link: '',
url: ''
}
};
},
watch: {
show(val) {
if (val) {
console.log(this.src);
}
}
},
methods: {
close() {
this.$emit('update:show', false);
},
download() {
if (this.sourceType) {
this.downloadImg();
} else {
this.downloadCodeImg(this.src);
}
},
downloadImg() {
const qrcode = document.getElementById('qrImg');
let img = qrcode.getElementsByTagName('img')[0];
let link = document.createElement('a');
let url = img.getAttribute('src');
link.setAttribute('href', url);
link.setAttribute('download', `${this.imageName}.png`);
link.click();
},
downloadCodeImg(url) {
let image = new Image(); //创建图片对象
image.setAttribute('crossOrigin', 'anonymous'); //设置允许跨域
image.src = url; //赋值src
image.onload = () => {
//等待图片加载完成创建canvas
let canvas = document.createElement('canvas');
//将图片绘制到canvas画布上
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, image.width, image.height);
//获取图片文件格式 jpg/jpeg/png
let ext = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase();
//导出画布快照 此时已越过跨域限制成功取到图片数据
let dataURL = canvas.toDataURL('image/' + ext);
//创建a标签
const a = document.createElement('a');
// 赋值a标签download属性值,标明该a标签提供下载功能,同时该属性指定了下载时的文件名称
a.download = this.imageName;
//赋值a标签下载地址,即canvas导出的画布快照 base64格式的图片地址
a.href = dataURL;
//添加a标签到dom中
document.body.appendChild(a);
//触发a标签点击事件 触发下载
a.click();
//下载完成 删除多余的a标签 保持页面原有元素不动
};
}
}
};
</script>
<style lang="scss" scoped>
.links__body {
// border: 1px solid #ddd;
flex: 1;
&--url {
height: 138px;
overflow-x: hidden;
overflow-y: auto;
word-break: break-all;
padding: 13px 16px 0 16px;
line-height: 17px;
font-size: 12px;
}
&--btn {
text-align: center;
line-height: 1;
}
}
.links__body--btn {
margin-bottom: 10px;
}
.links__qr {
padding: 22px 30px 10px 24px;
text-align: center;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.link__divider {
margin-top: 19px;
height: 130px;
width: 1px;
background-color: #ebecf0;
}
.links-block {
display: flex;
background: #f7f8fa;
margin: 10px 0 10px;
}
.link-title {
display: flex;
align-items: center;
font-weight: 500;
color: #303133;
line-height: 20px;
margin-top: 20px;
i {
font-size: 20px;
margin-right: 8px;
}
}
.imgs {
width: 102px;
height: 105px;
}
</style>
<template>
<el-popover placement="bottom" v-model="departmentVisible">
<dm-simple-transfer :value="selected" :canSelectAll="canSelectAll" :filterMethod="filterMethod" :props="props" :max="max" :data="data" :bodyH="62" :item-size="66" :titles="['选择门店', '已选门店']" filterable filter-placeholder="请输入门店名称/code" @change="change">
<div slot-scope="{ option }">
<el-tooltip :content="option.storeName" :disabled="option.storeName.length < 10">
<p class="storeName">{{ option.storeName }}</p>
</el-tooltip>
<p style="font-size: 12px;line-height: 14px">{{ option.storeCode }}</p>
<p v-if="option.isOver == 1" class="isOver">所有导购今日添加已到上限</p>
</div>
</dm-simple-transfer>
<div class="show-select-num cursor-pointer w-250" slot="reference">
<span v-if="selected && selected.length"> 已经选择{{ selected && selected.length }}家门店</span>
<span v-else style="color: #C4C6CF;">请选择门店</span>
<span class="el-input__suffix"
><span class="el-input__suffix-inner"><i :class="['el-select__caret el-input__icon el-icon-arrow-up', departmentVisible ? 'is-reverse' : '']"></i></span
></span>
</div>
</el-popover>
</template>
<script>
export default {
props: {
selected: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
},
max: {
type: Number,
default: 999999
},
canSelectAll: {
type: Boolean,
default: false
}
},
data() {
return {
departmentVisible: false,
props: {
key: 'storeId',
label: 'storeName',
disabledProp: 'disabled'
}
};
},
methods: {
change(val) {
console.log(val);
this.$emit('change', val);
},
filterMethod(query, list) {
return list.filter(el => {
return el.storeName.toLowerCase().indexOf(query.toLowerCase()) > -1 || el.storeCode.toLowerCase().indexOf(query.toLowerCase()) > -1;
});
}
}
};
</script>
<style lang="less" scoped>
/deep/.dm-transfer-panel .transfer-panel-body {
height: calc(100% - 58px);
}
.show-select-num {
position: relative;
display: inline-block;
font-size: inherit;
height: 32px;
line-height: 32px;
padding-left: 10px;
-webkit-appearance: none;
background-color: #fff;
background-image: none;
border-radius: 4px;
border: 1px solid #dcdfe6;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #606266;
.el-select__caret {
color: #c0c4cc;
font-size: 14px;
transition: transform 0.3s;
transform: rotate(180deg);
cursor: pointer;
&.is-reverse {
transform: rotate(0deg);
}
}
}
.storeName {
width: 208px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.isOver {
font-size: 12px;
color: #fa8c16;
line-height: 18px;
}
</style>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="bread-menu"> <div class="bread-menu">
<span class="bread-menu-item" v-for="(el, index) in menuList" :key="el.menuCode"> <span class="bread-menu-item" v-for="(el, index) in menuList" :key="el.menuCode">
<i v-if="index > 0" class="bread-menu-icon iconfont-hb3 iconnavigate_next"></i> <i v-if="index > 0" class="bread-menu-icon iconfont-hb3 iconnavigate_next"></i>
<span :class="['bread-menu-text', index == menuList.length - 1 ? 'bread-menu-actived' : 'is-link']" @click="toPage">{{ el.menuName }}</span> <span :class="['bread-menu-text', index == menuList.length - 1 ? 'bread-menu-actived' : 'is-link']" @click="toPage(index)">{{ el.menuName }}</span>
</span> </span>
</div> </div>
</template> </template>
...@@ -17,7 +17,8 @@ export default { ...@@ -17,7 +17,8 @@ export default {
} }
}, },
methods: { methods: {
toPage() { toPage(index) {
if (index == this.menuList.length - 1) return;
this.$router.go(-1); this.$router.go(-1);
} }
} }
......
...@@ -8,11 +8,9 @@ ...@@ -8,11 +8,9 @@
<bread-menu v-if="activedMenu.length > 3" :menu-list="activedMenu.slice(2)"></bread-menu> <bread-menu v-if="activedMenu.length > 3" :menu-list="activedMenu.slice(2)"></bread-menu>
<div class="hb-layout-pager" id="hb-layout-pager-one" :style="{ height: activedMenu.length > 3 ? `calc(100% - 30px)` : '100%', 'padding-bottom': pagePaddingBottom }"> <div class="hb-layout-pager" id="hb-layout-pager-one" :style="{ height: activedMenu.length > 3 ? `calc(100% - 30px)` : '100%', 'padding-bottom': pagePaddingBottom }">
<!-- 页面内容 --> <!-- 页面内容 -->
<!-- <router-view v-if="activeBrand" :brandId="activeBrand" :activeGroupId="activeGroup" :tabType="activeTab" @showTab="showTab"></router-view> --> <keep-alive :include="keepAlive">
<keep-alive> <router-view :key="$route.path" :brand-id="enterpriseId"></router-view>
<router-view :brand-id="enterpriseId" v-if="$route.meta.keepAlive"></router-view>
</keep-alive> </keep-alive>
<router-view v-if="!$route.meta.keepAlive" :brand-id="enterpriseId"></router-view>
</div> </div>
</div> </div>
</div> </div>
...@@ -45,6 +43,7 @@ export default { ...@@ -45,6 +43,7 @@ export default {
data() { data() {
return { return {
isShowNotice: false, isShowNotice: false,
keepAlive: [],
showAside: true, showAside: true,
pagePaddingBottom: null, pagePaddingBottom: null,
enterpriseId: '', enterpriseId: '',
...@@ -70,8 +69,10 @@ export default { ...@@ -70,8 +69,10 @@ export default {
} }
}, },
created() { created() {
this.setKeepAlive(this.$route, {});
this.$router.beforeEach((to, from, next) => { this.$router.beforeEach((to, from, next) => {
this.activedMenu = this.getActivedMenu(this.getMenuByPath(to.path.slice(1))); this.activedMenu = this.getActivedMenu(this.getMenuByPath(to.path.slice(1)));
this.setKeepAlive(to, from);
next(); next();
}); });
provideData.layoutVm = this; provideData.layoutVm = this;
...@@ -120,6 +121,32 @@ export default { ...@@ -120,6 +121,32 @@ export default {
getMenuByPath(path) { getMenuByPath(path) {
return this.pageRight.find(el => el.regexp.test('/' + path)) || {}; return this.pageRight.find(el => el.regexp.test('/' + path)) || {};
}, },
setKeepAlive(to, from) {
if (Array.isArray(to.meta.fromPath)) {
const isKeepAlive = to.meta.fromPath.some(el => {
let menuUrlReg = el;
let pathConfigReg = /(:.*)(\/?)/;
const pathRegStr = '([\\d\\w]+[\\-]*[\\d\\w]*)';
while (pathConfigReg.test(menuUrlReg)) {
menuUrlReg = menuUrlReg.replace(pathConfigReg, `${pathRegStr}$2`);
}
pathConfigReg = /(\/\*)(\/?)/;
while (pathConfigReg.test(menuUrlReg)) {
menuUrlReg = menuUrlReg.replace(pathConfigReg, `${pathRegStr}$2`);
}
const reg = new RegExp(`^${menuUrlReg}$`);
return reg.test(from.path);
});
if (!isKeepAlive) {
this.keepAlive = this.keepAlive.filter(el => el != to.meta.componentName);
}
setTimeout(() => {
if (this.keepAlive.every(el => el != to.meta.componentName)) {
this.keepAlive.push(to.meta.componentName);
}
}, 100);
}
},
onShowLoading(loading) { onShowLoading(loading) {
if (loading) { if (loading) {
this.fullLoading.visible = true; this.fullLoading.visible = true;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<div> <div>
<div class="flex flex-space-between"> <div class="flex flex-space-between">
<span class="font-12 color-fff">{{ item.storeGroupName }}</span <span class="font-12 color-fff">{{ item.storeGroupName }}</span
><span class="font-12 color-fff p-l-40">登录率:{{ item.loginRate }}</span> ><span class="font-12 color-fff p-l-40">登录率:{{ item.loginRateString }}</span>
</div> </div>
<div class="m-t-10"> <div class="m-t-10">
<span class="process-tip-dot bg-e6ecfa"></span> <span class="font-12 color-fff">员工人数:</span> <span class="font-12 color-fff">{{ item.totalClerkCnt }}</span> <span class="process-tip-dot bg-e6ecfa"></span> <span class="font-12 color-fff">员工人数:</span> <span class="font-12 color-fff">{{ item.totalClerkCnt }}</span>
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
</div> </div>
<div class="people-total"> <div class="people-total">
<div class="flex people-total-bg"> <div class="flex people-total-bg">
<div class="login-total" :style="{ width: item.loginRate }"></div> <div class="login-total" :style="{ width: item.loginRateString }"></div>
<div class="login-rate" :style="{ left: item.loginRate }">{{ item.loginRate }}</div> <div class="login-rate" :style="{ left: item.loginRateString }">{{ item.loginRateString }}</div>
</div> </div>
</div> </div>
</el-tooltip> </el-tooltip>
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
<div><img src="../../assets/data/people.png" class="m-w-46" alt="" /></div> <div><img src="../../assets/data/people.png" class="m-w-46" alt="" /></div>
<div class="m-l-20"> <div class="m-l-20">
<div class="cell-title"> <div class="cell-title">
<el-tooltip class="item" effect="dark" content="企业下的好办门店员工总人数,导购同时归属多家门店的记多人" placement="top-start"> <el-tooltip class="item" effect="dark" content="企业下所有门店的好办在职员工总人数,不区分门店状态" placement="top-start">
<span class="font-13 color-909399 cell-title-span" style="cursor: pointer;padding-bottom: 2px; ">员工总人数</span> <span class="font-13 color-909399 cell-title-span" style="cursor: pointer;padding-bottom: 2px; ">员工总人数</span>
</el-tooltip> </el-tooltip>
</div> </div>
......
<template>
<div class="iphone">
<span class="pageTitle">{{ card.pageTitle }}</span>
<div class="content">
<img :src="card.pageBackgroundImg" class="bgImg" v-if="card.pageBackgroundImg" />
<div class="enterpriseInfo">
<div class="logo" v-if="card.merchantLogo">
<img :src="card.merchantLogo" />
</div>
<div class="name">{{ card.merchantName }}</div>
</div>
<div class="QRcode"></div>
<div class="leadingText">{{ card.guideComment }}</div>
<div class="enterpriseNum" v-show="card.merchantPhoneNumber">
<i class="iconfont-hb3 icondianhua"></i>
<p>{{ card.merchantPhoneNumber }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
card: {
pageTitle: '',
merchantName: '',
merchantPhoneNumber: '',
merchantLogo: '',
pageBackgroundImg: '',
guideComment: ''
}
};
},
props: {
data: {
type: Object,
default: () => {}
}
},
watch: {
data: {
handler(val) {
if (val) {
const { pageTitle, merchantName, merchantPhoneNumber, merchantLogo, pageBackgroundImg, guideComment } = val;
this.card = { pageTitle, merchantName, merchantPhoneNumber, merchantLogo, pageBackgroundImg, guideComment };
}
},
deep: true,
immediate: true
}
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.iphone {
position: relative;
display: inline-block;
font-size: 0;
line-height: 0;
background-image: url('../assets/iphone3.png');
background-repeat: no-repeat;
background-size: 280px auto;
width: 280px;
height: 543px;
.pageTitle {
font-size: 14px;
position: absolute;
color: #000;
font-weight: 500;
width: 125px;
margin-left: 78px;
line-height: 20px;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
top: 44px;
}
.content {
width: 228px;
height: 437px;
box-sizing: border-box;
padding: 20px 16px;
position: absolute;
top: 70px;
left: 26px;
background: #ffffff;
display: flex;
align-items: center;
flex-direction: column;
border-radius: 0 0 24px 24px;
.bgImg {
position: absolute;
width: 228px;
border-radius: 10px 10px 24px 24px;
top: 0;
z-index: 0;
max-height: 410px;
}
.enterpriseInfo {
display: flex;
justify-content: flex-start;
align-items: center;
width: 100%;
height: 36px;
z-index: 100;
.logo {
width: 36px;
height: 36px;
border-radius: 60px;
img {
width: 36px;
height: 36px;
border-radius: 60px;
}
}
.name {
margin-left: 10px;
font-size: 12px;
font-weight: 500;
color: #242835;
line-height: 17px;
width: 80%;
}
}
.QRcode {
z-index: 100;
width: 176px;
height: 176px;
margin: 11px 0 16px 0;
background-image: url('../assets/QRcode.jpg');
background-size: 176px auto;
}
.leadingText {
z-index: 100;
font-size: 10px;
color: #7f818a;
line-height: 14px;
width: 88%;
text-align: center;
}
.enterpriseNum {
z-index: 100;
min-width: 130px;
margin-top: 68px;
height: 32px;
box-sizing: border-box;
border-radius: 40px;
border: 1px solid #9da0a6;
display: flex;
align-items: center;
padding: 9px 12px;
justify-content: center;
line-height: 14px;
color: #63666b;
font-size: 12px;
i {
font-size: 12px;
}
p {
margin-left: 5px;
}
}
}
}
</style>
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
<el-form-item label="标题" prop="title"> <el-form-item label="标题" prop="title">
<el-input show-word-limit placeholder="请输入标题" type="text" v-model="ruleForm.title" maxlength="80"></el-input> <el-input show-word-limit placeholder="请输入标题" type="text" v-model="ruleForm.title" maxlength="80"></el-input>
</el-form-item> </el-form-item>
<el-form-item label=" 封面" prop="pic"> <el-form-item label="封面" prop="pic">
<single-upload uploadType="1" :imgSrc.sync="ruleForm.imageUrl" :field="''" class="app-set" :uploadLimit="20"> </single-upload> <single-upload uploadType="1" :imgSrc.sync="ruleForm.imageUrl" :field="''" class="app-set"> </single-upload>
<p style="margin-top: 9px;font-size: 12px;color: #909399;line-height: 17px;">建议尺寸520*416,支持png、jpg、jpeg格式</p> <p style="margin-top: 9px;font-size: 12px;color: #909399;line-height: 17px;">建议尺寸520*416,支持png、jpg、jpeg格式</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
<el-form-item label="标题:" prop="title"> <el-form-item label="标题:" prop="title">
<el-input show-word-limit placeholder="请输入标题" type="text" v-model="ruleForm.title" maxlength="80"></el-input> <el-input show-word-limit placeholder="请输入标题" type="text" v-model="ruleForm.title" maxlength="80"></el-input>
</el-form-item> </el-form-item>
<el-form-item label=" 封面:" prop="pic"> <el-form-item label="封面:" prop="pic">
<single-upload uploadType="1" :imgSrc.sync="ruleForm.imageUrl" :field="''" class="app-set" :uploadLimit="20"> </single-upload> <single-upload uploadType="1" :imgSrc.sync="ruleForm.imageUrl" :field="''" class="app-set"> </single-upload>
<p style="margin-top: 9px;font-size: 12px;color: #909399;line-height: 17px;">建议尺寸520*416,支持png、jpg、jpeg格式</p> <p style="margin-top: 9px;font-size: 12px;color: #909399;line-height: 17px;">建议尺寸520*416,支持png、jpg、jpeg格式</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<limitInput :inputWidth="440" :inputValue.sync="ruleForm.link" :holder="'请输入页面路径'" :getByType="'word'" :maxLength="100"> </limitInput> <limitInput :inputWidth="440" :inputValue.sync="ruleForm.link" :holder="'请输入页面路径'" :getByType="'word'" :maxLength="100"> </limitInput>
</el-form-item> </el-form-item>
<el-form-item label="封面" prop="imgUrl"> <el-form-item label="封面" prop="imgUrl">
<single-upload uploadType="4" :uploadLimit="1" :imgSrc.sync="ruleForm.imgUrl"> </single-upload> <single-upload uploadType="4" uploadLimit="1/MB" :imgSrc.sync="ruleForm.imgUrl"> </single-upload>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
......
...@@ -152,7 +152,7 @@ export default { ...@@ -152,7 +152,7 @@ export default {
toDel(index, row) { toDel(index, row) {
const that = this; const that = this;
that that
.$confirm('确定删除当前素材?', '提示', { .$confirm('注意:删除该素材后,已经配置过的营销任务还是会正常触达。', '确定删除当前素材?', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
......
...@@ -148,7 +148,7 @@ export default { ...@@ -148,7 +148,7 @@ export default {
toDel(index, row) { toDel(index, row) {
const that = this; const that = this;
that that
.$confirm('确定删除当前素材?', '提示', { .$confirm('注意:删除该素材后,已经配置过的营销任务还是会正常触达。', '确定删除当前素材?', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
......
...@@ -149,7 +149,7 @@ export default { ...@@ -149,7 +149,7 @@ export default {
toDel(index, row) { toDel(index, row) {
const that = this; const that = this;
that that
.$confirm('确定删除当前素材?', '提示', { .$confirm('注意:删除该素材后,已经配置过的营销任务还是会正常触达。', '确定删除当前素材?', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
<limitInput :inputWidth="440" :inputValue.sync="ruleForm.materialTitle" :holder="'请输入视频标题'" :getByType="'word'" :maxLength="20"> </limitInput> <limitInput :inputWidth="440" :inputValue.sync="ruleForm.materialTitle" :holder="'请输入视频标题'" :getByType="'word'" :maxLength="20"> </limitInput>
</el-form-item> </el-form-item>
<el-form-item label="封面" prop="imgUrl"> <el-form-item label="封面" prop="imgUrl">
<single-upload uploadType="2" :uploadLimit="1" :imgSrc.sync="ruleForm.imgUrl"> </single-upload> <single-upload uploadType="2" uploadLimit="1/MB" :imgSrc.sync="ruleForm.imgUrl"> </single-upload>
</el-form-item> </el-form-item>
<el-form-item label="视频" prop="link"> <el-form-item label="视频" prop="link">
<single-upload uploadType="3" :uploadLimit="10" :videoSrc.sync="ruleForm.link"> </single-upload> <single-upload uploadType="3" uploadLimit="10/MB" :videoSrc.sync="ruleForm.link"> </single-upload>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
......
...@@ -153,7 +153,7 @@ export default { ...@@ -153,7 +153,7 @@ export default {
toDel(index, row) { toDel(index, row) {
const that = this; const that = this;
that that
.$confirm('确定删除当前素材?', '提示', { .$confirm('注意:删除该素材后,已经配置过的营销任务还是会正常触达。', '确定删除当前素材?', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<limitInput :inputWidth="440" :inputValue.sync="ruleForm.materialDesc" :holder="'请输入网页摘要'" :getByType="'word'" :maxLength="100"> </limitInput> <limitInput :inputWidth="440" :inputValue.sync="ruleForm.materialDesc" :holder="'请输入网页摘要'" :getByType="'word'" :maxLength="100"> </limitInput>
</el-form-item> </el-form-item>
<el-form-item label="封面" prop="imgUrl"> <el-form-item label="封面" prop="imgUrl">
<single-upload uploadType="2" :uploadLimit="1" :imgSrc.sync="ruleForm.imgUrl"> </single-upload> <single-upload uploadType="2" uploadLimit="1/MB" :imgSrc.sync="ruleForm.imgUrl"> </single-upload>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
......
...@@ -151,7 +151,7 @@ export default { ...@@ -151,7 +151,7 @@ export default {
toDel(index, row) { toDel(index, row) {
const that = this; const that = this;
that that
.$confirm('确定删除当前素材?', '提示', { .$confirm('注意:删除该素材后,已经配置过的营销任务还是会正常触达。', '确定删除当前素材?', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
</single-upload> </single-upload>
--> -->
<template> <template>
<<<<<<< HEAD
<div class="single-upload-wrap"> <div class="single-upload-wrap">
<el-upload class="avatar-uploader" :action="uploadUrl()" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <el-upload class="avatar-uploader" :action="uploadUrl()" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="imgSrc" :src="imgSrc" class="avatar" @mouseover="showImage(imgSrc)" /> <img v-if="imgSrc" :src="imgSrc" class="avatar" @mouseover="showImage(imgSrc)" />
...@@ -39,6 +40,29 @@ ...@@ -39,6 +40,29 @@
</p> </p>
<!-- 图片预览 --> <!-- 图片预览 -->
<!-- <vue-gic-img-preview :imgUrl="imgUrl" :imgShowFlag="imgShowFlag" @hideImage="hideImage"></vue-gic-img-preview> --> <!-- <vue-gic-img-preview :imgUrl="imgUrl" :imgShowFlag="imgShowFlag" @hideImage="hideImage"></vue-gic-img-preview> -->
=======
<div>
<i v-if="imgSrc && showDel" class="del-icon iconfont-hb3 iconclose-circle-fill" @click="handleRemove"></i>
<div class="single-upload-wrap">
<el-upload class="avatar-uploader" :action="uploadUrl()" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<img v-if="imgSrc" :src="imgSrc" class="avatar" @mouseover="showImage(imgSrc)" />
<video v-if="videoSrc != '' && videoFlag == false" :src="videoSrc" class="avatar">您的浏览器不支持视频播放</video>
<div v-if="!imgSrc && !videoSrc">
<i class="iconfont-hb3 iconPlusOutlined avatar-uploader-icon"></i>
<p class="font-12 color-606266" style="line-height: 6px">{{ uploadType == 1 || uploadType == 2 || uploadType == 4 ? '上传图片' : '上传视频' }}</p>
</div>
<!-- <el-progress v-if="videoFlag == true" type="circle" :percentage="videoUploadPercent" style="margin-top:30px;"></el-progress> -->
</el-upload>
<p v-if="uploadType == 1 && showTips" class="upload-tip color-909399 font-12">图片支持png、jpg、jpeg格式,大小不超过2M,可上传1张</p>
<p v-if="uploadType == 2 && showTips" class="upload-tip color-909399 font-12">建议尺寸:160×160;支持jpg、jpeg、png格式,图片大小不超过1MB</p>
<p v-if="uploadType == 3 && showTips" class="upload-tip color-909399 font-12">视频支持MP4格式,大小不超过10M,上传企业微信后3天内有效</p>
<p v-if="uploadType == 4 && showTips" class="upload-tip color-909399 font-12">建议尺寸:520×416,支持png、jpg、jpeg格式,大小不超过1M</p>
<!-- 图片预览 -->
<!-- <vue-gic-img-preview :imgUrl="imgUrl" :imgShowFlag="imgShowFlag" @hideImage="hideImage"></vue-gic-img-preview> -->
</div>
>>>>>>> master
</div> </div>
</template> </template>
<script> <script>
...@@ -66,11 +90,15 @@ export default { ...@@ -66,11 +90,15 @@ export default {
}, },
uploadLimit: { uploadLimit: {
type: [Number, String], type: [Number, String],
default: 2 default: '2/MB'
}, },
uploadType: { uploadType: {
type: [Number, String], type: [Number, String],
default: 1 // 1.图片 2.网页 3.视频 4小程序 default: 1 // 1.图片 2.网页 3.视频 4小程序
},
showDel: {
type: Boolean,
default: false
} }
}, },
data() { data() {
...@@ -93,6 +121,9 @@ export default { ...@@ -93,6 +121,9 @@ export default {
// that.upUrl = that.baseUrl + '/api-plug/upload-img?wxFlag=1' // that.upUrl = that.baseUrl + '/api-plug/upload-img?wxFlag=1'
}, },
methods: { methods: {
handleRemove() {
this.$emit('update:imgSrc', '');
},
/** /**
* 上传图片/视频 * 上传图片/视频
*/ */
...@@ -128,6 +159,7 @@ export default { ...@@ -128,6 +159,7 @@ export default {
/* eslint-disable */ /* eslint-disable */
beforeAvatarUpload(file) { beforeAvatarUpload(file) {
const that = this; const that = this;
<<<<<<< HEAD
// console.log(file); // console.log(file);
that.fileType = file.type === 'image/jpeg' ? 'jpeg' : file.type === 'image/jpg' ? 'jpg' : file.type === 'image/png' ? 'png' : file.type == 'video/mp4' ? 'mp4' : ''; that.fileType = file.type === 'image/jpeg' ? 'jpeg' : file.type === 'image/jpg' ? 'jpg' : file.type === 'image/png' ? 'png' : file.type == 'video/mp4' ? 'mp4' : '';
const isJPG = file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png'; const isJPG = file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png';
...@@ -135,15 +167,37 @@ export default { ...@@ -135,15 +167,37 @@ export default {
const isLt2M = file.size / 1024 / 1024 < that.uploadLimit; const isLt2M = file.size / 1024 / 1024 < that.uploadLimit;
if ((that.uploadType == 1 || that.uploadType == 2 || that.uploadType == 4) && !isJPG) { if ((that.uploadType == 1 || that.uploadType == 2 || that.uploadType == 4) && !isJPG) {
that.$message.error('上传图片支持png、jpg、jpeg格式!'); that.$message.error('上传图片支持png、jpg、jpeg格式!');
=======
console.log(file);
that.fileType = file.type === 'image/jpeg' || file.type === 'image/gif' ? 'jpeg' : file.type === 'image/jpg' ? 'jpg' : file.type === 'image/png' ? 'png' : file.type == 'video/mp4' ? 'mp4' : '';
const isJPG = this.imgType.includes(file.type);
const isMP4 = file.type == 'video/mp4';
const uploadLimit = that.uploadLimit.split('/')[0];
const unit = that.uploadLimit.split('/')[1];
let isLt2M = false;
if (unit == 'KB') {
isLt2M = file.size / 1024 < uploadLimit;
} else {
isLt2M = file.size / 1024 / 1024 < uploadLimit;
>>>>>>> master
} }
if ((that.uploadType == 1 || that.uploadType == 2 || that.uploadType == 4) && !isJPG) {
that.$message.error(`上传图片支持${this.imgType.map((item) => item.split('/')[1]).join('、')}格式!`);
return false;
}
if ((that.uploadType == 1 || that.uploadType == 2 || that.uploadType == 4) && !isLt2M) { if ((that.uploadType == 1 || that.uploadType == 2 || that.uploadType == 4) && !isLt2M) {
that.$message.error(`上传图片大小不能超过 ${that.uploadLimit}MB!`); that.$message.error(`上传图片大小不能超过 ${uploadLimit}${unit}!`);
return false;
} }
if (that.uploadType == 3 && !isMP4) { if (that.uploadType == 3 && !isMP4) {
that.$message.error('上传视频支持MP4格式!'); that.$message.error('上传视频支持MP4格式!');
return false;
} }
if (that.uploadType == 3 && !isLt2M) { if (that.uploadType == 3 && !isLt2M) {
that.$message.error(`上传视频大小不能超过 ${that.uploadLimit}MB!`); that.$message.error(`上传视频大小不能超过 ${uploadLimit}${unit}!`);
return false;
} }
if (that.uploadType == 3) { if (that.uploadType == 3) {
return isMP4 && isLt2M; return isMP4 && isLt2M;
...@@ -193,6 +247,7 @@ export default { ...@@ -193,6 +247,7 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.w-500 { .w-500 {
width: 500px; width: 500px;
} }
...@@ -263,19 +318,30 @@ export default { ...@@ -263,19 +318,30 @@ export default {
} }
.avatar-uploader-icon { .avatar-uploader-icon {
<<<<<<< HEAD
font-size: 28px; font-size: 28px;
color: #8c939d; color: #8c939d;
width: 100px; width: 100px;
// height: 100px; // height: 100px;
// line-height: 100px; // line-height: 100px;
text-align: center; text-align: center;
=======
font-size: 24px;
color: #303133;
>>>>>>> master
} }
.avatar { .avatar {
max-width: 100px; max-width: 100px;
max-height: 100px; max-height: 100px;
display: block; display: block;
} }
.del-icon{
position: absolute;
top: -13px;
left: 92px;
z-index: 2;
cursor: pointer;
}
.upload-tip { .upload-tip {
margin-top: 8px; margin-top: 8px;
font-size: 12px; font-size: 12px;
......
<template>
<div class="target-group">
<div class="target" :style="{ width: `${100 / dataList.length}%` }" v-for="(el, index) in dataList" :key="index">
<div class="target-label">
{{ el.label }}
<el-tooltip v-if="el.tips" placement="top" popper-class="target-tooltip">
<div slot="content" v-html="el.tips" style="max-width: 450px"></div>
<i class="iconfont icon-QuestionCircleOutlined target-label-icon"></i>
</el-tooltip>
</div>
<div class="target-value">
{{ el.value }}<span v-if="el.unit" class="target-value-unit">{{ el.unit }}</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TargetGroup',
props: {
dataList: {
type: Array,
default: () => []
}
}
};
</script>
<style lang="scss" scoped>
.target-group {
display: flex;
justify-content: flex-start;
align-items: flex-start;
margin-top: 16px;
padding: 20px;
width: 100%;
min-width: 265px;
background: #f7f8fa;
border-radius: 4px;
box-sizing: border-box;
.target {
flex-shrink: 0;
.target-label {
font-size: 14px;
font-weight: 400;
color: #606266;
line-height: 20px;
.target-label-icon {
font-size: inherit;
}
}
.target-value {
display: flex;
justify-content: flex-start;
align-items: flex-end;
margin-top: 8px;
font-size: 24px;
font-family: DIN Alternate-Bold, DIN Alternate;
font-weight: bold;
color: #303133;
line-height: 28px;
.target-value-unit {
font-size: 14px;
line-height: 25px;
font-weight: 600;
}
}
}
}
</style>
/**
* v-clipboard 剪切板
*/
import Vue from 'vue';
const clipboard = {
bind(el, binding, vnode, oldVnode) {
el.val = binding.value;
el.handler = function() {
const val = el.val;
const input = document.createElement('input');
el.appendChild(input);
input.value = val;
input.select();
document.execCommand('Copy');
Vue.prototype.$message({ type: 'success', message: '复制成功' });
input.parentNode.removeChild(input);
};
el.addEventListener('click', el.handler);
},
update(el, binding, vnode, oldVnode) {
el.val = binding.value;
},
unbind: function(el) {
el.removeEventListener('click', el.handler);
}
};
const linkMap = {
codeList: 'https://www.yuque.com/exnmlu/oo64hg/thm172#WRdju',
codeGl: 'https://www.yuque.com/exnmlu/oo64hg/thm172#ADEzt',
codeCkmx: 'https://www.yuque.com/exnmlu/oo64hg/thm172#mDlza',
linkList: 'https://www.yuque.com/exnmlu/oo64hg/lggf7q#WRdju',
linkGl: 'https://www.yuque.com/exnmlu/oo64hg/lggf7q#ADEzt',
linkCkmx: 'https://www.yuque.com/exnmlu/oo64hg/lggf7q#mDlza'
};
const jumpLink = {
bind(el, binding) {
const { arg } = binding;
el.handler = function() {
window.open(linkMap[arg]);
};
el.addEventListener('click', el.handler);
},
unbind: function(el) {
el.removeEventListener('click', el.handler);
}
};
export default { clipboard, jumpLink };
...@@ -14,7 +14,7 @@ import router from './router'; ...@@ -14,7 +14,7 @@ import router from './router';
import store from './store/store'; import store from './store/store';
/* eslint-disable */ /* eslint-disable */
import '../static/css/index.less'; import '../static/css/index.less';
import '../theme/index.css'; // import '../theme/index.css';
import '../static/css/dialog.css'; import '../static/css/dialog.css';
import filters from './filters/index.js'; import filters from './filters/index.js';
...@@ -75,24 +75,6 @@ router.beforeEach((to, from, next) => { ...@@ -75,24 +75,6 @@ router.beforeEach((to, from, next) => {
} else { } else {
baseUrl = host; baseUrl = host;
} }
const { fromPath = [] } = from.meta || {};
if (Array.isArray(fromPath)) {
from.meta.keepAlive = fromPath.some(el => {
let menuUrlReg = el;
let pathConfigReg = /(:.*)(\/?)/;
const pathRegStr = '([\\d\\w]+[\\-]*[\\d\\w]*)';
while (pathConfigReg.test(menuUrlReg)) {
menuUrlReg = menuUrlReg.replace(pathConfigReg, `${pathRegStr}$2`);
}
pathConfigReg = /(\/\*)(\/?)/;
while (pathConfigReg.test(menuUrlReg)) {
menuUrlReg = menuUrlReg.replace(pathConfigReg, `${pathRegStr}$2`);
}
const reg = new RegExp(menuUrlReg);
return reg.test(to.path);
});
}
next(); next();
}); });
......
import _import from '../_import.js';
const attractFlowLinkRouter = [
{
path: '/attractFlowLink',
name: '引流链接',
component: _import('salesleads/actCodeManage/attractFlowLink', 'index'),
meta: {
// 页面组件的name属性
componentName: 'attractFlowLink',
// 从fromPath回到当前页面时,需要使用keep-alive
fromPath: ['/attractFlowLinkEdit/:id', '/attractFlowLinkInfo/:id', '/attractFlowLinkInfos/:id']
}
},
{
path: '/attractFlowLinkAdd',
name: '新增引流链接',
meta: {
type: 'add'
},
component: _import('salesleads/actCodeManage/attractFlowLink', 'detail')
},
{
path: '/attractFlowLinkEdit/:id',
name: '编辑引流链接',
meta: {
type: 'edit'
},
component: _import('salesleads/actCodeManage/attractFlowLink', 'detail')
},
{
path: '/attractFlowLinkInfo/:id',
name: '详情引流链接',
meta: {
type: 'info'
},
component: _import('salesleads/actCodeManage/attractFlowLink', 'info')
},
{
path: '/attractFlowLinkInfos/:id',
name: '详情引流链接',
meta: {
type: 'info'
},
component: _import('salesleads/actCodeManage/attractFlowLink', 'info')
},
{
path: '/attLinkRecord',
name: '查看记录',
component: _import('salesleads/actCodeManage/staffActCode', 'actCodeRecord')
},
{
path: '/ladingPageList',
name: '落地页列表',
component: _import('salesleads/actCodeManage/attractFlowLink/landingPage', 'list'),
meta: {
componentName: 'ladingPageList',
fromPath: ['/ladingPageEdit/:id']
}
},
{
path: '/ladingPageAdd',
name: '新建落地页',
meta: {
type: 'add'
},
component: _import('salesleads/actCodeManage/attractFlowLink/landingPage', 'detail')
},
{
path: '/ladingPageEdit/:id',
name: '编辑落地页',
meta: {
type: 'edit'
},
component: _import('salesleads/actCodeManage/attractFlowLink/landingPage', 'detail')
},
{
path: '/operationLog',
name: '操作日志',
component: _import('salesleads/actCodeManage', 'operateLog')
}
];
export default attractFlowLinkRouter;
import _import from '../_import.js';
const staffActCodeRouter = [
{
path: '/staffActCode',
name: '员工活码',
component: _import('salesleads/actCodeManage/staffActCode', 'index'),
meta: {
componentName: 'staffActCode',
fromPath: ['/actCodeEdit', '/actCodeBatch', '/actCodeDetail', '/actCodeDetails']
}
},
{
path: '/actCodeRecord',
name: '查看记录',
component: _import('salesleads/actCodeManage/staffActCode', 'actCodeRecord')
},
{
path: '/actCodeDetail',
name: '活码详情-数据',
component: _import('salesleads/actCodeManage/staffActCode', 'actCodeDetail')
},
{
path: '/actCodeDetails',
name: '活码详情-详情',
component: _import('salesleads/actCodeManage/staffActCode', 'actCodeDetail'),
meta: {
componentName: 'actCodeDetail',
fromPath: ['/actCodeRecord']
}
},
{
path: '/actCodeAdd',
name: '新增活码',
component: _import('salesleads/actCodeManage/staffActCode/views', 'setActCode')
},
{
path: '/actCodeEdit',
name: '编辑活码',
component: _import('salesleads/actCodeManage/staffActCode/views', 'setActCode')
},
{
path: '/actCodeBatch',
name: '批量创建活码',
component: _import('salesleads/actCodeManage/staffActCode/views', 'batchAddCode')
}
];
export default staffActCodeRouter;
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
import Vue from 'vue'; import Vue from 'vue';
import Router from 'vue-router'; import Router from 'vue-router';
import _import from './_import.js'; import _import from './_import.js';
import actCodeManageRouter from './actCodeManageRouter';
Vue.use(Router); Vue.use(Router);
const errorPage = r => { const errorPage = r => {
...@@ -99,7 +100,11 @@ export const constantRouterMap = [ ...@@ -99,7 +100,11 @@ export const constantRouterMap = [
{ {
path: '/salutatory', path: '/salutatory',
name: '欢迎语', name: '欢迎语',
component: _import('enterprise', 'salutatory') component: _import('enterprise', 'salutatoryIndex'),
meta:{
componentName: 'salutatoryIndex',
fromPath: ['/editSalutatorySet']
}
}, },
{ {
path: '/salutatorySet', path: '/salutatorySet',
...@@ -143,7 +148,7 @@ export const constantRouterMap = [ ...@@ -143,7 +148,7 @@ export const constantRouterMap = [
name: '话务任务记录', name: '话务任务记录',
component: _import('salesleads/trafficTask', 'taskRecord'), component: _import('salesleads/trafficTask', 'taskRecord'),
meta: { meta: {
keepAlive: true, componentName: 'TaskRecord',
fromPath: ['/taskDetail'] fromPath: ['/taskDetail']
} }
...@@ -173,7 +178,7 @@ export const constantRouterMap = [ ...@@ -173,7 +178,7 @@ export const constantRouterMap = [
name: '门店视图', name: '门店视图',
component: _import('salesleads/groupSend', 'grStoreList'), component: _import('salesleads/groupSend', 'grStoreList'),
meta: { meta: {
keepAlive: true, componentName: 'grStoreList',
fromPath: ['/grStoreDetail/:id'] fromPath: ['/grStoreDetail/:id']
} }
}, },
...@@ -241,7 +246,7 @@ export const constantRouterMap = [ ...@@ -241,7 +246,7 @@ export const constantRouterMap = [
name: '客户分组设置', name: '客户分组设置',
component: _import('apps/customerApp', 'memberGroupSet'), component: _import('apps/customerApp', 'memberGroupSet'),
meta: { meta: {
keepAlive: true, componentName: 'memberGroupSet',
fromPath: ['/addGroupTemplate', '/editGroupTemplate', '/storeRangeSet'] fromPath: ['/addGroupTemplate', '/editGroupTemplate', '/storeRangeSet']
} }
}, },
...@@ -352,7 +357,7 @@ export const constantRouterMap = [ ...@@ -352,7 +357,7 @@ export const constantRouterMap = [
name: '月指标任务', name: '月指标任务',
component: _import('apps/quota', 'monthTask'), component: _import('apps/quota', 'monthTask'),
meta: { meta: {
keepAlive: true, componentName: 'monthTask',
fromPath: ['/monthTaskDetail'] fromPath: ['/monthTaskDetail']
} }
}, },
...@@ -435,6 +440,8 @@ export const constantRouterMap = [ ...@@ -435,6 +440,8 @@ export const constantRouterMap = [
name: '订单评价', name: '订单评价',
component: _import('apps/order-evaluate', 'evaluate-set') component: _import('apps/order-evaluate', 'evaluate-set')
}, },
// 活码相关路由
...actCodeManageRouter,
{ {
path: '/403', path: '/403',
......
import Vue from 'vue' import Vue from 'vue';
import Clipboard from 'clipboard' import Clipboard from 'clipboard';
function clipboardSuccess() { function clipboardSuccess() {
Vue.prototype.$message({ Vue.prototype.$message({
message: 'Copy successfully', message: 'Copy successfully',
type: 'success', type: 'success',
duration: 1500 duration: 1500
}) });
} }
function clipboardError() { function clipboardError() {
Vue.prototype.$message({ Vue.prototype.$message({
message: 'Copy failed', message: 'Copy failed',
type: 'error' type: 'error'
}) });
} }
export default function handleClipboard(text, event) { export default function handleClipboard(text, event) {
const clipboard = new Clipboard(event.target, { const clipboard = new Clipboard(event.target, {
text: () => text text: () => text
}) });
clipboard.on('success', () => { clipboard.on('success', () => {
clipboardSuccess() clipboardSuccess();
clipboard.off('error') clipboard.off('error');
clipboard.off('success') clipboard.off('success');
clipboard.destroy() clipboard.destroy();
}) });
clipboard.on('error', () => { clipboard.on('error', () => {
clipboardError() clipboardError();
clipboard.off('error') clipboard.off('error');
clipboard.off('success') clipboard.off('success');
clipboard.destroy() clipboard.destroy();
}) });
clipboard.onClick(event) clipboard.onClick(event);
} }
/*设置cookie*/ /*设置cookie*/
export function setCookie(c_name,value,expire) { export function setCookie(c_name, value, expire) {
var date=new Date(); var date = new Date();
date.setSeconds(date.getSeconds()+expire); date.setSeconds(date.getSeconds() + expire);
document.cookie = c_name + "="+ encodeURI(value)+"; expires="+date.toGMTString(); document.cookie = c_name + '=' + encodeURI(value) + '; expires=' + date.toGMTString();
} }
/*获取cookie*/ /*获取cookie*/
export function getCookie(c_name){ export function getCookie(c_name) {
if(document.cookie.length>0){ if (document.cookie.length > 0) {
var name = encodeURI(c_name); var name = encodeURI(c_name);
var allcookies = document.cookie; var allcookies = document.cookie;
name += "="; name += '=';
var pos = allcookies.indexOf(name); var pos = allcookies.indexOf(name);
if(pos != -1){ if (pos != -1) {
var start = pos + name.length; var start = pos + name.length;
var end = allcookies.indexOf(";",start); var end = allcookies.indexOf(';', start);
if(end == -1){ if (end == -1) {
end = allcookies.length; end = allcookies.length;
} }
var value = allcookies.substring(start,end); var value = allcookies.substring(start, end);
return decodeURI(value); return decodeURI(value);
} else{ } else {
return ""; return '';
} }
} }
} }
/*删除cookie*/ /*删除cookie*/
export function delCookie(c_name){ export function delCookie(c_name) {
setCookie(c_name, "", -1); setCookie(c_name, '', -1);
} }
...@@ -3,32 +3,32 @@ ...@@ -3,32 +3,32 @@
*/ */
export function isvalidUsername(str) { export function isvalidUsername(str) {
const valid_map = ['admin', 'editor'] const valid_map = ['admin', 'editor'];
return valid_map.indexOf(str.trim()) >= 0 return valid_map.indexOf(str.trim()) >= 0;
} }
/* 合法uri*/ /* 合法uri*/
export function validateURL(textval) { export function validateURL(textval) {
const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
return urlregex.test(textval) return urlregex.test(textval);
} }
/* 小写字母*/ /* 小写字母*/
export function validateLowerCase(str) { export function validateLowerCase(str) {
const reg = /^[a-z]+$/ const reg = /^[a-z]+$/;
return reg.test(str) return reg.test(str);
} }
/* 大写字母*/ /* 大写字母*/
export function validateUpperCase(str) { export function validateUpperCase(str) {
const reg = /^[A-Z]+$/ const reg = /^[A-Z]+$/;
return reg.test(str) return reg.test(str);
} }
/* 大小写字母*/ /* 大小写字母*/
export function validateAlphabets(str) { export function validateAlphabets(str) {
const reg = /^[A-Za-z]+$/ const reg = /^[A-Za-z]+$/;
return reg.test(str) return reg.test(str);
} }
/** /**
...@@ -37,7 +37,23 @@ export function validateAlphabets(str) { ...@@ -37,7 +37,23 @@ export function validateAlphabets(str) {
* @returns {boolean} * @returns {boolean}
*/ */
export function validateEmail(email) { export function validateEmail(email) {
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email) return re.test(email);
} }
/** 表单校验滚动到第一个错误项
* @param {Object} that vue实例
* this.scrollToError(this);
*/
export const scrollToError = (that, className = 'is-error') => {
that.$nextTick(_ => {
const isError = document.getElementsByClassName(className);
isError[0].scrollIntoView({
// 滚动到指定节点
// 值有start,center,end,nearest,当前显示在视图区域中间
block: 'center',
// 值有auto、instant,smooth,缓动动画(当前是慢速的)
behavior: 'smooth'
});
});
};
...@@ -418,7 +418,7 @@ export default { ...@@ -418,7 +418,7 @@ export default {
}, },
mounted() { mounted() {
let start = new Date(); let start = new Date();
start = new Date(start.setMonth(start.getMonth() - 3)); start = new Date(start.setMonth(start.getMonth() - 1));
const end = new Date(); const end = new Date();
const startDate = []; const startDate = [];
const endDate = []; const endDate = [];
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
import MemberGroupList from './memberGroupList.vue'; import MemberGroupList from './memberGroupList.vue';
import MemberGroupSetList from './memberGroupSetList.vue'; import MemberGroupSetList from './memberGroupSetList.vue';
export default { export default {
name: 'app-detail', name: 'memberGroupSet',
components: { MemberGroupList, MemberGroupSetList }, components: { MemberGroupList, MemberGroupSetList },
props: { props: {
brandId: { brandId: {
......
...@@ -165,7 +165,7 @@ export default { ...@@ -165,7 +165,7 @@ export default {
totalCount: 4, // 总同步次数 totalCount: 4, // 总同步次数
canUseCount: 0, // 剩余同步次数 canUseCount: 0, // 剩余同步次数
checkFirst: '', checkFirst: '',
syncStatusOpt: { 0: '未同步', 1: '同步中', 2: '同步完成 ' }, syncStatusOpt: { 0: '未同步', 1: '同步中', 2: '同步完成 ', 3: '同步失败' },
syncStatusClass: { 0: 'state-point-default', 1: 'state-point-loading-scale', 2: 'state-point-success', 3: 'state-point-error' } syncStatusClass: { 0: 'state-point-default', 1: 'state-point-loading-scale', 2: 'state-point-success', 3: 'state-point-error' }
}; };
}, },
......
...@@ -51,7 +51,7 @@ import { getRequest, postExcel } from '@/api/api'; ...@@ -51,7 +51,7 @@ import { getRequest, postExcel } from '@/api/api';
import { _debounce } from '@/common/js/public'; import { _debounce } from '@/common/js/public';
import errMsg from '@/common/js/error'; import errMsg from '@/common/js/error';
export default { export default {
name: 'reviewed', name: 'monthTask',
props: { props: {
brandId: { brandId: {
type: String, type: String,
......
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
<el-button v-if="scope.row.channelCode == 2005" class="cursor-unset" type="text">审核被解绑</el-button> <el-button v-if="scope.row.channelCode == 2005" class="cursor-unset" type="text">审核被解绑</el-button>
<el-button v-if="scope.row.channelCode == 2006" class="cursor-unset" type="text">权限变更解绑</el-button> <el-button v-if="scope.row.channelCode == 2006" class="cursor-unset" type="text">权限变更解绑</el-button>
<el-button v-if="scope.row.channelCode == 2007" class="cursor-unset" type="text">门店变更解绑</el-button> <el-button v-if="scope.row.channelCode == 2007" class="cursor-unset" type="text">门店变更解绑</el-button>
<el-button v-if="scope.row.channelCode == 2008" class="cursor-unset" type="text">GIC导购删除解绑</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
......
<template>
<el-dialog title="关联详情" width="610px" :visible.sync="dialogVisible" @close="$emit('update:dialogVisible', false)">
<div class="daily-set-content boder-box">
<div class="flex flex-space-between m-b-16">
<el-input placeholder="请输入关联ID / 关联名称 " class="w-260" v-model="form.searchContent" @keyup.native="value => toInput(value, searchInput)" clearable @clear="getList"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input>
</div>
</div>
<el-table class="select-table" ref="multipleTable" v-loading="loading" :data="tableData" height="450" tooltip-effect="dark">
<el-table-column prop="referCode" label="关联ID"></el-table-column>
<el-table-column prop="referName" label="关联名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="type" label="类型">
<template slot-scope="{ row }">
{{ row.type == 1 ? '引流链接' : '员工活码' }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template slot-scope="{ row }">
<div class="status-class">
<span :class="['state-point', logStatusClass[row.status]]">{{ relationSatusMap[row.status] || '- -' }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="" label="操作" width="80">
<template slot-scope="{ row }">
<el-button type="text" @click="$emit('goLinkDetail', row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination class="text-right margin-pg" @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-size.sync="form.pageSize" :current-page.sync="form.pageNum" layout="prev, pager, next" :total="total"> </el-pagination>
</el-dialog>
</template>
<script>
import { welcomeRelationList } from '@/api/actCode';
import { _debounce } from '@/common/js/public';
export default {
data() {
return {
form: {
searchContent: '',
welcomeId: '',
pageNum: 1,
pageSize: 20
},
loading: false,
total: 0,
tableData: [],
relationSatusMap: {
1: '正常',
0: '删除',
2: '废弃'
},
logStatusClass: { 1: 'state-point-success', 0: 'state-point-error', 2: 'state-point-warning' }
};
},
props: {
id: {
type: String,
default: ''
},
dialogVisible: {
type: Boolean,
default: false
}
},
watch: {
id(val) {
if (val) {
this.form = { searchContent: '', welcomeId: val, pageNum: 1, pageSize: 20 };
this.getList();
}
}
},
methods: {
toInput: _debounce(function(e, value) {
this.getList();
}, 500),
getList() {
this.loading = true;
welcomeRelationList(this.form)
.then(res => {
const { totalCount, result } = res.data.result;
if (result) {
this.total = totalCount;
this.tableData = result;
}
// let obj = { referCode: 'HM01421002535046766593', referId: '421002535046766593', referName: '吴苏兰', relationId: '421002538737754114', status: 1, type: 2, typeText: null };
// for (let i = 0; i < 50; i++) {
// this.tableData.push(obj);
// }
// this.total = 50;
})
.finally(_ => {
this.loading = false;
});
},
handleSizeChange(val) {
this.form.pageNum = 1;
this.form.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.form.pageNum = val;
this.getList();
}
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.margin-pg {
margin: 20px 0 0 0;
}
</style>
<template>
<div class="salutatory">
<el-tabs v-model="activeName">
<el-tab-pane label="普通欢迎语" :name="1">
<salutatory :type="activeName" v-if="activeName == 1" />
</el-tab-pane>
<el-tab-pane label="特殊欢迎语" :name="2">
<salutatory :type="activeName" v-if="activeName == 2" />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import salutatory from './salutatory.vue';
export default {
name: 'salutatoryIndex',
components: {
salutatory
},
data() {
return {
activeName: 1
};
},
mounted() {
if (sessionStorage.getItem('activeName')) {
this.activeName = Number(sessionStorage.getItem('activeName'));
}
},
activated() {
if (sessionStorage.getItem('activeName')) {
this.activeName = Number(sessionStorage.getItem('activeName'));
}
},
destroyed() {
sessionStorage.setItem('activeName', 1);
},
watch: {
activeName(val) {
sessionStorage.setItem('activeName', val);
}
}
};
</script>
<style type="text/scss" lang="scss" scoped></style>
...@@ -77,7 +77,11 @@ export default { ...@@ -77,7 +77,11 @@ export default {
*/ */
toLogin() { toLogin() {
const that = this; const that = this;
const href = `${window.location.origin}/haoban-manage3-web/gic-login?wxEnterpriseId=${that.enterpriseList[that.active].wxEnterpriseId}&random=${that.$route.query.random}`; const { random, hbPage } = this.$route.query;
let href = `${window.location.origin}/haoban-manage3-web/gic-login?wxEnterpriseId=${that.enterpriseList[that.active].wxEnterpriseId}&random=${random}`;
if (hbPage) {
href = `${window.location.origin}/haoban-manage3-web/gic-login?wxEnterpriseId=${that.enterpriseList[that.active].wxEnterpriseId}&random=${random}&hbPage=${hbPage}`;
}
window.location.href = href; window.location.href = href;
}, },
changeEnterprise(val) { changeEnterprise(val) {
......
<template>
<div class="card">
<div class="head">
<div class="operation">
<div class="idNum">ID:{{ card.pageCode }}</div>
<div class="btns">
<el-button type="text" @click="$emit('relationDetail')">关联详情</el-button>
<el-button type="text" @click="$emit('deleteTemp')">删除</el-button>
<el-button type="text" @click="$emit('editTemp')">编辑</el-button>
</div>
</div>
<div class="tempName">{{ card.pageName }}</div>
<div class="cardName">
<div class="createName">{{ card.createorName }}</div>
<div class="createTime">{{ card.createTime | formatTimeStamp }}</div>
</div>
</div>
<div class="iphone-content">
<div class="iphone">
<span class="pageTitle">{{ card.pageTitle }}</span>
<img src="@/assets/iphone-head.png" />
<div class="content">
<img :src="card.pageBackgroundImg" v-show="card.pageBackgroundImg" class="bgImg" />
<div class="enterpriseInfo">
<div v-if="card.merchantLogo" class="logo">
<img :src="card.merchantLogo" />
</div>
<div class="name">{{ card.merchantName }}</div>
</div>
<div class="QRcode"></div>
<div class="leadingText">{{ card.guideComment }}</div>
<div class="enterpriseNum" v-if="card.merchantPhoneNumber">
<i class="iconfont-hb3 icondianhua"></i>
<p>{{ card.merchantPhoneNumber }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
card: {
pageName: '',
pageCode: '',
pageId: '',
pageTitle: '',
merchantName: '',
merchantPhoneNumber: '',
merchantLogo: '',
pageBackgroundImg: '',
guideComment: ''
}
};
},
props: {
content: {
type: Object,
default: () => {}
}
},
watch: {
content: {
handler(val) {
if (val) {
const { pageName, pageCode, pageId, pageTitle, merchantName, merchantPhoneNumber, merchantLogo, pageBackgroundImg, guideComment, createorName, createTime } = val;
this.card = { pageName, pageCode, pageId, pageTitle, merchantName, merchantPhoneNumber, merchantLogo, pageBackgroundImg, guideComment, createorName, createTime };
}
},
immediate: true
}
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.card {
width: 380px;
height: 687px;
border-radius: 8px;
border: 1px solid #dcdfe6;
background: RGBA(240, 243, 253, 1);
.head {
width: 380px;
height: 87px;
border-radius: 8px 8px 0px 0px;
box-sizing: border-box;
padding: 15px 16px 8px 16px;
}
.operation {
display: flex;
justify-content: space-between;
margin-bottom: 7px;
.idNum {
font-size: 12px;
color: #606266;
line-height: 17px;
}
}
.tempName {
font-size: 14px;
font-weight: 500;
color: #303133;
line-height: 20px;
}
.cardName {
display: flex;
justify-content: space-between;
.createName,
.createTime {
font-size: 12px;
color: #606266;
line-height: 17px;
}
}
.iphone-content {
width: 380px;
height: 600px;
display: flex;
justify-content: center;
background: #ffffff;
border-radius: 0px 0px 8px 8px;
}
.iphone {
width: 320px;
height: 570px;
box-shadow: 0px 4px 8px 0px rgba(220, 223, 230, 0.6);
border-radius: 8px;
position: relative;
margin-top: 11px;
.pageTitle {
position: absolute;
font-size: 14px;
color: #000000;
font-weight: 500;
width: 135px;
margin-left: 85px;
line-height: 20px;
white-space: nowrap;
text-align: center;
top: 44px;
}
.content {
width: 320px;
height: 495px;
background: #ffffff;
border-radius: 8px;
top: 75px;
left: 0;
box-sizing: border-box;
padding: 20px 16px;
position: absolute;
display: flex;
align-items: center;
flex-direction: column;
.bgImg {
position: absolute;
width: 100%;
border-radius: 8px;
top: 0;
z-index: 0;
max-height: 100%;
}
.enterpriseInfo {
display: flex;
justify-content: flex-start;
align-items: center;
width: 100%;
z-index: 100;
height: 36px;
margin-bottom: 19px;
.logo {
width: 48px;
height: 48px;
background: #f6f6f6;
border-radius: 60px;
img {
width: 48px;
height: 48px;
border-radius: 60px;
}
}
.name {
margin-left: 10px;
font-size: 14px;
font-weight: 500;
color: #242835;
line-height: 20px;
width: 80%;
}
}
.QRcode {
z-index: 100;
width: 236px;
height: 236px;
background-image: url('../../../../../assets/QRcode.jpg');
background-size: 236px auto;
}
.leadingText {
z-index: 100;
font-size: 12px;
color: #7f818a;
line-height: 17px;
width: 88%;
margin-top: 16px;
height: 50px;
text-align: center;
}
.enterpriseNum {
z-index: 100;
min-width: 160px;
margin-top: 25px;
height: 40px;
box-sizing: border-box;
border-radius: 40px;
border: 1px solid #9da0a6;
display: flex;
align-items: center;
padding: 9px 12px;
line-height: 14px;
color: #63666b;
font-size: 12px;
justify-content: center;
i {
font-size: 17px;
}
p {
margin-left: 5px;
}
}
}
}
}
</style>
<template>
<div>
<div class="daily-set-content" v-loading="loading">
<el-form label-width="100px" ref="form" :model="form" :rules="rules" class="form">
<el-form-item label="模板名称" prop="pageName">
<el-input show-word-limit placeholder="请输入模板名称" type="text" v-model="form.pageName" maxlength="20" class="w-340"></el-input>
</el-form-item>
<el-form-item label="页面标题" prop="pageTitle">
<el-input show-word-limit placeholder="请输入页面标题" type="text" v-model="form.pageTitle" maxlength="10" class="w-340"></el-input>
</el-form-item>
<el-form-item label="商户名称" prop="merchantName">
<el-input show-word-limit placeholder="请输入商户名称" type="text" v-model="form.merchantName" maxlength="20" class="w-340"></el-input>
</el-form-item>
<el-form-item label="商户电话" prop="merchantPhoneNumber">
<el-input show-word-limit placeholder="请输入商户电话" type="text" v-model="form.merchantPhoneNumber" maxlength="20" class="w-340"></el-input>
</el-form-item>
<el-form-item label="商户LOGO">
<single-upload uploadType="1" :showDel="true" :showTips="false" :imgSrc.sync="form.merchantLogo" :field="''" class="app-set" uploadLimit="200/KB" :imgType="['image/jpeg', 'image/jpg', 'image/png', 'image/gif']"> </single-upload>
<p style="margin-top: 6px;font-size: 12px;color: #909399;line-height: 17px;">图片建议尺寸 240*240px,格式 jpg/jpep/png/gif,大小 200KB 以内。</p>
</el-form-item>
<el-form-item label="页面背景">
<single-upload uploadType="1" :showDel="true" :showTips="false" :imgSrc.sync="form.pageBackgroundImg" :field="''" class="app-set" :imgType="['image/jpeg', 'image/jpg', 'image/png', 'image/gif']"> </single-upload>
<p style="margin-top: 6px;font-size: 12px;color: #909399;line-height: 17px;">图片建议尺寸 750*1334px,格式 jpg/png/gif,大小 2M 以内。</p>
</el-form-item>
<el-form-item label="引导语" prop="guideComment">
<el-input show-word-limit placeholder="请输入引导语" type="textarea" v-model="form.guideComment" maxlength="50" class="w-340" :autosize="{ minRows: 4, maxRows: 6 }"></el-input>
</el-form-item>
</el-form>
<div class="rightContent">
<p class="previewTitle">落地页预览</p>
<previewPage :data="form" class="preview" />
<p class="previewBottom">此二维码只是样式预览效果,请勿直接使用</p>
</div>
</div>
<div class="footBtn">
<el-button type="primary" @click="save" :loading="btnLoading">保存</el-button>
</div>
</div>
</template>
<script>
import singleUpload from '@/components/single-upload.vue';
import previewPage from '@/components/preview-page.vue';
import { guidePageDetail, guidePageEdit, guidePageSave, wxEnterpriseList } from '@/api/actCode';
export default {
components: {
previewPage,
singleUpload
},
data() {
const merchantPhoneNumberVal = (rules, value, callback) => {
const reg = /^[0-9 \+\-]{0,20}$/;
const reg1 = /^\s*$/;
const reg2 = /^\+*$/;
const reg3 = /^\-*$/;
if (!value) {
callback();
return;
}
if (reg1.test(value) || reg2.test(value) || reg3.test(value)) {
callback('请输入正确的手机号');
}
if (!reg.test(value)) {
callback('仅支持输入数字,空格,-,+');
}
callback();
};
return {
form: {
pageName: '',
pageTitle: '',
merchantName: '',
merchantPhoneNumber: '',
merchantLogo: '',
//https://pic01-10001430.image.myqcloud.com/b91f73af-43e4-4733-a4d3-0ab0bcb4ce7f
pageBackgroundImg: '',
guideComment: '长按保存图片并识别二维码添加您的专属导购'
},
wxEnterpriseId: sessionStorage.getItem('userInfos') ? JSON.parse(sessionStorage.getItem('userInfos')).wxEnterpriseId : '',
logoImageList: [],
isEdit: this.$route.meta.type == 'edit',
isAdd: this.$route.meta.type == 'add',
loading: false,
btnLoading: false,
rules: {
merchantPhoneNumber: [{ validator: merchantPhoneNumberVal }],
pageName: [{ required: true, message: '请输入模板名称' }]
}
};
},
mounted() {
if (this.isEdit) {
this.getDetail();
} else {
this.getEchoEnterpriseInfo();
}
},
methods: {
getDetail() {
console.log(this.$route);
this.loading = true;
guidePageDetail({ pageId: this.$route.params.id })
.then(res => {
if (res.data.result) {
const result = res.data.result;
this.form = result;
}
})
.finally(_ => {
this.loading = false;
});
},
getEchoEnterpriseInfo() {
wxEnterpriseList({}).then(res => {
let resData = res.data;
if (!!resData.result && !!resData.result.length) {
const { customerPhone, enterpriseLogo, enterpriseName } = resData.result.filter(item => item.wxEnterpriseId == this.wxEnterpriseId)[0];
this.form.merchantLogo = enterpriseLogo;
this.form.merchantPhoneNumber = customerPhone;
this.form.merchantName = enterpriseName;
}
});
},
guidePageEdit() {
this.btnLoading = true;
guidePageEdit(this.form)
.then(_ => {
this.$router.push('/ladingPageList');
this.$message.success('保存成功');
})
.finally(_ => {
this.btnLoading = false;
});
},
guidePageSave() {
this.btnLoading = true;
guidePageSave(this.form)
.then(_ => {
this.$router.push('/ladingPageList');
this.$message.success('保存成功');
})
.finally(_ => {
this.btnLoading = false;
});
},
save() {
this.$refs.form.validate(val => {
if (!val) return;
if (this.isEdit) {
this.guidePageEdit();
} else {
this.guidePageSave();
}
});
}
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.daily-set-content {
padding: 20px;
margin-bottom: 56px;
}
.form {
float: left;
}
.rightContent {
margin-left: 734px;
width: 280px;
display: flex;
flex-direction: column;
align-items: center;
}
.previewTitle {
font-weight: 500;
color: #303133;
line-height: 20px;
font-size: 14px;
width: 70px;
text-align: center;
margin-bottom: 20px;
}
.footBtn {
width: calc(100vw - 190px);
height: 56px;
background: #ffffff;
box-shadow: 1px -2px 8px 0px rgba(220, 223, 230, 0.6);
position: fixed;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
}
.previewBottom {
font-size: 12px;
text-align: center;
width: 228px;
color: #909399;
line-height: 17px;
}
</style>
<template>
<div class="daily-set-content">
<div class="flex flex-space-between m-b-16">
<div class="flex flex-align-center">
<el-input placeholder="请输入模板ID/名称、创建人" class="w-260" v-model="form.pageSearchText" @keyup.native="toInput" clearable @clear="getList"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input>
<span style="font-size:14px;" class="m-l-10">模板创建时间:</span>
<el-date-picker class="m-l-10 w-256" v-model="form.dateRange" @change="getList" type="daterange" :value-format="'yyyy-MM-dd'" clearable @clear="getList" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期"> </el-date-picker>
</div>
<el-button type="primary" @click="addTemp">新增模板</el-button>
</div>
<div class="tips m-b-16">
二维码只是样式预览效果,请勿直接使用
</div>
<div v-loading="loading">
<div class="card-content" v-if="list && list.length">
<card-view :content="item" v-for="item in list" :key="item.pageId" @relationDetail="relationDetail(item)" @deleteTemp="deleteTemp(item)" @editTemp="editTemp(item)" />
</div>
<div v-else class="chart--nodata">
<div>
<img class="image-120" src="@/assets/no-data.svg" />
<p class="font-14 color-606266 no-data-text">暂无数据</p>
</div>
</div>
</div>
<relation-dialog :dialogVisible.sync="dialogVisible" :pageId="pageId" @goLinkDetail="goLinkDetail" />
<div class="text-right" v-if="list.length != 0">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-size.sync="form.pageSize" :current-page.sync="form.pageNum" layout="total, sizes, prev, pager, next, jumper" :page-sizes="[20, 40, 60, 80]" :total="total"> </el-pagination>
</div>
</div>
</template>
<script>
import cardView from './cardView';
import relationDialog from './relationDialog';
import { guidePageList, guidePageDel, guidePageRelation } from '@/api/actCode';
import { _debounce } from '@/common/js/public';
export default {
name: 'ladingPageList',
data() {
return {
form: {
pageSearchText: '',
dateRange: [],
pageSize: 20,
pageNum: 1
},
loading: false,
total: 0,
pageId: '',
dialogVisible: false,
list: []
};
},
components: {
cardView,
relationDialog
},
mounted() {
this.getList();
},
activated() {
this.getList();
},
methods: {
toInput: _debounce(function(e, value) {
this.getList();
}, 500),
getList() {
const param = { ...this.form };
if (this.form.dateRange && this.form.dateRange.length) {
param.startTime = this.form.dateRange[0] + ' 00:00:00';
param.endTime = this.form.dateRange[1] + ' 23:59:59';
}
delete param.dateRange;
this.loading = true;
guidePageList(param)
.then(res => {
const { result, totalCount } = res.data.result;
if (result) {
this.total = totalCount;
this.list = result;
}
})
.finally(_ => {
this.loading = false;
});
},
handleSizeChange(val) {
this.form.pageNum = 1;
this.form.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.form.pageNum = val;
this.getList();
},
addTemp() {
this.$router.push('/ladingPageAdd');
},
relationDetail(item) {
this.dialogVisible = true;
this.pageId = item.pageId;
},
deleteTemp(item) {
guidePageRelation({ pageId: item.pageId }).then(res => {
const { totalCount } = res.data.result;
if (totalCount) {
this.$confirm(`当前模板已关联链接(${totalCount}),请确认投放链接已投放结束,解除关联后才可删除该模板`, '无法删除该模板', {
confirmButtonText: '关联详情',
cancelButtonText: '取消',
type: 'warning'
}).then(_ => {
this.relationDetail(item);
});
} else {
this.$confirm('模板删除后将无法恢复', '确认要删除该模板吗?', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(_ => {
this.deleteRequest(item);
});
}
});
},
deleteRequest(item) {
guidePageDel({ pageId: item.pageId }).then(res => {
this.$message.success('删除成功');
this.getList();
});
},
editTemp(item) {
this.$router.push(`/ladingPageEdit/${item.pageId}`);
},
goLinkDetail(referId) {
window.open(`/haoban-3/#/attractFlowLinkInfo/${referId}`);
}
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.daily-set-content {
padding: 20px;
}
.card-content {
width: 100%;
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.chart--nodata {
height: 359px;
width: 100%;
display: flex;
justify-content: center;
.image-120 {
width: 120px;
height: 120px;
padding-top: 60px;
}
.no-data-text {
text-align: center;
padding-top: 18px;
}
}
</style>
<template>
<el-dialog title="关联详情" width="600px" :visible.sync="dialogVisible" @close="$emit('update:dialogVisible', false)">
<div class="daily-set-content boder-box">
<div class="flex flex-space-between m-b-16">
<el-input placeholder="请输入链接名称/ID" class="w-260" v-model="form.searchContent" @keyup.native="value => toInput(value, searchInput)" clearable @clear="getList"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input>
</div>
</div>
<el-table class="select-table" ref="multipleTable" v-loading="loading" :data="tableData" height="450" tooltip-effect="dark">
<el-table-column prop="releationId" label="链接ID" show-overflow-tooltip></el-table-column>
<el-table-column prop="referName" label="链接名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="" label="操作" width="80">
<template slot-scope="{ row }">
<el-button type="text" @click="$emit('goLinkDetail', row.referId)">查看</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination class="text-right margin-pg" @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-size.sync="form.pageSize" :current-page.sync="form.pageNum" layout="prev, pager, next" :total="total"> </el-pagination>
</el-dialog>
</template>
<script>
import { guidePageRelation } from '@/api/actCode';
import { _debounce } from '@/common/js/public';
export default {
data() {
return {
form: {
searchContent: '',
pageId: '',
pageNum: 1,
pageSize: 20
},
loading: false,
total: 0,
tableData: []
};
},
props: {
pageId: {
type: String,
default: ''
},
dialogVisible: {
type: Boolean,
default: false
}
},
watch: {
pageId(val) {
if (val) {
this.form = { searchContent: '', pageId: val, pageNum: 1, pageSize: 20 };
this.getList();
}
}
},
methods: {
toInput: _debounce(function(e, value) {
this.getList();
}, 500),
getList() {
this.loading = true;
guidePageRelation(this.form)
.then(res => {
const { totalCount, result } = res.data.result;
if (result) {
this.total = totalCount;
this.tableData = result;
}
})
.finally(_ => {
this.loading = false;
});
},
handleSizeChange(val) {
this.form.pageNum = 1;
this.form.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.form.pageNum = val;
this.getList();
}
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.margin-pg {
margin: 20px 0 0 0;
}
</style>
<template>
<div>
<div :id="id" class="chart--nodata"></div>
<div v-if="!charData.length" class="chart--nodata">
<div>
<img class="image-120" src="@/assets/no-data.svg" />
<p class="font-14 color-606266 no-data-text">暂无数据</p>
</div>
</div>
</div>
<!-- <div v-if="charData.length" :id="id"></div> -->
<!-- <div v-else class="chart--nodata"></div> -->
</template>
<script>
import * as G2 from '@antv/g2';
export default {
data() {
return {
chart: null,
maxNum: 0,
maxTimes: 0
};
},
props: {
charData: {
type: Array,
default() {
return [];
}
},
id: String
},
mounted() {
setTimeout(() => {
this.drawChart(); // 第一步是创建的时候更新图表,但是这个不适用于异步请求接口获取相关数据,采用下面的监听的方式
}, 30);
},
beforeUpdate() {
this.drawChart();
},
watch: {
charData() {
this.drawChart();
}
},
methods: {
async drawChart() {
this.chart && this.chart.destroy();
if (!this.charData.length) return;
const data = this.handleData(this.charData);
this.chart = new G2.Chart({
container: this.id,
autoFit: true,
forceFit: true,
height: 359,
width: 1400,
padding: [70, 60, 40, 70]
});
this.chart.source(data, {
value: {
type: 'linear',
tickInterval: 50
}
});
this.chart.tooltip({
showMarkers: false,
shared: true
});
this.chart.scale({
date: {
dataKey: 'date',
type: 'cat'
},
num: {
min: 0,
tickCount: this.maxNum > 2 ? 5 : this.maxNum + 1,
tickMethod: 'wilkinson-extended',
nice: true
},
times: {
min: 0,
tickCount: this.maxTimes > 2 ? 5 : this.maxTimes + 1,
tickMethod: 'wilkinson-extended',
nice: true
}
});
this.chart.legend({
position: 'top-left'
});
this.chart.axis('times', {
grid: {
line: {
type: 'line',
style: {
stroke: '#E4E7ED',
lineDash: [3, 3]
}
}
},
label: {
formatter: text => {
let num = Math.floor(text);
return num + '人次';
}
}
});
this.chart.axis('num', {
grid: {
line: {
type: 'line',
style: {
stroke: '#E4E7ED',
lineDash: [3, 3]
}
}
},
label: {
formatter: text => {
let num = Math.floor(text);
return num + '人';
}
}
});
this.chart.tooltip({
showMarkers: false,
shared: true,
showCrosshairs: true
});
this.chart
.line()
.position('date*num')
.color('type', ['rgba(75,116,232,1)', 'rgba(20, 201, 201, 1)', 'rgba(214, 179, 140, 1)']);
this.chart
.line()
.position('date*times')
.color('type', ['rgba(214, 179, 140, 1)']);
// this.chart.removeInteraction('legend-filter'); // 自定义图例,移除默认的分类图例筛选交互
//图表绘制的最后一步,用于将图表渲染至画布
this.chart.render();
},
handleData(data) {
let arr = [];
let maxNum = 0;
let maxTimes = 0;
data.forEach(item => {
item.clickNum > maxNum ? (maxNum = item.clickNum) : '';
item.clickTimes > maxTimes ? (maxTimes = item.clickTimes) : '';
arr.push({
date: item.bizDate,
type: '新增人数',
num: item.addNum
});
arr.push({
date: item.bizDate,
type: '点击人数',
num: item.clickNum
});
arr.push({
date: item.bizDate,
type: '点击人次',
times: item.clickTimes
});
});
this.maxNum = maxNum;
this.maxTimes = maxTimes;
console.log(maxNum, maxTimes);
return arr;
}
}
};
</script>
<style lang="scss" scoped>
.chart--nodata {
height: 359px;
width: 100%;
display: flex;
justify-content: center;
.image-120 {
width: 120px;
height: 120px;
padding-top: 60px;
}
.no-data-text {
text-align: center;
padding-top: 18px;
}
}
</style>
export default {
data() {
return {
dateKey: 0,
dateLis: [
{ key: 0, value: '近7天' },
{ key: 1, value: '近30天' },
{ key: 2, value: '近三个月' },
{ key: 3, value: '近半年' },
{ key: 4, value: '近一年' }
],
dateDefault: [],
pickerOptions() {
let pickerMinDate;
return {
onPick(obj) {
pickerMinDate = obj.minDate;
},
disabledDate(time) {
let start = new Date();
start = new Date(`${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()}`);
let start2 = new Date(pickerMinDate);
let end = new Date();
end = new Date(`${end.getFullYear()}-${end.getMonth() + 1}-${end.getDate()} 23:59:59`);
let end2 = new Date(pickerMinDate);
if (pickerMinDate) {
start = start.setFullYear(start.getFullYear() - 2);
start2 = start2.setDate(start2.getDate() - 59);
start = start > start2 ? start : start2;
end2 = end2.setDate(end2.getDate() + 59) + 24 * 60 * 60 * 1000 - 1000; // end2算到晚上23:59:59
end = end.getTime() > end2 ? end2 : end.getTime();
} else {
start = start.setFullYear(start.getFullYear() - 2);
end = end.getTime();
}
return time.getTime() < start || time.getTime() > end;
}
};
}
};
},
methods: {
getDateRange(setEndDate) {
const start = new Date();
let end = new Date();
end = setEndDate(end);
function getDate(date) {
const result = [];
result.push(date.getFullYear());
result.push((date.getMonth() + 1).toString().padStart(2, '0'));
result.push(
date
.getDate()
.toString()
.padStart(2, '0')
);
return result.join('-');
}
// yyyy-MM-dd
return [getDate(start), getDate(end)];
},
btnChange(index) {
let that = this;
that.dateKey = index;
that.dateDefault = [];
let setDate;
if (index == 0) {
// 近7天
setDate = endDate => {
endDate.setDate(endDate.getDate() - 6);
return new Date(endDate);
};
} else if (index == 1) {
// 近30天
setDate = endDate => {
endDate.setDate(endDate.getDate() - 29);
return new Date(endDate);
};
} else if (index == 2) {
// 近三个月
setDate = endDate => {
endDate.setMonth(endDate.getMonth() - 2);
endDate.setDate(1);
return new Date(endDate);
};
} else if (index == 3) {
// 近半年
setDate = endDate => {
endDate.setMonth(endDate.getMonth() - 5);
endDate.setDate(1); // 以1号为开端
return new Date(endDate);
};
} else {
// 近一年
setDate = endDate => {
console.log(endDate);
endDate.setFullYear(endDate.getFullYear() - 1);
endDate.setMonth(endDate.getMonth() + 1);
endDate.setDate(1);
return new Date(endDate);
};
}
const [start, end] = that.getDateRange(setDate);
that.dateDefault.push(end);
that.dateDefault.push(start);
that.getChartList();
}
}
};
<template>
<div>
<el-button class="select-clerk-trigger" v-if="!Array.isArray(data) || data.length == 0" :disabled="disabled" @click="showSelectClerk = true">
<i class="iconfont-hb3 iconPlusOutlined trigger-icon"></i>
添加成员
</el-button>
<template v-if="Array.isArray(data) && data.length > 0">
<div v-if="multiple" class="multiple-preview">
<dm-sub-title style="margin-left: 4px; width: calc(100% - 4px)" title-align="space-between">
<div>{{ `已选成员(${data.length})` }}</div>
<div v-if="!disabled" class="edit-btns">
<el-button class="del-btn" type="text" @click="onDelAll">清除</el-button>
<el-button class="update-clerk-trigger" type="text" @click="showSelectClerk = true">编辑</el-button>
</div>
</dm-sub-title>
<div class="clerk-list">
<selected-clerk-item v-for="el in data" :key="el.clerkId" :clerk-data="el" :show-del="!disabled" @del="onDel" class="clerk-item"></selected-clerk-item>
</div>
</div>
<div v-else class="single-preview">
<selected-clerk-item :clerk-data="data[0]" :show-del="false"></selected-clerk-item>
<el-button v-if="!disabled" type="text" class="update-clerk-trigger" @click="showSelectClerk = true">修改成员</el-button>
</div>
</template>
<select-clerk :visible.sync="showSelectClerk" :is-simple="isSimple" :multiple="multiple" :max="max" :data="data" @save="onChange"></select-clerk>
</div>
</template>
<script>
import SelectClerk from './select-clerk.vue';
import SelectedClerkItem from './selected-clerk-item.vue';
export default {
name: 'Index',
components: { SelectClerk, SelectedClerkItem },
props: {
// 是否单人活码
isSimple: {
type: Boolean,
default: false
},
// 是否多选
multiple: {
type: Boolean,
default: false
},
// 多选时最多可以选几条数据,默认100条
max: {
type: Number,
default: 100
},
// 选中的数据
data: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
showSelectClerk: false
};
},
methods: {
onChange(data) {
this.$emit('change', data);
},
onDel(clerkId) {
const data = JSON.parse(JSON.stringify(this.data));
this.onChange(data.filter(el => el.clerkId != clerkId));
},
onDelAll() {
this.onChange([]);
}
}
};
</script>
<style lang="scss" scoped>
.select-clerk-trigger {
color: #2f54eb;
border-color: #2f54eb;
.trigger-icon {
font-size: 12px;
}
}
.multiple-preview {
padding: 10px 12px 12px;
width: 720px;
max-height: 500px;
overflow-y: auto;
border-radius: 2px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
.edit-btns {
display: flex;
justify-content: flex-start;
align-items: center;
.del-btn {
color: #f5222d;
}
.update-clerk-trigger {
margin-left: 20px;
}
}
.clerk-list {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
margin-top: 6px;
.clerk-item {
margin: 4px;
}
}
}
.single-preview {
display: flex;
justify-content: flex-start;
align-items: center;
.update-clerk-trigger {
margin-left: 16px;
}
}
</style>
<template>
<div class="clerk-info-box">
<div class="clerk-info">
{{ clerkData.clerkName }}
<div class="clerk-code">code:{{ clerkData.clerkCode }}</div>
</div>
<i v-if="showDel" @click="$emit('del', clerkData.clerkId)" class="iconfont-hb3 iconclose1 del-clerk"></i>
</div>
</template>
<script>
export default {
name: 'SelectedClerkItem',
props: {
clerkData: {
type: Object,
default: () => ({})
},
showDel: {
type: Boolean,
default: true
}
}
};
</script>
<style lang="scss" scoped>
.clerk-info-box {
display: flex;
justify-content: center;
align-items: center;
padding: 4px 8px;
height: 51px;
background: #ebeffe;
border-radius: 4px;
box-sizing: border-box;
.clerk-info {
font-size: 14px;
font-weight: 500;
color: #303133;
line-height: 20px;
.clerk-code {
margin-top: 2px;
font-weight: 400;
}
}
.del-clerk {
margin-left: 10px;
flex-shrink: 0;
font-size: 12px;
color: #909399;
cursor: pointer;
&:hover {
color: #2f54eb;
}
}
}
</style>
<template>
<div class="right-wrap">
<div class="right-box" v-loading="loading">
<div>
<el-select placeholder="选择业务模块" v-model="search.businessType" style="width: 160px" clearable @change="onSearch">
<el-option v-for="el in moduleList" :key="el.key" :label="el.value" :value="el.key"></el-option>
</el-select>
<el-select placeholder="选择操作事项" v-model="search.optType" style="width: 160px;margin-left: 10px" clearable @change="onSearch">
<el-option v-for="el in businessList" :key="el.key" :label="el.value" :value="el.key"></el-option>
</el-select>
<el-select placeholder="操作人姓名/手机号" v-model="search.optUser" @clear="userList = []" style="width: 170px;margin-left: 10px" popper-class="operate-clerk-list" clearable filterable :filter-method="searchClerk" v-select-loadmore="loadMoreClerk" @change="onSearch">
<el-option v-for="el in userList" :key="el.clerkId" :value="el.clerkId" :label="el.clerkName">
<p>{{ el.clerkName }}</p>
<p>{{ el.phoneNumber }}</p>
</el-option>
</el-select>
<el-input placeholder="操作内容" v-model="search.search" style="width: 260px;margin-left: 10px" clearable prefix-icon="el-icon-search" @change="onSearch"></el-input>
<el-date-picker v-model="search.dateRange" @change="onSearch" :picker-options="pickerOptions" clearable style="width: 256px;margin-left: 10px" type="daterange" value-format="yyyy-MM-dd" range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期"> </el-date-picker>
</div>
<el-table :data="tableData" style="margin: 20px 0">
<el-table-column label="业务模块" prop="businessTypeName" :formatter="(row, col, val) => val || '--'"></el-table-column>
<el-table-column label="操作事项" prop="optTypeName" :formatter="(row, col, val) => val || '--'"></el-table-column>
<el-table-column label="操作页面" prop="optPage" :formatter="(row, col, val) => val || '--'"></el-table-column>
<el-table-column label="操作账号" show-overflow-tooltip>
<template slot-scope="{ row }">
<template v-if="row.userName || row.phoneNumber">
<p class="text-overflow">
{{ row.userName ? row.userName : '' }}
<span v-if="row.ywName" style="color: #909399">{{ row.ywName }}</span>
</p>
<p>{{ row.phoneNumber ? row.phoneNumber : '' }}</p>
</template>
<template v-else>--</template>
</template>
</el-table-column>
<el-table-column label="操作内容" prop="content" :formatter="(row, col, val) => val || '--'" show-overflow-tooltip></el-table-column>
<el-table-column label="操作时间" prop="createTime">
<template slot-scope="{ row }" v-if="row.createTime">
{{ filters.timeStampToYmd(Number(row.createTime)) }}<br />
{{ filters.timeStampToHms(Number(row.createTime)) }}
</template>
<template v-else>--</template>
</el-table-column>
</el-table>
<el-pagination v-if="pager.total > 0" background style="text-align: right" layout="total, sizes, prev, pager, next" @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="pager.total" :current-page="pager.currentPage" :page-size="pager.pageSize" :page-sizes="[20, 40, 60, 80]"></el-pagination>
</div>
</div>
</template>
<script>
import { logList, businessType, optTypes, listUserBySearchName } from '@/api/actCode';
import filters from '@/filters/index';
export default {
name: 'operateLog',
data() {
return {
filters,
requestProject: 'gic-web',
loading: false,
search: {
businessType: '',
optType: '',
optUser: '',
search: '',
dateRange: []
},
clerkListPager: {
searchName: '',
pageNum: 1,
pageSize: 20,
totalPage: 1
},
moduleList: [],
businessList: [],
userList: [],
tableData: [],
pager: {
currentPage: 1,
pageSize: 20,
total: 0
},
enterpriseId: JSON.parse(sessionStorage.getItem('userInfos')).enterpriseId,
pickerOptions: {
disabledDate(date) {
const now = new Date();
let start = new Date();
start = new Date(start.setMonth(now.getMonth() - 3));
return date.getTime() < start.getTime() || date.getTime() > now.getTime();
}
}
};
},
mounted() {
this.initData();
this.getTableData();
},
methods: {
initData() {
const params = {};
params.requestProject = this.requestProject;
businessType(params).then(res => {
const { code, result } = res.data || {};
if (code == 0) {
this.moduleList = (result || []).filter(el => el.key != 1001);
}
});
optTypes({ params }).then(res => {
const { code, result } = res.data || {};
if (code == 0) {
this.businessList = (result || []).filter(el => el.key != 1001);
}
});
this.getClerkList();
},
loadMoreClerk() {
if (this.clerkListPager.pageNum >= this.clerkListPager.totalPage) return;
this.clerkListPager.pageNum += 1;
this.getClerkList();
},
searchClerk(searchName) {
this.clerkListPager.searchName = searchName;
this.clerkListPager.pageNum = 1;
this.clerkListPager.totalPage = 1;
document.querySelector('.operate-clerk-list .el-scrollbar__wrap').scrollTop = 0;
this.getClerkList();
},
getClerkList() {
const { pageNum, pageSize, searchName } = this.clerkListPager;
const params = { searchName, pageNum, pageSize };
params.requestProject = this.requestProject;
listUserBySearchName(params).then(res => {
const { code, result } = res.data || {};
if (pageNum == 1) {
this.userList = [];
}
if (code == 0) {
this.userList = this.userList.concat(result.result || []);
this.clerkListPager.totalPage = result.totalPage;
}
});
},
getTableData() {
this.loading = true;
const { pageSize, currentPage } = this.pager;
const { businessType, optType, optUser, search, dateRange } = this.search;
let para = {
businessType,
optType,
optUser,
search,
startDate: Array.isArray(dateRange) ? dateRange[0] : '',
endDate: Array.isArray(dateRange) ? dateRange[1] : '',
pageSize,
pageNum: currentPage,
enterpriseId: this.enterpriseId
};
para.requestProject = this.requestProject;
logList(para).then(res => {
let data = res.data;
if (data.code == 0) {
this.tableData = data.result.result;
this.pager.total = data.result.totalCount;
}
this.loading = false;
});
},
onSearch() {
this.handleCurrentChange(1);
},
handleCurrentChange(val) {
this.pager.currentPage = val;
this.getTableData();
},
handleSizeChange(val) {
this.pager.pageSize = val;
this.handleCurrentChange(1);
}
}
};
</script>
<style scoped lang="less">
.right-wrap {
padding: 20px;
}
.text-overflow {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/deep/ .el-table::before {
display: none;
}
.operate-clerk-list .el-select-dropdown__item {
padding: 8px 12px;
height: 52px;
line-height: normal;
p:first-child {
line-height: 20px;
}
p:last-child {
line-height: 17px;
}
&:hover p {
color: #2f54eb;
}
}
</style>
<template>
<div class="app-detail-wrap p-20" v-loading="loading">
<div class="flex p-b-40">
<el-image v-if="codeInfo.hmType == 2" class="img-200" :src="codeInfo.wxQrcode" />
<div class="text-ellipsis-white color-303133" :style="codeInfo.hmType == 1 ? 'width:100%;' : 'width: calc(100% - 230px);'">
<div class="p-t-12 flex height-22">
<div class="font-16 line-22 text-ellipsis-white font-w-500">{{ codeInfo.name }}</div>
<el-tag size="small" effect="dark" :type="codeStatusLis[statusIndex].style" style="margin-left: 8px;">{{ codeStatusLis[statusIndex].value }}</el-tag>
<!-- 正常success/正常到上限warning/待生效info/已作废danger -->
</div>
<p class="font-14 m-t-10 ">ID:{{ codeInfo.hmCode }}</p>
<div class="flex font-14" style="padding-top:20px;">
<div class="flex flex-1">
<div class="font-14 line-22">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;型:
</div>
<el-tag size="small">{{ codeInfo.hmType == 1 ? '单人活码' : '多人活码' }}</el-tag>
</div>
<div class="font-14 line-22 flex-1">创建人:{{ codeInfo.creatorName || '--' }}</div>
<div class="font-14 line-22 flex-1">创建时间:{{ codeInfo.createTime | formatTimeStamp }}</div>
</div>
<div class="flex font-14" style="padding-top:15px;">
<div class="font-14 line-22 flex-1">所属分组:{{ codeInfo.hmGroupName || '--' }}</div>
<div class="flex flex-1">
<div class="font-14 line-22">自动通过好友:</div>
<el-tag size="small" :type="codeInfo.passFlag == 1 ? '' : 'danger'">{{ codeInfo.passFlag == 1 ? '已开启' : '已关闭' }}</el-tag>
</div>
<div class="flex flex-1">
<div class="font-14 line-22">活码标签:</div>
<el-tooltip :disabled="codeInfo.memberLabelStatus != 0" content="已删除" placement="top">
<el-tag size="small" :type="codeInfo.memberLabelStatus == 0 ? 'warning' : 'info'">{{ codeInfo.memberLabelName || '--' }}</el-tag>
</el-tooltip>
<!-- <el-tag size="small" type="info">{{ codeInfo.memberLabelName || '--' }}</el-tag> -->
</div>
</div>
<div v-if="codeInfo.statusFlag != 2 && codeInfo.statusFlag" class="flex" style="padding-top:20px;">
<el-button v-if="codeInfo.hmType == 2 && codeInfo.statusFlag == 1" type="primary" style="width:120px;margin-right: 12px;" @click="downloadQR"><i class="iconfont-hb3 iconxiazai m-r-6"></i>下载二维码</el-button>
<el-button type="primary" plain style="width:98px;" @click="modifyCode">编辑</el-button>
<el-button class="button-discard specter" type="danger" plain :style="codeInfo.hmType == 2 && useMemberList.length > 0 ? '' : 'border-color: #F5222D;'" @click="discardCode">作废</el-button>
</div>
</div>
</div>
<div class="fixed-tab" v-if="scrollTop >= fixedHeight">
<el-tabs v-model="activeName" type="card">
<el-tab-pane label="详情信息" name="first"> <div></div> </el-tab-pane>
<el-tab-pane label="数据统计" name="second">
<div></div>
</el-tab-pane>
</el-tabs>
</div>
<el-tabs v-model="activeName" type="card" ref="page">
<el-tab-pane label="详情信息" name="first" v-if="$getButtonLimit($buttonCode.infoActCode)" :limit-code="$buttonCode.infoActCode">
<act-code-detail-info :enterprise-id="codeInfo.enterpriseId" :welcome-id="codeInfo.welcomeId" :hm-id="$route.query.hmId" @useMemberList="useMemberData"></act-code-detail-info>
</el-tab-pane>
<el-tab-pane label="数据统计" name="second" v-if="$getButtonLimit($buttonCode.dataActCode)" :limit-code="$buttonCode.dataActCode">
<act-code-detail-statistics :chart-width="chartWidth" :hm-id="$route.query.hmId"></act-code-detail-statistics>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import actCodeDetailInfo from '../../components/actCodeDetailInfo.vue';
import actCodeDetailStatistics from './actCodeDetailStatistics.vue';
import { _throttle } from '@/common/js/public';
import { getRequest, deleteRequest } from '@/api/api';
import errMsg from '@/common/js/error';
export default {
name: 'actCodeDetail',
components: { actCodeDetailInfo, actCodeDetailStatistics },
props: {
hmId: {
type: String,
default: ''
}
},
data() {
return {
chartWidth: 0,
fixedHeight: 217,
codeInfo: {},
loading: false,
activeName: 'first',
codeStatusLis: [
{ value: '', style: '' },
{ value: '正常', style: 'success' },
{ value: '已作废', style: 'danger' },
{ value: '待生效', style: 'info' },
{ value: '正常-今日已达上限', style: 'warning' }
],
statusIndex: 1,
scrollTop: 0,
useMemberList: []
};
},
methods: {
downloadQR() {
const downloadFile = (fileName, content) => {
const url = content;
const x = new XMLHttpRequest();
x.open('GET', url, true);
x.responseType = 'blob';
x.onload = function(e) {
const blob = new Blob([x.response]);
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = fileName + '.png';
a.click();
};
x.send();
};
downloadFile(this.codeInfo.hmCode + '_' + this.codeInfo.name, this.codeInfo.wxQrcode);
},
modifyCode() {
this.$router.push(`/actCodeEdit?hmId=${this.$route.query.hmId}`);
},
discardCode() {
const that = this;
this.$confirm('此操作将永久废弃该活码,请确保不影响其他投放使用!', '确认要作废该活码?', {
confirmButtonText: '作废',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
that.loading = true;
deleteRequest('/haoban-manage3-web/hm/qrcode/del', { hmId: that.$route.query.hmId }).then(res => {
that.loading = false;
if (res.data.code == 0) {
this.getActCodeInfo();
return;
}
errMsg.errorMsg(res.data);
});
});
},
async getActCodeInfo() {
const that = this;
if (that.$route.query.hmId.length <= 0) return;
that.loading = true;
getRequest('/haoban-manage3-web/hm/qrcode/detail', { hmId: that.$route.query.hmId })
.then(res => {
let resData = res.data;
that.loading = false;
if (resData.code == 0) {
that.statusIndex = resData.result.statusFlag == 1 && resData.result.overFlag == 1 ? 4 : resData.result.statusFlag;
that.codeInfo = resData.result;
that.fixedHeight = that.codeInfo.statusFlag != 2 ? 260 : 217;
return;
}
errMsg.errorMsg(resData);
})
.catch(function(error) {
that.$message.error({
duration: 1000,
message: error.message
});
});
},
scrollMethod: _throttle(function() {
// 节流会不自然 左右不滑动
this.scrollTop = document.getElementById('hb-layout-pager-one').scrollTop;
}, 100),
useMemberData(data) {
this.useMemberList = data;
}
},
mounted() {
let that = this;
this.activeName = this.$route.query.activeName || 'first';
this.chartWidth = this.$refs.page.$el.clientWidth;
that.getActCodeInfo();
document.getElementById('hb-layout-pager-one').addEventListener('scroll', that.scrollMethod);
},
destroyed() {
document.getElementById('hb-layout-pager-one').removeEventListener('scroll', this.scrollMethod);
}
};
</script>
<style lang="scss" scoped>
.app-detail-wrap {
// height: 100%;
background: #fff;
.p-b-40 {
padding-bottom: 40px;
}
}
.img-200 {
width: 200px;
height: 200px;
border-radius: 8px;
padding-right: 30px;
}
.height-22 {
height: 22px;
}
.text-ellipsis-white {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.button-discard {
width: 98px;
margin-left: 20px;
}
</style>
<template>
<div class="app-detail-wrap">
<div>
<div class="flex justify-between title">
<div class="flex">
<div class="blue-block"></div>
<span class="font-w-500 color-303133">概览</span>
</div>
<div class="flex">
<el-button type="text" v-jumpLink:codeGl><i class="iconfont-hb3 iconzhibiaoshuoming m-r-6"></i>指标说明</el-button>
</div>
</div>
<ul class="flex">
<li class="data-total-cell m-r-22">
<div class="flex p-20">
<div class="icon-background">
<i class="iconfont-hb3 iconxinzengyonghu color-1890ff font-28"></i>
</div>
<div class="m-l-16">
<div class="font-14 color-606266 line-20">添加好友人数</div>
<span class="font-30 font-din" style="margin-top:1;">{{ overViewData.addNumT || 0 }}</span>
</div>
</div>
</li>
<li class="data-total-cell">
<div class="flex p-20">
<div class="icon-background" style="background: #d9f3fd;">
<i class="iconfont-hb3 iconxinzengyonghu color-35C4FC font-28"></i>
</div>
<div class="m-l-16">
<div class="font-14 color-606266 line-20">今日新增人数</div>
<span class="font-30 font-din" style="margin-top:1;">{{ overViewData.addNum || 0 }}</span>
</div>
</div>
</li>
</ul>
<div class="flex justify-end">
<div class="rightBox">
<ul class="datebox" v-for="(lis, index) in dateLis" :key="lis.key">
<li :class="dateKey == index ? 'activeClass' : 'noActive'" class="dateLisBox" @click="btnChange(index)">{{ lis.value }}</li>
</ul>
<el-date-picker class="w256" v-model="dateDefault" type="daterange" range-separator="~" start-placeholder="创建开始日期" end-placeholder="创建结束日期" :default-time="['00:00:00', '23:59:59']" :picker-options="pickerOptions()" @change="onDateChange" value-format="yyyy-MM-dd" :format="[2, 3, 4].includes(dateKey) ? 'yyyy-MM' : 'yyyy-MM-dd'" :clearable="false"> </el-date-picker>
</div>
</div>
<new-add-chart :chart-width="chartWidth" :charData="overViewData.dateList" id="new-add-chart"></new-add-chart>
</div>
<div>
<div class="flex justify-between title">
<div class="flex">
<div class="blue-block"></div>
<span class="font-w-500 color-303133">查看明细</span>
</div>
<div class="flex">
<el-button type="text" v-jumpLink:codeCkmx><i class="iconfont-hb3 iconzhibiaoshuoming m-r-6"></i>指标说明</el-button>
</div>
</div>
<data-detail :id="hmId"></data-detail>
</div>
</div>
</template>
<script>
import dataDetail from '../../components/dataDetail.vue';
import newAddChart from './newAddChart.vue';
import { postJsonRequest } from '@/api/api';
import mixin from '../components/mixin';
import errMsg from '@/common/js/error';
export default {
name: 'act-code-detail-statistics',
components: { dataDetail, newAddChart },
props: {
hmId: {
type: String,
default() {
return '';
}
},
chartWidth: Number
},
mixins: [mixin],
data() {
return {
loading: false,
dateList: [
// { bizDate: '2018/8/1', addNum: 4623 },
// { bizDate: '2018/8/2', addNum: 6145 },
// { bizDate: '2018/8/3', addNum: 508 },
// { bizDate: '2018/8/4', addNum: 289 },
// { bizDate: '2018/8/5', addNum: 289 },
// { bizDate: '2018/8/6', addNum: 289 },
// { bizDate: '2018/8/7', addNum: 289 },
// { bizDate: '2018/8/8', addNum: 289 },
// { bizDate: '2018/8/9', addNum: 289 },
// { bizDate: '2018/8/10', addNum: 289 },
// { bizDate: '2018/8/11', addNum: 289 },
// { bizDate: '2018/8/12', addNum: 289 },
// { bizDate: '2018/8/13', addNum: 2589 },
// { bizDate: '2018/8/14', addNum: 289 },
// { bizDate: '2018/8/15', addNum: 289 },
// { bizDate: '2018/8/16', addNum: 29 },
// { bizDate: '2018/8/17', addNum: 289 },
// { bizDate: '2018/8/18', addNum: 9 },
// { bizDate: '2018/8/19', addNum: 2189 },
// { bizDate: '2018/8/20', addNum: 289 },
// { bizDate: '2018/8/21', addNum: 2869 },
// { bizDate: '2018/8/22', addNum: 289 },
// { bizDate: '2018/8/23', addNum: 2809 }
],
overViewData: { addNumT: 0, addNum: 0, dateList: [] }
};
},
methods: {
explain(url) {
window.open(url);
},
getChartList() {
const that = this;
let para = {
inFields: {
hmId: that.hmId,
startTime: that.dateDefault[0] + ' 00:00:00',
endTime: that.dateDefault[1] + ' 23:59:59',
type: that.dateKey >= 2 ? 2 : 1
}
};
that.loading = true;
postJsonRequest('/haoban-manage3-web/hm/qrcode/detail-data-statistics', para)
.then(res => {
let resData = res.data;
that.loading = false;
if (resData.code == 0) {
let result = resData.result || { addNumT: 0, addNum: 0, dateList: [] };
// result.dateList = [
// { bizDate: '2018/8/1', 新增人数: 0 },
// { bizDate: '2018/8/2', 新增人数: 1 },
// { bizDate: '2018/8/3', 新增人数: 1 },
// { bizDate: '2018/8/4', 新增人数: 1 }
// ];
result.dateList.map(function(date, index) {
date['新增人数'] = date.addNum;
});
that.overViewData = result;
return;
}
errMsg.errorMsg(resData);
})
.catch(function(error) {
that.loading = false;
that.$message.error({
duration: 1000,
message: error.message
});
});
},
onDateChange() {
this.dateKey = -1;
this.getChartList();
}
},
mounted() {
let that = this;
// 默认显示近七天
that.btnChange(0);
}
};
</script>
<style lang="scss" scoped>
.blue-block {
width: 4px;
height: 16px;
background: #2f54eb;
margin: 7px 12px 7px 0;
}
.title {
line-height: 30px;
padding-bottom: 16px;
}
.justify-between {
justify-content: space-between;
}
.justify-end {
justify-content: flex-end;
}
.data-total-cell {
position: relative;
min-width: 282px;
height: 96px;
background: #ffffff;
box-shadow: 0px 2px 8px 1px rgba(221, 227, 237, 0.34);
border-radius: 10px;
.icon-background {
width: 48px;
height: 48px;
margin: 4px 0;
background: #e7ebfe;
border-radius: 12px;
text-align: center;
line-height: 48px;
}
}
.color-35C4FC {
color: #35c4fc;
}
.font-28 {
font-size: 28px;
}
.line-20 {
line-height: 20px;
}
.m-r-22 {
margin-right: 22px;
}
.w256 {
width: 256px;
}
.rightBox {
// float: right;
line-height: 32px;
padding-top: 20px;
// height: 32px;
.datebox {
display: inline-block;
.dateLisBox {
font-size: 14px;
margin-right: 24px;
cursor: pointer;
}
}
}
.activeClass {
color: #2f54eb;
}
.noActive {
color: #303133;
}
</style>
<template>
<section class="common-right-wrap">
<div class="p-20">
<!-- <div class="flex m-b-20">
<el-input placeholder="请输入门店名称/code" v-model="searchInputStore" class="m-r-10" style="width: 260px;" @keyup.native="value => toInput(value, searchInputStore)" clearable @clear="clearInput()" prefix-icon="el-icon-search"></el-input>
<el-input placeholder="请输入导购名称/code" v-model="searchInputGuide" style="width: 260px;" @keyup.native="value => toInput(value, searchInputGuide)" clearable @clear="clearInput()" prefix-icon="el-icon-search"></el-input>
</div> -->
<el-table ref="recordTableRef" v-loading="loading" :data="tableData" tooltip-effect="dark" class="act-code-table" @sort-change="sortChange">
<el-table-column prop="" label="基本信息" show-overflow-tooltip min-width="210px" fixed>
<template slot-scope="scope">
<div class="flex">
<img v-if="scope.row.memberImage" class="image-40" :src="scope.row.memberImage" />
<img v-if="!scope.row.memberImage" class="image-40" src="@/assets/user-default.svg" />
<div v-if="!scope.row.memberName && !scope.row.memberNick && !scope.row.memberPhone" class="p-l-10" style="width: calc(100% - 50px);line-height: 40px;">--</div>
<div v-if="(scope.row.memberName || scope.row.memberNick) && scope.row.memberPhone" class="p-l-10 line-20" style="width: calc(100% - 50px);">
<div class="flex text-ellipsis">
<span class="text-ellipsis">{{ scope.row.memberName }}</span>
<span :class="scope.row.memberName ? 'color-909399 text-ellipsis' : 'text-ellipsis'" v-if="scope.row.memberNick"> {{ !scope.row.memberName ? scope.row.memberNick : '(' + scope.row.memberNick + ')' }}</span>
</div>
<p class="font-12">{{ scope.row.memberPhone }}</p>
</div>
<div v-else>
<div v-if="scope.row.memberName && scope.row.memberNick && !scope.row.memberPhone" class="p-l-10" style="line-height: 40px;">
<div class="flex text-ellipsis">
<span class="text-ellipsis">{{ scope.row.memberName }}</span>
<span class="color-909399 text-ellipsis">{{ scope.row.memberNick }})</span>
</div>
</div>
<div v-else class="p-l-10" style="width: calc(100% - 50px);line-height: 40px;">{{ scope.row.memberName || scope.row.memberNick || scope.row.memberPhone }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="" label="会员卡号" show-overflow-tooltip min-width="126px">
<template slot-scope="scope">
{{ scope.row.memberCardNo || '--' }}
</template>
</el-table-column>
<el-table-column prop="" label="会员等级" show-overflow-tooltip min-width="86px">
<template slot-scope="scope">
{{ scope.row.memberGradeName || '--' }}
</template>
</el-table-column>
<el-table-column prop="" label="导购信息" show-overflow-tooltip min-width="128px">
<template slot-scope="scope">
<p class="line-20 text-ellipsis">{{ scope.row.clerkName || '--' }}</p>
<p class="color-606266 line-18 text-ellipsis font-12">code:{{ scope.row.clerkCode || '--' }}</p>
</template>
</el-table-column>
<el-table-column prop="" label="导购所属门店" show-overflow-tooltip min-width="185px">
<template slot-scope="scope">
<p class="line-20 text-ellipsis">{{ scope.row.storeName || '--' }}</p>
<p class="color-606266 line-18 text-ellipsis font-12">code:{{ scope.row.storeCode || '--' }}</p>
</template>
</el-table-column>
<el-table-column prop="" label="企微号" show-overflow-tooltip min-width="107px">
<template slot-scope="scope">
{{ scope.row.staffName || '--' }}
</template>
</el-table-column>
<el-table-column prop="" label="添加时间" show-overflow-tooltip min-width="106px" sortable>
<template slot-scope="scope">
<div class="line-20">{{ scope.row.createTime | timeStampToYmd }}</div>
<div class="line-20">{{ scope.row.createTime | timeStampToHms }}</div>
</template>
</el-table-column>
<el-table-column prop="" label="标签" show-overflow-tooltip min-width="144px">
<template slot-scope="scope">
{{ scope.row.memberLabelName || '--' }}
</template>
</el-table-column>
<el-table-column prop="" label="关联类型" show-overflow-tooltip min-width="103px">
<template slot-scope="scope">
{{ scope.row.addChannel == 1 ? '引流链接' : '员工活码' }}
</template>
</el-table-column>
<el-table-column prop="" label="关联信息" show-overflow-tooltip min-width="150px">
<template slot-scope="scope">
{{ scope.row.addChannel == 1 ? scope.row.linkName || '--' : scope.row.hmName || '--' }}
</template>
</el-table-column>
</el-table>
</div>
<div class="block common-wrap__page text-right m-t-24" v-if="tableData.length != 0">
<dm-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[20, 40, 60, 80]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </dm-pagination>
</div>
</section>
</template>
<script>
import errMsg from '@/common/js/error';
// import { _debounce } from '@/common/js/public';
import { postJsonRequest } from '@/api/api';
export default {
name: 'actCodeRecord',
components: {},
data() {
return {
loading: false,
tableData: [],
// searchInputStore: '',
// searchInputGuide: '',
// 分页参数
currentPage: 1,
pageSize: 20,
total: 0,
sortType: 'desc'
};
},
methods: {
// /**
// * 输入
// */
// toInput: _debounce(function(e, value, type) {
// const that = this;
// that.currentPage = 1;
// that.getTableList();
// }, 500),
// clearInput() {
// const that = this;
// that.currentPage = 1;
// that.getTableList();
// },
/**
* 排序
*/
sortChange(column, prop, order) {
const that = this;
that.currentPage = 1;
that.sortType = column.order == 'ascending' ? 'asc' : 'desc'; // 默认倒序
that.getTableList();
},
/**
* 分页---页码变化
* @param {Number} val
*/
handleSizeChange(val) {
let that = this;
that.currentPage = 1;
that.pageSize = val;
that.getTableList();
},
/**
* 分页---当前页变化
* @param {Number} val
*/
handleCurrentChange(val) {
let that = this;
that.currentPage = val;
that.getTableList();
},
/**
* 获取列表数据
*/
async getTableList() {
const that = this;
that.loading = true;
const { startTime, endTime, clerkId, linkId, hmId } = this.$route.query;
let para = {
pageNum: that.currentPage, // 当前页
pageSize: that.pageSize, // 一页显示个数
linkId,
hmId,
clerkId,
startTime,
endTime,
// addChannel: 1,
addChannel: linkId ? 1 : hmId ? this.$route.query.addChannel : 0, // 不具备传0
createTimeOrder: that.sortType || ''
};
postJsonRequest('/haoban-manage3-web/hm/qrcode/wxUserAddLog/list', para)
.then(res => {
let resData = res.data;
that.loading = false;
if (resData.code == 0) {
that.tableData = resData.result.result || [];
// that.tableData[0].memberPhone = '';
// that.tableData[0].memberNick = '';
// that.tableData[0].memberName = '';
that.total = resData.result.totalCount || 0;
return;
}
errMsg.errorMsg(resData);
})
.catch(function(error) {
that.loading = false;
that.$message.error({
duration: 1000,
message: error.message
});
});
}
},
mounted() {
let that = this;
that.getTableList();
console.log(this.$route.query);
}
};
</script>
<style type="text/scss" lang="scss" scoped>
.p-20 {
padding: 20px;
box-sizing: border-box;
}
.image-40 {
height: 40px;
width: 40px;
border-radius: 20px;
}
.line-20 {
line-height: 20px;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment