Przeglądaj źródła

feat(agent): 添加设计师其他活动信息页面

- 新增其他活动信息页面,用于记录设计师参与的非线上活动
- 实现活动列表展示、编辑和删除功能
- 添加活动名称、参与日期等字段
- 优化设计师档案页面,增加活动信息展示
-调整首页任务列表,支持代理刷新
EvilDragon 4 miesięcy temu
rodzic
commit
f667b11b00

+ 4 - 1
packages/app/src/core/libs/models.ts

@@ -822,7 +822,10 @@ export interface DesignerAward {
 }
 export interface DesignerEvent {
   name: string
-  applyTime: string
+  applyTime?: string
+  userId?: number
+  participationDate: string
+  id?: number
 }
 export interface DesignerPointsStatistics {
   /**

+ 3 - 3
packages/merchant/src/components/data-render.vue

@@ -4,7 +4,7 @@ import dayjs from 'dayjs'
 withDefaults(
   defineProps<{
     type: 'Original' | 'Date' | 'Avatar' | 'Select'
-    value: number | string | Date
+    value?: number | string | Date
     customClass?: string
     options?: { label: string; value: string | number }[]
   }>(),
@@ -14,8 +14,8 @@ withDefaults(
 <template>
   <div>
     <span v-if="type === 'Original'">{{ value }}</span>
-    <span v-if="type === 'Date'">{{ dayjs(value).format('YYYY-MM-DD') }}</span>
-    <img v-if="type === 'Avatar'" :src="value" class="w-10 h-10 rounded-full" />
+    <span v-if="type === 'Date'">{{ value && dayjs(value).format('YYYY-MM-DD') }}</span>
+    <wd-img v-if="type === 'Avatar'" width="40" height="40" round :src="String(value)" class="" />
     <span v-if="type === 'Select'">{{ options?.find((it) => it.value === value)?.label }}</span>
   </div>
 </template>

+ 8 - 0
packages/merchant/src/components/page-helper-evo.vue

@@ -92,6 +92,14 @@ defineExpose({
   },
 })
 </script>
+<script lang="ts">
+export default {
+  options: {
+    virtualHost: true,
+    styleIsolation: 'shared',
+  },
+}
+</script>
 <template>
   <div
     class="flex-grow flex flex-col"

+ 48 - 2
packages/merchant/src/core/libs/agent-requests.ts

@@ -80,12 +80,12 @@ export const getDesignerExtraEvents = (query = {}) =>
 /**
  * /app-api/member/stylist-extra-events/getStudyAndActivity 获取设计师学习和活动
  */
-export const getDesignerActivityEvents = (userId: number) =>
+export const getDesignerActivity = (query = {}) =>
   httpGet<{
     [key in 'study' | 'activity' | 'extraEventsQuantity']:
       | { type: number; quantity: number }[]
       | number
-  }>('/app-api/member/stylist-extra-events/getStudyAndActivity', { userId })
+  }>('/app-api/member/stylist-extra-events/getStudyAndActivity', query)
 /**
  * 设计师列表
  */
@@ -259,6 +259,27 @@ export const deleteOtherSales = (id: number) =>
  */
 export const updateOtherSales = (data: Partial<DesignerOrderSaleOther>) =>
   httpPost('/app-api/member/stylist-other-sales/update', data)
+/**
+ * 创建设计师活动
+ */
+export const createDesignerEvent = (query: Partial<DesignerEvent>) =>
+  httpPost('/app-api/member/stylist-extra-events/create', query)
+/**
+ * 删除设计师活动
+ */
+export const deleteDesignerEvent = (id: number) =>
+  httpDelete('/app-api/member/stylist-extra-events/delete', { id })
+/**
+ * 获取设计师活动
+ */
+export const getDesignerEvents = (query = {}) =>
+  httpGet<ResPageData<DesignerEvent>>('/app-api/member/stylist-extra-events/pageInfo', query)
+/**
+ * 更新设计师活动
+ */
+export const updateDesignerEvent = (query: Partial<DesignerEvent>) =>
+  httpPost('/app-api/member/stylist-extra-events/update', query)
+
 export const getSalesOrdersCounts = (query = {}) =>
   getSalesOrdersCount(query).then((res) => ({
     ...res,
@@ -321,3 +342,28 @@ export const getPointsCounts = (query = {}) =>
       },
     ],
   }))
+export const getDesignerActivities = (query = {}) =>
+  getDesignerActivity(query).then((res) => ({
+    ...res,
+    data: [
+      ...(res.data.study as any[]).map((it) => ({
+        type: '',
+        label: it.type,
+        value: it.quantity + '次',
+        path: '',
+      })),
+      { type: 'line', label: '', value: '' },
+      ...(res.data.study as any[]).map((it) => ({
+        type: '',
+        label: it.type,
+        value: it.quantity + '次',
+        path: '',
+      })),
+      {
+        type: '',
+        label: '其他活动',
+        value: res.data.extraEventsQuantity + '次',
+        path: '/pages/agent/designer/archives/index',
+      },
+    ],
+  }))

+ 4 - 0
packages/merchant/src/core/libs/messages.ts

@@ -81,5 +81,9 @@ export const messages = {
       createTime: '创建时间',
       userId: '用户ID',
     },
+    designerEvent: {
+      name: '活动名称',
+      applyTime: '活动时间',
+    },
   },
 }

+ 1 - 1
packages/merchant/src/layouts/default.vue

@@ -4,7 +4,7 @@ import { defaultThemeVars } from '../core/themes/default'
 <template>
   <wd-config-provider
     class="flex-grow flex flex-col"
-    custom-class="flex-grow "
+    custom-class="flex-grow flex flex-col"
     :themeVars="defaultThemeVars"
   >
     <view class="bg-[#f6f6f6] flex-grow flex flex-col">

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

@@ -230,6 +230,14 @@
       }
     },
     {
+      "path": "pages/agent/designer/archives/activity/others/index",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "其他活动信息",
+        "navigationBarBackgroundColor": "#fff"
+      }
+    },
+    {
       "path": "pages/agent/designer/archives/award/photos/index",
       "type": "page",
       "style": {

+ 186 - 0
packages/merchant/src/pages/agent/designer/archives/activity/others/index.vue

@@ -0,0 +1,186 @@
+<route lang="json">
+{ "style": { "navigationBarTitleText": "其他活动信息", "navigationBarBackgroundColor": "#fff" } }
+</route>
+<script setup lang="ts">
+import {
+  deleteOtherSales,
+  deleteDesignerEvent,
+  getDesignerEvents,
+  createDesignerEvent,
+  updateDesignerEvent,
+} from '@/core/libs/agent-requests'
+import Card from '@/components/card.vue'
+import PageHelperEvo from '@/components/page-helper-evo.vue'
+import BottomAppBar from '@/components/bottom-app-bar.vue'
+import DataForm from '@/components/data-form.vue'
+import { DataFormSchema } from '@/components/data-form'
+import { DesignerEvent, DesignerOrderSaleOther } from '@designer-hub/app/src/core/libs/models'
+import { ComponentExposed } from 'vue-component-type-helpers'
+import { requestToast } from '@designer-hub/app/src/core/utils/common'
+import { messages } from '@/core/libs/messages'
+import dayjs from 'dayjs'
+
+const id = ref()
+const actionSheetStatus = ref(false)
+const formData = ref({})
+const schema = ref<DataFormSchema<Omit<DesignerEvent, 'id' | 'createTime' | 'userId'>>>({
+  participationDate: {
+    type: 'TimePick',
+    label: messages.objects.designerEvent.applyTime,
+    required: true,
+    props: {
+      defaultValue: new Date(),
+    },
+  },
+  name: {
+    type: 'TextField',
+    label: messages.objects.designerEvent.name,
+    required: true,
+  },
+})
+const rules = ref({
+  participationDate: [
+    {
+      type: 'date',
+      message: '请选择活动时间',
+    },
+  ],
+  name: [{ required: true, message: '请输入活动名称' }],
+})
+const formRef = ref<ComponentExposed<typeof DataForm>>()
+const pageHelperRef = ref<ComponentExposed<typeof PageHelperEvo>>()
+const query = computed(() => ({ userId: id.value, type: 3 }))
+const handleSubmit = async () => {
+  const { valid } = await formRef.value!.validate()
+  if (!valid) return
+  if (Object.keys(formData.value).includes('id')) {
+    await requestToast(() => updateDesignerEvent(formData.value), {
+      success: true,
+      successTitle: '保存成功',
+    })
+  } else {
+    await requestToast(
+      () =>
+        createDesignerEvent({
+          ...formData.value,
+          userId: Number(id.value),
+        }),
+      { success: true, successTitle: '保存成功' },
+    )
+  }
+  actionSheetStatus.value = false
+  formData.value = {}
+  await pageHelperRef.value?.reload()
+}
+const handleEdit = (item: DesignerEvent) => {
+  formData.value = item
+  actionSheetStatus.value = true
+}
+const handleDelete = async (item: DesignerEvent) => {
+  await requestToast(() => deleteDesignerEvent(item.id), {
+    success: true,
+    successTitle: '删除成功',
+  })
+  await pageHelperRef.value?.reload()
+}
+onLoad((query?: Record<string | 'id', string>) => {
+  id.value = query?.id
+})
+</script>
+
+<template>
+  <div class="flex-grow flex flex-col">
+    <div class="mt-4 bg-white flex-grow">
+      <PageHelperEvo
+        ref="pageHelperRef"
+        :request="getDesignerEvents"
+        :query="query"
+        class="flex-grow"
+      >
+        <template #default="{ source }">
+          <div class="flex flex-col gap-4 p-8.75">
+            <template v-for="(it, index) in source?.list" :key="index">
+              <div>
+                <div
+                  class="text-black/90 text-base font-normal font-['PingFang SC'] leading-relaxed"
+                >
+                  {{ it.name }}
+                </div>
+                <div class="flex items-center justify-between">
+                  <div
+                    class="text-black/40 text-sm font-normal font-['PingFang SC'] leading-relaxed"
+                  >
+                    参加日期:
+                    {{ dayjs(it.applyTime).format('YYYY/MM/DD') }}
+                  </div>
+                  <div class="flex gap-6">
+                    <wd-button type="text" :round="false" size="small" @click="handleEdit(it)">
+                      编辑
+                    </wd-button>
+                    <wd-button type="text" :round="false" size="small" @click="handleDelete(it)">
+                      删除
+                    </wd-button>
+                  </div>
+                </div>
+              </div>
+              <!--              <div class="grid grid-cols-[90px_1fr] gap-2.5">-->
+              <!--                <template-->
+              <!--                  v-for="(item, i) in [-->
+              <!--                    { label: '材料商', value: it.supplierName },-->
+              <!--                    { label: '品牌', value: it.brandName },-->
+              <!--                    { label: '项目名称', value: it.projectName },-->
+              <!--                    { label: '客户姓名', value: it.customerName },-->
+              <!--                    { label: '客户电话', value: it.customerPhone },-->
+              <!--                    { label: '订单金额', value: it.orderAmount + '元' },-->
+              <!--                  ]"-->
+              <!--                  :key="i"-->
+              <!--                >-->
+              <!--                  <div class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-none">-->
+              <!--                    {{ item.label }}-->
+              <!--                  </div>-->
+              <!--                  <div class="text-black/60 text-sm font-normal font-['PingFang_SC'] leading-none">-->
+              <!--                    {{ item.value }}-->
+              <!--                  </div>-->
+              <!--                </template>-->
+              <!--              </div>-->
+              <!--              <div class="bg-[#f4f4f4] h-.25 my-4"></div>-->
+              <!--              <div class="flex justify-between">-->
+              <!--                <div class="text-black/60 text-sm font-normal font-['PingFang_SC'] leading-normal">-->
+              <!--                  {{ dayjs(it.createTime).format('YYYY-MM-DD HH:mm') }}-->
+              <!--                </div>-->
+              <!--              </div>-->
+            </template>
+          </div>
+        </template>
+      </PageHelperEvo>
+    </div>
+    <div class="py-2 bg-[#f0f4ff]">
+      <div
+        class="text-center text-[#2357e9] text-xs font-normal font-['PingFang_SC'] leading-normal"
+      >
+        其他活动不参与线上活动统计
+      </div>
+    </div>
+    <BottomAppBar fixed placeholder>
+      <div class="w-full">
+        <wd-button block :round="false" @click="((actionSheetStatus = true), (formData = {}))">
+          添加
+        </wd-button>
+      </div>
+    </BottomAppBar>
+    <wd-action-sheet v-model="actionSheetStatus">
+      <div class="p-4">
+        <DataForm
+          ref="formRef"
+          :rules="rules"
+          :schema="schema"
+          :direction="'horizontal'"
+          v-model="formData"
+        ></DataForm>
+        <wd-button :round="false" block @click="handleSubmit">保存</wd-button>
+      </div>
+    </wd-action-sheet>
+  </div>
+</template>
+
+<style scoped lang="scss"></style>

+ 60 - 23
packages/merchant/src/pages/agent/designer/archives/index.vue

@@ -11,6 +11,7 @@ import {
   createAward,
   deleteAward,
   getAwards,
+  getDesignerActivities,
   getDesignerBasicInfo,
   getDesignerExtraEvents,
   getDesignerFamilyInfo,
@@ -32,7 +33,7 @@ import ListHelperEvo from '@/components/list-helper-evo.vue'
 import SectionHeading from '@designer-hub/app/src/components/section-heading.vue'
 import dayjs from 'dayjs'
 
-const tab = ref('sale')
+const tab = ref('activity')
 // 基础信息 家庭信息 奖项信息 销售信息 游学/活动信息
 const tabs = [
   { label: '基础信息', value: 'basic' },
@@ -40,7 +41,7 @@ const tabs = [
   { label: '奖项信息', value: 'award' },
   { label: '销售信息', value: 'sale' },
   { label: '游学/活动信息', value: 'activity' },
-  { label: '其他活动信息', value: 'events' },
+  // { label: '其他活动信息', value: 'events' },
 ]
 const id = ref()
 const { data: basicData, run: setBasicData } = useRequest(() => getDesignerBasicInfo(id.value))
@@ -182,28 +183,30 @@ onLoad(async (query?: Record<string | 'id', any>) => {
     </wd-tabs>
     <div class="flex flex-col flex-grow gap-5">
       <template v-if="tab === 'basic'">
-        <template
-          v-for="([key, value], index) in Object.entries(omit(basicData, ['id', 'userId']))"
-          :key="index"
-        >
-          <div class="flex items-center justify-between">
-            <div class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-none">
-              {{ messages.objects.designerBasiceInfo[key] }}
+        <div class="bg-white mt-4 flex flex-col gap-5 p-4">
+          <template
+            v-for="([key, value], index) in Object.entries(omit(basicData, ['id', 'userId']))"
+            :key="index"
+          >
+            <div class="flex items-center justify-between">
+              <div class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-none">
+                {{ (messages.objects.designerBasiceInfo as any)[key] }}
+              </div>
+              <DataRender v-bind="(renders.designerBasiceInfo as any)[key](value)"></DataRender>
             </div>
-            <DataRender v-bind="renders.designerBasiceInfo[key](value)"></DataRender>
-          </div>
-          <!-- <SectionHeading size="base" :title="messages.objects.designerBasiceInfo[key]">
+            <!-- <SectionHeading size="base" :title="messages.objects.designerBasiceInfo[key]">
           <template #append>
             <DataRender v-bind="renders.designerBasiceInfo[key](value)"></DataRender>
           </template>
         </SectionHeading> -->
-          <div class="w-full h-.25 bg-[#f4f4f4]"></div>
-        </template>
+            <div class="w-full h-.25 bg-[#f4f4f4]"></div>
+          </template>
+        </div>
       </template>
       <template v-if="tab === 'family'">
         <PageHelperEvo ref="familyPageRef" :request="getDesignerFamilyInfo" :query="query">
           <template #default="{ source }">
-            <template v-for="(it, index) in source.list" :key="index">
+            <template v-for="(it, index) in source?.list" :key="index">
               <div>{{ it }}</div>
             </template>
           </template>
@@ -290,13 +293,6 @@ onLoad(async (query?: Record<string | 'id', any>) => {
                       : `/pages/agent/designer/archives/sale-info/others/index?id=${id}`
                   "
                 ></SectionHeading>
-                <!--                <SectionHeading-->
-                <!--                  title="奖项日期"-->
-                <!--                  :end-text="dayjs(item.awardsTime).format('YYYY-MM-DD')"-->
-                <!--                ></SectionHeading>-->
-                <!--                <SectionHeading title="奖项名次" :end-text="item.awardsRank"></SectionHeading>-->
-                <!--                <SectionHeading title="奖项照片" end-arrow></SectionHeading>-->
-                <!--                <wd-button type="text" @click="handleDeleteAward(item)">删除</wd-button>-->
               </div>
             </template>
           </ListHelperEvo>
@@ -316,10 +312,51 @@ onLoad(async (query?: Record<string | 'id', any>) => {
           <!--          </PageHelperEvo>-->
         </div>
       </template>
+      <template v-if="tab === 'activity'">
+        <div class="bg-white p-4 mt-4 flex-grow flex flex-col">
+          <SectionHeading title="游学/活动信息"></SectionHeading>
+          <ListHelperEvo :request="getDesignerActivities" :query="{ userId: id }">
+            <template #default="{ item, isLast }">
+              <div class="">
+                <template v-if="item.type === 'line'">
+                  <div class="w-full h-1 bg-[#dadada]"></div>
+                </template>
+                <template v-else>
+                  <div class="py-4">
+                    <SectionHeading
+                      :title="item.label"
+                      :end-text="item.value"
+                      :path="
+                        isLast
+                          ? `/pages/agent/designer/archives/activity/others/index?id=${id}`
+                          : ''
+                      "
+                    ></SectionHeading>
+                  </div>
+                </template>
+                <div v-if="!isLast" class="w-full h-.25 bg-[#f4f4f4]"></div>
+                <!--                </template>-->
+
+                <!--                <SectionHeading-->
+                <!--                  :title="item.label"-->
+                <!--                  size="base"-->
+                <!--                  :end-text="String(item.value)"-->
+                <!--                  end-arrow-->
+                <!--                  :path="-->
+                <!--                    !isLast-->
+                <!--                      ? `/pages/agent/designer/archives/sale-info/index?id=${id}`-->
+                <!--                      : `/pages/agent/designer/archives/sale-info/others/index?id=${id}`-->
+                <!--                  "-->
+                <!--                ></SectionHeading>-->
+              </div>
+            </template>
+          </ListHelperEvo>
+        </div>
+      </template>
       <template v-if="tab === 'events'">
         <PageHelperEvo :request="getDesignerExtraEvents" :query="eventsQuery">
           <template #default="{ source }">
-            <template v-for="(it, index) in source.list" :key="index">
+            <template v-for="(it, index) in source?.list" :key="index">
               <div>{{ it }}</div>
             </template>
           </template>

+ 6 - 2
packages/merchant/src/pages/home/index.vue

@@ -29,6 +29,7 @@ import { useRouter } from '../../composables/router'
 import PageHelperEvo from '@/components/page-helper-evo.vue'
 import TaskCard from '../agent/components/task-card.vue'
 import { getTasks } from '../../core/libs/agent-requests'
+import { ComponentExposed } from 'vue-component-type-helpers'
 
 defineOptions({
   name: 'Home',
@@ -37,6 +38,7 @@ const router = useRouter()
 const userStore = useUserStore()
 const { isLogined, userInfo, isAgent, isMerchant } = storeToRefs(userStore)
 const orderAmount = ref()
+const todoPageHelperRef = ref<ComponentExposed<typeof PageHelperEvo>>()
 const pointsAmount = computed(() => orderAmount.value * 10)
 const todosQuery = computed(() => ({
   brokerId: String(userInfo.value.userId),
@@ -82,7 +84,9 @@ const toAddReporting = () => {
   uni.navigateTo({ url: '/pages/home/merchant/add-reporting-information' })
 }
 onShow(async () => {
-  isAgent.value && (await Promise.all([setTasks()]))
+  if (isAgent.value) {
+    await Promise.all([setTasks(), todoPageHelperRef.value?.refresh()])
+  }
 })
 onLoad(() => {
   console.log(isLogined.value)
@@ -121,7 +125,7 @@ onShareAppMessage(() => ({}))
           </div>
           <Card>
             <div>
-              <PageHelperEvo :request="getTodoPage" :query="todosQuery">
+              <PageHelperEvo ref="todoPageHelperRef" :request="getTodoPage" :query="todosQuery">
                 <template #default="{ source }">
                   <div class="flex flex-col py-6">
                     <template v-for="(it, index) in source?.list" :key="index">

+ 3 - 2
packages/merchant/src/pages/mine/components/agent-mine.vue

@@ -6,15 +6,16 @@ import {
   getYearTarget,
 } from '../../../core/libs/requests'
 import { NetImages } from '../../../core/libs/net-images'
-import store, { useUserStore } from '../../../store'
+import { useUserStore } from '../../../store'
 import { storeToRefs } from 'pinia'
 import qrCode from '@designer-hub/assets/src/libs/assets/qrCode'
 import Card from '@designer-hub/app/src/components/card.vue'
+import SectionHeading from '@designer-hub/app/src/components/section-heading.vue'
 
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
 const { data: agent, run: setAgent } = useRequest(() =>
-  getBroker({ brokerId: userInfo.value.userId.toString() }),
+  getBroker({ brokerId: String(userInfo.value.userId) }),
 )
 const { data: yearTarget, run: setYearTarget } = useRequest(() => getYearTarget())
 const { data: designerData, run: setdesignerData } = useRequest(() => getDesignerStatistics())

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

@@ -26,6 +26,7 @@ interface NavigateToOptions {
        "/pages/agent/designer/archives/basic-info/index" |
        "/pages/agent/designer/archives/sale-info/index" |
        "/pages/mine/merchant/orders/detail/index" |
+       "/pages/agent/designer/archives/activity/others/index" |
        "/pages/agent/designer/archives/award/photos/index" |
        "/pages/agent/designer/archives/sale-info/others/index";
 }