wangmengwei 2 bulan lalu
induk
melakukan
f52131fb0c
100 mengubah file dengan 2840 tambahan dan 14 penghapusan
  1. 5 3
      ruoyi-ui/src/api/login.js
  2. 8 0
      ruoyi-ui/src/api/tool/gen.js
  3. 19 0
      ruoyi-ui/src/api/wuguan/staffManage.js
  4. 9 0
      ruoyi-ui/src/api/zhihuixy/tenant.js
  5. TEMPAT SAMPAH
      ruoyi-ui/src/assets/images/pic_sy_wsxx_bgs.png
  6. TEMPAT SAMPAH
      ruoyi-ui/src/assets/images/renyuandelet.png
  7. 55 0
      ruoyi-ui/src/components/Comment/Avatar.vue
  8. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/aini.gif
  9. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/baibai.gif
  10. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/baiyan.gif
  11. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/baobao.gif
  12. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/beishang.gif
  13. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/bishi.gif
  14. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/bizui.gif
  15. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/caonima.gif
  16. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/chanzui.gif
  17. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/chijing.gif
  18. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/dangao.gif
  19. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/fahongbao.gif
  20. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/fennu.gif
  21. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/fuyun.gif
  22. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/ganmao.gif
  23. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/geili.gif
  24. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/good.gif
  25. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/guzhang.gif
  26. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/haha.gif
  27. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/haixiu.gif
  28. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/han.gif
  29. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/haqian.gif
  30. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/heixian.gif
  31. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/heng.gif
  32. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/huatong.gif
  33. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/hufen.gif
  34. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/jiong.gif
  35. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/jiyan.gif
  36. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/keai.gif
  37. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/kelian.gif
  38. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/ku.gif
  39. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/kun.gif
  40. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/lai.gif
  41. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/lazhu.gif
  42. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/lei.gif
  43. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/no.gif
  44. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/nu.gif
  45. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/numa.gif
  46. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/ok.gif
  47. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/qian.gif
  48. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/qinqin.gif
  49. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/ruo.gif
  50. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/se.gif
  51. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shangxin.gif
  52. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shengbing.gif
  53. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shenma.gif
  54. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shiwang.gif
  55. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shuai.gif
  56. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shudaizi.gif
  57. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/shui.gif
  58. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/sikao.gif
  59. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/taikaixin.gif
  60. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/touxiao.gif
  61. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/tu.gif
  62. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/tuzi.gif
  63. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/wabi.gif
  64. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/weiguan.gif
  65. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/weiqu.gif
  66. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/weiwu.gif
  67. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/weixiao.gif
  68. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/xin.gif
  69. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/xiongmao.gif
  70. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/xixi.gif
  71. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/xu.gif
  72. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/ye.gif
  73. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/yinxian.gif
  74. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/yiwen.gif
  75. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/youhengheng.gif
  76. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/yun.gif
  77. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/zan.gif
  78. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/zhu.gif
  79. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/zhuakuang.gif
  80. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/face/zuohengheng.gif
  81. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/hbl.jpg
  82. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/icon/avatar.jpg
  83. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/icon/avtar.png
  84. TEMPAT SAMPAH
      ruoyi-ui/src/components/Comment/img/icon/reply.png
  85. 1356 0
      ruoyi-ui/src/components/Comment/index.vue
  86. 2 1
      ruoyi-ui/src/components/FileUpload/index.vue
  87. 223 0
      ruoyi-ui/src/components/FileUploadh/index.vue
  88. 2 1
      ruoyi-ui/src/components/FileUploads/index.vue
  89. 2 1
      ruoyi-ui/src/components/FileUploadsch/index.vue
  90. 222 0
      ruoyi-ui/src/components/FileUploadvio/index.vue
  91. 3 2
      ruoyi-ui/src/components/ImageUpload/index.vue
  92. 3 2
      ruoyi-ui/src/components/ImageUploads/index.vue
  93. 324 0
      ruoyi-ui/src/components/ImageUploadshib/index.vue
  94. 3 2
      ruoyi-ui/src/components/ImageUploadslis/index.vue
  95. 2 1
      ruoyi-ui/src/components/ImageUploadxy/index.vue
  96. 232 0
      ruoyi-ui/src/components/ImageUploadyuang/index.vue
  97. 360 0
      ruoyi-ui/src/components/vue-ueditor-wrap.vue
  98. 1 1
      ruoyi-ui/src/layout/components/Navbar.vue
  99. 7 0
      ruoyi-ui/src/main.js
  100. 2 0
      ruoyi-ui/src/store/getters.js

+ 5 - 3
ruoyi-ui/src/api/login.js

@@ -8,18 +8,20 @@ const clientId = process.env.VUE_APP_CLIENT_ID
  * @param data {LoginData}
  * @returns
  */
-export function login(username, password, code, uuid,tenantId) {
+export function login(username, password, code, uuid,tenantId,grantType,phonenumber,smsCode) {
 	const data = {
 	  username,
 	  password,
 	  code,
 	  uuid,
-	  tenantId
+	  tenantId,
+    grantType,
+    phonenumber,
+    smsCode
 	}
   const params = {
     ...data,
     clientId: data.clientId || clientId,
-    grantType: data.grantType || 'password'
   };
   return request({
     url: '/auth/login',

+ 8 - 0
ruoyi-ui/src/api/tool/gen.js

@@ -43,6 +43,14 @@ export function importTable(data) {
   })
 }
 
+export function getDataNames() {
+  return request({
+    url: '/tool/gen/getDataNames' ,
+    method: 'get'
+  })
+}
+
+
 // 预览生成代码
 export function previewTable(tableId) {
   return request({

+ 19 - 0
ruoyi-ui/src/api/wuguan/staffManage.js

@@ -8,6 +8,16 @@ export function listStaffManage(query) {
     params: query
   })
 }
+// 查询员工管理列表
+export function listStaffManagesh(query) {
+  return request({
+    url: '/wuYe/staffManage/list',
+    method: 'get',
+    params: query
+  })
+}
+
+
 
 export function listStaffManageNoPage(query) {
   return request({
@@ -17,6 +27,15 @@ export function listStaffManageNoPage(query) {
   })
 }
 
+// 注册认证
+export function examineStaff(data) {
+  return request({
+    url: '/wuYe/staffManage/examineStaff',
+    method: 'post',
+    data: data
+  })
+}
+
 
 
 // 查询员工管理详细

+ 9 - 0
ruoyi-ui/src/api/zhihuixy/tenant.js

@@ -17,6 +17,15 @@ export function getTenant(id){
   });
 }
 
+
+export function syncTenantPackaget(query) {
+  return request({
+    url: '/system/tenant/syncTenantDict',
+    method: 'get',
+    params: query
+  });
+}
+
 // 新增租户
 export function addTenant(data) {
   return request({

TEMPAT SAMPAH
ruoyi-ui/src/assets/images/pic_sy_wsxx_bgs.png


TEMPAT SAMPAH
ruoyi-ui/src/assets/images/renyuandelet.png


+ 55 - 0
ruoyi-ui/src/components/Comment/Avatar.vue

@@ -0,0 +1,55 @@
+<template>
+	<div class="user">
+		<div class="user-img" v-if="jsegs"><img :src="avatar? baseUrl + avatar:require('./img/icon/avatar.jpg')"/></div>
+    <div class="user-img" v-if="!jsegs"><img :src="avatar?avatar:require('./img/icon/avatar.jpg')"/></div>
+	</div>
+</template>
+
+
+<script>
+  const defaultSettings = require("@/settings.js");
+   // const defaultSettings = '../../settings.js'
+	export default {
+	  props:{
+	  	avatar:{
+	  		type:String,
+	  		default:''
+	  	}
+	  },
+	  data() {
+	    return {
+	      comment: '',
+        baseUrl:process.env.VUE_APP_BASE_API,
+        defaultSettings:defaultSettings,
+        jsegs:false,
+        avatar:avatar
+	    }
+	  },
+    created() {
+      this.baseUrl = process.env.VUE_APP_BASE_API
+      this.avatar = this.avatar
+      // console.log(this.defaultSettings,process.env.VUE_APP_BASE_API,this.baseUrl)
+      if(this.avatar =='/static/img/profile.473f5971.jpg'){
+        this.jsegs = false
+      }else{
+        this.jsegs = true
+      }
+      // console.log(this.jsegs,34)
+    },
+
+
+	}
+</script>
+
+<style type="text/css" scoped>
+	.user{
+		height: 50px;
+		width: 50px;
+	}
+	.user-img img{
+		height: 45px;
+		width: 45px;
+		border-radius:50%;
+	}
+
+</style>

TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/aini.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/baibai.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/baiyan.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/baobao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/beishang.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/bishi.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/bizui.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/caonima.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/chanzui.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/chijing.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/dangao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/fahongbao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/fennu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/fuyun.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/ganmao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/geili.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/good.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/guzhang.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/haha.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/haixiu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/han.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/haqian.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/heixian.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/heng.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/huatong.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/hufen.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/jiong.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/jiyan.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/keai.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/kelian.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/ku.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/kun.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/lai.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/lazhu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/lei.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/no.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/nu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/numa.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/ok.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/qian.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/qinqin.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/ruo.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/se.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shangxin.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shengbing.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shenma.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shiwang.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shuai.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shudaizi.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/shui.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/sikao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/taikaixin.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/touxiao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/tu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/tuzi.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/wabi.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/weiguan.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/weiqu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/weiwu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/weixiao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/xin.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/xiongmao.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/xixi.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/xu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/ye.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/yinxian.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/yiwen.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/youhengheng.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/yun.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/zan.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/zhu.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/zhuakuang.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/face/zuohengheng.gif


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/hbl.jpg


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/icon/avatar.jpg


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/icon/avtar.png


TEMPAT SAMPAH
ruoyi-ui/src/components/Comment/img/icon/reply.png


+ 1356 - 0
ruoyi-ui/src/components/Comment/index.vue

@@ -0,0 +1,1356 @@
+<template>
+  <div class="hbl-fa">
+    <div class="hbl-comm">
+      <div class="comment-avatar" v-if="showAvatar">
+        <avatar :avatar="avatar"></avatar>
+      </div>
+      <div class="comment" :style="{ width: commentWidth }">
+        <el-input
+          @focus="showButton(0)"
+          type="textarea"
+          :autosize="{ minRows: minRows, maxRows: maxRows }"
+          :placeholder="placeholder"
+          v-model="textareaMap[0]"
+        >
+        </el-input>
+
+        <div v-if="buttonMap[0]" class="hbl-owo">
+          <div
+            :class="pBodyMap[0] ? 'OwO' : 'OwO OwO-open'"
+            class="emoj publish"
+            :style="{ width: emojiWidth }"
+          >
+            <div class="OwO-logo" @click="pBodyStatus(0)">
+              <span @blur="blur">Emoji表情</span>
+            </div>
+            <div class="OwO-body">
+              <ul class="OwO-items OwO-items-show">
+                <li
+                  class="OwO-item"
+                  v-for="(oitem, index) in OwOlist"
+                  :key="'oitem' + index"
+                  @click="choseEmoji(0, oitem.title)"
+                >
+                  <img :src="require('./img/face/' + oitem.url)" alt="" />
+                </li>
+              </ul>
+            </div>
+          </div>
+
+          <div class="publish publish-btn">
+            <button class="btn" @click="doSend()">发送</button>
+            <button @click="cancel(0)" class="btn btn-cancel">取消</button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="comm">
+      <div class="su com-rep"></div>
+      <div class="com-rep com-title">
+        评论<span class="com-span">({{ commentNum }})</span>
+      </div>
+    </div>
+
+    <div v-for="(item, index) in commentList" class="hbl-child">
+      <div class="reply"></div>
+      <div class="content">
+        <div class="comment-f">
+         <avatar
+            :avatar="item.commentUser.avatar !=undefined ? item.commentUser.avatar : avatar"
+          ></avatar>
+        </div>
+
+        <div class="comment-f">
+          <div>
+            <div class="nickname author">
+              {{ item.commentUser.nickName == null?'暂无数据' :  item.commentUser.nickName}}
+            </div>
+            <div v-if="item.commentUser.id === authorId" class="icon author">
+              {{ label }}
+            </div>
+            <div class="date">
+              {{ item.createTime }}
+            </div>
+          </div>
+        </div>
+
+        <div class="reply-content" v-html="analyzeEmoji(item.content)">
+          {{ analyzeEmoji(item.content) }}
+        </div>
+        <div class="reply-content reply-fa">
+          <div style="display: flex;align-items: center;">
+            <div class="reply-font" @click="doReply(item.id)">
+              <div style="display: flex;align-items: center;">
+                <img src="../../assets/images/huifu.png" class="icon-reply" style="width: 18px;height: 18px;margin-right: 5px;" /><font
+                  class="icon-reply icon-hf"
+                  >回复</font>
+              </div>
+            </div>
+            <div class="reply-font" @click="doReplydiab(item.id,item)" style="margin-left: 10px;">
+              <div style="display: flex;align-items: center;">
+                <img src="../../assets/images/dianzanz.png" class="icon-reply" style="width: 18px;height: 18px;margin-right: 5px;" v-if="item.isLike =='Y'" />
+                <img src="../../assets/images/dianzan.png" class="icon-reply" style="width: 18px;height: 18px;margin-right: 5px;" v-else/>
+                <font
+                  class="icon-reply icon-hf"
+                  v-if="item.isLike =='Y'"
+                  >点赞</font>
+                  <font
+                    class="icon-reply icon-hf"
+                    v-if="item.isLike !='Y'"
+                    >{{item.likeCount == 0 ?'点': item.likeCount}}赞</font
+                >
+              </div>
+            </div>
+            <div v-if="item.isMyself == 'Y'" class="reply-font" @click="doReplydiabs(item.id,item)" style="margin-left: 10px;">
+              <div style="display: flex;align-items: center;">
+                <img src="../../assets/images/dele.png" class="icon-reply" style="width: 20px;height: 20px;margin-right: 5px;"/><font
+                  class="icon-reply icon-hf"
+                  >删除</font
+                >
+              </div>
+            </div>
+            <div class="reply-font" @click="doReplydiabh(item.id,item)" style="margin-left: 10px;">
+              <div style="display: flex;align-items: center;" v-if="item.iss == true">
+                <img src="../../assets/images/genduo.png" class="icon-reply" style="width: 15px;height: 15px;margin-right: 5px;" v-if="item.childrenListCount !=0"/>
+                <img src="../../assets/images/shouqi.png" class="icon-reply" style="width: 15px;height: 15px;margin-right: 5px;" v-if="item.childrenListCount ==0"/>
+                  <font
+                    class="icon-reply icon-hf"
+                    v-if="item.childrenListCount !=0"
+                    >展开{{item.childrenListCount}}条回复</font
+                  >
+                  <font
+                    class="icon-reply icon-hf"
+                    v-if="item.childrenListCount ==0"
+                    >收起</font
+                  >
+              </div>
+            </div>
+          </div>
+
+
+          <div
+            class="comment"
+            :style="{ width: commentWidth }"
+            v-if="replyMap[item.id]"
+            :showAvatar="showAvatar"
+          >
+            <el-input
+              @focus="showButton(item.id)"
+              type="textarea"
+              :autosize="{ minRows: minRows, maxRows: maxRows }"
+              :placeholder="placeholder"
+              v-model="textareaMap[item.id]"
+            >
+            </el-input>
+
+            <div v-if="buttonMap[item.id]" class="hbl-owo">
+              <div
+                :class="pBodyMap[item.id] ? 'OwO' : 'OwO OwO-open'"
+                class="emoj publish"
+                :style="{ width: emojiWidth }"
+              >
+                <div class="OwO-logo" @click="pBodyStatus(item.id)">
+                  <span>Emoji表情</span>
+                </div>
+                <div class="OwO-body">
+                  <ul class="OwO-items OwO-items-show">
+                    <li
+                      class="OwO-item"
+                      v-for="(oitem, index) in OwOlist"
+                      :key="'oitem' + index"
+                      @click="choseEmoji(item.id, oitem.title)"
+                    >
+                      <img :src="require('./img/face/' + oitem.url)" alt="" />
+                    </li>
+                  </ul>
+                </div>
+              </div>
+
+              <div class="publish publish-btn">
+                <button
+                  class="btn"
+                  @click="doChidSend(item.id, item.commentUser.id, item.id,item)"
+                >
+                  发送
+                </button>
+                <button @click="cancel(item.id)" class="btn btn-cancel">
+                  取消
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="children" v-for="(ritem, jndex) in item.childrenList">
+        <div class="reply"></div>
+        <div class="content">
+          <div class="comment-f">
+            <avatar
+              :avatar="
+                ritem.commentUser.avatar ? ritem.commentUser.avatar : avatar
+              "
+            ></avatar>
+          </div>
+
+          <div class="comment-f">
+            <div>
+              <div class="nickname author">
+                {{ ritem.commentUser.nickName }}
+              </div>
+              <div v-if="ritem.commentUser.id === authorId" class="icon author">
+                {{ label }}
+              </div>
+              <div class="date">
+                {{ ritem.createTime }}
+              </div>
+            </div>
+          </div>
+
+          <div class="reply-content">
+            <div class="cc cc-to">
+              <a href="#">@{{ ritem.targetUser.nickName + '\u2003' }}   </a>
+            </div>
+
+            <div class="cc" v-html="analyzeEmoji(ritem.content)">
+              {{ analyzeEmoji(ritem.content) }}
+            </div>
+          </div>
+
+          <div class="reply-content reply-fa">
+            <div style="display: flex;">
+              <div class="reply-font" @click="doReply(ritem.id,ritem)">
+                <div style="display: flex;align-items: center;">
+                  <img src="../../assets/images/huifu.png" class="icon-reply" style="width: 18px;height: 18px;margin-right: 5px;" /><font
+                    class="icon-reply icon-hf"
+                    >回复</font
+                  >
+                </div>
+              </div>
+              <div class="reply-font" @click="doReplydiab(ritem.id,ritem)" style="margin-left: 10px;">
+                <div style="display: flex;align-items: center;">
+                 <img src="../../assets/images/dianzanz.png" class="icon-reply" style="width: 18px;height: 18px;margin-right: 5px;" v-if="ritem.isLike =='Y'" />
+                 <img src="../../assets/images/dianzan.png" class="icon-reply" style="width: 18px;height: 18px;margin-right: 5px;" v-else/>
+                 <font
+                   class="icon-reply icon-hf"
+                   v-if="ritem.isLike =='Y'"
+                   >点赞</font>
+                   <font
+                     class="icon-reply icon-hf"
+                     v-if="ritem.isLike !='Y'"
+                     >{{ritem.likeCount == 0 ?'点': ritem.likeCount}}赞</font
+                 >
+                </div>
+              </div>
+              <div v-if="ritem.isMyself == 'Y'" class="reply-font" @click="doReplydiabs(ritem.id,ritem)" style="margin-left: 10px;">
+                <div style="display: flex;align-items: center;">
+                  <img src="../../assets/images/dele.png" class="icon-reply" style="width: 20px;height: 20px;margin-right: 5px;"/><font
+                    class="icon-reply icon-hf"
+                    >删除</font
+                  >
+                </div>
+              </div>
+            </div>
+
+            <div
+              class="comment"
+              :style="{ width: commentWidth }"
+              v-if="replyMap[ritem.id]"
+              :showAvatar="showAvatar"
+            >
+              <el-input
+                @focus="showButton(ritem.id)"
+                type="textarea"
+                :autosize="{ minRows: minRows, maxRows: maxRows }"
+                :placeholder="placeholder"
+                v-model="textareaMap[ritem.id]"
+              >
+              </el-input>
+
+              <div v-if="buttonMap[ritem.id]" class="hbl-owo">
+                <div
+                  :class="pBodyMap[ritem.id] ? 'OwO' : 'OwO OwO-open'"
+                  class="emoj publish"
+                  :style="{ width: emojiWidth }"
+                >
+                  <div class="OwO-logo" @click="pBodyStatus(ritem.id)">
+                    <span>Emoji表情</span>
+                  </div>
+                  <div class="OwO-body">
+                    <ul class="OwO-items OwO-items-show">
+                      <li
+                        class="OwO-item"
+                        v-for="(oitem, index) in OwOlist"
+                        :key="'oitem' + index"
+                        @click="choseEmoji(ritem.id, oitem.title)"
+                      >
+                        <img :src="require('./img/face/' + oitem.url)" alt="" />
+                      </li>
+                    </ul>
+                  </div>
+                </div>
+                <div class="publish publish-btn">
+                  <button
+                    class="btn"
+                    @click="doChidSend(ritem.id, ritem.commentUser.id, item.id,ritem)"
+                  >
+                    发送
+                  </button>
+                  <button @click="cancel(ritem.id)" class="btn btn-cancel">
+                    取消
+                  </button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import avatar from "./Avatar.vue";
+export default {
+  props: {
+    emojiWidth: {
+      type: String,
+      default: "560px",
+    },
+    showAvatar: {
+      type: Boolean,
+      default: false,
+    },
+    avatar: {
+      type: String,
+      default: "",
+    },
+    placeholder: {
+      type: String,
+      default: "在此输入评论内容...",
+    },
+    minRows: {
+      type: Number,
+      default: 4,
+    },
+    maxRows: {
+      type: Number,
+      default: 8,
+    },
+    commentNum: {
+      type: Number,
+      default: 2,
+    },
+    authorId: {
+      type: Number,
+      default: 1,
+    },
+    label: {
+      type: String,
+      default: "作者",
+    },
+    commentList: {
+      type: Array,
+      default: () => [
+        {
+          id: 1,
+          commentUser: {
+            id: 1,
+            nickName: "花非花",
+            avatar:
+              "http://qzapp.qlogo.cn/qzapp/101483738/6637A2B6611592A44A7699D14E13F7F7/50",
+          },
+          content:
+            "<a style='text-decoration:none;color: #409eff ' href='https://blog.csdn.net/qq_40942490?spm=1000.2115.3001.5113'>我的CSDN博客地址</a>[害羞][害羞][害羞]<br/>",
+          createDate: "2019-9-23 17:36:02",
+          childrenList: [
+            {
+              id: 2,
+              commentUser: {
+                id: 2,
+                nickName: "坏菠萝",
+                avatar: "",
+              },
+              targetUser: {
+                id: 1,
+                nickName: "花非花",
+                avatar:
+                  "http://qzapp.qlogo.cn/qzapp/101483738/6637A2B6611592A44A7699D14E13F7F7/50",
+              },
+              content: "真的就很棒!很Nice![爱你]",
+              createDate: "2019-9-23 17:45:26",
+            },
+          ],
+        },
+        {
+          id: 3,
+          commentUser: {
+            id: 1,
+            nickName: "花非花",
+            avatar:
+              "http://qzapp.qlogo.cn/qzapp/101483738/6637A2B6611592A44A7699D14E13F7F7/50",
+          },
+          content:
+            "<a style='text-decoration:none;color: #409eff ' href='https://blog.csdn.net/qq_40942490?spm=1000.2115.3001.5113'>我的CSDN博客地址</a>[害羞][害羞][害羞]<br/>",
+          createDate: "2019-9-23 17:36:02",
+          childrenList: [
+            {
+              id: 4,
+              commentUser: {
+                id: 2,
+                nickName: "坏菠萝",
+                avatar: "",
+              },
+              targetUser: {
+                id: 1,
+                nickName: "花非花",
+                avatar:
+                  "http://qzapp.qlogo.cn/qzapp/101483738/6637A2B6611592A44A7699D14E13F7F7/50",
+              },
+              content: "真的就很棒!很Nice![爱你]",
+              createDate: "2019-9-23 17:45:26",
+            },
+          ],
+        },
+      ],
+    },
+    commentWidth: {
+      type: String,
+      default: "80%",
+    },
+  },
+  data() {
+    return {
+      replyMap: [],
+      buttonMap: [],
+      pBodyMap: [],
+      textareaMap: [],
+      OwOlist: [
+        //表情包和表情路径
+        { title: "微笑", url: "weixiao.gif" },
+        { title: "嘻嘻", url: "xixi.gif" },
+        { title: "哈哈", url: "haha.gif" },
+        { title: "可爱", url: "keai.gif" },
+        { title: "可怜", url: "kelian.gif" },
+        { title: "挖鼻", url: "wabi.gif" },
+        { title: "吃惊", url: "chijing.gif" },
+        { title: "害羞", url: "haixiu.gif" },
+        { title: "挤眼", url: "jiyan.gif" },
+        { title: "闭嘴", url: "bizui.gif" },
+        { title: "鄙视", url: "bishi.gif" },
+        { title: "爱你", url: "aini.gif" },
+        { title: "泪", url: "lei.gif" },
+        { title: "偷笑", url: "touxiao.gif" },
+        { title: "亲亲", url: "qinqin.gif" },
+        { title: "生病", url: "shengbing.gif" },
+        { title: "太开心", url: "taikaixin.gif" },
+        { title: "白眼", url: "baiyan.gif" },
+        { title: "右哼哼", url: "youhengheng.gif" },
+        { title: "左哼哼", url: "zuohengheng.gif" },
+        { title: "嘘", url: "xu.gif" },
+        { title: "衰", url: "shuai.gif" },
+        { title: "吐", url: "tu.gif" },
+        { title: "哈欠", url: "haqian.gif" },
+        { title: "抱抱", url: "baobao.gif" },
+        { title: "怒", url: "nu.gif" },
+        { title: "疑问", url: "yiwen.gif" },
+        { title: "馋嘴", url: "chanzui.gif" },
+        { title: "拜拜", url: "baibai.gif" },
+        { title: "思考", url: "sikao.gif" },
+        { title: "汗", url: "han.gif" },
+        { title: "困", url: "kun.gif" },
+        { title: "睡", url: "shui.gif" },
+        { title: "钱", url: "qian.gif" },
+        { title: "失望", url: "shiwang.gif" },
+        { title: "酷", url: "ku.gif" },
+        { title: "色", url: "se.gif" },
+        { title: "哼", url: "heng.gif" },
+        { title: "鼓掌", url: "guzhang.gif" },
+        { title: "晕", url: "yun.gif" },
+        { title: "悲伤", url: "beishang.gif" },
+        { title: "抓狂", url: "zhuakuang.gif" },
+        { title: "黑线", url: "heixian.gif" },
+        { title: "阴险", url: "yinxian.gif" },
+        { title: "怒骂", url: "numa.gif" },
+        { title: "互粉", url: "hufen.gif" },
+        { title: "书呆子", url: "shudaizi.gif" },
+        { title: "愤怒", url: "fennu.gif" },
+        { title: "感冒", url: "ganmao.gif" },
+        { title: "心", url: "xin.gif" },
+        { title: "伤心", url: "shangxin.gif" },
+        { title: "猪", url: "zhu.gif" },
+        { title: "熊猫", url: "xiongmao.gif" },
+        { title: "兔子", url: "tuzi.gif" },
+        { title: "喔克", url: "ok.gif" },
+        { title: "耶", url: "ye.gif" },
+        { title: "棒棒", url: "good.gif" },
+        { title: "不", url: "no.gif" },
+        { title: "赞", url: "zan.gif" },
+        { title: "来", url: "lai.gif" },
+        { title: "弱", url: "ruo.gif" },
+        { title: "草泥马", url: "caonima.gif" },
+        { title: "神马", url: "shenma.gif" },
+        { title: "囧", url: "jiong.gif" },
+        { title: "浮云", url: "fuyun.gif" },
+        { title: "给力", url: "geili.gif" },
+        { title: "围观", url: "weiguan.gif" },
+        { title: "威武", url: "weiwu.gif" },
+        { title: "话筒", url: "huatong.gif" },
+        { title: "蜡烛", url: "lazhu.gif" },
+        { title: "蛋糕", url: "dangao.gif" },
+        { title: "发红包", url: "fahongbao.gif" },
+      ],
+    };
+  },
+  components: {
+    avatar,
+  },
+  methods: {
+    //事件处理器
+    blur() {
+      alert("ss");
+    },
+    showButton(index) {
+      //this.showFlag = true;
+      console.log(index + "index");
+      this.$set(this.buttonMap, index, true);
+    },
+    cancel(index) {
+      this.$set(this.buttonMap, index, false);
+      if (index !== 0) {
+        this.$set(this.replyMap, index, false);
+      }
+      console.log(index + "index");
+      //this.showFlag = false;
+    },
+    doSend() {
+      // console.log("====="+this.textareaMap[0]);
+      this.$emit("doSend", this.textareaMap[0]);
+      this.$set(this.textareaMap, 0, "");
+    },
+    doChidSend(index, commentUserId, pid,item) {
+      // console.log(this.textareaMap[index],commentUserId,pid)
+      this.$emit("doChidSend", this.textareaMap[index], commentUserId, pid,item);
+      this.$set(this.replyMap, index, false);
+      this.$set(this.textareaMap, index, "");
+    },
+
+
+
+    //选择表情包
+    choseEmoji: function (index, inner) {
+      var con = "";
+      if (!this.textareaMap[index]) {
+        this.$set(this.textareaMap, index, "");
+      }
+      con = this.textareaMap[index] += "[" + inner + "]";
+      this.$set(this.textareaMap, index, con);
+    },
+    analyzeEmoji: function (cont) {
+      //编译表情替换成图片展示出来
+      var pattern1 = /\[[\u4e00-\u9fa5]+\]/g;
+      var pattern2 = /\[[\u4e00-\u9fa5]+\]/;
+      var content = cont.match(pattern1);
+      var str = cont;
+      if (content) {
+        for (var i = 0; i < content.length; i++) {
+          for (var j = 0; j < this.OwOlist.length; j++) {
+            if ("[" + this.OwOlist[j].title + "]" == content[i]) {
+              var src = this.OwOlist[j].url;
+              break;
+            }
+          }
+          var s = require("./img/face/" + src);
+          var imoj = "<img src='" + s + "'/>";
+
+          str = str.replace(pattern2, imoj);
+        }
+      }
+      return str;
+    },
+    doReply(index) {
+      this.$set(this.replyMap, index, true);
+      console.log(this.replyMap[index]);
+    },
+    doReplydiab(index,row){
+      this.$emit("doReplydiab", index,row);
+      this.$set(this.replyMap, index, false);
+      console.log(this.replyMap[index]);
+    },
+    doReplydiabh(index,row){
+      this.$emit("doReplydiabh", index,row);
+      this.$set(this.replyMap, index, false);
+      console.log(this.replyMap[index]);
+    },
+    doReplydiabs(index,item){
+      this.$emit("doReplydiabs", index,item);
+      this.$set(this.replyMap, index, false);
+      console.log(this.replyMap[index]);
+    },
+    pBodyStatus(index) {
+      this.$set(this.pBodyMap, index, !this.pBodyMap[index]);
+    },
+  },
+  watch: {
+    // 如果路由有变化,会再次执行该方法
+    // '$route':'routeChange'
+  },
+  created() {
+    //生命周期函数
+    console.log(this.commentList)
+  },
+  mounted() {
+    //页面加载完成后
+  },
+};
+</script>
+<style type="text/css" scoped>
+.comment {
+  display: inline-block;
+  vertical-align: top;
+}
+.comment-avatar {
+  display: inline-block;
+  vertical-align: top;
+}
+.emoj {
+  /*width: 560px;*/
+}
+.publish {
+  margin-top: 10px;
+  display: inline-block;
+  vertical-align: top;
+}
+.publish-btn {
+  float: right;
+}
+.btn {
+  width: 70px; /* 宽度 */
+  margin-top: 3px;
+  height: 30px; /* 高度 */
+  border-width: 0px; /* 边框宽度 */
+  border-radius: 3px; /* 边框半径 */
+  background: #3cb371; /* 背景颜色 */
+  cursor: pointer; /* 鼠标移入按钮范围时出现手势 */
+  outline: none; /* 不显示轮廓线 */
+  font-family: Microsoft YaHei; /* 设置字体 */
+  color: white; /* 字体颜色 */
+  font-size: 13px; /* 字体大小 */
+  text-align: center;
+  line-height: 30px;
+  border-radius: 5px;
+  display: inline-block;
+  margin-left: 5px;
+  margin-right: 5px;
+}
+.btn-cancel {
+  background: grey; /* 背景颜色 */
+}
+
+.tmsgBox {
+  position: relative;
+  background: #fff;
+  padding: 15px;
+  margin-bottom: 20px;
+  border-radius: 5px;
+}
+.tmsg-respond h3 {
+  font-size: 18px;
+  font-weight: bold;
+  margin-bottom: 8px;
+}
+.tmsg-respond h3 small {
+  font-size: smaller;
+  cursor: pointer;
+}
+.tmsg-respond textarea {
+  background: #f4f6f7;
+  height: 100px;
+  margin-bottom: 10px;
+}
+
+.OwO {
+  position: relative;
+  z-index: 1;
+}
+.OwO .OwO-logo {
+  position: relative;
+  border-radius: 4px;
+  color: #444;
+  display: inline-block;
+  background: #fff;
+  border: 1px solid #ddd;
+  font-size: 13px;
+  padding: 0 6px;
+  cursor: pointer;
+  height: 30px;
+  box-sizing: border-box;
+  z-index: 2;
+  line-height: 30px;
+}
+.OwO .OwO-logo:hover {
+  animation: a 5s infinite ease-in-out;
+  -webkit-animation: a 5s infinite ease-in-out;
+}
+.OwO .OwO-body {
+  position: absolute;
+  background: #fff;
+  border: 1px solid #ddd;
+  z-index: 1;
+  top: 29px;
+  border-radius: 0 4px 4px 4px;
+  display: none;
+}
+.OwO-open .OwO-body {
+  display: block;
+}
+.OwO-open .OwO-logo {
+  border-radius: 4px 4px 0 0;
+  border-bottom: none;
+}
+.OwO-open .OwO-logo:hover {
+  animation: none;
+  -webkit-animation: none;
+}
+.OwO .OwO-items {
+  max-height: 197px;
+  overflow: scroll;
+  font-size: 0;
+  padding: 10px;
+  z-index: 1;
+}
+.OwO .OwO-items .OwO-item {
+  background: #f7f7f7;
+  padding: 5px 10px;
+  border-radius: 5px;
+  display: inline-block;
+  margin: 0 10px 12px 0;
+  transition: 0.3s;
+  line-height: 19px;
+  font-size: 20px;
+  cursor: pointer;
+}
+.OwO .OwO-items .OwO-item:hover {
+  background: #eee;
+  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2),
+    0 1px 5px 0 rgba(0, 0, 0, 0.12);
+  animation: a 5s infinite ease-in-out;
+  -webkit-animation: a 5s infinite ease-in-out;
+}
+.OwO .OwO-body .OwO-bar {
+  width: 100%;
+  height: 30px;
+  border-top: 1px solid #ddd;
+  background: #fff;
+  border-radius: 0 0 4px 4px;
+  color: #444;
+}
+.OwO .OwO-body .OwO-bar .OwO-packages li {
+  display: inline-block;
+  line-height: 30px;
+  font-size: 14px;
+  padding: 0 10px;
+  cursor: pointer;
+  margin-right: 3px;
+  text-align: center;
+}
+.OwO .OwO-body .OwO-bar .OwO-packages li:first-of-type {
+  border-radius: 0 0 0 3px;
+}
+@-webkit-keyframes a {
+  2% {
+    -webkit-transform: translateY(1.5px) rotate(1.5deg);
+    transform: translateY(1.5px) rotate(1.5deg);
+  }
+  4% {
+    -webkit-transform: translateY(-1.5px) rotate(-0.5deg);
+    transform: translateY(-1.5px) rotate(-0.5deg);
+  }
+  6% {
+    -webkit-transform: translateY(1.5px) rotate(-1.5deg);
+    transform: translateY(1.5px) rotate(-1.5deg);
+  }
+  8% {
+    -webkit-transform: translateY(-1.5px) rotate(-1.5deg);
+    transform: translateY(-1.5px) rotate(-1.5deg);
+  }
+  10% {
+    -webkit-transform: translateY(2.5px) rotate(1.5deg);
+    transform: translateY(2.5px) rotate(1.5deg);
+  }
+  12% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  14% {
+    -webkit-transform: translateY(-1.5px) rotate(1.5deg);
+    transform: translateY(-1.5px) rotate(1.5deg);
+  }
+  16% {
+    -webkit-transform: translateY(-0.5px) rotate(-1.5deg);
+    transform: translateY(-0.5px) rotate(-1.5deg);
+  }
+  18% {
+    -webkit-transform: translateY(0.5px) rotate(-1.5deg);
+    transform: translateY(0.5px) rotate(-1.5deg);
+  }
+  20% {
+    -webkit-transform: translateY(-1.5px) rotate(2.5deg);
+    transform: translateY(-1.5px) rotate(2.5deg);
+  }
+  22% {
+    -webkit-transform: translateY(0.5px) rotate(-1.5deg);
+    transform: translateY(0.5px) rotate(-1.5deg);
+  }
+  24% {
+    -webkit-transform: translateY(1.5px) rotate(1.5deg);
+    transform: translateY(1.5px) rotate(1.5deg);
+  }
+  26% {
+    -webkit-transform: translateY(0.5px) rotate(0.5deg);
+    transform: translateY(0.5px) rotate(0.5deg);
+  }
+  28% {
+    -webkit-transform: translateY(0.5px) rotate(1.5deg);
+    transform: translateY(0.5px) rotate(1.5deg);
+  }
+  30% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  32%,
+  34% {
+    -webkit-transform: translateY(1.5px) rotate(-0.5deg);
+    transform: translateY(1.5px) rotate(-0.5deg);
+  }
+  36% {
+    -webkit-transform: translateY(-1.5px) rotate(2.5deg);
+    transform: translateY(-1.5px) rotate(2.5deg);
+  }
+  38% {
+    -webkit-transform: translateY(1.5px) rotate(-1.5deg);
+    transform: translateY(1.5px) rotate(-1.5deg);
+  }
+  40% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  42% {
+    -webkit-transform: translateY(2.5px) rotate(-1.5deg);
+    transform: translateY(2.5px) rotate(-1.5deg);
+  }
+  44% {
+    -webkit-transform: translateY(1.5px) rotate(0.5deg);
+    transform: translateY(1.5px) rotate(0.5deg);
+  }
+  46% {
+    -webkit-transform: translateY(-1.5px) rotate(2.5deg);
+    transform: translateY(-1.5px) rotate(2.5deg);
+  }
+  48% {
+    -webkit-transform: translateY(-0.5px) rotate(0.5deg);
+    transform: translateY(-0.5px) rotate(0.5deg);
+  }
+  50% {
+    -webkit-transform: translateY(0.5px) rotate(0.5deg);
+    transform: translateY(0.5px) rotate(0.5deg);
+  }
+  52% {
+    -webkit-transform: translateY(2.5px) rotate(2.5deg);
+    transform: translateY(2.5px) rotate(2.5deg);
+  }
+  54% {
+    -webkit-transform: translateY(-1.5px) rotate(1.5deg);
+    transform: translateY(-1.5px) rotate(1.5deg);
+  }
+  56% {
+    -webkit-transform: translateY(2.5px) rotate(2.5deg);
+    transform: translateY(2.5px) rotate(2.5deg);
+  }
+  58% {
+    -webkit-transform: translateY(0.5px) rotate(2.5deg);
+    transform: translateY(0.5px) rotate(2.5deg);
+  }
+  60% {
+    -webkit-transform: translateY(2.5px) rotate(2.5deg);
+    transform: translateY(2.5px) rotate(2.5deg);
+  }
+  62% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  64% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  66% {
+    -webkit-transform: translateY(1.5px) rotate(-0.5deg);
+    transform: translateY(1.5px) rotate(-0.5deg);
+  }
+  68% {
+    -webkit-transform: translateY(-1.5px) rotate(-0.5deg);
+    transform: translateY(-1.5px) rotate(-0.5deg);
+  }
+  70% {
+    -webkit-transform: translateY(1.5px) rotate(0.5deg);
+    transform: translateY(1.5px) rotate(0.5deg);
+  }
+  72% {
+    -webkit-transform: translateY(2.5px) rotate(1.5deg);
+    transform: translateY(2.5px) rotate(1.5deg);
+  }
+  74% {
+    -webkit-transform: translateY(-0.5px) rotate(0.5deg);
+    transform: translateY(-0.5px) rotate(0.5deg);
+  }
+  76% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  78% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  80% {
+    -webkit-transform: translateY(1.5px) rotate(1.5deg);
+    transform: translateY(1.5px) rotate(1.5deg);
+  }
+  82% {
+    -webkit-transform: translateY(-0.5px) rotate(0.5deg);
+    transform: translateY(-0.5px) rotate(0.5deg);
+  }
+  84% {
+    -webkit-transform: translateY(1.5px) rotate(2.5deg);
+    transform: translateY(1.5px) rotate(2.5deg);
+  }
+  86% {
+    -webkit-transform: translateY(-1.5px) rotate(-1.5deg);
+    transform: translateY(-1.5px) rotate(-1.5deg);
+  }
+  88% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  90% {
+    -webkit-transform: translateY(2.5px) rotate(-0.5deg);
+    transform: translateY(2.5px) rotate(-0.5deg);
+  }
+  92% {
+    -webkit-transform: translateY(0.5px) rotate(-0.5deg);
+    transform: translateY(0.5px) rotate(-0.5deg);
+  }
+  94% {
+    -webkit-transform: translateY(2.5px) rotate(0.5deg);
+    transform: translateY(2.5px) rotate(0.5deg);
+  }
+  96% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  98% {
+    -webkit-transform: translateY(-1.5px) rotate(-0.5deg);
+    transform: translateY(-1.5px) rotate(-0.5deg);
+  }
+  0%,
+  to {
+    -webkit-transform: translate(0) rotate(0deg);
+    transform: translate(0) rotate(0deg);
+  }
+}
+@keyframes a {
+  2% {
+    -webkit-transform: translateY(1.5px) rotate(1.5deg);
+    transform: translateY(1.5px) rotate(1.5deg);
+  }
+  4% {
+    -webkit-transform: translateY(-1.5px) rotate(-0.5deg);
+    transform: translateY(-1.5px) rotate(-0.5deg);
+  }
+  6% {
+    -webkit-transform: translateY(1.5px) rotate(-1.5deg);
+    transform: translateY(1.5px) rotate(-1.5deg);
+  }
+  8% {
+    -webkit-transform: translateY(-1.5px) rotate(-1.5deg);
+    transform: translateY(-1.5px) rotate(-1.5deg);
+  }
+  10% {
+    -webkit-transform: translateY(2.5px) rotate(1.5deg);
+    transform: translateY(2.5px) rotate(1.5deg);
+  }
+  12% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  14% {
+    -webkit-transform: translateY(-1.5px) rotate(1.5deg);
+    transform: translateY(-1.5px) rotate(1.5deg);
+  }
+  16% {
+    -webkit-transform: translateY(-0.5px) rotate(-1.5deg);
+    transform: translateY(-0.5px) rotate(-1.5deg);
+  }
+  18% {
+    -webkit-transform: translateY(0.5px) rotate(-1.5deg);
+    transform: translateY(0.5px) rotate(-1.5deg);
+  }
+  20% {
+    -webkit-transform: translateY(-1.5px) rotate(2.5deg);
+    transform: translateY(-1.5px) rotate(2.5deg);
+  }
+  22% {
+    -webkit-transform: translateY(0.5px) rotate(-1.5deg);
+    transform: translateY(0.5px) rotate(-1.5deg);
+  }
+  24% {
+    -webkit-transform: translateY(1.5px) rotate(1.5deg);
+    transform: translateY(1.5px) rotate(1.5deg);
+  }
+  26% {
+    -webkit-transform: translateY(0.5px) rotate(0.5deg);
+    transform: translateY(0.5px) rotate(0.5deg);
+  }
+  28% {
+    -webkit-transform: translateY(0.5px) rotate(1.5deg);
+    transform: translateY(0.5px) rotate(1.5deg);
+  }
+  30% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  32%,
+  34% {
+    -webkit-transform: translateY(1.5px) rotate(-0.5deg);
+    transform: translateY(1.5px) rotate(-0.5deg);
+  }
+  36% {
+    -webkit-transform: translateY(-1.5px) rotate(2.5deg);
+    transform: translateY(-1.5px) rotate(2.5deg);
+  }
+  38% {
+    -webkit-transform: translateY(1.5px) rotate(-1.5deg);
+    transform: translateY(1.5px) rotate(-1.5deg);
+  }
+  40% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  42% {
+    -webkit-transform: translateY(2.5px) rotate(-1.5deg);
+    transform: translateY(2.5px) rotate(-1.5deg);
+  }
+  44% {
+    -webkit-transform: translateY(1.5px) rotate(0.5deg);
+    transform: translateY(1.5px) rotate(0.5deg);
+  }
+  46% {
+    -webkit-transform: translateY(-1.5px) rotate(2.5deg);
+    transform: translateY(-1.5px) rotate(2.5deg);
+  }
+  48% {
+    -webkit-transform: translateY(-0.5px) rotate(0.5deg);
+    transform: translateY(-0.5px) rotate(0.5deg);
+  }
+  50% {
+    -webkit-transform: translateY(0.5px) rotate(0.5deg);
+    transform: translateY(0.5px) rotate(0.5deg);
+  }
+  52% {
+    -webkit-transform: translateY(2.5px) rotate(2.5deg);
+    transform: translateY(2.5px) rotate(2.5deg);
+  }
+  54% {
+    -webkit-transform: translateY(-1.5px) rotate(1.5deg);
+    transform: translateY(-1.5px) rotate(1.5deg);
+  }
+  56% {
+    -webkit-transform: translateY(2.5px) rotate(2.5deg);
+    transform: translateY(2.5px) rotate(2.5deg);
+  }
+  58% {
+    -webkit-transform: translateY(0.5px) rotate(2.5deg);
+    transform: translateY(0.5px) rotate(2.5deg);
+  }
+  60% {
+    -webkit-transform: translateY(2.5px) rotate(2.5deg);
+    transform: translateY(2.5px) rotate(2.5deg);
+  }
+  62% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  64% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  66% {
+    -webkit-transform: translateY(1.5px) rotate(-0.5deg);
+    transform: translateY(1.5px) rotate(-0.5deg);
+  }
+  68% {
+    -webkit-transform: translateY(-1.5px) rotate(-0.5deg);
+    transform: translateY(-1.5px) rotate(-0.5deg);
+  }
+  70% {
+    -webkit-transform: translateY(1.5px) rotate(0.5deg);
+    transform: translateY(1.5px) rotate(0.5deg);
+  }
+  72% {
+    -webkit-transform: translateY(2.5px) rotate(1.5deg);
+    transform: translateY(2.5px) rotate(1.5deg);
+  }
+  74% {
+    -webkit-transform: translateY(-0.5px) rotate(0.5deg);
+    transform: translateY(-0.5px) rotate(0.5deg);
+  }
+  76% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  78% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  80% {
+    -webkit-transform: translateY(1.5px) rotate(1.5deg);
+    transform: translateY(1.5px) rotate(1.5deg);
+  }
+  82% {
+    -webkit-transform: translateY(-0.5px) rotate(0.5deg);
+    transform: translateY(-0.5px) rotate(0.5deg);
+  }
+  84% {
+    -webkit-transform: translateY(1.5px) rotate(2.5deg);
+    transform: translateY(1.5px) rotate(2.5deg);
+  }
+  86% {
+    -webkit-transform: translateY(-1.5px) rotate(-1.5deg);
+    transform: translateY(-1.5px) rotate(-1.5deg);
+  }
+  88% {
+    -webkit-transform: translateY(-0.5px) rotate(2.5deg);
+    transform: translateY(-0.5px) rotate(2.5deg);
+  }
+  90% {
+    -webkit-transform: translateY(2.5px) rotate(-0.5deg);
+    transform: translateY(2.5px) rotate(-0.5deg);
+  }
+  92% {
+    -webkit-transform: translateY(0.5px) rotate(-0.5deg);
+    transform: translateY(0.5px) rotate(-0.5deg);
+  }
+  94% {
+    -webkit-transform: translateY(2.5px) rotate(0.5deg);
+    transform: translateY(2.5px) rotate(0.5deg);
+  }
+  96% {
+    -webkit-transform: translateY(-0.5px) rotate(1.5deg);
+    transform: translateY(-0.5px) rotate(1.5deg);
+  }
+  98% {
+    -webkit-transform: translateY(-1.5px) rotate(-0.5deg);
+    transform: translateY(-1.5px) rotate(-0.5deg);
+  }
+  0%,
+  to {
+    -webkit-transform: translate(0) rotate(0deg);
+    transform: translate(0) rotate(0deg);
+  }
+}
+/*用户输入表单*/
+.tmsg-r-info {
+  margin: 10px 0;
+}
+.tmsg-r-info input {
+  height: 30px;
+  border-radius: 4px;
+  background: #f4f6f7;
+}
+.tmsg-r-info .info-submit {
+  margin: 10px 0;
+  text-align: center;
+}
+.tmsg-r-info .info-submit p,
+.tmsg-commentshow h1 {
+  /*background: #97dffd;*/
+  color: #fff;
+  border-radius: 5px;
+  cursor: pointer;
+  /*transition: all .3s ease-in-out;*/
+  height: 30px;
+  line-height: 30px;
+  text-align: center;
+}
+/*.tmsg-r-info .info-submit p:hover{
+    background: #47456d;
+}*/
+/*评论列表*/
+.tmsg-comments .tmsg-comments-tip {
+  display: block;
+  border-left: 2px solid #363d4c;
+  padding: 0 10px;
+  margin: 40px 0;
+  font-size: 20px;
+}
+.tmsg-commentlist {
+  margin-bottom: 20px;
+}
+.tmsg-commentshow > .tmsg-commentlist {
+  border-bottom: 1px solid #e5eaed;
+}
+.tmsg-c-item {
+  border-top: 1px solid #e5eaed;
+}
+.tmsg-c-item article {
+  margin: 20px 0;
+}
+.tmsg-c-item article header {
+  margin-bottom: 10px;
+}
+.tmsg-c-item article header img {
+  width: 65px;
+  height: 65px;
+  border-radius: 50%;
+  float: left;
+  transition: all 0.4s ease-in-out;
+  -webkit-transition: all 0.4s ease-in-out;
+  margin-right: 15px;
+  object-fit: cover;
+}
+.tmsg-c-item article header img:hover {
+  transform: rotate(360deg);
+  -webkit-transform: rotate(360deg);
+}
+.tmsg-c-item article header .i-name {
+  font-size: 14px;
+  margin: 5px 8px 7px 0;
+  color: #444;
+  font-weight: bold;
+  display: inline-block;
+}
+.tmsg-c-item article header .i-class {
+  display: inline-block;
+  margin-left: 10px;
+  background: #dff0d8;
+  color: #3c763d;
+  border-radius: 5px;
+  padding: 3px 6px;
+  font-size: 12px;
+  font-weight: 400;
+}
+.tmsg-c-item article header .i-time {
+  color: #aaa;
+  font-size: 12px;
+}
+.tmsg-c-item article section {
+  margin-left: 80px;
+}
+.tmsg-c-item article section p img {
+  vertical-align: middle;
+}
+.tmsg-c-item article section .tmsg-replay {
+  margin: 10px 0;
+  font-size: 12px;
+  color: #64609e;
+  cursor: pointer;
+}
+.hbl-owo {
+  text-align: left;
+}
+.comm {
+  padding: 20px;
+}
+.su {
+  margin-top: 2px;
+  width: 5px;
+  height: 23px;
+  background: #3cb371; /*#1E90FF*/
+}
+.com-rep {
+  display: inline-block;
+  vertical-align: top;
+}
+.com-title {
+  font-size: 20px;
+  margin-left: 5px;
+}
+.com-span {
+  font-size: 16px;
+}
+.hbl-fa {
+  text-align: left;
+}
+.hbl-comm {
+  padding: 40px;
+}
+
+.reply {
+  border-top: solid 1px #d9d9d9;
+}
+.content {
+  margin-top: 20px;
+  margin-bottom: 20px;
+}
+.comment-f {
+  display: inline-block;
+  vertical-align: top;
+}
+.nickname {
+  font-size: 14px;
+}
+.author {
+  display: inline-block;
+}
+.icon {
+  background: #dff0d8;
+  color: #3c763d;
+  border-radius: 5px;
+  padding: 3px 6px;
+  font-size: 12px;
+  font-weight: 400px;
+  margin-left: 10px;
+}
+.date {
+  font-size: 12px;
+  margin-top: 5px;
+  color: grey;
+}
+.reply-content {
+  word-wrap: break-word;
+  width: 90%;
+  font-size: 15px;
+  line-height: 25px;
+  margin-left: 56px;
+}
+
+.reply-fa {
+  margin-top: 5px;
+}
+.reply-font {
+  margin-bottom: 5px;
+  color: grey;
+  cursor: pointer;
+}
+.children {
+  padding-left: 40px;
+}
+.cc {
+  display: inline-block;
+}
+.cc-to a {
+  text-decoration: none;
+  color: #409eff;
+}
+.icon-reply {
+  display: inline-block;
+  vertical-align: top;
+}
+
+.icon-hf {
+  margin-top: 2px;
+}
+.hbl-child {
+  padding: 20px;
+}
+</style>

+ 2 - 1
ruoyi-ui/src/components/FileUpload/index.vue

@@ -76,6 +76,7 @@ export default {
       uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: [],
     };
@@ -147,7 +148,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 223 - 0
ruoyi-ui/src/components/FileUploadh/index.vue

@@ -0,0 +1,223 @@
+<template>
+  <div class="upload-file">
+    <el-upload
+      multiple
+      :action="uploadFileUrl"
+      :before-upload="handleBeforeUpload"
+      :file-list="fileList"
+      :limit="limit"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      :on-success="handleUploadSuccess"
+      :show-file-list="false"
+      :headers="headers"
+      class="upload-file-uploader"
+      ref="fileUpload"
+    >
+      <!-- 上传按钮 -->
+      <el-button size="mini" type="primary">选取文件</el-button>
+      <!-- 上传提示 -->
+      <div class="el-upload__tip" slot="tip" v-if="showTip">
+        请上传
+        <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
+        <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
+        的文件
+      </div>
+    </el-upload>
+
+    <!-- 文件列表 -->
+    <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
+      <li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
+        <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
+          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
+        </el-link>
+        <div class="ele-upload-list__item-content-action">
+          <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
+        </div>
+      </li>
+    </transition-group>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+
+export default {
+  name: "FileUpload",
+  props: {
+    // 值
+    value: [String, Object, Array],
+    // 数量限制
+    limit: {
+      type: Number,
+      default: 5,
+    },
+    // 大小限制(MB)
+    fileSize: {
+      type: Number,
+      default: 900,
+    },
+    // 文件类型, 例如['png', 'jpg', 'jpeg']
+    fileType: {
+      type: Array,
+      default: () => ["doc", "xls", "ppt", "txt", "pdf",'png', 'jpg', 'jpeg'],
+    },
+    // 是否显示提示
+    isShowTip: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      number: 0,
+      uploadList: [],
+      baseUrl: process.env.VUE_APP_BASE_API,
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
+      },
+      fileList: [],
+    };
+  },
+  watch: {
+    value: {
+      handler(val) {
+        if (val) {
+          let temp = 1;
+          // 首先将值转为数组
+          const list = Array.isArray(val) ? val : this.value.split(',');
+          // 然后将数组转为对象数组
+          this.fileList = list.map(item => {
+            if (typeof item === "string") {
+              item = { name: item, url: item };
+            }
+            item.uid = item.uid || new Date().getTime() + temp++;
+            return item;
+          });
+        } else {
+          this.fileList = [];
+          return [];
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  computed: {
+    // 是否显示提示
+    showTip() {
+      return this.isShowTip && (this.fileType || this.fileSize);
+    },
+  },
+  methods: {
+    // 上传前校检格式和大小
+    handleBeforeUpload(file) {
+      // 校检文件类型
+      if (this.fileType) {
+        const fileName = file.name.split('.');
+        const fileExt = fileName[fileName.length - 1];
+        const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
+        if (!isTypeOk) {
+          this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`);
+          return false;
+        }
+      }
+      // 校检文件名是否包含特殊字符
+      if (file.name.includes(',')) {
+        this.$modal.msgError('文件名不正确,不能包含英文逗号!');
+        return false;
+      }
+      // 校检文件大小
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      this.$modal.loading("正在上传文件,请稍候...");
+      this.number++;
+      return true;
+    },
+    // 文件个数超出
+    handleExceed() {
+      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
+    },
+    // 上传失败
+    handleUploadError(err) {
+      this.$modal.msgError("上传文件失败,请重试");
+      this.$modal.closeLoading();
+    },
+    // 上传成功回调
+    handleUploadSuccess(res, file) {
+      if (res.code === 200) {
+        this.uploadList.push({ name: res.data.newFileName, url: res.data.fileName,oldName:res.data.originalFilename });
+        this.uploadedSuccessfully();
+      } else {
+        this.number--;
+        this.$modal.closeLoading();
+        this.$modal.msgError(res.msg);
+        this.$refs.fileUpload.handleRemove(file);
+        this.uploadedSuccessfully();
+      }
+    },
+    // 删除文件
+    handleDelete(index) {
+      this.fileList.splice(index, 1);
+      this.$emit("input", this.listToString(this.fileList));
+    },
+    // 上传结束处理
+    uploadedSuccessfully() {
+      if (this.number > 0 && this.uploadList.length === this.number) {
+        this.fileList = this.fileList.concat(this.uploadList);
+        this.uploadList = [];
+        this.number = 0;
+        console.log(this.fileList)
+        this.$emit("input", this.fileList);
+        this.$modal.closeLoading();
+      }
+    },
+    // 获取文件名称
+    getFileName(name) {
+      // 如果是url那么取最后的名字 如果不是直接返回
+      if (name.lastIndexOf("/") > -1) {
+        return name.slice(name.lastIndexOf("/") + 1);
+      } else {
+        return name;
+      }
+    },
+    // 对象转成指定字符串分隔
+    listToString(list, separator) {
+      let strs = "";
+      separator = separator || ",";
+      for (let i in list) {
+        strs += list[i].url + separator;
+      }
+      return strs != '' ? strs.substr(0, strs.length - 1) : '';
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.upload-file-uploader {
+  margin-bottom: 5px;
+}
+.upload-file-list .el-upload-list__item {
+  border: 1px solid #e4e7ed;
+  line-height: 2;
+  margin-bottom: 10px;
+  position: relative;
+}
+.upload-file-list .ele-upload-list__item-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  color: inherit;
+}
+.ele-upload-list__item-content-action .el-link {
+  margin-right: 10px;
+}
+</style>

+ 2 - 1
ruoyi-ui/src/components/FileUploads/index.vue

@@ -76,6 +76,7 @@ export default {
       uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: [],
     };
@@ -147,7 +148,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 2 - 1
ruoyi-ui/src/components/FileUploadsch/index.vue

@@ -78,6 +78,7 @@ export default {
       uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: [],
     };
@@ -149,7 +150,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 222 - 0
ruoyi-ui/src/components/FileUploadvio/index.vue

@@ -0,0 +1,222 @@
+<template>
+  <div class="upload-file">
+    <el-upload
+      multiple
+      :action="uploadFileUrl"
+      :before-upload="handleBeforeUpload"
+      :file-list="fileList"
+      :limit="limit"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      :on-success="handleUploadSuccess"
+      :show-file-list="false"
+      :headers="headers"
+      class="upload-file-uploader"
+      ref="fileUpload"
+    >
+      <!-- 上传按钮 -->
+      <el-button size="mini" type="primary">选取文件</el-button>
+      <!-- 上传提示 -->
+      <div class="el-upload__tip" slot="tip" v-if="showTip">
+        请上传
+        <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
+        <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
+        的文件
+      </div>
+    </el-upload>
+
+    <!-- 文件列表 -->
+    <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
+      <li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
+        <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
+          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
+        </el-link>
+        <div class="ele-upload-list__item-content-action">
+          <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
+        </div>
+      </li>
+    </transition-group>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+
+export default {
+  name: "FileUpload",
+  props: {
+    // 值
+    value: [String, Object, Array],
+    // 数量限制
+    limit: {
+      type: Number,
+      default: 5,
+    },
+    // 大小限制(MB)
+    fileSize: {
+      type: Number,
+      default: 900,
+    },
+    // 文件类型, 例如['png', 'jpg', 'jpeg']
+    fileType: {
+      type: Array,
+      default: () => ["mp4",],
+    },
+    // 是否显示提示
+    isShowTip: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      number: 0,
+      uploadList: [],
+      baseUrl: process.env.VUE_APP_BASE_API,
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
+      },
+      fileList: [],
+    };
+  },
+  watch: {
+    value: {
+      handler(val) {
+        if (val) {
+          let temp = 1;
+          // 首先将值转为数组
+          const list = Array.isArray(val) ? val : this.value.split(',');
+          // 然后将数组转为对象数组
+          this.fileList = list.map(item => {
+            if (typeof item === "string") {
+              item = { name: item, url: item };
+            }
+            item.uid = item.uid || new Date().getTime() + temp++;
+            return item;
+          });
+        } else {
+          this.fileList = [];
+          return [];
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  computed: {
+    // 是否显示提示
+    showTip() {
+      return this.isShowTip && (this.fileType || this.fileSize);
+    },
+  },
+  methods: {
+    // 上传前校检格式和大小
+    handleBeforeUpload(file) {
+      // 校检文件类型
+      if (this.fileType) {
+        const fileName = file.name.split('.');
+        const fileExt = fileName[fileName.length - 1];
+        const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
+        if (!isTypeOk) {
+          this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`);
+          return false;
+        }
+      }
+      // 校检文件名是否包含特殊字符
+      if (file.name.includes(',')) {
+        this.$modal.msgError('文件名不正确,不能包含英文逗号!');
+        return false;
+      }
+      // 校检文件大小
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      this.$modal.loading("正在上传文件,请稍候...");
+      this.number++;
+      return true;
+    },
+    // 文件个数超出
+    handleExceed() {
+      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
+    },
+    // 上传失败
+    handleUploadError(err) {
+      this.$modal.msgError("上传文件失败,请重试");
+      this.$modal.closeLoading();
+    },
+    // 上传成功回调
+    handleUploadSuccess(res, file) {
+      if (res.code === 200) {
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
+        this.uploadedSuccessfully();
+      } else {
+        this.number--;
+        this.$modal.closeLoading();
+        this.$modal.msgError(res.msg);
+        this.$refs.fileUpload.handleRemove(file);
+        this.uploadedSuccessfully();
+      }
+    },
+    // 删除文件
+    handleDelete(index) {
+      this.fileList.splice(index, 1);
+      this.$emit("input", this.listToString(this.fileList));
+    },
+    // 上传结束处理
+    uploadedSuccessfully() {
+      if (this.number > 0 && this.uploadList.length === this.number) {
+        this.fileList = this.fileList.concat(this.uploadList);
+        this.uploadList = [];
+        this.number = 0;
+        this.$emit("input", this.listToString(this.fileList));
+        this.$modal.closeLoading();
+      }
+    },
+    // 获取文件名称
+    getFileName(name) {
+      // 如果是url那么取最后的名字 如果不是直接返回
+      if (name.lastIndexOf("/") > -1) {
+        return name.slice(name.lastIndexOf("/") + 1);
+      } else {
+        return name;
+      }
+    },
+    // 对象转成指定字符串分隔
+    listToString(list, separator) {
+      let strs = "";
+      separator = separator || ",";
+      for (let i in list) {
+        strs += list[i].url + separator;
+      }
+      return strs != '' ? strs.substr(0, strs.length - 1) : '';
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.upload-file-uploader {
+  margin-bottom: 5px;
+}
+.upload-file-list .el-upload-list__item {
+  border: 1px solid #e4e7ed;
+  line-height: 2;
+  margin-bottom: 10px;
+  position: relative;
+}
+.upload-file-list .ele-upload-list__item-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  color: inherit;
+}
+.ele-upload-list__item-content-action .el-link {
+  margin-right: 10px;
+}
+</style>

+ 3 - 2
ruoyi-ui/src/components/ImageUpload/index.vue

@@ -19,7 +19,7 @@
     >
       <i class="el-icon-plus"></i>
     </el-upload>
-    
+
     <!-- 上传提示 -->
     <div class="el-upload__tip" slot="tip" v-if="showTip">
       请上传
@@ -80,6 +80,7 @@ export default {
       uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: []
     };
@@ -155,7 +156,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 3 - 2
ruoyi-ui/src/components/ImageUploads/index.vue

@@ -20,7 +20,7 @@
       <i class="el-icon-plus"></i>
 	  <!-- <el-button size="small" type="primary">点击上传</el-button> -->
     </el-upload>
-    
+
     <!-- 上传提示 -->
     <div class="el-upload__tip" slot="tip" v-if="showTip">
       请上传
@@ -81,6 +81,7 @@ export default {
       uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 common/upload
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: []
     };
@@ -156,7 +157,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 324 - 0
ruoyi-ui/src/components/ImageUploadshib/index.vue

@@ -0,0 +1,324 @@
+<template>
+  <div class="component-upload-image">
+    <el-tooltip class="item" effect="dark" :content="'请上传' +fileType.join('/')+'格式的文件'  " placement="top-start">
+    <el-upload
+      multiple
+      :action="uploadImgUrl"
+      list-type="picture-card"
+      :on-success="handleUploadSuccess"
+      :before-upload="handleBeforeUpload"
+      :limit="limit"
+      :typeg="typeg"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      ref="imageUpload"
+      :on-remove="handleDelete"
+
+      :headers="headers"
+      :file-list="fileList"
+      :on-preview="handlePictureCardPreview"
+      :class="{hide: this.fileList.length >= this.limit}"
+    >
+      <i class="el-icon-camera"></i>
+    </el-upload>
+    </el-tooltip>
+
+    <!-- 上传提示 -->
+    <!-- <div class="el-upload__tip" slot="tip" v-if="showTip">
+      请上传
+      <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
+      <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
+      的文件
+    </div> -->
+
+    <el-dialog
+      :visible.sync="dialogVisible"
+      title="预览"
+      width="800"
+      append-to-body
+    >
+      <img
+        :src="dialogImageUrl"
+        style="display: block; max-width: 100%; margin: 0 auto"
+      />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import { isExternal } from "@/utils/validate";
+import { ocrIdCard,licensePlate,realEstateCertificate} from "@/api/wuguan/landlord";
+
+export default {
+  props: {
+    value: [String, Object, Array],
+    // 图片数量限制
+    limit: {
+      type: Number,
+      default: 5,
+    },
+    // 大小限制(MB)
+    fileSize: {
+       type: Number,
+      default: 900,
+    },
+    // 识别类型  1 身份证  2 车牌  3 违停 4房产证
+    typeg: {
+       type: Number,
+      default: 5,
+    },
+
+    // 文件类型, 例如['png', 'jpg', 'jpeg']
+    fileType: {
+      type: Array,
+      default: () => ["png", "jpg", "jpeg"],
+    },
+    // 是否显示提示
+    isShowTip: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      number: 0,
+      uploadList: [],
+      dialogImageUrl: "",
+      dialogVisible: false,
+      hideUpload: false,
+      baseUrl: process.env.VUE_APP_BASE_API,
+      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
+      },
+      fileList: [],
+      isgse:false
+    };
+  },
+  watch: {
+    value: {
+      handler(val) {
+        if (val) {
+          // 首先将值转为数组
+          const list = Array.isArray(val) ? val : this.value.split(',');
+          // 然后将数组转为对象数组
+          this.fileList = list.map(item => {
+            if (typeof item === "string") {
+              if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) {
+                  item = { name: this.baseUrl + item, url: this.baseUrl + item };
+              } else {
+                  item = { name: item, url: item };
+              }
+            }
+            return item;
+          });
+        } else {
+          this.fileList = [];
+          return [];
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  computed: {
+    // 是否显示提示
+    showTip() {
+      return this.isShowTip && (this.fileType || this.fileSize);
+    },
+
+  },
+  created() {
+    console.log(this.fileList)
+  },
+  methods: {
+    // 上传前loading加载
+    handleBeforeUpload(file) {
+      console.log(this.typeg,4,this.fileList,this.limit)
+      let isImg = false;
+      if (this.fileType.length) {
+        let fileExtension = "";
+        if (file.name.lastIndexOf(".") > -1) {
+          fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+        }
+        isImg = this.fileType.some(type => {
+          if (file.type.indexOf(type) > -1) return true;
+          if (fileExtension && fileExtension.indexOf(type) > -1) return true;
+          return false;
+        });
+      } else {
+        isImg = file.type.indexOf("image") > -1;
+      }
+
+      if (!isImg) {
+        this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`);
+        return false;
+      }
+      if (file.name.includes(',')) {
+        this.$modal.msgError('文件名不正确,不能包含英文逗号!');
+        return false;
+      }
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      this.$modal.loading("正在上传图片,请稍候...");
+      this.number++;
+    },
+    // 文件个数超出
+    handleExceed(files, fileList) {
+       // console.log(this.fileList,files, fileList,5,this.limit)
+       if(this.fileList.length !=0){
+         this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
+       }else{
+         this.clearFiles()
+         // return
+       }
+
+    },
+    // 清楚已经上传的文件
+    clearFiles () {
+          this.$refs['imageUpload'].clearFiles();
+      },
+
+    // 上传成功回调
+    handleUploadSuccess(res, file) {
+      if (res.code === 200) {
+        this.$modal.closeLoading();
+        this.isgse = false
+        // this.fileList= []
+        if(this.typeg == 1){
+          let nget={'idCardSide':'front','image':res.data.urlOnline}
+          ocrIdCard(nget).then(response => {
+           this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
+           this.isgse = true
+           this.uploadList.filter(rou=>{
+             rou.address =  response.data.address
+             rou.idCard= response.data.idCard
+             // idCard:342224199212121234,
+             rou.realName=  response.data.realName
+
+           })
+             this.uploadedSuccessfully();
+          });
+        }else if(this.typeg == 2){
+          let nget={'image':res.urlOnline}
+          // 车牌号
+          licensePlate(nget).then(response => {
+           this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
+           console.log(this.uploadList)
+           this.isgse = true
+           this.uploadList.filter(rou=>{
+             rou.plateNumber =  response.msg
+           })
+
+             this.uploadedSuccessfully();
+
+          });
+        }else if(this.typeg == 4){
+          // 房产证
+          let nget={'image':res.urlOnline}
+          // 车牌号
+          realEstateCertificate(nget).then(response => {
+           this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
+           this.isgse = true
+           this.uploadList.filter(row=>{
+             row.area = response.data.area
+             row.coOwner = response.data.coOwner
+             row.coOwnership = response.data.coOwnership
+             row.documentNumber = response.data.documentNumber
+             row.location = response.data.location
+             row.ownerName = response.data.ownerName
+             row.propertyUnitNumber = response.data.propertyUnitNumber
+             row.registrationDate = response.data.registrationDate
+             row.rightType = response.data.rightType
+             row.usagePeriod = response.data.usagePeriod
+             row.usageType = response.data.usageType
+
+             // rou.plateNumber =  response.msg
+           })
+             this.uploadedSuccessfully();
+          });
+        }
+       if(this.isgse == false){
+         this.clearFiles()
+         this.number = 1
+       }
+
+        // this.uploadedSuccessfully();
+      } else {
+        this.number--;
+        this.$modal.closeLoading();
+        this.$modal.msgError(res.msg);
+        this.$refs.imageUpload.handleRemove(file);
+        this.uploadedSuccessfully();
+      }
+    },
+    // 删除图片
+    handleDelete(file) {
+      const findex = this.fileList.map(f => f.name).indexOf(file.name);
+      if (findex > -1) {
+        this.fileList.splice(findex, 1);
+        this.$emit("input", this.listToString(this.fileList));
+      }
+    },
+    // 上传失败
+    handleUploadError() {
+      this.$modal.msgError("上传图片失败,请重试");
+      this.$modal.closeLoading();
+    },
+    // 上传结束处理
+    uploadedSuccessfully() {
+      console.log(2,this.uploadList,this.number)
+      if (this.number > 0 && this.uploadList.length === this.number) {
+        console.log(this.uploadList)
+        this.fileList = this.fileList.concat(this.uploadList);
+        this.uploadList = [];
+        this.number = 0;
+        console.log(this.fileList)
+        this.$emit("input", this.listToString(this.fileList));
+        this.$emit("uploadedSuccessfully", this.fileList);
+        this.$modal.closeLoading();
+      }
+    },
+    // 预览
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    // 对象转成指定字符串分隔
+    listToString(list, separator) {
+      let strs = "";
+      separator = separator || ",";
+      for (let i in list) {
+        if (list[i].url) {
+          strs += list[i].url.replace(this.baseUrl, "") + separator;
+        }
+      }
+      return strs != '' ? strs.substr(0, strs.length - 1) : '';
+    }
+  }
+};
+</script>
+<style scoped lang="scss">
+// .el-upload--picture-card 控制加号部分
+::v-deep.hide .el-upload--picture-card {
+    display: none;
+}
+// 去掉动画效果
+::v-deep .el-list-enter-active,
+::v-deep .el-list-leave-active {
+    transition: all 0s;
+}
+
+::v-deep .el-list-enter, .el-list-leave-active {
+  opacity: 0;
+  transform: translateY(0);
+}
+</style>
+

+ 3 - 2
ruoyi-ui/src/components/ImageUploadslis/index.vue

@@ -20,7 +20,7 @@
       <i class="el-icon-plus"></i>
 	  <!-- <el-button size="small" type="primary">点击上传</el-button> -->
     </el-upload>
-    
+
     <!-- 上传提示 -->
     <div class="el-upload__tip" slot="tip" v-if="showTip">
       请上传
@@ -81,6 +81,7 @@ export default {
       uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 common/upload
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: []
     };
@@ -156,7 +157,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 2 - 1
ruoyi-ui/src/components/ImageUploadxy/index.vue

@@ -81,6 +81,7 @@ export default {
       uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
       },
       fileList: []
     };
@@ -156,7 +157,7 @@ export default {
     // 上传成功回调
     handleUploadSuccess(res, file) {
       if (res.code === 200) {
-        this.uploadList.push({ name: res.fileName, url: res.fileName });
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
         this.uploadedSuccessfully();
       } else {
         this.number--;

+ 232 - 0
ruoyi-ui/src/components/ImageUploadyuang/index.vue

@@ -0,0 +1,232 @@
+<template>
+  <div class="component-upload-image">
+    <el-upload
+      multiple
+      :action="uploadImgUrl"
+      list-type="picture-card"
+      :on-success="handleUploadSuccess"
+      :before-upload="handleBeforeUpload"
+      :limit="limit"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      ref="imageUpload"
+      :on-remove="handleDelete"
+      :show-file-list="true"
+      :headers="headers"
+      :file-list="fileList"
+      :on-preview="handlePictureCardPreview"
+      :class="{hide: this.fileList.length >= this.limit}"
+    >
+      <i class="el-icon-plus"></i>
+    </el-upload>
+
+    <!-- 上传提示 -->
+    <div class="el-upload__tip" slot="tip" v-if="showTip">
+      请上传
+      <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
+      <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
+      的文件
+    </div>
+
+    <el-dialog
+      :visible.sync="dialogVisible"
+      title="预览"
+      width="800"
+      append-to-body
+    >
+      <img
+        :src="dialogImageUrl"
+        style="display: block; max-width: 100%; margin: 0 auto"
+      />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import { isExternal } from "@/utils/validate";
+
+export default {
+  props: {
+    value: [String, Object, Array],
+    // 图片数量限制
+    limit: {
+      type: Number,
+      default: 5,
+    },
+    // 大小限制(MB)
+    fileSize: {
+       type: Number,
+      default: 900,
+    },
+    // 文件类型, 例如['png', 'jpg', 'jpeg']
+    fileType: {
+      type: Array,
+      default: () => ["png", "jpg", "jpeg"],
+    },
+    // 是否显示提示
+    isShowTip: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      number: 0,
+      uploadList: [],
+      dialogImageUrl: "",
+      dialogVisible: false,
+      hideUpload: false,
+      baseUrl: process.env.VUE_APP_BASE_API,
+      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+        clientid:'e5cd7e4891bf95d1d19206ce24a7b32e'
+      },
+      fileList: []
+    };
+  },
+  watch: {
+    value: {
+      handler(val) {
+        if (val) {
+          // 首先将值转为数组
+          const list = Array.isArray(val) ? val : this.value.split(',');
+          // 然后将数组转为对象数组
+          this.fileList = list.map(item => {
+            if (typeof item === "string") {
+              if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) {
+                  item = { name: this.baseUrl + item, url: this.baseUrl + item };
+              } else {
+                  item = { name: item, url: item };
+              }
+            }
+            return item;
+          });
+        } else {
+          this.fileList = [];
+          return [];
+        }
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  computed: {
+    // 是否显示提示
+    showTip() {
+      return this.isShowTip && (this.fileType || this.fileSize);
+    },
+  },
+  methods: {
+    // 上传前loading加载
+    handleBeforeUpload(file) {
+      let isImg = false;
+      if (this.fileType.length) {
+        let fileExtension = "";
+        if (file.name.lastIndexOf(".") > -1) {
+          fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+        }
+        isImg = this.fileType.some(type => {
+          if (file.type.indexOf(type) > -1) return true;
+          if (fileExtension && fileExtension.indexOf(type) > -1) return true;
+          return false;
+        });
+      } else {
+        isImg = file.type.indexOf("image") > -1;
+      }
+
+      if (!isImg) {
+        this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`);
+        return false;
+      }
+      if (file.name.includes(',')) {
+        this.$modal.msgError('文件名不正确,不能包含英文逗号!');
+        return false;
+      }
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      this.$modal.loading("正在上传图片,请稍候...");
+      this.number++;
+    },
+    // 文件个数超出
+    handleExceed() {
+      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
+    },
+    // 上传成功回调
+    handleUploadSuccess(res, file) {
+      if (res.code === 200) {
+        this.uploadList.push({ name: res.data.fileName, url: res.data.fileName });
+        this.uploadedSuccessfully();
+      } else {
+        this.number--;
+        this.$modal.closeLoading();
+        this.$modal.msgError(res.msg);
+        this.$refs.imageUpload.handleRemove(file);
+        this.uploadedSuccessfully();
+      }
+    },
+    // 删除图片
+    handleDelete(file) {
+      const findex = this.fileList.map(f => f.name).indexOf(file.name);
+      if (findex > -1) {
+        this.fileList.splice(findex, 1);
+        this.$emit("input", this.listToString(this.fileList));
+      }
+    },
+    // 上传失败
+    handleUploadError() {
+      this.$modal.msgError("上传图片失败,请重试");
+      this.$modal.closeLoading();
+    },
+    // 上传结束处理
+    uploadedSuccessfully() {
+      if (this.number > 0 && this.uploadList.length === this.number) {
+        this.fileList = this.fileList.concat(this.uploadList);
+        this.uploadList = [];
+        this.number = 0;
+        this.$emit("input", this.listToString(this.fileList));
+        this.$modal.closeLoading();
+      }
+    },
+    // 预览
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    // 对象转成指定字符串分隔
+    listToString(list, separator) {
+      let strs = "";
+      separator = separator || ",";
+      for (let i in list) {
+        if (list[i].url) {
+          strs += list[i].url.replace(this.baseUrl, "") + separator;
+        }
+      }
+      return strs != '' ? strs.substr(0, strs.length - 1) : '';
+    }
+  }
+};
+</script>
+<style scoped lang="scss">
+// .el-upload--picture-card 控制加号部分
+::v-deep.hide .el-upload--picture-card {
+    display: none;
+}
+// 去掉动画效果
+::v-deep .el-list-enter-active,
+::v-deep .el-list-leave-active {
+    transition: all 0s;
+}
+
+::v-deep .el-list-enter, .el-list-leave-active {
+  opacity: 0;
+  transform: translateY(0);
+}
+</style>
+

+ 360 - 0
ruoyi-ui/src/components/vue-ueditor-wrap.vue

@@ -0,0 +1,360 @@
+<template>
+  <div>
+    <div ref="container" :name="name"></div>
+  </div>
+</template>
+
+<script>
+import LoadEvent from '../utils/Event.js';
+import debounce from '../utils/Debounce.js';
+import asyncSeries from '../utils/async-series.js';
+import randomString from '../utils/randomString.js';
+
+export default {
+  name: 'VueUeditorWrap',
+  data () {
+    return {
+      isEditorReady: false,
+      defaultConfig: {
+        // VUE CLI 3 会添加 process.env.BASE_URL 的环境变量,而 VUE CLI 2 没有,所以借此设置 UEDITOR_HOME_URL,能涵盖大部分 Vue 开发者的使用场景
+        UEDITOR_HOME_URL:
+          typeof process !== 'undefined' && process.env.BASE_URL
+            ? process.env.BASE_URL + 'UEditor/'
+            : '/static/UEditor/'
+      }
+    };
+  },
+  props: {
+    // v-model 实现方式
+    mode: {
+      type: String,
+      default: 'observer',
+      validator: function (value) {
+        // 1. observer 借助 MutationObserver API https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
+        // 2. listener 借助 UEditor 的 contentChange 事件 https://ueditor.baidu.com/doc/#UE.Editor:contentChange
+        return ['observer', 'listener'].indexOf(value) !== -1;
+      }
+    },
+    value: {
+      type: String,
+      default: ''
+    },
+    config: {
+      type: Object,
+      default: function () {
+        return {};
+      }
+    },
+    init: {
+      type: Function,
+      default: () => {}
+    },
+    destroy: {
+      type: Boolean,
+      default: true
+    },
+    name: {
+      type: String,
+      default: ''
+    },
+    observerDebounceTime: {
+      type: Number,
+      default: 50,
+      validator: function (value) {
+        return value >= 20;
+      }
+    },
+    observerOptions: {
+      type: Object,
+      default: function () {
+        // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit
+        return {
+          attributes: true, // 是否监听 DOM 元素的属性变化
+          attributeFilter: ['src', 'style', 'type', 'name'], // 只有在该数组中的属性值的变化才会监听
+          characterData: true, // 是否监听文本节点
+          childList: true, // 是否监听子节点
+          subtree: true // 是否监听后代元素
+        };
+      }
+    },
+    // 本组件提供对普通 Vue 项目和 Nuxt 项目开箱即用的支持,但如果是自己搭建的 Vue SSR 项目,可能需要自行区分是客户端还是服务端环境并跳过环境检测,直接初始化
+    forceInit: {
+      type: Boolean,
+      default: false
+    },
+    // 手动设置 UEditor ID
+    editorId: {
+      type: String
+    },
+    // 指定 UEditor 依赖的静态资源,js & css
+    editorDependencies: Array,
+    // 检测依赖的静态资源是否加载完成的方法
+    editorDependenciesChecker: Function
+  },
+  computed: {
+    mixedConfig () {
+      return {
+        ...this.defaultConfig,
+        ...this.config
+      };
+    }
+  },
+  methods: {
+	  
+
+    // 添加自定义按钮(自定义按钮,自定义弹窗等操作从 2.2.0 版本开始不再考虑直接集成,这会使得组件和 UEditor 过度耦合,但为了兼容一些老版用户的写法,这个方法依然保留)
+    registerButton ({ name, icon, tip, handler, index, UE = window.UE }) {
+      UE.registerUI(
+        name,
+        (editor, name) => {
+          editor.registerCommand(name, {
+            execCommand: () => {
+              handler(editor, name);
+            }
+          });
+          const btn = new UE.ui.Button({
+            name,
+            title: tip,
+            cssRules: `background-image: url(${icon}) !important;background-size: cover;`,
+            onclick () {
+              editor.execCommand(name);
+            }
+          });
+          editor.addListener('selectionchange', () => {
+            const state = editor.queryCommandState(name);
+            if (state === -1) {
+              btn.setDisabled(true);
+              btn.setChecked(false);
+            } else {
+              btn.setDisabled(false);
+              btn.setChecked(state);
+            }
+          });
+          return btn;
+        },
+        index,
+        this.id
+      );
+    },
+    // 实例化编辑器
+    _initEditor () {
+      this.$refs.container.id = this.id =
+        this.editorId || 'editor_' + randomString(8); // 这么做是为了支持 Vue SSR,因为如果把 id 属性放在 data 里会导致服务端和客户端分别计算该属性的值,而造成 id 不匹配无法初始化的 BUG
+      this.init();
+      this.$emit('before-init', this.id, this.mixedConfig);
+      this.$emit('beforeInit', this.id, this.mixedConfig); // 虽然这个驼峰的写法会导致使用 DOM 模版时出现监听事件自动转小写的 BUG,但如果经过编译的话并不会有这个问题,为了兼容历史版本,不做删除,参考 https://vuejs.org/v2/guide/components-custom-events.html#Event-Names
+      this.editor = window.UE.getEditor(this.id, this.mixedConfig);
+      this.editor.addListener('ready', () => {
+        if (this.isEditorReady) {
+          // 使用 keep-alive 组件会出现这种情况
+          this.editor.setContent(this.value);
+        } else {
+          this.isEditorReady = true;
+          this.$emit('ready', this.editor);
+          if (this.value) {
+            this.editor.setContent(this.value);
+          }
+        }
+        if (this.mode === 'observer' && window.MutationObserver) {
+          this._observerChangeListener();
+        } else {
+          this._normalChangeListener();
+        }
+      });
+    },
+    // 动态创建 script 标签来加载 JS 脚本,保证同一个脚本只被加载一次
+    _loadScript (link) {
+      return new Promise((resolve, reject) => {
+        window.$loadEventBus.on(link, resolve);
+        if (window.$loadEventBus.listeners[link].requested === false) {
+          window.$loadEventBus.listeners[link].requested = true;
+          // 如果这个资源从未被请求过,就手动创建脚本去加载
+          const script = document.createElement('script');
+          script.src = link;
+          script.onload = () => {
+            window.$loadEventBus.emit(link);
+          };
+          script.onerror = reject;
+          document.getElementsByTagName('head')[0].appendChild(script);
+        }
+      });
+    },
+    // 动态创建 link 标签来加载 CSS 文件
+    _loadCss (link) {
+      return new Promise((resolve, reject) => {
+        window.$loadEventBus.on(link, resolve);
+        if (window.$loadEventBus.listeners[link].requested === false) {
+          window.$loadEventBus.listeners[link].requested = true;
+          const css = document.createElement('link');
+          css.type = 'text/css';
+          css.rel = 'stylesheet';
+          css.href = link;
+          css.onload = () => {
+            window.$loadEventBus.emit(link);
+          };
+          css.onerror = reject;
+          document.getElementsByTagName('head')[0].appendChild(css);
+        }
+      });
+    },
+    // 加载 UEditor 相关的静态资源
+    _loadEditorDependencies () {
+      // 创建加载资源的事件通信载体
+      if (!window.$loadEventBus) {
+        window.$loadEventBus = new LoadEvent();
+      }
+      // 默认要加载的资源
+      const defaultEditorDependencies = [
+        'ueditor.config.js',
+        'ueditor.all.min.js',
+        '135editor.js',
+		'xiumi-ue-dialog-v5.js',
+        'selectKeywordByIndex.js'
+      ];
+      // 判断上面的默认资源是否已经加载过的校验函数
+      const defaultEditorDependenciesChecker = () => {
+        // 判断 ueditor.config.js 和 ueditor.all.js 是否均已加载
+        // 仅加载完ueditor.config.js时UE对象和UEDITOR_CONFIG对象存在,仅加载完ueditor.all.js时UEDITOR_CONFIG对象存在,但为空对象
+        return (
+          window.UE &&
+          window.UE.getEditor &&
+          window.UEDITOR_CONFIG &&
+          Object.keys(window.UEDITOR_CONFIG).length !== 0
+        );
+      };
+
+      return new Promise((resolve, reject) => {
+        if (
+          this.editorDependencies &&
+          this.editorDependenciesChecker &&
+          this.editorDependenciesChecker()
+        ) {
+          resolve();
+          return;
+        }
+
+        if (!this.editorDependencies && defaultEditorDependenciesChecker()) {
+          resolve();
+          return;
+        }
+
+        // 把 js 和 css 分组
+        const { jsLinks, cssLinks } = (
+          this.editorDependencies || defaultEditorDependencies
+        ).reduce(
+          (res, link) => {
+            // 如果不是完整的 URL 就在前面补上 UEDITOR_HOME_URL, 完整的 URL 形如:
+            // 1. http://www.example.com/xxx.js
+            // 2. https://www.example.com/xxx.js
+            // 3. //www.example.com/xxx.js
+            // 4. www.example.com/xxx.js
+            const isFullUrl = /^((https?:)?\/\/)?[-a-zA-Z0-9]+(\.[-a-zA-Z0-9]+)+\//.test(
+              link
+            );
+            if (!isFullUrl) {
+              link = (this.mixedConfig.UEDITOR_HOME_URL || '') + link;
+            }
+            if (link.slice(-3) === '.js') {
+              res.jsLinks.push(link);
+            } else if (link.slice(-4) === '.css') {
+              res.cssLinks.push(link);
+            }
+            return res;
+          },
+          {
+            jsLinks: [],
+            cssLinks: []
+          }
+        );
+
+        Promise.all([
+          Promise.all(cssLinks.map((link) => this._loadCss(link))),
+          // 依次加载依赖的 JS 文件,JS 执行是有顺序要求的,比如 ueditor.all.js 就要晚于 ueditor.config.js 执行
+          // 动态创建 script 是先加载完的先执行,所以不可以一次性创建所有资源的引入脚本
+          asyncSeries(jsLinks.map((link) => () => this._loadScript(link)))
+        ])
+          .then(() => resolve())
+          .catch(reject);
+      });
+    },
+    _contentChangeHandler () {
+      this.innerValue = this.editor.getContent();
+      this.$emit('input', this.innerValue);
+    },
+    // 基于 UEditor 的 contentChange 事件
+    _normalChangeListener () {
+      this.editor.addListener('contentChange', this._contentChangeHandler);
+    },
+    // 基于 MutationObserver API
+    _observerChangeListener () {
+      const changeHandle = () => {
+        if (this.editor.document.getElementById('baidu_pastebin')) {
+          return;
+        }
+        this.innerValue = this.editor.getContent();
+        this.$emit('input', this.innerValue);
+      };
+      // 函数防抖
+      this.observer = new MutationObserver(
+        debounce(changeHandle, this.observerDebounceTime)
+      );
+      this.observer.observe(this.editor.body, this.observerOptions);
+    },
+    //  查询定位字符串
+    _selectText(text,index,backJson){
+      this.editor.execCommand("selectkeywordbyindex", {searchStr: text, dir: 1, casesensitive: false, all: 1,index:index,callbackFun:function(rng){
+          backJson(rng);
+        }
+      });
+    }
+  },
+  deactivated () {
+    if (this.editor) {
+      this.editor.removeListener('contentChange', this._contentChangeHandler);
+    }
+    if (this.observer) {
+      this.observer.disconnect();
+    }
+  },
+  beforeDestroy () {
+    if (this.destroy && this.editor && this.editor.destroy) {
+      this.editor.destroy();
+    }
+    if (this.observer && this.observer.disconnect) {
+      this.observer.disconnect();
+    }
+  },
+  // v-model语法糖实现
+  watch: {
+    value: {
+      handler (value) {
+        if (this.isEditorReady) {
+          value === this.innerValue || this.editor.setContent(value || '');
+        } else {
+          (this.forceInit || typeof window !== 'undefined') &&
+            this._loadEditorDependencies()
+              .then(() => {
+                this.$refs.container
+                  ? this._initEditor()
+                  : this.$nextTick(() => this._initEditor());
+              })
+              .catch(() => {
+                throw new Error(
+                  '[vue-ueditor-wrap] UEditor 资源加载失败!请检查资源是否存在,UEDITOR_HOME_URL 是否配置正确!'
+                );
+              });
+        }
+      },
+      immediate: true
+    }
+  }
+};
+</script>
+<style>
+  .edui-button.edui-for-135editor .edui-button-wrap .edui-button-body .edui-icon{
+    background-image: url("http://static.135editor.com/img/icons/editor-135-icon.png") !important;
+    background-size: 85%;
+    background-position: center;
+    background-repeat: no-repeat;
+  }
+</style>

+ 1 - 1
ruoyi-ui/src/layout/components/Navbar.vue

@@ -19,7 +19,7 @@
 			  clearable
 			  filterable
 			  reserve-keyword
-			  placeholder="选择学校"
+			  placeholder="选择小区"
 			  v-if="userId === 1 && tenantEnabled"
 			  @change="dynamicTenantEvent"
 			  @clear="dynamicClearEvent"

+ 7 - 0
ruoyi-ui/src/main.js

@@ -53,6 +53,10 @@ import ImageUpload from "@/components/ImageUpload"
 import ImageUploads from "@/components/ImageUploads"
 import ImageUploadslis from "@/components/ImageUploadslis"
 import ImageUploadxy from "@/components/ImageUploadxy"
+import ImageUploadshib from "@/components/ImageUploadshib"
+import ImageUploadyuang from "@/components/ImageUploadyuang"
+
+
 
 // 图片预览组件
 import ImagePreview from "@/components/ImagePreview"
@@ -100,6 +104,9 @@ Vue.component('ImageUpload', ImageUpload)
 Vue.component('ImageUploads', ImageUploads)
 Vue.component('ImageUploadslis', ImageUploadslis)
 Vue.component('ImageUploadxy', ImageUploadxy)
+Vue.component('ImageUploadyuang', ImageUploadyuang)
+Vue.component('ImageUploadshib', ImageUploadshib)
+
 Vue.component('ImagePreview', ImagePreview)
 Vue.component('tinymce', Tinymce)
 

+ 2 - 0
ruoyi-ui/src/store/getters.js

@@ -16,6 +16,8 @@ const getters = {
   tenantId: state => state.user.tenantId,
   userType: state => state.user.userType,
   dept: state => state.user.dept,
+  authenticationUser: state => state.user.authenticationUser,
+  phonenumber: state => state.user.phonenumber,
   schoolId: state => state.user.schoolId,
   permissions: state => state.user.permissions,
   teacherClass: state => state.user.teacherClass,

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini