Browse Source

feat(app): 优化视频号关联功能并添加相关页面

- 更新视频号关联流程,增加验证和确认步骤
- 添加视频教程展示
- 优化设计师主页和荣誉页面的展示逻辑
- 更新底部操作栏的显示条件
- 添加 NetImages.VideoTutorial 图片链接- 升级 wot-design-uni 版本至 1.5.1
EvilDragon 2 months ago
parent
commit
e53246ad5d

+ 1 - 1
package.json

@@ -8,7 +8,7 @@
   "author": "",
   "license": "ISC",
   "dependencies": {
-    "wot-design-uni": "1.3.13"
+    "wot-design-uni": "1.5.1"
   },
   "resolutions": {
     "bin-wrapper": "npm:bin-wrapper-china"

+ 1 - 1
packages/app/package.json

@@ -114,7 +114,7 @@
     "vue": "^3.4.21",
     "vue-component-type-helpers": "^2.1.8",
     "vue-i18n": "^9.1.9",
-    "wot-design-uni": "^1.3.14",
+    "wot-design-uni": "^1.5.1",
     "z-paging": "^2.7.10"
   },
   "devDependencies": {

+ 4 - 2
packages/app/src/components/moment-item.vue

@@ -19,6 +19,7 @@ const props = withDefaults(
   defineProps<{
     options: CircleRes
     isOwn?: boolean
+    isShared?: boolean
   }>(),
   {},
 )
@@ -40,7 +41,7 @@ const isVideo = computed(
 )
 const toDetail = () => {
   uni.navigateTo({
-    url: `/pages/home/moment/index?${stringify({ id: props.options.id })}`,
+    url: `/pages/home/moment/index?${stringify({ id: props.options.id })}${props.isShared ? '&isShared=true' : ''}`,
   })
 }
 const handleDelete = async () => {
@@ -171,7 +172,8 @@ onMounted(async () => {
           </template>
         </template>
       </view>
-      <view class="flex justify-between">
+
+      <view v-if="!isShared" class="flex justify-between">
         <div>
           <template v-if="features.shareMoment">
             <button

+ 1 - 0
packages/app/src/core/libs/net-images.ts

@@ -14,4 +14,5 @@ export enum NetImages {
   CyclingRankingsHeaderBg = 'https://image.zhuchaohui.com/zhucaohui/2351014a57a0df427516c4993876ade7e3695ce33b1f227c52c8381aa631ba02.png',
   HonorsLogo = 'https://image.zhuchaohui.com/zhucaohui/109805f7e6a8866e6484eea793de572e97cde85c5d65a2f514cf66aacc41609d.svg',
   WechatChannelsGuide = 'https://image.zhuchaohui.com/zhucaohui/4127d21eb75ab479b89f566f0d9479664d595091098acedf0ec29d696a60d034.png',
+  VideoTutorial = '',
 }

+ 4 - 1
packages/app/src/core/utils/common.ts

@@ -148,7 +148,10 @@ export const qrCodeString2Object = (str: string): Record<string, any> => {
   }
   return { type, options: obj }
 }
-export const validate = (form, rules) => {
+export const validate = (
+  form,
+  rules: { [key: string]: { required?: boolean; message?: string; pattern?: RegExp }[] },
+) => {
   for (const field in rules) {
     for (const rule of rules[field]) {
       if (rule.required && !form[field]) {

+ 20 - 14
packages/app/src/pages/home/moment/index.vue

@@ -153,10 +153,17 @@ const handleUpvote = async (index?: number) => {
     await run()
   }
 }
+const toDesignerHomepage = () => {
+  if (['1', '2'].includes(String(data.value?.circleType))) {
+    router.push(
+      `/pages/mine/homepage/index?id=${data.value?.stylistId}${isShared.value ? '&isShared=true' : ''}`,
+    )
+  }
+}
 onMounted(async () => {})
-onLoad(async (query: { id: string; isShared?: boolean }) => {
-  id.value = query.id
-  isShared.value = query.isShared
+onLoad(async (query?: { id: string; isShared?: boolean }) => {
+  id.value = query?.id
+  isShared.value = query?.isShared
   await run()
   await setSwiperStyle()
   await runGetReviews()
@@ -172,13 +179,7 @@ onShareAppMessage(shareAppMessage)
   <view class="bg-white flex-grow">
     <NavBarEvo placeholder :isShowBack="!isShared">
       <template #prepend>
-        <div
-          class="flex items-center gap-2"
-          @click="
-            ['1', '2'].includes(data.circleType) &&
-            router.push(`/pages/mine/homepage/index?id=${data.stylistId}`)
-          "
-        >
+        <div class="flex items-center gap-2" @click="toDesignerHomepage">
           <wd-img width="24" height="24" round :src="data.headUrl"></wd-img>
           <div class="text-black/90 text-sm font-normal font-['PingFang_SC'] leading-[10.18px]">
             {{ data.stylistName || data.marketing }}
@@ -316,8 +317,8 @@ onShareAppMessage(shareAppMessage)
         <view class="flex-1"></view>
         <view><wd-icon class="text-black/65" name="arrow-right" size="22px"></wd-icon></view>
       </view> -->
-      <div class="h-0.25 bg-[#dadada] my-7"></div>
-      <SectionHeading :title="`评论`" size="base">
+      <div v-if="!isShared" class="h-0.25 bg-[#dadada] my-7"></div>
+      <SectionHeading v-if="!isShared" :title="`评论`" size="base">
         <template #append>
           <view v-if="reviews?.list" class="flex">
             <div class="text-black/90 text-xs font-normal font-['PingFang_SC'] leading-[10.18px]">
@@ -335,7 +336,7 @@ onShareAppMessage(shareAppMessage)
         </template>
       </SectionHeading>
 
-      <view clas="mt-8.25">
+      <view v-if="!isShared" clas="mt-8.25">
         <template v-if="reviews?.list.length">
           <template v-for="(it, i) in reviews?.list" :key="it.id">
             <CommentItem
@@ -367,7 +368,7 @@ onShareAppMessage(shareAppMessage)
         </template>
       </view>
     </div>
-    <BottomAppBar fixed placeholder border custom-class="">
+    <BottomAppBar v-if="!isShared" fixed placeholder border custom-class="">
       <div class="bg-white flex items-center">
         <div class="w-[168px] bg-[#f6f6f6] rounded-[60px] px-3.5 py-2 flex items-center">
           <wd-input
@@ -459,6 +460,11 @@ onShareAppMessage(shareAppMessage)
         </view>
       </div>
     </BottomAppBar>
+    <BottomAppBar v-if="isShared" fixed placeholder>
+      <div>
+        <wd-button block :round="false" @click="toDesignerHomepage">查看设计师主页</wd-button>
+      </div>
+    </BottomAppBar>
   </view>
 </template>
 <style lang="scss" scope>

+ 49 - 14
packages/app/src/pages/mine/homepage/channels/index.vue

@@ -7,14 +7,16 @@ import { getDesignerInfo, updateDesignerInfo } from '../../../../core/libs/reque
 import { useUserStore } from '../../../../store'
 import { storeToRefs } from 'pinia'
 import { pick } from 'radash'
-import { requestToast } from '../../../../core/utils/common'
+import { requestToast, validate } from '../../../../core/utils/common'
 import BottomAppBar from '@/components/bottom-app-bar.vue'
 import { useMessage } from 'wot-design-uni'
 import { NetImages } from '../../../../core/libs/net-images'
+import {useRouter} from "@/core/utils/router";
 
-const { alert } = useMessage()
+const { alert, confirm } = useMessage('wd-message-box-slot')
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
+const {back} = useRouter()
 const form = ref<{
   userId?: number
   videoNumber?: string
@@ -22,9 +24,27 @@ const form = ref<{
 const { data, run: setData } = useRequest(() => getDesignerInfo(userInfo.value.userId))
 const { loading, run: submiting } = useRequest(() => updateDesignerInfo(form.value))
 const handleSubmit = async () => {
-  await submiting()
-  await setData()
-  alert({ title: '关联成功', confirmButtonText: '我知道了' })
+  if (!validate(form.value, { videoNumber: [{ required: true, message: '请输入视频号ID' }] }))
+    return
+  const { action } = await confirm({
+    title: '温馨提示',
+    confirmButtonText: '同意并关联',
+    cancelButtonText: '不同意',
+  })
+  console.log(action)
+  if (action === 'confirm') {
+    await submiting()
+    uni.showToast({
+      title: '视频号关联成功',
+      icon: 'none',
+      duration: 2000,
+      success: () => {
+        back()
+      },
+    })
+    await setData()
+  }
+  // await alert({ title: '关联成功', confirmButtonText: '我知道了' })
 }
 onMounted(async () => {
   await setData()
@@ -44,20 +64,35 @@ onMounted(async () => {
     </div>
     <SectionHeading title="如何关联视频号?" size="sm"></SectionHeading>
     <wd-img class="rounded-2xl" width="100%" mode="widthFix" :src="NetImages.WechatChannelsGuide" />
-    <BottomAppBar fixed :border="false">
+    <SectionHeading title="视频教程" size="sm"></SectionHeading>
+    <div class="aspect-[1.87/1] rounded-2xl overflow-hidden">
+      <video class="w-full h-full" :src="NetImages.VideoTutorial"></video>
+    </div>
+    <BottomAppBar fixed placeholder :border="false" v-if="(data.videoNumber ?? '') === ''">
       <div>
-        <div class="text-center mb-5.5">
-          <span class="text-black/40 text-xs font-normal font-['PingFang_SC'] leading-tight">
-            点击确认关联即表示同意
-          </span>
-          <span class="text-[#0cbe7c] text-xs font-normal font-['PingFang_SC'] leading-tight">
-            《个人微信视频号授权使用协议》
-          </span>
-        </div>
+        <!--        <div class="text-center mb-5.5">-->
+        <!--          <span class="text-black/40 text-xs font-normal font-['PingFang_SC'] leading-tight">-->
+        <!--            点击确认关联即表示同意-->
+        <!--          </span>-->
+        <!--          <span class="text-[#0cbe7c] text-xs font-normal font-['PingFang_SC'] leading-tight">-->
+        <!--            《个人微信视频号授权使用协议》-->
+        <!--          </span>-->
+        <!--        </div>-->
         <wd-button :round="false" block :loading="loading" @click="handleSubmit">
           确定关联
         </wd-button>
       </div>
     </BottomAppBar>
+
+    <wd-message-box selector="wd-message-box-slot">
+      <div class="">
+        <span class="text-black/40 text-base font-normal font-['PingFang SC'] leading-relaxed">
+          关联后,小程序开发者将获取您的视频号相关信息,并为您提供相关服务,请您充分阅读
+        </span>
+        <span class="text-[#3f598f] text-base font-normal font-['PingFang SC'] leading-relaxed">
+          《个人微信视频号授权使用协议》
+        </span>
+      </div>
+    </wd-message-box>
   </div>
 </template>

+ 7 - 5
packages/app/src/pages/mine/homepage/index.vue

@@ -133,7 +133,6 @@ const handleUnbundle = async () => {
   })
 }
 onLoad(async (query: { id: string; isShared?: string }) => {
-  console.log(query)
   if (query.id) {
     id.value = query.id
   } else {
@@ -271,7 +270,9 @@ defineExpose({
         </div>
         <div
           class="w-[76px] h-[30px] px-3 right-0 top-1.5 absolute bg-black/90 rounded-tl-[30px] rounded-bl-[30px] justify-center items-center gap-2.5 inline-flex"
-          @click="router.push(`/pages/mine/honors/index?id=${id}`)"
+          @click="
+            router.push(`/pages/mine/honors/index?id=${id}${isShared ? '&isShared=true' : ''}`)
+          "
         >
           <div class="text-center text-white text-xs font-normal font-['PingFang_SC']">
             查看荣誉
@@ -352,6 +353,7 @@ defineExpose({
                   <MomentItem
                     :options="it"
                     :is-own="userInfo.userId === it.stylistId"
+                    :is-shared="isShared"
                     @delete="handleMomentDelete"
                     @like="handleLike"
                   ></MomentItem>
@@ -364,12 +366,12 @@ defineExpose({
     </div>
     <BottomAppBar fixed placeholder>
       <div class="flex gap-7.5">
-        <div class="flex-1" v-if="userInfo.userId === Number(id)">
+        <div class="flex-1" v-if="isOwn && !isShared">
           <wd-button block :round="false" @click="router.push(`/pages/mine/homepage/edit/index`)">
             编辑
           </wd-button>
         </div>
-        <div class="flex-1" v-if="userInfo.userId === Number(id)">
+        <div class="flex-1" v-if="isOwn && !isShared">
           <button
             v-if="features.shareMoment"
             class="p-0 after:b-none"
@@ -396,7 +398,7 @@ defineExpose({
             </wd-button>
           </template>
         </div>
-        <div class="flex-1" v-if="userInfo.userId !== Number(id)">
+        <div class="flex-1" v-if="!isOwn || isShared">
           <wd-button
             block
             :round="false"

+ 6 - 2
packages/app/src/pages/mine/honors/index.vue

@@ -21,6 +21,7 @@ import { useUserStore } from '@/store'
 import { storeToRefs } from 'pinia'
 
 const id = ref()
+const isShared = ref(false)
 const router = useRouter()
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
@@ -43,13 +44,16 @@ const { data: certificates, run: setCertificates } = useRequest(
 )
 const currentCertificate = ref<Certificate | undefined>()
 const isOwner = computed(() => String(userInfo.value?.userId) === id.value)
-onLoad(async (query?: Record<string | 'active' | 'id', string>) => {
+onLoad(async (query?: Record<string | 'active' | 'id' | 'isShared', string>) => {
   if (query?.active) {
     active.value = query.active
   }
   if (query?.id) {
     id.value = query.id
   }
+  if (query?.isShared) {
+    isShared.value = true
+  }
   await setStatistics()
   await setBadges()
   await setCertificates()
@@ -188,7 +192,7 @@ onLoad(async (query?: Record<string | 'active' | 'id', string>) => {
 
       <template v-for="([key, it], index) in Object.entries(badges)" :key="index">
         <Card
-          v-if="!(!isOwner && ['积分徽章'].includes(key))"
+          v-if="!((!isOwner || isShared) && ['积分徽章', '积分徽章'].includes(key))"
           custom-class="bg-[#171615]! text-white border border-solid border-[rgba(255,236,185,0.20)]"
         >
           <div class="flex items-center gap-2 py-4">

+ 1 - 1
packages/merchant/package.json

@@ -110,7 +110,7 @@
     "vue": "^3.4.21",
     "vue-component-type-helpers": "^2.1.8",
     "vue-i18n": "^9.1.9",
-    "wot-design-uni": "^1.3.14",
+    "wot-design-uni": "^1.5.1",
     "z-paging": "^2.7.10"
   },
   "devDependencies": {

+ 12 - 18
pnpm-lock.yaml

@@ -12,8 +12,8 @@ importers:
   .:
     dependencies:
       wot-design-uni:
-        specifier: 1.3.13
-        version: 1.3.13(vue@3.5.13(typescript@5.7.2))
+        specifier: 1.5.1
+        version: 1.5.1(vue@3.5.13(typescript@5.7.2))
     devDependencies:
       '@types/qs':
         specifier: ^6.9.17
@@ -121,8 +121,8 @@ importers:
         specifier: ^9.1.9
         version: 9.14.2(vue@3.5.13(typescript@4.9.5))
       wot-design-uni:
-        specifier: ^1.3.14
-        version: 1.4.0(vue@3.5.13(typescript@4.9.5))
+        specifier: ^1.5.1
+        version: 1.5.1(vue@3.5.13(typescript@4.9.5))
       z-paging:
         specifier: ^2.7.10
         version: 2.8.4
@@ -389,8 +389,8 @@ importers:
         specifier: ^9.1.9
         version: 9.14.2(vue@3.5.13(typescript@4.9.5))
       wot-design-uni:
-        specifier: ^1.3.14
-        version: 1.4.0(vue@3.5.13(typescript@4.9.5))
+        specifier: ^1.5.1
+        version: 1.5.1(vue@3.5.13(typescript@4.9.5))
       z-paging:
         specifier: ^2.7.10
         version: 2.8.4
@@ -8830,14 +8830,8 @@ packages:
     resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
     engines: {node: '>=0.10.0'}
 
-  wot-design-uni@1.3.13:
-    resolution: {integrity: sha512-3LHW480eivYAIDsxQr8KxMHCpeoj45XXpbmslLEvSWdPaRBvkXukaMW8z7wjejrMozxPBkQZT52bktCLBT/kOA==}
-    engines: {HBuilderX: ^3.8.7}
-    peerDependencies:
-      vue: '>=3.2.47'
-
-  wot-design-uni@1.4.0:
-    resolution: {integrity: sha512-h6sjrgfg7mP0nJwGTiHn/iTLPFyRswMpQV6MKhWN3skTnXe+FAyndvtXofpXp+uLkTXefGfw5BPI0uuCMD874w==}
+  wot-design-uni@1.5.1:
+    resolution: {integrity: sha512-jiDRuF8r7+xAldc4Dp+2T1VnqDnOoMWsXu6aRpDg2QG7ZH+/bJl7W8H8hHbKFgA9lu1By/HCDmpG7JC45nYtBw==}
     engines: {HBuilderX: ^3.8.7}
     peerDependencies:
       vue: '>=3.2.47'
@@ -19657,13 +19651,13 @@ snapshots:
 
   word-wrap@1.2.5: {}
 
-  wot-design-uni@1.3.13(vue@3.5.13(typescript@5.7.2)):
+  wot-design-uni@1.5.1(vue@3.5.13(typescript@4.9.5)):
     dependencies:
-      vue: 3.5.13(typescript@5.7.2)
+      vue: 3.5.13(typescript@4.9.5)
 
-  wot-design-uni@1.4.0(vue@3.5.13(typescript@4.9.5)):
+  wot-design-uni@1.5.1(vue@3.5.13(typescript@5.7.2)):
     dependencies:
-      vue: 3.5.13(typescript@4.9.5)
+      vue: 3.5.13(typescript@5.7.2)
 
   wrap-ansi@6.2.0:
     dependencies: