소스 검색

feat: 帮助中心页面开发联调

liangan 3 주 전
부모
커밋
44c2651b2f
9개의 변경된 파일277개의 추가작업 그리고 0개의 파일을 삭제
  1. 18 0
      pages.config.ts
  2. 15 0
      src/api/qa.ts
  3. 3 0
      src/locale/bn.json
  4. 3 0
      src/locale/en.json
  5. 3 0
      src/locale/zh-Hans.json
  6. 19 0
      src/pages.json
  7. 126 0
      src/pages/mine/helpCenter.vue
  8. 89 0
      src/pages/mine/helpCenterDetail.vue
  9. 1 0
      src/pages/mine/mine.vue

+ 18 - 0
pages.config.ts

@@ -125,6 +125,24 @@ export default defineUniPages({
         navigationBarBackgroundColor: '#fff',
       },
     },
+    {
+      path: 'pages/mine/helpCenter',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%helpCenter.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
+    {
+      path: 'pages/mine/helpCenterDetail',
+      type: 'page',
+      layout: 'default',
+      style: {
+        navigationBarTitleText: '%helpCenter.detail.title%',
+        navigationBarBackgroundColor: '#fff',
+      },
+    },
     {
       path: 'pages/mine/mine',
       type: 'page',

+ 15 - 0
src/api/qa.ts

@@ -0,0 +1,15 @@
+import { http } from '@/utils/http'
+
+const pre = import.meta.env.VITE_API_SECONDARY_URL_PREFIX
+
+export function qaGroupList() {
+  return http.get<any>(`${pre}/api/qa/groupList`)
+}
+
+export function qaList(data: any) {
+  return http.get<any>(`${pre}/api/qa/qaList`, data)
+}
+
+export function qaInfo(id: number) {
+  return http.get<any>(`${pre}/api/qa/qaInfo/${id}`)
+}

+ 3 - 0
src/locale/bn.json

@@ -128,8 +128,11 @@
   "mine.menu.address": "ঠিকানা বই",
   "mine.menu.share": "শেয়ার",
   "mine.menu.favorite": "আমার পছন্দ",
+  "mine.menu.helpCenter": "সাহায্য কেন্দ্র",
   "mine.menu.chat": "লাইভ চ্যাট",
   "mine.menu.activity": "কার্যকলাপ গ্রুপ",
+  "helpCenter.title": "সাহায্য কেন্দ্র",
+  "helpCenter.detail.title": "সাহায্য কেন্দ্র",
   "home.priceTab.allPrice": "সব দাম",
   "home.priceTab.300spot": "৩০০স্পট",
   "home.priceTab.500spot": "৫০০স্পট",

+ 3 - 0
src/locale/en.json

@@ -140,8 +140,11 @@
   "mine.menu.address": "Address Book",
   "mine.menu.share": "Share",
   "mine.menu.favorite": "My Favorite",
+  "mine.menu.helpCenter": "Help Center",
   "mine.menu.chat": "Live Chat",
   "mine.menu.activity": "Activity Group",
+  "helpCenter.title": "Help Center",
+  "helpCenter.detail.title": "Help Center",
   "income.totalEarnings": "Total Earnings",
   "income.accountBalance": "Revenue Account Balance",
   "income.settledAmount": "Settled Amount",

+ 3 - 0
src/locale/zh-Hans.json

@@ -128,8 +128,11 @@
   "mine.menu.address": "地址簿",
   "mine.menu.share": "分享",
   "mine.menu.favorite": "我的收藏",
+  "mine.menu.helpCenter": "帮助中心",
   "mine.menu.chat": "在线客服",
   "mine.menu.activity": "活动群组",
+  "helpCenter.title": "帮助中心",
+  "helpCenter.detail.title": "帮助中心",
   "home.priceTab.allPrice": "全部价格",
   "home.priceTab.300spot": "300积分",
   "home.priceTab.500spot": "500积分",

+ 19 - 0
src/pages.json

@@ -113,6 +113,24 @@
         "navigationBarBackgroundColor": "#fff"
       }
     },
+    {
+      "path": "pages/mine/helpCenter",
+      "type": "page",
+      "layout": "default",
+      "style": {
+        "navigationBarTitleText": "%helpCenter.title%",
+        "navigationBarBackgroundColor": "#fff"
+      }
+    },
+    {
+      "path": "pages/mine/helpCenterDetail",
+      "type": "page",
+      "layout": "default",
+      "style": {
+        "navigationBarTitleText": "%helpCenter.detail.title%",
+        "navigationBarBackgroundColor": "#fff"
+      }
+    },
     {
       "path": "pages/mine/mine",
       "type": "page",
@@ -146,6 +164,7 @@
       "type": "page",
       "layout": "default",
       "style": {
+        "navigationStyle": "custom",
         "navigationBarTitleText": "%setting.title%",
         "navigationBarBackgroundColor": "#fff"
       }

+ 126 - 0
src/pages/mine/helpCenter.vue

@@ -0,0 +1,126 @@
+<route lang="json5" type="page">
+{
+  layout: 'default',
+  style: {
+    navigationBarTitleText: '%helpCenter.title%',
+    navigationBarBackgroundColor: '#fff',
+  },
+}
+</route>
+
+<script lang="ts" setup>
+// eslint-disable-next-line unused-imports/no-unused-imports
+import { onPageScroll } from '@dcloudio/uni-app'
+import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
+
+import { qaGroupList, qaList } from '@/api/qa'
+import i18n from '@/locale/index'
+import { toPage } from '@/utils/page'
+
+defineOptions({
+  name: 'HelpCenter',
+})
+
+const systemInfo = uni.getSystemInfoSync()
+const safeAreaInsets = systemInfo.safeAreaInsets
+
+const paging = ref<any>(null)
+useZPaging(paging)
+
+const dataList = ref<any[]>([])
+
+const groupList = ref<any[]>([])
+const tab = ref<string>('')
+
+const locale = computed(() => i18n.global.locale)
+
+const shouldUseEn = computed(() => locale.value !== 'bn')
+
+watch(locale, () => {
+  paging.value?.reload()
+})
+
+function getGroupName(item: any) {
+  return shouldUseEn.value ? (item.enName || '') : (item.bnName || '')
+}
+
+function getQaTitle(item: any) {
+  return shouldUseEn.value ? (item.enTitle || '') : (item.bnTitle || '')
+}
+
+async function loadGroups() {
+  const res = await qaGroupList()
+  if (res.code === '200') {
+    const list = (res.data || []) as any[]
+    groupList.value = list
+    if (!tab.value && list.length)
+      tab.value = String(list[0].id)
+  }
+}
+
+async function queryList(pageNo: number, pageSize: number) {
+  if (!tab.value) {
+    paging.value?.complete([])
+    return
+  }
+  try {
+    const res = await qaList({
+      page: pageNo,
+      size: pageSize,
+      groupId: Number(tab.value),
+    })
+    if (res.code === '200') {
+      paging.value.complete(res.data?.list || [])
+    }
+    else {
+      paging.value.complete(false)
+    }
+  }
+  catch {
+    paging.value.complete(false)
+  }
+}
+function handleTabClick() {
+  paging.value?.reload()
+}
+
+function handleItemClick(item: any) {
+  toPage({ url: '/pages/mine/helpCenterDetail', params: { id: item.id } })
+}
+
+onShow(async () => {
+  if (!groupList.value.length) {
+    await loadGroups()
+  }
+  else {
+    paging.value?.reload()
+  }
+})
+</script>
+
+<template>
+  <z-paging v-if="tab" ref="paging" v-model="dataList" use-page-scroll @query="queryList">
+    <template #top>
+      <view class="bg-white" :style="{ paddingTop: `${safeAreaInsets?.top}px` }">
+        <wd-tabs v-if="groupList.length && tab" v-model="tab" :auto-line-width="true" custom-class="bg-transparent!" slidable="always" @click="handleTabClick">
+          <wd-tab v-for="g in groupList" :key="g.id" :name="String(g.id)" :title="getGroupName(g)" />
+        </wd-tabs>
+      </view>
+    </template>
+
+    <view v-for="item in dataList" :key="item.id" class="mb-20rpx bg-white px-22rpx py-18rpx" @click="handleItemClick(item)">
+      <view class="flex items-center justify-between">
+        <view class="flex-1 pr-16rpx text-26rpx font-bold">
+          {{ getQaTitle(item) }}
+        </view>
+        <wd-icon name="chevron-right" size="28rpx" />
+      </view>
+    </view>
+  </z-paging>
+</template>
+
+<style lang="scss" scoped>
+page {
+  background-color: #fff;
+}
+</style>

+ 89 - 0
src/pages/mine/helpCenterDetail.vue

@@ -0,0 +1,89 @@
+<route lang="json5" type="page">
+{
+  layout: 'default',
+  style: {
+    navigationBarTitleText: '%helpCenter.detail.title%',
+    navigationBarBackgroundColor: '#fff',
+  },
+}
+</route>
+
+<script lang="ts" setup>
+import { onLoad } from '@dcloudio/uni-app'
+
+import { qaInfo } from '@/api/qa'
+import i18n from '@/locale/index'
+
+defineOptions({
+  name: 'HelpCenterDetail',
+})
+
+interface QaItem {
+  id: number
+  bnTitle?: string
+  enTitle?: string
+  bnContent?: string
+  enContent?: string
+  groupId: number
+}
+
+const locale = computed(() => i18n.global.locale)
+const shouldUseEn = computed(() => locale.value === 'en' || locale.value === 'zh-Hans')
+
+const detail = ref<QaItem | null>(null)
+const contentHtml = ref<string>('')
+
+function formatTextToHtml(text: string) {
+  if (!text)
+    return ''
+  return text.replace(/\n/g, '<br>')
+}
+
+function getQaTitle(item: QaItem | null) {
+  if (!item)
+    return ''
+  return shouldUseEn.value ? (item.enTitle || item.bnTitle || '') : (item.bnTitle || item.enTitle || '')
+}
+
+async function loadDetail(id: number) {
+  const res = await qaInfo(id)
+  if (res.code === '200') {
+    detail.value = res.data as QaItem
+    const content = shouldUseEn.value
+      ? (detail.value.enContent || detail.value.bnContent || '')
+      : (detail.value.bnContent || detail.value.enContent || '')
+    contentHtml.value = formatTextToHtml(content)
+  }
+}
+
+watch(locale, () => {
+  if (!detail.value)
+    return
+  const content = shouldUseEn.value
+    ? (detail.value.enContent || detail.value.bnContent || '')
+    : (detail.value.bnContent || detail.value.enContent || '')
+  contentHtml.value = formatTextToHtml(content)
+})
+
+onLoad(async (options: any) => {
+  const id = Number(options?.id)
+  if (!Number.isFinite(id) || id <= 0)
+    return
+  await loadDetail(id)
+})
+</script>
+
+<template>
+  <view class="rounded-12rpx bg-white px-22rpx py-20rpx">
+    <view class="mb-18rpx text-30rpx font-bold">
+      {{ getQaTitle(detail) }}
+    </view>
+    <rich-text :nodes="contentHtml" />
+  </view>
+</template>
+
+<style lang="scss" scoped>
+page {
+  background-color: #fff;
+}
+</style>

+ 1 - 0
src/pages/mine/mine.vue

@@ -103,6 +103,7 @@ const menuList = computed(() => {
     { name: t('mine.menu.share'), url: '/pages/mine/share', icon: '/static/icons/share.png' },
     { name: t('mine.menu.favorite'), url: '/pages/mine/myFavorite', icon: '/static/icons/my-favorite.png' },
     { name: t('mine.menu.chat'), config: 'live_chat', icon: '/static/icons/live-chat.png' },
+    { name: t('mine.menu.helpCenter'), url: '/pages/mine/helpCenter', icon: '/static/icons/icon-info.png' },
     // { name: t('mine.menu.activity'), config: 'activity_group', icon: '/static/icons/activity-group.png' },
   ]
 })