zhengyiming
3 天以前 6c73b1255b612071d017ab4ebdad86a9ef9f880a
fix: 甲方小程序
已修改12个文件
已添加12个文件
712 ■■■■ 文件已修改
apps/housekeepingMiniApp/project.private.config.json 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/app.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/constants/router.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/pages/home/StandardServiceCard.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/pages/home/hooks/index.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/pages/home/index.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/components/MineServiceDetailView.vue 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineOrderDetail/InnerPage.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveService/mineReserveService.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceCancel/InnerPage.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceCancel/mineReserveServiceCancel.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceCancel/mineReserveServiceCancel.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceConfirm/InnerPage.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceConfirm/mineReserveServiceConfirm.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceConfirm/mineReserveServiceConfirm.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceDetail/InnerPage.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceDetail/mineReserveServiceDetail.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceDetail/mineReserveServiceDetail.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/src/subpackages/sercice/serciceDetail/serciceDetail.vue 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/hooks/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/hooks/standardOrder.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/enterprise.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/standardOrder.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/typings.d.ts 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/housekeepingMiniApp/project.private.config.json
@@ -23,11 +23,39 @@
        "miniprogram": {
            "list": [
                {
                    "name": "服务详情",
                    "pathName": "subpackages/sercice/serciceDetail/serciceDetail",
                    "query": "id=53208c5d-a823-40d3-e79e-08de429af17b",
                    "scene": null,
                    "launchMode": "default"
                },
                {
                    "name": "服务确认",
                    "pathName": "subpackages/mine/mineReserveServiceConfirm/mineReserveServiceConfirm",
                    "query": "id=undefined",
                    "launchMode": "default",
                    "scene": null
                },
                {
                    "name": "取消原因",
                    "pathName": "subpackages/mine/mineReserveServiceCancel/mineReserveServiceCancel",
                    "query": "id=undefined",
                    "launchMode": "default",
                    "scene": null
                },
                {
                    "name": "预约详情",
                    "pathName": "subpackages/mine/mineReserveServiceDetail/mineReserveServiceDetail",
                    "query": "",
                    "launchMode": "default",
                    "scene": null
                },
                {
                    "name": "订单详情",
                    "pathName": "subpackages/mine/mineOrderDetail/mineOrderDetail",
                    "query": "id=123",
                    "scene": null,
                    "launchMode": "default"
                    "launchMode": "default",
                    "scene": null
                },
                {
                    "name": "新增地址",
apps/housekeepingMiniApp/src/app.config.ts
@@ -84,6 +84,9 @@
        'addressManange/addressManange',
        'editAddress/editAddress',
        'mineOrderDetail/mineOrderDetail',
        'mineReserveServiceDetail/mineReserveServiceDetail',
        'mineReserveServiceCancel/mineReserveServiceCancel',
        'mineReserveServiceConfirm/mineReserveServiceConfirm',
      ],
    },
    {
apps/housekeepingMiniApp/src/constants/router.ts
@@ -29,6 +29,9 @@
  addressManange = '/subpackages/mine/addressManange/addressManange',
  editAddress = '/subpackages/mine/editAddress/editAddress',
  mineOrderDetail = '/subpackages/mine/mineOrderDetail/mineOrderDetail',
  mineReserveServiceDetail = '/subpackages/mine/mineReserveServiceDetail/mineReserveServiceDetail',
  mineReserveServiceCancel = '/subpackages/mine/mineReserveServiceCancel/mineReserveServiceCancel',
  mineReserveServiceConfirm = '/subpackages/mine/mineReserveServiceConfirm/mineReserveServiceConfirm',
  serciceDetail = '/subpackages/sercice/serciceDetail/serciceDetail',
apps/housekeepingMiniApp/src/pages/home/StandardServiceCard.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
<template>
  <div class="standard-service-card-wrapper">
    <img :src="setOSSLink(file)" class="standard-service-card-cover" />
    <div class="standard-service-card-content">
      <div class="standard-service-card-content-title">{{ name }}</div>
      <div class="standard-service-card-content-price-wrapper">
        <div class="standard-service-card-content-price">{{ minSpecPrice ?? 0 }}</div>
        <div class="standard-service-card-content-suffix">èµ·</div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { setOSSLink } from '@12333/utils';
defineOptions({
  name: 'StandardServiceCard',
});
type Props = {
  id?: string;
  file?: string;
  name?: string;
  /** æœ€ä½Žè§„格价格 */
  minSpecPrice?: number;
};
const props = withDefaults(defineProps<Props>(), {});
</script>
<style lang="scss">
@import '@/styles/common.scss';
.standard-service-card-wrapper {
  background-color: #fff;
  border-radius: 12px;
  .standard-service-card-cover {
    height: 240px;
    border-radius: 12px;
    object-fit: cover;
    width: 100%;
  }
  .standard-service-card-content {
    padding: 16px;
    padding-bottom: 24px;
    .standard-service-card-content-title {
      font-weight: 600;
      font-size: 28px;
      color: boleGetCssVar('text-color', 'primary');
      margin-bottom: 24px;
    }
    .standard-service-card-content-price-wrapper {
      display: flex;
      align-items: flex-end;
      .standard-service-card-content-price {
        font-weight: 600;
        font-size: 32px;
        color: #ff3949;
      }
      .standard-service-card-content-suffix {
        font-weight: 400;
        font-size: 24px;
        color: #ff3949;
      }
    }
  }
}
</style>
apps/housekeepingMiniApp/src/pages/home/hooks/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import * as advertisementServices from '@12333/services/apiV2/advertisement';
import { EnumAdvertisementPage, CategoryCode } from '@12333/constants';
import { useDictionaryDataSelect } from '@12333/hooks';
import _ from 'lodash';
export function useShowAdvertisements() {
  const { data: advertisements, refetch } = useQuery({
    queryKey: ['enterpriseWalletServices/getEnterpriseWalletAccessSelect'],
    queryFn: () => {
      return advertisementServices.getShowAdvertisements(
        {
          page: EnumAdvertisementPage.PartAWxmpHome,
        },
        {
          showLoading: false,
        }
      );
    },
    placeholderData: () => [] as API.GetShowAdvertisementsQueryResultItem[],
  });
  return {
    advertisements,
    advertisementRefetch: refetch,
  };
}
export function usePositionGrid() {
  const { dictionaryDataList: positionList } = useDictionaryDataSelect({
    categoryCode: CategoryCode.Position,
  });
  const positionListChunk = computed(() => _.chunk(positionList.value, 8));
  const positionGrid = computed(() => positionList.value.slice(0, 8));
  return {
    positionListChunk,
    positionGrid,
  };
}
apps/housekeepingMiniApp/src/pages/home/index.vue
@@ -15,7 +15,7 @@
          <div class="searchbar-container">
            <BlSearchbar
              v-model.trim="searchValue"
              placeholder="搜索任务"
              placeholder="搜索"
              @search="handleSearch"
              @change="handleSearch"
            ></BlSearchbar>
@@ -27,32 +27,36 @@
        </div>
        <div class="home-banner-wrapper">
          <nut-swiper :auto-play="3000">
            <nut-swiper-item v-for="(item, index) in list" :key="index">
              <img :src="item" class="banner-img" draggable="false" />
            <nut-swiper-item v-for="(item, index) in advertisements" :key="item.id">
              <img :src="item.file" class="banner-img" draggable="false" />
            </nut-swiper-item>
          </nut-swiper>
        </div>
        <div class="home-recommend-wrapper">
        <!-- <div class="home-recommend-wrapper">
          <div class="home-recommend-item">推荐</div>
          <div class="home-recommend-item">推荐</div>
          <div class="home-recommend-item">推荐</div>
        </div>
        </div> -->
        <!-- <nut-swiper :loop="false">
          <nut-swiper-item
            v-for="(chunk, index) in positionListChunk"
            :key="index"
            style="height: 160px"
          > -->
        <nut-grid class="home-gird">
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item text="text"><Dongdong /></nut-grid-item>
          <nut-grid-item v-for="item in positionGrid" :key="item.value" :text="item.label">
            <img :src="setOSSLink(item.data.field2)" class="home-grid-item-icon" />
            <!-- <Dongdong /> -->
          </nut-grid-item>
        </nut-grid>
        <!-- </nut-swiper-item>
        </nut-swiper> -->
      </div>
      <div class="home-good-list">
        <TaskCard
        <StandardServiceCard
          v-for="item in infiniteLoadingProps.flattenListData"
          :key="item.id"
          @click="goTaskDetail(item)"
          @click="goSerciceDetail(item)"
          v-bind="item"
          style="min-width: 0"
        />
@@ -77,24 +81,55 @@
import { setLocationCity } from '@/utils';
import _ from 'lodash';
import IconLogo from '@/assets/home/icon-logo.png';
import { TaskCard, ProTabs, ProTabPane } from '@12333/components';
import HomeQueryMenuView from './HomeQueryMenuView.vue';
import { TaskCard } from '@12333/components';
import IconLocaltion from '@/assets/task/icon-localtion.png';
import { useAllAreaList, useTaskList, HomeOrderType } from '@12333/hooks';
import { useAllAreaList, useInfiniteLoading, useTaskList } from '@12333/hooks';
import { useAccessLogin } from '@/hooks';
import { Dongdong } from '@nutui/icons-vue-taro';
import { usePositionGrid, useShowAdvertisements } from './hooks';
import { setOSSLink, trim } from '@12333/utils';
import * as standardServiceServices from '@12333/services/apiV2/standardService';
import { EnumPagedListOrder, EnumStandardServiceReleaseStatus } from '@12333/constants';
import StandardServiceCard from './StandardServiceCard.vue';
const { locationCity } = useUser();
const { findAreaCodeFromName } = useAllAreaList();
const searchValue = ref('');
const queryState = reactive({
  keywords: '',
});
const { searchValue, queryState, handleSearch, infiniteLoadingProps, queryMenuState } = useTaskList(
const handleSearch = _.debounce(function () {
  queryState.keywords = trim(searchValue.value);
}, 300);
const { infiniteLoadingProps, invalidateQueries } = useInfiniteLoading(
  ({ pageParam }) => {
    let params: API.GetStandardServicesQuery = {
      pageModel: {
        rows: 20,
        page: pageParam,
        orderInput: [
          { property: 'createdTime', order: EnumPagedListOrder.Desc },
          { property: 'recommendStatus', order: EnumPagedListOrder.Desc },
        ],
      },
      releaseStatus: EnumStandardServiceReleaseStatus.InProcess,
      keywords: queryState.keywords,
    };
    return standardServiceServices.getStandardServices(params, {
      showLoading: false,
    });
  },
  {
    cityCode: computed(() => findAreaCodeFromName(locationCity.value)),
    enabled: computed(() => !!findAreaCodeFromName(locationCity.value)),
    queryKey: ['standardServiceServices/getStandardServices', queryState],
  }
);
const { advertisementRefetch, advertisements } = useShowAdvertisements();
const { positionListChunk, positionGrid } = usePositionGrid();
onMounted(async () => {
  try {
    await setLocationCity();
@@ -107,28 +142,17 @@
  });
}
const list = ref([
  'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
  'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
  'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
  'https://storage.360buyimg.com/jdc-article/fristfabu.jpg',
]);
const selectItem = ref();
function handleMenuSelectClose() {
  selectItem.value?.toggle?.();
}
function goTaskDetail(item: API.GetTaskInfosQueryResultItem) {
  // Taro.navigateTo({
  //   url: `${RouterPath.taskDetail}?id=${item.id}&from=apply`,
  // });
function goSerciceDetail(item: API.GetStandardServicesQueryResultItem) {
  Taro.navigateTo({
    url: `${RouterPath.serciceDetail}?id=${item.id}`,
  });
}
const goTaskApply = useAccessLogin((item: API.GetTaskInfosQueryResultItem) => {
  console.log('item: ', item);
});
</script>
<style lang="scss">
@@ -185,6 +209,12 @@
  .home-gird {
    margin-bottom: 20px;
    .home-grid-item-icon {
      width: 64px;
      height: 64px;
      object-fit: cover;
    }
  }
  .home-header {
apps/housekeepingMiniApp/src/subpackages/components/MineServiceDetailView.vue
@@ -1,18 +1,31 @@
<template>
  <div class="mine-service-detail-view-wrapper">
    <div class="mine-service-detail-view-address">
    <div class="mine-service-detail-view-address mine-service-detail-card">
      <div class="mine-service-detail-view-title-wrapper">
        <div class="mine-service-detail-view-title">服务地址</div>
      </div>
      <div class="mine-service-detail-view-item">浙江省宁波市鄞州区河清北路55号博浪大厦24层</div>
      <div class="mine-service-detail-view-item">阳阳 13333333333</div>
    </div>
    <nut-card
      :img-url="'//img10.360buyimg.com/n2/s240x240_jfs/t1/210890/22/4728/163829/6163a590Eb7c6f4b5/6390526d49791cb9.jpg!q70.jpg'"
      :title="'服务名称'"
      :price="'155.00'"
      vip-price=""
    ></nut-card>
    <div class="mine-service-detail-card">
      <nut-card
        :img-url="'//img10.360buyimg.com/n2/s240x240_jfs/t1/210890/22/4728/163829/6163a590Eb7c6f4b5/6390526d49791cb9.jpg!q70.jpg'"
        :title="'服务名称'"
        :price="'155.00'"
      >
        <template #prolist>
          <div class="card-tag-list">
            <span class="tag">活鲜</span>
            <span class="tag">礼盒</span>
            <span class="tag">国产</span>
          </div>
        </template>
        <template #origin>
          <div></div>
        </template>
      </nut-card>
    </div>
    <List>
      <ListItem title="订单状态" :showArrow="false">
        <template #extra>
@@ -61,12 +74,32 @@
@import '@/styles/common.scss';
.mine-service-detail-view-wrapper {
  .mine-service-detail-view-address {
  .mine-service-detail-card {
    padding: 24px 32px;
    margin-bottom: 24px;
    background-color: #fff;
    border-radius: 12px;
    .card-tag-list {
      margin: 6px 0 2px;
      height: 30px;
      overflow: hidden;
      display: flex;
      .tag {
        padding: 0 10px;
        border-radius: 2px;
        font-size: 20px;
        height: 30px;
        line-height: 30px;
        color: #999;
        background-color: #f2f2f7;
        margin-right: 10px;
      }
    }
  }
  .mine-service-detail-view-address {
    .mine-service-detail-view-title-wrapper {
      display: flex;
      align-items: center;
apps/housekeepingMiniApp/src/subpackages/mine/mineOrderDetail/InnerPage.vue
@@ -3,6 +3,13 @@
  <ContentScrollView hasPaddingTop>
    <MineServiceDetailView />
  </ContentScrollView>
  <PageFooter class="order-settle-bar">
    <div class="order-settle-price-wrapper">
      <div class="order-settle-price-label">支付:</div>
      <nut-price :price="155" size="large" />
    </div>
    <PageFooterBtn type="primary" class="business-card-btn">立即下单</PageFooterBtn>
  </PageFooter>
  <!-- </LoadingLayout> -->
</template>
@@ -22,4 +29,21 @@
<style lang="scss">
@import '@/styles/common.scss';
.mineOrderDetail-page-wrapper {
  .order-settle-bar {
    .order-settle-price-wrapper {
      height: 100%;
      flex: 1;
      min-width: 0;
      display: flex;
      align-items: center;
      margin-left: 28px;
      .order-settle-price-label {
        color: boleGetCssVar('text-color', 'primary');
      }
    }
  }
}
</style>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveService/mineReserveService.vue
@@ -1,5 +1,5 @@
<template>
  <PageLayoutWithBg class="mineHire-page-wrapper" :title="'我的预约'">
  <PageLayoutWithBg class="mineReserveService-page-wrapper" :title="'我的预约'">
    <InnerPage></InnerPage>
  </PageLayoutWithBg>
</template>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceCancel/InnerPage.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
<template>
  <ContentScrollView :paddingH="false">
    <nut-form :model-value="form" ref="formRef" :rules="rules">
      <nut-form-item class="bole-form-item" prop="reason">
        <nut-textarea v-model="form.reason" rows="4" placeholder="请输入"> </nut-textarea>
      </nut-form-item>
    </nut-form>
  </ContentScrollView>
  <PageFooter>
    <PageFooterBtn type="primary" @click="handleConfirm">提交</PageFooterBtn>
  </PageFooter>
</template>
<script setup lang="ts">
import Taro from '@tarojs/taro';
import * as standardServiceServices from '@12333/services/apiV2/standardService';
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
defineOptions({
  name: 'InnerPage',
});
const route = Taro.useRouter();
const id = route.params?.id as string;
const form = reactive({
  reason: '',
});
const rules = reactive<FormRules>({
  reason: [{ required: true, message: '请输入取消原因' }],
});
const formRef = ref<any>(null);
function handleConfirm() {
  if (!formRef.value) return;
  formRef.value.validate().then(({ valid, errors }: any) => {
    if (valid) {
      confirm();
    }
  });
}
async function confirm() {
  try {
  } catch (error) {}
}
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceCancel/mineReserveServiceCancel.config.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
export default definePageConfig({
  disableScroll: true,
});
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceCancel/mineReserveServiceCancel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<template>
  <PageLayout class="mineReserveServiceCancel-page-wrapper" :title="'取消原因'" has-border>
    <InnerPage></InnerPage>
  </PageLayout>
</template>
<script setup lang="ts">
import InnerPage from './InnerPage.vue';
defineOptions({
  name: 'mineReserveServiceCancel',
});
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceConfirm/InnerPage.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <ContentScrollView style="background-color: transparent" has-padding-top>
    <TaskCheckFileCard
      :created-time="'2025-12-12 12:12:12'"
      :userCheckInTime="'2025-12-12 12:12:12'"
      :userCheckOutTime="'2025-12-12 12:12:12'"
      :checkReceiveStatus="10"
      :checkReceiveMethods="[10]"
      :files="list"
    ></TaskCheckFileCard>
    <nut-form :model-value="form" ref="formRef" :rules="rules" label-position="top">
      <nut-form-item class="bole-form-item" prop="remark" label="备注">
        <nut-textarea v-model="form.remark" rows="4" placeholder="请输入"> </nut-textarea>
      </nut-form-item>
    </nut-form>
  </ContentScrollView>
  <PageFooter>
    <PageFooterBtn type="primary" @click="handleConfirm">提交</PageFooterBtn>
  </PageFooter>
</template>
<script setup lang="ts">
import Taro from '@tarojs/taro';
import * as standardServiceServices from '@12333/services/apiV2/standardService';
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
import { TaskCheckFileCard } from '@12333/components';
import { setOSSLink } from '@12333/utils';
defineOptions({
  name: 'InnerPage',
});
const list = ref([
  'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
  'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
  'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
  'https://storage.360buyimg.com/jdc-article/fristfabu.jpg',
]);
const route = Taro.useRouter();
const id = route.params?.id as string;
const form = reactive({
  remark: '',
});
const rules = reactive<FormRules>({});
const formRef = ref<any>(null);
function handleConfirm() {
  if (!formRef.value) return;
  formRef.value.validate().then(({ valid, errors }: any) => {
    if (valid) {
      confirm();
    }
  });
}
async function confirm() {
  try {
  } catch (error) {}
}
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceConfirm/mineReserveServiceConfirm.config.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
export default definePageConfig({
  disableScroll: true,
});
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceConfirm/mineReserveServiceConfirm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<template>
  <PageLayout class="mineReserveServiceConfirm-page-wrapper" :title="'服务确认'" has-border>
    <InnerPage></InnerPage>
  </PageLayout>
</template>
<script setup lang="ts">
import InnerPage from './InnerPage.vue';
defineOptions({
  name: 'mineReserveServiceConfirm',
});
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceDetail/InnerPage.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
<template>
  <!-- <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch"> -->
  <ContentScrollView hasPaddingTop>
    <MineServiceDetailView />
  </ContentScrollView>
  <PageFooter>
    <PageFooterBtn type="primary" class="business-card-btn" @click="goCancel"
      >取消服务</PageFooterBtn
    >
    <PageFooterBtn type="primary" class="business-card-btn" @click="goConfirm"
      >服务确认</PageFooterBtn
    >
  </PageFooter>
  <!-- </LoadingLayout> -->
</template>
<script setup lang="ts">
import MineServiceDetailView from '../../components/MineServiceDetailView.vue';
import Taro from '@tarojs/taro';
import * as standardServiceServices from '@12333/services/apiV2/standardService';
import { RouterPath } from '@/constants';
defineOptions({
  name: 'InnerPage',
});
const route = Taro.useRouter();
const id = route.params?.id as string;
function goCancel() {
  Taro.navigateTo({
    url: `${RouterPath.mineReserveServiceCancel}?id=${id}`,
  });
}
function goConfirm() {
  Taro.navigateTo({
    url: `${RouterPath.mineReserveServiceConfirm}?id=${id}`,
  });
}
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceDetail/mineReserveServiceDetail.config.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
export default definePageConfig({
  disableScroll: true,
});
apps/housekeepingMiniApp/src/subpackages/mine/mineReserveServiceDetail/mineReserveServiceDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
<template>
  <PageLayout class="mineReserveServiceDetail-page-wrapper" title="预约详情" has-border>
    <InnerPage />
  </PageLayout>
</template>
<script setup lang="ts">
import InnerPage from './InnerPage.vue';
defineOptions({
  name: 'mineReserveServiceDetail',
});
</script>
apps/housekeepingMiniApp/src/subpackages/sercice/serciceDetail/serciceDetail.vue
@@ -2,14 +2,30 @@
  <PageLayoutWithBg class="mineHire-page-wrapper" :title="'服务名'" :need-auth="false">
    <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch">
      <ContentScrollView style="background-color: transparent"> serciceDetail </ContentScrollView>
      <PageFooter>
        <!-- <PageFooterAction
            :icon="IconShare"
            text="分享"
            :isFlex="false"
            openType="share"
          ></PageFooterAction>
          <PageFooterAction
            :icon="userResumeInfo.isCollected ? IconAttentionActive : IconAttention"
            text="收藏"
            :isFlex="false"
            @click="handleAttention"
          ></PageFooterAction> -->
        <PageFooterBtn type="primary" @click="pay">预约下单</PageFooterBtn>
        <PageFooterBtn type="primary" @click="pay">预约下单</PageFooterBtn>
      </PageFooter>
    </LoadingLayout>
  </PageLayoutWithBg>
</template>
<script setup lang="ts">
import { useTaskInfo } from '@12333/hooks';
import InnerPage from './InnerPage.vue';
import { useStandardServiceDetail } from '@12333/hooks';
import Taro from '@tarojs/taro';
import * as standardOrderServices from '@12333/services/apiV2/standardOrder';
defineOptions({
  name: 'serciceDetail',
@@ -18,9 +34,49 @@
const router = Taro.useRouter();
const id = router.params?.id ?? '';
const { isLoading, isError, detail, refetch } = useTaskInfo({
const { isLoading, isError, detail, refetch } = useStandardServiceDetail({
  id,
});
async function addStandardOrder() {
  try {
    let params: API.AddStandardOrderCommand = {
      serviceId: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
      serviceName: 'string',
      specId: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
      specName: 'string',
      specPrice: 0,
      specNumber: 0,
      addressId: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
      beginTime: '2025-12-24T06:44:24.840Z',
      endTime: '2025-12-24T06:44:24.840Z',
      supplierEnterpriseId: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
      enterpriseEmployeeIds: ['3fa85f64-5717-4562-b3fc-2c963f66afa6'],
      remark: 'string',
      payAccess: 1,
      payAmount: 0,
    };
    let res = await standardOrderServices.addStandardOrder(params);
  } catch (error) {}
}
async function pay() {
  try {
    let params: API.PayStandardOrderCommand = {
      id: '9e919af2-3d33-4eac-f6dc-08de429676b3',
    };
    let res = await standardOrderServices.payStandardOrder(params);
    if (res) {
      Taro.requestPayment({
        timeStamp: res.timestamp,
        nonceStr: res.nonceStr,
        package: res.package,
        signType: res.signType as any,
        paySign: res.paySign,
      });
    }
  } catch (error) {}
}
</script>
<style lang="scss">
packages/hooks/index.ts
@@ -11,3 +11,4 @@
export * from './payrollChange';
export * from './dialog';
export * from './insurance';
export * from './standardOrder';
packages/hooks/standardOrder.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import * as standardServiceServices from '@12333/services/apiV2/standardService';
import { MaybeRef, unref } from 'vue';
type UseStandardServiceDetailOptions = {
  id: MaybeRef<string>;
};
export function useStandardServiceDetail({ id }: UseStandardServiceDetailOptions) {
  const { data, refetch, isLoading, isError } = useQuery({
    queryKey: ['standardServiceServices/getStandardService', id],
    queryFn: async () => {
      let params: API.APIgetStandardServiceParams = {
        id: unref(id),
      };
      return await standardServiceServices.getStandardService(params, {
        showLoading: false,
      });
    },
    placeholderData: () => ({} as API.GetStandardServiceQueryResult),
  });
  return {
    detail: data,
    refetch,
    isLoading,
    isError,
  };
}
packages/services/apiV2/enterprise.ts
@@ -17,6 +17,21 @@
  });
}
/** ç¦ç”¨ä¼ä¸š POST /api/user/enterprise/disabledEnterprise */
export async function disabledEnterprise(
  body: API.DisabledEnterpriseCommand,
  options?: API.RequestConfig
) {
  return request<number>('/api/user/enterprise/disabledEnterprise', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
/** æŸ¥è¯¢ä¼ä¸šè¯¦æƒ… GET /api/user/enterprise/getEnterprise */
export async function getEnterprise(
  // å åŠ ç”Ÿæˆçš„Param类型 (非body参数swagger默认没有生成对象)
packages/services/apiV2/standardOrder.ts
@@ -7,7 +7,7 @@
  body: API.AddStandardOrderCommand,
  options?: API.RequestConfig
) {
  return request<API.AddStandardOrderCommandResult>('/api/flexjob/standardOrder/addStandardOrder', {
  return request<string>('/api/flexjob/standardOrder/addStandardOrder', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
packages/services/apiV2/typings.d.ts
@@ -55,13 +55,6 @@
    payAmount?: number;
  }
  interface AddStandardOrderCommandResult {
    /** Id */
    id?: string;
    /** æ”¯ä»˜åœ°å€ */
    payUrl?: string;
  }
  interface AgainSureTaskSettlementOrderRosterCommand {
    /** åå•Id */
    id?: string;
@@ -778,6 +771,12 @@
    ids: string[];
  }
  interface DisabledEnterpriseCommand {
    ids?: string[];
    /** æ˜¯å¦å·²ç¦ç”¨ */
    isDisabled?: boolean;
  }
  interface EditEnterpriseEmployeeCommand {
    /** Id */
    id?: string;
@@ -1878,24 +1877,6 @@
    settlementTimeEnd?: string;
  }
  interface FriendlyResultAddStandardOrderCommandResult {
    /** è·Ÿè¸ªId */
    traceId?: string;
    /** çŠ¶æ€ç  */
    code?: number;
    /** é”™è¯¯ç  */
    errorCode?: string;
    data?: AddStandardOrderCommandResult;
    /** æ‰§è¡ŒæˆåŠŸ */
    success?: boolean;
    /** é”™è¯¯ä¿¡æ¯ */
    msg?: any;
    /** é™„加数据 */
    extras?: any;
    /** æ—¶é—´æˆ³ */
    timestamp?: number;
  }
  interface FriendlyResultBatchEnterpriseSignContractCommandResult {
    /** è·Ÿè¸ªId */
    traceId?: string;
@@ -5941,6 +5922,10 @@
    /** æ˜¯å¦å·²é…ç½® */
    isConfigured?: boolean;
    type?: EnumEnterpriseType;
    /** åˆ›å»ºæ—¶é—´-起始 */
    createdTimeBegin?: string;
    /** åˆ›å»ºæ—¶é—´-截止 */
    createdTimeEnd?: string;
    pageModel?: PagedListQueryPageModel;
  }
@@ -5956,10 +5941,18 @@
    societyCreditCode?: string;
    /** æ˜¯å¦å®žå */
    isReal?: boolean;
    /** æ˜¯å¦ç¦ç”¨ */
    isDisabled?: boolean;
    /** è”系人 */
    contacts?: string;
    /** è”系电话 */
    contactPhoneNumber?: string;
    /** ç”¨æˆ·Id */
    userId?: string;
    /** ç”¨æˆ·å */
    userName?: string;
    /** æ‰‹æœºå· */
    userPhoneNumber?: string;
    /** æ‰€åœ¨çœä»½ */
    provinceContent?: string;
    /** æ‰€åœ¨åŸŽå¸‚ */
@@ -5973,6 +5966,8 @@
    serviceFeeCollectType?: EnumEnterpriseCooperationServiceFeeCollectType;
    /** æœåŠ¡è´¹ */
    serviceFeeRate?: number;
    /** åˆ›å»ºæ—¶é—´ */
    createdTime?: string;
  }
  interface GetEnterpriseWalletAccessSelectQueryOption {
@@ -9101,6 +9096,8 @@
  }
  interface HistoryQueryResultItem {
    /** Id */
    id?: string;
    /** è·Ÿè¸ªId */
    traceId?: string;
    /** æ“ä½œäºº */