Browse Source

feat(mine): 添加关联视频号功能

- 新增关联视频号页面和相关组件
- 实现获取和提交设计师信息的功能
- 优化个人主页,增加视频号相关展示和跳转
- 注释掉 App.vue 中的 Sentry 初始化代码
EvilDragon 4 months ago
parent
commit
f60e8e8cb3

+ 8 - 10
packages/app/.eslintrc-auto-import.json

@@ -3,11 +3,14 @@
     "Component": true,
     "ComponentPublicInstance": true,
     "ComputedRef": true,
+    "DirectiveBinding": true,
     "EffectScope": true,
     "ExtractDefaultPropTypes": true,
     "ExtractPropTypes": true,
     "ExtractPublicPropTypes": true,
     "InjectionKey": true,
+    "MaybeRef": true,
+    "MaybeRefOrGetter": true,
     "PropType": true,
     "Ref": true,
     "VNode": true,
@@ -20,7 +23,6 @@
     "effectScope": true,
     "getCurrentInstance": true,
     "getCurrentScope": true,
-    "h": true,
     "inject": true,
     "isProxy": true,
     "isReactive": true,
@@ -65,6 +67,7 @@
     "onUnload": true,
     "onUnmounted": true,
     "onUpdated": true,
+    "onWatcherCleanup": true,
     "provide": true,
     "reactive": true,
     "readonly": true,
@@ -82,20 +85,15 @@
     "useAttrs": true,
     "useCssModule": true,
     "useCssVars": true,
+    "useId": true,
+    "useModel": true,
     "useRequest": true,
     "useSlots": true,
+    "useTemplateRef": true,
     "useUpload": true,
-    "useUpload2": true,
     "watch": true,
     "watchEffect": true,
     "watchPostEffect": true,
-    "watchSyncEffect": true,
-    "onWatcherCleanup": true,
-    "useId": true,
-    "useModel": true,
-    "useTemplateRef": true,
-    "DirectiveBinding": true,
-    "MaybeRef": true,
-    "MaybeRefOrGetter": true
+    "watchSyncEffect": true
   }
 }

+ 3 - 3
packages/app/src/App.vue

@@ -4,9 +4,9 @@ import * as sentry from 'sentry-uniapp'
 
 onLaunch(() => {
   console.log('App Launch')
-  sentry.init({
-    dsn: 'https://285d1dabcc1091ba170bea48e6c332b2@o4507049702195200.ingest.us.sentry.io/4508207497871361',
-  })
+  // sentry.init({
+  //   dsn: 'https://285d1dabcc1091ba170bea48e6c332b2@o4507049702195200.ingest.us.sentry.io/4508207497871361',
+  // })
   // sentry.captureMessage('custom message from ' + uni.getSystemInfoSync().platform, {
   //   UserId: 123,
   //   Command: 'npm i -g uapp',

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

@@ -662,6 +662,7 @@ export const getDesignerInfo = (userId) =>
       homePageUrl: string
       sharePageUrl: string
       retryStatus: number
+      videoNumber: string
     }>
   >('/app-api/member/designer/getDesignerInfo', { userId })
 /**

+ 8 - 0
packages/app/src/pages.json

@@ -431,6 +431,14 @@
       }
     },
     {
+      "path": "pages/mine/homepage/channels/index",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "关联视频号",
+        "navigationBarBackgroundColor": "#fff"
+      }
+    },
+    {
       "path": "pages/mine/homepage/consult/index",
       "type": "page",
       "style": {

+ 177 - 0
packages/app/src/pages/mine/homepage/channels/index.vue

@@ -0,0 +1,177 @@
+<route lang="json">
+{ "style": { "navigationBarTitleText": "关联视频号", "navigationBarBackgroundColor": "#fff" } }
+</route>
+<script setup lang="ts">
+import Card from '@/components/card.vue'
+import SectionHeading from '@/components/section-heading.vue'
+import { getDesignerInfo, updateDesignerInfo } from '../../../../core/libs/requests'
+import { useUserStore } from '../../../../store'
+import { storeToRefs } from 'pinia'
+import { pick } from 'radash'
+import { requestToast } from '../../../../core/utils/common'
+import UploadEvo from '@/components/upload-evo.vue'
+import BottomAppBar from '@/components/bottom-app-bar.vue'
+
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
+const form = ref<{
+  userId?: number
+  //   serviceYears?: number | string
+  //   homePageUrl?: string
+  //   sharePageUrl?: string
+  //   designDesc?: string
+  //   designFee?: string
+  //   personalIdentity?: string
+  //   serviceCustomerCount?: number
+  videoNumber?: string
+}>()
+const { data, run: setData } = useRequest(() => getDesignerInfo(userInfo.value.userId))
+const { loading, run: submiting } = useRequest(() => updateDesignerInfo(form.value))
+const handleSubmit = async () => {
+  await requestToast(submiting, {
+    success: true,
+    successTitle: '关联成功',
+  }).then(() => setData())
+}
+onMounted(async () => {
+  await setData()
+  form.value = pick(data.value, [
+    'id',
+    'userId',
+    // 'homePageUrl',
+    // 'serviceYears',
+    // 'sharePageUrl',
+    // 'designDesc',
+    // 'designFee',
+    // 'personalIdentity',
+    // 'serviceCustomerCount',
+    'videoNumber',
+  ])
+})
+</script>
+<template>
+  <div class="flex-grow flex flex-col gap-5 px-3.5 py-6 bg-white">
+    <SectionHeading title="如何关联视频号?" size="sm"></SectionHeading>
+    <img class="w-[347px] h-[186px] rounded-2xl" src="https://via.placeholder.com/347x186" />
+    <SectionHeading title="视频号ID" size="sm"></SectionHeading>
+    <div class="bg-[#f6f6f6] rounded-lg px-3.5 py-2.5">
+      <wd-input
+        v-model="form.videoNumber"
+        placeholder="请输入视频号ID"
+        no-border
+        custom-class="bg-[#f6f6f6]!"
+      ></wd-input>
+    </div>
+    <BottomAppBar fixed :border="false">
+      <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>
+    <!-- <template v-if="form">
+      <Card>
+        <div>
+          <SectionHeading title="主页封面图"></SectionHeading>
+          <div
+            class="mt-4.5 mb-2.5 text-black/40 text-xs font-normal font-['PingFang_SC'] leading-snug"
+          >
+            用于主页形象封面图,请上传体现个人艺术设计风格的图片,建议竖图尺寸750x1920,也可上传自己的视频介绍
+          </div>
+          <UploadEvo v-model="form.homePageUrl"></UploadEvo>
+        </div>
+      </Card>
+      <Card>
+        <div>
+          <SectionHeading title="分享封面图"></SectionHeading>
+          <div
+            class="mt-4.5 mb-2.5 text-black/40 text-xs font-normal font-['PingFang_SC'] leading-snug"
+          >
+            用于分享到微信好友的卡片封面图,尺寸1920x1080;
+          </div>
+          <UploadEvo v-model="form.sharePageUrl"></UploadEvo>
+        </div>
+      </Card>
+      <SectionHeading title="个人信息"></SectionHeading>
+      <Card>
+        <div>
+          <SectionHeading title="设计理念" subtitle="请输入设计理念"></SectionHeading>
+          <div
+            class="mt-4.5 mx--3.5 text-black/40 text-xs font-normal font-['PingFang_SC'] leading-snug"
+          >
+            <wd-textarea
+              placeholder="例:设计没有风格,设计是对生活的一种诠释,不是所谓的造型与装饰!"
+              v-model="form.designDesc"
+            />
+          </div>
+          <div class="text-end text-black/40 text-xs font-normal font-['PingFang_SC'] leading-snug">
+            0/100
+          </div>
+        </div>
+      </Card>
+      <Card>
+        <div>
+          <SectionHeading title="个人信息" subtitle="请输入关于自己身份体现"></SectionHeading>
+          <div
+            class="mt-4.5 mx--3.5 text-black/40 text-xs font-normal font-['PingFang_SC'] leading-snug"
+          >
+            <wd-textarea
+              placeholder="例:中国室内装饰协会会员、 xxx 空间设计事务所创始人、筑巢奖金奖设计师等等"
+              v-model="form.personalIdentity"
+            />
+          </div>
+          <div class="text-end text-black/40 text-xs font-normal font-['PingFang_SC'] leading-snug">
+            0/100
+          </div>
+        </div>
+      </Card>
+      <Card>
+        <div>
+          <SectionHeading title="设计费">
+            <template #append>
+              <div class="flex">
+                <wd-input no-border v-model="form.designFee"></wd-input>
+                <div
+                  class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-relaxed"
+                >
+                  元/㎡
+                </div>
+              </div>
+            </template>
+          </SectionHeading>
+        </div>
+      </Card>
+      <Card>
+        <div>
+          <SectionHeading title="服务客户数">
+            <template #append>
+              <wd-input
+                placeholder="请输入真实客户数"
+                no-border
+                v-model="form.serviceCustomerCount"
+              ></wd-input>
+            </template>
+          </SectionHeading>
+        </div>
+      </Card>
+      <Card>
+        <div>
+          <SectionHeading title="从业年限">
+            <template #append>
+              <wd-input placeholder="请输入年限" no-border v-model="form.serviceYears"></wd-input>
+            </template>
+          </SectionHeading>
+        </div>
+      </Card>
+      <div class=""><wd-button block :round="false" @click="handleSubmit">保存</wd-button></div>
+    </template> -->
+  </div>
+</template>

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

@@ -68,6 +68,11 @@ const handleMomentDelete = async (id) => {
     },
   })
 }
+const handle2Video = () => {
+  // wx.openChannelsUserProfile({ finderUserName: 'sphtEhk7olIepB0' })
+
+  uni.openChannelsUserProfile({ finderUserName: designerInfo.value?.videoNumber })
+}
 onLoad(async (query: { id: string }) => {
   if (query.id) {
     id.value = query.id
@@ -163,30 +168,36 @@ defineExpose({
         {{ designerInfo?.designDesc }}
       </div>
       <div
+        v-if="isOwn || designerInfo?.videoNumber"
         class="bg-gradient-to-t from-[#fdf6ee] to-[#fefdfc] rounded-[10px] border border-[#fff4e6] border-solid flex items-center px-3.5 py-5 gap-3"
+        @click="handle2Video"
       >
         <div class="w-[37.01px] h-[37.01px] bg-[#fa9d3b] rounded-lg">
           <wd-img width="100%" height="100%" :src="wechatChannels"></wd-img>
         </div>
         <div class="flex-1">
           <div class="text-black/90 text-sm font-normal font-['PingFang SC'] leading-normal">
-            视频号
+            {{ designerInfo?.videoNumber ? '个人视频号' : '视频号' }}
           </div>
-          <div>
-            <span class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-normal">
-              您还没有关联视频号
-            </span>
-            <span class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-normal">
-              ,
-            </span>
-            <span class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-normal">
-              快去关联吧~
-            </span>
+          <div class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-normal">
+            {{
+              designerInfo?.videoNumber
+                ? '案例分享,打造专属生活美学空间'
+                : '您还没有关联视频号 , 快去关联吧~'
+            }}
           </div>
         </div>
         <div>
           <div
+            v-if="designerInfo?.videoNumber"
+            class="text-[#e08e38] text-xs font-normal font-['PingFang SC'] leading-normal"
+          >
+            去看看
+          </div>
+          <div
+            v-else
             class="h-7 px-4 py-0.5 bg-[#fa9d3b] rounded-[20px] justify-center items-center gap-2.5 inline-flex"
+            @click.stop="router.push('/pages/mine/homepage/channels/index')"
           >
             <div
               class="text-center text-white text-xs font-normal font-['PingFang SC'] leading-normal"
@@ -194,9 +205,6 @@ defineExpose({
               去关联
             </div>
           </div>
-          <!-- <div class="text-[#e08e38] text-xs font-normal font-['PingFang SC'] leading-normal">
-            去看看
-          </div> -->
         </div>
       </div>
       <div>

+ 0 - 4
packages/app/src/types/auto-import.d.ts

@@ -14,7 +14,6 @@ declare global {
   const effectScope: typeof import('vue')['effectScope']
   const getCurrentInstance: typeof import('vue')['getCurrentInstance']
   const getCurrentScope: typeof import('vue')['getCurrentScope']
-  const h: (typeof import('vue'))['h']
   const inject: typeof import('vue')['inject']
   const isProxy: typeof import('vue')['isProxy']
   const isReactive: typeof import('vue')['isReactive']
@@ -79,13 +78,10 @@ declare global {
   const useCssVars: typeof import('vue')['useCssVars']
   const useId: typeof import('vue')['useId']
   const useModel: typeof import('vue')['useModel']
-  const useNavbarWeixin: (typeof import('../hooks/useNavbarWeixin'))['default']
   const useRequest: typeof import('../hooks/useRequest')['default']
-  const useRouter: (typeof import('../core/utils/router'))['useRouter']
   const useSlots: typeof import('vue')['useSlots']
   const useTemplateRef: typeof import('vue')['useTemplateRef']
   const useUpload: typeof import('../hooks/useUpload')['default']
-  const useUpload2: (typeof import('../hooks/useUpload2'))['default']
   const watch: typeof import('vue')['watch']
   const watchEffect: typeof import('vue')['watchEffect']
   const watchPostEffect: typeof import('vue')['watchPostEffect']

+ 1 - 0
packages/app/src/types/uni-pages.d.ts

@@ -49,6 +49,7 @@ interface NavigateToOptions {
        "/pages/home/spread/case-shooting/index" |
        "/pages/home/spread/design-awards/index" |
        "/pages/home/spread/wx-agent-operation/index" |
+       "/pages/mine/homepage/channels/index" |
        "/pages/mine/homepage/consult/index" |
        "/pages/mine/homepage/edit/index" |
        "/pages/mine/orders/code/index" |