feedback.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <template>
  2. <view class="index tn-safe-area-inset-bottom">
  3. <tn-nav-bar customBack>
  4. <view slot="back" class='tn-custom-nav-bar__back' @click="goBack()">
  5. <text class='icon tn-icon-left'></text>
  6. </view>
  7. <view slot="default" style="display: flex;">
  8. <view style="flex:1;margin-left:25px">
  9. <text :style="{fontSize:(wxFontSize)+'px'}">我的反馈</text>
  10. </view>
  11. </view>
  12. </tn-nav-bar>
  13. <view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
  14. <!-- 图文信息 -->
  15. <block v-for="(item,index) in content" :key="index">
  16. <view class="blogger__item">
  17. <view class="blogger__author tn-flex tn-flex-row-between tn-flex-col-center">
  18. <view class="justify__author__info">
  19. <view class="tn-flex tn-flex-row-center">
  20. <view class="tn-flex tn-flex-row-center tn-flex-col-center">
  21. <view class="tn-padding-right tn-text-ellipsis">
  22. <view class="tn-padding-right tn-text-bold tn-text-lg" :style="{fontSize:(wxFontSize)+'px'}">
  23. {{ item.type==1?'【汇报系统故障】':item.type==2?'【平台机制咨询】':item.type==3?'【投诉】':item.type==5?'【平台用户举报】':'【其他】' }}
  24. </view>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <view
  30. class="blogger__author__btn justify-content-item tn-flex-col-center tn-flex-row-center" >
  31. <text class="" v-if="item.status==1" style="background: #3F51B542;font-size: 12px;
  32. padding: 8px;
  33. color: red;
  34. border-radius: 24px;
  35. " :style="{fontSize:(wxFontSize-6)+'px'}">已处理</text><text class="" v-if="item.status==0" style="background: #3F51B542;font-size: 12px;
  36. padding: 8px;
  37. color: #333333;
  38. border-radius: 24px;
  39. " :style="{fontSize:(wxFontSize-6)+'px'}">未处理</text>
  40. </view>
  41. </view>
  42. <view
  43. class="blogger__desc tn-margin-top-sm tn-margin-bottom-sm tn-text-justify tn-flex-col-center tn-flex-row-left">
  44. <text
  45. class="blogger__desc__content tn-flex-1 tn-text-justify tn-text-df" :style="{fontSize:(wxFontSize-1)+'px'}">{{ item.content }}</text>
  46. </view>
  47. <view v-if="item.ansowe"
  48. class="blogger__desc tn-margin-top-sm tn-margin-bottom-sm tn-text-justify tn-flex-col-center tn-flex-row-left">
  49. <text
  50. class="blogger__desc__content tn-flex-1 tn-text-justify tn-text-df" style="color:red" :style="{fontSize:(wxFontSize-2)+'px'}">回复:{{ item.ansowe }}</text>
  51. </view>
  52. <block v-if="item.imgList">
  53. <view v-if="[1,2,4].indexOf(item.imgList.length) != -1" class="tn-padding-top-xs"
  54. @click="tn('')">
  55. <image v-for="(image_item,image_index) in item.imgList" :key="image_index"
  56. class="blogger__main-image" :class="{
  57. 'blogger__main-image--1 tn-margin-bottom-sm': item.imgList.length === 1,
  58. 'blogger__main-image--2 tn-margin-right-sm tn-margin-bottom-sm': item.imgList.length === 2 || item.imgList.length === 4
  59. }" :src="image_item.ftpUrl" mode="aspectFill" @click="showImg(item.imgList,image_index)"></image>
  60. </view>
  61. <view v-else class="tn-padding-top-xs">
  62. <tn-grid hoverClass="none" :col="3">
  63. <block v-for="(image_item,image_index) in item.imgList" :key="image_index">
  64. <!-- #ifndef MP-WEIXIN -->
  65. <tn-grid-item style="width: 30%;margin: 10rpx;">
  66. <image class="blogger__main-image blogger__main-image--3"
  67. @click="showImg(item.imgList,image_index)" :src="image_item.ftpUrl"
  68. mode="aspectFill"></image>
  69. </tn-grid-item>
  70. <!-- #endif-->
  71. <!-- #ifdef MP-WEIXIN -->
  72. <tn-grid-item style="width: 30%;margin: 10rpx;">
  73. <image class="blogger__main-image blogger__main-image--3"
  74. @click="showImg(item.imgList,image_index)" :src="image_item.ftpUrl"
  75. mode="aspectFill"></image>
  76. </tn-grid-item>
  77. <!-- #endif-->
  78. </block>
  79. </tn-grid>
  80. </view>
  81. </block>
  82. <view class="tn-flex tn-flex-row-between tn-flex-col-center tn-margin-top-xs">
  83. <view class="justify-content-item tn-color-gray tn-text-center">
  84. <view class="tn-padding-right tn-padding-top-xs tn-color-gray" :style="{fontSize:(wxFontSize-3)+'px'}">
  85. {{ item.createTime|formatDate }}
  86. </view>
  87. </view>
  88. </view>
  89. </view>
  90. <!-- 边距间隔 -->
  91. <view class="tn-strip-bottom" v-if="index != content.length - 1"></view>
  92. </block>
  93. <view v-if="showEmpty" style="margin-top: 32vh;">
  94. <tn-empty mode="data"></tn-empty>
  95. </view>
  96. </view>
  97. <view class="edit tnxuanfu" @tap="showLandscape">
  98. <view class="bg0 pa">
  99. <view class="bg1">
  100. <text class='icon tn-icon-edit-write-fill'></text>
  101. </view>
  102. </view>
  103. <view class="hx-box pa">
  104. <view class="pr">
  105. <view class="hx-k1 pa0">
  106. <view class="span"></view>
  107. </view>
  108. <view class="hx-k2 pa0">
  109. <view class="span"></view>
  110. </view>
  111. <view class="hx-k3 pa0">
  112. <view class="span"></view>
  113. </view>
  114. <view class="hx-k4 pa0">
  115. <view class="span"></view>
  116. </view>
  117. <view class="hx-k5 pa0">
  118. <view class="span"></view>
  119. </view>
  120. <view class="hx-k6 pa0">
  121. <view class="span"></view>
  122. </view>
  123. </view>
  124. </view>
  125. </view>
  126. </view>
  127. </template>
  128. <script>
  129. import request from '../../utils/request'
  130. export default {
  131. data() {
  132. return {
  133. showHistory: false,
  134. content: [],
  135. showEmpty: false,
  136. wxFontSize:17
  137. }
  138. },
  139. filters: {
  140. formatDate(value) {
  141. if (!value) return '';
  142. const date = new Date(value);
  143. const today = new Date();
  144. const yesterday = new Date(today); // 昨天的日期
  145. yesterday.setDate(yesterday.getDate() - 1); // 将昨天的日期设置为前一天
  146. if (date.getFullYear() == today.getFullYear() && date.getMonth() == today.getMonth() && date.getDate() ==
  147. today.getDate()) {
  148. return '今天 ' + (date.getHours() > 9 ? '' : '0') + date.getHours() + ':' + (date
  149. .getMinutes() > 9 ? '' : '0') + date.getMinutes(); // 根据需要格式化日期
  150. }
  151. if (date.getFullYear() == yesterday.getFullYear() && date.getMonth() == yesterday.getMonth() && date
  152. .getDate() == yesterday.getDate()) {
  153. return '昨天 ' + (date.getHours() > 9 ? '' : '0') + date.getHours() + ':' + (date
  154. .getMinutes() > 9 ? '' : '0') + date.getMinutes(); // 根据需要格式化日期
  155. }
  156. return date.toLocaleDateString() + ' ' + (date.getHours() > 9 ? '' : '0') + date.getHours() + ':' + (date
  157. .getMinutes() > 9 ? '' : '0') + date.getMinutes(); // 根据需要格式化日期
  158. },
  159. },
  160. created() {
  161. },
  162. methods: {
  163. onPullDownRefresh() {
  164. this.loadData();
  165. },
  166. showLandscape() {
  167. uni.navigateTo({
  168. url: '/pages/mine/addFeed'
  169. })
  170. },
  171. goBack() {
  172. uni.navigateBack();
  173. },
  174. isImage(fileName) {
  175. const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'ico']
  176. const extension = fileName.split('.').pop().toLowerCase();
  177. return imageExtensions.includes(extension);
  178. },
  179. loadData(pageIndex=1) {
  180. if(!uni.getStorageSync('userNo')){
  181. return false;
  182. }
  183. let that = this;
  184. that.showEmpty = false;
  185. request.post('/slbFeedback/query', {
  186. limit:10,
  187. index:pageIndex,
  188. userNo: uni.getStorageSync('userNo'),
  189. }).then(res => {
  190. console.warn(res);
  191. if (res && res.success) {
  192. let newList = res.list || [];
  193. for (let i = 0; i < newList.length; i++) {
  194. newList[i].imgList = [];
  195. for (let j = 0; j < newList[i].fileDetailList.length; j++) {
  196. if (that.isImage(newList[i].fileDetailList[j].fileName)) {
  197. newList[i].imgList.push(newList[i].fileDetailList[j]);
  198. }
  199. }
  200. }
  201. if(pageIndex==1){
  202. that.content = newList;
  203. }else{
  204. that.content = that.content.concat(newList || []);
  205. }
  206. if (newList.length == 0) {
  207. that.showEmpty = true;
  208. } else {
  209. that.showEmpty = false;
  210. }
  211. if(res.total>that.content.length&&res.total>pageIndex*10){
  212. that.loadData(pageIndex+1);
  213. }
  214. }
  215. uni.stopPullDownRefresh();
  216. })
  217. },
  218. showImg(items, index) {
  219. let urls = [];
  220. for (let i = 0; i < items.length; i++) {
  221. urls.push(items[i].ftpUrl);
  222. }
  223. // 预览图片
  224. uni.previewImage({
  225. urls: urls,
  226. current: index,
  227. });
  228. },
  229. },
  230. onLoad() {
  231. const appBaseInfo = wx.getAppBaseInfo();
  232. this.wxFontSize = uni.getStorageSync('fontSize')||appBaseInfo.fontSizeSetting||17;
  233. this.loadData();
  234. }
  235. }
  236. </script>
  237. <style lang="scss" scoped>
  238. /* 胶囊*/
  239. .tn-custom-nav-bar__back {
  240. width: 60%;
  241. height: 100%;
  242. position: relative;
  243. display: flex;
  244. justify-content: space-evenly;
  245. align-items: center;
  246. box-sizing: border-box;
  247. // background-color: rgba(0, 0, 0, 0.15);
  248. border-radius: 1000rpx;
  249. // border: 1rpx solid rgba(255, 255, 255, 0.5);
  250. // color: #FFFFFF;
  251. font-size: 18px;
  252. .icon {
  253. display: block;
  254. flex: 1;
  255. margin: auto;
  256. text-align: center;
  257. }
  258. &:before {
  259. content: " ";
  260. width: 1rpx;
  261. height: 110%;
  262. position: absolute;
  263. top: 22.5%;
  264. left: 0;
  265. right: 0;
  266. margin: auto;
  267. transform: scale(0.5);
  268. transform-origin: 0 0;
  269. pointer-events: none;
  270. box-sizing: border-box;
  271. opacity: 0.7;
  272. background-color: #FFFFFF;
  273. }
  274. }
  275. /* 文章内容 start*/
  276. .blogger {
  277. &__item {
  278. padding: 30rpx;
  279. }
  280. &__author {
  281. &__btn {
  282. margin-right: -12rpx;
  283. opacity: 0.5;
  284. }
  285. }
  286. &__desc {
  287. line-height: 30rpx;
  288. &__label {
  289. color: #1D2541;
  290. background-color: #F3F2F7;
  291. border-radius: 10rpx;
  292. font-size: 22rpx;
  293. padding: 5rpx 15rpx;
  294. margin: 5rpx 18rpx 0 0;
  295. &--prefix {
  296. font-size: 24rpx;
  297. color: #1D2541;
  298. padding-right: 10rpx;
  299. }
  300. }
  301. &__content {
  302. line-height: 50rpx;
  303. }
  304. }
  305. &__content {
  306. margin-top: 18rpx;
  307. padding-right: 18rpx;
  308. &__data {
  309. line-height: 46rpx;
  310. text-align: justify;
  311. overflow: hidden;
  312. transition: all 0.25s ease-in-out;
  313. }
  314. &__status {
  315. margin-top: 10rpx;
  316. font-size: 26rpx;
  317. color: #82B2FF;
  318. }
  319. }
  320. &__main-image {
  321. border: 1rpx solid #F8F7F8;
  322. border-radius: 16rpx;
  323. &--1 {
  324. max-width: 80%;
  325. max-height: 300rpx;
  326. }
  327. &--2 {
  328. max-width: 260rpx;
  329. max-height: 260rpx;
  330. }
  331. &--3 {
  332. height: 212rpx;
  333. width: 100%;
  334. }
  335. }
  336. &__count-icon {
  337. font-size: 40rpx;
  338. padding-right: 5rpx;
  339. }
  340. &__ad {
  341. width: 100%;
  342. height: 500rpx;
  343. transform: translate3d(0px, 0px, 0px) !important;
  344. ::v-deep .uni-swiper-slide-frame {
  345. transform: translate3d(0px, 0px, 0px) !important;
  346. }
  347. .uni-swiper-slide-frame {
  348. transform: translate3d(0px, 0px, 0px) !important;
  349. }
  350. &__item {
  351. position: absolute;
  352. width: 100%;
  353. height: 100%;
  354. transform-origin: left center;
  355. transform: translate3d(100%, 0px, 0px) scale(1) !important;
  356. transition: transform 0.25s ease-in-out;
  357. z-index: 1;
  358. &--0 {
  359. transform: translate3d(0%, 0px, 0px) scale(1) !important;
  360. z-index: 4;
  361. }
  362. &--1 {
  363. transform: translate3d(13%, 0px, 0px) scale(0.9) !important;
  364. z-index: 3;
  365. }
  366. &--2 {
  367. transform: translate3d(26%, 0px, 0px) scale(0.8) !important;
  368. z-index: 2;
  369. }
  370. }
  371. &__content {
  372. border-radius: 40rpx;
  373. width: 640rpx;
  374. height: 500rpx;
  375. overflow: hidden;
  376. }
  377. &__image {
  378. width: 100%;
  379. height: 100%;
  380. }
  381. }
  382. }
  383. /* 文章内容 end*/
  384. /* 间隔线 start*/
  385. .tn-strip-bottom {
  386. width: 100%;
  387. border-bottom: 20rpx solid rgba(241, 241, 241, 0.8);
  388. }
  389. /* 间隔线 end*/
  390. /* 悬浮 */
  391. .tnxuanfu {
  392. animation: suspension 3s ease-in-out infinite;
  393. }
  394. @keyframes suspension {
  395. 0%,
  396. 100% {
  397. transform: translateY(0);
  398. }
  399. 50% {
  400. transform: translateY(-0.8rem);
  401. }
  402. }
  403. /* 悬浮按钮 */
  404. .button-shop {
  405. width: 90rpx;
  406. height: 90rpx;
  407. display: flex;
  408. flex-direction: row;
  409. position: fixed;
  410. /* bottom:200rpx;
  411. right: 20rpx; */
  412. left: 5rpx;
  413. top: 5rpx;
  414. z-index: 1001;
  415. border-radius: 100px;
  416. opacity: 0.9;
  417. }
  418. /* 按钮 */
  419. .edit {
  420. bottom: 300rpx;
  421. right: 75rpx;
  422. position: fixed;
  423. z-index: 9999;
  424. }
  425. .pa,
  426. .pa0 {
  427. position: absolute
  428. }
  429. .pa0 {
  430. left: 0;
  431. top: 0
  432. }
  433. .bg0 {
  434. width: 100rpx;
  435. height: 100rpx;
  436. top: 50%;
  437. left: 50%;
  438. transform: translate(-50%, -50%);
  439. background: #2196F3;
  440. border-radius: 50%;
  441. font-size: 32px;
  442. color: #fff;
  443. text-align: center;
  444. line-height: 50px;
  445. }
  446. .bg1 {
  447. width: 100%;
  448. height: 100%;
  449. }
  450. .hx-box {
  451. top: 50%;
  452. left: 50%;
  453. width: 100rpx;
  454. height: 100rpx;
  455. transform-style: preserve-3d;
  456. transform: translate(-50%, -50%) rotateY(75deg) rotateZ(10deg);
  457. }
  458. .hx-box .pr {
  459. width: 100rpx;
  460. height: 100rpx;
  461. transform-style: preserve-3d;
  462. animation: hxz 20s linear infinite;
  463. }
  464. @keyframes hxz {
  465. 0% {
  466. transform: rotateX(0deg);
  467. }
  468. 100% {
  469. transform: rotateX(-360deg);
  470. }
  471. }
  472. .hx-box .pr .pa0 {
  473. width: 100rpx;
  474. height: 100rpx;
  475. /* border: 4px solid #5ec0ff; */
  476. border-radius: 1000px;
  477. }
  478. @keyframes hx {
  479. to {
  480. transform: rotate(360deg);
  481. }
  482. }
  483. .hx-k1 {
  484. transform: rotateX(-60deg) rotateZ(-60deg)
  485. }
  486. .hx-k2 {
  487. transform: rotateX(-30deg) rotateZ(-30deg)
  488. }
  489. .hx-k3 {
  490. transform: rotateX(0deg) rotateZ(0deg)
  491. }
  492. .hx-k4 {
  493. transform: rotateX(30deg) rotateZ(30deg)
  494. }
  495. .hx-k5 {
  496. transform: rotateX(60deg) rotateZ(60deg)
  497. }
  498. .hx-k6 {
  499. transform: rotateX(90deg) rotateZ(90deg)
  500. }
  501. </style>