Compare commits

...

2 Commits

Author SHA1 Message Date
科技小王子 1521be9219 Merge remote-tracking branch 'origin/master' 6 months ago
科技小王子 c2b28eb8e1 修复已知问题 6 months ago
  1. 70
      api/shop/shopCart/model/index.ts
  2. 2
      api/system/company/model/index.ts
  3. 32
      components/CompanyList.vue
  4. 2
      composables/configState.ts
  5. 9
      nuxt.config.ts
  6. 4
      pages/components/Flash.vue
  7. 53
      pages/item/components/PageBanner.vue
  8. 32
      pages/item/index.vue
  9. 102
      pages/product/components/CardList.vue
  10. 428
      pages/product/create/index.vue
  11. 57
      pages/templates/components/CardList.vue
  12. 9
      pages/user/components/Order.vue

70
api/shop/shopCart/model/index.ts

@ -0,0 +1,70 @@
import type { PageParam } from '@/api';
import type {ShopOrderInfo} from "~/api/shop/shopOrderInfo/model";
import type {Company} from "~/api/system/company/model";
/**
*
*/
export interface ShopCart {
// 购物车表ID
id?: string;
// 类型 0商城 1外卖
type?: number;
// 唯一标识
code?: string;
// 商品ID
productId?: string;
// 商品规格
spec?: string;
// 商品价格
price?: string;
// 商品数量
cartNum?: number;
// 单商品合计
totalPrice?: string;
// 0 = 未购买 1 = 已购买
isPay?: string;
// 是否为立即购买
isNew?: string;
// 拼团id
combinationId?: number;
// 秒杀产品ID
seckillId?: number;
// 砍价id
bargainId?: number;
// 是否选中
selected?: string;
// 商户ID
merchantId?: string;
// 用户ID
userId?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
// 商品封面图
image?: string;
}
/**
*
*/
export interface ShopCartParam extends PageParam {
id?: number;
keywords?: string;
}
export interface MyCart {
appName?: string,
domain?: string,
num?: number,
type?: number;
payType?: number,
payPrice?: number,
month?: number,
comments?: string,
list?: Company[],
totalPrice?: number
}

2
api/system/company/model/index.ts

@ -10,6 +10,7 @@ export interface Company {
companyId?: number;
type?: number;
menuId?: number;
appName?: string;
shortName?: string;
companyName?: string;
companyType?: number;
@ -55,6 +56,7 @@ export interface Company {
userId?: number;
official?: boolean;
price?: number;
deliveryMethod?: number;
chargingMethod?: number;
planId?: number;
sortNumber?: number;

32
components/CompanyList.vue

@ -32,22 +32,24 @@
<el-avatar size="small" :src="item.companyLogo" />
<span class="text-gray-400 line-clamp-1 pr-2">{{ item.companyName }}</span>
</el-space>
<template v-if="item.isBuy">
<el-button v-if="item.installed" @click.stop="openSpmUrl(`https://${item.domain}`,item,item.companyId,true)">控制台</el-button>
<el-button v-else type="success">立即开通</el-button>
</template>
<template v-else>
<el-button type="warning" v-if="item.price" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">
<div class="flex items-center">
<span>{{ item.price * 0.1 }}</span>
<span v-if="item.chargingMethod == 2">/</span>
<span v-if="item.chargingMethod == 3">/</span>
<span v-if="item.chargingMethod == 4">/</span>
</div>
<el-button type="warning" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">立即开通
</el-button>
<el-button v-else type="success" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">立即开通
</el-button>
</template>
<!-- <template v-if="item.isBuy">-->
<!-- <el-button v-if="item.installed" @click.stop="openSpmUrl(`https://${item.domain}`,item,item.companyId,true)">控制台</el-button>-->
<!-- <el-button v-else type="success">立即开通</el-button>-->
<!-- </template>-->
<!-- <template v-else>-->
<!-- <el-button type="warning" v-if="item.price" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">-->
<!-- <div class="flex items-center">-->
<!-- <span>{{ item.price * 0.1 }}</span>-->
<!-- <span v-if="item.chargingMethod == 2">/</span>-->
<!-- <span v-if="item.chargingMethod == 3">/</span>-->
<!-- <span v-if="item.chargingMethod == 4">/</span>-->
<!-- </div>-->
<!-- </el-button>-->
<!-- <el-button v-else type="success" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">立即开通-->
<!-- </el-button>-->
<!-- </template>-->
</div>
</div>
</el-card>

2
composables/configState.ts

@ -73,6 +73,8 @@ export const useShowLogin = () => useState('showLogin',() => false)
// 购物车状态
export const useCart = () => useState<any>('cart', () => {
return {
appName: '',
domain: '',
num: 1,
type: 1,
payType: 102,

9
nuxt.config.ts

@ -27,15 +27,16 @@ export default defineNuxtConfig({
}
},
devServer: {
port: 10304
port: 16880
},
runtimeConfig: {
public: {
tenantId: 10304,
// 开发环境配置
// apiServer: 'http://127.0.0.1:9002/api',
// tenantId: '5',
apiServer: 'http://127.0.0.1:30000/api',
// 生产环境
apiServer: 'https://cms-api.websoft.top/api',
// apiServer: 'https://common-api.websoft.top/api',
globalTitle: '网宿软件',
domain: 'websoft.top'
},

4
pages/components/Flash.vue

@ -98,8 +98,8 @@
<div class="mt-10 flex flex-wrap gap-x-6 gap-y-3 justify-center">
<div class="flex flex-col gap-4">
<div class="flex items-center">
<el-button size="large" type="primary" v-if="!token" :icon="ElIconArrowRight" @click="openSpmUrl(`/passport/login`)">立即开始</el-button>
<el-button size="large" type="primary" v-else :icon="ElIconArrowRight" @click="loginAdminByToken">进入控制台</el-button>
<el-button size="large" type="primary" :icon="ElIconArrowRight" @click="openSpmUrl(`/product/create`, {},10297,true)">立即开始</el-button>
<!-- <el-button size="large" type="primary" v-else :icon="ElIconArrowRight" @click="loginAdminByToken">进入控制台</el-button>-->
<el-button size="large" type="success" :icon="ElIconDownload" @click="openSpmUrl(`http://git.gxwebsoft.com/free`, {},0,true)">源码下载</el-button>
<el-button size="large" type="danger" @click="openSpmUrl(`https://admin.websoft.top`, {},123)">商业版演示</el-button>
</div>

53
pages/item/components/PageBanner.vue

@ -63,32 +63,33 @@
<!-- <el-button v-else type="success" @click.stop="openSpmUrl(`/product/create`,form,form.companyId,true)">立即开通-->
<!-- </el-button>-->
<!-- </template>-->
<el-button type="primary" @click.stop="openSpmUrl(`https://${form.domain}`,form,form.companyId,true)">进入控制台</el-button>
<el-button @click="openSpmUrl(`/ask`,form,form.companyId,true)">产品文档</el-button>
<template v-for="(item,index) in form.links" :key="index">
<div v-if="item.qrcode">
<el-popover
placement="top-start"
:width="200"
trigger="hover"
>
<template #default>
<div class=" p-2 flex justify-center">
<el-image :src="item.qrcode" :size="160"/>
</div>
</template>
<template #reference>
<el-button :icon="ElIconFullScreen">{{ item.type }}</el-button>
</template>
</el-popover>
</div>
<el-button
v-else
@click="openSpmUrl(`${item.domain}`,item,item.tenantId,true)"
>
{{ item.type }}
</el-button>
</template>
<el-button type="warning" @click.stop="openSpmUrl(`/product/create`,form,form.companyId,true)">立即开通</el-button>
<el-button @click.stop="openSpmUrl(`https://${form.domain}`,form,form.companyId,true)">产品控制台</el-button>
<el-button @click="openSpmUrl(`/ask`,form,form.companyId,true)">帮助文档</el-button>
<!-- <template v-for="(item,index) in form.links" :key="index">-->
<!-- <div v-if="item.qrcode">-->
<!-- <el-popover-->
<!-- placement="top-start"-->
<!-- :width="200"-->
<!-- trigger="hover"-->
<!-- >-->
<!-- <template #default>-->
<!-- <div class=" p-2 flex justify-center">-->
<!-- <el-image :src="item.qrcode" :size="160"/>-->
<!-- </div>-->
<!-- </template>-->
<!-- <template #reference>-->
<!-- <el-button :icon="ElIconFullScreen">{{ item.type }}</el-button>-->
<!-- </template>-->
<!-- </el-popover>-->
<!-- </div>-->
<!-- <el-button-->
<!-- v-else-->
<!-- @click="openSpmUrl(`${item.domain}`,item,item.tenantId,true)"-->
<!-- >-->
<!-- {{ item.type }}-->
<!-- </el-button>-->
<!-- </template>-->
</el-space>
</div>
</div>

32
pages/item/index.vue

@ -12,34 +12,30 @@
</div>
</template>
<el-descriptions title="应用参数" :column="2" border>
<el-descriptions-item label="租户ID">{{form.tenantId}}</el-descriptions-item>
<el-descriptions-item label="插件ID">{{form.menuId || '-'}}</el-descriptions-item>
<el-descriptions-item label="名称">{{form.tenantName}}</el-descriptions-item>
<el-descriptions-item label="控制台"><a class="cursor-pointer" @click="openUrl(`https://${form.domain}`)">{{form.domain}}</a></el-descriptions-item>
<!-- <el-descriptions-item label="租户ID">{{form.tenantId}}</el-descriptions-item>-->
<!-- <el-descriptions-item label="插件ID">{{form.menuId || '-'}}</el-descriptions-item>-->
<el-descriptions-item :span="2" label="应用名称">{{form.tenantName}}</el-descriptions-item>
<!-- <el-descriptions-item label="管理地址"><a class="cursor-pointer" @click="openUrl(`https://${form.domain}`)">{{form.domain}}</a></el-descriptions-item>-->
<el-descriptions-item v-for="(item,index) in form.parameters" :key="index" :label="item.name">{{ item.value }}</el-descriptions-item>
</el-descriptions>
<template v-if="form.gits && form.gits.length > 0">
<div class="h-[24px]"></div>
<el-descriptions title="代码仓库" :column="1" border>
<el-descriptions-item v-for="(item,index) in form.gits" :key="index" :label="item.title">
<el-input v-model="item.domain" readonly />
</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="form.accounts && form.accounts.length > 0">
<div class="h-[24px]"></div>
<el-descriptions title="演示账号" :column="1" border>
<el-descriptions title="登录账号" :column="1" border>
<template v-for="(item,index) in form.accounts" :key="index">
<el-descriptions-item :label="item.type" v-if="item.account">
<el-space>
<span>{{ item.domain }}</span>
<span>{{ item.account }}</span>
<span>{{ item.password }}</span>
</el-space>
还没有账号? <el-button type="text" @click="openSpmUrl(`/passport/register`)">立即注册</el-button>
</el-descriptions-item>
</template>
</el-descriptions>
</template>
<template v-if="form.gits && form.gits.length > 0">
<div class="h-[24px]"></div>
<el-descriptions title="代码仓库" :column="1" border>
<el-descriptions-item v-for="(item,index) in form.gits" :key="index" :label="item.title">
<el-input v-model="item.domain" readonly />
</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="form.content">
<div class="h-[24px]"></div>
<el-descriptions title="详细说明" />

102
pages/product/components/CardList.vue

@ -0,0 +1,102 @@
<template>
<div class="xl:w-screen-xl sm:flex xl:p-0 p-4 m-auto relative">
<el-row :gutter="24" class="flex">
<template v-for="(item,index) in data?.list" :key="index">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-5 min-w-xs">
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="hover:bg-gray-50 cursor-pointer"
@click="openSpmUrl(`/item`, item,item.companyId,true)">
<el-image
:src="item.image"
:fit="fit" :lazy="true" class="w-full md:h-[150px] h-[199px] cursor-pointer bg-gray-50"/>
<div class="flex-1 px-4 py-5 sm:p-6 !p-4">
<div class="text-gray-700 dark:text-white text-base font-semibold flex flex-col gap-1.5">
<div class="flex-1 text-xl cursor-pointer flex items-center">
{{ item.shortName }}
<el-tag v-if="item.chargingMethod === 0" size="small" type="success" class="text-white ml-2"
effect="dark">免费
</el-tag>
</div>
</div>
<div class="flex items-center gap-1.5 py-2 text-gray-500 justify-between">
<div class="text-gray-500 line-clamp-2">{{ item.comments }}</div>
</div>
<div class="button-group flex justify-between items-center mt-3">
<el-space class="flex items-end">
<el-avatar size="small" :src="item.companyLogo"/>
<span class="text-gray-400 line-clamp-1 pr-2">{{ item.companyName }}</span>
</el-space>
<el-button type="warning" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">立即开通
</el-button>
<!-- <el-button @click.stop="loginByToken(item)">控制台</el-button>-->
<!-- <el-button type="warning" v-if="item.price" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">-->
<!-- <div class="flex items-center">-->
<!-- <span>{{ item.price * 0.1 }}</span>-->
<!-- <span v-if="item.chargingMethod == 2">/</span>-->
<!-- <span v-if="item.chargingMethod == 3">/</span>-->
<!-- <span v-if="item.chargingMethod == 4">/</span>-->
<!-- </div>-->
<!-- </el-button>-->
<!-- <el-button v-else type="success" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">立即开通-->
<!-- </el-button>-->
<!-- <template v-if="item.isBuy">-->
<!-- <el-button v-if="item.installed" @click.stop="openSpmUrl(`https://${item.domain}`,item,item.companyId,true)">控制台</el-button>-->
<!-- <el-button v-else type="success">立即开通</el-button>-->
<!-- </template>-->
<!-- <template v-else>-->
<!-- <el-button type="warning" v-if="item.price" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">-->
<!-- <div class="flex items-center">-->
<!-- <span>{{ item.price * 0.1 }}</span>-->
<!-- <span v-if="item.chargingMethod == 2">/</span>-->
<!-- <span v-if="item.chargingMethod == 3">/</span>-->
<!-- <span v-if="item.chargingMethod == 4">/</span>-->
<!-- </div>-->
<!-- </el-button>-->
<!-- <el-button v-else type="success" @click.stop="openSpmUrl(`/product/create`,item,item.companyId,true)">立即开通-->
<!-- </el-button>-->
<!-- </template>-->
</div>
</div>
</el-card>
</el-col>
</template>
</el-row>
</div>
<div class="flex justify-center py-3">
<el-pagination background layout="prev, pager, next" :total="data?.count" @change="onPage"/>
</div>
<!-- <div v-if="disabled" class="px-1 text-center text-gray-500">-->
<!-- 没有更多了-->
<!-- </div>-->
</template>
<script setup lang="ts">
import {loginAdminByToken, loginByToken, openSpmUrl} from "~/utils/common";
import type {Company} from "~/api/system/company/model";
import type {PageResult} from "~/api";
const props = withDefaults(
defineProps<{
data?: PageResult<Company>;
disabled?: boolean;
fit?: any;
}>(),
{
fit: 'cover'
}
);
const emit = defineEmits<{
(e: 'done', index: number): void;
}>();
// const load = () => {
// if(!props.disabled){
// emit('done')
// }
// }
const onPage = (index: number) => {
emit('done', index)
}
</script>

428
pages/product/create/index.vue

@ -0,0 +1,428 @@
<template>
<PageBanner :form="form" :active="active"/>
<div class="page-main md:w-screen-xl m-auto p-3">
<el-row :gutter="24">
<el-col :span="16" :xs="24">
<el-form :model="form" label-width="auto" label-position="left" class="w-full">
<el-card shadow="hover" class="mb-4">
<template #header>
<div class="card-header font-bold">
<span v-if="form.type === 0">产品</span>
<span v-if="form.type === 1">插件</span>
<span>{{ form.shortName }}</span>
</div>
</template>
<div class="flex flex-col">
<el-form-item label="应用名称">
<el-input v-model="cart.appName" style="width: 360px" placeholder="XXX公司官网"></el-input>
</el-form-item>
<!-- <el-form-item label="类型">-->
<!-- <el-radio-button v-if="form.type == 0" border>完整应用</el-radio-button>-->
<!-- <el-radio-button v-if="form.type == 1" border>插件</el-radio-button>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="交付方式" v-if="form.deliveryMethod">-->
<!-- <el-radio-button v-if="form.deliveryMethod == 1" border>SaaS交付</el-radio-button>-->
<!-- <el-radio-button v-if="form.deliveryMethod == 2" border>源码交付</el-radio-button>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="套餐版本">-->
<!-- <el-radio-group v-model="form.image">-->
<!-- <el-radio-button value="1" border>基础版</el-radio-button>-->
<!-- <el-radio-button value="2" border>标准版</el-radio-button>-->
<!-- <el-radio-button value="3" border>专业版</el-radio-button>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<el-form-item label="购买时长" v-if="form.chargingMethod && form.chargingMethod > 1">
<el-radio-group v-model="cart.month" @change="handleChargingMethod">
<el-radio-button :value="1" border>1个月</el-radio-button>
<el-radio-button :value="12" border>1</el-radio-button>
<el-radio-button :value="24" border>2</el-radio-button>
<el-radio-button :value="36" border>3</el-radio-button>
<el-radio-button :value="60" border>5</el-radio-button>
</el-radio-group>
</el-form-item>
<!-- 单价 {{ form.price }} x 购买时长 {{ cart.month }} x 数量 {{ cart.num }} x 折扣 0.1= {{ cart.totalPrice }}-->
<!-- <el-form-item label="购买数量">-->
<!-- <el-input-number v-model="cart.num" :min="1" :max="form.canBuyNumber" @change="handleChange"/>-->
<!-- </el-form-item>-->
</div>
</el-card>
<el-card shadow="hover" class="mb-4">
<template #header>
<div class="card-header font-bold">
<span>服务协议</span>
</div>
</template>
<div class="flex items-center">
<el-checkbox v-model="isAgree" @change="changeIsAgree"></el-checkbox>
<span class="ml-1">我已阅读并同意</span>
<span class="text-blue-400 hover:text-blue-500 cursor-pointer"
@click="openSpmUrl(`/detail`, {}, 357, true)">用户协议</span>
<span class="text-blue-400 hover:text-blue-500 cursor-pointer"
@click="openSpmUrl(`/detail`, {}, 69, true)">隐私协议</span>
<span class="text-blue-400 hover:text-blue-500 cursor-pointer"
@click="openSpmUrl(`/detail`, {}, 69, true)">产品购买协议</span>
</div>
</el-card>
</el-form>
</el-col>
<el-col :span="8" :xs="24">
<el-card shadow="hover" class="mb-4">
<template #header>
<div class="card-header font-bold">
<span>订单详情</span>
</div>
</template>
<el-descriptions :title="`订购产品`" :column="1" class="mb-4">
<el-descriptions-item label="产品名称:">{{ form.shortName }}</el-descriptions-item>
<el-descriptions-item label="产品类型:">{{ form.type == 1 ? '插件' : '完整应用' }}</el-descriptions-item>
<el-descriptions-item label="交付方式:">{{ form.deliveryMethod == 1 ? 'SaaS交付' : '源码交付' }}</el-descriptions-item>
<el-descriptions-item label="应用名称:">{{ cart.appName }}</el-descriptions-item>
<!-- <el-descriptions-item label="套餐版本:">标准版</el-descriptions-item>-->
<el-descriptions-item label="购买数量:">{{ cart.num }} </el-descriptions-item>
<el-descriptions-item label="购买时长:">{{ cart.month }} 个月</el-descriptions-item>
<!-- <el-descriptions-item label="到期时间:">2025-10-06</el-descriptions-item>-->
</el-descriptions>
<el-descriptions title="合计:" :column="1" class="mb-4">
<el-descriptions-item label="订单金额:"><span class="line-through"></span><span
class="text-xl line-through">{{ cart.totalPrice }}</span></el-descriptions-item>
<el-descriptions-item label="实付金额:"><span class="text-red-600"></span><span
class="font-bold text-xl text-red-600">{{ cart.payPrice }}</span></el-descriptions-item>
</el-descriptions>
<el-form-item>
<el-button type="danger" class="w-full" :disabled="!isAgree" size="large" @click="onPay">去支付</el-button>
</el-form-item>
</el-card>
</el-col>
</el-row>
</div>
<el-dialog
v-model="visible"
title="订单确认"
align-center
width="450"
:before-close="() => visible = false"
>
<div class="flex justify-center pt-3">
<el-radio-group v-model="cart.payType" @change="handlePayType">
<el-radio-button :value="102" border>微信支付</el-radio-button>
<!-- <el-radio-button :value="3" border>支付宝</el-radio-button>-->
<el-radio-button :value="0" border>余额支付</el-radio-button>
</el-radio-group>
</div>
<div class="flex justify-center py-4" v-if="cart.payType == 102">
<el-avatar :size="250" :src="wxPayQrCode"
shape="square"/>
</div>
<template #footer>
<div class="dialog-footer text-center pb-3" v-if="cart.payType != 0">
<el-tag type="success" size="large">
使用微信扫码完成支付
</el-tag>
</div>
<div class="flex flex-col justify-center w-1/2 m-auto pb-12" v-if="cart.payType === 0">
<span class="py-2 text-center">可用余额{{ userInfo?.balance || 0.00 }}</span>
<div class="flex flex-col">
<el-input type="password" class="py-2" size="large" v-model="payPassword" maxlength="6" show-password placeholder="请输入支付密码" />
<el-button type="danger" class="py-2 my-3" size="large" @click="onDone">
确定支付
</el-button>
</div>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {useConfigInfo, useToken, useUser, useWebsite} from "~/composables/configState";
import useFormData from '@/utils/use-form-data';
import type {User} from '@/api/system/user/model';
import {ref} from 'vue'
import QRCode from 'qrcode';
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult} from "~/api";
import PageBanner from './components/PageBanner.vue';
import type {FormInstance} from "element-plus";
import {useClientRequest} from "~/composables/useClientRequest";
import type {Company} from "~/api/system/company/model";
//
const runtimeConfig = useRuntimeConfig();
const route = useRoute();
const activeIndex = ref('');
const website = useWebsite()
const isAgree = ref<boolean>(true);
const active = ref<number>(1);
const visible = ref<boolean>(false);
const wxPayQrCode = ref<string>()
const payPassword = ref<string>()
const formRef = ref<FormInstance>()
const config = useConfigInfo();
const token = useToken();
const userInfo = useUser();
const cart = useCart();
const qrOptions = ref({
width: 200, //
margin: 10, //
color: { dark: '#000', light: '#fff' }, //
});
//
const {form, assignFields} = useFormData<Company>({
companyId: undefined,
menuId: undefined,
type: undefined,
appName: undefined,
shortName: undefined,
companyName: undefined,
companyType: undefined,
companyTypeMultiple: undefined,
appType: undefined,
companyLogo: undefined,
image: undefined,
companyCode: undefined,
domain: undefined,
phone: undefined,
tel: undefined,
email: undefined,
InvoiceHeader: undefined,
startTime: undefined,
expirationTime: undefined,
version: undefined,
versionName: undefined,
versionCode: undefined,
members: undefined,
storage: undefined,
storageMax: undefined,
buys: undefined,
clicks: undefined,
users: undefined,
departments: undefined,
industryParent: undefined,
industryChild: undefined,
country: undefined,
province: undefined,
city: undefined,
region: undefined,
address: undefined,
latitude: undefined,
longitude: undefined,
businessEntity: undefined,
comments: undefined,
authentication: undefined,
industryId: undefined,
industryName: undefined,
status: undefined,
userId: undefined,
official: undefined,
deliveryMethod: undefined,
chargingMethod: undefined,
price: undefined,
planId: undefined,
sortNumber: undefined,
authoritative: undefined,
merchantId: undefined,
tenantId: undefined,
tenantName: undefined,
tenantCode: undefined,
modules: undefined,
requestUrl: undefined,
socketUrl: undefined,
serverUrl: undefined,
modulesUrl: undefined,
merchantUrl: undefined,
websiteUrl: undefined,
mpWeixinCode: undefined,
mpAlipayCode: undefined,
h5Code: undefined,
androidUrl: undefined,
iosUrl: undefined,
avatar: undefined,
nickname: undefined,
code: undefined,
createTime: undefined,
updateTime: undefined,
password: undefined,
password2: undefined,
collection: undefined,
recommend: undefined,
title: undefined,
parentName: undefined,
categoryName: undefined,
});
const handleChange = (index:any): void => {
cart.value.num = index;
computeTotalPrice();
}
const handleChargingMethod = (index: any): void => {
cart.value.month = index;
computeTotalPrice();
}
const computeTotalPrice = () => {
// = ( * * ) /
cart.value.totalPrice = Math.round(Number(form.price)*Number(cart.value.num)*Number(cart.value.month));
cart.value.payPrice = Math.round(Number(cart.value.totalPrice) * Number(0.1));
}
const changeIsAgree = (index: any) => {
if (index) {
active.value = 2;
}
}
const handlePayType = (index: any) => {
cart.value.payType = index;
onPay();
}
//
const onPay = () => {
visible.value = true;
active.value = 3;
//
if(cart.value.payType == 0){
return;
}
//
if(cart.value.payType == 102){
useClientRequest<ApiResult<any>>(`/system/wx-native-pay/codeUrl`, {
method: 'POST',
body: cart.value
}).then(async res => {
if (res.code == 0) {
console.log(res.data)
try {
// URL
wxPayQrCode.value = await QRCode.toDataURL(res.data);
} catch (error) {
console.error('Error generating QR code:', error);
}
} else {
return ElMessage.error(res.message)
}
})
}
//
if(cart.value.payType == 3){
return;
}
}
const onSubmit = async () => {
const {data: modify} = await useServerRequest<ApiResult<User>>('/auth/user', {
baseURL: runtimeConfig.public.apiServer,
method: 'put',
body: form
})
if (modify.value?.code == 0) {
ElMessage.success('修改成功')
}
}
const reload = async () => {
//
if (!token.value || token.value == '') {
navigateTo(`/passport/login`)
return false;
}
// useClientRequest(`/auth/user`, {}).then(res => {
// if(res?.data?.balance){
// cart.value.balance = res?.data?.balance;
// }
// })
const {data: response} = await useServerRequest<ApiResult<Company>>(`/system/company/${getIdBySpm(5)}`, {baseURL: runtimeConfig.public.apiServer})
if (response.value?.data) {
assignFields(response.value?.data);
form.categoryName = '选择套餐';
cart.value.comments = `购买${response.value?.data.shortName}`;
if(response.value?.data.price){
cart.value.payPrice = response.value?.data.price;
computeTotalPrice();
}
useHead({
title: `${form.shortName}`,
meta: [{name: website.value.keywords, content: website.value.comments}]
});
}
}
//
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
ElMessage.error('还没有评分哦!')
// if (form.rate === 0) {
// ElMessage.error('!')
// return false;
// }
// form.productId = props.productId;
// useClientRequest<ApiResult<any>>(`/cms/cms-product-comment/`, {
// method: 'POST',
// body: form
// }).then(res => {
// if (res.code == 0) {
// ElMessage.success(res.message)
// visible.value = false
// resetFields();
// emit('done',1)
// } else {
// return ElMessage.error(res.message)
// }
// })
}
//
const onDone = () => {
cart.value.type = 1;
cart.value.list = [];
cart.value.list?.push(form);
useClientRequest<ApiResult<any>>(`/system/order/createOrder`, {
method: 'POST',
body: cart.value
}).then(res => {
if(res.code == 0){
ElMessage.success('购买成功');
visible.value = !visible.value;
setTimeout(() => {
navigateTo(`/user/order`)
},500)
}
if(res.code == 1){
ElMessage.error(res.message);
}
}).catch(res => {
})
// useClientRequest<ApiResult<any>>(`/system/menu/install`, {
// method: 'POST',
// body: {
// companyId: getIdBySpm(5)
// }
// }).then(res => {
// if (res.code == 0) {
// ElMessage.success(res.message)
// } else {
// return ElMessage.error(res.message)
// }
// })
}
watch(
() => route.path,
(path) => {
activeIndex.value = path;
console.log(path, '=>Path')
reload();
},
{immediate: true}
);
</script>
<style lang="scss">
.text-a123 {
color: #f0f2f5;
}
</style>

57
pages/templates/components/CardList.vue

@ -0,0 +1,57 @@
<template>
<div class="xl:w-screen-xl sm:flex xl:p-0 p-4 m-auto relative" v-infinite-scroll="load">
<el-row :gutter="24" class="flex">
<template v-for="(item,index) in list" :key="index">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="mb-5 min-w-xs">
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="hover:bg-gray-50 cursor-pointer">
<el-image
:src="item.image"
:fit="fit" :lazy="true" class="w-full md:h-[150px] h-[199px] cursor-pointer bg-gray-50"/>
<div class="flex-1 px-4 py-5 sm:p-6 !p-4">
<div class="text-gray-700 dark:text-white text-base font-semibold flex flex-col gap-1.5">
<div class="flex-1 text-xl cursor-pointer flex items-center">
{{ item.shortName }}
</div>
</div>
<div class="flex items-center gap-1.5 py-2 text-gray-500 justify-between">
<div class="text-gray-500 line-clamp-2">{{ item.comments }}</div>
</div>
<div class="button-group flex justify-between items-center mt-3">
<el-button class="w-full" @click="openSpmUrl(`https://${item.tenantId}.wsdns.cn`,item,item.companyId,true)">预览</el-button>
</div>
</div>
</el-card>
</el-col>
</template>
</el-row>
</div>
<div v-if="disabled" class="px-1 text-center text-gray-500 min-h-xs">
没有更多了
</div>
</template>
<script setup lang="ts">
import {openSpmUrl} from "~/utils/common";
import type {Company} from "~/api/system/company/model";
const props = withDefaults(
defineProps<{
list?: Company[];
disabled?: boolean;
fit?: any;
}>(),
{
fit: 'cover'
}
);
const emit = defineEmits<{
(e: 'done'): void;
}>();
const load = () => {
if(!props.disabled){
emit('done')
}
}
</script>

9
pages/user/components/Order.vue

@ -2,10 +2,14 @@
<el-table :data="tableData">
<el-table-column prop="orderId" label="订单号" />
<el-table-column prop="comments" label="产品名称" />
<el-table-column prop="payPrice" label="订单金额" />
<el-table-column prop="payPrice" label="订单金额(元)" />
<el-table-column prop="month" label="购买时长(月)" />
<el-table-column prop="appName" label="应用名称" />
<el-table-column prop="createTime" label="下单时间" />
<el-table-column prop="action" label="操作" />
<el-table-column prop="action" label="操作">
<template #default="scope">
<el-button @click="openSpmUrl(`https://${scope.row.tenantId}.websoft.top`,form,scope.row.tenantId,true)">控制台</el-button></template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
@ -32,6 +36,7 @@ const {data: response} = await useServerRequest<ApiResult<PageResult<OrderGoods>
})
if(response.value?.data){
tableData.value = response.value.data.list;
console.log(tableData.value,'tableData')
}
</script>

Loading…
Cancel
Save