ComplaintForm.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <template><page-meta :root-font-size="fontSize+'px'"></page-meta>
  2. <member-base :show="false"><view class="div container">
  3. <!-- header -->
  4. <view class="div common-header-wrap">
  5. <view :style="'height:'+navHeight+'px'"></view>
  6. <view class="common-header-holder"></view>
  7. <view class="common-header-fixed">
  8. <title-header />
  9. <uni-nav-bar title="投诉详情" class="common-header" left-icon="back" @clickLeft="goBack()">
  10. </uni-nav-bar>
  11. </view>
  12. </view>
  13. <view class="div" v-if="!complain_id">
  14. <!-- body -->
  15. <view class="div body">
  16. <view class="div" @click="showPopup('subjectVisible')">
  17. <flex-line :is-link="true" :show-border="true"><text class="span line-name">投诉主题</text><text class="span" slot="right">{{subject_name}}</text></flex-line>
  18. </view>
  19. <flex-line class="menu-item"><text class="span line-name">投诉凭证</text></flex-line>
  20. <view class="div image-wrapper">
  21. <view class="div user-avatar">
  22. <uni-file-picker v-model="image" fileMediatype="image" mode="grid" :limit="3" :auto-upload="false"
  23. @select="uploadComplaintPic" @delete="deleteComplaintPic"></uni-file-picker>
  24. </view>
  25. </view>
  26. <view class="div order-comment-body">
  27. <view class="div enter">
  28. <textarea
  29. placeholder="投诉内容"
  30. v-model="content"
  31. ></textarea>
  32. </view>
  33. </view>
  34. <view class="div pt-10 pb-10"><view class="div common-btn ds-button-large" @click="addComplaint">提交</view></view>
  35. </view>
  36. <!--投诉主题-->
  37. <uni-popup background-color="#fff" ref="subjectVisible" type="right" >
  38. <view :style="'width:'+screenWidth+'px'" class="common-popup-wrapper">
  39. <view class="div common-header-wrap">
  40. <view :style="'height:'+navHeight+'px'"></view>
  41. <view class="common-header-holder"></view>
  42. <view class="common-header-fixed">
  43. <title-header />
  44. <uni-nav-bar title="投诉主题" class="common-header" left-icon="back" @clickLeft="hidePopup('subjectVisible')">
  45. </uni-nav-bar>
  46. </view>
  47. </view>
  48. <view class="div common-popup-content">
  49. <scroll-view style="position: absolute;top:0;right:0;left:0;bottom:0" scroll-y="true">
  50. <radio-group @change="radioChange" class='radio-wrapper'>
  51. <view class='radio-item' v-for="(item, index) in subject_options" :key="index">
  52. <radio :value="item.value" :checked="subject==item.value" />
  53. <text>{{item.label}}</text>
  54. </view>
  55. </radio-group>
  56. </scroll-view>
  57. </view>
  58. </view>
  59. </uni-popup>
  60. </view>
  61. <view class="div" v-else>
  62. <!--投诉信息-->
  63. <view class="div body">
  64. <flex-line class="menu-item" :show-border="true"><text class="span line-name">投诉信息</text></flex-line>
  65. <view class="div menu-content">
  66. <flex-line :show-border="true"><text class="span line-name">投诉状态</text><text class="span" slot="right">{{complaint.complain_state_text}}</text></flex-line>
  67. <flex-line :show-border="true"><text class="span line-name">投诉人</text><text class="span" slot="right">{{complaint.accused_name}}</text></flex-line>
  68. <flex-line :show-border="true"><text class="span line-name">投诉主题</text><text class="span" slot="right">{{complaint.complain_subject_content}}</text></flex-line>
  69. <flex-line :show-border="true"><text class="span line-name">投诉时间</text><text class="span" slot="right">{{$moment.unix(complaint.complain_datetime).format('YYYY.MM.DD')}}</text></flex-line>
  70. <flex-line :show-border="true"><text class="span line-name">投诉内容</text><text class="span" slot="right">{{complaint.complain_content}}</text></flex-line>
  71. <view class="div" @click="showPopup('isshow')" v-if="complain_pic.length"><flex-line :show-border="true"><text class="span line-name">投诉凭证</text><text class="span" slot="right">查看</text></flex-line></view>
  72. </view>
  73. <uni-popup background-color="#fff" ref="isshow" v-if="complain_pic.length>0">
  74. <view class="div preview-picture">
  75. <title-header />
  76. <view
  77. class="div picture-header"
  78. v-on:click="hidePopup('isshow')"
  79. >
  80. <text class="span">关闭</text
  81. ><text class="span" v-if="complain_pic"
  82. >{{ defaultindex + 1 }} / {{ complain_pic.length }}</text
  83. >
  84. </view>
  85. <view class="div picture-body">
  86. <swiper
  87. :autoplay="false"
  88. :show-indicators="true"
  89. :current="defaultindex"
  90. class="ui-common-swiper"
  91. @change="handleChange"
  92. >
  93. <swiper-item
  94. class="ui-common-swiper-item"
  95. v-for="(item, index) in complain_pic"
  96. v-bind:key="index"
  97. >
  98. <image mode="aspectFit" class="img" v-bind:src="item" style="max-width: 100%;max-height: 100%" />
  99. </swiper-item>
  100. </swiper>
  101. </view>
  102. </view>
  103. </uni-popup>
  104. </view>
  105. <!--申诉信息-->
  106. <view class="div body" v-if="complaint.complain_state>20">
  107. <flex-line class="menu-item" :show-border="true"><text class="span line-name">申诉信息</text></flex-line>
  108. <view class="div menu-content">
  109. <flex-line :show-border="true"><text class="span line-name">申诉时间</text><text class="span" slot="right">{{$moment.unix(complaint.appeal_datetime).format('YYYY.MM.DD')}}</text></flex-line>
  110. <flex-line :show-border="true"><text class="span line-name">申诉内容</text><text class="span" slot="right">{{complaint.appeal_message}}</text></flex-line>
  111. <view class="div" @click="showPopup('isshow2')" v-if="appeal_pic.length"><flex-line :show-border="true"><text class="span line-name">申诉凭证</text><text class="span" slot="right">查看</text></flex-line></view>
  112. </view>
  113. <uni-popup background-color="#fff" ref="isshow2" v-if="appeal_pic.length>0">
  114. <view class="div preview-picture">
  115. <title-header />
  116. <view
  117. class="div picture-header"
  118. v-on:click="hidePopup('isshow2')"
  119. >
  120. <text class="span">关闭</text
  121. ><text class="span" v-if="appeal_pic"
  122. >{{ defaultindex2 + 1 }} / {{ appeal_pic.length }}</text
  123. >
  124. </view>
  125. <view class="div picture-body">
  126. <swiper
  127. :autoplay="false"
  128. :show-indicators="true"
  129. :current="defaultindex2"
  130. class="ui-common-swiper"
  131. @change="handleChange2"
  132. >
  133. <swiper-item
  134. class="ui-common-swiper-item"
  135. v-for="(item, index) in appeal_pic"
  136. v-bind:key="index"
  137. >
  138. <image mode="aspectFit" class="img" v-bind:src="item" style="max-width: 100%;max-height: 100%" />
  139. </swiper-item>
  140. </swiper>
  141. </view>
  142. </view>
  143. </uni-popup>
  144. </view>
  145. <!--对话-->
  146. <view class="div body">
  147. <flex-line class="menu-item" :show-border="true"><text class="span line-name">对话记录</text></flex-line>
  148. <flex-line v-for="(item,index) in talk_list" :key="index" :show-border="true"><text class="span line-name">{{item.talk}}</text></flex-line>
  149. </view>
  150. <view class="div" v-if="complaint.complain_state>20 && complaint.complain_state<99">
  151. <view class="div body">
  152. <view class="div order-comment-body">
  153. <view class="div enter">
  154. <textarea
  155. placeholder="对话内容"
  156. v-model="content"
  157. ></textarea>
  158. </view>
  159. </view>
  160. <view class="div pt-10 pb-10"><view class="div common-btn ds-button-large" @click="addComplaintTalk">提交</view></view>
  161. </view>
  162. </view>
  163. </view>
  164. <tui-picture-cropper v-if="cropperOption.imgUrl" :width="cropperOption.autoCropWidth" :height="cropperOption.autoCropHeight" :imageUrl="cropperOption.img" @ready="cropReady" @cropper="useCrop" @back="cropBack"></tui-picture-cropper>
  165. </view></member-base>
  166. </template>
  167. <script>
  168. import {getFontSize} from '@/util/common'
  169. import TitleHeader from '../../TitleHeader'
  170. import MemberBase from '../MemberBase'
  171. import tuiPictureCropper from "@/components/thorui/tui-picture-cropper/tui-picture-cropper"
  172. import { addComplaint, uploadComplaintPic, getCommonData, addComplaintTalk, getComplaintInfo, getComplaintTalk } from '../../../api/memberCompliant'
  173. import flexLine from '../../flexLine'
  174. export default {
  175. computed:{
  176. fontSize(){
  177. return getFontSize()
  178. },
  179. },
  180. data(){
  181. return {
  182. navHeight: 0,
  183. screenWidth:0,
  184. screenHeight:0,
  185. cropperOption: {
  186. img: '',
  187. canMove: false,
  188. autoCrop: true,
  189. autoCropWidth: 100,
  190. autoCropHeight: 100,
  191. maxImgSize: 500,
  192. outputType: 'png'
  193. },
  194. cropType: '',
  195. content: '',
  196. complain_id: 0,
  197. order_id: 0,
  198. goods_id: 0,
  199. subject_options: [],
  200. subject_name: '',
  201. subject: '',
  202. image: [],
  203. file_value: {},
  204. complaint: {},
  205. complain_pic: [],
  206. appeal_pic: [],
  207. defaultindex: 0,
  208. defaultindex2: 0,
  209. talk_list: []
  210. }
  211. },
  212. components:{
  213. TitleHeader,
  214. MemberBase,
  215. flexLine,
  216. tuiPictureCropper
  217. },
  218. onLoad: function (option) {
  219. this.complain_id=option.complain_id
  220. this.order_id=option.order_id
  221. this.goods_id=option.goods_id
  222. this.getData()
  223. },
  224. watch: {
  225. subject: function (subject) {
  226. let temp = subject.split(',')
  227. this.subject_name = temp[1]
  228. this.hidePopup('subjectVisible')
  229. }
  230. },
  231. mounted(){
  232. // #ifdef MP-WEIXIN
  233. this.navHeight = uni.getMenuButtonBoundingClientRect().top
  234. // #endif
  235. const res = uni.getSystemInfoSync()
  236. this.screenWidth = res.windowWidth
  237. this.screenHeight = res.windowHeight
  238. },
  239. methods:{
  240. radioChange(e){
  241. this.subject=e.detail.value
  242. },
  243. getData(){
  244. if (!this.complain_id) {
  245. getCommonData(this.order_id, this.goods_id).then(res => {
  246. let subject_options = res.result.subject_list
  247. for (var i in subject_options) {
  248. this.subject_options.push({
  249. label: subject_options[i].complainsubject_content,
  250. value: subject_options[i].complainsubject_id + ',' + subject_options[i].complainsubject_content
  251. })
  252. }
  253. this.subject = subject_options[0].complainsubject_id + ',' + subject_options[0].complainsubject_content
  254. }).catch(function (error) {
  255. uni.showToast({icon:'none',title: error.message})
  256. uni.navigateBack({delta:1})
  257. })
  258. } else {
  259. getComplaintTalk(this.complain_id).then(res => {
  260. this.talk_list = res.result.talk_list
  261. }).catch(function (error) {
  262. uni.showToast({icon:'none',title: error.message})
  263. })
  264. getComplaintInfo(this.complain_id).then(res => {
  265. this.complaint = res.result.complain_info
  266. this.complain_pic = res.result.complain_pic
  267. this.appeal_pic = res.result.appeal_pic
  268. }).catch(function (error) {
  269. uni.showToast({icon:'none',title: error.message})
  270. })
  271. }
  272. },
  273. showPopup(id){
  274. this.$refs[id].open()
  275. },
  276. hidePopup(id){
  277. this.$refs[id].close()
  278. },
  279. goBack(){uni.navigateBack({delta:1})},
  280. handleChange (e) {
  281. this.defaultindex = e.detail.current
  282. },
  283. handleChange2 (e) {
  284. this.defaultindex2 = e.detail.current
  285. },
  286. addComplaintTalk () {
  287. addComplaintTalk(this.complain_id, this.content).then(res => {
  288. this.getData()
  289. }).catch(function (error) {
  290. uni.showToast({icon:'none',title: error.message})
  291. })
  292. },
  293. addComplaint () {
  294. var file_value = []
  295. for (var i in this.file_value) {
  296. file_value.push(this.file_value[i])
  297. }
  298. addComplaint(this.order_id, this.goods_id, this.subject, this.content, file_value).then(res => {
  299. uni.navigateTo({url:'/pages/member/complaint/ComplaintList'})
  300. }).catch(function (error) {
  301. uni.showToast({icon:'none',title: error.message})
  302. })
  303. },
  304. useCrop(res) {
  305. let index = this.cropType
  306. var formdata = {
  307. filePath: res.url,
  308. name: 'complain_pic'
  309. }
  310. uploadComplaintPic(formdata).then(res => {
  311. this.file_value[index] = res.result.file_name
  312. this.image[index] = [{
  313. name: index,
  314. extname: 'jpg',
  315. url: res.result.pic
  316. }]
  317. this.cropperOption.imgUrl = ''
  318. this.$forceUpdate()
  319. uni.hideLoading()
  320. }).catch(function(error) {
  321. uni.showToast({
  322. icon: 'none',
  323. title: error.message
  324. })
  325. uni.hideLoading()
  326. this.cropperOption.imgUrl = ''
  327. this.$forceUpdate()
  328. })
  329. },
  330. deleteComplaintPic(event) {
  331. let file = event.tempFile
  332. var index = file.uuid
  333. delete this.file_value[index]
  334. },
  335. cropReady() {
  336. this.cropperOption.img = this.cropperOption.imgUrl
  337. },
  338. cropBack(){
  339. this.cropperOption.imgUrl=''
  340. this.$forceUpdate()
  341. },
  342. uploadComplaintPic(event) {
  343. let that = this
  344. let file = event.tempFiles[0]
  345. this.cropType = file.uuid
  346. that.cropperOption.imgUrl = file.path
  347. that.cropperOption.autoCropWidth = uni.getSystemInfoSync().windowWidth
  348. that.cropperOption.autoCropHeight = uni.getSystemInfoSync().windowWidth
  349. that.cropperOption.maxImgSize = uni.getSystemInfoSync().windowHeight - 40
  350. that.$forceUpdate()
  351. }
  352. }
  353. }
  354. </script>
  355. <style lang="scss" scoped>
  356. .common-header{
  357. .btn{background: #000;color: #fff;box-shadow: 0px 2px 4px #d2d2d2;}
  358. }
  359. .ui-common-swiper {
  360. width: 100%;
  361. }
  362. .ui-common-swiper-item{display: flex;align-content: center}
  363. .common-score-wrapper .back{display: block}
  364. .container {
  365. display: flex;
  366. flex-direction: column;
  367. justify-content: flex-start;
  368. align-items: stretch;
  369. .body {
  370. background: #fff;
  371. padding:0 $pageSpace;
  372. .order-comment-body {
  373. background: rgba(255, 255, 255, 1);
  374. .body-list {
  375. display: flex;
  376. justify-content: left;
  377. align-content: center;
  378. align-items: center;
  379. padding-bottom:0.75rem;
  380. border-bottom: 1px solid #e8eaed;
  381. }
  382. .image {
  383. width:3.7rem;
  384. height:3.7rem;
  385. flex-shrink: 0;
  386. .img {
  387. width: 100%;
  388. height: 100%;
  389. }
  390. }
  391. .comment {
  392. flex-basis: 100%;
  393. padding-left:0.75rem;
  394. .span {
  395. font-size:$h2;
  396. color: #7c7f88;
  397. text-align: left;
  398. display: block;
  399. }
  400. .ul {
  401. display: flex;
  402. justify-content: space-between;
  403. align-content: center;
  404. align-items: center;
  405. margin-top:1.2rem;
  406. .li {
  407. .img {
  408. width:1rem;
  409. height:1rem;
  410. flex-shrink: 0;
  411. }
  412. label {
  413. font-size:$subFontSize;
  414. color: rgba(78, 84, 93, 1);
  415. font-weight: normal;
  416. }
  417. }
  418. }
  419. }
  420. .enter {
  421. padding-top:0.75rem;
  422. textarea {
  423. width: 100%;
  424. height: 6rem;
  425. background: rgba(247, 249, 250, 1);
  426. border: 1px solid #f7f9fa;
  427. box-sizing: border-box;
  428. padding: 0.5rem 0 0 0.5rem;
  429. font-size:$subFontSize;
  430. -webkit-appearance: none;
  431. outline: none;
  432. }
  433. }
  434. }
  435. }
  436. }
  437. .swipe-wrapper {
  438. width: 100%;
  439. }
  440. .mint-popup {
  441. width: 100%;
  442. height: 100%;
  443. background-color: #000;
  444. }
  445. .mint-swipe,
  446. .mint-swipe-items-wrap {
  447. position: static;
  448. }
  449. .preview-picture {
  450. width: 100%;
  451. height: 100%;
  452. position: fixed;
  453. z-index: 10;
  454. top: 0;
  455. bottom: 0;
  456. left: 0;
  457. right: 0;
  458. background-color: #000;
  459. display: flex;
  460. flex-direction: column;
  461. .picture-header {
  462. color: #000;
  463. background-color: #fff;
  464. display: flex;
  465. justify-content: center;
  466. align-content: center;
  467. align-items: center;
  468. width: 100%;
  469. top: 0;
  470. padding-top:var(--status-bar-height);
  471. .span {
  472. font-size:$subFontSize;
  473. font-weight: normal;
  474. height:2.2rem;
  475. line-height:2.2rem;
  476. &:first-child {
  477. position: absolute;
  478. cursor: pointer;
  479. left:0.75rem;
  480. background-size:1.2rem;
  481. display: inline-block;
  482. height:2.2rem;
  483. line-height:2.2rem;
  484. }
  485. }
  486. }
  487. .picture-body {
  488. flex:1;
  489. display: flex;
  490. justify-content: center;
  491. align-content: center;
  492. align-items: center;
  493. }
  494. }
  495. .radio-wrapper{
  496. display: block;
  497. padding: 0 $pageSpace;
  498. .radio-item{
  499. padding:.5rem 0;
  500. border-bottom: 1px dashed #f5f5f5;
  501. }
  502. }
  503. </style>
  504. <style lang="scss">
  505. .menu-content .mint-cell-title{flex:unset;width:4rem}
  506. .menu-content .mint-cell-value{flex:1}
  507. </style>