提交 91db5f86 编写于 作者: 星梦苍天

Merge remote-tracking branch 'origin/back_end_dev' into back_end_dev

...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<div align="center"> <div align="center">
![GVP Stars](http://img.shields.io/badge/GPV%20Stars-600+-yellow) ![GVP Stars](http://img.shields.io/badge/GPV%20Stars-700+-yellow)
![GVP Forks](http://img.shields.io/badge/GPV%20Forks-200+-yellow) ![GVP Forks](http://img.shields.io/badge/GPV%20Forks-200+-yellow)
![license](http://img.shields.io/badge/license-GPL%203.0-green) ![license](http://img.shields.io/badge/license-GPL%203.0-green)
......
...@@ -43,9 +43,9 @@ public class WeChatItemController extends BaseController { ...@@ -43,9 +43,9 @@ public class WeChatItemController extends BaseController {
//@PreAuthorize("@ss.hasPermi('chat:item:list')") //@PreAuthorize("@ss.hasPermi('chat:item:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(@RequestParam(value = "sideId") Long sideId public TableDataInfo list(@RequestParam(value = "sideId") Long sideId
, @RequestParam(value = "keyword", required = false) String keyword) { , @RequestParam(value = "keyword", required = false) String keyword,@RequestParam(value = "mediaType") String mediaType) {
startPage(); startPage();
List<WeChatSideVo> weChatSideVos = weChatItemService.chatItems(sideId,keyword); List<WeChatSideVo> weChatSideVos = weChatItemService.chatItems(sideId,keyword,mediaType);
return getDataTable(weChatSideVos); return getDataTable(weChatSideVos);
} }
......
...@@ -190,8 +190,6 @@ wecome: ...@@ -190,8 +190,6 @@ wecome:
- /externalcontact/unionid_to_external_userid - /externalcontact/unionid_to_external_userid
- /externalcontact/add_msg_template - /externalcontact/add_msg_template
- /externalcontact/get_group_msg_result - /externalcontact/get_group_msg_result
- /get_jsapi_ticket
- /ticket/get
fileUplodUrl: /media/upload,/media/uploadimg fileUplodUrl: /media/upload,/media/uploadimg
needProviderTokenUrl: needProviderTokenUrl:
- /service/get_login_info - /service/get_login_info
...@@ -201,6 +199,8 @@ wecome: ...@@ -201,6 +199,8 @@ wecome:
- /msgaudit/check_room_agree - /msgaudit/check_room_agree
- /msgaudit/groupchat/get - /msgaudit/groupchat/get
needAgentTokenUrl: needAgentTokenUrl:
- /get_jsapi_ticket
- /ticket/get
- /message/send - /message/send
thirdAppUrl: thirdAppUrl:
- /user/getuserinfo - /user/getuserinfo
......
# 开发环境配置
ENV = 'development'
# 塬微管理系统/开发环境
VUE_APP_BASE_API = 'http://106.13.201.219'
# VUE_APP_BASE_API = 'http://3x2d6z.natappfree.cc'
# 开发环境IP
VUE_APP_BASE_URL = 'http://192.168.0.101'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 生产环境配置
ENV = 'production'
# 塬微管理系统/生产环境api
VUE_APP_BASE_API = 'http://106.13.201.219'
# 生产环境IP
VUE_APP_BASE_URL = 'http://106.13.201.219'
...@@ -1732,6 +1732,16 @@ ...@@ -1732,6 +1732,16 @@
"integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=", "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
"dev": true "dev": true
}, },
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"big.js": { "big.js": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npm.taobao.org/big.js/download/big.js-3.2.0.tgz", "resolved": "https://registry.npm.taobao.org/big.js/download/big.js-3.2.0.tgz",
...@@ -1764,12 +1774,47 @@ ...@@ -1764,12 +1774,47 @@
"unique-filename": "^1.1.1" "unique-filename": "^1.1.1"
} }
}, },
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"emojis-list": { "emojis-list": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz", "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz",
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
"dev": true "dev": true
}, },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"html-webpack-plugin": { "html-webpack-plugin": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz?cache=0&sync_timestamp=1609777842352&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz", "resolved": "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz?cache=0&sync_timestamp=1609777842352&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-webpack-plugin%2Fdownload%2Fhtml-webpack-plugin-3.2.0.tgz",
...@@ -1819,6 +1864,16 @@ ...@@ -1819,6 +1864,16 @@
"minipass": "^3.1.1" "minipass": "^3.1.1"
} }
}, },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"terser-webpack-plugin": { "terser-webpack-plugin": {
"version": "2.3.8", "version": "2.3.8",
"resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.8.tgz?cache=0&sync_timestamp=1603881694762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.8.tgz", "resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.8.tgz?cache=0&sync_timestamp=1603881694762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.8.tgz",
...@@ -1845,6 +1900,56 @@ ...@@ -1845,6 +1900,56 @@
"define-properties": "^1.1.2", "define-properties": "^1.1.2",
"object.getownpropertydescriptors": "^2.0.3" "object.getownpropertydescriptors": "^2.0.3"
} }
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.1.2",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz",
"integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"optional": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"optional": true
},
"json5": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
"dev": true,
"optional": true,
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
} }
} }
}, },
...@@ -7609,6 +7714,11 @@ ...@@ -7609,6 +7714,11 @@
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
"dev": true "dev": true
}, },
"mutation-observer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/mutation-observer/-/mutation-observer-1.0.3.tgz",
"integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
},
"mute-stream": { "mute-stream": {
"version": "0.0.8", "version": "0.0.8",
"resolved": "https://registry.npm.taobao.org/mute-stream/download/mute-stream-0.0.8.tgz", "resolved": "https://registry.npm.taobao.org/mute-stream/download/mute-stream-0.0.8.tgz",
...@@ -7793,6 +7903,11 @@ ...@@ -7793,6 +7903,11 @@
"integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=", "integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=",
"dev": true "dev": true
}, },
"normalize.css": {
"version": "8.0.1",
"resolved": "https://registry.npm.taobao.org/normalize.css/download/normalize.css-8.0.1.tgz",
"integrity": "sha1-m5iiCHOLnMJjTKrLxC0THJdIe/M="
},
"npm-run-path": { "npm-run-path": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-2.0.2.tgz", "resolved": "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-2.0.2.tgz",
...@@ -10804,6 +10919,11 @@ ...@@ -10804,6 +10919,11 @@
"punycode": "^2.1.1" "punycode": "^2.1.1"
} }
}, },
"transitionEnd": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/transitionEnd/-/transitionEnd-1.0.2.tgz",
"integrity": "sha1-GRTbW0Wn79w0oBr2koWjppOHFjM="
},
"tryer": { "tryer": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/tryer/download/tryer-1.0.1.tgz", "resolved": "https://registry.npm.taobao.org/tryer/download/tryer-1.0.1.tgz",
...@@ -11206,6 +11326,15 @@ ...@@ -11206,6 +11326,15 @@
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
"dev": true "dev": true
}, },
"vconsole": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/vconsole/-/vconsole-3.4.0.tgz",
"integrity": "sha512-N9py7Ch9M9nzsigYf8T/WHIOood7jq2MNtUWDqicnrCsPsOZj8Z3NsmFgBmDA3bPKwnzace11HXHxYKPfwV32A==",
"requires": {
"mutation-observer": "^1.0.3",
"transitionEnd": "^1.0.2"
}
},
"vendors": { "vendors": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npm.taobao.org/vendors/download/vendors-1.0.4.tgz?cache=0&sync_timestamp=1579857106626&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvendors%2Fdownload%2Fvendors-1.0.4.tgz", "resolved": "https://registry.npm.taobao.org/vendors/download/vendors-1.0.4.tgz?cache=0&sync_timestamp=1579857106626&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvendors%2Fdownload%2Fvendors-1.0.4.tgz",
...@@ -11298,87 +11427,6 @@ ...@@ -11298,87 +11427,6 @@
} }
} }
}, },
"vue-loader-v16": {
"version": "npm:vue-loader@16.1.2",
"resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-16.1.2.tgz?cache=0&sync_timestamp=1608188050165&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-16.1.2.tgz",
"integrity": "sha1-XAO2xQ0qX5g8fOuhXFDXjKKymPQ=",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1606792382140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
"integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz?cache=0&sync_timestamp=1591687076871&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-4.1.0.tgz",
"integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
"integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
"integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz",
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
"integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz",
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"vue-router": { "vue-router": {
"version": "3.4.9", "version": "3.4.9",
"resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.9.tgz?cache=0&sync_timestamp=1609110108136&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.4.9.tgz", "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.9.tgz?cache=0&sync_timestamp=1609110108136&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.4.9.tgz",
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
"dependencies": { "dependencies": {
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"normalize.css": "^8.0.1",
"vant": "^2.12.2", "vant": "^2.12.2",
"vconsole": "^3.4.0",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-router": "^3.2.0", "vue-router": "^3.2.0",
"vuex": "^3.4.0" "vuex": "^3.4.0"
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<meta charset="utf-8"> <head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
</head> <title><%= htmlWebpackPlugin.options.title %></title>
<body> <script src="./jweixin-1.2.0.js"></script>
<noscript> <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </head>
</noscript>
<div id="app"></div> <body>
<!-- built files will be auto injected --> <noscript>
</body> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
</html> Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
\ No newline at end of file
<script> <script>
import { getAgentTicket, getAppTicket } from '@/api/common'
export default { export default {
name: 'App', name: 'App',
data() { data() {
return { return {
timestamp: '', appId: 'appId',
nonceStr: '', agentId: '1000005',
signature: '',
} }
}, },
created() { created() {
// 调取服务端signature // this.wxConfig()
}, },
watch: { watch: {
// 通过config接口注入权限验证配置 // 通过config接口注入权限验证配置
// 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA(single-page application)的web app可在每次url变化时进行调用) // 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA(single-page application)的web app可在每次url变化时进行调用)
$router() { $route() {
wx.config({ this.wxConfig()
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题 },
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 },
appId: '123456', // 必填,企业微信的corpID methods: {
timestamp: this.timestamp, // 必填,生成签名的时间戳 wxConfig() {
nonceStr: this.nonceStr, // 必填,生成签名的随机串 getAgentTicket(window.location.href.split('#')[0]).then(({ data }) => {
signature: this.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法 let { timestamp, nonceStr, signature } = data
jsApiList: [], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来 wx.agentConfig({
corpid: this.appId, // 必填,企业微信的corpid,必须与当前登录的企业一致
agentid: this.agentId, // 必填,企业微信的应用id (e.g. 1000247)
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['sendChatMessage'], //必填
success: (res) => {
// 回调
},
fail: (res) => {
if (res.errMsg.indexOf('function not exist') > -1) {
alert('版本过低请升级')
}
},
})
})
},
_wxConfig() {
// 获取企业的jsapi_ticket
getAppTicket(window.location.href).then(({ data }) => {
let { timestamp, nonceStr, signature } = data
wx.config({
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: this.appId, // 必填,企业微信的corpID
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ['getContext', 'sendChatMessage'], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
})
wx.ready(() => {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
getAgentTicket(window.location.href).then(({ data }) => {
let { timestamp, nonceStr, signature } = data
wx.agentConfig({
corpid: this.appId, // 必填,企业微信的corpid,必须与当前登录的企业一致
agentid: this.agentId, // 必填,企业微信的应用id (e.g. 1000247)
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['sendChatMessage'], //必填
success: (res) => {
// 回调
},
fail: (res) => {
if (res.errMsg.indexOf('function not exist') > -1) {
alert('版本过低请升级')
}
},
})
})
})
wx.error(function(res) {
console.error(res)
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
})
}) })
}, },
}, },
...@@ -30,11 +87,7 @@ export default { ...@@ -30,11 +87,7 @@ export default {
</script> </script>
<template> <template>
<div id="app"> <div id="app">
<div id="nav"> <router-view class="page" />
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
</div> </div>
</template> </template>
...@@ -43,20 +96,6 @@ export default { ...@@ -43,20 +96,6 @@ export default {
font-family: Avenir, Helvetica, Arial, sans-serif; font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50; color: #2c3e50;
} }
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style> </style>
import request from '@/utils/request'
const service = window.CONFIG.services.wecom + '/chat'
/**
* 侧边栏列表
* @param {*} params
*/
export function getTypeList() {
return request({
url: service + '/side/h5List',
})
}
/**
* 素材列表
* @param {*} sideId
*/
export function getMaterialList(params) {
return request({
url: service + '/item/list',
params,
})
}
/**
* 收藏列表(h5我的)
* @param {*} userId
*/
export function getCollectionList(params) {
return request({
url: service + '/collection/list',
params,
})
}
/**
* 添加收藏
* @param {*} data
* {
materialId:素材id
userId:用户id
}
*/
export function addCollection(data) {
return request({
url: service + '/collection/addCollection',
method: 'post',
data,
})
}
/**
* 取消收藏
* @param {*} data
* {
materialId:素材id
userId:用户id
}
*/
export function cancleCollection(data) {
return request({
url: service + '/collection/cancleCollection',
method: 'post',
data,
})
}
import request from '@/utils/request'
import config from '@/config'
const service = config.services.wecom
/**
* 获取应用的jsapi_ticket
* @param {*} url 页面url
*/
export function getAgentTicket(url) {
return request({
url: service + '/ticket/getAgentTicket',
params: {
url,
},
})
}
/**
* 获取企业的jsapi_ticket
* @param {*} url 页面url
*/
export function getAppTicket(url) {
return request({
url: service + '/ticket/getAppTicket',
params: {
url,
},
})
}
/**
* 获取登录用户id
* @param {*} url 页面url
*/
export function getUserInfo(code) {
return request({
url: service + '/user/getUserInfo',
params: {
code,
agentId: '1000005',
},
})
}
...@@ -13,10 +13,13 @@ const config = { ...@@ -13,10 +13,13 @@ const config = {
* @description api请求基础路径 * @description api请求基础路径
*/ */
// 测试服 // 测试服
domain: process.env.NODE_ENV === 'development' ? 'http://192.168.1.32:8888' : 'http://192.168.1.26:8888', // domain:
process.env.NODE_ENV === 'development'
? 'http://192.168.1.32:8888'
: 'http://192.168.1.26:8888', //
// 正式服 // 正式服
// domain: process.env.NODE_ENV === 'development' ? 'http://192.168.1.35:8118' : 'https://gateway.visualinsur.cn:8888', // // domain: process.env.NODE_ENV === 'development' ? 'http://192.168.1.35:8118' : 'https://gateway.visualinsur.cn:8888', //
/** /**
* @description 默认打开的首页的路由name值,默认为home * @description 默认打开的首页的路由name值,默认为home
*/ */
...@@ -36,6 +39,7 @@ const config = { ...@@ -36,6 +39,7 @@ const config = {
} }
config.services = { config.services = {
wecom: '/wecom',
} }
export default config export default config
\ No newline at end of file
import wx from '@/utils/jweixin-1.2.0.js'
import Vue from 'vue' import Vue from 'vue'
import config from '@/config'
window.CONFIG = config
import 'normalize.css/normalize.css'
import Vant from 'vant' import Vant from 'vant'
import 'vant/lib/index.css' import 'vant/lib/index.css'
Vue.use(Vant) Vue.use(Vant)
import '@/styles/index.less' // global css
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
window.wx = wx import VConsole from 'vconsole'
process.env.NODE_ENV === 'production' && new VConsole()
Vue.config.productionTip = false Vue.config.productionTip = false
......
import Vue from "vue"; import Vue from 'vue'
import VueRouter from "vue-router"; import VueRouter from 'vue-router'
import Home from "../views/Home.vue"; import Home from '../views/Home.vue'
Vue.use(VueRouter); Vue.use(VueRouter)
const routes = [ const routes = [
{ {
path: "/", path: '/',
name: "Home", name: 'Home',
component: Home component: Home,
meta: {
title: '首页',
},
}, },
{ {
path: "/about", path: '/chat',
name: "About", name: 'chat',
// route level code-splitting // route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route // this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited. // which is lazy-loaded when the route is visited.
component: () => component: () => import(/* webpackChunkName: "about" */ '../views/chat'),
import(/* webpackChunkName: "about" */ "../views/About.vue") meta: {
} title: 'chat',
]; },
},
]
const router = new VueRouter({ const router = new VueRouter({
routes routes,
}); })
export default router; export default router
...@@ -33,9 +33,9 @@ td { ...@@ -33,9 +33,9 @@ td {
padding: 0; padding: 0;
} }
body,input, select, textarea /* for ie */ { body,input, select, textarea /* for ie */ {
font: 14px Microsoft YaHei, "宋体", arial, -apple-system, "PingFang SC", font: 14px Microsoft YaHei, '宋体', arial, -apple-system, 'PingFang SC',
"Helvetica Neue", Helvetica, "DejaVu Sans", "Lucida Grande", Tahoma, 'Helvetica Neue', Helvetica, 'DejaVu Sans', 'Lucida Grande', Tahoma,
"Hiragino Sans GB", STHeiti, SimSun, sans-serif; 'Hiragino Sans GB', STHeiti, SimSun, sans-serif;
line-height: 1.15; line-height: 1.15;
color: #333; /*touch-action: none*/ color: #333; /*touch-action: none*/
} /** 设置默认字体 **/ } /** 设置默认字体 **/
...@@ -119,18 +119,18 @@ a { ...@@ -119,18 +119,18 @@ a {
} }
/*click outline for firefox*/ /*click outline for firefox*/
button::-moz-focus-inner, button::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner, input[type='reset']::-moz-focus-inner,
input[type="button"]::-moz-focus-inner, input[type='button']::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner, input[type='submit']::-moz-focus-inner,
input[type="file"] > input[type="button"]::-moz-focus-inner { input[type='file'] > input[type='button']::-moz-focus-inner {
border: none; border: none;
} }
/*click outline for IE and other browser*/ /*click outline for IE and other browser*/
button:focus, button:focus,
input[type="reset"]:focus, input[type='reset']:focus,
input[type="button"]:focus, input[type='button']:focus,
input[type="submit"]:focus, input[type='submit']:focus,
input[type="file"] > input[type="button"]:focus { input[type='file'] > input[type='button']:focus {
outline: none; outline: none;
} }
...@@ -203,6 +203,23 @@ textarea:-ms-input-placeholder { ...@@ -203,6 +203,23 @@ textarea:-ms-input-placeholder {
float: right; float: right;
position: relative; position: relative;
} }
.flex {
display: flex;
}
.fxbw {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
ais {
align-items: stretch;
}
.aic {
align-items: center;
}
.al { .al {
text-align: left; text-align: left;
} }
...@@ -255,6 +272,17 @@ textarea:-ms-input-placeholder { ...@@ -255,6 +272,17 @@ textarea:-ms-input-placeholder {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.line2-toe {
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
display: -webkit-box;
white-space: pre-wrap;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
}
/*close*/ /*close*/
.close { .close {
position: relative; position: relative;
...@@ -278,3 +306,99 @@ textarea:-ms-input-placeholder { ...@@ -278,3 +306,99 @@ textarea:-ms-input-placeholder {
.cp { .cp {
cursor: pointer; cursor: pointer;
} }
.pt5 {
padding-top: 5px;
}
.pb5 {
padding-bottom: 5px;
}
.pt10 {
padding-top: 10px;
}
.pt15 {
padding-top: 15px;
}
.pt20 {
padding-top: 20px;
}
.pr5 {
padding-right: 5px;
}
.pb5 {
padding-bottom: 5px;
}
.pl5 {
padding-left: 5px;
}
.mt5 {
margin-top: 5px;
}
.mr5 {
margin-right: 5px;
}
.mb5 {
margin-bottom: 5px;
}
.mb8 {
margin-bottom: 8px;
}
.ml5 {
margin-left: 5px;
}
.mt10 {
margin-top: 10px;
}
.mr10 {
margin-right: 10px;
}
.mb10 {
margin-bottom: 10px;
}
.ml10 {
margin-left: 10px;
}
.mt15 {
margin-top: 15px;
}
.mr15 {
margin-right: 15px;
}
.mb15 {
margin-bottom: 15px;
}
.ml15 {
margin-left: 15px;
}
.mt20 {
margin-top: 20px;
}
.mr20 {
margin-right: 20px;
}
.mb20 {
margin-bottom: 20px;
}
.ml20 {
margin-left: 20px;
}
@import './common.css';
@import './transition.less';
\ No newline at end of file
import axios from axios import axios from 'axios'
import config from "@/config" import { Toast, Dialog } from 'vant'
function createAxios(baseUrl) { function createAxios(baseURL) {
const instance = axios.create({ const instance = axios.create({
baseUrl, baseURL,
headers: { headers: {
Auth_token: "" Auth_token: '',
}, },
timeout: 3000, timeout: 3000,
}) })
// 请求拦截 // 请求拦截
instance.interceptors.request.use(config => { instance.interceptors.request.use(
// console.log('request config: ' + JSON.stringify(config)) (config) => {
return config // console.log('request config: ' + JSON.stringify(config))
}, error => { return config
return Promise.reject(error) },
}) (error) => {
// 响应拦截 return Promise.reject(error)
instance.interceptors.response.use(res => {
// console.log('res: ' + res)
const { data, status } = res
// code 0:成功,-1/其它:错误
if (status === 200 && data.code === 0) {
return JSON.stringify(data.result) ? data.result : data.data
} else if (data.code === 201) {
// Message.error({
// content: `产品已存在`,
// duration: 3
// })
} else {
addErrorLog(res)
}
if (process.env.NODE_ENV === 'development') {
return Promise.reject(res) // 这样控制台会显示报错日志
} else {
return new Promise(() => { }) // 中断promise
} }
}, error => { )
if (error.response) { // 响应拦截
addErrorLog(error.response) instance.interceptors.response.use(
} else { (res) => {
// Message.error({ // console.log('res: ' + res)
// content: `服务器未启动或连接超时`, const { data, status } = res
// duration: 3 // code 0:成功,-1/其它:错误
// }) if (status === 200 && data.code === 200) {
console.error("服务器未启动或连接超时") return data
} else if (data.code === 201) {
// Message.error({
// content: `产品已存在`,
// duration: 3
// })
} else {
addErrorLog(res)
}
if (process.env.NODE_ENV === 'development') {
return Promise.reject(res) // 这样控制台会显示报错日志
} else {
return new Promise(() => {}) // 中断promise
}
},
(error) => {
if (error.response) {
addErrorLog(error.response)
} else {
Dialog({ message: '服务器未启动或连接超时' })
console.error('服务器未启动或连接超时')
}
return Promise.reject(error)
} }
return Promise.reject(error) )
})
// 错误日志 // 错误日志
const addErrorLog = errorInfo => { const addErrorLog = (errorInfo) => {
const { data, statusText, status, request: { responseText, responseURL } } = errorInfo const {
data,
statusText,
status,
request: { responseText, responseURL },
} = errorInfo
// let info = { // let info = {
// type: 'ajax', // type: 'ajax',
// code: status, // code: status,
...@@ -59,8 +67,9 @@ function createAxios(baseUrl) { ...@@ -59,8 +67,9 @@ function createAxios(baseUrl) {
// } // }
// if (!responseURL.includes('save_error_logger')) store.dispatch('addErrorLog', info) // if (!responseURL.includes('save_error_logger')) store.dispatch('addErrorLog', info)
process.env.NODE_ENV === 'development' process.env.NODE_ENV === 'development'
? console.error(`错误: 路径: ${responseURL}, 返回值 : ${responseText}`,) ? console.error(`错误: 路径: ${responseURL}, 返回值 : ${responseText}`)
: console.error(`${JSON.parse(responseText).message}`,) : console.error(`${JSON.parse(responseText).message}`)
Dialog({ message: responseText })
} }
return instance return instance
...@@ -68,4 +77,4 @@ function createAxios(baseUrl) { ...@@ -68,4 +77,4 @@ function createAxios(baseUrl) {
// const httpRequest = createAxios() // const httpRequest = createAxios()
export default createAxios(config.domain) export default createAxios(process.env.VUE_APP_BASE_API)
\ No newline at end of file
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<template> <template>
<div class="home"> <div class="home">
<img alt="Vue logo" src="../assets/logo.png" /> <div class="logo ac">linkWeChat</div>
<HelloWorld msg="Welcome to Your Vue.js App" /> <router-link
class="router-link"
v-for="(item, index) in $router.options.routes"
:to="item.path"
:key="index"
>{{ item.meta.title }}</router-link
>
</div> </div>
</template> </template>
<script> <script>
// @ is an alias to /src // @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
export default { export default {
name: "Home", name: 'Home',
components: { components: {},
HelloWorld }
}
};
</script> </script>
<style lang="less" scoped>
.logo {
margin: 0 auto;
width: 150px;
height: 50px;
line-height: 50px;
border: 2px solid #6582ff;
border-radius: 50px;
}
.router-link {
display: block;
text-align: center;
line-height: 40px;
}
</style>
<script>
import {
getMaterialList,
getCollectionList,
addCollection,
cancleCollection,
} from '@/api/chat'
export default {
components: {},
props: {
sideId: {
type: String,
default: '0',
},
userId: {
type: String,
default: '',
},
keyword: {
type: String,
default: '',
},
},
data() {
return {
loading: false,
finished: false,
error: false,
pageSize: 1,
pageNum: 10,
list: [],
collectList: [],
}
},
watch: {},
computed: {},
created() {
this.getList()
this.userId && this.getCollectionList()
},
mounted() {},
methods: {
getList(page) {
let pageSize = page || this.pageSize++
let pageNum = this.pageNum
let keyword = this.keyword
page == 1 && (this.list = [])
this.loading = true
;(this.sideId
? getMaterialList({ sideId: this.sideId, pageSize, pageNum, keyword })
: getCollectionList({ userId: this.userId, pageSize, pageNum, keyword })
)
.then(({ rows, total }) => {
this.list.push(...rows)
this.loading = false
// 数据全部加载完成
if (this.list.length >= total) {
this.finished = true
}
})
.catch(() => {
this.error = true
})
},
getCollectionList() {
let data = { userId: this.userId, pageSize: 1, pageNum: 1000 }
getCollectionList(data).then(({ rows, total }) => {
this.collectList = rows.map((d) => d.id)
})
},
isCollected(id) {
return this.collectList.includes(id)
},
send(data) {
let entry = undefined
wx.invoke('getContext', {}, function(res) {
if (res.err_msg == 'getContext:ok') {
entry = res.entry //返回进入H5页面的入口类型,目前有normal、contact_profile、single_chat_tools、group_chat_tools
if (!['single_chat_tools', 'group_chat_tools'].includes(entry)) {
return
}
// mediaType 0 图片(image)、1 语音(voice)、2 视频(video),3 普通文件(file) 4 文本 5 海报
// msgtype 文本(“text”),图片(“image”),视频(“video”),文件(“file”),H5(“news”)和小程序(“miniprogram”)
let mes = {}
let msgtype = {
0: 'image',
2: 'video',
3: 'file',
4: 'text',
5: 'news',
}
switch (data.mediaType) {
case '4':
default:
mes.text = {
content: data.content, //文本内容
}
break
case '0':
case '2':
case '3':
mes[msgtype[data.mediaType]] = {
mediaid: data.materialId, //
}
break
case '5':
mes.news = {
link: '', //H5消息页面url 必填
title: '', //H5消息标题
desc: '', //H5消息摘要
imgUrl: '', //H5消息封面图片URL
}
break
// case '6':
// mes.miniprogram = {
// appid: 'wx8bd80126147df384', //小程序的appid
// title: 'this is title', //小程序消息的title
// imgUrl:
// 'https://search-operate.cdn.bcebos.com/d054b8892a7ab572cb296d62ec7f97b6.png', //小程序消息的封面图。必须带http或者https协议头,否则报错 $apiName$:fail invalid imgUrl
// page: '/index/page.html', //小程序消息打开后的路径,注意要以.html作为后缀,否则在微信端打开会提示找不到页面
// }
// break
}
mes.msgtype = msgtype[data.mediaType]
wx.invoke('sendChatMessage', mes, function(res) {
if (res.err_msg == 'sendChatMessage:ok') {
//发送成功
}
})
} else {
//错误处理
}
})
},
collect(materialId) {
;(this.isCollected(materialId) ? cancleCollection : addCollection)({
userId: this.userId,
materialId,
}).then(({ data }) => {
this.isCollected(materialId)
? this.isCollected.splice(this.isCollected.indexOf(materialId), 1)
: this.isCollected.push(materialId)
})
},
},
}
</script>
<template>
<div>
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
:error.sync="error"
error-text="请求失败,点击重新加载"
@load="getList()"
>
<div v-for="(item, index) in list" class="list" :key="index">
<div class="title">{{ item.content }}</div>
<div class="info">
{{ item.content }}
<span>2020/2/4</span>
<div class="fr flex">
<div class="action" @click="send(item)">发送</div>
<div v-if="!!userId" class="action" @click="collect(item.id)">
{{ isCollected(item.id) ? '' : '' }}收藏
</div>
</div>
</div>
</div>
</van-list>
</div>
</template>
<style lang="less" scoped></style>
2
<script>
import { getUserInfo } from '@/api/common'
import { getTypeList } from '@/api/chat'
import List from './List'
export default {
components: { List },
props: {},
data() {
return {
keyword: '',
active: 0,
list: [],
loading: false,
finished: false,
show: false,
userId: '',
}
},
watch: {},
computed: {},
beforeCreate() {
// http://106.13.201.219/?auth_code=xxx#/authWehatCallback
// console.log('routerbeforeCreate', this.$route);
// let auth_code = location.search
// .slice(1)
// .split('&')[0]
// .split('=')[1]
// if (!auth_code) {
// this.$toast('未获得授权')
// return
// }
// getUserInfo(auth_code)
// .then(({ data }) => {
// this.userId = data.userId
// this.$toast('userId:' + this.userId)
// })
// .catch((err) => {
// this.$toast('err:' + err)
// })
},
created() {
let auth_code = location.search
.slice(1)
.split('&')[0]
.split('=')[1]
if (!auth_code) {
this.$toast('未获得授权')
return
}
getUserInfo(auth_code)
.then(({ data }) => {
this.userId = data.userId
this.$toast('userId:' + this.userId)
})
.catch((err) => {
Dialog.confirm({
title: '标题',
message: err,
})
})
this.getList()
},
mounted() {},
methods: {
getList() {
getTypeList().then(({ rows, total }) => {
this.list = rows
})
},
search() {
this.$refs['list' + this.active].getList(1)
},
add() {},
},
}
</script>
<template>
<div>
<van-search
v-model="keyword"
show-action
placeholder="请输入搜索关键词"
@search="search"
>
<!-- <template #action>
<van-icon name="plus" @click="add" />
</template> -->
</van-search>
<van-tabs v-model="active">
<van-tab v-if="!!userId" title="我的">
<List ref="list0" :userId="userId" :keyword="keyword"></List>
</van-tab>
<van-tab
:title="item.sideName"
v-for="(item, index) in list"
:key="index"
>
<List
:ref="'list' + (index + 1)"
:sideId="item.sideId"
:userId="userId"
:keyword="keyword"
></List>
</van-tab>
</van-tabs>
<!-- <van-dialog
v-model="show"
:title="`添加&quot;我的&quot;${radio}`"
show-cancel-button
>
<van-form @submit="onSubmit">
<van-field name="radio" label="添加类型">
<template #input>
<van-radio-group v-model="radio" direction="horizontal">
<van-radio name="1">文本</van-radio>
<van-radio name="2">分类</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field
v-model="username"
name="分类名称"
label="分类名称"
placeholder="分类名称"
:rules="[{ required: true, message: '请填写分类名称' }]"
/>
<template>
<van-field
readonly
clickable
name="picker"
:value="value"
label="文本分类"
placeholder="点击选择文本分类"
@click="showPicker = true"
/>
<van-popup v-model="showPicker" position="bottom">
<van-picker
show-toolbar
:columns="columns"
@confirm="onConfirm"
@cancel="showPicker = false"
/>
</van-popup>
<van-field
v-model="message"
rows="5"
autosize
label="文本信息"
type="textarea"
maxlength="150"
placeholder="请输入文本信息"
show-word-limit
/>
</template>
</van-form>
</van-dialog> -->
</div>
</template>
<style lang="less" scoped>
.page {
height: 100vh;
background: #f6f6f6;
}
/deep/ .list {
padding: 10px;
background: #fff;
border-top: 1px solid #eee;
.info {
padding-top: 10px;
}
.action {
padding-left: 5px;
}
}
</style>
...@@ -4,15 +4,14 @@ import cn.hutool.core.collection.CollectionUtil; ...@@ -4,15 +4,14 @@ import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.linkwechat.common.constant.WeConstans; import com.linkwechat.common.constant.WeConstans;
import com.linkwechat.common.core.domain.elastic.ElasticSearchEntity;
import com.linkwechat.common.core.elasticsearch.ElasticSearch; import com.linkwechat.common.core.elasticsearch.ElasticSearch;
import com.linkwechat.common.core.redis.RedisCache; import com.linkwechat.common.core.redis.RedisCache;
import com.linkwechat.common.utils.StringUtils; import com.linkwechat.common.utils.StringUtils;
import com.linkwechat.wecom.service.IWeChatContactMappingService; import com.linkwechat.wecom.service.IWeChatContactMappingService;
import com.linkwechat.wecom.service.IWeSensitiveActHitService;
import com.linkwechat.wecom.service.IWeSensitiveService; import com.linkwechat.wecom.service.IWeSensitiveService;
import com.tencent.wework.FinanceUtils; import com.tencent.wework.FinanceUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortBuilders;
...@@ -42,6 +41,8 @@ public class RyTask { ...@@ -42,6 +41,8 @@ public class RyTask {
private IWeChatContactMappingService weChatContactMappingService; private IWeChatContactMappingService weChatContactMappingService;
@Autowired @Autowired
private IWeSensitiveService weSensitiveService; private IWeSensitiveService weSensitiveService;
@Autowired
private IWeSensitiveActHitService weSensitiveActHitService;
public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
...@@ -59,24 +60,26 @@ public class RyTask { ...@@ -59,24 +60,26 @@ public class RyTask {
public void FinanceTask(String corpId, String secret) throws IOException { public void FinanceTask(String corpId, String secret) throws IOException {
log.info("执行有参方法: params:{},{}", corpId, secret); log.info("执行有参方法: params:{},{}", corpId, secret);
//创建索引 //创建索引
elasticSearch.createIndex2(WeConstans.WECOM_FINANCE_INDEX,elasticSearch.getFinanceMapping()); elasticSearch.createIndex2(WeConstans.WECOM_FINANCE_INDEX, elasticSearch.getFinanceMapping());
//从缓存中获取消息标识 //从缓存中获取消息标识
Object seqObject = Optional.ofNullable(redisCache.getCacheObject(WeConstans.CONTACT_SEQ_KEY)).orElse(0L); Object seqObject = Optional.ofNullable(redisCache.getCacheObject(WeConstans.CONTACT_SEQ_KEY)).orElse(0L);
Long seqLong = Long.valueOf(String.valueOf(seqObject)); Long seqLong = Long.valueOf(String.valueOf(seqObject));
AtomicLong index = new AtomicLong(seqLong); AtomicLong index = new AtomicLong(seqLong);
if (index.get() == 0){ if (index.get() == 0) {
setRedisCacheSeqValue(index); setRedisCacheSeqValue(index);
} }
log.info(">>>>>>>seq:{}",index.get()); log.info(">>>>>>>seq:{}", index.get());
FinanceUtils.initSDK(corpId, secret); FinanceUtils.initSDK(corpId, secret);
List<JSONObject> chatDataList = FinanceUtils.getChatData(index.get(), List<JSONObject> chatDataList = FinanceUtils.getChatData(index.get(),
"", "",
"", redisCache); "", redisCache);
if (CollectionUtil.isNotEmpty(chatDataList)){ if (CollectionUtil.isNotEmpty(chatDataList)) {
try { try {
List<JSONObject> elasticSearchEntities = weChatContactMappingService.saveWeChatContactMapping(chatDataList); List<JSONObject> elasticSearchEntities = weChatContactMappingService.saveWeChatContactMapping(chatDataList);
//获取敏感行为命中信息
weSensitiveActHitService.hitWeSensitiveAct(chatDataList);
List<Consumer<List<JSONObject>>> consumerList = Lists.newArrayList(); List<Consumer<List<JSONObject>>> consumerList = Lists.newArrayList();
consumerList.add(weSensitiveService::hitSensitive); consumerList.add(weSensitiveService::hitSensitive);
elasticSearch.insertBatchAsync(WeConstans.WECOM_FINANCE_INDEX, elasticSearchEntities, consumerList); elasticSearch.insertBatchAsync(WeConstans.WECOM_FINANCE_INDEX, elasticSearchEntities, consumerList);
...@@ -87,24 +90,23 @@ public class RyTask { ...@@ -87,24 +90,23 @@ public class RyTask {
} }
} }
private void setRedisCacheSeqValue(AtomicLong index){ private void setRedisCacheSeqValue(AtomicLong index) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SortBuilder<?> sortBuilderPrice = SortBuilders.fieldSort(WeConstans.CONTACT_SEQ_KEY).order( SortOrder.DESC); SortBuilder<?> sortBuilderPrice = SortBuilders.fieldSort(WeConstans.CONTACT_SEQ_KEY).order(SortOrder.DESC);
searchSourceBuilder.sort(sortBuilderPrice); searchSourceBuilder.sort(sortBuilderPrice);
searchSourceBuilder.size(1); searchSourceBuilder.size(1);
List<JSONObject> searchResultList = elasticSearch.search(WeConstans.WECOM_FINANCE_INDEX, searchSourceBuilder, JSONObject.class); List<JSONObject> searchResultList = elasticSearch.search(WeConstans.WECOM_FINANCE_INDEX, searchSourceBuilder, JSONObject.class);
searchResultList.stream().findFirst().ifPresent(result ->{ searchResultList.stream().findFirst().ifPresent(result -> {
index.set(result.getLong(WeConstans.CONTACT_SEQ_KEY) + 1); index.set(result.getLong(WeConstans.CONTACT_SEQ_KEY) + 1);
}); });
redisCache.setCacheObject(WeConstans.CONTACT_SEQ_KEY,index); redisCache.setCacheObject(WeConstans.CONTACT_SEQ_KEY, index);
} }
/** /**
*
* @param corpId 企业id * @param corpId 企业id
* @param secret 会话密钥 * @param secret 会话密钥
*/ */
public void getPermitUserList(String corpId, String secret){ public void getPermitUserList(String corpId, String secret) {
log.info("执行有参方法: params:{},{}", corpId, secret); log.info("执行有参方法: params:{},{}", corpId, secret);
} }
......
# 开发环境配置 # 开发环境配置
ENV = 'development' ENV = 'development'
# 微管理系统/开发环境 # 微管理系统/开发环境
VUE_APP_BASE_API = 'http://106.13.201.219' VUE_APP_BASE_API = 'http://146.56.222.200'
# VUE_APP_BASE_API = 'http://n3rpzt.natappfree.cc' # VUE_APP_BASE_API = 'http://n3rpzt.natappfree.cc'
# 开发环境IP # 开发环境IP
......
# 生产环境配置 # 生产环境配置
ENV = 'production' ENV = 'production'
# 微管理系统/生产环境api # 微管理系统/生产环境api
VUE_APP_BASE_API = 'http://106.13.236.58:8080' VUE_APP_BASE_API = 'http://146.56.222.200'
# 生产环境IP # 生产环境IP
VUE_APP_BASE_URL = 'http://106.13.236.58:8080' VUE_APP_BASE_URL = 'http://106.13.236.58:8080'
import request from '@/utils/request'
const service = window.CONFIG.services.wecom + '/chat'
/**
* 侧边栏列表
* @param {*} params
*/
export function getList() {
return request({
url: service + '/side/list',
})
}
/**
* 更新侧边栏信息
* @param {*} data
* {
"sideId": "",
"mediaType": "0 图片(image)、1 语音(voice)、2 视频(video),3 普通文件(file) 4 文本 5 海报",
"sideName": "聊天工具栏名称",
"total": "已抓取素材数量",
"using": "是否启用 0 启用 1 未启用"
}
*/
export function update(data) {
return request({
url: service + '/side',
method: 'put',
data,
})
}
/**
* 侧边栏抓取素材
* @param {*} data
* {
"sideId": "",
"materialIds": "素材id列表",
"mediaType": "素材类型 0 图片(image)、1 语音(voice)、2 视频(video),3 普通文件(file) 4 文本 5 海报",
"checkAll": "是否全选 0 全选 1 非全选"
}
*/
export function getMaterial(data) {
return request({
url: service + '/item',
method: 'put',
data,
})
}
import request from '@/utils/request' import request from '@/utils/request'
const service = window.CONFIG.services.common
export function upload(data) {
return request({
url: service + '/uploadFile2Cos',
method: 'POST',
data,
})
}
/** /**
* 下载网络连接文件 * 下载网络连接文件
......
...@@ -14,9 +14,16 @@ const getTree=(params)=>{ ...@@ -14,9 +14,16 @@ const getTree=(params)=>{
params, params,
}) })
} }
const chatGrounpList=(params)=>{
return request({
url:'/wecom/finance/getChatRoomContactList',
method: 'get',
params,
})
}
const listByCustomer=(params)=>{ const listByCustomer=(params)=>{
return request({ return request({
url:'/chat/mapping/listByCustomer', url:'/wecom/customer/list',
method: 'get', method: 'get',
params, params,
}) })
...@@ -33,5 +40,6 @@ const getTree=(params)=>{ ...@@ -33,5 +40,6 @@ const getTree=(params)=>{
getTree, getTree,
chatList, chatList,
listByCustomer, listByCustomer,
getChatAllList getChatAllList,
chatGrounpList
} }
\ No newline at end of file
import request from '@/utils/request'
const service = window.CONFIG.services.wecom + '/sensitive'
/**
* 获取敏感词触发列表
* @param {*} params
*
*/
export function getSecurityList(params) {
return request({
url: service + '/hit/list',
method: 'get',
params,
})
}
/**
* 获取敏感词设置列表
* @param {*} params
*
*/
export function getSettingSensitiveList(params) {
return request({
url: service + '/list',
method: 'get',
params,
})
}
/**
* 添加敏感词设置
* @param {*} params
*
*/
export function addSettingSensitive(data) {
return request({
url: service,
method: 'post',
data: data
})
}
/**
* 修改敏感词设置
* @param {*} params
*
*/
export function modifySettingSensitive(data) {
return request({
url: service,
method: 'put',
data: data
})
}
/**
* 获取敏感词详情
* @param {*} params
*
*/
export function getSensitiveDetails(tableId) {
return request({
url: service + '/' + tableId,
method: 'get'
})
}
/**
* 删除敏感词
* @param {*} params
*
*/
export function deleteSensitive(tableId) {
return request({
url: service + '/' + tableId,
method: 'delete'
})
}
/**
* 获取敏感行为警告敏感记录列表
* @param {*} params
*
*/
export function getSensitiveRecord(params) {
return request({
url: service + '/act/hit/list',
method: 'get',
params,
})
}
/**
* 获取敏感行为管理列表
* @param {*} params
*
*/
export function getSensitiveManagement(params) {
return request({
url: service + '/act/list',
method: 'get',
params,
})
}
import request from '@/utils/request'
const service = window.CONFIG.services.wecom + '/actual'
/**
* 获取实际群码
* @param {*} params
{
"groupCodeId": "群活码ID",
"pageNum": "当前页",
"pageSize": "每页显示条数",
"state": "状态",
}
*/
export function getList(params) {
return request({
url: service + '/list',
params
})
}
/**
* 添加实际群码
* @param {*} data
{
"groupName": 群名称,
"actualGroupQrCode": 实际群码图片,
"effectTime": 有效期,
"scanCodeTimesLimit": 扫码次数限制,
"chatId": 客户群,
"chatGroupName": 客户群名称
}
*/
export function add(data) {
return request({
url: service + '/',
method: 'post',
data
})
}
/**
* 添加实际群码
* @param {*} data
{
"id": 实际群码ID,
"groupName": 群名称,
"actualGroupQrCode": 实际群码图片,
"effectTime": 有效期,
"scanCodeTimesLimit": 扫码次数限制,
"chatId": 客户群,
"chatGroupName": 客户群名称
}
*/
export function update(data) {
return request({
url: service + '/',
method: 'put',
data
})
}
/**
* 删除实际群码
* @param {*}
* "ids": 实际群活ID,多个ID以逗号分隔
*/
export function remove(ids) {
return request({
url: service + '/' + ids,
method: 'delete',
})
}
import request from '@/utils/request'
const service = window.CONFIG.services.wecom + '/groupCode'
/**
* 获取群活码列表
* @param {*} params
{
"pageNum": "当前页",
"pageSize": "每页显示条数",
"activityName": "活码名",
"createBy": "创建人",
"beginTime": "开始时间",
"endTime": "结束时间"
}
*/
export function getList(params) {
return request({
url: service + '/list',
params
})
}
/**
* 新增群活码
* @param {*} data
{
"file": 活码头像
"activityName": 活码名称
"activityDesc": 活码描述
"guide": 引导语
"joinGroupIsTip": 进群是否提示:1:是;0:否
"tipMsg": 进群提示语
"customerServerQrCode":客服二维码
}
*/
export function add(data) {
return request({
url: service + '/',
method: 'post',
data,
})
}
/**
* 更新群活码
* @param {*} id 群活码ID
* @param {*} data
{
"file": 活码头像
"activityName": 活码名称
"activityDesc": 活码描述
"guide": 引导语
"joinGroupIsTip": 进群是否提示:1:是;0:否
"tipMsg": 进群提示语
"customerServerQrCode":客服二维码
}
*/
export function update(id, data) {
return request({
url: service + '/' + id,
method: 'put',
data,
})
}
/**
* 根据ID获取群活码数据
* @param {*} params
*/
export function getDetail(id) {
return request({
url: service + '/' + id,
})
}
/**
* 删除群活码
* @param {*}
* "ids": 群活码ID,多个ID以逗号分隔
*/
export function remove(ids) {
return request({
url: service + '/' + ids,
method: 'delete',
})
}
/**
* 批量下载群活码
* @param {*}
* "ids": 群活码ID,多个ID以逗号分隔
*/
export function downloadBatch(ids) {
return request({
url: service + '/downloadBatch',
params: {
ids,
},
responseType: 'blob'
})
}
/**
* 下载群活码
* @param {*}
* "id": 群活码ID,多个ID以逗号分隔
*/
export function download(id) {
return request({
url: service + '/download',
params: {
id,
},
responseType: 'blob'
})
}
import request from "@/utils/request"; import request from '@/utils/request'
const service = window.CONFIG.services.wecom + "/customerMessagePush"; const service = window.CONFIG.services.wecom + '/customerMessagePush'
/** /**
* 新增企业id * 新增企业id
...@@ -35,10 +35,10 @@ const service = window.CONFIG.services.wecom + "/customerMessagePush"; ...@@ -35,10 +35,10 @@ const service = window.CONFIG.services.wecom + "/customerMessagePush";
*/ */
export function add(data) { export function add(data) {
return request({ return request({
url: service + "/add", url: service + '/add',
method: "post", method: 'post',
data data,
}); })
} }
/** /**
...@@ -53,9 +53,9 @@ endTime:结束时间} ...@@ -53,9 +53,9 @@ endTime:结束时间}
*/ */
export function getList(params) { export function getList(params) {
return request({ return request({
url: service + "/list", url: service + '/list',
params params,
}); })
} }
/** /**
...@@ -64,9 +64,9 @@ export function getList(params) { ...@@ -64,9 +64,9 @@ export function getList(params) {
*/ */
export function getDetail(messageId) { export function getDetail(messageId) {
return request({ return request({
url: service + "/getInfo", url: service + '/getInfo',
params: { messageId } params: { messageId },
}); })
} }
/** /**
...@@ -77,7 +77,21 @@ status:发送状态 0-未发送 1-已发送 2-因客户不是好友导致发送 ...@@ -77,7 +77,21 @@ status:发送状态 0-未发送 1-已发送 2-因客户不是好友导致发送
*/ */
export function getPushResult(params) { export function getPushResult(params) {
return request({ return request({
url: service + "/pushResults", url: service + '/pushResults',
params params,
}); })
}
/**
* 同步消息发送结果
* @param {*} data
* msgid:列表msgid
messageId:消息id
*/
export function syncMsg(data) {
return request({
url: service + '/asyncResult',
method: 'post',
data,
})
} }
...@@ -25,7 +25,7 @@ export default { ...@@ -25,7 +25,7 @@ export default {
<template> <template>
<div class="preview ac"> <div class="preview ac">
<div class="top">小微</div> <div class="top">小微</div>
<div class="small">微科技-企微</div> <div class="small">微科技-企微</div>
<div class="time">凌晨2:20</div> <div class="time">凌晨2:20</div>
<div class="flex msg-li"> <div class="flex msg-li">
<el-avatar <el-avatar
......
<script>
import { getList } from '@/api/customer/tag'
import list from './list'
export default {
components: { list },
props: {
// 添加标签显隐
visible: {
type: Boolean,
default: false,
},
// title: {
// type: String,
// default: '',
// },
// 素材类型 0:'文本', 1:'图片'
type: {
type: String,
default: '0',
},
// 显示哪些素材类型标签
showArr: {
type: Array,
default: () => [0, 1],
},
},
data() {
return {
text: {},
image: {},
file: {},
}
},
watch: {},
computed: {
Pvisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
},
},
Ptype: {
get() {
return this.type
},
set(val) {
this.$emit('update:type', val)
},
},
},
created() {},
mounted() {},
methods: {
submit() {
this.Pvisible = false
this.$emit('success', this.text, this.image, this.file)
},
changeText(data) {
this.text = data
},
changeImage(data) {
this.image = data
},
},
}
</script>
<template>
<el-dialog title="选择素材" :visible.sync="Pvisible" width="650px">
<div>
<el-tabs v-model="Ptype">
<el-tab-pane name="0" v-if="showArr.includes(0)">
<span slot="label"> <i class="el-icon-date"></i> 文本 </span>
<list type="4" @change="changeText"> </list>
</el-tab-pane>
<el-tab-pane name="1" v-if="showArr.includes(1)">
<span slot="label"> <i class="el-icon-date"></i> 图片 </span>
<list type="0" @change="changeImage"> </list>
</el-tab-pane>
<!-- <el-tab-pane name="2">
<span slot="label"> <i class="el-icon-date"></i> 文件 </span>
<list>
<el-table :data="list" style="width: 100%">
<el-table-column width="50">
<template slot-scope="scope">
<el-radio v-model="radio" :label="scope.row.id"></el-radio>
</template>
</el-table-column>
<el-table-column prop="content"> </el-table-column>
</el-table>
</list>
</el-tab-pane> -->
</el-tabs>
</div>
<div slot="footer">
<el-button @click="Pvisible = false">取 消</el-button>
<el-button type="primary" @click="submit">确 定</el-button>
</div>
</el-dialog>
</template>
<style lang="scss" scoped>
.user-list {
.el-row {
line-height: 26px;
}
}
.mr30 {
margin-right: 30px;
}
</style>
<script>
import { getTree, getList } from '@/api/material'
export default {
components: {},
props: {
// 0: '图片', 1: '语音', 2: '视频', 3: '普通文件', 4: '文本', 5: '海报',
type: {
type: String,
default: '4',
},
multiple: {
type: Boolean,
default: false,
},
selected: {
type: Array,
default: () => [],
},
},
data() {
return {
loading: true, // 遮罩层
// 查询条件
query: {
pageNum: 1,
pageSize: 10,
categoryId: '',
search: '',
mediaType: '4',
},
list: [], // 列表
total: 0, // 总条数
treeData: [], // 树
// 树props
treeProps: {
children: 'children',
label: 'name',
},
// 分组props
groupProps: {
// expandTrigger: 'hover',
checkStrictly: true,
children: 'children',
label: 'name',
value: 'id',
emitPath: false,
},
radio: '',
// 树props
treeProps: {
children: 'children',
label: 'name',
},
selectedx: [],
}
},
watch: {
radio(val) {
this.$emit('change', val)
},
},
computed: {},
created() {
this.query.mediaType = this.type
this.getTree()
this.getList()
},
mounted() {},
methods: {
// 获取类目树
getTree() {
getTree(this.type).then(({ data }) => {
this.treeData = data
})
},
// 获取素材列表
getList(page) {
page && (this.query.pageNum = page)
this.loading = true
getList(this.query)
.then(({ rows, total }) => {
this.list = rows
this.total = +total
this.loading = false
this.$emit('listChange', this.list)
})
.catch(() => {
this.loading = false
})
},
// 节点单击事件
handleNodeClick(data) {
this.query.categoryId = data.id
this.getList(1)
},
// 多选框选中数据
handleSelectionChange(selection) {
this.$emit('update:selected', selection)
},
},
}
</script>
<template>
<div>
<template v-if="false">
<el-form ref="form" :model="query" label-width="80px">
<el-form-item label="选择分组">
<el-cascader
v-model="query.categoryId"
:options="treeData"
:props="groupProps"
></el-cascader>
<el-input
v-model="query.search"
class="ml10 mr10"
style="width: 150px"
@keydown.enter="getList(1)"
></el-input>
<el-button
v-hasPermi="['contacts:organization:query']"
icon="el-icon-search"
circle
@click="getList(1)"
></el-button>
<el-pagination
class="fr"
@current-change="getList"
:current-page="query.pageNum"
:page-size="query.pageSize"
layout="prev, pager, next"
:total="total"
></el-pagination>
</el-form-item>
</el-form>
<!-- 文本 -->
<el-table
v-if="type == 4"
v-loading="loading"
:data="list"
:show-header="false"
>
<el-table-column width="30">
<template slot-scope="scope">
<el-radio v-model="radio" :label="scope.row">'</el-radio>
</template>
</el-table-column>
<el-table-column prop="content"> </el-table-column>
</el-table>
<!-- 图片 -->
<el-radio-group
v-if="type == 0"
v-loading="loading"
class="img-wrap"
v-model="radio"
>
<el-radio v-for="(item, index) in list" :label="item" :key="index">
<img class="img-li" :src="item.materialUrl" alt />
<div class="ac mt5">{{ item.materialName }}</div>
</el-radio>
</el-radio-group>
</template>
<el-row :gutter="10">
<el-col :span="6">
<el-tree
class="bfc-o"
ref="tree"
:data="treeData"
:props="treeProps"
:expand-on-click-node="false"
highlight-current
default-expand-all
@node-click="handleNodeClick"
>
</el-tree>
</el-col>
<el-col :span="18">
<div class="fxbw">
素材库更新本分类素材后,自动同步到聊天工具栏
<el-pagination
class="fr"
@current-change="getList"
:current-page="query.pageNum"
:page-size="query.pageSize"
layout="prev, pager, next"
:total="total"
></el-pagination>
</div>
<el-table
v-if="[1, 3, 4].includes(+type)"
:data="list"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
v-if="type == 4"
prop="content"
label="文本内容"
></el-table-column>
<el-table-column
v-else
prop="materialName"
label="素材名称"
></el-table-column>
<el-table-column prop="createTime" label="时间"></el-table-column>
</el-table>
<el-row v-else :gutter="20">
<el-checkbox-group
v-model="selectedx"
@change="handleSelectionChange"
>
<el-col
:span="6"
style="margin-bottom: 24px; min-width: 220px"
v-for="(item, index) in list"
:key="index"
>
<el-card shadow="hover" body-style="padding: 0px;">
<div class="img-wrap">
<el-image :src="item.materialUrl" fit="contain"></el-image>
</div>
<div style="padding: 14px">
<el-checkbox :label="item">{{
item.materialName
}}</el-checkbox>
</div>
</el-card>
</el-col>
</el-checkbox-group>
</el-row>
</el-col>
</el-row>
</div>
</template>
<style lang="scss" scoped>
// .img-wrap {
// /deep/.el-radio__input {
// position: absolute;
// left: 50%;
// top: 50%;
// transform: translate(-50%, -50%);
// }
// }
.img-li {
width: 160px;
height: 160px;
border-radius: 8px;
border: 1px solid #e6ebf5;
}
.img-wrap {
position: relative;
height: 0;
padding: 70% 0 0 0;
border-bottom: 1px solid #e6ebf5;
.el-image {
position: absolute;
width: 100%;
height: 100%;
top: 0;
}
}
</style>
...@@ -30,9 +30,9 @@ export default { ...@@ -30,9 +30,9 @@ export default {
loading: false, loading: false,
action: action:
process.env.VUE_APP_BASE_API + process.env.VUE_APP_BASE_API +
window.CONFIG.services.wecom + '/common/uploadFile2Cos',
'/material/upload',
headers: window.CONFIG.headers, headers: window.CONFIG.headers,
domain: process.env.VUE_APP_BASE_API
} }
}, },
watch: {}, watch: {},
...@@ -101,8 +101,10 @@ export default { ...@@ -101,8 +101,10 @@ export default {
onSuccess(res, file) { onSuccess(res, file) {
if (res.code === 200) { if (res.code === 200) {
this.loading = false this.loading = false
this.$emit('update:fileUrl', res.data.materialUrl) // this.$emit('update:fileUrl', res.data.materialUrl)
this.$emit('update:fileName', res.data.materialName) // this.$emit('update:fileName', res.data.materialName)
this.$emit('update:fileUrl', res.url)
this.$emit('update:fileName', res.fileName)
// this.fileUrl = URL.createObjectURL(file.raw) // this.fileUrl = URL.createObjectURL(file.raw)
} }
}, },
......
...@@ -31,6 +31,7 @@ window.CONFIG = { ...@@ -31,6 +31,7 @@ window.CONFIG = {
services: { services: {
wecom: '/wecom', wecom: '/wecom',
common: '/common',
}, },
get headers() { get headers() {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
<div class="right-menu"> <div class="right-menu">
<template v-if="device!=='mobile'"> <template v-if="device !== 'mobile'">
<search id="header-search" class="right-menu-item" /> <search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom"> <el-tooltip content="源码地址" effect="dark" placement="bottom">
...@@ -28,9 +28,12 @@ ...@@ -28,9 +28,12 @@
<screenfull id="screenfull" class="right-menu-item hover-effect" /> <screenfull id="screenfull" class="right-menu-item hover-effect" />
</template> </template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> <el-dropdown
class="avatar-container right-menu-item hover-effect"
trigger="click"
>
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<!-- <img :src="avatar" class="user-avatar"> --> <!-- <img :src="avatar" class="user-avatar"> -->
<i class="el-icon-caret-bottom" /> <i class="el-icon-caret-bottom" />
</div> </div>
...@@ -51,11 +54,11 @@ ...@@ -51,11 +54,11 @@
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from 'vuex'
import Breadcrumb from "@/components/Breadcrumb"; import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from "@/components/Hamburger"; import Hamburger from '@/components/Hamburger'
import Search from "@/components/HeaderSearch"; import Search from '@/components/HeaderSearch'
import screenfull from "@/components/Screenfull"; import screenfull from '@/components/Screenfull'
export default { export default {
components: { components: {
...@@ -65,43 +68,43 @@ export default { ...@@ -65,43 +68,43 @@ export default {
screenfull, screenfull,
}, },
computed: { computed: {
...mapGetters(["sidebar", "avatar", "device"]), ...mapGetters(['sidebar', 'avatar', 'device']),
setting: { setting: {
get() { get() {
return this.$store.state.settings.showSettings; return this.$store.state.settings.showSettings
}, },
set(val) { set(val) {
this.$store.dispatch("settings/changeSetting", { this.$store.dispatch('settings/changeSetting', {
key: "showSettings", key: 'showSettings',
value: val, value: val,
}); })
}, },
}, },
}, },
methods: { methods: {
toggleSideBar() { toggleSideBar() {
this.$store.dispatch("app/toggleSideBar"); this.$store.dispatch('app/toggleSideBar')
}, },
async logout() { async logout() {
this.$confirm("确定注销并退出系统吗?", "提示", { this.$confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning',
}).then(() => { }).then(() => {
this.$store.dispatch("LogOut").then(() => { this.$store.dispatch('LogOut').then(() => {
location.href = "/"; location.href = '/'
}); })
}); })
}, },
goto(type) { goto(type) {
window.open( window.open(
type type
? "https://gitee.com/LinkWeChat/link-wechat" ? 'https://gitee.com/LinkWeChat/link-wechat'
: "https://gitee.com/LinkWeChat/link-wechat" : 'https://gitee.com/LinkWeChat/link-wechat'
); )
}, },
}, },
}; }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<script> <script>
import { getList, update, getMaterial } from '@/api/appTool/chatBar'
import SelectMaterialMult from '@/components/SelectMaterialMult/list'
export default { export default {
components: {}, components: { SelectMaterialMult },
props: {}, props: {},
data() { data() {
return { return {
dialogVisible: false, dialogVisible: false,
list: [ loading: false,
{ type: "文本类型", name: "企业资料", number: 105, isStart: 1 }, list: [],
{ type: "图片类型", name: "图片类型", number: 86, isStart: 1 }, mediaType: Object.freeze({
{ type: "网页类型", name: "网页类型", number: 55, isStart: 1 }, 0: '图片',
{ type: "文件类型", name: "文件类型", number: 667, isStart: 1 }, 1: '语音',
{ type: "视频类型", name: "视频类型", number: 29, isStart: 1 } 2: '视频',
] 3: '普通文件',
}; 4: '文本',
5: '海报',
}),
metarialParams: {
sideId: '',
materialIds: [], // '素材id列表',
mediaType: '', // '素材类型 0 图片(image)、1 语音(voice)、2 视频(video),3 普通文件(file) 4 文本 5 海报',
checkAll: '1', // '是否全选 0 全选 1 非全选',
},
selectedMaterial: [],
}
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() {}, created() {
this.getList()
},
mounted() {}, mounted() {},
methods: {} methods: {
}; getList() {
this.loading = true
getList()
.then(({ rows, total }) => {
this.list = rows
this.loading = false
})
.catch(() => {
this.loading = false
})
},
openDialog(data) {
this.dialogVisible = true
this.metarialParams.sideId = data.sideId
this.metarialParams.mediaType = data.mediaType
},
// 抓取素材
getMaterial() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
})
this.metarialParams.materialIds = this.selectedMaterial.map((d) => d.id)
if (this.metarialParams.checkAll == 0) {
this.metarialParams.materialIds = []
}
getMaterial(this.metarialParams)
.then(({ rows, total }) => {
// this.list = rows
loading.close()
this.msgSuccess('操作成功')
this.dialogVisible = false
this.getList()
})
.catch(() => {
loading.close()
})
},
update(data) {
// this.loading = true
update(data)
.then(() => {
this.msgSuccess('操作成功')
this.$set(data, 'isEdit', false)
this.loading = false
})
.catch(() => {
this.loading = false
})
},
},
}
</script> </script>
<template> <template>
<div> <div>
...@@ -36,36 +105,57 @@ export default { ...@@ -36,36 +105,57 @@ export default {
<div slot="header"> <div slot="header">
<span>抓取快捷回复素材</span> 素材抓取后,即可在聊天工具栏使用 <span>抓取快捷回复素材</span> 素材抓取后,即可在聊天工具栏使用
</div> </div>
<el-table <el-table v-loading="loading" :data="list">
v-loading="loading" <el-table-column label="素材类型" align="center" prop="mediaType">
:data="list" <template slot-scope="scope">
@selection-change="handleSelectionChange" {{ mediaType[scope.row.mediaType] }}
> </template>
<el-table-column type="selection" width="55" align="center" /> </el-table-column>
<el-table-column label="素材类型" align="center" prop="type" /> <el-table-column label="聊天工具栏名称" align="center" prop="sideName">
<el-table-column label="聊天工具栏名称" align="center" prop="name" /> <template slot-scope="{ row }">
<el-table-column label="已抓取素材数量" align="center" prop="number" /> <el-input
class="bfc-d"
style="width: 100px;"
v-if="row.isEdit"
v-model="row.sideName"
placeholder="请输入"
></el-input>
<span v-else>
{{ row.sideName }}
</span>
<i
v-if="!row.isEdit"
class="row-icon el-icon-edit"
@click="$set(row, 'isEdit', true)"
></i>
<i
v-else
class="row-icon el-icon-circle-check"
@click="update(row)"
></i>
</template>
</el-table-column>
<el-table-column label="已抓取素材数量" align="center" prop="total" />
<el-table-column <el-table-column
label="是否启用" label="是否启用"
align="center" align="center"
prop="isStart" prop="using"
width="180" width="180"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch
v-model="scope.row.isStart" v-model="scope.row.using"
:active-value="1" :active-value="0"
:inactive-value="0" :inactive-value="1"
inactive-color="#ff4949" inactive-color="#ddd"
@change="update(scope.row)"
></el-switch> ></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" prop="operId"> <el-table-column label="操作" align="center" prop="operId">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button type="text" @click="openDialog(scope.row)"
size="mini"
type="text"
@click="handleView(scope.row, scope.index)"
>抓取素材</el-button >抓取素材</el-button
> >
</template> </template>
...@@ -73,8 +163,7 @@ export default { ...@@ -73,8 +163,7 @@ export default {
</el-table> </el-table>
</el-card> </el-card>
<el-card class="mt20" shadow="never" header="红包工具栏"> <!-- <el-card class="mt20" shadow="never" header="红包工具栏">
<!-- <div slot="header"></div> -->
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="10"> <el-col :span="10">
<div> <div>
...@@ -120,52 +209,26 @@ export default { ...@@ -120,52 +209,26 @@ export default {
> >
<div class="el-image logo" style> <div class="el-image logo" style>
<div class="el-image__error">加载失败</div> <div class="el-image__error">加载失败</div>
<!---->
</div> </div>
<el-image class="logo" :src="url" :fit="fit"></el-image> <el-image class="logo" :src="url" fit="fit"></el-image>
<div class="company-name">脑白金</div> <div class="company-name">脑白金</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
</el-card> </el-card> -->
<el-dialog <el-dialog
title="抓取文本类型素材库" :title="`抓取${mediaType[metarialParams.mediaType]}类型素材库`"
:visible.sync="dialogVisible" :visible.sync="dialogVisible"
:before-close="dialogBeforeClose"
> >
<el-row :gutter="10"> <SelectMaterialMult
<el-col :span="6"> :selected.sync="selectedMaterial"
<el-tree :data="d" :props="d" @node-click="d"></el-tree> :type="metarialParams.mediaType"
</el-col> :key="metarialParams.mediaType"
<el-col :span="18"> ></SelectMaterialMult>
<div class="fxbw">
素材库更新本分类素材后,自动同步到聊天工具栏
<div class="filter-right">
<i class="el-icon-arrow-left"></i> 1/1
<i class="el-icon-arrow-right"></i>
</div>
</div>
<el-table :data="data" style="width: 100%">
<el-table-column type="selection" width="55" align="center" />
<el-table-column
prop="prop"
label="文本内容"
width="width"
></el-table-column>
<el-table-column
prop="prop"
label="时间"
width="width"
></el-table-column>
</el-table>
</el-col>
</el-row>
<div slot="footer"> <div slot="footer">
<el-button @click="dialogVisible = false">取 消</el-button> <el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false" <el-button type="primary" @click="getMaterial">确 定</el-button>
>确 定</el-button
>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
...@@ -200,4 +263,22 @@ export default { ...@@ -200,4 +263,22 @@ export default {
width: 100%; width: 100%;
} }
} }
.el-table__row {
.el-icon-edit {
visibility: hidden;
}
&:hover {
.el-icon-edit {
visibility: visible;
}
}
}
.row-icon {
font-size: 14px;
// vertical-align: middle;
margin-left: 5px;
}
.el-icon-circle-check {
margin-top: 10px;
}
</style> </style>
<script> <script>
import * as api from "@/api/customer"; import * as api from '@/api/customer'
// import clipboard from "clipboard"; // import clipboard from "clipboard";
export default { export default {
...@@ -10,7 +10,7 @@ export default { ...@@ -10,7 +10,7 @@ export default {
query: { query: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: "" name: '',
}, },
dateRange: [], // 添加日期 dateRange: [], // 添加日期
total: 0, total: 0,
...@@ -20,18 +20,18 @@ export default { ...@@ -20,18 +20,18 @@ export default {
disabled: false, disabled: false,
loading: false, loading: false,
rules: Object.freeze({ rules: Object.freeze({
name: [{ required: true, message: "必填项", trigger: "blur" }], name: [{ required: true, message: '必填项', trigger: 'blur' }],
corpId: [{ required: true, message: "必填项", trigger: "blur" }], corpId: [{ required: true, message: '必填项', trigger: 'blur' }],
corpSecret: [{ required: true, message: "必填项", trigger: "blur" }], corpSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
contactSecret: [{ required: true, message: "必填项", trigger: "blur" }] contactSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
}), }),
status: ["正常", "停用"] status: ['正常', '停用'],
}; }
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList()
}, },
mounted() { mounted() {
// new clipboard(".copy-btn"); // new clipboard(".copy-btn");
...@@ -39,53 +39,53 @@ export default { ...@@ -39,53 +39,53 @@ export default {
methods: { methods: {
getList(page) { getList(page) {
if (this.dateRange[0]) { if (this.dateRange[0]) {
this.query.beginTime = this.dateRange[0]; this.query.beginTime = this.dateRange[0]
this.query.endTime = this.dateRange[1]; this.query.endTime = this.dateRange[1]
} else { } else {
this.query.beginTime = ""; this.query.beginTime = ''
this.query.endTime = ""; this.query.endTime = ''
} }
page && (this.query.pageNum = page); page && (this.query.pageNum = page)
this.loading = true; this.loading = true
api api
.getList(this.query) .getList(this.query)
.then(({ rows, total }) => { .then(({ rows, total }) => {
this.list = rows; this.list = rows
this.total = +total; this.total = +total
this.loading = false; this.loading = false
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false
}); })
}, },
edit(data, type) { edit(data, type) {
this.form = Object.assign({}, data || {}); this.form = Object.assign({}, data || {})
this.dialogVisible = true; this.dialogVisible = true
type || !data ? (this.disabled = false) : (this.disabled = true); type || !data ? (this.disabled = false) : (this.disabled = true)
}, },
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
api[this.form.id ? "update" : "add"](this.form) api[this.form.id ? 'update' : 'add'](this.form)
.then(() => { .then(() => {
this.msgSuccess("操作成功"); this.msgSuccess('操作成功')
this.dialogVisible = false; this.dialogVisible = false
this.getList(!this.form.id && 1); this.getList(!this.form.id && 1)
}) })
.catch(() => { .catch(() => {
this.dialogVisible = false; this.dialogVisible = false
}); })
} }
}); })
}, },
goRoute(id, path) { goRoute(id, path) {
this.$router.push({ this.$router.push({
path: "/appTool/groupFissionAev", path: '/appTool/groupFissionAev',
query: { id } query: { id },
}); })
} },
} },
}; }
</script> </script>
<template> <template>
...@@ -222,7 +222,7 @@ export default { ...@@ -222,7 +222,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item label="外部联系人管理secret" prop="contactSecret"> <el-form-item label="外部联系人管理secret" prop="contactSecret">
<el-input v-model="form.contactSecret"></el-input> <el-input v-model="form.contactSecret"></el-input>
...@@ -232,7 +232,7 @@ export default { ...@@ -232,7 +232,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item <el-form-item
label="企业微信扫码登陆回调地址" label="企业微信扫码登陆回调地址"
......
<script> <script>
import * as api from "@/api/customer"; import * as api from '@/api/customer'
// import clipboard from "clipboard"; // import clipboard from "clipboard";
export default { export default {
...@@ -10,7 +10,7 @@ export default { ...@@ -10,7 +10,7 @@ export default {
query: { query: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: "" name: '',
}, },
dateRange: [], // 添加日期 dateRange: [], // 添加日期
total: 0, total: 0,
...@@ -20,18 +20,18 @@ export default { ...@@ -20,18 +20,18 @@ export default {
disabled: false, disabled: false,
loading: false, loading: false,
rules: Object.freeze({ rules: Object.freeze({
name: [{ required: true, message: "必填项", trigger: "blur" }], name: [{ required: true, message: '必填项', trigger: 'blur' }],
corpId: [{ required: true, message: "必填项", trigger: "blur" }], corpId: [{ required: true, message: '必填项', trigger: 'blur' }],
corpSecret: [{ required: true, message: "必填项", trigger: "blur" }], corpSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
contactSecret: [{ required: true, message: "必填项", trigger: "blur" }] contactSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
}), }),
status: ["正常", "停用"] status: ['正常', '停用'],
}; }
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList()
}, },
mounted() { mounted() {
// new clipboard(".copy-btn"); // new clipboard(".copy-btn");
...@@ -39,53 +39,53 @@ export default { ...@@ -39,53 +39,53 @@ export default {
methods: { methods: {
getList(page) { getList(page) {
if (this.dateRange[0]) { if (this.dateRange[0]) {
this.query.beginTime = this.dateRange[0]; this.query.beginTime = this.dateRange[0]
this.query.endTime = this.dateRange[1]; this.query.endTime = this.dateRange[1]
} else { } else {
this.query.beginTime = ""; this.query.beginTime = ''
this.query.endTime = ""; this.query.endTime = ''
} }
page && (this.query.pageNum = page); page && (this.query.pageNum = page)
this.loading = true; this.loading = true
api api
.getList(this.query) .getList(this.query)
.then(({ rows, total }) => { .then(({ rows, total }) => {
this.list = rows; this.list = rows
this.total = +total; this.total = +total
this.loading = false; this.loading = false
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false
}); })
}, },
edit(data, type) { edit(data, type) {
this.form = Object.assign({}, data || {}); this.form = Object.assign({}, data || {})
this.dialogVisible = true; this.dialogVisible = true
type || !data ? (this.disabled = false) : (this.disabled = true); type || !data ? (this.disabled = false) : (this.disabled = true)
}, },
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
api[this.form.id ? "update" : "add"](this.form) api[this.form.id ? 'update' : 'add'](this.form)
.then(() => { .then(() => {
this.msgSuccess("操作成功"); this.msgSuccess('操作成功')
this.dialogVisible = false; this.dialogVisible = false
this.getList(!this.form.id && 1); this.getList(!this.form.id && 1)
}) })
.catch(() => { .catch(() => {
this.dialogVisible = false; this.dialogVisible = false
}); })
} }
}); })
}, },
goRoute(id, path) { goRoute(id, path) {
this.$router.push({ this.$router.push({
path: "/appTool/taskAev", path: '/appTool/taskAev',
query: { id } query: { id },
}); })
} },
} },
}; }
</script> </script>
<template> <template>
...@@ -222,7 +222,7 @@ export default { ...@@ -222,7 +222,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item label="外部联系人管理secret" prop="contactSecret"> <el-form-item label="外部联系人管理secret" prop="contactSecret">
<el-input v-model="form.contactSecret"></el-input> <el-input v-model="form.contactSecret"></el-input>
...@@ -232,7 +232,7 @@ export default { ...@@ -232,7 +232,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item <el-form-item
label="企业微信扫码登陆回调地址" label="企业微信扫码登陆回调地址"
......
<script> <script>
import * as api from "@/api/customer"; import * as api from '@/api/customer'
export default { export default {
components: {}, components: {},
...@@ -9,7 +9,7 @@ export default { ...@@ -9,7 +9,7 @@ export default {
query: { query: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: "" name: '',
}, },
dateRange: [], // 添加日期 dateRange: [], // 添加日期
total: 0, total: 0,
...@@ -19,22 +19,22 @@ export default { ...@@ -19,22 +19,22 @@ export default {
disabled: false, disabled: false,
loading: false, loading: false,
rules: Object.freeze({ rules: Object.freeze({
name: [{ required: true, message: "必填项", trigger: "blur" }], name: [{ required: true, message: '必填项', trigger: 'blur' }],
corpId: [{ required: true, message: "必填项", trigger: "blur" }], corpId: [{ required: true, message: '必填项', trigger: 'blur' }],
corpSecret: [{ required: true, message: "必填项", trigger: "blur" }], corpSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
contactSecret: [{ required: true, message: "必填项", trigger: "blur" }] contactSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
}), }),
status: ["正常", "停用"], status: ['正常', '停用'],
pushType: { pushType: {
0: "发给客户", 0: '发给客户',
1: "发给客户群" 1: '发给客户群',
} },
}; }
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList()
}, },
mounted() { mounted() {
// new clipboard(".copy-btn"); // new clipboard(".copy-btn");
...@@ -42,53 +42,53 @@ export default { ...@@ -42,53 +42,53 @@ export default {
methods: { methods: {
getList(page) { getList(page) {
if (this.dateRange[0]) { if (this.dateRange[0]) {
this.query.beginTime = this.dateRange[0]; this.query.beginTime = this.dateRange[0]
this.query.endTime = this.dateRange[1]; this.query.endTime = this.dateRange[1]
} else { } else {
this.query.beginTime = ""; this.query.beginTime = ''
this.query.endTime = ""; this.query.endTime = ''
} }
page && (this.query.pageNum = page); page && (this.query.pageNum = page)
this.loading = true; this.loading = true
api api
.getList(this.query) .getList(this.query)
.then(({ rows, total }) => { .then(({ rows, total }) => {
this.list = rows; this.list = rows
this.total = +total; this.total = +total
this.loading = false; this.loading = false
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false
}); })
}, },
edit(data, type) { edit(data, type) {
this.form = Object.assign({}, data || {}); this.form = Object.assign({}, data || {})
this.dialogVisible = true; this.dialogVisible = true
type || !data ? (this.disabled = false) : (this.disabled = true); type || !data ? (this.disabled = false) : (this.disabled = true)
}, },
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
api[this.form.id ? "update" : "add"](this.form) api[this.form.id ? 'update' : 'add'](this.form)
.then(() => { .then(() => {
this.msgSuccess("操作成功"); this.msgSuccess('操作成功')
this.dialogVisible = false; this.dialogVisible = false
this.getList(!this.form.id && 1); this.getList(!this.form.id && 1)
}) })
.catch(() => { .catch(() => {
this.dialogVisible = false; this.dialogVisible = false
}); })
} }
}); })
}, },
goRoute(id, path) { goRoute(id, path) {
this.$router.push({ this.$router.push({
path: "/communityOperating/groupSOPAev", path: '/communityOperating/groupSOPAev',
query: { id } query: { id },
}); })
} },
} },
}; }
</script> </script>
<template> <template>
...@@ -207,7 +207,7 @@ export default { ...@@ -207,7 +207,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item label="外部联系人管理secret" prop="contactSecret"> <el-form-item label="外部联系人管理secret" prop="contactSecret">
<el-input v-model="form.contactSecret"></el-input> <el-input v-model="form.contactSecret"></el-input>
...@@ -217,7 +217,7 @@ export default { ...@@ -217,7 +217,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item <el-form-item
label="企业微信扫码登陆回调地址" label="企业微信扫码登陆回调地址"
......
<script> <script>
import * as api from "@/api/customer"; import * as api from '@/api/customer'
export default { export default {
components: {}, components: {},
...@@ -9,7 +9,7 @@ export default { ...@@ -9,7 +9,7 @@ export default {
query: { query: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: "" name: '',
}, },
dateRange: [], // 添加日期 dateRange: [], // 添加日期
total: 0, total: 0,
...@@ -19,22 +19,22 @@ export default { ...@@ -19,22 +19,22 @@ export default {
disabled: false, disabled: false,
loading: false, loading: false,
rules: Object.freeze({ rules: Object.freeze({
name: [{ required: true, message: "必填项", trigger: "blur" }], name: [{ required: true, message: '必填项', trigger: 'blur' }],
corpId: [{ required: true, message: "必填项", trigger: "blur" }], corpId: [{ required: true, message: '必填项', trigger: 'blur' }],
corpSecret: [{ required: true, message: "必填项", trigger: "blur" }], corpSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
contactSecret: [{ required: true, message: "必填项", trigger: "blur" }] contactSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
}), }),
status: ["正常", "停用"], status: ['正常', '停用'],
pushType: { pushType: {
0: "发给客户", 0: '发给客户',
1: "发给客户群" 1: '发给客户群',
} },
}; }
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList()
}, },
mounted() { mounted() {
// new clipboard(".copy-btn"); // new clipboard(".copy-btn");
...@@ -42,53 +42,53 @@ export default { ...@@ -42,53 +42,53 @@ export default {
methods: { methods: {
getList(page) { getList(page) {
if (this.dateRange[0]) { if (this.dateRange[0]) {
this.query.beginTime = this.dateRange[0]; this.query.beginTime = this.dateRange[0]
this.query.endTime = this.dateRange[1]; this.query.endTime = this.dateRange[1]
} else { } else {
this.query.beginTime = ""; this.query.beginTime = ''
this.query.endTime = ""; this.query.endTime = ''
} }
page && (this.query.pageNum = page); page && (this.query.pageNum = page)
this.loading = true; this.loading = true
api api
.getList(this.query) .getList(this.query)
.then(({ rows, total }) => { .then(({ rows, total }) => {
this.list = rows; this.list = rows
this.total = +total; this.total = +total
this.loading = false; this.loading = false
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false
}); })
}, },
edit(data, type) { edit(data, type) {
this.form = Object.assign({}, data || {}); this.form = Object.assign({}, data || {})
this.dialogVisible = true; this.dialogVisible = true
type || !data ? (this.disabled = false) : (this.disabled = true); type || !data ? (this.disabled = false) : (this.disabled = true)
}, },
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
api[this.form.id ? "update" : "add"](this.form) api[this.form.id ? 'update' : 'add'](this.form)
.then(() => { .then(() => {
this.msgSuccess("操作成功"); this.msgSuccess('操作成功')
this.dialogVisible = false; this.dialogVisible = false
this.getList(!this.form.id && 1); this.getList(!this.form.id && 1)
}) })
.catch(() => { .catch(() => {
this.dialogVisible = false; this.dialogVisible = false
}); })
} }
}); })
}, },
goRoute(id, path) { goRoute(id, path) {
this.$router.push({ this.$router.push({
path: "/communityOperating/keywordsAev", path: '/communityOperating/keywordsAev',
query: { id } query: { id },
}); })
} },
} },
}; }
</script> </script>
<template> <template>
...@@ -219,7 +219,7 @@ export default { ...@@ -219,7 +219,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item label="外部联系人管理secret" prop="contactSecret"> <el-form-item label="外部联系人管理secret" prop="contactSecret">
<el-input v-model="form.contactSecret"></el-input> <el-input v-model="form.contactSecret"></el-input>
...@@ -229,7 +229,7 @@ export default { ...@@ -229,7 +229,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item <el-form-item
label="企业微信扫码登陆回调地址" label="企业微信扫码登陆回调地址"
......
<script> <script>
import * as api from "@/api/customer"; import * as api from '@/api/customer'
export default { export default {
components: {}, components: {},
...@@ -9,7 +9,7 @@ export default { ...@@ -9,7 +9,7 @@ export default {
query: { query: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: "" name: '',
}, },
dateRange: [], // 添加日期 dateRange: [], // 添加日期
total: 0, total: 0,
...@@ -19,22 +19,22 @@ export default { ...@@ -19,22 +19,22 @@ export default {
disabled: false, disabled: false,
loading: false, loading: false,
rules: Object.freeze({ rules: Object.freeze({
name: [{ required: true, message: "必填项", trigger: "blur" }], name: [{ required: true, message: '必填项', trigger: 'blur' }],
corpId: [{ required: true, message: "必填项", trigger: "blur" }], corpId: [{ required: true, message: '必填项', trigger: 'blur' }],
corpSecret: [{ required: true, message: "必填项", trigger: "blur" }], corpSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
contactSecret: [{ required: true, message: "必填项", trigger: "blur" }] contactSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
}), }),
status: ["正常", "停用"], status: ['正常', '停用'],
pushType: { pushType: {
0: "发给客户", 0: '发给客户',
1: "发给客户群" 1: '发给客户群',
} },
}; }
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList()
}, },
mounted() { mounted() {
// new clipboard(".copy-btn"); // new clipboard(".copy-btn");
...@@ -42,53 +42,53 @@ export default { ...@@ -42,53 +42,53 @@ export default {
methods: { methods: {
getList(page) { getList(page) {
if (this.dateRange[0]) { if (this.dateRange[0]) {
this.query.beginTime = this.dateRange[0]; this.query.beginTime = this.dateRange[0]
this.query.endTime = this.dateRange[1]; this.query.endTime = this.dateRange[1]
} else { } else {
this.query.beginTime = ""; this.query.beginTime = ''
this.query.endTime = ""; this.query.endTime = ''
} }
page && (this.query.pageNum = page); page && (this.query.pageNum = page)
this.loading = true; this.loading = true
api api
.getList(this.query) .getList(this.query)
.then(({ rows, total }) => { .then(({ rows, total }) => {
this.list = rows; this.list = rows
this.total = +total; this.total = +total
this.loading = false; this.loading = false
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false
}); })
}, },
edit(data, type) { edit(data, type) {
this.form = Object.assign({}, data || {}); this.form = Object.assign({}, data || {})
this.dialogVisible = true; this.dialogVisible = true
type || !data ? (this.disabled = false) : (this.disabled = true); type || !data ? (this.disabled = false) : (this.disabled = true)
}, },
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
api[this.form.id ? "update" : "add"](this.form) api[this.form.id ? 'update' : 'add'](this.form)
.then(() => { .then(() => {
this.msgSuccess("操作成功"); this.msgSuccess('操作成功')
this.dialogVisible = false; this.dialogVisible = false
this.getList(!this.form.id && 1); this.getList(!this.form.id && 1)
}) })
.catch(() => { .catch(() => {
this.dialogVisible = false; this.dialogVisible = false
}); })
} }
}); })
}, },
goRoute(id, path) { goRoute(id, path) {
this.$router.push({ this.$router.push({
path: "/communityOperating/newCustomerAev", path: '/communityOperating/newCustomerAev',
query: { id } query: { id },
}); })
} },
} },
}; }
</script> </script>
<template> <template>
...@@ -231,7 +231,7 @@ export default { ...@@ -231,7 +231,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item label="外部联系人管理secret" prop="contactSecret"> <el-form-item label="外部联系人管理secret" prop="contactSecret">
<el-input v-model="form.contactSecret"></el-input> <el-input v-model="form.contactSecret"></el-input>
...@@ -241,7 +241,7 @@ export default { ...@@ -241,7 +241,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item <el-form-item
label="企业微信扫码登陆回调地址" label="企业微信扫码登陆回调地址"
......
<script> <script>
import * as api from "@/api/customer"; import * as api from '@/api/customer'
// import clipboard from "clipboard"; // import clipboard from "clipboard";
export default { export default {
...@@ -10,7 +10,7 @@ export default { ...@@ -10,7 +10,7 @@ export default {
query: { query: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: "" name: '',
}, },
dateRange: [], // 添加日期 dateRange: [], // 添加日期
total: 0, total: 0,
...@@ -20,18 +20,18 @@ export default { ...@@ -20,18 +20,18 @@ export default {
disabled: false, disabled: false,
loading: false, loading: false,
rules: Object.freeze({ rules: Object.freeze({
name: [{ required: true, message: "必填项", trigger: "blur" }], name: [{ required: true, message: '必填项', trigger: 'blur' }],
corpId: [{ required: true, message: "必填项", trigger: "blur" }], corpId: [{ required: true, message: '必填项', trigger: 'blur' }],
corpSecret: [{ required: true, message: "必填项", trigger: "blur" }], corpSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
contactSecret: [{ required: true, message: "必填项", trigger: "blur" }] contactSecret: [{ required: true, message: '必填项', trigger: 'blur' }],
}), }),
status: ["正常", "停用"] status: ['正常', '停用'],
}; }
}, },
watch: {}, watch: {},
computed: {}, computed: {},
created() { created() {
this.getList(); this.getList()
}, },
mounted() { mounted() {
// new clipboard(".copy-btn"); // new clipboard(".copy-btn");
...@@ -39,53 +39,53 @@ export default { ...@@ -39,53 +39,53 @@ export default {
methods: { methods: {
getList(page) { getList(page) {
if (this.dateRange[0]) { if (this.dateRange[0]) {
this.query.beginTime = this.dateRange[0]; this.query.beginTime = this.dateRange[0]
this.query.endTime = this.dateRange[1]; this.query.endTime = this.dateRange[1]
} else { } else {
this.query.beginTime = ""; this.query.beginTime = ''
this.query.endTime = ""; this.query.endTime = ''
} }
page && (this.query.pageNum = page); page && (this.query.pageNum = page)
this.loading = true; this.loading = true
api api
.getList(this.query) .getList(this.query)
.then(({ rows, total }) => { .then(({ rows, total }) => {
this.list = rows; this.list = rows
this.total = +total; this.total = +total
this.loading = false; this.loading = false
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false
}); })
}, },
edit(data, type) { edit(data, type) {
this.form = Object.assign({}, data || {}); this.form = Object.assign({}, data || {})
this.dialogVisible = true; this.dialogVisible = true
type || !data ? (this.disabled = false) : (this.disabled = true); type || !data ? (this.disabled = false) : (this.disabled = true)
}, },
submit() { submit() {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
api[this.form.id ? "update" : "add"](this.form) api[this.form.id ? 'update' : 'add'](this.form)
.then(() => { .then(() => {
this.msgSuccess("操作成功"); this.msgSuccess('操作成功')
this.dialogVisible = false; this.dialogVisible = false
this.getList(!this.form.id && 1); this.getList(!this.form.id && 1)
}) })
.catch(() => { .catch(() => {
this.dialogVisible = false; this.dialogVisible = false
}); })
} }
}); })
}, },
goRoute(id, path) { goRoute(id, path) {
this.$router.push({ this.$router.push({
path: "/communityOperating/oldCustomerAev", path: '/communityOperating/oldCustomerAev',
query: { id } query: { id },
}); })
} },
} },
}; }
</script> </script>
<template> <template>
...@@ -222,7 +222,7 @@ export default { ...@@ -222,7 +222,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将成员、部门的增删改以及成员的标签变更实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item label="外部联系人管理secret" prop="contactSecret"> <el-form-item label="外部联系人管理secret" prop="contactSecret">
<el-input v-model="form.contactSecret"></el-input> <el-input v-model="form.contactSecret"></el-input>
...@@ -232,7 +232,7 @@ export default { ...@@ -232,7 +232,7 @@ export default {
<el-radio label="label">开启</el-radio> <el-radio label="label">开启</el-radio>
<el-radio label="label">不开启</el-radio> <el-radio label="label">不开启</el-radio>
</el-radio-group> </el-radio-group>
<div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div> <div>开启后,可以将企业客户的添加、编辑以及主动删除客户和被动被客户删除实时的同步到微SCRM,无需手动更新同步。</div>
</el-form-item>--> </el-form-item>-->
<el-form-item <el-form-item
label="企业微信扫码登陆回调地址" label="企业微信扫码登陆回调地址"
......
...@@ -8,14 +8,13 @@ ...@@ -8,14 +8,13 @@
{{item.text.content}} {{item.text.content}}
</div> </div>
<div v-else-if="item.msgtype=='image'" class="msgtypeimg"> <div v-else-if="item.msgtype=='image'" class="msgtypeimg">
<img :src="item.image.attachment"> <img src="http://146.56.222.200/api/profile/upload/2021/01/14/544c8259-b3b6-4a49-8a53-b5eeac476384.png">
</div> </div>
<div v-else-if="item.msgtype=='file'" class="msgtypefile" @click="down(item.file)"> <div v-else-if="item.msgtype=='file'" class="msgtypefile" @click="down(item.file)">
{{item.file.filename}} {{item.file.filename}}
</div> </div>
<!-- <div v-else-if="item.msgtype=='link'&&item.text" class="msgtypelink">
{{item.text.content}}
</div>-->
<div v-else-if="item.msgtype=='voice'" class="msgtypevoice"> <div v-else-if="item.msgtype=='voice'" class="msgtypevoice">
<i class="el-icon-video-play" @click="play(item,'voice')"></i> <i class="el-icon-video-play" @click="play(item,'voice')"></i>
</div> </div>
...@@ -124,8 +123,10 @@ ...@@ -124,8 +123,10 @@
width: 100px; width: 100px;
height: 80px; height: 80px;
margin: 10px; margin: 10px;
img{width: 100px;
height: 80px;}
} }
.msgtypecard { .msgtypecard {
width: 300px; width: 300px;
height: 140px; height: 140px;
......
<template>
<div class="list" v-loading="loading">
<div v-if="personList.length>=1">
<ul>
<li v-for="(item,index) in personList" :key="index" @click="liClick(item)">
<el-row style="padding:10px">
<el-col :span="3"><img :src="item.receiveWeUser.avatarMediaid" ></el-col>
<el-col :span="21">
<p>{{item.receiveWeUser.name}} <span class="fr gray">{{parseTime(item.finalChatContext.msgtime)}}</span></p>
<p class="gray padt10" v-if="item.finalChatContext.text">{{item.finalChatContext.text.content}}</p>
</el-col>
</el-row>
</li>
</ul>
</div>
<div v-else></div>
</div>
</template>
<script>
import {parseTime} from '@/utils/common.js'
export default {
props: {
personList: {
type: Array,
defluat: () => []
},
loading: {
type: Boolean,
defluat: false
},
},
data() {
return{
loadings:true
}
},
methods:{
liClick(e){
this.$emit('chatFn',e)
}
}
}
</script>
<style lang="scss" scoped>
*{ padding: 0;
margin: 0;}
.list {
overflow-y:scroll;
height: 651px;
::-webkit-scrollbar {
display: none;
}
/deep/ .el-loading-spinner{margin-top: 20px;}
.fr{float:right;}
.gray{color: #999;}
.padt10{padding-top: 10px;}
ul li {
padding: 10px;
overflow: hidden;
border-bottom: 1px solid #efefef;
cursor: pointer;
p{white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;}
:hover{ background: #efefef;}
img {
width: 40px;
height: 40px;
float: left
}
}
}
</style>
\ No newline at end of file
<template>
<div class="list" v-loading="loading">
<div v-if="personList.length>=1">
<ul>
<li v-for="(item,index) in personList" :key="index" @click="liClick(item)">
<el-row style="padding:10px" v-if="item.finalChatContext.msgtype=='text'">
<el-col :span="3"> <img v-if="item.finalChatContext.fromInfo" :src="item.finalChatContext.fromInfo.avatar"></el-col>
<el-col :span="21">
<p>{{item.finalChatContext.roomInfo.name}} <span class="fr gray">{{parseTime(item.finalChatContext.fromInfo.updateTime)}}</span></p>
<p class="gray padt10" v-if="item.finalChatContext.fromInfo">{{item.finalChatContext.fromInfo.name}}:{{item.finalChatContext.text.content}}</p>
</el-col>
</el-row>
<el-row style="padding:10px" v-if="item.finalChatContext.msgtype=='file'">
<el-col :span="3">&nbsp; `</el-col>
<el-col :span="21">
<p><span class="fr gray">{{parseTime(item.finalChatContext.msgtime)}}</span></p>
<p class="gray padt10" >{{item.finalChatContext.from}}:
<span v-if="item.finalChatContext.file.fileext=='mp4'">[视频]</span>
</p>
</el-col>
</el-row>
</li>
</ul>
</div>
<div v-else></div>
</div>
</template>
<script>
import {parseTime} from '@/utils/common.js'
export default {
props: {
personList: {
type: Array,
defluat: () => []
},
loading: {
type: Boolean,
defluat: false
},
},
data() {
return{
loadings:true
}
},
methods:{
liClick(e){
this.$emit('groupFn',e)
}
}
}
</script>
<style lang="scss" scoped>
*{ padding: 0;
margin: 0;}
.list {
overflow-y:scroll;
::-webkit-scrollbar {
display: none;
}
/deep/ .el-loading-spinner{margin-top: 20px;}
.fr{float:right;}
.gray{color: #999;}
.padt10{padding-top: 10px;}
ul li {
padding: 10px;
overflow: hidden;
border-bottom: 1px solid #efefef;
cursor: pointer;
p{white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;}
:hover{ background: #efefef;}
img {
width: 40px;
height: 40px;
float: left
}
}
}
</style>
\ No newline at end of file
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<ul> <ul>
<li v-for="(item,index) in personList" :key="index" @click="liClick(item)"> <li v-for="(item,index) in personList" :key="index" @click="liClick(item)">
<el-row style="padding:10px"> <el-row style="padding:10px">
<el-col :span="4"> <img :src="item.receiveWeCustomer.avatar"></el-col> <el-col :span="3"> <img :src="item.receiveWeCustomer.avatar"></el-col>
<el-col :span="20"> <el-col :span="21">
<p>{{item.receiveWeCustomer.name}} <span class="fr gray">{{parseTime(item.finalChatContext.msgtime)}}</span></p> <p>{{item.receiveWeCustomer.name}} <span class="fr gray">{{parseTime(item.finalChatContext.msgtime)}}</span></p>
<p class="gray padt10" v-if="item.finalChatContext.text">{{item.finalChatContext.text.content}}</p> <p class="gray padt10" v-if="item.finalChatContext.text">{{item.finalChatContext.text.content}}</p>
</el-col> </el-col>
</el-row> </el-row>
</li> </li>
......
<template>
<div class="security">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="敏感词触发" name="1">
<sensitive-list />
</el-tab-pane>
<el-tab-pane label="敏感词设置" name="2">
<set-sensitive-word />
</el-tab-pane>
<el-tab-pane label="敏感行为警告" name="3">
<alarming-sensitive />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import alarmingSensitive from './securityPage/alarmingSensitive.vue'
import sensitiveList from './securityPage/sensitiveList.vue'
import setSensitiveWord from './securityPage/setSensitiveWord'
export default {
components:{
sensitiveList,
setSensitiveWord,
alarmingSensitive
},
data() {
return {
activeName: '1',
}
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
}
}
}
</script>
<!-- 敏感行为警告页面 -->
<template>
<div class="alarming">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="敏感记录" name="1">
<el-table :data="recordSensitive" stripe style="width: 100%"
:header-cell-style="{background:'#fff'}">
<el-table-column prop="operator" label="操作员工">
</el-table-column>
<el-table-column prop="operateTarget" label="操作对象">
</el-table-column>
<el-table-column prop="sensitiveAct" label="敏感行为">
</el-table-column>
<el-table-column prop="updateTime" label="操作时间">
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="recordPageTotal"
:page.sync="recordPageConfig.pageNum"
:limit.sync="recordPageConfig.pageSize"
@pagination="getSensiveRecordList()"
/>
</el-tab-pane>
<el-tab-pane label="敏感行为管理" name="2">
<el-table :data="tabData" stripe style="width: 100%"
:header-cell-style="{background:'#fff'}">
<el-table-column prop="actName" label="敏感操作">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-switch v-model="scope.row.enableFlag" :active-value="1" :inactive-value="2" @change="handleStatusChange(scope.row)"></el-switch>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="query.pageNum"
:limit.sync="query.pageSize"
@pagination="getSensitiveManagementList()"
/>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import * as sensitiveApis from '@/api/conversation/security'
export default {
data() {
return {
activeName: '1',
recordSensitive: [],
tabData: [],
total: 0,
query: {
pageNum: 1,
pageSize: 10
},
recordPageTotal: 0,
recordPageConfig: {
pageNum: 1,
pageSize: 10
}
}
},
mounted() {
this.getSensiveRecordList()
this.getSensitiveManagementList()
},
methods: {
getSensiveRecordList() {
sensitiveApis.getSensitiveRecord(this.recordPageConfig).then(res => {
if (res.code === 200) {
this.recordSensitive = res.rows
this.recordPageTotal = Number(res.total)
}
})
},
getSensitiveManagementList() {
sensitiveApis.getSensitiveManagement(this.query).then(res => {
if (res.code === 200) {
this.tabData = res.rows
this.total = Number(res.total)
}
})
},
handleStatusChange(e) {
console.log(e)
},
handleClick(tab, event) {
console.log(tab, event)
}
}
}
</script>
\ No newline at end of file
<!-- 敏感词触发页面 -->
<template>
<div>
<el-form :inline="true" :model="form" class="demo-form-inline">
<el-form-item label="添加人">
<div class="tag-input" @click="dialogVisibleSelectUser = true">
<span class="tag-place" v-if="!queryUser.length">请选择</span>
<template v-else>
<el-tag
type="info"
v-for="(unit, unique) in queryUser"
:key="unique"
>{{ unit.name }}</el-tag
>
</template>
</div>
</el-form-item>
<el-form-item>
<el-input v-model="form.keyword" placeholder="搜索关键词" style="width:300px">
<el-button slot="prepend" icon="el-icon-search"></el-button>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getSensitiveList">查询</el-button>
</el-form-item>
</el-form>
<div class="search-content">
<el-row>
<el-col :span="8">
<div class="left-title">触发记录</div>
</el-col>
<el-col :span="16" style="text-align: right;">
<el-radio-group v-model="selectDate" size="small">
<el-radio-button label="昨日"></el-radio-button>
<el-radio-button label="7日"></el-radio-button>
<el-radio-button label="30日"></el-radio-button>
</el-radio-group>
<el-date-picker
v-model="dateRangeValue"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
class="date-range">
</el-date-picker>
</el-col>
</el-row>
</div>
<el-table :data="tableData" stripe style="width: 100%"
:header-cell-style="{background:'#fff'}">
<el-table-column prop="pattern_words" label="敏感词">
</el-table-column>
<el-table-column prop="content" label="内容">
</el-table-column>
<el-table-column prop="from" label="触发者">
</el-table-column>
<el-table-column prop="status" label="消息状态">
<template slot="header" >
{{floorRange}}
<el-select size="mini" v-model="floorRange" class="noborder" @change="chechName(floorRange)">
<el-option v-for="item in displayOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="msgtime" label="发送时间">
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="query.pageNum"
:limit.sync="query.pageSize"
@pagination="getSensitiveList()"
/>
<!-- 选择添加人弹窗 -->
<SelectUser
:visible.sync="dialogVisibleSelectUser"
title="选择添加人"
:isSigleSelect="true"
@success="selectedUser"
></SelectUser>
</div>
</template>
<script>
import * as sensitiveApis from '@/api/conversation/security'
import SelectUser from "@/components/SelectUser"
export default {
components: {
SelectUser
},
data() {
return {
form: {
pageSize: 10,
pageNum: 1,
scopeType: '',
auditScopeId: '',
keyword: '' // 关键词
},
selectDate: '',
dateRangeValue: '', // 时间选择
tableData: [],
queryUser: [], // 搜索框选择的添加人
query: {
pageNum: 1,
pageSize: 10
},
total: 0,
dialogVisibleSelectUser: false, // 选择添加人弹窗显隐
floorRange:'全部',
displayOptions: [{
value: "0",
label: "全部"
},
{
value: "1",
label: "已发送"
},
{
value: "2",
label: "已撤回"
},
{
value: "3",
label: "已删除"
}
]
}
},
methods: {
getSensitiveList() {
if (this.queryUser.length > 0) {
this.form.pageSize = this.query.pageSize
this.form.pageNum = this.query.pageNum
sensitiveApis.getSecurityList(this.form).then(res => {
if (res.code === 200) {
this.tableData = res.rows
this.total = Number(res.total)
}
})
} else {
this.$message.warning('请选择人员!')
}
},
chechName(e) {
if (e == 0) {
this.floorRange = '全部'
} else if (e == 1) {
this.floorRange = '已发送'
} else if (e == 2) {
this.floorRange = '已撤回'
} else {
this.floorRange = '切回企业日志'
}
},
selectedUser(list) {
// console.log(list)
this.queryUser = list
this.form.scopeType = list.map(d => d.department) + ""
this.form.auditScopeId = list.map(d => d.userId) + ""
this.getSensitiveList()
}
}
}
</script>
<style lang="scss" scoped>
.demo-form-inline {
background: #efefef;
padding: 18px 10px 0 10px;
}
.tag-input {
width: 240px;
display: flex;
border-radius: 4px;
border: 1px solid #dcdfe6;
align-items: center;
padding: 0 15px;
overflow: hidden;
height: 32px;
background: #fff;
.tag-place {
color: #bbb;
font-size: 14px;
}
}
.search-content {
height: 40px;
margin-top: 15px;
padding: 10px;
.left-title {
height: 40px;
line-height: 40px;
}
.date-range {
margin-left: 10px;
width: 300px;
}
}
.noborder {
/deep/ .el-input--mini .el-input__inner{
width: 2px;
border: none;
}
}
.content {
margin-top: 15px;
padding: 10px;
}
</style>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
:rules="loginRules" :rules="loginRules"
class="login-form" class="login-form"
> >
<h3 class="title">微后台管理系统</h3> <h3 class="title">微后台管理系统</h3>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input
v-model="loginForm.username" v-model="loginForm.username"
......
...@@ -39,5 +39,5 @@ public interface WeChatItemMapper extends BaseMapper<WeChatItem> { ...@@ -39,5 +39,5 @@ public interface WeChatItemMapper extends BaseMapper<WeChatItem> {
* @param keyword 关键词 * @param keyword 关键词
* @return * @return
*/ */
public List<WeChatSideVo> findChatItems(@Param("sideId") Long sideId, @Param("keyword") String keyword); public List<WeChatSideVo> findChatItems(@Param("sideId") Long sideId, @Param("keyword") String keyword,@Param("mediaType") String mediaType);
} }
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册