LeaveMessage.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. <template>
  2. <div>
  3. <div class="row allAlignment">
  4. <leftNav/>
  5. <div>
  6. <hader/>
  7. <messageCenter></messageCenter>
  8. <div class="column allAlignment box" style="background:#F6F8FF; ">
  9. <div style="height:8vh; background:#FFF; " class="row allAlignment">
  10. <div class="name_box row center">
  11. <span>留言列表</span>
  12. </div>
  13. <div class="row center allAlignment">
  14. <el-select v-model="value" size="mini" style="width: 28%;" placeholder="请选择">
  15. <el-option
  16. v-for="item in options"
  17. :key="item.value"
  18. :label="item.label"
  19. :value="item.value"
  20. ></el-option>
  21. </el-select>
  22. <div>
  23. <el-input
  24. placeholder="请输入内容"
  25. size="mini"
  26. v-model="input3"
  27. class="input-with-select"
  28. >
  29. <el-button slot="append" icon="el-icon-search"></el-button>
  30. </el-input>
  31. </div>
  32. </div>
  33. </div>
  34. <div style="margin:0 20px;">
  35. <el-table
  36. :header-cell-style="{background:'#eef1f6',color:'#606266'}"
  37. :row-style="{background:'#ffffff',color:'#606266'}"
  38. :data="tableData"
  39. stripe
  40. @row-dblclick="click_row"
  41. style="width: 100%;"
  42. >
  43. <el-table-column prop="name" label="用户名"></el-table-column>
  44. <el-table-column prop="time" label="留言时间" width="180"></el-table-column>
  45. <el-table-column prop="content" label="留言内容"></el-table-column>
  46. <el-table-column prop="phone" label="手机"></el-table-column>
  47. <el-table-column prop="email" label="邮箱"></el-table-column>
  48. <el-table-column prop="endTime" label="当前状态">
  49. <template slot-scope="scope">
  50. <span
  51. style="color:#FF6600"
  52. v-if="scope.row.currentState === '未回复'"
  53. >{{scope.row.currentState}}</span>
  54. <span v-if="scope.row.currentState === '已回复'">{{scope.row.currentState}}</span>
  55. </template>
  56. </el-table-column>
  57. <!-- <el-table-column
  58. prop="currentState"
  59. label="当前状态"
  60. width="100"
  61. :filters="[{ text: '未回复', value: '未回复' }, { text: '已回复', value: '已回复' }]"
  62. :filter-method="filterTag"
  63. filter-placement="bottom-end">
  64. <template slot-scope="scope">
  65. <el-tag
  66. :type="scope.row.currentState === '未回复' ? 'primary' : 'success'"
  67. disable-transitions>{{scope.row.currentState}}</el-tag>
  68. </template>
  69. </el-table-column>-->
  70. <el-table-column prop="satisfaction" label="处理人"></el-table-column>
  71. </el-table>
  72. </div>
  73. <div v-show="pages >9" style=" padding: 10px;">
  74. <el-pagination background layout="prev, pager, next" :total="pages" @prev-click='upData'
  75. @next-click="downData" @current-change="current_page"></el-pagination>
  76. </div>
  77. <div class="right_box" v-show="isShow">
  78. <historicalRecord :show="isShow" :uid="uid" v-on:childValue="childValue"/>
  79. </div>
  80. </div>
  81. </div>
  82. <!-- 详情抽屉-->
  83. <el-drawer
  84. id="leaveMessage"
  85. :close-on-press-escape="true"
  86. :show-close="false"
  87. style="margin-top:50px"
  88. :visible.sync="drawer"
  89. size="780px">
  90. <el-row class="content_box">
  91. <el-row class="headers">
  92. <el-col :span="12">留言信息</el-col>
  93. <!-- <el-col :span="12" style="text-align: right">-->
  94. <!-- <el-button class="chuli" type="warning">未处理</el-button>-->
  95. <!-- </el-col>-->
  96. </el-row>
  97. <el-row class="chat_user">
  98. <el-col :span="17">
  99. <div class="chat_box">
  100. <!-- 内容展示 -->
  101. <el-row id="main">
  102. <el-col class="user">
  103. <div class="text">{{getUserItem.content}}</div>
  104. <div class="img" v-for="item in getUserItem.image">
  105. <img :src="img_http +item" alt="">
  106. </div>
  107. </el-col>
  108. <el-col class="serive">
  109. <el-input class="text" resize="none" type="textarea"
  110. @blur="widthCheck($event.target, 100)" placeholder="请回复用户留言"
  111. v-model="leaveInfor"></el-input>
  112. </el-col>
  113. <el-col>
  114. <el-upload style="margin:10px;"
  115. action="/api/index/upload/uploadImg"
  116. :before-upload="beforeAvatarUpload"
  117. :on-progress="onProgress"
  118. :on-change='uploadChange'
  119. :on-success='uploadSuccess'
  120. :on-error="uploadError"
  121. :on-remove="handleRemove"
  122. :auto-upload="false"
  123. list-type="picture-card"
  124. ref="upload"
  125. :limit="4"
  126. :on-exceed="handleExceed"
  127. >
  128. <i slot="default" class="el-icon-plus"></i>
  129. </el-upload>
  130. <el-dialog>
  131. <img width="100%" :src="dialogImageUrl" alt="">
  132. </el-dialog>
  133. </el-col>
  134. </el-row>
  135. <el-row class="chatting">
  136. <el-button class="send" type="primary" @click="sendMessage">提交</el-button>
  137. </el-row>
  138. </div>
  139. </el-col>
  140. <el-col :span="7">
  141. <div class="user_box">
  142. <ul>
  143. <li class="title">用户信息</li>
  144. <li>账号:{{userInfo.account_name}}</li>
  145. <li>标签:{{userInfo.label}}</li>
  146. <li>昵称:{{userInfo.nick_name}}</li>
  147. <li>手机:{{userInfo.account_phone}}</li>
  148. <li>邮箱:{{userInfo.account_email}}</li>
  149. <li>地址:{{userInfo.address}}</li>
  150. <li>备注:{{userInfo.remark}}</li>
  151. </ul>
  152. <ul>
  153. <li class="title">访问信息</li>
  154. <li>来源ip:{{getUserItem.account_ip}}</li>
  155. <li>来源终端:{{getUserItem.system}}-{{getUserItem.browse}}</li>
  156. </ul>
  157. </div>
  158. </el-col>
  159. </el-row>
  160. </el-row>
  161. </el-drawer>
  162. </div>
  163. </div>
  164. </template>
  165. <script>
  166. import "@/css/index.css";
  167. import leftNav from "@/components/leftNav";
  168. import hader from "@/components/hader";
  169. import historicalRecord from "@/components/historicalRecord";
  170. import messageCenter from "@/components/messageCenter";
  171. import frce from '../assets/frce.js';
  172. export default {
  173. name: "SessionHistory",
  174. data() {
  175. return {
  176. isShow: false,
  177. uid: "",
  178. pages: 0,
  179. tableData: [],
  180. options: [
  181. {
  182. value: "今日",
  183. label: "今日"
  184. },
  185. {
  186. value: "最近3天",
  187. label: "最近3天"
  188. },
  189. {
  190. value: "最近7天",
  191. label: "最近7天"
  192. },
  193. {
  194. value: "最近15天",
  195. label: "最近15天"
  196. },
  197. {
  198. value: "最近30天",
  199. label: "最近30天"
  200. }
  201. ],
  202. value: "",
  203. input3: "",
  204. startTime: "", // 请求结果开始时间
  205. endTime: "", // 请求结果结束时间
  206. drawer: false,
  207. sendCol: false, // 发送按钮切换样式
  208. leaveInfor: '', // 留言信息
  209. dialogImageUrl: '',
  210. userInfo: [], //用户信息
  211. getUserItem: [],
  212. img_http: 'http://kfadmin.bocai186.com',//图片路径域
  213. // img_http: 'http://192.168.2.187:8090',//图片路径域
  214. uploadImg:[],
  215. users:[]
  216. };
  217. },
  218. components: {
  219. leftNav,
  220. hader,
  221. historicalRecord,
  222. messageCenter
  223. },
  224. mounted() {
  225. this.frceArr = frce.frce;
  226. this.value = this.options[2].value;
  227. this.getSessionList(1)
  228. this.get_vuex_info();
  229. },
  230. computed: {
  231. // 获取客服查询时间
  232. getValueChange() {
  233. return this.value;
  234. }
  235. },
  236. watch: {
  237. getValueChange(val) {
  238. this.getStartEndAjaxTime(val);
  239. }
  240. },
  241. methods: {
  242. /******************上一页*****************/
  243. upData(e) {
  244. this.getSessionList(e)
  245. },
  246. /*********************下一页******************/
  247. downData(e) {
  248. this.getSessionList(e)
  249. },
  250. /*******************选择页数******************/
  251. current_page(e) {
  252. this.getSessionList(e)
  253. },
  254. // 上传之前
  255. beforeAvatarUpload(file) {
  256. // console.log(file, '上传之前')
  257. const isJPG = file.type == 'image/jpeg' || 'image/jpg' || 'image/png' || 'image/svg';
  258. if (!isJPG) {
  259. this.$message.error('上传只能是图片格式!');
  260. }
  261. return isJPG
  262. },
  263. // 上传成功时的回调
  264. uploadSuccess(res, file) {
  265. // console.log('res',file)
  266. this.uploadImg.push(URL.createObjectURL(file.raw))
  267. // console.log(this.uploadImg)
  268. return this.uploadImg
  269. },
  270. // 发送中
  271. onProgress() {
  272. },
  273. // 上传失败
  274. uploadError() {
  275. this.$message.error('上传失败,请重新上传')
  276. },
  277. handleRemove(file, fileList) {
  278. // this.uploadImg = []
  279. // fileList.forEach((res,index) => {
  280. // this.uploadImg.push(URL.createObjectURL(res.raw))
  281. // });
  282. // console.log(this.uploadImg)
  283. },
  284. // 每次改变图片状态返回的回调
  285. uploadChange(file, fileList) {
  286. },
  287. handleExceed(files, fileList) {
  288. this.$message.error(`图片上传数量最多4张`);
  289. },
  290. sendMessage() {
  291. this.$refs.upload.submit();
  292. console.log(this.uploadImg, '图片');
  293. let formData = new FormData();
  294. formData.append("user_id",this.users.id);
  295. formData.append("message_id", this.uid);
  296. formData.append("reply_content", this.leaveInfor);
  297. formData.append("images",this.uploadImg);
  298. this.post('/api/service/Message/dealmessage', formData).then(res => {
  299. console.log(res,'提交成功')
  300. return false;
  301. })
  302. },
  303. /*****************获取当前聊天用户信息****************/
  304. get_user(id) {
  305. let obj = {
  306. headers: {
  307. "apiToken": this.$md5('accountInfo' + "customer-service" + 'service' + this.time + 'service'),
  308. 'userToken': this.token
  309. },
  310. account_id: id
  311. };
  312. this.post('api' + this.$ports.userInfo.accountInfo, obj).then(res => {
  313. if (res.data.code == 1) {
  314. // console.log(res.data.data, '用户信息');
  315. this.userInfo = res.data.data;
  316. }
  317. })
  318. },
  319. get_vuex_info(){
  320. this.users = this.$store.getters.get_user_info
  321. console.log(this.users,'用户信息');
  322. },
  323. widthCheck(str, len) {
  324. var temp = 0
  325. for (var i = 0; i < str.value.length; i++) {
  326. if (str.value.length < 4) {
  327. str.value = ''
  328. }
  329. }
  330. },
  331. // 获取请求参数开始和结束时间
  332. getStartEndAjaxTime(e) {
  333. let time = new Date();
  334. let time2 = new Date(time)
  335. function getDate(year, month, date) {
  336. return year + '-' + ((month + 1) < 10 ? '0' + (month + 1) : month + 1) + '-' + (date < 10 ? '0' + date : date)
  337. }
  338. if (e == "今日") {
  339. time2.setDate(time.getDate())
  340. } else if (e == "最近3天") {
  341. time2.setDate(time.getDate() - 3)
  342. } else if (e == "最近7天") {
  343. time2.setDate(time.getDate() - 7)
  344. } else if (e == "最近15天") {
  345. time2.setDate(time.getDate() - 15)
  346. } else if (e == "最近30天") {
  347. time2.setDate(time.getDate() - 30)
  348. }
  349. this.endTime = getDate(time.getFullYear(), time.getMonth(), time.getDate())
  350. this.startTime = getDate(time2.getFullYear(), time2.getMonth(), time2.getDate())
  351. this.getSessionList(1)
  352. },
  353. // 获取列表数据
  354. getSessionList(page, size = 10) {
  355. let str = "index" + "customer-service" + "Message" + this.time + "service";
  356. let obj = {
  357. headers: {
  358. "Content-Type": "application/x-www-form-urlencoded",
  359. apiToken: this.$md5(str),
  360. userToken: this.token
  361. }
  362. };
  363. this.post(
  364. "api/service/Message/index", {
  365. start_time: this.startTime,
  366. end_time: this.endTime,
  367. pageSize: size,
  368. pageNumber: page
  369. },
  370. obj,
  371. str
  372. ).then(res => {
  373. if (res.data.data) {
  374. this.tableData = res.data.data;
  375. this.pages = res.data.data.length;
  376. console.log(this.pages)
  377. }
  378. });
  379. },
  380. click_row(row, column, event) {
  381. // console.log(this.value);
  382. console.log(row)
  383. this.uid = row.message_id;
  384. this.drawer = true;
  385. // this.isShow = true;
  386. this.getUserItem = row;
  387. console.log(this.getUserItem)
  388. this.get_user(row.message_id)
  389. },
  390. childValue(e) {
  391. //console.log(e);
  392. //this.drawer =true;
  393. // this.isShow = e;
  394. },
  395. filterTag(value, row) {
  396. return row.tag === value;
  397. }
  398. }
  399. };
  400. </script>
  401. <style>
  402. .el-upload--picture-card {
  403. width: 100px;
  404. height: 100px;
  405. line-height: 100px;
  406. }
  407. .el-upload-list--picture-card .el-upload-list__item {
  408. width: 100px;
  409. height: 100px;
  410. line-height: 100px;
  411. }
  412. </style>
  413. <style lang="less" scoped>
  414. .chatting {
  415. text-align: center;
  416. }
  417. .serive {
  418. padding: 0 10px;
  419. text-align: right;
  420. .text {
  421. margin-top: 20px;
  422. background: #F5F5F5;
  423. border: 1px solid #EEEEEE;
  424. padding: 20px;
  425. font-size: 14px;
  426. color: #666;
  427. line-height: 1.8;
  428. .el-textarea__inner {
  429. border: none;
  430. resize: none;
  431. height: 300px;
  432. }
  433. }
  434. }
  435. .user {
  436. .text {
  437. margin-top: 20px;
  438. background: #F5F5F5;
  439. border: 1px solid #EEEEEE;
  440. padding: 20px;
  441. font-size: 14px;
  442. color: #666;
  443. line-height: 1.8;
  444. }
  445. .img {
  446. margin-top: 20px;
  447. }
  448. }
  449. .netSendCol {
  450. cursor: not-allowed;
  451. }
  452. .content_box {
  453. .chat_user {
  454. border-top: 1px solid #D5E5FF;
  455. }
  456. }
  457. .user_box {
  458. height: 100vh;
  459. }
  460. .el-pagination .btn-next .el-icon {
  461. display: none;
  462. }
  463. .cell {
  464. text-align: center;
  465. }
  466. .el-pagination {
  467. text-align: center;
  468. font-size: 0;
  469. }
  470. .el-table::before {
  471. z-index: 0 !important;
  472. }
  473. .input-with-select {
  474. width: 100%;
  475. }
  476. .name_box {
  477. margin-left: 20px;
  478. font-size: 14px;
  479. font-weight: bold;
  480. color: rgba(102, 102, 102, 1);
  481. }
  482. .box {
  483. width: 100%;
  484. }
  485. .right_box {
  486. position: fixed;
  487. top: 33px;
  488. right: 0;
  489. width: 100%;
  490. /* height: 100vh;
  491. background: red; */
  492. /* //background: rgba(255, 255, 255, 0.315); */
  493. }
  494. .el-input-group__append {
  495. text-align: center;
  496. }
  497. .el-table td {
  498. padding: 8px 0;
  499. }
  500. .headers {
  501. display: flex;
  502. justify-content: flex-start;
  503. padding: 0 20px;
  504. height: 50px;
  505. line-height: 50px;
  506. }
  507. .user_box {
  508. padding: 20px;
  509. background: #F6F8FF;
  510. }
  511. .chuli {
  512. width: 70px;
  513. height: 30px;
  514. border-radius: 5px;
  515. color: #fff;
  516. background: #FF6600
  517. }
  518. .title {
  519. font-weight: bold;
  520. color: #333333;
  521. font-size: 14px;
  522. }
  523. li {
  524. margin: 10px 0;
  525. color: #999999;
  526. }
  527. ul {
  528. margin: 0;
  529. padding: 0;
  530. }
  531. #main {
  532. height: 65vh;
  533. }
  534. .icons {
  535. padding: 0 20px;
  536. height: 40px;
  537. line-height: 40px;
  538. }
  539. .send {
  540. margin: 0 auto;
  541. color: #fff;
  542. width: 60%;
  543. height: 40px;
  544. background: rgba(221, 221, 221, 1);
  545. opacity: 1;
  546. border-radius: 5px;
  547. }
  548. .send.sendCol {
  549. background: linear-gradient(90deg, rgba(22, 84, 209, 1) 0%, rgba(9, 52, 173, 1) 100%);
  550. }
  551. </style>