complaintListDetail.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <template>
  2. <view class="mainbox">
  3. <view class="imgs">
  4. <image v-for="(img,i) in images" :key="i" :src="img" mode="aspectFill" @click="previewImage(i,images)"></image>
  5. </view>
  6. <viwe class="con">
  7. <view class="title">
  8. <text class="tag" :style="{backgroundColor: info.isProcessCompleted==1? '#eee': info.isHandlePlatform==0&&info.isHandleStore==0 ? 'red':'#2583EB', color: item.isProcessCompleted==1? '#666':'#fff'}">
  9. {{info.isProcessCompleted==1? '已结束':info.isHandlePlatform==0&&info.isHandleStore==0 ? '待处理':'已处理'}}
  10. </text>{{info.title}}</view>
  11. <view>{{info.content}}</view>
  12. <view style="margin-top: 24rpx;color:#999999">时间:{{info.createTime || '--'}}</view>
  13. </viwe>
  14. <viwe class="con" v-show="msgList&&msgList.length>0">
  15. <view class="msg">
  16. <view v-for="(msg,i) in msgList" :key="i" :class="msg.sendType !=1?'storemsg':''" style="margin-bottom: 24rpx;">
  17. <view class="lable">{{msg.sendType ==2?'商家回复:':msg.sendType ==3?'平台回复:':msg.sendType ==1?'我:':''}}</view>
  18. <view class="imgs" v-if="msg.images">
  19. <image v-for="(img,i) in msg.images.split(',')" :key="i" :src="img" mode="aspectFill" @click="previewImage(i,msg.images.split(','))"></image>
  20. </view>
  21. <view class="val">{{msg.content||''}}</view>
  22. <view class="val x-f" style="margin-top: 10rpx;font-size: 28rpx;color:#999999;">
  23. <text style="margin-right: 16rpx;">{{msg.createTime || '--'}}</text>
  24. <!-- <u-icon name="chat" color="#999" size="48rpx" v-if="info.isProcessCompleted!=1&&(msg.sendType ==2||msg.sendType ==3)" @click="open"></u-icon> -->
  25. </view>
  26. </view>
  27. </view>
  28. <!-- <view class="mymsg">
  29. <view class="val">问题问题问题问题问题问题问题问题问题问题</view>
  30. <view class="val x-f" style="margin-top: 10rpx;font-size: 28rpx;color:#999999;"><text style="margin-right: 16rpx;">2022-12-22 12:33</text></view>
  31. </view> -->
  32. </viwe>
  33. <view class="chatbox" v-if="info.isProcessCompleted!=1">
  34. <u-icon name="chat" color="#999" size="48rpx"@click="open"></u-icon>
  35. </view>
  36. <u-popup :show="show" :closeable="true" @close="close">
  37. <view class="replybox">
  38. <view class="replybox-title">回复:</view>
  39. <view class="form-item">
  40. <u-upload v-if="fileList1.length>0" :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" width="60" height="60":maxCount="4"></u-upload>
  41. <u--textarea v-model="content" placeholder="输入回复内容" border="none" count
  42. maxlength='300'></u--textarea>
  43. </view>
  44. <view class="replybox-footer x-bc">
  45. <view class="uploadbox" :style="{visibility: fileList1.length>0 ? 'hidden':'visible'}">
  46. <u-upload :disabled="fileList1.length>0" :fileList="fileList1" uploadIcon="photo" uploadIconColor="#666" @afterRead="afterRead" @delete="deletePic" name="1" width="24" height="24":maxCount="4"></u-upload>
  47. </view>
  48. <view class="send" @click="send">发送</view>
  49. </view>
  50. </view>
  51. </u-popup>
  52. </view>
  53. </template>
  54. <script>
  55. import {storeComplaintDetail,storeComplaintMsg,storeComplaintMsgAdd} from "@/api/user.js"
  56. export default {
  57. data() {
  58. return {
  59. id:'',
  60. images:[],
  61. info: {},
  62. msgList: [],
  63. fileList1: [],
  64. show: false,
  65. content:'',
  66. replyImages: ""
  67. }
  68. },
  69. onLoad(option) {
  70. this.id = option.id
  71. this.getDetail()
  72. this.getMsg()
  73. },
  74. methods: {
  75. open() {
  76. this.content = ''
  77. this.fileList1 = []
  78. this.replyImages = ''
  79. this.show = true
  80. },
  81. close() {
  82. this.show = false
  83. },
  84. previewImage(index,images) {
  85. uni.previewImage({
  86. current: index,
  87. urls: images
  88. });
  89. },
  90. getDetail() {
  91. storeComplaintDetail(this.id).then(res=>{
  92. if(res.code == 200) {
  93. this.info = res.data || {}
  94. this.images = res.data&&res.data.images.split(',')
  95. } else {
  96. uni.showToast({
  97. title:res.msg,
  98. icon: "none"
  99. })
  100. }
  101. })
  102. },
  103. getMsg() {
  104. storeComplaintMsg({
  105. complaintId: this.id,
  106. pageNum: 1,
  107. pageSize: 100,
  108. }).then(res=>{
  109. if(res.code == 200) {
  110. this.msgList = res.rows
  111. } else {
  112. uni.showToast({
  113. title:res.msg,
  114. icon: "none"
  115. })
  116. }
  117. })
  118. },
  119. send() {
  120. if (this.fileList1.length > 0) {
  121. this.replyImages = this.fileList1.map(item=>item.url).join(',')
  122. }
  123. if(!this.content) {
  124. uni.showToast({
  125. title: '请输入回复内容',
  126. icon: "none"
  127. })
  128. return
  129. }
  130. const param = {
  131. complaintId: this.id,
  132. sendType: 1,
  133. content: this.content,
  134. images: this.replyImages
  135. }
  136. storeComplaintMsgAdd(param).then(res=>{
  137. if(res.code == 200) {
  138. this.getMsg()
  139. this.show = false
  140. } else {
  141. uni.showToast({
  142. title: res.msg,
  143. icon: "none"
  144. })
  145. }
  146. })
  147. },
  148. deletePic(event) {
  149. this[`fileList${event.name}`].splice(event.index, 1)
  150. },
  151. async afterRead(event) {
  152. // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
  153. let lists = [].concat(event.file)
  154. let fileListLen = this[`fileList${event.name}`].length
  155. lists.map((item) => {
  156. this[`fileList${event.name}`].push({
  157. ...item,
  158. status: 'uploading',
  159. message: '上传中'
  160. })
  161. })
  162. for (let i = 0; i < lists.length; i++) {
  163. const result = await this.uploadFilePromise(lists[i].url)
  164. let item = this[`fileList${event.name}`][fileListLen]
  165. this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
  166. status: 'success',
  167. message: '',
  168. url: result
  169. }))
  170. fileListLen++
  171. }
  172. },
  173. uploadFilePromise(url) {
  174. return new Promise((resolve, reject) => {
  175. let a = uni.uploadFile({
  176. url: uni.getStorageSync('requestPath') + '/app/common/uploadOSS',
  177. filePath: url,
  178. name: 'file',
  179. formData: {
  180. user: 'test'
  181. },
  182. success: (res) => {
  183. setTimeout(() => {
  184. console.log(JSON.parse(res.data).url)
  185. resolve(JSON.parse(res.data).url)
  186. }, 1000)
  187. }
  188. });
  189. })
  190. },
  191. }
  192. }
  193. </script>
  194. <style scoped lang="scss">
  195. .chatbox {
  196. height: 80rpx;
  197. width: 80rpx;
  198. border-radius: 50%;
  199. display: flex;
  200. align-items: center;
  201. justify-content: center;
  202. position: fixed;
  203. bottom: 200rpx;
  204. right: 50rpx;
  205. z-index: 999;
  206. box-shadow: 0 0 20px 5px #eee;
  207. background-color: #fff;
  208. }
  209. .lable {
  210. margin-bottom: 16rpx;
  211. font-weight: bold;
  212. }
  213. .tag {
  214. padding: 5rpx 6rpx;
  215. font-size: 20rpx;
  216. color: #FFFFFF;
  217. background-color: red;
  218. border-radius: 10rpx;
  219. margin-right: 10rpx;
  220. }
  221. .send{
  222. flex-shrink: 0;
  223. padding: 10rpx 24rpx;
  224. font-size: 28rpx;
  225. border-radius: 28rpx 28rpx 28rpx 28rpx;
  226. background-color: #2583EB;
  227. font-weight: 500;
  228. font-size: 24rpx;
  229. color: #fff;
  230. }
  231. .replybox {
  232. padding: 0 24rpx 24rpx 24rpx;
  233. &-title {
  234. padding: 24rpx 0;
  235. }
  236. .form-item {
  237. background-color: #fff;
  238. border: 1rpx solid #ddd;
  239. border-radius: 10rpx;
  240. padding: 16rpx;
  241. }
  242. &-footer {
  243. margin-top: 24rpx;
  244. }
  245. .uploadbox {
  246. position: relative;
  247. }
  248. }
  249. .msg{
  250. margin-bottom: 20rpx;
  251. border-radius: 16rpx 16rpx 16rpx 16rpx;
  252. }
  253. .storemsg {
  254. background-color: #f5f5f5;
  255. padding: 16rpx;
  256. border-radius: 16rpx;
  257. }
  258. .val {
  259. color:#222;
  260. word-break: break-all;
  261. }
  262. .mainbox {
  263. padding: 24rpx;
  264. .imgs {
  265. display: flex;
  266. flex-wrap: wrap;
  267. image {
  268. height: 150rpx;
  269. width: 150rpx;
  270. margin: 0 20rpx 20rpx 0;
  271. }
  272. }
  273. .con{
  274. display: block;
  275. background: #FFFFFF;
  276. border-radius: 16rpx 16rpx 16rpx 16rpx;
  277. padding: 24rpx;
  278. overflow: hidden;
  279. font-size: 28rpx;
  280. margin-bottom: 24rpx;
  281. color: #666666;
  282. .title {
  283. font-size: 30rpx;
  284. font-weight: bold;
  285. color: #333;
  286. margin-bottom: 16rpx;
  287. }
  288. }
  289. }
  290. </style>