zhengyiming
2025-03-28 8bb9173a95a87e3ceab4f48b5b34041af38b7c70
fix: 四期需求
10个文件已修改
1个文件已添加
245 ■■■■■ 已修改文件
apps/taro/src/hooks/user.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/pages/mine/index.vue 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/stores/modules/user.ts 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/subpackages/my/shareQrcode/InnerPage.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/core-vue/src/plugin.ts 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/core/src/lifeRecharge.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/core/src/lifeRechargeAccountModel.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/core/src/lifeRechargeServices.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/core/src/listener.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/api/Account.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/api/typings.d.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/taro/src/hooks/user.ts
@@ -10,8 +10,32 @@
  useLifeRechargeContext,
  APIgetLifePayWxIndentityParams,
  WxMiniAppIndentityInfo,
  LifePayPhoneMesssageCodeLoginOutput,
} from '@life-payment/core-vue';
import { isInWeChat } from '@/utils/env';
export function useVirtualUserInfo() {
  const { blLifeRecharge } = useLifeRechargeContext();
  const { data: virtualUserInfo } = useQuery({
    queryKey: ['blLifeRecharge/lifePayUserMesssageByIduser', blLifeRecharge.accountModel.userId],
    queryFn: async () => {
      return await blLifeRecharge.services.lifePayUserMesssageByIduser(
        {
          id: blLifeRecharge.accountModel.userId,
        },
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => ({} as LifePayPhoneMesssageCodeLoginOutput),
    enabled: computed(() => !!blLifeRecharge.accountModel.userId),
    staleTime: Infinity,
  });
  return { virtualUserInfo };
}
export function useUser() {
  const userStore = useUserStore();
@@ -30,7 +54,10 @@
    return userStore.getCurrentUserInfo();
  }
  const isChannelAccount = computed(() => !!virtualUserId.value && true);
  const { blLifeRecharge } = useLifeRechargeContext();
  const { virtualUserInfo } = useVirtualUserInfo();
  const isChannelAccount = computed(() => virtualUserInfo.value.isBackClientUser);
  return {
    user: userInfo,
@@ -42,6 +69,7 @@
    wxCode,
    wxOpenId,
    isChannelAccount,
    virtualUserInfo,
  };
}
apps/taro/src/pages/mine/index.vue
@@ -13,7 +13,9 @@
    <div class="mine-page-top-view" @click="goLogin">
      <img class="mine-avatar" :src="DefaultAvatar" alt="" />
      <div class="user-info">
        <div class="user-info-name" v-if="isLogin">{{ hiddenPhoneNumber(virtualPhoneNumber) }}</div>
        <div class="user-info-name" v-if="isLogin">
          {{ hiddenPhoneNumber(virtualPhoneNumber) }}
        </div>
        <div class="mine-go-login" v-else>登录</div>
      </div>
    </div>
@@ -47,6 +49,7 @@
import { hiddenPhoneNumber } from '@life-payment/utils';
const { userDetail, virtualPhoneNumber, isChannelAccount } = useUser();
const isLogin = useIsLogin();
const systemStore = useSystemStore();
const userStore = useUserStore();
apps/taro/src/stores/modules/user.ts
@@ -21,6 +21,8 @@
import { getAccountInfoFromAccessToken, AccountInfo, setOSSLink } from '@life-payment/utils';
import DefaultAvatar from '@/assets/components/icon-default-avatar.png';
import { myClient } from '@/constants/query';
import { blLifeRecharge } from '@/utils/blLifeRecharge';
import { LifePayPhoneMesssageCodeLoginOutput } from '@life-payment/core-vue';
interface UserState {
  userInfo?: Nullable<API.IdentityModelTokenCacheItem>;
@@ -38,6 +40,8 @@
  wxCode?: string;
  wxOpenId?: string;
  virtualUserInfo?: LifePayPhoneMesssageCodeLoginOutput;
}
const goAuthorization = debounce(
@@ -174,6 +178,7 @@
    async loginVirtualSuccess(virtualUserRes: LoginVirtualRes) {
      try {
        this.setVirtualUserId(virtualUserRes);
        this.getCurrentUserInfo();
      } catch (error) {}
    },
@@ -218,9 +223,10 @@
    async getCurrentUserInfo() {
      try {
        // let res = await userServices.getUserInfo({ showLoading: false });
        // let res = await blLifeRecharge.accountModel.getUserInfo(this.virtualUserId);
        // if (res) {
        //   this.setUserDetail(res);
        //   // this.setUserDetail(res);
        //   this.virtualUserInfo = res;
        //   this.firstGetUserDetail = false;
        // }
      } catch (error) {}
apps/taro/src/subpackages/my/shareQrcode/InnerPage.vue
@@ -1,23 +1,31 @@
<template>
  <ProTabs v-model="orderType" name="user-home-tabs" class="user-home-tabs" flexTitle fullHeight>
    <ProTabPane title="话费订单" pane-key="1">
      <ShareQrcodeView :channles-num="'818'" />
    </ProTabPane>
    <ProTabPane title="电费订单" pane-key="2">
      <ShareQrcodeView :channles-num="'818'" />
  <ProTabs v-model="channlesType" name="user-home-tabs" class="user-home-tabs" flexTitle fullHeight>
    <ProTabPane
      :title="item.name"
      :pane-key="item.channlesNum"
      v-for="item in userChannles"
      :key="item.channlesNum"
    >
      <ShareQrcodeView :channles-num="item.channlesNum" />
    </ProTabPane>
  </ProTabs>
</template>
<script setup lang="ts">
import { ShareQrcodeView } from '@life-payment/components';
import { useLifePayChannlesAllList } from '@/hooks';
import { useUser } from '@/hooks';
defineOptions({
  name: 'InnerPage',
});
const orderType = ref('1');
const { virtualUserInfo } = useUser();
const { getChannlesNameByNum } = useLifePayChannlesAllList();
const userChannles = computed(() => virtualUserInfo.value.channlesNum ?? []);
const channlesType = ref(userChannles.value[0]?.channlesNum ?? '');
watch(userChannles, (val) => {
  channlesType.value = val?.[0]?.channlesNum ?? '';
});
</script>
packages/core-vue/src/plugin.ts
@@ -1,5 +1,5 @@
import { BlLifeRecharge } from '@life-payment/core';
import { inject, shallowReactive } from 'vue';
import { BlLifeRecharge, BlLifeRechargeOptions } from '@life-payment/core';
import { inject, reactive, provide, ref } from 'vue';
import type { InjectionKey, UnwrapNestedRefs, Ref } from 'vue';
export type LifeRechargeContext = {
@@ -12,10 +12,24 @@
  blLifeRecharge: BlLifeRecharge;
};
function updateState(state: Record<string, unknown>, update: Record<string, any>): void {
  Object.keys(state).forEach((key) => {
    state[key] = update[key];
  });
}
export const VueLifeRechargePlugin = {
  install: (app: any, { blLifeRecharge }: VueLifeRechargePluginOptions) => {
    const _blLifeRecharge = reactive(blLifeRecharge);
    // blLifeRecharge.listener.addListener({
    //   update: (state) => {
    //     updateState(_blLifeRecharge, state);
    //   },
    // });
    app.provide(clientKey, {
      blLifeRecharge: shallowReactive(blLifeRecharge),
      blLifeRecharge: _blLifeRecharge,
    });
  },
};
packages/core/src/lifeRecharge.ts
@@ -2,21 +2,29 @@
  BlLifeRechargeServices,
  PhoneMesssageCodeLoginInput,
  RequestConfig,
  ChannelOutput,
} from './lifeRechargeServices';
import { BlLifeRechargeOptions } from './types';
import { LifeRechargeConstants } from './lifeRechargeConstants';
import { BlLifeRechargeAccountModel } from './lifeRechargeAccountModel';
import { LifeRechargeListener } from './listener';
export class BlLifeRecharge<TResponse = any, TRequestOptions = any> {
  services: BlLifeRechargeServices<TResponse, TRequestOptions>;
  accountModel: BlLifeRechargeAccountModel;
  listener: LifeRechargeListener;
  static constants = LifeRechargeConstants;
  constants = LifeRechargeConstants;
  /**用户所有的渠道 */
  userChannles = [] as ChannelOutput[];
  isBackClientUser: boolean;
  constructor(options: BlLifeRechargeOptions<TResponse, TRequestOptions>) {
    this.listener = new LifeRechargeListener();
    this.services = new BlLifeRechargeServices(this, options);
    this.accountModel = new BlLifeRechargeAccountModel({
    this.accountModel = new BlLifeRechargeAccountModel(this, {
      userId: options.userId,
      phoneNumber: options.phoneNumber,
      channlesNum: options.channlesNum,
@@ -37,6 +45,7 @@
  loginout() {
    this.accountModel.setUserId('');
    this.accountModel.setPhoneNumber('');
    this.accountModel.setUserChannles([]);
  }
  isLogin() {
packages/core/src/lifeRechargeAccountModel.ts
@@ -1,13 +1,20 @@
import { BlLifeRechargeAccountModelOptions } from './types';
import { LifePayPhoneMesssageCodeLoginOutput } from './lifeRechargeServices';
import { ChannelOutput } from './lifeRechargeServices';
import { BlLifeRecharge } from './lifeRecharge';
export class BlLifeRechargeAccountModel {
export class BlLifeRechargeAccountModel<TResponse = any, TRequestOptions = any> {
  ctx: BlLifeRecharge<TResponse, TRequestOptions>;
  userId = '';
  phoneNumber = '';
  channlesNum = '';
  constructor(options: BlLifeRechargeAccountModelOptions = {}) {
  constructor(
    ctx: BlLifeRecharge<TResponse, TRequestOptions>,
    options: BlLifeRechargeAccountModelOptions = {}
  ) {
    const { userId = '', phoneNumber = '', channlesNum } = options;
    this.ctx = ctx;
    this.setUserId(userId);
    this.setPhoneNumber(phoneNumber);
    this.setChannlesNum(channlesNum);
@@ -15,12 +22,42 @@
  setUserId(userId: string) {
    this.userId = userId;
    this.ctx.listener.fireEvent('update', this.ctx);
    if (userId) {
      this.getUserInfo(userId);
    }
  }
  async getUserInfo(userId: string) {
    try {
      let res = await this.ctx.services.lifePayUserMesssageByIduser(
        {
          id: userId,
        },
        {
          showLoading: false,
        }
      );
      this.ctx.isBackClientUser = res.isBackClientUser;
      if (res && res.isBackClientUser) {
        this.setUserChannles(res.channlesNum ?? []);
      }
      return res;
    } catch (error) {
      console.log('error: ', error);
    }
  }
  setPhoneNumber(phoneNumber: string) {
    this.phoneNumber = phoneNumber;
    this.ctx.listener.fireEvent('update', this.ctx);
  }
  setChannlesNum(channlesNum: string) {
    this.channlesNum = channlesNum;
    this.ctx.listener.fireEvent('update', this.ctx);
  }
  setUserChannles(userChannles: ChannelOutput[]) {
    this.ctx.userChannles = userChannles;
    this.ctx.listener.fireEvent('update', this.ctx);
  }
}
packages/core/src/lifeRechargeServices.ts
@@ -357,6 +357,24 @@
      ...(options || {}),
    });
  }
  /** 根据用户ID获取用户是否为后台管理员 POST /api/Account/LifePayUserMesssageByIduser */
  async lifePayUserMesssageByIduser(
    body: LifePayUserMesssageByIduserInput,
    options?: RequestConfig
  ) {
    return this.request<LifePayPhoneMesssageCodeLoginOutput>(
      '/api/Account/LifePayUserMesssageByIduser',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        data: body,
        ...(options || {}),
      }
    );
  }
}
export interface PhoneMesssageCodeLoginInput {
@@ -809,5 +827,17 @@
  /** 是否是后台用户 */
  isBackClientUser?: boolean;
  /** 渠道号 */
  channlesNum?: string[];
  channlesNum?: ChannelOutput[];
}
export interface ChannelOutput {
  name?: string;
  channlesNum?: string;
}
export interface LifePayUserMesssageByIduserInput {
  pageModel?: Pagination;
  checkChannelId?: string;
  /** 用户编号 */
  id?: string;
}
packages/core/src/listener.ts
New file
@@ -0,0 +1,36 @@
class BaseListener<ListenerMap extends { [key: string]: any }> {
  listenerList: ListenerMap[] = [];
  fireEvent(eventName: keyof ListenerMap, ...data: any[]) {
    this.listenerList.forEach((listener) => {
      var callback = listener[eventName];
      callback && callback(...data);
    });
  }
}
type LifeRechargeListenerMap = {
  update: (store: any) => any;
};
export class LifeRechargeListener extends BaseListener<LifeRechargeListenerMap> {
  addListener(listener: LifeRechargeListenerMap) {
    this.listenerList.push(listener);
  }
  removeListener(listener?: LifeRechargeListenerMap) {
    if (listener) {
      var index = -1;
      for (var i = 0, len = this.listenerList.length; i < len; i++) {
        if (listener == this.listenerList[i]) {
          index = i;
        }
      }
      if (index > -1) {
        this.listenerList.splice(index, 1);
      }
    } else {
      this.listenerList = [];
    }
  }
}
packages/services/api/Account.ts
@@ -55,6 +55,24 @@
  );
}
/** 根据用户ID获取用户是否为后台管理员 POST /api/Account/LifePayUserMesssageByIduser */
export async function lifePayUserMesssageByIduser(
  body: API.LifePayUserMesssageByIduserInput,
  options?: API.RequestConfig
) {
  return request<API.LifePayPhoneMesssageCodeLoginOutput>(
    '/api/Account/LifePayUserMesssageByIduser',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      data: body,
      ...(options || {}),
    }
  );
}
/** 此处后端没有提供注释 GET /api/accountAuth/GetCode */
export async function getCode(options?: API.RequestConfig) {
  return request<any>('/api/accountAuth/GetCode', {
packages/services/api/typings.d.ts
@@ -512,6 +512,11 @@
    type?: number;
  }
  interface ChannelOutput {
    name?: string;
    channlesNum?: string;
  }
  interface ChannelRateOutput {
    channlesRate?: number;
  }
@@ -1295,7 +1300,7 @@
    /** 是否是后台用户 */
    isBackClientUser?: boolean;
    /** 渠道号 */
    channlesNum?: string[];
    channlesNum?: ChannelOutput[];
  }
  interface LifePayPremiumInput {
@@ -1421,6 +1426,13 @@
  type LifePayTypeEnum = 10 | 20;
  interface LifePayUserMesssageByIduserInput {
    pageModel?: Pagination;
    checkChannelId?: string;
    /** 用户编号 */
    id?: string;
  }
  interface LifePhoneData {
    /** 运营商编码,例如:"yidong", "dianxin", "liantong"。 */
    ispCode: string;