vueMchatKf.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. <template>
  2. <div>
  3. <!-- <div class="top-group">
  4. <el-button type="primary">查看全部</el-button>
  5. </div> -->
  6. <div class="whole-wrapper">
  7. <!-- 左边的聊天列表 -->
  8. <!-- <div class="left_whole_wrapper">
  9. 搜索框
  10. <div class="search">
  11. <el-input placeholder="搜索联系人" suffix-icon="el-icon-search" v-model="userName" clearable @change="changeSearch"
  12. @input="searchChange"></el-input>
  13. </div>
  14. 聊天列表
  15. <div class="left_wrapper" style="overflow-y: auto" v-if="chatList">
  16. <div class="left-item" style="position: relative; cursor: pointer" v-bind:class="{ blue: index == current }"
  17. v-for="(item, index) in chatList" :key="index" @click="clickItem(item, index)">
  18. <div class="left-item-left">
  19. <div class="left-item-head" v-if="item.userHead == null || item.userHead == ''">
  20. <img src="~@/assets/img/head.png" />
  21. </div>
  22. <div class="left-item-head" v-else><img :src="item.userHead" /></div>
  23. <div class="left-item-info">
  24. <div class="left-item-info_title">{{ item.userName }}</div>
  25. <div class="left-item-info_content">{{ item.content }}</div>
  26. </div>
  27. </div>
  28. <div class="left-item-time">
  29. <div class="left-item-time-time" v-if="item.contentTime == null"></div>
  30. <div class="left-item-time-time" v-else>
  31. {{ item.contentTime.substring(11, 16) }}
  32. </div>
  33. <div class="left-item-time-number" style="position: absolute; left: 59px; top: 8px"
  34. v-if="item.storeCount">
  35. {{ item.storeCount }}
  36. </div>
  37. <div class="" @click="deletes(item)" style="position: relative; top: 6px"
  38. v-if="isAuth('vueMchat:delete')">
  39. <img src="~@/assets/img/delete.png" alt="" width="25" height="25" />
  40. </div>
  41. </div>
  42. </div>
  43. </div>
  44. </div> -->
  45. <!-- 中间的对话-->
  46. <div class="center_whole_wrapper">
  47. <div class="center_wrapper">
  48. <!-- 上面的表头 -->
  49. <div class="center_wrapper_top">
  50. <div class="center_wrapper_top_name">{{ name }}</div>
  51. <!-- <el-button v-if="name" size="mini" style="top: 30px; right: 20px; border-radius: 4px; position: absolute"
  52. @click="updates(userId)">用户详情
  53. </el-button> -->
  54. </div>
  55. <!-- 中间的聊天框,尝试模拟数据 -->
  56. <div class="center_wrapper_center" id="ele" style="overflow-y: auto" ref="dialogue_box">
  57. <!-- <div class="item loading">{{loadText}}<span>{{"第" + pageNum + "页"}}</span></div> -->
  58. <div v-for="(item, index) in dialogueList" :key="index" :class="
  59. item.sendType == 2
  60. ? center_wrapper_center_item
  61. : center_wrapper_center_item_reserve
  62. ">
  63. <div class="left-item-head">
  64. <img v-if="item.sendType == 1 && userHead !== null" :src="userHead" />
  65. <img v-else-if="item.sendType == 1 && userHead == null" src="~@/assets/img/head.png" />
  66. <img v-else src="~@/assets/img/avatar.png" />
  67. </div>
  68. <!-- 文字 -->
  69. <div class="center-item-info_wrapper" v-if="item.type == 1">
  70. <div class="center-item-tip">
  71. <div class="center-item-info">
  72. {{ item.content }}
  73. </div>
  74. </div>
  75. <div class="center-item-time">{{ item.createTime }}</div>
  76. </div>
  77. <!-- 图片 -->
  78. <div class="center-item-info_wrapper" v-if="item.type == 2">
  79. <div class="center-item-tip">
  80. <div>
  81. <el-popover placement="top-start" title="" trigger="hover">
  82. <img style="width: 100px; height: 100px" :src="item.content" alt="" slot="reference" />
  83. <img style="width: 300px; height: 300px" :src="item.content" alt="" />
  84. </el-popover>
  85. <!-- <img :src="item.content" alt="" width="100" height="100"> -->
  86. </div>
  87. </div>
  88. <div class="center-item-time">{{ item.createTime }}</div>
  89. </div>
  90. <!-- 订单 -->
  91. <div class="center-item-info_wrapper" v-if="item.type == 3">
  92. <div class="center-item-tip"
  93. style="background-color: #fff;cursor: pointer;padding: 10px;border-radius: 4px;">
  94. <div class="" @click="orderDetails(item.content.split(',')[2])">
  95. <div style="display: flex">
  96. <img :src="item.content.split(',')[0]" alt="" width="40" height="40" />
  97. <div style="
  98. width: 145px;
  99. font-size: 13px;
  100. line-height: 20px;
  101. margin-left: 5px;
  102. overflow: hidden;
  103. text-overflow: ellipsis;
  104. display: -webkit-box;
  105. -webkit-line-clamp: 2;
  106. -webkit-box-orient: vertical;
  107. ">
  108. {{ item.content.split(",")[1] }}
  109. </div>
  110. </div>
  111. <p class="hoverp" style="font-size: 13px; color: #999999">
  112. 订单编号: {{ item.content.split(",")[3] }}
  113. </p>
  114. <p style="font-size: 13px; color: #999999">
  115. 创建时间:{{ item.content.split(",")[4] }}
  116. </p>
  117. </div>
  118. </div>
  119. <div class="center-item-time">{{ item.createTime }}</div>
  120. </div>
  121. <!-- 商品 -->
  122. <div class="center-item-info_wrapper" v-if="item.type == 4">
  123. <div class="center-item-tip" style="background-color: #fff; padding: 10px; border-radius: 4px">
  124. <div class="">
  125. <img :src="item.content.split(',')[0]" alt="" width="160" height="120" />
  126. <p style="width: 160px; line-height: 20px; margin-bottom: 0">
  127. {{ item.content.split(",")[1] }}
  128. </p>
  129. <p style="color: #f56c6c; margin-bottom: 0">
  130. ¥{{ item.content.split(",")[2] }}
  131. </p>
  132. </div>
  133. </div>
  134. <div class="center-item-time">{{ item.createTime }}</div>
  135. </div>
  136. </div>
  137. <!-- <a id="mao2"></a> -->
  138. </div>
  139. <!-- 下面的输入框,发送 -->
  140. <div class="center_wrapper_right">
  141. <div class="icon-list">
  142. <!-- 表情 -->
  143. <!-- <div class="icon-item" title="表情">
  144. <el-popover v-model="emojiShow" placement="top-start" width="400" trigger="click" class="emoBox">
  145. <div class="emotionList">
  146. <a href="javascript:void(0);" @click="getEmo(index)" v-for="(item,index) in faceList" :key="index" class="emotionItem">{{item}}</a>
  147. </div>
  148. <el-button
  149. style="background: transparent;border: none;"
  150. class="emotionSelect"
  151. icon="iconfont icon-biaoqing"
  152. slot="reference"
  153. >😁</el-button>
  154. </el-popover>
  155. </div> -->
  156. <!-- 上传文件 -->
  157. <div class="icon-item">
  158. <el-upload class="avatar-uploader" v-model="coverImg"
  159. action="https://mxys.chuanghai-tech.com/sqx_fast/alioss/upload" :show-file-list="false"
  160. :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
  161. <div class="icon-item" title="发送文件">
  162. <img class="icon-item-img" src="~@/assets/img/wenjian.png" />
  163. </div>
  164. </el-upload>
  165. </div>
  166. </div>
  167. <el-input type="textarea" id="textarea" :rows="2" placeholder="请输入内容" v-model="content"
  168. @keyup.enter.native="sendTextarea(1)"></el-input>
  169. <el-button type="primary" style="font-size: 12px" v-if="content" @click="sendTextarea(1)">发送
  170. </el-button>
  171. <el-button type="primary" style="font-size: 12px" v-else disabled @click="sendTextarea(1)">发送
  172. </el-button>
  173. </div>
  174. </div>
  175. </div>
  176. </div>
  177. </div>
  178. </template>
  179. <script>
  180. export default {
  181. data() {
  182. return {
  183. chatList: [],
  184. page: 1,
  185. size: 5,
  186. storeId: 0,
  187. targetId: "",
  188. userName: "",
  189. userId: "",
  190. chatId: "",
  191. type: "",
  192. current: 0,
  193. coverImg: "",
  194. sendType: 1,
  195. // 表情包列表
  196. faceList: [],
  197. // 发送文字
  198. content: "",
  199. // 模拟对话
  200. name: "",
  201. userHead: "",
  202. numlist: {},
  203. info: {
  204. stockDate: this.getNowTime(), //日期
  205. },
  206. emojiShow: false,
  207. dialogueInfo: {},
  208. dialogueList: [],
  209. loadText: "加载中...",
  210. pageNum: 1,
  211. loadText1: "加载中...",
  212. pageNum1: 1,
  213. center_wrapper_center_item: "center_wrapper_center_item",
  214. center_wrapper_center_item_reserve: "center_wrapper_center_item_reserve",
  215. };
  216. },
  217. created() {
  218. this.loadEmojis();
  219. },
  220. watch: {
  221. $route: function(to, from) {
  222. if (to.name == "vueMchat") {
  223. let ele = document.getElementById("ele");
  224. this.$nextTick(() => {
  225. ele.scrollTop = ele.scrollHeight;
  226. });
  227. }
  228. },
  229. },
  230. activated() {
  231. let {
  232. userId,
  233. userName
  234. } = this.$route.query;
  235. if (userId && userName) {
  236. this.userName = userName;
  237. this.current = 0;
  238. } else {
  239. this.userName = "";
  240. }
  241. this.dataSelect();
  242. this.initWebSocket();
  243. },
  244. methods: {
  245. initWebSocket() {
  246. this.websock = new WebSocket(
  247. this.$http.adornWss("websocket/0"));
  248. // "ws://192.168.0.119:8171/sqx_fast/websocket/0"); //这个连接ws://固定,后面的根据自己的IP和端口进行改变,我设置监听的就是8081
  249. // this.websock = new WebSocket("ws://yungameadmin.xianmxkj.com/ws/websocket/0");
  250. this.websock.onmessage = this.websocketonmessage;
  251. this.websock.onerror = this.websocketonerror;
  252. this.websock.onopen = this.websocketonopen;
  253. this.websock.onclose = this.websocketclose;
  254. },
  255. websocketonopen() {
  256. // 连接建立之后执行send方法发送数据,这个和自己的后端沟通好需要传什么数据,我的是要进行token验证
  257. console.log("WebSocket连接成功");
  258. },
  259. websocketonerror() {
  260. //连接错误
  261. console.log("WebSocket连接失败");
  262. },
  263. websocketonmessage(e) {
  264. // 数据接收
  265. let msg = JSON.parse(e.data);
  266. this.dialogueList.push(msg);
  267. console.log(msg);
  268. let ele = document.getElementById("ele");
  269. this.dataSelect();
  270. this.$nextTick(() => {
  271. ele.scrollTop = ele.scrollHeight;
  272. });
  273. },
  274. websocketclose(e) {
  275. // 关闭连接
  276. console.log("已关闭连接", e);
  277. },
  278. //加载表情,存放到表情列表中
  279. loadEmojis() {
  280. const appData = require("@/assets/img/emojis.json");
  281. for (let i in appData) {
  282. this.faceList.push(appData[i].char);
  283. }
  284. },
  285. //处理默认选中当前日期
  286. getNowTime() {
  287. var now = new Date();
  288. var year = now.getFullYear(); //得到年份
  289. var month = now.getMonth(); //得到月份
  290. var date = now.getDate(); //得到日期
  291. var hour = now.getHours();
  292. var minute = now.getMinutes();
  293. var second = now.getSeconds();
  294. month = month + 1;
  295. month = month.toString().padStart(2, "0");
  296. date = date.toString().padStart(2, "0");
  297. var defaultDate = `${year}-${month}-${date} ${hour}:${minute}:${second}`;
  298. return defaultDate;
  299. this.$set(this.info, "stockDate", defaultDate);
  300. },
  301. // 详情跳转
  302. updates(userId) {
  303. this.$router.push({
  304. path: "/userDetail",
  305. query: {
  306. userId: userId
  307. }
  308. });
  309. },
  310. // 订单详情跳转
  311. orderDetails(id) {
  312. this.$router.push({
  313. path: "/orderDetails",
  314. query: {
  315. id: id
  316. }
  317. });
  318. },
  319. // 获取用户点击之后的标签 ,存放到输入框内
  320. getEmo(index) {
  321. var textArea = document.getElementById("textarea");
  322. function changeSelectedText(obj, str) {
  323. if (window.getSelection) {
  324. // 非IE浏览器
  325. textArea.setRangeText(str);
  326. // 在未选中文本的情况下,重新设置光标位置
  327. textArea.selectionStart += str.length;
  328. textArea.focus();
  329. } else if (document.selection) {
  330. // IE浏览器
  331. obj.focus();
  332. var sel = document.selection.createRange();
  333. sel.text = str;
  334. }
  335. }
  336. changeSelectedText(textArea, this.faceList[index]);
  337. this.description = textArea.value; // 要同步data中的数据
  338. // console.log(this.faceList[index]);
  339. this.emojiShow = false;
  340. return;
  341. },
  342. changeSearch(e) {
  343. if (!e) {
  344. this.userName = ""
  345. this.dataSelect();
  346. }
  347. },
  348. searchChange() {
  349. this.dataSelect();
  350. },
  351. // 点击聊天列表的某一项
  352. clickItem(item, index) {
  353. this.current = index;
  354. this.userId = item.userId;
  355. this.name = item.userName;
  356. this.userHead = item.userHead;
  357. this.chatId = item.chatId;
  358. this.chatList[index].storeCount = 0
  359. this.clickItem2();
  360. this.initWebSocket();
  361. },
  362. clickItem2() {
  363. this.$http({
  364. url: this.$http.adornUrlMsg("chatsContent/storeList"),
  365. method: "get",
  366. params: this.$http.adornParams({
  367. chatId: this.chatId,
  368. }),
  369. }).then(({
  370. data
  371. }) => {
  372. let returnData = data.data;
  373. this.dialogueList = returnData;
  374. let ele = document.getElementById("ele");
  375. this.$nextTick(() => {
  376. ele.scrollTop = ele.scrollHeight;
  377. });
  378. });
  379. },
  380. // 点击发送
  381. sendTextarea(type) {
  382. let data = {
  383. content: this.content,
  384. type: type,
  385. createTime: this.info.stockDate,
  386. sendType: this.sendType,
  387. userId: this.userId,
  388. storeId: this.storeId,
  389. chatId: this.chatId,
  390. };
  391. this.numlist = data;
  392. data = JSON.stringify(data);
  393. this.websock.send(data);
  394. this.content = "";
  395. this.dialogueList.push(this.numlist);
  396. let ele = document.getElementById("ele");
  397. this.$nextTick(() => {
  398. ele.scrollTop = ele.scrollHeight;
  399. });
  400. this.initWebSocket();
  401. this.dataSelect();
  402. // this.clickItem2()
  403. },
  404. //删除会话
  405. deletes(item) {
  406. this.$confirm(`确定删除聊天记录,删除后不能恢复?`, "提示", {
  407. confirmButtonText: "确定",
  408. cancelButtonText: "取消",
  409. type: "warning",
  410. })
  411. .then(() => {
  412. this.$http({
  413. url: this.$http.adornUrlMsg(`chats/delete/?id=${item.chatId}`),
  414. method: "get",
  415. params: this.$http.adornParams({}),
  416. }).then(({
  417. data
  418. }) => {
  419. this.$message({
  420. message: "删除成功",
  421. type: "success",
  422. duration: 1500,
  423. onClose: () => {
  424. this.dataSelect();
  425. },
  426. });
  427. });
  428. })
  429. .catch(() => {});
  430. },
  431. // 上传成功
  432. handleAvatarSuccess(file, fileList) {
  433. this.coverImg = file.data;
  434. this.content = this.coverImg;
  435. this.sendTextarea(2);
  436. },
  437. // 获取左边实时聊天用户列表
  438. dataSelect() {
  439. this.tableDataLoading = true;
  440. var userId = this.$cookie.get('userId')
  441. this.$http({
  442. url: this.$http.adornUrlMsg("app/chats/save"),
  443. method: "post",
  444. data: this.$http.adornData({
  445. storeHead: '墨轩云商',
  446. storeId: 0,
  447. storeName:'',
  448. userId:userId,
  449. isShop:1
  450. }),
  451. }).then(({
  452. data
  453. }) => {
  454. this.tableDataLoading = false;
  455. let returnData = data.data;
  456. this.name = returnData.storeHead;
  457. this.userId = returnData.userId
  458. this.chatId = returnData.chatId
  459. this.userHead = returnData.userHead;
  460. this.clickItem2();
  461. // this.clickItem(this.chatList[this.current], this.current);
  462. });
  463. },
  464. // 验证只能上传音频
  465. beforeAvatarUpload(file) {
  466. var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
  467. var extension;
  468. if (testmsg == 'png' || testmsg == 'jpg' || testmsg == 'jpeg' || testmsg == 'gif') {
  469. extension = testmsg
  470. }
  471. // const extension = testmsg==='png'
  472. if (!extension) {
  473. this.$message({
  474. message: "只能上传图片!",
  475. type: 'error'
  476. })
  477. }
  478. return extension;
  479. },
  480. },
  481. mounted() {
  482. // this.timer = window.setInterval(() => {
  483. // setTimeout(() => {
  484. // this.dataSelect()
  485. // },0)
  486. // },2000)
  487. },
  488. destroyed() {
  489. window.clearInterval(this.timer);
  490. if (this.websock) {
  491. this.websock.close(); // 页面销毁后断开websocket连接
  492. }
  493. },
  494. };
  495. </script>
  496. <style scoped>
  497. .whole-wrapper {
  498. display: flex;
  499. background: #fff;
  500. height: 600px;
  501. position: relative;
  502. }
  503. .top-group {
  504. padding-bottom: 30px;
  505. padding-top: 10px;
  506. }
  507. /* 左边部分 */
  508. .left_whole_wrapper {
  509. display: flex;
  510. flex-direction: column;
  511. width: 24%;
  512. }
  513. .left_wrapper {
  514. flex: 1;
  515. background-color: #ebe9e8;
  516. }
  517. .left-item {
  518. display: flex;
  519. justify-content: space-between;
  520. padding: 18px 24px;
  521. background-color: #e9e7e6;
  522. }
  523. .left-item.blue {
  524. background-color: #c3c3c4;
  525. }
  526. .active {
  527. background: #ebebeb;
  528. }
  529. .left-item-left {
  530. display: flex;
  531. }
  532. .left-item-head>img {
  533. width: 48px;
  534. height: 48px;
  535. }
  536. .left-item-info {
  537. margin-left: 12px;
  538. max-width: 135px;
  539. display: flex;
  540. flex-direction: column;
  541. justify-content: space-around;
  542. }
  543. .left-item-info_title {
  544. font-size: 14px;
  545. font-family: PingFang SC, PingFang SC-Regular;
  546. font-weight: 400;
  547. text-align: left;
  548. color: #292929;
  549. /* 文字超出处理 */
  550. white-space: nowrap;
  551. overflow: hidden;
  552. text-overflow: ellipsis;
  553. }
  554. .left-item-info_content {
  555. font-size: 14px;
  556. font-family: PingFang SC, PingFang SC-Regular;
  557. font-weight: 400;
  558. text-align: left;
  559. color: #909090;
  560. margin-top: 4px;
  561. /* 文字超出处理 */
  562. white-space: nowrap;
  563. overflow: hidden;
  564. text-overflow: ellipsis;
  565. }
  566. .left-item-time {
  567. display: flex;
  568. flex-direction: column;
  569. text-align: right;
  570. align-items: flex-end;
  571. }
  572. .left-item-time-time {
  573. font-size: 14px;
  574. font-family: PingFang SC, PingFang SC-Regular;
  575. font-weight: 400;
  576. text-align: right;
  577. color: #909090;
  578. }
  579. .left-item-time-number {
  580. width: 20px;
  581. height: 20px;
  582. line-height: 20px;
  583. border-radius: 50%;
  584. background: #ff4949;
  585. color: #ffffff;
  586. text-align: center;
  587. font-size: 12px;
  588. font-family: PingFang SC, PingFang SC-Regular;
  589. font-weight: 400;
  590. margin-top: 5px;
  591. }
  592. .search {
  593. padding: 46px 24px;
  594. height: 5%;
  595. background-color: #eeebe8;
  596. }
  597. /* 中间部分*/
  598. .center_whole_wrapper {
  599. flex: 1;
  600. background: #f5f5f5;
  601. }
  602. .center_wrapper {
  603. height: 100%;
  604. display: flex;
  605. flex-direction: column;
  606. }
  607. .center_wrapper_top {
  608. display: flex;
  609. align-items: center;
  610. padding: 30px 24px;
  611. flex: 1;
  612. position: relative;
  613. }
  614. .center_wrapper_top_name {
  615. font-size: 18px;
  616. font-family: PingFang SC, PingFang SC-Bold;
  617. font-weight: 700;
  618. text-align: left;
  619. color: #292929;
  620. }
  621. .center_wrapper_top_number {
  622. font-size: 14px;
  623. font-family: PingFang SC, PingFang SC-Regular;
  624. font-weight: 400;
  625. text-align: left;
  626. color: #292929;
  627. margin-left: 12px;
  628. }
  629. .center_wrapper_center {
  630. flex: 10;
  631. padding: 30px 24px 0px 24px;
  632. border-top: 1px solid #ececec;
  633. border-bottom: 1px solid #ececec;
  634. }
  635. .center_wrapper_center_item {
  636. display: flex;
  637. margin-bottom: 32px;
  638. }
  639. .center_wrapper_right {
  640. flex: 4;
  641. background-color: #ffffff;
  642. padding: 20px 20px;
  643. position: relative;
  644. border-right: 1px solid #ececec;
  645. border-bottom: 1px solid #ececec;
  646. }
  647. .center-item-info_wrapper {
  648. margin: 0px 16px;
  649. }
  650. .center-item-tip {
  651. display: flex;
  652. align-items: center;
  653. }
  654. .error-tip>img {
  655. width: 20px;
  656. margin: 0 10px;
  657. }
  658. .center_wrapper_center_item .center-item-info {
  659. background: #ffffff;
  660. border-radius: 3px;
  661. }
  662. .center_wrapper_center_item_reserve .center-item-info {
  663. background: #9eea6a;
  664. border-radius: 3px;
  665. }
  666. .center-item-info {
  667. max-width: 336px;
  668. font-size: 14px;
  669. font-family: PingFang SC, PingFang SC-Regular;
  670. font-weight: 400;
  671. text-align: left;
  672. color: #333333;
  673. line-height: 22px;
  674. padding: 16px;
  675. }
  676. .center-item-time {
  677. font-size: 12px;
  678. font-family: PingFang SC, PingFang SC-Regular;
  679. font-weight: 400;
  680. text-align: left;
  681. color: #909090;
  682. line-height: 22px;
  683. margin-top: 12px;
  684. }
  685. /* 反向样式开始*/
  686. .center_wrapper_center_item_reserve {
  687. display: flex;
  688. flex-direction: row-reverse;
  689. margin-bottom: 32px;
  690. }
  691. .center_wrapper_center_item_reserve .center-item-time {
  692. text-align: right;
  693. }
  694. .center_wrapper_center_item_reserve {
  695. display: flex;
  696. flex-direction: row-reverse;
  697. margin-bottom: 32px;
  698. }
  699. .center_wrapper_center_item_reserve .center-item-tip {
  700. display: flex;
  701. flex-direction: row-reverse;
  702. align-items: center;
  703. }
  704. .center_wrapper_center_item_reserve .error-tip>img {
  705. width: 20px;
  706. margin: 0 10px;
  707. }
  708. /* 反向样式结束*/
  709. /* 右边样式 */
  710. .right_whole_wrapper {
  711. background: #fff;
  712. }
  713. .right_wrapper {
  714. flex: 1;
  715. }
  716. .right_wrapper_center {
  717. border: none;
  718. color: #909090;
  719. }
  720. .center-item-name {
  721. font-size: 12px;
  722. }
  723. .center-item-info {
  724. word-wrap: bre省钱兄-word;
  725. word-bre省钱兄: bre省钱兄-all;
  726. }
  727. .center-item-info_img {
  728. width: 150px;
  729. /* height: 100px; */
  730. }
  731. .center-item-info_img>img {
  732. width: 100%;
  733. height: 100%;
  734. }
  735. /* 几个图标 */
  736. .icon-list {
  737. display: flex;
  738. }
  739. .icon-list>div:not(:first-child) {
  740. margin-left: 15px;
  741. }
  742. .icon-item-img {
  743. width: 25px;
  744. }
  745. /* 修改组件样式 */
  746. .whole-wrapper>>>.el-input__inner {
  747. border-radius: 5px;
  748. }
  749. .whole-wrapper>>>.el-textarea__inner {
  750. min-height: 80px;
  751. resize: none;
  752. border: none;
  753. background: #ffffff;
  754. padding: 5px 0px;
  755. }
  756. .whole-wrapper>>>.el-button--primary {
  757. width: 100px;
  758. height: 40px;
  759. position: absolute;
  760. bottom: 20px;
  761. right: 20px;
  762. }
  763. .loading {
  764. text-align: center;
  765. color: #909090;
  766. }
  767. .loading span {
  768. margin-left: 10px;
  769. }
  770. .center_wrapper_center_item_reserve,
  771. .center_wrapper_center_item {
  772. position: relative;
  773. }
  774. .center_wrapper_center_item_reserve .center-item-info::after {
  775. content: "";
  776. position: absolute;
  777. right: 55px;
  778. top: 12px;
  779. width: 0;
  780. height: 0;
  781. border: 5px solid #9eea6a;
  782. border-top-color: transparent;
  783. border-right-color: transparent;
  784. border-bottom-color: transparent;
  785. }
  786. .center_wrapper_center_item .center-item-info::after {
  787. content: "";
  788. position: absolute;
  789. left: 55px;
  790. top: 12px;
  791. width: 0;
  792. height: 0;
  793. border: 5px solid #ffffff;
  794. border-top-color: transparent;
  795. border-left-color: transparent;
  796. border-bottom-color: transparent;
  797. }
  798. </style>
  799. <style lang="scss">
  800. /* el-popover是和app同级的,所以scoped的局部属性设置了无效 */
  801. /* 需要设置全局style */
  802. .el-popover {
  803. height: 200px;
  804. width: 400px;
  805. overflow: scroll;
  806. overflow-x: auto;
  807. font-size: 20px;
  808. }
  809. </style>