You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

626 lines
13 KiB

  1. <template>
  2. <view class="main">
  3. <view class="top" :style="{height:iSMT+'px'}"></view>
  4. <!-- 头部导航 -->
  5. <view class="header">
  6. <view class="back-icon">
  7. <image src="/static/customer-service-platform/cs-platform-back.png" class="header-icon-image"></image>
  8. </view>
  9. <view class="title">{{headerTitle}}</view>
  10. <view class="notification-icon">
  11. <image src="/static/customer-service-platform/message.png" class="header-icon-image"></image>
  12. </view>
  13. </view>
  14. <!-- 内容区域 - 使用滚动视图 -->
  15. <scroll-view scroll-y class="content-container">
  16. <view class="content-header">
  17. <view class="logo">
  18. <image mode="aspectFit" src="/static/customer-service-platform/ellipse-dc-img.png"></image>
  19. </view>
  20. <view class="greeting">
  21. <text class="greet-title">我能为你做点什么</text>
  22. <text class="greet-sub">DeepChart随时为您提供服务</text>
  23. </view>
  24. </view>
  25. <!--猜你想问卡片部分-->
  26. <view class="card">
  27. <view class="suggest-header">
  28. <text class="suggest-title">猜你想问</text>
  29. <view class="swap" @click="shuffleQuestions">
  30. <image class="swap-icon" src="/static/customer-service-platform/refresh-icon.png"></image>
  31. <text class="swap-title">换一换</text>
  32. </view>
  33. </view>
  34. <view class="card-line"></view>
  35. <view class="suggest-list">
  36. <view class="suggest-item" v-for="(q, idx) in showQuestions" :key="q.id"
  37. @click="onQuestionClick(q)">
  38. <view class="left">
  39. <view :class="['num', 'num-' + ((idx % 5) + 1)]">{{ idx + 1 }}</view>
  40. </view>
  41. <view class="mid">
  42. <text class="q-text">{{ q.text }}</text>
  43. </view>
  44. <view class="right">
  45. <text class="arrow"></text>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. <!--反馈卡片部分-->
  51. <text class="feedback-card-title">反馈中心</text>
  52. <view class="card">
  53. <view class="suggest-header">
  54. <text class="feedback-title">填写反馈内容</text>
  55. </view>
  56. <view class="card-line"></view>
  57. <textarea class="feedback-input" placeholder="请描述您想反馈的内容 最多可输入200字" maxlength="200"
  58. v-model="feedbackText" />
  59. <view class="meta-row">
  60. <text class="char-count">{{ feedbackText.length }}/200</text>
  61. </view>
  62. <view class="suggest-header">
  63. <text class="upload-img-tip">上传图片</text>
  64. </view>
  65. <view class="upload-row">
  66. <view class="img-slot" v-for="(img, index) in images" :key="index">
  67. <image :src="img" mode="scaleToFill" class="slot-img" />
  68. <button v-if="img" class="remove" @click="removeImage(index)">×</button>
  69. </view>
  70. <view class="img-slot" v-if="images.length < 9">
  71. <view class="slot-empty" @click="chooseImage()">
  72. <image src="/static/customer-service-platform/camera.png" class="camera-icon" />
  73. </view>
  74. </view>
  75. <text class="tip-text" v-if="images.length === 0">最多添加9张图片</text>
  76. </view>
  77. <button class="feedback-btn" @click="submit">提交</button>
  78. </view>
  79. <!--历史反馈卡片部分-->
  80. <view class="card">
  81. <text class="feedback-title">历史反馈内容</text>
  82. <view class="card-line"></view>
  83. <button class="feedback-btn" @click="viewHistory">查看</button>
  84. </view>
  85. </scroll-view>
  86. </view>
  87. </template>
  88. <script>
  89. export default {
  90. data() {
  91. return {
  92. headerTitle: '智能客服中台',
  93. iSMT: 0,
  94. questions: [{
  95. id: 1,
  96. text: '如何注册账号?'
  97. },
  98. {
  99. id: 2,
  100. text: '为什么无法注册账户?'
  101. },
  102. {
  103. id: 3,
  104. text: 'DeepChart的主要功能有哪些?'
  105. },
  106. {
  107. id: 4,
  108. text: '什么是机构行为?'
  109. },
  110. {
  111. id: 5,
  112. text: '为什么机构行为很重要?'
  113. },
  114. {
  115. id: 6,
  116. text: '如何绑定银行卡?'
  117. },
  118. {
  119. id: 7,
  120. text: '忘记密码怎么办?'
  121. }
  122. ],
  123. showQuestions: [],
  124. feedbackText: '',
  125. images: [],
  126. capacity: 2
  127. }
  128. },
  129. mounted() {
  130. // 状态栏高度
  131. this.iSMT = uni.getSystemInfoSync().statusBarHeight;
  132. },
  133. created() {
  134. this.shuffleQuestions();
  135. },
  136. methods: {
  137. onBack() {
  138. // uni.navigateBack 或自定义
  139. if (typeof uni !== 'undefined') uni.navigateBack();
  140. },
  141. shuffleQuestions() {
  142. // 随机取前4条或展示5条
  143. const arr = this.questions.slice();
  144. for (let i = arr.length - 1; i > 0; i--) {
  145. const j = Math.floor(Math.random() * (i + 1));
  146. [arr[i], arr[j]] = [arr[j], arr[i]];
  147. }
  148. this.showQuestions = arr.slice(0, 5);
  149. },
  150. onQuestionClick(q) {
  151. // 可跳转到问答页或直接填入反馈
  152. this.feedbackText = q.text;
  153. },
  154. chooseImage() {
  155. const that = this;
  156. if (typeof uni === 'undefined' || !uni.chooseImage) return;
  157. const remain = 9 - (that.images ? that.images.length : 0);
  158. if (remain <= 0) {
  159. if (typeof uni !== 'undefined') uni.showToast({
  160. title: '最多只能上传9张',
  161. icon: 'none'
  162. });
  163. return;
  164. }
  165. uni.chooseImage({
  166. count: remain, // 最多选取剩余可上传数量
  167. sizeType: ['original', 'compressed'],
  168. sourceType: ['album', 'camera'],
  169. success(res) {
  170. // res.tempFilePaths 是数组(小程序/APP)
  171. const paths = res.tempFilePaths || (res.tempFiles && res.tempFiles.map(f => f.path)) || [];
  172. // 追加到 images(Vue2 下 push 是响应式的)
  173. for (let p of paths) {
  174. if (that.images.length < 9) {
  175. that.images.push(p);
  176. }
  177. }
  178. // 可选:若要立即上传到服务器,可在这里调用 uni.uploadFile
  179. },
  180. fail(err) {
  181. // 处理取消或失败(不需要提示太多)
  182. // console.log('chooseImage fail', err)
  183. }
  184. });
  185. },
  186. removeImage(index) {
  187. // 删除并保持响应
  188. this.images.splice(index, 1);
  189. },
  190. submit() {
  191. if (!this.feedbackText.trim()) {
  192. if (typeof uni !== 'undefined') uni.showToast({
  193. title: '请填写反馈内容',
  194. icon: 'none'
  195. });
  196. return;
  197. }
  198. // 模拟上传
  199. if (typeof uni !== 'undefined') uni.showLoading({
  200. title: '提交中...'
  201. });
  202. setTimeout(() => {
  203. if (typeof uni !== 'undefined') {
  204. uni.hideLoading();
  205. uni.showToast({
  206. title: '提交成功',
  207. icon: 'success'
  208. });
  209. } else {
  210. console.log('提交数据', {
  211. text: this.feedbackText,
  212. images: this.images
  213. });
  214. }
  215. // 清空
  216. this.feedbackText = '';
  217. this.images = [null, null];
  218. }, 1000);
  219. },
  220. viewHistory() {
  221. // 跳转到历史页
  222. if (typeof uni !== 'undefined') uni.navigateTo({
  223. url: '/pages/customerServicePlatform/historyRecord'
  224. });
  225. }
  226. }
  227. }
  228. </script>
  229. <style scoped>
  230. .main {
  231. display: flex;
  232. flex-direction: column;
  233. height: 100vh;
  234. background-color: #ffffff;
  235. }
  236. .header {
  237. display: flex;
  238. justify-content: space-between;
  239. align-items: center;
  240. padding: 20rpx 30rpx;
  241. background-color: #ffffff;
  242. }
  243. .title {
  244. color: #000000;
  245. text-align: center;
  246. font-size: 32rpx;
  247. font-style: normal;
  248. font-weight: 400;
  249. }
  250. .back-icon,
  251. .notification-icon {
  252. width: 40rpx;
  253. display: flex;
  254. align-items: center;
  255. justify-content: center;
  256. }
  257. .header-icon-image {
  258. width: 40rpx;
  259. height: 40rpx;
  260. object-fit: contain;
  261. }
  262. .content-container {
  263. padding: 20rpx;
  264. width: 100%;
  265. box-sizing: border-box;
  266. overflow-x: hidden;
  267. }
  268. .content-header {
  269. display: flex;
  270. align-items: center;
  271. gap: 24rpx;
  272. padding: 0 60rpx;
  273. width: 100%;
  274. box-sizing: border-box;
  275. height: 188rpx;
  276. }
  277. .logo {
  278. width: 120rpx;
  279. height: 120rpx;
  280. display: flex;
  281. align-items: center;
  282. justify-content: center;
  283. flex: 0 0 112rpx;
  284. }
  285. .greeting {
  286. display: flex;
  287. flex-direction: column;
  288. justify-content: center;
  289. flex: 1 1 auto;
  290. }
  291. .greet-title {
  292. color: #000;
  293. font-size: 40rpx;
  294. font-style: normal;
  295. font-weight: 500;
  296. line-height: normal;
  297. margin: 0;
  298. overflow: hidden;
  299. text-overflow: ellipsis;
  300. white-space: nowrap;
  301. }
  302. .greet-sub {
  303. color: #838383;
  304. font-size: 28rpx;
  305. font-style: normal;
  306. font-weight: 400;
  307. line-height: normal;
  308. margin-top: 12rpx;
  309. overflow: hidden;
  310. text-overflow: ellipsis;
  311. white-space: nowrap;
  312. }
  313. .card {
  314. width: 90%;
  315. margin: 0 auto;
  316. border-radius: 16rpx;
  317. padding: 20rpx 40rpx;
  318. box-sizing: border-box;
  319. border-radius: 12rpx;
  320. border: 4rpx solid #FCC8D4;
  321. background: linear-gradient(180deg, #FCC8D3 0%, #FEF0F3 30%, #FFF 100%);
  322. margin-bottom: 20rpx;
  323. }
  324. .suggest-header {
  325. width: 100%;
  326. display: flex;
  327. align-items: center;
  328. justify-content: space-between;
  329. }
  330. .suggest-title {
  331. color: #000000;
  332. font-size: 32rpx;
  333. font-style: normal;
  334. font-weight: 400;
  335. line-height: normal;
  336. }
  337. .swap {
  338. display: flex;
  339. align-items: center;
  340. transition: transform 0.1s ease, background-color 0.1s ease;
  341. }
  342. .swap:active {
  343. transform: scale(0.95);
  344. }
  345. .swap-icon {
  346. width: 30rpx;
  347. height: 30rpx;
  348. }
  349. .swap-title {
  350. padding-left: 8rpx;
  351. color: #000000;
  352. font-size: 24rpx;
  353. font-style: normal;
  354. font-weight: 400;
  355. line-height: normal;
  356. }
  357. .suggest-list {
  358. margin-top: 20rpx;
  359. }
  360. .card-line {
  361. margin-top: 20rpx;
  362. width: 100%;
  363. height: 2rpx;
  364. border-radius: 2rpx;
  365. background: #FFF;
  366. }
  367. .suggest-item {
  368. display: flex;
  369. justify-content: space-between;
  370. align-items: center;
  371. padding-top: 10rpx;
  372. border-radius: 12rpx;
  373. margin-bottom: 20rpx;
  374. width: 100%;
  375. box-sizing: border-box;
  376. }
  377. .left {
  378. width: 72rpx;
  379. display: flex;
  380. justify-content: center;
  381. align-items: center;
  382. padding-right: 12rpx;
  383. }
  384. .num {
  385. font-size: 40rpx;
  386. font-style: normal;
  387. font-weight: 700;
  388. line-height: normal;
  389. }
  390. .num-1 {
  391. color: #df5662;
  392. }
  393. .num-2 {
  394. color: #ec6d4f;
  395. }
  396. .num-3 {
  397. color: #f3ba40;
  398. }
  399. .num-4 {
  400. color: #9296a0;
  401. }
  402. .num-5 {
  403. color: #9296a0;
  404. }
  405. .mid {
  406. flex: 1 1 auto;
  407. min-width: 0;
  408. }
  409. .q-text {
  410. display: block;
  411. color: #333;
  412. font-size: 28rpx;
  413. white-space: nowrap;
  414. overflow: hidden;
  415. text-overflow: ellipsis;
  416. }
  417. .right {
  418. width: 48rpx;
  419. display: flex;
  420. align-items: center;
  421. justify-content: flex-end;
  422. }
  423. .arrow {
  424. color: #cfcfcf;
  425. font-size: 36rpx;
  426. }
  427. .suggest-item:active {
  428. background: rgba(255, 77, 128, 0.06);
  429. }
  430. .feedback-card-title {
  431. display: flex;
  432. justify-content: center;
  433. color: #000000;
  434. font-size: 32rpx;
  435. font-weight: 700;
  436. line-height: 40rpx;
  437. width: 100%;
  438. margin-bottom: 20rpx;
  439. }
  440. .feedback-title {
  441. color: #000000;
  442. font-size: 32rpx;
  443. font-style: normal;
  444. font-weight: 400;
  445. line-height: normal;
  446. }
  447. .feedback-input {
  448. width: 100%;
  449. display: flex;
  450. padding: 20rpx;
  451. flex-direction: column;
  452. box-sizing: border-box;
  453. align-items: flex-start;
  454. gap: 12rpx;
  455. align-self: stretch;
  456. border-radius: 12rpx;
  457. border: 2rpx solid #F0F1F1;
  458. margin-top: 20rpx;
  459. display: flex;
  460. background: #FFF;
  461. color: #8a8a8a;
  462. font-size: 24rpx;
  463. font-weight: 700;
  464. line-height: normal;
  465. }
  466. .meta-row {
  467. display: flex;
  468. justify-content: flex-end;
  469. margin-top: 12rpx;
  470. }
  471. .char-count {
  472. color: #999
  473. }
  474. .upload-img-tip {
  475. color: #000000;
  476. font-size: 24rpx;
  477. font-style: normal;
  478. font-weight: 400;
  479. line-height: normal;
  480. }
  481. .upload-row {
  482. display: flex;
  483. justify-content: flex-start;
  484. align-items: flex-start;
  485. align-content: flex-start;
  486. flex-wrap: wrap;
  487. gap: 20rpx;
  488. margin-top: 20rpx;
  489. width: 100%;
  490. }
  491. .img-slot {
  492. width: calc((100% - 2 * 30rpx) / 3);
  493. aspect-ratio: 1 / 1;
  494. border-radius: 6px;
  495. border: 1px solid #F0F1F1;
  496. background: #FFF;
  497. position: relative;
  498. display: flex;
  499. align-items: center;
  500. justify-content: center;
  501. overflow: hidden;
  502. box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.08);
  503. transition: transform 0.2s ease;
  504. }
  505. .slot-empty {
  506. width: 100%;
  507. height: 100%;
  508. display: flex;
  509. align-items: center;
  510. justify-content: center;
  511. }
  512. .camera-icon {
  513. width: 34rpx;
  514. height: 34rpx;
  515. }
  516. .slot-img {
  517. width: 100%;
  518. height: 100%;
  519. border-radius: 16rpx;
  520. }
  521. .remove {
  522. position: absolute;
  523. right: 6rpx;
  524. top: 6rpx;
  525. border-radius: 50%;
  526. background: #fd5c58;
  527. padding: 0;
  528. color: #fff;
  529. width: 36rpx;
  530. height: 36rpx;
  531. font-size: 28rpx;
  532. line-height: 36rpx;
  533. text-align: center;
  534. border: none;
  535. outline: none;
  536. cursor: pointer;
  537. }
  538. .remove:active {
  539. background: rgba(0, 0, 0, 0.75);
  540. }
  541. .image-upload-tip {
  542. display: flex;
  543. align-items: center;
  544. }
  545. .tip-text {
  546. color: #999999;
  547. font-size: 24rpx;
  548. font-style: normal;
  549. font-weight: 400;
  550. line-height: 40rpx;
  551. padding-top: 64rpx;
  552. }
  553. .feedback-btn {
  554. margin-top: 24rpx;
  555. width: 180rpx;
  556. height: 60rpx;
  557. aspect-ratio: 89/30;
  558. border-radius: 30rpx;
  559. background: #090A08;
  560. color: #ffffff;
  561. display: flex;
  562. justify-content: center;
  563. align-items: center;
  564. font-size: 16px;
  565. font-style: normal;
  566. font-weight: 700;
  567. line-height: normal;
  568. }
  569. </style>